Letras Diferentes
Unicode research · Font character coverage

Font Coverage and Unicode Support: Cmap Tables, Shaping and Real-World Limits

Distinguish Unicode assignment from font glyph coverage, OpenType cmap mappings, variation selectors, GSUB/GPOS shaping, color emoji and cross-platform support tests.

Technical referenceUnicode baseline: 18.0.0

Unicode defines text; fonts draw glyphs

The Unicode Standard assigns code points, character properties and textual algorithms. It does not require each installed font to contain a glyph for every assigned character. A file can contain perfectly valid UTF-8 and a string can preserve the intended Unicode scalar sequence while a device displays empty squares because its available fonts do not provide suitable outlines or rendering behavior.

The word “supported” needs qualification. A code point may be assigned in the Unicode version known to a newer operating system, but an older system's fonts may not cover it. Another font may nominally contain a mapping yet lack appropriate contextual shaping or mark positioning. A sequence can also require an emoji ZWJ ligature, variation-selector response or color-glyph technology that an otherwise broad Unicode font does not provide.

OpenType cmap maps code points to glyph IDs

In OpenType, the cmap table connects character codes to glyph indices, usually called glyph IDs. For example, a font might map U+0041 LATIN CAPITAL LETTER A to glyph 36. The number 36 is meaningful only within that font; glyph IDs are not Unicode code points and are not stable across fonts or font versions. cmap format 4 supports mappings within the Basic Multilingual Plane, while format 12 supports segmented mappings using 32-bit codes, important for supplementary characters.

A cmap mapping is necessary for straightforward glyph access but not sufficient to prove that a complex script will render correctly. Many scripts require glyph substitution and positioning driven by shaping rules. Variation sequences have specialized cmap format 14 support for Unicode variation selectors, with default and non-default UVS mappings. A simple check for an isolated base character does not establish correct variant presentation.

LayerQuestionWhat a pass does not prove
Unicode scalarIs the text well-formed and code point assigned?Font contains a suitable glyph
OpenType cmapIs there a glyph mapping?Correct shaping for full sequence
GSUB/GPOSCan features select and position glyphs?Renderer enables required script features
Font fallbackIs another face available?Matched metrics and consistent design
Color glyph supportCan a renderer paint color emoji?Every emoji ZWJ sequence is recognized

Unicode versions and font-release history

Character repertoire evolves over time. A website that outputs U+1D400 MATHEMATICAL BOLD CAPITAL A relies on a recipient device having a font capable of drawing it. The character was standardized long ago, but support varies across platforms. Recently added emoji or script characters are more likely to display as missing glyphs on older devices. Neither the code point's age nor the operating system's version alone guarantees that every selected font can render it.

When documenting a bug, record the exact Unicode scalar sequence, font family and version, browser/OS build, text direction and relevant CSS. A vague claim that “Unicode is unsupported” hides whether the issue comes from repertoire coverage, fallback selection, shaping or a stale glyph cache.

Coverage versus shaping: GSUB and GPOS

Complex scripts may use multiple underlying scalars for one orthographic unit. An Arabic joining form, Indic consonant conjunct or mark combination can require a shaping engine to apply OpenType GSUB substitution and GPOS positioning. A font may provide individual glyphs for every character but still fail to assemble or position them according to the script's expected conventions.

Contextual shaping is distinct from Unicode normalization. A sequence can be canonically normalized while still needing shaping; a font with correct glyphs may display decomposed accents poorly if it lacks mark anchors. Conversely, a visually convincing ligature does not merge its underlying characters into one Unicode scalar.

Emoji variation selectors and color fonts

Emoji presentation often depends on U+FE0E VARIATION SELECTOR-15 for text style and U+FE0F VARIATION SELECTOR-16 for emoji style where the sequence supports them. A font that covers the base code point may not provide the selected presentation or a colored glyph. Modern color-font technologies include COLR/CPAL, CBDT/CBLC and sbix, with support varying by rendering engine.

Emoji ZWJ sequences are still more demanding: a single user-perceived emoji can require several code points, including U+200D ZERO WIDTH JOINER, and a shaping or emoji implementation that recognizes the combined sequence. If the combined glyph is unavailable, the system may display components separately rather than a square; this outcome does not by itself mean the UTF-8 bytes changed.

CSS font families, language and Unicode-range

CSS font-family defines an ordered preference list; the browser selects a usable face for characters or runs, potentially invoking system fallback when a preferred face lacks coverage. The @font-face unicode-range descriptor can help a browser choose which web font resource to fetch for selected code-point ranges, but it is not a magic glyph generator or proof that the underlying font contains every range member.

Likewise, CSS font-weight changes presentation of ordinary characters rather than creating Unicode mathematical bold letters. For a technical illustration, the US Fancy Text tool can produce genuine mathematical and enclosed Unicode characters whose exact scalars can be compared across font stacks. If a glyph is missing, first determine whether the underlying code point survived copy-paste.

/* Font choice is presentation, not Unicode scalar conversion. */
.sample {
  font-family: "Noto Sans", "Segoe UI Symbol", sans-serif;
  font-weight: 400;
}
.sample strong { font-weight: 700; }
/* 𝐀 is U+1D400 even when the font fallback looks different. */

Inspect glyph coverage using font tools

A developer can inspect cmap tables using fontTools (for example, Python's TTFont), graphical font inspectors or an OpenType dump utility. A reliable test checks whether the selected face maps a target scalar and whether shaping produces appropriate glyphs for the entire sequence. Font metadata and rendered output must agree: a glyph mapping to .notdef signals missing coverage, but a mapping to a placeholder-looking glyph can also produce a box.

# Example with third-party fontTools installed:
from fontTools.ttLib import TTFont
font = TTFont("YourFont.ttf")
cmap = font.getBestCmap() or {}
for cp in [0x41, 0x00E9, 0x1D400, 0x1F600]:
    print(f"U+{cp:04X}",cmap.get(cp,"NO DIRECT CMAP GLYPH"))
# This is a mapping probe, not a full GSUB/GPOS/emoji test.

A file must be licensed for inspection and distribution, and the diagnostic should use the actual installed or served version. Font coverage can change between releases under the same family name. A browser may be rendering a different font than the one you inspected, so confirm the chosen run's font in developer tools when possible.

Per-run coverage and shape-sensitive font fallback

Font fallback typically selects substitute fonts when a requested font lacks glyphs for text. However, fallback is not always a one-code-point operation: a shaping run with multiple marks or joining characters may need consistent glyph handling in a single face to render correctly. Splitting a base character and combining mark across unrelated fonts can cause alignment problems, even if both fonts individually have the required glyphs.

Language tags such as lang="ja" versus lang="zh-Hans" can affect CJK glyph selection where the same unified ideograph has regional glyph variations. These variations do not necessarily imply different Unicode code points. Unicode encoding, language metadata and font design are separate dimensions of interoperability.

A minimal cross-platform test plan

Test vectorExpected diagnostic
U+0041 ABasic Latin glyph mapping present
U+00E9 é and e + U+0301Compare composed/decomposed rendering and marks
U+1D400 𝐀Probe supplementary cmap coverage
U+1F600 😀Check emoji font and monochrome/color support
Woman + ZWJ + laptopCompare combined versus decomposed emoji presentation
Arabic joining sequenceCheck GSUB contextual joining
Indic base + matraCheck GPOS and script shaping
Same code point with language changeCheck locale-appropriate CJK glyph variant

Document exact scalar sequences, font files, shaping-engine versions and screenshots as separate evidence. Running a broad code-point coverage script is only the first layer of a meaningful Unicode rendering assessment.

Standards and implementation references

  1. OpenType specification — cmap table
  2. OpenType specification — GSUB
  3. OpenType specification — GPOS
  4. UTS #51 — Unicode Emoji
  5. MDN — CSS unicode-range
  6. fontTools — TTFont reference

Independent research. A Unicode-valid scalar, a font cmap entry and a correctly shaped glyph are different interoperability guarantees.