From: Vincent Povirk Subject: [3/5] gdiplus: Implement writing Clear operation to metafiles. Message-Id: <1466790703-1608-3-git-send-email-madewokherd@gmail.com> Date: Fri, 24 Jun 2016 12:51:41 -0500 From: Vincent Povirk Signed-off-by: Vincent Povirk --- dlls/gdiplus/gdiplus_private.h | 1 + dlls/gdiplus/graphics.c | 3 ++ dlls/gdiplus/metafile.c | 27 +++++++++++++ dlls/gdiplus/tests/metafile.c | 90 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+) diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 8924ae6..e21085f 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -86,6 +86,7 @@ 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_GraphicsClear(GpMetafile* metafile, ARGB color) DECLSPEC_HIDDEN; extern GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush, GDIPCONST GpRectF* rects, INT count) DECLSPEC_HIDDEN; extern GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, REAL scale) DECLSPEC_HIDDEN; diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 58d59fe..37990cf 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -4379,6 +4379,9 @@ GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics *graphics, ARGB color) if(graphics->busy) return ObjectBusy; + if (graphics->image && graphics->image->type == ImageTypeMetafile) + return METAFILE_GraphicsClear((GpMetafile*)graphics->image, color); + if((stat = GdipCreateSolidFill(color, &brush)) != Ok) return stat; diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index ca8aac4..2a5d830 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -57,6 +57,12 @@ typedef struct EmfPlusHeader DWORD LogicalDpiY; } EmfPlusHeader; +typedef struct EmfPlusClear +{ + EmfPlusRecordHeader Header; + DWORD Color; +} EmfPlusClear; + typedef struct EmfPlusFillRects { EmfPlusRecordHeader Header; @@ -370,6 +376,27 @@ GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc) return Ok; } +GpStatus METAFILE_GraphicsClear(GpMetafile* metafile, ARGB color) +{ + if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual) + { + EmfPlusClear *record; + GpStatus stat; + + stat = METAFILE_AllocateRecord(metafile, sizeof(EmfPlusClear), (void**)&record); + if (stat != Ok) + return stat; + + record->Header.Type = EmfPlusRecordTypeClear; + record->Header.Flags = 0; + record->Color = color; + + METAFILE_WriteRecords(metafile); + } + + return Ok; +} + static BOOL is_integer_rect(const GpRectF *rect) { SHORT x, y, width, height; diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index 741f752..4686c41 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -862,6 +862,95 @@ static void test_fillrect(void) expect(Ok, stat); } +static const emfplus_record clear_emf_records[] = { + {0, EMR_HEADER}, + {0, EmfPlusRecordTypeHeader}, + {0, EmfPlusRecordTypeClear}, + {1, EMR_SAVEDC}, + {1, EMR_SETICMMODE}, + {1, EMR_BITBLT}, + {1, EMR_RESTOREDC}, + {0, EmfPlusRecordTypeEndOfFile}, + {0, EMR_EOF}, + {0} +}; + +static void test_clear(void) +{ + GpStatus stat; + GpMetafile *metafile; + GpGraphics *graphics; + HDC hdc; + HENHMETAFILE hemf; + static const GpRectF frame = {0.0, 0.0, 100.0, 100.0}; + static const GpPointF dst_points[3] = {{10.0,10.0},{20.0,10.0},{10.0,20.0}}; + static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0}; + GpBitmap *bitmap; + ARGB color; + + hdc = CreateCompatibleDC(0); + + stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile); + expect(Ok, stat); + + DeleteDC(hdc); + + if (stat != Ok) + return; + + stat = GdipGetHemfFromMetafile(metafile, &hemf); + expect(InvalidParameter, stat); + + stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics); + expect(Ok, stat); + + stat = GdipGraphicsClear(graphics, 0xffffff00); + expect(Ok, stat); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + + save_metafile(metafile, "clear.emf"); + + stat = GdipCreateBitmapFromScan0(30, 30, 0, PixelFormat32bppRGB, NULL, &bitmap); + expect(Ok, stat); + + stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics); + expect(Ok, stat); + + stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3, + 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL); + expect(Ok, stat); + + stat = GdipBitmapGetPixel(bitmap, 5, 5, &color); + expect(Ok, stat); + expect(0xff000000, color); + + stat = GdipBitmapGetPixel(bitmap, 15, 15, &color); + expect(Ok, stat); + todo_wine expect(0xffffff00, color); + + stat = GdipBitmapGetPixel(bitmap, 25, 25, &color); + expect(Ok, stat); + expect(0xff000000, color); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + + stat = GdipDisposeImage((GpImage*)bitmap); + expect(Ok, stat); + + stat = GdipGetHemfFromMetafile(metafile, &hemf); + expect(Ok, stat); + + stat = GdipDisposeImage((GpImage*)metafile); + expect(Ok, stat); + + check_emfplus(hemf, clear_emf_records, "clear emf"); + + DeleteEnhMetaFile(hemf); +} + static void test_nullframerect(void) { GpStatus stat; GpMetafile *metafile; @@ -1345,6 +1434,7 @@ START_TEST(metafile) test_getdc(); test_emfonly(); test_fillrect(); + test_clear(); test_nullframerect(); test_pagetransform(); test_converttoemfplus(); -- 2.7.4