[cairo] API Shakeup: cairo_fill_preserve, cairo_stroke_preserve,
cairo_clip_preserve
Carl Worth
cworth at cworth.org
Tue Feb 15 22:07:45 PST 2005
As has recently been discussed, it would be quite convenient to be
able to write functions that can append to the current path. Things
like:
void
logo_path (cairo_t *cr)
{
cairo_save (cr);
/* Muck with CTM, and draw logo here. */
cairo_restore (cr);
}
With the current implementation, a function written as above will not
work as the logo path will be destroyed at the call to cairo_restore.
To avoid this, the function can be re-written without
cairo_save/restore, but then it's a pain to write as the user must
manually save and restore the CTM, (and use a local variable for
this).
There has been a good proposal to solve this problem by moving the
path out of the graphics state, (eg. it will not be affected by
cairo_save/restore). The problem with this approach is that it would
break the (admittedly awkward) idiom for filling/stroking the same
path:
cairo_save (cr);
/* set source for fill */
cairo_fill (cr);
cairo_restore (cr);
/* set source for stroke */
cairo_stroke (cr);
We propose to address this problem by introducing two new variants of
cairo_fill and cairo_stroke that do not consume the current path:
/* Like cairo_fill, but preserve the path after the fill. */
void
cairo_fill_preserve (cairo_t *cr);
/* Like cairo_stroke, but preserve the path after the stroke. */
void
cairo_stroke_preserve (cairo_t *cr);
We do this by adding two new drawing operations rather than changing
the behavior of cairo_fill/stroke to always preserve in order to avoid
having to call cairo_new_path in the common case after most calls to
cairo_fill/stroke.
With this new API, the fill-then-stroke idiom becomes:
/* set source for fill */
cairo_fill_preserve (cr);
/* set source for stroke */
cairo_stroke (cr);
which I think we can all agree is much cleaner.
Also, this approach provides a great opportunity for eliminating
another source of confusion from the API. Currently, cairo_clip does
not consume the path, (since if it did, wrapping it in
cairo_save/restore to prevent this would make the call to cairo_clip
do nothing).
Instead, we can make cairo_clip consume the path, and also add:
/* Like cairo_clip, but preserve the path after the clip. */
void
cairo_clip_preserve (cairo_t *cr);
Which provides nice consistency, and allows us to avoid having to add
a phrase to the documentation such as "this can cause unexpected
behavior" like the PostScript manual has when describing the
non-path-consumption behavior of the clip operator.
-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/21adaadd/attachment.pgp
More information about the cairo
mailing list