Skip to content

Japanese text in PDFs reads in full - #146

Merged
Chimi6 merged 2 commits into
mainfrom
japanese
Oct 30, 2026
Merged

Chimi6 merged 2 commits into
mainfrom
japanese

Conversation

@Chimi6

@Chimi6 Chimi6 commented Oct 30, 2026

Copy link
Copy Markdown
Owner

A user's project found Japanese PDFs reading badly: a PDF made on a Mac gave 1 Japanese character in 360, and one in a standard Japanese encoding gave nothing.

  • Composite fonts read through their own encoding. Identity-H/V and embedded CMaps give CIDs, read through Adobe-Japan1 when the font is in that collection. That's how the Mac writes Hiragino, with no ToUnicode map. The Unicode CMaps (UniJIS-UCS2-H and the like, Chinese and Korean too) give Unicode. The Shift_JIS (90ms-RKSJ-H), EUC-JP and JIS CMaps are decoded. The tables are generated by scripts/gen-cjk-tables.py from Adobe's mapping resources and WHATWG's JIS X 0208 index, both BSD 3-Clause; NOTICE credits them.
  • Radicals read as ideographs. Chrome's ToUnicode maps give some ideographs as Kangxi radicals.
  • /ActualText replaces its glyphs' text. LibreOffice draws one placeholder glyph per character when it has no Japanese font.
  • Vertical writing reads by column, both for a -V font and for the Mac's glyph-by-glyph columns.
  • Japanese lines join without spaces when a PDF becomes Markdown, Word, HTML, or another document.

Tested on twelve PDFs from seven producers (Quartz with four fonts, Chrome, cupsfilter, PyMuPDF, reportlab in three encodings, and vertical text): every character reads as PyMuPDF reads it. On 70 to 100-page documents, a whole run takes 0.01 to 0.05 s at 8 to 13 MB, against PyMuPDF's extraction alone at 0.06 to 0.14 s and 186 MB. tests/pdf_japanese.rs covers eight fixtures from tests/fixtures/pdf-japanese/make.py, none of which embeds a font.

The tables add about 75 KB to the binary; CI will show whether the size budget needs raising.

Composite fonts are read through their encoding CMap: Identity and
embedded CMaps give CIDs, read through Adobe-Japan1 when the font is in
that collection (the Mac's Hiragino without ToUnicode); the Unicode
CMaps give Unicode; the Shift_JIS, EUC-JP, and JIS CMaps are decoded.
Radicals read as ideographs, /ActualText replaces its glyphs' text,
vertical writing reads by column, and Japanese lines join without
spaces in documents.
@Chimi6
Chimi6 merged commit 75dbfd0 into main Oct 30, 2026
16 checks passed
@Chimi6 Chimi6 mentioned this pull request Oct 30, 2026
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