Pdf Zig Reference Documentation
Current Version: 11.7.0
Markdown version of this page for AI tools (v 11.7.0) · all AI docs
Work with PDF signatures, embedded files, metadata, and LTV information
Chilkat.Pdf provides PDF operations focused on digital signatures,
embedded files, metadata, signature verification, and long-term validation support.
It can load PDFs from files or memory, inspect page, signature, and attachment
counts, sign PDFs with visible or invisible signatures, verify existing signatures,
retrieve signer certificates, and manage DSS/LTV verification information.
The class is commonly used for PDF signing workflows, PDF/A-3-style embedded-file scenarios, signature validation, and adding long-term validation material after signing.
For an extended overview, see Pdf Class Overview.
Object Creation
// Add the package once:
// zig fetch --save https://chilkatdownload.com/11.7.0/chilkat-zig-11.7.0.tar.gz
// and in build.zig:
// const chilkat = b.dependency("chilkat", .{ .target = target, .optimize = optimize });
// exe.root_module.addImport("chilkat", chilkat.module("chilkat"));
const chilkat = @import("chilkat");
// Once per process, before any other Chilkat call:
try chilkat.unlockBundle("Anything for 30-day trial");
const pdf = try chilkat.Pdf.init();
defer pdf.deinit();Creates the underlying native Chilkat object. Pdf is a one-pointer struct passed by value; copying it copies the handle (two names for one object). Returns error.OutOfMemory if the library could not allocate the object. Use an object from one thread at a time; it may be handed from one thread to another.
Releases the native object. Call it exactly once per object (usually with defer); the handle is invalid afterwards. Objects returned by methods are owned by the caller too and are released the same way.
Wraps a handle obtained from the C API (chilkat.c.CkPdf), taking ownership of it. The struct's handle field goes the other way, for anything the Zig API does not cover.
Errors and memory
Methods that can fail return an error union: a method whose only outcome is success or failure returns Error!void; a method producing a string returns (Error || Allocator.Error)![:0]u8; a method producing an object returns Error!T. chilkat.Error is error{ChilkatFailed}; the reason for a failure is in getLastErrorText, and the object remains usable. Properties never fail, and methods that answer a question (hasMember, isUnlocked, ...) return a plain bool.
String arguments are [:0]const u8 (UTF-8; string literals can be passed as is). String results are copies allocated with the allocator argument and owned by the caller, so they stay valid across later calls on the same object.
const text = pdf.someMethod(allocator, ...) catch |err| {
const why = try pdf.getLastErrorText(allocator);
defer allocator.free(why);
std.debug.print("{s}\n", .{why});
return err;
};
defer allocator.free(text);
Properties
DebugLogFilePath
pub fn getDebugLogFilePath(self: Pdf, allocator: Allocator) Allocator.Error![:0]u8
pub fn setDebugLogFilePath(self: Pdf, value: [:0]const u8) void
If set to a file path, this property logs the LastErrorText of each Chilkat method or property call to the specified file. This logging helps identify the context and history of Chilkat calls leading up to any crash or hang, aiding in debugging.
Enabling the VerboseLogging property provides more detailed information. This property is mainly used for debugging rare instances where a Chilkat method call causes a hang or crash, which should generally not happen.
Possible causes of hangs include:
- A timeout property set to 0, indicating an infinite timeout.
- A hang occurring within an event callback in the application code.
- An internal bug in the Chilkat code causing the hang.
HasCertificationSig
pub fn getHasCertificationSig(self: Pdf) bool
Returns true if the currently open PDF has a certification signature.
PDF defines two types of signatures: approval and certification.
The differences are as follows:
- Approval: There can be any number of approval signatures in a document.
- Certification: There can be only one certification signature and it must be the first one in a document.
LastErrorHtml
pub fn getLastErrorHtml(self: Pdf, allocator: Allocator) Allocator.Error![:0]u8
Provides HTML-formatted information about the last called method or property. If a method call fails or behaves unexpectedly, check this property for details. Note that information is available regardless of the method call's success.
topLastErrorText
pub fn getLastErrorText(self: Pdf, allocator: Allocator) Allocator.Error![:0]u8
Provides plain text information about the last called method or property. If a method call fails or behaves unexpectedly, check this property for details. Note that information is available regardless of the method call's success.
LastErrorXml
pub fn getLastErrorXml(self: Pdf, allocator: Allocator) Allocator.Error![:0]u8
Provides XML-formatted information about the last called method or property. If a method call fails or behaves unexpectedly, check this property for details. Note that information is available regardless of the method call's success.
topLastMethodSuccess
pub fn getLastMethodSuccess(self: Pdf) bool
pub fn setLastMethodSuccess(self: Pdf, value: bool) void
Indicates the success or failure of the most recent method call: true means success, false means failure. This property remains unchanged by property setters or getters. This method is present to address challenges in checking for null or Nothing returns in certain programming languages. Note: This property does not apply to methods that return integer values or to boolean-returning methods where the boolean does not indicate success or failure.
NumEmbeddedFiles
pub fn getNumEmbeddedFiles(self: Pdf) i32
NumPages
pub fn getNumPages(self: Pdf) i32
The number of pages in the currently open PDF.
topNumSignatures
pub fn getNumSignatures(self: Pdf) i32
The number of digital signatures present in the currently open PDF.
topOwnerPassword
pub fn getOwnerPassword(self: Pdf, allocator: Allocator) Allocator.Error![:0]u8
pub fn setOwnerPassword(self: Pdf, value: [:0]const u8) void
The PDF owner password, if required.
topPreserveSignatures
pub fn getPreserveSignatures(self: Pdf) bool
pub fn setPreserveSignatures(self: Pdf, value: bool) void
Controls what Chilkat may do to a PDF that contains digital signatures. The default is true.
A signature covers the bytes of the file as they were when it was signed, so a PDF can only be changed afterwards by appending an incremental update that leaves those bytes untouched. Some changes cannot be made that way: rewriting page content (TextReplace, and most Watermark approaches), changing the encryption, passwords or permissions (Protection), and rewriting the file (Optimize). While this property is true, such operations are refused on a signed PDF and the reason is given in the LastErrorText; the operations that only append (adding a Watermark with the annotation approach, adding signatures, embedded files or metadata) remain available.
Set this property to false to allow any change, accepting that the existing signatures become invalid: the saved PDF is a full rewrite and viewers report the signatures as broken. The property is also read when the PDF is written: with it false, WriteFile and WriteBd may rewrite a signed PDF instead of appending to it.
SigAllocateSize
pub fn getSigAllocateSize(self: Pdf) i32
pub fn setSigAllocateSize(self: Pdf, value: i32) void
Defaults to 15000. This property should generally be left unchanged. If signing fails and the following message is in the LastErrorText: Did not allocate enough space for the PDF signature., then you should increase this value. The actual signature size will be noted in the LastErrorText, and you can use that value to set an allocation size that is somewhat larger.
UncommonOptions
pub fn getUncommonOptions(self: Pdf, allocator: Allocator) Allocator.Error![:0]u8
pub fn setUncommonOptions(self: Pdf, value: [:0]const u8) void
This is a catch-all property to be used for uncommon needs. This property defaults to the empty string. It can be set to a list of one or more of the following comma separated keywords:
- WriteStandardXref - When writing the PDF, write the cross reference section in standard format if possible. (The
standard formatis the older non-compressed format.) - NO_VERIFY_CERT_SIGNATURES - When countersigning a PDF (i.e. adding a new signature to a PDF that already contains one or more signatures), Chilkat will automatically validate the existing signatures and their certificates. (The signing certificates are typically embedded within a signature.) If any of these validations fail, the new signature is not added. Sometimes, an existing signature is validated, but the certs in the chain of authentication, such as issuer certs or root CA certs, are not included and not available to check. In this case, you can add the
NO_VERIFY_CERT_SIGNATURESto skip the existing signature certificate validations. - SIGN_IGNORE_PERMISSIONS - (v11.7.0) Sign an encrypted PDF even when it was not opened with owner rights and its permissions do not allow the signature. Starting in v11.7.0 the signing methods refuse such a PDF (see
SignPdf); this keyword restores the earlier behavior for applications that depend on it. It does not help with a PDF that could not be opened at all: that one cannot be signed.
UserPassword
pub fn getUserPassword(self: Pdf, allocator: Allocator) Allocator.Error![:0]u8
pub fn setUserPassword(self: Pdf, value: [:0]const u8) void
The PDF user password, if required.
topVerboseLogging
pub fn getVerboseLogging(self: Pdf) bool
pub fn setVerboseLogging(self: Pdf, value: bool) void
If set to true, then the contents of LastErrorText (or LastErrorXml, or LastErrorHtml) may contain more verbose information. The default value is false. Verbose logging should only be used for debugging. The potentially large quantity of logged information may adversely affect peformance.
Version
pub fn getVersion(self: Pdf, allocator: Allocator) Allocator.Error![:0]u8
Methods
AddEmbeddedFiles
Embeds one or more files in a PDF.
The json specifies the files to be attached to the PDF. See the linked example below.
The json is a JSON object containing an array of JSON objects, where each object can contain the following members.
- localFilePath: (required) The local file to be embedded in the PDF.
- description: (required) It is a short description of the embedded file.
- subType: (optional) Specifies the file type, such as application/xml, text/plain, etc. If not specified, then Chilkat will automatically choose a subType based on the file extension.
- embeddedFilename: (optional) Specifies the name of the file to be used within the PDF in the desire is for it to be different than the filename in the local filesystem. If not present, then the filename part of the localFilePath.
- AFRelationship: (optional starting in v11.1.0) Specifies specify the nature of the relationship of the embedded file. Possible values are
Source,Data,Alternative,Supplement, andUnspecified. If unset, the default isAlternative.
If successful, the updated PDF with embedded files is written to out_file_path.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
AddEmbeddedFiles2
The same as AddEmbeddedFiles, except that the updated PDF stays in memory instead of being written to a file. Call WriteFile or WriteBd to write it, or go on to other operations first: the embedded files are part of the loaded document as soon as this method returns, so NumEmbeddedFiles and GetEmbeddedFileInfo see them, and so do Protection, Watermark, Optimize and SignPdf.
Changes pending from other methods (a watermark added, a security change, an optimization, replaced text) are committed first, so the files are added to the document's current state; the embedded files themselves are added as an incremental update. See AddEmbeddedFiles for the members of json.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
AddEmbeddedFilesBd
The same as AddEmbeddedFiles, but writes the resultant PDF to the bd.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
AddEncryptCert
Adds a recipient certificate for certificate-based encryption. Call it once per recipient before calling Protection with the encrypt operation and "method": "certificate"; the PDF is then encrypted so that any one of the recipients can open it with the matching certificate and private key (see SetDecryptCert). Only the public certificate is needed here. The order of the calls matters: the nth certificate added corresponds to recipientPermissions[n-1] in the Protection options.
The certificates stay in effect for later encrypt operations until ClearEncryptCerts is called.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
AddSigningCert
Adds a certificate to be used for PDF signing. To sign with more than one certificate, call AddSigningCert once per certificate.
Note: This method is used to provide the ability to sign once with multiple certificates. This is different than signing with one certificate, and then signing again with a different certificate.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
AddVerificationInfo
Adds LTV verification information to the PDF, and saves the updated PDF to out_file_path. This create or update a DSS (Document Security Store) in the PDF with the needed certificates, OCSP responses, and CRL information.
Pass an empty json_options. The json_options exists as a placeholder for adding options if needed.
This object keeps its state from before the call; to add the verification information to the loaded document in place (and go on to other operations without reloading), use AddVerificationInfo2. Starting in v11.7.0, changes pending from other methods are committed before the verification information is added.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
AddVerificationInfo2
The same as AddVerificationInfo, except that the updated PDF stays in memory instead of being written to a file. Call WriteFile or WriteBd to write it, or go on to other operations first: the DSS (Document Security Store) with the certificates, OCSP responses and CRLs of the existing signatures is part of the loaded document as soon as this method returns.
Changes pending from other methods are committed first; the DSS itself is added as an incremental update, which leaves the existing signatures valid. Pass an empty json_options (a placeholder for future options).
Returns true on success and false on failure.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
ClearEncryptCerts
Removes every recipient certificate added with AddEncryptCert.
ExtractText
Extracts the text of the loaded PDF. The op selects what is returned, the json_in holds the options (an empty JSON object extracts all pages in automatic reading order with the default clean-up), and the json_out receives the result together with a quality report that says how trustworthy the text is. Returns true on success and false on failure. A page without extractable text (such as a scanned image) is not a failure: the quality report identifies it. Chilkat does not perform OCR.
See the examples below for more detailed information about the operations and JSON members listed here.
Operations (op)
- text - Plain text, as flowing paragraphs, visual lines, or a layout-preserving grid (see the
layoutoption). - markdown - Markdown with headings, emphasis, lists, links, code, ruled tables, image placeholders and page markers. Suited to AI and search pipelines.
- search - The matches for a string or regular expression, each with its page and the text around it.
- tables - The tables detected on the pages, as rows and cells with spans.
- assess - Only the quality report, computed without producing text. Use it to triage documents before extracting: is the text trustworthy, and which pages need OCR.
Summary of JSON Options (json_in)
The options under Scope, Reading order, Filters and Clean-up apply to all operations. The groups that follow them apply only to the operation named.
Scope (all operations)
- pages - The pages to extract. Can be
all(the default),first,last,odd,even, or a list of 1-based pages and ranges such as1,3,5-9,12-. - label - Restricts the operation to the text belonging to a label found on the page, such as
Invoice Number:orBill To, so that fields can be captured without coordinates. Matching ignores case, extra spaces and a trailing colon. Works with every operation:textreturns the value,markdownreturns it as Markdown,searchlooks only inside the labelled text, andtablesreturns only the tables inside it. - labelValue - Which text belongs to the label. Can be
auto(the default),right,below, orsection.auto- The rest of the label's line if there is text there, otherwise the block directly below the label.right- The rest of the label's line.below- The block directly below the label, ending at the next gap or heading.section- Everything after the label up to the next heading of the same or higher level (the label is itself a heading). Most reliable on tagged PDFs.
- labelOccurrence - Which occurrences of the label on the selected pages are used. Can be
first(the default),all, or a number (2for the second occurrence). Occurrences are counted in reading order. - labelRegex - Set to true to treat
labelas a regular expression. The default is false.
- readingOrder - Can be
auto(the default),structure,visual, orcontent.autofollows the structure tree when the PDF is tagged and the tree is usable, otherwise it reads in visual order.visualdetects columns and reads top to bottom within each column.contentis the order in which the text is drawn. - columns - Can be
auto(the default) ornone.noneswitches off column detection and reads the full page width line by line.
Each filter can be include or exclude and decides whether a kind of text appears in the output.
- artifacts - Tagged artifacts, Acrobat and Chilkat watermarks and backgrounds, and Acrobat headers and footers. The default is
exclude. - repeatedHeadersFooters - Untagged text repeated at the same position on most pages, such as running heads and page numbers. The default is
exclude. - invisibleText - Text drawn in an invisible rendering mode. Can be
auto(the default),include, orexclude.autoincludes invisible text only on pages that have no visible text, which is exactly an OCR layer over a scanned image. - clippedText - Text hidden by a clipping path. The default is
exclude. - offPageText - Text outside the page's crop box. The default is
exclude. - obscuredText - Text drawn in the same color as a filled area directly beneath it (white on white). The default is
exclude. - rotatedText - Text not aligned with the page, such as vertical margin labels. The default is
include. - formFields - The values of form fields, placed at the field's position in reading order. The default is
exclude. - annotations - Free-text annotations and comment text. The default is
exclude.
- expandLigatures - Boolean (default true). Ligatures are expanded, so that "fi" becomes "fi".
- dehyphenate - Boolean (default true). Rejoins words split by a hyphen at the end of a line, while keeping hyphens that belong to the word.
- actualText - Boolean (default true). Uses the PDF's ActualText replacements where present (common for symbols and decorative letters).
- bidi - Boolean (default true). Reorders right-to-left scripts into logical order.
- normalize - Unicode normalization of the output. Can be
NFC(the default),NFKC, ornone. - lineEnding - The line ending used in the text. Can be
\n(the default) or\r\n. The keywordslfandcrlfare also accepted.
- layout - Can be
flow(the default),lines, orgrid.flowjoins the lines of each paragraph;lineskeeps each visual line on its own line;gridpads with spaces so that the horizontal positions are preserved, as in a fixed-pitch rendering of the page. - pageSeparator - The string inserted between pages in the joined
text. The default is a form feed (\f).
- headings - Boolean (default true). Headings come from the structure tree when the PDF is tagged; otherwise they are inferred from the font size and weight relative to the body text.
- maxHeadingLevel - An integer from 1 to 6 (default
3). Deeper inferred heading levels are folded into the last level. - emphasis - Boolean (default true). Bold and italic spans.
- lists - Boolean (default true). Bullets, numbering and hanging indents become Markdown lists.
- links - Boolean (default true). Link annotations over the text become Markdown links.
- code - Boolean (default true). Monospaced runs become code spans and monospaced blocks become code blocks.
- tables - Can be
ruled(the default),all, ornone.ruledconverts tables that have drawn cell borders.allis accepted for tables detected from column alignment alone, but this release detects only ruled tables. - images - Can be
placeholder(the default) ornone. A placeholder such asmarks where an image sits in the flow. - pageBreaks - Can be
comment(the default),rule, ornone. Pages are separated by an HTML comment such as<!-- page 3 -->, by a horizontal rule (---), or by nothing. - footnotes - Can be
inline(the default),end, ornone. Small-print notes at the foot of a page are kept in place, gathered at the end of the document (after the last page, in the joined Markdown), or dropped.
- query - The string or regular expression to find. Required.
- regex - Boolean (default false). Set to true to treat
queryas a regular expression. - caseSensitive - Boolean (default false).
- wholeWord - Boolean (default false). Matches only whole words.
- maxResults - The maximum number of matches to return. The default is to return all matches.
- context - The number of characters of text returned before and after each match. The default is
40.
- detection - Can be
ruled(the default) orall. As for the markdowntablesoption; this release detects only ruled tables. - minRows, minColumns - Grids smaller than this are not reported as tables. The default for each is
2.
Results (json_out)
- text - The joined text of all selected pages (text operation), and pages[i].page / pages[i].text with each page's text.
- markdown - The joined Markdown (markdown operation), and pages[i].page / pages[i].markdown with each page's Markdown.
- labelMatches[i] - When
labelis set: one entry per label occurrence used, with page, label (the label as found) and the value as text or markdown. The top-leveltextormarkdownholds the values joined. A label that is not found is still success:labelMatchesis empty and the quality report carries the issuelabelNotFound. - count and matches[i] - Search results: each match has page, text (the matched text), before and after (the context).
- count and tables[i] - Each table has page, detectedBy (
ruled,alignedorstructure), rows, columns, and cells[j] with row, col, rowSpan, colSpan and text. Rows and columns are counted from 0. - quality - Returned by every operation. quality.rating is
good,fair,poor, ornonefor the document as a whole (the worst page rating among the pages that have text). quality.tagged and quality.structureUsable tell whether the PDF has a structure tree and whether it could be used. quality.pagesNeedingOcr lists the image-only pages, such as4,9. quality.pages[i] rates each page:- page, rating
- textSource -
text(real text),ocrLayer(invisible text over an image),imageOnly(needs OCR),mixed, orempty. - unicodeCoverage - The share of glyphs with a reliable Unicode mapping, from 0 to 1.
- unmappedFonts - Fonts whose glyphs could not be mapped, so their text is likely wrong.
- suspiciousCharRatio - The share of replacement, private-use and control characters in the output.
- readingOrderSource -
structure,visual, orcontent: how the reading order was decided. - columns - The number of columns detected.
- structure.headings -
structure,inferred, ornone; structure.tables.ruled and structure.tables.aligned count the tables of each kind. - issues[j].code, issues[j].message - Machine-readable codes with a sentence each:
imageOnly,ocrLayer,missingUnicode,suspiciousCharacters,multiColumn,unruledTable,structureTreeUnusable,rotatedText,obscuredTextSkipped,clippedTextSkipped,labelNotFound,structureTreeMisaligned,layoutUncertain. - uncertain - The layout decisions on the page that were borderline (an empty array when none):
columns(a gutter close to the minimum width, or sides whose line lengths barely pass or fail the test that tells two text columns from a caption column beside its values),heading(a heading candidate whose size is close to the cut-off, or an accepted heading long enough to be a pull quote),table(a ruled grid with more empty cells than filled ones, or of the smallest size detected),paragraph(a paragraph break decided by a line spacing close to the block's own). The decision is still made; the entry says the output around it deserves a look. When the array is not empty the page also carries the issuelayoutUncertain.
goodmeans the coverage is at least 0.99 with no suspicious characters to speak of;fairmeans coverage between 0.95 and 0.99 or structure inferred on a complex page (columns, unruled tables, rotated text);poormeans coverage below 0.95 or suspicious characters above 1%, so the text should not be trusted without review;nonemeans there is no text to extract.
Permissions
Extraction is read-only and never affects signatures or the saved output. For an encrypted PDF, every operation except assess requires owner rights or the copy permission; load the PDF with the OwnerPassword property set to extract from a PDF that restricts copying. assess reports only counts and ratings, never text, and is always allowed. Whole-document Markdown can be large; use ExtractTextSb to receive it in a StringBuilder.
Example: capture a field by its label
jsonIn: { "label": "Invoice Number" }
jsonOut: { "text": "INV-2026-0412",
"pages": [ { "page": 1, "text": "INV-2026-0412" } ],
"labelMatches": [ { "page": 1, "label": "Invoice Number:", "text": "INV-2026-0412" } ],
"quality": { "rating": "good", ... } }
Example: find a total with a regular expression
jsonIn: { "query": "Total\\s+\\$?[0-9,]+\\.[0-9]{2}", "regex": true }
jsonOut: { "count": 1,
"matches": [ { "page": 2, "text": "Total $1,234.56", "before": "... ", "after": " ..." } ],
"quality": { ... } }
Example: triage before extracting
jsonIn: { }
jsonOut (assess): { "quality": { "rating": "fair", "tagged": true, "structureUsable": false, "pagesNeedingOcr": "4,9",
"pages": [ { "page": 3, "rating": "fair", "textSource": "text", "unicodeCoverage": 0.97,
"unmappedFonts": [ "F12+Wingdings" ], "suspiciousCharRatio": 0.004,
"readingOrderSource": "visual", "columns": 2,
"structure": { "headings": "inferred", "tables": { "ruled": 1, "aligned": 0 } },
"issues": [ { "code": "multiColumn", "message": "Multi-column layout; reading order inferred" } ] },
{ "page": 4, "rating": "none", "textSource": "imageOnly",
"issues": [ { "code": "imageOnly", "message": "No text; page is a scanned image" } ] } ] } }
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
ExtractTextSb
The same as ExtractText, except that the joined text or Markdown is written to sb_out instead of being returned in the text or markdown member of json_out. Use this method for large documents, where whole-document text or Markdown would be an unwieldy JSON string. json_out still receives everything else: the pages array (the page numbers only; the pages' text is in the StringBuilder), labelMatches, the search or table results, and the quality report.
See the ExtractText method for the operations, the JSON options and the results.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
GetDss
Gets the contents of the PDF's Document Security Store (/DSS) if it exists. Returns the information in JSON format (in json). If there is no /DSS then an empty JSON document {} is returned in json.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
GetEmbeddedFileBd
Loads the bd with the contents of the Nth embedded file contained in the currently open PDF. The index specifies the index of the embedded file. The 1st embedded file is at index 0. See the example linked below.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
GetEmbeddedFileInfo
Gets information about the Nth embedded file contained in the currently open PDF. The index specifies the index of the embedded file. The 1st embedded file is at index 0. The json is filled with information about the embedded file. See the example linked below.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
GetLastJsonData
Provides information about what transpired in the last method called. For many methods, there is no information. For some methods, details about what transpired can be obtained via LastJsonData. For example, after calling a method to verify a signature, the LastJsonData will return JSON with details about the algorithms used for signature verification.
topGetMetadata
If the PDF contains Metadata, then loads the Metadata XML into sb and returns true. If the PDF does not contain Metadata, then clears sb and returns false.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
GetSignatureContent
Returns the CMS signature for the Nth signature contained in the PDF. The 1st signature is at index 0.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
GetSignerCert
This method retrieves the signer certificate after calling VerifySignature. Use the same index for index as the one passed to VerifySignature. If successful and the signer certificate is fully available, cert will contain the certificate.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
GetUnsignedSigFields
Returns JSON containing the name of each unsigned signature field found in the PDF.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
LoadBd
Loads the PDF file contained in pdf_data.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
LoadFile
Load a PDF file into this object in memory.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
Optimize
Measures and shrinks the loaded PDF without changing how any page looks. The op selects the operation, the json_in holds the options, and the json_out receives the report. Returns true on success and false on failure.
Operations (op)
- audit - Reports where the file's bytes go, by category, and what each option would save. Changes nothing, and is allowed on any PDF. The same options as
optimizeselect which savings to estimate. - optimize - Applies the selected options to the PDF in memory and reports what was done and the bytes saved per option. The result is written by
WriteFileorWriteBd.
Every option is lossless: pages render identically before and after. JPEG, JPEG 2000, JBIG2 and CCITT image data are never re-encoded. Most of the work is done in memory during the optimize call, so its savings are exact; two options (objectStreams and dropOldRevisions) take effect when the PDF is written, so their savings are estimates until then.
Summary of JSON Options (json_in)
An empty json_in applies the lossless preset, which is every option below at its default. Any option can be set to override the preset.
General
- preset -
lossless, the only preset and the default. - pages - Limits the page-level work (page content and resources) to these pages: a list of 1-based pages and ranges such as
1,3,5-9,12-. The default is all pages. Document-wide work always applies to the whole file.
- compressUncompressed - Boolean (default true). Flate-encodes streams stored with no filter.
- recompressFlate - Boolean (default true). Re-deflates Flate streams at
compressionLevel, keeping the result only if it is smaller. - replaceLegacyFilters - Boolean (default true). Re-encodes LZW, ASCIIHex, ASCII85 and RunLength streams as Flate, including chains of several such stages (a RunLength stream that was then Flate-encoded, say), which become one Flate stream. These streams are always re-encoded, even in the rare case where the Flate stream comes out a little larger than the original chain. A chain that includes an image filter or an unknown filter is left as it is.
- imagePredictors - Boolean (default true). Tries PNG predictors on uncompressed and Flate images, keeping the result only if it is smaller.
- compressionLevel - The Flate level, 1 to 9, used by the options above. The default is
9.
- dedupeStreams - Boolean (default true). Stores byte-identical streams with identical dictionaries once: images, embedded fonts, form XObjects, ICC profiles and page content.
- dedupeObjects - Boolean (default true). Stores identical non-stream objects (font dictionaries, color spaces, graphics states) once.
- mergeFontSubsets - Boolean (default false). Reserved for merging several subsets of the same font into one; not implemented in this release and reported in
skippedwhen set.
- removeUnreferenced - Boolean (default true). Drops objects not reachable from the document catalog.
- removeUnusedResources - Boolean (default true). Drops entries in page and form resource dictionaries that the content never uses.
- removeUnusedLayers - Boolean (default true). Drops optional-content layers that no content refers to, such as the empty "Watermark" layer Acrobat leaves behind after removing a watermark.
- coalesceContent - Boolean (default true). Merges a page's multiple content streams into one, so that they compress together.
- tidyContent - Boolean (default true). Removes redundant white space, empty q/Q pairs and graphics-state operators that change nothing. Numbers are never rounded and marked-content tags are never dropped.
- subsetFonts - Boolean (default true). Reduces fully embedded TrueType/OpenType fonts (CIDFontType2 with a FontFile2 program) to the glyphs used. Fonts that form fields need for newly typed text are left whole, as are Type 1, CFF and already-subset fonts.
- compactType1Fonts - Boolean (default false). Reserved for converting embedded Type 1 fonts to CFF; not implemented in this release and reported in
skippedwhen set.
- objectStreams -
generate(the default),preserve, ordisable.generatepacks small objects into compressed object streams with a cross-reference stream (PDF 1.5; the file's version is raised to 1.5 if lower, never lowered).preservegenerates them only if the file already had them.disablewrites classic objects and a classic cross-reference table, for consumers that cannot read object streams. - dropOldRevisions - Boolean (default true). Saves a single revision, discarding the superseded content kept by earlier incremental updates. This is also a privacy gain, since old revisions can hold deleted text.
Results (json_out)
For audit:
- fileSize, pdfVersion, pdfa - The file size in bytes, the PDF version, and the PDF/A part and conformance the file claims (such as
2b), ornone. - usage - Where the bytes go, as stored (compressed) in the file: images, fonts, pageContent, formXObjects, annotations, structureTree, metadata, embeddedFiles, oldRevisions and overhead (cross-reference data, object headers and everything not counted elsewhere), each with bytes and, where it makes sense, count. The categories cover the whole file, including those the lossless options cannot touch.
- estimatedSavings - total, and the estimated bytes saved by each option, by option name. Options that would save nothing are omitted.
optimize:
- fileSize - The size of the PDF as loaded, so that the saving can be measured against the file written afterwards.
- bytesSaved - The bytes the options above account for. The file written afterwards is usually smaller still: rewriting the document also packs objects into object streams, writes a compact cross-reference stream and leaves the old cross-reference sections behind, none of which belongs to a particular option. The exact saving is fileSize minus the size of the written file.
- bytesSavedIsEstimate - Boolean:
truewhile a save-time option (objectStreams,dropOldRevisions) contributes. - actions - Per option name: count (the objects affected, where it makes sense), bytesSaved, and estimate true for the save-time options.
- skipped[i] - Options that were requested but not applied: option, pages (when page-specific) and reason, such as page content that could not be parsed, a reserved option, or
objectStreamson a PDF/A-1 file.
Signed, encrypted and PDF/A files
Optimizing rewrites the whole file. With PreserveSignatures true (the default), optimize fails on a signed PDF; with it false, the file is optimized and its signatures are invalidated. An encrypted PDF is saved with its original security unchanged, and optimize requires owner rights or the modify permission. A PDF/A file stays within its part's rules: for PDF/A-1 object streams are skipped, the output intent and XMP metadata are kept, and fonts stay embedded (subsetting is allowed). The structure tree of a tagged PDF is never touched.
Example: audit
jsonOut: { "fileSize": 4831022, "pdfVersion": "1.4", "pdfa": "none",
"usage": { "images": { "bytes": 3120455, "count": 41 }, "fonts": { "bytes": 1204310, "count": 12 },
"pageContent": { "bytes": 288112, "count": 60 }, "formXObjects": { "bytes": 61200, "count": 9 },
"annotations": { "bytes": 8400, "count": 22 }, "structureTree": { "bytes": 51020 },
"metadata": { "bytes": 6400 }, "embeddedFiles": { "bytes": 0, "count": 0 },
"oldRevisions": { "bytes": 18210 }, "overhead": { "bytes": 72915 } },
"estimatedSavings": { "total": 1290410, "subsetFonts": 942000, "dedupeStreams": 211800,
"objectStreams": 54300, "recompressFlate": 41210, "dropOldRevisions": 18210,
"removeUnreferenced": 12890, "coalesceContent": 10000 } }
Example: optimize with the defaults, then write the file
jsonIn: { }
pdf.Optimize("optimize", jsonIn, jsonOut)
pdf.WriteFile("out.pdf")
jsonOut: { "fileSize": 4831022, "bytesSaved": 1236110, "bytesSavedIsEstimate": true,
"actions": { "subsetFonts": { "count": 7, "bytesSaved": 942000 },
"dedupeStreams": { "count": 39, "bytesSaved": 211800 },
"objectStreams": { "bytesSaved": 54300, "estimate": true },
"recompressFlate": { "count": 88, "bytesSaved": 41210 },
"removeUnreferenced": { "count": 17, "bytesSaved": 12890 } },
"skipped": [ { "option": "tidyContent", "pages": "12", "reason": "content could not be parsed; left unchanged" } ] }
Example: override individual options
jsonIn: { "objectStreams": "disable", "dropOldRevisions": false }
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
PreLoadCheck
Reports what can be known about a PDF file's encryption before it is loaded, so that an application can decide which password or certificate it needs: whether the file is encrypted, by which method and algorithm, whether a password is needed to open it, what a user may do with it, or which certificates can open it. Nothing is loaded into this object, and no password is needed. Returns false only when the file cannot be read or is not a PDF; an unencrypted PDF returns true with encrypted false.
Results (json_out)
- encrypted - Boolean. When
false, nothing else is returned. - method -
password, orcertificate(a certificate with its private key is needed to open the file; seeSetDecryptCert). - algorithm -
rc4-40,rc4-128,aes-128,aes-256-r5,aes-256, oraes-256-gcm. - pdfVersion - The version in the file header, such as
1.7, with adobeExtensionLevel or isoExtensionLevel when the file declares one. The declaration is in the document catalog, which an encrypted PDF often stores encrypted (inside an object stream), so the extension level is frequently not reported for a PDF that needs a password to open.ProtectionwithgetInforeports it once the PDF is loaded. - scope -
all,allExceptMetadata, orattachmentsOnly. - openPasswordRequired - Password method only:
falsewhen the file opens with an empty user password (it may still have restrictions). - permissions - Password method only (readable without any password): print (
full,lowQualityornone) and the booleans modify, copy, accessibility, annotate, fillForms and assemble. - recipients[i] - Certificate method only: the issuer and serialNumber of each recipient certificate, which tells the application which certificate it needs.
Example
jsonOut: { "encrypted": true, "method": "password", "algorithm": "aes-256", "pdfVersion": "1.7",
"adobeExtensionLevel": 8, "scope": "all", "openPasswordRequired": false,
"permissions": { "print": "full", "modify": false, "copy": true, "accessibility": true,
"annotate": false, "fillForms": true, "assemble": false } }
Then, typically: if method is certificate, call SetDecryptCert; otherwise if openPasswordRequired is true, set the UserPassword (or OwnerPassword) property; then call LoadFile.Returns error.ChilkatFailed on failure; getLastErrorText explains why.
PreLoadCheckBd
The same as PreLoadCheck, but examines the PDF contained in bd instead of a file. See PreLoadCheck for the members returned in json_out.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
Protection
Encrypts the loaded PDF, removes or changes its encryption, passwords and permissions, or reports its security settings. The op selects the operation, the json_in holds the options, and the json_out receives the resulting security settings. Returns true on success and false on failure.
Every operation except getInfo changes the pending security: the settings the PDF will be saved with. Nothing is encrypted or decrypted until WriteFile or WriteBd is called, and if no operation changed anything, the PDF is saved with exactly the security it was loaded with. An operation that changes nothing is still success (removeEncryption on an unencrypted PDF returns true).
Owner rights
Every operation except getInfo requires owner rights, which means the PDF was not encrypted, or was loaded with its owner password (set the OwnerPassword property before calling LoadFile or LoadBd), or, under certificate security, was opened by a recipient that has the changeSecurity permission. Chilkat does not offer a way to ignore owner restrictions. An operation refused for lack of owner rights returns false and says why in the LastErrorText.
Operations (op)
- encrypt - Replaces the pending security entirely: method, algorithm, scope and permissions from
json_in, and the passwords from theUserPasswordandOwnerPasswordproperties as they are at the time of the call (or the recipients added withAddEncryptCert, for the certificate method). An emptyjson_inencrypts everything with AES-256 (revision 6) using the two password properties and grants every permission. - removeEncryption - The PDF will be saved unencrypted, with no passwords and no restrictions.
- removeRestrictions - Grants every permission; keeps the user password and the algorithm. With an empty user password the result is unencrypted, the same as
removeEncryption. - changePasswords - Takes the new user and owner passwords from the
UserPasswordandOwnerPasswordproperties; the algorithm, scope and permissions are kept. Password security only. - changePermissions - Takes new permissions from the
permissionsobject injson_in(the same object as forencrypt); passwords, algorithm and scope are kept. The object is the complete new set of permissions, not a change to the existing ones: as forencrypt, a permission it does not mention is granted, whatever the PDF had before. - getInfo - Changes nothing; reports the security the PDF was loaded with and the security it will be saved with.
changePermissions and removeRestrictions are refused unless UserPassword was also set when the PDF was loaded; changePasswords and encrypt work because they set both passwords afresh.
Summary of JSON Options for encrypt (json_in)
- method -
password(the default) orcertificate. The certificate method encrypts for the recipients whose certificates were added withAddEncryptCert; a recipient opens the PDF with the matching certificate and private key (seeSetDecryptCert). - algorithmChoice - The encryption algorithm. The PDF version in the file header is raised to what the algorithm requires when the PDF is saved, and never lowered. It can also be raised by the form the file is written in, because object streams and a cross-reference stream are both PDF 1.5 features. The two RC4 choices are the exception: they exist for readers older than PDF 1.5, so a PDF saved with either is always written with a classic cross-reference table and no object streams -- even when
Optimize'sobjectStreamsasked for them -- and its header keeps to the version RC4 itself needs.aes-256- (the default) AES-256, revision 6. Saved as PDF 1.7 with Adobe extension level 8, or as PDF 2.0 if the PDF is already 2.0.aes-256-gcm- AES-256-GCM (ISO/TS 32003), authenticated encryption. Saved as PDF 2.0. Few viewers can open it yet.aes-128- AES-128, revision 4. Saved as PDF 1.6.aes-256-r5- AES-256, Adobe revision 5. Saved as PDF 1.7 with Adobe extension level 3. Deprecated; only for readers that predate revision 6.rc4-128- RC4 128-bit, revision 3. Saved as PDF 1.4, or the document's own version if that is higher, with a classic cross-reference table. Broken; for legacy compatibility only.rc4-40- RC4 40-bit, revision 2. Saved as PDF 1.3, or the document's own version if that is higher, with a classic cross-reference table. Broken; for legacy compatibility only.
- scope - What is encrypted.
all- (the default) Everything.allExceptMetadata- Everything except the XMP metadata stream, which stays readable so that indexers can read the title, author and keywords. Needsaes-128or later.attachmentsOnly- Only the embedded files; pages, metadata and everything else stay readable, and viewers ask for the password when an attachment is opened. Needsaes-128or later and a non-emptyUserPassword.
- permissions - An object with what a user who opens the PDF without the owner password may do. Every permission is granted by default.
- print -
full(the default),lowQuality, ornone.lowQualityis honored fromrc4-128on. - modify - Boolean. Changes other than those covered by the permissions below.
- copy - Boolean. Copying and extracting text and graphics.
- accessibility - Boolean. Extraction for screen readers. PDF 2.0 readers always allow it, so it has no effect with
aes-256oraes-256-gcm. - annotate - Boolean. Adding or changing annotations; also allows filling forms.
- fillForms - Boolean. Filling existing form fields even when
annotateis false. - assemble - Boolean. Inserting, deleting and rotating pages, and creating bookmarks.
- changeSecurity - Boolean (default false). Certificate method only: the recipient has owner rights (may change or remove the security), and every other permission is implied. The encrypting program normally gives its own certificate this permission so that the file can be managed later.
rc4-40onlyprint(as none or full),modify,copyandannotateexist; the rest are ignored. - print -
- recipientPermissions[n] - Certificate method only: a permissions object (as above) for the nth certificate added with
AddEncryptCert, overridingpermissionsfor that recipient.
Passwords
encrypt and changePasswords read the UserPassword and OwnerPassword properties at the time of the call. An empty UserPassword gives a PDF that opens without a prompt but keeps its restrictions. encrypt with the password method refuses an empty OwnerPassword whenever any permission is restricted, since anyone would then have owner rights and the restrictions would mean nothing; an empty OwnerPassword is allowed when every permission is granted. With aes-256 and aes-256-gcm a password can be any Unicode text up to 127 bytes as UTF-8; with the older algorithms it is limited to 32 Latin characters, and encrypt fails if a password cannot be represented.
Results (json_out)
getInfo returns changed (whether the pending security differs from the loaded security; when false, saving keeps the original security), loaded (the security the PDF was loaded with) and pending (the security it will be saved with). Every other operation returns changed and pending. While changed is false, pending is the loaded security exactly as the file has it: the same as loaded, without openedWith. Each of loaded and pending is an object with:
- encrypted - Boolean. An unencrypted state is just
{ "encrypted": false }. - method -
passwordorcertificate. - algorithm - The same values as
algorithmChoice. - pdfVersion - The PDF version, such as
1.7, with adobeExtensionLevel or isoExtensionLevel when one applies. - scope -
all,allExceptMetadata, orattachmentsOnly. - userPasswordRequired, ownerPasswordSet - Password method: whether a password is needed to open the PDF, and whether the owner password is non-empty (when
false, anyone has owner rights). - openedWith - In
loadedonly:owner,user,emptyPassword,certificate,notOpened, ornotEncrypted. - permissions - Password method: the permissions object as above (without
changeSecurity). - recipients[i] - Certificate method: each recipient's issuer and serialNumber, and its permissions (including
changeSecurity). Inloaded, only the recipient that opened the PDF has readable permissions; inpending, every recipient shows its permissions.
Signed PDFs
A change of security means rewriting the whole file, which invalidates every signature. With PreserveSignatures true (the default), every operation except getInfo fails on a signed PDF; with it false, the change is allowed and the signatures are invalidated.
Example: open password, no copying, low-quality printing
pdf.UserPassword = "open-me"
pdf.OwnerPassword = "admin-secret"
jsonIn: { "permissions": { "print": "lowQuality", "copy": false } }
pdf.Protection("encrypt", jsonIn, jsonOut) -- AES-256 revision 6 by default
pdf.WriteFile("protected.pdf") -- saved as PDF 1.7, Adobe extension level 8
Example: getInfo
jsonOut: { "changed": true,
"loaded": { "encrypted": true, "method": "password", "algorithm": "aes-128", "pdfVersion": "1.6",
"scope": "all", "userPasswordRequired": true, "ownerPasswordSet": true, "openedWith": "owner",
"permissions": { "print": "lowQuality", "modify": false, "copy": false, "accessibility": true,
"annotate": false, "fillForms": true, "assemble": false } },
"pending": { "encrypted": true, "method": "password", "algorithm": "aes-256", "pdfVersion": "1.7",
"adobeExtensionLevel": 8, "scope": "all", "userPasswordRequired": true, "ownerPasswordSet": true,
"permissions": { "print": "full", "modify": false, "copy": false, "accessibility": true,
"annotate": false, "fillForms": true, "assemble": false } } }
Example: encrypt for two recipients
pdf.AddEncryptCert(aliceCert)
pdf.AddEncryptCert(bobCert)
jsonIn: { "method": "certificate",
"recipientPermissions": [ { "changeSecurity": true }, { "modify": false } ] }
pdf.Protection("encrypt", jsonIn, jsonOut)
Example: remove encryption (needs the owner password)
pdf.OwnerPassword = "admin-secret"
pdf.LoadFile("protected.pdf")
pdf.Protection("removeEncryption", jsonIn, jsonOut)
pdf.WriteFile("plain.pdf")
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
SetDecryptCert
Sets the certificate (with its private key) used to open a certificate-encrypted PDF. Call it before LoadFile or LoadBd. The certificate must be one of the PDF's recipients and must have its private key available, such as a certificate loaded from a PFX/.p12 file or from the Windows certificate store. Use PreLoadCheck to learn whether a PDF is certificate-encrypted and which recipient certificates (by issuer and serial number) can open it.
On Windows, calling this method is not needed for a certificate that is installed with its private key in the Windows certificate store (Current User or Local Machine): the store is searched for the private key of each recipient when a certificate-encrypted PDF is loaded.
For password-encrypted PDFs, set the OwnerPassword or UserPassword property instead.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
SetHttpObj
Sets the HTTP object to be used to communicate with the timestamp authority (TSA) server for cases where long term validation (LTV) of signatures is desired. The http is used to send the requests, and it allows for connection related settings and timeouts to be set. For example, if HTTP or SOCKS proxies are required, these features can be specified on the http.
The http is also used to send OCSP requests to store OCSP responses in the PDF's document security store (DSS).
SetSignatureJpeg
Provides an optional JPG image to be included in the signature appearance. The JPG data is passed in jpg_data.
Note: JPG images must use the BaseLine format and not the Progressive format. (Programs typically save JPEG's using the BaseLine format as default.)
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
SetSigningCert
Specifies a certificate to be used when signing the PDF. Signing requires both a certificate and private key. In this case, the private key is implicitly specified if the certificate originated from a PFX that contains the corresponding private key, or if on a Windows-based computer where the certificate and corresponding private key are pre-installed.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
SetSigningCert2
Specifies a digital certificate and private key to be used for signing the PDF.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
SignPdf
Signs the open PDF and if successful writes the signed PDF to the ARG3. The json_options contains information and instructions about the signature. This object keeps its state from before the call; to sign the loaded document in place (and sign again, or add a DocTimeStamp, without reloading), use SignPdf2. Starting in v11.7.0, changes pending from other methods are committed before the signature is added. See the examples below for more detailed information about the JSON options listed here.
Signing an encrypted PDF - An encrypted PDF can be signed, with an approval or a certification signature, and stays encrypted: the signature is added with the document's own key and everything it adds is encrypted, except the signature value itself, which PDF never encrypts. The PDF must have been opened (load it with its UserPassword or OwnerPassword). Starting in v11.7.0, a PDF that was not opened with owner rights is signed only if its permissions allow it: adding a new signature field needs both the modify and the annotate permission, and filling in an existing unsigned signature field (appearance.fillUnsignedSignatureField) needs the fillForms or the annotate permission. Otherwise the call fails and the LastErrorText names what is missing; load the PDF with its owner password to sign it regardless of its permissions. (See Protection for a PDF's permissions, and the SIGN_IGNORE_PERMISSIONS keyword of UncommonOptions.)
Summary of PDF Signing Options
- appearance.fillUnsignedSignatureField - Can be set to true) to tell Chilkat to sign an existing unsigned signature field. Chilkat will automatically scale the visual appearance (text + graphics) to fit the pre-existing signature field. When fillUnsignedSignatureField is specified, it is not necessary to set appearance.x, appearance.y, appearance.fontScale, etc.
Starting in v9.5.0.90, the unsignedSignatureField option (see below) can be used to specify the unsigned signature field to be used. Otherwise, the 1st available unsigned field is used.
- appearance.fontScale - The font scale (in pts) to be used, such as
10.0. - appearance.height - Optional to specify the exact height of the visible signature rectangle in points, where 72 points equals 1 inch. If the appearance.height is set, then appearance.width should be set to
auto(or left unset). Chilkat will compute the font scale to achieve the desired rectangle height, and the resulting width will depend on the text. - appearance.image - Indicates an image will be included in the signature. Set to the keyword
custom-jpgto use an image set by calling the SetSignatureJpeg method. Otherwise can be set to one of the following keywords to indicate a built-in SVG graphic. (These are graphics embedded within the Chilkat library itself.)- green-check-grey-circle
- green-check-green-circle
- application-approved
- application-rejected
- document-accepted
- approved
- blue-check-mark
- green-check-mark
- green-check-grey-circle
- red-x-red-circle
- rejected
- result-failure
- result-pass
- signature
- document-check
- document-x
- red-x-grey-circle
- appearance.imageOpacity - Sets the image opacity. Can be an integer from 1 to 100.
- appearance.imagePlacement - Sets the image placment within the signature rectangle. Can be
left,right, orcenter. Images placed in the center typically have opacity 50% or less because the text is displayed over the image (i.e. it is a background image). Images placed left or right are not background images. The signature rectangle is divided into two sub-rectangles, one for the image, and one for the text. - appearance.margin_x - If the appearance.x is set to
left, then this can optionally be use to specify the position from the left edge. The default margin is 10.0 (10 points, where 72 points equals 1 inch). - appearance.margin_y - If the appearance.y is set to
top, then this can optionally be use to specify the position from the top. The default margin for y is 20.0 (20 points, where 72 points equals 1 inch). - appearance.text[i] - The text that should appear in the signature box. Each line is specified in a JSON array item, where
iis an integer starting with0as the 1st line. The text can contain the following keywords which are replaced with actual values:- cert_country - The signing certificate's subject country (C).
- cert_cn - The signing certificate's subject common name (CN).
- cert_dn - The signing certificate's DN (distinguished name).
- cert_email - The signing certificate's subject email address (E).
- cert_issuer_cn - The signing certificate's issuer's common name (CN).
- cert_locality - The signing certificate's subject locality (L).
- cert_organization - The signing certificate's subject organization (O).
- cert_org_id - The signing certificate's organization ID.
- cert_ou - The signing certificate's subject organizational unit (OU).
- cert_san_rfc822name - The signing certificate's RFC822 subject alternative name.
- cert_serial_dec - The signing certificate's serial number in decimal format.
- cert_serial_hex - The signing certificate's serial number in hex format.
- cert_state - The signing certificate's subject state (S).
- cert_thumbprint - The signing certificate's thumbprint (The SHA1 hash of the binary DER representation in hex format).
- current_datetime - Current local date/time in the format such as
Sep 11 2020 16:30:54. - current_dt - Current local date/time in PDF date/time string format, such as YYYY.MM.DD hh:mm:ss -05'00'.
- current_rfc822_dt_gmt - Current GMT date/time in RFC822 format, such as
Mon, 22 Nov 2021 15:58:41 GMT. - current_rfc822_dt_local - Current local date/time in RFC822 format, such as
Mon, 22 Nov 2021 09:56:16 -0600. - current_timestamp_gmt - Current GMT date/time in timestamp format, such as
1990-12-31T23:59:60Z. - current_timestamp_local - Current local date/time in timestamp format, such as
2019-10-12T03:20:50.52-04:00.
- appearance.width - Optional to specify the exact width of the visible signature rectangle in points, where 72 points equals 1 inch. If the appearance.width is set, then appearance.height should be set to
auto(or left unset). Chilkat will compute the font scale to achieve the desired rectangle width, and the resulting height will depend on the text and number of lines of text. - appearance.x - The horizontal position on the page of the left edge of the signature box. Can be a keyword such as
left,right, ormiddleto specify a typical placement with default margins. Otherwise can be a floating point number where 0.0 is the leftmost coordinate of a page, and 612.0 is the right most. Can also be the keywordafterto place the signature just to the right of the rightmost signature on the page. Starting in v11.7.0, if the signature would not fit on the page there, it continues as a line of text does: to the right of the signatures in the lowest row if there is room, and otherwise at the left margin in a new row under the existing signatures. (In earlier versions it was placed to the right of the rightmost signature regardless, and could lie partly or entirely off the page.) - appearance.y - The vertical position on the page of the top edge of the signature box. Can be one of the keywords
toporbottomto specify a typical placement with default margins. Otherwise can be a floating point number where 0.0 is the bottom coordinate of a page, and 792.0 is the top. Can also be the keywordunderto place the signature just under the bottommost signature on the page. Invisible signatures are not counted (starting in v11.7.0; in earlier versions a signature placedunderon a page that had an invisible signature was put below the bottom of the page).Rotated pages - On a page that is displayed rotated (a page with a /Rotate of 90, 180 or 270), appearance.x, appearance.y, the keywords and the margins all refer to the page as it is displayed: x is measured from the displayed left edge and y from the displayed bottom edge, and the signature is upright as the page is read. Starting in v11.7.0 this holds for every rotation. In earlier versions a page rotated by 180 or 270 was treated as if it were not rotated, and on a page rotated by 90 a numeric appearance.y was misplaced.
- contactInfo - Optional to provide free-form text with contact information about the signer.
- docMDP.add - Set this boolean value to true to include the Document MDP Permissions with a certifying signature. When a certifying signature is desired, both
lockAfterSigninganddocMDP.addshould be specified. The default Doc MDP permission level is 2. - docMDP.accessPermissions - Include this if the docMDP.add is specified, and a permission level different from the default value of 2 is desired. Possible values are:
- 1: No changes to the document are permitted and any changes invalidate the signature.
- 2: Permitted changes include filling in forms, instantiating page templates and signing.
- 3: Same as 2, but also allow annotation creation, deletion, and modification.
- embedCertChain - Boolean to control whether the certificate chain is included in the signature. The default is to include the certificates in the chain of authentication. Set this to false to only include the signing certificate (this is not common).
- hashAlgorithm - If the signing certificate is RSA-based, and the signing scheme (padding scheme) is RSA-PSS, then this specifies the PSS hash algorithm. Can be
sha1,sha256,sha384, orsha512. (sha256is what should be commonly chosen.) - includeRootCert - Boolean to control whether the root CA certificate is included in the certificate chain (assuming the certificate chain is included). The default is to include the root CA certificate. Set this to false to exclude the root CA certificate from being included (this is not common).
- info.* - (added in Chilkat v9.5.0.90) Provides the ability to add or update the PDF document's
/Info, such asCreator,Producer,Title, etc. Any number of arbitrary member names can be specified and these will be added to the document's /Info dictionary. However, Chilkat will ignoreModDateandCreationDatebecause ModDate is automatically set to the current system date/time and the CreationDate should not change. - invisibleSignature - Set this boolean to true to create an invisible signature with no appearance.
- legalAttestation - Set to provide a free-form text legal attestation.
- location - Optional to provide free-form text with a description of the geographic location where the PDF was signed.
- lockAfterSigning - Set this boolean to true to certify and lock a PDF as opposed to adding an approval signature (the default) which allows for additional countersignatures.
- ltvOcsp - Set this boolean to true to create an LTV-enabled signature.
- noDss - Set this boolean to true to prevent adding a /DSS (Document Security Store).
- page - The page number where the signature will be placed. Page 1 is the 1st page.
- reason - Optional to provide text indicating the reason for the signature.
- signingAlgorithm - If the signing certificate is RSA-based, then chooses the RSA padding scheme. Possible values are
pkcsfor PKCS-v1_5 orpssfor RSASSA-PSS. - signingCertificateV2 - Set to
1to include theSigningCertificateV2authenticated attribute. This is desired in most cases. - signingTime - Set to
1to include theSigningTimeauthenticated attribute. This is desired in most cases. Note: This is not the same as time-stamping. This is a fundamental authenticated attribute that should be included with or without the addition of time-stamping. - sigTextLabel - Set to provide free-form text for the signatures annotation text label, which is the name of the new signature field. If not set, the field is named
Signature2,Signature3, and so on. Starting in v11.7.0 a name that a field of the PDF already has is skipped; in earlier versions a PDF with an unsigned field of that name got a second field of the same name, and viewers did not show the new signature. - subFilter - Set to
/ETSI.CAdES.detached,/adbe.pkcs7.detached, or something else. - timestampToken.enabled - Set to true to tell Chilkat to request a timestamp from a TSA server and include the timestamp token in the signature's authentication attributes
- timestampToken.tsaUrl - The timestamp server's URL.
- timestampToken.tsaUsername, timestampToken.tsaPassword - If the timestamp server requires a login and password.
- timestampToken.bearerToken - Use this if the timestamp server requires a bearer token instead of a password. This feature was added in Chilkat
v11.2.0. - timestampToken.requestTsaCert - Set to true to ask the timestamp server to include its certificate in the timestamp token.
- unsignedSignatureField - (added in Chilkat v9.5.0.90) Can be set to specify the name of the unsigned signature field that is to be signed.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
SignPdf2
The same as SignPdf, except that the signed PDF stays in memory instead of being written to a file. Call WriteFile or WriteBd to write it, or go on to other operations first: the signature is part of the loaded document as soon as this method returns, so NumSignatures and VerifySignature see it, and a second call adds another signature (or a DocTimeStamp) on top of it.
Changes pending from other methods (a watermark added, a security change, an optimization, replaced text) are committed first, so the signature covers the document's current state; the signature itself is added as an incremental update, which leaves earlier signatures valid. See SignPdf for the members of json_options.
Returns true on success and false on failure.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
SignPdfBd
Signs the open PDF and if successful writes the signed PDF to the bd. The json_options contains information and instructions about the signature. This object keeps its state from before the call; to sign the loaded document in place (and sign again, or add a DocTimeStamp, without reloading), use SignPdf2. Starting in v11.7.0, changes pending from other methods are committed before the signature is added. See the reference documentation for the SignPdf method for details about json_options.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
TextReplace
Replaces text in the page content of the loaded PDF: placeholders such as {{name}}, and the values that follow labels such as Invoice #:. The op selects the operation, the json_in names the values to put in, and the json_out receives a report. Returns true on success and false on failure; for apply, false also when the replacements could not be made, in which case the PDF is unchanged and the report says why.
A PDF stores positioned glyphs drawn with particular fonts, not editable text, so a replacement is only possible when the new text can be drawn with the font the original used. Chilkat finds each placeholder or label on the assembled lines of the selected pages, encodes the new value with that font and size, recomputes its width, and rewrites the content stream in place. The font rule: a standard-14 font (Helvetica, Times, Courier and their faces, or a non-embedded font that every viewer substitutes with one of them: Arial, Times New Roman, Courier New) can draw any character its encoding has; an embedded font can draw any character it has a glyph for; any other font that is not embedded cannot be used. Every replacement is checked first, and apply is all or nothing: if any replacement fails the rule, nothing is changed.
Operations (op)
- check - Finds every placeholder and label and applies the font rule, but changes nothing. The report says whether
applywould succeed (ok) and lists the problems. - apply - The same, then makes the replacements when there are no problems. The changes are written when
WriteFileorWriteBdis called; the PDF is then saved as a full rewrite, so that the old values do not survive in an earlier revision of the file.
Summary of JSON Options (json_in)
- pages - The pages to search. Can be
all(the default),first,last,odd,even, or a list of 1-based pages and ranges such as1,3,5-9,12-. - placeholders - An object whose member names are placeholder names and whose values are the text to put in, such as
{ "customer": "Acme Corp", "total": "$1,234.56" }for the placeholders{{customer}}and{{total}}. A value may be a string, number or boolean;nullmeans an empty string. Every occurrence of a placeholder on the selected pages is replaced. - placeholderSyntax - The delimiters around a placeholder name, written around the word
name: the default is{{name}};[[name]]or<<name>>are other choices. - labels - An array of objects, each with:
- label - The label text as it appears on the page, such as
Invoice #:. Matching ignores case, extra spaces and a trailing colon. - value - The new text. It replaces the rest of the label's line; when nothing follows the label, the value is inserted after it.
- occurrence -
first(the default),all, or a number (2for the second occurrence). Occurrences are counted in reading order across the selected pages.
- label - The label text as it appears on the page, such as
- align -
auto(the default),left,right, orcenter. Where the new text sits when its width differs from the old.autokeeps a placeholder in place when it is right-aligned with other text on the page, or centered on the page, and otherwise keeps the left edge; a label's value is always left-aligned after its label. - unusedPlaceholders - What to do with a placeholder found on the page that has no value in
placeholders:error(the default; a problem with the reasonunusedPlaceholder),blank(replaced by nothing), orkeep(left as it is). - unmatchedValues - What to do with a value whose placeholder or label is not found on the selected pages:
error(the default; a problem with the reasonnotFound) orignore.
Results (json_out)
- applied - Boolean: the replacements were made (
applyonly). - ok - Boolean (
checkonly): no problems were found, soapplywould succeed. - replacements[i] - One entry per placeholder or label that was (or would be) replaced: field (the placeholder name) or label, pages (such as
1,3) and count. - problems[i] - What prevents
apply: field or label, reason, page, and for font problems font and chars (the characters the font cannot draw). The reasons:notFound- The placeholder or label was not found on the selected pages.unusedPlaceholder- A placeholder on the page has no value (seeunusedPlaceholders).missingGlyph- The embedded font has no glyph for one or more characters of the value.notInEncoding- The standard font's encoding has no code for one or more characters of the value.nonStandardUnembeddedFont- The text is drawn with a font that is neither standard-14 nor embedded, so Chilkat has no way to know what it can draw.unsupportedFont- The font cannot be used for new text (a Type 3 font, or a font program that could not be read).placeholderSpansFonts- The placeholder or value is drawn with more than one font or size, so there is no single font to draw the replacement with.
- warnings[i] - Replacements that were made but may not look right: the reason
overlapmeans the new text runs into neighbouring text or off the page. - notReplaced[i] - Placeholders found outside the page content, which this method does not change: field and where (
metadatafor the document's Title, Author, Subject, Keywords, Creator or Producer;linkTargetfor a link's URL;formFieldfor a form field value).
Signed and encrypted PDFs
apply rewrites the page content, which invalidates signatures: on a signed PDF it is refused while PreserveSignatures is true (the default). An encrypted PDF must have been opened, and apply requires owner rights or the modify permission. check only reads.
Example: fill a template
jsonIn: { "placeholders": { "customer": "Acme Corp", "date": "2026-10-18", "total": "$1,234.56" },
"labels": [ { "label": "Invoice #:", "value": "INV-2026-0412" } ] }
pdf.TextReplace("apply", jsonIn, jsonOut)
jsonOut: { "applied": true,
"replacements": [ { "field": "customer", "pages": "1", "count": 1 },
{ "field": "date", "pages": "1", "count": 1 },
{ "field": "total", "pages": "1", "count": 1 },
{ "label": "Invoice #:", "pages": "1", "count": 1 } ],
"warnings": [], "problems": [], "notReplaced": [] }
Example: a check that fails the font rule
jsonIn: { "placeholders": { "customer": "Müller GmbH" } }
pdf.TextReplace("check", jsonIn, jsonOut)
jsonOut: { "applied": false, "ok": false,
"replacements": [],
"problems": [ { "field": "customer", "reason": "missingGlyph", "chars": "ü", "font": "ABCDEF+OpenSans-Regular", "page": 1 } ],
"warnings": [], "notReplaced": [] }
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
UpdateMetadata
Updates or adds XMP metadata to a PDF. The metadata is passed in sb. If successful, the PDF with updated or inserted metadata is written to out_file_path, and the loaded document is the updated PDF. To update the metadata of the loaded document without writing a file, use UpdateMetadata2. Starting in v11.7.0, changes pending from other methods are committed before the metadata is updated.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
UpdateMetadata2
The same as UpdateMetadata, except that the updated PDF stays in memory instead of being written to a file. The XMP metadata is passed in sb and replaces the document's metadata (or is added when the document has none). Call WriteFile or WriteBd to write it, or go on to other operations first: the new metadata is part of the loaded document as soon as this method returns (GetMetadata returns it).
Changes pending from other methods are committed first; the metadata itself is added as an incremental update, which leaves existing signatures valid.
Returns true on success and false on failure.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
UpdateMetadataBd
Updates or adds XMP metadata to a PDF. The metadata is passed in sb. If successful, the PDF with updated or inserted metadata is written to bd, and the loaded document is the updated PDF. See UpdateMetadata.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
VerifySignature
Verifies the Nth signature contained in the PDF, where the 1st signature is indicated by an index of 0. Returns true if the signature valid, otherwise returns false. The sig_info is an output argument and is populated with information about the validated or unvalidated signature.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
Watermark
Adds, detects, lists and removes watermarks in the loaded PDF. The op selects the operation, the json_in holds the options or the filter, and the json_out receives the result. Returns true on success and false on failure. Finding nothing is still success: detect returns true with found false, and remove returns true with removed 0. Changes are made in memory and are written when WriteFile or WriteBd is called.
Operations (op)
- add - Adds one watermark (text, an image, or a page of another PDF) to the selected pages.
json_outreceives theidof the new watermark and thepagesit was added to. A text watermark plus a logo is two calls. - detect - Answers whether any watermark matching the filter is present.
json_outreceivesfoundandcount. - list - Enumerates the matching watermarks with their properties.
json_outreceivescountand awatermarksarray. - remove - Removes the matching watermarks.
json_outreceivesremoved, the number removed. An empty filter is refused unlessallis true.
How a watermark is stored (the approach)
The approach member of json_in selects how an added watermark is stored, which decides whether it can be found and removed later:
- artifact - (the default) Marked content tagged as a Watermark or Background artifact. Visible in all viewers, removable later, skipped by text extraction.
- annotation - A Watermark annotation. Always drawn on top, removable later; the only approach allowed on a signed PDF while
PreserveSignaturesis true. - layer - An optional-content layer, which the viewer's layers panel can hide, and which can be made print-only. Removable later.
- content - Drawn directly into the page content with no identifying marker. Visible in all viewers and the tamper-resistant choice, but by design it cannot be listed or removed afterwards.
content, Chilkat stores a private identifier with the watermark; that is what lets list and remove target it later.
Summary of JSON Options for add (json_in)
Only type and the content for that type are required; every other member has a default. Members are given as dotted paths, as used with the JsonObject update methods.
General
- approach -
artifact(the default),annotation,layer, orcontent. See above. - id - A string identifying the watermark, returned in
json_outand used bylistandremove. Generated when not given. An id already present in the document is refused. Not stored for thecontentapproach. - label - A free-form description stored with the watermark and returned by
list. - zOrder -
front(the default) orback: in front of or behind the existing page content. Ignored for theannotationapproach, which is always in front. - pages - The pages to stamp. Can be
all(the default),first,last,odd,even, or a list of 1-based pages and ranges such as1,3,5-9,12-. - excludePages - A range list of pages to leave out, applied after
pages. - units -
pt(the default),in,mm, orcm: the units of the image size, wrap width, padding, margins, offsets, maximum sizes and tile spacing. Font size, outline width and border width are always in points. - pageBox -
crop(the default) ormedia: the page box that placement is measured against. - followPageRotation - Boolean (default true). Keeps the watermark upright for the reader on pages that have a /Rotate setting.
- type - Required:
text,image, orpdfPage. Any type can be stored with any approach. (barcodeis reserved for a later release; an existing barcode or QR image can be added as animage.) - text - Required for
text. A newline breaks lines. Placeholders are replaced per page:{page}(the page number),{pages}(the page count),{date:FORMAT}(the current local date/time, withyyyy,yy,M/MM,d/dd,H/HH,h/hh,m/mm,s/ssandttfor AM/PM; the format defaults toyyyy-MM-dd), and{filename}(the name of the file loaded byLoadFile).{{gives a literal brace. - image.path or image.base64 - Required for
image: the path of a JPEG or PNG file, or its data in base64. PNG transparency is kept. Interlaced PNGs are not supported. - image.width, image.height - The size to draw the image at. Give one of the two to keep the aspect ratio; the default is the image's natural size.
- pdf.path or pdf.base64 - Required for
pdfPage: another PDF whose page is placed as the watermark, such as a letterhead, a cover overlay, or a vector logo saved as PDF. - pdf.password - The password of the source PDF, if it is encrypted.
- pdf.page - The 1-based page of the source PDF to use (default
1), ormatchto place source page n on target page n, cycling when the source has fewer pages.
- font.name -
Helvetica(the default), another standard-14 font name such asTimes-RomanorCourier, or the path of a TTF/OTF font file, which is embedded as a subset. Symbol and ZapfDingbats are not supported. - font.size - The size in points (default
48), orautoto size the text to the box chosen byscale.fit. - font.bold, font.italic, font.underline, font.strikeout - Booleans (default false). Bold and italic select the matching standard-14 face, or are synthesized for an embedded font file.
- color - The fill color:
#RRGGBB,#RGB, or a color name such asredorgray. The default is#808080. - render -
fill(the default),stroke(outlined, hollow text),fillStroke, orinvisible(present and searchable, but not seen). - outline.color, outline.width - The outline color (default
#000000) and width in points (default1), used bystrokeandfillStroke. - textAlign -
center(the default),left, orright: the alignment of multi-line text within its own box. - lineSpacing - The line spacing as a multiple of the font size. The default is
1.2. - wrapWidth - Wraps long text to this width. The default is no wrapping.
- pageNumber.start - The value of
{page}on the first page. The default is1. - pageNumber.style - The format of
{page}and{pages}:decimal(the default),romanUpper,romanLower,letterUpper, orletterLower. - background.color, background.opacity, background.padding - A box filled behind the stamp (text or image): its color (none by default), opacity (default
1.0) and the space between the content and the box edge (default0). - border.color, border.width - A box stroked around the stamp: its color (none by default) and width in points (default
1).
- opacity - From 0.0 to 1.0 (default
1.0), applied to the whole stamp. - rotation - Degrees counter-clockwise (default
0), ordiagonal(bottom-left to top-right, computed per page size) ordiagonalReverse. - blendMode -
normal(the default),multiply,darken,lighten,screen, oroverlay.multiplymakes a front watermark read as if it were behind scanned pages.
- position.align -
center(the default),top,bottom,left,right,topLeft,topRight,bottomLeft, orbottomRight. - position.margin - The inset from the page edges, used for alignment and fitting: a single number, or an object with
left,top,rightandbottom. The default is0. - position.offsetX, position.offsetY - A nudge from the aligned position (default
0); positive values move right and down. - scale.factor - Multiplies the natural size. The default is
1.0. - scale.fit -
none(the default),page,width, orheight: fits the rotated stamp inside the margin box. - scale.fitPercent - The share of the fit box to fill. The default is
100. - scale.maxWidth, scale.maxHeight - Caps on the final size. No cap by default.
- tile.enabled - Boolean (default false). Repeats the stamp across the page, which overrides
position.align. - tile.spacingX, tile.spacingY - The gaps between tiles. The default is
72points for each. - tile.stagger - Boolean (default true). Offsets alternate rows by half a tile.
- annotation.view, annotation.print - Booleans (default true).
viewfalse withprinttrue gives a print-only watermark. - annotation.locked - Boolean (default true). Users cannot move or delete the annotation in a viewer.
- annotation.fixedPrint - Boolean (default false). Keeps the printed size and position fixed whatever the paper size.
- artifact.subtype -
Watermark(the default) orBackground: the artifact subtype written to the marked content. - artifact.acrobatCompatible - Boolean (default false). Also writes the structure that Acrobat's own watermark tool uses, so that Acrobat can update or remove the watermark.
- layer.name - The name shown in the viewer's layers panel. The default is
Watermark. An existing layer of the same name is reused. - layer.view, layer.print -
on(the default) oroff.viewoff withprinton gives a print-only watermark. - layer.locked - Boolean (default false). Prevents users from toggling the layer in the layers panel.
- link.url - Adds a link annotation over the stamp's area on each page, opening this URL.
The filter for detect, list and remove (json_in)
An empty filter means every watermark in the document. These operations recognize Chilkat's own watermarks and the standard forms other tools write: Watermark annotations from any producer, marked content tagged as a Watermark or Background artifact, Acrobat watermarks and backgrounds (Acrobat headers and footers are not watermarks and are ignored), and optional-content layers whose name contains "watermark".
- pages - Restricts the operation to these pages; the same syntax as for
add. The default isall. - approach -
any(the default), or one ofannotation,artifact,layer,content. - source -
any(the default),chilkat,acrobat, orother: who produced the watermark. - id - An exact match on the watermark's id.
- label - An exact match on a Chilkat label.
- textContains - A case-insensitive match on the watermark's text.
- heuristic - Boolean (default false). Reserved for finding untagged page content that looks like a watermark; accepted but not implemented in this release.
- all - Boolean (default false). For
removeonly: required to remove with an otherwise empty filter.
Results (json_out)
- add - id (the watermark's id, generated or as given) and pages (the pages it was added to, such as
1-12). - detect - found and count.
- list - count and watermarks[i] with id, label, source (
chilkat,acrobatorother), approach, type, text, zOrder, opacity, rotation, removable and pages. Watermarks from other producers have no id of their own, so Chilkat assigns one (ext1,ext2, ...) that stays valid until the PDF is changed, so that alistfollowed by aremoveby id works. Properties that cannot be read back are omitted rather than guessed. - remove - removed, the number of watermarks removed. An annotation is deleted; an artifact's marked content, and any form XObject used only by it, is deleted; a layer's content is deleted, and the layer itself once nothing else uses it.
contentwatermarks are never removable.
Signed and encrypted PDFs
On a signed PDF with PreserveSignatures true (the default), only the annotation approach can be added and nothing can be removed, because any other change to the page content would invalidate the signatures. Set PreserveSignatures to false to allow such changes. An encrypted PDF must have been opened (see the OwnerPassword and UserPassword properties), and adding or removing requires owner rights or the modify permission.
Example: diagonal CONFIDENTIAL across every page, removable later
jsonIn: { "type": "text", "text": "CONFIDENTIAL", "id": "conf",
"color": "#C00000", "opacity": 0.25, "rotation": "diagonal",
"scale": { "fit": "page", "fitPercent": 80 } }
jsonOut: { "id": "conf", "pages": "1-12" }
Example: company logo bottom-right, printed only
jsonIn: { "approach": "layer", "type": "image", "image": { "path": "logo.png", "width": 1.5 },
"units": "in", "layer": { "name": "Print logo", "view": "off", "print": "on" },
"position": { "align": "bottomRight", "margin": 0.5 } }
Example: tiled user ID behind the content
jsonIn: { "type": "text", "text": "jdoe@example.com {date:yyyy-MM-dd}", "zOrder": "back",
"font": { "size": 14 }, "opacity": 0.15, "rotation": 30,
"tile": { "enabled": true, "spacingX": 60, "spacingY": 80 } }
Example: letterhead behind page 1 from another PDF
jsonIn: { "approach": "artifact", "artifact": { "subtype": "Background" },
"type": "pdfPage", "zOrder": "back", "pages": "first",
"pdf": { "path": "letterhead.pdf", "page": 1 }, "scale": { "fit": "page" } }
Example: list, then remove every Acrobat watermark
list: jsonIn: { "source": "acrobat" }
jsonOut: { "count": 1, "watermarks": [ { "id": "ext1", "source": "acrobat", "approach": "artifact",
"type": "text", "text": "DRAFT", "opacity": 0.3, "rotation": 45, "removable": true, "pages": "1-4" } ] }
remove: jsonIn: { "source": "acrobat" }
jsonOut: { "removed": 1 }
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
WriteBd
The same as WriteFile, but the PDF is written to bd (a BinData object) instead of a file. See WriteFile for what is written and when the file is rewritten in full.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
WriteFile
Writes the loaded PDF, with every change made since it was loaded, to the file at path. The changes written are those made by Watermark (add and remove), Protection, Optimize and TextReplace (apply), which are kept in memory until this method or WriteBd is called. Files embedded with AddEmbeddedFiles2 are already part of the loaded document and are written as well. Returns true on success and false on failure.
When nothing requires more, the PDF is written as an incremental update: the original bytes are kept and the changes are appended, which leaves existing digital signatures valid. The file is written in full (a rewrite) when a change requires it: an Optimize with dropOldRevisions or generated object streams, a change of security by Protection, or a TextReplace apply. A rewrite invalidates existing signatures, which is why those operations are refused on a signed PDF while PreserveSignatures is true.
After writing, this object reloads the PDF it wrote, so that later calls work on the saved state. With no changes pending, the PDF is written as it was loaded.
To sign a PDF, use SignPdf2, which adds the signature to the loaded document (this method then writes it), or SignPdf / SignPdfBd, which write the signed PDF themselves.
Returns error.ChilkatFailed on failure; getLastErrorText explains why.
Events
All Chilkat methods are synchronous: the call returns when the work is done. During a call, Pdf raises three events so your program can show progress and offer a way out. Declare any subset of abortCheck, percentDone and progressInfo in a struct of your own and install a pointer to it with setEventHandler:
const Progress = struct {
pub fn percentDone(_: *Progress, pct: i32) bool {
std.debug.print("{d}%\n", .{pct});
return false; // return true to abort the method in progress
}
pub fn progressInfo(_: *Progress, name: [:0]const u8, value: [:0]const u8) void {
std.debug.print("{s}: {s}\n", .{ name, value });
}
};
var progress = Progress{};
pdf.setEventHandler(&progress); // progress must outlive the installation
defer pdf.clearEventHandler();
pdf.setHeartbeatMs(250); // abortCheck 4 times per second during Chilkat callsInstalls handler, a pointer to any struct, as the receiver of this object's events, replacing any handler installed earlier. The dispatch is resolved at compile time: only the methods the struct declares are called, and a struct declaring none of the three is a compile error. The struct must stay alive, at the same address, until clearEventHandler or deinit.
Removes the handler; events are no longer delivered.
AbortCheck fires at regular intervals controlled by the HeartbeatMs property (0, the default, disables it); PercentDone fires when an operation's completion percentage is known; ProgressInfo delivers named progress values. Returning true from abortCheck or percentDone aborts the running method, which then returns error.ChilkatFailed.
Events fire on the thread that called the method, before that method returns. To abort a long operation from another thread, have abortCheck read a std.atomic.Value(bool), or set the object's AbortCurrent property.
AbortCheck
pub fn abortCheck(self: *T) bool
Enables a method call to be aborted by triggering the AbortCheck event at intervals defined by the HeartbeatMs property. If HeartbeatMs is set to its default value of 0, no events will occur. For instance, set HeartbeatMs to 200 to trigger 5 AbortCheck events per second.
Example
const Abort = struct {
stop: std.atomic.Value(bool) = .init(false),
pub fn abortCheck(self: *Abort) bool {
return self.stop.load(.acquire); // another thread may call abort.stop.store(true, .release)
}
};
var abort = Abort{};
pdf.setHeartbeatMs(250); // call abortCheck 4 times per second
pdf.setEventHandler(&abort);
defer pdf.clearEventHandler();PercentDone
pub fn percentDone(self: *T, pct: i32) bool
This provides the percentage completion for any method involving network communications or time-consuming processing, assuming the progress can be measured as a percentage. This event is triggered only when it's possible and logical to express the operation's progress as a percentage. The pctDone argument will range from 1 to 100. For methods that finish quickly, the number of PercentDone callbacks may vary, but the final callback will have pctDone equal to 100. For longer operations, callbacks will not exceed one per percentage point (e.g., 1, 2, 3, ..., 98, 99, 100).
The PercentDone callback also acts as an AbortCheck event. For fast methods where PercentDone fires, an AbortCheck event may not trigger since the PercentDone callback already provides an opportunity to abort. For longer operations, where time between PercentDone callbacks is extended, AbortCheck callbacks enable more responsive operation termination.
To abort the operation, set the abort output argument to true. This will cause the method to terminate and return a failure status or corresponding failure value.
Example
const Progress = struct {
pub fn percentDone(_: *Progress, pct: i32) bool {
// pct ranges from 1 to 100.
std.debug.print("Percent done: {d}\n", .{pct});
return false; // return true to abort the method in progress
}
};
var progress = Progress{};
pdf.setEventHandler(&progress);
defer pdf.clearEventHandler();ProgressInfo
pub fn progressInfo(self: *T, name: [:0]const u8, value: [:0]const u8) void
This event callback provides tag name/value pairs that detail what occurs during a method call. To discover existing tag names, create code to handle the event, emit the pairs, and review them. Most tag names are self-explanatory.
Note: Some Chilkat methods don't fire any ProgressInfo events.
Example
const Info = struct {
pub fn progressInfo(_: *Info, name: [:0]const u8, value: [:0]const u8) void {
std.debug.print("{s}: {s}\n", .{ name, value });
}
};
var info = Info{};
pdf.setEventHandler(&info);
defer pdf.clearEventHandler();