diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 25672530313..0745e7997ff 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -117,6 +117,7 @@ extern GpStatus METAFILE_FillPie(GpMetafile *metafile, GpBrush *brush, const GpR REAL startAngle, REAL sweepAngle) DECLSPEC_HIDDEN; extern GpStatus METAFILE_DrawArc(GpMetafile *metafile, GpPen *pen, const GpRectF *rect, REAL startAngle, REAL sweepAngle) DECLSPEC_HIDDEN; +extern GpStatus METAFILE_OffsetClip(GpMetafile *metafile, REAL dx, REAL dy) 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 e292afdfb2c..dd34cf81ddb 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -7011,6 +7011,8 @@ HPALETTE WINGDIPAPI GdipCreateHalftonePalette(void) */ GpStatus WINGDIPAPI GdipTranslateClip(GpGraphics *graphics, REAL dx, REAL dy) { + GpStatus stat; + TRACE("(%p, %.2f, %.2f)\n", graphics, dx, dy); if(!graphics) @@ -7019,6 +7021,13 @@ GpStatus WINGDIPAPI GdipTranslateClip(GpGraphics *graphics, REAL dx, REAL dy) if(graphics->busy) return ObjectBusy; + if (is_metafile_graphics(graphics)) + { + stat = METAFILE_OffsetClip((GpMetafile *)graphics->image, dx, dy); + if (stat != Ok) + return stat; + } + return GdipTranslateRegion(graphics->clip, dx, dy); } @@ -7029,16 +7038,9 @@ GpStatus WINGDIPAPI GdipTranslateClipI(GpGraphics *graphics, INT dx, INT dy) { TRACE("(%p, %d, %d)\n", graphics, dx, dy); - if(!graphics) - return InvalidParameter; - - if(graphics->busy) - return ObjectBusy; - - return GdipTranslateRegion(graphics->clip, (REAL)dx, (REAL)dy); + return GdipTranslateClip(graphics, dx, dy); } - /***************************************************************************** * GdipMeasureDriverString [GDIPLUS.@] */ diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index d9fa9e77c91..8ab1acadb42 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -573,6 +573,13 @@ typedef struct EmfPlusFillRegion } data; } EmfPlusFillRegion; +typedef struct EmfPlusOffsetClip +{ + EmfPlusRecordHeader Header; + float dx; + float dy; +} EmfPlusOffsetClip; + static void metafile_free_object_table_entry(GpMetafile *metafile, BYTE id) { struct emfplus_object *object = &metafile->objtable[id]; @@ -5196,3 +5203,27 @@ GpStatus METAFILE_DrawArc(GpMetafile *metafile, GpPen *pen, const GpRectF *rect, return Ok; } + +GpStatus METAFILE_OffsetClip(GpMetafile *metafile, REAL dx, REAL dy) +{ + EmfPlusOffsetClip *record; + GpStatus stat; + + if (metafile->metafile_type == MetafileTypeEmf) + { + FIXME("stub!\n"); + return NotImplemented; + } + + stat = METAFILE_AllocateRecord(metafile, EmfPlusRecordTypeOffsetClip, + sizeof(*record), (void **)&record); + if (stat != Ok) + return stat; + + record->dx = dx; + record->dy = dy; + + METAFILE_WriteRecords(metafile); + + return Ok; +} diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index 92c738f5116..9ffd9ef60c8 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -3707,6 +3707,54 @@ static void test_drawrectangle(void) expect(Ok, stat); } +static void test_offsetclip(void) +{ + static const GpRectF frame = { 0.0f, 0.0f, 100.0f, 100.0f }; + static const emfplus_record offset_clip_records[] = + { + { EMR_HEADER }, + { EmfPlusRecordTypeHeader }, + { EmfPlusRecordTypeOffsetClip }, + { EmfPlusRecordTypeOffsetClip }, + { EmfPlusRecordTypeEndOfFile }, + { EMR_EOF }, + { 0 }, + }; + + GpMetafile *metafile; + GpGraphics *graphics; + HENHMETAFILE hemf; + GpStatus stat; + 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 = GdipTranslateClip(graphics, 1.0f, -1.0f); + expect(Ok, stat); + + stat = GdipTranslateClipI(graphics, 2, 3); + expect(Ok, stat); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + sync_metafile(&metafile, "offset_clip.emf"); + + stat = GdipGetHemfFromMetafile(metafile, &hemf); + expect(Ok, stat); + + check_emfplus(hemf, offset_clip_records, "offset clip"); + DeleteEnhMetaFile(hemf); + + stat = GdipDisposeImage((GpImage*)metafile); + expect(Ok, stat); +} + START_TEST(metafile) { struct GdiplusStartupInput gdiplusStartupInput; @@ -3764,6 +3812,7 @@ START_TEST(metafile) test_drawellipse(); test_fillellipse(); test_drawrectangle(); + test_offsetclip(); GdiplusShutdown(gdiplusToken); }