Huw Davies : gdiplus: Blend in the background colour.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Oct 29 07:36:57 CDT 2014


Module: wine
Branch: master
Commit: 6df5ce7c9ef947df265c389859dc11977ddcf46b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6df5ce7c9ef947df265c389859dc11977ddcf46b

Author: Huw Davies <huw at codeweavers.com>
Date:   Tue Oct 28 16:28:47 2014 +0000

gdiplus: Blend in the background colour.

---

 dlls/gdiplus/image.c       | 23 ++++++++++++
 dlls/gdiplus/tests/image.c | 91 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 0564f33..eec76f6 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -1483,6 +1483,18 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromResource(HINSTANCE hInstance,
     return stat;
 }
 
+static inline DWORD blend_argb_no_bkgnd_alpha(DWORD src, DWORD bkgnd)
+{
+    BYTE b = (BYTE)src;
+    BYTE g = (BYTE)(src >> 8);
+    BYTE r = (BYTE)(src >> 16);
+    DWORD alpha  = (BYTE)(src >> 24);
+    return ((b     + ((BYTE)bkgnd         * (255 - alpha) + 127) / 255) |
+            (g     + ((BYTE)(bkgnd >> 8)  * (255 - alpha) + 127) / 255) << 8 |
+            (r     + ((BYTE)(bkgnd >> 16) * (255 - alpha) + 127) / 255) << 16 |
+            (alpha << 24));
+}
+
 GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
     HBITMAP* hbmReturn, ARGB background)
 {
@@ -1523,6 +1535,17 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
 
         if (stat == Ok)
             stat = GdipBitmapUnlockBits(bitmap, &lockeddata);
+
+        if (stat == Ok && (background & 0xffffff))
+        {
+            DWORD *ptr;
+            UINT i;
+            for (ptr = (DWORD*)bits, i = 0; i < width * height; ptr++, i++)
+            {
+                if ((*ptr & 0xff000000) == 0xff000000) continue;
+                *ptr = blend_argb_no_bkgnd_alpha(*ptr, background);
+            }
+        }
     }
     else
         stat = GenericError;
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index b88238b..fe80bd6 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -1695,6 +1695,10 @@ static void test_createhbitmap(void)
     stat = GdipDisposeImage((GpImage*)bitmap);
     expect(Ok, stat);
 
+    /* make (1,0) have no alpha and (2,0) a different blue value. */
+    bits[7] = 0x00;
+    bits[8] = 0x40;
+
     /* create alpha Bitmap */
     stat = GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB, bits, &bitmap);
     expect(Ok, stat);
@@ -1720,21 +1724,106 @@ static void test_createhbitmap(void)
         {
             DWORD val = *(DWORD*)bm.bmBits;
             ok(val == 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val);
+            val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
+            ok(val == 0x0, "got %x, expected 0x682a2a2a\n", val);
         }
 
         hdc = CreateCompatibleDC(NULL);
 
         oldhbitmap = SelectObject(hdc, hbitmap);
         pixel = GetPixel(hdc, 5, 5);
+        expect(0x2a2a2a, pixel);
+        pixel = GetPixel(hdc, 1, 0);
+        expect(0x0, pixel);
+
         SelectObject(hdc, oldhbitmap);
 
         DeleteDC(hdc);
 
-        expect(0x2a2a2a, pixel);
 
         DeleteObject(hbitmap);
     }
 
+    /* create HBITMAP with bkgnd colour */
+    stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0xff00ff);
+    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 == 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val);
+            val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
+            ok(val == 0xff00ff, "got %x, expected 0x682a2a2a\n", val);
+        }
+
+        hdc = CreateCompatibleDC(NULL);
+
+        oldhbitmap = SelectObject(hdc, hbitmap);
+        pixel = GetPixel(hdc, 5, 5);
+        expect(0xc12ac1, pixel);
+        pixel = GetPixel(hdc, 1, 0);
+        expect(0xff00ff, pixel);
+        pixel = GetPixel(hdc, 2, 0);
+        expect(0xb12ac1, pixel);
+
+        SelectObject(hdc, oldhbitmap);
+        DeleteDC(hdc);
+        DeleteObject(hbitmap);
+    }
+
+    /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
+    stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0x80ff00ff);
+    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 == 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val);
+            val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
+            ok(val == 0xff00ff, "got %x, expected 0x682a2a2a\n", val);
+        }
+
+        hdc = CreateCompatibleDC(NULL);
+
+        oldhbitmap = SelectObject(hdc, hbitmap);
+        pixel = GetPixel(hdc, 5, 5);
+        expect(0xc12ac1, pixel);
+        pixel = GetPixel(hdc, 1, 0);
+        expect(0xff00ff, pixel);
+        pixel = GetPixel(hdc, 2, 0);
+        expect(0xb12ac1, pixel);
+
+        SelectObject(hdc, oldhbitmap);
+        DeleteDC(hdc);
+        DeleteObject(hbitmap);
+    }
+
     stat = GdipDisposeImage((GpImage*)bitmap);
     expect(Ok, stat);
 }




More information about the wine-cvs mailing list