dib fixes

Rein Klazes wijn at wanadoo.nl
Mon Apr 11 09:59:22 CDT 2005


On Sat, 09 Apr 2005 10:19:36 +0200, you wrote:

> > Are you suggesting more checks then that the pixels are within the
> > dimensions of the drawable?
> you need at least to use the intersection of the bitmap and the drawable (not 
> sure both start at (0,0) corner though).

I tried to do this, you need to clip to the visible region as well. I
could not get it 100% full proof because of races between the clip
calculations and the actual positions on the screen.

So I get the pixels now from the root window (clipped to the screen) and
everything is rock solid. The code is simpler too.

> I was also wondering what would happen when stretching is required, but IIRC 
> this is done way before (normally)

Funny, in my tests StretchDIBits() with such bitmaps leaves black gaps
(Wine2K and WinME) as long as you do not do a 1:1 stretch. With 1:1
stretches or using SetDIBitsToDevice I see the behavior as you
described.

Changelog:
dlls/x11drv	: dib.c

In X11DRV_DIB_SetImageBits avoid BadMatch errors when calling
XGetSubImage.

Rein.
-------------- next part --------------
--- wine/dlls/x11drv/dib.c	2005-04-01 13:32:29.000000000 +0200
+++ mywine/dlls/x11drv/dib.c	2005-04-11 15:33:39.000000000 +0200
@@ -3434,6 +3444,32 @@ static void X11DRV_DIB_GetImageBits_32( 
 }
 
 /***********************************************************************
+ *           X11DRV_DIB_SetImageBits_GetSubImage
+ *
+ *  Helper for X11DRV_DIB_SetImageBits
+ */
+static void X11DRV_DIB_SetImageBits_GetSubImage(
+        const X11DRV_DIB_IMAGEBITS_DESCR *descr, XImage *bmpImage)
+{
+    /* compressed bitmaps may contain gaps in them. So make a copy
+     * of the existing pixels first */
+    RECT bmprc = { descr->xDest, descr->yDest,
+        descr->xDest + descr->width , descr->yDest + descr->height};
+    RECT rc = { 0, 0, screen_width, screen_height};
+
+    /* - convert to screen coordinates */
+    OffsetRect( &bmprc, descr->physDev->drawable_org.x,
+             descr->physDev->drawable_org.y);
+    /* clip to screen rectangle */
+    if( IntersectRect( &rc, &rc, &bmprc))
+        XGetSubImage( gdi_display, root_window, rc.left, rc.top,
+                rc.right - rc.left, rc.bottom - rc.top, AllPlanes,
+                ZPixmap, bmpImage,
+                descr->xSrc + rc.left - bmprc.left,
+                descr->ySrc + rc.top - bmprc.top);
+}
+
+/***********************************************************************
  *           X11DRV_DIB_SetImageBits
  *
  * Transfer the bits to an X image.
@@ -3475,10 +3511,7 @@ static int X11DRV_DIB_SetImageBits( cons
 	break;
     case 4:
         if (descr->compression) {
-	    XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
-			  descr->width, descr->height, AllPlanes, ZPixmap,
-			  bmpImage, descr->xSrc, descr->ySrc );
-
+            X11DRV_DIB_SetImageBits_GetSubImage( descr, bmpImage);
 	    X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
 					  descr->infoWidth, descr->width,
 					  descr->xSrc, (int *)(descr->colorMap),
@@ -3491,9 +3524,7 @@ static int X11DRV_DIB_SetImageBits( cons
 	break;
     case 8:
         if (descr->compression) {
-	    XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
-			  descr->width, descr->height, AllPlanes, ZPixmap,
-			  bmpImage, descr->xSrc, descr->ySrc );
+            X11DRV_DIB_SetImageBits_GetSubImage( descr, bmpImage);
 	    X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
 					  descr->infoWidth, descr->width,
 					  descr->xSrc, (int *)(descr->colorMap),


More information about the wine-patches mailing list