Jacek Caban : gdi32: Use EMR_TRANSPARENTBLT to record GetTransparentBlt.

Alexandre Julliard julliard at winehq.org
Fri Sep 10 15:29:45 CDT 2021


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Sep 10 14:27:39 2021 +0200

gdi32: Use EMR_TRANSPARENTBLT to record GetTransparentBlt.

And use NtGdiTransparentBlt.

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/bitblt.c      | 44 +++++++++++++++++++++++++-------------------
 dlls/gdi32/emfdc.c       | 11 ++++++++++-
 dlls/gdi32/gdi_private.h |  3 +++
 dlls/gdi32/gdidc.c       | 17 +++++++++++++++++
 include/ntgdi.h          |  3 +++
 5 files changed, 58 insertions(+), 20 deletions(-)

diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c
index 33ce6966f87..cff84bc1dce 100644
--- a/dlls/gdi32/bitblt.c
+++ b/dlls/gdi32/bitblt.c
@@ -835,11 +835,11 @@ BOOL WINAPI NtGdiMaskBlt( HDC hdcDest, INT nXDest, INT nYDest, INT nWidth, INT n
 }
 
 /******************************************************************************
- *           GdiTransparentBlt [GDI32.@]
+ *           NtGdiTransparentBlt    (win32u.@)
  */
-BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest, int heightDest,
-                            HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc,
-                            UINT crTransparent )
+BOOL WINAPI NtGdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest, int heightDest,
+                                 HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc,
+                                 UINT crTransparent )
 {
     BOOL ret = FALSE;
     HDC hdcWork;
@@ -858,8 +858,8 @@ BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest,
         return FALSE;
     }
 
-    oldBackground = SetBkColor(hdcDest, RGB(255,255,255));
-    oldForeground = SetTextColor(hdcDest, RGB(0,0,0));
+    NtGdiGetAndSetDCDword( hdcDest, NtGdiSetBkColor, RGB(255,255,255), &oldBackground );
+    NtGdiGetAndSetDCDword( hdcDest, NtGdiSetTextColor, RGB(0,0,0), &oldForeground );
 
     /* Stretch bitmap */
     oldStretchMode = GetStretchBltMode(hdcSrc);
@@ -867,9 +867,9 @@ BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest,
         SetStretchBltMode(hdcSrc, COLORONCOLOR);
     hdcWork = NtGdiCreateCompatibleDC( hdcDest );
     if ((GetObjectType( hdcDest ) != OBJ_MEMDC ||
-         GetObjectW( NtGdiGetDCObject( hdcDest, NTGDI_OBJ_SURF ),
-                     sizeof(dib), &dib ) == sizeof(BITMAP)) &&
-        GetDeviceCaps( hdcDest, BITSPIXEL ) == 32)
+         NtGdiExtGetObjectW( NtGdiGetDCObject( hdcDest, NTGDI_OBJ_SURF ),
+                             sizeof(dib), &dib ) == sizeof(BITMAP)) &&
+        NtGdiGetDeviceCaps( hdcDest, BITSPIXEL ) == 32)
     {
         /* screen DCs or DDBs are not supposed to have an alpha channel, so use a 24-bpp bitmap as copy */
         BITMAPINFO info;
@@ -883,37 +883,43 @@ BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest,
     }
     else bmpWork = NtGdiCreateCompatibleBitmap( hdcDest, widthDest, heightDest );
     oldWork = NtGdiSelectBitmap(hdcWork, bmpWork);
-    if(!StretchBlt(hdcWork, 0, 0, widthDest, heightDest, hdcSrc, xSrc, ySrc, widthSrc, heightSrc, SRCCOPY)) {
+    if (!NtGdiStretchBlt( hdcWork, 0, 0, widthDest, heightDest, hdcSrc, xSrc, ySrc,
+                          widthSrc, heightSrc, SRCCOPY, 0 ))
+    {
         TRACE("Failed to stretch\n");
         goto error;
     }
-    SetBkColor(hdcWork, crTransparent);
+    NtGdiGetAndSetDCDword( hdcWork, NtGdiSetBkColor, crTransparent, NULL );
 
     /* Create mask */
     hdcMask = NtGdiCreateCompatibleDC( hdcDest );
     bmpMask = NtGdiCreateCompatibleBitmap( hdcMask, widthDest, heightDest );
     oldMask = NtGdiSelectBitmap(hdcMask, bmpMask);
-    if(!BitBlt(hdcMask, 0, 0, widthDest, heightDest, hdcWork, 0, 0, SRCCOPY)) {
+    if (!NtGdiBitBlt( hdcMask, 0, 0, widthDest, heightDest, hdcWork, 0, 0, SRCCOPY, 0, 0 ))
+    {
         TRACE("Failed to create mask\n");
         goto error;
     }
 
     /* Replace transparent color with black */
-    SetBkColor(hdcWork, RGB(0,0,0));
-    SetTextColor(hdcWork, RGB(255,255,255));
-    if(!BitBlt(hdcWork, 0, 0, widthDest, heightDest, hdcMask, 0, 0, SRCAND)) {
+    NtGdiGetAndSetDCDword( hdcWork, NtGdiSetBkColor, RGB(0,0,0), NULL );
+    NtGdiGetAndSetDCDword( hdcWork, NtGdiSetTextColor, RGB(255,255,255), NULL );
+    if (!NtGdiBitBlt( hdcWork, 0, 0, widthDest, heightDest, hdcMask, 0, 0, SRCAND, 0, 0 ))
+    {
         TRACE("Failed to mask out background\n");
         goto error;
     }
 
     /* Replace non-transparent area on destination with black */
-    if(!BitBlt(hdcDest, xDest, yDest, widthDest, heightDest, hdcMask, 0, 0, SRCAND)) {
+    if (!NtGdiBitBlt( hdcDest, xDest, yDest, widthDest, heightDest, hdcMask, 0, 0, SRCAND, 0, 0 ))
+    {
         TRACE("Failed to clear destination area\n");
         goto error;
     }
 
     /* Draw the image */
-    if(!BitBlt(hdcDest, xDest, yDest, widthDest, heightDest, hdcWork, 0, 0, SRCPAINT)) {
+    if (!NtGdiBitBlt( hdcDest, xDest, yDest, widthDest, heightDest, hdcWork, 0, 0, SRCPAINT, 0, 0 ))
+    {
         TRACE("Failed to paint image\n");
         goto error;
     }
@@ -921,8 +927,8 @@ BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest,
     ret = TRUE;
 error:
     SetStretchBltMode(hdcSrc, oldStretchMode);
-    SetBkColor(hdcDest, oldBackground);
-    SetTextColor(hdcDest, oldForeground);
+    NtGdiGetAndSetDCDword( hdcDest, NtGdiSetBkColor, oldBackground, NULL );
+    NtGdiGetAndSetDCDword( hdcDest, NtGdiSetTextColor, oldForeground, NULL );
     if(hdcWork) {
         NtGdiSelectBitmap(hdcWork, oldWork);
         NtGdiDeleteObjectApp( hdcWork );
diff --git a/dlls/gdi32/emfdc.c b/dlls/gdi32/emfdc.c
index 79220a5e1e0..a1c7eb74fd5 100644
--- a/dlls/gdi32/emfdc.c
+++ b/dlls/gdi32/emfdc.c
@@ -1287,7 +1287,7 @@ static BOOL emfdrv_stretchblt( struct emf *emf, INT x_dst, INT y_dst, INT width_
     emr->cyDest = height_dst;
     emr->xSrc = x_src;
     emr->ySrc = y_src;
-    if (type == EMR_STRETCHBLT || type == EMR_ALPHABLEND)
+    if (type != EMR_BITBLT)
     {
         EMRSTRETCHBLT *emr_stretchblt = (EMRSTRETCHBLT *)emr;
         emr_stretchblt->cxSrc = width_src;
@@ -1388,6 +1388,15 @@ BOOL EMFDC_StretchBlt( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT width_dst, IN
                               height_src, rop, EMR_STRETCHBLT );
 }
 
+BOOL EMFDC_TransparentBlt( DC_ATTR *dc_attr, 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,
+                           UINT color )
+{
+    return emfdrv_stretchblt( dc_attr->emf, x_dst, y_dst, width_dst, height_dst,
+                              hdc_src, x_src, y_src, width_src,
+                              height_src, color, EMR_TRANSPARENTBLT );
+}
+
 BOOL EMFDC_MaskBlt( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
                     HDC hdc_src, INT x_src, INT y_src, HBITMAP mask,
                     INT x_mask, INT y_mask, DWORD rop )
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index efadf3a7c82..238ae3b7de1 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -271,6 +271,9 @@ extern BOOL EMFDC_StretchDIBits( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT wid
                                  UINT coloruse, DWORD rop ) DECLSPEC_HIDDEN;
 extern BOOL EMFDC_StrokeAndFillPath( DC_ATTR *dc_attr ) DECLSPEC_HIDDEN;
 extern BOOL EMFDC_StrokePath( DC_ATTR *dc_attr ) DECLSPEC_HIDDEN;
+extern BOOL EMFDC_TransparentBlt( DC_ATTR *dc_attr, 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, UINT color ) DECLSPEC_HIDDEN;
 extern BOOL EMFDC_WidenPath( DC_ATTR *dc_attr ) DECLSPEC_HIDDEN;
 
 extern HENHMETAFILE EMF_Create_HENHMETAFILE( ENHMETAHEADER *emh, DWORD filesize,
diff --git a/dlls/gdi32/gdidc.c b/dlls/gdi32/gdidc.c
index 61b318ce067..b2e673fe581 100644
--- a/dlls/gdi32/gdidc.c
+++ b/dlls/gdi32/gdidc.c
@@ -1532,6 +1532,23 @@ BOOL WINAPI PlgBlt( HDC hdc, const POINT *points, HDC hdc_src, INT x_src, INT y_
                         mask, x_mask, y_mask, 0 /* FIXME */ );
 }
 
+/******************************************************************************
+ *           GdiTransparentBlt    (GDI32.@)
+ */
+BOOL WINAPI GdiTransparentBlt( 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,
+                               UINT color )
+{
+    DC_ATTR *dc_attr;
+
+    if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
+    if (dc_attr->emf && !EMFDC_TransparentBlt( dc_attr, x_dst, y_dst, width_dst, height_dst, hdc_src,
+                                               x_src, y_src, width_src, height_src, color ))
+        return FALSE;
+    return NtGdiTransparentBlt( hdc, x_dst, y_dst, width_dst, height_dst, hdc_src, x_src, y_src,
+                                width_src, height_src, color );
+}
+
 /******************************************************************************
  *           GdiAlphaBlend   (GDI32.@)
  */
diff --git a/include/ntgdi.h b/include/ntgdi.h
index 44a27878792..4ee02942346 100644
--- a/include/ntgdi.h
+++ b/include/ntgdi.h
@@ -417,6 +417,9 @@ INT      WINAPI NtGdiStretchDIBitsInternal( HDC hdc, INT x_dst, INT y_dst, INT w
                                             HANDLE xform );
 BOOL     WINAPI NtGdiStrokePath( HDC hdc );
 BOOL     WINAPI NtGdiStrokeAndFillPath( HDC hdc );
+BOOL     WINAPI NtGdiTransparentBlt( 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,
+                                     UINT color );
 BOOL     WINAPI NtGdiTransformPoints( HDC hdc, const POINT *points_in, POINT *points_out,
                                       INT count, UINT mode );
 BOOL     WINAPI NtGdiUnrealizeObject( HGDIOBJ obj );




More information about the wine-cvs mailing list