Text shaping is an integral part of preparing text for display. Before a Unicode sequence can be rendered, the codepoints in the sequence must be mapped to the corresponding glyphs provided in the font, and those glyphs must be positioned correctly relative to each other. For many of the scripts supported in Unicode, these steps involve script-specific layout rules, including complex joining, reordering, and positioning behavior. Implementing these rules is the job of the shaping engine.
Text shaping is a fairly low-level operation. HarfBuzz is used directly by text-handling libraries like Pango, as well as by the layout engines in Firefox, LibreOffice, and Chromium. Unless you are writing one of these layout engines yourself, you will probably not need to use HarfBuzz: normally, a layout engine, toolkit, or other library will turn text into glyphs for you.
However, if you are writing a layout engine or graphics library yourself, then you will need to perform text shaping, and this is where HarfBuzz can help you.
Here are some specific scenarios where a text-shaping engine like HarfBuzz helps you:
-
OpenType fonts contain a set of glyphs (that is, shapes to represent the letters, numbers, punctuation marks, and all other symbols), which are indexed by a
glyph ID
.A particular glyph ID within the font does not necessarily correlate to a predictable Unicode codepoint. For instance, some fonts have the letter "a" as glyph ID 1, but many others do not. In order to retrieve the right glyph from the font to display "a", you need to consult the table inside the font (the
cmap
table) that maps Unicode codepoints to glyph IDs. In other words, text shaping turns codepoints into glyph IDs. -
Many OpenType fonts contain ligatures: combinations of characters that are rendered as a single unit. For instance, it is common for the "f, i" letter sequence to appear in print as the single ligature glyph "fi".
Whether you should render an "f, i" sequence as
fi
or as "fi" does not depend on the input text. Instead, it depends on the whether or not the font includes an "fi" glyph and on the level of ligature application you wish to perform. The font and the amount of ligature application used are under your control. In other words, text shaping involves querying the font's ligature tables and determining what substitutions should be made. -
While ligatures like "fi" are optional typographic refinements, some languages require certain substitutions to be made in order to display text correctly.
For example, in Tamil, when the letter "TTA" (ட) letter is followed by the vowel sign "U" (ு), the pair must be replaced by the single glyph "டு". The sequence of Unicode characters "ட,ு" needs to be substituted with a single "டு" glyph from the font.
But "டு" does not have a Unicode codepoint. To find this glyph, you need to consult the table inside the font (the
GSUB
table) that contains substitution information. In other words, text shaping chooses the correct glyph for a sequence of characters provided. -
Similarly, each Arabic character has four different variants corresponding to the different positions it might appear in within a sequence. Inside a font, there will be separate glyphs for the initial, medial, final, and isolated forms of each letter, each at a different glyph ID.
Unicode only assigns one codepoint per character, so a Unicode string will not tell you which glyph variant to use for each character. To decide, you need to analyze the whole string and determine the appropriate glyph for each character based on its position. In other words, text shaping chooses the correct form of the letter by its position and returns the correct glyph from the font.
-
Other languages involve marks and accents that need to be rendered in specific positions relative a base character. For instance, the Moldovan language includes the Cyrillic letter "zhe" (ж) with a breve accent, like so: "ӂ".
Some fonts will provide this character as a single zhe-with-breve glyph, but other fonts will not and, instead, will expect the rendering engine to form the character by superimposing the separate "ж" and "˘" glyphs.
But exactly where you should draw the breve depends on the height and width of the preceding zhe glyph. To find the right position, you need to consult the table inside the font (the
GPOS
table) that contains positioning information. In other words, text shaping tells you whether you have a precomposed glyph within your font or if you need to compose a glyph yourself out of combining marks—and, if so, where to position those marks.
If tasks like these are something that you need to do, then you need a text shaping engine. You could use Uniscribe if you are writing Windows software; you could use CoreText on macOS; or you could use HarfBuzz.
In the rest of this manual, the text will assume that the reader is that implementor of a text-layout engine.