Module: wine Branch: master Commit: af500612f26db776629d470ca8b4cdbb70592a29 URL: http://source.winehq.org/git/wine.git/?a=commit;h=af500612f26db776629d470ca8...
Author: Vincent Povirk vincent@codeweavers.com Date: Fri Aug 12 15:47:14 2016 -0500
gdiplus: Implement recording/playback for TranslateWorldTransform.
Signed-off-by: Vincent Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/gdiplus/gdiplus_private.h | 1 + dlls/gdiplus/graphics.c | 9 +++++++++ dlls/gdiplus/metafile.c | 43 ++++++++++++++++++++++++++++++++++++++++++ dlls/gdiplus/tests/metafile.c | 31 ++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index a4a2c53..1a028a5 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -94,6 +94,7 @@ extern GpStatus METAFILE_SetWorldTransform(GpMetafile* metafile, GDIPCONST GpMat extern GpStatus METAFILE_ScaleWorldTransform(GpMetafile* metafile, REAL sx, REAL sy, MatrixOrder order) DECLSPEC_HIDDEN; extern GpStatus METAFILE_MultiplyWorldTransform(GpMetafile* metafile, GDIPCONST GpMatrix* matrix, MatrixOrder order) DECLSPEC_HIDDEN; extern GpStatus METAFILE_RotateWorldTransform(GpMetafile* metafile, REAL angle, MatrixOrder order) DECLSPEC_HIDDEN; +extern GpStatus METAFILE_TranslateWorldTransform(GpMetafile* metafile, REAL dx, REAL dy, MatrixOrder order) DECLSPEC_HIDDEN; extern GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile) DECLSPEC_HIDDEN; extern GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN;
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index c04a847..e3b34fc 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -5517,6 +5517,8 @@ GpStatus WINGDIPAPI GdipSetWorldTransform(GpGraphics *graphics, GpMatrix *matrix GpStatus WINGDIPAPI GdipTranslateWorldTransform(GpGraphics *graphics, REAL dx, REAL dy, GpMatrixOrder order) { + GpStatus stat; + TRACE("(%p, %.2f, %.2f, %d)\n", graphics, dx, dy, order);
if(!graphics) @@ -5525,6 +5527,13 @@ GpStatus WINGDIPAPI GdipTranslateWorldTransform(GpGraphics *graphics, REAL dx, if(graphics->busy) return ObjectBusy;
+ if (graphics->image && graphics->image->type == ImageTypeMetafile) { + stat = METAFILE_TranslateWorldTransform((GpMetafile*)graphics->image, dx, dy, order); + + if (stat != Ok) + return stat; + } + return GdipTranslateMatrix(&graphics->worldtrans, dx, dy, order); }
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index 7dbbf6d..63d9e22 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -109,6 +109,13 @@ typedef struct EmfPlusRotateWorldTransform REAL Angle; } EmfPlusRotateWorldTransform;
+typedef struct EmfPlusTranslateWorldTransform +{ + EmfPlusRecordHeader Header; + REAL dx; + REAL dy; +} EmfPlusTranslateWorldTransform; + static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, DWORD size, void **result) { DWORD size_needed; @@ -673,6 +680,30 @@ GpStatus METAFILE_RotateWorldTransform(GpMetafile* metafile, REAL angle, MatrixO return Ok; }
+GpStatus METAFILE_TranslateWorldTransform(GpMetafile* metafile, REAL dx, REAL dy, MatrixOrder order) +{ + if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual) + { + EmfPlusTranslateWorldTransform *record; + GpStatus stat; + + stat = METAFILE_AllocateRecord(metafile, + sizeof(EmfPlusTranslateWorldTransform), + (void**)&record); + if (stat != Ok) + return stat; + + record->Header.Type = EmfPlusRecordTypeTranslateWorldTransform; + record->Header.Flags = (order == MatrixOrderAppend ? 0x2000 : 0); + record->dx = dx; + record->dy = dy; + + METAFILE_WriteRecords(metafile); + } + + return Ok; +} + GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile) { if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual) @@ -1082,6 +1113,18 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
return METAFILE_PlaybackUpdateWorldTransform(real_metafile); } + case EmfPlusRecordTypeTranslateWorldTransform: + { + EmfPlusTranslateWorldTransform *record = (EmfPlusTranslateWorldTransform*)header; + MatrixOrder order = (flags & 0x2000) ? MatrixOrderAppend : MatrixOrderPrepend; + + if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusTranslateWorldTransform)) + return InvalidParameter; + + GdipTranslateMatrix(real_metafile->world_transform, record->dx, record->dy, order); + + return METAFILE_PlaybackUpdateWorldTransform(real_metafile); + } case EmfPlusRecordTypeResetWorldTransform: { GdipSetMatrixElements(real_metafile->world_transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index 49a1dd7..c2cc400 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -1298,6 +1298,8 @@ static const emfplus_record worldtransform_records[] = { {0, EmfPlusRecordTypeFillRects}, {0, EmfPlusRecordTypeSetWorldTransform}, {0, EmfPlusRecordTypeFillRects}, + {0, EmfPlusRecordTypeTranslateWorldTransform}, + {0, EmfPlusRecordTypeFillRects}, {0, EmfPlusRecordTypeEndOfFile}, {0, EMR_EOF}, {0} @@ -1478,6 +1480,31 @@ static void test_worldtransform(void) stat = GdipDeleteBrush(brush); expect(Ok, stat);
+ /* translate transform */ + stat = GdipTranslateWorldTransform(graphics, -1.0, 0.0, MatrixOrderAppend); + expect(Ok, stat); + + stat = GdipGetWorldTransform(graphics, transform); + expect(Ok, stat); + + stat = GdipGetMatrixElements(transform, elements); + expect(Ok, stat); + expectf(1.0, elements[0]); + expectf(0.0, elements[1]); + expectf(0.0, elements[2]); + expectf(3.0, elements[3]); + expectf(-1.0, elements[4]); + expectf(0.0, elements[5]); + + stat = GdipCreateSolidFill((ARGB)0xffffffff, (GpSolidFill**)&brush); + expect(Ok, stat); + + stat = GdipFillRectangle(graphics, brush, 1.0, 1.0, 1.0, 1.0); + expect(Ok, stat); + + stat = GdipDeleteBrush(brush); + expect(Ok, stat); + stat = GdipDeleteMatrix(transform); expect(Ok, stat);
@@ -1524,6 +1551,10 @@ static void test_worldtransform(void) expect(Ok, stat); expect(0xffffff00, color);
+ stat = GdipBitmapGetPixel(bitmap, 10, 90, &color); + expect(Ok, stat); + expect(0xffffffff, color); + stat = GdipDeleteGraphics(graphics); expect(Ok, stat);