From 681cd545ea3f7633744f068111e2ed1a553d23b7 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Fri, 22 Nov 2013 16:19:13 -0600 Subject: [PATCH] gdiplus: Set world transform when drawing metafiles. --- dlls/gdiplus/gdiplus_private.h | 4 +++ dlls/gdiplus/metafile.c | 62 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index d95ea88ed91..5e8f78a6185 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -298,8 +298,12 @@ struct GpMetafile{ GpGraphics *playback_graphics; HDC playback_dc; GpPointF playback_points[3]; + GpRectF src_rect; HANDLETABLE *handle_table; int handle_count; + GpMatrix *world_transform; + GpUnit page_unit; + REAL page_scale; }; struct GpBitmap{ diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index 14995dd0474..a79bfc3007a 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -484,6 +484,28 @@ static void METAFILE_PlaybackReleaseDC(GpMetafile *metafile) } } +static GpStatus METAFILE_PlaybackUpdateWorldTransform(GpMetafile *metafile) +{ + GpMatrix *real_transform; + GpStatus stat; + + stat = GdipCreateMatrix3(&metafile->src_rect, metafile->playback_points, &real_transform); + + if (stat == Ok) + { + /* FIXME: Prepend page transform. */ + + stat = GdipMultiplyMatrix(real_transform, metafile->world_transform, MatrixOrderPrepend); + + if (stat == Ok) + stat = GdipSetWorldTransform(metafile->playback_graphics, real_transform); + + GdipDeleteMatrix(real_transform); + } + + return stat; +} + GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, EmfPlusRecordType recordType, UINT flags, UINT dataSize, GDIPCONST BYTE *data) { @@ -672,6 +694,7 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics, struct enum_metafile_data data; GpStatus stat; GpMetafile *real_metafile = (GpMetafile*)metafile; /* whoever made this const was joking */ + GraphicsContainer state; TRACE("(%p,%p,%p,%i,%p,%i,%p,%p,%p)\n", graphics, metafile, destPoints, count, srcRect, srcUnit, callback, callbackData, @@ -696,19 +719,46 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics, real_metafile->playback_graphics = graphics; real_metafile->playback_dc = NULL; + real_metafile->src_rect = *srcRect; memcpy(real_metafile->playback_points, destPoints, sizeof(PointF) * 3); stat = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, real_metafile->playback_points, 3); - if (stat == Ok && (metafile->metafile_type == MetafileTypeEmf || - metafile->metafile_type == MetafileTypeWmfPlaceable || - metafile->metafile_type == MetafileTypeWmf)) - stat = METAFILE_PlaybackGetDC((GpMetafile*)metafile); + if (stat == Ok) + stat = GdipBeginContainer2(graphics, &state); if (stat == Ok) - EnumEnhMetaFile(0, metafile->hemf, enum_metafile_proc, &data, NULL); + { + stat = GdipSetPageScale(graphics, 1.0); + + if (stat == Ok) + stat = GdipSetPageUnit(graphics, UnitPixel); - METAFILE_PlaybackReleaseDC((GpMetafile*)metafile); + if (stat == Ok) + stat = GdipCreateMatrix(&real_metafile->world_transform); + + if (stat == Ok) + { + real_metafile->page_unit = UnitPixel; /* FIXME: Use frame unit here? */ + real_metafile->page_scale = 1.0; + stat = METAFILE_PlaybackUpdateWorldTransform(real_metafile); + } + + if (stat == Ok && (metafile->metafile_type == MetafileTypeEmf || + metafile->metafile_type == MetafileTypeWmfPlaceable || + metafile->metafile_type == MetafileTypeWmf)) + stat = METAFILE_PlaybackGetDC(real_metafile); + + if (stat == Ok) + EnumEnhMetaFile(0, metafile->hemf, enum_metafile_proc, &data, NULL); + + METAFILE_PlaybackReleaseDC(real_metafile); + + GdipDeleteMatrix(real_metafile->world_transform); + real_metafile->world_transform = NULL; + + GdipEndContainer(graphics, state); + } real_metafile->playback_graphics = NULL; -- 2.11.4.GIT