BS_PATTERN brushes in mfdrv

Walt Ogburn reuben at ugcs.caltech.edu
Thu Jan 13 02:41:09 CST 2005


This patch makes the metafile test in gdi not crash (and work properly).
This version uses helper functions to convert the BMP into DIB, like
the enhmfdrv version does.

Changelog:
Fix BS_PATTERN brushes in mfdrv.  Un-comment the corresponding test.

- Walter


? dlls/gdi/tests/.metafile.c.swp
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	13 Jan 2005 08:31:03 -0000
@@ -126,6 +126,68 @@
     return 0;
 }

+/***********************************************************************
+ * Internal helper for MFDRV_CreateBrushIndirect():
+ * Change the padding of a bitmap from 16 (BMP) to 32 (DIB) bits.
+ */
+static inline void MFDRV_PadTo32(LPBYTE lpRows, int height, int width)
+{
+    int bytes16 = 2 * ((width + 15) / 16);
+    int bytes32 = 4 * ((width + 31) / 32);
+    LPBYTE lpSrc, lpDst;
+    int i;
+
+    if (!height)
+        return;
+
+    height = abs(height) - 1;
+    lpSrc = lpRows + height * bytes16;
+    lpDst = lpRows + height * bytes32;
+
+    /* Note that we work backwards so we can re-pad in place */
+    while (height >= 0)
+    {
+        for (i = bytes32; i > bytes16; i--)
+            lpDst[i - 1] = 0; /* Zero the padding bytes */
+        for (; i > 0; i--)
+            lpDst[i - 1] = lpSrc[i - 1]; /* Move image bytes into alignment */
+        lpSrc -= bytes16;
+        lpDst -= bytes32;
+        height--;
+    }
+}
+
+/***********************************************************************
+ * Internal helper for MFDRV_CreateBrushIndirect():
+ * Reverse order of bitmap rows in going from BMP to DIB.
+ */
+static inline void MFDRV_Reverse(LPBYTE lpRows, int height, int width)
+{
+    int bytes = 4 * ((width + 31) / 32);
+    LPBYTE lpSrc, lpDst;
+    BYTE temp;
+    int i;
+
+    if (!height)
+        return;
+
+    lpSrc = lpRows;
+    lpDst = lpRows + (height-1) * bytes;
+    height = height/2;
+
+    while (height > 0)
+    {
+        for (i = 0; i < bytes; i++)
+        {
+            temp = lpDst[i];
+            lpDst[i] = lpSrc[i];
+            lpSrc[i] = temp;
+        }
+        lpSrc += bytes;
+        lpDst -= bytes;
+        height--;
+    }
+}

 /******************************************************************
  *         MFDRV_CreateBrushIndirect
@@ -162,9 +224,9 @@
     case BS_PATTERN:
         {
 	    BITMAP bm;
-	    BYTE *bits;
 	    BITMAPINFO *info;
 	    DWORD bmSize;
+	    COLORREF cref;

 	    GetObjectA((HANDLE)logbrush.lbHatch, sizeof(bm), &bm);
 	    if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) {
@@ -190,12 +252,30 @@
 	    info->bmiHeader.biHeight = bm.bmHeight;
 	    info->bmiHeader.biPlanes = 1;
 	    info->bmiHeader.biBitCount = 1;
-	    bits = ((BYTE *)info) + sizeof(BITMAPINFO) + sizeof(RGBQUAD);
+	    info->bmiHeader.biSizeImage = bmSize;

-	    GetDIBits(physDev->hdc, (HANDLE)logbrush.lbHatch, 0, bm.bmHeight,
-		      bits, info, DIB_RGB_COLORS);
-	    *(DWORD *)info->bmiColors = 0;
-	    *(DWORD *)(info->bmiColors + 1) = 0xffffff;
+	    GetBitmapBits((HANDLE)logbrush.lbHatch,
+		      bm.bmHeight * BITMAP_GetWidthBytes (bm.bmWidth, bm.bmBitsPixel),
+		      (LPBYTE)info + sizeof(BITMAPINFO) + sizeof(RGBQUAD));
+
+	    /* Change the padding to be DIB compatible if needed */
+	    if(bm.bmWidth & 31)
+	        MFDRV_PadTo32((LPBYTE)info + sizeof(BITMAPINFO) + sizeof(RGBQUAD),
+		      bm.bmWidth, bm.bmHeight);
+	    /* BMP and DIB have opposite row order conventions */
+            MFDRV_Reverse((LPBYTE)info + sizeof(BITMAPINFO) + sizeof(RGBQUAD),
+		      bm.bmWidth, bm.bmHeight);
+
+	    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;
 	    break;
 	}

Index: dlls/gdi/tests/metafile.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/tests/metafile.c,v
retrieving revision 1.4
diff -u -r1.4 metafile.c
--- dlls/gdi/tests/metafile.c	27 Dec 2004 17:46:36 -0000	1.4
+++ dlls/gdi/tests/metafile.c	13 Jan 2005 08:31:03 -0000
@@ -442,8 +442,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