Better PolyLine drawing

Rein Klazes wijn at wanadoo.nl
Thu May 5 05:53:01 CDT 2005


Hi,

cc to wine-devel: I may overlooked something here.

The patch fixes a problem in BigJig a jigsaw puzzle game (free download
at www.lenagames.com) when it generates the pieces. The jigsaw piece
shapes are generated with a series of short (5-7 points) Polyline calls,
followed by a call to FloodFill.

Unfortunately in Wine there are sometimes gaps between the polyline
segments, leaking the floodfill. In Windows if a line or polyline is
drawn from x1,y1 to xn,yn , the pixel at x1,y1 is always painted and the
one at xn,yn not (unless it is also painted as another part of the
segment), that guarantees that there are no gaps.

X11DRV_PolyLine refuses to use the pen if the pen width is zero, it
changes the width to 1 instead. This causes 'X' to use an alternate line
drawing algorithm, more focused on pleasing appearance then on details
like mentioned above. Setting the pen width to zero make all the
problems go away.

I do not know why the pen width is set to zero, this came into wine
somewhere in 1998 before the change to cvs. Arguments against it are:

- line drawing with pen width 1 are not like in Windows, in contrast to
width 0 are very much like in Windows;
- line drawing with pen width 1 is slower;
- PolyPolyLine, LineTo and all other algorithms in wine do not do this;
- Xlib programming manual recommends not to mix pen with 0 and pen width
1 drawing.

I have looked at this both on a Debian XFree86 system and a Suse 9.2
with XOrg.


Changelog:

dlls/x11drv	: graphics.c, pen.c

Don't set the pen width to 1 in X11DRV_PolyLine.

Rein.
-------------- next part --------------
--- wine/dlls/x11drv/graphics.c	2004-08-12 01:45:34.000000000 +0200
+++ mywine/dlls/x11drv/graphics.c	2005-05-05 11:39:37.000000000 +0200
@@ -1017,12 +1017,9 @@ X11DRV_PaintRgn( X11DRV_PDEVICE *physDev
 BOOL
 X11DRV_Polyline( X11DRV_PDEVICE *physDev, const POINT* pt, INT count )
 {
-    INT oldwidth;
-    register int i;
+    int i;
     XPoint *points;
 
-    if((oldwidth = physDev->pen.width) == 0) physDev->pen.width = 1;
-
     if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * count )))
     {
         WARN("No memory to convert POINTs to XPoints!\n");
@@ -1047,7 +1044,6 @@ X11DRV_Polyline( X11DRV_PDEVICE *physDev
     }
 
     HeapFree( GetProcessHeap(), 0, points );
-    physDev->pen.width = oldwidth;
     return TRUE;
 }
 
--- wine/dlls/x11drv/pen.c	2004-01-15 07:19:35.000000000 +0100
+++ mywine/dlls/x11drv/pen.c	2005-05-05 11:43:21.000000000 +0200
@@ -47,7 +47,8 @@ HPEN X11DRV_SelectPen( X11DRV_PDEVICE *p
 
     physDev->pen.width = X11DRV_XWStoDS( physDev, logpen.lopnWidth.x );
     if (physDev->pen.width < 0) physDev->pen.width = -physDev->pen.width;
-    if (physDev->pen.width == 1) physDev->pen.width = 0;  /* Faster */
+    if (physDev->pen.width == 1) physDev->pen.width = 0;  /* Faster and more
+                                                             Windows likeness */
     if (hpen == GetStockObject( DC_PEN ))
         logpen.lopnColor = GetDCPenColor( physDev->hdc );
     physDev->pen.pixel = X11DRV_PALETTE_ToPhysical( physDev, logpen.lopnColor );


More information about the wine-devel mailing list