Vincent Povirk : gdiplus: Implement EMR_SETWORLDTRANSFORM playback.

Alexandre Julliard julliard at winehq.org
Mon Oct 10 15:09:44 CDT 2016


Module: wine
Branch: master
Commit: 28cfa306b467abb026da1f9442bc247c4c9dc790
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=28cfa306b467abb026da1f9442bc247c4c9dc790

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Fri Oct  7 16:03:44 2016 -0500

gdiplus: Implement EMR_SETWORLDTRANSFORM playback.

Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdiplus/gdiplus_private.h |  1 +
 dlls/gdiplus/metafile.c        | 50 +++++++++++++++++++++++++++++-------------
 dlls/gdiplus/tests/metafile.c  |  2 +-
 3 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 86a29a0..340e9bd 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -374,6 +374,7 @@ struct GpMetafile{
     GpRectF src_rect;
     HANDLETABLE *handle_table;
     int handle_count;
+    XFORM gdiworldtransform;
     GpMatrix *world_transform;
     GpUnit page_unit;
     REAL page_scale;
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c
index 409a6c4..32cd04e 100644
--- a/dlls/gdiplus/metafile.c
+++ b/dlls/gdiplus/metafile.c
@@ -1040,6 +1040,30 @@ GpStatus WINGDIPAPI GdipGetHemfFromMetafile(GpMetafile *metafile, HENHMETAFILE *
     return Ok;
 }
 
+static GpStatus METAFILE_PlaybackUpdateGdiTransform(GpMetafile *metafile)
+{
+    XFORM combined, final;
+    const GpRectF *rect;
+    const GpPointF *pt;
+
+    /* This transforms metafile device space to output points. */
+    rect = &metafile->src_rect;
+    pt = metafile->playback_points;
+    final.eM11 = (pt[1].X - pt[0].X) / rect->Width;
+    final.eM21 = (pt[2].X - pt[0].X) / rect->Height;
+    final.eDx = pt[0].X - final.eM11 * rect->X - final.eM21 * rect->Y;
+    final.eM12 = (pt[1].Y - pt[0].Y) / rect->Width;
+    final.eM22 = (pt[2].Y - pt[0].Y) / rect->Height;
+    final.eDy = pt[0].Y - final.eM12 * rect->X - final.eM22 * rect->Y;
+
+    CombineTransform(&combined, &metafile->gdiworldtransform, &final);
+
+    SetGraphicsMode(metafile->playback_dc, GM_ADVANCED);
+    SetWorldTransform(metafile->playback_dc, &combined);
+
+    return Ok;
+}
+
 static GpStatus METAFILE_PlaybackGetDC(GpMetafile *metafile)
 {
     GpStatus stat = Ok;
@@ -1048,20 +1072,10 @@ static GpStatus METAFILE_PlaybackGetDC(GpMetafile *metafile)
 
     if (stat == Ok)
     {
-        /* The result of GdipGetDC always expects device co-ordinates, but the
-         * device co-ordinates of the source metafile do not correspond to
-         * device co-ordinates of the destination. Therefore, we set up the DC
-         * so that the metafile's bounds map to the destination points where we
-         * are drawing this metafile. */
-        SetMapMode(metafile->playback_dc, MM_ANISOTROPIC);
-
-        SetWindowOrgEx(metafile->playback_dc, metafile->bounds.X, metafile->bounds.Y, NULL);
-        SetWindowExtEx(metafile->playback_dc, metafile->bounds.Width, metafile->bounds.Height, NULL);
-
-        SetViewportOrgEx(metafile->playback_dc, metafile->playback_points[0].X, metafile->playback_points[0].Y, NULL);
-        SetViewportExtEx(metafile->playback_dc,
-            metafile->playback_points[1].X - metafile->playback_points[0].X,
-            metafile->playback_points[2].Y - metafile->playback_points[0].Y, NULL);
+        static const XFORM identity = {1, 0, 0, 1, 0, 0};
+
+        metafile->gdiworldtransform = identity;
+        METAFILE_PlaybackUpdateGdiTransform(metafile);
     }
 
     return stat;
@@ -1141,12 +1155,18 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
             case EMR_SETVIEWPORTORGEX:
             case EMR_SETVIEWPORTEXTEX:
             case EMR_EXTSELECTCLIPRGN:
-            case EMR_SETWORLDTRANSFORM:
             case EMR_SCALEVIEWPORTEXTEX:
             case EMR_SCALEWINDOWEXTEX:
             case EMR_MODIFYWORLDTRANSFORM:
                 FIXME("not implemented for record type %x\n", recordType);
                 break;
+            case EMR_SETWORLDTRANSFORM:
+            {
+                const XFORM* xform = (void*)data;
+                real_metafile->gdiworldtransform = *xform;
+                METAFILE_PlaybackUpdateGdiTransform(real_metafile);
+                break;
+            }
             default:
                 break;
             }
diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c
index 83054ca..a61206d 100644
--- a/dlls/gdiplus/tests/metafile.c
+++ b/dlls/gdiplus/tests/metafile.c
@@ -2260,7 +2260,7 @@ static void test_gditransform(void)
 
     stat = GdipBitmapGetPixel(bitmap, 30, 30, &color);
     expect(Ok, stat);
-    todo_wine expect(0x00000000, color);
+    expect(0x00000000, color);
 
     stat = GdipDeleteGraphics(graphics);
     expect(Ok, stat);




More information about the wine-cvs mailing list