[cairo] API Shakeup: cairo_begin_group, cairo_end_group, cairo_get_group

Carl Worth cworth at cworth.org
Wed Feb 16 05:24:31 PST 2005


On Wed, 16 Feb 2005 13:36:05 +0100, Øyvind Kolås wrote:
> I haven't
> thought this through completely, but I think adding another stack of
> states to the cairo context needs
> a lot of thinking through.

Yeah, I think I need to retract my proposal to lodge the group pattern
reference in the cairo context. Keith pointed out a fundamental
problem with this approach which is that the context will hold on to a
reference to the group "forever".

> -         void
> +         cairo_pattern_t *
>          cairo_begin_group (cairo_t *cr);

The problem with this is that the between begin_group and end_group
you have an pattern in a weird, quasi-initialized state. So it would
be invalid to use this object for anything, (which we could detect),
but it's just creating a trap for the user. 

> +       /* sets the current group */ 
> +       void
> +       cairo_set_group (cairo_t *cr, cairo_pattern_t *pattern);

There's no new function needed here. Once the user has a
cairo_pattern_t for a group the only useful operations will be either
cairo_set_source or cairo_mask.

So, to avoid the invalid object, and to still have a name that clearly
indicates the need to destroy the object, I propose the following:

	/* Begin creating a group. */
	void
	cairo_create_group_begin (cairo_t *cr);

	/* Begin creating a group with a specific format. */
	void
	cairo_create_group_begin_format (cairo_t *cr, cairo_format_t format);

	/* Complete the creation of a group, and return it. */
	cairo_pattern_t *
	cairo_create_group_end (cairo_t *cr);

With this, the user doesn't get a handle on the object until it is
valid.

It's a slightly weird interface in that we have a "split constructor"
and the two halves can appear distant in the code. The shared name of
"cairo_create" is intended to make this more clear.

And users can keep the two halves of the constructor close with:

	cairo_create_group_begin (cr);
	draw_my_group (cr, ...);
	group = cairo_create_group_end (cr);

And better languages than C can do this kind of thing quite nicely.

-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/20050216/b003ba2d/attachment.pgp


More information about the cairo mailing list