Matterhorn 31-024 · PDF/UA-1 UA1:7.21.6-8
Symbolic TrueType font that also has an Encoding
Symbolic TrueType fonts must not carry an /Encoding; the font's own cmap governs.
The condition, as the protocol states it. “The Encoding entry is present in the font dictionary for a symbolic TrueType font.”
Matterhorn Protocol 1.1, checkpoint 31, index 31-024, section UA1:7.21.6-8. Software can decide this one on its own.
What a screen reader actually does
The conflicting encoding produces wrong characters on extraction.
Two instructions for one byte
A simple TrueType font’s font descriptor carries a /Flags integer, and two of its bits say what kind of font it is: Symbolic (bit 3, value 4) and Nonsymbolic (bit 6, value 32). The difference decides how a byte in the content stream finds its glyph.
For a non-symbolic font, the byte goes through a named encoding to a glyph name, and the name to a glyph. For a symbolic font, the byte goes straight to the font program’s own cmap table — the (3,0) Microsoft Symbol subtable if there is one, otherwise the (1,0) Macintosh one — and no encoding is involved.
12 0 obj
<< /Type /Font
/Subtype /TrueType
/BaseFont /ABCDEF+Wingdings-Regular
/Encoding /WinAnsiEncoding % ← says: go through WinAnsi
/FontDescriptor 13 0 R % /Flags 4: says: go straight to the cmap
>>
That font gives two instructions for the same byte. ISO 32000-1 does not settle it cleanly — read one way it tells the viewer to build a table from a WinAnsi or MacRoman /Encoding, read another it says a symbolic font’s /Encoding is ignored — so viewers settle it themselves. PDF/UA-1 clause 7.21.6 removes the conflict by forbidding the /Encoding entry on a symbolic TrueType font altogether. Condition 31-024 is a font that has one.
What the user hears
The drawing problem is that different viewers can pick different glyphs. The reading problem is quieter and usually worse.
A font with /WinAnsiEncoding is exempt from needing a ToUnicode CMap, because WinAnsi says what every byte is. For a text font that is true. For a dingbat font it is not: the bytes are positions in a picture font, and WinAnsi’s names for them are letters. If the font carries no ToUnicode CMap, a reader that takes the encoding at its word turns pictures into letters. Wingdings draws a filled bullet at 0x6C and a check mark at 0xFC; WinAnsi calls those l and ü. A list whose bullets are set in such a font can be read as items each beginning with the letter l, and a ticked checklist as a column of ü.
That is also why this condition can stand alone in a report. Taggart does not report a missing ToUnicode CMap (31-027) for a font with /WinAnsiEncoding, because the exemption applies; 31-024 is the finding that tells you the exemption is resting on a contradiction.
Where it comes from
Producers that write /WinAnsiEncoding on every simple font by default, and set the flags from what the font contains. The two disagree whenever the font has any glyph outside the Adobe standard Latin set — which is the flag’s definition of symbolic — and that covers every dingbat font and many text fonts with a few extra characters.
The opposite combination is the one PDF/UA wants. ReportLab, for example, marks every TrueType subset it embeds as symbolic and writes no /Encoding for it; its fonts pass this condition.
How to check it free
Not with pdffonts. Its encoding column reports what Poppler uses, and on our test files it printed WinAnsi both for a symbolic TrueType font with /Encoding /WinAnsiEncoding and for one with no /Encoding at all.
Read the two objects. pdffonts gives the font’s object number; qpdf --show-object=12 file.pdf prints the font dictionary, and the same command on its /FontDescriptor gives /Flags. Bit 3 is set if the value, written in binary, has a 1 in the 4s place: 4, 5, 68 and 262148 all qualify. Bit 6 is the 32s place, and a value with both, such as 36, is not symbolic to Taggart.
In Acrobat Pro, both dictionaries are visible, read-only, through All tools → Use print production → Preflight, then Options → Browse Internal PDF Structure, as Adobe describes in advanced preflight inspections.
veraPDF’s PDF/UA-1 profile has a rule for exactly this: a symbolic TrueType font with an /Encoding in its dictionary.
How to fix it free
Decide what the font really is, because the two repairs are different.
A genuine symbol font — dingbats, icons, a pictogram font. Delete the /Encoding entry, and give the font a ToUnicode CMap that says what each symbol is, U+2022 for a bullet, U+2713 for a check mark. Without the CMap, the font no longer qualifies for the WinAnsi exemption and fails 31-027 instead. If the program has a (3,0) subtable, removing the encoding should not change what is drawn; compare in more than one viewer before trusting it. Both edits can be made with qpdf in QDF mode (qpdf --qdf --object-streams=disable, edit, fix-qdf), but writing a ToUnicode CMap by hand is slow work, and a re-export is usually faster.
A text font marked symbolic — the letters are ordinary letters. Here the encoding is right and the flag is wrong: change /Flags to clear bit 3 and set bit 6. The font is then held to the non-symbolic rules, which want a non-symbolic cmap subtable in the program (31-017) and, if the encoding has Differences, a (3,1) one (31-023), so check the program before you change the flag.
Or re-export. For the Accessibility Checker’s Character encoding rule, Adobe’s guidance in Create and verify PDF accessibility is to use a different font, preferably OpenType, in the source and re-create the PDF; Adobe documents no way to edit a font dictionary inside Acrobat.
What Taggart reports
One finding per symbolic TrueType font, saying which kind of /Encoding it found — the name, or dictionary if it is an encoding dictionary:
/ABCDEF+Wingdings-Regular is a symbolic TrueType font but its font dictionary contains an /Encoding entry, which PDF/UA-1 forbids.
A font is symbolic to Taggart when the Symbolic bit is set and the Nonsymbolic bit is not. A descriptor with both set is checked as non-symbolic, and an encoding problem on it is reported as 31-021 or its neighbours rather than this.
There is no repair. Deleting the entry, or changing the flag, is a decision about what the font is, and either one can change the glyphs some viewers draw.
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
Which flag makes a font symbolic?
Bit 3 of /Flags in the font descriptor, value 4, is Symbolic; bit 6, value 32, is Nonsymbolic. Taggart treats a font as symbolic only when bit 3 is set and bit 6 is not, so a descriptor with both set is held to the non-symbolic rules instead.
Can I just delete the /Encoding entry?
For a genuine symbol font, that is the fix, and if the program has a (3,0) cmap the drawing should not change. But a WinAnsi or MacRoman entry is also what exempted the font from needing a ToUnicode CMap, so once it goes the font needs one, or it fails 31-027 instead.
pdffonts says WinAnsi either way. Why?
pdffonts shows the encoding Poppler uses, and it shows WinAnsi for a symbolic TrueType font with no /Encoding at all as well as for one with /WinAnsiEncoding. Read the font dictionary itself with qpdf --show-object.
Why would a text font be marked symbolic?
Because of how the flag is defined: a font is symbolic if it has any glyph outside the Adobe standard Latin set. Some producers set it on every font they embed, which is defensible for the flag and wrong as soon as they also write an encoding.
Where this sits in the standards
| Standard | Reference |
|---|---|
| Matterhorn Protocol 1.1 | Checkpoint 31 (Fonts), index 31-024 |
| PDF/UA-1 (ISO 14289-1) | Clause 7.21.6-8 |
| 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-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-021 BaseEncoding is neither MacRomanEncoding nor WinAnsiEncodingOnly MacRomanEncoding and WinAnsiEncoding are permitted for non-symbolic TrueType fonts.
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-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-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 .