gdi: maskblt

Huw D M Davies h.davies1 at physics.ox.ac.uk
Wed Aug 11 08:34:39 CDT 2004


This relies on my 'removing 8x8 restriction on pattern brushes' patch

        Huw Davies <huw at codeweavers.com>
        Fix maskblt to work with any set of rops and to also take into
        account the current brush.  It also now works if the mask
        bitmap is already selected into a dc.
-- 
Huw Davies
huw at codeweavers.com
Index: dlls/gdi/bitblt.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/bitblt.c,v
retrieving revision 1.4
diff -u -r1.4 bitblt.c
--- dlls/gdi/bitblt.c	6 Aug 2004 18:59:31 -0000	1.4
+++ dlls/gdi/bitblt.c	11 Aug 2004 13:30:17 -0000
@@ -106,15 +106,8 @@
     return ret;
 }
 
-static inline BYTE SwapROP3_SrcDst(BYTE bRop3)
-{
-    return (bRop3 & 0x99) | ((bRop3 & 0x22) << 1) | ((bRop3 & 0x44) >> 1);
-}
-
 #define FRGND_ROP3(ROP4)	((ROP4) & 0x00FFFFFF)
-#define BKGND_ROP3(ROP4)	(ROP3Table[(SwapROP3_SrcDst((ROP4)>>24)) & 0xFF])
-#define DSTCOPY 		0x00AA0029
-#define DSTERASE		0x00220326 /* dest = dest & (~src) : DSna */
+#define BKGND_ROP3(ROP4)	(ROP3Table[((ROP4)>>24) & 0xFF])
 
 /***********************************************************************
  *           MaskBlt [GDI32.@]
@@ -124,8 +117,10 @@
 			INT nXSrc, INT nYSrc, HBITMAP hbmMask,
 			INT xMask, INT yMask, DWORD dwRop)
 {
-    HBITMAP hOldMaskBitmap, hBitmap2, hOldBitmap2, hBitmap3, hOldBitmap3;
-    HDC hDCMask, hDC1, hDC2;
+    HBITMAP hBitmap1, hOldBitmap1, hBitmap2, hOldBitmap2;
+    HDC hDC1, hDC2;
+    HBRUSH hbrMask, hbrDst, hbrTmp;
+
     static const DWORD ROP3Table[256] = 
     {
         0x00000042, 0x00010289,
@@ -261,50 +256,50 @@
     if (!hbmMask)
 	return BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));
 
-    /* 1. make mask bitmap's dc */
-    hDCMask = CreateCompatibleDC(hdcDest);
-    hOldMaskBitmap = (HBITMAP)SelectObject(hDCMask, hbmMask);
-
-    /* 2. make masked Background bitmap */
+    hbrMask = CreatePatternBrush(hbmMask);
+    hbrDst = SelectObject(hdcDest, GetStockObject(NULL_BRUSH));
 
-    /* 2.1 make bitmap */
+    /* make bitmap */
     hDC1 = CreateCompatibleDC(hdcDest);
-    hBitmap2 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
-    hOldBitmap2 = (HBITMAP)SelectObject(hDC1, hBitmap2);
-
-    /* 2.2 draw dest bitmap and mask */
-    BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY);
-    BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, BKGND_ROP3(dwRop));
-    BitBlt(hDC1, 0, 0, nWidth, nHeight, hDCMask, xMask, yMask, DSTERASE);
+    hBitmap1 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
+    hOldBitmap1 = SelectObject(hDC1, hBitmap1);
 
-    /* 3. make masked Foreground bitmap */
+    /* draw using bkgnd rop */
+    BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
+    hbrTmp = SelectObject(hDC1, hbrDst);
+    BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, BKGND_ROP3(dwRop));
+    SelectObject(hDC1, hbrTmp);
 
-    /* 3.1 make bitmap */
+    /* make bitmap */
     hDC2 = CreateCompatibleDC(hdcDest);
-    hBitmap3 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
-    hOldBitmap3 = (HBITMAP)SelectObject(hDC2, hBitmap3);
+    hBitmap2 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
+    hOldBitmap2 = SelectObject(hDC2, hBitmap2);
 
-    /* 3.2 draw src bitmap and mask */
+    /* draw using foregnd rop */
     BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
+    hbrTmp = SelectObject(hDC2, hbrDst);
     BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));
-    BitBlt(hDC2, 0, 0, nWidth, nHeight, hDCMask, xMask, yMask, SRCAND);
 
-    /* 4. combine two bitmap and copy it to hdcDest */
-    BitBlt(hDC1, 0, 0, nWidth, nHeight, hDC2, 0, 0, SRCPAINT);
-    BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hDC1, 0, 0, SRCCOPY);
-
-    /* 5. restore all object */
-    SelectObject(hDCMask, hOldMaskBitmap);
-    SelectObject(hDC1, hOldBitmap2);
-    SelectObject(hDC2, hOldBitmap3);
-
-    /* 6. delete all temp object */
-    DeleteObject(hBitmap2);
-    DeleteObject(hBitmap3);
+    /* combine both using the mask as a pattern brush */
+    SelectObject(hDC2, hbrMask);
+    BitBlt(hDC2, 0, 0, nWidth, nHeight, hDC1, 0, 0, 0xac0744 ); /* (D & P) | (S & ~P) */ 
+    SelectObject(hDC2, hbrTmp);
+
+    /* blit to dst */
+    BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hDC2, 0, 0, SRCCOPY);
+
+    /* restore all objects */
+    SelectObject(hdcDest, hbrDst);
+    SelectObject(hDC1, hOldBitmap1);
+    SelectObject(hDC2, hOldBitmap2);
+
+    /* delete all temp objects */
+    DeleteObject(hBitmap1);
+    DeleteObject(hBitmap1);
+    DeleteObject(hbrMask);
 
     DeleteDC(hDC1);
     DeleteDC(hDC2);
-    DeleteDC(hDCMask);
 
     return TRUE;
 }



More information about the wine-patches mailing list