Jacek Caban : gdi32: Handle EMFs recording directly in LineTo implementation.
Alexandre Julliard
julliard at winehq.org
Wed Jul 21 16:04:30 CDT 2021
Module: wine
Branch: master
Commit: 340a445289ed5777bfc177336fb6e315dfda273c
URL: https://source.winehq.org/git/wine.git/?a=commit;h=340a445289ed5777bfc177336fb6e315dfda273c
Author: Jacek Caban <jacek at 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 at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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__ */
More information about the wine-cvs
mailing list