[PATCH] Added tests for DrawIcon and DrawIconEx
Joel Holdsworth
joel at airwebreathe.org.uk
Sat Jun 6 10:07:43 CDT 2009
---
dlls/user32/tests/cursoricon.c | 377 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 377 insertions(+), 0 deletions(-)
diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c
index 9475534..1bd7be4 100644
--- a/dlls/user32/tests/cursoricon.c
+++ b/dlls/user32/tests/cursoricon.c
@@ -956,6 +956,381 @@ 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 void flood_background(HDC hdc, int width, int height, COLORREF color)
+{
+ RECT rect = {0, 0, 1, 1};
+ HBRUSH backgroundBrush = CreateSolidBrush(color);
+ FillRect(hdc, &rect, backgroundBrush);
+ DeleteObject(backgroundBrush);
+}
+
+static void check_alpha_draw(HDC hdc, BOOL drawiconex, BOOL alpha, int bpp, int line)
+{
+ HICON hicon;
+ UINT32 mask;
+ UINT32 color[2];
+ COLORREF expected, result;
+
+ mask = 0x00000000;
+ color[0] = 0x00A0B0C0;
+ color[1] = alpha ? 0xFF000000 : 0x00000000;
+ expected = alpha ? 0x00FFFFFF : 0x00C0B0A0;
+
+ hicon = create_test_icon(hdc, 2, 1, bpp, 0, color, sizeof(color));
+ if (!hicon) return;
+
+ flood_background(hdc, 1, 1, 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 (result == expected,
+ "%s. Expected %08X with %s. Got %08X from line %d\n",
+ alpha ? "Alpha blending" : "Not alpha blending",
+ (unsigned int)expected, drawiconex ? "DrawIconEx" : "DrawIcon",
+ (unsigned int)result, line);
+}
+
+static void check_DrawIcon(HDC hdc, BOOL maskvalue, UINT32 color, int bpp,
+ COLORREF background, COLORREF expected, int line)
+{
+ COLORREF result;
+ HICON hicon = create_test_icon(hdc, 1, 1, bpp, maskvalue, &color, sizeof(color));
+ if (!hicon) return;
+ flood_background(hdc, 1, 1, background);
+ DrawIcon(hdc, 0, 0, hicon);
+ result = GetPixel(hdc, 0, 0);
+
+ ok (result == expected,
+ "Overlaying Mask %d on Color %08X with DrawIcon. Expected %08X. Got %08X from line %d\n",
+ maskvalue, (unsigned int)color, (unsigned int)expected, (unsigned int)result, line);
+}
+
+static void test_DrawIcon_true_color(HDC hdcDst)
+{
+ DWORD dwVersion = GetVersion();
+ DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
+ DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
+
+ /* Mask is only heeded if alpha channel is always zero */
+ check_DrawIcon(hdcDst, FALSE, 0x00A0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, __LINE__);
+ check_DrawIcon(hdcDst, TRUE, 0x00A0B0C0, 32, 0x00FFFFFF, 0x003F4F5F, __LINE__);
+
+ /* Test alpha blending */
+ /* Applicable to XP and up */
+ if(dwMajorVersion > 5 || (dwMajorVersion == 5 && dwMinorVersion >= 1))
+ {
+ check_DrawIcon(hdcDst, FALSE, 0xFFA0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, __LINE__);
+
+ todo_wine
+ {
+ check_DrawIcon(hdcDst, TRUE, 0xFFA0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, __LINE__);
+
+ check_DrawIcon(hdcDst, FALSE, 0x80A0B0C0, 32, 0x00000000, 0x00605850, __LINE__);
+ check_DrawIcon(hdcDst, TRUE, 0x80A0B0C0, 32, 0x00000000, 0x00605850, __LINE__);
+ check_DrawIcon(hdcDst, FALSE, 0x80A0B0C0, 32, 0x00FFFFFF, 0x00DFD7CF, __LINE__);
+ check_DrawIcon(hdcDst, TRUE, 0x80A0B0C0, 32, 0x00FFFFFF, 0x00DFD7CF, __LINE__);
+
+ check_DrawIcon(hdcDst, FALSE, 0x01FFFFFF, 32, 0x00000000, 0x00010101, __LINE__);
+ check_DrawIcon(hdcDst, TRUE, 0x01FFFFFF, 32, 0x00000000, 0x00010101, __LINE__);
+ check_DrawIcon(hdcDst, FALSE, 0xFEFFFFFF, 32, 0x00000000, 0x00FEFEFE, __LINE__);
+ check_DrawIcon(hdcDst, TRUE, 0xFEFFFFFF, 32, 0x00000000, 0x00FEFEFE, __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__);
+ }
+}
+
+static void test_DrawIcon()
+{
+ BITMAPINFO bitmapInfo;
+ HDC hdcDst = NULL;
+ HBITMAP bmpDst = NULL;
+ HBITMAP bmpOld = NULL;
+ UINT32 *bits = 0;
+ OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO), };
+
+ GetVersionEx(&ovi);
+
+ hdcDst = CreateCompatibleDC(0);
+ ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
+ if (!hdcDst)
+ return;
+
+ memset(&bitmapInfo, 0, sizeof(bitmapInfo));
+ bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfo.bmiHeader.biWidth = 1;
+ bitmapInfo.bmiHeader.biHeight = 1;
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+ bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
+
+ /* 16-bit Tests */
+ bitmapInfo.bmiHeader.biBitCount = 16;
+ 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);
+
+ /* Only test on NT Windows. 9X series does 16-bit conversions differently. */
+ if(ovi.dwPlatformId >= 2)
+ {
+ check_DrawIcon(hdcDst, FALSE, 0x00A0B0C0, 16, 0x00FFFFFF, 0x00003163, __LINE__);
+ check_DrawIcon(hdcDst, TRUE, 0x00A0B0C0, 16, 0x00FFFFFF, 0x00FFCE9C, __LINE__);
+
+ check_DrawIcon(hdcDst, FALSE, 0xFFA0B0C0, 16, 0x00FFFFFF, 0x00003163, __LINE__);
+ check_DrawIcon(hdcDst, TRUE, 0xFFA0B0C0, 16, 0x00FFFFFF, 0x00FFCE9C, __LINE__);
+ check_DrawIcon(hdcDst, FALSE, 0x80A0B0C0, 16, 0x00FFFFFF, 0x00003163, __LINE__);
+ check_DrawIcon(hdcDst, TRUE, 0x80A0B0C0, 16, 0x00FFFFFF, 0x00FFCE9C, __LINE__);
+ }
+
+ SelectObject(hdcDst, bmpOld);
+ DeleteObject(bmpDst);
+ bmpOld = NULL;
+ bmpDst = NULL;
+
+ /* 24-bit Tests */
+ bitmapInfo.bmiHeader.biBitCount = 24;
+ 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_DrawIcon_true_color(hdcDst);
+
+ SelectObject(hdcDst, bmpOld);
+ DeleteObject(bmpDst);
+ bmpOld = NULL;
+ bmpDst = NULL;
+
+ /* 32-bit Tests */
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ 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_DrawIcon_true_color(hdcDst);
+
+ 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 expected, int line)
+{
+ COLORREF result;
+ HICON hicon = create_test_icon(hdc, 1, 1, bpp, maskvalue, &color, sizeof(color));
+ if (!hicon) return;
+ flood_background(hdc, 1, 1, background);
+ DrawIconEx(hdc, 0, 0, hicon, 1, 1, 0, NULL, flags);
+ result = GetPixel(hdc, 0, 0);
+
+ ok (result == expected,
+ "Overlaying Mask %d on Color %08X with DrawIconEx flags %08X. Expected %08X. Got %08X from line %d\n",
+ maskvalue, (unsigned int)color, flags, (unsigned int)expected, (unsigned int)result, line);
+}
+
+static void test_DrawIconEx_true_color(HDC hdcDst)
+{
+ DWORD dwVersion = GetVersion();
+ DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
+ DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
+
+ /* Test null, image only, and mask only drawing */
+ todo_wine
+ {
+ check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, 0, 0x00102030, 0x00102030, __LINE__);
+ check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, 0, 0x00102030, 0x00102030, __LINE__);
+ }
+
+ check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_MASK, 0x00FFFFFF, 0x00000000, __LINE__);
+ check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_MASK, 0x00FFFFFF, 0x00FFFFFF, __LINE__);
+
+ todo_wine
+ {
+ check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, DI_IMAGE, 0x00FFFFFF, 0x00C0B0A0, __LINE__);
+ check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, DI_IMAGE, 0x00FFFFFF, 0x00C0B0A0, __LINE__);
+ }
+
+ /* Test normal drawing */
+ check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, __LINE__);
+ todo_wine check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x003F4F5F, __LINE__);
+ check_DrawIconEx(hdcDst, FALSE, 0xFFA0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, __LINE__);
+
+ /* Test alpha blending */
+ /* Applicable to XP and up */
+ if(dwMajorVersion > 5 || (dwMajorVersion == 5 && dwMinorVersion >= 1))
+ {
+ todo_wine
+ {
+ check_DrawIconEx(hdcDst, TRUE, 0xFFA0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, __LINE__);
+
+ check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_NORMAL, 0x00000000, 0x00605850, __LINE__);
+ check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_NORMAL, 0x00000000, 0x00605850, __LINE__);
+ check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00DFD7CF, __LINE__);
+ check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00DFD7CF, __LINE__);
+
+ check_DrawIconEx(hdcDst, FALSE, 0x01FFFFFF, 32, DI_NORMAL, 0x00000000, 0x00010101, __LINE__);
+ check_DrawIconEx(hdcDst, TRUE, 0x01FFFFFF, 32, DI_NORMAL, 0x00000000, 0x00010101, __LINE__);
+ check_DrawIconEx(hdcDst, FALSE, 0xFEFFFFFF, 32, DI_NORMAL, 0x00000000, 0x00FEFEFE, __LINE__);
+ check_DrawIconEx(hdcDst, TRUE, 0xFEFFFFFF, 32, DI_NORMAL, 0x00000000, 0x00FEFEFE, __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__);
+ }
+}
+
+static void test_DrawIconEx()
+{
+ BITMAPINFO bitmapInfo;
+ HDC hdcDst = NULL;
+ HBITMAP bmpDst = NULL;
+ HBITMAP bmpOld = NULL;
+ UINT32 bits = 0;
+ OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO), };
+
+ GetVersionEx(&ovi);
+
+ hdcDst = CreateCompatibleDC(0);
+ ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
+ if (!hdcDst)
+ return;
+
+ memset(&bitmapInfo, 0, sizeof(bitmapInfo));
+ bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfo.bmiHeader.biWidth = 1;
+ bitmapInfo.bmiHeader.biHeight = 1;
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+ bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
+
+ /* 16-bit Tests */
+ bitmapInfo.bmiHeader.biBitCount = 16;
+ 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);
+
+ /* Only test on NT Windows. 9X series does 16-bit conversions differently. */
+ if(ovi.dwPlatformId >= 2)
+ {
+ check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 16, DI_NORMAL, 0x00FFFFFF, 0x00003163, __LINE__);
+ todo_wine check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 16, DI_NORMAL, 0x00FFFFFF, 0x00FFCE9C, __LINE__);
+
+ check_DrawIconEx(hdcDst, FALSE, 0xFFA0B0C0, 16, DI_NORMAL, 0x00FFFFFF, 0x00003163, __LINE__);
+ todo_wine check_DrawIconEx(hdcDst, TRUE, 0xFFA0B0C0, 16, DI_NORMAL, 0x00FFFFFF, 0x00FFCE9C, __LINE__);
+ check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 16, DI_NORMAL, 0x00FFFFFF, 0x00003163, __LINE__);
+ todo_wine check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 16, DI_NORMAL, 0x00FFFFFF, 0x00FFCE9C, __LINE__);
+ }
+
+ SelectObject(hdcDst, bmpOld);
+ DeleteObject(bmpDst);
+ bmpOld = NULL;
+ bmpDst = NULL;
+
+ /* 24-bit Tests */
+ bitmapInfo.bmiHeader.biBitCount = 24;
+ 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_DrawIconEx_true_color(hdcDst);
+
+ SelectObject(hdcDst, bmpOld);
+ DeleteObject(bmpDst);
+ bmpOld = NULL;
+ bmpDst = NULL;
+
+ /* 32-bit Tests */
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ 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_DrawIconEx_true_color(hdcDst);
+
+ 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 +1438,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
--=-cAj0Ee21tKDeOxUz2ksD--
More information about the wine-patches
mailing list