Hi,
I have a test that I wrote from scratch for bug 4543. It tests the operation of BitBlt to a metafile, first from the screen then pure whiteness. Unfortunately, I have no Windows boxes to test on, so I need people to run my test on Windows. After all, I need to verify that this test is an accurate representation of Windows' behavior!
Also, testing under Wine would be appreciated. As a Mac user, I don't think my system is representative of the vast majority of Wine users (who probably run Linux).
I've attached the patch so you can build a gdi32_test.exe that contains my tests.
Thanks in advance.
Chip
From db073155c888747b9259cb8fe0d5ff2a59ee5666 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 | 68 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index b559901..6bf25e4 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -665,6 +665,74 @@ static void test_SaveDC(void) DestroyWindow(hwnd); }
+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; + ok( emrbb->xDest == 0, "wrong xDest for BitBlt record: got %d, expected 0\n", emrbb->xDest ); + ok( emrbb->yDest == 0, "wrong yDest for BitBlt record: got %d, expected 0\n", emrbb->yDest ); + ok( emrbb->xSrc == 0, "wrong xSrc for BitBlt record: got %d, expected 0\n", emrbb->xSrc ); + ok( emrbb->ySrc == 0, "wrong ySrc for BitBlt record: got %d, expected 0\n", emrbb->ySrc ); + ok( emrbb->cxDest == GetSystemMetrics(SM_CXSCREEN), "wrong cxDest for BitBlt record: got %d\n", emrbb->cxDest ); + ok( emrbb->cyDest == GetSystemMetrics(SM_CYSCREEN), "wrong cyDest for BitBlt record: got %d\n", emrbb->cyDest ); + if(*pi == 1) /* First BitBlt */ + { + ok( emrbb->dwRop == SRCCOPY, "wrong ROP for BitBlt record: got %x, expected SRCCOPY\n", emrbb->dwRop ); + } + else + { + ok( emrbb->dwRop == WHITENESS, "wrong ROP for BitBlt record: got %x, expected WHITENESS\n", emrbb->dwRop ); + } + return 1; +} + +static void test_emf_BitBlt(void) +{ + HDC hdcDisplay, hdcMetafile; + HENHMETAFILE hMetafile; + ENHMETAHEADER emh; + BYTE *bits; + BOOL ret; + UINT i; + + hdcDisplay = CreateDCA(NULL, "DISPLAY", NULL, NULL); + ok( hdcDisplay != 0, "CreateDCA error %d\n", GetLastError() ); + hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL); + ok( hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError() ); + + ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), hdcDisplay, 0, 0, SRCCOPY); + ok( ret, "BitBlt error %d\n", GetLastError() ); + ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 0, 0, 0, WHITENESS); + ok( ret, "BitBlt error %d\n", GetLastError() ); + + hMetafile = CloseEnhMetaFile(hdcMetafile); + ok( hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError() ); + + ret = GetEnhMetaFileHeader( hMetafile, sizeof(emh), &emh ); + ok( ret != 0, "GetEnhMetaFileHeader error %d\n", GetLastError() ); + ok( emh.dSignature == ENHMETA_SIGNATURE, "bad metafile signature %x\n", emh.dSignature ); + + bits = HeapAlloc( GetProcessHeap(), 0, emh.nBytes ); + if(!bits) + { + skip( "not enough memory for EMF bits\n" ); + return; + } + ret = GetEnhMetaFileBits( hMetafile, emh.nBytes, bits ); + ok( ret != 0, "GetEnhMetaFileBits error %d\n", GetLastError() ); + for(i = 0; i < emh.nBytes; i++) + ok( bits[i] == 0xff, "unexpected EMF bits: got %02x, expected 0xff\n", bits[i] ); + + EnumEnhMetaFile(0, hMetafile, test_BitBlt_record, (LPARAM)&i, NULL); + ok( i == 2, "too many/not enough BitBlt records: got %d, expected 2\n", i ); +} + static void test_mf_SaveDC(void) { HDC hdcMetafile;
This passes on my Windows XP vm and on Wine here.
On Tue, Nov 17, 2009 at 12:44 PM, Charles Davis cdavis@mymail.mines.edu wrote:
Hi,
I have a test that I wrote from scratch for bug 4543. It tests the operation of BitBlt to a metafile, first from the screen then pure whiteness. Unfortunately, I have no Windows boxes to test on, so I need people to run my test on Windows. After all, I need to verify that this test is an accurate representation of Windows' behavior!
Also, testing under Wine would be appreciated. As a Mac user, I don't think my system is representative of the vast majority of Wine users (who probably run Linux).
I've attached the patch so you can build a gdi32_test.exe that contains my tests.
Thanks in advance.
Chip
From db073155c888747b9259cb8fe0d5ff2a59ee5666 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 | Â 68 +++++++++++++++++++++++++++++++++++++++++++ Â 1 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index b559901..6bf25e4 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -665,6 +665,74 @@ static void test_SaveDC(void) Â Â DestroyWindow(hwnd); Â }
+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;
- ok( emrbb->xDest == 0, "wrong xDest for BitBlt record: got %d, expected 0\n", emrbb->xDest );
- ok( emrbb->yDest == 0, "wrong yDest for BitBlt record: got %d, expected 0\n", emrbb->yDest );
- ok( emrbb->xSrc == 0, "wrong xSrc for BitBlt record: got %d, expected 0\n", emrbb->xSrc );
- ok( emrbb->ySrc == 0, "wrong ySrc for BitBlt record: got %d, expected 0\n", emrbb->ySrc );
- ok( emrbb->cxDest == GetSystemMetrics(SM_CXSCREEN), "wrong cxDest for BitBlt record: got %d\n", emrbb->cxDest );
- ok( emrbb->cyDest == GetSystemMetrics(SM_CYSCREEN), "wrong cyDest for BitBlt record: got %d\n", emrbb->cyDest );
- if(*pi == 1) Â Â /* First BitBlt */
- {
- ok( emrbb->dwRop == SRCCOPY, "wrong ROP for BitBlt record: got %x, expected SRCCOPY\n", emrbb->dwRop );
- }
- else
- {
- ok( emrbb->dwRop == WHITENESS, "wrong ROP for BitBlt record: got %x, expected WHITENESS\n", emrbb->dwRop );
- }
- return 1;
+}
+static void test_emf_BitBlt(void) +{
- HDC hdcDisplay, hdcMetafile;
- HENHMETAFILE hMetafile;
- ENHMETAHEADER emh;
- BYTE *bits;
- BOOL ret;
- UINT i;
- hdcDisplay = CreateDCA(NULL, "DISPLAY", NULL, NULL);
- ok( hdcDisplay != 0, "CreateDCA error %d\n", GetLastError() );
- hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
- ok( hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError() );
- ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), hdcDisplay, 0, 0, SRCCOPY);
- ok( ret, "BitBlt error %d\n", GetLastError() );
- ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 0, 0, 0, WHITENESS);
- ok( ret, "BitBlt error %d\n", GetLastError() );
- hMetafile = CloseEnhMetaFile(hdcMetafile);
- ok( hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError() );
- ret = GetEnhMetaFileHeader( hMetafile, sizeof(emh), &emh );
- ok( ret != 0, "GetEnhMetaFileHeader error %d\n", GetLastError() );
- ok( emh.dSignature == ENHMETA_SIGNATURE, "bad metafile signature %x\n", emh.dSignature );
- bits = HeapAlloc( GetProcessHeap(), 0, emh.nBytes );
- if(!bits)
- {
- skip( "not enough memory for EMF bits\n" );
- return;
- }
- ret = GetEnhMetaFileBits( hMetafile, emh.nBytes, bits );
- ok( ret != 0, "GetEnhMetaFileBits error %d\n", GetLastError() );
- for(i = 0; i < emh.nBytes; i++)
- ok( bits[i] == 0xff, "unexpected EMF bits: got %02x, expected 0xff\n", bits[i] );
- EnumEnhMetaFile(0, hMetafile, test_BitBlt_record, (LPARAM)&i, NULL);
- ok( i == 2, "too many/not enough BitBlt records: got %d, expected 2\n", i );
+}
static void test_mf_SaveDC(void) Â { Â Â HDC hdcMetafile; -- 1.6.5.2
On closer inspection, you didn't add a call to your static function, so that was meaningless.
On Tue, Nov 17, 2009 at 1:59 PM, Vincent Povirk madewokherd+8cd9@gmail.com wrote:
This passes on my Windows XP vm and on Wine here.
On Tue, Nov 17, 2009 at 12:44 PM, Charles Davis cdavis@mymail.mines.edu wrote:
Hi,
I have a test that I wrote from scratch for bug 4543. It tests the operation of BitBlt to a metafile, first from the screen then pure whiteness. Unfortunately, I have no Windows boxes to test on, so I need people to run my test on Windows. After all, I need to verify that this test is an accurate representation of Windows' behavior!
Also, testing under Wine would be appreciated. As a Mac user, I don't think my system is representative of the vast majority of Wine users (who probably run Linux).
I've attached the patch so you can build a gdi32_test.exe that contains my tests.
Thanks in advance.
Chip
From db073155c888747b9259cb8fe0d5ff2a59ee5666 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 | Â 68 +++++++++++++++++++++++++++++++++++++++++++ Â 1 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index b559901..6bf25e4 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -665,6 +665,74 @@ static void test_SaveDC(void) Â Â DestroyWindow(hwnd); Â }
+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;
- ok( emrbb->xDest == 0, "wrong xDest for BitBlt record: got %d, expected 0\n", emrbb->xDest );
- ok( emrbb->yDest == 0, "wrong yDest for BitBlt record: got %d, expected 0\n", emrbb->yDest );
- ok( emrbb->xSrc == 0, "wrong xSrc for BitBlt record: got %d, expected 0\n", emrbb->xSrc );
- ok( emrbb->ySrc == 0, "wrong ySrc for BitBlt record: got %d, expected 0\n", emrbb->ySrc );
- ok( emrbb->cxDest == GetSystemMetrics(SM_CXSCREEN), "wrong cxDest for BitBlt record: got %d\n", emrbb->cxDest );
- ok( emrbb->cyDest == GetSystemMetrics(SM_CYSCREEN), "wrong cyDest for BitBlt record: got %d\n", emrbb->cyDest );
- if(*pi == 1) Â Â /* First BitBlt */
- {
- ok( emrbb->dwRop == SRCCOPY, "wrong ROP for BitBlt record: got %x, expected SRCCOPY\n", emrbb->dwRop );
- }
- else
- {
- ok( emrbb->dwRop == WHITENESS, "wrong ROP for BitBlt record: got %x, expected WHITENESS\n", emrbb->dwRop );
- }
- return 1;
+}
+static void test_emf_BitBlt(void) +{
- HDC hdcDisplay, hdcMetafile;
- HENHMETAFILE hMetafile;
- ENHMETAHEADER emh;
- BYTE *bits;
- BOOL ret;
- UINT i;
- hdcDisplay = CreateDCA(NULL, "DISPLAY", NULL, NULL);
- ok( hdcDisplay != 0, "CreateDCA error %d\n", GetLastError() );
- hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
- ok( hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError() );
- ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), hdcDisplay, 0, 0, SRCCOPY);
- ok( ret, "BitBlt error %d\n", GetLastError() );
- ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 0, 0, 0, WHITENESS);
- ok( ret, "BitBlt error %d\n", GetLastError() );
- hMetafile = CloseEnhMetaFile(hdcMetafile);
- ok( hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError() );
- ret = GetEnhMetaFileHeader( hMetafile, sizeof(emh), &emh );
- ok( ret != 0, "GetEnhMetaFileHeader error %d\n", GetLastError() );
- ok( emh.dSignature == ENHMETA_SIGNATURE, "bad metafile signature %x\n", emh.dSignature );
- bits = HeapAlloc( GetProcessHeap(), 0, emh.nBytes );
- if(!bits)
- {
- skip( "not enough memory for EMF bits\n" );
- return;
- }
- ret = GetEnhMetaFileBits( hMetafile, emh.nBytes, bits );
- ok( ret != 0, "GetEnhMetaFileBits error %d\n", GetLastError() );
- for(i = 0; i < emh.nBytes; i++)
- ok( bits[i] == 0xff, "unexpected EMF bits: got %02x, expected 0xff\n", bits[i] );
- EnumEnhMetaFile(0, hMetafile, test_BitBlt_record, (LPARAM)&i, NULL);
- ok( i == 2, "too many/not enough BitBlt records: got %d, expected 2\n", i );
+}
static void test_mf_SaveDC(void) Â { Â Â HDC hdcMetafile; -- 1.6.5.2
-- Vincent Povirk
On windows, I get:
metafile.c:705: Test failed: CreateDCA error 1801
metafile.c:710: Test failed: BitBlt error 1801
metafile.c:730: Test failed: unexpected EMF bits: got 01, expected 0xff
metafile.c:730: Test failed: unexpected EMF bits: got 00, expected 0xff
metafile.c:730: Test failed: unexpected EMF bits: got 00, expected 0xff
...
On Wine, I get:
metafile.c:710: Test failed: BitBlt error 0 wine: Unhandled page fault on read access to 0x00000000 at address 0x686476e5 (thread 0009), starting debugger... (same crash that's on bug 4543)
On Tue, Nov 17, 2009 at 2:04 PM, Vincent Povirk madewokherd+8cd9@gmail.com wrote:
On closer inspection, you didn't add a call to your static function, so that was meaningless.
On Tue, Nov 17, 2009 at 1:59 PM, Vincent Povirk madewokherd+8cd9@gmail.com wrote:
This passes on my Windows XP vm and on Wine here.
On Tue, Nov 17, 2009 at 12:44 PM, Charles Davis cdavis@mymail.mines.edu wrote:
Hi,
I have a test that I wrote from scratch for bug 4543. It tests the operation of BitBlt to a metafile, first from the screen then pure whiteness. Unfortunately, I have no Windows boxes to test on, so I need people to run my test on Windows. After all, I need to verify that this test is an accurate representation of Windows' behavior!
Also, testing under Wine would be appreciated. As a Mac user, I don't think my system is representative of the vast majority of Wine users (who probably run Linux).
I've attached the patch so you can build a gdi32_test.exe that contains my tests.
Thanks in advance.
Chip
From db073155c888747b9259cb8fe0d5ff2a59ee5666 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 | Â 68 +++++++++++++++++++++++++++++++++++++++++++ Â 1 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index b559901..6bf25e4 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -665,6 +665,74 @@ static void test_SaveDC(void) Â Â DestroyWindow(hwnd); Â }
+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;
- ok( emrbb->xDest == 0, "wrong xDest for BitBlt record: got %d, expected 0\n", emrbb->xDest );
- ok( emrbb->yDest == 0, "wrong yDest for BitBlt record: got %d, expected 0\n", emrbb->yDest );
- ok( emrbb->xSrc == 0, "wrong xSrc for BitBlt record: got %d, expected 0\n", emrbb->xSrc );
- ok( emrbb->ySrc == 0, "wrong ySrc for BitBlt record: got %d, expected 0\n", emrbb->ySrc );
- ok( emrbb->cxDest == GetSystemMetrics(SM_CXSCREEN), "wrong cxDest for BitBlt record: got %d\n", emrbb->cxDest );
- ok( emrbb->cyDest == GetSystemMetrics(SM_CYSCREEN), "wrong cyDest for BitBlt record: got %d\n", emrbb->cyDest );
- if(*pi == 1) Â Â /* First BitBlt */
- {
- ok( emrbb->dwRop == SRCCOPY, "wrong ROP for BitBlt record: got %x, expected SRCCOPY\n", emrbb->dwRop );
- }
- else
- {
- ok( emrbb->dwRop == WHITENESS, "wrong ROP for BitBlt record: got %x, expected WHITENESS\n", emrbb->dwRop );
- }
- return 1;
+}
+static void test_emf_BitBlt(void) +{
- HDC hdcDisplay, hdcMetafile;
- HENHMETAFILE hMetafile;
- ENHMETAHEADER emh;
- BYTE *bits;
- BOOL ret;
- UINT i;
- hdcDisplay = CreateDCA(NULL, "DISPLAY", NULL, NULL);
- ok( hdcDisplay != 0, "CreateDCA error %d\n", GetLastError() );
- hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
- ok( hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError() );
- ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), hdcDisplay, 0, 0, SRCCOPY);
- ok( ret, "BitBlt error %d\n", GetLastError() );
- ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 0, 0, 0, WHITENESS);
- ok( ret, "BitBlt error %d\n", GetLastError() );
- hMetafile = CloseEnhMetaFile(hdcMetafile);
- ok( hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError() );
- ret = GetEnhMetaFileHeader( hMetafile, sizeof(emh), &emh );
- ok( ret != 0, "GetEnhMetaFileHeader error %d\n", GetLastError() );
- ok( emh.dSignature == ENHMETA_SIGNATURE, "bad metafile signature %x\n", emh.dSignature );
- bits = HeapAlloc( GetProcessHeap(), 0, emh.nBytes );
- if(!bits)
- {
- skip( "not enough memory for EMF bits\n" );
- return;
- }
- ret = GetEnhMetaFileBits( hMetafile, emh.nBytes, bits );
- ok( ret != 0, "GetEnhMetaFileBits error %d\n", GetLastError() );
- for(i = 0; i < emh.nBytes; i++)
- ok( bits[i] == 0xff, "unexpected EMF bits: got %02x, expected 0xff\n", bits[i] );
- EnumEnhMetaFile(0, hMetafile, test_BitBlt_record, (LPARAM)&i, NULL);
- ok( i == 2, "too many/not enough BitBlt records: got %d, expected 2\n", i );
+}
static void test_mf_SaveDC(void) Â { Â Â HDC hdcMetafile; -- 1.6.5.2
-- Vincent Povirk
-- Vincent Povirk
Vincent Povirk wrote:
On windows, I get:
metafile.c:705: Test failed: CreateDCA error 1801
Hmm... now that I think about it, I think the call to CreateDCA() should look like this: hdcDisplay = CreateDCA("DISPLAY", NULL, NULL, NULL);
metafile.c:710: Test failed: BitBlt error 1801
BitBlt() failed because there was no DC to blit from. That should go away when I fix CreateDCA().
metafile.c:730: Test failed: unexpected EMF bits: got 01, expected 0xff
metafile.c:730: Test failed: unexpected EMF bits: got 00, expected 0xff
metafile.c:730: Test failed: unexpected EMF bits: got 00, expected 0xff
...
Now this is interesting. I would expect all the bits to be ones, yet here, they're (almost) all zeros. It's like BitBlt(..., WHITENESS) had no effect. Or, maybe I got the meaning of the bits backwards.
On Wine, I get:
metafile.c:710: Test failed: BitBlt error 0
Now why does that one fail? I also need to stop printing the last error, because BitBlt() apparently doesn't set the last error. (Need to pay more attention to MSDN...)
wine: Unhandled page fault on read access to 0x00000000 at address 0x686476e5 (thread 0009), starting debugger... (same crash that's on bug 4543)
Since it crashes, I'll have to if(0) that one out.
On Tue, Nov 17, 2009 at 2:04 PM, Vincent Povirk madewokherd+8cd9@gmail.com wrote:
On closer inspection, you didn't add a call to your static function, so that was meaningless.
On Tue, Nov 17, 2009 at 1:59 PM, Vincent Povirk madewokherd+8cd9@gmail.com wrote:
This passes on my Windows XP vm and on Wine here.
On Tue, Nov 17, 2009 at 12:44 PM, Charles Davis cdavis@mymail.mines.edu wrote:
Hi,
I have a test that I wrote from scratch for bug 4543. It tests the operation of BitBlt to a metafile, first from the screen then pure whiteness. Unfortunately, I have no Windows boxes to test on, so I need people to run my test on Windows. After all, I need to verify that this test is an accurate representation of Windows' behavior!
Also, testing under Wine would be appreciated. As a Mac user, I don't think my system is representative of the vast majority of Wine users (who probably run Linux).
I've attached the patch so you can build a gdi32_test.exe that contains my tests.
Thanks in advance.
Chip
From db073155c888747b9259cb8fe0d5ff2a59ee5666 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 | 68 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index b559901..6bf25e4 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -665,6 +665,74 @@ static void test_SaveDC(void) DestroyWindow(hwnd); }
+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;
- ok( emrbb->xDest == 0, "wrong xDest for BitBlt record: got %d, expected 0\n", emrbb->xDest );
- ok( emrbb->yDest == 0, "wrong yDest for BitBlt record: got %d, expected 0\n", emrbb->yDest );
- ok( emrbb->xSrc == 0, "wrong xSrc for BitBlt record: got %d, expected 0\n", emrbb->xSrc );
- ok( emrbb->ySrc == 0, "wrong ySrc for BitBlt record: got %d, expected 0\n", emrbb->ySrc );
- ok( emrbb->cxDest == GetSystemMetrics(SM_CXSCREEN), "wrong cxDest for BitBlt record: got %d\n", emrbb->cxDest );
- ok( emrbb->cyDest == GetSystemMetrics(SM_CYSCREEN), "wrong cyDest for BitBlt record: got %d\n", emrbb->cyDest );
- if(*pi == 1) /* First BitBlt */
- {
ok( emrbb->dwRop == SRCCOPY, "wrong ROP for BitBlt record: got %x, expected SRCCOPY\n", emrbb->dwRop );
- }
- else
- {
ok( emrbb->dwRop == WHITENESS, "wrong ROP for BitBlt record: got %x, expected WHITENESS\n", emrbb->dwRop );
- }
- return 1;
+}
+static void test_emf_BitBlt(void) +{
- HDC hdcDisplay, hdcMetafile;
- HENHMETAFILE hMetafile;
- ENHMETAHEADER emh;
- BYTE *bits;
- BOOL ret;
- UINT i;
- hdcDisplay = CreateDCA(NULL, "DISPLAY", NULL, NULL);
- ok( hdcDisplay != 0, "CreateDCA error %d\n", GetLastError() );
- hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
- ok( hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError() );
- ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), hdcDisplay, 0, 0, SRCCOPY);
- ok( ret, "BitBlt error %d\n", GetLastError() );
- ret = BitBlt(hdcMetafile, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 0, 0, 0, WHITENESS);
- ok( ret, "BitBlt error %d\n", GetLastError() );
- hMetafile = CloseEnhMetaFile(hdcMetafile);
- ok( hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError() );
- ret = GetEnhMetaFileHeader( hMetafile, sizeof(emh), &emh );
- ok( ret != 0, "GetEnhMetaFileHeader error %d\n", GetLastError() );
- ok( emh.dSignature == ENHMETA_SIGNATURE, "bad metafile signature %x\n", emh.dSignature );
- bits = HeapAlloc( GetProcessHeap(), 0, emh.nBytes );
- if(!bits)
- {
skip( "not enough memory for EMF bits\n" );
return;
- }
- ret = GetEnhMetaFileBits( hMetafile, emh.nBytes, bits );
- ok( ret != 0, "GetEnhMetaFileBits error %d\n", GetLastError() );
- for(i = 0; i < emh.nBytes; i++)
ok( bits[i] == 0xff, "unexpected EMF bits: got %02x, expected 0xff\n", bits[i] );
- EnumEnhMetaFile(0, hMetafile, test_BitBlt_record, (LPARAM)&i, NULL);
- ok( i == 2, "too many/not enough BitBlt records: got %d, expected 2\n", i );
+}
static void test_mf_SaveDC(void) { HDC hdcMetafile; -- 1.6.5.2
-- Vincent Povirk
-- Vincent Povirk
Thanks.
Chip
OK, try this one. It has the BitBlt(..., WHITENESS) call if(0)'d out, so the test doesn't crash. I also fixed the issue with the other BitBlt() failing on Wine (I used a memory DC).
I also put some tests that depend on the WHITENESS call succeeding into todo_wine blocks. Oddly enough, the check for the bits being all 1s succeeds on wine, even though it's not supposed to.
I also fixed the increment of the number of BitBlt() records in test_BitBlt_record(). Now instead of incrementing the pointer, it actually increments the count. (How could I have been so blind?)
This should work on Windows, too.
Chip
From 2d5aa7c607496c1b05a7a08adfee09db446754cb 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 | 83 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 83 insertions(+), 0 deletions(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index b559901..19401ed 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -665,6 +665,88 @@ static void test_SaveDC(void) DestroyWindow(hwnd); }
+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; + ok( emrbb->xDest == 0, "wrong xDest for BitBlt record: got %d, expected 0\n", emrbb->xDest ); + ok( emrbb->yDest == 0, "wrong yDest for BitBlt record: got %d, expected 0\n", emrbb->yDest ); + ok( emrbb->xSrc == 0, "wrong xSrc for BitBlt record: got %d, expected 0\n", emrbb->xSrc ); + ok( emrbb->ySrc == 0, "wrong ySrc for BitBlt record: got %d, expected 0\n", emrbb->ySrc ); + ok( emrbb->cxDest == GetSystemMetrics(SM_CXSCREEN), "wrong cxDest for BitBlt record: got %d\n", emrbb->cxDest ); + ok( emrbb->cyDest == GetSystemMetrics(SM_CYSCREEN), "wrong cyDest for BitBlt record: got %d\n", emrbb->cyDest ); + if(*pi == 1) /* First BitBlt */ + { + ok( emrbb->dwRop == SRCCOPY, "wrong ROP for BitBlt record: got %x, expected SRCCOPY\n", emrbb->dwRop ); + } + else + { + todo_wine ok( emrbb->dwRop == WHITENESS, "wrong ROP for BitBlt record: got %x, expected WHITENESS\n", emrbb->dwRop ); + } + return 1; +} + +static void test_emf_BitBlt(void) +{ + HDC hdcDisplay, hdcMetafile, hdcBitmap; + HBITMAP hBitmap, hOldBitmap; + HENHMETAFILE hMetafile; + ENHMETAHEADER emh; + BYTE *bits; + 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" ); + + ret = GetEnhMetaFileHeader( hMetafile, sizeof(emh), &emh ); + ok( ret != 0, "GetEnhMetaFileHeader failed\n" ); + ok( emh.dSignature == ENHMETA_SIGNATURE, "bad metafile signature %x\n", emh.dSignature ); + + bits = HeapAlloc( GetProcessHeap(), 0, emh.nBytes ); + if(!bits) + { + skip( "not enough memory for EMF bits\n" ); + return; + } + ret = GetEnhMetaFileBits( hMetafile, emh.nBytes, bits ); + ok( ret != 0, "GetEnhMetaFileBits error %d\n", GetLastError() ); + for(i = 0; i < emh.nBytes; i++) + todo_wine ok( bits[i] == 0xff, "unexpected EMF bits: got %02x, expected 0xff\n", bits[i] ); + + EnumEnhMetaFile(0, hMetafile, test_BitBlt_record, &i, NULL); + todo_wine ok( i == 2, "too many/not enough BitBlt records: got %d, expected 2\n", i ); + + SelectObject(hdcBitmap, hOldBitmap); + DeleteObject(hBitmap); + DeleteDC(hdcBitmap); +} + static void test_mf_SaveDC(void) { HDC hdcMetafile; @@ -2628,6 +2710,7 @@ START_TEST(metafile) /* For enhanced metafiles (enhmfdrv) */ test_ExtTextOut(); test_SaveDC(); + test_emf_BitBlt();
/* For win-format metafiles (mfdrv) */ test_mf_SaveDC();
Now on windows (with s/if(0)/if(1)/) I get lots of:
metafile.c:740: Test failed: unexpected EMF bits: got 01, expected 0xff
metafile.c:740: Test failed: unexpected EMF bits: got 00, expected 0xff
metafile.c:740: Test failed: unexpected EMF bits: got 00, expected 0xff
...
You, uh, do realize metafiles are a vector format, right? The data isn't really going to be all 1's.
If I comment out the for loop and initialize i to 1, the test succeeds on Windows.
Vincent Povirk wrote:
Now on windows (with s/if(0)/if(1)/) I get lots of:
metafile.c:740: Test failed: unexpected EMF bits: got 01, expected 0xff
metafile.c:740: Test failed: unexpected EMF bits: got 00, expected 0xff
metafile.c:740: Test failed: unexpected EMF bits: got 00, expected 0xff
...
You, uh, do realize metafiles are a vector format, right? The data isn't really going to be all 1's.
Right. I thought, though, that the GetEnhMetaFileBits() function would return the bits as they are drawn by playing the metafile. Silly me. It returns the raw bits in the metafile itself. (The use of the term "bits" confused me.) That test is going to go away then.
If I comment out the for loop and initialize i to 1, the test succeeds on Windows.
There's one test that succeeds if there are exactly two BitBlt() records in the metafile. The test_BitBlt_record() function just increments i (through a pointer) every time it encounters a BitBlt() record. What happens when i is initialized to 0?
Chip
On Tue, Nov 17, 2009 at 3:50 PM, Charles Davis cdavis@mymail.mines.edu wrote:
If I comment out the for loop and initialize i to 1, the test succeeds on Windows.
There's one test that succeeds if there are exactly two BitBlt() records in the metafile. The test_BitBlt_record() function just increments i (through a pointer) every time it encounters a BitBlt() record. What happens when i is initialized to 0?
Sorry, that was a typo. I really did initialize i to 0.
All right, this should be the last one. The tests pass on Wine, and should pass on Windows if you un-if(0) the call to BitBlt(..., WHITENESS). I still don't have any results for the many other Windows versions (95, 98, ME, NT4, 2000, Vista, Win7), so I'm going to wait for results from these other platforms before I send this to wine-patches.
Chip
From 2d5aa7c607496c1b05a7a08adfee09db446754cb 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 | 83 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 83 insertions(+), 0 deletions(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index b559901..19401ed 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -665,6 +665,88 @@ static void test_SaveDC(void) DestroyWindow(hwnd); }
+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; + ok( emrbb->xDest == 0, "wrong xDest for BitBlt record: got %d, expected 0\n", emrbb->xDest ); + ok( emrbb->yDest == 0, "wrong yDest for BitBlt record: got %d, expected 0\n", emrbb->yDest ); + ok( emrbb->xSrc == 0, "wrong xSrc for BitBlt record: got %d, expected 0\n", emrbb->xSrc ); + ok( emrbb->ySrc == 0, "wrong ySrc for BitBlt record: got %d, expected 0\n", emrbb->ySrc ); + ok( emrbb->cxDest == GetSystemMetrics(SM_CXSCREEN), "wrong cxDest for BitBlt record: got %d\n", emrbb->cxDest ); + ok( emrbb->cyDest == GetSystemMetrics(SM_CYSCREEN), "wrong cyDest for BitBlt record: got %d\n", emrbb->cyDest ); + if(*pi == 1) /* First BitBlt */ + { + ok( emrbb->dwRop == SRCCOPY, "wrong ROP for BitBlt record: got %x, expected SRCCOPY\n", emrbb->dwRop ); + } + else + { + todo_wine ok( emrbb->dwRop == WHITENESS, "wrong ROP for BitBlt record: got %x, expected WHITENESS\n", emrbb->dwRop ); + } + return 1; +} + +static void test_emf_BitBlt(void) +{ + HDC hdcDisplay, hdcMetafile, hdcBitmap; + HBITMAP hBitmap, hOldBitmap; + HENHMETAFILE hMetafile; + ENHMETAHEADER emh; + BYTE *bits; + 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" ); + + ret = GetEnhMetaFileHeader( hMetafile, sizeof(emh), &emh ); + ok( ret != 0, "GetEnhMetaFileHeader failed\n" ); + ok( emh.dSignature == ENHMETA_SIGNATURE, "bad metafile signature %x\n", emh.dSignature ); + + bits = HeapAlloc( GetProcessHeap(), 0, emh.nBytes ); + if(!bits) + { + skip( "not enough memory for EMF bits\n" ); + return; + } + ret = GetEnhMetaFileBits( hMetafile, emh.nBytes, bits ); + ok( ret != 0, "GetEnhMetaFileBits error %d\n", GetLastError() ); + for(i = 0; i < emh.nBytes; i++) + todo_wine ok( bits[i] == 0xff, "unexpected EMF bits: got %02x, expected 0xff\n", bits[i] ); + + EnumEnhMetaFile(0, hMetafile, test_BitBlt_record, &i, NULL); + todo_wine ok( i == 2, "too many/not enough BitBlt records: got %d, expected 2\n", i ); + + SelectObject(hdcBitmap, hOldBitmap); + DeleteObject(hBitmap); + DeleteDC(hdcBitmap); +} + static void test_mf_SaveDC(void) { HDC hdcMetafile; @@ -2628,6 +2710,7 @@ START_TEST(metafile) /* For enhanced metafiles (enhmfdrv) */ test_ExtTextOut(); test_SaveDC(); + test_emf_BitBlt();
/* For win-format metafiles (mfdrv) */ test_mf_SaveDC();
"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()?
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.
Chip
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();
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();
"Charles Davis" cdavis@mymail.mines.edu wrote:
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.
I fail to see an improvement.