Friday, September 19, 2014

How to deal with font extremas

I don’t know about you, but this is definitely my least favorite font error. If your glyph outlines aren’t constructed in just the right way, fontforge will complain about missing “extremas”. But what are extremas anyway?

An extrema is a special kind of point that helps define the edges of a glyph. The word is Latin—technically a single extrema is called an extremum, with extrema being the plural. But the term has become so common among type designers, that extrema and extremas have become the terms used to describe these points in a glyph outline.

An extrema is just a curve’s minimum or maximum in the xy coordinate plane. This is just like finding the maximum of a parabola or some other curve, except applied to bézier curves.
Each bézier segment of a glyph’s outline (read: each segment between two points, not the entire glyph outline) must be a one-to-one function*—i.e. it has to pass both the horizontal and vertical line tests. A bézier segment in a font shouldn’t change direction in either the x or the y direction—otherwise it should be split into two one-to-one segments. A handy (but not foolproof) way of checking this is looking to see if the curve fits into the rectangle determined by its endpoints (though an ‘s’ shaped curve can pass this test and still not be one-to-one).
The curve on the left is acceptable—it doesn’t change direction in the x or y axis. The curve in the middle folds back on itself, so it needs to be split in two (right).
The curve on the left is acceptable—it doesn’t change direction in the x or y axis. The curve in the middle folds back on itself, so it needs to be split in two (right).
Why is this a thing? Well apparently it helps with hinting, by letting the renderer know the bounding boxes of the glyph outline. It also makes it easier to measure stems and set sidebearings, since you can measure distances between points instead of vague spots along a curve. But the truth is, most renderers get along fine without any extremas. No vector illustration program requires extremas on its paths. Extremas are just extra points on the ends that help protect glyph outlines, since fonts undergo much more heavy-duty scaling and rasterizing than most other forms of vector art. Think of them as protective bumpers on your letters that keep your font from getting distorted by dumb renderers.


 Go horizontal-vertical if possible


Take a look at this ‘o’. You can see that the inner contour needs four extrema points, denoted by in fontforge with ⴲ points (you may need to enable ViewShowExtrema). But that would make a counter with eight bézier points, which is a bit excessive and difficult to edit. But the extremas are very close to the existing on-curve points (filled circles). That’s because those curve points are very near horizontal or vertical.
In this case, we can just make those angled curve points horizontal or vertical (PointHVCurve), which makes those points extremas themselves, eliminating the need for extra extrema points.
That works just fine for the outer contour—its curve points were already perfectly horizontal or vertical—making them HV points (fontforge draws them as diamonds) just ensures that we don’t mess them up. But it distorted the inner contour a bit. Luckily, since the original points were so close to their extremas, you can tweak the new HV curves to match the original contour almost perfectly. This ‘o’ differs from its non HV version by less than a fraction of a font unit. To do this, it can be helpful to copy the original glyph outline to fontforge’s background layer and match it in the foreground (glyph) layer with HV points.

Always add the extrema if it’s far away from the original points 

(and try to use it to replace nonextrema points) 


The ‘a’ here is missing its overshoot and undershoot extremas, as well as several on its bowl. These extremas, especially the ones on the outside of the glyph, are important, so they should be made explicit.
To add the extremas, just select the curve segments that need them, and go ElementAdd Extrema. Fontforge will almost certainly create the extremas on fractional coordinates, so run Round to Int every time you do this. Once you have extrema points, it’s very likely that you won’t need some of the original points anymore. Fewer points is almost always better. You can delete the old points, and adjust the extrema points’ handles to match the original curve. ElementSimplifySimplify can do some of this for you too. But see that extrema on the bottom edge of the ‘a’ terminal? I would leave it out. It’s close enough to another on-curve point, and “un-extreme” enough that adding the extrema there would cause more problems than it would solve.

Extremas can prevent overlap issues


The crossbar on the ‘e’ was drawn so that the crossbar overlaps with the letter’s bowl. This makes it easier to edit both the crossbar and the bowl, but eventually, the overlap will have to be removed, and doing so will create a new corner point where the two intersect. But since there is already a curve point near the intersection, removing the overlap will create an outline with two points very close to each other. Which is bad.

A good way to fix this would be to move the existing curve point onto the intersection, and making it an extrema, making a single point satisfy three roles. Like the ‘o’ a couple other curve points an be made into extremas as well.
Notice, though, that I left out the extrema on the right edge of the ‘e’. Again, since that curve offends so slightly, the extrema would be so close to the corner point just below it that it just isn’t worth putting the extrema in.

Leave out extremas in diagonal and italic serifs.


Diagonal strokes with bracketed serifs are a common source of extrema errors. While the curve segments that need them certainly bend out enough to require extremas normally, serif brackets are so small and so numerous that adding in the extremas is more trouble than it’s worth. Most designers leave them out.

Should I design with extremas in the first place?


Yes and no. Try to have a bias towards horizontal and vertical curve points when you’re drawing vector glyphs. It can save you a lot of trouble later on. But oftentimes, it is very difficult to draw glyphs like ‘o’ and ‘c’ using only horizontal and vertical curve points. It’s much more natural to draw round letters like them using angled curve points, and you’ll get nicer looking glyphs that way. It’s perfectly possible to draw the same thing using extremal points, but it would be a lot less natural and a lot more annoying. In that case, it’s better to draw the glyph normally and retrace it with extremas later on.

*Technically, a bézier curve isn’t a typical y = {} function, it’s a pair of parametric functions that map x and y separately. But in font files, the two parametric functions still, for some reason, have to be one-to-one.