Charles Davis wrote:
Dmitry Timoshkov wrote:
"Charles Davis" cdavis@mymail.mines.edu wrote:
I've attached the patch so you can build a gdi32_test.exe that contains my tests.
Why don't you use the same way of comparing EMFs as other tests do, compare_emf_bits()/dump_emf_bits()/dump_emf_records()?
Because I didn't look. I guess I'll rewrite the tests to use these functions.
OK, here's a version that uses the same method of comparing EMFs as the other tests. It passes on Wine (at least on my system).
Chip
From d1f2029efc5ab0a335c6b95002de4ee5e394bcf5 Mon Sep 17 00:00:00 2001
From: Charles Davis cdavis@mymail.mines.edu Date: Tue, 17 Nov 2009 11:10:50 -0700 Subject: [PATCH] gdi32/tests: Test BitBlt() to a metafile. To: wine-patches wine-patches@winehq.org Reply-To: wine-devel wine-devel@winehq.org
--- dlls/gdi32/tests/metafile.c | 167 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 167 insertions(+), 0 deletions(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index b559901..de8cd41 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -1382,6 +1382,172 @@ static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits, return 0; }
+/*********************************************************************** + * DIB_GetDIBWidthBytes + * + * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned. + * Shamelessly borrowed from dlls/gdi32/dib.c. + */ +int DIB_GetDIBWidthBytes( int width, int depth ) +{ + int words; + + switch(depth) + { + case 1: words = (width + 31) / 32; break; + case 4: words = (width + 7) / 8; break; + case 8: words = (width + 3) / 4; break; + case 15: + case 16: words = (width + 1) / 2; break; + case 24: words = (width * 3 + 3)/4; break; + + default: + /* fall through */ + case 32: + words = width; + } + return 4 * words; +} + +static int CALLBACK test_BitBlt_record(HDC hdc, HANDLETABLE *table, const ENHMETARECORD *emfr, int nobj, LPARAM data) +{ + UINT *pi = (UINT *)data; + EMRBITBLT *emrbb; + + if(emfr->iType != EMR_BITBLT) return 1; + emrbb = (EMRBITBLT *)emfr; + + (*pi)++; + if(*pi > 2) return 1; + if(*pi == 1) /* First BitBlt */ + { + EMRBITBLT *first_bb; + DWORD size, bits_size, bmi_size; + DWORD nBPP; + BITMAP bm; + HBITMAP hbm = GetCurrentObject(hdc, OBJ_BITMAP); + BITMAPINFOHEADER *bmi; + + GetObjectW(hbm, sizeof(bm), &bm); + nBPP = bm.bmPlanes * bm.bmBitsPixel; + + bits_size = DIB_GetDIBWidthBytes(bm.bmWidth, nBPP) * bm.bmHeight; + bmi_size = sizeof(BITMAPINFOHEADER) + + (nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD); + trace("bits_size = %d, bmi_size = %d\n", bits_size, bmi_size); + size = sizeof(EMRBITBLT) + bits_size + bmi_size; + first_bb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if(!first_bb) + { + skip("Not enough memory for EMF record\n"); + return 1; + } + + first_bb->emr.iType = EMR_BITBLT; + first_bb->emr.nSize = size; + first_bb->rclBounds.right = GetSystemMetrics(SM_CXSCREEN); + first_bb->rclBounds.bottom = GetSystemMetrics(SM_CYSCREEN); + first_bb->cxDest = GetSystemMetrics(SM_CXSCREEN); + first_bb->cyDest = GetSystemMetrics(SM_CYSCREEN); + first_bb->dwRop = SRCCOPY; + first_bb->xformSrc.eM11 = 1.0; + first_bb->xformSrc.eM12 = 0.0; + first_bb->xformSrc.eM21 = 0.0; + first_bb->xformSrc.eM22 = 1.0; + first_bb->xformSrc.eDx = 0.0; + first_bb->xformSrc.eDy = 0.0; + first_bb->crBkColorSrc = GetBkColor(hdc); + first_bb->iUsageSrc = DIB_RGB_COLORS; + first_bb->offBmiSrc = sizeof(EMRBITBLT); + first_bb->cbBmiSrc = bmi_size; + first_bb->offBitsSrc = sizeof(EMRBITBLT) + bmi_size; + first_bb->cbBitsSrc = bits_size; + + bmi = (BITMAPINFOHEADER *)((BYTE *)first_bb + first_bb->offBmiSrc); + bmi->biSize = sizeof(BITMAPINFOHEADER); + bmi->biWidth = bm.bmWidth; + bmi->biHeight = bm.bmHeight; + bmi->biPlanes = bm.bmPlanes; + bmi->biBitCount = nBPP; + bmi->biCompression = BI_RGB; + bmi->biSizeImage = bits_size; + bmi->biYPelsPerMeter = MulDiv(GetDeviceCaps(hdc, LOGPIXELSX), 3937, 100); + bmi->biXPelsPerMeter = MulDiv(GetDeviceCaps(hdc, LOGPIXELSY), 3937, 100); + bmi->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0; + bmi->biClrImportant = 0; + + GetDIBits(hdc, hbm, 0, (UINT)bmi->biHeight, + (BYTE *)first_bb + first_bb->offBitsSrc, + (BITMAPINFO *)bmi, DIB_RGB_COLORS); + + match_emf_record(emfr, (ENHMETARECORD *)first_bb, "emr_BitBlt_first", FALSE); + } + else if(0) + { + EMRBITBLT second_bb = + { + {EMR_BITBLT, sizeof(EMRBITBLT)}, + {0, 0, 0, 0}, + 0, 0, + 0, 0, + WHITENESS, + 0, 0, + {1.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + 0, + 0, + 0, 0, 0, 0 + }; + + second_bb.rclBounds.right = GetSystemMetrics(SM_CXSCREEN); + second_bb.rclBounds.bottom = GetSystemMetrics(SM_CYSCREEN); + second_bb.cxDest = GetSystemMetrics(SM_CXSCREEN); + second_bb.cyDest = GetSystemMetrics(SM_CYSCREEN); + match_emf_record(emfr, (ENHMETARECORD *)&second_bb, "emr_BitBlt_second", FALSE); + } + return 1; +} + +/* tests blitting to an EMF */ +static void test_emf_BitBlt(void) +{ + HDC hdcDisplay, hdcMetafile, hdcBitmap; + HBITMAP hBitmap, hOldBitmap; + HENHMETAFILE hMetafile; + BOOL ret; + UINT i; + + hdcDisplay = CreateDCA("DISPLAY", NULL, NULL, NULL); + ok( hdcDisplay != 0, "CreateDCA error %d\n", GetLastError() ); + hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL); + ok( hdcMetafile != 0, "CreateEnhMetaFileA failed\n" ); + + hdcBitmap = CreateCompatibleDC(hdcDisplay); + ok( hdcBitmap != 0, "CreateCompatibleDC failed\n" ); + hBitmap = CreateCompatibleBitmap(hdcDisplay, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); + ok( hBitmap != 0, "CreateCompatibleBitmap failed\n" ); + hOldBitmap = SelectObject(hdcBitmap, hBitmap); + + ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), hdcBitmap, 0, 0, SRCCOPY); + ok( ret, "BitBlt failed\n" ); + if(0) /* Crashes on wine */ + { + ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 0, 0, 0, WHITENESS); + ok( ret, "BitBlt failed\n" ); + } + + hMetafile = CloseEnhMetaFile(hdcMetafile); + ok( hMetafile != 0, "CloseEnhMetaFile failed\n" ); + + i = 0; + EnumEnhMetaFile(hdcBitmap, hMetafile, test_BitBlt_record, &i, NULL); + if(0) + ok( i == 2, "too many/not enough BitBlt records: got %d, expected 2\n", i ); + + SelectObject(hdcBitmap, hOldBitmap); + DeleteObject(hBitmap); + DeleteDC(hdcBitmap); +} + /* Test a blank metafile. May be used as a template for new tests. */
static void test_mf_Blank(void) @@ -2628,6 +2794,7 @@ START_TEST(metafile) /* For enhanced metafiles (enhmfdrv) */ test_ExtTextOut(); test_SaveDC(); + test_emf_BitBlt();
/* For win-format metafiles (mfdrv) */ test_mf_SaveDC();