

Nibble Stew: The unbearable tightness of printing
source link: https://nibblestew.blogspot.com/2023/04/the-unbearable-tightness-of-printing.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

A gathering of development thoughts of Jussi Pakkanen. Some of you may know him as the creator of the Meson build system. jpakkane at gmail dot com
Saturday, April 29, 2023
The unbearable tightness of printing
Let's say you want to print a full colour comic book in the best possible quality. For simplicity we'll use this image as an example.
As you can probably guess, just putting this image in a PDF does not work, even if it had sufficient resolution. Instead what you need to do is to create two images. One for linework that is monochrome and has least 600 PPI and one for colours, which is typically a 300 PPI colour managed CMYK TIFF.
The colour image is drawn first and then the monochrome image is drawn on top of it. In this way you get both smooth colours and crisp linework. Most people would stop here, but this where the actual work begins. It is also where things start to wander into undocumented (or, rather, "implementation defined") territory.
Printing in true black
In computer monitors the blackest colour possible is when all colour components are off, or (0, 0, 0) in RGB values. Thus you might expect that the blackest CMYK colour is either (0, 0, 0, 1) or (1, 1, 1, 1). Surprisingly it is neither. The former looks grayish when printed whereas the latter can't be printed at all because of physical limitations. If you put too much ink in one place on the page, the underlying proper gets too wet, warps and might even rip. And tear.
Instead what you need to do is to use a colour called rich black. Each print shop has their own values for this, as the exact amount of inks to use to get the deepest black colour is dependent on the inks, paper and printing machine used. We'll use the value (0.1, 0.1, 0.1, 1.0) for rich black in this text.
Thus we need three different images rather than two.
First the colour image is laid down, then the image holding the areas that should be printed in rich black. This is a 300PPI colour image with the colour value (0.1, 0.1, 0.1, 0) on pixels that should be painted with rich black. Finally the line work is drawn on top the other two. The first two images can be combined into one. This is usually done by graphic artists when preparing their artwork to print. However the middle image can be automatically generated from the linework image with some Python so we're doing that to reduce manual work and reduce the possibility of human error.
If you create a PDF with these images you are still not done. In fact the output would be identical to the previous setup. There are still more quirks to handle.
Trapping and overprinting
Since all of the colours are printed separately they are suspect to misregistration. That is, the various colours might shift relative to each other during the printing process. This causes visual artifacts in the edges between two colours. This is a fairly complicated topic, Wikipedia has more details. This issue can be fixed by trapping, that is, "spreading" the colour under the "edge" of the linework. Like so:
If you look closely at the middle image, the gray area is slightly smaller than in the previous picture. This shrunk image can be automatically generated from the linework image with morphological erode/dilate operations. Now we have everything needed to print things properly, but if you actually try it it still won't work.
The way the PDF imaging model works is that if you draw on the canvas with any colour, all colour channels of the existing colour on the page get affected. That is, if the existing colour on the canvas is (0.1, 0.1, 0.1, 0) and you draw on top of it with (0, 0, 0, 1) the output is (0, 0, 0, 1). All the work we did getting the proper rich black colour under the linework gets erased as if it was never there.
PDF has a feature called overprinting to handle this exact case (you could also use the "multiply" filter but it requires the use of transparency, which is still prohibited in some workflows). It does pretty much what it says on the tin. When overprinting is enabled any draw operations accumulate over the existing inks. Thus the final step is to enable overprinting for the final line work image and then Bob's your uncle?
In theory yes. In practice lol no, because this part of the PDF specification is about as hand-wavy as things go. There are several toggles that affect how overprinting gets handled. What they actually do is only explained in descriptive text. One of the outcomes of this is that every single generally available PDF viewer renders the output incorrectly. Poppler, Ghostscript, Apple Preview and even Adobe Acrobat Reader all produce outputs that are incorrect in different ways. They don't even warn you that the PDF uses overprinting and that the output might be incorrect. This makes development and debugging this use case somewhat challenging.
The only way to get correct output is to use Adobe Acrobat Pro and tell it to enable overprint simulation. Fortunately I have a friend who has a 10 year old version (remember, back when you could actually buy software once and keep using it as opposed to a monthly license that can get yanked at any time?). After pestering him with an endless flow of test PDFs I finally managed to work out the exact steps needed to make this work:
- Create a 300 PPI image with the colours, a 300 or 600 PPI monochrome image with the rich black areas and a 600 DPI monochrome image for the linework (the rich black image can be autogenerated from the linework image and/or precomposited in the colour image)
- Load and draw the colour image as usual
- Load the rich black image and store it as a PDF ImageMask rather than a plain image
- Set nonstroke colour to (0.1, 0.1, 0.1, 0), set the rich black image as a stencil and fill it
- Load the linework image as an imagemask
- Enable overprinting mode
- Set overprinting mode to 1
- Set nonstroke colour to (0, 0, 0, 1)
- Draw the line image as a stencil
If you deviate from any of the above steps, the output will be silently wrong. If you process the resulting PDF with anything except Adobe's tool suite the end result might become silently wrong. As an example here is the output of colour separation using Adobe Acrobat and Ghostscript.
Acrobat has preserved the rich black values under the linework whereas Ghostscript has instead cleared the colour value to zero losing the "rich" part of black. Interestingly Ghostscript seems to handle overprinting correctly in basic PDF shape drawing operations but not in stencil drawing operations.
Or maybe it does and Acrobat is incorrect here. The only way to know for sure would be to print test samples on a dozen or so commercial offset printing presses, inspecting the plates manually and then seeing what ends up on paper. Sadly I don't have the resources for that.
Recommend
-
6
Nibble Stew A gathering of development thoughts of Jussi Pakkanen. Some of you may know him as the creator of the Meson build...
-
10
Millennium prize problems but for LinuxWednesday, February 24, 2021 Millennium prize problems but for Linux There is a longstanding tradition in mathematics to create a list of hard unsolved pro...
-
12
Microsoft is shipping a product built with Meson Some time ago Microsoft announced a compatibility pack to get OpenGL and OpenCL running even on computers whose hardware does not provide native OpenGL drivers. It is basically Ope...
-
15
Monday, February 1, 2021 Using a gamepad to control a painting application One of the hardest things in drawing and painting is controlling the individual strokes. Not only...
-
10
Never use environment variables for configurationWednesday, March 31, 2021 Never use environment variables for configuration Suppose you need to create a function for adding two numbers together...
-
8
Nibble Stew A gathering of development thoughts of Jussi Pakkanen. Some of you may know him as the creator of the Meson build...
-
14
A recent blog post talked about how to build and manage dependencies with CMake and FetchContent. The example that they used was a simple GUI application using the
-
5
Typesetting a full book part II, ScribusFriday, June 11, 2021 Typesetting a full book part II, Scribus Some time ago I wrote a b
-
7
Looking at the performance of ReftermMonday, July 5, 2021 Looking at the performance of Refterm Recently a known strong-opinion-holder Casey Muratori wrote a reference implementation for a new...
-
17
Nibble Stew A gathering of development thoughts of Jussi Pakkanen. Some of you may know him as the creator of the Meson build...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK