[2/3] gdiplus: If a 32-bit dib is selected in an hdc, use the dib directly.

Vincent Povirk madewokherd at gmail.com
Mon Dec 3 17:13:30 CST 2012


-------------- next part --------------
From 78c0dabff1dfb4d6d4c03d5b72d85df50bd4afae Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Mon, 3 Dec 2012 16:57:16 -0600
Subject: [PATCH 2/3] gdiplus: If a 32-bit dib is selected in an hdc, use the
 dib directly.

---
 dlls/gdiplus/gdiplus_private.h |    1 +
 dlls/gdiplus/graphics.c        |   40 ++++++++++++++++++++++++++++++++++++++++
 dlls/gdiplus/tests/graphics.c  |    4 ++--
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 4a8b10a..6a47d09 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -153,6 +153,7 @@ struct GpGraphics{
     HWND hwnd;
     BOOL owndc;
     GpImage *image;
+    BOOL ownimage;
     SmoothingMode smoothing;
     CompositingQuality compqual;
     InterpolationMode interpolation;
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 247b17d..0a95ddf 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -2250,6 +2250,8 @@ GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics)
 GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **graphics)
 {
     GpStatus retval;
+    HBITMAP hbm;
+    DIBSECTION dib;
 
     TRACE("(%p, %p, %p)\n", hdc, hDevice, graphics);
 
@@ -2264,6 +2266,41 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra
     if(graphics == NULL)
         return InvalidParameter;
 
+    hbm = GetCurrentObject(hdc, OBJ_BITMAP);
+    if (hbm && GetObjectW(hbm, sizeof(dib), &dib) && dib.dsBm.bmBitsPixel == 32)
+    {
+        /* Make a bitmap object so we can use the alpha channel */
+        GpBitmap *bitmap;
+        DWORD height, stride;
+        BYTE *bits;
+
+        height = abs(dib.dsBmih.biHeight);
+        stride = dib.dsBmih.biWidth * 4;
+
+        if(dib.dsBmih.biHeight > 0) /* bottom-up */
+        {
+            bits = (BYTE*)dib.dsBm.bmBits + (height - 1) * stride;
+            stride = -dib.dsBmih.biWidth * 4;
+        }
+        else
+            bits = dib.dsBm.bmBits;
+
+        retval = GdipCreateBitmapFromScan0(dib.dsBmih.biWidth, height, stride,
+                                           PixelFormat32bppPARGB, bits, &bitmap);
+
+        if (retval == Ok)
+        {
+            retval = graphics_from_image((GpImage*)bitmap, graphics);
+
+            if (retval == Ok)
+                (*graphics)->ownimage = TRUE;
+            else
+                GdipDisposeImage((GpImage*)bitmap);
+        }
+
+        return retval;
+    }
+
     *graphics = GdipAlloc(sizeof(GpGraphics));
     if(!*graphics)  return OutOfMemory;
 
@@ -2518,6 +2555,9 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
     if(graphics->owndc)
         ReleaseDC(graphics->hwnd, graphics->hdc);
 
+    if (graphics->ownimage)
+        GdipDisposeImage(graphics->image);
+
     LIST_FOR_EACH_ENTRY_SAFE(cont, next, &graphics->containers, GraphicsContainerItem, entry){
         list_remove(&cont->entry);
         delete_container(cont);
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
index 553e77f..40ca01b 100644
--- a/dlls/gdiplus/tests/graphics.c
+++ b/dlls/gdiplus/tests/graphics.c
@@ -4115,7 +4115,7 @@ static void test_alpha_hdc(void)
     status = GdipGraphicsClear(graphics, 0xffaaaaaa);
     expect(Ok, status);
 
-    todo_wine expect(0xffaaaaaa, bits[0]);
+    expect(0xffaaaaaa, bits[0]);
 
     SelectObject(hdc, old_hbm);
 
@@ -4124,7 +4124,7 @@ static void test_alpha_hdc(void)
     status = GdipGraphicsClear(graphics, 0xffbbbbbb);
     expect(Ok, status);
 
-    todo_wine expect(0xffbbbbbb, bits[0]);
+    expect(0xffbbbbbb, bits[0]);
 
     GdipDeleteGraphics(graphics);
 
-- 
1.7.10.4


More information about the wine-patches mailing list