Alexandre Julliard : comctl32: Always alpha blend images for 32-bpp imagelists.

Alexandre Julliard julliard at winehq.org
Fri May 14 11:17:28 CDT 2010


Module: wine
Branch: master
Commit: 91948f9ce84735c61cf733e767929fac541b0977
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=91948f9ce84735c61cf733e767929fac541b0977

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri May 14 13:50:38 2010 +0200

comctl32: Always alpha blend images for 32-bpp imagelists.

---

 dlls/comctl32/imagelist.c       |   36 ++++++++++++++++++++++--------------
 dlls/comctl32/tests/imagelist.c |    2 +-
 2 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index 2083d39..bd1530e 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -1142,16 +1142,15 @@ ImageList_DrawEx (HIMAGELIST himl, INT i, HDC hdc, INT x, INT y,
 
 
 static BOOL alpha_blend_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int dest_y,
-                               int src_x, int src_y, int cx, int cy, int alpha )
+                               int src_x, int src_y, int cx, int cy, BLENDFUNCTION func )
 {
-    BLENDFUNCTION func;
     BOOL ret = FALSE;
     HDC hdc;
     HBITMAP bmp = 0, mask = 0;
     BITMAPINFO *info;
     void *bits, *mask_bits;
     unsigned int *ptr;
-    int i, j, has_alpha = 0;
+    int i, j;
 
     if (!(hdc = CreateCompatibleDC( 0 ))) return FALSE;
     if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) goto done;
@@ -1170,8 +1169,6 @@ static BOOL alpha_blend_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int des
     SelectObject( hdc, bmp );
     BitBlt( hdc, 0, 0, cx, cy, himl->hdcImage, src_x, src_y, SRCCOPY );
 
-    for (i = 0, ptr = bits; i < cx * cy; i++) if ((has_alpha = (ptr[i] & 0xff000000) != 0)) break;
-
     if (himl->hbmMask)
     {
         unsigned int width_bytes = (cx + 31) / 32 * 4;
@@ -1186,13 +1183,9 @@ static BOOL alpha_blend_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int des
         for (i = 0, ptr = bits; i < cy; i++)
             for (j = 0; j < cx; j++, ptr++)
                 if ((((BYTE *)mask_bits)[i * width_bytes + j / 8] << (j % 8)) & 0x80) *ptr = 0;
-                else if (!has_alpha) *ptr |= 0xff000000;
+                else *ptr |= 0xff000000;
     }
 
-    func.BlendOp = AC_SRC_OVER;
-    func.BlendFlags = 0;
-    func.SourceConstantAlpha = alpha;
-    func.AlphaFormat = AC_SRC_ALPHA;
     ret = GdiAlphaBlend( dest_dc, dest_x, dest_y, cx, cy, hdc, 0, 0, cx, cy, func );
 
 done:
@@ -1229,6 +1222,7 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
     HIMAGELIST himl;
     HBRUSH hOldBrush;
     POINT pt;
+    BOOL has_alpha;
 
     if (!pimldp || !(himl = pimldp->himl)) return FALSE;
     if (!is_valid(himl)) return FALSE;
@@ -1278,14 +1272,25 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
     oldImageFg = SetTextColor( hImageDC, RGB( 0, 0, 0 ) );
     oldImageBk = SetBkColor( hImageDC, RGB( 0xff, 0xff, 0xff ) );
 
-    if (fState & ILS_ALPHA)
+    has_alpha = (himl->has_alpha && himl->has_alpha[pimldp->i]);
+    if (!bMask && (has_alpha || (fState & ILS_ALPHA)))
     {
         COLORREF colour;
+        BLENDFUNCTION func;
+
+        func.BlendOp = AC_SRC_OVER;
+        func.BlendFlags = 0;
+        func.SourceConstantAlpha = (fState & ILS_ALPHA) ? pimldp->Frame : 255;
+        func.AlphaFormat = AC_SRC_ALPHA;
 
         if (bIsTransparent)
         {
-            bResult = alpha_blend_image( himl, pimldp->hdcDst, pimldp->x, pimldp->y,
-                                         pt.x, pt.y, cx, cy, pimldp->Frame );
+            if (himl->uBitsPixel == 32)  /* we already have an alpha channel in this case */
+                bResult = GdiAlphaBlend( pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
+                                         himl->hdcImage, pt.x, pt.y, cx, cy, func );
+            else
+                bResult = alpha_blend_image( himl, pimldp->hdcDst, pimldp->x, pimldp->y,
+                                             pt.x, pt.y, cx, cy, func );
             goto end;
         }
         colour = pimldp->rgbBk;
@@ -1294,7 +1299,10 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
 
         hOldBrush = SelectObject (hImageDC, CreateSolidBrush (colour));
         PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY );
-        alpha_blend_image( himl, hImageDC, 0, 0, pt.x, pt.y, cx, cy, pimldp->Frame );
+        if (himl->uBitsPixel == 32)
+            GdiAlphaBlend( hImageDC, 0, 0, cx, cy, himl->hdcImage, pt.x, pt.y, cx, cy, func );
+        else
+            alpha_blend_image( himl, hImageDC, 0, 0, pt.x, pt.y, cx, cy, func );
         DeleteObject (SelectObject (hImageDC, hOldBrush));
         bResult = BitBlt( pimldp->hdcDst, pimldp->x,  pimldp->y, cx, cy, hImageDC, 0, 0, SRCCOPY );
         goto end;
diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c
index b80f351..43eeeca 100644
--- a/dlls/comctl32/tests/imagelist.c
+++ b/dlls/comctl32/tests/imagelist.c
@@ -1201,7 +1201,7 @@ static void test_ImageList_DrawIndirect(void)
         check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
     }
 
-    todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
+    check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
 
     check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__);
     check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);




More information about the wine-cvs mailing list