BS_PATTERN brushes in metafiles

Walt Ogburn reuben at ugcs.caltech.edu
Thu Dec 9 21:25:51 CST 2004


I've submitted patches for this crash before, but this one now has a test
to show the output is correct.  The patch also un-comments the test,
which now passes.

- Walter


Changelog:
Handle BS_PATTERN brushes in mfdrv by converting the 16-bit bitmap to a
32-bit bitmap.




Index: dlls/gdi/mfdrv/objects.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/mfdrv/objects.c,v
retrieving revision 1.14
diff -u -r1.14 objects.c
--- dlls/gdi/mfdrv/objects.c	22 Nov 2004 18:19:59 -0000	1.14
+++ dlls/gdi/mfdrv/objects.c	10 Dec 2004 04:01:55 -0000
@@ -164,7 +164,9 @@
 	    BITMAP bm;
 	    BYTE *bits;
 	    BITMAPINFO *info;
-	    DWORD bmSize;
+	    DWORD bmRowSize, dibRowSize, dibSize;
+	    DWORD i;
+	    COLORREF cref;

 	    GetObjectA((HANDLE)logbrush.lbHatch, sizeof(bm), &bm);
 	    if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) {
@@ -172,10 +174,12 @@
 		goto done;
 	    }

-	    bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, DIB_PAL_COLORS);
-
+	    /* Input bitmap is known to be 1 bpp. */
+	    bmRowSize = 2 * ((bm.bmWidth + 15) >> 4);
+            dibRowSize = 4 * ((bm.bmWidth + 31) >> 5);
+            dibSize = dibRowSize * bm.bmHeight;
 	    size = sizeof(METARECORD) + sizeof(WORD) + sizeof(BITMAPINFO)
+
-	      sizeof(RGBQUAD) + bmSize;
+	      sizeof(RGBQUAD) + dibSize;

 	    mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
 	    if(!mr) goto done;
@@ -190,12 +194,30 @@
 	    info->bmiHeader.biHeight = bm.bmHeight;
 	    info->bmiHeader.biPlanes = 1;
 	    info->bmiHeader.biBitCount = 1;
-	    bits = ((BYTE *)info) + sizeof(BITMAPINFO) + sizeof(RGBQUAD);
+	    info->bmiHeader.biSizeImage = dibSize;
+
+            /* Turn 16-bit-aligned BITMAP rows into 32-bit-aligned
+             * dib rows, in reverse order.
+             */
+            bits = ((BYTE *)info) + sizeof(BITMAPINFO) + sizeof(RGBQUAD)
+	        + dibSize - dibRowSize;
+            for (i=0; i<bm.bmHeight; i++)
+            {
+                memcpy (bits, (BYTE *)bm.bmBits + i*bmRowSize, bmRowSize);
+                bits -= dibRowSize;
+            }
+
+            cref = GetTextColor(physDev->hdc);
+            info->bmiColors[0].rgbRed = GetRValue(cref);
+            info->bmiColors[0].rgbGreen = GetGValue(cref);
+            info->bmiColors[0].rgbBlue = GetBValue(cref);
+            info->bmiColors[0].rgbReserved = 0;
+            cref = GetBkColor(physDev->hdc);
+            info->bmiColors[1].rgbRed = GetRValue(cref);
+            info->bmiColors[1].rgbGreen = GetGValue(cref);
+            info->bmiColors[1].rgbBlue = GetBValue(cref);
+            info->bmiColors[1].rgbReserved = 0;

-	    GetDIBits(physDev->hdc, (HANDLE)logbrush.lbHatch, 0, bm.bmHeight,
-		      bits, info, DIB_RGB_COLORS);
-	    *(DWORD *)info->bmiColors = 0;
-	    *(DWORD *)(info->bmiColors + 1) = 0xffffff;
 	    break;
 	}

Index: dlls/gdi/tests/metafile.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/tests/metafile.c,v
retrieving revision 1.3
diff -u -r1.3 metafile.c
--- dlls/gdi/tests/metafile.c	9 Dec 2004 11:37:59 -0000	1.3
+++ dlls/gdi/tests/metafile.c	10 Dec 2004 04:01:56 -0000
@@ -424,8 +424,5 @@
     /* For win-format metafiles (mfdrv) */
     test_mf_Blank();
     test_mf_Graphics();
-
-    /* Crashes under wine: */
-    /* test_mf_PatternBrush(); */
-
+    test_mf_PatternBrush();
 }



More information about the wine-patches mailing list