[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