Graded by construct, not by feature list.
The table below grades every construct family at the level the code actually
reaches. The page counts are a manual LibreOffice-oracle measurement
recorded in
docs/60
on 2026-07-27, not a CI gate: the automated geometry gate
(oracle_geometry.rs) is written but inert until its reference
is blessed, and no pixel-diff gate exists yet. Treat these as dated evidence,
not a live build signal.
Page counts are this engine's output against a LibreOffice oracle on the
five-document review corpus, measured by hand and recorded in
docs/60
on 2026-07-27; they have not been re-measured since. The documents are not
redistributable, so only the measurements are published.
tools/opendoc-fidelity now also compares page geometry against a
LibreOffice reference and reports differences as measurements; it still produces
no images, and it is a proxy, not Word. These are dated evidence, not a
Word-grade claim.
Support by construct family
The oracle numbers above summarize whole documents; this is the granular breakdown behind them. Support is tracked per DOCX construct family across four stages — modeled, rendered, editable, and round-trips on export. A construct can be fully modeled and round-tripped while still not being editable or fully painted yet, and this table never claims support a stage does not actually have.
How to read a cell
- Full — implemented and exercised by tests.
- Partial — common cases work; documented gaps remain.
- Placeholder — a visible stand-in, not the real content (e.g. undecodable images, EMF/WMF, math,
w:altChunk). - Preserved, not rendered — kept losslessly for export (the retention floor) but not painted.
- Not yet — not implemented.
| Construct family | Modeled | Rendered | Editable | Round-trips |
|---|
Notes, placeholders, and explicit non-support
- Editing is a developer test harness, not a product. The Editable column reflects what the current in-browser editor can actually change today, not a supported product surface.
- Every editable surface takes every editing operation. Body, header, footer, footnote/endnote body, text box, and a box inside a shape group each accept typing, selection, character and paragraph formatting, cut/copy/paste, find and replace, comments, and tracked changes. This is pinned by an operation × surface matrix in CI, not by sampling.
- Not authorable yet: shape rotation and flip (they render and round-trip, but there is no handle or control to set them), custom shape geometry, replacing an existing picture's bytes in place, text-box body properties (internal margins, vertical anchor, autofit), inserting or splitting a section, creating or updating a named style, and part of a chart's formatting — its data, type, title, legend, data labels, axes, gridlines and palette are authorable, but an individual series' colour, number formats, axis titles and combination charts are not.
- Math (OMML) is fully typed and round-trips; the common constructs typeset inline. Box/border-box rules and full Word-parity math typesetting are partial, and math is not editable — there is no equation editor.
- Charts and SmartArt are not the same story any more. Six classic chart families — bar/column, line, area, pie, doughnut and scatter — are typed, painted as live charts, and written back as a real chart part; every other family (every 3-D variant, surface, stock, radar, bubble and pie-of-pie, and the newer chartex set) declines projection and keeps a text placeholder over byte-preserved bytes. SmartArt is a preserved reference only: nothing under
word/diagramsis parsed, so there is no typed diagram to paint (⊟). No preview bitmap is ever used for either — the importer passes none, and Word writes none for a classic chart part. - Non-PNG/JPEG images (EMF/WMF, SVG on the browser build), undecodable images, and
w:altChunkpaint a visible placeholder that reserves layout space, so nothing silently vanishes (▢). - Color fonts and color emoji render. The CPU rasterizer tries bitmap strikes (
sbix,CBDT) and thenCOLRv0/v1 paint graphs with the defaultCPALpalette before falling back to monochrome outlines. Gradient and clip-heavy COLRv1 graphs are approximated; a face the bundled set does not cover still needs a host-registered font. - Real-text PDF export is available. File → Export as PDF produces a deterministic vector PDF with selectable/searchable text and embedded TrueType subset fonts. Hyperlink annotations, outlines, tagged PDF/PDF-A, page ranges, and live host-font parity remain incomplete; physical printing still uses browser-rendered raster pages. See docs/98.
- Text wrap around floats reserves shared flow for top-and-bottom and square wrapping, including inside table cells, headers and footers. Tight and through contour wrapping, and page-coupled reflow, remain partial.
.docmmacro-enabled files are rejected at open. Strip-and-open versus explicit non-support is an undecided policy question, not an oversight.- Round-trips means a semantic fixed point (import → export → reopen yields an equal model), not a byte-identical file. Byte-exact preservation applies to the retention/no-edit floor.
- Data-loss reporting is partial, not total. The disposition taxonomy is the intended contract and whole unmodeled parts are preserved verbatim. But the DOCX exporter has no reporting path yet, unknown attributes (notably
w:rsid*) are outside the report vocabulary, and the theme, font-table and comment-extension parsers regenerate their parts without reporting. Tracked in docs/105.