Man Linux: Main Page and Category List

NAME

       Prima::gp-problems - Problems, questionable or intricate topics in 2-D
       Graphics

Introduction

       One of the most important goals of the Prima project is portability
       between different operating systems. Independently to efforts in
       keeping Prima internal code that it behaves more or less identically on
       different platforms, it is always possible to write non-portable and
       platform-dependent code.  Here are some guidelines and suggestions for
       2-D graphics programming.

Minimal display capabilities

       A compliant display is expected to have minimal set of capabilities,
       that programmer can rely upon.  Following items are guaranteedly
       supported by Prima:

       Minimal capabilities
           Distinct black and white colors

           Line widths 0 and 1

           One monospaced font

           Solid fill

           rop::Copy and rop::NoOper

       Plotting primitives
           SetPixel,GetPixel

           Line,PolyLine,PolyLines

           Ellipse,Arc,Chord,Sector

           Rectangle

           FillPoly

           FillEllipse,FillChord,FillSector

           TextOut

           PutImage,GetImage

       Information services
           GetTextWidth,GetFontMetrics,GetCharacterABCWidths

           GetImageBitsLayout

       Properties
           color

           backColor

           rop

           backRop

           lineWidth

           lineJoin

           lineStyle

           fillPattern

           fillPolyWinding

           textOpaque

           clipRect

           All these properties must be present, however it is not required
           for them to be changeable. Even if an underlying platform-specific
           code can only support one mode for a property, it have to follow
           all obligations for the mode. For example, if platform supports
           full functionality for black color but limited functionality for
           the other colors, the wrapping code should not allow color property
           to be writable then.

Inevident issues

   Colors
       Black and white colors on paletted displays
           Due the fact that paletted displays employ indexed color
           representation, ’black’ and ’white’ indices are not always 0 and
           2^n-1, so result of raster image operations may look garbled (X).
           Win32 and OS/2 protect themselves from this condition by forcing
           white to be the last color in the system palette.

           Example: if white color on 8-bit display occupies palette index 15
           then desired masking effect wouldn’t work for xoring transparent
           areas with cl::White.

           Workaround: Use two special color constants cl::Clear and cl::Set,
           that represent all zeros and all ones values for bit-sensitive
           raster operations.

       Black might be not 0, and white not 0xffffff
           This inevident issue happens mostly on 15- and 16-bits pixel
           displays. Internal color representation for the white color on a
           15-color display ( assuming R,G and B are 5-bits fields) is

            11111000 11111000 11111000

            --R----- --G----- --B-----
           that equals to 0xf8f8f8. (All)

           Advise: do not check for ’blackness’ and ’whiteness’ merely by
           comparing a pixel value.

       Pixel value coding
           Status: internal

           It is not checked how does Prima behave when a pixel value and a
           platform integer use different bit and/or byte priority (X).

   Filled shapes
       Dithering
           If a non-solid pattern is selected and a background and/or a
           foreground color cannot be drawn as a solid, the correct rendering
           requires correspondingly 3 or 4 colors.  Some rendering engines
           (Win9X) fail to produce correct results.

       Overfill effect
           In complex shapes ( FillPoly, for example) the platform renderer
           can fill certain areas two or more times. Whereas the effect is not
           noticeable with rop::CopyPut, the other raster operations (like
           rop::Xor) produce incorrect picture. (OS/2)

           NB - has nothing in common with the fill winding rule.

           Workaround: Do not use raster operations with complex filled shapes

       Pattern offset
           For a widget that contains a pattern-filled shape, its picture will
           be always garbled after scrolling, because it is impossible to
           provide an algorithm for a correct rendering without a prior
           knowledge of the widget nature. (All)

           Workaround: Do not use patterned backgrounds.  Since the same
           effect is visible on dithered backgrounds, routine check for pure
           color might be applied.

   Lines
       Line caps over patterned styles
           It is not clear, whether gaps between dashes should be a multiple
           to a line width or not. For example, lp::DotDot looks almost as a
           solid line when lineWidth is over 10 if the first (non-multiple)
           tactic is chosen.  From the other hand it is hardly possible to
           predict the plotting strategy from a high-level code. The problem
           is related more to Prima design rather than to a platform-specific
           code. (All)

           Workaround: use predefined patterns (lp::XXX)

       Line joins
           Joint areas may be drawn two (or more) times - the problem emerges
           if logical ROP (rop::Xor) is chosen.(OS/2)

       Dithering
           Dithering might be not used for line plotting. (Win9X)

   Fonts
       Font metric inconsistency
           A font is loaded by request with one size, but claims another
           afterwards.(OS/2, X).

           Impact: system-dependent font description may not match to Prima’s.

           Advise: do not try to deduce Prima font metrics from system-
           dependent ones and vice versa.

       Transparent plotting
           No internal function for drawing transparent bitmaps (like fonts).
           Therefore, if a font emulation is desired, special ROPs cannot be
           reproduced. (OS/2, Win9X, WinNT)

           Impact: font emulation is laborsome, primarily because the glyphs
           have to be plotted by consequential anding and xoring a bitmap.
           Full spectrum of the raster operations cannot be achieved with this
           approach.

       Kerning
           Prima do not use text kernings, nor encourages underlying platform-
           specific code to use it - primarily because of its complexity.
           From the other hand, sometimes glyph position cannot be determined
           correctly if no information for the text kerning is provided.
           (Win9X)

       Fractional text position
           If the font glyphs have fractional widths, it might be observed
           that letters may change their position in a string.

           Example: A set of glyphs has width of 8.6 pixels for each symbol.
           If the string "abcd" is drawn at position 0, then black part of "d"
           starts at 25th pixel, but if "cd" is drawn at 17th, as it supposed
           to be if the integer arithmetics is used, it starts at 24th pixel.
           (OS/2)

           Solution: Do not rely to Drawable::get_text_width information,
           because it always returns integer value, but to
           Drawable::get_font_abc, which returns real values.

       Text background
           If a text is drawn with non-CopyPut raster operation, text
           background is not expected to be mixed with symbols - however this
           is hardly reachable, so results differs for different platforms.

           Text background may be only drawn with pure ( non-dithered ) color
           (Win9X,WinNT) - but this is (arguably) a more correct behavior.

           Advise: Do not use ::rop2 and text background for special effects

       Internal platform features
           Font change notification is not provided. (X, OS/2)

           Raster fonts cannot be synthesized (OS/2, partly X)

   Raster operations ( ROPs)
       Background raster operations are not supported (X,Win9X,WinNT) and
       foreground ROPs have limited number of modes (OS/2,X). Not all ROPs can
       be emulated for certain primitives, like fonts, complex shapes, and
       patterned shapes.

       It is yet unclear which primitives have to support ROPs, - like
       FloodFill and SetPixel. Behavior of the current implementation is that
       they do not.

   Arcs
       Platforms tend to produce different results for angles outside 0 and
       2pi. Although Prima assures that correct plotting would be performed
       for any angle, minor inconsistencies may be noticed.  If emulating,
       note that 2 and 4-pi arcs are not the same - for example, they look
       differently with rop::Xor.

   Palettes
       Static palettes
           Some displays are unable to change their hardware palette, so
           detecting 8- or 4- bits display doesn’t automatically mean that
           palette is writable.(X)

       Widget::palette
           Widget::palette property is used for explicit declaration of extra
           color needs for a widget. The request might be satisfacted in
           different ways, or might not at all. It is advisable not to rely
           onto platform behavior for the palette operations.

       Dynamic palette change
           It is possible (usually on 8-bits displays) for a display to change
           asynchronously its hardware palette in order to process different
           color requests. All platforms behave differently.

           Win9X/WinNT - only one top-level window at a time and its direct
           children ( not ::clipOwner(0)) can benefit from using
           Widget::palette. System palette is switched every time as different
           windows moved to the front.

           OS/2 - not implemented, but in principle the same as under win32.

           X - Any application can easily ruin system color table.  Since this
           behavior is such by design, no workaround can be applied here.

   Bitmaps
       Invalid scaling
           Scaling is invalid (Win9X) or not supported (X). Common mistake is
           to not take into an account the fractional pixels that appear when
           the scaling factor is more than 1. This mistake can be observed in
           Win9X.

           Workaround: none

       Large scale factors
           Request for drawing a bitmap might fail if large scaling factor is
           selected. (OS/2,Win9X,WinNT).  This effect is obviously due that
           fact that these platforms scale the bitmap into a memory before the
           plotting takes place.

Platform-specific peculiarities

   OS/2
       Some ROPs are ambiguous - SRCTRANSPARENT, for example. Some times they
       work, some times they don’t. The particular behavior depends on a video
       driver.

       Circles cannot be drawn using an even diameter.

       Fast GDI operations on HWND_DESKTOP may be delayed, thus GetPixel may
       return invalid pixel values.

   Windows 9X
       Amount of GDI objects can not exceed some unknown threshold -
       experiments show that 128 objects is safe enough.

       No transformations.

       Color cursor creation routine is broken.

       Filled shapes are broken.

   X
       No transformations

       No bitmap scaling

       No font rotation

       No GetPixel, FloodFill ( along with some other primitives)

       White is not 2^n-1 on n-bit paletted displays (tested on XFree86).

       Filled shapes are broken.

       Color bitmaps cannot be drawn onto mono bitmaps.

Implementation notes

   OS/2
       Palettes are not implemented

   Win32
       Plotting speed of DeviceBitmaps is somewhat less on 8-bit displays than
       Images and Icons. It is because DeviceBitmaps are bound to their
       original palette, so putting a DeviceBitmap onto different palette
       drawable employs inefficient algorithms in order to provide correct
       results.

   X
       Image that was first drawn on a paletted Drawable always seen in 8
       colors if drawn afterwards on a Drawable with the different palette.
       That is because the image has special cache in display pixel format,
       but cache refresh on every PutImage call is absolutely inappropriate
       (although technically possible).  It is planned to fix the problem by
       checking the palette difference for every PutImage invocation.  NB -
       the effect is seen on dynamic color displays only.

AUTHOR

       Dmitry Karasik, <dmitry@karasik.eu.org>.

SEE ALSO

       Prima