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