=head1 NAME

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

=head1 Introduction

One of the most important goals of the Prima project is the portability between
different operating systems. Independently to efforts in keeping Prima's internal
code that 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.

=head1 Minimal display capabilities

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

=over

=item Minimal capabilities

Distinct black and white colors

At least one monospaced font

Solid fill

rop::Copy and rop::NoOper

=item Plotting primitives

SetPixel,GetPixel

Line,PolyLine

Rectangle

FillPoly

TextOut

PutImage,GetImage

=item Information services

GetTextWidth,GetFontMetrics,GetCharacterABCWidths

GetImageBitsLayout

=item Properties

color

backColor

rop

rop2

fillPattern

fillMode

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 has to follow all obligations for the mode. For
example, if the platform supports full functionality for black color but
limited functionality for the other colors, the wrapping code should not allow
the color property to be writable.

=back

=head1 Inevident issues

=head2 Colors

=over

=item Black and white colors on paletted displays

Since paletted displays use indexed color representation, the 'black' and
'white' indices are not always 0 and 2^n-1, so if one uses the indexes for
the actual black and white colors in the palette, the result of raster image
operations may look garbled (X11).  Win32 protects itself from this condition
by forcing white to be the last color in the system palette.

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

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

=item Black might be not 0, and white not 0xffffff

This obscure issue happens mostly on the 15- and 16-bit pixel displays. Internal
color representation for the white color on a 15-color display ( assuming R,G
and B are 5-bit fields) is

 11111000 11111000 11111000
 --R----- --G----- --B-----

that equals 0xf8f8f8.

A bit of advice: do not check for 'blackness' and 'whiteness' merely by comparing to
the 0x000000 or 0xffffff constant.

=back

=head2 Filled shapes

=over

=item Dithering

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

=item Pattern offset

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

Workaround: Do not use patterned backgrounds or use C<fillPatternOffset>
property.  Since the same effect is visible on dithered backgrounds, check 
if the color used is pure.

=back

=head2 Lines

=over

=item Dithering

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

=back

=head2 Fonts

=over

=item Font metric inconsistency

A font is loaded by request with one size but claims another afterward (X11).

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

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

=item Transparent plotting

No internal function for drawing transparent bitmaps (to implement text
plotting).  Therefore, if a font emulation is desired, special ROPs cannot be
reproduced. (Win9X, WinNT)

Impact: font emulation is laborious, primarily because the glyphs
have to be plotted by consequential I<and>-ing and I<xor>-ing a bitmap.
A full spectrum of the raster operations cannot be achieved with this
approach.

=item Text background

If a text is drawn with a non-CopyPut raster operation, the text background is
not expected to be mixed with glyphs - however, this is too hard to
implement uniformly, so results may differ for different platforms.

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

A bit of advice: Do not use ::rop2 and text background for special effects

=item Internal platform features

Font change notification is not provided. (X11)

Raster fonts cannot be synthesized (partly X11)

=back

=head2 Raster operations ( ROPs)

The background raster operations are not supported (X11,Win9X,WinNT. 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. The behavior of the current implementation is that they do not.

=head2 Palettes

=over

=item Static palettes

Some displays are unable to change their hardware palette, so detecting an 8-
or 4-bit display doesn't automatically mean that the palette is writable.(X11)

=item Widget::palette

The C<Widget::palette> property is used for an explicit declaration of extra
colors needed by a widget. The request might be satisfied in different ways, or
might not be at all. It is advisable not to rely on platform behavior for the
palette operations.

=item Dynamic palette change

It is possible (usually on 8-bit displays) for a display to change
asynchronously its hardware palette 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 the Widget::palette property. The system
palette is switched every time as different windows move to the front.

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

=back

=head2 Bitmaps

=over

=item Invalid scaling

Bitmap scaling is invalid (Win9X) or not supported (X11 without XRender). A
common mistake is to not take into account the fractional pixels that appear
when the scaling factor is more than 1

Workaround: described in L<Prima::ImageViewer/zoom> .

=item Large scale factors

Request for drawing a bitmap might fail if a large scaling factor is selected.
(Win9X,WinNT).  This is probably because these platforms scale the
bitmap into memory before the plotting takes place.

=back

=head2 Layering

On win32, layered widgets with pixels assigned zero alpha component, will not
receive mouse events.

=head1 Platform-specific peculiarities

=head2 Windows 9X

The number of GDI objects can not exceed some unknown threshold - experiments
show that 128 objects is a number that is safe enough.

The color cursor creation routine is broken.

Filled shapes are broken.

=head2 X11

No bitmap scaling (if compiled without XRender)

No font rotation (if compiled without Xft)

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.

=head1 Implementation notes

=head2 Win32

The plotting speed of DeviceBitmaps is somewhat less on 8-bit displays than
when plotting Images and Icons. It is because DeviceBitmaps are bound to their
original palette, so putting a DeviceBitmap on a drawable with a different
palette uses inefficient algorithms to provide correct results.

=head2 X11

If an image was first drawn on a paletted Drawable, then drawing it on
another paletted Drawable would reduce the image to 8 safe colors.

This is by design and is so because the image has a special cache in the
display pixel format.  Refreshing the cache on every PutImage call is very
inefficient (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.

=head1 AUTHOR

Dmitry Karasik, E<lt>dmitry@karasik.eu.orgE<gt>.

=head1 SEE ALSO

L<Prima>
