Native Stack & Licensing
FolioPDF bundles three native engines — Skia, PDFium, and qpdf — with zero managed runtime dependencies. This page documents the versions, licenses, and customizations applied to each component.
Architecture Overview
Every FolioPDF API routes to exactly one of three native backends:
| Engine | Binary | Role |
|---|---|---|
| Skia | FolioSkia.dll / libFolioSkia.so |
Renders new PDFs from layout code, encodes images (PNG/JPEG/WebP), HarfBuzz text shaping |
| qpdf | qpdf30.dll / libqpdf.so.30 |
Restructures existing PDFs: encrypt, decrypt, merge, split, linearize, overlay, attach files, edit metadata |
| PDFium | FolioPdfium.dll / libFolioPdfium.so |
Parses existing PDFs: text extraction, page rendering, form fields, signing, redaction, image extraction |
One-line mental model: Skia writes pixels. qpdf restructures objects. PDFium parses content.
Component Versions
Linked into FolioSkia
| Component | Version | License | Role |
|---|---|---|---|
| Skia | m147 (Chrome 147) | BSD-3-Clause | 2D rendering engine, PDF generation backend |
| HarfBuzz | bundled with Skia m147 | MIT | OpenType text shaping for complex scripts |
| libgrapheme | 3.0.0 (Unicode 17.0.0) | ISC | Grapheme/word/line segmentation (replaces ICU) |
| icu_bidi | bundled with Skia m147 | Unicode-DFS-2016 | Bidirectional text reordering (Arabic/Hebrew) |
| FreeType | bundled with Skia m147 | FTL (BSD-style) | Font rasterization |
| libpng | bundled with Skia m147 | libpng-2.0 | PNG encode/decode |
| libjpeg-turbo | bundled with Skia m147 | BSD-3-Clause + IJG | JPEG encode/decode |
| libwebp | bundled with Skia m147 | BSD-3-Clause | WebP encode/decode |
| wuffs | bundled with Skia m147 | MIT | Safe image codec wrappers |
| expat | bundled with Skia m147 | MIT | XML parsing (SVG module) |
| zlib | bundled with Skia m147 | Zlib | DEFLATE compression |
Linked into qpdf
| Component | Version | License | Role |
|---|---|---|---|
| qpdf | 12.3.2 (ABI 30) | Apache-2.0 | PDF object manipulation engine |
| OpenSSL | 3.x | Apache-2.0 | AES-256 encryption, CMS signing |
| libjpeg-turbo | bundled with qpdf | BSD-3-Clause + IJG | JPEG codec for qpdf streams |
| zlib | bundled with qpdf | Zlib | DEFLATE for qpdf streams |
Linked into FolioPdfium
| Component | Version | License | Role |
|---|---|---|---|
| PDFium | chromium/7690 (m147 era) | BSD-3-Clause | PDF parsing, AGG rendering, text extraction, form access |
| AGG | bundled with PDFium | BSD-3-Clause | Anti-aliased 2D rasteriser for page-to-bitmap |
| OpenJPEG | bundled with PDFium | BSD-2-Clause | JPEG 2000 decoder |
| lcms2 | bundled with PDFium | MIT | ICC color management |
| libtiff | bundled with PDFium | libtiff (BSD-style) | TIFF image decoding |
| abseil-cpp | bundled with PDFium | Apache-2.0 | C++ utility library |
Downstream Customizations
Note: All native components are permissively licensed (BSD, MIT, Apache-2.0, ISC, Zlib, FTL). None are GPL/LGPL/MPL. The combined binaries can be redistributed under a proprietary license.
qpdf Extensions
FolioPDF carries a small downstream patch on qpdf 12.3.2 that adds two features required for ZUGFeRD / Factur-X / PDF/A-3 compliance:
extendMetadata— a top-level JSON job key that appends RDF/XMP fragments to the document's/Metadatastream. Used byPdfEditor.ExtendXmpMetadata()andDocumentOperation.ExtendMetadata()to inject Factur-X namespace declarations, PDF/UA identification, and Dublin Core fields without replacing the entire XMP packet.addAttachment.relationship— a sub-key underadd-attachmentthat sets the PDF/A-3/AFRelationshipentry on the file specification dictionary and adds the file spec to the document-level/AFarray. Required for Factur-X/ZUGFeRD compliance where the CII XML must declare/AFRelationship /Alternative.
The patch is applied automatically by the build scripts before compilation. When bumping the qpdf version, the patch is re-validated against the new source — git apply will fail loudly if anything conflicts.
PDFium Extensions
FolioPDF carries one downstream patch on PDFium chromium/7690:
- Redaction annotation support — adds
FPDF_ANNOT_REDACTto the allowlist inFPDFAnnot_IsSupportedSubtype(), enabling the standard two-phase redaction workflow (create REDACT annotations, then flatten the page). The internal PDFium machinery already supports REDACT — only the public API allowlist was missing the entry.
FolioPDF also includes custom C++ extensions compiled into libFolioPdfium:
- Bookmark editing —
FPDFBookmark_Add,FPDFBookmark_Delete,FPDFBookmark_Move,FPDFBookmark_SetTitle,FPDFBookmark_SetDestfor programmatic bookmark/outline tree manipulation. - Metadata editing —
FPDFInfo_SetMetaTextfor writing/Infodictionary entries (Title, Author, Subject, etc.) directly via PDFium internals. - CMS signing — PKCS#7 detached signature orchestrator using OpenSSL's
PKCS7_signagainst thelibcryptoalready shipped with qpdf, enabling digital signing without adding any managed dependencies. - CMS verification —
PKCS7_verifywrapper for cryptographic signature validation, also routed through the bundledlibcrypto.
Skia Configuration
FolioSkia is a custom C++ wrapper around Google Skia m147 built with specific configuration flags:
skia_use_freetype=true— FreeType for font rasterization (no system font dependencies)skia_pdf_subset_harfbuzz=true— HarfBuzz subset for PDF text shapingskia_use_libgrapheme=true— libgrapheme instead of full ICU (eliminates the 27 MBicudtl.datdata file)- No SkiaSharp — FolioPDF owns the full native interop via P/Invoke bindings
Platform Binaries
Windows x64
| File | Component |
|---|---|
FolioSkia.dll | Skia + HarfBuzz + FreeType + libgrapheme + image codecs |
FolioPdfium.dll | PDFium + AGG + OpenJPEG + lcms2 + signing extensions |
qpdf30.dll | qpdf 12.3.2 with FolioPDF patches |
jpeg62.dll | libjpeg-turbo (qpdf dependency) |
libcrypto-3-x64.dll | OpenSSL 3.x cryptographic primitives |
libssl-3-x64.dll | OpenSSL 3.x TLS (transitive, not used at runtime) |
zlib1.dll | zlib (qpdf dependency) |
Linux x64
| File | Component |
|---|---|
libFolioSkia.so | Skia + HarfBuzz + FreeType + libgrapheme + image codecs |
libFolioPdfium.so | PDFium + AGG + OpenJPEG + lcms2 + signing extensions |
libqpdf.so.30 | qpdf 12.3.2 with FolioPDF patches |
libjpeg.so.62 | libjpeg-turbo (bundled, RPATH=$ORIGIN) |
libcrypto.so.3 | OpenSSL 3.x (bundled, RPATH=$ORIGIN) |
libz.so.1 | zlib (bundled, RPATH=$ORIGIN) |
Linux bundling: All transitive .so dependencies are bundled alongside libqpdf.so.30 with RPATH=$ORIGIN so they load from the same directory at runtime. This eliminates the need for system-installed libjpeg-turbo, OpenSSL, or zlib — the NuGet package is self-contained.
Acknowledgements
FolioPDF is built on the work of these open-source projects and their contributors:
- Skia by Google — the 2D rendering engine that powers Chrome, Android, and Flutter. BSD-3-Clause license.
- qpdf by Jay Berkenbilt — the PDF transformation library used for encryption, linearization, merging, and metadata. Apache-2.0 license. FolioPDF extends qpdf with
extendMetadataandaddAttachment.relationshipfor PDF/A-3 and ZUGFeRD compliance. - PDFium by the Chromium Authors — the PDF parser and renderer used for text extraction, form access, signing, and page rasterization. BSD-3-Clause license. FolioPDF extends PDFium with bookmark editing, metadata editing, and CMS signing support.
- HarfBuzz by Behdad Esfahbod and contributors — the OpenType text shaping engine. MIT license.
- OpenSSL by the OpenSSL Project — cryptographic primitives for AES encryption and PKCS#7 signing. Apache-2.0 license.
- FreeType by David Turner, Robert Wilhelm, and Werner Lemberg — font rasterization. FreeType License (BSD-style).
- Lato by Lukasz Dziedzic (tyPoland) — the default font family bundled with FolioPDF. SIL Open Font License 1.1.
- Inter by Rasmus Andersson — the secondary font family bundled with FolioPDF. SIL Open Font License 1.1.
Full license texts for all bundled components are included in THIRD-PARTY-NOTICES.md inside the NuGet package.