From letterform anatomy to TrueType file, grounded in real measurements of working fonts.
A font is not a drawing. It is a system — a few hundred shapes engineered to look right together, at any size, in any sequence, on any surface. This guide explains what makes that system work. Every claim about proportion or weight is backed by measurements pulled directly from production TrueType files: Liberation Sans, Liberation Serif, Liberation Mono, Carlito, Caladea, and FreeSerif. Where we say "the x-height is typically about half the em," we have measured it.
The guide is organized so that you can read it through or jump to the section you need. It moves from the anatomy of a single letterform, to the patterns that hold a family together, to the file format that delivers it, and finally to a twelve-step process for building one from scratch.
Great fonts are judged by three things in this order: readability, character, and craft. Readability is whether the eye can move through text without friction. Character is whether the type feels like something — warm, precise, austere, friendly — rather than nothing. Craft is the thousand invisible adjustments that make the letters behave consistently in every word, every weight, every size.
None of these are decorative. They are all structural. A font that fails on readability is unusable no matter how beautiful, and a font with no character is forgettable no matter how clean. The goal of the type designer is to hold all three in tension.
You cannot critique what you cannot name. Before drawing anything, learn to see these parts in every letter you look at. The figure below shows the four fundamental horizontal guidelines, drawn against six real glyphs from Liberation Sans — the same shapes that ship in the file on your system.
Before you draw a single curve, decide your vertical proportions. Every glyph you draw afterward will be measured against them. Type design happens on a grid called the em, conventionally either 1000 or 2048 units per em. Liberation and the Cros-extra fonts use 2048; FreeSerif and Caladea use 1000. The number itself is arbitrary, but every measurement is expressed in it, so pick one and stick with it.
The table below lists the actual published metrics from each TrueType file analyzed for this guide. The percentages are normalized to the em so you can compare across designs.
| Typeface | Class | UPM | x-height | cap height | x/em | x/cap |
|---|---|---|---|---|---|---|
| Liberation Sans | Sans (Neo-grotesque) | 2048 | 1082 | 1409 | 52.8% | 76.8% |
| Liberation Sans Bold | Sans, bold | 2048 | 1082 | 1409 | 52.8% | 76.8% |
| Liberation Serif | Transitional serif | 2048 | 940 | 1341 | 45.9% | 70.1% |
| Liberation Mono | Monospace | 2048 | 1082 | 1349 | 52.8% | 80.2% |
| Carlito | Humanist sans | 2048 | 978 | 1314 | 47.8% | 74.4% |
| Caladea | Transitional serif | 1000 | 467 | 667 | 46.7% | 70.0% |
| FreeSans | Sans (Helvetica-like) | 1000 | 524 | 729 | 52.4% | 71.9% |
| FreeSerif | Old-style serif | 1000 | 450 | 662 | 45.0% | 68.0% |
A pattern emerges immediately. The sans-serif designs cluster around 52–53% x-height-to-em. The serif designs cluster around 45–48%. This is not an accident. A sans-serif has nothing decorative to carry the eye, so its lowercase letters lean larger and more open to compensate. A serif font earns visual rhythm from its terminals and so can afford smaller lowercase, leaving more room for ascenders and descenders that aid word-shape recognition.
Round letters and pointed letters must extend slightly beyond the baseline and x-height to look the same height as flat letters. In Liberation Sans we measured the lowercase o reaching to y=1102 against an x-height of 1082 — an overshoot of 20 units, or just under 2% of x-height. The same font's lowercase n reaches exactly 1102 as well, because its top is curved. Without overshoot, every round letter would appear too small. With too much overshoot, the type looks wobbly. The right amount is something you train your eye to feel.
Western type has settled into five broad style families, each with a different historical lineage and a different best use. A designer picks the family before drawing anything because it determines almost every other decision: the shape of the o, the stress of curves, the kind of terminal, the rhythm of the stems.
Descended from the earliest printed types of the 15th and 16th centuries. Modest stroke contrast, diagonal stress (the thinnest part of an o lies on a diagonal axis, as if drawn with a slanted pen), bracketed serifs, lowercase that feels handwritten. Best for long-form reading: novels, essays, books. Examples in the wild: Garamond, Caslon, Bembo, Minion. FreeSerif on your system is in this lineage.
The 18th-century compromise. Higher stroke contrast than old-style, vertical (rather than diagonal) stress, sharper serifs, more rationalized letterforms. The workhorse class for editorial design. Times New Roman, Baskerville, Georgia. Liberation Serif and Caladea sit here. Below is Liberation Serif's H, a, g, o, n, R drawn at scale from the file:
The late 18th-century rationalist break. Extreme stroke contrast (very thick stems against hairline thins), strictly vertical stress, unbracketed flat serifs. High elegance, low legibility at small sizes. Bodoni, Didot, Walbaum. Best for headlines, fashion, luxury. Avoid for body text.
Born in the 19th century for advertising. Low stroke contrast, rectangular slab serifs that match stem thickness. Robust, friendly, holds up at small sizes and on rough paper. Rockwell, Roboto Slab, Tisa, Archer. Excellent for UI subheads.
No serifs. The fastest-growing class for two centuries and the default for screens. The sans family sub-divides further:
A monospace font assigns every glyph the same advance width. In Liberation Mono we measured every analyzed glyph — H, x, n, o, p, I, l, 1, g — with an advance width of exactly 1229 units. That constraint warps everything: the I and l need flared serifs to fill their cell; the m and w need to be compressed to fit; spacing cannot be optical, only mechanical. Used for code, tabular data, and anywhere column alignment matters.
Stroke contrast is the ratio between the thickest and thinnest part of a letter. Stress is the axis along which the contrast falls. Together they tell almost the whole story of a typeface's voice.
A low-contrast vertical-stress design feels rational and mechanical (Helvetica). A high-contrast vertical-stress design feels formal and refined (Bodoni). A low-contrast diagonal-stress design feels warm and handwritten (Garamond). A high-contrast diagonal-stress design is rare and looks like calligraphy.
Stem widths from the files we analyzed, normalized to x-height:
| Font | Stem (em-units) | x-height | Stem / x-height |
|---|---|---|---|
| Liberation Sans (Regular) | ~191 | 1082 | 17.7% |
| Liberation Sans (Bold) | ~295 | 1082 | 27.3% |
| FreeSans (Regular) | ~94 | 524 | 17.9% |
| Carlito (Regular) | ~182 | 978 | 18.6% |
For sans-serif regular weights, the stem lands consistently at 17–19% of x-height. That is not coincidence; it is the band where strokes look solid but counters stay open. Below 12% the strokes look fragile; above 25% the counters start to fill in. For bold weights, the stem grows to roughly 27–30% — about 50–60% thicker than the regular. (Liberation Sans Bold's 295 vs Regular's 191 is precisely a 1.54× ratio.)
A high x-height makes letters look larger at a given point size. But x-height has to be paid for: every unit you raise it is a unit you steal from ascender and descender length, and short ascenders make words harder to recognize. The eye reads not single letters but word-shapes, and ascenders/descenders are what give words their silhouettes.
Counter size and aperture matter just as much. Compare the lowercase a in three faces, drawn from the actual files:
The lowercase g is where designers are most expressive. Single-story (one closed bowl plus a tail, like Futura) is geometric and direct. Double-story (closed upper bowl, closed lower bowl connected by a link, with an ear) is more readable and considered more elegant. Almost every serif and most humanist sans use double-story g.
The single most common font-design failure is the I-l-1 collision. A capital I, a lowercase l, and a digit 1 can be nearly indistinguishable in a strict geometric design. This is a critical problem for any context involving passwords, code, license keys, or numerical data.
Strategies for a great font:
Beautiful glyphs can produce ugly words. Every glyph carries a left side bearing (LSB) and right side bearing (RSB) — the gap between the glyph's drawn outline and the edges of its allocated horizontal cell, called the advance width. Spacing is more than half the work of finishing a typeface.
In Liberation Sans, the capital H is drawn with an LSB of 168 em-units and an advance width of 1479. The letterform itself spans 1144 units, which means the RSB is 1479 − 168 − 1144 = 167 units. The bearings are symmetric, because the H is symmetric. The lowercase o has LSB 86 and RSB about 86 too — bearings smaller than the H's, because the round form already has a perceived gap built into its curve.
HHH. Aim for a comfortable gap that is neither cramped nor airy.HOHO HHOO and adjust the O's bearings until both letter pairs look even.Modern fonts store kerning in the OpenType GPOS table; legacy files used the simpler kern table. Of the eight fonts analyzed for this guide, all eight have GPOS; six also retain a legacy kern table for compatibility.
An outline that looks perfect in your design tool may render as mush at 11px on a screen. The pixel grid is too coarse to honor the curves you drew. Hinting is the set of instructions embedded in a TrueType file that tells the rasterizer how to bend your outline onto the grid without destroying it.
For a great font, hinting answers four questions at every pixel size:
Three flavors exist:
A .ttf file is a binary container holding a set of named tables. To ship a real font you need each of these populated correctly, not just glyph outlines. The most important:
| Table | Purpose |
|---|---|
head | Global font header: units-per-em, creation date, bounding box of all glyphs, flags. |
hhea / vhea | Horizontal (and optional vertical) header: ascender, descender, line gap. |
OS/2 | Windows-specific metrics: x-height, cap height, weight class (400 regular / 700 bold), width class, Panose classification, typographic family name. |
name | Family name, style, copyright, license, designer credit — the strings the OS shows in font menus. |
cmap | Character-to-glyph mapping. Maps every Unicode codepoint to its internal glyph index. |
glyf | The actual outlines, in quadratic Bézier curves. (The OpenType variant CFF uses cubic curves instead.) |
hmtx | Per-glyph horizontal metrics: advance width and left side bearing. |
maxp | Total number of glyphs and various memory-allocation maxima. |
post | PostScript glyph names — legacy but still required. |
GSUB | Glyph substitution rules: ligatures (fi → fi), small caps, alternates, contextual swaps. |
GPOS | Glyph positioning: modern kerning, mark-to-base attachment for accents. |
kern | Legacy kerning, optional; superseded by GPOS but often kept for compatibility. |
fpgm / prep / cvt | TrueType hinting bytecode and control values. |
To give a sense of scale: the Liberation Sans file holds 2,620 glyphs; FreeSerif holds 13,477. The difference reflects coverage of non-Latin scripts. A first-release Latin-only font typically ships 250–800 glyphs, covering basic Latin, Latin-1 supplement, currency symbols, punctuation, and small caps.
Write down, in one paragraph, what the font is for. “A humanist sans for long-form magazine reading on tablets, 14–18px, with a quiet, slightly bookish personality.” Every later decision is judged against this paragraph. Without it, you will drift.
Pick UPM (1000 or 2048). Decide cap height, x-height, ascender, descender, and overshoot. Use the proportions table in §03 as a starting point. Write these down and never change them after you start drawing — if you do, every glyph must be redrawn.
Draw n, o, H, O first. These four letters establish: the stem width (n, H), the curve handling and overshoot (o, O), the bowl shape (n, O), the cap-to-x ratio (H vs n), and the contrast and stress (o). Don't move on until they feel correct in the strings nnn, noon, HHH, HOOH.
Draw p, b, d, h, l, m, u, a, e, s, t, v, x and D, E, V, S, X, R. By the time these are in place, you have committed to most of the typeface's character. Test with the word-set adhesion, HAMBURGER, nominal, vox dramatic.
Fill in the remaining lowercase and uppercase. Then design the numerals as a coherent set — either lining figures (all the same height as caps, good for tables) or old-style figures (with ascenders and descenders, good for running text). A great font ships both.
Periods, commas, quotation marks — subtle but high-impact. Quotes should be true typographic quotes (“ ” ‘ ’), not straight marks. Build accented characters by combining a base glyph with a mark; the OpenType GPOS table can handle the placement. Cover at least Latin-1 supplement and currency: £ € ¥ ¢.
Follow the H/O method in §08. Type the words HHOOHH nnoonn and adjust until the rhythm is even. Then test against a long passage of Latin pseudo-text. If the page has dark spots or holes, fix the bearings of the offending glyphs — never use kerning to mask bad bearings.
Likely candidates: T+ vowels, A+V, A+W, A+Y, F+ vowels, L+T, L+Y, P+a, P+o, V+a, W+a, Y+a, r+,, r+., quotation+vowels. Start with maybe 200 pairs; a thorough professional font carries 1,000–3,000. Use OpenType classes (@uppercase, @lowercase-round) so one rule covers many pairs.
A typeface with one weight is not a typeface, it is a sketch. At minimum ship Regular, Italic, Bold, Bold Italic. Better: add Light, Medium, Semibold, Black. Best: design as a variable font with a weight axis (and optionally width, optical-size, slant). Variable fonts are the modern default and a single file replaces a dozen.
Run ttfautohint over the file. Inspect the result at 9, 11, 13, 16, and 24 pixels on Windows ClearType, macOS, and a phone. Fix glyphs that break. If you have time and need, hand-hint the critical ASCII range.
Body paragraphs (a Wikipedia article or two), a headline at 96px, a UI mockup with labels and buttons, a table of figures, a passage in another language that uses your diacritics, code with the I/l/1 disambiguation test. If the font fails any of these, go back — do not ship.
Generate .ttf (and .woff2 for web). Fill in the name table with proper family, version, copyright, and license metadata. Pick a license — SIL OFL 1.1 is the standard for open-source release and is what Liberation, FreeSans, Carlito, and Caladea all ship under. Write documentation. Release.
adhesion, nominal, handgloves, HAMBURGEFONTSIV read cleanly.name table is fully populated with family, style, version, designer, copyright, license URL.
Every measurement and every glyph figure in this guide was extracted directly from production TrueType files using Python's fontTools library. No data was approximated or invented.