Avalonia.Controls.Documents.Serialization.Rtf
12.2.1
Prefix Reserved
See the version list below for details.
dotnet add package Avalonia.Controls.Documents.Serialization.Rtf --version 12.2.1
NuGet\Install-Package Avalonia.Controls.Documents.Serialization.Rtf -Version 12.2.1
<PackageReference Include="Avalonia.Controls.Documents.Serialization.Rtf" Version="12.2.1" />
<PackageVersion Include="Avalonia.Controls.Documents.Serialization.Rtf" Version="12.2.1" />
<PackageReference Include="Avalonia.Controls.Documents.Serialization.Rtf" />
paket add Avalonia.Controls.Documents.Serialization.Rtf --version 12.2.1
#r "nuget: Avalonia.Controls.Documents.Serialization.Rtf, 12.2.1"
#:package Avalonia.Controls.Documents.Serialization.Rtf@12.2.1
#addin nuget:?package=Avalonia.Controls.Documents.Serialization.Rtf&version=12.2.1
#tool nuget:?package=Avalonia.Controls.Documents.Serialization.Rtf&version=12.2.1
Avalonia.Controls.Documents.Rtf
RTF serialization support for Avalonia.Controls.Documents. Enables reading and writing FlowDocument content in RTF format using a streaming tokenizer.
Features
- Import RTF files into a FlowDocument
- Export FlowDocument content to RTF format
- Streaming tokenizer for low-allocation parsing
- Implements the
IDocumentSerializerinterface
Quick Start
// Read an RTF file
var serializer = new RtfSerializer();
var document = serializer.Deserialize(stream);
// Write an RTF file
serializer.Serialize(document, outputStream);
Dependencies
Avalonia.Controls.Documents
Documentation
See the documentation for more details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Avalonia.Controls.Documents (>= 12.2.1)
- AvaloniaUI.Licensing (>= 3.1.1)
-
net8.0
- Avalonia.Controls.Documents (>= 12.2.1)
- AvaloniaUI.Licensing (>= 3.1.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Avalonia.Controls.Documents.Serialization.Rtf:
| Package | Downloads |
|---|---|
|
Avalonia.Controls.RichTextEditor
Interactive rich text editor control for Avalonia with selection, formatting, and undo/redo support |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 13.0.0-rc2 | 134 | 9/10/2026 |
| 12.3.1 | 6,659 | 10/8/2026 |
| 12.3.0 | 3,960 | 9/11/2026 |
| 12.2.3 | 14,122 | 8/20/2026 |
| 12.2.2 | 3,765 | 7/31/2026 |
| 12.2.1 | 197 | 7/29/2026 |
| 12.2.0 | 5,273 | 7/23/2026 |
| 12.1.5 | 1,455 | 6/29/2026 |
| 12.1.4 | 8,396 | 6/22/2026 |
| 12.1.3 | 232 | 6/9/2026 |
| 12.1.2 | 188 | 6/2/2026 |
| 12.1.1 | 439 | 5/14/2026 |
| 12.1.0 | 529 | 5/12/2026 |
## 12.2.0
### Features
- Inline image round-trip: reads `{\pict}` and Word's `{\*\shppict{\pict}}` (skipping the `\nonshppict` duplicate) and writes PNG/JPEG `{\pict\pngblip|jpegblip}` with hex payloads. `ImageRtfMetadata` preserves the original blip word and dimension control words. Honors `DocumentSerializerOptions.MaxImageBytes`. Vector/metafile blips and floating `{\shp}` images are not read.
### Fixes
- Table cells now keep their inset on every edge. Word writes the cell padding once per row as `\trpaddl` / `\trpaddt` / `\trpaddr` / `\trpaddb` instead of repeating `\clpad*` on each cell, and those were not read at all - the inset fell through to `\trgaph`, which only ever fed the left edge, so right-aligned text sat flush against the right border and bottom-aligned text against the bottom one. Row padding is now honoured as the default for cells that declare no `\clpad*` of their own, and `\trgaph` is no longer added on top of it (Word emits both to describe the same inset, so adding them doubled the left padding).
- Per-cell table formatting now lands on the cell it belongs to. The count of cells emitted so far was kept in the group-scoped parsing state, and Word writes every run and every `\cell` marker inside its own group (`{\rtlch ... \cell }`), so closing that group rolled the count back and every cell in the row read the *first* cell's row-definition entry. A cell background (`\clcbpat`) therefore never appeared unless it was on the leading cell, and per-cell borders (`\clbrdr*`) were smeared across the row. Tables written without those per-run groups were unaffected, which is why the same document imported correctly from DOCX.
- Table row heights are now applied. `\trrh` was parsed for round-tripping but never reached the model, so every row collapsed to the height of its content. It now sets the row's minimum height; a negative value (Word's "exact height" rule) is applied as a minimum too, so content taller than the declared height is not clipped.
- Cell vertical alignment is now imported and written. `\clvertalc` and `\clvertalb` map to `TableCell.VerticalAlignment`, matching what the DOCX reader does with `w:vAlign`; `\clvertalt` is the default and carries nothing. The writer emits them back, and it now also falls back to the row's model height when a row carries no RTF round-trip metadata.
- Empty paragraphs now survive a save and reload, together with their paragraph-mark character formatting. The writer terminates a trailing paragraph with `\par` (Word's one-`\par`-per-paragraph convention; not emitted after a trailing table or list) and emits an empty paragraph's character formatting before its `\par`; the reader materializes an empty paragraph for every `\par` that follows a paragraph boundary with no content in between, restoring the active character formatting onto it. A document whose only paragraph is empty previously came back with no blocks at all, so the formatting the editor keeps on an emptied paragraph was lost across save/load. Importing gains fidelity too: blank lines in Word files (`\par\par` sequences) were silently collapsed and now survive. Word interop is preserved: content followed by a single `\par` stays one paragraph, and a `\par` that closes a table, list, or section boundary remains a separator.
- Embedded OLE objects no longer import as text. The reader skips object groups (`\object` with its `\objdata` binary and `\result` fallback) instead of accumulating their hex-encoded blob as document text: a single embedded object is megabytes of hex, which otherwise floods the text buffer and bloats the document. Skipping the group also covers producers that omit the `\*` ignorable marker on `\objdata`. Objects are dropped for now; the surrounding text and paragraph structure are preserved.
- Merged table cells and a shared column grid are now imported. The table's columns come from the union of every row's `\cellx` boundaries instead of each row overwriting them, so a merged row (fewer, wider cells) no longer misaligns the grid or drops a column. A cell wider than the union grid becomes `TableCell.ColumnSpan`, and a vertical merge (`\clvmgf` on the first cell, `\clvmrg` on the cells below) becomes `TableCell.RowSpan` with the continuation cells folded into the cell above. Spans are matched to cells by grid position, so if a document emits a different number of cells than its boundaries describe, the corrected columns are still applied but the spans are skipped rather than landing on the wrong cell. Saving is now covered too: a column span writes one wide `\cellx` and a vertical merge writes `\clvmgf` on the start cell plus the `\clvmrg` continuation cells for the rows below, so a merged table round-trips through a save. Verified on the real customer file: its 7-column table with a column merge and a row merge saves and reloads with the same structure.
- A table row now imports one cell per `\cell` terminator, fixing two ways Word-authored tables came out with the wrong cell count (which then misaligned the columns and any merges). An empty cell (no text between two `\cell` markers) is no longer dropped, and the row-terminator paragraph Word writes after the last `\cell` (a `\pard\intbl`, with the `\trowd` block repeated before `\row`) no longer becomes a phantom trailing cell.
- List indentation is now imported onto the `List` rather than each item. Each numbering level's `\li` becomes the list's content padding (as the per-level delta from the parent level) and its hanging `\fi` becomes `List.MarkerOffset`, so nested lists step by the real `\li` (matching Word) and the marker hangs back instead of collapsing to the computed column. The item keeps its own `\li`/`\fi` measurements, so exact round-trips are unaffected, and an explicit `{\*\acdlistpad}` padding marker still wins over the derived indent.