From 1cb437ac256280cfab5c325b660dd4833d17cda8 Mon Sep 17 00:00:00 2001 From: "Shawn M. Chapla" Date: Mon, 20 Jul 2020 22:45:19 -0400 Subject: [PATCH] gdiplus: Add FillRegion serialization. Signed-off-by: Shawn M. Chapla Signed-off-by: Esme Povirk Signed-off-by: Alexandre Julliard --- dlls/gdiplus/gdiplus_private.h | 2 ++ dlls/gdiplus/graphics.c | 13 ++++++--- dlls/gdiplus/metafile.c | 48 ++++++++++++++++++++++++++++++++++ dlls/gdiplus/tests/metafile.c | 16 ++++++------ 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 1b2de4e8f47..aac5509afa7 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -107,6 +107,8 @@ extern GpStatus METAFILE_FillPath(GpMetafile *metafile, GpBrush *brush, GpPath * extern GpStatus METAFILE_DrawDriverString(GpMetafile *metafile, GDIPCONST UINT16 *text, INT length, GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format, GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix) DECLSPEC_HIDDEN; +extern GpStatus METAFILE_FillRegion(GpMetafile* metafile, GpBrush* brush, + GpRegion* region) DECLSPEC_HIDDEN; extern void METAFILE_Free(GpMetafile *metafile) DECLSPEC_HIDDEN; extern void calc_curve_bezier(const GpPointF *pts, REAL tension, REAL *x1, diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 1307bdc1ef6..f0da41c6cbb 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -4700,11 +4700,16 @@ GpStatus WINGDIPAPI GdipFillRegion(GpGraphics* graphics, GpBrush* brush, if(graphics->busy) return ObjectBusy; - if (!graphics->image && !graphics->alpha_hdc) - stat = GDI32_GdipFillRegion(graphics, brush, region); + if (graphics->image && graphics->image->type == ImageTypeMetafile) + stat = METAFILE_FillRegion((GpMetafile*)graphics->image, brush, region); + else + { + if (!graphics->image && !graphics->alpha_hdc) + stat = GDI32_GdipFillRegion(graphics, brush, region); - if (stat == NotImplemented) - stat = SOFTWARE_GdipFillRegion(graphics, brush, region); + if (stat == NotImplemented) + stat = SOFTWARE_GdipFillRegion(graphics, brush, region); + } if (stat == NotImplemented) { diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index ed4e8a8be4b..1d7c0fe3062 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -4854,3 +4854,51 @@ GpStatus METAFILE_DrawDriverString(GpMetafile *metafile, GDIPCONST UINT16 *text, return Ok; } + +GpStatus METAFILE_FillRegion(GpMetafile* metafile, GpBrush* brush, GpRegion* region) +{ + GpStatus stat; + DWORD brush_id; + DWORD region_id; + EmfPlusFillRegion *fill_region_record; + BOOL inline_color; + + if (metafile->metafile_type != MetafileTypeEmfPlusOnly && + metafile->metafile_type != MetafileTypeEmfPlusDual) + { + FIXME("metafile type not supported: %i\n", metafile->metafile_type); + return NotImplemented; + } + + inline_color = (brush->bt == BrushTypeSolidColor); + if (!inline_color) + { + stat = METAFILE_AddBrushObject(metafile, brush, &brush_id); + if (stat != Ok) + return stat; + } + + stat = METAFILE_AddRegionObject(metafile, region, ®ion_id); + if (stat != Ok) + return stat; + + stat = METAFILE_AllocateRecord(metafile, sizeof(EmfPlusFillRegion), + (void**)&fill_region_record); + if (stat != Ok) + return stat; + + fill_region_record->Header.Type = EmfPlusRecordTypeFillRegion; + fill_region_record->Header.Flags = region_id; + + if (inline_color) + { + fill_region_record->Header.Flags |= 0x8000; + fill_region_record->data.Color = ((GpSolidFill*)brush)->color; + } + else + fill_region_record->data.BrushId = brush_id; + + METAFILE_WriteRecords(metafile); + + return Ok; +} diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index f0b31b4f9c9..ddb58504c99 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -3177,11 +3177,11 @@ static void test_unknownfontdecode(void) static const emfplus_record fillregion_records[] = { { EMR_HEADER }, { EmfPlusRecordTypeHeader }, - { EmfPlusRecordTypeObject, ObjectTypeRegion << 8, 1 }, - { EmfPlusRecordTypeFillRegion, 0x8000, 1 }, - { EmfPlusRecordTypeObject, (ObjectTypeBrush << 8) | 1, 1 }, - { EmfPlusRecordTypeObject, (ObjectTypeRegion << 8) | 2, 1 }, - { EmfPlusRecordTypeFillRegion, 2, 1 }, + { EmfPlusRecordTypeObject, ObjectTypeRegion << 8 }, + { EmfPlusRecordTypeFillRegion, 0x8000 }, + { EmfPlusRecordTypeObject, (ObjectTypeBrush << 8) | 1 }, + { EmfPlusRecordTypeObject, (ObjectTypeRegion << 8) | 2 }, + { EmfPlusRecordTypeFillRegion, 2 }, { EmfPlusRecordTypeEndOfFile }, { EMR_EOF }, { 0 } @@ -3251,15 +3251,15 @@ static void test_fillregion(void) stat = GdipBitmapGetPixel(bitmap, 25, 25, &color); expect(Ok, stat); - todo_wine expect(0xffaabbcc, color); + expect(0xffaabbcc, color); stat = GdipBitmapGetPixel(bitmap, 56, 56, &color); expect(Ok, stat); - todo_wine expect(0xffff0000, color); + expect(0xffff0000, color); stat = GdipBitmapGetPixel(bitmap, 57, 57, &color); expect(Ok, stat); - todo_wine expect(0xff0000ff, color); + expect(0xff0000ff, color); GdipDeleteRegion(solidregion); GdipDeleteRegion(hatchregion);