Repository navigation
Measure the exact boxes of non-embedded CJK fonts on their faces (#624) - #659
Merged
Merged
Conversation
`words(exact_bboxes=True)`, `layout`, `chars`, and `search` now measure a font that a document does not embed on the fallback face that draws it, as frozen pylopdf does. The faces join the memo key of the layout with exact boxes, and other text stays the same under any faces. Records still come from an interpretation without faces, and only their ink from a second one through them: hayro 0.9 keeps a face's stretch to the PDF's widths in the glyph's transform, which would change advances and so split or join words. A watch on the font resolver runs that second interpretation only when a face would draw a font of the page, so a document with embedded fonts reads no face. Frozen pylopdf fills its faces at its first rendering, so its first page read without them. The parity dump now renders first, which replaces the earlier explanation of that page by its descendant font type. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…boxes # Conflicts: # crates/pyropdf-engine/src/extract/text.rs
Every output of the 7 pages of nonembedded-cjk.pdf now matches frozen pylopdf, so `fallback-exact-boxes` retires. PR #650 moved nothing in the report: the corpus keeps its one close raster and the heading of patent-us223898.pdf. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #624
words,layout,chars, andsearchwithexact_bboxes=Truenow measure a font that a document does not embed on the fallback face that draws it, as frozen pylopdf does.fallback-exact-boxesretires fromevidence/phase1-parity.Acceptance
tests/assets/text/nonembedded-cjk.pdf,words(exact_bboxes=True)matches frozen pylopdf with its CJK extras, andevidence/phase1-parity/causes.tomlno longer listsfallback-exact-boxes.run.pymeasured the merged tree: every output of the 7 pages is equal, and the corpus keeps only the one close raster and the heading ofpatent-us223898.pdf. PR Read a multi-glyph cluster as its text in other readers (#637) #650 moved nothing in the report.tests/test_parity.pypasses withPYROPDF_PARITY_PYLOPDFset.doc.fallback_fontschanges the exact boxes that the next call returns, and a call with the same faces reuses the memoized result (test_editing_the_fallback_fonts_changes_the_exact_boxes_of_the_next_call, which counts hits and computations). Other text keeps its memo key (test_the_memo_of_other_text_keeps_its_key_when_the_fallback_fonts_change).exact_boxes_measure_a_font_that_a_document_does_not_embed_on_its_face,only_exact_boxes_of_a_font_that_is_not_embedded_read_a_face).exact_bboxessays that the boxes depend on the fallback faces (Page.words,Page.layout,Document.fallback_fonts).python tools/check.py --lockedpasses. No engine API thatfuzz/uses changed:page_textkeeps its signature, soAnnotation.textandDocument.text, which have noexact_bboxes, are untouched too.Two things that differ from what the issue expected
The faces supply only the ink, in a second interpretation. Interpreting the page through the faces once, as frozen pylopdf does, is not enough on hayro 0.9. hayro 0.8 stretched a substitute's outline to the PDF's width, and hayro 0.9 puts that stretch in the glyph's transform, where nothing tells it apart. Advances taken through it are scaled: with
/W [0 65535 500],計画地split into three words in exact mode. So the records still come from an interpretation without faces, which also keeps a face's line metrics out of the font's, and the faces give only ink. A watch on the font resolver runs the second interpretation only when a face would draw a font of the page, so other pages cost what they did and read no face.I checked this against the oracle beyond the Acceptance, on the fixture and on the same pages with explicit half and full
/W:words,layoutwith and without chars and styles, andsearchwith boxes and quads, all withexact_bboxes=True, have no difference over 0.01 point. That script is not committed.Page 1 was not equal because of
CIDFontType0. Frozen pylopdf fills its faces at its first rendering, and text extraction before that gives what it gives without them. The dump rendered each page after reading it, so only page 1 read without faces, and the README's explanation was wrong.dump.py --fallback-fontsnow renders first, and the README says so. pyropdf gives the same boxes in any order, so a frozen pylopdf call before any rendering still differs from it, by design.Beyond the issue's Paths
docs/en/api/is generated from the docstrings, anddocs/en/rendering.mdanddocs/ja/rendering.mdsaid that text extraction does not use the faces, which is no longer true.Follow-ups, both filed
words()andlayout()boxes of a non-embedded Latin font move when its/Widthsdiffer from the substitute's (Helloends at 106.14, against 90.0 in frozen pylopdf). This is the same stretch, without any face, and comes from Move to hayro 0.9 with LaurenzV/hayro#1734 patched in, and read streams that name a file #609, after 0.2.1. It is a regression of 0.2.2 if it ships as it is, and the corpus does not show it. Whether it goes into 0.2.2 is the owner's call.page.content()still have no ink on these fonts, where frozen pylopdf measures the faces. The issue's Notes leave it out, since onlyexact_bboxes=Truereads the faces here.For 0.2.2's changelog
page.words,page.layout,page.chars, andpage.searchwithexact_bboxes=Truemeasure a CJK font that the document does not embed on thedoc.fallback_fontsface that draws it, so these boxes now depend on those faces. Text and other boxes do not change. (Measure the exact boxes of non-embedded CJK fonts on their fallback faces #624)🤖 Generated with Claude Code