Skip to content

fix(xlsx): price a bold cell's own digit advance for weight-sensitive faces - #1768

Merged
developer0hye merged 2 commits into
mainfrom
fix/issue-1623-cambria-bold-cell-inset
Sep 17, 2026
Merged

developer0hye merged 2 commits into
mainfrom
fix/issue-1623-cambria-bold-cell-inset

Conversation

@developer0hye

Copy link
Copy Markdown
Owner

File submission policy

  • Any submitted sample files or attachments satisfy the submission policy, or none are submitted.

Summary

  • Price a cell's left/right inset from the cell's own bold flag, not just its family: Cambria and Verdana measurably widen their decimal digits when bold (verified directly against Excel's own Cambria.ttc/Cambriab.ttf and Verdana.ttf/Verdana Bold.ttf with fontTools), so a bold cell in either family was priced on the regular-weight digit width and undershot its whole-point left inset by a full step.
  • Thread bold: bool through reference_digit_advance_em, digit_advance_em, column_unit_pt, cell_left_inset_pt, cell_right_inset_pt, and max_digit_advance_em; add a matching typst::text::FontVariant to the live-face lookup so an unlisted family also resolves its bold digit advance from the real face.
  • Reuse first_face_in_chain (issue PPTX: line-box metrics take the bundled Noto Serif over a face supplied on --font-path, seating Avenir Next LT Pro 2pt high #1629's interleaved in-memory-then-disk order) from the new weight-aware live-face lookup instead of duplicating that resolution order inline, so the two can never drift apart.

Related issue

Fixes #1623

Testing

  • Font metrics verified directly against Excel's own DFonts, not estimated: python3 -c "from fontTools.ttLib import TTFont, TTCollection; ..." over Cambria.ttc/Cambriab.ttf/Verdana.ttf/Verdana Bold.ttf gives Cambria regular 1134/2048em, Cambria bold 1213/2048em, Verdana regular 1302/2048em, Verdana bold 1456/2048em — exactly the constants this PR adds.
  • Native Excel for Mac differential probe (2026-09-17, no probe_harness.py SPEC — a fresh one-cell umya workbook round-tripped through scripts/macos/export_excel_pdfs.applescript): Cambria 36pt regular vs bold shifts the printed digit start by +1.0pt, 48pt by +0.0pt, matching this PR's table (6→7pt, 8→8pt) exactly.
  • Mutation check: temporarily made the Cambria/Verdana branches of reference_digit_advance_em ignore bold, confirmed test_bold_cell_font_prices_its_own_bold_digit_advance and test_reference_digit_advance_em_is_bold_aware_only_where_measured both fail (and the Calibri negative-control test still passes), then restored the fix — the new tests are not vacuously green.
  • cargo test --locked -p office2pdf --lib (3092 passed)
  • cargo fmt --all -- --check
  • cargo clippy --locked -p office2pdf --all-targets (stable 1.98, matching CI)
  • cargo check --locked -p office2pdf --target wasm32-unknown-unknown
  • python3 scripts/compare_layout.py gt.pdf before.pdf --page 2 --audit --fine-shift 0.5 --noise-floor 0.5 --json (Monthlycollegebudget dx -1.255pt)
  • python3 scripts/compare_layout.py gt.pdf after.pdf --page 2 --audit --fine-shift 0.5 --noise-floor 0.5 --json (same instance dx -0.475pt; the other 546 fine-shift entries are byte-identical before/after — nothing else moved)
  • python3 scripts/compare_render.py gt.pdf after.pdf --page 2 --dpi 300 --fine-shift 0.5 --artifacts-dir artifacts-page2 --cluster-report assets/bugfixes/issue-1623/render-clusters-page-2.json --cluster-dispositions final-dispositions.json --strict-clusters (354/354 dispositioned, PASS; 348 reused by exact bbox match from PR fix(xlsx): scale Excel worksheet bar-chart value-axis label gap with font size #1766's report for XLSX: fitted horizontal bar-chart value labels sit about 0.61pt too high #1622 on this same fixture/page, 6 new clusters are this fix's own effect — the title and the "Monthly Cash After Expenses" sub-heading, both bold Cambria — dispositioned to XLSX: fitted worksheet text keeps the physical margin origin while its paint layer snaps to Excel's sheet-space origin #1719, the already-tracked fitted-text-origin residual that both now land on)

Visual impact

  • No rendered PDF change
  • Rendered PDF change or visual evidence added
  • Reason: every left-aligned bold Cambria or Verdana cell now starts its text at the correct whole-point inset instead of one step too far left.

Visual audit

Visual comparison

GT Before After
GT Before After

Required inspection

  • Rendered all evidence at 150 DPI or higher
  • Stored progressive JPEG quality 86 assets with metadata stripped
  • Used Codex/Claude vision to inspect the full GT/output pages, diff, and matched crops
  • Inspected matched region crops at full resolution
  • Ran compare_layout.py --audit --fine-shift PT and dispositioned every fine/large text-instance shift, rectangle geometry deviation, painted-text visibility mismatch, and visible-fill occlusion
  • Ran compare_render.py --cluster-report PATH --strict-clusters and dispositioned every material 5% fuzz diff cluster by explicit ID
  • Inventoried hairlines and border dash styles
  • Inventoried font weight, italic, and underline emphasis

Deviation audit

Check Result
Page count/order Matches GT
Element presence Matches GT
Position/size Remaining: #1621, #1719, #1721, #1757, #1767 cover pre-existing category-label, fitted-sheet-origin, tight-row, form-control-label, and title-baseline (dy) position; this PR fixes the bold Cambria/Verdana title's own horizontal position (dx -1.255pt to -0.475pt).
Rotation/flip No deviation observed
Fill Remaining: #1632, #1759 cover pre-existing cell-fill and bar-fill geometry, unrelated to this fix.
Stroke/border No deviation observed: this text-position correction changes no gridline, axis, or border stroke.
Shape outline geometry No deviation observed: no shape geometry changes from this fix.
Text content No deviation observed
Font family/weight/style Matches GT
Text color Matches GT
Alignment Remaining: #1631, #1761 cover pre-existing right-aligned/number-format and repeated-header alignment; this PR fixes left-aligned bold Cambria/Verdana/Segoe UI/Malgun Gothic cell alignment.
Line/paragraph spacing Remaining: #1760 covers the pre-existing 1-into-2 line reflow on this page.
Clipping/overflow No deviation observed

Checklist

  • Commits include a Signed-off-by line
  • PR scope contains one root cause
  • Remaining converter or harness deviations each reference an open issue

Related: #1545, #1621, #1631, #1632, #1719, #1721, #1757, #1759, #1760, #1761, #1767

developer0hye and others added 2 commits September 17, 2026 09:57
… faces

Cambria, Verdana, Segoe UI/Selawik, and Malgun Gothic each measurably widen
their decimal digits when bold (verified directly against Excel's own
Cambria.ttc/Cambriab.ttf, Verdana.ttf/Verdana Bold.ttf, malgun.ttf/malgunbd.ttf,
and this crate's bundled Selawik-Regular.ttf/Selawik-Bold.ttf with fontTools),
so a bold cell in one of these families was priced on the regular-weight
digit width and undershot its whole-point left inset by a full step. A 42pt
bold Cambria title landed 1.255pt left of a native Excel for Mac export.

Thread bold: bool through reference_digit_advance_em, digit_advance_em,
column_unit_pt, cell_left_inset_pt, cell_right_inset_pt, and
max_digit_advance_em, and add a matching typst::text::FontVariant to the
live-face lookup so an unlisted family also resolves its bold digit advance
from the real face. Reuse first_face_in_chain (issue #1629's interleaved
in-memory-then-disk order) from the new weight-aware lookup instead of
duplicating that resolution order inline.

Calibri/Carlito, Arial/Helvetica/Liberation Sans, Times New Roman, and
Courier New are confirmed weight-invariant the same way and left untouched.

Fixes #1623

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Yonghye Kwon <developer.0hye@gmail.com>
Fresh native Excel for Mac 300 DPI GT/before/after for page 2 of
tests/fixtures/xlsx/issue_1181_fit_to_height.xlsx, plus a --fine-shift 0.5
layout audit and a strict render-cluster report for the same page. The
title's measured dx moves from -1.255pt to -0.475pt; 348 of 354 render
clusters are reused byte-for-byte (exact bbox match) from PR #1766's report
for #1622 on this same fixture/page, and the 6 new clusters are exactly the
text this fix moves.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Yonghye Kwon <developer.0hye@gmail.com>
@developer0hye
developer0hye merged commit d9467bd into main Sep 17, 2026
18 checks passed
@developer0hye
developer0hye deleted the fix/issue-1623-cambria-bold-cell-inset branch September 17, 2026 01:45
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.

XLSX: large left-aligned Cambria title starts 1.255pt left of native

1 participant