[PATCH 3/4] gdi32: Make EMFDRV_StretchBlt() compatible with display drivers.

Zhiyi Zhang zzhang at codeweavers.com
Mon May 17 04:00:21 CDT 2021


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/gdi32/enhmfdrv/bitblt.c | 121 +++++------------------------------
 dlls/gdi32/tests/metafile.c  |  29 ++++-----
 2 files changed, 27 insertions(+), 123 deletions(-)

diff --git a/dlls/gdi32/enhmfdrv/bitblt.c b/dlls/gdi32/enhmfdrv/bitblt.c
index 597a6110abd..0fa6226ebaa 100644
--- a/dlls/gdi32/enhmfdrv/bitblt.c
+++ b/dlls/gdi32/enhmfdrv/bitblt.c
@@ -27,14 +27,15 @@
 #include "enhmetafiledrv.h"
 #include "wine/debug.h"
 
-BOOL CDECL EMFDRV_AlphaBlend( PHYSDEV dev_dst, struct bitblt_coords *dst,
-                              PHYSDEV dev_src, struct bitblt_coords *src, BLENDFUNCTION func )
+/* Generate an EMRSTRETCHBLT or EMRALPHABLEND record depending on the alpha_blend parameter */
+static BOOL emfdrv_stretchblt( PHYSDEV dev_dst, struct bitblt_coords *dst, PHYSDEV dev_src,
+                               struct bitblt_coords *src, DWORD rop, BOOL alpha_blend )
 {
     unsigned char src_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
     BITMAPINFO *src_info = (BITMAPINFO *)src_buffer;
     UINT bits_size, bmi_size, emr_size, size, bpp;
     struct gdi_image_bits bits;
-    EMRALPHABLEND *emr;
+    EMRSTRETCHBLT *emr;
     BITMAPINFO *bmi;
     DC *dc_src;
     DWORD err;
@@ -56,14 +57,15 @@ BOOL CDECL EMFDRV_AlphaBlend( PHYSDEV dev_dst, struct bitblt_coords *dst,
         bmi_size = sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD);
     else
         bmi_size = sizeof(BITMAPINFOHEADER);
-    emr_size = sizeof(EMRALPHABLEND);
+    /* EMRALPHABLEND and EMRSTRETCHBLT have the same structure */
+    emr_size = sizeof(EMRSTRETCHBLT);
     bits_size = src_info->bmiHeader.biSizeImage;
     size = emr_size + bmi_size + bits_size;
 
     emr = HeapAlloc(GetProcessHeap(), 0, size);
     if (!emr) goto err;
 
-    emr->emr.iType = EMR_ALPHABLEND;
+    emr->emr.iType = alpha_blend ? EMR_ALPHABLEND : EMR_STRETCHBLT;
     emr->emr.nSize = size;
     emr->rclBounds.left = dst->log_x;
     emr->rclBounds.top = dst->log_y;
@@ -77,7 +79,7 @@ BOOL CDECL EMFDRV_AlphaBlend( PHYSDEV dev_dst, struct bitblt_coords *dst,
     emr->ySrc = src->log_y;
     emr->cxSrc = src->log_width;
     emr->cySrc = src->log_height;
-    emr->dwRop = *(DWORD *)&func;
+    emr->dwRop = rop;
     GetTransform(dev_src->hdc, 0x204, &emr->xformSrc);
     emr->crBkColorSrc = GetBkColor(dev_src->hdc);
     emr->iUsageSrc = DIB_RGB_COLORS;
@@ -115,6 +117,12 @@ err:
     return ret;
 }
 
+BOOL CDECL EMFDRV_AlphaBlend( PHYSDEV dev_dst, struct bitblt_coords *dst,
+                              PHYSDEV dev_src, struct bitblt_coords *src, BLENDFUNCTION func )
+{
+    return emfdrv_stretchblt( dev_dst, dst, dev_src, src, *(DWORD *)&func, TRUE );
+}
+
 BOOL CDECL EMFDRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
 {
     EMRBITBLT emr;
@@ -155,106 +163,7 @@ BOOL CDECL EMFDRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
 BOOL CDECL EMFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
                               PHYSDEV devSrc, struct bitblt_coords *src, DWORD rop )
 {
-    BOOL ret;
-    PEMRBITBLT pEMR;
-    UINT emrSize;
-    UINT bmiSize;
-    UINT bitsSize;
-    UINT size;
-    BITMAP  BM;
-    WORD nBPP = 0;
-    LPBITMAPINFOHEADER lpBmiH;
-    HBITMAP hBitmap = NULL;
-    DWORD emrType;
-
-    if (devSrc->funcs == devDst->funcs) return FALSE;  /* can't use a metafile DC as source */
-
-    if (src->log_width == dst->log_width && src->log_height == dst->log_height)
-    {
-        emrType = EMR_BITBLT;
-        emrSize = sizeof(EMRBITBLT);
-    }
-    else
-    {
-        emrType = EMR_STRETCHBLT;
-        emrSize = sizeof(EMRSTRETCHBLT);
-    }
-
-    hBitmap = GetCurrentObject(devSrc->hdc, OBJ_BITMAP);
-
-    if(sizeof(BITMAP) != GetObjectW(hBitmap, sizeof(BITMAP), &BM))
-        return FALSE;
-
-    nBPP = BM.bmPlanes * BM.bmBitsPixel;
-    if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
-    bitsSize = get_dib_stride( BM.bmWidth, nBPP ) * BM.bmHeight;
-    bmiSize = sizeof(BITMAPINFOHEADER) +
-        (nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD);
-
-   size = emrSize + bmiSize + bitsSize;
-
-    pEMR = HeapAlloc(GetProcessHeap(), 0, size);
-    if (!pEMR) return FALSE;
-
-    /* Initialize EMR */
-    pEMR->emr.iType = emrType;
-    pEMR->emr.nSize = size;
-    pEMR->rclBounds.left = dst->log_x;
-    pEMR->rclBounds.top = dst->log_y;
-    pEMR->rclBounds.right = dst->log_x + dst->log_width - 1;
-    pEMR->rclBounds.bottom = dst->log_y + dst->log_height - 1;
-    pEMR->xDest = dst->log_x;
-    pEMR->yDest = dst->log_y;
-    pEMR->cxDest = dst->log_width;
-    pEMR->cyDest = dst->log_height;
-    pEMR->dwRop = rop;
-    pEMR->xSrc = src->log_x;
-    pEMR->ySrc = src->log_y;
-    GetTransform(devSrc->hdc, 0x204, &pEMR->xformSrc);
-    pEMR->crBkColorSrc = GetBkColor(devSrc->hdc);
-    pEMR->iUsageSrc = DIB_RGB_COLORS;
-    pEMR->offBmiSrc = emrSize;
-    pEMR->offBitsSrc = emrSize + bmiSize;
-    pEMR->cbBmiSrc = bmiSize;
-    pEMR->cbBitsSrc = bitsSize;
-    if (emrType == EMR_STRETCHBLT) 
-    {
-        PEMRSTRETCHBLT pEMRStretch = (PEMRSTRETCHBLT)pEMR;
-        pEMRStretch->cxSrc = src->log_width;
-        pEMRStretch->cySrc = src->log_height;
-    }
-
-    /* Initialize BITMAPINFO structure */
-    lpBmiH = (LPBITMAPINFOHEADER)((BYTE*)pEMR + pEMR->offBmiSrc);
-
-    lpBmiH->biSize = sizeof(BITMAPINFOHEADER);
-    lpBmiH->biWidth =  BM.bmWidth;
-    lpBmiH->biHeight = BM.bmHeight;
-    lpBmiH->biPlanes = BM.bmPlanes;
-    lpBmiH->biBitCount = nBPP;
-    /* Assume the bitmap isn't compressed and set the BI_RGB flag. */
-    lpBmiH->biCompression = BI_RGB;
-    lpBmiH->biSizeImage = bitsSize;
-    lpBmiH->biYPelsPerMeter = 0;
-    lpBmiH->biXPelsPerMeter = 0;
-    lpBmiH->biClrUsed   = nBPP <= 8 ? 1 << nBPP : 0;
-    /* Set biClrImportant to 0, indicating that all of the
-       device colors are important. */
-    lpBmiH->biClrImportant = 0;
-
-    /* Initialize bitmap bits */
-    if (GetDIBits(devSrc->hdc, hBitmap, 0, (UINT)lpBmiH->biHeight,
-                  (BYTE*)pEMR + pEMR->offBitsSrc,
-                  (LPBITMAPINFO)lpBmiH, DIB_RGB_COLORS))
-    {
-        ret = EMFDRV_WriteRecord(devDst, (EMR*)pEMR);
-        if (ret) EMFDRV_UpdateBBox(devDst, &(pEMR->rclBounds));
-    }
-    else
-        ret = FALSE;
-
-    HeapFree( GetProcessHeap(), 0, pEMR);
-    return ret;
+    return emfdrv_stretchblt( devDst, dst, devSrc, src, rop, FALSE );
 }
 
 INT CDECL EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 0e35e02b8da..0ac7f366ae6 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -2829,26 +2829,25 @@ static void test_emf_StretchBlt(void)
         DWORD used_color_count;
         DWORD color_count;
         RGBQUAD colors[3];
-        BOOL todo;
     }
     tests[] =
     {
         {1, 3, 3, BI_RGB, EMF_STRETCHBLT_1BIT_3X3, sizeof(EMF_STRETCHBLT_1BIT_3X3), 1, 1, {{0xff, 0xff, 0xff}}},
         {4, 3, 3, BI_RGB, EMF_STRETCHBLT_4BIT_3X3, sizeof(EMF_STRETCHBLT_4BIT_3X3), 1, 1, {{0xff, 0xff, 0xff}}},
         {8, 3, 3, BI_RGB, EMF_STRETCHBLT_8BIT_3X3, sizeof(EMF_STRETCHBLT_8BIT_3X3), 1, 1, {{0xff, 0xff, 0xff}}},
-        {16, 3, 3, BI_RGB, EMF_STRETCHBLT_16BIT_555_3X3, sizeof(EMF_STRETCHBLT_16BIT_555_3X3), 0, 0, {{0}}, TRUE},
+        {16, 3, 3, BI_RGB, EMF_STRETCHBLT_16BIT_555_3X3, sizeof(EMF_STRETCHBLT_16BIT_555_3X3)},
         {24, 3, 3, BI_RGB, EMF_STRETCHBLT_24BIT_3X3, sizeof(EMF_STRETCHBLT_24BIT_3X3)},
-        {32, 3, 3, BI_RGB, EMF_STRETCHBLT_32BIT_888_3X3, sizeof(EMF_STRETCHBLT_32BIT_888_3X3), 0, 0, {{0}}, TRUE},
-        {16, 3, 3, BI_BITFIELDS, EMF_STRETCHBLT_16BIT_3X3, sizeof(EMF_STRETCHBLT_16BIT_3X3), 0, 3, {{0x00, 0xf8, 0x00}, {0xe0, 0x07, 0x00}, {0x1f, 0x00, 0x00}}, TRUE},
-        {32, 3, 3, BI_BITFIELDS, EMF_STRETCHBLT_32BIT_3X3, sizeof(EMF_STRETCHBLT_32BIT_3X3), 0, 3, {{0x00, 0x00, 0xff}, {0xe0, 0xff, 0x00}, {0xff, 0x00, 0x00}}, TRUE},
-        {1, 4, 4, BI_RGB, EMF_STRETCHBLT_1BIT_4X4, sizeof(EMF_STRETCHBLT_1BIT_4X4), 1, 1, {{0xff, 0xff, 0xff}}, TRUE},
-        {4, 4, 4, BI_RGB, EMF_STRETCHBLT_4BIT_4X4, sizeof(EMF_STRETCHBLT_4BIT_4X4), 1, 1, {{0xff, 0xff, 0xff}}, TRUE},
-        {8, 4, 4, BI_RGB, EMF_STRETCHBLT_8BIT_4X4, sizeof(EMF_STRETCHBLT_8BIT_4X4), 1, 1, {{0xff, 0xff, 0xff}}, TRUE},
-        {16, 4, 4, BI_RGB, EMF_STRETCHBLT_16BIT_555_4X4, sizeof(EMF_STRETCHBLT_16BIT_555_4X4), 0, 0, {{0}}, TRUE},
-        {24, 4, 4, BI_RGB, EMF_STRETCHBLT_24BIT_4X4, sizeof(EMF_STRETCHBLT_24BIT_4X4), 0, 0, {{0}}, TRUE},
-        {32, 4, 4, BI_RGB, EMF_STRETCHBLT_32BIT_888_4X4, sizeof(EMF_STRETCHBLT_32BIT_888_4X4), 0, 0, {{0}}, TRUE},
-        {16, 4, 4, BI_BITFIELDS, EMF_STRETCHBLT_16BIT_4X4, sizeof(EMF_STRETCHBLT_16BIT_4X4), 0, 3, {{0x00, 0xf8, 0x00}, {0xe0, 0x07, 0x00}, {0x1f, 0x00, 0x00}}, TRUE},
-        {32, 4, 4, BI_BITFIELDS, EMF_STRETCHBLT_32BIT_4X4, sizeof(EMF_STRETCHBLT_32BIT_4X4), 0, 3, {{0x00, 0x00, 0xff}, {0xe0, 0xff, 0x00}, {0xff, 0x00, 0x00}}, TRUE},
+        {32, 3, 3, BI_RGB, EMF_STRETCHBLT_32BIT_888_3X3, sizeof(EMF_STRETCHBLT_32BIT_888_3X3)},
+        {16, 3, 3, BI_BITFIELDS, EMF_STRETCHBLT_16BIT_3X3, sizeof(EMF_STRETCHBLT_16BIT_3X3), 0, 3, {{0x00, 0xf8, 0x00}, {0xe0, 0x07, 0x00}, {0x1f, 0x00, 0x00}}},
+        {32, 3, 3, BI_BITFIELDS, EMF_STRETCHBLT_32BIT_3X3, sizeof(EMF_STRETCHBLT_32BIT_3X3), 0, 3, {{0x00, 0x00, 0xff}, {0xe0, 0xff, 0x00}, {0xff, 0x00, 0x00}}},
+        {1, 4, 4, BI_RGB, EMF_STRETCHBLT_1BIT_4X4, sizeof(EMF_STRETCHBLT_1BIT_4X4), 1, 1, {{0xff, 0xff, 0xff}}},
+        {4, 4, 4, BI_RGB, EMF_STRETCHBLT_4BIT_4X4, sizeof(EMF_STRETCHBLT_4BIT_4X4), 1, 1, {{0xff, 0xff, 0xff}}},
+        {8, 4, 4, BI_RGB, EMF_STRETCHBLT_8BIT_4X4, sizeof(EMF_STRETCHBLT_8BIT_4X4), 1, 1, {{0xff, 0xff, 0xff}}},
+        {16, 4, 4, BI_RGB, EMF_STRETCHBLT_16BIT_555_4X4, sizeof(EMF_STRETCHBLT_16BIT_555_4X4)},
+        {24, 4, 4, BI_RGB, EMF_STRETCHBLT_24BIT_4X4, sizeof(EMF_STRETCHBLT_24BIT_4X4)},
+        {32, 4, 4, BI_RGB, EMF_STRETCHBLT_32BIT_888_4X4, sizeof(EMF_STRETCHBLT_32BIT_888_4X4)},
+        {16, 4, 4, BI_BITFIELDS, EMF_STRETCHBLT_16BIT_4X4, sizeof(EMF_STRETCHBLT_16BIT_4X4), 0, 3, {{0x00, 0xf8, 0x00}, {0xe0, 0x07, 0x00}, {0x1f, 0x00, 0x00}}},
+        {32, 4, 4, BI_BITFIELDS, EMF_STRETCHBLT_32BIT_4X4, sizeof(EMF_STRETCHBLT_32BIT_4X4), 0, 3, {{0x00, 0x00, 0xff}, {0xe0, 0xff, 0x00}, {0xff, 0x00, 0x00}}},
     };
 
     hdc = GetDC(0);
@@ -2872,10 +2871,6 @@ static void test_emf_StretchBlt(void)
     /* Test StretchBlt with different format of bitmaps */
     for (test_idx = 0; test_idx < ARRAY_SIZE(tests); ++test_idx)
     {
-        /* Don't run tests failing on Wine */
-        if (tests[test_idx].todo && !strcmp(winetest_platform, "wine"))
-            continue;
-
         winetest_push_context("Test %d", test_idx);
 
         memset(bmi_buffer, 0, sizeof(bmi_buffer));
-- 
2.30.2




More information about the wine-devel mailing list