modern-pdf-lib 0.29.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/browser.cjs +29 -3
- package/dist/browser.d.cts +5 -5
- package/dist/browser.d.mts +5 -5
- package/dist/browser.mjs +4 -4
- package/dist/{compressionAnalysis-InMeGrqw.d.mts → compressionAnalysis-0m5jJG1_.d.mts} +2 -2
- package/dist/{compressionAnalysis-CyBVhRU5.d.cts.map → compressionAnalysis-0m5jJG1_.d.mts.map} +1 -1
- package/dist/{compressionAnalysis-CyBVhRU5.d.cts → compressionAnalysis-CSBcmi0_.d.cts} +2 -2
- package/dist/{compressionAnalysis-InMeGrqw.d.mts.map → compressionAnalysis-CSBcmi0_.d.cts.map} +1 -1
- package/dist/create.cjs +2 -2
- package/dist/create.d.cts +2 -2
- package/dist/create.d.mts +2 -2
- package/dist/create.mjs +2 -2
- package/dist/{fontEmbed-N-VWoZ0F.d.mts → fontEmbed-Bzv89wgp.d.mts} +2 -2
- package/dist/{fontEmbed-DxtdZxUj.d.cts.map → fontEmbed-Bzv89wgp.d.mts.map} +1 -1
- package/dist/{fontEmbed-DxtdZxUj.d.cts → fontEmbed-Dwl1XeEA.d.cts} +2 -2
- package/dist/{fontEmbed-N-VWoZ0F.d.mts.map → fontEmbed-Dwl1XeEA.d.cts.map} +1 -1
- package/dist/{index--7OpQy6B.d.cts → index-CTL7WUTU.d.cts} +600 -61
- package/dist/index-CTL7WUTU.d.cts.map +1 -0
- package/dist/{index-Cai7jC6u.d.mts → index-D8FO08WM.d.mts} +600 -61
- package/dist/index-D8FO08WM.d.mts.map +1 -0
- package/dist/index.cjs +29 -3
- package/dist/index.d.cts +5 -5
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +4 -4
- package/dist/{layout-DiO_3JLh.cjs → layout-BYXpcYtC.cjs} +2 -2
- package/dist/{layout-D035GpU8.mjs → layout-xOcesNCh.mjs} +2 -2
- package/dist/parse.cjs +1 -1
- package/dist/parse.d.cts +2 -2
- package/dist/parse.d.mts +2 -2
- package/dist/parse.mjs +1 -1
- package/dist/{pdfDocument-5Do0LKQh.d.cts → pdfDocument-B-8iPl_j.d.mts} +85 -3
- package/dist/pdfDocument-B-8iPl_j.d.mts.map +1 -0
- package/dist/{pdfDocument-B_0VSUHL.d.mts → pdfDocument-B8tQcZqj.d.cts} +85 -3
- package/dist/pdfDocument-B8tQcZqj.d.cts.map +1 -0
- package/dist/{pdfDocument-BaQlOkYr.cjs → pdfDocument-Bh4ebDqE.cjs} +41 -2
- package/dist/{pdfDocument-B6czyaVI.mjs → pdfDocument-Cgkkk8F8.mjs} +41 -2
- package/dist/{src-Ci9ZjqhP.mjs → src-B7SQNDvy.mjs} +1004 -9
- package/dist/{src-DQ63jYIR.cjs → src-VeeIdf7B.cjs} +1159 -8
- package/package.json +1 -1
- package/dist/index--7OpQy6B.d.cts.map +0 -1
- package/dist/index-Cai7jC6u.d.mts.map +0 -1
- package/dist/pdfDocument-5Do0LKQh.d.cts.map +0 -1
- package/dist/pdfDocument-B_0VSUHL.d.mts.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_pdfDocument = require("./pdfDocument-
|
|
1
|
+
const require_pdfDocument = require("./pdfDocument-Bh4ebDqE.cjs");
|
|
2
2
|
const require_pdfObjects = require("./pdfObjects-BcPlSI0a.cjs");
|
|
3
3
|
const require_streamDecode = require("./streamDecode-kQ-REV7v.cjs");
|
|
4
4
|
const require_pdfForm = require("./pdfForm-BVS_do95.cjs");
|
|
@@ -277,7 +277,7 @@ function compressStream(stream, level) {
|
|
|
277
277
|
* @returns The incremental save result.
|
|
278
278
|
*/
|
|
279
279
|
async function saveDocumentIncremental(originalBytes, doc, options) {
|
|
280
|
-
const { buildDocumentStructure } = await Promise.resolve().then(() => require("./pdfDocument-
|
|
280
|
+
const { buildDocumentStructure } = await Promise.resolve().then(() => require("./pdfDocument-Bh4ebDqE.cjs")).then((n) => n.pdfCatalog_exports);
|
|
281
281
|
const registry = doc.getRegistry();
|
|
282
282
|
const structure = buildDocumentStructure(doc.getInternalPages().map((p) => p.finalize()), {
|
|
283
283
|
producer: doc.getProducer(),
|
|
@@ -17060,7 +17060,7 @@ const SECTION_TYPES = /* @__PURE__ */ new Set([
|
|
|
17060
17060
|
"BlockQuote"
|
|
17061
17061
|
]);
|
|
17062
17062
|
/** Illustration types that require alt text per PDF/UA. */
|
|
17063
|
-
const ILLUSTRATION_TYPES = /* @__PURE__ */ new Set([
|
|
17063
|
+
const ILLUSTRATION_TYPES$1 = /* @__PURE__ */ new Set([
|
|
17064
17064
|
"Figure",
|
|
17065
17065
|
"Formula",
|
|
17066
17066
|
"Form"
|
|
@@ -17403,7 +17403,7 @@ function findPreviousHeadingInSection(current, sectionHeadings) {
|
|
|
17403
17403
|
*/
|
|
17404
17404
|
function checkAltText(elements, errors) {
|
|
17405
17405
|
for (const elem of elements) {
|
|
17406
|
-
if (!ILLUSTRATION_TYPES.has(elem.type)) continue;
|
|
17406
|
+
if (!ILLUSTRATION_TYPES$1.has(elem.type)) continue;
|
|
17407
17407
|
if (elem.options.artifact) continue;
|
|
17408
17408
|
if (elem.options.altText === void 0 && elem.options.actualText === void 0) errors.push({
|
|
17409
17409
|
code: "UA-STRUCT-005",
|
|
@@ -29946,6 +29946,1001 @@ var RenderCache = class {
|
|
|
29946
29946
|
}
|
|
29947
29947
|
};
|
|
29948
29948
|
//#endregion
|
|
29949
|
+
//#region src/compliance/afAttach.ts
|
|
29950
|
+
/**
|
|
29951
|
+
* @module compliance/afAttach
|
|
29952
|
+
*
|
|
29953
|
+
* Attach embedded / associated files to any PDF object.
|
|
29954
|
+
*
|
|
29955
|
+
* The Associated Files mechanism (`/AF`) lets a PDF declare that one or more
|
|
29956
|
+
* embedded files are *associated* with a given object. ISO 32000-2 allows the
|
|
29957
|
+
* `/AF` key on the document catalog (§7.11.4) as well as on individual objects
|
|
29958
|
+
* — page dictionaries, annotation dictionaries, Form/Image XObject stream
|
|
29959
|
+
* dictionaries, and structure elements (§14.13). Because every one of those
|
|
29960
|
+
* targets is a plain {@link PdfDict}, the same helper attaches `/AF` uniformly.
|
|
29961
|
+
*
|
|
29962
|
+
* In addition, a *document-level* associated file must also be reachable
|
|
29963
|
+
* through the catalog's embedded-files name tree
|
|
29964
|
+
* (`/Names` → `/EmbeddedFiles` → `/Names`). {@link createAssociatedFile} (in
|
|
29965
|
+
* `associatedFiles.ts`) intentionally leaves that wiring to the caller;
|
|
29966
|
+
* {@link registerEmbeddedFile} completes it.
|
|
29967
|
+
*
|
|
29968
|
+
* These are pure builders: they mutate the supplied dictionaries in place and
|
|
29969
|
+
* return nothing. Object numbers / serialization remain the writer's concern.
|
|
29970
|
+
*
|
|
29971
|
+
* Reference: ISO 32000-2:2020, §7.11.4 (embedded file streams) and §14.13
|
|
29972
|
+
* (associated files).
|
|
29973
|
+
*/
|
|
29974
|
+
/**
|
|
29975
|
+
* Attach one or more associated files to any PDF object via its `/AF` key.
|
|
29976
|
+
*
|
|
29977
|
+
* Works uniformly for the document catalog, a page dictionary, an annotation
|
|
29978
|
+
* dictionary, a Form/Image XObject stream's dictionary, or a structure-element
|
|
29979
|
+
* dictionary — all of which are plain {@link PdfDict} instances.
|
|
29980
|
+
*
|
|
29981
|
+
* If `target` has no `/AF` yet, a fresh array (built with
|
|
29982
|
+
* {@link buildAfArray}) is set. If `/AF` is already a {@link PdfArray}, the
|
|
29983
|
+
* new refs are appended to it, preserving the existing entries and order. Any
|
|
29984
|
+
* other (malformed) `/AF` value is replaced with a fresh array.
|
|
29985
|
+
*
|
|
29986
|
+
* @param target The object dictionary to attach the files to.
|
|
29987
|
+
* @param fileSpecRefs Indirect references to file-specification dictionaries.
|
|
29988
|
+
*/
|
|
29989
|
+
function attachAssociatedFiles(target, fileSpecRefs) {
|
|
29990
|
+
const existing = target.get("/AF");
|
|
29991
|
+
if (existing instanceof require_pdfObjects.PdfArray) {
|
|
29992
|
+
for (const ref of fileSpecRefs) existing.push(ref);
|
|
29993
|
+
return;
|
|
29994
|
+
}
|
|
29995
|
+
target.set("/AF", buildAfArray([...fileSpecRefs]));
|
|
29996
|
+
}
|
|
29997
|
+
/**
|
|
29998
|
+
* Locate the `/EmbeddedFiles` name-tree `/Names` array on the catalog,
|
|
29999
|
+
* creating the intermediate `/Names` and `/EmbeddedFiles` dictionaries (and
|
|
30000
|
+
* the leaf `/Names` array) if they do not yet exist. Existing dictionaries
|
|
30001
|
+
* are reused in place rather than replaced.
|
|
30002
|
+
*/
|
|
30003
|
+
function ensureEmbeddedFilesNames(catalog) {
|
|
30004
|
+
const namesEntry = catalog.get("/Names");
|
|
30005
|
+
const namesDict = namesEntry instanceof require_pdfObjects.PdfDict ? namesEntry : new require_pdfObjects.PdfDict();
|
|
30006
|
+
if (namesDict !== namesEntry) catalog.set("/Names", namesDict);
|
|
30007
|
+
const efEntry = namesDict.get("/EmbeddedFiles");
|
|
30008
|
+
const efDict = efEntry instanceof require_pdfObjects.PdfDict ? efEntry : new require_pdfObjects.PdfDict();
|
|
30009
|
+
if (efDict !== efEntry) namesDict.set("/EmbeddedFiles", efDict);
|
|
30010
|
+
const leafEntry = efDict.get("/Names");
|
|
30011
|
+
const leaf = leafEntry instanceof require_pdfObjects.PdfArray ? leafEntry : new require_pdfObjects.PdfArray();
|
|
30012
|
+
if (leaf !== leafEntry) efDict.set("/Names", leaf);
|
|
30013
|
+
return leaf;
|
|
30014
|
+
}
|
|
30015
|
+
/**
|
|
30016
|
+
* Insert a `[name, fileSpecRef]` pair into an embedded-files name-tree `/Names`
|
|
30017
|
+
* array, keeping the array sorted by name. The array is a flat sequence of
|
|
30018
|
+
* alternating key/value entries: `[ name0, ref0, name1, ref1, … ]`.
|
|
30019
|
+
*/
|
|
30020
|
+
function insertNamePairSorted(leaf, name, fileSpecRef) {
|
|
30021
|
+
const items = leaf.items;
|
|
30022
|
+
let insertAt = items.length;
|
|
30023
|
+
for (let i = 0; i < items.length; i += 2) {
|
|
30024
|
+
const entry = items[i];
|
|
30025
|
+
if ((entry instanceof require_pdfObjects.PdfString ? entry.value : "") > name) {
|
|
30026
|
+
insertAt = i;
|
|
30027
|
+
break;
|
|
30028
|
+
}
|
|
30029
|
+
}
|
|
30030
|
+
items.splice(insertAt, 0, require_pdfObjects.PdfString.literal(name), fileSpecRef);
|
|
30031
|
+
}
|
|
30032
|
+
/**
|
|
30033
|
+
* Complete {@link createAssociatedFile}'s "caller responsibility" by wiring a
|
|
30034
|
+
* file-specification reference into the document catalog at the *document
|
|
30035
|
+
* level*.
|
|
30036
|
+
*
|
|
30037
|
+
* Two things happen:
|
|
30038
|
+
* 1. The pair `[PdfString.literal(name), fileSpecRef]` is added to the
|
|
30039
|
+
* catalog's `/Names` → `/EmbeddedFiles` → `/Names` array, keeping the
|
|
30040
|
+
* array's name/value pairs sorted by name (as required for a name tree).
|
|
30041
|
+
* The intermediate dictionaries and the leaf array are created on demand
|
|
30042
|
+
* and reused if already present.
|
|
30043
|
+
* 2. `fileSpecRef` is added to the catalog's `/AF` array (via
|
|
30044
|
+
* {@link attachAssociatedFiles}).
|
|
30045
|
+
*
|
|
30046
|
+
* @param catalog The document catalog dictionary.
|
|
30047
|
+
* @param name The name under which the file is registered in the tree.
|
|
30048
|
+
* @param fileSpecRef Indirect reference to the file-specification dictionary.
|
|
30049
|
+
*/
|
|
30050
|
+
function registerEmbeddedFile(catalog, name, fileSpecRef) {
|
|
30051
|
+
insertNamePairSorted(ensureEmbeddedFilesNames(catalog), name, fileSpecRef);
|
|
30052
|
+
attachAssociatedFiles(catalog, [fileSpecRef]);
|
|
30053
|
+
}
|
|
30054
|
+
//#endregion
|
|
30055
|
+
//#region src/compliance/pageOutputIntent.ts
|
|
30056
|
+
/**
|
|
30057
|
+
* @module compliance/pageOutputIntent
|
|
30058
|
+
*
|
|
30059
|
+
* Per-page and per-stream output intents (ISO 32000-2 §14.11.5).
|
|
30060
|
+
*
|
|
30061
|
+
* In addition to the document-level `/OutputIntents` array carried on the
|
|
30062
|
+
* catalog, PDF 2.0 permits an `/OutputIntents` array on individual *page*
|
|
30063
|
+
* dictionaries and on *Form XObject* stream dictionaries. These narrower
|
|
30064
|
+
* intents override the document intent for the colour-managed content of that
|
|
30065
|
+
* page or form, which is essential for documents that mix output conditions
|
|
30066
|
+
* (for example, a PDF/X job whose individual pages target different print
|
|
30067
|
+
* presses).
|
|
30068
|
+
*
|
|
30069
|
+
* This module provides two pure builders:
|
|
30070
|
+
*
|
|
30071
|
+
* - {@link buildPageOutputIntent} constructs a single `/OutputIntent`
|
|
30072
|
+
* dictionary (reusing {@link buildOutputIntent} for the embedded ICC
|
|
30073
|
+
* `/DestOutputProfile`) and registers it as an indirect object.
|
|
30074
|
+
* - {@link attachOutputIntents} sets — or, when one already exists, appends
|
|
30075
|
+
* to — the `/OutputIntents` array on a target dictionary (a page dict for
|
|
30076
|
+
* per-page intents, or a Form XObject stream's dict for per-stream).
|
|
30077
|
+
*
|
|
30078
|
+
* Reference: ISO 32000-2:2020, §14.11.5 (Output intents).
|
|
30079
|
+
*/
|
|
30080
|
+
/**
|
|
30081
|
+
* Attach output-intent references to a target dictionary's `/OutputIntents`
|
|
30082
|
+
* array.
|
|
30083
|
+
*
|
|
30084
|
+
* If the target has no `/OutputIntents` entry, a fresh {@link PdfArray} is
|
|
30085
|
+
* created and populated with `intentRefs`. If one already exists (and is an
|
|
30086
|
+
* array), the references are appended to it in order, preserving the existing
|
|
30087
|
+
* array instance.
|
|
30088
|
+
*
|
|
30089
|
+
* The target may be a page dictionary (for per-page intents) or a Form
|
|
30090
|
+
* XObject stream's dictionary (for per-stream intents).
|
|
30091
|
+
*
|
|
30092
|
+
* @param target The page or Form XObject dictionary to mutate.
|
|
30093
|
+
* @param intentRefs Indirect references to `/OutputIntent` dictionaries.
|
|
30094
|
+
*/
|
|
30095
|
+
function attachOutputIntents(target, intentRefs) {
|
|
30096
|
+
const existing = target.get("/OutputIntents");
|
|
30097
|
+
const array = existing instanceof require_pdfObjects.PdfArray ? existing : new require_pdfObjects.PdfArray();
|
|
30098
|
+
for (const ref of intentRefs) array.push(ref);
|
|
30099
|
+
if (!(existing instanceof require_pdfObjects.PdfArray)) target.set("/OutputIntents", array);
|
|
30100
|
+
}
|
|
30101
|
+
/**
|
|
30102
|
+
* Build a per-page / per-stream `/OutputIntent` dictionary and register it.
|
|
30103
|
+
*
|
|
30104
|
+
* The embedded ICC `/DestOutputProfile` is produced by reusing
|
|
30105
|
+
* {@link buildOutputIntent}; this builder then layers the per-page subtype
|
|
30106
|
+
* (`/S`), output-condition identifier and optional `/Info` string on top.
|
|
30107
|
+
* The resulting dictionary carries `/Type /OutputIntent` and may be attached
|
|
30108
|
+
* to a page or Form XObject dictionary via {@link attachOutputIntents}.
|
|
30109
|
+
*
|
|
30110
|
+
* @param registry The PDF object registry to register objects into.
|
|
30111
|
+
* @param options Output-intent configuration.
|
|
30112
|
+
* @returns An indirect reference to the `/OutputIntent` dictionary.
|
|
30113
|
+
*/
|
|
30114
|
+
function buildPageOutputIntent(registry, options = {}) {
|
|
30115
|
+
const intentRef = buildOutputIntent(registry, {
|
|
30116
|
+
subtype: options.subtype ?? "/GTS_PDFA1",
|
|
30117
|
+
...options.iccProfile !== void 0 ? { iccProfile: options.iccProfile } : {},
|
|
30118
|
+
...options.components !== void 0 ? { components: options.components } : {},
|
|
30119
|
+
...options.outputConditionIdentifier !== void 0 ? { outputConditionIdentifier: options.outputConditionIdentifier } : {}
|
|
30120
|
+
});
|
|
30121
|
+
const intentDict = registry.resolve(intentRef);
|
|
30122
|
+
if (intentDict !== void 0 && intentDict.kind === "dict") {
|
|
30123
|
+
intentDict.set("/Type", require_pdfObjects.PdfName.of("OutputIntent"));
|
|
30124
|
+
if (options.outputConditionIdentifier !== void 0) intentDict.set("/OutputConditionIdentifier", require_pdfObjects.PdfString.literal(options.outputConditionIdentifier));
|
|
30125
|
+
if (options.info !== void 0) intentDict.set("/Info", require_pdfObjects.PdfString.literal(options.info));
|
|
30126
|
+
}
|
|
30127
|
+
return intentRef;
|
|
30128
|
+
}
|
|
30129
|
+
//#endregion
|
|
30130
|
+
//#region src/compliance/encryptedPayload.ts
|
|
30131
|
+
/**
|
|
30132
|
+
* @module compliance/encryptedPayload
|
|
30133
|
+
*
|
|
30134
|
+
* Unencrypted wrapper documents and encrypted payloads
|
|
30135
|
+
* (ISO 32000-2:2020 §7.6.7).
|
|
30136
|
+
*
|
|
30137
|
+
* A PDF 2.0 *unencrypted wrapper document* is an ordinary, viewable PDF that
|
|
30138
|
+
* carries an *encrypted payload* as an embedded file. The wrapper itself is
|
|
30139
|
+
* not encrypted (so any conforming reader can open it and show a cover page),
|
|
30140
|
+
* while the sensitive content lives in the embedded payload, which is
|
|
30141
|
+
* protected by an external/handler-specific crypto filter.
|
|
30142
|
+
*
|
|
30143
|
+
* The payload is declared through an *Encrypted Payload* dictionary
|
|
30144
|
+
* (`/Type /EncryptedPayload`). Its `/Subtype` names the crypto filter used to
|
|
30145
|
+
* protect the payload (for example `/AESV3`), and an optional `/Version`
|
|
30146
|
+
* records the version of that filter. The Encrypted Payload dictionary is
|
|
30147
|
+
* attached to the embedded file's *file specification* dictionary via the
|
|
30148
|
+
* `/EP` key, and that file specification is also marked with
|
|
30149
|
+
* `/AFRelationship /EncryptedPayload`.
|
|
30150
|
+
*
|
|
30151
|
+
* This module provides two pure builders:
|
|
30152
|
+
*
|
|
30153
|
+
* - {@link buildEncryptedPayload} — build the `/EncryptedPayload` dictionary.
|
|
30154
|
+
* - {@link buildUnencryptedWrapper} — embed the payload bytes as an
|
|
30155
|
+
* associated file and attach the `/EP` dictionary to its file
|
|
30156
|
+
* specification, returning the file-spec reference.
|
|
30157
|
+
*
|
|
30158
|
+
* The caller attaches the returned file-spec reference to the catalog `/AF`
|
|
30159
|
+
* array and to the `/Names /EmbeddedFiles` name tree (for example via
|
|
30160
|
+
* `afAttach`).
|
|
30161
|
+
*
|
|
30162
|
+
* Reference: ISO 32000-2:2020, §7.6.7 (Unencrypted wrapper document).
|
|
30163
|
+
*/
|
|
30164
|
+
/**
|
|
30165
|
+
* Build an `/EncryptedPayload` dictionary (ISO 32000-2 §7.6.7).
|
|
30166
|
+
*
|
|
30167
|
+
* The returned dictionary has:
|
|
30168
|
+
* - `/Type /EncryptedPayload`
|
|
30169
|
+
* - `/Subtype /<subtype>` — the crypto filter name
|
|
30170
|
+
* - `/Version /<version>` — only when {@link EncryptedPayloadOptions.version}
|
|
30171
|
+
* is supplied
|
|
30172
|
+
*
|
|
30173
|
+
* @param options - The crypto-filter subtype and optional version.
|
|
30174
|
+
* @returns A spec-shaped `/EncryptedPayload` {@link PdfDict}.
|
|
30175
|
+
*/
|
|
30176
|
+
function buildEncryptedPayload(options) {
|
|
30177
|
+
const dict = new require_pdfObjects.PdfDict();
|
|
30178
|
+
dict.set("/Type", require_pdfObjects.PdfName.of("EncryptedPayload"));
|
|
30179
|
+
dict.set("/Subtype", require_pdfObjects.PdfName.of(options.subtype));
|
|
30180
|
+
if (options.version !== void 0) dict.set("/Version", require_pdfObjects.PdfName.of(options.version));
|
|
30181
|
+
return dict;
|
|
30182
|
+
}
|
|
30183
|
+
/**
|
|
30184
|
+
* Build the embedded encrypted-payload file for an unencrypted wrapper
|
|
30185
|
+
* document and return its file-specification reference.
|
|
30186
|
+
*
|
|
30187
|
+
* The payload bytes are embedded via {@link createAssociatedFile} with an
|
|
30188
|
+
* `/AFRelationship` of `/EncryptedPayload` and an `application/octet-stream`
|
|
30189
|
+
* MIME type. The resolved file-specification dictionary then receives an
|
|
30190
|
+
* `/EP` entry holding the {@link buildEncryptedPayload} dictionary.
|
|
30191
|
+
*
|
|
30192
|
+
* The caller is responsible for attaching the returned file-spec reference to
|
|
30193
|
+
* the catalog `/AF` array and the `/Names /EmbeddedFiles` name tree.
|
|
30194
|
+
*
|
|
30195
|
+
* @param registry - The PDF object registry to register objects into.
|
|
30196
|
+
* @param options - The payload bytes, filename, crypto subtype/version, and
|
|
30197
|
+
* optional description.
|
|
30198
|
+
* @returns An indirect reference to the file-specification dictionary.
|
|
30199
|
+
*/
|
|
30200
|
+
function buildUnencryptedWrapper(registry, options) {
|
|
30201
|
+
const { fileSpecRef } = createAssociatedFile(registry, {
|
|
30202
|
+
data: options.data,
|
|
30203
|
+
filename: options.filename,
|
|
30204
|
+
mimeType: "application/octet-stream",
|
|
30205
|
+
relationship: "EncryptedPayload",
|
|
30206
|
+
description: options.description
|
|
30207
|
+
});
|
|
30208
|
+
const fileSpec = registry.resolve(fileSpecRef);
|
|
30209
|
+
if (fileSpec instanceof require_pdfObjects.PdfDict) {
|
|
30210
|
+
const ep = buildEncryptedPayload({
|
|
30211
|
+
subtype: options.subtype,
|
|
30212
|
+
version: options.version
|
|
30213
|
+
});
|
|
30214
|
+
fileSpec.set("/EP", ep);
|
|
30215
|
+
}
|
|
30216
|
+
return fileSpecRef;
|
|
30217
|
+
}
|
|
30218
|
+
//#endregion
|
|
30219
|
+
//#region src/core/softMask.ts
|
|
30220
|
+
/**
|
|
30221
|
+
* @module core/softMask
|
|
30222
|
+
*
|
|
30223
|
+
* Soft-mask groups in graphics state (ISO 32000-1 §11.6.5.2).
|
|
30224
|
+
*
|
|
30225
|
+
* A *soft mask* defines a per-pixel shape/opacity for subsequent painting
|
|
30226
|
+
* operations. It is carried in an `ExtGState` dictionary under the `/SMask`
|
|
30227
|
+
* key. The mask is derived from a *transparency-group XObject* (a form
|
|
30228
|
+
* XObject whose `/Group` dictionary has `/S /Transparency`):
|
|
30229
|
+
*
|
|
30230
|
+
* - A **luminosity** mask (`/S /Luminosity`) computes the mask value from the
|
|
30231
|
+
* luminosity of the group's composited result. An optional `/BC` backdrop
|
|
30232
|
+
* color sets the colour against which the group is composited before the
|
|
30233
|
+
* luminosity is measured.
|
|
30234
|
+
* - An **alpha** mask (`/S /Alpha`) computes the mask value from the group's
|
|
30235
|
+
* accumulated alpha (shape/opacity). `/BC` is not meaningful and is omitted.
|
|
30236
|
+
*
|
|
30237
|
+
* An optional `/TR` *transfer function* remaps the computed mask values; it may
|
|
30238
|
+
* be an indirect reference to a function object or the name `/Identity`.
|
|
30239
|
+
*
|
|
30240
|
+
* These are pure builders: they return spec-shaped `ExtGState` dictionaries.
|
|
30241
|
+
* Registering the result and naming it in a page's `/Resources /ExtGState`
|
|
30242
|
+
* (e.g. via `page.registerExtGState(name, registry.register(extGState))`) is
|
|
30243
|
+
* the caller's concern.
|
|
30244
|
+
*
|
|
30245
|
+
* Reference: ISO 32000-1:2008, §11.6.5.2 (Mask shape and opacity);
|
|
30246
|
+
* ISO 32000-1:2008, §8.4.5 (Graphics state, `/SMask`).
|
|
30247
|
+
*/
|
|
30248
|
+
/**
|
|
30249
|
+
* Build an `ExtGState` dictionary that installs a soft-mask group.
|
|
30250
|
+
*
|
|
30251
|
+
* The returned dictionary has `/Type /ExtGState` and an `/SMask` mask
|
|
30252
|
+
* dictionary:
|
|
30253
|
+
*
|
|
30254
|
+
* - `/Type /Mask`
|
|
30255
|
+
* - `/S /Luminosity` or `/S /Alpha` (per {@link SoftMaskGroupOptions.type},
|
|
30256
|
+
* defaulting to `Luminosity`)
|
|
30257
|
+
* - `/G` → the supplied group XObject reference
|
|
30258
|
+
* - `/BC [ … ]` — backdrop colour, **only** for luminosity masks and only
|
|
30259
|
+
* when {@link SoftMaskGroupOptions.backdropColor} is provided
|
|
30260
|
+
* - `/TR` → the transfer function (indirect reference) or the name
|
|
30261
|
+
* `/Identity`, only when {@link SoftMaskGroupOptions.transferFunction} is
|
|
30262
|
+
* provided
|
|
30263
|
+
*
|
|
30264
|
+
* @param options - The soft-mask group description.
|
|
30265
|
+
* @returns A spec-shaped `ExtGState` {@link PdfDict}.
|
|
30266
|
+
*/
|
|
30267
|
+
function buildSoftMaskGroupExtGState(options) {
|
|
30268
|
+
const subtype = options.type ?? "Luminosity";
|
|
30269
|
+
const smask = new require_pdfObjects.PdfDict();
|
|
30270
|
+
smask.set("/Type", require_pdfObjects.PdfName.of("Mask"));
|
|
30271
|
+
smask.set("/S", require_pdfObjects.PdfName.of(subtype));
|
|
30272
|
+
smask.set("/G", options.groupXObject);
|
|
30273
|
+
if (subtype === "Luminosity" && options.backdropColor !== void 0 && options.backdropColor.length > 0) smask.set("/BC", require_pdfObjects.PdfArray.fromNumbers([...options.backdropColor]));
|
|
30274
|
+
if (options.transferFunction !== void 0) smask.set("/TR", options.transferFunction === "Identity" ? require_pdfObjects.PdfName.of("Identity") : options.transferFunction);
|
|
30275
|
+
const extGState = new require_pdfObjects.PdfDict();
|
|
30276
|
+
extGState.set("/Type", require_pdfObjects.PdfName.of("ExtGState"));
|
|
30277
|
+
extGState.set("/SMask", smask);
|
|
30278
|
+
return extGState;
|
|
30279
|
+
}
|
|
30280
|
+
/**
|
|
30281
|
+
* Build an `ExtGState` dictionary that clears any active soft mask by setting
|
|
30282
|
+
* `/SMask /None`. Apply this after a masked region to restore unmasked
|
|
30283
|
+
* painting.
|
|
30284
|
+
*
|
|
30285
|
+
* @returns An `ExtGState` {@link PdfDict} with `/SMask /None`.
|
|
30286
|
+
*/
|
|
30287
|
+
function buildSoftMaskNone() {
|
|
30288
|
+
const extGState = new require_pdfObjects.PdfDict();
|
|
30289
|
+
extGState.set("/Type", require_pdfObjects.PdfName.of("ExtGState"));
|
|
30290
|
+
extGState.set("/SMask", require_pdfObjects.PdfName.of("None"));
|
|
30291
|
+
return extGState;
|
|
30292
|
+
}
|
|
30293
|
+
//#endregion
|
|
30294
|
+
//#region src/core/imageMask.ts
|
|
30295
|
+
/**
|
|
30296
|
+
* @module core/imageMask
|
|
30297
|
+
*
|
|
30298
|
+
* Image masks and black-point compensation per ISO 32000-2 §8.9.6
|
|
30299
|
+
* (Masked images) and §8.6.5.9 (Black-point compensation).
|
|
30300
|
+
*
|
|
30301
|
+
* PDF supports three ways of masking an image XObject:
|
|
30302
|
+
*
|
|
30303
|
+
* - **Stencil mask** — a 1-bit-per-component `/ImageMask` image whose sample
|
|
30304
|
+
* values select which areas of the page are painted with the current fill
|
|
30305
|
+
* colour and which are left untouched (§8.9.6.2). The mask data is packed
|
|
30306
|
+
* one bit per sample, each row byte-aligned (`ceil(width / 8)` bytes per
|
|
30307
|
+
* row); the caller supplies the already-packed bytes.
|
|
30308
|
+
* - **Colour-key mask** — a `/Mask` array of `[min0 max0 min1 max1 …]`
|
|
30309
|
+
* integer ranges (two per colour component) that makes matching sample
|
|
30310
|
+
* colours transparent (§8.9.6.4).
|
|
30311
|
+
* - **Soft mask** — a separate DeviceGray image referenced from a base
|
|
30312
|
+
* image's `/SMask` entry, giving per-pixel opacity (§11.6.5.2).
|
|
30313
|
+
*
|
|
30314
|
+
* Black-point compensation (§8.6.5.9) is controlled through an ExtGState's
|
|
30315
|
+
* `/UseBlackPtComp` entry, which selects whether the conversion between
|
|
30316
|
+
* colour spaces maps source black to destination black.
|
|
30317
|
+
*
|
|
30318
|
+
* These are pure builders: they construct (and, for the stream variants,
|
|
30319
|
+
* register) PDF objects but do not wire them into a page or resource
|
|
30320
|
+
* dictionary — that is the caller's concern.
|
|
30321
|
+
*
|
|
30322
|
+
* Reference: ISO 32000-2:2020, §8.9.6 (Masked images), §8.6.5.9
|
|
30323
|
+
* (Black-point compensation).
|
|
30324
|
+
*/
|
|
30325
|
+
/**
|
|
30326
|
+
* Build a stencil mask: a 1-bit `/ImageMask` image XObject (§8.9.6.2).
|
|
30327
|
+
*
|
|
30328
|
+
* The returned stream has `/Type /XObject`, `/Subtype /Image`,
|
|
30329
|
+
* `/ImageMask true`, `/BitsPerComponent 1`, and the supplied `/Width` and
|
|
30330
|
+
* `/Height`. When a `decode` pair is given it is emitted as a `/Decode`
|
|
30331
|
+
* array, allowing the mask polarity to be inverted (`[1 0]`).
|
|
30332
|
+
*
|
|
30333
|
+
* The `bits` buffer must already be packed one bit per sample with each row
|
|
30334
|
+
* byte-aligned (`ceil(width / 8)` bytes per row); this builder stores it
|
|
30335
|
+
* verbatim and does not repack it.
|
|
30336
|
+
*
|
|
30337
|
+
* @param registry - Registry to register the stream into.
|
|
30338
|
+
* @param bits - Packed, byte-aligned 1-bpc mask data.
|
|
30339
|
+
* @param width - Image width in samples.
|
|
30340
|
+
* @param height - Image height in samples.
|
|
30341
|
+
* @param decode - Optional `[d0, d1]` decode pair.
|
|
30342
|
+
* @returns An indirect reference to the registered image XObject stream.
|
|
30343
|
+
*/
|
|
30344
|
+
function buildStencilMask(registry, bits, width, height, decode) {
|
|
30345
|
+
const dict = new require_pdfObjects.PdfDict();
|
|
30346
|
+
dict.set("/Type", require_pdfObjects.PdfName.of("XObject"));
|
|
30347
|
+
dict.set("/Subtype", require_pdfObjects.PdfName.of("Image"));
|
|
30348
|
+
dict.set("/ImageMask", require_pdfObjects.PdfBool.TRUE);
|
|
30349
|
+
dict.set("/BitsPerComponent", require_pdfObjects.PdfNumber.of(1));
|
|
30350
|
+
dict.set("/Width", require_pdfObjects.PdfNumber.of(width));
|
|
30351
|
+
dict.set("/Height", require_pdfObjects.PdfNumber.of(height));
|
|
30352
|
+
if (decode !== void 0) dict.set("/Decode", require_pdfObjects.PdfArray.fromNumbers([decode[0], decode[1]]));
|
|
30353
|
+
dict.set("/Length", require_pdfObjects.PdfNumber.of(bits.length));
|
|
30354
|
+
return registry.register(new require_pdfObjects.PdfStream(dict, bits));
|
|
30355
|
+
}
|
|
30356
|
+
/**
|
|
30357
|
+
* Build a colour-key masking array (§8.9.6.4).
|
|
30358
|
+
*
|
|
30359
|
+
* The `ranges` list holds two integers — a minimum and a maximum — per
|
|
30360
|
+
* colour component, laid out as `[min0 max0 min1 max1 …]`. Sample colours
|
|
30361
|
+
* whose every component falls within its range become transparent. The
|
|
30362
|
+
* returned {@link PdfArray} is assigned to a base image's `/Mask` entry.
|
|
30363
|
+
*
|
|
30364
|
+
* @param ranges - An even-length list of `[min, max]` integer pairs.
|
|
30365
|
+
* @returns A `/Mask` {@link PdfArray} of {@link PdfNumber}s.
|
|
30366
|
+
* @throws RangeError if `ranges` is empty or has an odd length.
|
|
30367
|
+
*/
|
|
30368
|
+
function buildColorKeyMask(ranges) {
|
|
30369
|
+
if (ranges.length === 0 || ranges.length % 2 !== 0) throw new RangeError(`colour-key mask requires a non-empty even number of values (min/max pairs); got ${ranges.length}`);
|
|
30370
|
+
return new require_pdfObjects.PdfArray(ranges.map((v) => require_pdfObjects.PdfNumber.of(v)));
|
|
30371
|
+
}
|
|
30372
|
+
/**
|
|
30373
|
+
* Build an image soft mask: a DeviceGray image XObject usable as a base
|
|
30374
|
+
* image's `/SMask` (§11.6.5.2).
|
|
30375
|
+
*
|
|
30376
|
+
* The returned stream has `/Type /XObject`, `/Subtype /Image`,
|
|
30377
|
+
* `/ColorSpace /DeviceGray`, the supplied `/Width` and `/Height`, and
|
|
30378
|
+
* `/BitsPerComponent` (defaulting to 8). Each grayscale sample provides the
|
|
30379
|
+
* opacity of the corresponding base-image pixel.
|
|
30380
|
+
*
|
|
30381
|
+
* @param registry - Registry to register the stream into.
|
|
30382
|
+
* @param gray - Grayscale opacity samples.
|
|
30383
|
+
* @param width - Image width in samples.
|
|
30384
|
+
* @param height - Image height in samples.
|
|
30385
|
+
* @param bitsPerComponent - Bits per sample; defaults to 8.
|
|
30386
|
+
* @returns An indirect reference to the registered soft-mask image XObject.
|
|
30387
|
+
*/
|
|
30388
|
+
function buildImageSoftMask(registry, gray, width, height, bitsPerComponent) {
|
|
30389
|
+
const dict = new require_pdfObjects.PdfDict();
|
|
30390
|
+
dict.set("/Type", require_pdfObjects.PdfName.of("XObject"));
|
|
30391
|
+
dict.set("/Subtype", require_pdfObjects.PdfName.of("Image"));
|
|
30392
|
+
dict.set("/Width", require_pdfObjects.PdfNumber.of(width));
|
|
30393
|
+
dict.set("/Height", require_pdfObjects.PdfNumber.of(height));
|
|
30394
|
+
dict.set("/ColorSpace", require_pdfObjects.PdfName.of("DeviceGray"));
|
|
30395
|
+
dict.set("/BitsPerComponent", require_pdfObjects.PdfNumber.of(bitsPerComponent ?? 8));
|
|
30396
|
+
dict.set("/Length", require_pdfObjects.PdfNumber.of(gray.length));
|
|
30397
|
+
return registry.register(new require_pdfObjects.PdfStream(dict, gray));
|
|
30398
|
+
}
|
|
30399
|
+
/**
|
|
30400
|
+
* Build an ExtGState that controls black-point compensation (§8.6.5.9).
|
|
30401
|
+
*
|
|
30402
|
+
* The returned dictionary has `/Type /ExtGState` and `/UseBlackPtComp` set
|
|
30403
|
+
* to the requested mode:
|
|
30404
|
+
*
|
|
30405
|
+
* - `Default` — leave the choice to the conforming reader.
|
|
30406
|
+
* - `ON` — always apply black-point compensation.
|
|
30407
|
+
* - `OFF` — never apply black-point compensation.
|
|
30408
|
+
*
|
|
30409
|
+
* @param mode - The `/UseBlackPtComp` mode.
|
|
30410
|
+
* @returns An ExtGState {@link PdfDict}.
|
|
30411
|
+
*/
|
|
30412
|
+
function buildBlackPointCompensationExtGState(mode) {
|
|
30413
|
+
const gs = new require_pdfObjects.PdfDict();
|
|
30414
|
+
gs.set("/Type", require_pdfObjects.PdfName.of("ExtGState"));
|
|
30415
|
+
gs.set("/UseBlackPtComp", require_pdfObjects.PdfName.of(mode));
|
|
30416
|
+
return gs;
|
|
30417
|
+
}
|
|
30418
|
+
//#endregion
|
|
30419
|
+
//#region src/accessibility/taggingHelpers.ts
|
|
30420
|
+
/**
|
|
30421
|
+
* The property key under which {@link tagList} records the chosen
|
|
30422
|
+
* {@link ListNumbering} on a list element's `options` object.
|
|
30423
|
+
*
|
|
30424
|
+
* `StructureElementOptions` has no dedicated `listNumbering` field, so
|
|
30425
|
+
* the value is stored as an extra (string-keyed) property on the same
|
|
30426
|
+
* options object. When the structure tree is serialized this is the
|
|
30427
|
+
* value an attribute writer should emit as the list's `/ListNumbering`
|
|
30428
|
+
* entry inside an `/A` attribute dictionary whose owner is `/List`
|
|
30429
|
+
* (ISO 32000, Table 384):
|
|
30430
|
+
*
|
|
30431
|
+
* ```
|
|
30432
|
+
* /A << /O /List /ListNumbering /Decimal >>
|
|
30433
|
+
* ```
|
|
30434
|
+
*
|
|
30435
|
+
* Using a well-known string key (rather than a `Symbol`) keeps the
|
|
30436
|
+
* value plain-serializable and inspectable from tests.
|
|
30437
|
+
*/
|
|
30438
|
+
const LIST_NUMBERING_KEY = "__listNumbering";
|
|
30439
|
+
/**
|
|
30440
|
+
* Heading level → structure-type mapping for {@link tagHeading}.
|
|
30441
|
+
*
|
|
30442
|
+
* Indexed by the numeric heading level (`1`..`6`); the result is the
|
|
30443
|
+
* corresponding standard heading structure type (`'H1'`..`'H6'`).
|
|
30444
|
+
*/
|
|
30445
|
+
const HEADING_TYPE = {
|
|
30446
|
+
1: "H1",
|
|
30447
|
+
2: "H2",
|
|
30448
|
+
3: "H3",
|
|
30449
|
+
4: "H4",
|
|
30450
|
+
5: "H5",
|
|
30451
|
+
6: "H6"
|
|
30452
|
+
};
|
|
30453
|
+
/**
|
|
30454
|
+
* Tag a heading element of the given level.
|
|
30455
|
+
*
|
|
30456
|
+
* @param tree The structure tree to add the element to.
|
|
30457
|
+
* @param parent The parent element, or `null` to add under the root
|
|
30458
|
+
* `Document` element.
|
|
30459
|
+
* @param level The heading level (`1`..`6`); maps to `H1`..`H6`.
|
|
30460
|
+
* @param options Optional attributes (title, language, id, …).
|
|
30461
|
+
* @returns The newly created heading element (type `H1`..`H6`).
|
|
30462
|
+
*
|
|
30463
|
+
* @example
|
|
30464
|
+
* ```ts
|
|
30465
|
+
* const tree = doc.createStructureTree();
|
|
30466
|
+
* const h2 = tagHeading(tree, null, 2, { title: 'Background' });
|
|
30467
|
+
* // h2.type === 'H2'
|
|
30468
|
+
* ```
|
|
30469
|
+
*/
|
|
30470
|
+
function tagHeading(tree, parent, level, options) {
|
|
30471
|
+
return tree.addElement(parent, HEADING_TYPE[level], options);
|
|
30472
|
+
}
|
|
30473
|
+
/**
|
|
30474
|
+
* Tag a paragraph (`P`) element.
|
|
30475
|
+
*
|
|
30476
|
+
* @param tree The structure tree to add the element to.
|
|
30477
|
+
* @param parent The parent element, or `null` for the root.
|
|
30478
|
+
* @param options Optional attributes.
|
|
30479
|
+
* @returns The newly created `P` element.
|
|
30480
|
+
*/
|
|
30481
|
+
function tagParagraph(tree, parent, options) {
|
|
30482
|
+
return tree.addElement(parent, "P", options);
|
|
30483
|
+
}
|
|
30484
|
+
/**
|
|
30485
|
+
* Tag a figure (`Figure`) element with alternative text.
|
|
30486
|
+
*
|
|
30487
|
+
* The `altText` argument is required because PDF/UA mandates
|
|
30488
|
+
* alternative text for illustration elements. If the caller also
|
|
30489
|
+
* supplies `altText` in `options`, that explicit value takes
|
|
30490
|
+
* precedence over the positional argument.
|
|
30491
|
+
*
|
|
30492
|
+
* @param tree The structure tree to add the element to.
|
|
30493
|
+
* @param parent The parent element, or `null` for the root.
|
|
30494
|
+
* @param altText Alternative text describing the figure.
|
|
30495
|
+
* @param options Optional additional attributes.
|
|
30496
|
+
* @returns The newly created `Figure` element with `/Alt` set.
|
|
30497
|
+
*/
|
|
30498
|
+
function tagFigure(tree, parent, altText, options) {
|
|
30499
|
+
const merged = {
|
|
30500
|
+
altText,
|
|
30501
|
+
...options
|
|
30502
|
+
};
|
|
30503
|
+
return tree.addElement(parent, "Figure", merged);
|
|
30504
|
+
}
|
|
30505
|
+
/**
|
|
30506
|
+
* Tag a link (`Link`) element.
|
|
30507
|
+
*
|
|
30508
|
+
* @param tree The structure tree to add the element to.
|
|
30509
|
+
* @param parent The parent element, or `null` for the root.
|
|
30510
|
+
* @param options Optional attributes.
|
|
30511
|
+
* @returns The newly created `Link` element.
|
|
30512
|
+
*/
|
|
30513
|
+
function tagLink(tree, parent, options) {
|
|
30514
|
+
return tree.addElement(parent, "Link", options);
|
|
30515
|
+
}
|
|
30516
|
+
/**
|
|
30517
|
+
* Tag a list (`L`) element and record its numbering style.
|
|
30518
|
+
*
|
|
30519
|
+
* The chosen {@link ListNumbering} is stored on the returned element's
|
|
30520
|
+
* `options` object under {@link LIST_NUMBERING_KEY} (since
|
|
30521
|
+
* `StructureElementOptions` has no dedicated field). A serializer can
|
|
30522
|
+
* emit it as the list's `/ListNumbering` attribute (ISO 32000,
|
|
30523
|
+
* Table 384) inside an `/A` dictionary owned by `/List`.
|
|
30524
|
+
*
|
|
30525
|
+
* @param tree The structure tree to add the element to.
|
|
30526
|
+
* @param parent The parent element, or `null` for the root.
|
|
30527
|
+
* @param numbering The list numbering style (default `'None'`).
|
|
30528
|
+
* @param options Optional additional attributes.
|
|
30529
|
+
* @returns The newly created `L` element.
|
|
30530
|
+
*/
|
|
30531
|
+
function tagList(tree, parent, numbering = "None", options) {
|
|
30532
|
+
const list = tree.addElement(parent, "L", options);
|
|
30533
|
+
list.options[LIST_NUMBERING_KEY] = numbering;
|
|
30534
|
+
return list;
|
|
30535
|
+
}
|
|
30536
|
+
/**
|
|
30537
|
+
* Tag a list item under a list, building the conventional
|
|
30538
|
+
* `LI` → (`Lbl`, `LBody`) substructure.
|
|
30539
|
+
*
|
|
30540
|
+
* @param tree The structure tree to add the elements to.
|
|
30541
|
+
* @param list The parent `L` (list) element.
|
|
30542
|
+
* @param options Optional attributes for the `LI` element.
|
|
30543
|
+
* @returns The created `item` (`LI`), `label` (`Lbl`) and
|
|
30544
|
+
* `body` (`LBody`) elements.
|
|
30545
|
+
*
|
|
30546
|
+
* @example
|
|
30547
|
+
* ```ts
|
|
30548
|
+
* const list = tagList(tree, null, 'Decimal');
|
|
30549
|
+
* const { item, label, body } = tagListItem(tree, list);
|
|
30550
|
+
* // item.type === 'LI', label.type === 'Lbl', body.type === 'LBody'
|
|
30551
|
+
* ```
|
|
30552
|
+
*/
|
|
30553
|
+
function tagListItem(tree, list, options) {
|
|
30554
|
+
const item = tree.addElement(list, "LI", options);
|
|
30555
|
+
return {
|
|
30556
|
+
item,
|
|
30557
|
+
label: tree.addElement(item, "Lbl"),
|
|
30558
|
+
body: tree.addElement(item, "LBody")
|
|
30559
|
+
};
|
|
30560
|
+
}
|
|
30561
|
+
/**
|
|
30562
|
+
* Tag a table (`Table`) element.
|
|
30563
|
+
*
|
|
30564
|
+
* @param tree The structure tree to add the element to.
|
|
30565
|
+
* @param parent The parent element, or `null` for the root.
|
|
30566
|
+
* @param options Optional attributes.
|
|
30567
|
+
* @returns The newly created `Table` element.
|
|
30568
|
+
*/
|
|
30569
|
+
function tagTable(tree, parent, options) {
|
|
30570
|
+
return tree.addElement(parent, "Table", options);
|
|
30571
|
+
}
|
|
30572
|
+
/**
|
|
30573
|
+
* Tag a table row (`TR`) under a table.
|
|
30574
|
+
*
|
|
30575
|
+
* @param tree The structure tree to add the element to.
|
|
30576
|
+
* @param table The parent `Table` element.
|
|
30577
|
+
* @returns The newly created `TR` element.
|
|
30578
|
+
*/
|
|
30579
|
+
function tagTableRow(tree, table) {
|
|
30580
|
+
return tree.addElement(table, "TR");
|
|
30581
|
+
}
|
|
30582
|
+
/**
|
|
30583
|
+
* Tag a table header cell (`TH`) under a row, recording its scope.
|
|
30584
|
+
*
|
|
30585
|
+
* The `scope` is stored in the element's options (`/Scope` attribute,
|
|
30586
|
+
* one of `Row`, `Column`, or `Both`) and is used by table-header
|
|
30587
|
+
* validation to associate header cells with the cells they describe.
|
|
30588
|
+
*
|
|
30589
|
+
* @param tree The structure tree to add the element to.
|
|
30590
|
+
* @param row The parent `TR` element.
|
|
30591
|
+
* @param scope The header scope (default `'Column'`).
|
|
30592
|
+
* @param options Optional additional attributes (e.g. colSpan/rowSpan).
|
|
30593
|
+
* @returns The newly created `TH` element with `scope` set.
|
|
30594
|
+
*/
|
|
30595
|
+
function tagTableHeaderCell(tree, row, scope = "Column", options) {
|
|
30596
|
+
const merged = {
|
|
30597
|
+
...options,
|
|
30598
|
+
scope
|
|
30599
|
+
};
|
|
30600
|
+
return tree.addElement(row, "TH", merged);
|
|
30601
|
+
}
|
|
30602
|
+
/**
|
|
30603
|
+
* Tag a table data cell (`TD`) under a row.
|
|
30604
|
+
*
|
|
30605
|
+
* @param tree The structure tree to add the element to.
|
|
30606
|
+
* @param row The parent `TR` element.
|
|
30607
|
+
* @param options Optional attributes (e.g. colSpan/rowSpan).
|
|
30608
|
+
* @returns The newly created `TD` element.
|
|
30609
|
+
*/
|
|
30610
|
+
function tagTableDataCell(tree, row, options) {
|
|
30611
|
+
return tree.addElement(row, "TD", options);
|
|
30612
|
+
}
|
|
30613
|
+
//#endregion
|
|
30614
|
+
//#region src/accessibility/pdfUa2.ts
|
|
30615
|
+
/** The AIIM PDF/UA identification namespace URI (used in the XMP packet). */
|
|
30616
|
+
const PDFUA_ID_NS = "http://www.aiim.org/pdfua/ns/id/";
|
|
30617
|
+
/** The PDF/UA part identified by this module's XMP. */
|
|
30618
|
+
const PDFUA2_PART = 2;
|
|
30619
|
+
/**
|
|
30620
|
+
* The PDF/UA-2 revision year. ISO 14289-2 was published in 2024, which the
|
|
30621
|
+
* AIIM `pdfuaid:rev` field records as a four-digit year.
|
|
30622
|
+
*/
|
|
30623
|
+
const PDFUA2_REV = 2024;
|
|
30624
|
+
/** Illustration types that require alternative text under PDF/UA-2. */
|
|
30625
|
+
const ILLUSTRATION_TYPES = /* @__PURE__ */ new Set([
|
|
30626
|
+
"Figure",
|
|
30627
|
+
"Formula",
|
|
30628
|
+
"Form"
|
|
30629
|
+
]);
|
|
30630
|
+
/**
|
|
30631
|
+
* Validate a PDF document against PDF/UA-2 (ISO 14289-2) requirements.
|
|
30632
|
+
*
|
|
30633
|
+
* The check reuses {@link validatePdfUa} for the shared tagging, language,
|
|
30634
|
+
* MarkInfo, and metadata requirements, then layers the PDF 2.0 / UA-2
|
|
30635
|
+
* specific requirements on top:
|
|
30636
|
+
*
|
|
30637
|
+
* - **UA2-STRUCT-001** — a structure tree must exist (tagged PDF).
|
|
30638
|
+
* - **UA2-NS-001** — the structure tree must declare structure
|
|
30639
|
+
* `/Namespaces` (PDF/UA-2 builds on PDF 2.0 namespaces).
|
|
30640
|
+
* - **UA2-LANG-001** — the document must declare a natural language
|
|
30641
|
+
* (`/Lang`).
|
|
30642
|
+
* - **UA2-FIG-001** — every figure must carry alternative text.
|
|
30643
|
+
*
|
|
30644
|
+
* Each failure is mapped to an ISO 14289-2 clause string. The returned
|
|
30645
|
+
* result is `conformant` only when there are no issues.
|
|
30646
|
+
*
|
|
30647
|
+
* @param doc The PDF document to validate.
|
|
30648
|
+
* @returns A {@link PdfUa2Result} describing conformance and issues.
|
|
30649
|
+
*
|
|
30650
|
+
* @example
|
|
30651
|
+
* ```ts
|
|
30652
|
+
* import { createPdf } from 'modern-pdf-lib';
|
|
30653
|
+
* import { validatePdfUa2 } from 'modern-pdf-lib/accessibility';
|
|
30654
|
+
*
|
|
30655
|
+
* const doc = createPdf();
|
|
30656
|
+
* const result = validatePdfUa2(doc);
|
|
30657
|
+
* if (!result.conformant) {
|
|
30658
|
+
* for (const issue of result.issues) {
|
|
30659
|
+
* console.error(`[${issue.code}] ${issue.message} (§${issue.clause})`);
|
|
30660
|
+
* }
|
|
30661
|
+
* }
|
|
30662
|
+
* ```
|
|
30663
|
+
*/
|
|
30664
|
+
function validatePdfUa2(doc) {
|
|
30665
|
+
const issues = [];
|
|
30666
|
+
const tree = doc.getStructureTree();
|
|
30667
|
+
if (!tree) issues.push({
|
|
30668
|
+
code: "UA2-STRUCT-001",
|
|
30669
|
+
message: "Document has no structure tree (/StructTreeRoot). PDF/UA-2 requires a fully tagged PDF 2.0 document with logical structure.",
|
|
30670
|
+
clause: "8.2"
|
|
30671
|
+
});
|
|
30672
|
+
if (!hasDeclaredNamespaces(tree)) issues.push({
|
|
30673
|
+
code: "UA2-NS-001",
|
|
30674
|
+
message: "Structure tree does not declare structure /Namespaces. PDF/UA-2 builds on PDF 2.0 structure namespaces (ISO 32000-2 §14.7.4); the StructTreeRoot must declare its namespaces.",
|
|
30675
|
+
clause: "8.2.2"
|
|
30676
|
+
});
|
|
30677
|
+
const lang = doc.getLanguage();
|
|
30678
|
+
if (lang === void 0 || lang.trim().length === 0) issues.push({
|
|
30679
|
+
code: "UA2-LANG-001",
|
|
30680
|
+
message: "Document has no natural language (/Lang). PDF/UA-2 requires the document catalog to specify a default natural language.",
|
|
30681
|
+
clause: "7.2"
|
|
30682
|
+
});
|
|
30683
|
+
if (tree) for (const elem of tree.getAllElements()) {
|
|
30684
|
+
if (!ILLUSTRATION_TYPES.has(elem.type)) continue;
|
|
30685
|
+
if (elem.options.artifact) continue;
|
|
30686
|
+
const alt = elem.options.altText;
|
|
30687
|
+
const actual = elem.options.actualText;
|
|
30688
|
+
const hasAlt = alt !== void 0 && alt.trim().length > 0;
|
|
30689
|
+
const hasActual = actual !== void 0 && actual.trim().length > 0;
|
|
30690
|
+
if (!hasAlt && !hasActual) issues.push({
|
|
30691
|
+
code: "UA2-FIG-001",
|
|
30692
|
+
message: `${elem.type} element has no /Alt or /ActualText. PDF/UA-2 requires alternative text for all non-decorative illustration elements.`,
|
|
30693
|
+
clause: "7.3"
|
|
30694
|
+
});
|
|
30695
|
+
}
|
|
30696
|
+
const ua1 = validatePdfUa(doc);
|
|
30697
|
+
for (const err of ua1.errors) {
|
|
30698
|
+
if (isCoveredByUa2(err.code)) continue;
|
|
30699
|
+
issues.push({
|
|
30700
|
+
code: `UA2-${err.code}`,
|
|
30701
|
+
message: err.message,
|
|
30702
|
+
clause: mapUa1Clause(err.clause)
|
|
30703
|
+
});
|
|
30704
|
+
}
|
|
30705
|
+
return {
|
|
30706
|
+
conformant: issues.length === 0,
|
|
30707
|
+
issues
|
|
30708
|
+
};
|
|
30709
|
+
}
|
|
30710
|
+
/**
|
|
30711
|
+
* Build an XMP packet (RDF/XML) that identifies a document as PDF/UA-2.
|
|
30712
|
+
*
|
|
30713
|
+
* The packet declares the AIIM PDF/UA identification schema
|
|
30714
|
+
* (`pdfuaid`, namespace `http://www.aiim.org/pdfua/ns/id/`) with:
|
|
30715
|
+
*
|
|
30716
|
+
* - `pdfuaid:part` = `2` — the PDF/UA part (ISO 14289-2);
|
|
30717
|
+
* - `pdfuaid:rev` = the revision year of the standard.
|
|
30718
|
+
*
|
|
30719
|
+
* The result is a serialized, packet-wrapped XMP string suitable for
|
|
30720
|
+
* embedding as the document's `/Metadata` stream.
|
|
30721
|
+
*
|
|
30722
|
+
* @returns The serialized PDF/UA-2 identification XMP packet.
|
|
30723
|
+
*
|
|
30724
|
+
* @example
|
|
30725
|
+
* ```ts
|
|
30726
|
+
* import { buildPdfUa2Xmp } from 'modern-pdf-lib/accessibility';
|
|
30727
|
+
*
|
|
30728
|
+
* doc.setXmpMetadata(buildPdfUa2Xmp());
|
|
30729
|
+
* ```
|
|
30730
|
+
*/
|
|
30731
|
+
function buildPdfUa2Xmp() {
|
|
30732
|
+
return [
|
|
30733
|
+
"<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>",
|
|
30734
|
+
"<x:xmpmeta xmlns:x=\"adobe:ns:meta/\">",
|
|
30735
|
+
" <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">",
|
|
30736
|
+
` <rdf:Description rdf:about=""`,
|
|
30737
|
+
` xmlns:pdfuaid="${PDFUA_ID_NS}">`,
|
|
30738
|
+
` <pdfuaid:part>${PDFUA2_PART}</pdfuaid:part>`,
|
|
30739
|
+
` <pdfuaid:rev>${PDFUA2_REV}</pdfuaid:rev>`,
|
|
30740
|
+
" </rdf:Description>",
|
|
30741
|
+
" </rdf:RDF>",
|
|
30742
|
+
"</x:xmpmeta>",
|
|
30743
|
+
"<?xpacket end=\"w\"?>"
|
|
30744
|
+
].join("\n");
|
|
30745
|
+
}
|
|
30746
|
+
/**
|
|
30747
|
+
* Determine whether a structure tree declares one or more structure
|
|
30748
|
+
* namespaces.
|
|
30749
|
+
*
|
|
30750
|
+
* The in-memory {@link PdfStructureTree} model does not yet carry a
|
|
30751
|
+
* first-class namespaces field, so callers declare namespaces by attaching
|
|
30752
|
+
* a `namespaces` array (of namespace URI strings, or namespace descriptor
|
|
30753
|
+
* objects) to the tree. This helper reads that field defensively and also
|
|
30754
|
+
* recognizes a per-element `namespace` option as evidence of namespace use.
|
|
30755
|
+
*
|
|
30756
|
+
* @internal
|
|
30757
|
+
*/
|
|
30758
|
+
function hasDeclaredNamespaces(tree) {
|
|
30759
|
+
if (!tree) return false;
|
|
30760
|
+
const declared = tree.namespaces;
|
|
30761
|
+
if (Array.isArray(declared) && declared.length > 0) return true;
|
|
30762
|
+
for (const elem of tree.getAllElements()) {
|
|
30763
|
+
const ns = elem.options.namespace;
|
|
30764
|
+
if (typeof ns === "string" && ns.length > 0) return true;
|
|
30765
|
+
}
|
|
30766
|
+
return false;
|
|
30767
|
+
}
|
|
30768
|
+
/**
|
|
30769
|
+
* Whether a PDF/UA-1 error code is already represented by a dedicated
|
|
30770
|
+
* UA-2 issue produced above (to avoid duplicate structure-tree / language
|
|
30771
|
+
* findings).
|
|
30772
|
+
*
|
|
30773
|
+
* @internal
|
|
30774
|
+
*/
|
|
30775
|
+
function isCoveredByUa2(ua1Code) {
|
|
30776
|
+
return ua1Code === "UA-STRUCT-001" || ua1Code === "UA-STRUCT-002" || ua1Code === "UA-META-001" || ua1Code === "UA-META-002" || ua1Code === "UA-META-003";
|
|
30777
|
+
}
|
|
30778
|
+
/**
|
|
30779
|
+
* Map a PDF/UA-1 (ISO 14289-1) clause reference onto the corresponding
|
|
30780
|
+
* PDF/UA-2 (ISO 14289-2) clause. The two standards share most clause
|
|
30781
|
+
* numbering; when a UA-1 clause is absent we fall back to the general
|
|
30782
|
+
* UA-2 conformance clause.
|
|
30783
|
+
*
|
|
30784
|
+
* @internal
|
|
30785
|
+
*/
|
|
30786
|
+
function mapUa1Clause(ua1Clause) {
|
|
30787
|
+
if (ua1Clause === void 0 || ua1Clause.length === 0) return "5";
|
|
30788
|
+
return ua1Clause;
|
|
30789
|
+
}
|
|
30790
|
+
//#endregion
|
|
30791
|
+
//#region src/accessibility/autoTag.ts
|
|
30792
|
+
/** Default heading-detection scale relative to body text size. */
|
|
30793
|
+
const DEFAULT_HEADING_SCALE = 1.2;
|
|
30794
|
+
/**
|
|
30795
|
+
* Maximum vertical gap (in page-space units, as a fraction of the run's
|
|
30796
|
+
* font size) within which two text runs are considered to belong to the
|
|
30797
|
+
* same visual line. Runs whose baselines are within this fraction of an
|
|
30798
|
+
* em are merged onto one line.
|
|
30799
|
+
*/
|
|
30800
|
+
const SAME_LINE_FRACTION = .5;
|
|
30801
|
+
/** Highest heading level tag supported. */
|
|
30802
|
+
const MAX_HEADING_LEVEL = 6;
|
|
30803
|
+
/**
|
|
30804
|
+
* Infer a coarse logical structure for a single untagged page and add the
|
|
30805
|
+
* inferred `H1`..`H6` and `P` elements to the document's structure tree.
|
|
30806
|
+
*
|
|
30807
|
+
* The procedure:
|
|
30808
|
+
* 1. Interpret the page into positioned text runs.
|
|
30809
|
+
* 2. Group runs into visual lines by their baseline y-position.
|
|
30810
|
+
* 3. Determine the body font size as the median run font size.
|
|
30811
|
+
* 4. Order lines top-to-bottom (reading order on a y-up page).
|
|
30812
|
+
* 5. Classify each line as a heading (font size `>= headingScale × body`)
|
|
30813
|
+
* or body text; map distinct heading sizes to `H1`..`H6`
|
|
30814
|
+
* (largest → `H1`).
|
|
30815
|
+
* 6. Emit one heading element per heading line and one `P` element per
|
|
30816
|
+
* contiguous block of body lines.
|
|
30817
|
+
*
|
|
30818
|
+
* Never throws on an empty (or text-free) page — it returns all-zero
|
|
30819
|
+
* counts and leaves the structure tree untouched.
|
|
30820
|
+
*
|
|
30821
|
+
* @param doc The document containing the page.
|
|
30822
|
+
* @param pageIndex Zero-based index of the page to tag.
|
|
30823
|
+
* @param options Optional heuristic tuning ({@link AutoTagOptions}).
|
|
30824
|
+
* @returns Counts of the elements that were added.
|
|
30825
|
+
*/
|
|
30826
|
+
function autoTagPage(doc, pageIndex, options) {
|
|
30827
|
+
const headingScale = options?.headingScale ?? DEFAULT_HEADING_SCALE;
|
|
30828
|
+
const textItems = collectTextItems(doc, pageIndex);
|
|
30829
|
+
if (textItems.length === 0) return {
|
|
30830
|
+
headings: 0,
|
|
30831
|
+
paragraphs: 0,
|
|
30832
|
+
elements: 0
|
|
30833
|
+
};
|
|
30834
|
+
const lines = groupIntoLines(textItems);
|
|
30835
|
+
if (lines.length === 0) return {
|
|
30836
|
+
headings: 0,
|
|
30837
|
+
paragraphs: 0,
|
|
30838
|
+
elements: 0
|
|
30839
|
+
};
|
|
30840
|
+
const bodySize = medianFontSize(textItems);
|
|
30841
|
+
const ordered = [...lines].sort((a, b) => b.y - a.y);
|
|
30842
|
+
const headingThreshold = bodySize * headingScale;
|
|
30843
|
+
const headingLevelForSize = buildHeadingLevelMap(ordered, headingThreshold);
|
|
30844
|
+
const tree = doc.createStructureTree();
|
|
30845
|
+
let headings = 0;
|
|
30846
|
+
let paragraphs = 0;
|
|
30847
|
+
let paragraphOpen = false;
|
|
30848
|
+
for (const line of ordered) if (line.fontSize >= headingThreshold) {
|
|
30849
|
+
paragraphOpen = false;
|
|
30850
|
+
const type = `H${headingLevelForSize.get(line.fontSize) ?? 1}`;
|
|
30851
|
+
tree.addElement(null, type, { title: line.text });
|
|
30852
|
+
headings++;
|
|
30853
|
+
} else if (!paragraphOpen) {
|
|
30854
|
+
tree.addElement(null, "P");
|
|
30855
|
+
paragraphs++;
|
|
30856
|
+
paragraphOpen = true;
|
|
30857
|
+
}
|
|
30858
|
+
return {
|
|
30859
|
+
headings,
|
|
30860
|
+
paragraphs,
|
|
30861
|
+
elements: headings + paragraphs
|
|
30862
|
+
};
|
|
30863
|
+
}
|
|
30864
|
+
/**
|
|
30865
|
+
* Interpret the page and return only its text runs. Returns an empty
|
|
30866
|
+
* array (never throws) if the page cannot be interpreted.
|
|
30867
|
+
*
|
|
30868
|
+
* @internal
|
|
30869
|
+
*/
|
|
30870
|
+
function collectTextItems(doc, pageIndex) {
|
|
30871
|
+
const pageCount = doc.getPageCount();
|
|
30872
|
+
if (pageIndex < 0 || pageIndex >= pageCount) return [];
|
|
30873
|
+
let items = [];
|
|
30874
|
+
try {
|
|
30875
|
+
items = interpretPage(doc.getPage(pageIndex)).items.filter((it) => it.type === "text" && it.text.trim().length > 0);
|
|
30876
|
+
} catch {
|
|
30877
|
+
return [];
|
|
30878
|
+
}
|
|
30879
|
+
return [...items];
|
|
30880
|
+
}
|
|
30881
|
+
/**
|
|
30882
|
+
* Group text runs into visual lines by their baseline y-position.
|
|
30883
|
+
*
|
|
30884
|
+
* The baseline is taken from the run's text-space → page-space transform
|
|
30885
|
+
* (`transform[5]`, the `f` translation component). Runs whose baselines
|
|
30886
|
+
* fall within {@link SAME_LINE_FRACTION} of an em of an existing line are
|
|
30887
|
+
* merged onto that line; the line's font size is the maximum run size.
|
|
30888
|
+
*
|
|
30889
|
+
* @internal
|
|
30890
|
+
*/
|
|
30891
|
+
function groupIntoLines(items) {
|
|
30892
|
+
const sorted = [...items].sort((a, b) => b.transform[5] - a.transform[5]);
|
|
30893
|
+
const lines = [];
|
|
30894
|
+
for (const item of sorted) {
|
|
30895
|
+
const y = item.transform[5];
|
|
30896
|
+
const size = item.fontSize > 0 ? item.fontSize : Math.abs(item.transform[3]) || 1;
|
|
30897
|
+
const last = lines[lines.length - 1];
|
|
30898
|
+
const tolerance = size * SAME_LINE_FRACTION;
|
|
30899
|
+
if (last && Math.abs(last.y - y) <= tolerance) {
|
|
30900
|
+
last.text = `${last.text} ${item.text}`.trim();
|
|
30901
|
+
if (size > last.fontSize) last.fontSize = size;
|
|
30902
|
+
} else lines.push({
|
|
30903
|
+
y,
|
|
30904
|
+
fontSize: size,
|
|
30905
|
+
text: item.text.trim()
|
|
30906
|
+
});
|
|
30907
|
+
}
|
|
30908
|
+
return lines.map((l) => ({
|
|
30909
|
+
y: l.y,
|
|
30910
|
+
fontSize: l.fontSize,
|
|
30911
|
+
text: l.text
|
|
30912
|
+
}));
|
|
30913
|
+
}
|
|
30914
|
+
/**
|
|
30915
|
+
* Compute the median font size across all text runs. The median is more
|
|
30916
|
+
* robust than the mean against a handful of oversized heading runs, so it
|
|
30917
|
+
* gives a reliable estimate of the body text size.
|
|
30918
|
+
*
|
|
30919
|
+
* @internal
|
|
30920
|
+
*/
|
|
30921
|
+
function medianFontSize(items) {
|
|
30922
|
+
const sizes = items.map((it) => it.fontSize > 0 ? it.fontSize : Math.abs(it.transform[3])).filter((s) => s > 0).sort((a, b) => a - b);
|
|
30923
|
+
if (sizes.length === 0) return 1;
|
|
30924
|
+
const mid = sizes.length >> 1;
|
|
30925
|
+
if (sizes.length % 2 === 1) return sizes[mid];
|
|
30926
|
+
return (sizes[mid - 1] + sizes[mid]) / 2;
|
|
30927
|
+
}
|
|
30928
|
+
/**
|
|
30929
|
+
* Build a map from each distinct heading font size to a heading level.
|
|
30930
|
+
* The largest heading size becomes `H1`, the next-largest `H2`, and so on,
|
|
30931
|
+
* capped at {@link MAX_HEADING_LEVEL} (`H6`).
|
|
30932
|
+
*
|
|
30933
|
+
* @internal
|
|
30934
|
+
*/
|
|
30935
|
+
function buildHeadingLevelMap(lines, headingThreshold) {
|
|
30936
|
+
const distinct = [...new Set(lines.filter((l) => l.fontSize >= headingThreshold).map((l) => l.fontSize))].sort((a, b) => b - a);
|
|
30937
|
+
const map = /* @__PURE__ */ new Map();
|
|
30938
|
+
distinct.forEach((size, index) => {
|
|
30939
|
+
map.set(size, Math.min(index + 1, MAX_HEADING_LEVEL));
|
|
30940
|
+
});
|
|
30941
|
+
return map;
|
|
30942
|
+
}
|
|
30943
|
+
//#endregion
|
|
29949
30944
|
//#region src/index.ts
|
|
29950
30945
|
/** Whether initWasm has already completed successfully. */
|
|
29951
30946
|
let wasmInitialized = false;
|
|
@@ -29972,15 +30967,15 @@ async function initWasm(options) {
|
|
|
29972
30967
|
if (wasmInitialized) return;
|
|
29973
30968
|
const inits = [];
|
|
29974
30969
|
if (options.deflate || options.deflateWasm) inits.push((async () => {
|
|
29975
|
-
const { initDeflateWasm } = await Promise.resolve().then(() => require("./pdfDocument-
|
|
30970
|
+
const { initDeflateWasm } = await Promise.resolve().then(() => require("./pdfDocument-Bh4ebDqE.cjs")).then((n) => n.libdeflateWasm_exports);
|
|
29976
30971
|
await initDeflateWasm(options.deflateWasm);
|
|
29977
30972
|
})());
|
|
29978
30973
|
if (options.png || options.pngWasm) inits.push((async () => {
|
|
29979
|
-
const { initPngWasm } = await Promise.resolve().then(() => require("./pdfDocument-
|
|
30974
|
+
const { initPngWasm } = await Promise.resolve().then(() => require("./pdfDocument-Bh4ebDqE.cjs")).then((n) => n.pngEmbed_exports);
|
|
29980
30975
|
await initPngWasm(options.pngWasm);
|
|
29981
30976
|
})());
|
|
29982
30977
|
if (options.fonts || options.fontWasm) inits.push((async () => {
|
|
29983
|
-
const { initSubsetWasm } = await Promise.resolve().then(() => require("./pdfDocument-
|
|
30978
|
+
const { initSubsetWasm } = await Promise.resolve().then(() => require("./pdfDocument-Bh4ebDqE.cjs")).then((n) => n.fontSubset_exports);
|
|
29984
30979
|
await initSubsetWasm(options.fontWasm);
|
|
29985
30980
|
})());
|
|
29986
30981
|
if (options.jpeg || options.jpegWasm) inits.push((async () => {
|
|
@@ -30099,6 +31094,12 @@ Object.defineProperty(exports, "InvalidPageSizeError", {
|
|
|
30099
31094
|
return InvalidPageSizeError;
|
|
30100
31095
|
}
|
|
30101
31096
|
});
|
|
31097
|
+
Object.defineProperty(exports, "LIST_NUMBERING_KEY", {
|
|
31098
|
+
enumerable: true,
|
|
31099
|
+
get: function() {
|
|
31100
|
+
return LIST_NUMBERING_KEY;
|
|
31101
|
+
}
|
|
31102
|
+
});
|
|
30102
31103
|
Object.defineProperty(exports, "MATHML_NAMESPACE", {
|
|
30103
31104
|
enumerable: true,
|
|
30104
31105
|
get: function() {
|
|
@@ -30411,6 +31412,24 @@ Object.defineProperty(exports, "assembleTiles", {
|
|
|
30411
31412
|
return assembleTiles;
|
|
30412
31413
|
}
|
|
30413
31414
|
});
|
|
31415
|
+
Object.defineProperty(exports, "attachAssociatedFiles", {
|
|
31416
|
+
enumerable: true,
|
|
31417
|
+
get: function() {
|
|
31418
|
+
return attachAssociatedFiles;
|
|
31419
|
+
}
|
|
31420
|
+
});
|
|
31421
|
+
Object.defineProperty(exports, "attachOutputIntents", {
|
|
31422
|
+
enumerable: true,
|
|
31423
|
+
get: function() {
|
|
31424
|
+
return attachOutputIntents;
|
|
31425
|
+
}
|
|
31426
|
+
});
|
|
31427
|
+
Object.defineProperty(exports, "autoTagPage", {
|
|
31428
|
+
enumerable: true,
|
|
31429
|
+
get: function() {
|
|
31430
|
+
return autoTagPage;
|
|
31431
|
+
}
|
|
31432
|
+
});
|
|
30414
31433
|
Object.defineProperty(exports, "batchFlatten", {
|
|
30415
31434
|
enumerable: true,
|
|
30416
31435
|
get: function() {
|
|
@@ -30435,6 +31454,12 @@ Object.defineProperty(exports, "buildAfArray", {
|
|
|
30435
31454
|
return buildAfArray;
|
|
30436
31455
|
}
|
|
30437
31456
|
});
|
|
31457
|
+
Object.defineProperty(exports, "buildBlackPointCompensationExtGState", {
|
|
31458
|
+
enumerable: true,
|
|
31459
|
+
get: function() {
|
|
31460
|
+
return buildBlackPointCompensationExtGState;
|
|
31461
|
+
}
|
|
31462
|
+
});
|
|
30438
31463
|
Object.defineProperty(exports, "buildBoxDict", {
|
|
30439
31464
|
enumerable: true,
|
|
30440
31465
|
get: function() {
|
|
@@ -30465,6 +31490,12 @@ Object.defineProperty(exports, "buildCollection", {
|
|
|
30465
31490
|
return buildCollection;
|
|
30466
31491
|
}
|
|
30467
31492
|
});
|
|
31493
|
+
Object.defineProperty(exports, "buildColorKeyMask", {
|
|
31494
|
+
enumerable: true,
|
|
31495
|
+
get: function() {
|
|
31496
|
+
return buildColorKeyMask;
|
|
31497
|
+
}
|
|
31498
|
+
});
|
|
30468
31499
|
Object.defineProperty(exports, "buildDPartRoot", {
|
|
30469
31500
|
enumerable: true,
|
|
30470
31501
|
get: function() {
|
|
@@ -30495,6 +31526,12 @@ Object.defineProperty(exports, "buildDssDictionary", {
|
|
|
30495
31526
|
return buildDssDictionary;
|
|
30496
31527
|
}
|
|
30497
31528
|
});
|
|
31529
|
+
Object.defineProperty(exports, "buildEncryptedPayload", {
|
|
31530
|
+
enumerable: true,
|
|
31531
|
+
get: function() {
|
|
31532
|
+
return buildEncryptedPayload;
|
|
31533
|
+
}
|
|
31534
|
+
});
|
|
30498
31535
|
Object.defineProperty(exports, "buildFieldLockDict", {
|
|
30499
31536
|
enumerable: true,
|
|
30500
31537
|
get: function() {
|
|
@@ -30513,6 +31550,12 @@ Object.defineProperty(exports, "buildGtsPdfxVersion", {
|
|
|
30513
31550
|
return buildGtsPdfxVersion;
|
|
30514
31551
|
}
|
|
30515
31552
|
});
|
|
31553
|
+
Object.defineProperty(exports, "buildImageSoftMask", {
|
|
31554
|
+
enumerable: true,
|
|
31555
|
+
get: function() {
|
|
31556
|
+
return buildImageSoftMask;
|
|
31557
|
+
}
|
|
31558
|
+
});
|
|
30516
31559
|
Object.defineProperty(exports, "buildLab", {
|
|
30517
31560
|
enumerable: true,
|
|
30518
31561
|
get: function() {
|
|
@@ -30537,12 +31580,24 @@ Object.defineProperty(exports, "buildOutputIntent", {
|
|
|
30537
31580
|
return buildOutputIntent;
|
|
30538
31581
|
}
|
|
30539
31582
|
});
|
|
31583
|
+
Object.defineProperty(exports, "buildPageOutputIntent", {
|
|
31584
|
+
enumerable: true,
|
|
31585
|
+
get: function() {
|
|
31586
|
+
return buildPageOutputIntent;
|
|
31587
|
+
}
|
|
31588
|
+
});
|
|
30540
31589
|
Object.defineProperty(exports, "buildPdfA4Xmp", {
|
|
30541
31590
|
enumerable: true,
|
|
30542
31591
|
get: function() {
|
|
30543
31592
|
return buildPdfA4Xmp;
|
|
30544
31593
|
}
|
|
30545
31594
|
});
|
|
31595
|
+
Object.defineProperty(exports, "buildPdfUa2Xmp", {
|
|
31596
|
+
enumerable: true,
|
|
31597
|
+
get: function() {
|
|
31598
|
+
return buildPdfUa2Xmp;
|
|
31599
|
+
}
|
|
31600
|
+
});
|
|
30546
31601
|
Object.defineProperty(exports, "buildPdfVtDParts", {
|
|
30547
31602
|
enumerable: true,
|
|
30548
31603
|
get: function() {
|
|
@@ -30591,6 +31646,24 @@ Object.defineProperty(exports, "buildSeparationColorSpace", {
|
|
|
30591
31646
|
return buildSeparationColorSpace;
|
|
30592
31647
|
}
|
|
30593
31648
|
});
|
|
31649
|
+
Object.defineProperty(exports, "buildSoftMaskGroupExtGState", {
|
|
31650
|
+
enumerable: true,
|
|
31651
|
+
get: function() {
|
|
31652
|
+
return buildSoftMaskGroupExtGState;
|
|
31653
|
+
}
|
|
31654
|
+
});
|
|
31655
|
+
Object.defineProperty(exports, "buildSoftMaskNone", {
|
|
31656
|
+
enumerable: true,
|
|
31657
|
+
get: function() {
|
|
31658
|
+
return buildSoftMaskNone;
|
|
31659
|
+
}
|
|
31660
|
+
});
|
|
31661
|
+
Object.defineProperty(exports, "buildStencilMask", {
|
|
31662
|
+
enumerable: true,
|
|
31663
|
+
get: function() {
|
|
31664
|
+
return buildStencilMask;
|
|
31665
|
+
}
|
|
31666
|
+
});
|
|
30594
31667
|
Object.defineProperty(exports, "buildThresholdHalftone", {
|
|
30595
31668
|
enumerable: true,
|
|
30596
31669
|
get: function() {
|
|
@@ -30615,6 +31688,12 @@ Object.defineProperty(exports, "buildType5Halftone", {
|
|
|
30615
31688
|
return buildType5Halftone;
|
|
30616
31689
|
}
|
|
30617
31690
|
});
|
|
31691
|
+
Object.defineProperty(exports, "buildUnencryptedWrapper", {
|
|
31692
|
+
enumerable: true,
|
|
31693
|
+
get: function() {
|
|
31694
|
+
return buildUnencryptedWrapper;
|
|
31695
|
+
}
|
|
31696
|
+
});
|
|
30618
31697
|
Object.defineProperty(exports, "buildVtDpm", {
|
|
30619
31698
|
enumerable: true,
|
|
30620
31699
|
get: function() {
|
|
@@ -31539,6 +32618,12 @@ Object.defineProperty(exports, "redactRegions", {
|
|
|
31539
32618
|
return redactRegions;
|
|
31540
32619
|
}
|
|
31541
32620
|
});
|
|
32621
|
+
Object.defineProperty(exports, "registerEmbeddedFile", {
|
|
32622
|
+
enumerable: true,
|
|
32623
|
+
get: function() {
|
|
32624
|
+
return registerEmbeddedFile;
|
|
32625
|
+
}
|
|
32626
|
+
});
|
|
31542
32627
|
Object.defineProperty(exports, "removeAllBookmarks", {
|
|
31543
32628
|
enumerable: true,
|
|
31544
32629
|
get: function() {
|
|
@@ -31713,6 +32798,66 @@ Object.defineProperty(exports, "tableToJson", {
|
|
|
31713
32798
|
return tableToJson;
|
|
31714
32799
|
}
|
|
31715
32800
|
});
|
|
32801
|
+
Object.defineProperty(exports, "tagFigure", {
|
|
32802
|
+
enumerable: true,
|
|
32803
|
+
get: function() {
|
|
32804
|
+
return tagFigure;
|
|
32805
|
+
}
|
|
32806
|
+
});
|
|
32807
|
+
Object.defineProperty(exports, "tagHeading", {
|
|
32808
|
+
enumerable: true,
|
|
32809
|
+
get: function() {
|
|
32810
|
+
return tagHeading;
|
|
32811
|
+
}
|
|
32812
|
+
});
|
|
32813
|
+
Object.defineProperty(exports, "tagLink", {
|
|
32814
|
+
enumerable: true,
|
|
32815
|
+
get: function() {
|
|
32816
|
+
return tagLink;
|
|
32817
|
+
}
|
|
32818
|
+
});
|
|
32819
|
+
Object.defineProperty(exports, "tagList", {
|
|
32820
|
+
enumerable: true,
|
|
32821
|
+
get: function() {
|
|
32822
|
+
return tagList;
|
|
32823
|
+
}
|
|
32824
|
+
});
|
|
32825
|
+
Object.defineProperty(exports, "tagListItem", {
|
|
32826
|
+
enumerable: true,
|
|
32827
|
+
get: function() {
|
|
32828
|
+
return tagListItem;
|
|
32829
|
+
}
|
|
32830
|
+
});
|
|
32831
|
+
Object.defineProperty(exports, "tagParagraph", {
|
|
32832
|
+
enumerable: true,
|
|
32833
|
+
get: function() {
|
|
32834
|
+
return tagParagraph;
|
|
32835
|
+
}
|
|
32836
|
+
});
|
|
32837
|
+
Object.defineProperty(exports, "tagTable", {
|
|
32838
|
+
enumerable: true,
|
|
32839
|
+
get: function() {
|
|
32840
|
+
return tagTable;
|
|
32841
|
+
}
|
|
32842
|
+
});
|
|
32843
|
+
Object.defineProperty(exports, "tagTableDataCell", {
|
|
32844
|
+
enumerable: true,
|
|
32845
|
+
get: function() {
|
|
32846
|
+
return tagTableDataCell;
|
|
32847
|
+
}
|
|
32848
|
+
});
|
|
32849
|
+
Object.defineProperty(exports, "tagTableHeaderCell", {
|
|
32850
|
+
enumerable: true,
|
|
32851
|
+
get: function() {
|
|
32852
|
+
return tagTableHeaderCell;
|
|
32853
|
+
}
|
|
32854
|
+
});
|
|
32855
|
+
Object.defineProperty(exports, "tagTableRow", {
|
|
32856
|
+
enumerable: true,
|
|
32857
|
+
get: function() {
|
|
32858
|
+
return tagTableRow;
|
|
32859
|
+
}
|
|
32860
|
+
});
|
|
31716
32861
|
Object.defineProperty(exports, "timestampPlugin", {
|
|
31717
32862
|
enumerable: true,
|
|
31718
32863
|
get: function() {
|
|
@@ -31815,6 +32960,12 @@ Object.defineProperty(exports, "validatePdfUa", {
|
|
|
31815
32960
|
return validatePdfUa;
|
|
31816
32961
|
}
|
|
31817
32962
|
});
|
|
32963
|
+
Object.defineProperty(exports, "validatePdfUa2", {
|
|
32964
|
+
enumerable: true,
|
|
32965
|
+
get: function() {
|
|
32966
|
+
return validatePdfUa2;
|
|
32967
|
+
}
|
|
32968
|
+
});
|
|
31818
32969
|
Object.defineProperty(exports, "validatePdfX", {
|
|
31819
32970
|
enumerable: true,
|
|
31820
32971
|
get: function() {
|
|
@@ -31870,4 +33021,4 @@ Object.defineProperty(exports, "wrapText", {
|
|
|
31870
33021
|
}
|
|
31871
33022
|
});
|
|
31872
33023
|
|
|
31873
|
-
//# sourceMappingURL=src-
|
|
33024
|
+
//# sourceMappingURL=src-VeeIdf7B.cjs.map
|