We only check alpha value before, now also check red, green, blue.
-- v2: comctl32/tests: Also test v5 with test_alpha() comctl32/tests: Test image flags in test_alpha. comctl32/tests: Use winetest_{push,pop}_context in test_alpha. comctl32/tests: Test adding 32bpp images with alpha to 24bpp image list. comctl32/tests: Test image bitmap bits in test_alpha. comctl32/tests: Check RGB value in test_alpha.
From: Ziqing Hui zhui@codeweavers.com
We only check alpha value before, now also check red, green, blue. --- dlls/comctl32/tests/imagelist.c | 126 ++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 53 deletions(-)
diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index a1da365ece8..e8917562609 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -42,6 +42,7 @@ #include "resources.h"
#define IMAGELIST_MAGIC (('L' << 8) | 'I') +#define get_alpha(argb) (((argb) & 0xff000000) >> 24)
#pragma pack(push,2) /* Header used by ImageList_Read() and ImageList_Write() */ @@ -278,6 +279,44 @@ static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size, dump_bits(bits, checkbits, size); }
+static UINT32 get_premultiplied_argb(UINT32 pixel) +{ + UINT32 alpha = (pixel & 0xff000000) >> 24; + return ((pixel & 0xff000000) + | (((pixel & 0x00ff0000) * alpha / 0xff) & 0x00ff0000) + | (((pixel & 0x0000ff00) * alpha / 0xff) & 0x0000ff00) + | (((pixel & 0x000000ff) * alpha / 0xff))); +} + +static void image_list_get_image_bits_by_draw(HIMAGELIST image_list, int index, UINT32 *bits) +{ + BITMAPINFO bitmap_info = {}; + int ret, width, height; + void *bitmap_bits; + HBITMAP hbm_dst; + HDC hdc_dst; + + ret = pImageList_GetIconSize(image_list, &width, &height); + ok(ret, "ImageList_GetIconSize failed.\n"); + + bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bitmap_info.bmiHeader.biWidth = width; + bitmap_info.bmiHeader.biHeight = -height; + bitmap_info.bmiHeader.biPlanes = 1; + bitmap_info.bmiHeader.biBitCount = 32; + bitmap_info.bmiHeader.biCompression = BI_RGB; + + hdc_dst = CreateCompatibleDC(0); + hbm_dst = CreateDIBSection(hdc_dst, &bitmap_info, DIB_RGB_COLORS, &bitmap_bits, NULL, 0); + SelectObject(hdc_dst, hbm_dst); + + pImageList_Draw(image_list, index, hdc_dst, 0, 0, ILD_TRANSPARENT); + memcpy(bits, bitmap_bits, (size_t)(width * height * 32 / 8)); + + DeleteObject(hbm_dst); + DeleteDC(hdc_dst); +} + static void test_begindrag(void) { HIMAGELIST himl = createImageList(7,13); @@ -2388,25 +2427,6 @@ static void test_loadimage(void) pImageList_Destroy( list ); }
-#define GetAValue(argb) ((BYTE) ((argb) >> 24)) - -static void get_image_bits(HIMAGELIST himl, int index, int width, int height, UINT32 *bits) -{ - HBITMAP hbm_dst; - void *bitmap_bits; - BITMAPINFO bitmap_info = {{sizeof(BITMAPINFOHEADER), width, height, 1, 32, BI_RGB, 0, 0, 0, 0, 0}}; - - HDC hdc_dst = CreateCompatibleDC(0); - hbm_dst = CreateDIBSection(hdc_dst, &bitmap_info, DIB_RGB_COLORS, &bitmap_bits, NULL, 0); - SelectObject(hdc_dst, hbm_dst); - - pImageList_Draw(himl, index, hdc_dst, 0, 0, ILD_TRANSPARENT); - memcpy(bits, bitmap_bits, (size_t)(width * height * 32 / 8)); - - DeleteObject(hbm_dst); - DeleteDC(hdc_dst); -} - static void test_alpha(void) { /* each line is a 2*1 bitmap */ @@ -2429,36 +2449,38 @@ static void test_alpha(void) }; const static BYTE mask_bits = 0xAA;
- int i, ret; - HDC hdc; + UINT32 bits[2], expected[2]; HBITMAP hbm_test, hbm_mask; + const UINT32 *bitmap_bits; HIMAGELIST himl; - UINT32 bits[2]; + int i, ret; + HDC hdc;
hdc = CreateCompatibleDC(0); himl = pImageList_Create(2, 1, ILC_COLOR32 | ILC_MASK, 0, 15);
for (i = 0; i < ARRAY_SIZE(test_bitmaps); i += 2) { - hbm_test = create_test_bitmap(hdc, 2, 1, 32, test_bitmaps + i); - ret = pImageList_AddMasked(himl, hbm_test, RGB(0x65,0x43,0x21)); + bitmap_bits = test_bitmaps + i; + + hbm_test = create_test_bitmap(hdc, 2, 1, 32, bitmap_bits); + ret = pImageList_AddMasked(himl, hbm_test, RGB(0x65, 0x43, 0x21)); ok(ret == i / 2, "ImageList_AddMasked returned %d, expected %d\n", ret, i / 2); DeleteObject(hbm_test);
- get_image_bits(himl, i / 2, 2, 1, bits); - ok(GetAValue(bits[0]) == GetAValue(test_bitmaps[i]) && GetAValue(bits[1]) == GetAValue(test_bitmaps[i + 1]), - "Bitmap [%08X, %08X] returned alpha value [%02X, %02X], expected [%02X, %02X]\n", - test_bitmaps[i], test_bitmaps[i + 1], GetAValue(bits[0]), GetAValue(bits[1]), - GetAValue(test_bitmaps[i]), GetAValue(test_bitmaps[i + 1])); - - /* If all alpha values are zero, the image is considered to have no alpha and gets masked */ - if (!GetAValue(bits[0]) && !GetAValue(bits[1])) - ok(bits[0] == (test_bitmaps[i] == 0x654321 ? 0 : test_bitmaps[i]) && - bits[1] == (test_bitmaps[i + 1] == 0x654321 ? 0 : test_bitmaps[i + 1]), - "Bitmap [%08X, %08X] returned [%08X, %08X], expected [%08X, %08X]\n", - test_bitmaps[i], test_bitmaps[i + 1], bits[0], bits[1], - test_bitmaps[i] == 0x654321 ? 0 : test_bitmaps[i], - test_bitmaps[i + 1] == 0x654321 ? 0 : test_bitmaps[i + 1]); + expected[0] = get_premultiplied_argb(bitmap_bits[0]); + expected[1] = get_premultiplied_argb(bitmap_bits[1]); + /* If all alpha values are zero, the image is considered to have no alpha and gets masked. */ + if (!get_alpha(bitmap_bits[0]) && !get_alpha(bitmap_bits[1])) + { + expected[0] = (bitmap_bits[0] == 0x654321 ? 0 : bitmap_bits[0]); + expected[1] = (bitmap_bits[1] == 0x654321 ? 0 : bitmap_bits[1]); + } + + image_list_get_image_bits_by_draw(himl, i / 2, bits); + ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), + "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", + bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], expected[1]); }
pImageList_Destroy(himl); @@ -2467,28 +2489,26 @@ static void test_alpha(void)
for (i = 0; i < ARRAY_SIZE(test_bitmaps); i += 2) { + bitmap_bits = test_bitmaps + i; + hbm_test = create_test_bitmap(hdc, 2, 1, 32, test_bitmaps + i); ret = pImageList_Add(himl, hbm_test, hbm_mask); ok(ret == i / 2, "ImageList_Add returned %d, expected %d\n", ret, i / 2); DeleteObject(hbm_test);
- get_image_bits(himl, i / 2, 2, 1, bits); - ok(GetAValue(bits[0]) == GetAValue(test_bitmaps[i]) && GetAValue(bits[1]) == GetAValue(test_bitmaps[i + 1]), - "Bitmap [%08X, %08X] returned alpha value [%02X, %02X], expected [%02X, %02X]\n", - test_bitmaps[i], test_bitmaps[i + 1], GetAValue(bits[0]), GetAValue(bits[1]), - GetAValue(test_bitmaps[i]), GetAValue(test_bitmaps[i + 1])); - - /* If all alpha values are zero, the image is considered to have no alpha and gets masked */ - if (!GetAValue(bits[0]) && !GetAValue(bits[1])) - ok(!bits[0] && bits[1] == test_bitmaps[i + 1], - "Bitmap [%08X, %08X] returned [%08X, %08X], expected [%08X, %08X]\n", - test_bitmaps[i], test_bitmaps[i + 1], bits[0], bits[1], 0, test_bitmaps[i + 1]); - else + expected[0] = get_premultiplied_argb(bitmap_bits[0]); + expected[1] = get_premultiplied_argb(bitmap_bits[1]); + /* If all alpha values are zero, the image is considered to have no alpha and gets masked. */ + if (!get_alpha(bitmap_bits[0]) && !get_alpha(bitmap_bits[1])) { - if (GetAValue(bits[0]) >= 0x80) - ok(bits[0] & 0x00FFFFFF, "Bitmap [%08X, %08X] has alpha and masked first pixel [%08X]\n", - test_bitmaps[i], test_bitmaps[i + 1], bits[0]); + expected[0] = 0; + expected[1] = bitmap_bits[1]; } + + image_list_get_image_bits_by_draw(himl, i / 2, bits); + ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), + "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", + bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], expected[1]); }
pImageList_Destroy(himl);
From: Ziqing Hui zhui@codeweavers.com
We use ImageList_Draw and test the draw result before. Now adding tests which get bitmap bits directly. --- dlls/comctl32/tests/imagelist.c | 65 +++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+)
diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index e8917562609..9f48aea4812 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -288,6 +288,59 @@ static UINT32 get_premultiplied_argb(UINT32 pixel) | (((pixel & 0x000000ff) * alpha / 0xff))); }
+/* Remember to free the bits after usage. */ +static void bitmap_get_bits(HBITMAP bitmap, UINT32 **bits) +{ + BITMAPINFO bitmap_info; + UINT32 image_size; + BITMAP bm; + HDC hdc; + int ret; + + ret = GetObjectW(bitmap, sizeof(bm), &bm); + ok(ret, "GetObjectW failed.\n"); + + image_size = bm.bmWidth * bm.bmHeight * 4; + *bits = calloc(1, image_size); + ok(!!*bits, "Failed to allocate buffer of %u bytes.\n", image_size); + + bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bitmap_info.bmiHeader.biWidth = bm.bmWidth; + bitmap_info.bmiHeader.biHeight = -bm.bmHeight; + bitmap_info.bmiHeader.biPlanes = 1; + bitmap_info.bmiHeader.biBitCount = 32; + bitmap_info.bmiHeader.biCompression = BI_RGB; + bitmap_info.bmiHeader.biSizeImage = image_size; + bitmap_info.bmiHeader.biXPelsPerMeter = 0; + bitmap_info.bmiHeader.biYPelsPerMeter = 0; + bitmap_info.bmiHeader.biClrUsed = 0; + bitmap_info.bmiHeader.biClrImportant = 0; + + hdc = CreateCompatibleDC(NULL); + ok(!!hdc, "CreateCompatibleDC failed.\n"); + ret = GetDIBits(hdc, bitmap, 0, bm.bmHeight, *bits, &bitmap_info, DIB_RGB_COLORS); + ok(ret, "GetDIBits failed.\n"); + + DeleteDC(hdc); +} + +static void image_list_get_image_bits_by_bitmap(HIMAGELIST image_list, int index, UINT32 *bits) +{ + int ret, width, height; + IMAGEINFO image_info; + UINT32 *image_bits; + + ret = pImageList_GetImageInfo(image_list, index, &image_info); + ok(ret, "ImageList_GetImageInfo failed.\n"); + ret = pImageList_GetIconSize(image_list, &width, &height); + ok(ret, "ImageList_GetIconSize failed.\n"); + + bitmap_get_bits(image_info.hbmImage, &image_bits); + memcpy(bits, image_bits + width * height * index, width * height * 4); + + free(image_bits); +} + static void image_list_get_image_bits_by_draw(HIMAGELIST image_list, int index, UINT32 *bits) { BITMAPINFO bitmap_info = {}; @@ -2477,6 +2530,12 @@ static void test_alpha(void) expected[1] = (bitmap_bits[1] == 0x654321 ? 0 : bitmap_bits[1]); }
+ image_list_get_image_bits_by_bitmap(himl, i / 2, bits); + todo_wine_if(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]), + "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", + bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], expected[1]); + image_list_get_image_bits_by_draw(himl, i / 2, bits); ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", @@ -2505,6 +2564,12 @@ static void test_alpha(void) expected[1] = bitmap_bits[1]; }
+ image_list_get_image_bits_by_bitmap(himl, i / 2, bits); + todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && i != 18) + ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), + "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", + bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], expected[1]); + image_list_get_image_bits_by_draw(himl, i / 2, bits); ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n",
From: Ziqing Hui zhui@codeweavers.com
--- dlls/comctl32/tests/imagelist.c | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index 9f48aea4812..c40382b09ad 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -288,6 +288,32 @@ static UINT32 get_premultiplied_argb(UINT32 pixel) | (((pixel & 0x000000ff) * alpha / 0xff))); }
+static UINT32 get_alpha_blended(UINT32 dst, UINT32 src) +{ + UINT32 src_a, src_r, src_g, src_b; + UINT32 dst_a, dst_r, dst_g, dst_b; + UINT32 ret_a, ret_r, ret_g, ret_b; + + src = get_premultiplied_argb(src); + + src_a = (src & 0xff000000) >> 24; + src_r = (src & 0x00ff0000) >> 16; + src_g = (src & 0x0000ff00) >> 8; + src_b = (src & 0x000000ff); + + dst_a = (dst & 0xff000000) >> 24; + dst_r = (dst & 0x00ff0000) >> 16; + dst_g = (dst & 0x0000ff00) >> 8; + dst_b = (dst & 0x000000ff); + + ret_a = dst_a ? (src_a + (0xff - src_a) * dst_a / 0xff) : 0; + ret_r = src_r + (0xff - src_a) * dst_r / 0xff; + ret_g = src_g + (0xff - src_a) * dst_g / 0xff; + ret_b = src_b + (0xff - src_a) * dst_b / 0xff; + + return (ret_a << 24) | (ret_r << 16) | (ret_g << 8) | ret_b; +} + /* Remember to free the bits after usage. */ static void bitmap_get_bits(HBITMAP bitmap, UINT32 **bits) { @@ -2510,6 +2536,8 @@ static void test_alpha(void) HDC hdc;
hdc = CreateCompatibleDC(0); + + /* Test ImageList_AddMasked with alpha. */ himl = pImageList_Create(2, 1, ILC_COLOR32 | ILC_MASK, 0, 15);
for (i = 0; i < ARRAY_SIZE(test_bitmaps); i += 2) @@ -2543,6 +2571,8 @@ static void test_alpha(void) }
pImageList_Destroy(himl); + + /* Test ImageList_Add with alpha. */ hbm_mask = CreateBitmap(2, 1, 1, 1, &mask_bits); himl = pImageList_Create(2, 1, ILC_COLOR32 | ILC_MASK, 0, 15);
@@ -2578,6 +2608,42 @@ static void test_alpha(void)
pImageList_Destroy(himl); DeleteObject(hbm_mask); + + /* Test adding 32bpp images with alpha to 24bpp image list. */ + himl = pImageList_Create(2, 1, ILC_COLOR24 | ILC_MASK, 0, 15); + + for (i = 0; i < ARRAY_SIZE(test_bitmaps); i += 2) + { + bitmap_bits = test_bitmaps + i; + + hbm_test = create_test_bitmap(hdc, 2, 1, 32, test_bitmaps + i); + ret = pImageList_Add(himl, hbm_test, NULL); + ok(ret == i / 2, "ImageList_Add returned %d, expected %d\n", ret, i / 2); + DeleteObject(hbm_test); + + expected[0] = bitmap_bits[0]; + expected[1] = bitmap_bits[1]; + if (get_alpha(bitmap_bits[0]) || get_alpha(bitmap_bits[1])) + { + expected[0] = get_alpha_blended(0x00ffffff, bitmap_bits[0]); + expected[1] = get_alpha_blended(0x00ffffff, bitmap_bits[1]); + } + + image_list_get_image_bits_by_bitmap(himl, i / 2, bits); + todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && i != 18) + ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), + "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", + bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], expected[1]); + + image_list_get_image_bits_by_draw(himl, i / 2, bits); + todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && i != 18) + ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), + "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", + bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], expected[1]); + } + + pImageList_Destroy(himl); + DeleteDC(hdc); }
From: Ziqing Hui zhui@codeweavers.com
--- dlls/comctl32/tests/imagelist.c | 36 ++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index c40382b09ad..c870467da4a 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -2544,6 +2544,8 @@ static void test_alpha(void) { bitmap_bits = test_bitmaps + i;
+ winetest_push_context("Bitmap [%08X, %08X]", bitmap_bits[0], bitmap_bits[1]); + hbm_test = create_test_bitmap(hdc, 2, 1, 32, bitmap_bits); ret = pImageList_AddMasked(himl, hbm_test, RGB(0x65, 0x43, 0x21)); ok(ret == i / 2, "ImageList_AddMasked returned %d, expected %d\n", ret, i / 2); @@ -2561,13 +2563,15 @@ static void test_alpha(void) image_list_get_image_bits_by_bitmap(himl, i / 2, bits); todo_wine_if(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]), - "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", - bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], 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); ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), - "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", - bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], expected[1]); + "Got bits [%08X, %08X], expected [%08X, %08X].\n", + bits[0], bits[1], expected[0], expected[1]); + + winetest_pop_context(); }
pImageList_Destroy(himl); @@ -2580,6 +2584,8 @@ static void test_alpha(void) { bitmap_bits = test_bitmaps + i;
+ winetest_push_context("Bitmap [%08X, %08X]", bitmap_bits[0], bitmap_bits[1]); + hbm_test = create_test_bitmap(hdc, 2, 1, 32, test_bitmaps + i); ret = pImageList_Add(himl, hbm_test, hbm_mask); ok(ret == i / 2, "ImageList_Add returned %d, expected %d\n", ret, i / 2); @@ -2597,13 +2603,15 @@ static void test_alpha(void) image_list_get_image_bits_by_bitmap(himl, i / 2, bits); todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && i != 18) ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), - "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", - bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], 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); ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), - "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", - bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], expected[1]); + "Got bits [%08X, %08X], expected [%08X, %08X].\n", + bits[0], bits[1], expected[0], expected[1]); + + winetest_pop_context(); }
pImageList_Destroy(himl); @@ -2616,6 +2624,8 @@ static void test_alpha(void) { bitmap_bits = test_bitmaps + i;
+ winetest_push_context("Bitmap [%08X, %08X]", bitmap_bits[0], bitmap_bits[1]); + hbm_test = create_test_bitmap(hdc, 2, 1, 32, test_bitmaps + i); ret = pImageList_Add(himl, hbm_test, NULL); ok(ret == i / 2, "ImageList_Add returned %d, expected %d\n", ret, i / 2); @@ -2632,14 +2642,16 @@ static void test_alpha(void) image_list_get_image_bits_by_bitmap(himl, i / 2, bits); todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && i != 18) ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), - "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", - bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], 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(i != 0 && i != 2 && i != 4 && i != 6 && i != 18) ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), - "Bitmap [%08X, %08X] returned bits [%08X, %08X], expected [%08X, %08X].\n", - bitmap_bits[0], bitmap_bits[1], bits[0], bits[1], expected[0], expected[1]); + "Got bits [%08X, %08X], expected [%08X, %08X].\n", + bits[0], bits[1], expected[0], expected[1]); + + winetest_pop_context(); }
pImageList_Destroy(himl);
From: Ziqing Hui zhui@codeweavers.com
--- dlls/comctl32/tests/imagelist.c | 38 +++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index c870467da4a..e73e333931e 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -2528,10 +2528,14 @@ static void test_alpha(void) }; const static BYTE mask_bits = 0xAA;
+ IImageList2 *image_list_iface; UINT32 bits[2], expected[2]; HBITMAP hbm_test, hbm_mask; const UINT32 *bitmap_bits; + DWORD flag, expected_flag; HIMAGELIST himl; + BOOL has_alpha; + HRESULT hr; int i, ret; HDC hdc;
@@ -2540,6 +2544,9 @@ static void test_alpha(void) /* Test ImageList_AddMasked with alpha. */ himl = pImageList_Create(2, 1, ILC_COLOR32 | ILC_MASK, 0, 15);
+ hr = pHIMAGELIST_QueryInterface(himl, &IID_IImageList2, (void **)&image_list_iface); + ok(hr == S_OK, "QueryInterface returned %#lx.\n", hr); + for (i = 0; i < ARRAY_SIZE(test_bitmaps); i += 2) { bitmap_bits = test_bitmaps + i; @@ -2551,15 +2558,22 @@ static void test_alpha(void) ok(ret == i / 2, "ImageList_AddMasked returned %d, expected %d\n", ret, i / 2); DeleteObject(hbm_test);
+ has_alpha = get_alpha(bitmap_bits[0]) || get_alpha(bitmap_bits[1]); expected[0] = get_premultiplied_argb(bitmap_bits[0]); expected[1] = get_premultiplied_argb(bitmap_bits[1]); + expected_flag = ILIF_ALPHA; /* If all alpha values are zero, the image is considered to have no alpha and gets masked. */ - if (!get_alpha(bitmap_bits[0]) && !get_alpha(bitmap_bits[1])) + if (!has_alpha) { expected[0] = (bitmap_bits[0] == 0x654321 ? 0 : bitmap_bits[0]); expected[1] = (bitmap_bits[1] == 0x654321 ? 0 : bitmap_bits[1]); + expected_flag = 0; }
+ hr = IImageList2_GetItemFlags(image_list_iface, i / 2, &flag); + ok(hr == S_OK, "GetItemFlags returned %#lx.\n", hr); + ok(flag == expected_flag, "Unexpected flag %#lx, expected %#lx.\n", flag, expected_flag); + image_list_get_image_bits_by_bitmap(himl, i / 2, bits); todo_wine_if(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]), @@ -2574,12 +2588,16 @@ static void test_alpha(void) winetest_pop_context(); }
+ IImageList2_Release(image_list_iface); pImageList_Destroy(himl);
/* Test ImageList_Add with alpha. */ hbm_mask = CreateBitmap(2, 1, 1, 1, &mask_bits); himl = pImageList_Create(2, 1, ILC_COLOR32 | ILC_MASK, 0, 15);
+ hr = pHIMAGELIST_QueryInterface(himl, &IID_IImageList2, (void **)&image_list_iface); + ok(hr == S_OK, "QueryInterface returned %#lx.\n", hr); + for (i = 0; i < ARRAY_SIZE(test_bitmaps); i += 2) { bitmap_bits = test_bitmaps + i; @@ -2591,15 +2609,22 @@ static void test_alpha(void) ok(ret == i / 2, "ImageList_Add returned %d, expected %d\n", ret, i / 2); DeleteObject(hbm_test);
+ has_alpha = get_alpha(bitmap_bits[0]) || get_alpha(bitmap_bits[1]); expected[0] = get_premultiplied_argb(bitmap_bits[0]); expected[1] = get_premultiplied_argb(bitmap_bits[1]); + expected_flag = ILIF_ALPHA; /* If all alpha values are zero, the image is considered to have no alpha and gets masked. */ - if (!get_alpha(bitmap_bits[0]) && !get_alpha(bitmap_bits[1])) + if (!has_alpha) { expected[0] = 0; expected[1] = bitmap_bits[1]; + expected_flag = 0; }
+ hr = IImageList2_GetItemFlags(image_list_iface, i / 2, &flag); + ok(hr == S_OK, "GetItemFlags returned %#lx.\n", hr); + ok(flag == expected_flag, "Unexpected flag %#lx, expected %#lx.\n", flag, expected_flag); + image_list_get_image_bits_by_bitmap(himl, i / 2, bits); todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && i != 18) ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), @@ -2614,12 +2639,16 @@ static void test_alpha(void) winetest_pop_context(); }
+ IImageList2_Release(image_list_iface); pImageList_Destroy(himl); DeleteObject(hbm_mask);
/* Test adding 32bpp images with alpha to 24bpp image list. */ himl = pImageList_Create(2, 1, ILC_COLOR24 | ILC_MASK, 0, 15);
+ hr = pHIMAGELIST_QueryInterface(himl, &IID_IImageList2, (void **)&image_list_iface); + ok(hr == S_OK, "QueryInterface returned %#lx.\n", hr); + for (i = 0; i < ARRAY_SIZE(test_bitmaps); i += 2) { bitmap_bits = test_bitmaps + i; @@ -2639,6 +2668,10 @@ static void test_alpha(void) expected[1] = get_alpha_blended(0x00ffffff, bitmap_bits[1]); }
+ hr = IImageList2_GetItemFlags(image_list_iface, i / 2, &flag); + ok(hr == S_OK, "GetItemFlags returned %#lx.\n", hr); + ok(flag == 0, "Unexpected flag %#lx.\n", flag); + image_list_get_image_bits_by_bitmap(himl, i / 2, bits); todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && i != 18) ok(colour_match(bits[0], expected[0]) && colour_match(bits[1], expected[1]), @@ -2654,6 +2687,7 @@ static void test_alpha(void) winetest_pop_context(); }
+ IImageList2_Release(image_list_iface); pImageList_Destroy(himl);
DeleteDC(hdc);
From: Ziqing Hui zhui@codeweavers.com
--- dlls/comctl32/tests/imagelist.c | 100 +++++++++++++++++++------------- 1 file changed, 61 insertions(+), 39 deletions(-)
diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index e73e333931e..3b547732fd5 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -2506,7 +2506,7 @@ static void test_loadimage(void) pImageList_Destroy( list ); }
-static void test_alpha(void) +static void test_alpha(BOOL v6) { /* each line is a 2*1 bitmap */ const static UINT32 test_bitmaps[] = @@ -2529,10 +2529,10 @@ static void test_alpha(void) const static BYTE mask_bits = 0xAA;
IImageList2 *image_list_iface; + DWORD flag, expected_flag = 0; UINT32 bits[2], expected[2]; HBITMAP hbm_test, hbm_mask; const UINT32 *bitmap_bits; - DWORD flag, expected_flag; HIMAGELIST himl; BOOL has_alpha; HRESULT hr; @@ -2541,12 +2541,10 @@ static void test_alpha(void)
hdc = CreateCompatibleDC(0);
+ winetest_push_context(v6 ? "v6" : "v5"); + /* Test ImageList_AddMasked with alpha. */ himl = pImageList_Create(2, 1, ILC_COLOR32 | ILC_MASK, 0, 15); - - hr = pHIMAGELIST_QueryInterface(himl, &IID_IImageList2, (void **)&image_list_iface); - ok(hr == S_OK, "QueryInterface returned %#lx.\n", hr); - for (i = 0; i < ARRAY_SIZE(test_bitmaps); i += 2) { bitmap_bits = test_bitmaps + i; @@ -2562,42 +2560,44 @@ static void test_alpha(void) expected[0] = get_premultiplied_argb(bitmap_bits[0]); expected[1] = get_premultiplied_argb(bitmap_bits[1]); expected_flag = ILIF_ALPHA; - /* If all alpha values are zero, the image is considered to have no alpha and gets masked. */ - if (!has_alpha) + /* v5: The image always gets masked. + * v6: If all alpha values are zero, the image is considered to have no alpha and gets masked. */ + if (!v6 || (v6 && !has_alpha)) { expected[0] = (bitmap_bits[0] == 0x654321 ? 0 : bitmap_bits[0]); expected[1] = (bitmap_bits[1] == 0x654321 ? 0 : bitmap_bits[1]); expected_flag = 0; }
- hr = IImageList2_GetItemFlags(image_list_iface, i / 2, &flag); - ok(hr == S_OK, "GetItemFlags returned %#lx.\n", hr); - ok(flag == expected_flag, "Unexpected flag %#lx, expected %#lx.\n", flag, expected_flag); + if (v6) + { + hr = pHIMAGELIST_QueryInterface(himl, &IID_IImageList2, (void **)&image_list_iface); + ok(hr == S_OK, "QueryInterface returned %#lx.\n", hr); + hr = IImageList2_GetItemFlags(image_list_iface, i / 2, &flag); + ok(hr == S_OK, "GetItemFlags returned %#lx.\n", hr); + ok(flag == expected_flag, "Unexpected flag %#lx, expected %#lx.\n", flag, expected_flag); + IImageList2_Release(image_list_iface); + }
image_list_get_image_bits_by_bitmap(himl, i / 2, bits); - todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && i != 12 && i != 18) + 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]);
image_list_get_image_bits_by_draw(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]);
winetest_pop_context(); } - - IImageList2_Release(image_list_iface); pImageList_Destroy(himl);
/* Test ImageList_Add with alpha. */ hbm_mask = CreateBitmap(2, 1, 1, 1, &mask_bits); himl = pImageList_Create(2, 1, ILC_COLOR32 | ILC_MASK, 0, 15); - - hr = pHIMAGELIST_QueryInterface(himl, &IID_IImageList2, (void **)&image_list_iface); - ok(hr == S_OK, "QueryInterface returned %#lx.\n", hr); - for (i = 0; i < ARRAY_SIZE(test_bitmaps); i += 2) { bitmap_bits = test_bitmaps + i; @@ -2613,42 +2613,50 @@ static void test_alpha(void) expected[0] = get_premultiplied_argb(bitmap_bits[0]); expected[1] = get_premultiplied_argb(bitmap_bits[1]); expected_flag = ILIF_ALPHA; - /* If all alpha values are zero, the image is considered to have no alpha and gets masked. */ - if (!has_alpha) + + if (!v6) + { + /* v5: The image always gets masked, though the alpha value of the masked bit is kept. */ + expected[0] = bitmap_bits[0] & 0xff000000; + expected[1] = bitmap_bits[1]; + } + else if (!has_alpha) { + /* v6: If all alpha values are zero, the image is considered to have no alpha and gets masked. */ expected[0] = 0; expected[1] = bitmap_bits[1]; expected_flag = 0; }
- hr = IImageList2_GetItemFlags(image_list_iface, i / 2, &flag); - ok(hr == S_OK, "GetItemFlags returned %#lx.\n", hr); - ok(flag == expected_flag, "Unexpected flag %#lx, expected %#lx.\n", flag, expected_flag); + if (v6) + { + hr = pHIMAGELIST_QueryInterface(himl, &IID_IImageList2, (void **)&image_list_iface); + ok(hr == S_OK, "QueryInterface returned %#lx.\n", hr); + hr = IImageList2_GetItemFlags(image_list_iface, i / 2, &flag); + ok(hr == S_OK, "GetItemFlags returned %#lx.\n", hr); + ok(flag == expected_flag, "Unexpected flag %#lx, expected %#lx.\n", flag, expected_flag); + IImageList2_Release(image_list_iface); + }
image_list_get_image_bits_by_bitmap(himl, i / 2, bits); - todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && i != 18) + todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && (!v6 || 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 != 12) 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]);
winetest_pop_context(); } - - IImageList2_Release(image_list_iface); pImageList_Destroy(himl); DeleteObject(hbm_mask);
/* Test adding 32bpp images with alpha to 24bpp image list. */ himl = pImageList_Create(2, 1, ILC_COLOR24 | ILC_MASK, 0, 15); - - hr = pHIMAGELIST_QueryInterface(himl, &IID_IImageList2, (void **)&image_list_iface); - ok(hr == S_OK, "QueryInterface returned %#lx.\n", hr); - for (i = 0; i < ARRAY_SIZE(test_bitmaps); i += 2) { bitmap_bits = test_bitmaps + i; @@ -2662,34 +2670,47 @@ static void test_alpha(void)
expected[0] = bitmap_bits[0]; expected[1] = bitmap_bits[1]; - if (get_alpha(bitmap_bits[0]) || get_alpha(bitmap_bits[1])) + if (!v6) { + /* v5: Copy the bits to the image list. */ + expected[0] = bitmap_bits[0] & 0x00ffffff; + expected[1] = bitmap_bits[1] & 0x00ffffff; + } + else if (get_alpha(bitmap_bits[0]) || get_alpha(bitmap_bits[1])) + { + /* v6: Alpha blend the bits to the image list. */ expected[0] = get_alpha_blended(0x00ffffff, bitmap_bits[0]); expected[1] = get_alpha_blended(0x00ffffff, bitmap_bits[1]); }
- hr = IImageList2_GetItemFlags(image_list_iface, i / 2, &flag); - ok(hr == S_OK, "GetItemFlags returned %#lx.\n", hr); - ok(flag == 0, "Unexpected flag %#lx.\n", flag); + if (v6) + { + hr = pHIMAGELIST_QueryInterface(himl, &IID_IImageList2, (void **)&image_list_iface); + ok(hr == S_OK, "QueryInterface returned %#lx.\n", hr); + hr = IImageList2_GetItemFlags(image_list_iface, i / 2, &flag); + ok(hr == S_OK, "GetItemFlags returned %#lx.\n", hr); + ok(flag == 0, "Unexpected flag %#lx.\n", flag); + IImageList2_Release(image_list_iface); + }
image_list_get_image_bits_by_bitmap(himl, i / 2, bits); - todo_wine_if(i != 0 && i != 2 && i != 4 && i != 6 && i != 18) + 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(i != 0 && i != 2 && i != 4 && i != 6 && i != 18) + 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]);
winetest_pop_context(); } - - IImageList2_Release(image_list_iface); pImageList_Destroy(himl);
+ winetest_pop_context(); + DeleteDC(hdc); }
@@ -2898,6 +2919,7 @@ START_TEST(imagelist) test_color_table(ILC_COLOR8); test_copy(); test_loadimage(); + test_alpha(FALSE);
/* Now perform v6 tests */ if (!load_v6_module(&ctx_cookie, &hCtx)) @@ -2918,7 +2940,7 @@ START_TEST(imagelist) test_color_table(ILC_COLOR8); test_copy(); test_loadimage(); - test_alpha(); + test_alpha(TRUE);
test_ImageList_DrawIndirect(); test_shell_imagelist();
Added v5 test_alpha() tests. The pipeline failures are not caused by this MR.
On Wed Jul 16 00:28:07 2025 +0000, Ziqing Hui wrote:
OK, I'll add v5 tests to this MR to get it merged.
I sent https://gitlab.winehq.org/wine/wine/-/merge_requests/8595 for the comctl32 separation.
This merge request was approved by Zhiyi Zhang.
This merge request was approved by Nikolay Sivov.