Accéder au contenu principal
☀️ Summer Founder's Deal : licence à vie FontCreator à $49 (au lieu de $199). Offre limitée — se termine le 14 juillet. Profiter de l'offre →

FontCreator Tutorials

Creating Connecting Handwritten Fonts

written by Erwin Denissen, published June 26, 2026

You'll need: FontCreator (Windows and macOS), a base alphabet plus a few alternate glyphs (word-start, word-middle, word-end, and one or two extra "between" variants), and comfort with the OpenType Designer's Code Editor.

FontCreator preview comparing a handwritten word with one form per letter against the same word with contextual alternates varying by position.

a handwritten word rendered twice — once with a single design per letter (mechanical, repeating shapes) and once with contextual alternates (start, middle and end forms varying along the word).

A handwritten font or script font feels alive when no two letters are identical and the strokes connect naturally. Real handwriting changes shape at the start of a word, in the middle, and at the end — and it never repeats exactly. In this font editor you reproduce that with contextual alternates (the calt OpenType feature): FontCreator swaps in word-position forms and cycles through "between" variants so a typed word looks drawn, not stamped.

This tutorial keeps the original calt approach and adds two things that make connecting scripts read as genuinely organic: word-position forms (initial / medial / final) and pseudo-random cycling between multiple middle variants.

Why handwritten fonts need contextual alternates

A handwritten font offers a personalized, organic feel, making it ideal for creative projects. But to avoid the mechanical look of repeating glyphs, we use OpenType layout features to replace the first and last letter of a word and swap other letters with pseudo-random alternatives.

What we'll cover:

  • How to replace first and last letters with contextual alternates.
  • How to create pseudo-random alternates for letters within words.
  • A deep dive into using the calt feature to make these substitutions.

Understanding word boundaries

Contextual substitutions enhance the visual variety of a handwritten font by providing alternate versions of glyphs based on their position in a word. Detecting word boundaries — and how shaping engines process text — can be tricky, but the approach below works across all software that supports OpenType layout features, by reasoning about each letter's neighbours rather than relying on the engine to tell you where a word starts or ends.

The two kinds of alternates (the idea first)

Before any glyph names or feature code, it helps to picture what you're building. Connecting handwriting needs exactly two kinds of alternates, and each one fixes a different way that "typed handwriting" looks fake.

1. Word-position forms — initial, medial, final

A real pen does different things at different points in a word. The first letter usually starts with a lead-in stroke that has nothing to connect to on its left. The last letter often trails off into an exit flourish. The letters in the middle connect on both sides. Type designers call these three the initial, medial, and final forms — the same trio OpenType names init, medi, and fina.

`` word "min" first middle last ───────────── (initial) (medial) (final) ✗ one form: m i n ← all identical, stamped ✓ position forms: m.start i.between n.end ← lead-in, joined, exit ``

So for each letter you draw up to three shapes: a .start (entry stroke, no left join), a .between (joins on both sides), and an .end (exit flourish). The feature then picks the right one based on where the letter sits — does it have a letter before it? after it? — rather than asking the app where words begin.

The letter a shown as initial, medial and final forms with different entry and exit strokes.

the letter "a" drawn three ways — a.start with a left-side lead-in, a.between joining both sides, and a.end with an exit flourish — labelled initial / medial / final.

2. Pseudo-random rotating alternates

Position forms stop the ends of words from looking mechanical, but a long word — or a doubled letter like the two p's in "happy" — still shows the same middle shape twice in a row, which instantly reads as a font rather than a hand. The fix is to draw two or more middle variants (.between1, .between2, …) and have the feature rotate through them: whenever the same middle form would appear twice running, the second one is swapped for the next variant in the cycle.

`` "happy" ✗ one middle: h a p p y ← the two p's are identical ✓ rotating: h a p1 p2 y ← second p uses the next variant ``

This isn't true randomness — it's a deterministic cycle — but because adjacent repeats never match, the eye reads it as the natural variation of real handwriting. Two variants kill most visible repetition; add a third or fourth only if your script has very frequent doubled letters.

With those two ideas in mind — position forms for the ends of words, rotating variants for repeats in the middle — the rest of this tutorial is just naming the glyphs and wiring calt so it applies them.

FontCreator OpenType Designer Code Editor showing the calt feature lookups for start, between, end and rotate.

the OpenType Designer Code Editor in FontCreator showing the calt feature with the ChainingContextStart, ChainingContextBetween, ChainingContextEnd and ChainingContextRotate lookups.

Step 1: Prepare the alternate glyphs

For each letter, prepare alternate glyphs for word-initial, word-final, and middle positions. You can also create multiple middle alternates for pseudo-random variation.

Use a clear, consistent naming convention so the feature classes stay readable. For the letter a:

  • a.start — the word-initial form (often with an entry stroke that doesn't connect on the left).
  • a.between1, a.between2 — middle forms that connect on both sides; two (or more) variants give the random cycling.
  • a.end — the word-final form (often with an exit flourish).

Keep the connecting points aligned across forms so letters join cleanly. For a connecting script, the right side of one letter should meet the left side of the next at the same height.

Tip: Build the base alphabet first and get the connections looking right, then derive .start, .between, and .end forms from it. That keeps the joins consistent.

How the position forms map to lookups

The three position forms from the concept section each become one lookup in the calt code you'll add in Step 2:

  • InitialChainingContextStart: a letter with no letter before it becomes its .start form.
  • MedialChainingContextBetween: a letter that follows a .start or .between form, and has a letter after it, becomes a .between form.
  • FinalChainingContextEnd: a letter with no letter after it becomes its .end form.

Note: Latin script fonts wire word-position behaviour through calt rather than the dedicated init/medi/fina features, because those three are not enabled by default in most Latin text apps, whereas calt is. The result is the same — forms that change by position — but it works without the user turning anything on.

Step 2: Implement the calt feature

The calt (contextual alternates) feature is the key to making contextual substitutions happen. We set up lookups that identify word boundaries and substitute the appropriate glyphs.

In FontCreator, open the OpenType Designer (Font menu → OpenType Designer), click the Code Editor button at the bottom, and replace the existing code (or merge it) with this fea code:

``` ### # OpenType Layout feature definitions # Format: OpenType Feature File Specification version 1.25.1 # Generated by: FontCreator #

languagesystem latn dflt; # Latin default

@letter = [a-z]; @letter.start = [a.start]; @letter.between1 = [a.between1]; @letter.between2 = [a.between2]; @letter.end = [a.end];

lookup SingleSubstitutionEnd { # GSUB lookup type SingleSubstitution sub @letter by @letter.end; } SingleSubstitutionEnd;

lookup SingleSubstitutionBetween { # GSUB lookup type SingleSubstitution sub @letter by @letter.between1; } SingleSubstitutionBetween;

lookup SingleSubstitutionStart { # GSUB lookup type SingleSubstitution sub @letter by @letter.start; } SingleSubstitutionStart;

lookup SingleSubstitution1 { # GSUB lookup type SingleSubstitution sub @letter.between1 by @letter.between2; } SingleSubstitution1;

feature calt { # Contextual Alternates lookup ChainingContextStart { # GSUB lookup type ChainingContext ignore sub @letter.start @letter'; ignore sub @letter.between1 @letter'; ignore sub @letter @letter'; sub @letter' lookup SingleSubstitutionStart @letter; } ChainingContextStart;

lookup ChainingContextBetween { # GSUB lookup type ChainingContext sub @letter.start @letter' lookup SingleSubstitutionBetween @letter; sub @letter.between1 @letter' lookup SingleSubstitutionBetween @letter; } ChainingContextBetween;

lookup ChainingContextEnd { # GSUB lookup type ChainingContext ignore sub @letter' @letter; sub @letter.start @letter' lookup SingleSubstitutionEnd; sub @letter.between1 @letter' lookup SingleSubstitutionEnd; } ChainingContextEnd;

lookup ChainingContextRotate { # GSUB lookup type ChainingContext sub @letter.between1 @letter.between1' lookup SingleSubstitution1; } ChainingContextRotate; } calt; ```

The classes above list only a for brevity. To cover the alphabet, extend each @letter.* class with every letter's matching forms (for example @letter.start = [a.start b.start c.start …];).

Pseudo-random cycling between variants

Real handwriting never repeats the same middle form twice in a row. The ChainingContextRotate lookup creates that illusion cheaply: whenever a .between1 form is immediately followed by another .between1 form, the second one is swapped to .between2. Adjacent repeats therefore alternate between1 → between2, breaking up the "stamped" look without any real randomness.

You can deepen the effect by adding more variants (.between3, .between4) and chaining further rotate rules (between2 → between3, and so on). Each extra rule pushes the next repeat one step further along the cycle, so a long run of the same letter walks through all your variants before it could ever repeat.

FontCreator preview of a doubled letter rendering as two different between forms via the rotate lookup.

a word with a doubled letter — e.g. "happy" — showing the two middle p forms rendered as between1 and between2 rather than two identical shapes.

Tip: Two middle variants are enough to kill most visible repetition. Add more only if your script has very frequent doubled letters.

Step 3: Test and refine

Use FontCreator's preview to test the contextual substitutions in different contexts — single letters, short words, doubled letters, and words that start and end with the same letter. Type real words, not just aaa, so you see the start/between/end logic interact.

Then make sure the font works across a variety of software that supports OpenType features, such as Adobe applications, Microsoft Word, and web browsers. The calt feature is enabled by default in most of them, which is exactly why we routed the word-position logic through it.

Watch out: Order matters. The lookups run top-to-bottom, and the ignore sub rules are what stop a form from being re-substituted once it's already correct. If you reorder the lookups or drop an ignore rule, letters can flip to the wrong position form.

Troubleshooting

SymptomLikely causeFix
No alternates appear at allcalt disabled in the app, or no .start/.between/.end glyphsEnable contextual alternates; confirm the alternate glyphs exist and are named correctly
First letter of a word stays in its default form@letter.start class missing that letter, or ChainingContextStart reorderedAdd the letter to @letter.start; keep the start lookup first
Doubled letters still look identicalChainingContextRotate missing or .between2 not drawnAdd the rotate lookup and a distinct .between2 glyph
Letters connect at the wrong heightEntry/exit points not aligned across formsAlign connection points across .start, .between, .end
Last letter doesn't get its end formChainingContextEnd reordered, or @letter.end incompleteKeep the end lookup in place; complete the @letter.end class

Frequently asked questions

What is the calt feature? calt (contextual alternates) is an OpenType feature that substitutes glyphs based on their surrounding glyphs. For a handwritten font, a font editor uses it to apply word-start, middle, and end forms and to vary repeated letters.

Why use calt instead of init, medi, and fina? For Latin script fonts, calt is enabled by default in most apps while init/medi/fina are not. Routing word-position logic through calt means the alternates appear without the user turning anything on, while producing the same positional behaviour.

How do I make a handwriting font look random? Create two or more "between" variants of each letter and use a rotate lookup that swaps a .between1 followed by another .between1 into .between2. This pseudo-random cycling prevents adjacent repeats from looking identical.

How many alternates per letter do I need? At minimum a start, a middle, and an end form. Adding a second (or third) middle variant is what enables the pseudo-random cycling that breaks up doubled letters.

What to read next