One thing Lanedo’s often asked to do is to work on improvements of the compatibility of LibreOffice with different file formats. A large part of this work is to test whether documents are formatted correctly in LibreOffice. This task involves many documents to be converted manually. So, naturally, as an engineer, I could not help but try to automate all the document conversion tasks we need to do when working on a particular problematic file. The result of that work will be made public during my talk with Lionel Dricot at the LibreOffice Milano Conference 2013: ”Improving interoperability as a business” (teasing, teasing).
The one thing I can already tell you is that this automation makes extensive use of the PDF export functionality of LibreOffice. It’s a very handy feature but I’ve stumbled onto a bug, or rather, an incompatibility between the gradients shown in LibreOffice and the way gradients are rendered for exported PDF files by the popular Linux PDF reader Evince (or actually poppler, the underlying PDF rendering library used by Evince). To explain the problem, let’s consider this simple gradient:
When the time comes to export this gradient to a PDF, LibreOffice has several options.
Option 1: Line sequencing
The approach originally used by LibreOffice exports the gradient as a sequence of lines, each with a unique color which are drawn like this:
This is technically valid and displays well in some PDF readers (e.g. Adobe’s own reader). But if you use Evince, you’ll see white stripes over the gradient:
Option 2: Shading dictionaries
When I started looking at the LibreOffice code that’s relevant to this issue, I found some disabled code which looked promising. The intent of this code was to use the gradient feature of the PDF format (see Shading Dictionaries in the PDF specifications). This feature was used in the most generic way possible: export the gradient as an array of samples, with each sample being a color sampled inside the filled area.
The PDF viewer then interpolates between samples and should produce the correct looking gradient. After cleaning up existing code it was ready for testing.
Unfortunately, despite being a very valid solution it ends up being affected a by poppler bug as well:
The poppler bug in itself is interesting (and may be a Cairo bug): when poppler uses filled rectangles to draw either the lines (from option 1) or interpolated areas (from option 2), each of those rectangles has an incorrect border color. So every change in the LibreOffice PDF export code for Evince/poppler using this rendering method is doomed. But, luckily there’s another way to express simple gradients: PDF’s axial shading feature (option 3).
Option 3: Axial shading
Axial shading can be reduced to a shading of axis and colors at the beginning and ending of the axis:
When the PDF viewer fills an area with such a gradient, color is extended until the left and right edges result in a correct gradient!
So I implemented this, taking care of possible gradient variations (borders and angles). After several iterations the code was ready for integration into the LibreOffice code base. Here is the final result with the fix applied:
Even though only linear and axial gradients are supported currently (other types of gradients use the original code as a fallback) this is already quite an improvement in rendering fidelity for all PDF readers.
Finally, the patches I wrote have already been merged into LibreOffice so the latest daily versions of it should feature correct exporting of gradients, enjoy!
If you want to discuss anything related to file formats or LibreOffice support in general, don’t hesitate to say hello to Eilidh, Lionel or myself during the LibreOffice Conference 2013 in Milan. If you cannot attend, drop us an email or leave a comment to see how we can help you!