Matterhorn 31-021 · PDF/UA-1 UA1:7.21.6-5
TrueType encoding other than WinAnsi or MacRoman
Only MacRomanEncoding and WinAnsiEncoding are permitted for non-symbolic TrueType fonts.
The condition, as the protocol states it. “The value for either the Encoding entry or the BaseEncoding entry in the Encoding dictionary in a non-symbolic TrueType font dictionary is neither MacRomanEncoding nor WinAnsiEncoding.”
Matterhorn Protocol 1.1, checkpoint 31, index 31-021, section UA1:7.21.6-5. Software can decide this one on its own.
What a screen reader actually does
Character codes cannot be reliably mapped to characters.
Two names, out of a short list
ISO 32000-1 defines three encodings a simple font can name: MacRomanEncoding, MacExpertEncoding and WinAnsiEncoding. An /Encoding entry is one of those names or a dictionary whose /BaseEncoding is. PDF/UA-1 clause 7.21.6 narrows that for non-symbolic TrueType fonts to two:
/Encoding /WinAnsiEncoding % allowed
/Encoding /MacRomanEncoding % allowed
/Encoding << /BaseEncoding /WinAnsiEncoding
/Differences [ 128 /Euro ] >> % allowed
/Encoding /MacExpertEncoding % 31-021
/Encoding << /BaseEncoding /StandardEncoding >> % 31-021
The reason is the route this kind of font takes from a byte to a character. A non-symbolic TrueType font needs no ToUnicode CMap under PDF/UA, because its encoding is supposed to answer the question on its own: the byte becomes a glyph name through the encoding, and the glyph name becomes a Unicode character through the Adobe Glyph List. That only works if the encoding is one whose names are ordinary characters. WinAnsi and MacRoman are. The others are not, or are not encodings at all.
What the other names do
MacExpertEncoding is the encoding of Adobe’s “expert” fonts: small capitals, old-style figures, fractions. Its glyph names are things like Asmall, oneoldstyle and dollaroldstyle, and the Adobe Glyph List maps those to code points in the Private Use Area: Asmall is U+F761, oneoldstyle U+F731. Those values mean something only inside Adobe’s own fonts. Screen readers have no name to announce for U+F761, so a heading set in small capitals arrives as a string of characters that are, as far as any reader is concerned, nothing.
StandardEncoding is a real encoding, the default built into Type 1 fonts, but it is not one of the names /Encoding or /BaseEncoding accepts. A producer that writes it is writing down what it believes the font’s encoding is. Viewers that do not recognise the name fall back to their own default, which is a guess, and StandardEncoding and WinAnsi disagree on 117 of the 224 codes from 32 to 255, including the apostrophe and every accented letter.
Anything else. Some names were never encodings for a simple font at all. /Identity-H belongs to composite fonts; in a simple TrueType font’s dictionary it is a sign that a generator has confused its font types. These fail the same way: the viewer substitutes a default, and nothing in the file says which.
What the user hears
Depends on the name, and on whether the font also has a ToUnicode CMap. If it does, readers use the CMap first and the text survives; the font still fails the condition, and the page may still draw differently in different viewers. If it does not, which is legitimate for this font type, extraction runs through the encoding: Private Use Area characters for MacExpert; for StandardEncoding, whatever the reader takes the name to mean — the right letters for plain ASCII either way, apart from the apostrophe and the backtick, and a coin toss for anything accented or typographic.
How to check it free
Do not trust the encoding column in pdffonts. It reports the encoding Poppler chose to use. On our test files it showed WinAnsi for a TrueType font whose dictionary said /BaseEncoding /StandardEncoding, and WinAnsi again for one that said /Identity-H. It does show MacExpert when that is the name.
Read the dictionary. pdffonts gives you the object number in its last column; qpdf --show-object=12 file.pdf prints that object, and if /Encoding is a reference, show that one too. You are looking for the name after /Encoding or /BaseEncoding.
In Acrobat Pro, the same dictionary is visible in Preflight’s internal structure browser. Adobe’s advanced preflight inspections page gives the route: All tools → Use print production → Preflight, then Options → Browse Internal PDF Structure in the Preflight dialog. It is read-only.
veraPDF’s PDF/UA-1 profile tests that a non-symbolic TrueType font’s encoding, or its base encoding, is MacRoman or WinAnsi.
How to fix it free
Re-export, with a different font if need be. For the Accessibility Checker’s Character encoding rule, Adobe’s advice in Create and verify PDF accessibility is to use a different font, preferably OpenType, in the source document and re-create the PDF, and it says plainly that some character-encoding problems are not repairable within Acrobat. Adobe documents no way to change a font’s encoding in Acrobat itself.
For expert-set small capitals in particular, the fix in the source is to use a font with real small capitals reached through OpenType features, or to set the text in ordinary capitals at a smaller size. Either gives the producer ordinary letters to map, instead of a separate expert font.
Edit the name, carefully. A dictionary that says /BaseEncoding /StandardEncoding can be changed to /WinAnsiEncoding with qpdf in QDF mode (qpdf --qdf --object-streams=disable in.pdf edit.pdf, edit, then fix-qdf edit.pdf out.pdf). For plain ASCII text, other than the apostrophe and the backtick, that changes nothing visible. For text with accents or curly quotes it changes what is drawn, and you should compare the page before and after. A MacExpertEncoding font cannot be fixed this way; its codes mean different glyphs.
What Taggart reports
One finding per non-symbolic TrueType font, naming the encoding it found, taken from /Encoding if that is a name and from /BaseEncoding if it is a dictionary:
/ABCDEF+Garamond is a non-symbolic TrueType font whose encoding is /MacExpertEncoding, which is neither /MacRomanEncoding nor /WinAnsiEncoding.
A dictionary with no /BaseEncoding at all is 31-020, not this. A symbolic TrueType font with any encoding is 31-024, not this: the same /MacExpertEncoding on a font flagged symbolic produces that finding instead.
There is no repair. Changing an encoding name changes what the bytes in the content stream mean, and on most files that changes what is drawn.
How Taggart handles it
Taggart checks for this condition automatically and reports it as a blocker, with where in the file it found it.
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
Why is MacExpertEncoding not allowed when ISO 32000-1 defines it?
Because its glyph names resolve through the Adobe Glyph List into the Private Use Area. A small-capital A is named Asmall and maps to U+F761, a code point with no meaning outside the font that drew it, so the text extracts as characters a screen reader has nothing to say for.
pdffonts says WinAnsi. Why does Taggart say StandardEncoding?
pdffonts reports the encoding Poppler decided to use, not the name in the file, and it falls back to WinAnsi for a name it does not honour. Taggart reads the dictionary. qpdf --show-object on the font settles which of the two is right.
Is StandardEncoding wrong for Type 1 fonts too?
This condition is only about non-symbolic TrueType fonts. A Type 1 font whose built-in encoding is StandardEncoding is fine; what no simple font may do under ISO 32000-1 is name /StandardEncoding as its /Encoding or /BaseEncoding, because it is not one of the three predefined names that entry accepts.
Can I just change the name to WinAnsiEncoding?
Only where the codes the text uses mean the same thing in both. From StandardEncoding that is true of letters, digits and most ASCII punctuation. From MacExpertEncoding it is true of almost nothing, and the edit would change the page.
Where this sits in the standards
| Standard | Reference |
|---|---|
| Matterhorn Protocol 1.1 | Checkpoint 31 (Fonts), index 31-021 |
| PDF/UA-1 (ISO 14289-1) | Clause 7.21.6-5 |
| 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-019 The font dictionary for a non-symbolic TrueType font does not contain an Encoding entryNon-symbolic TrueType fonts must declare an /Encoding.
- 31-022 Differences contains glyph names not listed in the Adobe Glyph ListGlyph names in /Differences must be resolvable through the Adobe Glyph List so a processor can derive Unicode.
- 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.
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-022 Differences contains glyph names not listed in the Adobe Glyph ListGlyph names in /Differences must be resolvable through the Adobe Glyph List so a processor can derive Unicode.
- 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 .