From: Ziqing Hui zhui@codeweavers.com
We used to do this when drawing the image. But our tests show that for v6, the image bitmaps have been alpha pre-multiplied before drawing. So we should do this when adding images. --- dlls/comctl32/imagelist.c | 47 +++++++++++++++++++++++++-------- dlls/comctl32/tests/imagelist.c | 3 +-- 2 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c index 58e54799127..db846924a36 100644 --- a/dlls/comctl32/imagelist.c +++ b/dlls/comctl32/imagelist.c @@ -216,6 +216,38 @@ static void premultiply_alpha_channel(DWORD *bits, int pixel_count) } }
+static void do_alpha_processing(DWORD *bits, int n, int width, int height, int stride, + BOOL generate_mask, BYTE *mask_bits, int mask_stride) +{ + int i, j; + +#if __WINE_COMCTL32_VERSION == 6 + /* Premultiply alpha for each line of the nth image. */ + for (i = 0; i < height; i++) + premultiply_alpha_channel(&bits[i * stride + n * width], width); +#endif /* __WINE_COMCTL32_VERSION == 6 */ + + /* Generate the mask from the alpha channel. */ + if (generate_mask) + { + 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 */ + mask_bits[i * mask_stride + j / 8] &= ~(0x80 >> (j % 8)); + else + mask_bits[i * mask_stride + j / 8] |= 0x80 >> (j % 8); + } +} + +static BOOL is_alpha_premultiplied(void) +{ +#if __WINE_COMCTL32_VERSION == 6 + return TRUE; +#else + return FALSE; +#endif /* __WINE_COMCTL32_VERSION == 6 */ +} + 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 ) { @@ -238,16 +270,8 @@ static void add_dib_bits( HIMAGELIST himl, int pos, int count, int width, int he if (has_alpha) { himl->item_flags[pos + n] = ILIF_ALPHA; - - 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 */ - mask_bits[i * mask_stride + j / 8] &= ~(0x80 >> (j % 8)); - else - mask_bits[i * mask_stride + j / 8] |= 0x80 >> (j % 8); - } + do_alpha_processing(bits, n, width, height, stride, + mask_info && himl->hbmMask, mask_bits, mask_stride); } else if (mask_info) /* mask out the background */ { @@ -1252,7 +1276,8 @@ static BOOL alpha_blend_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int des
if (has_alpha) /* we already have an alpha channel in this case */ { - premultiply_alpha_channel(bits, cx * cy); + if (!is_alpha_premultiplied()) + premultiply_alpha_channel(bits, cx * cy); } else if (himl->hbmMask) { diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index c8a1a25b71d..6f44c1c30a0 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -2581,7 +2581,6 @@ 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 != 12 && 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]); @@ -2640,7 +2639,7 @@ static void test_alpha(BOOL v6) }
image_list_get_image_bits_by_bitmap(himl, i / 2, bits); - todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && (!v6 || i != 18)) + todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && !v6) 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]);