Question about XRender specification

Carl Worth cworth at
Tue Apr 8 14:36:42 PDT 2008

On Tue, 08 Apr 2008 17:21:49 -0400, Peter Harris wrote:
> Helge Bahmann wrote:
> >> 				XRenderCompositeTrapezoids(display,
> >> 					PictOpOver, red_transp, picture, 0,
> >> 					0, 0, &trap, 2);
> >
> > the way you are calling, they are drawn independently, this means the first
> > trapezoid covers the pixel by 1/2, the second gets drawn over and now the
> > pixel is covered by 3/4 and NOT 1 !

No. The XRenderCompositeTrapezoids call pre-composes the trapezoids
together into a single mask, (with ADD I believe), and the uses that
as the mask for the Over operation being asked for here.

> > The solution is to use PictOpDisjointOver; possibly to have to composite your
> > figure into a temporary mask and then use this pre-composited shape in a
> > second rendering step

The XRenderAddTraps call can be used if you want to have an explicit
temporary mask, (though note that it uses a different trapezoid
specification, and also Keith just very recently fixed some bugs in
it). I don't think PictOpDisjointOver should ever be necessary,
(indeed, trapezoid rendering existed before that operator ever
did). But yes, it probably would work.

> Alternatively, you could specify a maskFormat other than NULL when you
> call XRenderCompositeTrapezoids.

That 0 there is odd, and I assume it must be a bug.

But even with that I wasn't able to replicate the original reported

I've attached my working program below. It uses an A8 format for the
maskFormat and I get seamless rendering with antialiasing on the outer
edges. If I use 0 there, I still get seamless rendering, but
non-antialiased outer edges, (which is what I would expect for an A1
format, so maybe that is what the 0 is being interpreted as).

Clemens, is there something very different in your test case compared
to mine?


PS. Ouch, it sure is painful to write programs that draw with Xrender
directly. I'm glad that I've got cairo to take care of these details
for me.

-------------- next part --------------
/* gcc -o argb_demo argb_demo.c -L/usr/X11R6/lib -lXrender -lX11 */
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrender.h>

#define WIDTH_DEFAULT 200
#define HEIGHT_DEFAULT 100

/* Naming a window shouldn't require specifying width/height, but
 * that's what Xlib makes us do here. */
static void
name_window (Display *dpy, Window win, int width, int height,
	     const char *name)
    XSizeHints *size_hints;
    XWMHints *wm_hints;
    XClassHint *class_hint;

    size_hints = XAllocSizeHints ();
    size_hints->flags = 0;
    size_hints->x = 0;
    size_hints->y = 0;
    size_hints->width = width;
    size_hints->height = height;

    wm_hints = XAllocWMHints ();
    wm_hints->flags = InputHint;
    wm_hints->input = True;

    class_hint = XAllocClassHint ();
    class_hint->res_name  = "argb-demo";
    class_hint->res_class = "ARGB-demo";

    Xutf8SetWMProperties (dpy, win, name, name, 0, 0,
			  size_hints, wm_hints, class_hint);
    XFree (size_hints);
    XFree (wm_hints);
    XFree (class_hint);

static void
draw (Display *dpy, Window win, Visual *visual,
      unsigned int width, unsigned int height)
    int off;
    XTrapezoid trap[2];
    Pixmap source_pix;
    Picture source, dest;
    XRenderPictureAttributes source_attr;
    XRenderColor red;
    XRenderPictFormat *rgb24_format, *a8_format;

    rgb24_format = XRenderFindStandardFormat (dpy, PictStandardRGB24);
    a8_format = XRenderFindStandardFormat (dpy, PictStandardA8);

    XClearWindow (dpy, win);

    source_attr.repeat = RepeatNormal;
    source_pix = XCreatePixmap (dpy, win, 1, 1, rgb24_format->depth);
    source = XRenderCreatePicture (dpy, source_pix,
				   CPRepeat, &source_attr);   = 0xffff; = 0;  = 0;
    red.alpha = 0xffff;
    XRenderFillRectangle (dpy, PictOpSrc, source, &red,
			  0, 0, 1, 1);

    dest = XRenderCreatePicture (dpy, win,
				 XRenderFindVisualFormat (dpy, visual),
				 0, NULL);

    trap[0].left.p1.x=30<<16; trap[0].left.p1.y=0<<16;
    trap[0].left.p2.x=20<<16; trap[0].left.p2.y=90<<16;
    trap[0].right.p1.x=XDoubleToFixed(100); trap[0].right.p1.y=0<<16;
    trap[0].right.p2.x=XDoubleToFixed(90); trap[0].right.p2.y=90<<16;

    trap[1].left.p1.x=XDoubleToFixed(100); trap[1].left.p1.y=0<<16;
    trap[1].left.p2.x=XDoubleToFixed(90); trap[1].left.p2.y=90<<16;
    trap[1].right.p1.x=160<<16; trap[1].right.p1.y=0<<16;
    trap[1].right.p2.x=150<<16; trap[1].right.p2.y=90<<16;

			       source, dest, a8_format,
			       0, 0, trap, 2);

    XRenderFreePicture (dpy, dest);
    XRenderFreePicture (dpy, source);
    XFreePixmap (dpy, source_pix);

    Display *dpy;
    int scr;
    Window win, root;
    Visual *visual;
    XSetWindowAttributes wattr;
    unsigned long wmask;
    unsigned int width  = WIDTH_DEFAULT;
    unsigned int height = HEIGHT_DEFAULT;
    int needs_redraw;

    dpy = XOpenDisplay (0);
    if (dpy == NULL) {
	fprintf(stderr, "Failed to open display: %s\n", XDisplayName(0));
	return 1;

    scr = DefaultScreen (dpy);
    root = RootWindow (dpy, scr);
    visual = DefaultVisual (dpy, scr);

    wattr.event_mask = ExposureMask | StructureNotifyMask;
    wattr.background_pixel = transparent;
    wattr.border_pixel = 0;
    wattr.colormap = XCreateColormap (dpy, root, visual, AllocNone);
    wmask = CWEventMask | CWBackPixel | CWBorderPixel | CWColormap;

    win = XCreateWindow (dpy, root, 0, 0, width, height, 0,
			 DefaultDepth (dpy, scr),
			 InputOutput, visual, wmask, &wattr);

    name_window (dpy, win, width, height, "Trap test");

    XSelectInput (dpy, win, KeyPressMask | StructureNotifyMask | ExposureMask);

    XMapWindow (dpy, win);

    needs_redraw = 1;

    while (1) {
	XEvent xev;

	if (! XPending (dpy) && needs_redraw) {
	    draw (dpy, win, visual, width, height);
	    needs_redraw = 0;

	XNextEvent (dpy, &xev);

	/* Quit on key press. */
	switch (xev.xany.type) {
	case KeyPress:
	    goto DONE;
	case ConfigureNotify:
	    width = xev.xconfigure.width;
	    height = xev.xconfigure.height;
	    /* fall-through */
	    needs_redraw = 1;

    XCloseDisplay (dpy);

    return 0;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <>

More information about the xorg mailing list