[cairo] Re: On copying graphics state and path between contexts (was: cairo reset)

Mike Emmel mike.emmel at gmail.com
Fri Sep 22 11:48:23 PDT 2006

On 9/22/06, Carl Worth <cworth at cworth.org> wrote:
> On Fri, 22 Sep 2006 08:49:19 -0700, "Mike Emmel" wrote:
> > Finally of course there is no efficient way to copy the path between cairo_t's
> > In general one programing style I'd love to use is to create a cairo_t
> > thats  abstract
> > and not attached to a real surface ( I do this now with a 1,1 image
> > surface ) then
> > use it as a template for a real surface.  save  and restors on the template path
> > should protect it from modification.
> First, I think it's important to point out the separation between the
> (stacked) graphics state and the path within the cairo_t context. The
> graphics state does _not_ include the path, and the graphics state
> exists on a stack which can be manipulated with cairo_save and
> cairo_restore.
> The path is separate from the graphics state, and is unaffected by
> the cairo_save and cairo_restore operations.
> Currently, one can copy the path from one context to another with
> cairo_copy_path and cairo_append_path. Those two function calls do do
> some conversion in addition to copying. I'd be glad to consider a
> proposal for more direct copying of a path from one context to another
> along with some direct evidence that the conversion of
> copy/append_path is causing a "real-world" performance problem.
> As for copying the graphics state, most of it can be copied now in a
> piecemeal fashion, with the various get/set functions, (and hopefully
> with Vlad's recent addition of various get functions it's now possible
> to copy all of the graphics state). Admittedly, that's not a very
> convenient thing to do, and we've had proposals (and even
> implementations) for things like cairo_copy and
> cairo_save/restore_state.
> The cairo_save_state/cairo_restore_state proposal was the most recent
> and I rather liked it:
> http://lists.freedesktop.org/archives/cairo/2006-January/006187.html
> But the discussion pretty much stopped right after that when Owen
> asked for a non-trivial use case for the new API and nobody ever
> offered one:
> http://lists.freedesktop.org/archives/cairo/2006-January/006193.html
> > cairo_set_destination_surface(cairo_t* template,cairo_surface_t* dest);
> Before cairo 1.0 we did have a way to change the destination
> surface...
> > cairo_save(cr)
> > cairo_set_destination_surface(cr,dest);
> > cairo_restor(cr); //restores cr to last state.
> and we did have the destination surface as part of the graphics state
> manipulated with save/restore.
> We found there was some dramatic conceptual simplification when we
> eliminated the ability to change the destination surface and made that
> instead an immutable property of a cairo_t context.
> One example of the confusion is the strong dependence of a some
> elements of the graphics state (such as the transformation matrix) on
> the destination surface. For instance, should switching a
> screen-display surface to a PDF surface also change to the default,
> identity transformation matrix?  Should it reset other parts of the
> graphics state?
> It's much more obvious how things work when a separate context, with
> its own graphics state is used for each separate destination surface.

Then maybe we need a abstract container for all this information
that can hold it in internal form so we can set up a cairo_t.

This would be a public version of gstate minus maybe some surface
dependent bits.
cairo_gstate_t* cairo_get_gstate(cr);
We already have this with path the public path is not the same as the
private path
but similar.

> As for the need to create a 1x1 dummy surface to do some cairo
> operations that don't require a destination surface, that is a bit
> annoying. We've been improving this in some ways by the addition of
> things like cairo_scaled_font_text_extents so that it's now possible
> to measure text and know how big the destination surface will need to
> be, without having to create a dummy surface for the measurement.
> Path construction does still require a surface, but I don't see that
> as nearly as much of a problem, (though it might still be necessary to
> use a dummy surface to measure the extents of a path before creating a
> surface that will cache a rendering of it). But cairo really isn't
> trying to provide data structures for holding on to and manipulating
> paths. So I think it would be a mistake to add a bunch of API calls
> that would give that appearance. Users of cairo really should use
> their own structures for holding on to their own geometry and should
> simply create paths in cairo at the they are ready to draw them.
Except then you have to replicate a ton of operations that cairo already
knows how to do. In fact you replicate a good bit of the cairo api with
your custom path implementation which may be buggy and differ from
someone  elses. Why should I have to implement cairo_rel_curve_to myself
you did a good job. I don't want to replicate it.

As far as showing a performance problem just grab the famous tiger and
copy its path a bunch of times and draw it to different surfaces.
A real world example is svg fonts. If we could do a good job with paths
then using svg fonts over truetype is compelling.

 The internal fixed point representation is good stuff.
I don't want to covert back and forth from the external form.

Hit detection for example.

> -Carl

More information about the cairo mailing list