[cairo] Adventures in line widths and font sizes

Bill Spitzak spitzak at d2.com
Fri Sep 1 11:15:04 PDT 2006


Having been doing some more work with cairo, I am getting increasingly 
frustruated with the total uselessness of the PostScript model of 
scaling the pen and font. As pointed out before, it is very difficult to 
draw an ellipse with a circular pen (though not impossible), and this is 
leading people to suggest adding more drawing primitives, which I do not 
think is a good idea. I have found it completly impossible to use 
cairo's transformations due to this, it is far easier to transform all 
my own coordinates using my own transform matrix stack. I believe this 
is true of every program that attempts to use cairo, and that the 
transformation stack is probably not being used by any non-demo programs 
except to translate.

Carl suggested this before for pens, and I have also been very 
interested in this working for fonts and suggested that as well. Carl 
was considering this for the most recent version of cairo but dropped it 
  because of worries about it introducing bugs. It does seem the 
consensus is that the current cairo scheme is so useless that there is 
no worry about incompatability, since no sensible program is relying on 
the current behavior. So I would very much like to see this reconsidered 
for the next version.

The basic idea is that at the moment you specify *any* source for the 
compositing operation (ie a pen, a font, a path, the source pattern, or 
anything else) everything is frozen in device space, by compositing 
together the arguments passed to cairo and the current transformation 
matrix. Changing the transformation matrix after that has no effect.

Querying any piece of information will do an inverse-transform to report 
it in the current transform, so that if you then feed the information 
back to Cairo at that moment you will get the same state (if you ignore 
rounding errors).

The primary advantage of this is that an illustrator-type program can 
use the cairo transforms for making line drawings and for labeling 
vertices. Currently this is *impossible* except by leaving the transform 
at the identity and doing all the transforms itself.

Other advantages are:

* It is much easier to draw ellipses and rounded corners

* it makes elliptical pens (which cairo already has all the code to do) 
usable

* it matches the OpenGL and DirectX api and thus probably matches the 
hardware better

* that I think it is impossible to make a "3D cairo" unless this rule 
applies, since a 3D transformation cannot be applied in any useful way 
to a pen or font, all possible interpretations are trivial to reproduce 
with a texture map of the 2D drawing, while desirable effects such as 3D 
fixed-weight line drawings are quite impossible.

* The path, pattern, and clip interface to cairo already act this way so 
this is more consistent.

* The implementation may be simpler and faster (because the 
non-device-space representation can be thrown away).

The only disadvantage I can see is that this is incompatable with 
PostScript. Converting cairo to PostScript and/or pdf will require doing 
all the transformations and ignoring the postscript transform stack.

The only api change would be that pens could be specified as a 2x2 
matrix, the transform of a 1-diameter circle by this matrix would be the 
pen.

Any chance of this idea reappearing?

The addition of this and a "hairline mode" for stroke would instantly 
reduce the amount of interface code between our stuff and cairo by a 
factor of 10 or more, I think.

Carl Worth wrote:

> But, the ambiguity is the precise meaning of "user space" in the
> documentation above. Currently, the implementation is using the user
> space at the time of cairo_stroke. I contend that that is a bug and
> that cairo_set_line_width should use the current user space at the
> time of that call.
> 
> Changing this behavior would make cairo_set_line_width consistent with
> things like cairo_set_source that "lock" the current CTM regardless of
> the fact that the source pattern will actually be used by some later
> drawing operation that is operating under a different user space.



More information about the cairo mailing list