Skip to content

feat(document): fit a printed sheet to the paper the file states - #820

Merged
andiwand merged 1 commit into
mainfrom
feat/fit-a-sheet-to-the-paper-it-states
Sep 5, 2026
Merged

feat(document): fit a printed sheet to the paper the file states#820
andiwand merged 1 commit into
mainfrom
feat/fit-a-sheet-to-the-paper-it-states

Conversation

@andiwand

@andiwand andiwand commented Sep 5, 2026

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

Stacked on #817 — review that first; this branch contains it.

The second part of #816: the file's own paper reaches the printed page. #817 fits the sheet to whatever paper it lands on, by capping the table's width — which never clips, but squeezes the column widths unevenly. This reads the paper the file states and scales the sheet by it, so the printed sheet keeps the proportions the document has.

What was missing

Sheet had no page layout, and no engine parsed one. The paper, orientation and margins an ods states for a sheet live on the master page its table style names — the same indirection a paragraph's page uses, and StyleRegistry::master_page_of_style already walked it for text roots, slides and drawing pages. Nothing asked it for a sheet.

What this adds

  • Sheet::page_layout() — new on the public API, a new virtual on abstract::SheetAdapter, implemented by all five engines that provide sheets, and mirrored in the Python, JNI and Apple bindings (wasm binds no document elements). Real for ods; empty, with the reason, for xlsx, xls, .numbers and csv.
  • translate_sheet states the factor the paper asks for, per sheet, as --odr-print-fit on the sheet's own table: the printable width (page less its side margins) over the sum of the column widths. Only ever down — a sheet that already fits is printed at its size, never enlarged.
  • The print stylesheet applies it as zoom, which scales the layout, so rows still break across pages. fix(html): print a sheet onto the page, without our ruler #817's max-width cap stays behind it, as the guard for paper the file did not expect.

Measured

A 6-column sheet of 3in,1in,3in,1in,3in,1in on Letter with 1in margins, rendered by translate, printed with Chrome headless, columns measured from the PDF text positions:

printed column widths ratio (file says 3:1) type size
#817's cap alone 127, 54, 128, 54, 127 pt 2.35 : 1 10pt
with the fit 117, 39, 117, 39, 117 pt 3.00 : 1 5.4pt

117pt is 216pt × 0.5417, and 0.5417 is exactly the 6.5in printable width over the 12in the sheet is wide — so the sheet prints at the scale the file's paper implies, undistorted.

What it does not do

Half the corpus states no paper. 22 of the 52 ods here carry fo:page-width; the rest state margins only and leave the paper to the printer. Those get no factor and keep #817's behaviour exactly. Reading a frontend-supplied paper from HtmlConfig — the Android side knows its PrintAttributes — is the obvious next increment, and would cover them.

No @page rule. Declaring the file's paper to the printer would want one, but a print path that honours CSS page size over the framework's own attributes has to be established per frontend first, and a view that renders several sheets has several answers. Left out deliberately.

xlsx is not wired up, and its pageSetup alone would buy nothing: a column width there is a ch, so no absolute content width can be summed to compare against the paper. Both halves are one follow-up.

Pagination — a wide sheet continuing onto further pages at full size, the way a spreadsheet application prints it — remains the open half of #816.

Tests

Document.ods_sheet_page_layout reads the paper off a real ods; Document.ods_sheet_page_layout_without_a_paper_size pins the common margins-only case. On the renderer, html.a_sheet_is_fitted_to_the_paper_the_file_states checks the factor against the file's numbers, and html.a_sheet_is_only_ever_fitted_down drives three inline flat-ods sheets — narrower than, exactly, and twice its paper.

Reference output is unchanged in what it renders: the new attribute is inert outside print, so no pixel moves and no pin advances.

@andiwand
andiwand force-pushed the feat/fit-a-sheet-to-the-paper-it-states branch from 7571d4d to 9fccbc5 Compare September 5, 2026 20:20
@andiwand
andiwand force-pushed the fix/print-a-sheet-onto-the-page branch 2 times, most recently from ee58f5c to 3813aaa Compare September 5, 2026 20:22
Base automatically changed from fix/print-a-sheet-onto-the-page to main September 5, 2026 20:22
@andiwand
andiwand force-pushed the feat/fit-a-sheet-to-the-paper-it-states branch 2 times, most recently from ef95563 to 5f79400 Compare September 5, 2026 20:23
A sheet's page style — the paper it is printed on — was neither parsed
nor exposed, so the print stylesheet had nothing to fit against and left
the browser to squeeze the sheet to the page, which distorts the column
widths the file gives it.

New `Sheet::page_layout()`, read for ods from the master page the table
style names, the way a paragraph's page is; empty for the formats whose
print setup is unparsed. `translate_sheet` states the factor the paper
asks for per sheet, and the print stylesheet applies it as a `zoom`, so
the sheet prints at the file's own proportions. Only ever down, and the
stylesheet's cap stays as the guard for paper the file did not expect.

Towards #816.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fp26La4hFAu9VRMHPjKmXd
@andiwand
andiwand force-pushed the feat/fit-a-sheet-to-the-paper-it-states branch from 5f79400 to 375cd9c Compare September 5, 2026 20:38
@andiwand
andiwand merged commit d4af337 into main Sep 5, 2026
22 of 25 checks passed
@andiwand
andiwand deleted the feat/fit-a-sheet-to-the-paper-it-states branch September 5, 2026 20:41
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