Avalonia.Controls.Documents.Serialization.Pdf 12.3.0

Prefix Reserved
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Avalonia.Controls.Documents.Serialization.Pdf --version 12.3.0
                    
NuGet\Install-Package Avalonia.Controls.Documents.Serialization.Pdf -Version 12.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Avalonia.Controls.Documents.Serialization.Pdf" Version="12.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Avalonia.Controls.Documents.Serialization.Pdf" Version="12.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Avalonia.Controls.Documents.Serialization.Pdf" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Avalonia.Controls.Documents.Serialization.Pdf --version 12.3.0
                    
#r "nuget: Avalonia.Controls.Documents.Serialization.Pdf, 12.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Avalonia.Controls.Documents.Serialization.Pdf@12.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Avalonia.Controls.Documents.Serialization.Pdf&version=12.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Avalonia.Controls.Documents.Serialization.Pdf&version=12.3.0
                    
Install as a Cake Tool

Avalonia.Controls.Documents.Pdf

Write-only PDF export for Avalonia.Controls.Documents. Paginates FlowDocument content and emits vector PDF with embedded fonts.

Features

  • Export FlowDocument content to PDF via the IDocumentSerializer interface
  • Write-only: PDF import is not supported by design
  • UI-free pipeline: serialization runs on background threads without controls or a dispatcher
  • Text laid out with the same engine as the editor; fonts embedded as Type0 with ToUnicode maps, or written as WinAnsi-encoded simple fonts when the program cannot travel with the file
  • Lists, tables (including merged cells), inline images, and hyperlink annotations
  • Page size and margins from the document (PageWidth, PageHeight, PagePadding) or PdfSerializerOptions
  • Deterministic output mode for reproducible pipelines and tests
  • PdfSerializerOptions.Diagnostics reports every fidelity loss the export accepted

Quick Start

using var stream = File.Create("document.pdf");
document.Save(stream, new PdfSerializer());

Limitations

  • Font subsetting is not implemented; PdfFontEmbedding.Subset currently behaves like Full
  • A face whose licence forbids embedding, a TrueType collection (.ttc), and PdfFontEmbedding.None all write the font without its program; viewers substitute a local face, so the letterforms are not the document's
  • Color-font glyphs render as monochrome outlines; variable fonts render their default instance
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
13.0.0-rc2 54 9/10/2026
12.3.0 50 9/11/2026

## 12.3.0

Adds to 12.2.3 and removes nothing: every type and member a 12.2.3 build could reference is still there with the same signature, checked against the released packages on every build.

### Features
- Footnote numbers render like the view's containers: the number in the document's `FootnoteNumberFormat`, in the note's first run's font and color at the superscript scale with tabular figures, its ink a quarter em before the content at the top of the note's first line, inside one number strip every note shares, at least 1.5 em of the document's root font and wide enough for the last ordinal. The strip was a fixed 24 device-independent pixels before.
- Per-section page setup: a `Section` declaring `PageWidth`/`PageHeight`/`PagePadding` gets its own pages - the section starts on a fresh page (entering and leaving are section-break edges, which also sever keep-with-next chains like explicit breaks), its content composes and wraps at ITS content width, its pages fill against ITS content height, and each PDF page carries its own MediaBox and margins (a landscape section between portrait pages emits a landscape page). Unset values inherit the document's; explicit `PdfSerializerOptions.PageSize`/`Margins` remain the uniform-paper override. The paged screen view breaks the same document on identical boundaries.
- Footnotes render as a per-page notes region, Word-style: each `Footnote` body composes once at the content width and draws at the bottom of the page whose content carries its anchor, below a short separator rule and with its number as marker chrome in the note's padding strip. The anchor's line reserves its notes' heights against the page band (one separator per page with notes), so a line that no longer fits the reduced band pushes to the next page together with its notes - the reserve uses the same separator constant and fit rule as the paged screen view, and both engines break anchored documents on identical boundaries. Hyperlinks inside note bodies keep their annotations; an anchor without a matching note body reserves nothing.
- Page bands render on every page: each page shows the header and footer `PageBandPolicy` resolves for its section and position (the section of the page's first line; its first-page reference on its first page, else the document's first-page band on page one, else its even band on even pages, else the section's running reference, else the document's default band), composed once per content width from the band's nested snapshot and emitted in the margin areas one band distance from the sheet edge, clipped to the margin. A band with page-number fields composes per page, so PAGE and NUMPAGES show the page's numbers. Previously bands were skipped entirely.
- Page bands push the body like in the paged view: a band that outgrows its margin grows the page's body inset to the band distance plus the band's height, the paginator fills the reduced height (`LayoutPaginator.Paginate` takes a per-page inset resolver, `PdfPageBands.ResolveInsets`), and the band emits unclipped inside the inset; a band with page-count fields paginates again until the page count is stable. Link annotations use the page's own paper and inset.
- Keep rules are honored in pagination: `Block.KeepTogether`, `Block.KeepWithNext` (chains of flagged blocks move as one, giving up when the chain exceeds a page), and `Paragraph.WidowControl` (on by default - at least two lines on each side of a break, so three-line paragraphs never split). The cut decisions come from the same policy the paged screen view consults, keeping print output identical to print layout. Since widow control defaults on, page breaks of existing exports can move by a line.
- `PdfSerializer`: write-only `IDocumentSerializer` that paginates FlowDocument content and emits vector PDF 1.7. The pipeline is UI-free (no controls, no dispatcher) and runs on any thread once an Avalonia platform (font manager + text shaper) is initialized.
- Text: paragraphs laid out with the same `TextLayout` engine as the editor (line breaking, wrapping, alignment, line height, letter spacing, bidi, font fallback); glyph-exact output via `Tf`/`Tm`/`TJ` with kerning adjustments and glyph offsets; underline/strikethrough/overline; run and block backgrounds; faux bold/oblique emulation for simulated faces.
- Fonts: an embedded typeface becomes one Type0 font with full-file embedding (`FontFile2`, or `FontFile3`/OpenType for CFF), `W` widths and a `ToUnicode` CMap. A typeface whose program stays out of the file - `PdfFontEmbedding.None`, an `OS/2` fsType that forbids embedding, a TrueType collection, or a face with no readable stream - becomes a simple font instead: single-byte character codes over `WinAnsiEncoding` with a `Differences` array for anything outside it, its own `Widths` array and a one-byte `ToUnicode` CMap, so the substituted face renders and copies out the document's text. The fsType gate tests each licence bit on its own, so a font restricted to bitmap embedding (bit 9) or one pairing the restricted-licence bit with another usage bit is refused. Subsetting is not supported yet (`PdfFontEmbedding.Subset` behaves like `Full`). Color fonts embed but render as monochrome outlines in viewers; variable fonts render their default instance.
- `PdfSerializerOptions.Diagnostics`: an optional callback receiving one `PdfDiagnostic` per fidelity loss the export accepted rather than failed on - a font left unembedded and the reason, a color or variable font no viewer can reproduce. Export raises nothing without a sink, so the checks cost nothing when unused.
- Blocks: lists (bullet shapes and numbered markers with the editor's shared marker column), tables (Pixel/Auto/Star columns, merged cells, vertical alignment, row-group/row/cell backgrounds, interior gridlines), sections, images (JPEG passthrough, everything else re-encoded with an alpha SMask), hyperlink annotations.
- Pagination: page size and margins from options, the document (`PageWidth`/`PageHeight`/`PagePadding`), or A4/2 cm defaults; lines never split; table rows paginate atomically by their row box (a pushed row lands on the next page with its cell padding intact, and rows covered by a row-spanning cell move together with their anchor row, so merged cells are never sliced); explicit page breaks honored via the new `Block.BreakPageBefore`/`BlockFormatting.PageBreakBefore`.
- A `PdfSerializerOptions.PageSize` that is not finite and positive on both axes is rejected before any byte reaches the target stream, instead of writing `/MediaBox [0 0 NaN NaN]` into a file no viewer opens. A non-finite or negative `Margins` component falls back to the 2 cm default on a section's pages as well as the document's.
- `PdfSerializerOptions`: page geometry, font embedding mode, document metadata (`Title`/`Author`/`Subject`/`Keywords`/`Language`), and a deterministic mode (fixed creation date and file id) for byte-stable output.
- Layout parity with the on-screen editor is enforced by tests that compare the export engine against the headless view line-for-line.

### Fixes
- The export paginated against the default page-band distance whatever the document declared, so a header or footer at any other distance broke pages where the screen and print did not - about two lines per A4 page at a one-inch distance. It reads `DocumentFormatting.PageBandDistance` now.