[cairo] Stroke and Fill
cworth at east.isi.edu
Wed Sep 1 07:06:21 PDT 2004
On Tue, 31 Aug 2004 23:02:21 -0400, Jose O Gonzalez wrote:
> If one uses colors with some transparency, or some
> compositing operation such as "add" say, one may want to do this
> so that there's no overdrawing of the stroking and filling -- ie. one
> may want to do this without overlapping the stroke and fill regions.
> Does Cairo's path rendering semantics have support
> for this? eg. if the context has stroke line-width set to a value > 0,
> will filling of the interior occur complementary to the corresponding
> stroke region?
Cairo does not provide a direct mechanism for this.
Like PostScript, it has independent stroke and fill operators, (although
PostScript doesn't have a similar problem since it has only opaque
PDF provides non-opaque paint and resolves this issue by providing
stroke, fill, and stroke-and-fill operators. I don't like this approach
as it then has independent operators set_stroke_color and
There is a not-too-difficult means of getting the desired effect with
cairo. The trick is to do the stroke and fill with opaque paint onto an
intermediate surface, and then use cairo_show_surface to composite that
intermediate result with the desired compositing operator.
One advantage to this approach is that it can be used for more general
effects than just overlapping stroke and fill. For example the following
image shows overlapping text, fill, and an image, all composited as a
That image was rendered by cairo through code in the libsvg-cairo
library. The relevant code is something like the following:
intermediate_surface = cairo_surface_create_similar (cairo_current_target_surface (cr),
cairo_set_target_surface (cr, intermediate_surface);
/* Draw all the overlapping objects here. */
/* Set up the compositing desired for the group */
cairo_set_alpha (cr, opacity);
cairo_show_surface (cr, intermediate_surface,
This is a bit of work, and I've been mulling over making this easier
with cairo, (via some sort of push_group/pop_group_function). We even
had such a thing at one point in time. Providing that kind of support in
cairo would have a few benefits:
1) The user wouldn't have to actually create/destroy the
2) The interface would not necessarily need the width/height of
the intermediate surface, but could automatically deal with
things as they were drawn.
3) There would likely be a way to simplify the matrix
handling. If you look at the actual code in libsvg-cairo,
you'll see that I actually have to set an identity matrix
just before calling cairo_show_surface. We could probably
eliminate the need for this extra manipulation with direct
group support in cairo.
Well, that was a long answer to a short question. But I hope it was helpful.
More information about the cairo