# How does PDF or PDF Viewer define a rounding rule for stroke thickness?

I defined a sequence of line segments of different thickness each as follows.

\documentclass{article}
\usepackage{multido}
\parindent=0sp
\begin{document}
\multido{\dx=0sp+1000sp}{100}{\rule{0.01\linewidth}{\dx}}%
\end{document}


And I got the result as follows.

If we magnify the output 6400 times, we will notice there is an interval in which adjacent line segments have the same thickness. In other words, any value in x sp to y sp results in strokes with the same thickness.

I am interested in finding the formula used by PDF to determine the x and y. How does PDF or PDF Viewer define a rounding rule for stroke thickness?

• Isn't that purely up to the rendering engine? – topskip Jul 14 '11 at 17:52
• @Patrick: It is also purely up to the printer ? – xport Jul 14 '11 at 18:10
• I have no idea but I strongly believe so. I once heard that very thin "hairlines" are thickened automatically, but this was in postscript times. Don't know if this applies to PDF. – topskip Jul 14 '11 at 18:21
• Note that your screenshot is scaled by tex.sx, too. It's actually 1148px × 104px, scaled to 630px × 57px, which might make a difference in the optical impression again, quite possibly depending on personal browser/computer configuration. (I would assume the tex.sx dimensions are the same for everybody.) – doncherry Jul 15 '11 at 10:14
• @doncherry: It depends also on our eyes and lighting. – xport Jul 15 '11 at 10:17

## 1 Answer

The PDF imaging model is quite complicated. You can read about it in section 10.6 of the PDF specification (you can download it here). The important point is that a pixel is supposed to be coloured when painting a shape if any part of it intersects the shape, no matter how small the intersecting area. The idea is to ensure that no shape never disappears because of the way it aligns with the pixel grid, although misunderstanding of this rule can cause other problems such as disappearing box border lines in latex when you don't use xcolor (see this answer), where the problem is that a black line is painted and then a white rectangle is painted to its right, but due to the above rule, the white rectangle can completely obscure the black line. There is also an optional "stroke adjustment" feature, where lines are rounded to an integer number of pixels thickness, to make sure all vertical or horizontal lines appear the same weight, no matter how they align with the pixel grid (see section 10.6.5 of the spec).

Having said all that, many PDF viewers do not actually implement the scan conversion rules as given in the spec. The PDF specification was originally mostly concerned with describing the printed page, where pixels are either completely black or completely white (well, for most printing technologies, anyway). For the screen, most people prefer antialiased rendering, where pixels are darkened in proportion to the amount of area covered. In Adobe reader you can switch between rendering as per the spec, and antialiased rendering, with the checkbox "Smooth line art" under "Page display" in the preferences settings. However, it is more subtle still than this, because now very fine lines can disappear, so there is another checkbox "Enhance thin lines", which selectively switches the scan conversion rules of the spec back on for thin lines only. Other than Adobe Reader, some other PDF viewers (eg evince, sumatraPDF) use only an antialiasing algorithm, but they still need some heuristic for making thin lines visible, others (eg xpdf, okular) use only the scan conversion rules of the specification.

EDIT to add a few more points:

1. I should have mentioned that zero-width lines have a special device-dependent interpretation of "as thin as possible", so it's best to avoid using these.

2. There is another source of rounding that very rarely comes up: coordinates in PDF are stored as textual representations of floating-point numbers, truncated to a certain number of figures after the decimal, eg "10.124". You can adjust the number of digits in pdfTeX using \pdfdecimaldigits (equal to 3 by default in my miktex installation). The truncation to 3 digits corresponds in the usual case where the distance is in pt to a rounding to about 66sp. It seems that ps2pdf will by default round to 2 digits but this can be altered with the -r option, eg -r10000 (asking for 10000dpi resolution) will give a PDF with 5 decimal digits. It seems dvipdfm uses 2 digits by default, but one can change this with the -d command line option.

Obviously, including more digits will make the PDF file size (very slightly) larger.

3. dvips will do rounding to whatever is given by the -D option to set the resolution. dvips -Ppdf will set -D8000 for 8000dpi, or rounding to the nearest approx 600sp. On my installation, without any special options, dvips defaults to 600dpi or 8000sp. (This is sufficiently coarse to cause around 8 adjacent segments to have the same thickness, in the example given in the question).

EDIT 2: A final complication that affects the example given in the question: how to represent TeX \rules in pdf? There are 2 options: as stroked lines, or as filled rectangles. dvips without any special options will use rectangles (because this works best with certain old PostScript engines, such as in LaserJet III printers). dvips -Ppdf will use lines (because it loads alt-rule.pro) which works better with PDF, at least for thin rules. pdftex will use lines for rules narrower than 1bp and rectangles for larger rules. dvipdfm uses lines. It's interesting to compare the results of the various different ways of making a PDF from the example in the question: there is certainly a noticeable difference if you look carefully at certain zoom levels in different pdf viewers.