Jacek Caban : gdi32: Use GetDIBits instead of GetObject in MFDRV_StretchBlt.

Alexandre Julliard julliard at winehq.org
Thu Aug 12 16:35:20 CDT 2021


Module: wine
Branch: master
Commit: 7f9d847b9bcc21fc03fdd6beb2cb3285c2285b2b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=7f9d847b9bcc21fc03fdd6beb2cb3285c2285b2b

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Aug 12 12:00:05 2021 +0200

gdi32: Use GetDIBits instead of GetObject in MFDRV_StretchBlt.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/mfdrv/bitblt.c | 130 +++++++++++++++++++---------------------------
 1 file changed, 52 insertions(+), 78 deletions(-)

diff --git a/dlls/gdi32/mfdrv/bitblt.c b/dlls/gdi32/mfdrv/bitblt.c
index a08d6ef6608..a3ebd2feadd 100644
--- a/dlls/gdi32/mfdrv/bitblt.c
+++ b/dlls/gdi32/mfdrv/bitblt.c
@@ -35,96 +35,70 @@ BOOL METADC_PatBlt( HDC hdc, INT left, INT top, INT width, INT height, DWORD rop
 }
 
 
-/***********************************************************************
- *           MFDRV_StretchBlt
- * this function contains TWO ways for processing StretchBlt in metafiles,
- * decide between rdFunction values  META_STRETCHBLT or META_DIBSTRETCHBLT
- * via #define STRETCH_VIA_DIB
- */
-#define STRETCH_VIA_DIB
-
-BOOL CDECL MFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
-                             PHYSDEV devSrc, struct bitblt_coords *src, DWORD rop )
+static BOOL metadc_stretchblt( HDC hdc, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
+                               HDC hdc_src, INT x_src, INT y_src, INT width_src, INT height_src,
+                               DWORD rop )
 {
-    BOOL ret;
-    DWORD len;
+    BITMAPINFO src_info = {{ sizeof( src_info.bmiHeader ) }};
+    UINT bmi_size, size, bpp;
+    BITMAPINFO *bmi;
     METARECORD *mr;
-    BITMAP BM;
-#ifdef STRETCH_VIA_DIB
-    LPBITMAPINFOHEADER lpBMI;
-    WORD nBPP;
-#endif
-    HBITMAP hBitmap = GetCurrentObject(devSrc->hdc, OBJ_BITMAP);
+    HBITMAP bitmap;
+    BOOL ret;
 
-    if (devSrc->funcs == devDst->funcs) return FALSE;  /* can't use a metafile DC as source */
+    if (!(bitmap = GetCurrentObject( hdc_src, OBJ_BITMAP ))) return FALSE;
+    if (!GetDIBits( hdc_src, bitmap, 0, INT_MAX, NULL, &src_info, DIB_RGB_COLORS )) return FALSE;
 
-    if (GetObjectW(hBitmap, sizeof(BITMAP), &BM) != sizeof(BITMAP))
-    {
-        WARN("bad bitmap object %p passed for hdc %p\n", hBitmap, devSrc->hdc);
-        return FALSE;
-    }
-#ifdef STRETCH_VIA_DIB
-    nBPP = BM.bmPlanes * BM.bmBitsPixel;
-    if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
-    len = sizeof(METARECORD) + 10 * sizeof(INT16)
-            + sizeof(BITMAPINFOHEADER) + (nBPP <= 8 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
-              + get_dib_stride( BM.bmWidth, nBPP ) * BM.bmHeight;
-    if (!(mr = HeapAlloc( GetProcessHeap(), 0, len)))
-	return FALSE;
+    bpp = src_info.bmiHeader.biBitCount;
+    if (bpp <= 8)
+        bmi_size = sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD);
+    else if (bpp == 16 || bpp == 32)
+        bmi_size = sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD);
+    else
+        bmi_size = sizeof(BITMAPINFOHEADER);
+
+    size = FIELD_OFFSET( METARECORD, rdParm[10] ) + bmi_size +
+        src_info.bmiHeader.biSizeImage;
+    if (!(mr = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
     mr->rdFunction = META_DIBSTRETCHBLT;
-    lpBMI=(LPBITMAPINFOHEADER)(mr->rdParm+10);
-    lpBMI->biSize      = sizeof(BITMAPINFOHEADER);
-    lpBMI->biWidth     = BM.bmWidth;
-    lpBMI->biHeight    = BM.bmHeight;
-    lpBMI->biPlanes    = 1;
-    lpBMI->biBitCount  = nBPP;
-    lpBMI->biSizeImage = get_dib_image_size( (BITMAPINFO *)lpBMI );
-    lpBMI->biClrUsed   = nBPP <= 8 ? 1 << nBPP : 0;
-    lpBMI->biCompression = BI_RGB;
-    lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(devSrc->hdc,LOGPIXELSX),3937,100);
-    lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(devSrc->hdc,LOGPIXELSY),3937,100);
-    lpBMI->biClrImportant  = 0;                          /* 1 meter  = 39.37 inch */
-
-    TRACE("MF_StretchBltViaDIB->len = %d  rop=%x  PixYPM=%d Caps=%d\n",
-	  len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(devSrc->hdc, LOGPIXELSY));
-
-    if (GetDIBits(devSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight,
-                  (LPSTR)lpBMI + get_dib_info_size( (BITMAPINFO *)lpBMI, DIB_RGB_COLORS ),
-                  (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
-#else
-    len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
-    if (!(mr = HeapAlloc( GetProcessHeap(), 0, len )))
-	return FALSE;
-    mr->rdFunction = META_STRETCHBLT;
-    *(mr->rdParm +10) = BM.bmWidth;
-    *(mr->rdParm +11) = BM.bmHeight;
-    *(mr->rdParm +12) = BM.bmWidthBytes;
-    *(mr->rdParm +13) = BM.bmPlanes;
-    *(mr->rdParm +14) = BM.bmBitsPixel;
-    TRACE("len = %ld  rop=%lx\n", len, rop);
-    if (GetBitmapBits( hBitmap, BM.bmWidthBytes * BM.bmHeight, mr->rdParm + 15))
-#endif
+    bmi = (BITMAPINFO *)&mr->rdParm[10];
+    bmi->bmiHeader = src_info.bmiHeader;
+    TRACE( "size = %u  rop=%x\n", size, rop );
+
+    ret = GetDIBits( hdc_src, bitmap, 0, src_info.bmiHeader.biHeight, (BYTE *)bmi + bmi_size,
+                     bmi, DIB_RGB_COLORS );
+    if (ret)
     {
-      mr->rdSize = len / sizeof(INT16);
-      *(mr->rdParm) = LOWORD(rop);
-      *(mr->rdParm + 1) = HIWORD(rop);
-      *(mr->rdParm + 2) = src->log_height;
-      *(mr->rdParm + 3) = src->log_width;
-      *(mr->rdParm + 4) = src->log_y;
-      *(mr->rdParm + 5) = src->log_x;
-      *(mr->rdParm + 6) = dst->log_height;
-      *(mr->rdParm + 7) = dst->log_width;
-      *(mr->rdParm + 8) = dst->log_y;
-      *(mr->rdParm + 9) = dst->log_x;
-      ret = MFDRV_WriteRecord( devDst, mr, mr->rdSize * 2);
+        mr->rdSize = size / sizeof(WORD);
+        mr->rdParm[0] = LOWORD(rop);
+        mr->rdParm[1] = HIWORD(rop);
+        mr->rdParm[2] = height_src;
+        mr->rdParm[3] = width_src;
+        mr->rdParm[4] = y_src;
+        mr->rdParm[5] = x_src;
+        mr->rdParm[6] = height_dst;
+        mr->rdParm[7] = width_dst;
+        mr->rdParm[8] = y_dst;
+        mr->rdParm[9] = x_dst;
+        ret = metadc_record( hdc, mr, size );
     }
-    else
-        ret = FALSE;
+
     HeapFree( GetProcessHeap(), 0, mr);
     return ret;
 }
 
 
+/***********************************************************************
+ *           MFDRV_StretchBlt
+ */
+BOOL CDECL MFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
+                             PHYSDEV devSrc, struct bitblt_coords *src, DWORD rop )
+{
+    return metadc_stretchblt( devDst->hdc, dst->log_x, dst->log_y, dst->log_width, dst->log_height,
+                              devSrc->hdc, src->log_x, src->log_y, src->log_width, src->log_height,
+                              rop );
+}
+
 /***********************************************************************
  *           MFDRV_StretchDIBits
  */




More information about the wine-cvs mailing list