[cairo] Serious concerns about cairo
spitzak at d2.com
Wed Sep 27 10:23:57 PDT 2006
Bertram Felgenhauer wrote:
> Bill Spitzak wrote:
>> The biggest problem I have with Cairo is the fact that the pen and font
>> is changed by the current transform
> I don't see that as much of a problem. This is exactly what I need
> when I want to, say, transform an SVG and let the rendering be done by
> a different library (librsvg, say). I'd expect that to be a common
> use case.
As Behdad pointed out this will still work, as long as you set the pen
*after* doing the transform. Since the SVG interperter almost certainly
sets the pen as the first step, this will work with no changes.
In fact I suspect that NO Cairo programs, or even any PDF or PostScript
files, depend on the current behavior. It is possible to make a test in
Cairo to see if a program is depending on this: when doing a transform
by the matrix [a b c d x y] check if a*a+c*c!=1 || b*b+d*d!=1
(indicating it will distort a circular pen) and set a flag. Clear the
flag on any call to set the pen. And in stroke(), if the flag is set,
dump a warning message. See if any programs produce this warning.
I would also like the font transfromation to be fixed at the time it is
set. This is really useful in OpenGL for labelling objects in 3D space,
and would allow the same ability to use Cairo's transforms to label
things in 2D. I also suspect that this would simplify font handling
considerably. However I do think some programs rely on the current
behavior (mostly demos producing text swirls), but I feel this
incompatibility is worth it.
>> II. Proposed fix for "hairline" mode:
> I thought the main thing to figure out is that on an image surface
> with identity transform, (0,0) is the corner of a pixel and for lines
> you usually want to start at the center of a pixel instead.
This is really difficult since .5,.5 must be added to the path
coordinates in device space. You could use the cairo interface to
transform to device coordinates, then offset them, then use cairo to
transform back, then use cairo to set the coordinates (3 calls!). This
suffers from math inaccuracy, and also fails in degenerate transforms.
It is much easier to just never tell Cairo to transform and do the them
yourself, which appears to be the solution used by all toolkit graphics
Moving the path is a real pain because emulating a Cairo/PostScript type
API that has a hairline mode means the entire path must be stored
locally, because until the fill or stroke is done you cannot know if the
path needs to be offset or not. The end result is that lots of Cairo's
machinery is unused and wasted.
> I too would like to see a separate API for that. Using zero line width
> or even negative line widths (which would be the next obvious idea) is
> a dirty hack in my opinion. Degenerate matrices are even worse. How
> close to zero would the determinant have to be?
Negative line widths must draw the same as the absolute value in the
current Cairo. If asymmetric line caps are ever supported the negative
line width would reflect them about the centerline of the stroke.
If hairline mode is triggered by zero line width, it will require a
value==0 to be passed to set-pen. A non-zero value will not turn on
hairline mode, either due to numeric underflow (when a tiny pen is set
in a tiny scale) or due to the CTM being degenerate.
It sounds to me like a more popular solution here is to have a separate
call to turn on hairline mode. This is acceptable because it is no
problem for an emulator to check for zero in it's set-line-width call. I
highly recommend that there only be a call to turn on hairline mode,
turning it off is done by setting the pen.
More information about the cairo