Skip to content

fix(xlsx): overlay same-row worksheet drawings#472

Merged
developer0hye merged 1 commit into
mainfrom
fix/xlsx-drawing-overlay
Jul 26, 2026
Merged

fix(xlsx): overlay same-row worksheet drawings#472
developer0hye merged 1 commit into
mainfrom
fix/xlsx-drawing-overlay

Conversation

@developer0hye

Copy link
Copy Markdown
Owner

Summary

  • emit one reserved flow box per worksheet anchor row instead of one per shape
  • size that box to the tallest shape on the row and place each shape at its own horizontal offset
  • drop generate_sheet_anchor, whose placed-drawing arms became dead

Related issue

Fixes #459

Details

Excel lays shapes anchored to the same row out side by side over the grid. office2pdf reserved a full-width flow box per shape, so each one advanced the flow before the next.

Shape top coordinate at 150 DPI:

Shape Excel GT before after
accent1 188 246 246
accent1 lighter 60 188 486 246
accent6 shade 75 188 726 246

The tripled reservation also spilled the sheet onto a blank second page; the workbook now exports to one page, as Excel does. The remaining offset from Excel's 188 px, and the undersized shape bounds, are the anchor metrics tracked in #460.

Testing

  • cargo fmt --all -- --check
  • cargo test --workspace
  • cargo clippy --workspace --all-targets --all-features
  • pdfinfo page-count comparison
  • pdftoppm -r 150 rendering, fill-bounds sampling, and magick compare -metric AE -fuzz 5%

Visual impact

  • No rendered PDF change
  • Rendered PDF change or visual evidence added
  • Reason: same-row worksheet drawings no longer stack, and the sheet no longer gains a blank page.

Visual audit

  • Issue: XLSX: same-row worksheet drawings stack vertically and spill onto a blank page #459
  • Fixture: tests/fixtures/xlsx/theme_color_drawing.xlsx
  • Page(s): page 1 of the Excel GT and of the office2pdf output
  • Renderer and DPI: pdftoppm, 150 DPI
  • Evidence mode: fix
  • New follow-up issues found in this audit: None
  • GT: assets/bugfixes/issue-459/gt.jpg
  • Before: assets/bugfixes/issue-459/before.jpg
  • After: assets/bugfixes/issue-459/after.jpg

The GT is the native Microsoft Excel export already captured for this fixture in #434, reused unchanged: same workbook, same page, same renderer, same 150 DPI.

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
  • Inspected matched region crops at full resolution
  • Ran the 5% fuzz pixel-difference sweep
  • Inventoried hairlines and border dash styles
  • Inventoried font weight, italic, and underline emphasis

The 5% fuzz sweep against the size-normalized GT falls from 290,500 to 121,943 differing pixels. Every remaining cluster is the residual shape displacement and undersizing tracked in #460. The fixture has no hairlines, borders, or dashed strokes, and every run is regular weight with no italic or underline.

Deviation audit

Check Result
Page count/order Fixed - the workbook exports to one page, as Excel does; the blank second page is gone
Element presence Matches GT - the title and all three drawing labels are present
Position/size Fixed - the three shapes now share one top coordinate instead of stacking at 246/486/726 px; Remaining: #460 for the residual offset from Excel's 188 px and the undersized bounds
Rotation/flip No deviation observed - the fixture contains no rotated or flipped elements
Fill Matches GT - all three RGB values match Excel exactly after #430
Stroke/border No deviation observed - the shapes intentionally have no outline or hairline
Text content Matches GT - all four strings are preserved
Font family/weight/style Matches GT - the labels render Calibri after #461 and the title the workbook Normal font
Text color Matches GT - all text remains black
Alignment Matches GT - drawing labels remain horizontally and vertically centered
Line/paragraph spacing No deviation observed - each text region is one regular single-line paragraph
Clipping/overflow Fixed - the flow no longer reserves three shape heights, so nothing spills past the page

Checklist

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

Excel lays shapes anchored to the same row out side by side over the grid.
office2pdf reserved a full-width flow box per shape, so each one advanced
the flow before the next: three shapes on row 3 formed a diagonal stack at
150 DPI tops of 246, 486, and 726 px against Excel's 188, 188, 188, and the
tripled reservation spilled the sheet onto a blank second page.

Emit one reserved box per anchor row, as tall as the tallest shape on it,
and place each shape at its own horizontal offset inside it. Charts stay
ordinary flow content.

On the regression fixture the three shapes now share a top of 246 px and the
workbook exports to one page. The 5% fuzz pixel difference against the
native Excel export falls from 290,500 to 121,943.

The remaining offset from Excel's 188 px, and the undersized shape bounds,
are the anchor metrics tracked in #460.

`generate_sheet_anchor` is gone: its text-box and image arms were dead once
every placed drawing routed through the row emitter, and charts call
`generate_chart` directly.

Fixes #459

Signed-off-by: Yonghye Kwon <developer.0hye@gmail.com>
@developer0hye
developer0hye merged commit 806b1cc into main Jul 26, 2026
17 checks passed
@developer0hye
developer0hye deleted the fix/xlsx-drawing-overlay branch July 26, 2026 00:59
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: same-row worksheet drawings stack vertically and spill onto a blank page

1 participant