[PATCH] gdi32/tests: Test BitBlt() to a metafile.
Charles Davis
cdavis at mymail.mines.edu
Tue Nov 17 12:10:50 CST 2009
---
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();
--
1.6.5.2
--------------050001040400090909040703--
More information about the wine-devel
mailing list