]> git.cworth.org Git - cworth.org/blobdiff - src/cairo/a_chain_of_bugs.mdwn
Add 'a chain of bugs' post
[cworth.org] / src / cairo / a_chain_of_bugs.mdwn
diff --git a/src/cairo/a_chain_of_bugs.mdwn b/src/cairo/a_chain_of_bugs.mdwn
new file mode 100644 (file)
index 0000000..0e3d92d
--- /dev/null
@@ -0,0 +1,109 @@
+[[meta title="A chain of bugs"]
+
+With cairo's recent 1.6.4 release, we've hoped to reach the nirvana of
+applications that display and print documents with perfect
+fidelity. Unfortunately, reality isn't always as pleasant as we would
+like. I recently received a bug report that Firefox 3 (using cairo
+1.6.4) resulted in a blurry mess when printing a very simple web page,
+(some text, a table, and an image). Exploring the details of this case
+reveals at least three independent problems that conspire to give the
+bad results.
+
+# Bug 1: Firefox+cairo uses image fallbacks for table borders
+
+First, here's the simplest web page I was able to construct to show
+the problem, (nothing more than a single-cell table with a border):
+[[bug.html]] (122 bytes).
+
+Using Firefox3 with cairo 1.6.4 on a Fedora9 system, I did a "print to
+file" and obtained the following PDF output: [[bug.pdf]] (14,465
+bytes).
+
+This output is still quite accurate and farly usable. But we've
+already seen problem #1. Note that the file size has increased by a
+factor of 100 compared to the original HTML. The PDF does have more
+content, (firefox adds a header and footer for example), but nothing
+that explains such a large file. Instead, something about the way that
+firefox is expressing the table border is resulting in cairo putting
+fallback images into the resulting PDF file. So that's the first
+bug. I'll look closer at this, (probably with libcairowrap), and make
+a bug report to the mozilla folks if necessary.
+
+Also, note that when cairo puts the fallback images into the PDF file
+it uses a "knockout group" to do so. This is a particular PDF
+construct that I'll discuss later.
+
+# Bug 2: Poppler+cairo expands knockout groups to full-page fallbacks
+
+Next, we can use the poppler library, (with evince or a pdf2ps
+utility), to read the PDF file and use cairo to generate a PostScript
+file: [[bug.ps]] (138,067 bytes).
+
+Notice that there has been another factor of 10 increase in the file
+size. Here, poppler has convinced cairo to generate a full-page
+fallback image rather than just the minimal fallback images present in
+the PDF file. This is due to the way poppler is handling the knockout
+group and really comes down to the difficulty of getting a single,
+desired result to pass through two systems with very different
+rendering models.
+
+To explain a bit, (but ignoring many gory details), a PDF knockout
+group can be a very complicated thing, so poppler has some fairly
+sophisticated code to handle these. This support involves rendering
+everything in the group twice and then using cairo's DEST_OUT and ADD
+compositing operators to properly combine them. Well, PostScript can't
+do fancy compositing like DEST_OUT and ADD, so of course cairo falls
+back to image-based rendering for things. The irony here is that the
+only reason cairo is using a knockout group in the original PDF file
+is to _prevent_ any compositing from happening, (the fallback image
+needs to replace any "native" content that might appear below it). And
+it turns out that painting an image without any compositing is the
+_only_ kind of image painting that PostScript knows how to do.
+
+So, cairo is using an advanced feature of PDF to describe precisely the
+semantic that PostScript supports natively. The change we need is to
+fix poppler to recognize this case and ask for the simple thing from
+cairo's PostScript backend so that we don't get this full-page fallback
+explosion.
+
+# Bug 3: Cairo uses the wrong resolution for fallback images (in groups)
+
+If it were only for those first two bugs, the intermediate file sizes
+would have been larger than normal, but the final result would have
+looked great and printed just fine. And in that case, I probably would
+have never even received a bug report.
+
+But there's a third problme that is the most pernicious, because it
+results in the final result looking ust awful. When cairo inserts the
+full-page fallback into the final PostScript file, it is inserting it
+at 300dpi, but it does that only after rendering it to an intermediate
+72dpi image, which is then scaled up. That's why the final PostScript
+file appears so blurry and hard to read.
+
+This third problem is the first I attempted to fix, (since it involves
+cairo alone), and I described my attempts in several posts to the cairo
+mailing list over the past couple of days, beginning here:
+
+[Bug with fallback resolution of
+groups](href="http://lists.cairographics.org/archives/cairo/2008-May/014169.html)
+
+In that series of posts I coded a minimal test case in cairo's test
+suite for the resolution problem, and a patch that fixes that test
+case. But when I use a patched cairo for the PDF to PostScript
+conversion of the file described here, I end up with the following
+result: [[bug-patched-cairo.ps">bug-patched-cairo.ps]].
+
+Here, there's still a giant, full-page fallback image, (this is
+expected since I haven't touched poppler yet). And the image is at
+least rendered at the correct resolution this time, (notice that the
+text that appears is much more sharp than in the previous PostScript
+file). However, the original HTML table is now entirely missing. So
+there's definitely something wrong with my patch.
+
+I'll continue to chase these bugs down, and continue my quest to get
+high-quality display and print output from cairo-using
+applications. It can be a difficult goal, but it's also a lot of fun
+and very rewarding.
+
+Please feel free to jump in and help if you're interested.
+