gdi32: Use EMR_PLGBLT to record PlgBlt.
And use NtGdiPlgBlt. 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
dcf7d7d5c4
commit
03ec246e52
|
@ -1014,12 +1014,11 @@ BOOL WINAPI NtGdiAlphaBlend( HDC hdcDst, int xDst, int yDst, int widthDst, int h
|
|||
}
|
||||
|
||||
/*********************************************************************
|
||||
* PlgBlt [GDI32.@]
|
||||
*
|
||||
* NtGdiPlgBlt (win32u.@)
|
||||
*/
|
||||
BOOL WINAPI PlgBlt( HDC hdcDest, const POINT *lpPoint,
|
||||
HDC hdcSrc, INT nXSrc, INT nYSrc, INT nWidth,
|
||||
INT nHeight, HBITMAP hbmMask, INT xMask, INT yMask)
|
||||
BOOL WINAPI NtGdiPlgBlt( HDC hdcDest, const POINT *lpPoint, HDC hdcSrc, INT nXSrc, INT nYSrc,
|
||||
INT nWidth, INT nHeight, HBITMAP hbmMask, INT xMask, INT yMask,
|
||||
DWORD bk_color )
|
||||
{
|
||||
DWORD prev_mode;
|
||||
/* parallelogram coords */
|
||||
|
@ -1071,20 +1070,18 @@ BOOL WINAPI PlgBlt( HDC hdcDest, const POINT *lpPoint,
|
|||
rect[2].x*(rect[0].y*plg[1].y - rect[1].y*plg[0].y)
|
||||
) / det;
|
||||
|
||||
GetWorldTransform(hdcSrc,&SrcXf);
|
||||
NtGdiGetTransform( hdcSrc, 0x203, &SrcXf );
|
||||
combine_transform( &xf, &xf, &SrcXf );
|
||||
|
||||
/* save actual dest transform */
|
||||
GetWorldTransform(hdcDest,&oldDestXf);
|
||||
NtGdiGetTransform( hdcDest, 0x203, &oldDestXf );
|
||||
|
||||
SetWorldTransform(hdcDest,&xf);
|
||||
NtGdiModifyWorldTransform( hdcDest, &xf, MWT_SET );
|
||||
/* now destination and source DCs use same coords */
|
||||
MaskBlt(hdcDest,nXSrc,nYSrc,nWidth,nHeight,
|
||||
hdcSrc, nXSrc,nYSrc,
|
||||
hbmMask,xMask,yMask,
|
||||
SRCCOPY);
|
||||
NtGdiMaskBlt( hdcDest, nXSrc, nYSrc, nWidth, nHeight, hdcSrc, nXSrc, nYSrc,
|
||||
hbmMask, xMask, yMask, SRCCOPY, 0 );
|
||||
/* restore dest DC */
|
||||
SetWorldTransform(hdcDest,&oldDestXf);
|
||||
NtGdiModifyWorldTransform( hdcDest, &oldDestXf, MWT_SET );
|
||||
NtGdiGetAndSetDCDword( hdcDest, NtGdiSetGraphicsMode, prev_mode, NULL );
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -1484,6 +1484,109 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL EMFDC_PlgBlt( DC_ATTR *dc_attr, const POINT *points, HDC hdc_src, INT x_src, INT y_src,
|
||||
INT width, INT height, HBITMAP mask, INT x_mask, INT y_mask )
|
||||
{
|
||||
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;
|
||||
EMRPLGBLT *emr = NULL;
|
||||
BITMAPINFO *bmi;
|
||||
HDC blit_dc, mask_dc = NULL;
|
||||
int x_min, y_min, x_max, y_max, i;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
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_PLGBLT;
|
||||
emr->emr.nSize = size;
|
||||
|
||||
/* FIXME: not exactly what native does */
|
||||
x_min = x_max = points[1].x + points[2].x - points[0].x;
|
||||
y_min = y_max = points[1].y + points[2].y - points[0].y;
|
||||
for (i = 0; i < ARRAYSIZE(emr->aptlDest); i++)
|
||||
{
|
||||
x_min = min( x_min, points[i].x );
|
||||
y_min = min( y_min, points[i].y );
|
||||
x_max = max( x_max, points[i].x );
|
||||
y_max = max( y_min, points[i].y );
|
||||
}
|
||||
emr->rclBounds.left = x_min;
|
||||
emr->rclBounds.top = y_min;
|
||||
emr->rclBounds.right = x_max;
|
||||
emr->rclBounds.bottom = y_max;
|
||||
memcpy( emr->aptlDest, points, sizeof(emr->aptlDest) );
|
||||
emr->xSrc = x_src;
|
||||
emr->ySrc = y_src;
|
||||
emr->cxSrc = width;
|
||||
emr->cySrc = height;
|
||||
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 )
|
||||
|
|
|
@ -212,6 +212,8 @@ extern BOOL EMFDC_MoveTo( DC_ATTR *dc_attr, INT x, INT y ) DECLSPEC_HIDDEN;
|
|||
extern BOOL EMFDC_OffsetClipRgn( DC_ATTR *dc_attr, INT x, INT y ) DECLSPEC_HIDDEN;
|
||||
extern BOOL EMFDC_PaintRgn( DC_ATTR *dc_attr, HRGN hrgn ) DECLSPEC_HIDDEN;
|
||||
extern BOOL EMFDC_PatBlt( DC_ATTR *dc_attr, INT left, INT top, INT width, INT height, DWORD rop );
|
||||
extern BOOL EMFDC_PlgBlt( DC_ATTR *dc_attr, const POINT *point, HDC hdc_src, INT x_src, INT y_src,
|
||||
INT width, INT height, HBITMAP mask, INT x_mask, INT y_mask ) DECLSPEC_HIDDEN;
|
||||
extern BOOL EMFDC_PolyBezier( DC_ATTR *dc_attr, const POINT *points, DWORD count ) DECLSPEC_HIDDEN;
|
||||
extern BOOL EMFDC_PolyBezierTo( DC_ATTR *dc_attr, const POINT *points, DWORD count ) DECLSPEC_HIDDEN;
|
||||
extern BOOL EMFDC_PolyDraw( DC_ATTR *dc_attr, const POINT *points, const BYTE *types,
|
||||
|
|
|
@ -1516,6 +1516,22 @@ BOOL WINAPI MaskBlt( HDC hdc, INT x_dst, INT y_dst, INT width_dst, INT height_ds
|
|||
mask, x_mask, y_mask, rop, 0 /* FIXME */ );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* PlgBlt (GDI32.@)
|
||||
*/
|
||||
BOOL WINAPI PlgBlt( HDC hdc, const POINT *points, HDC hdc_src, INT x_src, INT y_src,
|
||||
INT width, INT height, HBITMAP mask, INT x_mask, INT y_mask )
|
||||
{
|
||||
DC_ATTR *dc_attr;
|
||||
|
||||
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
|
||||
if (dc_attr->emf && !EMFDC_PlgBlt( dc_attr, points, hdc_src, x_src, y_src,
|
||||
width, height, mask, x_mask, y_mask ))
|
||||
return FALSE;
|
||||
return NtGdiPlgBlt( hdc, points, hdc_src, x_src, y_src, width, height,
|
||||
mask, x_mask, y_mask, 0 /* FIXME */ );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GdiAlphaBlend (GDI32.@)
|
||||
*/
|
||||
|
|
|
@ -353,6 +353,9 @@ INT WINAPI NtGdiOffsetClipRgn( HDC hdc, INT x, INT y );
|
|||
INT WINAPI NtGdiOffsetRgn( HRGN hrgn, INT x, INT y );
|
||||
BOOL WINAPI NtGdiPatBlt( HDC hdc, INT left, INT top, INT width, INT height, DWORD rop );
|
||||
HRGN WINAPI NtGdiPathToRegion( HDC hdc );
|
||||
BOOL WINAPI NtGdiPlgBlt( HDC hdc, const POINT *point, HDC hdc_src, INT x_src, INT y_src,
|
||||
INT width, INT height, HBITMAP mask, INT x_mask, INT y_mask,
|
||||
DWORD bk_color );
|
||||
BOOL WINAPI NtGdiPolyDraw(HDC hdc, const POINT *points, const BYTE *types, DWORD count );
|
||||
ULONG WINAPI NtGdiPolyPolyDraw( HDC hdc, const POINT *points, const UINT *counts,
|
||||
DWORD count, UINT function );
|
||||
|
|
Loading…
Reference in New Issue