[cairo] using cairo_stroke_preserve with transparent color

M Joonas Pihlaja jpihlaja at cc.helsinki.fi
Mon May 24 21:56:55 PDT 2010


On Mon, 24 May 2010, ds wrote:

> Is there any standard way to draw a transparent path with a line width
> and make inbetween displaying?

I think you're asking "how can I stroke and fill a path in a way that 
the stroked part of the path doesn't bleed into the filled part", 
right?

The basic approach is to use a temporary surface where you first 
stroke your border and then fill in a way that _overwrites_ the filled 
parts rather than merges the colours.  Then you composite the 
temporary surface to your target surface.  Here's an example:

cairo_push_group(cr);  /* creates the temporary surface. */
{
	<add your path using move_to, line_to, etc.>

	<set the stroke colour, possibly with alpha>
	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
	cairo_stroke_preserve(cr);

	<set the fill colour, possibly with alpha>
	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
	cairo_fill(cr);
}
cairo_pop_group_to_source(cr);
cairo_paint(cr); /* composites the temporary surface to the target */

You can avoid the temporary surfaces if you can use 
CAIRO_OPERATOR_SOURCE for all your path rendering (although internally 
cairo will probably use temporary surfaces, so this is a coin toss.)

You _may_ get faster results if the stroke and fill colours have
the same alpha, like this:

cairo_push_group(cr);
{
	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);

	<add your path using move_to, line_to, etc.>

	<set the opaque stroke colour, no alpha>
	cairo_stroke_preserve(cr);

	<set the opaque fill colour, no alpha>
	cairo_fill(cr);
}
cairo_pop_group_to_source(cr);
cairo_paint_with_alpha(cr, <the alpha>);

A third method which sometimes works is to use cairo_clip() to clip 
out the inside of the path which shouldn't interact with the stroke 
before you stroke.

Hope that was actually what you were looking for. :)

Cheers,

Jooans


More information about the cairo mailing list