COMCTL32: fix image list mask and blending
Mike McCormack
mike at codeweavers.com
Thu Jan 6 00:48:15 CST 2005
Imagelist is best tested with a visual test. Here's a test program I
put to together a while back, and a patch that makes it work better.
Mike
ChangeLog:
* fix image list mask and blending
-------------- next part --------------
Index: dlls/comctl32/imagelist.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/imagelist.c,v
retrieving revision 1.93
diff -u -r1.93 imagelist.c
--- dlls/comctl32/imagelist.c 30 Nov 2004 17:33:27 -0000 1.93
+++ dlls/comctl32/imagelist.c 6 Jan 2005 06:39:05 -0000
@@ -612,6 +612,8 @@
}
SelectObject(himl->hdcMask, himl->hbmMask);
}
+ else
+ himl->hbmMask = 0;
/* create blending brushes */
hbmTemp = CreateBitmap (8, 8, 1, 1, &aBitBlend25);
@@ -1056,10 +1058,10 @@
INT cx, cy, lx, ly, nOvlIdx;
DWORD fState, dwRop;
UINT fStyle;
- COLORREF clrBk, oldImageBk, oldImageFg;
+ COLORREF oldImageBk, oldImageFg;
HDC hImageDC, hImageListDC, hMaskListDC;
HBITMAP hImageBmp, hOldImageBmp, hBlendMaskBmp;
- BOOL bIsTransparent, bBlend, bResult = FALSE;
+ BOOL bIsTransparent, bBlend, bResult = FALSE, bMask;
HIMAGELIST himl;
if (!pimldp || !(himl = pimldp->himl)) return FALSE;
@@ -1073,9 +1075,14 @@
fStyle = pimldp->fStyle & ~ILD_OVERLAYMASK;
cx = (pimldp->cx == 0) ? himl->cx : pimldp->cx;
cy = (pimldp->cy == 0) ? himl->cy : pimldp->cy;
- clrBk = (pimldp->rgbBk == CLR_DEFAULT) ? himl->clrBk : pimldp->rgbBk;
- bIsTransparent = (fStyle & ILD_TRANSPARENT) || clrBk == CLR_NONE;
- bBlend = fStyle & (ILD_BLEND25 | ILD_BLEND50);
+
+ bIsTransparent = (fStyle & ILD_TRANSPARENT);
+ if( pimldp->rgbBk == CLR_NONE )
+ bIsTransparent = TRUE;
+ if( ( pimldp->rgbBk == CLR_DEFAULT ) && ( himl->clrBk == CLR_NONE ) )
+ bIsTransparent = TRUE;
+ bMask = (himl->flags & ILC_MASK) && (fStyle & ILD_MASK) ;
+ bBlend = (fStyle & (ILD_BLEND25 | ILD_BLEND50) ) && !bMask;
TRACE("himl(0x%lx) hbmMask(%p) iImage(%d) x(%d) y(%d) cx(%d) cy(%d)\n",
(DWORD)himl, himl->hbmMask, pimldp->i, pimldp->x, pimldp->y, cx, cy);
@@ -1107,24 +1114,43 @@
/*
* Draw the initial image
*/
- if (fStyle & ILD_MASK) {
+ if( bMask ) {
if (himl->hbmMask) {
- BitBlt(hImageDC, 0, 0, cx, cy, hMaskListDC, lx, ly, SRCCOPY);
+ HBRUSH hOldBrush;
+ hOldBrush = SelectObject (hImageDC, CreateSolidBrush (GetTextColor(pimldp->hdcDst)));
+ PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY );
+ BitBlt(hImageDC, 0, 0, cx, cy, hMaskListDC, lx, ly, SRCPAINT);
+ DeleteObject (SelectObject (hImageDC, hOldBrush));
+ if( bIsTransparent )
+ {
+ BitBlt ( pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, hImageDC, 0, 0, SRCAND);
+ bResult = TRUE;
+ goto end;
+ }
} else {
HBRUSH hOldBrush = SelectObject (hImageDC, GetStockObject(BLACK_BRUSH));
PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY);
SelectObject(hImageDC, hOldBrush);
}
- } else if (himl->hbmMask && !bIsTransparent) {
+ } else {
/* blend the image with the needed solid background */
- HBRUSH hOldBrush = SelectObject (hImageDC, CreateSolidBrush (clrBk));
+ COLORREF colour = RGB(0,0,0);
+ HBRUSH hOldBrush;
+
+ if( !bIsTransparent )
+ {
+ colour = pimldp->rgbBk;
+ if( colour == CLR_DEFAULT )
+ colour = himl->clrBk;
+ if( colour == CLR_NONE )
+ colour = GetBkColor(pimldp->hdcDst);
+ }
+
+ hOldBrush = SelectObject (hImageDC, CreateSolidBrush (colour));
PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY );
BitBlt( hImageDC, 0, 0, cx, cy, hMaskListDC, lx, ly, SRCAND );
BitBlt( hImageDC, 0, 0, cx, cy, hImageListDC, lx, ly, SRCPAINT );
DeleteObject (SelectObject (hImageDC, hOldBrush));
- } else {
- /* start off with the image, if we have a mask, we'll use it later */
- BitBlt( hImageDC, 0, 0, cx, cy, hImageListDC, lx, ly, SRCCOPY);
}
/* Time for blending, if required */
@@ -1179,7 +1205,7 @@
/* now copy the image to the screen */
dwRop = SRCCOPY;
- if (himl->hbmMask && bIsTransparent && !(fStyle & ILD_MASK)) {
+ if (himl->hbmMask && bIsTransparent ) {
COLORREF oldDstFg = SetTextColor(pimldp->hdcDst, RGB( 0, 0, 0 ) );
COLORREF oldDstBk = SetBkColor(pimldp->hdcDst, RGB( 0xff, 0xff, 0xff ));
BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, hMaskListDC, lx, ly, SRCAND);
@@ -1191,7 +1217,7 @@
BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, hImageDC, 0, 0, dwRop);
bResult = TRUE;
-
+end:
/* cleanup the mess */
SetBkColor(hImageDC, oldImageBk);
SetTextColor(hImageDC, oldImageFg);
@@ -1387,15 +1413,19 @@
/* draw mask*/
ii.hbmMask = CreateCompatibleBitmap (hdcDst, himl->cx, himl->cy);
- hOldDstBitmap = SelectObject (hdcDst, ii.hbmMask);
- PatBlt (hdcDst, 0, 0, himl->cx, himl->cy, WHITENESS);
- ImageList_Draw(himl, i, hdcDst, 0, 0, fStyle | ILD_MASK);
+ hOldDstBitmap = (HBITMAP)SelectObject (hdcDst, ii.hbmMask);
+ if (himl->hbmMask) {
+ BitBlt (hdcDst, 0, 0, himl->cx, himl->cy,
+ himl->hdcMask, i * himl->cx, 0, SRCCOPY);
+ }
+ else
+ PatBlt (hdcDst, 0, 0, himl->cx, himl->cy, BLACKNESS);
/* draw image*/
ii.hbmColor = CreateCompatibleBitmap (himl->hdcImage, himl->cx, himl->cy);
SelectObject (hdcDst, ii.hbmColor);
- PatBlt (hdcDst, 0, 0, himl->cx, himl->cy, BLACKNESS);
- ImageList_Draw(himl, i, hdcDst, 0, 0, fStyle | ILD_TRANSPARENT);
+ BitBlt (hdcDst, 0, 0, himl->cx, himl->cy,
+ himl->hdcImage, i * himl->cx, 0, SRCCOPY);
/*
* CreateIconIndirect requires us to deselect the bitmaps from
-------------- next part --------------
A non-text attachment was scrubbed...
Name: imlist.tar.gz
Type: application/x-tar
Size: 12099 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20050106/f01043f4/imlist.tar.tar
More information about the wine-patches
mailing list