After a PDF document is rasterized, why do we see jaggies around lines?
The answer starts with a bit of theory on the coordinates: In a PDF document these coordinates denotes a positions on a plane using a X and an Y axis. These positions uses floating point numbers which result in the ability to point to any location, not only at the grid lines but also anywhere in between.
However, at the moment that a PDF document is printed or viewed on a screen, it has to be rasterized to something what we call the 'device space'. This device space is a bitmap which consist of discrete pixels, each with its own coordinate. So in this device space case the X and Y coordinates are integers.
So how exactly are the floating point coordinates mapped to the pixels then?
If we forget about the transformations for a moment, the definition is as follows: "Pixel boundaries always fall on integer coordinates in device space. A pixel is a square region identified by the location of its corner with minimum horizontal and vertical coordinates. The region is half-open, meaning that it includes its lower but not its upper boundaries " In other words: it looks like this:
What happens if we draw a black vertical line with a width of 1 pixel wide positioned exactly at the PDF coordinates (2, 1) to (2,6)?
Then you get a line with a width of 2 pixels with all pixels grayed out, grey instead of black because all pixels are only 50% part of the line. However if you draw a line at exactly halfway each coordinates, you get what you might expect in the first place:
Note that you usually don't want to do this kind of exact positioning, as it is most likely that the PDF coordinates will be scaled by the one or more transformations. When you print an PDF document it will be scaled to A4, letter, or any other format. On screen it will depend on the 'dots per inch' and the size of the window in which it is displayed. So this these exact coordinates are most likely changed in something entirely different in the somewhere in process of viewing. So, just don't use halfway coordinates for this reason.
The jaggies will become visible if the PDF is rendered to a black and white bitmap, e.g. for a printed page. It is not possible to use gray values then so dithering has to be used instead like:
Why do this dithering instead of moving the line half a pixel?
The question is: Is this dithering really what we want or can we do something better here? it is clear that there is a decision to be made here on what is most important:
- Either the rasterizer tries to approach the exact position of the lines by means of dithering,
- or it rounds the position of the line to the nearest pixel.
Neither of these give perfect results, dithering will look strange if you zoom into the details, and rounding results in lines with variations in location and thickness (as a 2.5 pixel wide line may be rounded to either 2 of 3 pixels). So there is no way to render the following line to a thickness of 2.5 pixels without dithering:
The reason that we have chosen in our implementation for these jaggies (is dithering) is that we believe that it results in better readability because:
- we think that unintended variations in location and thickness are more noticeable than jaggies.
- the dithering is supposed to be performed at such resolution that the individual pixels are indistinguishable, so you would not see it in normal situations.
Therefore the answer is: we do dithering as it gives the appearance of sub-pixel precision at the cost of strange pixels, which you will only see if you zoom in too much.