Commit 9277cf19 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

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.
parent 175208f5
......@@ -106,15 +106,8 @@ BOOL WINAPI StretchBlt( HDC hdcDst, INT xDst, INT yDst,
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 @@ BOOL WINAPI MaskBlt(HDC hdcDest, INT nXDest, INT nYDest,
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 @@ BOOL WINAPI MaskBlt(HDC hdcDest, INT nXDest, INT nYDest,
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);
/* 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);
/* 5. restore all object */
SelectObject(hDCMask, hOldMaskBitmap);
SelectObject(hDC1, hOldBitmap2);
SelectObject(hDC2, hOldBitmap3);
/* restore all objects */
SelectObject(hdcDest, hbrDst);
SelectObject(hDC1, hOldBitmap1);
SelectObject(hDC2, hOldBitmap2);
/* 6. delete all temp object */
DeleteObject(hBitmap2);
DeleteObject(hBitmap3);
/* delete all temp objects */
DeleteObject(hBitmap1);
DeleteObject(hBitmap1);
DeleteObject(hbrMask);
DeleteDC(hDC1);
DeleteDC(hDC2);
DeleteDC(hDCMask);
return TRUE;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment