Repository navigation
fix(docx): count a table's rules as both editors do, and round a cell and the chip composed in it once - #878
Merged
Merged
Conversation
… and the chip composed in it once - A rule of w:sz eighths takes floor(sz x 2.5) twips of a row's height (eighthsInTwips), as Word and LibreOffice count it: measured on ten-row tables ruled at 3, 5, 6, 7 and 9 eighths, 7, 12, 15, 17 and 22 twips. - A rule between two rows is shared in whole twips, the row above taking half rounded down and the row under it the rest (clearOfTheRules), and the first and last rows' held heights agree with that split (outerRulesBeyondOne). - A cell's top and bottom margins are rounded to the twip together (applyCellPadding). - A shape composed in a table cell is held, and its label cut, in whole twips rounded down (holdThePanelsHeight, cutTheLabelToItsOutline, twipsDown): the row the cell is in holds the page's height rounded once. - What an outlined chip's letters keep its label past the height its row holds comes out of the margins of the cell it is in, where it is all the cell holds and the cell all its row holds (giveBackWhatTheLabelNeeds). - Docs: CHANGELOG (v2.5.0), the recipe's Tables row and composed-shape paragraph, the capability matrix's table and composed-shape rows. - Fidelity baselines rewritten (Word, LibreOffice on Windows); the companion DOCX preview re-rendered. - Tests: DocxCellPaddingTest (half-twip rules, the split, the pair), DocxRuledRowHeightTest (odd and half-twip rules, a row to the nearest), DocxComposedCellTest (a chip rounded down, the give-back, its clamp and beside another cell); DocxRuleRowTest and DocxPanelTailTest at the new count.
A 1.05pt outline leaves its chip 17 twips taller than its row holds: 8 come out of the cell's top margin and 9 out of its bottom one.
…e count The DOCX Fidelity job's measurement of this branch, taken from its artifact (run 38138931753). Against the job's measurement of 2.5-dev: 11 documents nearer, 5 further, the sum of the medians 0.36pt nearer. rota-cobalt's median 0.23 -> 0.17pt and its p90 0.79 -> 0.90pt: its grid no longer runs 0.8pt low, and the stacked chips' labels, which LibreOffice on Linux sets about 0.7pt high in their chips, stand 1pt high.
…-twips # Conflicts: # qa/src/test/resources/docx-fidelity/libreoffice-linux-lines.tsv # qa/src/test/resources/docx-fidelity/libreoffice-linux.tsv
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.
Why
A table's rows in Word and LibreOffice were held a twip apart from the page's wherever a rule's
width, a cell's margins or a chip composed in a cell rounded to the twip, and the twips added up row
by row. Each was measured in isolation:
w:szeighths of a point is 2.5 twips aneighth; ten-row tables ruled at three, five, six, seven and nine eighths stepped each row by its
margins, its line and 7, 12, 15, 17 and 22 twips, in both editors alike to a tenth of a twip — the
width rounded down (12.5 → 12, 17.5 → 17). Counted to the nearest, a row held by its height
under a rule of an odd number of eighths stood a twip short of the page's.
off a twip short: 15 twips as 7 and 7, every row of
NorthlineProposal's andEditorialProposal's investment tables a twip taller in both editors.CobaltRota's stacked shift chips are 183.69 twips; each held at 184 and its label cut at 184,two in a day cell stood every row they were in a twip taller (row probes of the sheet's staff
rows, fifteen copies each, Word = LibreOffice to 0.03 twip). And an outlined chip whose letters
keep its label taller than its borders leave room for grows in Word by the rest: every staff row
with a split shift in one stood 3 twips taller.
Counted to the nearest, the rule had hidden most of this:
CobaltRota's single-shift rows came outright only because the extra twip of each rule cancelled the extra twip of their margins, and its
header stood up to 0.4pt high above a grid that ran to 0.8pt low.
What changed
In
DocxSemanticBackend:eighthsInTwipscounts a rule asfloor(sz × 2.5)twips — the countborderTwips(a row'sheld height,
verticalMargins,outerRulesBeyondOne) andruleTwips(clearOfTheRules) share.clearOfTheRulesshares a rule between two rows in whole twips: the row above it gives uphalf rounded down, the row under it the rest; the rules above and below the table stay whole to
their row.
outerRulesBeyondOneholds the first and last rows' extra rule twips to that samesplit (a first row its share of the rule under it, a last row the rest of the rule above it), so
a held row's height and its margins agree to the twip.
applyCellPaddingrounds a cell's top and bottom margins together: the top to the nearest,the bottom to what the two come to less it. Panels' cells take the same path.
rounded down (
holdThePanelsHeight(…, inACell)→holdRowAtLeast(…, down)→twipsDown), andcutTheLabelToItsOutlinecuts its label to the room rounded down: the row the cell is in holdsthe page's height rounded once, and anything in it rounded up grows it. A shape in the flow keeps
rounding to the nearest.
giveBackWhatTheLabelNeeds: where a cut label is still taller than the height its shape's rowholds — an outlined chip whose letters stop the cut — that much comes out of the margins of the
cell the shape is in, half above (rounded down) and half below, as far as they hold. The chip
stays centred where the page centres it and the row keeps the page's height. Only where the shape
is all its cell holds and the cell all its row holds (
aloneInItsRow, set bywriteCellNodes):what stands above the shape in its cell would move up with the top margin, and both editors give
every cell of a row the row's largest margins, so beside another cell it gives nothing back.
Docs:
CHANGELOG.md(v2.5.0), the recipe's Tables row and composed-shape paragraph, the backendcapability matrix's table and composed-shape rows.
Verification
./mvnw -B -ntp clean verify→ BUILD SUCCESS: render-docx 1359 run, 0 failures, 1 skipped(+9), qa 1820, examples 93, core 818; with the odd-twip test added after it, render-docx
1360 run, 0 failures.
DocxCellPaddingTest— a 0.625pt and a 0.875pt rule come off at 12 and 17 twips; a0.7pt rule between two rows comes off as 7 above it and 8 below it; 1.6345pt margins are written
33 and 32.
DocxRuledRowHeightTest— every row of three-row tables ruled at five, six and seveneighths is held at its content's height, and a table's own unpadded, unruled row at five sizes
at its line, both rounded to the nearest.
DocxComposedCellTest— a 9.1846pt chip is held and itslabel cut at 183 twips; an outlined chip whose letters keep its label 20 twips past its row's 140
leaves the cell it is all of 10 twips less above and below, a filled one nothing, a cell of 5
twips nothing below zero, a chip beside another cell nothing at all, and 17 twips are given back
8 above and 9 below. Changed:
DocxRuleRowTest(a 0.9pt border counts 17 twips, the last row's share of the rule above it 9),DocxPanelTailTest(a 1.1pt panel border counts 22).floored; the upper row's ceiled; the margins rounded apart; the first row's share ceiled; the last
row's floored; the chip held to the nearest; the label cut to the nearest; no give-back; the
give-back above only; a give-back beside another cell; every held row rounded down; the give-back
past the margins; the odd twip given back above.
between two lines, Lato 10pt, 4pt padding): every table takes the page's height to within ±0.8 twip
in Word (its 2.4-twip grid) and to the twip in LibreOffice.
2.5-dev, Word (word-windows*.tsv): 10 documents nearer, 7further, the sum of the medians 0.16pt nearer —
proposal-northline's p90 0.71 → 0.43pt,proposal-editorial's 1.20 → 0.81pt,cv-panel's median 0.43 → 0.31pt,invoice-subscription's0.43 → 0.33pt. LibreOffice on Windows (
libreoffice-windows*.tsv): 10 nearer, 7 further —proposal-northline0.27 → 0.17pt,cv-panel0.39 → 0.26pt,invoice-subscription0.34 → 0.24pt.LibreOffice on Linux (CI's
docx-fidelityjob,libreoffice-linux*.tsv, rewritten from itsartifact on this branch in its own commit): against its measurement of
2.5-dev, 11 nearer, 5further, the sum of the medians 0.36pt nearer —
invoice-subscription0.34 → 0.19pt,invoice-platform0.42 → 0.32pt,proposal-northline0.27 → 0.17pt. The report is unchanged: the same 969 notes.Notes for review
CobaltRota's grid now stands where the page sets it: every rule under the table's top within aquarter point of the page's in Word, where they ran from 0.4pt high to 0.8pt low; its p90 0.99 →
0.46pt in Word and 0.84 → 0.39pt in LibreOffice. Its median moves 0.32 → 0.38pt (0.23 → 0.31pt):
the shifts' labels stand about 0.3pt low in their chips, a composed cell's first line not being
seated, which the grid standing high had hidden. That seat is its own change.
panels now take the page's height, and the lines after them show what they had hidden:
invoice-classic's notes 0.2pt low under its totals table (which had stood 0.13pt high), whereboth editors leave more space after a table than the page does;
invoice-platform's line items,already 0.3pt high in their cells, a twip higher with their rows where the page draws them (its
rules within 0.11pt of the page's in LibreOffice);
letter-panel's body, already 0.25pt high, atwip higher under its panel; the line items of
invoice-consultingand its long version,invoice-meteredandinvoice-paymentsa step of the grid, or two to three twips.proposal-editorialin LibreOffice (44.46 → 44.75pt) is thedocument LibreOffice sets on a new page.
rota-cobalt's median moves nearer (0.23 → 0.17pt) and its p90 further (0.79 → 0.90pt):its grid no longer runs 0.8pt low, and the stacked chips' labels, which LibreOffice on Linux sets
about 0.7pt high in their chips (its face substitutions), stand 1pt high. The job held 22 of its
lines further against the baseline from before fix(docx): stand a table's text cells on the page's baselines, through their row's margins #876, with 5 of
proposal-editorial's.the chip, at the page's height.
lighter of the two) and where its label's room is read: a panel's rule widths are their own change.
At
CobaltRota's 1.1pt outline the two counts agree to the twip.Lane: shared-engine (DOCX backend) —
render-docxonly, no public API.