Module: wine Branch: master Commit: 784fe04994f1558ea67b16990ef2690c8c83ca18 URL: http://source.winehq.org/git/wine.git/?a=commit;h=784fe04994f1558ea67b16990e...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Tue Nov 7 12:28:01 2017 +0300
gdiplus/metafile: Implement playback for EmfPlusRecordTypeFillClosedCurve.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Vincent Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/gdiplus/metafile.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+)
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index 989ecd0..c28ce4b 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -487,6 +487,20 @@ typedef struct EmfPlusFillPath } data; } EmfPlusFillPath;
+typedef struct EmfPlusFillClosedCurve +{ + EmfPlusRecordHeader Header; + DWORD BrushId; + float Tension; + DWORD Count; + union + { + EmfPlusPointR7 pointsR[1]; + EmfPlusPoint points[1]; + EmfPlusPointF pointsF[1]; + } PointData; +} EmfPlusFillClosedCurve; + typedef struct EmfPlusFillEllipse { EmfPlusRecordHeader Header; @@ -2982,6 +2996,86 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, GdipDeleteBrush((GpBrush *)solidfill); return stat; } + case EmfPlusRecordTypeFillClosedCurve: + { + static const UINT fixed_part_size = FIELD_OFFSET(EmfPlusFillClosedCurve, PointData) - + sizeof(EmfPlusRecordHeader); + EmfPlusFillClosedCurve *fill = (EmfPlusFillClosedCurve *)header; + GpSolidFill *solidfill = NULL; + GpFillMode mode; + GpBrush *brush; + UINT size, i; + + if (dataSize <= fixed_part_size) + return InvalidParameter; + + if (fill->Count == 0) + return InvalidParameter; + + if (flags & 0x800) /* P */ + size = (fixed_part_size + sizeof(EmfPlusPointR7) * fill->Count + 3) & ~3; + else if (flags & 0x4000) /* C */ + size = fixed_part_size + sizeof(EmfPlusPoint) * fill->Count; + else + size = fixed_part_size + sizeof(EmfPlusPointF) * fill->Count; + + if (dataSize != size) + return InvalidParameter; + + mode = flags & 0x200 ? FillModeWinding : FillModeAlternate; /* W */ + + if (flags & 0x8000) /* S */ + { + stat = GdipCreateSolidFill(fill->BrushId, (GpSolidFill **)&solidfill); + if (stat != Ok) + return stat; + brush = (GpBrush *)solidfill; + } + else + { + if (fill->BrushId >= EmfPlusObjectTableSize || + real_metafile->objtable[fill->BrushId].type != ObjectTypeBrush) + return InvalidParameter; + + brush = real_metafile->objtable[fill->BrushId].u.brush; + } + + if (flags & (0x800 | 0x4000)) + { + GpPointF *points = GdipAlloc(fill->Count * sizeof(*points)); + if (points) + { + if (flags & 0x800) /* P */ + { + for (i = 1; i < fill->Count; i++) + { + points[i].X = points[i - 1].X + fill->PointData.pointsR[i].X; + points[i].Y = points[i - 1].Y + fill->PointData.pointsR[i].Y; + } + } + else + { + for (i = 0; i < fill->Count; i++) + { + points[i].X = fill->PointData.points[i].X; + points[i].Y = fill->PointData.points[i].Y; + } + } + + stat = GdipFillClosedCurve2(real_metafile->playback_graphics, brush, + points, fill->Count, fill->Tension, mode); + GdipFree(points); + } + else + stat = OutOfMemory; + } + else + stat = GdipFillClosedCurve2(real_metafile->playback_graphics, brush, + (const GpPointF *)fill->PointData.pointsF, fill->Count, fill->Tension, mode); + + GdipDeleteBrush((GpBrush *)solidfill); + return stat; + } case EmfPlusRecordTypeFillEllipse: { EmfPlusFillEllipse *fill = (EmfPlusFillEllipse *)header;