Module: wine Branch: master Commit: 340a445289ed5777bfc177336fb6e315dfda273c URL: https://source.winehq.org/git/wine.git/?a=commit;h=340a445289ed5777bfc177336...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Jul 20 09:18:50 2021 +0200
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
---
dlls/gdi32/enhmfdrv/dc.c | 13 +------------ dlls/gdi32/enhmfdrv/graphics.c | 28 +++++++++++++++------------- dlls/gdi32/enhmfdrv/init.c | 1 + dlls/gdi32/gdi_private.h | 12 ++++++++++-- dlls/gdi32/gdidc.c | 16 ++++++++++++++++ dlls/gdi32/objects.c | 2 +- include/ntgdi.h | 1 + 7 files changed, 45 insertions(+), 28 deletions(-)
diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c index 9edd09a179e..79c3032daa6 100644 --- a/dlls/gdi32/enhmfdrv/dc.c +++ b/dlls/gdi32/enhmfdrv/dc.c @@ -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 */ diff --git a/dlls/gdi32/enhmfdrv/graphics.c b/dlls/gdi32/enhmfdrv/graphics.c index f504aee8e36..8d6445779b9 100644 --- a/dlls/gdi32/enhmfdrv/graphics.c +++ b/dlls/gdi32/enhmfdrv/graphics.c @@ -133,23 +133,29 @@ BOOL CDECL EMFDRV_MoveTo(PHYSDEV dev, INT x, INT y) }
/*********************************************************************** - * EMFDRV_LineTo + * EMFDC_LineTo */ -BOOL CDECL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y ) +BOOL EMFDC_LineTo( DC_ATTR *dc_attr, 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; + return EMFDRV_WriteRecord( dc_attr->emf, &emr.emr ); +}
- if(!EMFDRV_WriteRecord( dev, &emr.emr )) - return FALSE; + +/*********************************************************************** + * EMFDRV_LineTo + */ +BOOL CDECL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y ) +{ + EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); + DC *dc = get_physdev_dc( dev ); + RECTL bounds; + 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 */ diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c index 9a611e0f1bc..62e35fe4029 100644 --- a/dlls/gdi32/enhmfdrv/init.c +++ b/dlls/gdi32/enhmfdrv/init.c @@ -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); diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 436846c5bd5..bb4504f4934 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -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 */ diff --git a/dlls/gdi32/gdidc.c b/dlls/gdi32/gdidc.c index 01c9dfdf8c7..c011d66deb9 100644 --- a/dlls/gdi32/gdidc.c +++ b/dlls/gdi32/gdidc.c @@ -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 ); }
diff --git a/dlls/gdi32/objects.c b/dlls/gdi32/objects.c index e5aafc1fed4..e614a9d6a52 100644 --- a/dlls/gdi32/objects.c +++ b/dlls/gdi32/objects.c @@ -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; } diff --git a/include/ntgdi.h b/include/ntgdi.h index b03ffc0fea8..53915033c89 100644 --- a/include/ntgdi.h +++ b/include/ntgdi.h @@ -89,6 +89,7 @@ enum typedef struct DC_ATTR { POINT cur_pos; + void *emf; } DC_ATTR;
#endif /* __WINESRC__ */