Native Linux Cairo renderer

HPDFHeadlessCairoDevice renders a loaded PDF page to an RGB PNG using Cairo image surfaces and FreeType, without a display server or PDF reader

Supply a serial borrowed view from THPDFHeadlessDocument.GetRenderAccess(PageIndex) and keep that document loaded and unchanged until rendering returns

Document := THPDFHeadlessDocument.Create;
try
  Document.LoadFromFile('input.pdf');
  Options := THPDFHeadlessRenderOptions.Default;
  Info := HPDFRenderHeadlessPagePNGFile(
    Document.GetRenderAccess(0), 'page.png', Options);
finally
  Document.Free;
end;

Runtime dependencies

Native Linux uses libcairo.so.2, libfreetype.so.6, and the standard-font provider's Fontconfig dependency; install suitable fonts for Helvetica, Times, and Courier substitution

HOTPDF_CAIRO_LIBRARY and HOTPDF_FREETYPE_LIBRARY can select explicit compatible library paths before the first render; successful modules remain loaded because native font caches may retain destruction callbacks

The host must keep its HotPDF executable, DLL, or package code loaded whilst those native caches can retain HotPDF font-destruction callbacks; unloading a host module independently of the cache lifetime is outside this profile

Windows uses compatible libcairo-2.dll and libfreetype-6.dll through the same bridge; runtime binaries and their licensing are supplied by the application

ICCBased colours additionally load liblcms2.so.2; JPEG uses libturbojpeg.so.0, and JPEG 2000 uses an OpenJPEG 2.5-compatible libopenjp2.so.7; these dependencies are loaded only for corresponding inputs

HOTPDF_LCMS_LIBRARY, HOTPDF_TURBOJPEG_LIBRARY, and HOTPDF_OPENJPEG_LIBRARY override those paths; Windows defaults are lcms2.dll, turbojpeg.dll, and openjp2.dll

Rendering profile

Supported content includes path construction and painting, nonzero and even-odd fill rules, clipping, nested graphics state, CTM transforms, line style, DeviceGray/RGB/CMYK colours, normal alpha, and repeated Form XObjects with their own resources, Matrix, and BBox

Line widths may be zero: PDF hairlines requested by 0 w or ExtGState LW=0 use a one-pixel device-space stroke; negative widths are rejected

ExtGState D and the content-stream d operator share bounded dash validation: solid empty patterns, odd-length repetition, zero-length entries, fractional lengths and signed phases are supported

A dash pattern admits at most 256 finite nonnegative lengths up to 1e9, with at least one positive length when nonempty and a finite phase of absolute value at most 1e9; each element consumes operation work and temporary storage participates in working-byte admission

Operand arrays accept PDF comments, including numeric dash arrays and TJ text arrays; malformed lexical values and missing closing brackets are retained by the shared scanner and rejected by the renderer instead of silently disappearing

Horizontal text uses the shared glyph interpreter for text matrices, explicit PDF widths, canonical Helvetica/Times/Courier advances, character and word spacing, horizontal scale, and TJ adjustments

Embedded supported font programs use FreeType with resolved glyph IDs; Unicode ToUnicode mappings remain available through the document text API, whilst standard-font raster shapes depend on installed substitutes

Composite text supports Identity-H, Identity-V, explicit embedded encoding CMap streams, and built-in UniJIS, UniGB, UniCNS and UniKS UCS2/UTF16 horizontal and vertical mappings; separately installed CMap resources are not required

Vertical glyph painting honours default and explicit DW2/W2 positioning vectors, text rise, horizontal scale, text and graphics matrices, and TJ displacement; UTF-16 mappings accept supplementary character codes

All eight text rendering modes are supported, including vertical fill/stroke/invisible outlines accumulated into the clip at ET; embedded encoding CMap streams retain their WMode and nonidentity CID mappings

Transparent combined fill-and-stroke operations use object knockout compositing so overlapping fill does not leak through the stroke; Type3 glyph procedures execute their own bounded resources and font matrices

Images accept 1/2/4/8/16-bit samples and Decode arrays, stencil, explicit, color-key and soft masks, differently sized masks, and Matte recovery; missing Interpolate uses nearest-neighbour sampling and true selects bilinear sampling

JPX codestreams accept signed or unsigned source components through 26 bits, including mixed precision, subsampling and explicit opacity, and normalise into bounded 8 or 16-bit samples; the image dictionary BitsPerComponent and non-stencil Decode entries are ignored for JPX images as required by the PDF image profile

Indexed palettes and validated ICCBased profile-to-sRGB transforms are supported for images and path colours; DeviceCMYK without a profile retains the simple device conversion

ICCBased transforms accept Gray, RGB, CMYK, Lab and XYZ profile signatures and strictly validate the declared component count and component ranges

Lab profile operands use physical L a b coordinates with default ranges [0 100 -128 127 -128 127]; XYZ operands use physical X Y Z coordinates with a default unsigned 1.15 range [0 65535/32768] per component

XYZ profile inputs are a native compatibility extension and do not imply archival PDF conformance; Lab and XYZ source profiles do not select a supported transparency blending space

An ICC stream's Range requires two finite ordered values per component and bounds colour operands; raw image Decode defaults and Indexed lookup values use those component ranges

CalGray, CalRGB and Lab support paths, text, images and Indexed palette bases; parameters are strictly validated, CalRGB Matrix entries follow PDF column ordering, and Lab components and image Decode defaults use the declared ranges

CIE colours use Bradford chromatic adaptation and relative sRGB output; BlackPoint metadata is validated, whilst additional black-point compensation and rendering-intent state policies remain separate extensions

Separation and DeviceN composite colours retain one through thirty-two tint components for paths, text, Indexed bases and packed images; device or CIE alternate colours use bounded sampled, exponential, stitching or calculator tint functions

ICCBased Lab/XYZ and CalGray/CalRGB/Lab alternate color sources retain their physical coordinates through the tint transform before conversion into a supported transparency group

Multidimensional sampled tint functions support linear and cubic interpolation, Domain, Encode, Decode, output Range and packed sample depths through 32 bits; cubic evaluation extends the existing scalar four-knot convention by tensor products, with linear fallback for short dimensions and bounded work and cancellation

See Native sampled color functions for interpolation conventions and separate formula and reader evidence

Separation None and DeviceN spaces containing only None colorants contribute neither colour nor knockout shape; mixed None components still reach the alternate tint transform

Separation All applies its tint to every available output colorant, using neutral RGB page output and preserving every process component within CMYK groups

CMYK groups receive original four-component alternate tint values before blending; spot separation plates, NChannel process/colorant selection and mixing-hint simulation remain separate extensions

The terminal image callback preserves document decryption and preceding stream filters before native JPEG, JPEG 2000, CCITT or JBIG2 decoding; JBIG2 supports arithmetic and Huffman text, MMR, and shared global dictionaries

JPEG 2000 supports subsampled and signed components, inferred color and sample declarations, embedded ICC profiles, explicit color-space overrides, and separate or associated opacity through SMaskInData; its component values are normalised to eight or sixteen bits and its image Decode array is ignored

Embedded or explicit Lab/XYZ ICC profiles use physical component ranges; associated opacity is removed from normalised stored samples before applying the physical coordinate mapping, preserving Lab offset channels

Graphics-state SMask supports Alpha and Luminosity groups, backdrop colours, Form matrices, saved-state restoration, and sampled, exponential, stitching, and bounded calculator transfer functions; an image's own soft mask overrides the graphics-state soft mask

All sixteen standard PDF blend modes are supported; Form and page groups support isolated and nonisolated composition, object knockout, and DeviceGray, DeviceRGB, DeviceCMYK, CalGray, CalRGB or one-, three-, and four-component ICCBased blending spaces

Calibrated groups retain native component values until a group boundary and accept device or Lab source colours through inverse calibrated transforms; Lab itself is not a valid blending space

Calibrated Luminosity masks retain their group coordinates and evaluate CIE XYZ-Y, including group opacity and backdrop colours, before applying the transfer function

Knockout compositing keeps the object's geometric shape separate from soft-mask opacity; stencil holes preserve preceding objects whilst a masked path replaces them throughout its painted geometry

Nested knockout groups retain the union of their children's geometric shapes, including zero-opacity objects; nonisolated child groups use the enclosing knockout group's initial backdrop

CMYK groups preserve complementary CMY and black components in separate bounded image planes and convert the combined result at group boundaries; nonseparable blend modes retain or replace black according to the selected mode

Nonisolated groups render an additional bounded opacity pass, remove the initial backdrop contribution, and apply the incoming group alpha and blend mode once; page transparency groups use an isolated surface before compositing onto the page background

A nonisolated Form inherits its enclosing blending space; an explicit group CS entry does not switch the initial backdrop to another space

Existing normal annotation appearances are fitted from their transformed BBox to Rect; RenderAnnotations=false omits appearances in either usage

Usage defaults to hruView, which skips Hidden and NoView annotations and unknown annotation types with Invisible set; ISO 32000 standard annotation types, including PDF 2.0 RichMedia and Projection, with supported normal appearances remain visible when only Invisible is set

RichMedia and Projection acceptance covers existing static normal appearances with valid media assets or an associated default 3D view; media playback and interactive 3D activation are outside this raster path

hruPrint paints only annotations with Print set and Hidden clear; Invisible suppresses unknown annotation types in either usage, NoView does not suppress printing, and NoZoom does not change printed appearance size

Visible annotations require an existing supported normal appearance stream; the renderer does not synthesise appearances from annotation metadata or field values

For view output, annotation NoZoom removes the render scale from appearance size whilst preserving UserUnit; NoRotate keeps the fitted appearance upright through page rotation in either usage, and both preserve the transformed upper-left Rect anchor and page clip

Text annotations with existing normal appearances behave as NoZoom and NoRotate in view output regardless of their explicit flags; print output retains their NoRotate behaviour whilst ignoring NoZoom

Usage controls static raster visibility and annotation geometry; interaction-only flags do not create hover or editing behaviour, and the existing extraction-permission callback remains required without granting print permission

Optional content in static output

Rendering consumes the catalog's default OCProperties/D configuration, initializes group states from BaseState, applies ON and OFF overrides, and uses matching Intent values when determining visibility

Membership dictionaries support AnyOn, AllOn, AnyOff, and AllOff; recursive VE expressions support And, Or, and single-operand Not, with VE taking precedence over the simpler policy

Null, unavailable, and stale group references have no membership effect; groups outside the configuration's intents do not control visibility, and a membership or expression without applicable groups leaves content visible

Nested /OC marked content, image and Form XObjects, and annotations respect the resulting state; hidden marked sections still update colours, matrices, clipping, and text position, whilst hidden whole XObjects and annotations may be skipped

Ordinary marked-content property dictionaries remain usable, including nested inline values; content arrays preserve marked-content state across their component streams, and child streams keep their own marked-content nesting

Standalone final-form rasterisation uses the default configuration in both view and print modes without automatically applying interactive AS usage recommendations, as specified by ISO 32000-1:2008 section 8.11.4.5; explicit ViewerState enables View, Print, Export, Zoom, Language, and User recommendations with persistent manual selection and temporary event state

Missing optional-content properties or a nil borrowed catalog leave optional-content structures without a visibility effect; malformed live memberships, expression cycles, and configured work, memory, or recursion limits fail before PNG publication

Affine appearance matrices and nonzero BBox origins retain their normal fit under these flags; an extremely small render scale can still make Cairo's initial page matrix numerically noninvertible

The rendered page uses the MediaBox/CropBox intersection, inherited page boxes and quarter-turn Rotate, and the page's UserUnit; scale 1 produces one pixel per effective page point, with surface dimensions rounded upward

The sh operator paints function-based, axial and radial shadings (ShadingTypes 1–3), with two-input domains, shading matrices, radial-circle selection, Extend endpoints, BBox and existing path clips

Supported color functions and scalar function arrays convert through device, calibrated, ICC Lab/XYZ and Separation/DeviceN source colours; current fill opacity, blend modes, graphics-state soft masks and transparency-group knockout apply to the resulting shading

The current path and colour are preserved; shading Background is ignored by sh, and AntiAlias is a device hint with pixel-centre color sampling

Unsupported ExtGState entries and unsupported content operators remain outside this profile

Triangle mesh shadings

ShadingTypes 4 and 5 paint free-form and lattice Gouraud triangle meshes with edge reuse, arbitrary lattice geometry, byte-aligned vertex records, coordinate precision through 32 bits and component precision through 16 bits

Vertex components interpolate at device pixel centres before color conversion; an optional one-input function or component function array evaluates the interpolated parameter, including calibrated, ICC and special color spaces

Indexed sources round interpolated indices to the nearest palette entry; hexadecimal lookup strings decode once with whitespace, mixed-case digits and odd final nibble padding, whilst literal lookup strings retain their decoded bytes

Current transforms, clipping, BBox, fill opacity, blend mode, soft masks, nonmarking colorants and group knockout apply to the completed mesh; retained stream bytes, the temporary page surface and two lattice rows join working-memory admission

Vertex parsing, triangle rasterisation and functions share aggregate operations and cancellation polling; malformed or truncated records and incomplete lattice rows fail before output publication

Focused acceptance checks closed barycentric equations and separate MuPDF and Poppler output; proof records keep source-reader failures separate for vertex padding, unused flag bits and mesh transparency, and use explicit alternate reader equations for nonmarking colours and normalised Indexed values

Coons and tensor patch meshes

ShadingTypes 6 and 7 paint cubic Coons boundaries and tensor control nets, with preceding-edge reuse, byte-aligned records, low-two-bit flag semantics and the same coordinate and component precisions as triangle meshes

Corner components interpolate bilinearly in patch parameters before optional functions and color conversion; Coons boundaries elevate to an equivalent bicubic Bernstein net, whose second-derivative bounds select subdivisions with at most 0.125 output-pixel geometry error

Polynomial inversion refines pixel parameters; folded coverage chooses the greatest v parameter and then the greatest u parameter for equal v, whilst later patches replace earlier colours before the completed shading receives object transparency

The shared mesh compositor applies clipping, BBox, shading patterns, nonmarking colorants, opacity, blending, soft masks and group knockout; two subdivision rows and per-pixel parameter and order arrays join active working-byte admission

Control-point parsing, subdivision, rasterization and color functions share operation limits and cancellation; focused acceptance uses independent Coons and tensor equations and cubic roots for folded patches, with source-reader failures recorded separately from ordinary RGB equation-page verification

Inherited text state

Form, Type3 and pattern child streams inherit the applicable font object, font size, character spacing, word spacing, horizontal scale, leading, rendering mode and rise from their initial graphics state; a child resource with the same font name does not replace an inherited font until a local Tf selects it

Saved graphics state restores text parameters, and TD and double-quote operators retain their leading and spacing changes for subsequent child streams; each child starts with its own text matrices

Independent annotation appearances start from default text parameters without retaining the final text state of page content

Type3 text in rendering mode 3 contributes no visible glyph graphics; focused Type3 nested-text proof retains MuPDF's default-parameter deviation separately from the inherited-state equations, whilst Poppler follows the inherited parameters in those fixtures

Tiling and shading patterns

Pattern color spaces support colored and uncolored tiling patterns, TilingType 1–3, shading patterns, PatternMatrix, cell BBox, positive or negative spacing, pattern selection, saved-state restoration, and fill or stroke painting

Uncolored patterns obtain their components from a supported base color space and can paint image stencils; explicit colour changes, colored images and direct shadings inside an uncolored definition are invalid PDF content and are rejected through nested Forms and Type3 procedures as well

Selected patterns retain the default coordinate space of the content stream that resolved their definition; later cm operations and an inherited pattern used inside a Form do not replace that origin

Definitions start with the parent's initial supported graphics state and default transparency parameters; tiling definitions form a nonisolated non-knockout group, whilst shading definitions use object knockout

Transparent and overlapping tiling cells evaluate against the current backdrop; incoming object alpha and blend mode apply once when painting the completed pattern, including nested patterns, text, strokes and image masks

Shading-pattern ExtGState augments supported shading parameters, including opacity and soft masks; Background is painted before the shading, BBox clips both contributions, and nonmarking None colours contribute neither colour nor shape

Pattern evaluation admits two page surfaces and decoded cell content, bounds visible cell enumeration to the current clip, and polls cancellation whilst rendering cells and removing the backdrop contribution

Focused fixtures compare closed coordinate, colour and compositing equations with native pixels and independent reader output; proof files retain reader differences for inherited Form pattern origins, shading-pattern ExtGState opacity and nonmarking None colours, with separate ordinary vector equation pages for those cases

CID-keyed CFF fonts

Embedded CIDFontType0 fonts resolve real CFF CIDs in standalone and OpenType containers, including nonidentity mappings, CID 65535, embedded Encoding CMaps, vertical W2 origins, transformed outlines and text clipping

Standalone CFF faces load by CID and SFNT-wrapped faces load by compact glyph index; the bridge uses the correct FreeType face layout for Linux LP64 and Windows LLP64

An unmapped character code or absent requested CID consults notdefchar and notdefrange for the original code, then uses the mandatory CID 0 glyph if the replacement is absent; ranges have constant CID targets and character entries take precedence, whilst present glyphs retain their requested CID

Focused acceptance uses declared polygon contours and origin equations for 28 valid sources, with separate MuPDF and Poppler comparisons and ordinary RGB equation pages

Proof files retain source-reader differences for CID-keyed OpenType glyph selection and omitted notdef substitutions; the omission alternate is measured separately and does not replace the required native source equation

Bounds and cancellation

Exact built-in Type0 encodings cover all 200 bundled encoding names: Identity-H and Identity-V, sixteen UCS2 and UTF16 mappings, and 182 additional legacy and Unicode maps with flattened vertical character overrides

Mixed one-byte through four-byte operands use per-byte codespace bounds and longest-prefix invalid-code recovery; UTF8 and UTF32 decoding and reverse encoding preserve supplementary scalars and significant leading zero bytes

Encoding and ToUnicode streams resolve body usecmap and dictionary UseCMap names or streams, with dictionary precedence and local character, range, Unicode-sequence and notdef overrides

Each child CMap keeps its own writing mode, defaulting to horizontal when WMode is omitted; explicit vertical mode selects inherited mappings and the font's vertical metrics

CMap inheritance uses thread-local nested depth limits without changing THPDFCMapBounds layout; cycles, malformed parents and excess depth fail before output publication, and finally blocks restore limits after cancellation or exceptions

Focused proof retains named UTF8 and UTF32 source failures in an independent reader without those built-in tables, verifies separate embedded-map companions, and records source text differences when multiple codes select the same CID

Tests/Linux/Run-HeadlessLegacyCMapAcceptance.sh builds and tests exact encoding intervals, mixed-width source PDFs, nested rendering, thread isolation and cancellation recovery on native Linux

Tests/Linux/Run-HeadlessLegacyCMapWindowsAcceptance.py runs matching native Windows executables, records source, binary, PNG and diagnostic hashes, then transfers fixed captures to native Linux storage for separate MuPDF and Poppler checks

The packed maps preserve their resource hashes and complete redistribution notices; keep the CMap data licence with source and binary distributions

Hexadecimal escapes in PDF name values and content name operands decode once before resolving fonts, color spaces, blend modes and resources; a literal hash produced by decoding remains part of the semantic name

The shared font decoder applies these semantics to font dictionary values, named encodings, Differences glyph names and CIDToGIDMap, without modifying borrowed objects or decoding string values

Escaped renderer names use linear decoding, temporary working-byte admission, aggregate operation limits and cancellation polling; focused acceptance compares equivalent native PNG bytes and text plus independent MuPDF and Poppler output

Shading raster work and color functions share aggregate operation limits and cancellation polling; the temporary surface and an exact-coordinate cache of at most 8,192 converted colours join active working-byte admission

Focused shading acceptance uses closed geometry/function/colour equations and separate vector equation pages, retaining source-reader differences for BBox clipping, degenerate geometry, color conversion, special colorant names and knockout tessellation

Options bound surface pixels, active managed buffers, cumulative decoded bytes, encoded PNG bytes, token and operator work, and recursive or graphics-state depth

Font decoding uses conservative admission allowances: 32 MiB of transient capacity, 64 times decoded font-stream size, 128 times recursively checked array slots, and twice the retained decoder estimate in the active aggregate

CID tables admit 65,536 retained entries; enumeration bounds real charstrings, and notdef arrays join decoder deep-copy and retained-byte accounting

CMap parsing and notdef lookup share thread-local, nested entry bounds and work polling; renderer scopes share aggregate token and operation limits, and long lexical scans poll at most every 256 bytes

The interpreter also reserves per-glyph Unicode sequence capacity from input operand bytes and the longest ToUnicode mapping before creating glyph records, so repeated long mappings cannot bypass the working-memory admission

A small working-memory budget can reject a simple font even when its eventual allocation would fit; these checks cover managed buffers and CPU image surfaces, whilst Cairo, Fontconfig, FreeType caches, and total process RSS are outside the accounting

Transparency, soft-mask, backdrop, opacity and object-knockout surfaces join the active surface budget; transfer functions share the aggregate operation budget, ICC and image codecs use conservative admission, and the native JBIG2 decoder bounds bitmap/context allocation cumulatively and polls cancellation during decoding

Complementary CMY, black and geometric shape traversals share the aggregate operation, decoding and cancellation limits; profiles using the same resolved stream share one validated transform and active admission reservation until page rendering finishes

Retained function streams, function evaluation and graphics-state records join working-byte admission; recursive tint functions, multidimensional interpolation and calculator instructions share operation and cancellation limits

The borrowed cancellation token is polled during bounded decoding, tokenization, operators, glyph resolver calls, image rows, recursion, PNG encoding, and before publication; the caller owns its lifetime

The renderer checks extraction permission through the borrowed document policy and retains source object values and source bytes

Output ownership

HPDFRenderHeadlessPagePNG completes rendering and PNG encoding privately before writing to a caller-owned stream; a final stream I/O failure can retain bytes already accepted

HPDFRenderHeadlessPagePNGFile checks source identity, exclusively creates a staging file in the target directory, flushes it, checks identity and cancellation again, and atomically replaces the destination

Windows publication uses at most eight atomic replacement attempts and seven waits of 1, 2, 4, 8, 16, 16 and 16 milliseconds, retrying only access-denied, sharing-violation and lock-violation errors; cancellation is checked before every attempt and on both sides of each wait

Failed Windows publication reports the captured final Windows error code through EHPDFHeadlessRenderError; cancellation retains the renderer's cancellation diagnostic, and neither path deletes the existing destination or falls back to non-atomic copying

Rendering, budget, cancellation, and staging failures preserve an existing destination and remove owned unpublished staging files; source-path and hardlink aliases are rejected

Acceptance

Windows runtime acceptance uses matching native console executables and an isolated, SHA256-pinned portable DLL import closure; a separate WSL process runs independent MuPDF and Poppler pixel, equation and geometry checks against the Windows-produced PNG files

Windows standard-font substitutes use explicit Cairo GDI faces for Unicode text and real outlines, including clipping and fill-and-stroke modes; embedded fonts retain their FreeType glyph mapping

OpenJPEG calls use the Windows stdcall ABI and Win32 decorated exports, whilst stream and message callbacks retain the C callback convention

Tests/Linux/Run-HeadlessCairoAcceptance.sh performs fresh native ELF builds, clears DISPLAY and WAYLAND_DISPLAY, rejects directly linked desktop libraries, and runs independent pypdf/MuPDF oracles

The fixtures exercise standard fonts, Unicode TrueType, Type3, all text rendering and blend modes, alpha and knockout, RGB transparency groups, sample depths and Decode, image masks and Matte, Indexed and ICC colours, terminal codecs, AES-encrypted filter chains, page geometry, annotation transforms, budgets, cancellation, source preservation, and atomic output

See THPDFHeadlessRenderResult for counters and EHPDFHeadlessRenderError for error handling