gdiplus: Include an alpha channel in HBITMAPs created from Bitmaps.

Vincent Povirk vincent at codeweavers.com
Mon Oct 3 09:22:23 CDT 2011


For bug 25549.
-------------- next part --------------
From e1fcb02c48ae2bd397da1ed60319eda8eb1ff445 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Thu, 29 Sep 2011 11:58:17 -0500
Subject: [PATCH] gdiplus: Include an alpha channel in HBITMAPs created from Bitmaps.

---
 dlls/gdiplus/image.c       |   26 +++++++++--------------
 dlls/gdiplus/tests/image.c |   49 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index fe1656f..4ae1d64 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -1370,12 +1370,12 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
     HBITMAP* hbmReturn, ARGB background)
 {
     GpStatus stat;
-    HBITMAP result, oldbitmap;
+    HBITMAP result;
     UINT width, height;
     HDC hdc;
-    GpGraphics *graphics;
     BITMAPINFOHEADER bih;
-    void *bits;
+    LPBYTE bits;
+    BitmapData lockeddata;
     TRACE("(%p,%p,%x)\n", bitmap, hbmReturn, background);
 
     if (!bitmap || !hbmReturn) return InvalidParameter;
@@ -1398,25 +1398,19 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
     hdc = CreateCompatibleDC(NULL);
     if (!hdc) return GenericError;
 
-    result = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, &bits,
+    result = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&bits,
         NULL, 0);
 
     if (result)
     {
-        oldbitmap = SelectObject(hdc, result);
-
-        stat = GdipCreateFromHDC(hdc, &graphics);
-        if (stat == Ok)
-        {
-            stat = GdipGraphicsClear(graphics, background);
+        lockeddata.Stride = -width * 4;
+        lockeddata.Scan0 = bits - (lockeddata.Stride * (height - 1));
 
-            if (stat == Ok)
-                stat = GdipDrawImage(graphics, (GpImage*)bitmap, 0, 0);
+        stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead|ImageLockModeUserInputBuf,
+            PixelFormat32bppPARGB, &lockeddata);
 
-            GdipDeleteGraphics(graphics);
-        }
-
-        SelectObject(hdc, oldbitmap);
+        if (stat == Ok)
+            stat = GdipBitmapUnlockBits(bitmap, &lockeddata);
     }
     else
         stat = GenericError;
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 77aec93..44554a5 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -1514,6 +1514,12 @@ static void test_createhbitmap(void)
         expect(32, bm.bmBitsPixel);
         ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
 
+        if (bm.bmBits)
+        {
+            DWORD val = *(DWORD*)bm.bmBits;
+            ok(val == 0xff686868, "got %x, expected 0xff686868\n", val);
+        }
+
         hdc = CreateCompatibleDC(NULL);
 
         oldhbitmap = SelectObject(hdc, hbitmap);
@@ -1529,6 +1535,49 @@ static void test_createhbitmap(void)
 
     stat = GdipDisposeImage((GpImage*)bitmap);
     expect(Ok, stat);
+
+    /* create alpha Bitmap */
+    stat = GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB, bits, &bitmap);
+    expect(Ok, stat);
+
+    /* create HBITMAP */
+    stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
+    expect(Ok, stat);
+
+    if (stat == Ok)
+    {
+        ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
+        expect(sizeof(BITMAP), ret);
+
+        expect(0, bm.bmType);
+        expect(8, bm.bmWidth);
+        expect(20, bm.bmHeight);
+        expect(32, bm.bmWidthBytes);
+        expect(1, bm.bmPlanes);
+        expect(32, bm.bmBitsPixel);
+        ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
+
+        if (bm.bmBits)
+        {
+            DWORD val = *(DWORD*)bm.bmBits;
+            ok(val == 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val);
+        }
+
+        hdc = CreateCompatibleDC(NULL);
+
+        oldhbitmap = SelectObject(hdc, hbitmap);
+        pixel = GetPixel(hdc, 5, 5);
+        SelectObject(hdc, oldhbitmap);
+
+        DeleteDC(hdc);
+
+        expect(0x2a2a2a, pixel);
+
+        DeleteObject(hbitmap);
+    }
+
+    stat = GdipDisposeImage((GpImage*)bitmap);
+    expect(Ok, stat);
 }
 
 static void test_getthumbnail(void)
-- 
1.7.4.1


More information about the wine-patches mailing list