Break a container's children onto lines, and place 4 361 more fields - #14
Merged
Conversation
…a node is pdf.js's lr-tb and rl-tb wrap their children onto lines, and the rule is two functions read together: addHTML says where a child goes once it is accepted (layout.js:107-129) and checkDimensions says whether it is accepted at all (layout.js:279-338). The two-attempt protocol between them IS the line breaking: attempt 0 tries the line in hand, a refusal raises it to 1, which opens a fresh line, resets numberInLine and drops straight back to line mode. Packing needs a quantity this package has never computed: how wide a node comes out. widthOf is the mirror of heightOf, memoised per node and per width for the same reason, and contentWidth is addHTML's width column for each of the five layouts. The break is decided on width alone. checkDimensions would also move a child too tall for the room left onto the next line; the room left is not carried by a measurement that runs before the layout, which is the same limit contentHeight has for tb. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…se 4 live
pdf.js splits an lr-tb: $isSplittable refuses "position" and anything
containing "row" (template.js:4952-4955), and "lr-tb".includes("row") is false.
Clause 2 says so now, which puts a wrapping container in the flowing chain, and
that is what the fourth clause has been waiting for — it reads the parent's
numberInLine, which only a container filling a line has. It is asked 440 times
over the corpus and refuses 4, all on us-uscis__g-1055.
A LINE is what moves to the next content area, never part of one, because every
child of a line pdf.js has flushed is already in that line's div. The check is
stricter than pdf.js's literal one and turnTo says why: pdf.js accepts a child
of unwritten height on "more than two points remain" and takes it back when the
child's own contents fail, and there is no failure to take back here.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… doc Every branch of the packing, of widthOf and contentWidth, and of flowLines is witnessed: the two-attempt protocol child by child, a child re-measured against a whole line after the tail of one refused it, rl-tb anchored at the right, a container split between two of its lines, and the fourth clause of $isSplittable asked of the same subform first on a line and second on one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The number, and the disagreement first
79 851 of the 81 750 body fields, on 3 040 sheets. v0.9.0 placed 75 490 on
2 864. Nothing that was on the paper came off it.
Two forms now come out on MORE sheets than pdf.js, and none ever has before.
us-uscis__i-956is on 14 against pdf.js's 12 andus-uscis__i-956gon 16against 15. Both were far SHORT before — 3 against 12 and 1 against 15 — so
this is a wall coming out from behind another one rather than a regression, but
it is an overshoot and the judge counts it as a defect. Traced to the
container:
form1.P1.sfPart4is an lr-tb whose lines begin at 300 points downour second sheet and would have to begin at 252 or less for pdf.js's answer, so
something ABOVE it is 48 points taller here. Not diagnosed to the line, and I
will not name a cause without a witness.
The bucket was not what the label said
Classified before writing anything, as slice 6 was. Of the 4 303 fields whose
first blocker was
lr-tb:rl-tbandrl-rowdo not appear in the corpus at all — zero occurrencesin 560 templates — so the half of this change that fills a line from the right
moves no field and nothing measures whether it is right. It is written because
the two are one arithmetic in pdf.js and differ only in a CSS class.
790 wrapping containers exist in the expanded forms, holding 1 027 body fields
and 2 751 draws. Only 49 had ever been reached: a stack rejects everything after
the first child whose height it cannot compute, so every later wrapping sibling
was behind the first one.
What it does
addHTML(layout.js:107-129) andcheckDimensions(layout.js:279-338) readtogether. The two-attempt protocol between them IS the line breaking: attempt 0
tries the line in hand, a refusal raises it to 1, which opens a fresh line,
resets
numberInLineand drops straight back to line mode. The heightarithmetic differs between the branches and that difference is the whole of it.
Packing needs a quantity this package has never computed: how wide a node
comes out.
widthOfis the mirror ofheightOf, memoised per node and perwidth for the same reason, and
contentWidthis addHTML's width column foreach of the five layouts. 2 239 of the 2 374 children of a wrapping container
write a width outright; the 135 that do not are all subforms and all on one
form, which is why the container arithmetic had to be real rather than refused.
Clause 4 of
$isSplittableis live. pdf.js splits an lr-tb —"lr-tb".includes("row")is false (template.js:4952-4955) — so clause 2 admitsit, which puts a wrapping container in the flowing chain, which is the only
place
numberInLineexists. Over the corpus the clause is asked 440 times andrefuses 4, all on
us-uscis__g-1055.What it does not do, and says so
child too tall for the room left onto the next line; the room left is not a
quantity a measurement that runs before the layout carries. Same limit
contentHeighthas for tb.that shares a line moves whole even where clause 4 would allow it: splitting
it would leave the rest of its line to be placed on a sheet the first half of
it is not on. 137 splittable children of a line in the corpus, 136 of them
alone on it.
pdf.js's answer there turns on
$isThereMoreWidth— whether a containerabove is mid-line — which is layout state a measurement does not have. It
fires nowhere on the corpus.
turnTomoves a whole line where pdf.js moves a child. pdf.js accepts achild of unwritten height on "more than two points remain" and takes the
acceptance back when the child's own contents fail; there is no failure to
take back here. Measured: taking pdf.js's literal test costs 33 fields of
us-uscis__i-956hand gains none, and i-956h is one of the 77 forms pdf.jscannot lay out, so no judge can say which is right there.
The reconciliation, field by field
Every field's disposition dumped from
origin/mainand from this branch andpaired on
(form, path, occurrence)— 81 750 of them, same multiset of keys:lr-tb, in a tb stack → placedlr-tb, in a table stack → placed75 490 + 4 361 = 79 851. Second slice running with no loss. 34 fields
placed both times are on another sheet.
The judges, and the pairing re-audited
The pairing, since line breaking changes which boxes exist and in what
order. Of 162 163 body boxes on the 472 agreeing forms: 150 792 paired,
6 781 unnamed and so never keyed, 4 590 keyed but absent from pdf.js's dump
(1 900 of them
presence="hidden"), and 0 dropped because the two sidescounted a key differently. The same audit on
origin/maingives 4 522 absentof 1 872 hidden and 0 dropped, so the absent are pre-existing in the same
proportion and not this change's.
What the judge cannot see here, and it is most of the chain half. pdf.js
emits no coordinate inside a line at all —
createLinewraps the children in aflexbox div — so where along a line a box went is unjudged in both directions,
exactly as stacking was for tb. And the 212 field-sheet changes the chain half
makes fall on
us-uscis__g-1055(6),us-uscis__i-956h(199) andus-uscis__i-956(7): the first two are among the 77 forms pdf.js cannot layout at all and the third is not fully placed, so no judge sees any of them.
Splitting a wrapping container across a sheet is checked by its own tests and
by nothing external.
Four sheet-count disagreements remain and are the same four as v0.9.0:
us-opm__sf813andus-opm__sf39a(a positioned outermost subform, whose fitcheck has never been done) and
us-uscis__i-600aandus-uscis__i-821(onesheet behind after a
breakBefore, undiagnosed).What is left
Gate: 100% statement coverage,
go vet,gofmt -lempty,-race, ninecross-compile targets,
CGO_ENABLED=0,GOWORK=off, Go 1.27.1 viaGOTOOLCHAIN.🤖 Generated with Claude Code