[1/3] gdiplus: Implement recording/playback for TranslateWorldTransform.

Vincent Povirk madewokherd at gmail.com
Fri Aug 12 15:47:14 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        | 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);
 
-- 
2.7.4




More information about the wine-patches mailing list