Vincent Povirk : gdiplus: Implement recording/ playback for RotateWorldTransform.
Alexandre Julliard
julliard at winehq.org
Mon Aug 8 11:09:28 CDT 2016
Module: wine
Branch: master
Commit: cfae34a7e20b3fc6ce26b08766822ad3e715a9ab
URL: http://source.winehq.org/git/wine.git/?a=commit;h=cfae34a7e20b3fc6ce26b08766822ad3e715a9ab
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Fri Aug 5 16:14:38 2016 -0500
gdiplus: Implement recording/playback for RotateWorldTransform.
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/graphics.c | 9 +++++++++
dlls/gdiplus/metafile.c | 41 +++++++++++++++++++++++++++++++++++++++++
dlls/gdiplus/tests/metafile.c | 31 +++++++++++++++++++++++++++++++
4 files changed, 82 insertions(+)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 65135f8..e42e429 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -92,6 +92,7 @@ extern GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush,
extern GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, REAL scale) 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;
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 9b0d9b5..5cab9cb 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -5156,6 +5156,8 @@ GpStatus WINGDIPAPI GdipRestoreGraphics(GpGraphics *graphics, GraphicsState stat
GpStatus WINGDIPAPI GdipRotateWorldTransform(GpGraphics *graphics, REAL angle,
GpMatrixOrder order)
{
+ GpStatus stat;
+
TRACE("(%p, %.2f, %d)\n", graphics, angle, order);
if(!graphics)
@@ -5164,6 +5166,13 @@ GpStatus WINGDIPAPI GdipRotateWorldTransform(GpGraphics *graphics, REAL angle,
if(graphics->busy)
return ObjectBusy;
+ if (graphics->image && graphics->image->type == ImageTypeMetafile) {
+ stat = METAFILE_RotateWorldTransform((GpMetafile*)graphics->image, angle, order);
+
+ if (stat != Ok)
+ return stat;
+ }
+
return GdipRotateMatrix(&graphics->worldtrans, angle, order);
}
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c
index 8d4002c..aa0da21 100644
--- a/dlls/gdiplus/metafile.c
+++ b/dlls/gdiplus/metafile.c
@@ -97,6 +97,12 @@ typedef struct EmfPlusMultiplyWorldTransform
REAL MatrixData[6];
} EmfPlusMultiplyWorldTransform;
+typedef struct EmfPlusRotateWorldTransform
+{
+ EmfPlusRecordHeader Header;
+ REAL Angle;
+} EmfPlusRotateWorldTransform;
+
static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, DWORD size, void **result)
{
DWORD size_needed;
@@ -615,6 +621,29 @@ GpStatus METAFILE_MultiplyWorldTransform(GpMetafile* metafile, GDIPCONST GpMatri
return Ok;
}
+GpStatus METAFILE_RotateWorldTransform(GpMetafile* metafile, REAL angle, MatrixOrder order)
+{
+ if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
+ {
+ EmfPlusRotateWorldTransform *record;
+ GpStatus stat;
+
+ stat = METAFILE_AllocateRecord(metafile,
+ sizeof(EmfPlusRotateWorldTransform),
+ (void**)&record);
+ if (stat != Ok)
+ return stat;
+
+ record->Header.Type = EmfPlusRecordTypeRotateWorldTransform;
+ record->Header.Flags = (order == MatrixOrderAppend ? 0x2000 : 0);
+ record->Angle = angle;
+
+ METAFILE_WriteRecords(metafile);
+ }
+
+ return Ok;
+}
+
GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile)
{
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
@@ -1001,6 +1030,18 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
}
+ case EmfPlusRecordTypeRotateWorldTransform:
+ {
+ EmfPlusRotateWorldTransform *record = (EmfPlusRotateWorldTransform*)header;
+ MatrixOrder order = (flags & 0x2000) ? MatrixOrderAppend : MatrixOrderPrepend;
+
+ if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusRotateWorldTransform))
+ return InvalidParameter;
+
+ GdipRotateMatrix(real_metafile->world_transform, record->Angle, 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 98b3f3e..67e2b9d 100644
--- a/dlls/gdiplus/tests/metafile.c
+++ b/dlls/gdiplus/tests/metafile.c
@@ -1294,6 +1294,8 @@ static const emfplus_record worldtransform_records[] = {
{0, EmfPlusRecordTypeFillRects},
{0, EmfPlusRecordTypeMultiplyWorldTransform},
{0, EmfPlusRecordTypeFillRects},
+ {0, EmfPlusRecordTypeRotateWorldTransform},
+ {0, EmfPlusRecordTypeFillRects},
{0, EmfPlusRecordTypeEndOfFile},
{0, EMR_EOF},
{0}
@@ -1421,6 +1423,31 @@ static void test_worldtransform(void)
stat = GdipDeleteBrush(brush);
expect(Ok, stat);
+ /* rotate transform */
+ stat = GdipRotateWorldTransform(graphics, 90.0, MatrixOrderAppend);
+ expect(Ok, stat);
+
+ stat = GdipGetWorldTransform(graphics, transform);
+ expect(Ok, stat);
+
+ stat = GdipGetMatrixElements(transform, elements);
+ expect(Ok, stat);
+ expectf(0.0, elements[0]);
+ expectf(2.0, elements[1]);
+ expectf(-1.0, elements[2]);
+ expectf(0.0, elements[3]);
+ expectf(0.0, elements[4]);
+ expectf(0.0, elements[5]);
+
+ stat = GdipCreateSolidFill((ARGB)0xffff00ff, (GpSolidFill**)&brush);
+ expect(Ok, stat);
+
+ stat = GdipFillRectangle(graphics, brush, 1.0, -1.0, 0.5, 1.0);
+ expect(Ok, stat);
+
+ stat = GdipDeleteBrush(brush);
+ expect(Ok, stat);
+
stat = GdipDeleteMatrix(transform);
expect(Ok, stat);
@@ -1459,6 +1486,10 @@ static void test_worldtransform(void)
expect(Ok, stat);
expect(0xffff0000, color);
+ stat = GdipBitmapGetPixel(bitmap, 10, 50, &color);
+ expect(Ok, stat);
+ expect(0xffff00ff, color);
+
stat = GdipDeleteGraphics(graphics);
expect(Ok, stat);
More information about the wine-cvs
mailing list