Engineeringこの記事を日本語で読む

Fonts are a localization problem too — glyph coverage, fallback, and tofu

A translation can be word-perfect and still fail on screen. Text rendering is a two-step process — the string has to be correct, and the font drawing it has to actually contain a glyph for every character in that string. Teams that verify translations carefully sometimes skip the second step entirely, because in a Latin-only project it never fails: a Latin font simply covers Latin text. That assumption stops holding the moment another script enters the picture.

Glyph coverage and tofu

A font file is not a general text renderer — it is a fixed set of glyphs mapped to specific code points. A typical Latin UI font covers a few hundred characters: the Latin alphabet in a couple of cases, digits, punctuation, maybe some Latin-adjacent accented letters. That is nowhere near enough for kana or kanji, which is an entirely different, much larger repertoire.

When a font is asked to render a code point it has no glyph for, it cannot skip silently — some rendering systems substitute the font's own placeholder glyph, commonly a hollow box, informally called 'tofu.' Others substitute a designated 'missing glyph' outline that varies by font. Either way, the player sees a visibly broken character where a translated word should be, even though the underlying text data is completely correct.

Why CJK fonts are large

A font's file size is driven mostly by how many glyphs it defines, each with its own outline data. Japanese text alone routinely draws on thousands of distinct kanji beyond the kana syllabaries, and a font aiming for reasonable real-world coverage has to include a large share of them. A Latin font with a few hundred glyphs and a CJK font with several thousand are not comparable in size for that reason alone — it is not inefficiency, it is repertoire.

Fallback chains

The practical fix is not one font that covers everything — very few do — but a fallback chain: a primary font plus one or more backups the rendering system tries, in order, whenever the primary font lacks a glyph for a given code point. A UI can keep its designed Latin font for English and Latin-script languages while falling back to a CJK font only for the characters that need it, including mixed strings that combine both in a single line (a product name in Latin mixed with Japanese surrounding text, for example).

Fallback has to be configured per platform and per rendering path — a chain that works in an editor preview does not automatically apply in a shipped build if the runtime text system has its own, separately configured fallback list.

Han unification: same code point, different expected shape

Unicode's CJK Unified Ideographs block deliberately assigns one code point to characters that Chinese, Japanese, and Korean share a common historical origin for, even where the conventional printed glyph shape differs slightly between those languages — differences in stroke style that a native reader of one language would immediately notice as 'wrong' if shown the other language's typical shape.

This means the same underlying character data can be expected to render differently depending on the target language, which is why font selection has to be tied to language, not just to script. Using a font (or a font's default shaping) tuned for the wrong language in that pair can render technically correct text with visibly foreign-looking glyph shapes to a native reader.

Two things to check before shipping

Two checks are easy to skip and cheap to do:

  • License terms for embedding. A font being freely viewable or usable in a document is not the same as a license that permits embedding it in a distributed application or game — check the specific embedding and redistribution terms before shipping a font with your build.
  • Visual verification per language, not just translation review. A string can pass every translation check and still render as tofu, wrong glyph shapes, or missing punctuation if nobody actually looked at it on screen in that language.

Related articles