Architecture

Broadside's vocabulary lives in CONTEXT.md. This page summarizes it and the design decisions the library is built on; CONTEXT.md is authoritative for the terms.

Vocabulary

Capabilities. Read parses an existing PDF file into the object model, including damaged files. Write produces a new file. Edit modifies an existing file and saves it, preserving everything not touched. Render turns a page into drawing operations on a surface.

Object model. A COS object is one of the primitive values a PDF file is built from, exactly as stored (boolean, number, string, name, array, dictionary, stream, null, indirect reference). The document model is the typed view over COS objects (document, page, font, annotation, form field), and a document-model object is a view over its COS object, never a copy.

Parsing. A diagnostic records one deviation from the specification and what was done about it. Lenient mode, the default, repairs and records; strict mode makes the first deviation an error. A filter is a stream encoding such as FlateDecode or JBIG2Decode and the codec for it; image codecs are filters.

Fonts. A font program is embedded or substituted glyph data (TrueType, OpenType, CFF, Type 1, Type 3). The Standard 14 fonts may be used without embedding. The font resolver finds a font program for a font that is not embedded.

Rendering. The display list is the device-independent, fully resolved sequence of drawing operations every backend consumes. The software rasterizer is the managed reference backend; a native backend draws through a platform API (CoreGraphics, Direct2D, Android Canvas). The SkiaSharp and WebGL 2 backends consume the same display list.

Viewer. A document session is one open document in a viewer: it owns the document, the engine, the options and the tile backends. A tile is a rectangle of one page at one zoom, rendered from the page's cached display list and handed to a surface, which each UI shell implements over its own canvas, image or texture. The tile scheduler decides which tiles are drawn and when, within one memory budget. A remote tile renderer draws tiles outside the viewer's thread; in the browser that is the render worker, a second .NET runtime in a Web Worker.

Text and layout. The structure tree is the tagged-PDF hierarchy stored in the file (ISO 32000-2 ยง14.7). The layout tree is the logical content recovered from a page, from the structure tree when the file is tagged and from geometry when it is not.

Principles. Fully managed means no dependency outside packages Microsoft ships without a native component. An extension point is a contract with a managed default that a consumer can replace. The canonical model is PDF 2.0. Parse-and-preserve is the posture toward out-of-scope features: kept and written back, never executed or rendered. The conformance map is the per-clause implementation record (Conformance).

Decisions

  • Fully managed core, with extension points for every component a consumer may want to substitute.
  • Target net10.0 only.
  • PDF 2.0 is the canonical object model; the written version is raised to what the used features need.
  • Two public layers: COS objects and a document model that is a live view over them.
  • Lenient reading by default, every repair recorded as a diagnostic.
  • Rendering goes through a display list; no backend sees content-stream operators.
  • Standard 14 glyph data ships in a separate package; the core carries only metrics.
  • MIT license; sponsorship is asked for, not enforced.
  • One font resolver interface, asked in order (configured resolvers, then system fonts), serves font programs and named CMap resources.
  • Remote files are read synchronously behind an asynchronous prefetch boundary.
  • Signing goes through one signer interface that signs a digest; the core hashes the byte ranges and encodes the CMS object.
  • The browser viewer gets an optional WebGL 2 backend; the software rasterizer stays the default, and what WebGL cannot draw falls back to it with a diagnostic.
  • Tiles render off the UI thread; in the browser, in an opt-in render worker rather than with .NET WebAssembly threads.