Saturday, August 30, 2014

From typeface to font—part two: Font metrics and importing into fontforge


 Part one »

Since I drew the glyphs in a vector program, Inkscape, the letters are technically already digitized. If I had drawn them out on paper I would have to scan and then trace the glyphs. But before we can copy and paste glyphs into a font, we must first understand exactly how a font deals with all those little em rectangles.

Fonts subdivide ems into an arbitrary number of font units which they use as their internal coordinate system. For a truetype font (one that ends in .ttf), each em is typically broken down into 1024 or 2048 font units. In the newer opentype format (.otf), each em usually contains 1000 font units, though this isn’t a requirement.

The origin of a font’s coordinate system is usually displaced some distance upwards, giving rise to negative coordinates. The x-axis is used as the baseline of the typeface. Typically, the displacement is between one quarter and one fifth of an em unit, so a font’s em rectangle might extend all the way up to 780 font units, and all the way down to –220 font units, giving a total height of one thousand font units. Letter parts can be found outside of this range—the descender of a ‘p’ might reach a coordinate of –235 font units, but if the text is set with no leading, the descender will intrude into the next line's em rectangles.
Metrics of Proforma
Vertical metrics of Proforma. Proforma has an ascent of 0.8 ems and a descent of 0.2 ems.
The app we’re going to use to put the glyphs into a font is called FontForge. It’s free and open source and at the time of writing, still being actively developed (after a period of dormancy). I won’t go over how to install it as there are plenty of guides on how to do so. I recommend building fontforge from its source code. It's easier than it sounds and the build guide holds your hand every step of the way. Plus the precompiled fontforge packages tend to be very old and buggy, so building from source is a good way of ensuring freshness.

You can actually just select svg glyphs in Inkscape and copy and paste them into fontforge. When copying from Inkscape, fontforge will map pixels to font units. Since I scaled my typeface to match an 800 point Libertine font, and 800 points in Inkscape corresponds to 1000 pixels (beware if you’re sketching in other programs—they have different point–pixel ratios), each 1000 pixel glyph will translate perfectly into 1000 font units in fontforge.

But if you just copy and paste a glyph, you might find that something like this happens:

Fontforge will take the letter, and jam it up in the upper left corner. It does that because fontforge doesn't know where to put the letter in that giant em square. We have to include the glyph with its position relative to the em square. We do that by drawing a 1000 pixel em square in Inkscape and positioning it relative to our typeface using the Libertine em square as guidance.
When you copy and paste it along with the letter, fontforge will take the corners of that 1000 pixel square and line them up with fontforge's own em squares. Be sure to convert all circles (like the tittle of the ‘i’) to paths in Inkscape, as fontforge often misreads them and adds a ton of unnecessary points for no reason. Edit: This has been fixed in the latest fontforge source.


Then you can remove the square to reveal the perfectly positioned glyph inside.


But there’s still a problem. The glyph is floating some distance above the default baseline. How far above the baseline? Left click the lowest point of the glyph and select Get Info to see the coordinates of that point.


You can see that the bottom of the ‘i’ is hovering 43.26 font units above the baseline. Since the default baseline in fontforge is 200 font units above the bottom of the em square, that means that the font’s true baseline is located 243.26 units above the descent line. In other words, our typeface’s descent is 243.26 units (and its ascent is 756.74 units). Ascents and descents, by convention are typically round numbers, so we’ll just make the descent 240 units and the ascent 760 units. You can adjust the ascent and descent in ElementFont Info. Note that you have to close out your current project and create a new project in fontforge with these metrics, since at the time of writing, if you change the ascent and descent after you’ve pasted in a glyph, fontforge will stop lining up the corners of the em squares when you repaste the glyph.


And if you paste the ‘i’ back in, the baseline will be closer to its bottom (albeit still 3.26 units too high).


Then you can go and paste in the rest of the glyphs in the same way.


It’s likely that some pieces of your letters will appear to go missing along the way. In my case, it looks like I lost my entire ‘b’. But the paths are still there; fontforge just fails to render them because they aren't closed shapes. Just select the endpoints and go PointMake Line to close off the shapes.


In the ‘a’, I closed off the open bowl, but there remained a strange hairline between the two shapes.


That was because the bowl was closed in a counter-clockwise direction, so fontforge was interpreting it as a counter—causing the intersection between it and the stem to be rendered as an empty space. Just select any point on the bowl and go ElementClockwise to fix it.


There’s just a few last things to do. First select all the present glyphs, and go ElementTransformationsTransform, and translate all the glyphs down 3.26 units. This cancels out the remaining 3.26 unit discrepancy between the typeface baseline and the font baseline.


But as you can see from Get Info, the glyph coordinates are still at annoying decimals.


To fix that just select everything and run ElementRoundTo Int. This is a useful command and run it often since there are very few cases where you would want to have a point at a non integer coordinate. Finally, go through your glyphs, and if there are any curve points that are horizontal or vertical, mark them as such, as this will help reduce headaches with extremas later.


At this point, you should have the ‘a’, ‘i’, ‘o’, ‘b’, ‘n’, ‘v’, ‘f’, and ‘e’ all cleaned up and in their encoding slots in a font file!