Line-spacing: getting it right

If you’re a new font designer wondering how to set your OpenType font’s em-height and line-spacing, the advice you’ll find online is just about all wrong. Technology has changed, and the historical measures no longer hold true. Here’s how you do it in FontForge.

The em-height originally derives from the height of the metal slug on which each character was contained in traditional mechanical printing. There’s advice floating round that you should extend the “descent” down to accommodate every descender in your font, and raise the “ascent” to accommodate every accent. Don’t. In electronic typefaces the em-height no longer relates to those measures, and if you try to do this your 12pt font will come out looking tiny compared to most other 12pt fonts. Instead, do the following:

  • Create your initial glyphs at whatever size is convenient. You don’t need the whole alphabet, and it’s good to have your metrics sorted out as early as possible, so you can do this even before your basic alphabet is complete. You’ll need enough glyphs to be able to produce a line of sample text; and you’ll need at least one ascender such as ‘d’ and one descender such as ‘g’.
  • Print out a line of text of your font in 12pt, just above the same text set in 12pt of a similar popular font, such as Times New Roman or Linux Libertine. This provides a reference size. Divide the horizontal length of the reference text by the length of your text; the result is the factor by which you’ll need to scale your em-height.
  • Your current em height = ascent + descent. Your target em height = current em-height × factor.
  • Now you get to choose how much of the em-height goes into the ascent and how much into the descent. I like to have the ascent reach just above the d or the h, and the descent is of course whatever’s left over. In Coelacanth, the descent doesn’t reach all the way down the actual descenders of the letters; it doesn’t matter. Nowadays the em size is no longer the bounding box of your glyphs, and nothing will be chopped off. When you think you’ve calculated it right, change the ascent and descent (Element> Font Info> General), making sure that “Scale Outlines” is not checked. You can keep adjusting until you think it looks right.
  • Next step: It is convention for Postscript type 2 fonts (which is what these OpenType fonts are, under the hood) to have an em-height of 1000. That’s not supposed to be mandatory, but some badly-written type rendering engines will probably break if you don’t do this. So multiply both your ascent and descent by (current em height ÷ 1000). Now change the ascent and descent to these new values, leaving “Scale Outlines” checked this time. All the glyphs will be scaled to the new metrics.
  • Generate and test your font, to ensure it reaches the desired length alongside your reference text. (When testing your font on Ubuntu, you can rapidly install it by copying it to the ~/.fonts directory.)
  • Now that the characters are coming out the right size, you need to set line-spacing. This is finally where you need to consider how high your tallest accent will be and how low your lowest descender. Note, though, that there are a few really crazy tall characters out there, such as Ǻ — A with ring above and acute. These trouble-makers don’t have to spoil the party, because most text-setting engines will recognise when you’ve used an over-large character and increase the spacing on that one line. There are also OpenType tricks to change the line-spacing for certain languages that use a lot of tall glyphs. So only try to accommodate the glyphs you think will be used in normal text.
  • Go to Element> Font Info> OS/2> Metrics. (Originally, these settings were for the OS/2 operating system, but are now used by most type engines.) Make sure all the IsOffset fields are not checked. Figure out a) the top of your highest commonly-used accent plus any extra padding you require between lines, and b) the depth of your lowest (commonly-used) descender. These will become the Win Ascent and Win Descent fields (both positive values). Now copy these values to Typo Ascent and Descent and HHead Ascent and Descent, except make the descent negative for these fields. Both line gap fields should be zero, and ensure “Really use Typo metrics” is checked.
  • Others may disagree with my choice of values, and I can’t say these fields are being used exactly as originally intended (no two sources seem to agree on correct usage); however, I am following the example of some widely-used and widely-supported fonts, so don’t blame me. There’s safety in numbers, since the popular fonts are the ones that all text rendering is tested against. Font formats seem to be full of idiosyncrasies like this, where original standards have been abandoned because some popular type engine implemented things wrongly and everyone else had to follow suit.
  • Generate and test the font again to see how the line spacing looks. If you need to go any tighter you may need to consider changing the shape of the accents, because otherwise the lines will be rubbing together. If the font’s not intended to be commonly used with accents then you can make the ascent lower.
  • Note: Text is often used with extra leading (space between lines, so called from the strip of lead that was once inserted between the metal slugs to make this space); e.g. 12pt type may be set with an extra 2 points between lines as though it was 14pt. Typographers would say the text was set 12/14. In various text editors and document processors this leading comes as default. This is not the spacing you’re looking for when setting the OS/2 spacing values. You’re trying to achieve the correct spacing for text set solid, with no extra space interposed. Some fonts are designed to look great set solid, some are not quite so elegant; but just remember, whatever space you add between lines, more will be added by default by some programs.
  • Another note: When interpolating fonts, FontForge doesn’t interpolate the fields in the OS/2 panel. You will need to manually set these for each new interpolated font.

For my Coelacanth Regular font I ended up with 761 ascent, 239 descent; and in the OS/2 metrics ascents are 912, descents 348, line gaps 0.

6 thoughts on “Line-spacing: getting it right

  • I’m wondering whether you are going to update/upgrade the typeface family you have created or it is already finished. I love it, thank you for your efforts.

    Regards, Q

  • It’s in a semi-constant state of gradual improvement. I haven’t put out a second release yet, since a lot is in flux at the moment and also it currently takes a lot of manual work each time I generate the various font files. Thanks for your encouragement, it’s a good incentive to keep up the pace!

  • Yes, I’ve seen that. I think it’s been around longer than my attempt. My hope is that by open-sourcing this family I can attract other talented people to contribute. I haven’t quite figured out the best workflow for collaborative editing (how do you diff a font-file?), but I’m very open to learning.

  • No good way to diff a font file, that’s for sure. Went through this issue collaborating on EB Garamond (IIRC) and decided to store each glyph file separately (sfdir format, in FontForge-speak), so at least you can tell which characters were updated. But for comparisons, I don’t see how you can avoid having to download the “patch” separately for manual review in the editor. There’s no way to tell from the source what it will end up looking like.

  • Cool, I think you got everything right. All I can add is that in web, line-height:1 seems to be solid, whereas line-height:normal seems to use the Typo ascender and descender and not the general one in OS/2 to determine line height.

Leave a Reply

Your email address will not be published.


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>