Module: wine Branch: master Commit: 689268d2f2f6121c40bf2014baf8a958fd2948f5 URL: http://source.winehq.org/git/wine.git/?a=commit;h=689268d2f2f6121c40bf2014ba...
Author: Piotr Caban piotr@codeweavers.com Date: Mon Jul 10 11:30:40 2017 +0200
gdiplus: Add support for ImageAttributes when drawing image to metafile.
Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Vincent Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/gdiplus/metafile.c | 99 ++++++++++++++++++++++++++++++++++++++++--- dlls/gdiplus/tests/metafile.c | 20 ++++++++- 2 files changed, 112 insertions(+), 7 deletions(-)
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index a3f94a1..1aafdf7 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -198,6 +198,24 @@ typedef struct EmfPlusImage } ImageData; } EmfPlusImage;
+typedef struct EmfPlusARGB +{ + BYTE Blue; + BYTE Green; + BYTE Red; + BYTE Alpha; +} EmfPlusARGB; + +typedef struct EmfPlusImageAttributes +{ + DWORD Version; + DWORD Reserved1; + DWORD WrapMode; + EmfPlusARGB ClampColor; + DWORD ObjectClamp; + DWORD Reserved2; +} EmfPlusImageAttributes; + typedef enum ObjectType { ObjectTypeInvalid, @@ -218,6 +236,7 @@ typedef struct EmfPlusObject union { EmfPlusImage image; + EmfPlusImageAttributes image_attributes; } ObjectData; } EmfPlusObject;
@@ -2414,13 +2433,48 @@ static GpStatus METAFILE_AddImageObject(GpMetafile *metafile, GpImage *image, DW } }
+static GpStatus METAFILE_AddImageAttributesObject(GpMetafile *metafile, const GpImageAttributes *attrs, DWORD *id) +{ + EmfPlusObject *object_record; + EmfPlusImageAttributes *attrs_record; + GpStatus stat; + + *id = -1; + + if (metafile->metafile_type != MetafileTypeEmfPlusOnly && metafile->metafile_type != MetafileTypeEmfPlusDual) + return Ok; + + if (!attrs) + return Ok; + + stat = METAFILE_AllocateRecord(metafile, + FIELD_OFFSET(EmfPlusObject, ObjectData.image_attributes) + sizeof(EmfPlusImageAttributes), + (void**)&object_record); + if (stat != Ok) return stat; + + *id = METAFILE_AddObjectId(metafile); + object_record->Header.Type = EmfPlusRecordTypeObject; + object_record->Header.Flags = *id | (ObjectTypeImageAttributes << 8); + attrs_record = &object_record->ObjectData.image_attributes; + attrs_record->Version = 0xDBC01002; + attrs_record->Reserved1 = 0; + attrs_record->WrapMode = attrs->wrap; + attrs_record->ClampColor.Blue = attrs->outside_color & 0xff; + attrs_record->ClampColor.Green = (attrs->outside_color >> 8) & 0xff; + attrs_record->ClampColor.Red = (attrs->outside_color >> 16) & 0xff; + attrs_record->ClampColor.Alpha = attrs->outside_color >> 24; + attrs_record->ObjectClamp = attrs->clamp; + attrs_record->Reserved2 = 0; + return Ok; +} + GpStatus METAFILE_DrawImagePointsRect(GpMetafile *metafile, GpImage *image, GDIPCONST GpPointF *points, INT count, REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight, GpUnit srcUnit, GDIPCONST GpImageAttributes* imageAttributes, DrawImageAbort callback, VOID *callbackData) { EmfPlusDrawImagePoints *draw_image_record; - DWORD image_id; + DWORD image_id, attributes_id; GpStatus stat;
if (count != 3) return InvalidParameter; @@ -2433,20 +2487,55 @@ GpStatus METAFILE_DrawImagePointsRect(GpMetafile *metafile, GpImage *image, else FIXME("semi-stub\n");
- if (imageAttributes) + if (!imageAttributes) { - FIXME("ImageAttributes != NULL not supported\n"); + stat = METAFILE_AddImageObject(metafile, image, &image_id); + } + else if (image->type == ImageTypeBitmap) + { + INT width = ((GpBitmap*)image)->width; + INT height = ((GpBitmap*)image)->height; + GpGraphics *graphics; + GpBitmap *bitmap; + + stat = GdipCreateBitmapFromScan0(width, height, + 0, PixelFormat32bppARGB, NULL, &bitmap); + if (stat != Ok) return stat; + + stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics); + if (stat != Ok) + { + GdipDisposeImage((GpImage*)bitmap); + return stat; + } + + stat = GdipDrawImageRectRectI(graphics, image, 0, 0, width, height, + 0, 0, width, height, UnitPixel, imageAttributes, NULL, NULL); + GdipDeleteGraphics(graphics); + if (stat != Ok) + { + GdipDisposeImage((GpImage*)bitmap); + return stat; + } + + stat = METAFILE_AddImageObject(metafile, (GpImage*)bitmap, &image_id); + GdipDisposeImage((GpImage*)bitmap); + } + else + { + FIXME("imageAttributes not supported (image type %d)\n", image->type); return NotImplemented; } + if (stat != Ok) return stat;
- stat = METAFILE_AddImageObject(metafile, image, &image_id); + stat = METAFILE_AddImageAttributesObject(metafile, imageAttributes, &attributes_id); if (stat != Ok) return stat;
stat = METAFILE_AllocateRecord(metafile, sizeof(EmfPlusDrawImagePoints), (void**)&draw_image_record); if (stat != Ok) return stat; draw_image_record->Header.Type = EmfPlusRecordTypeDrawImagePoints; draw_image_record->Header.Flags = image_id; - draw_image_record->ImageAttributesID = -1; + draw_image_record->ImageAttributesID = attributes_id; draw_image_record->SrcUnit = UnitPixel; draw_image_record->SrcRect.X = units_to_pixels(srcx, srcUnit, metafile->image.xres); draw_image_record->SrcRect.Y = units_to_pixels(srcy, srcUnit, metafile->image.yres); diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index 9048619..cbf63a6 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -2326,6 +2326,7 @@ static const emfplus_record draw_image_records[] = { {0, EMR_HEADER}, {0, EmfPlusRecordTypeHeader}, {0, EmfPlusRecordTypeObject}, + {0, EmfPlusRecordTypeObject}, {0, EmfPlusRecordTypeDrawImagePoints}, {1, EMR_SAVEDC}, {1, EMR_SETICMMODE}, @@ -2341,7 +2342,14 @@ static void test_drawimage(void) static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0}; static const GpPointF dst_points[3] = {{10.0,10.0},{25.0,15.0},{10.0,20.0}}; static const GpRectF frame = {0.0, 0.0, 100.0, 100.0}; - + const ColorMatrix double_red = {{ + {2.0,0.0,0.0,0.0,0.0}, + {0.0,1.0,0.0,0.0,0.0}, + {0.0,0.0,1.0,0.0,0.0}, + {0.0,0.0,0.0,1.0,0.0}, + {0.0,0.0,0.0,0.0,1.0}}}; + + GpImageAttributes *imageattr; GpMetafile *metafile; GpGraphics *graphics; HENHMETAFILE hemf; @@ -2370,8 +2378,16 @@ static void test_drawimage(void) stat = GdipCreateBitmapFromGdiDib(&info, buff, &bm); expect(Ok, stat);
+ stat = GdipCreateImageAttributes(&imageattr); + expect(Ok, stat); + + stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, + TRUE, &double_red, NULL, ColorMatrixFlagsDefault); + expect(Ok, stat); + stat = GdipDrawImagePointsRect(graphics, (GpImage*)bm, dst_points, 3, - 0.0, 0.0, 10.0, 10.0, UnitPixel, NULL, NULL, NULL); + 0.0, 0.0, 10.0, 10.0, UnitPixel, imageattr, NULL, NULL); + GdipDisposeImageAttributes(imageattr); expect(Ok, stat);
GdipDisposeImage((GpImage*)bm);