From f2b993d414517037cf064e9aed954cdae96646f5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 14 May 2010 20:19:58 +0200 Subject: [PATCH] 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 bd1530eb601..7b30643eec8 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 43eeeca2b68..cf749c82732 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: -- 2.11.4.GIT