[PATCH v3] d2d1: Make ID2D1Device::CreateImageBrush() accept only bitmap as a source image.

Dmitry Timoshkov dmitry at baikal.ru
Thu May 19 06:34:47 CDT 2022


ID2D1Bitmap derives from ID2D1Image, which in turn derives from ID2D1Resource.
That means that ID2D1Device::CreateImageBrush() can't be really passed anything
but a ID2D1Bitmap* represented as a ID2D1Image*.

I've added QueryInterface+FIXME just in case, probably it could be dropped.

v2: Fix test crashes with image == NULL.
v3: Add a QueryInterface() check to SetImage().

Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/d2d1/brush.c        | 27 ++++++++++++++++++++++++++-
 dlls/d2d1/d2d1_private.h |  1 -
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c
index b9a673fe54c..99aaedeb43f 100644
--- a/dlls/d2d1/brush.c
+++ b/dlls/d2d1/brush.c
@@ -1209,7 +1209,19 @@ static void STDMETHODCALLTYPE d2d_image_brush_SetImage(ID2D1ImageBrush *iface, I
     TRACE("iface %p, image %p.\n", iface, image);
 
     if (image)
+    {
+        ID2D1Bitmap *bitmap;
+
+        if (FAILED(ID2D1Image_QueryInterface(image, &IID_ID2D1Bitmap, (void **)&bitmap)))
+        {
+            FIXME("ID2D1Image doesn't support ID2D1Bitmap interface.\n");
+            return;
+        }
+
+        ID2D1Bitmap_Release(bitmap);
         ID2D1Image_AddRef(image);
+    }
+
     if (brush->u.image.image)
         ID2D1Image_Release(brush->u.image.image);
     brush->u.image.image = image;
@@ -1327,7 +1339,20 @@ HRESULT d2d_image_brush_create(ID2D1Factory *factory, ID2D1Image *image,
     if (!(*brush = heap_alloc_zero(sizeof(**brush))))
         return E_OUTOFMEMORY;
 
-    d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_IMAGE,
+    if (image)
+    {
+        ID2D1Bitmap *bitmap;
+
+        if (FAILED(ID2D1Image_QueryInterface(image, &IID_ID2D1Bitmap, (void **)&bitmap)))
+        {
+            FIXME("ID2D1Image doesn't support ID2D1Bitmap interface.\n");
+            return E_FAIL;
+        }
+
+        ID2D1Bitmap_Release(bitmap);
+    }
+
+    d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_BITMAP,
             brush_desc, (ID2D1BrushVtbl *)&d2d_image_brush_vtbl);
     if (((*brush)->u.image.image = image))
         ID2D1Image_AddRef((*brush)->u.image.image);
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index 29469f5142e..6183d9d4c99 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -42,7 +42,6 @@ enum d2d_brush_type
     D2D_BRUSH_TYPE_LINEAR,
     D2D_BRUSH_TYPE_RADIAL,
     D2D_BRUSH_TYPE_BITMAP,
-    D2D_BRUSH_TYPE_IMAGE,
     D2D_BRUSH_TYPE_COUNT,
 };
 
-- 
2.36.1




More information about the wine-devel mailing list