Alexandre Julliard : comctl32/imagelist: Pre-multiply the colors by the alpha channel when storing an image with alpha .

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


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri May 14 20:19:58 2010 +0200

comctl32/imagelist: Pre-multiply the colors by the alpha channel when storing an image with alpha.

---

 dlls/comctl32/imagelist.c       |   18 ++++++++++++++----
 dlls/comctl32/tests/imagelist.c |   16 ++++++++--------
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index bd1530e..7b30643 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -202,15 +202,25 @@ 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;
-            StretchDIBits( himl->hdcImage, pt.x, pt.y, himl->cx, himl->cy,
-                           n * width, 0, width, height, bits, info, DIB_RGB_COLORS, SRCCOPY );
         }
         else
         {
             if (himl->has_alpha) himl->has_alpha[pos + n] = 1;
-            StretchBlt( himl->hdcImage, pt.x, pt.y, himl->cx, himl->cy,
-                        hdc, n * width, 0, width, height, SRCCOPY );
+
+            /* 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];
+                    DWORD alpha = argb >> 24;
+                    bits[i * bm.bmWidth + j] = ((argb & 0xff000000) |
+                                                (((argb & 0x00ff0000) * alpha / 255) & 0x00ff0000) |
+                                                (((argb & 0x0000ff00) * alpha / 255) & 0x0000ff00) |
+                                                (((argb & 0x000000ff) * alpha / 255)));
+                }
         }
+        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 );
diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c
index 43eeeca..cf749c8 100644
--- a/dlls/comctl32/tests/imagelist.c
+++ b/dlls/comctl32/tests/imagelist.c
@@ -1189,17 +1189,17 @@ static void test_ImageList_DrawIndirect(void)
     check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__);
     check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__);
 
+    check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
+    check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
     todo_wine
     {
-        check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
-        check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
         check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x009DA8B1, __LINE__);
         check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x008C99A3, __LINE__);
 
-        check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
-        check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
-        check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
     }
+    check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
+    check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
+    todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
 
     check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
 
@@ -1207,8 +1207,8 @@ static void test_ImageList_DrawIndirect(void)
     check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);
 
     /* ILD_ROP is ignored when the image has an alpha channel */
-    todo_wine check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
-    todo_wine check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
+    check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
+    check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
 
     todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__);
     todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__);
@@ -1217,7 +1217,7 @@ static void test_ImageList_DrawIndirect(void)
     check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__);
 
     check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__);
-    todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
+    check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
     todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__);
 
 cleanup:




More information about the wine-cvs mailing list