fix(xlsx): seat top-aligned fixed-row text on Excel's whole-point top seat - #1744
Merged
Merged
Conversation
… seat A top-aligned worksheet cell in a fixed-height row rested its line box on the cell's top inset, so its first baseline sat at the inset plus the face's continuous ascent. Excel seats that line a whole number of sheet points below the row's top boundary: the hhea ascent plus line gap at the declared size, offset by 1.17pt and rounded together, then printed through the fit scale. The #982 workbook's nine-line Segoe UI 14 block matched native only by coincidence at 100% and sat 0.79pt low on the 0.82-fitted original. `sheet_cell_top_baseline_from_track_top_pt` states the seat, measured on the #1063 Arial probes (13 sizes, track- and border-independent) and confirmed on Segoe UI 14 (both #982 exports) and Malgun Gothic 14 (the #1060 probe's native export). `word_cell_line_box` redistributes the box around that baseline for a single-row top-aligned sheet cell, keeping the box height, row advance and wrapped-line leading unchanged; the #1496 fitted lift moves into `fitted_sheet_lift_pt`, shared by the centred and top seats. Evidence for the fitted page 2 is under assets/bugfixes/issue-1606/. Fixes #1606 Related: #1063, #1496, #1719, #1659 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Yonghye Kwon <developer.0hye@gmail.com>
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.
File submission policy
Before attaching or committing files, read the submission policy.
Complete a security review and obtain your organization's internal approval for
public sharing where applicable. You are responsible for lawful disclosure;
the project and maintainers disclaim related liability to the extent permitted
by applicable law.
Summary
A top-aligned worksheet cell in a fixed-height row rested its line box on the cell's top inset, so its first baseline sat at the inset plus the face's continuous ascent. Excel seats that line a whole number of sheet points below the row's top boundary: the face's
hheaascent plus line gap at the declared size, offset by a constant and rounded together, evaluated in sheet space and then printed through the fit-to-page scale. On the public #982 workbook the nine-line Segoe UI 14 instruction block therefore matched native by coincidence at 100% (1pt inset + 15.107pt ascent ≈ 16) and sat 0.79pt low on the 0.82-fitted original; every other top-aligned fixed row was off by the rounding remainder of its own face and size.Key changes:
sheet_cell_top_baseline_from_track_top_pt(typst_gen_text.rs) states the seat:round((ascent + line gap) x declared size + 1.17)sheet points below the track top, minus the shared fitted-sheet lift, times the print scale. The 1.17pt constant is the window[1.12, 1.23)the XLSX: every baseline on a fixed-track sheet page seats 0.6-1.5pt above the native export's #1063 Arial probes admit; no composition of the centred seat's separately rounded ascent and gap reproduces the series (documented on the constant).word_cell_line_boxgains a top-alignment arm that redistributes the box around that baseline (the seat less the cell's top inset above, the rest below), so the box height, the row advance and the XLSX: a wrapped cell's lines advance on the face's bare hhea box, 1.95pt short of the native export's per line #1163 wrapped-line leading are unchanged.generate_table_cellno longer excludes single-row top-aligned cells fromcell_sheet_seat; top-aligned multi-row merges stay outside the measured regime.fitted_sheet_lift_pt, shared by the centred and top seats and documented as the stand-in for the XLSX: fitted worksheet text keeps the physical margin origin while its paint layer snaps to Excel's sheet-space origin #1719 text-origin snap so both seats are re-derived together when that lands.top_aligned_sheet_cell_seat_reproduces_the_native_excel_probepins the thirteen-size Arial series of the XLSX: every baseline on a fixed-track sheet page seats 0.6-1.5pt above the native export's #1063 probes (probe 1 size and track sweeps, probe 2 bordered/unbordered pairing), Segoe UI 14 from the two native Gift Budget and Tracker1.xlsx misc issues #982 exports and Malgun Gothic 14 from the XLSX: whether a sheet row's East Asian line box keys on the face or the text is unmeasured #1060 probe's native export;scaled_top_aligned_sheet_cell_seat_prints_the_lifted_sheet_pointpins the 0.82 case;top_aligned_fixed_track_sheet_cell_starts_on_the_native_seatcompiles a Libertinus control at both scales and reads the first baseline and the wrapped advance back off the page.spreadsheet_rows_share_one_line_box_whatever_scriptnow asserts the seated top edge instead of the bare ascent; its script-invariance assertion is unchanged.Related issue
Fixes #1606
Related: #1063, #1496, #1719, #1659
Testing
cargo test --locked -p office2pdf --lib -- top_aligned_fails onmain(the helper does not exist; on the compiled control the first baseline sits at the inset plus the continuous ascent) and passes with the change.cargo test --locked --workspace --no-fail-fast— see the run recorded below.cargo +1.97 clippy --locked --workspace --all-targets -- -D warningsandcargo fmt --all -- --checkclean.2aa03cafa6a156d553a2f1e03e0458257319ff6416a188f1132ce7817ecaeae1) and of the issue's unscaled control (fitToPage=false, 3 pages, SHA-2560935ca38e497a657d2f972fb7ddfc3163cf69e8edfe6d79d230202b5db5d7bfa); before binary ismainat d79360d; both conversions with--font-pathfor the Office cloud-font cache (Segoe UI) and Excel's DFonts bundle.mutool draw -F trace, page 2 of the fitted original: B4's nine baselines were 154.948/172.168/…/292.708pt (native 154.16/171.38/…/291.92, +0.79pt each); they are now 154.040/171.260/…/291.800pt (-0.12pt each, pitch 17.22pt on both sides). Unscaled control: 177.107 → 177.000pt against native 177.000, all nine lines exact on the 21pt pitch. The XLSX: whether a sheet row's East Asian line box keys on the face or the text is unmeasured #1060 Malgun probe's eight top-alignedht=36rows now sit 16pt below their tracks with 0.00pt relative deviation from its native export.python3 scripts/compare_layout.py GT.pdf after.pdf --audit --fine-shift 0.5 --noise-floor 0.5 --json(page 2: 34 matched, 0 fine shifts; before the fix 8 fine shifts of +0.79pt and one re-grouped line);python3 scripts/compare_render.py GT.pdf after.pdf --page 2 --dpi 300 --fine-shift 0.5 --artifacts-dir … --cluster-report … --cluster-dispositions … --strict-clusters(34/34 clusters dispositioned, strict PASS);python3 scripts/compare_text_layer.py(the GT carries two more spaces from native's own word fragmentation, as in the XLSX: category-axis stroke overpaints a coincident line series #1604 audit). Page 1 is byte-identical to the before PDF's page 1 in the trace; a 5% fuzz comparison of the before and after page-2 renders with the sidebar block masked out differs on 0 pixels.Visual impact
Visual audit
tests/fixtures/xlsx/issue_1603_gift_budget.xlsx(the unchanged public Gift Budget and Tracker1.xlsx from Gift Budget and Tracker1.xlsx misc issues #982, SHA-25625f5dc75dab19ea12042979a61842314ddc226e3e45d447e36b2a2a104112613)fixassets/bugfixes/issue-1606/layout-audit.jsonassets/bugfixes/issue-1606/render-clusters-page-2.jsonassets/bugfixes/issue-1606/gt.jpgassets/bugfixes/issue-1606/before.jpgassets/bugfixes/issue-1606/after.jpgVisual comparison
Required inspection
Deviation audit
Checklist
Signed-off-byline🤖 Generated with Claude Code