diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c4bea0..d90b814 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -177,7 +177,12 @@ merely unimplemented belongs in the list above, not here. drift apart along the line (identical word widths, 0.45 mm apart by the 150th mm). A matching negative `word-spacing` was tried and reverted — it fixes the break but shortens every last line; see - `tests/render-parity/README.md`. Noted 2026-08-09. + `tests/render-parity/README.md`. A third case is a run with no break + opportunity in it that is longer than the space left (a row of leader dots, a + long URL): LibreOffice fills the line and breaks the run at the margin, where + Chromium moves the whole run to the next line. `overflow-wrap: anywhere` would + match it but also breaks runs LibreOffice keeps whole and shrinks a table + column to its narrowest glyph. Noted 2026-08-09, revised 2026-08-11. - A text box anchored inside a paragraph loses the vertical offset it was anchored by: it is a block node here, so the importer lifts it out and it simply follows that paragraph (measured 4.7 mm on the thesis' figure page). @@ -196,6 +201,29 @@ merely unimplemented belongs in the list above, not here. editor). LibreOffice recomputes auto-grow heights on open, so a re-saved box keeps its content but sheds excess empty height. Shapes (rect/ellipse) export with fixed geometry instead. Noted 2026-07-03. +- A list marker does not size the line it labels. Word and LibreOffice put the + numbering's own font on that line, so a marker whose font reaches deeper than + the text grows it (measured: a Courier New bullet on 11 pt Carlito text adds + 0.031 em ≈ 0.12 mm, which is ~1 mm down a page of bullets). Root cause: the + marker is an out-of-flow `::before` (`editor.css`) because CSS gives an + outside `::marker` no position; and an outside `::marker` has no metric + influence either — probed, changing its `font-family` moves nothing, only its + `font-size` does, and that grows the line *above* the baseline where a word + processor grows it below. Noted 2026-08-11. +- **Deliberate, not a defect:** an inline formula is typeset here, not placed as + a box. LibreOffice stores each one as an OLE frame and positions that frame + (`style:vertical-pos="middle"`/`"from-top"`); we render MathML, whose own + baseline is the typographically right one, so the frame's vertical placement is + ignored on import. Honouring it was tried and measured worse — every inline + formula in the Math Guide sank ~1 mm and the corpus went from 100 to 125 + reported differences. It also means a render-parity run cannot compare a + formula-heavy page: the two sides typeset the glyphs independently. + Noted 2026-08-11. +- **Deliberate, not a defect:** a table of contents shows live page numbers. + LibreOffice and Word print the numbers cached in the file until the reader + updates the index, so a document whose cache is stale disagrees with us (the + deputy-standards fixture caches page 7 for a heading that is on page 8 in both + renderings). Noted 2026-08-11. --- diff --git a/tests/render-parity/README.md b/tests/render-parity/README.md index b608f87..23d248e 100644 --- a/tests/render-parity/README.md +++ b/tests/render-parity/README.md @@ -89,8 +89,8 @@ form), the summary (a student summary: bullets, wrapped pictures, one table), the thesis (a 48-page thesis with charts, metafile figures and a German TOC) and the Math Guide (LibreOffice's own 63-page Math Guide: a title page, a three-page index, per-section masters, ~35 figure frames and 400 formulas) — still -report. The thesis matches LibreOffice's 49 pages and so does the Math Guide at 63 — -most of what is left is the engine rules below, not layout: +report. Both run one page off LibreOffice (thesis 48 against 49, Math Guide 64 against 63), +in each case downstream of a line the rules below cost or gained: - **A page-anchored frame's coordinates are its page's, but a frame in a *header* keeps the ones its zone gives it.** Both are drawn out of flow; the body one (`anchorPage`, @@ -110,11 +110,25 @@ most of what is left is the engine rules below, not layout: it holds is a float, so its height is the text's alone. - **A page's last line is where the footer band ends.** The body margin a file's header or footer reconstructs is the page margin plus the zone's declared height; the zone's own gap - to the body sits *inside* that height (probed — `styleResolver.ts`). Getting that wrong - costs a line on every page, which is worth more than any single block's spacing. + to the body sits *inside* that height (probed — `styleResolver.ts`). The height is the + zone's *own* font: it is one paragraph here, so its mark struts every line of the band + (`blockFontSize.ts` is in the zone schema, `hfReachPx` measures the same value). Getting + that wrong costs a line on every page, which is worth more than any single block's + spacing. - **Chromium floors every painted border to one pixel**, so a table's rows come out ~0.25mm too tall each unless the excess is taken off the cell padding (`docs/architecture/tables.md`). +- **A bulleted line is 0.12mm shorter here than in LibreOffice.** The numbering font joins + the line it labels there; our marker is out of flow and CSS gives an outside `::marker` + no metric influence either (probed: its `font-family` changes nothing, its `font-size` + grows the line above the baseline where LibreOffice grows it below). The summary + fixture's bullet pages drift ~1mm by their last line — that is all its `position` + reports are. +- **A formula page cannot be compared.** LibreOffice draws each formula from its own OLE + frame; we typeset MathML, so `pdftotext` and `getClientRects` measure two different + typesettings and the harness splits a row whose glyph boxes disagree. Honouring the + frame's `style:vertical-pos` on a formula was tried and **reverted** — every inline + formula sank ~1mm and the Math Guide went from 100 to 125 issues (CHANGELOG). - **Page geometry is document-wide.** Headers and footers are per section (each is editable in place), but margins, orientation and format are not: they come from the master page governing the most body blocks (`import/odt.ts`), so a title page with its