Documentation
¶
Overview ¶
Package pdfengine is the pdfcpu adapter: the only package that imports pdfcpu. It inspects source PDFs and assembles the final document from them and from a generated-pages document. It knows nothing of plans, styles or layout; callers hand it facts (SourceInfo), a compact page order (Run) and file paths, and it returns failures as *Error values with stable Codes.
Operations ¶
Inspect reads one captured source once and reports SourceInfo: page count, effective version, whether pages carry page-local objects, whether a form or destinations exist, and the visible size of the first and last pages, plus material scope-specific feature observations captured before validator repairs. With a requested target it also checks every original page and captures compact fit geometry ranges. Assemble takes the inspected sources, the generated resource document and the final order, and writes and verifies one PDF.
Visible page geometry ¶
A page's visible size is the effective CropBox clipped to the effective MediaBox (MediaBox alone when there is no CropBox), swapped in width and height for a rotation of 90 or 270 degrees, and multiplied by the page's UserUnit. MediaBox, CropBox and Rotate are inherited through the page tree, each independently; UserUnit is not inherited. Boxes may be written with any two opposite corners. Only the first and last pages are measured without fitting; fitting checks every page. A malformed box, an empty or non-overlapping CropBox, a rotation that is not a multiple of 90, or a non-positive UserUnit on those pages is an error. Sizes above any generated-page limit are returned unchanged: preserving a legal large page is the caller's rule to apply. The rule was checked against Poppler renderings (pdftoppm -cropbox) in the tests; Poppler ignores UserUnit, which the tests multiply in.
Assembly design ¶
Every document is merged into one pool with pdfcpu's exported merge primitive, then the pool's page tree is replaced in place by a flat tree of the final order. Page objects keep their identity, so links, destinations and /P back-references stay consistent, and fonts, images and content streams stay shared. pdfcpu's page-collection primitive was rejected: with repeated pages it leaves link destinations pointing at orphan page copies, shares annotation arrays between copies, and drops inherited CropBox (the tests keep a negative control showing the independent oracle detects this).
The pool is built in one sequential pass and written once; the growing output is never rewritten. Memory grows with the total size of the imported documents plus a page dictionary per output page: the pool and the written file are both held in memory (the file again, when it is re-read to verify it). There is no streaming mode and no fixed memory bound; MaxOutputPages only bounds a request. The package benchmarks measure wall time, memory and descriptors.
AssemblyPlan.Validate applies source-known instruction policy without opening files; callers use it for preflight as well as assembly. Assemble calls the same validator defensively before importing. Preflight cannot establish later file/destination state or successful output verification.
Source policy ¶
A source whose pages have /Annots, /AA or /B, or that has an AcroForm or destinations, is "per occurrence": it is imported anew for every run that uses it, so each occurrence owns its annotations, widgets and destinations. Such a source must be used whole in each run (a partial range would leave links, fields or destinations pointing at dropped pages: CodePartialRange). A source with the legacy catalog /Dests dictionary is supported for at most one source occurrence across the entire output (CodeLegacyDestsRepeated), including sources with different destination names. The backend conservatively refuses a second dictionary because pdfcpu merges legacy destinations by overwriting equal keys. Every other source is imported once; repeated pages get a cloned page dictionary and share everything else. Inherited MediaBox, CropBox, Rotate and Resources are copied onto each page, so reordering never changes a page's geometry, and the root of the output page tree carries none.
Backend behavior for document-level features ¶
- Annotations and links: kept with the page, and for per-occurrence sources re-pointed to the occurrence's own pages (direct /Dest, GoTo actions, page /AA actions, /P back-references).
- Forms: the AcroForm is kept. Fields of equal name in different documents or occurrences stay separate fields; pdfcpu nests the fields of later documents under a generated numeric parent field, so qualified names differ from the source's. Effective DA/Q defaults and actual AcroForm resource bindings are preserved per occurrence; widget AP and page resources retain independent scopes. Ordinary appearance/editability is supported; field-name references in retained scripts are not rewritten. Unsupported form defaults/ancestry reject with CodeFormUnsupported during inspection and import.
- Named destinations: the /Names /Dests tree is kept and merged. pdfcpu renames a colliding name in a later occurrence (a control-character suffix) and its links follow the rename.
- Outlines/bookmarks, document information, XMP metadata, page labels, open action, viewer preferences, permissions and other non-rendering catalog entries: dropped. The output has a fresh /Info with pdfcpu's producer and the current date.
- Catalog tagged-PDF structure (StructTreeRoot, MarkInfo): dropped; output is not tagged.
- Non-destination catalog name trees, including EmbeddedFiles and JavaScript, and catalog AF associated-file indices: dropped. An index removal does not remove payloads still reachable through kept page FileAttachment annotations. Page/annotation/widget actions remain, including executable actions. The assembler does not execute scripts and output is not sanitized. Material keep/drop facts are returned once per kind/source for application warning projection; ordinary GoTo/URI links, absent/empty features and producer metadata do not warn.
- Optional content (OCProperties, OCG/OCMD and /OC references) and OutputIntents: rejected with CodeUnsupportedRendering because document-wide layer/color configuration cannot be reconciled.
- Dynamic XFA forms and NeedsRendering true: rejected before validator repairs, including XFA-only forms with no static fields. Ordinary static AcroForm widgets and NeedsRendering false are supported.
- Encryption: encrypted sources are rejected (CodeEncrypted), including those that open with an empty password. Output is never encrypted.
- PDF version: the output is PDF 2.0 when any input is PDF 2.0, else PDF 1.7. A 2.0 source may appear anywhere in the order.
- Actual signatures, certification/usage-rights signatures and document timestamps: rejected before validator repairs and during import with CodeSignatureUnsupported. Supported empty unsigned signature fields remain allowed. Assemble unsigned sources and sign the final document externally; the adapter does not authenticate signers, strip signatures or claim preserved signed-byte integrity.
Output is written by pdfcpu with a fresh creation date, so it is not byte-reproducible.
Robustness ¶
Sources are hostile input. pdfcpu panics on some malformed files and re-panics from its own recovery; Inspect and Assemble convert panics into errors. The context is checked between imports, while page clones are compiled, and before the write; pdfcpu checks it internally as well.
Index ¶
Constants ¶
const ( // CodeUnreadable means a file could not be opened or is not a regular file. CodeUnreadable Code = "pdf_unreadable" // CodeInvalid means the PDF is malformed or fails validation. CodeInvalid Code = "pdf_invalid" // CodeEncrypted means the PDF is encrypted; encrypted sources are not supported, even with an empty password. CodeEncrypted Code = "pdf_encrypted" // CodeUnsupportedRendering means source rendering depends on document state the assembler cannot reconcile. CodeUnsupportedRendering Code = "pdf_rendering_unsupported" // CodeSignatureUnsupported rejects signature values that assembly would invalidate. CodeSignatureUnsupported Code = "pdf_signature_unsupported" // CodeFormUnsupported rejects form semantics the backend cannot preserve faithfully. CodeFormUnsupported Code = "pdf_form_unsupported" // CodeFitUnsupported rejects source geometry or semantics fitting cannot preserve. CodeFitUnsupported Code = "pdf_fit_unsupported" // CodeNoPages means the PDF has no pages. CodeNoPages Code = "pdf_no_pages" // CodePageGeometry means the first or last page has missing or malformed page boxes, rotation or UserUnit. CodePageGeometry Code = "pdf_page_geometry_invalid" // CodePartialRange means a source whose page-local objects, forms or destinations must be re-imported // per occurrence was used for only some of its pages. CodePartialRange Code = "pdf_partial_range_unsupported" // CodeLegacyDestsRepeated means more than one legacy catalog /Dests source occurrence is requested. CodeLegacyDestsRepeated Code = "pdf_legacy_dests_repeated" // CodeRequestInvalid means the assembly request is inconsistent: a bad index, range, count or total. CodeRequestInvalid Code = "assemble_request_invalid" // CodeAssemblyFailed means the PDF backend failed while importing, reordering or writing. CodeAssemblyFailed Code = "assemble_failed" // CodeOutputInvalid means the written PDF failed validation. CodeOutputInvalid Code = "output_invalid" // CodeOutputPageCount means the written PDF does not contain the expected number of pages. CodeOutputPageCount Code = "output_page_count_mismatch" // CodeCanceled means the context was canceled or its deadline passed. CodeCanceled Code = "canceled" // NoSource marks failures not attributable to an inspected source. NoSource = -1 // NoRun marks failures not attributable to a compact-order run. NoRun = -1 // ReasonOrder identifies an empty page order. The other reasons distinguish instruction refusals // from the internally derived total invariant. ReasonOrder PolicyReason = "order" ReasonCount PolicyReason = "count" ReasonSource PolicyReason = "source" ReasonRange PolicyReason = "range" ReasonResource PolicyReason = "resource" ReasonWholeSource PolicyReason = "whole_source" ReasonLegacyDests PolicyReason = "legacy_destinations" ReasonPageLimit PolicyReason = "page_limit" ReasonTotalMismatch PolicyReason = "total_mismatch" ReasonFit PolicyReason = "fit_to" )
Failure codes. They are part of the package contract: callers branch on them and reports carry them.
const ( FeatureBookmarks FeatureKind = "bookmarks" FeatureTaggedStructure FeatureKind = "tagged_structure" FeatureCatalogAttachments FeatureKind = "catalog_attachments" FeatureCatalogActions FeatureKind = "catalog_actions" FeaturePageActions FeatureKind = "page_actions" FeaturePageAttachments FeatureKind = "page_attachments" FeaturePageLabels FeatureKind = "page_labels" FeatureOtherCatalogNames FeatureKind = "other_catalog_names" FeatureURIBase FeatureKind = "uri_base" FeatureRemoved FeatureDisposition = "removed" FeatureRetained FeatureDisposition = "retained" )
Feature kinds distinguish catalog removal from page-local retention.
const MaxOutputPages = 2_000_000
MaxOutputPages is the largest page total Assemble accepts. The pool holds one dictionary per output page in memory, so the bound turns a request that could only exhaust memory into an immediate error. The engine's measured envelope is far smaller (see the package documentation).
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Affine ¶ added in v0.2.0
type Affine [6]float64
Affine maps source default user space to output physical points using PDF's six coefficients.
type AssembleRequest ¶
type AssembleRequest struct {
Observer observation.Observer
FitTarget *PageSize
Resource *ResourceDocument
Destination string
OutputDigest string
Sources []SourceFile
Order []Run
ExpectedPages int
// contains filtered or unexported fields
}
AssembleRequest describes one output document.
type AssemblyPlan ¶ added in v0.2.0
type AssemblyPlan struct {
FitTarget *PageSize
Sources []SourceFile
Order []Run
GeneratedSpecs int
ExpectedPages int
}
AssemblyPlan is the source-known instruction policy, independent of destination and resource files.
func (AssemblyPlan) Validate ¶ added in v0.2.0
func (r AssemblyPlan) Validate() error
Validate checks inspected source facts and compact order without I/O or page-sized allocations. At most one legacy catalog /Dests source occurrence is supported, even across distinct sources: the backend cannot safely reconcile their catalog dictionaries.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine performs PDF inspection and assembly with the embedded pdfcpu library, using stateless, offline configuration. It is safe for concurrent use: every operation works on a clone of its configuration.
func New ¶
New constructs an Engine.
The configuration is stateless (no pdfcpu configuration directory is read or written), offline, and relaxed in validation. Merge bookmark creation is off, and the command mode is MERGECREATE, which makes pdfcpu reject encrypted files at read time, before decrypting anything.
func (*Engine) Assemble ¶
func (e *Engine) Assemble(ctx context.Context, req *AssembleRequest) error
Assemble writes the request's pages, in order, as one PDF at req.Destination and verifies the result.
The sequence, each step once per call:
- validate the request and enforce the source policy (no file is read);
- import the resource document and the source documents into one pool, merging their object graphs. A source with page-local objects, forms or named destinations is imported anew for every run that uses it; every other source is imported once and its page dictionaries are cloned for repeated pages while all other objects stay shared;
- reorder the pool's page tree in place to the compiled order and reduce the catalog to the entries the policy keeps;
- optimize (merging duplicate fonts and images) and write the file once;
- validate the written file and compare its page count with req.ExpectedPages.
The pool holds every imported object graph in memory until the single write, so memory grows with the total size of the imported documents, not with the number of output pages; there is no bounded or streaming mode. The growing output is never rewritten.
The context is checked between imports, while repeated pages are compiled, and before the write. Failures are *Error values with stable codes naming the source where one is responsible.
func (*Engine) Inspect ¶
Inspect reads and validates the PDF at path and reports its facts in one pass.
The object graph is not retained after Inspect returns: only the returned values survive, so memory use is bounded by one source at a time per concurrent caller.
Encrypted PDFs are rejected with CodeEncrypted even when they open with an empty password. A first or last page whose boxes, rotation or UserUnit are malformed is rejected with CodePageGeometry. Optional content, document output intents and dynamic XFA rendering are rejected with CodeUnsupportedRendering. A nonnil target adds shared raw all-page fitting policy and geometry capture before validation repairs.
type Error ¶
type Error struct {
// Err is the underlying cause.
Err error
// Code is the stable failure category.
Code Code
// Path is the file concerned, or empty.
Path string
// Reason is nonempty for assembly-plan policy failures.
Reason PolicyReason
// Source is the index into AssembleRequest.Sources, or NoSource.
Source int
// Run is the offending compact-order index, or NoRun for non-run failures.
Run int
}
Error is a failure with a stable code and, where known, the identity of the file it concerns.
type FeatureDisposition ¶ added in v0.2.0
type FeatureDisposition string
FeatureDisposition is the assembly policy for an observed feature.
type FeatureKind ¶ added in v0.2.0
type FeatureKind string
FeatureKind identifies a material source feature whose handling matters to the assembled packet.
type FitRange ¶ added in v0.2.0
FitRange captures consecutive source pages with identical original and final geometry.
type PageFit ¶ added in v0.2.0
type PageFit struct {
Media [4]float64
Crop [4]float64
Visible [4]float64
Original PageSize
Target PageSize
Matrix Affine
Scale float64
UserUnit float64
Rotation int
HasCrop bool
}
PageFit captures original physical geometry and the final sheet transform once per geometry.
type PageSize ¶
type PageSize struct {
Width, Height float64
}
PageSize is a page's visible size in physical points (1/72 inch), as a viewer shows it.
type PolicyReason ¶ added in v0.2.0
type PolicyReason string
PolicyReason identifies an instruction-policy refusal without parsing its message.
type ResourceDocument ¶
type ResourceDocument struct {
// Path is the generated PDF.
Path string
// Pages is the number of pages it holds.
Pages int
}
ResourceDocument is the generated-pages PDF: one page per distinct generated-page specification. Assemble only reads it, and uses its pages by index.
type Run ¶
type Run struct {
// Generated selects the kind: false for pages of Sources[Index], true for page Index of the resource.
Generated bool
// Index is the source index, or the 0-based resource page index.
Index int
// Start is the 1-based first source page; it is unused for generated runs.
Start int
// Count is the number of consecutive source pages, or the number of repetitions of the generated page.
Count int
}
Run is one compact element of the final page order.
func GeneratedPages ¶
GeneratedPages is a run of repeat copies of the 0-based resource page spec.
func SourcePages ¶
SourcePages is a run of count consecutive pages of Sources[source] beginning at the 1-based page start.
type SourceFeature ¶ added in v0.2.0
type SourceFeature struct {
Kind FeatureKind
Disposition FeatureDisposition
}
SourceFeature is an observed source fact and its scope-specific assembly policy.
type SourceFile ¶
type SourceFile struct {
// Path is the private snapshot to read; the bytes inspected are the bytes assembled.
Path string
// Info is the result of Inspect(Path).
Info SourceInfo
}
SourceFile is one captured source document and the facts Inspect reported for it.
type SourceInfo ¶
type SourceInfo struct {
// Features captures material scope-specific source effects before validator repairs.
Features []SourceFeature
// Fits captures compact all-page fitting geometry when a target was requested.
Fits []FitRange
// Pages is the number of pages, at least 1.
Pages int
// Version is the effective PDF version: the catalog /Version entry when present, else the header.
Version Version
// PageLocal reports that some page has an /Annots entry, an /AA additional-actions
// dictionary or a /B article-beads array: objects that belong to one page and refer to others.
PageLocal bool
// AcroForm reports that the catalog has an interactive form.
AcroForm bool
// NamedDests reports that the catalog has a /Names /Dests name tree.
NamedDests bool
// LegacyDests reports that the catalog has the legacy /Dests dictionary.
LegacyDests bool
// First and Last are the visible sizes of the first and last pages; see PageSize.
First, Last PageSize
}
SourceInfo is what the assembly policy and layout need to know about one PDF.
func (SourceInfo) ImportPerOccurrence ¶
func (s SourceInfo) ImportPerOccurrence() bool
ImportPerOccurrence reports whether Assemble imports the source anew for every run that uses it, because its annotations, forms or destinations are tied to its page objects and a shared copy would leave the second occurrence pointing at the first.
Source Files
¶
- assemble.go
- doc.go
- engine.go
- errors.go
- feature_objects.go
- feature_pages.go
- feature_uri.go
- features.go
- fit_affine_error.go
- fit_blending.go
- fit_child_geometry.go
- fit_color_restrictions.go
- fit_content.go
- fit_destinations.go
- fit_dispatch.go
- fit_facts.go
- fit_geometry.go
- fit_graph.go
- fit_hotspots.go
- fit_import.go
- fit_links.go
- fit_patterns_masks.go
- fit_policy.go
- fit_precision.go
- fit_print_boxes.go
- fit_resource_errors.go
- fit_resource_geometry.go
- fit_resource_programs.go
- fit_resources.go
- fit_simple_metrics.go
- fit_streams.go
- fit_text_state.go
- fit_type3.go
- fit_type3_metrics.go
- fit_verification.go
- form_appearance.go
- form_button_streams.go
- form_buttons.go
- form_resources.go
- form_state.go
- form_variable_choices.go
- form_variable_encoding.go
- form_variable_font.go
- form_variable_geometry.go
- form_variable_streams.go
- form_variable_widths.go
- form_variable_wrapping.go
- form_variables.go
- geometry.go
- inspect.go
- pagetree.go
- pool.go
- rendering.go
- request.go
- signature.go
- source_page_roles.go
- version.go