[1/2] user32/tests/cursoricon.c: DrawState: New Testcase for correct drawing of Icons

Wilfried Pasquazzo wilfried.pasquazzo at gmail.com
Thu Oct 1 13:35:27 CDT 2009


[1/2] New Testcase to check if DrawState() behaves correctly when drawing Icons.

affected files: dlls/user32/tests/cursoricon.c

Currently checks:

- if the Icons are drawn at the correct size. Should always be the
original icon size,
  independent of the width and height parameters passed to DrawState().
- if Icons without a bit-mask are drawn with correct color.
- if Icons with a bit-mask are drawn with correct color.

Test is successful in WindowsXP SP2, but fails in git-Wine, because
the Icons are
drawn too big.

----

[2/2] Make Wine pass the new Testcase and Fix Regression Bug 20153

affected files: dlls/user32/uitools.c

Make DrawState() use the Icon dimensions when drawing. This makes it pass all
in [1/2] implemented tests and fixes regression
http://bugs.winehq.org/show_bug.cgi?id=20153 . The width and height, that are
passed to UITOOLS_DrawStateJam() are taken directly from the icon that is to be
drawn (see implementation of UITOOLS_DrawState()), therefore it is correct to
simply use them as the target drawing dimensions.

Note: This fix was sent before without the testcase (see
http://www.winehq.org/pipermail/wine-patches/2009-September/078927.html),
but not committed. Didn't get feedback on that, so I guessed the reason was the
missing testcase.

----

Feedback is welcome!

Wilfried Pasquazzo

PS: When this gets committed, I can add other tests for DrawState(),
to e.g. test for
correct drawing of the "Disabled" effect.
-------------- next part --------------
From 299b793c611071800ba4cc12c11b5a2b867eb2ca Mon Sep 17 00:00:00 2001
From: Wilfried Pasquazzo <wilfried.pasquazzo at gmail.com>
Date: Thu, 1 Oct 2009 19:36:32 +0000
Subject: [PATCH 1/2] Testcase for drawing Icons with DrawState

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

diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c
index 064f6c7..330ff54 100644
--- a/dlls/user32/tests/cursoricon.c
+++ b/dlls/user32/tests/cursoricon.c
@@ -1229,6 +1229,133 @@ cleanup:
         DeleteDC(hdcDst);
 }
 
+static void check_DrawState(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, HBRUSH hbr, 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;
+    /* Set color of the 3 pixels that will be checked afterwards */
+    SetPixelV(hdc, 0, 0, background);
+    SetPixelV(hdc, 1, 1, background);
+    SetPixelV(hdc, 2, 2, background);
+
+    /* Let DrawState calculate the size of the icon (1x1) */
+    DrawState(hdc, hbr, NULL, (LPARAM) hicon, 0, 1, 1, 0, 0, ( DST_ICON | flags ));
+
+    /* Check if the icon wasn't drawn bigger than expected or at wrong place */
+    result = GetPixel(hdc, 0, 0);
+    ok(color_match(result, background), 
+        "Drawing Icon with size 1x1: Pixel at 0,0 should still have background "
+	"Color %06X, Got %06X from line %d\n",
+	background, result, line);
+ 
+    result = GetPixel(hdc, 2, 2);
+    ok(color_match(result, background), 
+        "Drawing Icon with size 1x1: Pixel at 2,2 should still have background "
+	"Color %06X, Got %06X from line %d\n",
+	background, result, line);
+    
+    /* Check if the icon was drawn with correct color */
+    result = GetPixel(hdc, 1, 1);
+
+    ok (color_match(result, modern_expected) ||         /* Windows 2000 and up */
+        broken(color_match(result, legacy_expected)),   /* Windows NT 4.0, 9X and below */
+        "Drawing Icon with size 1x1: Overlaying Mask %d on Color %06X with 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);
+
+    /* Check if manually specifying the icon size DOESN'T work */
+
+    /* IMPORTANT: For Icons, DrawState wants the size of the source image, not the 
+     *            size in which it should be ultimately drawn. Therefore giving
+     *            width/height 2x2 if the icon is only 1x1 pixels in size should
+     *            result in drawing it with size 1x1. The size parameters must be 
+     *            ignored if a Icon has to be drawn! */
+    SetPixelV(hdc, 0, 0, background);
+    SetPixelV(hdc, 1, 1, background);
+    SetPixelV(hdc, 2, 2, background);
+
+    /* Draw Icon with size 2x2 */
+    DrawState(hdc, hbr, NULL, (LPARAM) hicon, 0, 1, 1, 2, 2, ( DST_ICON | flags ));
+
+    /* Check if the icon wasn't drawn bigger than expected or at wrong place */
+    result = GetPixel(hdc, 0, 0);
+    ok(color_match(result, background), 
+        "Drawing Icon stretched to 2x2: Pixel at 0,0 should still have background "
+	"Color %06X, Got %06X from line %d\n",
+	background, result, line);
+ 
+    result = GetPixel(hdc, 2, 2);
+    ok(color_match(result, background), 
+        "Drawing Icon stretched to 2x2: Pixel at 2,2 should still have background "
+	"Color %06X, Got %06X from line %d\n",
+	background, result, line);
+    
+    /* Again, color check the result */    
+    result = GetPixel(hdc, 1, 1);
+
+    ok (color_match(result, modern_expected) ||         /* Windows 2000 and up */
+        broken(color_match(result, legacy_expected)),   /* Windows NT 4.0, 9X and below */
+        "Drawing Icon stretched to 2x2: Overlaying Mask %d on Color %06X with 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_DrawState(void)
+{
+    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 = 3;
+    bitmapInfo.bmiHeader.biHeight = 3;
+    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);
+
+
+    /* potential flags to test with DrawState are: */
+    /* DSS_DISABLED embosses the icon */
+    /* DSS_MONO draw Icon using a brush as parameter 5 */
+    /* DSS_NORMAL draw Icon without any modifications */
+    /* DSS_UNION draw the Icon dithered */
+    
+    check_DrawState(hdcDst, FALSE, 0x00A0B0C0, 32, DSS_NORMAL, 0, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
+    check_DrawState(hdcDst, TRUE, 0x00A0B0C0, 32, DSS_NORMAL, 0, 0x00FFFFFF, 0x003F4F5F, 0x003F4F5F, __LINE__);
+
+
+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];
@@ -1338,6 +1465,7 @@ START_TEST(cursoricon)
     test_CreateIconFromResource();
     test_DrawIcon();
     test_DrawIconEx();
+    test_DrawState();
     test_DestroyCursor();
     do_parent();
     test_child_process();
-- 
1.6.4.4


More information about the wine-patches mailing list