skip to main content

Making your own font with Fontra

And learning along the way

I've been working on and off on my own custom typeface for about a year now, slowly piecing together info from the net in the process. Here's a screenshot of the thin weight I'm currently working on.

Zephyr Thin Demo

If you're doing the same thing this should speed you up a bit, even if I myself am still a newbie to this.

Fontra is open-source and cross-platform while being more user-friendly than FontForge, and its development has been sponsored by Google Fonts and Black[Foundry].

Creating a font

Install FontraPak from https://fontra.xyz

Fontra is split on a server (Python) and client (JS/Web) side, which enables multiplayer collaboration à-la Figma and Penpot. FontraPak runs both locally on your device.

Once opened, a window like the following will appear.

FontraPak window

Click on New Font on the top left. You'll see multiple formats (Designspace, Fontra, RoboCJK and UFO), pick Designspace.

UFO is the standard app-independent format for a single font (folders like MyFont_Light.ufo, MyFont_Regular.ufo and so on -- yes, a folder with a pseudo-extension).

Designspace is a folder of UFOs (plus a MyFont.designspace XML file) that combines those fonts into the single typeface. By picking Designspace you're both future proofing your font in case you ever want to scale it up, while still allowing for other potential contributors to use their preferred editor like Glyphs, RoboFont, Fontlab etc. which may have advanced features like plugins, curvature combs and Arabic support.

You should see a page like the following open up in your browser:

Fontra webapp with a new, empty file

Adding glyph sets

Glyph sets are a way to specify which characters you plan on supporting on your fonts. You can pick a standardized glyph set from an existing collection like the one from Google Fonts.

Click on the + button to the right of Project glyph sets. Select the Google Fonts collection and check GF Latin Kernel for now, then save.

Glyph set view

You'll now see the coverage on your font, with light gray cards for each character (from now on simply called glyph) already added.

Line metrics

Before we start drawing any glyphs, we need to think about the anatomy of the font we want to make.

Line metrics diagram

A default Fontra Designspace project has 1000 units per em, but you may come across 1024 or 2048 sometimes. This number is basically the resolution -- while the format is vector based, the nodes snap unit by unit, like if it were pixel based.

Now, out of these 1000 vertical units, we have to pick how many go to each section. Get some paper out and sketch a bit. Draw enough glyphs to figure out the proportions for the ascender, x-height and descender, then try to retroactively give it sizes by literally measuring on paper and rounding.

Glyph sketches

You can probably tell I drew this sketch before I learned all of this lol.

In this case I chose to make the lowercase A double-storey, roughly following the 2/sqrt(2) ratio from baseline to the upper area of A's bowl. Then I added a second one on top that was once again compressed to sqrt(2), which defined the x-height.

I took that same compressed height and stacked it again for the ascender and descender.

The cap height should be derived from the x-height. Body fonts (those used for long-form text at small sizes) should hover around from 65% to 75% caps height to x-height ratio -- I picked as close to 75% as possible which is roughly where Inter and Helvetica hover around, as my intention for this font is to be used on an UI context.

You can just vibe this step with your eyes if you don't want to overcomplicate things yet.

Line metrics view

As you can see, 550/740 is ≈ 75%, 775-550 = 225 (which matches the descender).

The values on the left should sum up to your units per em (default to 1000), 775+225 = 1000. At least, I think so -- I'm still learning!

Compensating for optical illusions

The number inputs on the right of each metric act as buffer zones for overshoots. As a rule of thumb, the smaller in size you expect the font to be used, the greater the buffer has to be. Read this page from Fábio Duarte for more info on this.


Drawing our first glyph in Fontra

We can now start drawing our first glyphs, lowercase N and O. These will act as the base for the others.

Go back to the glyph grid and double click the lowercase N card. A new editor tab will open. The UI is pretty self explanatory so just play around with it and we'll start drawing once you come back.

Empty glyph editor tab

Select the rectangle tool, and add a rectangle from the x-height to the baseline to make a vertical stroke. Unlike on editors like Figma, the selection tool (Pointer) doesn't select the entire shape by just clicking on the fill -- you need to do a rectangle selection OR shift+click each individual node.

On the right sidebar, select the Selection Transformation tab. You'll be able to see the width and height of the selected shape.

There's also an option to see the coordinates on each selected node. It's on View ➜ Glyph editor appearance ➜ Coordinates.

There's also a Ruler tool that sticks and rotates along the closest edge where you click, which is pretty handy.

Rectangle in editor

Pick the pencil tool and start drawing a custom shape. We'll now do the shoulder.

Starting shoulder

Hold shift to lock the X or Y axis down and draw a straight line down. Then finish this shape by drawing your way back to the initial point, where you click to complete it. You'll see a blue circle while hovering the node, clicking here will close the contour.

Closing shoulder

You can also click on the middle of a line to split it with a node -- you'll see the blue circle again.

Closed shoulder

Now, to make the lines curved instead of straight, hold the Alt key and click with your Pencil tool. You'll see two smaller blue circles before clicking.

Curve indicator preview

Curve handles

It's better to have the same angle on either side, so hold shift when moving the handles.

Once you're finished making all the lines curved, chances are it'll look a bit rough.

This does not bring joy

Some tips: make sure the shoulder goes up to the overshoot region. Remember that it's rounded so it needs that compensation.

Slightly better now

Now while having both nodes selected like in the picture, hold Alt and use the arrow keys to nudge the nodes left or right while keeping the curve handles where they are. Trust your eyes. Also nudge the nodes on the right side.

Acceptable

Now we have to think about contrast, which would be how much narrower are horizontal strokes compared to vertical ones.

If you were to set both to, say, 80, the top side of N's shoulder would paradoxically look bolder/wider than the vertical lines on either side -- this is another optical illusion that we want to compensate for.

If you want to make it visually the same, you should do about 10% less on horizontal strokes, which is what we'll do here by setting it to 72. You can make it more contrasty if you want.

With proper contrast

Now we have to fix that weird hole where both shapes intersect. Why is that happening? Well, it's because of the draw direction. Notice how every shape has a node with a half circle -- that's where the shape starts to be drawn by the computer. If both shapes happen to have the same direction, they will combine. If they don't, they'll cancel each other out and leave a hole.

Best practice is to have additive shapes be drawn clockwise and subtractive ones like counterforms (the negative space in O for example) counter-clockwise.

I also recommend to start drawing every shape on the nodes closest to the top of the shape for consistency's sake.

Setting start point

New start point

Now we can see clearly that it's drawing on the other direction. Change it to clockwise to make it additive. Right click ➜ Reverse contour direction.

You can hold the Space key to hide the editor UI and preview the glyph with a solid color.

N preview

Now try drawing the lowercase O by yourself. Remember that you should do both vertical and horizontal overshoots, so it should be wider than the lowercase N -- in this case, it's about 40 units wider horizontally, according to the Dimensions section in the Glyph info panel on the right.

O preview

Side bearings

That's the name of the space we've been leaving at either side of the glyphs. It varies depending on the shape of each glyph -- the gap on the right side of the lowercase R has more space for volume than, say, the lowercase Q, so we have to take that into consideration.

You can eyeball it but it's better to follow some sort of guideline to keep things consistent. One of those is called the Tracy method, which you can read more about in this page.

#DescriptionUnits
1Same as left side bearing of n70
2Same as right side bearing of n65
3Slightly more than left side bearing of n75
4Minimum side bearings35
5Same side bearings as o50
6Slightly less than side bearings of o45

Kerning

Unfortunately side bearings only gets us so far.

Kerning groups

foo

(advanced) interpolation theory

luc(as) de groot interpolation theory


Further reading

  • Designing Type by Karen Cheng
  • The Stroke: Theory of Writing by Gerrit Noordzij