[cairo] Explanation/justification for tolerance change?
Behdad Esfahbod
behdad at behdad.org
Wed Dec 5 23:48:20 PST 2007
On Wed, 2007-12-05 at 17:32 -0500, Carl Worth wrote:
> Some of you might have noticed that I had a couple of open questions
> in the release notes for the 1.5.4 snapshot I sent out last
> night. Here's the promised follow-up for one[*] of them:
Yes. Very welcome habit.
> The commit of interest says only the following:
>
> [meta-surface] Adjust tolerance when replaying to surfaces
> with device
> scale
>
> such that we get a consistent look with different fallback
> resolutions.
>
> Behdad, can you explain/justify this change please? In what cases is
> the output different, and how is it better?
Sure. For output difference please see before/after PDFs in the mail I
sent in October (that got no comments):
http://lists.cairographics.org/archives/cairo/2007-October/011815.html
The pages show the same piece rendered to fallback images of various
resolutions. Tolerance has been increased to 5.0 IIRC.
In my book, the after shot is more consistent and so preferred.
> I know that Adrian doesn't agree with the change, so I'm hoping for a
> good debate. :-)
Adrian has a point of course, the short version being: "why would one
ask for 1200dpi fallback image but get the same output of seemingly
300dpi"? The main issue is that we have not defined tolerance for
vector backends, and the main reason is that normally those backends
don't need to flatten curves.
It also doesn't help that cairo_set_tolerance() specifically define it
as maximum error tolerated when flattening curves.
So lets define tolerance more usefully: maximum error distance, measured
in device units. To implement this I suggest:
- Use tolerance to round numbers printed in vector output. It just
wastes space to write out to a precision of 1e-5 PS points when
tolerance is just 0.1 points.
- Deprecate cairo_surface_[sg]et_fallback_resolution() and use
tolerance to deduce fallback resolution. That is, a default tolerance
of 0.1 will generate a fallback image of 600dpi and draw to it with a
fixed tolerance of 0.1. (0.1 points means 720dpi, times sqrt(2) for the
diameter and then div by two to get pixel rounding error gives ~509 dpi.
Round up to 600. The second 0.1 is quite arbitrary.)
This makes a whole lot of sense. Now if you need a fast light *draft*
PDF to print at 300dpi, you set tolerance to 0.2. If you want a heavy
camera-ready 2400dpi PDF, you set tolerance to 0.02.
It's simply beautiful and thanks to the tolerance living in gstate (as
opposed to surface) and fine-grained fallbacks, it means that you can
immediately get different fallback resolutions for different parts of
the same page. It will all just work.
I also noticed now that our tolerance guarantee is not as strong as it
should be. For example we don't account for rounding error that happens
when converting paths to cairo_fixed_t. Not hard to fix.
Another issue that Adrian raised was that 0.1 is too coarse for PDF. I
don't think it is, but if that's the case, we can easily make default
tolerance come from surface, like font options.
Now does that make any sense or I'm just crazy?
> Personally, I'm undecided because I don't think I fully understand the
> issue yet. But I definitely want to get some good consensus on this
> before
> 1.6.
>
> -Carl
--
behdad
http://behdad.org/
...very few phenomena can pull someone out of Deep Hack Mode, with two
noted exceptions: being struck by lightning, or worse, your *computer*
being struck by lightning. -- Matt Welsh
More information about the cairo
mailing list