Piotr Caban : gdiplus: Add support for ImageAttributes when drawing image to metafile.
Alexandre Julliard
julliard at winehq.org
Mon Jul 10 15:52:47 CDT 2017
Module: wine
Branch: master
Commit: 689268d2f2f6121c40bf2014baf8a958fd2948f5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=689268d2f2f6121c40bf2014baf8a958fd2948f5
Author: Piotr Caban <piotr at 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 at codeweavers.com>
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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);
More information about the wine-cvs
mailing list