comctl32/imagelist: use proper color format for merged image lists (try 3)

Daniel Jelinski djelinski1 at gmail.com
Wed Mar 6 15:39:00 CST 2013


tested with native comctl in 8, 16 and 32bit color depth.
-------------- next part --------------
From b933197f9bae5fa538d5beba325acce7dac0293e Mon Sep 17 00:00:00 2001
From: Daniel Jelinski <djelinski1 at gmail.com>
Date: Wed, 27 Feb 2013 21:47:43 +0100
Subject: [PATCH] comctl32/imagelist: use proper color format for merged image
 lists

this time also with tests for DDB
---
 dlls/comctl32/imagelist.c       |    6 +++-
 dlls/comctl32/tests/imagelist.c |   65 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 1 deletions(-)

diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index 03c359f..76d5709 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -2082,6 +2082,7 @@ ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
     INT      cxDst, cyDst;
     INT      xOff1, yOff1, xOff2, yOff2;
     POINT    pt1, pt2;
+    INT      newFlags;
 
     TRACE("(himl1=%p i1=%d himl2=%p i2=%d dx=%d dy=%d)\n", himl1, i1, himl2,
 	   i2, dx, dy);
@@ -2121,7 +2122,10 @@ ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
         yOff2 = 0;
     }
 
-    himlDst = ImageList_Create (cxDst, cyDst, ILC_MASK | ILC_COLOR, 1, 1);
+    newFlags = (himl1->flags > himl2->flags ? himl1->flags : himl2->flags) & ILC_COLORDDB;
+    if (newFlags == ILC_COLORDDB && (himl1->flags & ILC_COLORDDB) == ILC_COLOR16)
+        newFlags = ILC_COLOR16; /* this is what native (at least v5) does, don't know why */
+    himlDst = ImageList_Create (cxDst, cyDst, ILC_MASK | newFlags, 1, 1);
 
     if (himlDst)
     {
diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c
index 19d2437..58a7e70 100644
--- a/dlls/comctl32/tests/imagelist.c
+++ b/dlls/comctl32/tests/imagelist.c
@@ -492,6 +492,70 @@ static void test_DrawIndirect(void)
     DestroyWindow(hwndfortest);
 }
 
+static int get_color_format(HBITMAP bmp)
+{
+    BITMAPINFO bmi;
+    HDC hdc = CreateCompatibleDC(0);
+    HBITMAP hOldBmp = SelectObject(hdc, bmp);
+    int ret;
+
+    memset(&bmi, 0, sizeof(bmi));
+    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    ret = GetDIBits(hdc, bmp, 0, 0, 0, &bmi, DIB_RGB_COLORS);
+    ok(ret, "GetDIBits failed\n");
+
+    SelectObject(hdc, hOldBmp);
+    DeleteDC(hdc);
+    return bmi.bmiHeader.biBitCount;
+}
+
+static void test_merge_colors(void)
+{
+    HIMAGELIST himl[8], hmerge;
+    int sizes[] = { ILC_COLOR, ILC_COLOR | ILC_MASK, ILC_COLOR4, ILC_COLOR8, ILC_COLOR16, ILC_COLOR24, ILC_COLOR32, ILC_COLORDDB };
+    HICON hicon1;
+    IMAGEINFO info;
+    int bpp, i, j;
+
+    hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
+    ok(hicon1 != NULL, "failed to create hicon1\n");
+
+    for (i = 0; i < 8; i++)
+    {
+        himl[i] = ImageList_Create(32, 32, sizes[i], 0, 3);
+        ok(himl[i] != NULL, "failed to create himl[%d]\n", i);
+        ok(0 == ImageList_AddIcon(himl[i], hicon1), "add icon1 to himl[%d] failed\n", i);
+        if (i == 0 || i == 1 || i == 7)
+        {
+            ImageList_GetImageInfo(himl[i], 0, &info);
+            sizes[i] = get_color_format(info.hbmImage);
+        }
+    }
+    DestroyIcon(hicon1);
+    for (i = 0; i < 8; i++)
+        for (j = 0; j < 8; j++)
+        {
+            hmerge = ImageList_Merge(himl[i], 0, himl[j], 0, 0, 0);
+            ok(hmerge != NULL, "merge himl[%d], himl[%d] failed\n", i, j);
+
+            ImageList_GetImageInfo(hmerge, 0, &info);
+            bpp = get_color_format(info.hbmImage);
+            /* ILC_COLOR[X] is defined as [X] */
+            if (i == 4 && j == 7)
+                ok(bpp == 16, /* merging ILC_COLOR16 with ILC_COLORDDB seems to be a special case */
+                    "wrong biBitCount %d when merging lists %d (%d) and %d (%d)\n", bpp, i, sizes[i], j, sizes[j]);
+            else
+                ok(bpp == (i > j ? sizes[i] : sizes[j]),
+                    "wrong biBitCount %d when merging lists %d (%d) and %d (%d)\n", bpp, i, sizes[i], j, sizes[j]);
+            ok(info.hbmMask != 0, "Imagelist merged from %d and %d had no mask\n", i, j);
+
+            if (hmerge) ImageList_Destroy(hmerge);
+        }
+
+    for (i = 0; i < 8; i++)
+        ImageList_Destroy(himl[i]);
+}
+
 static void test_merge(void)
 {
     HIMAGELIST himl1, himl2, hmerge;
@@ -2017,6 +2081,7 @@ START_TEST(imagelist)
     test_imagecount();
     test_DrawIndirect();
     test_merge();
+    test_merge_colors();
     test_imagelist_storage();
     test_iconsize();
 
-- 
1.7.5.4


More information about the wine-patches mailing list