[cairo] Bug in PDF output with independent path/pen transformations

Adrian Johnson ajohnson at redneon.com
Thu Nov 1 06:14:29 PDT 2007

Behdad Esfahbod wrote:
> On Tue, 2007-10-30 at 21:17 -0700, Carl Worth wrote:
>> On Tue, 30 Oct 2007 21:58:03 -0400, Behdad Esfahbod wrote:
>>> I did.  The bug is in how we print doubles out.  We use %f, because
>>> scientific syntax is not ok in the output.  But then %f is not
>> flexible
>>> enough and is producing 0.000001 when it should be doing
>>> 0.000000707106781 or something more like that.  I really wish %g
>> could
>>> be used.
>> Thanks for the diagnosis, Behdad. That was a good catch.
>>> Anyway, I'll cook a patch that should also optimize the way we
>>> write out numbers a bit.
>> I'll look forward to that. 
> So, I pushed %.18f and then Adrian made it smarter by using %f if number
> is > 0.1 and otherwise %.18f, then prune it to have only 6 meaningful
> digits.
> I suggest we refine it further:
>   - 18 digits is still not enough to write a number like 7e-100.  What
> we really want is up to a large number of digits (100?), but only 5 6
> meaningful digits.  How many and how many exactly?  For implementing it,
> we can either write a loop of some kind or use more expensive operations
> like ickle is showing me:
> 	http://rafb.net/p/OQ9e7495.html

The PDF and PS references both specify that the implementation limit of
the smallest nonzero is 1e-38. Anything under that is rounded to zero.

Reducing the x scale value in the "line at an angle" test in
degenerate-pen.c shows that Evince and Adobe Reader stop working before
limits of printing with "%.18f" are reached.

At the scale (0.000000001, 1.0) Evince produces incorrect output.
Reducing the x scale by another factor of 10 results in no output.

The scale (0.00000000000001, 1.0) is the point where Adobe Reader 8
produces no output. At this scale the matrix values near zero still have
four significant digits (0.000000000000007071).

At the scale that Evince breaks the pen width is equal to 1 dot on a
72,000,000,000 dpi device. As no device has anywhere near this
resolution one possible solution is to adjust the matrix to limit the
minimum dimensions of the pen so that it will produce correct output on
all devices.

>   - Those are useful for writing out matrices, and we can't get much
> better at them.  But for path coordinates we can do better, namely, use
> tolerance.  If tolerance is 0.1, we need not more than two digits after
> decimal point.  However, we should scale tolerance exactly like in my
> recent mail about scaled-tolerance in meta-surface.
> /me waits for ickle to chip in his part in this bug :-P

I am not seeing why the resolution of the path coordinates should be
linked to the curve flattening tolerance. They are two separate things.
A user may increase the curve flattening tolerance for better
performance but still expect all objects to be accurately positioned
when imported into another application and rescaled.

More information about the cairo mailing list