Sunday, December 4, 2022

Color management, this time with PDF

In previous posts the topic of color management in Cairo was examined. Since then people have told me a few things about the issue. According to them (and who am I do to proper background research and fact checking, I'm just someone writing on the Internet) there are a few fundamental problems with Cairo. The main one is that Cairo's imaging model is difficult to implement in GPU shaders. It also is (again, according to Internet rumors) pretty much impossible to make work with wide gamut and HDR content.

Dealing with all that and printing (which is what I was originally interested in) seems like a too large a mouthful to swallow. One thing lead to another and thus in the spirit of Bender, I wrote my own color managed PDF generator library. It does not try to do any imaging or such, just exposes the functionality that is in the PDF image and document model directly. This turned out to take surprisingly little work because this is a serialization/deserialization problem rather than an image processing one. You just dump the draw commands and pixels to a file and let the PDF viewer take care of showing them. Within a few days I had this:

This is a CMYK PDF that is fully color managed. The image on the second page was originally an RGB PNG image with an alpha channel  that was converted to CMYK automatically. The red square is not part of the image, it is there to demonstrate that transparency compositing works. All drawing commands use the /DeviceCMYK color space. When creating the PDF you can select whether the output should be in RGB, grayscale or CMYK and the library automatically generates the corresponding PDF commands. All of the heavy lifting is done by LittleCMS, there are no unmanaged color conversions in the code base.

Since everything was so straightforward, I went even further. That screenshow is not actually showing a CMYK PDF. The yellow text on the purple background is a spot color that uses a special gold ink. Thus the PDF has five color channels instead of four. Those are typically used only in high quality print shops for special cases like printing with specific Pantone inks or specifying which parts of the print should be em/debossed, varnished or the like.

What would it take to use this for realsies?

There does seem to be some sort of a need for a library that produces color managed PDFs. It could be used at least by Inkscape and Gimp, possibly others as well. In theory Cairo could also use it for PDF generation so it could delete its own PDF backend code (and possibly also the PostScript one) and concentrate only on pushing and compositing pixels. Then again, maybe its backwards compatibility requirements are too strict for that.

In any case the work needed splits neatly into two parts. The first one is exposing the remaining functionality in PDF in the API. Most of it is adding functions like "draw a bezier with values ..." and writing out the equivalent PDF command. As the library itself does not even try to have its own imaging model, it just passes things directly on. This takes elbow grease, but is fairly simple.

The other part is text. PDF's text model predates Unicode so it is interesting to say the least. The current code only supports (a subset of) PDF builtin fonts and really only ASCII. To make things actually work you'd probably need to reimplement Cairo's glyph drawing API. Basically you should be able to take PangoCairo, change it a bit and point it to the new library and have things work just as before. I have not looked into how much work that would actually be.

There are currently zero tests and all validation has been done with the tried and true method of "try the output on different programs and fix issues until they stop complaining". For real testing you'd need access to a professional level printer or Adobe Acrobat Pro and I have neither.


  1. Nice work! Maybe use poppler to write some basic tests? i.e. feed the output to poppler and compare to a known good bitmap.

    Also, Khaled Hosny ( was recently working on improving the stuff LibreOffice does when pushing non-Latin text to PDF.

    1. Something like that would definitely make sense, but not yet. This was mostly an experiment to see how PDF works internally and also gauging if there is general interest for a library like this. If people really want to use this, then of course tests would be added.