Files
wordcraft/docs/layout-parity.md
T
Valentin KleinandClaude Opus 5.5 bd10795306 Free rotation and flips for pictures, shapes and text boxes (#332) (#340)
Drawings carry an angle and horizontal/vertical flips on their placement
(Float::rot, flip_h, flip_v), read and written as DrawingML a:xfrm rot,
flipH and flipV for pictures, shapes, text boxes and groups; the written
effect extent covers the rotated bounds and reading takes that overhang
back out. Layout draws them turned about their centre (screen and PDF),
square wrap and inline lines keep clear of the rotated bounds, and hit
testing follows the turned shape. arrange.rotate now turns the frame
(90 degrees, flips) instead of rewriting pixels; arrange.rotation sets an
exact angle. The canvas frame has a rotation handle (Shift snaps to 15
degrees) and turned frames resize along their own axes; Picture Format
and Shape Format get a Rotation box and a Rotate menu. Text inside a
rotated text box stays upright for now.

Groups turn and flip as a whole (wpg:grpSpPr a:xfrm): members keep their
own turn inside the group's, are carried round its centre, and a group's
text boxes move with it. Shape effects are drawn inside the turn; a
shadow's direction follows DrawingML rotWithShape (kept on the model,
true when absent; Word's presets write 0, so their shadows keep their
page direction).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 17:10:09 -04:00

6.7 KiB
Raw Blame History

Layout and pagination parity with Microsoft Word

Last reviewed: 2026-10-10 · Last updated: 2026-10-10 · Change: major (first version; line breaking, pagination and object placement checked against Word's behaviour from the layout source on origin/main) · Target: Microsoft Word (Microsoft 365) for Mac 16.113.4

A document only "opens correctly" if its pages break where Word breaks them: the same lines, the same page count, footnotes and pictures on the same pages. This checklist covers line breaking, pagination and object placement in crates/layout. Typing behaviour is in typing-parity.md; the reading and writing of the properties is in file-format-parity.md.

Dimension: ~55% (estimated), 90–145 h to full (the sum of the rows below). The engine implements most of Word's layout rules, but nothing has been compared page-for-page with Word on real documents, and the default font can't match Word's metrics.

Checklist

✅ matches Word as far as our tests show · 🟡 implemented, differs or untested against Word · ❌ missing

Feature State Evidence / gap Hours
Line breaking (UAX #14 with Word's exceptions: no break after /) ✅ layout::tests::no_line_break_right_after_a_slash —
Justification, Word 2013+ space shrinking (compat mode 15) ✅ #109 —
Kashida justification (Arabic) ❌ no kashida in crates/layout 3–5
Distributed / Thai distributed alignment 🟡 read; layout untested 1–2
Default font metrics (Aptos, Calibri, Cambria…) 🟡 Carlito/Caladea/Liberation are metric-compatible for Calibri/Cambria/Arial/Times/Courier; Aptos (Word's default since 2024) has no metric-compatible open substitute, so new Word documents wrap differently (typing-parity.md Known gaps). Needs an owner decision (commission or license a metric-matched font) 6–10 + owner
Line spacing (single, 1.5, double, at least, exactly, multiple), spacing before/after, contextual spacing 🟡 Word puts multiple-spacing extra below the text and collapses spacing differently (#135, #108 open) 3–5
Widow/orphan control, keep with next, keep lines together, page break before ✅ lib.rs keep_next/keep_lines —
Tabs (left, center, right, decimal, bar), leaders 🟡 Bar tabs untested 1–2
Hyphenation (automatic, 0.25" zone, soft hyphens, consecutive limit) 🟡 English patterns only; other languages hyphenate wrongly or not at all in localization
Drop caps ✅ 2026-10-06 —
Columns, column breaks, separators 🟡 Columns don't balance at a continuous section break or document end 4–6
Section breaks (next page, continuous, even, odd), different first page, odd/even headers ✅ Section breaks don't show in Draft view (#42) 1–2
Body top below a tall header, footer pushes body up ✅ #138 —
Footnotes at the page bottom, endnotes at the end, note numbering 🟡 A long note doesn't continue onto the next page; no continuation separator/notice; per-section restart partial 4–6
Tables: row heights (at least/exact), rows split across pages, header rows repeat, Can't Split ✅ 2026-10-06, #138 —
Tables: autofit to contents/window, fixed widths, Word 2013 edge 🟡 #137; #44: AutoFit Contents measures each column's narrowest and widest text and shares the width like Word, once (not live as you type); cell preferred widths and spans still differ 3–5
Floating tables (w:tblpPr) 🟡 #137; overlap rules untested 2–3
Nested tables 🟡 render; polish missing 2–4
Floating pictures/shapes placement (relative to page/margin/column/paragraph/line/character) ✅ #136 —
Text wrap: square, top-and-bottom, behind, in front ✅ 2026-10-06 —
Text wrap: tight, through (contour, wrap polygon) ❌ laid out as square 6–10
Text boxes, overflow, linked text boxes 🟡 #46; linked text boxes missing 3–5
Rotated objects and text 🟡 #332: pictures, shapes, charts and groups drawn turned and flipped about their centre (screen and PDF); square wrap and inline lines keep clear of the rotated bounds; hit testing on the turned shape. Text in a rotated text box stays upright 2–3
Page borders (from page edge or text), page colour, watermark ✅ —
Line numbers (restart per page/section, count by) ✅ —
Vertical page alignment ✅ —
Gutter, mirror margins, book fold, 2 pages per sheet 🟡 gutter and mirror margins; book fold missing 2–3
Document grid (w:docGrid, lines per page, characters per line) ❌ East Asian documents paginate differently without it 4–6
Vertical text (tbRl) in sections and text boxes; cell text direction 🟡 cell text direction landed (#245); page-level and text-box vertical text missing 8–12
Ruby / phonetic guide, enclose characters, combined characters ❌ 4–6
Bidirectional paragraphs, mixed-direction lines 🟡 #207; RTL sections and tables (w:bidiVisual) missing 4–6
Equations: display layout, numbering, wrapping long display equations ✅ #191; long display equations break at top-level operators (m:brkBin, m:brkBinSub), manual breaks and m:alnAt, continuation lines indented by m:wrapIndent or set right (m:wrapRight) (#326) —
Hidden text excluded from breaking and hyphenation ✅ #173 —
Fields: PAGE, NUMPAGES, SECTIONPAGES, TOC page numbers ✅ #52 —
Compatibility modes (Word 2003/2007/2010 layout for old files: w:compat options) 🟡 mode 15 behaviour; the ~60 legacy compat options are mostly ignored 10–20
Page-by-page comparison harness against Word ❌ Run Word locally on our own synthetic documents, export PDF, compare line breaks; Word output stays under plan/ (never committed) 8–12

Performance

Measure WordCraft Word Kind
Cold layout, 188-page document 61 ms not measured measured 2026-10-06 (not re-run this pass)
Relayout after an edit 1.4 ms not measured measured 2026-10-06
Font picker with many installed fonts fixed freezes (#233) instant issue #31, #59
Large real-world documents (500+ pages, many pictures) not measured gap

Revision history

Date Change Summary
2026-10-10 trivial Rotated and flipped objects laid out and drawn (#332)
2026-10-10 trivial Long display equations wrap across lines (#326)
2026-10-10 trivial AutoFit Contents measures the text (#44)
2026-10-10 major First version: layout and pagination checklist with evidence from crates/layout, PRs and issues