Skip to content

Draw correct glyphs for non-embedded Identity TrueType CID fonts - #566

Open
Velli20 wants to merge 1 commit into
mainfrom
fix-non-embedded-identity-cid-glyphs
Open

Velli20 wants to merge 1 commit into
mainfrom
fix-non-embedded-identity-cid-glyphs

Conversation

@Velli20

@Velli20 Velli20 commented Oct 13, 2026

Copy link
Copy Markdown
Owner

Problem

The fx/FRC_8.2.4_part1/* cover pages (in the #479 cluster) drew "Foxit Ü^æå^¦ or Foxit…" where the text should read "Foxit Reader or Foxit PhantomPDF".

The font is a non-embedded Type0 Arial,Bold with an Identity-H encoding. Its descendant is a CIDFontType2 with no FontFile2, CIDToGIDMap or ToUnicode. Its CIDs are glyph indices into the real Arial Bold. Safe-PDF used each CID directly as a glyph index into the bundled FoxitSans.cff substitute, whose glyph order is unrelated, and it always picked the regular weight for Type0 substitutes.

Change

  • New cid_to_unicode.rs with a CidToUnicode enum:

    • Collection wraps the existing runtime CJK maps.
    • StandardGlyphOrder reads a compile-time [Option<char>; 258] table that maps the standard Macintosh glyph order to Unicode.

    TrueType core fonts such as Arial, Times New Roman and Courier New keep that order for their first 258 glyphs.

  • CidFontSpec uses StandardGlyphOrder for a non-embedded CIDFontType2 font that has no CIDToGIDMap and names a non-symbolic core font (new Standard14Font::has_standard_glyph_order). The text engine already picks substitute glyphs by Unicode, so the substitute now draws the correct characters.

  • PdfFontSpec::substitute_standard14 takes a Type0 font's weight and style from its base font name, so Arial,Bold gets the bold substitute.

PDFium draws its own wrong text here ("FYUXYf"), so these pages still differ from the reference. The rest of their difference is the logo image, which PDFium downscales more softly.

Testing

🤖 Generated with Claude Code

A non-embedded CIDFontType2 font with Identity encoding and no
CIDToGIDMap selects glyphs of the named system font by index. The
substitute is a name-keyed CFF with a different glyph order, so using
the CID as its glyph index drew the wrong glyphs.

TrueType core fonts such as Arial keep the standard Macintosh glyph
order for their first 258 glyphs. For such fonts, map CIDs to Unicode
through a compile-time table of that order, so the substitute draws
glyphs by character. Type0 fonts also now pick the substitute's weight
and style from their base font name instead of always regular
Helvetica.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Conformance reads

Documents that Safe-PDF reads differently from the base commit, compared with PDFium. A read
regresses when Safe-PDF fails to open a document it opened before, crashes or times out, or
counts a different number of pages than PDFium.

pdf.js corpus

1008 documents compared with b469ecf: 2 read worse, 0 read better.

Regressions

Document Base This pull request
issue17190_1 read, 1 page timeout: time limit exceeded (stage safe-read)
issue19517 read, 1 page timeout: time limit exceeded (stage safe-read)

840 documents of the PDFium corpus read as on b469ecf.

Details are in the job summaries of the workflow run. Rerun a case locally with
cargo conformance run --corpus <corpus> --read-only --case <id>.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant