[5/5] gdiplus: Implement recording/playback for SetWorldTransform.

Vincent Povirk madewokherd at gmail.com
Fri Aug 5 16:14:39 CDT 2016


From: Vincent Povirk <vincent at codeweavers.com>

Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
---
 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);
 
-- 
2.7.4




More information about the wine-patches mailing list