X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=src%2Fcairo%2Fa_chain_of_bugs.mdwn;fp=src%2Fcairo%2Fa_chain_of_bugs.mdwn;h=0e3d92d30757ea020aee1ec6f79c97a46800374d;hb=80048766efa4ef276e118631d11f607534a3421c;hp=0000000000000000000000000000000000000000;hpb=c9eb3deb433ef35b06469d3ea6930052033a6667;p=cworth.org diff --git a/src/cairo/a_chain_of_bugs.mdwn b/src/cairo/a_chain_of_bugs.mdwn new file mode 100644 index 0000000..0e3d92d --- /dev/null +++ b/src/cairo/a_chain_of_bugs.mdwn @@ -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. +