[PATCH] Added tests for DrawIcon and DrawIconEx

Joel Holdsworth joel at airwebreathe.org.uk
Tue Jun 16 08:59:58 CDT 2009


---
 dlls/user32/tests/cursoricon.c |  278 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 278 insertions(+), 0 deletions(-)

diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c
index 9475534..536f354 100644
--- a/dlls/user32/tests/cursoricon.c
+++ b/dlls/user32/tests/cursoricon.c
@@ -956,6 +956,282 @@ static void test_CreateIconFromResource(void)
     HeapFree(GetProcessHeap(), 0, hotspot);
 }
 
+static HICON create_test_icon(HDC hdc, int width, int height, int bpp,
+                              BOOL maskvalue, UINT32 *color, int colorSize)
+{
+    ICONINFO iconInfo;
+    BITMAPINFO bitmapInfo;
+    UINT32 *buffer = NULL;
+    UINT32 mask = maskvalue ? 0xFFFFFFFF : 0x00000000;
+
+    memset(&bitmapInfo, 0, sizeof(bitmapInfo));
+    bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    bitmapInfo.bmiHeader.biWidth = width;
+    bitmapInfo.bmiHeader.biHeight = height;
+    bitmapInfo.bmiHeader.biPlanes = 1;
+    bitmapInfo.bmiHeader.biBitCount = bpp;
+    bitmapInfo.bmiHeader.biCompression = BI_RGB;
+    bitmapInfo.bmiHeader.biSizeImage = colorSize;
+
+    iconInfo.fIcon = TRUE;
+    iconInfo.xHotspot = 0;
+    iconInfo.yHotspot = 0;
+
+    iconInfo.hbmMask = CreateBitmap( width, height, 1, 1, &mask );
+    if(!iconInfo.hbmMask) return NULL;
+
+    iconInfo.hbmColor = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
+    if(!iconInfo.hbmColor || !buffer)
+    {
+        DeleteObject(iconInfo.hbmMask);
+        return NULL;
+    }
+
+    memcpy(buffer, color, colorSize);
+
+    return CreateIconIndirect(&iconInfo);
+}
+
+static BOOL color_match(COLORREF a, COLORREF b)
+{
+    /* 5-bit accuracy is a sufficient test. This will match, so long as
+     * colors are never truncated to less that 3x5-bit accuracy i.e.
+     * paletized. */
+    return (a & 0x00F8F8F8) == (b & 0x00F8F8F8);
+}
+
+static void check_alpha_draw(HDC hdc, BOOL drawiconex, BOOL alpha, int bpp, int line)
+{
+    HICON hicon;
+    UINT32 mask;
+    UINT32 color[2];
+    COLORREF modern_expected, legacy_expected, result;
+
+    mask = 0x00000000;
+    color[0] = 0x00A0B0C0;
+    color[1] = alpha ? 0xFF000000 : 0x00000000;
+    modern_expected = alpha ? 0x00FFFFFF : 0x00C0B0A0;
+    legacy_expected = 0x00C0B0A0;
+
+    hicon = create_test_icon(hdc, 2, 1, bpp, 0, color, sizeof(color));
+    if (!hicon) return;
+
+    SetPixelV(hdc, 0, 0, 0x00FFFFFF);
+
+    if(drawiconex)
+        DrawIconEx(hdc, 0, 0, hicon, 2, 1, 0, NULL, DI_NORMAL);
+    else
+        DrawIcon(hdc, 0, 0, hicon);
+
+    result = GetPixel(hdc, 0, 0);
+    ok (color_match(result, modern_expected) ||         /* Windows 2000 and up */
+        broken(color_match(result, legacy_expected)),   /* Windows NT 4.0, 9X and below */
+        "%s. Expected a close match to %06X (modern) or %06X (legacy) with %s. "
+        "Got %06X from line %d\n",
+        alpha ? "Alpha blending" : "Not alpha blending", modern_expected, legacy_expected,
+        drawiconex ? "DrawIconEx" : "DrawIcon", result, line);
+}
+
+static void check_DrawIcon(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, COLORREF background,
+                           COLORREF modern_expected, COLORREF legacy_expected, int line)
+{
+    COLORREF result;
+    HICON hicon = create_test_icon(hdc, 1, 1, bpp, maskvalue, &color, sizeof(color));
+    if (!hicon) return;
+    SetPixelV(hdc, 0, 0, background);
+    DrawIcon(hdc, 0, 0, hicon);
+    result = GetPixel(hdc, 0, 0);
+
+    ok (color_match(result, modern_expected) ||         /* Windows 2000 and up */
+        broken(color_match(result, legacy_expected)),   /* Windows NT 4.0, 9X and below */
+        "Overlaying Mask %d on Color %06X with DrawIcon. "
+        "Expected a close match to %06X (modern), or %06X (legacy). Got %06X from line %d\n",
+        maskvalue, color, modern_expected, legacy_expected, result, line);
+}
+
+static void test_DrawIcon()
+{
+    BITMAPINFO bitmapInfo;
+    HDC hdcDst = NULL;
+    HBITMAP bmpDst = NULL;
+    HBITMAP bmpOld = NULL;
+    UINT32 *bits = 0;
+
+    hdcDst = CreateCompatibleDC(0);
+    ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
+    if (!hdcDst)
+        return;
+
+    if(GetDeviceCaps(hdcDst, BITSPIXEL) <= 8)
+    {
+        skip("Windows will distort DrawIcon colors at 8-bpp and less due to palletizing.\n");
+        goto cleanup;
+    }
+
+    memset(&bitmapInfo, 0, sizeof(bitmapInfo));
+    bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    bitmapInfo.bmiHeader.biWidth = 1;
+    bitmapInfo.bmiHeader.biHeight = 1;
+    bitmapInfo.bmiHeader.biBitCount = 32;
+    bitmapInfo.bmiHeader.biPlanes = 1;
+    bitmapInfo.bmiHeader.biCompression = BI_RGB;
+    bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
+
+    bmpDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+    ok (bmpDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
+    if (!bmpDst || !bits)
+        goto cleanup;
+    bmpOld = SelectObject(hdcDst, bmpDst);
+
+    /* Mask is only heeded if alpha channel is always zero */
+    check_DrawIcon(hdcDst, FALSE, 0x00A0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
+    check_DrawIcon(hdcDst, TRUE, 0x00A0B0C0, 32, 0x00FFFFFF, 0x003F4F5F, 0x003F4F5F, __LINE__);
+
+    /* Test alpha blending */
+    /* Windows 2000 and up will alpha blend, earlier Windows versions will not */
+    check_DrawIcon(hdcDst, FALSE, 0xFFA0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
+
+    todo_wine
+    {
+        check_DrawIcon(hdcDst, TRUE, 0xFFA0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, 0x003F4F5F, __LINE__);
+
+        check_DrawIcon(hdcDst, FALSE, 0x80A0B0C0, 32, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__);
+        check_DrawIcon(hdcDst, TRUE, 0x80A0B0C0, 32, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__);
+        check_DrawIcon(hdcDst, FALSE, 0x80A0B0C0, 32, 0x00FFFFFF, 0x00DFD7CF, 0x00C0B0A0, __LINE__);
+        check_DrawIcon(hdcDst, TRUE, 0x80A0B0C0, 32, 0x00FFFFFF, 0x00DFD7CF, 0x003F4F5F, __LINE__);
+
+        check_DrawIcon(hdcDst, FALSE, 0x01FFFFFF, 32, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__);
+        check_DrawIcon(hdcDst, TRUE, 0x01FFFFFF, 32, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__);
+    }
+
+    /* Test detecting of alpha channel */
+    /* If a single pixel's alpha channel is non-zero, the icon
+       will be alpha blended, otherwise it will be draw with
+       and + xor blts. */
+    check_alpha_draw(hdcDst, FALSE, FALSE, 32, __LINE__);
+    todo_wine check_alpha_draw(hdcDst, FALSE, TRUE, 32, __LINE__);
+
+    SelectObject(hdcDst, bmpOld);
+    DeleteObject(bmpDst);
+    bmpOld = NULL;
+    bmpDst = NULL;
+
+cleanup:
+    if(bmpOld)
+        SelectObject(hdcDst, bmpOld);
+    if(bmpDst)
+        DeleteObject(bmpDst);
+    if(hdcDst)
+        DeleteDC(hdcDst);
+}
+
+static void check_DrawIconEx(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, UINT flags, COLORREF background,
+                             COLORREF modern_expected, COLORREF legacy_expected, int line)
+{
+    COLORREF result;
+    HICON hicon = create_test_icon(hdc, 1, 1, bpp, maskvalue, &color, sizeof(color));
+    if (!hicon) return;
+    SetPixelV(hdc, 0, 0, background);
+    DrawIconEx(hdc, 0, 0, hicon, 1, 1, 0, NULL, flags);
+    result = GetPixel(hdc, 0, 0);
+
+    ok (color_match(result, modern_expected) ||         /* Windows 2000 and up */
+        broken(color_match(result, legacy_expected)),   /* Windows NT 4.0, 9X and below */
+        "Overlaying Mask %d on Color %06X with DrawIconEx flags %08X. "
+        "Expected a close match to %06X (modern) or %06X (legacy). Got %06X from line %d\n",
+        maskvalue, color, flags, modern_expected, legacy_expected, result, line);
+}
+
+static void test_DrawIconEx()
+{
+    BITMAPINFO bitmapInfo;
+    HDC hdcDst = NULL;
+    HBITMAP bmpDst = NULL;
+    HBITMAP bmpOld = NULL;
+    UINT32 bits = 0;
+
+    hdcDst = CreateCompatibleDC(0);
+    ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
+    if (!hdcDst)
+        return;
+
+    if(GetDeviceCaps(hdcDst, BITSPIXEL) <= 8)
+    {
+        skip("Windows will distort DrawIconEx colors at 8-bpp and less due to palletizing.\n");
+        goto cleanup;
+    }
+
+    memset(&bitmapInfo, 0, sizeof(bitmapInfo));
+    bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    bitmapInfo.bmiHeader.biWidth = 1;
+    bitmapInfo.bmiHeader.biHeight = 1;
+    bitmapInfo.bmiHeader.biBitCount = 32;
+    bitmapInfo.bmiHeader.biPlanes = 1;
+    bitmapInfo.bmiHeader.biCompression = BI_RGB;
+    bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
+    bmpDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+    ok (bmpDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
+    if (!bmpDst || !bits)
+        goto cleanup;
+    bmpOld = SelectObject(hdcDst, bmpDst);
+
+    /* Test null, image only, and mask only drawing */
+    todo_wine
+    {
+        check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, 0, 0x00102030, 0x00102030, 0x00102030, __LINE__);
+        check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, 0, 0x00102030, 0x00102030, 0x00102030, __LINE__);
+    }
+
+    check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_MASK, 0x00FFFFFF, 0x00000000, 0x00000000, __LINE__);
+    check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_MASK, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, __LINE__);
+
+    todo_wine
+    {
+        check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, DI_IMAGE, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
+        check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, DI_IMAGE, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
+    }
+
+    /* Test normal drawing */
+    check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
+    todo_wine check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x003F4F5F, 0x003F4F5F, __LINE__);
+    check_DrawIconEx(hdcDst, FALSE, 0xFFA0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
+
+    /* Test alpha blending */
+    /* Windows 2000 and up will alpha blend, earlier Windows versions will not */
+    todo_wine check_DrawIconEx(hdcDst, TRUE, 0xFFA0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, 0x003F4F5F, __LINE__);
+
+    todo_wine
+    {
+        check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_NORMAL, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__);
+        check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_NORMAL, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__);
+        check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00DFD7CF, 0x00C0B0A0, __LINE__);
+        check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00DFD7CF, 0x003F4F5F, __LINE__);
+
+        check_DrawIconEx(hdcDst, FALSE, 0x01FFFFFF, 32, DI_NORMAL, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__);
+        check_DrawIconEx(hdcDst, TRUE, 0x01FFFFFF, 32, DI_NORMAL, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__);
+    }
+
+    /* Test detecting of alpha channel */
+    /* If a single pixel's alpha channel is non-zero, the icon
+       will be alpha blended, otherwise it will be draw with
+       and + xor blts. */
+    check_alpha_draw(hdcDst, TRUE, FALSE, 32, __LINE__);
+    todo_wine check_alpha_draw(hdcDst, TRUE, TRUE, 32, __LINE__);
+
+    SelectObject(hdcDst, bmpOld);
+    DeleteObject(bmpDst);
+    bmpOld = NULL;
+    bmpDst = NULL;
+
+cleanup:
+    if(bmpOld)
+        SelectObject(hdcDst, bmpOld);
+    if(bmpDst)
+        DeleteObject(bmpDst);
+    if(hdcDst)
+        DeleteDC(hdcDst);
+}
+
 static void test_DestroyCursor(void)
 {
     static const BYTE bmp_bits[4096];
@@ -1063,6 +1339,8 @@ START_TEST(cursoricon)
     test_CreateIcon();
     test_LoadImage();
     test_CreateIconFromResource();
+    test_DrawIcon();
+    test_DrawIconEx();
     test_DestroyCursor();
     do_parent();
     test_child_process();
-- 
1.6.0.4


--=-b6E9K1jaZVpBlySU/U1d--





More information about the wine-patches mailing list