winex11.drv: Support GdiAlphaBlend with blendfn.AlphaFormat == 0 (2nd try, fixes bug #9262)

Mikolaj Zalewski mikolajz at google.com
Wed Aug 29 13:18:04 CDT 2007


I'm not sure if I understood how it's supposed to look like. Is
something like this good? It adds an 'if' in the inner loop, but it's
an 'if' that is easy to predict and this version makes less memory
reads so maybe it will be better.

I've also added casting to LONGLONG as an integer overflow is another
option that will make us read outside of the bitmap.
-------------- next part --------------
From 5330504534681ce0b75da104f19d19de69d40eaf Mon Sep 17 00:00:00 2001
From: Mikolaj Zalewski <mikolaj at zalewski.pl>
Date: Wed, 29 Aug 2007 11:07:16 -0700
Subject: [PATCH] winex11.drv: Support GdiAlphaBlend with blendfn.AlphaFormat == 0 (fixes bug #9262)
---
 dlls/winex11.drv/xrender.c |   26 +++++++++++++++++++++-----
 1 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index 449c671..6172ed7 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -1572,14 +1572,17 @@ #endif
         return FALSE;
     }
 
-    if (xSrc < 0 || ySrc < 0 || widthSrc < 0 || heightSrc < 0 || xSrc + widthSrc > dib.dsBmih.biWidth
-        || ySrc + heightSrc > abs(dib.dsBmih.biHeight))
+    if (xSrc < 0 || ySrc < 0 || widthSrc < 0 || heightSrc < 0 || (LONGLONG)xSrc + widthSrc > dib.dsBmih.biWidth
+        || (LONGLONG)ySrc + heightSrc > abs(dib.dsBmih.biHeight))
     {
         WARN("Invalid src coords: (%d,%d), size %dx%d\n", xSrc, ySrc, widthSrc, heightSrc);
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
 
+    if ((blendfn.AlphaFormat & AC_SRC_ALPHA) && blendfn.SourceConstantAlpha != 0xff)
+        FIXME("Ignoring SourceConstantAlpha %d for AC_SRC_ALPHA\n", blendfn.SourceConstantAlpha);
+
     if(dib.dsBm.bmBitsPixel != 32) {
         FIXME("not a 32 bpp dibsection\n");
         return FALSE;
@@ -1598,9 +1601,22 @@ #endif
         y2 = y - heightSrc + 1;
     }
     for(; y >= y2; y--) {
-        memcpy(dstbits, (char *)dib.dsBm.bmBits + y * dib.dsBm.bmWidthBytes + xSrc * 4,
-               widthSrc * 4);
-        dstbits += (top_down ? -1 : 1) * widthSrc * 4;
+        char *srcbits = (char *)dib.dsBm.bmBits + y * dib.dsBm.bmWidthBytes + xSrc * 4;
+        int source_alpha = ((DWORD)blendfn.SourceConstantAlpha) << 24;
+        int x;
+
+        for (x = 0; x < widthSrc; x++)
+        {
+            DWORD argb = *(DWORD *)srcbits;
+
+            if (!(blendfn.AlphaFormat & AC_SRC_ALPHA))
+                argb = (argb & 0xffffff) | source_alpha;
+            *(DWORD *)dstbits = argb;
+            srcbits += 4;
+            dstbits += 4;
+        }
+        if (top_down)  /* we traversed the row forward so we should go back by two rows */
+            dstbits -= 2 * widthSrc * 4;
     }
 
     wine_tsx11_lock();
-- 
1.4.1


More information about the wine-patches mailing list