winex11.drv: Implement FIXME in AlphaBlend

View: New views
1 Messages — Rating Filter:   Alert me  

winex11.drv: Implement FIXME in AlphaBlend

by Peter Urbanec :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Resubmit of my earlier patch that implements the missing case of
SourceConstantAlpha combined with source alpha.


commit d7b323719e42cbd3c4972b48c5540dfad9d971bf
Author: Peter Urbanec <winehq.org@...>
Date:   Sun Nov 8 14:31:54 2009 +1100

    Implement AlphaBlend mode for the case where SourceConstantAlpha is combined with source alpha.

diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index 005296b..e1ce393 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -1956,9 +1956,6 @@ BOOL CDECL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT wid
         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;
@@ -1977,13 +1974,37 @@ BOOL CDECL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT wid
         y2 = y - heightSrc + 1;
     }
 
-    if (blendfn.AlphaFormat & AC_SRC_ALPHA)
+    if(blendfn.AlphaFormat & AC_SRC_ALPHA)
     {
-        for(; y >= y2; y--)
+        if(blendfn.SourceConstantAlpha == 0xff)
+        {
+            for(; y >= y2; y--)
+            {
+                memcpy(dstbits, (char *)dib.dsBm.bmBits + y * dib.dsBm.bmWidthBytes + xSrc * 4,
+                       widthSrc * 4);
+                dstbits += (top_down ? -1 : 1) * widthSrc;
+            }
+        }
+        else
         {
-            memcpy(dstbits, (char *)dib.dsBm.bmBits + y * dib.dsBm.bmWidthBytes + xSrc * 4,
-                   widthSrc * 4);
-            dstbits += (top_down ? -1 : 1) * widthSrc;
+            /* SourceConstantAlpha combined with source alpha */
+            for(; y >= y2; y--)
+            {
+                int x;
+                DWORD *srcbits = (DWORD *)((char *)dib.dsBm.bmBits + y * dib.dsBm.bmWidthBytes) + xSrc;
+                for(x = 0; x < widthSrc; x++)
+                {
+                    DWORD argb = *srcbits++;
+                    BYTE *s = (BYTE *) &argb;
+                    s[0] = (s[0] * blendfn.SourceConstantAlpha) / 255;
+                    s[1] = (s[1] * blendfn.SourceConstantAlpha) / 255;
+                    s[2] = (s[2] * blendfn.SourceConstantAlpha) / 255;
+                    s[3] = (s[3] * blendfn.SourceConstantAlpha) / 255;
+                    *dstbits++ = argb;
+                }
+                if(top_down)  /* we traversed the row forward so we should go back by two rows */
+                    dstbits -= 2 * widthSrc;
+            }
         }
     }
     else
@@ -1994,16 +2015,15 @@ BOOL CDECL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT wid
         for(; y >= y2; y--)
         {
             DWORD *srcbits = (DWORD *)((char *)dib.dsBm.bmBits + y * dib.dsBm.bmWidthBytes) + xSrc;
-            for (x = 0; x < widthSrc; x++)
+            for(x = 0; x < widthSrc; x++)
             {
                 DWORD argb = *srcbits++;
-                argb = (argb & 0xffffff) | source_alpha;
+                argb = (argb & 0x00ffffff) | source_alpha;
                 *dstbits++ = argb;
             }
-            if (top_down)  /* we traversed the row forward so we should go back by two rows */
+            if(top_down)  /* we traversed the row forward so we should go back by two rows */
                 dstbits -= 2 * widthSrc;
         }
-
     }
 
     dst_pict = get_xrender_picture(devDst);