Skip to content

Print a page bigger than the paper it has to go on - #21

Merged
tannevaled merged 1 commit into
mainfrom
poster
Aug 30, 2026
Merged

Print a page bigger than the paper it has to go on#21
tannevaled merged 1 commit into
mainfrom
poster

Conversation

@tannevaled

@tannevaled tannevaled commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Poster spreads each page over across×down sheets, so the sheets printed and
taped together make one page the size of a wall. It is the inverse of NUp,
which is the verb this library already had for the other direction.

Every sheet is the size of the page it came from. That is the whole of the
constraint: a piece of a poster that is not the shape of the page will not tape
back into it, and a printer asked for something other than the paper in its
tray does its own scaling, which is exactly what a poster must not have done to
it. So an A4 document posters onto A4. The page is then enlarged as far as it
goes inside the wall of sheets and centred, which is min(across, down) times —
so a square grid uses every sheet whole, and an oblong one leaves white at two
opposite edges rather than stretching the page to fill it.

No overlap. Poster is told how many sheets and not how wide the printer's
unprinted border is, so an overlap would have to be a constant guessing at a
printer nobody here can see: too small and the seam still gaps, too large and
more of the poster goes to trimming than the margin saves, and neither could be
turned off. Meeting exactly is also the only arrangement that is exactly
undone — every part of the page on one sheet and one only.

The order is asserted rather than counted. A PDF's origin is at the BOTTOM, so
the sheet showing the TOP of the page is the one that pushes the page furthest
down, and the four matrices of a two-by-two poster end in -200, -200, 0, 0 and
not the other way about. Get it wrong and every piece is present, every sheet
is the right size, and the poster is upside down — which no count of pages
would catch. The tests pin the matrices, and pin them twice: once as six
numbers, and once turned back into the region of the page each sheet shows, so
that the table can be read as the poster laid out on the floor.

Those tests were checked by breaking the code on purpose. Rows counted from the
bottom, the loops transposed, the scale taken from across alone, the leftover
not centred, the scale made non-uniform: each is caught, by 6 to 18 assertions.

And poppler was asked rather than ourselves, since a package that agrees with
itself about where it put something has proved nothing. A page of nine coloured
blocks, one to a cell, each with a black pip in its cell's top-left corner, is
postered three by three and rendered by pdftoppm: sheet i carries cell i's
colour and no other cell's, the block lands in the middle at three times life
size, and the pip is in the sheet's own top-left corner. Flip the rows and six
sheets report the wrong colour; transpose the loops and six do.

It is the first test here to shell out at all, and CI now installs poppler so
that it runs there rather than skipping: the runner image does not carry
poppler-utils, so as written it would have gone quiet in CI and said nothing
about it. It skips on a machine that has no poppler and FAILS when CI does not,
because a judge that quietly absents itself is no better than no judge.

100% statement coverage, go vet and -race clean, nine cross-compile targets.

Poster spreads each page over across×down sheets, so the sheets printed and
taped together make one page the size of a wall. It is the inverse of NUp,
which is the verb this library already had for the other direction.

Every sheet is the size of the page it came from. That is the whole of the
constraint: a piece of a poster that is not the shape of the page will not tape
back into it, and a printer asked for something other than the paper in its
tray does its own scaling, which is exactly what a poster must not have done to
it. So an A4 document posters onto A4. The page is then enlarged as far as it
goes inside the wall of sheets and centred, which is min(across, down) times —
so a square grid uses every sheet whole, and an oblong one leaves white at two
opposite edges rather than stretching the page to fill it.

No overlap. Poster is told how many sheets and not how wide the printer's
unprinted border is, so an overlap would have to be a constant guessing at a
printer nobody here can see: too small and the seam still gaps, too large and
more of the poster goes to trimming than the margin saves, and neither could be
turned off. Meeting exactly is also the only arrangement that is exactly
undone — every part of the page on one sheet and one only.

The order is asserted rather than counted. A PDF's origin is at the BOTTOM, so
the sheet showing the TOP of the page is the one that pushes the page furthest
down, and the four matrices of a two-by-two poster end in -200, -200, 0, 0 and
not the other way about. Get it wrong and every piece is present, every sheet
is the right size, and the poster is upside down — which no count of pages
would catch. The tests pin the matrices, and pin them twice: once as six
numbers, and once turned back into the region of the page each sheet shows, so
that the table can be read as the poster laid out on the floor.

Those tests were checked by breaking the code on purpose. Rows counted from the
bottom, the loops transposed, the scale taken from across alone, the leftover
not centred, the scale made non-uniform: each is caught, by 6 to 18 assertions.

And poppler was asked rather than ourselves, since a package that agrees with
itself about where it put something has proved nothing. A page of nine coloured
blocks, one to a cell, each with a black pip in its cell's top-left corner, is
postered three by three and rendered by pdftoppm: sheet i carries cell i's
colour and no other cell's, the block lands in the middle at three times life
size, and the pip is in the sheet's own top-left corner. Flip the rows and six
sheets report the wrong colour; transpose the loops and six do.

It is the first test here to shell out at all, and CI now installs poppler so
that it runs there rather than skipping: the runner image does not carry
poppler-utils, so as written it would have gone quiet in CI and said nothing
about it. It skips on a machine that has no poppler and FAILS when CI does not,
because a judge that quietly absents itself is no better than no judge.

100% statement coverage, go vet and -race clean, nine cross-compile targets.
@tannevaled
tannevaled merged commit 9091587 into main Aug 30, 2026
1 check passed
@tannevaled
tannevaled deleted the poster branch August 30, 2026 15:19
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