Module: wine Branch: master Commit: c491d528212e87e46e2639891426808ca56eeee0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c491d528212e87e46e26398914...
Author: Vincent Povirk vincent@codeweavers.com Date: Wed Nov 20 16:50:51 2013 -0600
gdiplus: Write FillRects records to metafiles.
---
dlls/gdiplus/gdiplus_private.h | 2 + dlls/gdiplus/graphics.c | 7 +++ dlls/gdiplus/metafile.c | 94 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 0 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index b2327f9..d95ea88 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -57,6 +57,8 @@ extern GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) DECLS extern GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **result) DECLSPEC_HIDDEN; extern GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc) DECLSPEC_HIDDEN; extern GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc) DECLSPEC_HIDDEN; +extern GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush, + GDIPCONST GpRectF* rects, INT count) DECLSPEC_HIDDEN; extern GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN; extern MetafileType METAFILE_GetEmfType(HENHMETAFILE hemf) DECLSPEC_HIDDEN;
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index de0fb30..122581d 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -3858,6 +3858,13 @@ GpStatus WINGDIPAPI GdipFillRectangles(GpGraphics *graphics, GpBrush *brush, GDI if(!rects) return InvalidParameter;
+ if (graphics->image && graphics->image->type == ImageTypeMetafile) + { + status = METAFILE_FillRectangles((GpMetafile*)graphics->image, brush, rects, count); + /* FIXME: Add gdi32 drawing. */ + return status; + } + status = GdipCreatePath(FillModeAlternate, &path); if (status != Ok) return status;
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index bcb5be7..4949bd9 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -57,6 +57,21 @@ typedef struct EmfPlusHeader DWORD LogicalDpiY; } EmfPlusHeader;
+typedef struct EmfPlusFillRects +{ + EmfPlusRecordHeader Header; + DWORD BrushID; + DWORD Count; +} EmfPlusFillRects; + +typedef struct EmfPlusRect +{ + SHORT X; + SHORT Y; + SHORT Width; + SHORT Height; +} EmfPlusRect; + static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, DWORD size, void **result) { DWORD size_needed; @@ -316,6 +331,85 @@ GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc) return Ok; }
+static BOOL is_integer_rect(const GpRectF *rect) +{ + SHORT x, y, width, height; + x = rect->X; + y = rect->Y; + width = rect->Width; + height = rect->Height; + if (rect->X != (REAL)x || rect->Y != (REAL)y || + rect->Width != (REAL)width || rect->Height != (REAL)height) + return FALSE; + return TRUE; +} + +GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush, + GDIPCONST GpRectF* rects, INT count) +{ + if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual) + { + EmfPlusFillRects *record; + GpStatus stat; + BOOL integer_rects=1; + int i; + DWORD brushid; + int flags = 0; + + if (brush->bt == BrushTypeSolidColor) + { + flags |= 0x8000; + brushid = ((GpSolidFill*)brush)->color; + } + else + { + FIXME("brush serialization not implemented\n"); + return NotImplemented; + } + + for (i=0; i<count; i++) + { + if (!is_integer_rect(&rects[i])) + { + integer_rects = 0; + break; + } + } + + if (integer_rects) + flags |= 0x4000; + + stat = METAFILE_AllocateRecord(metafile, + sizeof(EmfPlusFillRects) + count * (integer_rects ? sizeof(EmfPlusRect) : sizeof(GpRectF)), + (void**)&record); + if (stat != Ok) + return stat; + + record->Header.Type = EmfPlusRecordTypeFillRects; + record->Header.Flags = flags; + record->BrushID = brushid; + record->Count = count; + + if (integer_rects) + { + EmfPlusRect *record_rects = (EmfPlusRect*)(record+1); + for (i=0; i<count; i++) + { + record_rects[i].X = (SHORT)rects[i].X; + record_rects[i].Y = (SHORT)rects[i].Y; + record_rects[i].Width = (SHORT)rects[i].Width; + record_rects[i].Height = (SHORT)rects[i].Height; + } + } + else + memcpy(record+1, rects, sizeof(GpRectF) * count); + + METAFILE_WriteRecords(metafile); + } + + return Ok; +} + GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc) { if (hdc != metafile->record_dc)