mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
gdi32: Use EMR_MASKBLT to record MaskBlt.
And use NtGdiMaskBlt. 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:
parent
839a951f67
commit
dcf7d7d5c4
5 changed files with 134 additions and 14 deletions
|
@ -567,7 +567,7 @@ BOOL WINAPI NtGdiPatBlt( HDC hdc, INT left, INT top, INT width, INT height, DWOR
|
|||
|
||||
|
||||
/***********************************************************************
|
||||
* BitBlt (GDI32.@)
|
||||
* NtGdiBitBlt (win32u.@)
|
||||
*/
|
||||
BOOL WINAPI NtGdiBitBlt( HDC hdc_dst, INT x_dst, INT y_dst, INT width, INT height,
|
||||
HDC hdc_src, INT x_src, INT y_src, DWORD rop, DWORD bk_color, FLONG fl )
|
||||
|
@ -638,12 +638,11 @@ BOOL WINAPI NtGdiStretchBlt( HDC hdcDst, INT xDst, INT yDst, INT widthDst, INT h
|
|||
#define BKGND_ROP3(ROP4) (ROP3Table[((ROP4)>>24) & 0xFF])
|
||||
|
||||
/***********************************************************************
|
||||
* MaskBlt [GDI32.@]
|
||||
* NtGdiMaskBlt (win32u.@)
|
||||
*/
|
||||
BOOL WINAPI MaskBlt(HDC hdcDest, INT nXDest, INT nYDest,
|
||||
INT nWidth, INT nHeight, HDC hdcSrc,
|
||||
INT nXSrc, INT nYSrc, HBITMAP hbmMask,
|
||||
INT xMask, INT yMask, DWORD dwRop)
|
||||
BOOL WINAPI NtGdiMaskBlt( HDC hdcDest, INT nXDest, INT nYDest, INT nWidth, INT nHeight,
|
||||
HDC hdcSrc, INT nXSrc, INT nYSrc, HBITMAP hbmMask,
|
||||
INT xMask, INT yMask, DWORD dwRop, DWORD bk_color )
|
||||
{
|
||||
HBITMAP hBitmap1, hOldBitmap1, hBitmap2, hOldBitmap2;
|
||||
HDC hDC1, hDC2;
|
||||
|
@ -782,9 +781,10 @@ BOOL WINAPI MaskBlt(HDC hdcDest, INT nXDest, INT nYDest,
|
|||
};
|
||||
|
||||
if (!hbmMask)
|
||||
return BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));
|
||||
return NtGdiBitBlt( hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc,
|
||||
nXSrc, nYSrc, FRGND_ROP3(dwRop), bk_color, 0 );
|
||||
|
||||
hbrMask = CreatePatternBrush(hbmMask);
|
||||
hbrMask = NtGdiCreatePatternBrushInternal( hbmMask, FALSE, FALSE );
|
||||
hbrDst = NtGdiSelectBrush( hdcDest, get_stock_object(NULL_BRUSH) );
|
||||
|
||||
/* make bitmap */
|
||||
|
@ -793,9 +793,9 @@ BOOL WINAPI MaskBlt(HDC hdcDest, INT nXDest, INT nYDest,
|
|||
hOldBitmap1 = NtGdiSelectBitmap(hDC1, hBitmap1);
|
||||
|
||||
/* draw using bkgnd rop */
|
||||
BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
|
||||
NtGdiBitBlt( hDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY, 0, 0 );
|
||||
hbrTmp = NtGdiSelectBrush(hDC1, hbrDst);
|
||||
BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, BKGND_ROP3(dwRop));
|
||||
NtGdiBitBlt( hDC1, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, BKGND_ROP3(dwRop), 0, 0 );
|
||||
NtGdiSelectBrush(hDC1, hbrTmp);
|
||||
|
||||
/* make bitmap */
|
||||
|
@ -804,18 +804,19 @@ BOOL WINAPI MaskBlt(HDC hdcDest, INT nXDest, INT nYDest,
|
|||
hOldBitmap2 = NtGdiSelectBitmap(hDC2, hBitmap2);
|
||||
|
||||
/* draw using foregnd rop */
|
||||
BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
|
||||
NtGdiBitBlt( hDC2, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY, 0, 0 );
|
||||
hbrTmp = NtGdiSelectBrush(hDC2, hbrDst);
|
||||
BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));
|
||||
NtGdiBitBlt( hDC2, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop), 0, 0 );
|
||||
|
||||
/* combine both using the mask as a pattern brush */
|
||||
NtGdiSelectBrush(hDC2, hbrMask);
|
||||
SetBrushOrgEx(hDC2, -xMask, -yMask, NULL);
|
||||
BitBlt(hDC2, 0, 0, nWidth, nHeight, hDC1, 0, 0, 0xac0744 ); /* (D & P) | (S & ~P) */
|
||||
/* (D & P) | (S & ~P) */
|
||||
NtGdiBitBlt(hDC2, 0, 0, nWidth, nHeight, hDC1, 0, 0, 0xac0744, 0, 0 );
|
||||
NtGdiSelectBrush(hDC2, hbrTmp);
|
||||
|
||||
/* blit to dst */
|
||||
BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hDC2, 0, 0, SRCCOPY);
|
||||
NtGdiBitBlt( hdcDest, nXDest, nYDest, nWidth, nHeight, hDC2, 0, 0, SRCCOPY, bk_color, 0 );
|
||||
|
||||
/* restore all objects */
|
||||
NtGdiSelectBrush(hdcDest, hbrDst);
|
||||
|
|
|
@ -1388,6 +1388,102 @@ BOOL EMFDC_StretchBlt( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT width_dst, IN
|
|||
height_src, rop, EMR_STRETCHBLT );
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
unsigned char mask_info_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
|
||||
BITMAPINFO *mask_bits_info = (BITMAPINFO *)mask_info_buffer;
|
||||
struct emf *emf = dc_attr->emf;
|
||||
BITMAPINFO mask_info = {{ sizeof( mask_info.bmiHeader ) }};
|
||||
BITMAPINFO src_info = {{ sizeof( src_info.bmiHeader ) }};
|
||||
HBITMAP bitmap, blit_bitmap = NULL, mask_bitmap = NULL;
|
||||
UINT bmi_size, size, mask_info_size = 0;
|
||||
EMRMASKBLT *emr = NULL;
|
||||
BITMAPINFO *bmi;
|
||||
HDC blit_dc, mask_dc = NULL;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (!rop_uses_src( rop ))
|
||||
return EMFDC_PatBlt( dc_attr, x_dst, y_dst, width_dst, height_dst, rop );
|
||||
|
||||
if (!(bitmap = GetCurrentObject( hdc_src, OBJ_BITMAP ))) return FALSE;
|
||||
blit_dc = hdc_src;
|
||||
blit_bitmap = bitmap;
|
||||
if (!(bmi_size = get_bitmap_info( &blit_dc, &blit_bitmap, &src_info ))) return FALSE;
|
||||
|
||||
if (mask)
|
||||
{
|
||||
mask_dc = hdc_src;
|
||||
mask_bitmap = mask;
|
||||
if (!(mask_info_size = get_bitmap_info( &mask_dc, &mask_bitmap, &mask_info ))) goto err;
|
||||
if (mask_info.bmiHeader.biBitCount == 1)
|
||||
mask_info_size = sizeof(BITMAPINFOHEADER); /* don't include colors */
|
||||
}
|
||||
else mask_info.bmiHeader.biSizeImage = 0;
|
||||
|
||||
size = sizeof(*emr) + bmi_size + src_info.bmiHeader.biSizeImage +
|
||||
mask_info_size + mask_info.bmiHeader.biSizeImage;
|
||||
|
||||
if (!(emr = HeapAlloc(GetProcessHeap(), 0, size))) goto err;
|
||||
|
||||
emr->emr.iType = EMR_MASKBLT;
|
||||
emr->emr.nSize = size;
|
||||
emr->rclBounds.left = x_dst;
|
||||
emr->rclBounds.top = y_dst;
|
||||
emr->rclBounds.right = x_dst + width_dst - 1;
|
||||
emr->rclBounds.bottom = y_dst + height_dst - 1;
|
||||
emr->xDest = x_dst;
|
||||
emr->yDest = y_dst;
|
||||
emr->cxDest = width_dst;
|
||||
emr->cyDest = height_dst;
|
||||
emr->dwRop = rop;
|
||||
emr->xSrc = x_src;
|
||||
emr->ySrc = y_src;
|
||||
NtGdiGetTransform( hdc_src, 0x204, &emr->xformSrc );
|
||||
emr->crBkColorSrc = GetBkColor( hdc_src );
|
||||
emr->iUsageSrc = DIB_RGB_COLORS;
|
||||
emr->offBmiSrc = sizeof(*emr);
|
||||
emr->cbBmiSrc = bmi_size;
|
||||
emr->offBitsSrc = emr->offBmiSrc + bmi_size;
|
||||
emr->cbBitsSrc = src_info.bmiHeader.biSizeImage;
|
||||
emr->xMask = x_mask;
|
||||
emr->yMask = y_mask;
|
||||
emr->iUsageMask = DIB_PAL_MONO;
|
||||
emr->offBmiMask = mask_info_size ? emr->offBitsSrc + emr->cbBitsSrc : 0;
|
||||
emr->cbBmiMask = mask_info_size;
|
||||
emr->offBitsMask = emr->offBmiMask + emr->cbBmiMask;
|
||||
emr->cbBitsMask = mask_info.bmiHeader.biSizeImage;
|
||||
|
||||
bmi = (BITMAPINFO *)((char *)emr + emr->offBmiSrc);
|
||||
bmi->bmiHeader = src_info.bmiHeader;
|
||||
ret = GetDIBits( blit_dc, blit_bitmap, 0, src_info.bmiHeader.biHeight,
|
||||
(char *)emr + emr->offBitsSrc, bmi, DIB_RGB_COLORS );
|
||||
if (!ret) goto err;
|
||||
|
||||
if (mask_info_size)
|
||||
{
|
||||
mask_bits_info->bmiHeader = mask_info.bmiHeader;
|
||||
ret = GetDIBits( blit_dc, mask_bitmap, 0, mask_info.bmiHeader.biHeight,
|
||||
(char *)emr + emr->offBitsMask, mask_bits_info, DIB_RGB_COLORS );
|
||||
if (ret) memcpy( (char *)emr + emr->offBmiMask, mask_bits_info, mask_info_size );
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
ret = emfdc_record( emf, (EMR *)emr );
|
||||
if (ret) emfdc_update_bounds( emf, &emr->rclBounds );
|
||||
}
|
||||
|
||||
err:
|
||||
HeapFree( GetProcessHeap(), 0, emr );
|
||||
if (mask_bitmap != mask) DeleteObject( mask_bitmap );
|
||||
if (mask_dc != hdc_src) DeleteObject( mask_dc );
|
||||
if (blit_bitmap != bitmap) DeleteObject( blit_bitmap );
|
||||
if (blit_dc != hdc_src) DeleteDC( blit_dc );
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL EMFDC_StretchDIBits( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
|
||||
INT x_src, INT y_src, INT width_src, INT height_src, const void *bits,
|
||||
const BITMAPINFO *info, UINT usage, DWORD rop )
|
||||
|
|
|
@ -203,6 +203,9 @@ extern BOOL EMFDC_IntersectClipRect( DC_ATTR *dc_attr, INT left, INT top, INT ri
|
|||
INT bottom ) DECLSPEC_HIDDEN;
|
||||
extern BOOL EMFDC_InvertRgn( DC_ATTR *dc_attr, HRGN hrgn ) DECLSPEC_HIDDEN;
|
||||
extern BOOL EMFDC_LineTo( DC_ATTR *dc_attr, INT x, INT y ) DECLSPEC_HIDDEN;
|
||||
extern 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 ) DECLSPEC_HIDDEN;
|
||||
extern BOOL EMFDC_ModifyWorldTransform( DC_ATTR *dc_attr, const XFORM *xform,
|
||||
DWORD mode ) DECLSPEC_HIDDEN;
|
||||
extern BOOL EMFDC_MoveTo( DC_ATTR *dc_attr, INT x, INT y ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -1499,6 +1499,23 @@ BOOL WINAPI StretchBlt( HDC hdc, INT x_dst, INT y_dst, INT width_dst, INT height
|
|||
height_src, rop, 0 /* FIXME */ );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MaskBlt [GDI32.@]
|
||||
*/
|
||||
BOOL WINAPI MaskBlt( HDC hdc, 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 )
|
||||
{
|
||||
DC_ATTR *dc_attr;
|
||||
|
||||
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
|
||||
if (dc_attr->emf && !EMFDC_MaskBlt( dc_attr, x_dst, y_dst, width_dst, height_dst,
|
||||
hdc_src, x_src, y_src, mask, x_mask, y_mask, rop ))
|
||||
return FALSE;
|
||||
return NtGdiMaskBlt( hdc, x_dst, y_dst, width_dst, height_dst, hdc_src, x_src, y_src,
|
||||
mask, x_mask, y_mask, rop, 0 /* FIXME */ );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GdiAlphaBlend (GDI32.@)
|
||||
*/
|
||||
|
|
|
@ -344,6 +344,9 @@ BOOL WINAPI NtGdiFontIsLinked( HDC hdc );
|
|||
INT WINAPI NtGdiIntersectClipRect( HDC hdc, INT left, INT top, INT right, INT bottom );
|
||||
BOOL WINAPI NtGdiInvertRgn( HDC hdc, HRGN hrgn );
|
||||
BOOL WINAPI NtGdiLineTo( HDC hdc, INT x, INT y );
|
||||
BOOL WINAPI NtGdiMaskBlt( HDC hdc, 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, DWORD bk_color );
|
||||
BOOL WINAPI NtGdiModifyWorldTransform( HDC hdc, const XFORM *xform, DWORD mode );
|
||||
BOOL WINAPI NtGdiMoveTo( HDC hdc, INT x, INT y, POINT *pt );
|
||||
INT WINAPI NtGdiOffsetClipRgn( HDC hdc, INT x, INT y );
|
||||
|
|
Loading…
Reference in a new issue