Alexandre Julliard : comctl32/imagelist: Generate the mask from the alpha channel if present.

Alexandre Julliard julliard at winehq.org
Mon May 17 09:39:25 CDT 2010


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Sun May 16 12:48:08 2010 +0200

comctl32/imagelist: Generate the mask from the alpha channel if present.

---

 dlls/comctl32/imagelist.c |   37 +++++++++++++++++++++++++++----------
 1 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index 7b30643..e8d3323 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -145,15 +145,18 @@ static BOOL add_with_alpha( HIMAGELIST himl, HDC hdc, int pos, int count,
     BOOL ret = FALSE;
     HDC hdcMask = 0;
     BITMAP bm;
-    BITMAPINFO *info;
+    BITMAPINFO *info, *mask_info = NULL;
     DWORD *bits = NULL;
     BYTE *mask_bits = NULL;
     int i, j, n;
     POINT pt;
     DWORD mask_width;
 
-    if (himl->uBitsPixel != 32) return FALSE;
     if (!GetObjectW( hbmImage, sizeof(bm), &bm )) return FALSE;
+
+    /* if neither the imagelist nor the source bitmap can have an alpha channel, bail out now */
+    if (himl->uBitsPixel != 32 && bm.bmBitsPixel != 32) return FALSE;
+
     SelectObject( hdc, hbmImage );
     mask_width = (bm.bmWidth + 31) / 32 * 4;
 
@@ -174,13 +177,13 @@ static BOOL add_with_alpha( HIMAGELIST himl, HDC hdc, int pos, int count,
 
     if (hbmMask)
     {
-        info->bmiHeader.biBitCount = 1;
-        info->bmiHeader.biSizeImage = mask_width * height;
+        if (!(mask_info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[2] ))))
+            goto done;
+        mask_info->bmiHeader = info->bmiHeader;
+        mask_info->bmiHeader.biBitCount = 1;
+        mask_info->bmiHeader.biSizeImage = mask_width * height;
         if (!(mask_bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) goto done;
-        if (!GetDIBits( hdc, hbmMask, 0, height, mask_bits, info, DIB_RGB_COLORS )) goto done;
-        /* restore values for color info */
-        info->bmiHeader.biBitCount = 32;
-        info->bmiHeader.biSizeImage = bm.bmWidth * height * 4;
+        if (!GetDIBits( hdc, hbmMask, 0, height, mask_bits, mask_info, DIB_RGB_COLORS )) goto done;
         hdcMask = CreateCompatibleDC( 0 );
         SelectObject( hdcMask, hbmMask );
     }
@@ -202,6 +205,8 @@ static BOOL add_with_alpha( HIMAGELIST himl, HDC hdc, int pos, int count,
                 for (j = n * width; j < (n + 1) * width; j++)
                     if (!mask_bits || !((mask_bits[i * mask_width + j / 8] << (j % 8)) & 0x80))
                         bits[i * bm.bmWidth + j] |= 0xff000000;
+            if (hdcMask) StretchBlt( himl->hdcMask, pt.x, pt.y, himl->cx, himl->cy,
+                                     hdcMask, n * width, 0, width, height, SRCCOPY );
         }
         else
         {
@@ -209,6 +214,7 @@ static BOOL add_with_alpha( HIMAGELIST himl, HDC hdc, int pos, int count,
 
             /* pre-multiply by the alpha channel */
             for (i = 0; i < height; i++)
+            {
                 for (j = n * width; j < (n + 1) * width; j++)
                 {
                     DWORD argb = bits[i * bm.bmWidth + j];
@@ -218,12 +224,23 @@ static BOOL add_with_alpha( HIMAGELIST himl, HDC hdc, int pos, int count,
                                                 (((argb & 0x0000ff00) * alpha / 255) & 0x0000ff00) |
                                                 (((argb & 0x000000ff) * alpha / 255)));
                 }
+            }
+
+            if (mask_info && himl->hbmMask)  /* generate the mask from the alpha channel */
+            {
+                for (i = 0; i < height; i++)
+                    for (j = n * width; j < (n + 1) * width; j++)
+                        if ((bits[i * bm.bmWidth + j] >> 24) > 25) /* more than 10% alpha */
+                            mask_bits[i * mask_width + j / 8] &= ~(0x80 >> (j % 8));
+                        else
+                            mask_bits[i * mask_width + j / 8] |= 0x80 >> (j % 8);
+                StretchDIBits( himl->hdcMask, pt.x, pt.y, himl->cx, himl->cy,
+                               n * width, 0, width, height, mask_bits, mask_info, DIB_RGB_COLORS, SRCCOPY );
+            }
         }
         StretchDIBits( himl->hdcImage, pt.x, pt.y, himl->cx, himl->cy,
                        n * width, 0, width, height, bits, info, DIB_RGB_COLORS, SRCCOPY );
 
-        if (hdcMask) StretchBlt( himl->hdcMask, pt.x, pt.y, himl->cx, himl->cy,
-                                 hdcMask, n * width, 0, width, height, SRCCOPY );
     }
     ret = TRUE;
 




More information about the wine-cvs mailing list