Skip to content

Add page composition: n-up, booklets, overlays and blanks - #2

Merged
tannevaled merged 1 commit into
mainfrom
page-composition
Aug 25, 2026
Merged

Add page composition: n-up, booklets, overlays and blanks#2
tannevaled merged 1 commit into
mainfrom
page-composition

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Pages that this package builds rather than borrows. A page is now borrowed,
composed of other pages, or empty, and the three write out through the same
path — which is what lets a laid-out sheet be laid out again, and a watermark
later be just another tile.

Each page placed inside another becomes a Form XObject whose own coordinates
run from the origin to its effective size, so whatever places it need only
scale and translate. A page's rotation is baked into that form's matrix
exactly as a viewer would apply it, and a rotation of ninety or two hundred and
seventy swaps which way round it is measured — so a sideways page laid out
two-up takes the shape it will actually print in, not the shape its media box
claims. The box used is the crop box where there is one, since that is what
gets printed.

NUp picks the grid rather than being told it: of every arrangement with at
least n cells, the one whose cells come closest in shape to the pages going
into them, with a small penalty for cells left over. Booklet reorders for
saddle stitching — pages folded in half and stapled through the spine — padding
to a multiple of four and laying two to a sheet. Overlay and Underlay draw one
document over or under another, centred and scaled to fit.

Generated content streams are compressed, which they have to be: they were
decoded to get here and would otherwise go out several times the size they came
in.

Verified on the corpus rather than by assertion: for each of the 1 959
multi-page files, two-up produces the right number of sheets and every form
drawn on them carries exactly the bytes of the page it stands for, blanks
included. All 1 959 hold, and the 118 833-file checks of the earlier verbs
still do.

Exact 100% statement coverage over the package and the command, go vet clean,
nine cross-compilation targets.

Pages that this package builds rather than borrows. A page is now borrowed,
composed of other pages, or empty, and the three write out through the same
path — which is what lets a laid-out sheet be laid out again, and a watermark
later be just another tile.

Each page placed inside another becomes a Form XObject whose own coordinates
run from the origin to its effective size, so whatever places it need only
scale and translate. A page's rotation is baked into that form's matrix
exactly as a viewer would apply it, and a rotation of ninety or two hundred and
seventy swaps which way round it is measured — so a sideways page laid out
two-up takes the shape it will actually print in, not the shape its media box
claims. The box used is the crop box where there is one, since that is what
gets printed.

NUp picks the grid rather than being told it: of every arrangement with at
least n cells, the one whose cells come closest in shape to the pages going
into them, with a small penalty for cells left over. Booklet reorders for
saddle stitching — pages folded in half and stapled through the spine — padding
to a multiple of four and laying two to a sheet. Overlay and Underlay draw one
document over or under another, centred and scaled to fit.

Generated content streams are compressed, which they have to be: they were
decoded to get here and would otherwise go out several times the size they came
in.

Verified on the corpus rather than by assertion: for each of the 1 959
multi-page files, two-up produces the right number of sheets and every form
drawn on them carries exactly the bytes of the page it stands for, blanks
included. All 1 959 hold, and the 118 833-file checks of the earlier verbs
still do.

Exact 100% statement coverage over the package and the command, go vet clean,
nine cross-compilation targets.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 9492b96 into main Aug 25, 2026
1 check passed
@tannevaled
tannevaled deleted the page-composition branch August 25, 2026 10:26
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