Repository navigation
Conversation
For a PDF without /Lang, `TextLayer.#getCtx` gave its measuring canvas `lang=""`. An empty lang attribute does not inherit the document's language but declares it unknown, while the text layer's spans keep inheriting the document's language. The generic font families can then resolve to different fonts for the canvas and the spans, so every span is scaled by the wrong ratio: with `<html lang="ja">`, spans ended 12-15% past their glyphs in Chromium and WebKit, and in Firefox on a Japanese system with `<html lang="en">`, 11% short of them. PR 17476 appended the canvas to the document precisely so that it would inherit the document's language, and PR 17770 then set it to the text content's language, which is right when the PDF has one. Without one, leave the attribute off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Viewer previewCommit 0d13991 (build logs).
🔒 A user with write access must approve this commit with the |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #22261 +/- ##
==========================================
- Coverage 90.44% 90.44% -0.01%
==========================================
Files 277 277
Lines 68277 68278 +1
==========================================
- Hits 61756 61753 -3
- Misses 6521 6525 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| // Without a language, the canvas must inherit the document's one, as | ||
| // the text layer does: an empty lang attribute would instead declare | ||
| // the language unknown, which can resolve to other fonts. | ||
| if (lang) { |
There was a problem hiding this comment.
Can we receive a lang that is "" here, and if so do we need to distinguish it from null?
There was a problem hiding this comment.
Yes, but rarely. Catalog.lang already returns null for a missing /Lang and for /Lang (), so "" only comes from a non-empty string that decodes to nothing (<FEFF>, or only a language escape sequence), or from a text content object passed to TextLayer directly.
I don't think we need to distinguish them: the canvas is only there to measure text in the fonts the spans are drawn with, and the spans inherit the page's language whether lang is null or "". The PDF specification doesn't distinguish them either: an empty language identifier means the language is unknown, and so does a missing /Lang in the catalog. Both keep sharing the "" cache entry.
nicolo-ribaudo
left a comment
There was a problem hiding this comment.
Code looks good, but it needs a second review from somebody else.
Fixes #22258.
For a PDF without /Lang,
TextLayer.#getCtxgives its measuring canvaslang="", which declares the language unknown instead of inheriting the document's one (as intended by #17476), while the spans keep inheriting it. When the generic font families resolve to other fonts for the two, every span is scaled by the wrong ratio: with<html lang="ja">, spans ended 12–15% past their glyphs in Chromium and WebKit, and on a Japanese system with<html lang="en">, 11% short in Firefox.This leaves the attribute off when the text content has no language. With it, the spans' widths match their items' in all three browsers, on the display API and in the viewer with and without a
langon its root element.The unit test checks that a text layer without a language creates a measuring canvas without a
langattribute, next to one with a language.🤖 Generated with Claude Code