From b06e6147d1ba42e164cc183c8ebdf1c3987363a4 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 17 Jun 2016 15:08:57 +0900 Subject: [PATCH] gdi32: Implement PolyDraw in enhanced metafiles. Signed-off-by: Alexandre Julliard --- dlls/gdi32/enhmfdrv/enhmetafiledrv.h | 1 + dlls/gdi32/enhmfdrv/graphics.c | 37 ++++++++++++++++++++++++++++ dlls/gdi32/enhmfdrv/init.c | 2 +- dlls/gdi32/tests/metafile.c | 27 ++++++++++++++------ 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h index f4ed16553dd..c7e4489eee0 100644 --- a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h +++ b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h @@ -94,6 +94,7 @@ extern BOOL EMFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT botto INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN; extern BOOL EMFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count ) DECLSPEC_HIDDEN; extern BOOL EMFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count ) DECLSPEC_HIDDEN; +extern BOOL EMFDRV_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count ) DECLSPEC_HIDDEN; extern BOOL EMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys) DECLSPEC_HIDDEN; extern BOOL EMFDRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polys) DECLSPEC_HIDDEN; extern BOOL EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/enhmfdrv/graphics.c b/dlls/gdi32/enhmfdrv/graphics.c index 7c0aadb9a9d..80cca1f6d45 100644 --- a/dlls/gdi32/enhmfdrv/graphics.c +++ b/dlls/gdi32/enhmfdrv/graphics.c @@ -575,6 +575,43 @@ BOOL EMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT p } +/********************************************************************** + * EMFDRV_PolyDraw + */ +BOOL EMFDRV_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count ) +{ + EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev; + EMRPOLYDRAW *emr; + BOOL ret; + BYTE *types_dest; + BOOL use_small_emr = can_use_short_points( pts, count ); + DWORD size; + + size = use_small_emr ? offsetof( EMRPOLYDRAW16, apts[count] ) : offsetof( EMRPOLYDRAW, aptl[count] ); + size += (count + 3) & ~3; + + if (!(emr = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE; + + emr->emr.iType = use_small_emr ? EMR_POLYDRAW16 : EMR_POLYDRAW; + emr->emr.nSize = size; + emr->cptl = count; + + types_dest = store_points( emr->aptl, pts, count, use_small_emr ); + memcpy( types_dest, types, count ); + if (count & 3) memset( types_dest + count, 0, 4 - (count & 3) ); + + if (!physDev->path) + get_points_bounds( &emr->rclBounds, pts, count, 0 ); + else + emr->rclBounds = empty_bounds; + + ret = EMFDRV_WriteRecord( dev, &emr->emr ); + if (ret && !physDev->path) EMFDRV_UpdateBBox( dev, &emr->rclBounds ); + HeapFree( GetProcessHeap(), 0, emr ); + return ret; +} + + /********************************************************************** * EMFDRV_ExtFloodFill */ diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c index 8d6acf24eef..1678f412a42 100644 --- a/dlls/gdi32/enhmfdrv/init.c +++ b/dlls/gdi32/enhmfdrv/init.c @@ -106,7 +106,7 @@ static const struct gdi_dc_funcs EMFDRV_Funcs = EMFDRV_Pie, /* pPie */ EMFDRV_PolyBezier, /* pPolyBezier */ EMFDRV_PolyBezierTo, /* pPolyBezierTo */ - NULL, /* pPolyDraw */ + EMFDRV_PolyDraw, /* pPolyDraw */ EMFDRV_PolyPolygon, /* pPolyPolygon */ EMFDRV_PolyPolyline, /* pPolyPolyline */ EMFDRV_Polygon, /* pPolygon */ diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index f90a747a64c..2ad7206af57 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -3601,7 +3601,7 @@ static const unsigned char EMF_PATH_BITS[] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xff, 0xff, 0xff, 0xd8, 0xff, 0xff, 0xff, 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00, - 0x60, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0xac, 0x02, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00, @@ -3667,16 +3667,28 @@ static const unsigned char EMF_PATH_BITS[] = 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x3c, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 + 0x14, 0x00, 0x14, 0x00, 0x5c, 0x00, 0x00, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0a, 0x00, + 0x0a, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x1e, 0x00, 0x1e, 0x00, 0x28, 0x00, 0x14, 0x00, + 0x14, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x14, 0x00, 0x0a, 0x00, 0x06, 0x02, 0x04, 0x04, + 0x04, 0x02, 0x03, 0x06, 0x02, 0x00, 0x00, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00 }; static void test_emf_GetPath(void) { - POINT pts[4] = {{10, 10}, {20, 10}, {10, 20}, {20, 20}}; + POINT pts[9] = {{10, 10}, {20, 10}, {10, 20}, {20, 20}, {30, 30}, {40, 20}, {20, 30}, {20, 20}, {20, 10}}; DWORD counts[2] = {2, 2}; + BYTE types[9] = { PT_MOVETO, PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO, + PT_LINETO | PT_CLOSEFIGURE, PT_MOVETO, PT_LINETO }; HDC hdcMetafile; HENHMETAFILE hemf; BOOL ret; @@ -3707,10 +3719,11 @@ static void test_emf_GetPath(void) Polyline(hdcMetafile, pts, 4); PolylineTo(hdcMetafile, pts, 4); PolyPolyline(hdcMetafile, pts, counts, 2); + PolyDraw(hdcMetafile, pts, types, 9); EndPath(hdcMetafile); size = GetPath(hdcMetafile, NULL, NULL, 0); - todo_wine ok( size == 93, "GetPath returned %d.\n", size); + todo_wine ok( size == 102, "GetPath returned %d.\n", size); hemf = CloseEnhMetaFile(hdcMetafile); ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());