[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