[cairo] New API: cairo_{push,pop}_group and friends

Carl Worth cworth at cworth.org
Thu May 4 03:25:06 PDT 2006


It's been discussed recently, and now it has finally landed in cairo's
tree. Hurray! the push-pop-group stuff is in cairo now.

For anyone that isn't aware, this is a very convenient interface for
doing intermediate compositing. This is a similar notion to that of an
SVG group (and the group opacity attribute) or to what PDF calls a
transparency group (and its knockout semantics).

One common use for this API is to render multiple shapes to the
intermediate (off-screen) surface in an opaque fashion, so that they
occlude each other. Then the results can be blended onto the
destination with some alpha as a single group.

Way back before 1.0 we had an API for this, and I've been missing it
ever since. (The original API had some bad semantics, so it really was
a good thing we removed it when we did.) Owen Taylor was very helpful
in coming up with the improved semantics. I made a preliminary patch
sometime ago, and Vladimir Vukicevic did the hard work of completing
it and patiently waiting for me to finally get around to reviewing and
applying it.

I had thought that this work wouldn't really be interesting until we
added support for "growable" surfaces, (so the intermediate surface
could start off consuming no memory and grow only as large as needed
for what was rendered to it). Vladimir took a much simpler
approach---the intermediate surface is created at the size of the
current clip extents. So, as long as the user of this API knows the
final size of the group in advance, the current implementation can
still be quite efficient.

Here is what the new API looks like:

	cairo_public void
	cairo_push_group (cairo_t *cr);
 
	cairo_public void
	cairo_push_group_with_content (cairo_t *cr, cairo_content_t content);

	cairo_public cairo_pattern_t *
	cairo_pop_group (cairo_t *cr);

	cairo_public void
	cairo_pop_group_to_source (cairo_t *cr);

	cairo_public cairo_surface_t *
	cairo_get_group_target (cairo_t *cr);

There's still some documentation missing, but I'll go ahead and add
that soon. In the meantime, all of the above has now been pushed out
to cairo's master branch.

I do have a couple of questions/comments which might still result in a
change to the API above.

Vladimir, I noticed that your push-pop-group changes the
get_group_target API to also return the offset of the intermediate
surface. Should that patch be pushed out? (It looks like the rest of
your mozilla branch doesn't actually base off of it).

Second, I wonder if we even need to have cairo_get_group_target.
Couldn't we just specify cairo_get_target as returning the current
target, (so group target if there is a group in effect, and the same
behavior as today if not)? Surely any code that does group rendering
could save the original target if it would be needed during the group
rendering.

Second, if the group target offset information is necessary, (which I
imagine it is), can't some existing mechanism provide access to it? I
haven't looked to see how that offset is implemented, but is it in
some "special" place that is neither the pattern transformation,
(where cairo_pattern_get_matrix could be used to fetch it), nor the
device offset (where cairo_surface_get_device_offset could be used?

Oh, I guess that does point out that we are currently missing a way to
get the surface out of a surface pattern. Now that we've got the
pattern_get_type stuff, I think we could add calls such as:

	cairo_public cairo_surface_t *
	cairo_surface_pattern_get_surface (cairo_pattern_t *pattern);

	cairo_public void
	cairo_solid_pattern_get_rgba (cairo_pattern_t *pattern,
				      double *r, double *g, double *b, double *a);

	/* cairo_linear_pattern_get_something ? */
	/* cairo_radial_pattern_get_something ? */
	/* cairo_gradient_pattern_get_color_stops ? */

Anyway, if there's not an easy way to reuse existing functions, then
adding the new cairo_get_group_target is fine. But I would like to
know that we have explored those options first.

-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/20060504/e7a09791/attachment.pgp


More information about the cairo mailing list