diff --git a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h index a1cead51f8e..53d69bc10cb 100644 --- a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h +++ b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h @@ -94,6 +94,8 @@ extern BOOL EMFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN; extern BOOL EMFDRV_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop ) DECLSPEC_HIDDEN; extern BOOL EMFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom, 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_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 71fd1189581..553801c0215 100644 --- a/dlls/gdi32/enhmfdrv/graphics.c +++ b/dlls/gdi32/enhmfdrv/graphics.c @@ -451,6 +451,26 @@ BOOL EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYGON ); } +/********************************************************************** + * EMFDRV_PolyBezier + */ +BOOL EMFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count ) +{ + if(EMFDRV_Polylinegon16( dev, pts, count, EMR_POLYBEZIER16 )) + return TRUE; + return EMFDRV_Polylinegon( dev, pts, count, EMR_POLYBEZIER ); +} + +/********************************************************************** + * EMFDRV_PolyBezierTo + */ +BOOL EMFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count ) +{ + if(EMFDRV_Polylinegon16( dev, pts, count, EMR_POLYBEZIERTO16 )) + return TRUE; + return EMFDRV_Polylinegon( dev, pts, count, EMR_POLYBEZIERTO ); +} + /********************************************************************** * EMFDRV_PolyPolylinegon diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c index f988ebd0159..d254cba1431 100644 --- a/dlls/gdi32/enhmfdrv/init.c +++ b/dlls/gdi32/enhmfdrv/init.c @@ -109,8 +109,8 @@ static const struct gdi_dc_funcs EMFDRV_Funcs = EMFDRV_PaintRgn, /* pPaintRgn */ EMFDRV_PatBlt, /* pPatBlt */ EMFDRV_Pie, /* pPie */ - NULL, /* pPolyBezier */ - NULL, /* pPolyBezierTo */ + EMFDRV_PolyBezier, /* pPolyBezier */ + EMFDRV_PolyBezierTo, /* pPolyBezierTo */ NULL, /* pPolyDraw */ EMFDRV_PolyPolygon, /* pPolyPolygon */ EMFDRV_PolyPolyline, /* pPolyPolyline */ diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index 206e15ad8a1..0bbf9c3121e 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -1321,6 +1321,51 @@ static const unsigned char EMF_DCBRUSH_BITS[] = 0x14, 0x00, 0x00, 0x00 }; +static const unsigned char EMF_BEZIER_BITS[] = +{ + 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1a, 0x2a, 0x0d, 0x00, 0x1a, 0x2f, 0x0d, 0x00, + 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00, + 0x44, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x51, 0x01, 0x00, 0x00, 0x0e, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x24, 0x05, 0x00, + 0xb0, 0x1e, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x0f, 0x00, 0x0f, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x0f, 0x00, 0x0f, 0x00, 0x19, 0x00, 0x19, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, + 0x01, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, + 0x01, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00 +}; + /* For debugging or dumping the raw metafiles produced by * new test functions. */ @@ -1588,6 +1633,28 @@ static BOOL match_emf_record(const ENHMETARECORD *emr1, const ENHMETARECORD *emr HeapFree(GetProcessHeap(), 0, emr_nt4); } } + else if (emr1->iType == EMR_POLYBEZIERTO16 || emr1->iType == EMR_POLYBEZIER16) + { + EMRPOLYBEZIER16 *eto1, *eto2; + + eto1 = (EMRPOLYBEZIER16*)emr1; + eto2 = (EMRPOLYBEZIER16*)emr2; + + diff = eto1->cpts != eto1->cpts; + if(!diff) + diff = memcmp(eto1->apts, eto2->apts, eto1->cpts * sizeof(POINTS)); + } + else if (emr1->iType == EMR_POLYBEZIERTO || emr1->iType == EMR_POLYBEZIER) + { + EMRPOLYBEZIER *eto1, *eto2; + + eto1 = (EMRPOLYBEZIER*)emr1; + eto2 = (EMRPOLYBEZIER*)emr2; + + diff = eto1->cptl != eto1->cptl; + if(!diff) + diff = memcmp(eto1->aptl, eto2->aptl, eto1->cptl * sizeof(POINTL)); + } else diff = memcmp(emr1, emr2, emr1->nSize); @@ -1658,17 +1725,17 @@ static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits, offset2 = emh2->nSize; /* Needed for Win9x/WinME/NT4 */ while (offset1 < emh1->nBytes) { - const ENHMETARECORD *emr1 = (const ENHMETARECORD *)(bits + offset1); - const ENHMETARECORD *emr2 = (const ENHMETARECORD *)(buf + offset2); + const ENHMETARECORD *emr1 = (const ENHMETARECORD *)(bits + offset1); + const ENHMETARECORD *emr2 = (const ENHMETARECORD *)(buf + offset2); - trace("%s: EMF record %u, size %u/record %u, size %u\n", + trace("%s: EMF record %u, size %u/record %u, size %u\n", desc, emr1->iType, emr1->nSize, emr2->iType, emr2->nSize); if (!match_emf_record(emr1, emr2, desc, ignore_scaling)) return -1; /* We have already bailed out if iType or nSize don't match */ - offset1 += emr1->nSize; - offset2 += emr2->nSize; + offset1 += emr1->nSize; + offset2 += emr2->nSize; } return 0; } @@ -2250,7 +2317,7 @@ static int CALLBACK clip_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table, { if (emr->iType == EMR_EXTSELECTCLIPRGN) { - const EMREXTSELECTCLIPRGN *clip = (const EMREXTSELECTCLIPRGN *)emr; + const EMREXTSELECTCLIPRGN *clip = (const EMREXTSELECTCLIPRGN *)emr; union _rgn { RGNDATA data; @@ -3089,6 +3156,45 @@ static void test_SetEnhMetaFileBits(void) DeleteEnhMetaFile(hemf); } +static void test_emf_polybezier(void) +{ + HDC hdcMetafile; + HENHMETAFILE hemf; + POINT pts[4]; + BOOL ret; + + SetLastError(0xdeadbeef); + hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL); + ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError()); + + pts[0].x = pts[0].y = 10; + pts[1].x = pts[1].y = 20; + pts[2].x = pts[2].y = 15; + pts[3].x = pts[3].y = 25; + ret = PolyBezierTo(hdcMetafile, pts, 3); /* EMR_POLYBEZIERTO16 */ + ok( ret, "PolyBezierTo failed\n" ); + ret = PolyBezier(hdcMetafile, pts, 4); /* EMR_POLYBEZIER16 */ + ok( ret, "PolyBezier failed\n" ); + + pts[0].x = pts[0].y = 32769; + ret = PolyBezier(hdcMetafile, pts, 4); /* EMR_POLYBEZIER */ + ok( ret, "PolyBezier failed\n" ); + ret = PolyBezierTo(hdcMetafile, pts, 3); /* EMR_POLYBEZIERTO */ + ok( ret, "PolyBezierTo failed\n" ); + + hemf = CloseEnhMetaFile(hdcMetafile); + ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError()); + + if(compare_emf_bits(hemf, EMF_BEZIER_BITS, sizeof(EMF_BEZIER_BITS), + "emf_Bezier", FALSE) != 0) + { + dump_emf_bits(hemf, "emf_Bezier"); + dump_emf_records(hemf, "emf_Bezier"); + } + + DeleteEnhMetaFile(hemf); +} + START_TEST(metafile) { init_function_pointers(); @@ -3111,6 +3217,7 @@ START_TEST(metafile) test_mf_ExtTextOut_on_path(); test_emf_ExtTextOut_on_path(); test_emf_clipping(); + test_emf_polybezier(); /* For metafile conversions */ test_mf_conversions();