[cairo] semantics of cairo_copy()

Bill Spitzak spitzak at d2.com
Wed Feb 16 13:13:18 PST 2005



Carl Worth wrote:

> I don't see any problem with line width. In cairo, already, the CTM
> used to construct the path can be totally different than the CTM used
> for the line width. So the only missing piece is the ability to
> change the CTM during path construction and easily restore the
> original CTM.

 > As for "locking" the line width based on the CTM at the time of
 > set_line_width, I don't think this is consistent. There are many
 > stroke parameters, (line_width, line_cap, line_join, dash,
 > miter_limit), and all of these are simply parameters that are set in
 > the gstate. All of these parameters just sit there until the call to
 > cairo_stroke at which time they are read and acted upon. So, I think
 > that that is the most reasonable time to run the line_width through
 > the CTM.

Yes, I believe your proposal will do what is necessary. It makes it 
possible for a program to draw transformed diagrams in fixed pen sizes 
while still taking advantage of Cairo's transforms. I'm not totally 
convinced of the consistency problems of my idea, but it certainly does 
not match PS or PDF (or possible SVG?) so that may make my idea unworkable.

My pessimistic example where my idea works best is if the program wants 
to stroke several shapes in different colors and in a skewed transform, 
but wants to have a circular pen. Imagine a program like Illustrator, 
where this is not uncommon. In my proposal this would be:

	set_line_width();
	gsave();
	  set_skewed_transform();
	  build_path_1();
	  set_color(1); stroke();
	  build_path_2();
	  set_color(2); stroke();
	grestore();

In your new API this would be:

	set_line_width();
	gsave();
	  set_skewed_transform();
	  build_path_1();
	grestore();
	set_color(1); stroke();
	gsave();
	  set_skewed_transform();
	  build_path_2();
	grestore();
	set_color(2); stroke();

If set_skewed_transform() is difficult or expensive to call twice, but 
you can save/restore the CTM, it can be done this way:

	set_line_width();
	CTM = get_ctm();
	set_skewed_transform();
	  CTM2 = get_ctm();
	  build_path_1();
	set_ctm(CTM);
	set_color(1); stroke();
	set_ctm(CTM2);
	  build_path_2();
	set_ctm(CTM);
	set_color(2); stroke();

PS: in general I am very happy with all your proposed API changes. In 
all cases where you disagree with me you have come up with a *better* 
solution!

>>The fill+stroke problem can be solved by not actually clearing the path 
>>after a fill until the next path-construction operator. Ie you can build 
>>a path and fill and stroke it as many times as you want.
> 
> That's a good idea. Doing it by default would force a *lot* of new
> calls to cairo_new_path. The refinement to this idea that has been
> proposed this week is to provide new versions of cairo_fill and
> cairo_stroke that do not clear the path. See the upcoming message:
> 
> 	API Shakeup: cairo_fill_preserve and cairo_stroke_preserve

I think your idea is fine, but I'm not sure you understood mine. What I 
meant is that any path-construction operator after a fill/stroke would 
do an implicit new-path. Basically the implicit new-path is moved from 
the fill/stroke to the first lineto, moveto, curveto, or similar call 
after it. I would think that most programs would not have to be changed 
at all for this. My proposal has the possible advantage that you don't 
have to support modifying the path after the fill/stroke, this may make 
implementation easier somehow?



More information about the cairo mailing list