From: Ziqing Hui zhui@codeweavers.com
--- dlls/comctl32/imagelist.c | 25 +++++++++++++++++++++++-- dlls/comctl32/tests/imagelist.c | 2 -- 2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c index db5beb14042..edf0d40e476 100644 --- a/dlls/comctl32/imagelist.c +++ b/dlls/comctl32/imagelist.c @@ -270,6 +270,7 @@ static void premultiply_alpha_channel(DWORD *bits, int pixel_count) static void add_dib_bits( HIMAGELIST himl, int pos, int count, int width, int height, BITMAPINFO *info, BITMAPINFO *mask_info, DWORD *bits, BYTE *mask_bits ) { + BOOL image_list_is_32bpp = (image_list_color_flag(himl) == ILC_COLOR32); int i, j, n; POINT pt; int stride = info->bmiHeader.biWidth; @@ -293,13 +294,32 @@ static void add_dib_bits( HIMAGELIST himl, int pos, int count, int width, int he #if __WINE_COMCTL32_VERSION == 6 for (i = 0; i < height; i++) premultiply_alpha_channel(&bits[i * stride + n * width], width); + + if (!image_list_is_32bpp) + { + himl->item_flags[pos + n] = 0; + + /* Image list is not 32bpp, no alpha channel in image list bitmap. + * We need to do alpha blend here by ourselves. */ + for (i = 0; i < height; i++) + { + for (j = n * width; j < (n + 1) * width; j++) + { + DWORD *pixel = &bits[i * stride + j], alpha = *pixel >> 24; + DWORD r = (*pixel & 0x00ff0000) >> 16; + DWORD g = (*pixel & 0x0000ff00) >> 8; + DWORD b = *pixel & 0x000000ff; + *pixel = ((r + 0xff - alpha) << 16) | ((g + 0xff - alpha) << 8) | (b + 0xff - alpha); + } + } + } #endif /* __WINE_COMCTL32_VERSION == 6 */
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 * stride + j] >> 24) > 25) /* more than 10% alpha */ + if (!image_list_is_32bpp || (bits[i * stride + j] >> 24) > 25) /* more than 10% alpha */ mask_bits[i * mask_stride + j / 8] &= ~(0x80 >> (j % 8)); else mask_bits[i * mask_stride + j / 8] |= 0x80 >> (j % 8); @@ -333,8 +353,9 @@ static BOOL add_with_alpha( HIMAGELIST himl, HDC hdc, int pos, int count,
if (!GetObjectW( hbmImage, sizeof(bm), &bm )) return FALSE;
- /* if either the imagelist or the source bitmap don't have an alpha channel, bail out now */ +#if __WINE_COMCTL32_VERSION == 5 if (image_list_color_flag(himl) != ILC_COLOR32) return FALSE; +#endif /* __WINE_COMCTL32_VERSION == 5 */ if (bm.bmBitsPixel != 32) return FALSE;
SelectObject( hdc, hbmImage ); diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index 7cd23a9da2f..98f061ba712 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -2693,13 +2693,11 @@ static void test_alpha(BOOL v6) }
image_list_get_image_bits_by_bitmap(himl, i / 2, bits); - todo_wine_if(v6 && i != 0 && i != 2 && i != 4 && i != 6 && i != 18) ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), "Got bits [%08X, %08X], expected [%08X, %08X].\n", bits[0], bits[1], expected[0], expected[1]);
image_list_get_image_bits_by_draw(himl, i / 2, bits); - todo_wine_if(v6 && i != 0 && i != 2 && i != 4 && i != 6 && i != 18) ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), "Got bits [%08X, %08X], expected [%08X, %08X].\n", bits[0], bits[1], expected[0], expected[1]);