Bug 14232

Summary: XftDrawRect buggy when Render not supported
Product: xorg Reporter: Brice Goglin <brice.goglin>
Component: Lib/XftAssignee: Xorg Project Team <xorg-team>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium    
Version: 7.3 (2007.09)   
Hardware: Other   
OS: All   
URL: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=462262
i915 platform: i915 features:
Bug Depends on:    
Bug Blocks: 10101    

Description Brice Goglin 2008-01-24 10:30:24 UTC
Bug reported by Marc Lehmann on the Debian BTS. He's using Xft but I don't see any commit that could have fixed this since then. He says:

XftDrawRect works differently when the alpha channel is < 32768 depending on wether the server supports the Render extension or not.

First of all, it is documented to "fill a solid rectangle". This is the actual behaviour when the server supports Render: the pixel value (including alpha channel) is taken as it is and the destination rectangle will be filled with the value:

        XRenderFillRectangle (draw->dpy, PictOpSrc, draw->render.pict,
                              &color->color, x, y, width, height);

(pictopsrc is documented to just copy all four channels (rgba) from source to destination).

However, when the Render extension is not supported by the server, the behaviour is different: when the alpha value is >= 32768, then the rectangle will be filled with the pixel value as-is (which is the correct behaviour), otherwise _NOTHING_ will be done:

    if (color->color.alpha >= 0x8000)
        XSetForeground (draw->dpy, draw->core.gc, color->pixel);
        XFillRectangle (draw->dpy, draw->drawable, draw->core.gc,
                        x, y, width, height);

This makes xftdrawrect unsuitable for the purpose it was actually created for: filling the background to some defined value. Regardless of what the purpose behind XftDrawRect, this is completely different behaviour depending on wether the server supports Render or not.

(for example, when xftdrawrect'ing a 100% transparent red over a newly allocated and uncleared pixmap will result in that pixmap being filled with 100% transparent red when the server supports Render, and with retaining the garbage it contained when the server doesn't support Render).

The fix is to always call xfillrectangle even for partly transparent
colours, resulting in the same behaviour regardless of the availability of
Comment 1 Adam Jackson 2008-03-24 09:12:11 UTC
Fixed in git, thanks!

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.