Charles Davis wrote:
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
Sorry, that last version had some issues. Here's one that fixes them.
Chip
From a2607301f33c42265f441b84dfc8f99467201ff9 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 | 169 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 169 insertions(+), 0 deletions(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index b559901..02e5e9b 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -1382,6 +1382,174 @@ 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. + */ +static 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; + if(nBPP > 8) nBPP = 24; /* FIXME */ + + bits_size = DIB_GetDIBWidthBytes(bm.bmWidth, nBPP) * bm.bmHeight; + bmi_size = sizeof(BITMAPINFOHEADER) + + (nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD); + 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)-1; + first_bb->rclBounds.bottom = GetSystemMetrics(SM_CYSCREEN)-1; + 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((ENHMETARECORD *)first_bb, emfr, "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)-1; + second_bb.rclBounds.bottom = GetSystemMetrics(SM_CYSCREEN)-1; + second_bb.cxDest = GetSystemMetrics(SM_CXSCREEN); + second_bb.cyDest = GetSystemMetrics(SM_CYSCREEN); + match_emf_record((ENHMETARECORD *)&second_bb, emfr, "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; + RECT rc; + + 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; + SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); + EnumEnhMetaFile(hdcBitmap, hMetafile, test_BitBlt_record, &i, &rc); + 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 +2796,7 @@ START_TEST(metafile) /* For enhanced metafiles (enhmfdrv) */ test_ExtTextOut(); test_SaveDC(); + test_emf_BitBlt();
/* For win-format metafiles (mfdrv) */ test_mf_SaveDC();