gdiplus: Implement recording/playback for RotateWorldTransform.

Signed-off-by: Vincent Povirk <vincent@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Vincent Povirk 2016-08-05 16:14:38 -05:00 committed by Alexandre Julliard
parent 69a7c2c6a2
commit cfae34a7e2
4 changed files with 82 additions and 0 deletions

View File

@ -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_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_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_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_ResetWorldTransform(GpMetafile* metafile) DECLSPEC_HIDDEN;
extern GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN; extern GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN;

View File

@ -5156,6 +5156,8 @@ GpStatus WINGDIPAPI GdipRestoreGraphics(GpGraphics *graphics, GraphicsState stat
GpStatus WINGDIPAPI GdipRotateWorldTransform(GpGraphics *graphics, REAL angle, GpStatus WINGDIPAPI GdipRotateWorldTransform(GpGraphics *graphics, REAL angle,
GpMatrixOrder order) GpMatrixOrder order)
{ {
GpStatus stat;
TRACE("(%p, %.2f, %d)\n", graphics, angle, order); TRACE("(%p, %.2f, %d)\n", graphics, angle, order);
if(!graphics) if(!graphics)
@ -5164,6 +5166,13 @@ GpStatus WINGDIPAPI GdipRotateWorldTransform(GpGraphics *graphics, REAL angle,
if(graphics->busy) if(graphics->busy)
return ObjectBusy; 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); return GdipRotateMatrix(&graphics->worldtrans, angle, order);
} }

View File

@ -97,6 +97,12 @@ typedef struct EmfPlusMultiplyWorldTransform
REAL MatrixData[6]; REAL MatrixData[6];
} EmfPlusMultiplyWorldTransform; } EmfPlusMultiplyWorldTransform;
typedef struct EmfPlusRotateWorldTransform
{
EmfPlusRecordHeader Header;
REAL Angle;
} EmfPlusRotateWorldTransform;
static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, DWORD size, void **result) static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, DWORD size, void **result)
{ {
DWORD size_needed; DWORD size_needed;
@ -615,6 +621,29 @@ GpStatus METAFILE_MultiplyWorldTransform(GpMetafile* metafile, GDIPCONST GpMatri
return Ok; 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) GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile)
{ {
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual) if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
@ -1001,6 +1030,18 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
return METAFILE_PlaybackUpdateWorldTransform(real_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: case EmfPlusRecordTypeResetWorldTransform:
{ {
GdipSetMatrixElements(real_metafile->world_transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); GdipSetMatrixElements(real_metafile->world_transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);

View File

@ -1294,6 +1294,8 @@ static const emfplus_record worldtransform_records[] = {
{0, EmfPlusRecordTypeFillRects}, {0, EmfPlusRecordTypeFillRects},
{0, EmfPlusRecordTypeMultiplyWorldTransform}, {0, EmfPlusRecordTypeMultiplyWorldTransform},
{0, EmfPlusRecordTypeFillRects}, {0, EmfPlusRecordTypeFillRects},
{0, EmfPlusRecordTypeRotateWorldTransform},
{0, EmfPlusRecordTypeFillRects},
{0, EmfPlusRecordTypeEndOfFile}, {0, EmfPlusRecordTypeEndOfFile},
{0, EMR_EOF}, {0, EMR_EOF},
{0} {0}
@ -1421,6 +1423,31 @@ static void test_worldtransform(void)
stat = GdipDeleteBrush(brush); stat = GdipDeleteBrush(brush);
expect(Ok, stat); 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); stat = GdipDeleteMatrix(transform);
expect(Ok, stat); expect(Ok, stat);
@ -1459,6 +1486,10 @@ static void test_worldtransform(void)
expect(Ok, stat); expect(Ok, stat);
expect(0xffff0000, color); expect(0xffff0000, color);
stat = GdipBitmapGetPixel(bitmap, 10, 50, &color);
expect(Ok, stat);
expect(0xffff00ff, color);
stat = GdipDeleteGraphics(graphics); stat = GdipDeleteGraphics(graphics);
expect(Ok, stat); expect(Ok, stat);