Drawn glyph contradicts stored character
The character the document claims for a code is not the glyph that code actually draws, so the page reads one way and the extracted text reads another.
How the text is hidden
Two independent mappings decide what a code means. /ToUnicode says what it extracts as; what it DRAWS is named by the producer — a standard /Encoding base plus a /Differences array — or, where the document declares neither, by the embedded font program's own glyph names. Rewrite one side and they disagree — the page shows $90,000 and the bytes say $10,000.
Why a model still reads it
This is not concealment by invisibility. Every extractor faithfully returns the claimed character, which is precisely the character the page does not show.
What we do about it
Per code the parser compares codeToText (what the document claims) against codeToGlyphText (what the glyph is named), using sameCharacter; any mismatch sets cmapDivergent on the run and fills drawnText with what the page draws. A code with no resolvable glyph name is not counted as divergent — it falls back to the extracted character, on the reasoning that a position we cannot speak about should not be accused. The rule pdf-cmap-divergence fires at high, action flag; the run stays visible, deliberately, so contrast and geometry rules do not also fire on a legible page.
How often it fires
1% of 400 real UK public-sector contract PDFs (Contracts Finder, 2019–2023) — Word, Adobe, Nitro, office copiers, measured 2026-08-23.
This is an alert-volume number and nothing else. It says how often the alarm sounds on documents as found — not how often it is right, and not whether what it found was harmless. Documents as found may themselves carry concealment. Read it against the population named above rather than as a property of documents in general.
Check your own file
Three commands: a key, credit, a verdict.
Start with the API