Module: wine Branch: master Commit: 690e0f269caf110ce92ec5701a5ab30b5847ed38 URL: http://source.winehq.org/git/wine.git/?a=commit;h=690e0f269caf110ce92ec5701a...
Author: Vincent Povirk vincent@codeweavers.com Date: Fri Aug 5 16:14:39 2016 -0500
gdiplus: Implement recording/playback for SetWorldTransform.
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 | 40 ++++++++++++++++++++++++++++++++++++++++ dlls/gdiplus/tests/metafile.c | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index e42e429..a4a2c53 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -90,6 +90,7 @@ extern GpStatus METAFILE_GraphicsClear(GpMetafile* metafile, ARGB color) DECLSPE extern GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush, GDIPCONST GpRectF* rects, INT count) DECLSPEC_HIDDEN; extern GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, REAL scale) DECLSPEC_HIDDEN; +extern GpStatus METAFILE_SetWorldTransform(GpMetafile* metafile, GDIPCONST GpMatrix* transform) DECLSPEC_HIDDEN; 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; diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 5cab9cb..c04a847 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -5488,6 +5488,8 @@ GpStatus WINGDIPAPI GdipSetTextRenderingHint(GpGraphics *graphics,
GpStatus WINGDIPAPI GdipSetWorldTransform(GpGraphics *graphics, GpMatrix *matrix) { + GpStatus stat; + TRACE("(%p, %p)\n", graphics, matrix);
if(!graphics || !matrix) @@ -5500,6 +5502,13 @@ GpStatus WINGDIPAPI GdipSetWorldTransform(GpGraphics *graphics, GpMatrix *matrix matrix->matrix[0], matrix->matrix[1], matrix->matrix[2], matrix->matrix[3], matrix->matrix[4], matrix->matrix[5]);
+ if (graphics->image && graphics->image->type == ImageTypeMetafile) { + stat = METAFILE_SetWorldTransform((GpMetafile*)graphics->image, matrix); + + if (stat != Ok) + return stat; + } + graphics->worldtrans = *matrix;
return Ok; diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index aa0da21..7dbbf6d 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -84,6 +84,12 @@ typedef struct EmfPlusRect SHORT Height; } EmfPlusRect;
+typedef struct EmfPlusSetWorldTransform +{ + EmfPlusRecordHeader Header; + REAL MatrixData[6]; +} EmfPlusSetWorldTransform; + typedef struct EmfPlusScaleWorldTransform { EmfPlusRecordHeader Header; @@ -574,6 +580,29 @@ GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, REAL scale return Ok; }
+GpStatus METAFILE_SetWorldTransform(GpMetafile* metafile, GDIPCONST GpMatrix* transform) +{ + if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual) + { + EmfPlusSetWorldTransform *record; + GpStatus stat; + + stat = METAFILE_AllocateRecord(metafile, + sizeof(EmfPlusSetWorldTransform), + (void**)&record); + if (stat != Ok) + return stat; + + record->Header.Type = EmfPlusRecordTypeSetWorldTransform; + record->Header.Flags = 0; + memcpy(record->MatrixData, transform->matrix, sizeof(record->MatrixData)); + + METAFILE_WriteRecords(metafile); + } + + return Ok; +} + GpStatus METAFILE_ScaleWorldTransform(GpMetafile* metafile, REAL sx, REAL sy, MatrixOrder order) { if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual) @@ -1003,6 +1032,17 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
return METAFILE_PlaybackUpdateWorldTransform(real_metafile); } + case EmfPlusRecordTypeSetWorldTransform: + { + EmfPlusSetWorldTransform *record = (EmfPlusSetWorldTransform*)header; + + if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusSetWorldTransform)) + return InvalidParameter; + + memcpy(real_metafile->world_transform->matrix, record->MatrixData, sizeof(record->MatrixData)); + + return METAFILE_PlaybackUpdateWorldTransform(real_metafile); + } case EmfPlusRecordTypeScaleWorldTransform: { EmfPlusScaleWorldTransform *record = (EmfPlusScaleWorldTransform*)header; diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index 67e2b9d..49a1dd7 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -1296,6 +1296,8 @@ static const emfplus_record worldtransform_records[] = { {0, EmfPlusRecordTypeFillRects}, {0, EmfPlusRecordTypeRotateWorldTransform}, {0, EmfPlusRecordTypeFillRects}, + {0, EmfPlusRecordTypeSetWorldTransform}, + {0, EmfPlusRecordTypeFillRects}, {0, EmfPlusRecordTypeEndOfFile}, {0, EMR_EOF}, {0} @@ -1448,6 +1450,34 @@ static void test_worldtransform(void) stat = GdipDeleteBrush(brush); expect(Ok, stat);
+ /* set transform */ + stat = GdipSetMatrixElements(transform, 1.0, 0.0, 0.0, 3.0, 0.0, 0.0); + expect(Ok, stat); + + stat = GdipSetWorldTransform(graphics, transform); + 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(0.0, elements[4]); + expectf(0.0, elements[5]); + + stat = GdipCreateSolidFill((ARGB)0xffffff00, (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);
@@ -1490,6 +1520,10 @@ static void test_worldtransform(void) expect(Ok, stat); expect(0xffff00ff, color);
+ stat = GdipBitmapGetPixel(bitmap, 30, 90, &color); + expect(Ok, stat); + expect(0xffffff00, color); + stat = GdipDeleteGraphics(graphics); expect(Ok, stat);