gdi32: Use EMR_TRANSPARENTBLT to record GetTransparentBlt.

And use NtGdiTransparentBlt.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-09-10 14:27:39 +02:00 committed by Alexandre Julliard
parent 7b8a9db513
commit 953a219004
5 changed files with 58 additions and 20 deletions

View file

@ -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, BOOL WINAPI NtGdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest, int heightDest,
HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc,
UINT crTransparent ) UINT crTransparent )
{ {
BOOL ret = FALSE; BOOL ret = FALSE;
HDC hdcWork; HDC hdcWork;
@ -858,8 +858,8 @@ BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest,
return FALSE; return FALSE;
} }
oldBackground = SetBkColor(hdcDest, RGB(255,255,255)); NtGdiGetAndSetDCDword( hdcDest, NtGdiSetBkColor, RGB(255,255,255), &oldBackground );
oldForeground = SetTextColor(hdcDest, RGB(0,0,0)); NtGdiGetAndSetDCDword( hdcDest, NtGdiSetTextColor, RGB(0,0,0), &oldForeground );
/* Stretch bitmap */ /* Stretch bitmap */
oldStretchMode = GetStretchBltMode(hdcSrc); oldStretchMode = GetStretchBltMode(hdcSrc);
@ -867,9 +867,9 @@ BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest,
SetStretchBltMode(hdcSrc, COLORONCOLOR); SetStretchBltMode(hdcSrc, COLORONCOLOR);
hdcWork = NtGdiCreateCompatibleDC( hdcDest ); hdcWork = NtGdiCreateCompatibleDC( hdcDest );
if ((GetObjectType( hdcDest ) != OBJ_MEMDC || if ((GetObjectType( hdcDest ) != OBJ_MEMDC ||
GetObjectW( NtGdiGetDCObject( hdcDest, NTGDI_OBJ_SURF ), NtGdiExtGetObjectW( NtGdiGetDCObject( hdcDest, NTGDI_OBJ_SURF ),
sizeof(dib), &dib ) == sizeof(BITMAP)) && sizeof(dib), &dib ) == sizeof(BITMAP)) &&
GetDeviceCaps( hdcDest, BITSPIXEL ) == 32) NtGdiGetDeviceCaps( hdcDest, BITSPIXEL ) == 32)
{ {
/* screen DCs or DDBs are not supposed to have an alpha channel, so use a 24-bpp bitmap as copy */ /* screen DCs or DDBs are not supposed to have an alpha channel, so use a 24-bpp bitmap as copy */
BITMAPINFO info; BITMAPINFO info;
@ -883,37 +883,43 @@ BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest,
} }
else bmpWork = NtGdiCreateCompatibleBitmap( hdcDest, widthDest, heightDest ); else bmpWork = NtGdiCreateCompatibleBitmap( hdcDest, widthDest, heightDest );
oldWork = NtGdiSelectBitmap(hdcWork, bmpWork); 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"); TRACE("Failed to stretch\n");
goto error; goto error;
} }
SetBkColor(hdcWork, crTransparent); NtGdiGetAndSetDCDword( hdcWork, NtGdiSetBkColor, crTransparent, NULL );
/* Create mask */ /* Create mask */
hdcMask = NtGdiCreateCompatibleDC( hdcDest ); hdcMask = NtGdiCreateCompatibleDC( hdcDest );
bmpMask = NtGdiCreateCompatibleBitmap( hdcMask, widthDest, heightDest ); bmpMask = NtGdiCreateCompatibleBitmap( hdcMask, widthDest, heightDest );
oldMask = NtGdiSelectBitmap(hdcMask, bmpMask); 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"); TRACE("Failed to create mask\n");
goto error; goto error;
} }
/* Replace transparent color with black */ /* Replace transparent color with black */
SetBkColor(hdcWork, RGB(0,0,0)); NtGdiGetAndSetDCDword( hdcWork, NtGdiSetBkColor, RGB(0,0,0), NULL );
SetTextColor(hdcWork, RGB(255,255,255)); NtGdiGetAndSetDCDword( hdcWork, NtGdiSetTextColor, RGB(255,255,255), NULL );
if(!BitBlt(hdcWork, 0, 0, widthDest, heightDest, hdcMask, 0, 0, SRCAND)) { if (!NtGdiBitBlt( hdcWork, 0, 0, widthDest, heightDest, hdcMask, 0, 0, SRCAND, 0, 0 ))
{
TRACE("Failed to mask out background\n"); TRACE("Failed to mask out background\n");
goto error; goto error;
} }
/* Replace non-transparent area on destination with black */ /* 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"); TRACE("Failed to clear destination area\n");
goto error; goto error;
} }
/* Draw the image */ /* 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"); TRACE("Failed to paint image\n");
goto error; goto error;
} }
@ -921,8 +927,8 @@ BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest,
ret = TRUE; ret = TRUE;
error: error:
SetStretchBltMode(hdcSrc, oldStretchMode); SetStretchBltMode(hdcSrc, oldStretchMode);
SetBkColor(hdcDest, oldBackground); NtGdiGetAndSetDCDword( hdcDest, NtGdiSetBkColor, oldBackground, NULL );
SetTextColor(hdcDest, oldForeground); NtGdiGetAndSetDCDword( hdcDest, NtGdiSetTextColor, oldForeground, NULL );
if(hdcWork) { if(hdcWork) {
NtGdiSelectBitmap(hdcWork, oldWork); NtGdiSelectBitmap(hdcWork, oldWork);
NtGdiDeleteObjectApp( hdcWork ); NtGdiDeleteObjectApp( hdcWork );

View file

@ -1287,7 +1287,7 @@ static BOOL emfdrv_stretchblt( struct emf *emf, INT x_dst, INT y_dst, INT width_
emr->cyDest = height_dst; emr->cyDest = height_dst;
emr->xSrc = x_src; emr->xSrc = x_src;
emr->ySrc = y_src; emr->ySrc = y_src;
if (type == EMR_STRETCHBLT || type == EMR_ALPHABLEND) if (type != EMR_BITBLT)
{ {
EMRSTRETCHBLT *emr_stretchblt = (EMRSTRETCHBLT *)emr; EMRSTRETCHBLT *emr_stretchblt = (EMRSTRETCHBLT *)emr;
emr_stretchblt->cxSrc = width_src; 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 ); 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, 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, HDC hdc_src, INT x_src, INT y_src, HBITMAP mask,
INT x_mask, INT y_mask, DWORD rop ) INT x_mask, INT y_mask, DWORD rop )

View file

@ -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; UINT coloruse, DWORD rop ) DECLSPEC_HIDDEN;
extern BOOL EMFDC_StrokeAndFillPath( DC_ATTR *dc_attr ) 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_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 BOOL EMFDC_WidenPath( DC_ATTR *dc_attr ) DECLSPEC_HIDDEN;
extern HENHMETAFILE EMF_Create_HENHMETAFILE( ENHMETAHEADER *emh, DWORD filesize, extern HENHMETAFILE EMF_Create_HENHMETAFILE( ENHMETAHEADER *emh, DWORD filesize,

View file

@ -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 */ ); 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.@) * GdiAlphaBlend (GDI32.@)
*/ */

View file

@ -417,6 +417,9 @@ INT WINAPI NtGdiStretchDIBitsInternal( HDC hdc, INT x_dst, INT y_dst, INT w
HANDLE xform ); HANDLE xform );
BOOL WINAPI NtGdiStrokePath( HDC hdc ); BOOL WINAPI NtGdiStrokePath( HDC hdc );
BOOL WINAPI NtGdiStrokeAndFillPath( 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, BOOL WINAPI NtGdiTransformPoints( HDC hdc, const POINT *points_in, POINT *points_out,
INT count, UINT mode ); INT count, UINT mode );
BOOL WINAPI NtGdiUnrealizeObject( HGDIOBJ obj ); BOOL WINAPI NtGdiUnrealizeObject( HGDIOBJ obj );