Matterhorn 31-022 · PDF/UA-1 UA1:7.21.6-6
Glyph names like g17 in a TrueType Differences array
Glyph names in /Differences must be resolvable through the Adobe Glyph List so a processor can derive Unicode.
The condition, as the protocol states it. “The Differences array in the Encoding entry in a non-symbolic TrueType font dictionary contains one or more glyph names which are not listed in the Adobe Glyph List.”
Matterhorn Protocol 1.1, checkpoint 31, index 31-022, section UA1:7.21.6-6. Software can decide this one on its own.
What a screen reader actually does
Characters using those names extract as nothing.
Why the names have to mean something
A simple font maps each byte in the content stream to a glyph name through its encoding, and a /Differences array overrides the names for some codes:
/Encoding << /Type /Encoding
/BaseEncoding /WinAnsiEncoding
/Differences [ 1 /g3 /g17 /g42 /g8 ]
>>
Code 1 is now the glyph named g3, code 2 g17, and so on. For other font types, what the names mean matters only when the font has no ToUnicode CMap. For a non-symbolic TrueType font it matters regardless, because of how PDF/UA treats this font type.
PDF/UA-1 clause 7.21.7 exempts non-symbolic TrueType fonts from needing a ToUnicode CMap. The reasoning is that their encoding already says what every code is: a byte becomes a glyph name, and the glyph name becomes a Unicode character through the Adobe Glyph List, Adobe’s published table from names such as eacute and quoteright to code points. That only holds if every name is in the list. Clause 7.21.6 makes it a requirement, and condition 31-022 is a /Differences array with names that are not.
g17 is not in the list. It is a name a subsetting tool made up: glyph number 17 in the original font. Nothing outside that font program knows what it is.
What breaks, and what the user hears
The page often looks right. ISO 32000-1 lets a viewer that cannot resolve a glyph name look it up among the glyph names stored in the font program, and when the subsetter wrote the same invented names into the program, g17 is there to be found. Poppler and PDFium both drew the right glyphs from our test file built that way. When the program carries no names, they have nothing to find: from the same file with the names removed from the program, both drew the .notdef box for every character.
The text is another matter. If the font has no ToUnicode CMap, which this font type is allowed to omit, the only route from code 2 to a character is g17, and g17 leads nowhere. What a reader gets is a fallback: Poppler’s pdftotext extracted the raw byte values from our test file, the control characters U+0001 and U+0002, and PDFium did no better. A screen reader has nothing to say for those, and copy and paste produce the same gaps.
If the font does carry a ToUnicode CMap, readers use it first and the text survives. The font still fails the condition: it is relying on a CMap that PDF/UA says this font type should not need.
Where it comes from
A /Differences array needs a name for every glyph it uses. TrueType programs keep glyph names in their post table, and plenty keep none: version 3 of that table carries no names at all. A subsetting tool working from such a font invents names from the glyph numbers, and the careful ones write the same invented names into the subset’s own post table so that viewers can find the glyphs. Typical results are g17, glyph17 or index17. A font whose post table carries real names produces real ones, such as eacute, and passes.
How to check it free
Copy and paste a paragraph into a plain text editor. Missing letters or control characters where the page shows text is the symptom, though a ToUnicode CMap can hide it.
pdffonts shows Custom in the encoding column for any font with a Differences array, which tells you which fonts to look at. Then print the encoding with qpdf --show-object= and the object number, and read the names. Names made of a letter or a short word and a number, such as g17 or glyph42, are the usual sign.
Acrobat Pro shows the same dictionary in Preflight’s internal structure browser: All tools → Use print production → Preflight, then Options → Browse Internal PDF Structure, as Adobe describes in advanced preflight inspections. It does not let you edit it.
veraPDF tests the Differences names of non-symbolic TrueType fonts in its PDF/UA-1 profile.
How to fix it free
Re-export from the source, with a different font if necessary. A font whose program carries proper glyph names, or a producer that embeds TrueType fonts as Type 0 fonts with a ToUnicode CMap, avoids the condition entirely. Adobe’s guidance for the Accessibility Checker’s Character encoding rule, in Create and verify PDF accessibility, is the same: use a different font, preferably OpenType, in the original document and re-create the PDF. Adobe also notes that some character-encoding problems cannot be repaired within Acrobat.
Renaming by hand is possible and rarely worth it. If the font has a ToUnicode CMap you trust, it tells you what each code is, and g17 could be rewritten as uni00E9 in the Differences array. But a non-symbolic TrueType viewer then finds the glyph by looking U+00E9 up in the program’s Unicode cmap, not by name, so the edit is only safe if that cmap maps every one of those characters to the same glyph the name did. That is a check for fontTools, one glyph at a time.
What Taggart catches, and what it doesn’t
One finding per font, counting the names it rejected and quoting up to five:
/ABCDEF+Calibri: the /Differences array contains 2 glyph name(s) that do not resolve through the Adobe Glyph List (e.g. g17, g88).
The full list of rejected names, up to twenty, is in the finding’s evidence.
The test is a shape test, not a lookup in the full list. A name passes if it looks like a glyph name — a letter followed by letters, digits, dots or underscores, or the uniXXXX and uXXXX forms — and is not one of the invented prefixes: g, G, glyph, index or cid followed by a number. It catches the names subsetters produce, and names that cannot be glyph names at all, such as a bare number. It does not catch a name that is well formed and simply not in the list: Bullet2 passes Taggart and fails the condition.
Taggart does not report 10-001 or 31-027 for these codes, because a non-symbolic TrueType font is exempt from needing a ToUnicode CMap. This finding is the one that tells you the text has no defined route to Unicode. There is no repair: it would mean deciding what g17 is, and the file does not say.
How Taggart handles it
Taggart checks for the common form of this condition automatically and reports it as a blocker. The check does not cover every form of it; what it misses is described above.
Whatever Taggart changes, the page still looks identical. Fixes edit the PDF object model, not the content streams, and every remediation is re-rendered and compared against the original at structural similarity ≥ 0.999 before you get the file back. A tool that quietly reflows your document is worse than no tool.
Frequently asked questions
The text copies fine. Is this still a failure?
Yes. Copying probably works because the font also carries a ToUnicode CMap, which readers use first. PDF/UA still requires the encoding itself to resolve, because non-symbolic TrueType fonts are exempt from needing a ToUnicode CMap at all, and the exemption rests on their glyph names meaning something.
What counts as being in the Adobe Glyph List?
The names in Adobe's published list — a, eacute, Euro, quoteright and several thousand more — and, under the list's own rules, names of the form uni20AC that spell out the code point. Names a subsetting tool makes up from glyph numbers, such as g17 or glyph42, are not in it.
Does Taggart look every name up in the list?
No. It checks that each name has the shape of a glyph name and rejects the prefixes subsetting tools invent. A name that is well formed but not in the list, such as Bullet2, gets past it. veraPDF's PDF/UA-1 profile is the free tool to run alongside if your files use unusual names.
Where this sits in the standards
| Standard | Reference |
|---|---|
| Matterhorn Protocol 1.1 | Checkpoint 31 (Fonts), index 31-022 |
| PDF/UA-1 (ISO 14289-1) | Clause 7.21.6-6 |
| WCAG 2.1 | 1.3.1 Info and Relationships — Level A |
| EN 301 549 / Section 508 / ADA Title II | All three point at WCAG 2.1 Level AA for non-web documents, so a Level A or AA criterion here is in scope for each of them. |
Related conditions
- 31-020 The Encoding dictionary for a non-symbolic TrueType font does not contain BaseEncodingIf /Encoding is a dictionary it must name a /BaseEncoding.
- 31-023 Differences present but the font has no (3,1) Microsoft Unicode cmapThe Differences array is resolved through the (3,1) cmap; without it the mapping is undefined.
- 10-001 Character code cannot be mapped to UnicodeA glyph is painted whose character code has no Unicode equivalent reachable through the font's ToUnicode CMap, encoding, or glyph names. The text renders correctly but cannot be extracted.
- 31-027 A font dictionary does not contain the ToUnicode entry and no exemption appliesA ToUnicode CMap is required unless the font uses MacRoman/MacExpert/WinAnsi encoding, or is a Type 1/Type 3 whose glyph names are all in the Adobe Glyph List or the Symbol set, or is a Type 0 whose descendant uses a standard Adobe character collection, or is a non-symbolic TrueType.
Other conditions in checkpoint 31
Checkpoint 31 covers fonts. These are its other failure conditions; the ones without a link are in the rule set but do not have a written page yet.
- 31-001 CIDSystemInfo Registry values are not identicalThe CMap and the descendant CID font must agree on the character collection registry.
- 31-002 CIDSystemInfo Ordering values are not identicalThe CMap and the descendant CID font must agree on the character collection ordering.
- 31-003 CIDSystemInfo Supplement of the CID font is lower than that of the CMapThe font's character collection supplement must be at least as new as the CMap's, or the CMap may reference CIDs the font does not define.
- 31-004 A Type 2 CID font contains neither a stream nor the name Identity as CIDToGIDMapCIDToGIDMap must be either the name /Identity or a stream mapping CIDs to glyph indices.
- 31-005 A Type 2 CID font does not contain a CIDToGIDMap entryThe entry is absent entirely.
- 31-006 A CMap is neither listed in ISO 32000-1 Table 118 nor embeddedA predefined CMap must be one of the standard names; anything else must be embedded in the file.
- 31-007 The WMode entry in a CMap dictionary is not identical to the WMode value in the CMap streamWriting mode (horizontal or vertical) must be declared consistently in the dictionary and the stream.
- 31-008 A CMap references another CMap which is not listed in ISO 32000-1 Table 118A UseCMap chain must terminate at a predefined CMap.
- 31-009 For a font used by text intended to be rendered the font program is not embeddedPDF/UA-1 requires every font used for visible text to be embedded, so the document renders and extracts identically everywhere. A glyph counts as rendered if the text render mode is not 3.
- 31-010 A font program is embedded that is not legally embeddable for unlimited, universal renderingThe font's embedding permission bits forbid the kind of embedding used. Machines can read the flags but the flags may not reflect the actual licence.
- 31-011 The embedded font program does not contain glyphs for all referenced glyphsThe subset embedded in the file is missing glyphs the content stream asks for — very common when a document is edited after subsetting.
- 31-012 A glyph present in an embedded Type 1 font program is not listed in CharSetCharSet must accurately list the glyphs in the embedded subset.
- 31-013 A glyph listed in CharSet is not present in the Type 1 font programCharSet promises glyphs the font does not contain.
- 31-014 A glyph present in an embedded CID font program is not listed in CIDSetCIDSet must accurately list the CIDs in the embedded subset.
- 31-015 A glyph listed in CIDSet is not present in the CID font programCIDSet promises CIDs the font does not contain.
- 31-016 Glyph widths in the font dictionary and the font program differThe /Widths array must agree with the embedded font program.
- 31-017 A non-symbolic TrueType font has no non-symbolic cmapA font declared non-symbolic must actually carry a (3,1) or (1,0) cmap subtable.
- 31-018 A glyph cannot be looked up by any non-symbolic cmap entrySome rendered glyph is unreachable through the declared cmap tables.
- 31-019 The font dictionary for a non-symbolic TrueType font does not contain an Encoding entryNon-symbolic TrueType fonts must declare an /Encoding.
- 31-020 The Encoding dictionary for a non-symbolic TrueType font does not contain BaseEncodingIf /Encoding is a dictionary it must name a /BaseEncoding.
- 31-021 BaseEncoding is neither MacRomanEncoding nor WinAnsiEncodingOnly MacRomanEncoding and WinAnsiEncoding are permitted for non-symbolic TrueType fonts.
- 31-023 Differences present but the font has no (3,1) Microsoft Unicode cmapThe Differences array is resolved through the (3,1) cmap; without it the mapping is undefined.
- 31-024 The Encoding entry is present in the font dictionary for a symbolic TrueType fontSymbolic TrueType fonts must not carry an /Encoding; the font's own cmap governs.
- 31-025 The embedded font program for a symbolic TrueType font contains no cmapA symbolic TrueType font must contain at least one cmap subtable.
- 31-026 A symbolic TrueType font has multiple cmaps but none is a (3,0) Microsoft Symbol cmapWith multiple cmaps present, a (3,0) symbol cmap is required to disambiguate.
- 31-027 A font dictionary does not contain the ToUnicode entry and no exemption appliesA ToUnicode CMap is required unless the font uses MacRoman/MacExpert/WinAnsi encoding, or is a Type 1/Type 3 whose glyph names are all in the Adobe Glyph List or the Symbol set, or is a Type 0 whose descendant uses a standard Adobe character collection, or is a non-symbolic TrueType.
- 31-028 Unicode values in the ToUnicode CMap are zeroU+0000 is not a valid mapping target; it usually means the producer could not determine the character and wrote a placeholder.
- 31-029 Unicode values in the ToUnicode CMap are U+FEFF or U+FFFEByte-order marks are not characters and must not appear as mapping targets.
- 31-030 Characters used in text showing operators reference the .notdef glyphThe content stream paints glyph index 0, which is by definition "no glyph" — typically a hollow box or nothing at all.
Check your own file. Taggart’s validator is free and unlimited — 75 of the 87 Matterhorn conditions software can decide, with the other 12 listed for you to confirm; no watermark, no expiry, and no account needed up to 60 pages.
Checked with Taggart on a generated file that fails this condition on . The Acrobat steps follow Adobe’s documentation and were not walked through by hand. Last updated .