Repository navigation
fix(export): keep text an exact-height row clips whole in the PDF text layer (#1140) - #1172
Merged
Merged
Conversation
…t layer (#1140) Chromium's PDF writer drops every glyph that lies wholly outside the bounding rectangle of the clip it is drawn under, so a line an exact row cuts through extracted as broken word fragments. An overflowing exact-row clip box now moves into an inline SVG whose clipPath paints the same visible rectangle but whose bounds, stretched by zero-area spikes, cover the hidden content: the clipped text stays whole, once and in order.
…residuals, and the whole-paragraph limit (#1140)
… clip id, keep mixed cells in tree order (#1140) Layout overflow counted a one-line row a little shorter than its line, or a paragraph's space after, as hidden text; a cell is now rewritten only when the clip edge passes a text line's baseline or a whole character lies beyond a side edge. The clipPath id skips ids a bookmark already holds, which url(#id) would otherwise resolve to. A cell with text in both paint phases puts its in-flow text in a relative box so its own text is written in tree order.
…hich cells are rewritten (#1140)
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 #1140
Why
A table row with
w:hRule="exact"clips content taller than the row, as Word does, and that clipping is visually correct. But Chromium's PDF writer keeps a glyph in the text layer only when the glyph's bounds touch the clip's bounding rectangle. The clipped line therefore survived as fragments:Overflow Birch continuation line.extracted asfl h l. LibreOffice writes the whole line.How it works
The new module
npm/src/exact-row-text.tsruns only in the standalone export (export-browser.ts). It runs after the export's clip check and baseline alignment, and before word-text painting and PageMap materialization. The paginated viewer and editor are unaffected.<svg><foreignObject>.clipPathwhose painted area is exactly the rectangle Chromium used for theoverflow:hiddenclip. Zero-area spikes in four directions make the clip's bounding rectangle cover the hidden content, so Skia writes every glyph to the text layer, and the clip still hides it.foreignObjecttakes back the fraction (to 1/64 px), so the content lays out and paints exactly where it did.clip-pathwould move it to the end of the page. The root takesposition:relativewhen any of the cell's text is in a positioned box, so the cell paints in the same phase as that text did. A cell with text in both phases gives its in-flow text an offset-free relative box, so the cell reads in tree order.Validation
npm-export/tests/export.test.mjs. Each fails if its part of the fix is mutated out (dropping the fractional compensation, the edge snapping, either position rule, the six-decimal lengths, the id skip, or the hidden-text detection):mainwithfl h l.w:after.mainin every case.main.npm run typecheckpasses.npm/Playwright specs could not run on this machine, so they run in CI.Residuals (also in
docs/architecture/standalone_paginated_export.md)maintoo and is filed as PDF export fails when an exact-height row hides a whole paragraph #1168.Adversarial review
One round of hostile review ran on the first three commits. It confirmed the pipeline order, that the change is export-only, the tests' mutation coverage, and the link and footnote handling. It found three defects, fixed in the last two commits:
docx-exact-row-clip-0captured the clip id, so the hidden text painted over the next row. Ids are now minted free.Two pre-existing bugs it found are filed as #1171.