gdiplus: Implement recording/playback for MultiplyWorldTransform.
Signed-off-by: Vincent Povirk <vincent@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
25e8c83a8a
commit
69a7c2c6a2
|
@ -91,6 +91,7 @@ extern GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush,
|
||||||
GDIPCONST GpRectF* rects, INT count) DECLSPEC_HIDDEN;
|
GDIPCONST GpRectF* rects, INT count) DECLSPEC_HIDDEN;
|
||||||
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_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;
|
||||||
|
|
||||||
|
|
|
@ -5744,6 +5744,13 @@ GpStatus WINGDIPAPI GdipMultiplyWorldTransform(GpGraphics *graphics, GDIPCONST G
|
||||||
if(graphics->busy)
|
if(graphics->busy)
|
||||||
return ObjectBusy;
|
return ObjectBusy;
|
||||||
|
|
||||||
|
if (graphics->image && graphics->image->type == ImageTypeMetafile) {
|
||||||
|
ret = METAFILE_MultiplyWorldTransform((GpMetafile*)graphics->image, matrix, order);
|
||||||
|
|
||||||
|
if (ret != Ok)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
m = graphics->worldtrans;
|
m = graphics->worldtrans;
|
||||||
|
|
||||||
ret = GdipMultiplyMatrix(&m, matrix, order);
|
ret = GdipMultiplyMatrix(&m, matrix, order);
|
||||||
|
|
|
@ -91,6 +91,12 @@ typedef struct EmfPlusScaleWorldTransform
|
||||||
REAL Sy;
|
REAL Sy;
|
||||||
} EmfPlusScaleWorldTransform;
|
} EmfPlusScaleWorldTransform;
|
||||||
|
|
||||||
|
typedef struct EmfPlusMultiplyWorldTransform
|
||||||
|
{
|
||||||
|
EmfPlusRecordHeader Header;
|
||||||
|
REAL MatrixData[6];
|
||||||
|
} EmfPlusMultiplyWorldTransform;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -586,6 +592,29 @@ GpStatus METAFILE_ScaleWorldTransform(GpMetafile* metafile, REAL sx, REAL sy, Ma
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GpStatus METAFILE_MultiplyWorldTransform(GpMetafile* metafile, GDIPCONST GpMatrix* matrix, MatrixOrder order)
|
||||||
|
{
|
||||||
|
if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
|
||||||
|
{
|
||||||
|
EmfPlusMultiplyWorldTransform *record;
|
||||||
|
GpStatus stat;
|
||||||
|
|
||||||
|
stat = METAFILE_AllocateRecord(metafile,
|
||||||
|
sizeof(EmfPlusMultiplyWorldTransform),
|
||||||
|
(void**)&record);
|
||||||
|
if (stat != Ok)
|
||||||
|
return stat;
|
||||||
|
|
||||||
|
record->Header.Type = EmfPlusRecordTypeMultiplyWorldTransform;
|
||||||
|
record->Header.Flags = (order == MatrixOrderAppend ? 0x2000 : 0);
|
||||||
|
memcpy(record->MatrixData, matrix->matrix, sizeof(record->MatrixData));
|
||||||
|
|
||||||
|
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)
|
||||||
|
@ -957,6 +986,21 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
|
||||||
|
|
||||||
return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
|
return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
|
||||||
}
|
}
|
||||||
|
case EmfPlusRecordTypeMultiplyWorldTransform:
|
||||||
|
{
|
||||||
|
EmfPlusMultiplyWorldTransform *record = (EmfPlusMultiplyWorldTransform*)header;
|
||||||
|
MatrixOrder order = (flags & 0x2000) ? MatrixOrderAppend : MatrixOrderPrepend;
|
||||||
|
GpMatrix matrix;
|
||||||
|
|
||||||
|
if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusMultiplyWorldTransform))
|
||||||
|
return InvalidParameter;
|
||||||
|
|
||||||
|
memcpy(matrix.matrix, record->MatrixData, sizeof(matrix.matrix));
|
||||||
|
|
||||||
|
GdipMultiplyMatrix(real_metafile->world_transform, &matrix, 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);
|
||||||
|
|
|
@ -1292,6 +1292,8 @@ static const emfplus_record worldtransform_records[] = {
|
||||||
{0, EmfPlusRecordTypeFillRects},
|
{0, EmfPlusRecordTypeFillRects},
|
||||||
{0, EmfPlusRecordTypeResetWorldTransform},
|
{0, EmfPlusRecordTypeResetWorldTransform},
|
||||||
{0, EmfPlusRecordTypeFillRects},
|
{0, EmfPlusRecordTypeFillRects},
|
||||||
|
{0, EmfPlusRecordTypeMultiplyWorldTransform},
|
||||||
|
{0, EmfPlusRecordTypeFillRects},
|
||||||
{0, EmfPlusRecordTypeEndOfFile},
|
{0, EmfPlusRecordTypeEndOfFile},
|
||||||
{0, EMR_EOF},
|
{0, EMR_EOF},
|
||||||
{0}
|
{0}
|
||||||
|
@ -1391,6 +1393,34 @@ static void test_worldtransform(void)
|
||||||
stat = GdipDeleteBrush(brush);
|
stat = GdipDeleteBrush(brush);
|
||||||
expect(Ok, stat);
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
/* multiply transform */
|
||||||
|
stat = GdipSetMatrixElements(transform, 2.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipMultiplyWorldTransform(graphics, transform, MatrixOrderPrepend);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipGetWorldTransform(graphics, transform);
|
||||||
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
stat = GdipGetMatrixElements(transform, elements);
|
||||||
|
expect(Ok, stat);
|
||||||
|
expectf(2.0, elements[0]);
|
||||||
|
expectf(0.0, elements[1]);
|
||||||
|
expectf(0.0, elements[2]);
|
||||||
|
expectf(1.0, elements[3]);
|
||||||
|
expectf(0.0, elements[4]);
|
||||||
|
expectf(0.0, elements[5]);
|
||||||
|
|
||||||
|
stat = GdipCreateSolidFill((ARGB)0xffff0000, (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);
|
||||||
|
|
||||||
|
@ -1425,6 +1455,10 @@ static void test_worldtransform(void)
|
||||||
expect(Ok, stat);
|
expect(Ok, stat);
|
||||||
expect(0xff00ffff, color);
|
expect(0xff00ffff, color);
|
||||||
|
|
||||||
|
stat = GdipBitmapGetPixel(bitmap, 50, 30, &color);
|
||||||
|
expect(Ok, stat);
|
||||||
|
expect(0xffff0000, color);
|
||||||
|
|
||||||
stat = GdipDeleteGraphics(graphics);
|
stat = GdipDeleteGraphics(graphics);
|
||||||
expect(Ok, stat);
|
expect(Ok, stat);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue