dibs: improve monochrome dibsection bitblting

Huw D M Davies h.davies1 at physics.ox.ac.uk
Thu Sep 16 14:32:31 CDT 2004


	Huw Davies <huw at codeweavers.com>
	When we blit with a monochrome dibsection as the source we should
	use the colour table of that dib.
	Add a test for this.
Index: dlls/gdi/tests/bitmap.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/tests/bitmap.c,v
retrieving revision 1.2
diff -u -r1.2 bitmap.c
--- dlls/gdi/tests/bitmap.c	16 Sep 2004 19:10:14 -0000	1.2
+++ dlls/gdi/tests/bitmap.c	16 Sep 2004 19:24:50 -0000
@@ -157,8 +157,8 @@
 
 static void test_dibsections(void)
 {
-    HDC hdc, hdcmem;
-    HBITMAP hdib, oldbm;
+    HDC hdc, hdcmem, hdcmem2;
+    HBITMAP hdib, oldbm, hdib2, oldbm2;
     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
     BYTE *bits;
@@ -167,6 +167,7 @@
     char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
     LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
     WORD *index;
+    DWORD *bits32;
     HPALETTE hpal, oldpal;
 
     hdc = GetDC(0);
@@ -234,6 +235,25 @@
        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
 
+    /* Bottom and 2nd row from top green, everything else magenta */
+    bits[0] = bits[1] = 0xff;
+    bits[13 * 4] = bits[13*4 + 1] = 0xff;
+
+
+    pbmi->bmiHeader.biBitCount = 32;
+
+    hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
+    ok(hdib2 != NULL, "CreateDIBSection failed\n");
+    hdcmem2 = CreateCompatibleDC(hdc);
+    oldbm2 = SelectObject(hdcmem2, hdib2);
+
+    BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
+
+    ok(bits32[0] == 0xff00, "lower left pixel is %08lx\n", bits32[0]);
+    ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08lx\n", bits32[17]);
+
+    SelectObject(hdcmem2, oldbm2);
+    DeleteObject(hdib2);
 
     SelectObject(hdcmem, oldbm);
     DeleteObject(hdib);
Index: dlls/x11drv/bitblt.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/bitblt.c,v
retrieving revision 1.7
diff -u -r1.7 bitblt.c
--- dlls/x11drv/bitblt.c	26 Apr 2004 20:06:08 -0000	1.7
+++ dlls/x11drv/bitblt.c	16 Sep 2004 19:24:50 -0000
@@ -563,6 +563,24 @@
     return perfect;
 }
 
+static void get_colors(X11DRV_PDEVICE *physDevDst, X11DRV_PDEVICE *physDevSrc,
+		       int *fg, int *bg)
+{
+    RGBQUAD rgb[2];
+
+    *fg = physDevDst->textPixel;
+    *bg = physDevDst->backgroundPixel;
+    if(physDevSrc->depth == 1) {
+        if(GetDIBColorTable(physDevSrc->hdc, 0, 2, rgb) == 2) {
+            DWORD logcolor;
+            logcolor = RGB(rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue);
+            *fg = X11DRV_PALETTE_ToPhysical( physDevDst, logcolor );
+            logcolor = RGB(rgb[1].rgbRed, rgb[1].rgbGreen,rgb[1].rgbBlue);
+            *bg = X11DRV_PALETTE_ToPhysical( physDevDst, logcolor );
+        }
+    }
+}
+
 /***********************************************************************
  *           BITBLT_StretchRow
  *
@@ -868,6 +886,7 @@
     XImage *imageSrc, *imageDst;
     RECT rectSrc = *visRectSrc;
     RECT rectDst = *visRectDst;
+    int fg, bg;
 
     if (widthSrc < 0) xSrc += widthSrc;
     if (widthDst < 0) xDst += widthDst;
@@ -882,6 +901,7 @@
     rectDst.top    -= yDst;
     rectDst.bottom -= yDst;
 
+    get_colors(physDevDst, physDevSrc, &fg, &bg);
     /* FIXME: avoid BadMatch errors */
     imageSrc = XGetImage( gdi_display, physDevSrc->drawable,
                           physDevSrc->org.x + visRectSrc->left,
@@ -893,9 +913,8 @@
                                         rectDst.bottom - rectDst.top, physDevDst->depth );
     BITBLT_StretchImage( imageSrc, imageDst, widthSrc, heightSrc,
                          widthDst, heightDst, &rectSrc, &rectDst,
-                         physDevDst->textPixel, physDevDst->depth != 1 ?
-                         physDevDst->backgroundPixel :
-			 physDevSrc->backgroundPixel,
+                         fg, physDevDst->depth != 1 ?
+                         bg : physDevSrc->backgroundPixel,
                          GetStretchBltMode(physDevDst->hdc) );
     XPutImage( gdi_display, pixmap, gc, imageDst, 0, 0, 0, 0,
                rectDst.right - rectDst.left, rectDst.bottom - rectDst.top );
@@ -919,6 +938,7 @@
     int exposures = 0;
     INT width  = visRectSrc->right - visRectSrc->left;
     INT height = visRectSrc->bottom - visRectSrc->top;
+    int fg, bg;
 
     if (physDevSrc->depth == physDevDst->depth)
     {
@@ -976,17 +996,19 @@
     {
         if (physDevSrc->depth == 1)  /* monochrome -> color */
         {
+	    get_colors(physDevDst, physDevSrc, &fg, &bg);
+
             if (X11DRV_PALETTE_XPixelToPalette)
             {
                 XSetBackground( gdi_display, gc,
-                             X11DRV_PALETTE_XPixelToPalette[physDevDst->textPixel] );
+                             X11DRV_PALETTE_XPixelToPalette[fg] );
                 XSetForeground( gdi_display, gc,
-                             X11DRV_PALETTE_XPixelToPalette[physDevDst->backgroundPixel]);
+                             X11DRV_PALETTE_XPixelToPalette[bg]);
             }
             else
             {
-                XSetBackground( gdi_display, gc, physDevDst->textPixel );
-                XSetForeground( gdi_display, gc, physDevDst->backgroundPixel );
+                XSetBackground( gdi_display, gc, fg );
+                XSetForeground( gdi_display, gc, bg );
             }
             XCopyPlane( gdi_display, physDevSrc->drawable, pixmap, gc,
                         physDevSrc->org.x + visRectSrc->left,
@@ -1399,11 +1421,15 @@
             wine_tsx11_unlock();
             return TRUE;
         }
+
         if (physDevSrc->depth == 1)
         {
+            int fg, bg;
+	    get_colors(physDevDst, physDevSrc, &fg, &bg);
             wine_tsx11_lock();
-            XSetBackground( gdi_display, physDevDst->gc, physDevDst->textPixel );
-            XSetForeground( gdi_display, physDevDst->gc, physDevDst->backgroundPixel );
+
+            XSetBackground( gdi_display, physDevDst->gc, fg );
+            XSetForeground( gdi_display, physDevDst->gc, bg );
             XSetFunction( gdi_display, physDevDst->gc, GXcopy );
             XCopyPlane( gdi_display, physDevSrc->drawable,
                         physDevDst->drawable, physDevDst->gc,



More information about the wine-patches mailing list