Vincent Povirk : gdiplus: Implement FillRects record playback.

Alexandre Julliard julliard at winehq.org
Mon Nov 25 13:33:14 CST 2013


Module: wine
Branch: master
Commit: fc560b212119acce3a8da506d762607af3f614bc
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=fc560b212119acce3a8da506d762607af3f614bc

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Fri Nov 22 14:55:31 2013 -0600

gdiplus: Implement FillRects record playback.

---

 dlls/gdiplus/metafile.c |   70 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c
index 4949bd9..14995dd 100644
--- a/dlls/gdiplus/metafile.c
+++ b/dlls/gdiplus/metafile.c
@@ -487,6 +487,8 @@ static void METAFILE_PlaybackReleaseDC(GpMetafile *metafile)
 GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
     EmfPlusRecordType recordType, UINT flags, UINT dataSize, GDIPCONST BYTE *data)
 {
+    GpStatus stat;
+
     TRACE("(%p,%x,%x,%d,%p)\n", metafile, recordType, flags, dataSize, data);
 
     if (!metafile || (dataSize && !data) || !metafile->playback_graphics)
@@ -518,6 +520,8 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
     }
     else
     {
+        EmfPlusRecordHeader *header = (EmfPlusRecordHeader*)(data)-1;
+
         METAFILE_PlaybackReleaseDC((GpMetafile*)metafile);
 
         switch(recordType)
@@ -528,6 +532,72 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile,
         case EmfPlusRecordTypeGetDC:
             METAFILE_PlaybackGetDC((GpMetafile*)metafile);
             break;
+        case EmfPlusRecordTypeFillRects:
+        {
+            EmfPlusFillRects *record = (EmfPlusFillRects*)header;
+            GpBrush *brush, *temp_brush=NULL;
+            GpRectF *rects, *temp_rects=NULL;
+
+            if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects))
+                return InvalidParameter;
+
+            if (flags & 0x4000)
+            {
+                if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects) + sizeof(EmfPlusRect) * record->Count)
+                    return InvalidParameter;
+            }
+            else
+            {
+                if (dataSize + sizeof(EmfPlusRecordHeader) < sizeof(EmfPlusFillRects) + sizeof(GpRectF) * record->Count)
+                    return InvalidParameter;
+            }
+
+            if (flags & 0x8000)
+            {
+                stat = GdipCreateSolidFill((ARGB)record->BrushID, (GpSolidFill**)&temp_brush);
+                brush = temp_brush;
+            }
+            else
+            {
+                FIXME("brush deserialization not implemented\n");
+                return NotImplemented;
+            }
+
+            if (stat == Ok)
+            {
+                if (flags & 0x4000)
+                {
+                    EmfPlusRect *int_rects = (EmfPlusRect*)(record+1);
+                    int i;
+
+                    rects = temp_rects = GdipAlloc(sizeof(GpRectF) * record->Count);
+                    if (rects)
+                    {
+                        for (i=0; i<record->Count; i++)
+                        {
+                            rects[i].X = int_rects[i].X;
+                            rects[i].Y = int_rects[i].Y;
+                            rects[i].Width = int_rects[i].Width;
+                            rects[i].Height = int_rects[i].Height;
+                        }
+                    }
+                    else
+                        stat = OutOfMemory;
+                }
+                else
+                    rects = (GpRectF*)(record+1);
+            }
+
+            if (stat == Ok)
+            {
+                stat = GdipFillRectangles(metafile->playback_graphics, brush, rects, record->Count);
+            }
+
+            GdipDeleteBrush(temp_brush);
+            GdipFree(temp_rects);
+
+            return stat;
+        }
         default:
             FIXME("Not implemented for record type %x\n", recordType);
             return NotImplemented;




More information about the wine-cvs mailing list