Should font contour directions be clockwise or counter-clockwise?
The font forge documentation states:
“All paths must be drawn in a consistent direction. Clockwise for external paths, anti-clockwise for internal paths.”
They state that this is the TrueType/OpenType convention, and that the Postscript convention is the opposite.
A separate section of the documentation continues:
“TECHNICAL AND CONFUSING: the exact behavior of rasterizers varies. Early PostScript rasterizers used a “non-zero winding number rule” while more recent ones use an “even-odd” rule. TrueType uses the “non-zero” rule. The description given above is for the “non-zero” rule. The “even-odd” rule would fill the “o” correctly no matter which way the paths were drawn (though there would probably be subtle problems with hinting).
Filling using the even-odd rules that a line is drawn from the current pixel to infinity (in any direction) and the number of contour crossings is counted. If this number is even the pixel is not filled. If the number is odd the pixel is filled. In the non-zero winding number rule the same line is drawn, contour crossings in a clockwise direction add 1 to the crossing count, counter-clockwise contours subtract 1. If the result is 0 the pixel is not filled, any other result will fill it.”
I conducted an audit of a large corpus of fonts to see how this played out in practice. Here are the results:
Posted 11 months ago with 0 notes
Total fonts scanned: 62,192
.otf: L contour is clockwise: 200
.otf: L contour is not clockwise: 18,337
.otf: O has 0 clockwise contours and 2 counter-clockwise contours: 259
.otf: O has 1 clockwise contours and 1 counter-clockwise contours: 17,584
.otf: O has 2 clockwise contours and 0 counter-clockwise contours: 23
.ttf: L contour is clockwise: 24,021
.ttf: L contour is not clockwise: 3,268
.ttf: O has 0 clockwise contours and 2 counter-clockwise contours: 290
.ttf: O has 1 clockwise contours and 1 counter-clockwise contours: 25,691
.ttf: O has 2 clockwise contours and 0 counter-clockwise contours: 618