diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 04294e823b7..5909174d2ba 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -119,6 +119,7 @@ extern GpStatus METAFILE_DrawArc(GpMetafile *metafile, GpPen *pen, const GpRectF REAL startAngle, REAL sweepAngle) DECLSPEC_HIDDEN; extern GpStatus METAFILE_OffsetClip(GpMetafile *metafile, REAL dx, REAL dy) DECLSPEC_HIDDEN; extern GpStatus METAFILE_ResetClip(GpMetafile *metafile) DECLSPEC_HIDDEN; +extern GpStatus METAFILE_SetClipPath(GpMetafile *metafile, GpPath *path, CombineMode mode) DECLSPEC_HIDDEN; extern void calc_curve_bezier(const GpPointF *pts, REAL tension, REAL *x1, REAL *y1, REAL *x2, REAL *y2) DECLSPEC_HIDDEN; diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 0eb7aa71d46..89fce949531 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -6443,6 +6443,13 @@ GpStatus WINGDIPAPI GdipSetClipPath(GpGraphics *graphics, GpPath *path, CombineM if(graphics->busy) return ObjectBusy; + if (is_metafile_graphics(graphics)) + { + status = METAFILE_SetClipPath((GpMetafile*)graphics->image, path, mode); + if (status != Ok) + return status; + } + status = GdipClonePath(path, &clip_path); if (status == Ok) { diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index c5a97246da2..f3bd83196cb 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -5248,3 +5248,30 @@ GpStatus METAFILE_ResetClip(GpMetafile *metafile) return Ok; } + +GpStatus METAFILE_SetClipPath(GpMetafile *metafile, GpPath *path, CombineMode mode) +{ + EmfPlusRecordHeader *record; + DWORD path_id; + GpStatus stat; + + if (metafile->metafile_type == MetafileTypeEmf) + { + FIXME("stub!\n"); + return NotImplemented; + } + + stat = METAFILE_AddPathObject(metafile, path, &path_id); + if (stat != Ok) return stat; + + stat = METAFILE_AllocateRecord(metafile, EmfPlusRecordTypeSetClipPath, + sizeof(*record), (void **)&record); + if (stat != Ok) + return stat; + + record->Flags = ((mode & 0xf) << 8) | path_id; + + METAFILE_WriteRecords(metafile); + + return Ok; +} diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index 9701a7d7ba6..569c975565f 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -3803,6 +3803,62 @@ static void test_resetclip(void) expect(Ok, stat); } +static void test_setclippath(void) +{ + static const GpRectF frame = { 0.0f, 0.0f, 100.0f, 100.0f }; + static const emfplus_record set_clip_path_records[] = + { + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeObject, ObjectTypePath << 8 }, + { EmfPlusRecordTypeSetClipPath, 0x100 }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 }, + }; + + GpMetafile *metafile; + GpGraphics *graphics; + HENHMETAFILE hemf; + GpStatus stat; + GpPath *path; + HDC hdc; + + hdc = CreateCompatibleDC(0); + stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile); + expect(Ok, stat); + DeleteDC(hdc); + + stat = GdipGetImageGraphicsContext((GpImage *)metafile, &graphics); + expect(Ok, stat); + + stat = GdipCreatePath(FillModeAlternate, &path); + expect(Ok, stat); + stat = GdipAddPathLine(path, 5, 5, 30, 30); + expect(Ok, stat); + stat = GdipAddPathLine(path, 30, 30, 5, 30); + expect(Ok, stat); + + stat = GdipSetClipPath(graphics, path, CombineModeIntersect); + expect(Ok, stat); + + stat = GdipDeletePath(path); + expect(Ok, stat); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + sync_metafile(&metafile, "set_clip_path.emf"); + + stat = GdipGetHemfFromMetafile(metafile, &hemf); + expect(Ok, stat); + + check_emfplus(hemf, set_clip_path_records, "set clip path"); + DeleteEnhMetaFile(hemf); + + stat = GdipDisposeImage((GpImage*)metafile); + expect(Ok, stat); +} + START_TEST(metafile) { struct GdiplusStartupInput gdiplusStartupInput; @@ -3862,6 +3918,7 @@ START_TEST(metafile) test_drawrectangle(); test_offsetclip(); test_resetclip(); + test_setclippath(); GdiplusShutdown(gdiplusToken); }