Skip to content

Lookup Type 4 — Ligature Substitution

Ligature Substitution is a GSUB rule that replaces two or more glyphs or glyph classes with a single glyph.

sub f i by fi;

Rules are written inside a feature block. Used in the liga feature, for example:

feature liga {
sub f i by fi;
} liga;
sub <glyph sequence> by <glyph>;
  • <glyph sequence> — two or more glyphs or glyph classes, written in the order they occur.
  • <glyph> — the single glyph that replaces the whole sequence.

sub is the short form of substitute. These two rules are the same:

substitute f i by fi;
sub f i by fi;

Within a block, longer sequences are matched first.

The first matching rule is the one applied (first match wins), so rules that replace more glyphs must be stored first. The specification requires the compiler to do this sorting, so the order you write the rules in does not matter.

The syntax is similar to Lookup Type 2, but there is no need to state the Lookup Type. The compiler determines it from the shape of the rule.

# two glyphs → one glyph = Ligature Substitution (Lookup Type 4)
sub f i by fi;
# one glyph → two glyphs = Multiple Substitution (Lookup Type 2)
sub fi by f i;
Without rules
difficult waffle
With rules
difficult waffle
Compiling…
Without rules
1/2 1/4 3/4
With rules
1/2 1/4 3/4
Compiling…

The OpenType specification recommends implementing the following features with this lookup type.

  • liga — Standard Ligatures. Common ligatures such as fi and ffl.
  • dlig — Discretionary Ligatures. Decorative ligatures applied only when the user asks for them explicitly.
  • hlig — Historical Ligatures. Ligatures from historical orthography, such as long s combinations.
  • rlig — Required Ligatures. Ligatures the script requires, such as Arabic lam-alef.
  • ccmp — Glyph Composition/Decomposition. Merges a character sequence into a single glyph before other features run.
  • frac — Fractions. One recommended implementation maps digit–slash–digit sequences to precomposed fraction glyphs.

clig (Contextual Ligatures) also forms ligatures, but it works only in specific contexts, so it is written with contextual rules.