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