Splitting Hairlines

2/19/2014 By Marco Kesseler 0 comments

You probably all have seen PDF documents that have very fat graphics when viewed at a low zoom level:

And, when zooming in, the fat graphics disappear, and slim down to something more sensible.

The effect that you see here is that of a “hairline”. Hairlines can be surprisingly fat at low resolutions but thin at high resolutions. The PDF Reference manual says the following about them:

“A line width of 0 shall denote the thinnest line that can be rendered at device resolution: 1 device pixel wide. However, some devices cannot reproduce 1-pixel lines, and on high-resolution devices, they are nearly invisible. Since the results of rendering such zero-width lines are device-dependent, they should not be used.”

The reality is however that since the PDF specification allows this, documents with these hairlines do exist, and this leads to the effects seen above.

Luckily, this effect is not really that problematic in practice, because the rendering results are pretty much the same for all viewers.

Empty Rectangles

There is another related effect, which is more subtle, and a bit trickier because the PDF reference does not precisely say what to do in this case: rectangles with a zero width or height that are “filled” with a color.

At first sight, one would assume that these should not be painted at all. It seems logical. GDI in fact does not render anything for such zero-width fills. Adobe Reader however shows these rectangles as hairlines. The closest hint we get from the PDF Reference manual is the following information about the fill operator “f”:

“If a subpath is degenerate (consists of a single-point closed path or of two or more points at the same coordinates), f shall paint the single device pixel lying under that point; the result is device-dependent and not generally useful.”

Extending this reasoning to rectangles with a zero width, this seems to imply that indeed, filling these should result in a hairline. And in fact, we have encountered several PDF documents that confirm this.


But now take a look at the following graphics. Adobe reader renders them as follows:

Our software (PDFRasterizer.NET) however produces this:

Is this wrong? Well apparently. But what is happening here? Closer inspection reveals that this area is covered with zero-width rectangles that are all filled with black. The image below has been taken from the same area, but rendered at a higher resolution by PDFRasterizer.NET.

To make things more complex, this area is also covered with very narrow (non empty!) rectangles filled with white. The black and white rectangles are painted alternately.

Logically, the zero width black rectangles should not be visible, because the white rectangles are wider and painted over them. But officially - as these zero-width black rectangles must be painted as hairlines -, they will rendered “thicker” than the white rectangles at low resolutions, and thus become visible. That is exactly what you see in PDFRasterizer.NET.

Note that strictly, one can never render anything thinner than a pixel. What happens normally, is that elements smaller than a pixel get interpolated with their background pixel with a factor that reflects how much they cover that background pixel. At low resolutions however, the black hairlines cause the background pixels to become entirely black, while the thin white rectangles only cover that background for a small fraction, leading to a largely dark-gray appearance.

The question for us here is not so much why our software renders these lines at low resolutions, but rather why Adobe Reader does not. The PDF Reference manual does not give any clue. It could be that Adobe does not take into account hairlines when interpolating new pixels with the existing background. This in itself would make sense, as these hairlines do not really constitute any real area. Unfortunately, if that is the case here, we will probably not be able to solve this in GDI+, as it does not offer us that kind of control.

The good news is however, that these graphical constructs are very exceptional, and there is a workaround by rendering at higher resolutions.

And essentially, this kind of problem is exactly why Adobe indicates that hairlines should not be used.