Commit 28cfa306 authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

gdiplus: Implement EMR_SETWORLDTRANSFORM playback.

parent 094516d4
...@@ -374,6 +374,7 @@ struct GpMetafile{ ...@@ -374,6 +374,7 @@ struct GpMetafile{
GpRectF src_rect; GpRectF src_rect;
HANDLETABLE *handle_table; HANDLETABLE *handle_table;
int handle_count; int handle_count;
XFORM gdiworldtransform;
GpMatrix *world_transform; GpMatrix *world_transform;
GpUnit page_unit; GpUnit page_unit;
REAL page_scale; REAL page_scale;
......
...@@ -1040,6 +1040,30 @@ GpStatus WINGDIPAPI GdipGetHemfFromMetafile(GpMetafile *metafile, HENHMETAFILE * ...@@ -1040,6 +1040,30 @@ GpStatus WINGDIPAPI GdipGetHemfFromMetafile(GpMetafile *metafile, HENHMETAFILE *
return Ok; return Ok;
} }
static GpStatus METAFILE_PlaybackUpdateGdiTransform(GpMetafile *metafile)
{
XFORM combined, final;
const GpRectF *rect;
const GpPointF *pt;
/* This transforms metafile device space to output points. */
rect = &metafile->src_rect;
pt = metafile->playback_points;
final.eM11 = (pt[1].X - pt[0].X) / rect->Width;
final.eM21 = (pt[2].X - pt[0].X) / rect->Height;
final.eDx = pt[0].X - final.eM11 * rect->X - final.eM21 * rect->Y;
final.eM12 = (pt[1].Y - pt[0].Y) / rect->Width;
final.eM22 = (pt[2].Y - pt[0].Y) / rect->Height;
final.eDy = pt[0].Y - final.eM12 * rect->X - final.eM22 * rect->Y;
CombineTransform(&combined, &metafile->gdiworldtransform, &final);
SetGraphicsMode(metafile->playback_dc, GM_ADVANCED);
SetWorldTransform(metafile->playback_dc, &combined);
return Ok;
}
static GpStatus METAFILE_PlaybackGetDC(GpMetafile *metafile) static GpStatus METAFILE_PlaybackGetDC(GpMetafile *metafile)
{ {
GpStatus stat = Ok; GpStatus stat = Ok;
...@@ -1048,20 +1072,10 @@ static GpStatus METAFILE_PlaybackGetDC(GpMetafile *metafile) ...@@ -1048,20 +1072,10 @@ static GpStatus METAFILE_PlaybackGetDC(GpMetafile *metafile)
if (stat == Ok) if (stat == Ok)
{ {
/* The result of GdipGetDC always expects device co-ordinates, but the static const XFORM identity = {1, 0, 0, 1, 0, 0};
* device co-ordinates of the source metafile do not correspond to
* device co-ordinates of the destination. Therefore, we set up the DC
* so that the metafile's bounds map to the destination points where we
* are drawing this metafile. */
SetMapMode(metafile->playback_dc, MM_ANISOTROPIC);
SetWindowOrgEx(metafile->playback_dc, metafile->bounds.X, metafile->bounds.Y, NULL);
SetWindowExtEx(metafile->playback_dc, metafile->bounds.Width, metafile->bounds.Height, NULL);
SetViewportOrgEx(metafile->playback_dc, metafile->playback_points[0].X, metafile->playback_points[0].Y, NULL); metafile->gdiworldtransform = identity;
SetViewportExtEx(metafile->playback_dc, METAFILE_PlaybackUpdateGdiTransform(metafile);
metafile->playback_points[1].X - metafile->playback_points[0].X,
metafile->playback_points[2].Y - metafile->playback_points[0].Y, NULL);
} }
return stat; return stat;
...@@ -1141,12 +1155,18 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, ...@@ -1141,12 +1155,18 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
case EMR_SETVIEWPORTORGEX: case EMR_SETVIEWPORTORGEX:
case EMR_SETVIEWPORTEXTEX: case EMR_SETVIEWPORTEXTEX:
case EMR_EXTSELECTCLIPRGN: case EMR_EXTSELECTCLIPRGN:
case EMR_SETWORLDTRANSFORM:
case EMR_SCALEVIEWPORTEXTEX: case EMR_SCALEVIEWPORTEXTEX:
case EMR_SCALEWINDOWEXTEX: case EMR_SCALEWINDOWEXTEX:
case EMR_MODIFYWORLDTRANSFORM: case EMR_MODIFYWORLDTRANSFORM:
FIXME("not implemented for record type %x\n", recordType); FIXME("not implemented for record type %x\n", recordType);
break; break;
case EMR_SETWORLDTRANSFORM:
{
const XFORM* xform = (void*)data;
real_metafile->gdiworldtransform = *xform;
METAFILE_PlaybackUpdateGdiTransform(real_metafile);
break;
}
default: default:
break; break;
} }
......
...@@ -2260,7 +2260,7 @@ static void test_gditransform(void) ...@@ -2260,7 +2260,7 @@ static void test_gditransform(void)
stat = GdipBitmapGetPixel(bitmap, 30, 30, &color); stat = GdipBitmapGetPixel(bitmap, 30, 30, &color);
expect(Ok, stat); expect(Ok, stat);
todo_wine expect(0x00000000, color); expect(0x00000000, color);
stat = GdipDeleteGraphics(graphics); stat = GdipDeleteGraphics(graphics);
expect(Ok, stat); expect(Ok, stat);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment