[cairo] Re: Filling and stroking an object with different color/alpha

Carl Worth cworth at cworth.org
Mon May 1 17:42:14 PDT 2006


On Mon, 01 May 2006 16:19:00 -0700, Christopher Barker wrote:
> 
> I had suspected as much, but had no idea how to do it. Thanks for the 
> pointers. However, while we're talking pie-in-the-sky, I wonder if the 
> "filling and stroking as distinct operations" approach is a bit dated. 
> It certainly has issues with alpha channels.
>
> My fantasy would be a fill_and_stroke call, that would do them both at 
> once.

If you compare PostScript and PDF you'll see that PostScript provides
separate fill and stroke operations while PDF provides fill, stroke,
and fill_and_stroke.

We looked at both of those when designing cairo. The big problem that
fill_and_stroke has is that you will of course want to do each with a
different color. So, in PDF you end up with a stroking color and a
non-stroking color, a stroking alpha and a non-stroking alpha
etc. It ends up over-complicating the rendering model and the
interfaces for only a modest benefit, in my view.

For example, instead of set_source, set_source_rgb, set_source_rgba,
and set_source_surface, we would have to have two variants of
each. And then we'd have to carefully specify which of the two sources
would be used by all the other operators besides fill and stroke,
(paint, mask, show_glyphs, etc.) which wouldn't actually be
obvious.

So that seems like the wrong direction to me.

Instead, with the the upcoming push/pop_group stuff, the code for
actually doing fill-and-stroke with the current model really isn't too
bad. For the uniform-alpha case, it would be:

	/* create path here */

	cairo_push_group (cr);
	{
	    cairo_set_source_rgb (cr, fr, fg, fb); /* fill color */
	    cairo_fill_preserve (cr);
	    cairo_set_source_rgb (cr, sr, sg, sb); /* stroke color */
	    cairo_stroke (cr);
	}
	cairo_pop_group_to_source (cr);

	cairo_paint_with_alpha (cr, alpha);

While the more general case might look something like this:

	/* create path here */

	cairo_push_group (cr);
	{
	    cairo_set_source_rgba (cr, fr, fg, fb, fa); /* fill color/alpha */
	    cairo_fill_preserve (cr);

	    cairo_set_source_rgba (cr, sr, sg, sb, sa); /* stroke color/alpha */

	    /* First subtract stroke from fill with DEST_OUT */
	    cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OUT);
	    cairo_stroke_preserve (cr);

	    /* Then add it back with ADD to avoid seams. */
	    cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
	    cairo_stroke (cr);
	}
	cairo_pop_group_to_source (cr);

	cairo_paint (cr);

That's totally untested, so it's probably wrong, (should it be using
some other source color for DEST_OUT ?). But hopefully it at least
shows the order of complexity here. (And just typing that makes me
excited to go start playing with vladimir's push-pop-group branch).

And these functions would be very easy to provide as a custom
fill_and_stroke operation in any layer that would be willing to accept
separate colors/patterns for the filling and stroking parts.

> By the way, what would happen with PDF and PS? do they support and 
> intermediate surface?

Cairo is designed so that any code that works for any backend will
work for all backends. So the result should look the same no matter
what. The only question with PS/PDF is whether the output is all
vector, or if there is some pre-rasterized content in there.

The way you get an intermediate surface is with
cairo_surface_create_similar. And at the moment, calling this on a
PS/PDF surface will give you an image surface (so, rasterized).

But, Emmanuel recently committed code to the SVG backend that returns a
meta-surface from create_similar. This does the same
operation-recording that the SVG/PS/PDF backends use already. So when
the meta-surface is used as a source, the recorded operations are
replayed to create vectors in the output.

I think there's just a minor bug that's preventing PS/PDF from using a
meta-surface for create_similar. It's definitely something we should
fix soon.

> Thanks for all your help.

You're quite welcome.

-Carl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20060501/02012c55/attachment-0001.pgp


More information about the cairo mailing list