From 953a2190048e56866be5dc7af3711635ed7b9e08 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 10 Sep 2021 14:27:39 +0200 Subject: [PATCH] gdi32: Use EMR_TRANSPARENTBLT to record GetTransparentBlt. And use NtGdiTransparentBlt. Signed-off-by: Jacek Caban Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- 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 );