]> git.cworth.org Git - cworth.org/blob - src/cairo/a_chain_of_bugs.mdwn
Add 'a chain of bugs' post
[cworth.org] / src / cairo / a_chain_of_bugs.mdwn
1 [[meta title="A chain of bugs"]
2
3 With cairo's recent 1.6.4 release, we've hoped to reach the nirvana of
4 applications that display and print documents with perfect
5 fidelity. Unfortunately, reality isn't always as pleasant as we would
6 like. I recently received a bug report that Firefox 3 (using cairo
7 1.6.4) resulted in a blurry mess when printing a very simple web page,
8 (some text, a table, and an image). Exploring the details of this case
9 reveals at least three independent problems that conspire to give the
10 bad results.
11
12 # Bug 1: Firefox+cairo uses image fallbacks for table borders
13
14 First, here's the simplest web page I was able to construct to show
15 the problem, (nothing more than a single-cell table with a border):
16 [[bug.html]] (122 bytes).
17
18 Using Firefox3 with cairo 1.6.4 on a Fedora9 system, I did a "print to
19 file" and obtained the following PDF output: [[bug.pdf]] (14,465
20 bytes).
21
22 This output is still quite accurate and farly usable. But we've
23 already seen problem #1. Note that the file size has increased by a
24 factor of 100 compared to the original HTML. The PDF does have more
25 content, (firefox adds a header and footer for example), but nothing
26 that explains such a large file. Instead, something about the way that
27 firefox is expressing the table border is resulting in cairo putting
28 fallback images into the resulting PDF file. So that's the first
29 bug. I'll look closer at this, (probably with libcairowrap), and make
30 a bug report to the mozilla folks if necessary.
31
32 Also, note that when cairo puts the fallback images into the PDF file
33 it uses a "knockout group" to do so. This is a particular PDF
34 construct that I'll discuss later.
35
36 # Bug 2: Poppler+cairo expands knockout groups to full-page fallbacks
37
38 Next, we can use the poppler library, (with evince or a pdf2ps
39 utility), to read the PDF file and use cairo to generate a PostScript
40 file: [[bug.ps]] (138,067 bytes).
41
42 Notice that there has been another factor of 10 increase in the file
43 size. Here, poppler has convinced cairo to generate a full-page
44 fallback image rather than just the minimal fallback images present in
45 the PDF file. This is due to the way poppler is handling the knockout
46 group and really comes down to the difficulty of getting a single,
47 desired result to pass through two systems with very different
48 rendering models.
49
50 To explain a bit, (but ignoring many gory details), a PDF knockout
51 group can be a very complicated thing, so poppler has some fairly
52 sophisticated code to handle these. This support involves rendering
53 everything in the group twice and then using cairo's DEST_OUT and ADD
54 compositing operators to properly combine them. Well, PostScript can't
55 do fancy compositing like DEST_OUT and ADD, so of course cairo falls
56 back to image-based rendering for things. The irony here is that the
57 only reason cairo is using a knockout group in the original PDF file
58 is to _prevent_ any compositing from happening, (the fallback image
59 needs to replace any "native" content that might appear below it). And
60 it turns out that painting an image without any compositing is the
61 _only_ kind of image painting that PostScript knows how to do.
62
63 So, cairo is using an advanced feature of PDF to describe precisely the
64 semantic that PostScript supports natively. The change we need is to
65 fix poppler to recognize this case and ask for the simple thing from
66 cairo's PostScript backend so that we don't get this full-page fallback
67 explosion.
68
69 # Bug 3: Cairo uses the wrong resolution for fallback images (in groups)
70
71 If it were only for those first two bugs, the intermediate file sizes
72 would have been larger than normal, but the final result would have
73 looked great and printed just fine. And in that case, I probably would
74 have never even received a bug report.
75
76 But there's a third problme that is the most pernicious, because it
77 results in the final result looking ust awful. When cairo inserts the
78 full-page fallback into the final PostScript file, it is inserting it
79 at 300dpi, but it does that only after rendering it to an intermediate
80 72dpi image, which is then scaled up. That's why the final PostScript
81 file appears so blurry and hard to read.
82
83 This third problem is the first I attempted to fix, (since it involves
84 cairo alone), and I described my attempts in several posts to the cairo
85 mailing list over the past couple of days, beginning here:
86
87 [Bug with fallback resolution of
88 groups](href="http://lists.cairographics.org/archives/cairo/2008-May/014169.html)
89
90 In that series of posts I coded a minimal test case in cairo's test
91 suite for the resolution problem, and a patch that fixes that test
92 case. But when I use a patched cairo for the PDF to PostScript
93 conversion of the file described here, I end up with the following
94 result: [[bug-patched-cairo.ps">bug-patched-cairo.ps]].
95
96 Here, there's still a giant, full-page fallback image, (this is
97 expected since I haven't touched poppler yet). And the image is at
98 least rendered at the correct resolution this time, (notice that the
99 text that appears is much more sharp than in the previous PostScript
100 file). However, the original HTML table is now entirely missing. So
101 there's definitely something wrong with my patch.
102
103 I'll continue to chase these bugs down, and continue my quest to get
104 high-quality display and print output from cairo-using
105 applications. It can be a difficult goal, but it's also a lot of fun
106 and very rewarding.
107
108 Please feel free to jump in and help if you're interested.
109