gdi32: Handle EMFs recording directly in LineTo implementation.

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-07-20 09:18:50 +02:00 committed by Alexandre Julliard
parent 317fe5bcb0
commit 340a445289
7 changed files with 47 additions and 30 deletions

View file

@ -734,17 +734,6 @@ static BOOL CDECL emfpathdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
next->funcs->pExtTextOut( next, x, y, flags, rect, str, count, dx ));
}
/***********************************************************************
* emfpathdrv_LineTo
*/
static BOOL CDECL emfpathdrv_LineTo( PHYSDEV dev, INT x, INT y )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pLineTo );
return (emfdev->funcs->pLineTo( emfdev, x, y ) && next->funcs->pLineTo( next, x, y ));
}
/***********************************************************************
* emfpathdrv_MoveTo
*/
@ -953,7 +942,7 @@ static const struct gdi_dc_funcs emfpath_driver =
NULL, /* pGradientFill */
NULL, /* pIntersectClipRect */
NULL, /* pInvertRgn */
emfpathdrv_LineTo, /* pLineTo */
NULL, /* pLineTo */
NULL, /* pModifyWorldTransform */
emfpathdrv_MoveTo, /* pMoveTo */
NULL, /* pOffsetClipRgn */

View file

@ -132,6 +132,21 @@ BOOL CDECL EMFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
return EMFDRV_WriteRecord( dev, &emr.emr );
}
/***********************************************************************
* EMFDC_LineTo
*/
BOOL EMFDC_LineTo( DC_ATTR *dc_attr, INT x, INT y )
{
EMRLINETO emr;
emr.emr.iType = EMR_LINETO;
emr.emr.nSize = sizeof(emr);
emr.ptl.x = x;
emr.ptl.y = y;
return EMFDRV_WriteRecord( dc_attr->emf, &emr.emr );
}
/***********************************************************************
* EMFDRV_LineTo
*/
@ -139,17 +154,8 @@ BOOL CDECL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y )
{
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
DC *dc = get_physdev_dc( dev );
POINT pt;
EMRLINETO emr;
RECTL bounds;
emr.emr.iType = EMR_LINETO;
emr.emr.nSize = sizeof(emr);
emr.ptl.x = x;
emr.ptl.y = y;
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
return FALSE;
POINT pt;
pt = dc->attr->cur_pos;
@ -157,14 +163,10 @@ BOOL CDECL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y )
bounds.top = min(y, pt.y);
bounds.right = max(x, pt.x);
bounds.bottom = max(y, pt.y);
if(!physDev->path)
EMFDRV_UpdateBBox( dev, &bounds );
EMFDRV_UpdateBBox( &physDev->dev, &bounds );
return TRUE;
}
/***********************************************************************
* EMFDRV_ArcChordPie
*/

View file

@ -342,6 +342,7 @@ HDC WINAPI CreateEnhMetaFileW(
free_dc_ptr( dc );
return 0;
}
dc->attr->emf = physDev;
if(description) { /* App name\0Title\0\0 */
length = lstrlenW(description);
length += lstrlenW(description + length + 1);

View file

@ -31,10 +31,15 @@
void set_gdi_client_ptr( HGDIOBJ handle, void *ptr ) DECLSPEC_HIDDEN;
void *get_gdi_client_ptr( HGDIOBJ handle, WORD type ) DECLSPEC_HIDDEN;
static inline WORD gdi_handle_type( HGDIOBJ obj )
{
unsigned int handle = HandleToULong( obj );
return (handle & NTGDI_HANDLE_TYPE_MASK) >> NTGDI_HANDLE_TYPE_SHIFT;
}
static inline BOOL is_meta_dc( HDC hdc )
{
unsigned int handle = HandleToULong( hdc );
return (handle & NTGDI_HANDLE_TYPE_MASK) >> NTGDI_HANDLE_TYPE_SHIFT == NTGDI_OBJ_METADC;
return gdi_handle_type( hdc ) == NTGDI_OBJ_METADC;
}
extern BOOL METADC_Arc( HDC hdc, INT left, INT top, INT right, INT bottom,
@ -46,4 +51,7 @@ extern BOOL METADC_MoveTo( HDC hdc, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL METADC_Pie( HDC hdc, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
/* enhanced metafiles */
extern BOOL EMFDC_LineTo( DC_ATTR *dc_attr, INT x, INT y ) DECLSPEC_HIDDEN;
#endif /* __WINE_GDI_PRIVATE_H */

View file

@ -25,14 +25,30 @@
WINE_DEFAULT_DEBUG_CHANNEL(gdi);
static DC_ATTR *get_dc_attr( HDC hdc )
{
WORD type = gdi_handle_type( hdc );
DC_ATTR *dc_attr;
if ((type & 0x1f) != NTGDI_OBJ_DC || !(dc_attr = get_gdi_client_ptr( hdc, 0 )))
{
SetLastError( ERROR_INVALID_HANDLE );
return NULL;
}
return dc_attr;
}
/***********************************************************************
* LineTo (GDI32.@)
*/
BOOL WINAPI LineTo( HDC hdc, INT x, INT y )
{
DC_ATTR *dc_attr;
TRACE( "%p, (%d, %d)\n", hdc, x, y );
if (is_meta_dc( hdc )) return METADC_LineTo( hdc, x, y );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
if (dc_attr->emf && !EMFDC_LineTo( dc_attr, x, y )) return FALSE;
return NtGdiLineTo( hdc, x, y );
}

View file

@ -70,7 +70,7 @@ void set_gdi_client_ptr( HGDIOBJ obj, void *ptr )
void *get_gdi_client_ptr( HGDIOBJ obj, WORD type )
{
GDI_HANDLE_ENTRY *entry = handle_entry( obj );
if (!entry || entry->ExtType != type || !entry->UserPointer)
if (!entry || (type && entry->ExtType != type) || !entry->UserPointer)
return NULL;
return (void *)(UINT_PTR)entry->UserPointer;
}

View file

@ -89,6 +89,7 @@ enum
typedef struct DC_ATTR
{
POINT cur_pos;
void *emf;
} DC_ATTR;
#endif /* __WINESRC__ */