Skip to content

fix(xlsx): preserve category label boundary spaces - #1575

Merged
developer0hye merged 1 commit into
mainfrom
fix/issue-1567-axis-label-spaces
Sep 5, 2026
Merged

fix(xlsx): preserve category label boundary spaces#1575
developer0hye merged 1 commit into
mainfrom
fix/issue-1567-axis-label-spaces

Conversation

@developer0hye

Copy link
Copy Markdown
Owner

Summary

Preserve single leading and trailing spaces in standalone category-axis labels. Typst collapsed these literal boundary spaces, so centered month labels ignored part of the source label width. Emit them using the same code-mode string representation already used for consecutive spaces. Apply it to bar, column, line, area, and radar category labels, including rotated labels.

Related: #1567. The existing chart-origin offset and separate label-baseline residual remain tracked in #1542 and #1568.

Testing

  • Real-workbook regression fails before the fix and passes afterward: jan retains its single trailing space; year keeps its existing two spaces.
  • Five chart-type controls cover leading, trailing, both-boundary, multiple, one-space-only, and absent spaces.
  • cargo test --locked -p office2pdf --lib: 2,837 passed.
  • cargo test --locked --workspace: 3,469 passed.
  • cargo clippy --locked --workspace --all-targets -- -D warnings: passed.
  • Identical fixture and lockfile baseline/after with Excel DFonts. Page 1 is pixel-identical at 150 DPI; page 2 changes 16,689 pixels at 300 DPI, confined to the 12 month labels. All 831 canonical drawing primitives preserve geometry and paint. The two-space year label is unchanged.
  • January moves from x=187.26976pt to 185.98150pt against native x=186.45680pt. The remaining -0.47530pt difference matches the chart zero-axis origin difference (-0.47501pt); the baseline remains y=347.31837pt against native 347.88pt (Charts: Cambria line-chart category baselines sit 0.56pt above Excel #1568).
  • All 55 page-1 and 480 page-2 material clusters have reviewed explicit dispositions; six prior label clusters disappear, with no new cluster. Normalized pdftotext -layout content matches native and baseline on both pages (486 and 2,120 non-whitespace characters).

Baseline: d4d8ef3ff4374126b2b69ce0e8378e0f79adf14f, including the separate axis-font and chart-line alpha fixes. Fixture SHA-256: 2b4a2d8dceda58758593c88409875efbda05780559154c02bd13fef4f7a1c65b; Cargo.lock SHA-256: 750f50c507b281f84b945b09573333ffa02dc45cddd566481af8535ae101e612.

Reproduce conversion with cargo run --locked -p office2pdf-cli -- tests/fixtures/xlsx/issue_1181_fit_to_height.xlsx -o output.pdf --font-path '/Applications/Microsoft Excel.app/Contents/Resources/DFonts'. Compare both pages using scripts/compare_layout.py GT.pdf output.pdf --audit --fine-shift 0.5 --json, and scripts/compare_render.py GT.pdf output.pdf --page P --dpi DPI --fine-shift 0.5 --cluster-report PATH --cluster-dispositions PATH --strict-clusters (150 DPI page 1, 300 DPI page 2).

Visual impact

  • Rendered PDF change or visual evidence added

Visual audit

Visual comparison

Native Excel 16.112.3 exports, verified Excel/Quartz PDF provenance. Page 2 at 300 DPI:

GT Before After
GT Before After

The unchanged page-1 native comparison is attached to #1550, #1551, and #1552.

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: two printable sheets retain their native order.
Element presence Remaining: #1185 marker rendering and #1566 omitted worksheet separator lines. Existing axes and chart grid paths are retained.
Position/size Remaining: #1272 chart frame, #1542 fitted drawings, #1545 fixed-row text, #1550 title-row height, #1552 footer position, and #1568 category-label baseline. Fixed: source category boundary spaces contribute to label centering.
Rotation/flip No deviation observed: no transform changes.
Fill Matches GT: intended series, header, and table fills are unchanged.
Stroke/border Remaining: #1566 omitted worksheet separator lines; #1564 fitted worksheet rule thickness/placement. Declared chart-line opacity remains 25% and 50%, matching native. Gray table hairlines, teal total rules, and brown category rules retain their paths; no dashed or dotted source rules are lost.
Shape outline geometry Remaining: #1185 marker, #1272 chart frame, and #1550 title-band height. All 831 canonical primitives retain geometry and paint.
Text content Matches GT after whitespace normalization of pdftotext -layout; all label/value characters are preserved; the source month categories also retain their significant trailing space.
Font family/weight/style Matches GT: the existing Cambria major-theme category font is preserved. Bold Cambria section headings, bold Trebuchet expense headings, Arial bold instruction title, and Aptos footer retain their emphasis. No italic or underlined runs are changed.
Text color Matches GT: chart labels and worksheet text retain their colors.
Alignment Remaining: #1542 drawing labels, #1545 row text, #1550 first-page content, #1552 footer baselines, and #1568 category-label baseline. Fixed: single boundary spaces are preserved in the aligned label width.
Line/paragraph spacing Remaining: #1545 fixed-row seating and #1551 wrapped note line pitch.
Clipping/overflow No deviation observed: no new clipping or overflow; native and output both display ##### in the narrow annual-total cells.

Signed-off-by: Yonghye Kwon <developer.0hye@gmail.com>
@developer0hye
developer0hye merged commit bbcaecd into main Sep 5, 2026
18 checks passed
@developer0hye
developer0hye deleted the fix/issue-1567-axis-label-spaces branch September 5, 2026 09:56
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.

1 participant