[cairo] Bug with paint_with_alpha and perf issues when compositing with SOURCE

Owen Taylor otaylor at redhat.com
Tue May 27 06:11:17 PDT 2008

On Thu, 2008-05-01 at 03:34 -0400, Antoine Azar wrote:
> Hey all,
> I discussed this already with cworth and am looking for feedback on
> this issue.
> paint_with_alpha will return an "incorrect" result when used with a
> SOURCE operator. According to the doc, paint_with_alpha is "A drawing
> operator that paints the current source everywhere within the current
> clip region using a mask of constant alpha value alpha. The effect is
> similar to cairo_paint(), but the drawing is faded out using the alpha
> value."
> So doing the following:
> cairo_set_source_rgb (cr, 0.2, 0.6, 0.9);
> cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
> cairo_paint_with_alpha (cr, 0.5);
> Should return a blueish color with a 0.5 alpha all over the surface
> with no more trace of the previous contents. Currently, the blueish
> color is being composited like an OVER operator. This is because we
> avoid the SOURCE operator and replace it to accomodate different
> backends. So we implement our own definition of SOURCE which is:
> (src IN mask IN clip) ADD (dst OUT (mask IN
> clip))                      //see _clip_and_composite_source in
> cairo-surface-fallback.c
> According to the doc, in the paint_with_alpha case, this definition
> should actually be:
> (src IN mask IN clip) ADD (dst OUT clip)

Which doc is this? 

Original discussion that led to the above code is:


(Subject: Redoing SOURCE and CLEAR, Date: 2005-08-17. The main cairo 
archives were not handling my posts OK at that time, so it's hard
to read things there.)

I can sort of see why you think that paint_with_alpha() should be
different ... there's an intuitive understanding of the operation as
"make the source partially transparent and then paint it"... but that's
not how it's defined. It's defined as painting with a uniform mask.
And the rendering equations in cairo for masks don't care whether a 50%
alpha is 50% alpha from anti-aliasing at the edge of a shape, or from

And so, for OPERATOR_SOURCE that means linear interpolation between the
source and destination depending on the alpha value.

It definitely would be a good idea to add a test for this to the test
suite and make sure that all the backends get it right. Seems an easy
thing to get wrong for the vector backends.

In terms of the performance: there's an obvious optimization missing 
where we create a temporary surface for mask IN clip even when there is
no surface clip (see _create_composite_mask_pattern()) but other than
that _clip_and_composite_source() doesn't look particularly slow to me.
It's a straight-forward two-pass rendering operation where both passes
can be hardware accelerated and are reasonably MMX accelerated in

- Owen

More information about the cairo mailing list