Skip to content

The API

npond edited this page Aug 24, 2026 · 1 revision

The API

Eight public types, and that is the whole of what a version promises. Everything else — the OPC reader, the document model, the style cascade, the font engine, the layout engine, the PDF writer — is internal. All of it used to be public, which would have frozen 174 types at the first published version: the shape of a positioned line, the name of a table's border edge, every enum the parser reads. PublicApiTests writes the surface out in full and fails the build on anything that grows it, so adding to the promise is a deliberate act with a diff to show for it.

Converter

The entry point. Static, three overloads:

static byte[] Convert(byte[] docx, ConversionOptions? options = null);
static void   Convert(Stream docx, Stream pdf, ConversionOptions? options = null);
static void   ConvertFile(string docxPath, string pdfPath, ConversionOptions? options = null);

ConvertFile also sets ConversionOptions.FileName for you — it is the one entry point that knows the name a FILENAME field should show.

ConversionOptions

Member Default What it does
Fonts null The FontLibrary for the conversion. Null discovers the platform's installed fonts (read once per process, shared). Supply your own for reproducible output.
Layout new() A LayoutOptions — see below.
Limits new() A PackageLimits bounding what a hostile document may cost — see below and Security.
PdfA false Claim and honour PDF/A-2b: an XMP metadata packet agreeing with the information dictionary, an sRGB output intent, and a file identifier in the trailer. What A-2b demands of the content — embedded subset fonts, no external references, no encryption — is true of every file this writes anyway.
ApplyWordBuiltInStyleDefaults true Fill in what a document's styles leave unstated from Word's built-in definitions, as Word itself does. These sit below docDefaults in precedence — a fallback, not an override. Turn off to render strictly what the document says.
DropFontHinting false Leave hinting (cvt, fpgm, prep and per-glyph instructions) out of embedded subsets — about a quarter of an embedded face's weight. Off because Word keeps it, and matching Word is the point.
Title null Title recorded in the PDF's document information dictionary.
FileName null What a FILENAME field shows. Set automatically by ConvertFile.
FieldsAsOf null The instant DATE and TIME fields report, for a conversion that must come out the same twice. Defaults to CreationDate if given, otherwise now.
CreationDate null Creation timestamp for the PDF. Left null, converting the same document twice produces identical bytes — which is what makes golden comparison possible.
MergeRecord null The record to fill a document's merge fields from. Without one, each field shows its own name in guillemets — which is what Word shows for the same document.

LayoutOptions

Member Default What it does
ApplyKerning true Apply pair kerning where w:kern asks for it, read from a font's GPOS table as well as the legacy kern table (Calibri has only the former, Times New Roman only the latter).
DefaultTabStopTwips 720 The default tab stop interval, in twips (720 = half an inch).

FontLibrary

Member What it does
UseSystemFonts Whether the platform's installed fonts are discovered. Turn off for fully explicit, reproducible libraries.
Register(byte[] data) Register a face from memory.
RegisterFile(string path) Register a face from a file (.ttf, .otf, .ttc supported).
RegisterDirectory(string path, bool recursive = …) Register every face in a directory; returns how many were registered.
RegisteredFamilies The family names registered so far.
RegisteredFaceCount How many faces are registered.
FallbackFamilies The ordered list of families tried when no registered or named face can draw a character.
GetSystemFontDirectories() The platform directories a discovery scan would read.

Registering something that is not a font throws FontFormatException.

MailMergeRecord

Member What it does
.ctor(IEnumerable<KeyValuePair<string,string>>? fields = …) Build a record from field name/value pairs.
Fields The dictionary of merge fields.
Value(string name) Look a field up.
Number, Sequence What MERGEREC and MERGESEQ report.

PackageLimits

Bounds on what a document may cost to read. All are counted against what actually comes out of the decompressor, not what any header claims — see Security.

Member Default Bounds
MaximumPartBytes 128 MB One decompressed part.
MaximumTotalBytes 512 MB Decompressed bytes across the whole package.
MaximumPartCount 4096 Parts in the package.
MaximumImagePixels 50,000,000 The pixel area an image may declare (a 600dpi A4 scan with room to spare), counted in long arithmetic so an overflowing width×height cannot slip under it. An image past the limit is left out like any unreadable image — the document loses the picture, not the conversion.
MaximumFontBytes An embedded face past this is left out and the conversion proceeds in substitutes.

Exceptions

  • PackageTooLargeException — the document decompressed past the limits. Catch it to know that is what happened, and raise the limits for a document that genuinely needs more.
  • FontFormatException — what registering something that is not a font throws.

What is deliberately not public

Layout — the positioned pages before PDF serialisation — is the thing the fidelity suite inspects, and it stays internal. Making it public would freeze the whole layout model: every page, line, run, resolved format and font it reaches, none of which is settled enough to promise. If a caller ever needs something of it, the thing to add is that something.

Clone this wiki locally