How DocWright works
Every conversion follows the same pipeline. Knowing its stages explains most of DocWright's behaviour: why edits never lose unknown markup, why a PDF and a PNG of the same page always agree, and why a report and a Word document share renderers.
The pipeline
input stream
│ a reader (DOCX, DOC, RTF, HTML, Markdown, text, or your own)
▼
WordDocument ─────────────────────────────▶ a writer ─▶ .docx .html .rtf .md .txt .odt .epub .rdl
(editable, keeps everything it read)
│ style resolution
▼
resolved document (every property concrete, in whole twips)
│ layout: line breaking, tables, floats, pagination
▼
laid-out pages
├──▶ PDF renderer ─▶ .pdf
└──▶ image renderer ─▶ .png / .jpg
- Read. A reader turns bytes into a
WordDocument: the editable model you work with. Anything the model doesn't represent is kept as-is, so a load-and-save loses nothing. - Edit (optional). Editing, mail merge, comparison and composition all change the
WordDocumentand nothing else. - Resolve. Styles, themes, numbering and defaults are flattened into concrete formatting for every paragraph and run.
- Lay out. Text is measured with the real fonts, and lines, tables, floating objects, headers, footers and pages are positioned, the way Word does it.
- Render. The PDF and image renderers draw the same laid-out pages. If they ever disagreed beyond anti-aliasing, one of them would have a bug.
Saving takes a different path: writers read the WordDocument directly, not the resolved or laid-out forms. That's how a saved file keeps the difference between "bold because I set it" and "bold because the style says so".
Where the packages fit
| Layer | Packages |
|---|---|
| The facade | DocWright: DocWrightConverter |
| Readers and writers | Formats.Docx, .Doc, .Html, .Rtf, .Markdown, .Text, .Odt, .Epub, .Rdl, .Pdf |
| The document model | Dom: model, editing, fields, forms, content controls, revisions |
| Layout | Layout: style resolution and page layout |
| Rendering | Renderers.Pdf, Renderers.Imaging |
| Foundations | Core (units, diagnostics, limits, exceptions), Fonts, Ole, Cryptography |
| Capabilities on the model | MailMerge, Compare, Composition, Signatures, ComplexText |
| Reports | Reporting, Reporting.Rdl, Reporting.Viewer, Reporting.Export, Formats.Xlsx |
Reports take a parallel path. A report definition is processed against your data and paginated into a report page model. That model lowers to the same laid-out pages the PDF and image renderers draw. A report never becomes a WordDocument, and its text is measured the way Reporting Services measures it, not the way Word does.
Extension points
| To… | Implement |
|---|---|
| Read or write a new format | IDocumentReader / IDocumentWriter, registered on FormatRegistry. See Add your own formats. |
| Collect warnings | IConversionDiagnostics |
| Shape complex scripts | ITextShaper, or use DocWright.ComplexText |
| Evaluate a custom field | IFieldHandler |
| Feed a mail merge | IMergeDataReader |
| Supply report data | ReportDataProvider |
| Run report code | ReportCodeHost |
| Sign documents | ISignatureProvider, IPdfSignatureProvider |
| Draw laid-out pages yourself | ILayoutRenderer |