pdf-codec 3.1.3 → 3.2.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 +2 -2
- package/dist/annotations.cjs +104 -0
- package/dist/annotations.d.cts +9 -0
- package/dist/annotations.d.ts +9 -0
- package/dist/annotations.js +103 -0
- package/dist/attachments.cjs +65 -0
- package/dist/attachments.d.cts +8 -0
- package/dist/attachments.d.ts +8 -0
- package/dist/attachments.js +64 -0
- package/dist/bytes/flate.cjs +1 -1
- package/dist/bytes/flate.js +1 -1
- package/dist/codec.d.cts +109 -0
- package/dist/codec.d.ts +109 -0
- package/dist/content-read.cjs +1 -1
- package/dist/content-read.js +1 -1
- package/dist/content-write.cjs +2 -2
- package/dist/content-write.js +2 -2
- package/dist/document.cjs +12 -3
- package/dist/document.d.cts +2 -0
- package/dist/document.d.ts +2 -0
- package/dist/document.js +12 -3
- package/dist/embedded-font-write.cjs +1 -1
- package/dist/embedded-font-write.js +1 -1
- package/dist/encrypt.cjs +1 -1
- package/dist/encrypt.js +1 -1
- package/dist/filters.cjs +1 -1
- package/dist/filters.js +1 -1
- package/dist/font-read.cjs +1 -1
- package/dist/font-read.js +1 -1
- package/dist/font-registry.cjs +1 -1
- package/dist/font-registry.js +1 -1
- package/dist/form.cjs +138 -0
- package/dist/form.d.cts +9 -0
- package/dist/form.d.ts +9 -0
- package/dist/form.js +137 -0
- package/dist/image/png-decode.cjs +1 -1
- package/dist/image/png-decode.js +1 -1
- package/dist/image/png-encode.cjs +1 -1
- package/dist/image/png-encode.js +1 -1
- package/dist/index.cjs +12 -2
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/interpret.cjs +70 -10
- package/dist/interpret.d.cts +9 -1
- package/dist/interpret.d.ts +9 -1
- package/dist/interpret.js +70 -10
- package/dist/layout.cjs +132 -2
- package/dist/layout.d.cts +335 -1
- package/dist/layout.d.ts +335 -1
- package/dist/layout.js +124 -4
- package/dist/math-content-write.cjs +1 -1
- package/dist/math-content-write.js +1 -1
- package/dist/math-font.cjs +1 -1
- package/dist/math-font.js +1 -1
- package/dist/names.cjs +41 -0
- package/dist/names.d.cts +11 -0
- package/dist/names.d.ts +11 -0
- package/dist/names.js +40 -0
- package/dist/navigation.cjs +210 -0
- package/dist/navigation.d.cts +18 -0
- package/dist/navigation.d.ts +18 -0
- package/dist/navigation.js +207 -0
- package/dist/optional-content.cjs +63 -0
- package/dist/optional-content.d.cts +12 -0
- package/dist/optional-content.d.ts +12 -0
- package/dist/optional-content.js +62 -0
- package/dist/parse.cjs +1 -1
- package/dist/parse.d.cts +1 -1
- package/dist/parse.d.ts +1 -1
- package/dist/parse.js +1 -1
- package/dist/pdf-text.cjs +21 -0
- package/dist/pdf-text.d.cts +5 -0
- package/dist/pdf-text.d.ts +5 -0
- package/dist/pdf-text.js +19 -0
- package/dist/read.cjs +128 -58
- package/dist/read.d.cts +2 -4
- package/dist/read.d.ts +2 -4
- package/dist/read.js +125 -53
- package/dist/serialize.cjs +5 -1
- package/dist/serialize.d.cts +3 -2
- package/dist/serialize.d.ts +3 -2
- package/dist/serialize.js +5 -2
- package/dist/write.cjs +51 -5
- package/dist/write.js +51 -5
- package/dist/xmp.cjs +46 -0
- package/dist/xmp.d.cts +14 -0
- package/dist/xmp.d.ts +14 -0
- package/dist/xmp.js +45 -0
- package/dist/xref.cjs +2 -2
- package/dist/xref.js +2 -2
- package/package.json +2 -2
package/dist/layout.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { ColorSchema, ContentStrokeStyleSchema, LayoutFontSchema, LayoutMetadataSchema } from "document-schema.js";
|
|
2
|
+
import { ColorSchema, ContentStrokeStyleSchema, LayoutFontSchema, LayoutMetadataSchema, SourceResidueSchema } from "document-schema.js";
|
|
3
3
|
//#region src/layout.ts
|
|
4
4
|
const LAYOUT_FORMAT_VERSION = 1;
|
|
5
5
|
const LayoutTextSchema = z.object({
|
|
@@ -13,6 +13,9 @@ const LayoutTextSchema = z.object({
|
|
|
13
13
|
widthPt: z.number().nonnegative().optional(),
|
|
14
14
|
rotationDeg: z.number().optional(),
|
|
15
15
|
underline: z.boolean().optional(),
|
|
16
|
+
layer: z.string().optional(),
|
|
17
|
+
actualText: z.string().optional(),
|
|
18
|
+
alt: z.string().optional(),
|
|
16
19
|
sourcePath: z.string().optional()
|
|
17
20
|
});
|
|
18
21
|
const LayoutImageSchema = z.object({
|
|
@@ -23,6 +26,7 @@ const LayoutImageSchema = z.object({
|
|
|
23
26
|
widthPt: z.number().positive(),
|
|
24
27
|
heightPt: z.number().positive(),
|
|
25
28
|
rotationDeg: z.number().optional(),
|
|
29
|
+
layer: z.string().optional(),
|
|
26
30
|
sourcePath: z.string().optional()
|
|
27
31
|
});
|
|
28
32
|
const LayoutRectSchema = z.object({
|
|
@@ -36,6 +40,7 @@ const LayoutRectSchema = z.object({
|
|
|
36
40
|
color: ColorSchema,
|
|
37
41
|
widthPt: z.number().positive()
|
|
38
42
|
}).optional(),
|
|
43
|
+
layer: z.string().optional(),
|
|
39
44
|
sourcePath: z.string().optional()
|
|
40
45
|
});
|
|
41
46
|
const LayoutLineSchema = z.object({
|
|
@@ -47,6 +52,7 @@ const LayoutLineSchema = z.object({
|
|
|
47
52
|
color: ColorSchema,
|
|
48
53
|
widthPt: z.number().positive(),
|
|
49
54
|
style: ContentStrokeStyleSchema.optional(),
|
|
55
|
+
layer: z.string().optional(),
|
|
50
56
|
sourcePath: z.string().optional()
|
|
51
57
|
});
|
|
52
58
|
const LayoutEllipseSchema = z.object({
|
|
@@ -60,6 +66,7 @@ const LayoutEllipseSchema = z.object({
|
|
|
60
66
|
color: ColorSchema,
|
|
61
67
|
widthPt: z.number().positive()
|
|
62
68
|
}).optional(),
|
|
69
|
+
layer: z.string().optional(),
|
|
63
70
|
sourcePath: z.string().optional()
|
|
64
71
|
});
|
|
65
72
|
const LayoutPathSegmentSchema = z.discriminatedUnion("kind", [z.object({
|
|
@@ -91,6 +98,7 @@ const LayoutPathSchema = z.object({
|
|
|
91
98
|
widthPt: z.number().positive()
|
|
92
99
|
}).optional(),
|
|
93
100
|
style: ContentStrokeStyleSchema.optional(),
|
|
101
|
+
layer: z.string().optional(),
|
|
94
102
|
sourcePath: z.string().optional()
|
|
95
103
|
});
|
|
96
104
|
const LayoutLinkSchema = z.object({
|
|
@@ -100,8 +108,18 @@ const LayoutLinkSchema = z.object({
|
|
|
100
108
|
yPt: z.number(),
|
|
101
109
|
widthPt: z.number().nonnegative(),
|
|
102
110
|
heightPt: z.number().nonnegative(),
|
|
111
|
+
title: z.string().optional(),
|
|
103
112
|
sourcePath: z.string().optional()
|
|
104
113
|
});
|
|
114
|
+
const LayoutInternalLinkSchema = z.object({
|
|
115
|
+
kind: z.literal("internalLink"),
|
|
116
|
+
destination: z.string(),
|
|
117
|
+
xPt: z.number(),
|
|
118
|
+
yPt: z.number(),
|
|
119
|
+
widthPt: z.number().nonnegative(),
|
|
120
|
+
heightPt: z.number().nonnegative(),
|
|
121
|
+
title: z.string().optional()
|
|
122
|
+
});
|
|
105
123
|
const LayoutItemSchema = z.discriminatedUnion("kind", [
|
|
106
124
|
LayoutTextSchema,
|
|
107
125
|
LayoutImageSchema,
|
|
@@ -109,12 +127,44 @@ const LayoutItemSchema = z.discriminatedUnion("kind", [
|
|
|
109
127
|
LayoutLineSchema,
|
|
110
128
|
LayoutEllipseSchema,
|
|
111
129
|
LayoutPathSchema,
|
|
112
|
-
LayoutLinkSchema
|
|
130
|
+
LayoutLinkSchema,
|
|
131
|
+
LayoutInternalLinkSchema
|
|
113
132
|
]);
|
|
133
|
+
const LayoutAnnotationQuadSchema = z.tuple([
|
|
134
|
+
z.object({
|
|
135
|
+
xPt: z.number(),
|
|
136
|
+
yPt: z.number()
|
|
137
|
+
}),
|
|
138
|
+
z.object({
|
|
139
|
+
xPt: z.number(),
|
|
140
|
+
yPt: z.number()
|
|
141
|
+
}),
|
|
142
|
+
z.object({
|
|
143
|
+
xPt: z.number(),
|
|
144
|
+
yPt: z.number()
|
|
145
|
+
}),
|
|
146
|
+
z.object({
|
|
147
|
+
xPt: z.number(),
|
|
148
|
+
yPt: z.number()
|
|
149
|
+
})
|
|
150
|
+
]);
|
|
151
|
+
const LayoutAnnotationSchema = z.object({
|
|
152
|
+
subtype: z.string(),
|
|
153
|
+
xPt: z.number(),
|
|
154
|
+
yPt: z.number(),
|
|
155
|
+
widthPt: z.number().nonnegative(),
|
|
156
|
+
heightPt: z.number().nonnegative(),
|
|
157
|
+
contents: z.string().optional(),
|
|
158
|
+
author: z.string().optional(),
|
|
159
|
+
modifiedIso: z.string().optional(),
|
|
160
|
+
quads: z.array(LayoutAnnotationQuadSchema).optional(),
|
|
161
|
+
source: SourceResidueSchema.optional()
|
|
162
|
+
});
|
|
114
163
|
const LayoutPageSchema = z.object({
|
|
115
164
|
widthPt: z.number().positive(),
|
|
116
165
|
heightPt: z.number().positive(),
|
|
117
166
|
items: z.array(LayoutItemSchema),
|
|
167
|
+
annotations: z.array(LayoutAnnotationSchema).optional(),
|
|
118
168
|
notes: z.string().optional()
|
|
119
169
|
});
|
|
120
170
|
const LayoutImageAssetSchema = z.object({
|
|
@@ -123,11 +173,81 @@ const LayoutImageAssetSchema = z.object({
|
|
|
123
173
|
widthPx: z.number().int().positive(),
|
|
124
174
|
heightPx: z.number().int().positive()
|
|
125
175
|
});
|
|
176
|
+
const LayoutDestinationTargetSchema = z.object({
|
|
177
|
+
kind: z.enum([
|
|
178
|
+
"xyz",
|
|
179
|
+
"fit",
|
|
180
|
+
"fitH",
|
|
181
|
+
"fitV",
|
|
182
|
+
"fitR",
|
|
183
|
+
"fitB",
|
|
184
|
+
"fitBH",
|
|
185
|
+
"fitBV"
|
|
186
|
+
]),
|
|
187
|
+
leftPt: z.number().optional(),
|
|
188
|
+
topPt: z.number().optional(),
|
|
189
|
+
bottomPt: z.number().optional(),
|
|
190
|
+
rightPt: z.number().optional(),
|
|
191
|
+
zoom: z.number().optional()
|
|
192
|
+
});
|
|
193
|
+
const LayoutDestinationSchema = z.object({
|
|
194
|
+
name: z.string(),
|
|
195
|
+
pageIndex: z.number().int().nonnegative(),
|
|
196
|
+
target: LayoutDestinationTargetSchema
|
|
197
|
+
});
|
|
198
|
+
const LayoutOutlineItemSchema = z.lazy(() => z.object({
|
|
199
|
+
title: z.string(),
|
|
200
|
+
destination: z.string().optional(),
|
|
201
|
+
children: z.array(LayoutOutlineItemSchema)
|
|
202
|
+
}));
|
|
203
|
+
const LayoutAttachmentSchema = z.object({
|
|
204
|
+
name: z.string(),
|
|
205
|
+
description: z.string().optional(),
|
|
206
|
+
mimeType: z.string().optional(),
|
|
207
|
+
base64: z.string()
|
|
208
|
+
});
|
|
209
|
+
const LayoutFormWidgetSchema = z.object({
|
|
210
|
+
pageIndex: z.number().int().nonnegative(),
|
|
211
|
+
xPt: z.number(),
|
|
212
|
+
yPt: z.number(),
|
|
213
|
+
widthPt: z.number().nonnegative(),
|
|
214
|
+
heightPt: z.number().nonnegative()
|
|
215
|
+
});
|
|
216
|
+
const LayoutFormFieldSchema = z.lazy(() => z.object({
|
|
217
|
+
name: z.string(),
|
|
218
|
+
fieldType: z.enum([
|
|
219
|
+
"text",
|
|
220
|
+
"checkbox",
|
|
221
|
+
"radio",
|
|
222
|
+
"button",
|
|
223
|
+
"listbox",
|
|
224
|
+
"combobox",
|
|
225
|
+
"signature",
|
|
226
|
+
"group"
|
|
227
|
+
]),
|
|
228
|
+
value: z.string().optional(),
|
|
229
|
+
checked: z.boolean().optional(),
|
|
230
|
+
options: z.array(z.string()).optional(),
|
|
231
|
+
alias: z.string().optional(),
|
|
232
|
+
readOnly: z.boolean().optional(),
|
|
233
|
+
widgets: z.array(LayoutFormWidgetSchema),
|
|
234
|
+
children: z.array(LayoutFormFieldSchema)
|
|
235
|
+
}));
|
|
236
|
+
const LayoutLayerSchema = z.object({
|
|
237
|
+
name: z.string(),
|
|
238
|
+
visible: z.boolean()
|
|
239
|
+
});
|
|
126
240
|
const LayoutDocumentSchema = z.object({
|
|
127
241
|
formatVersion: z.literal(1),
|
|
128
242
|
metadata: LayoutMetadataSchema,
|
|
129
243
|
pages: z.array(LayoutPageSchema),
|
|
130
|
-
images: z.record(z.string(), LayoutImageAssetSchema)
|
|
244
|
+
images: z.record(z.string(), LayoutImageAssetSchema),
|
|
245
|
+
destinations: z.array(LayoutDestinationSchema).optional(),
|
|
246
|
+
outline: z.array(LayoutOutlineItemSchema).optional(),
|
|
247
|
+
attachments: z.array(LayoutAttachmentSchema).optional(),
|
|
248
|
+
layers: z.array(LayoutLayerSchema).optional(),
|
|
249
|
+
form: z.array(LayoutFormFieldSchema).optional(),
|
|
250
|
+
source: z.record(z.string(), SourceResidueSchema).optional()
|
|
131
251
|
});
|
|
132
252
|
//#endregion
|
|
133
|
-
export { LAYOUT_FORMAT_VERSION, LayoutDocumentSchema, LayoutEllipseSchema, LayoutImageAssetSchema, LayoutImageSchema, LayoutItemSchema, LayoutLineSchema, LayoutLinkSchema, LayoutPageSchema, LayoutPathSchema, LayoutPathSegmentSchema, LayoutRectSchema, LayoutSubpathSchema, LayoutTextSchema };
|
|
253
|
+
export { LAYOUT_FORMAT_VERSION, LayoutAnnotationQuadSchema, LayoutAnnotationSchema, LayoutAttachmentSchema, LayoutDestinationSchema, LayoutDestinationTargetSchema, LayoutDocumentSchema, LayoutEllipseSchema, LayoutFormFieldSchema, LayoutFormWidgetSchema, LayoutImageAssetSchema, LayoutImageSchema, LayoutInternalLinkSchema, LayoutItemSchema, LayoutLayerSchema, LayoutLineSchema, LayoutLinkSchema, LayoutOutlineItemSchema, LayoutPageSchema, LayoutPathSchema, LayoutPathSegmentSchema, LayoutRectSchema, LayoutSubpathSchema, LayoutTextSchema };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_bytes_writer = require("./bytes/writer.cjs");
|
|
3
2
|
const require_objects = require("./objects.cjs");
|
|
3
|
+
const require_bytes_writer = require("./bytes/writer.cjs");
|
|
4
4
|
const require_serialize = require("./serialize.cjs");
|
|
5
5
|
//#region src/math-content-write.ts
|
|
6
6
|
function toPdfX(positioned, itemXPt) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ByteWriter } from "./bytes/writer.js";
|
|
2
1
|
import { pdfDict, pdfHexString, pdfName } from "./objects.js";
|
|
2
|
+
import { ByteWriter } from "./bytes/writer.js";
|
|
3
3
|
import { formatNumber, writeObject } from "./serialize.js";
|
|
4
4
|
//#region src/math-content-write.ts
|
|
5
5
|
function toPdfX(positioned, itemXPt) {
|
package/dist/math-font.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_util_base64 = require("./util/base64.cjs");
|
|
2
3
|
const require_sfnt = require("./sfnt.cjs");
|
|
3
4
|
const require_cff_bounds = require("./cff-bounds.cjs");
|
|
4
5
|
const require_cmap_table = require("./cmap-table.cjs");
|
|
5
|
-
const require_util_base64 = require("./util/base64.cjs");
|
|
6
6
|
const require_hmtx_table = require("./hmtx-table.cjs");
|
|
7
7
|
const require_assets_stix_two_math_font = require("./assets/stix-two-math-font.cjs");
|
|
8
8
|
const require_math_stretch = require("./math-stretch.cjs");
|
package/dist/math-font.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { base64ToBytes } from "./util/base64.js";
|
|
1
2
|
import { i16, parseSfnt, sfntTableBytes, u16 } from "./sfnt.js";
|
|
2
3
|
import { parseCffGlyphBounds } from "./cff-bounds.js";
|
|
3
4
|
import { buildCmapLookup } from "./cmap-table.js";
|
|
4
|
-
import { base64ToBytes } from "./util/base64.js";
|
|
5
5
|
import { parseHmtx } from "./hmtx-table.js";
|
|
6
6
|
import { STIX_TWO_MATH_FONT_BASE64 } from "./assets/stix-two-math-font.js";
|
|
7
7
|
import { assembleStretchyGlyph, scaleMathStretchConstruction } from "./math-stretch.js";
|
package/dist/names.cjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_objects = require("./objects.cjs");
|
|
3
|
+
const require_pdf_text = require("./pdf-text.cjs");
|
|
4
|
+
//#region src/names.ts
|
|
5
|
+
function walkNameTree(root, resolver, sink) {
|
|
6
|
+
const entries = [];
|
|
7
|
+
collectNameTreeEntries(root, resolver, sink, entries, /* @__PURE__ */ new Set());
|
|
8
|
+
return entries;
|
|
9
|
+
}
|
|
10
|
+
function collectNameTreeEntries(node, resolver, sink, entries, visited) {
|
|
11
|
+
const dict = require_objects.asDict(resolver.resolve(node));
|
|
12
|
+
if (dict === void 0) {
|
|
13
|
+
if (node !== void 0) sink({
|
|
14
|
+
code: "pdf/name-tree-node-invalid",
|
|
15
|
+
severity: "warning",
|
|
16
|
+
message: "a name tree node did not resolve to a dictionary; skipping it"
|
|
17
|
+
});
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (visited.has(dict)) {
|
|
21
|
+
sink({
|
|
22
|
+
code: "pdf/name-tree-cycle",
|
|
23
|
+
severity: "warning",
|
|
24
|
+
message: "the name tree contains a cycle; stopping descent at the repeated node"
|
|
25
|
+
});
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
visited.add(dict);
|
|
29
|
+
const names = require_objects.asArray(require_objects.dictGet(dict, "Names"));
|
|
30
|
+
if (names !== void 0) for (let i = 0; i + 1 < names.length; i += 2) {
|
|
31
|
+
const key = names[i];
|
|
32
|
+
if (key?.kind === "string") entries.push({
|
|
33
|
+
name: require_pdf_text.decodePdfString(key.bytes),
|
|
34
|
+
value: names[i + 1]
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const kids = require_objects.asArray(require_objects.dictGet(dict, "Kids"));
|
|
38
|
+
if (kids !== void 0) for (const kid of kids) collectNameTreeEntries(kid, resolver, sink, entries, visited);
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
exports.walkNameTree = walkNameTree;
|
package/dist/names.d.cts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PdfDiagnosticSink } from "./diagnostics.cjs";
|
|
2
|
+
import { PdfObject } from "./objects.cjs";
|
|
3
|
+
import { PdfObjectResolver } from "./interpret.cjs";
|
|
4
|
+
//#region src/names.d.ts
|
|
5
|
+
interface NameTreeEntry {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly value: PdfObject;
|
|
8
|
+
}
|
|
9
|
+
declare function walkNameTree(root: PdfObject | undefined, resolver: PdfObjectResolver, sink: PdfDiagnosticSink): NameTreeEntry[];
|
|
10
|
+
//#endregion
|
|
11
|
+
export { NameTreeEntry, walkNameTree };
|
package/dist/names.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PdfDiagnosticSink } from "./diagnostics.js";
|
|
2
|
+
import { PdfObject } from "./objects.js";
|
|
3
|
+
import { PdfObjectResolver } from "./interpret.js";
|
|
4
|
+
//#region src/names.d.ts
|
|
5
|
+
interface NameTreeEntry {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly value: PdfObject;
|
|
8
|
+
}
|
|
9
|
+
declare function walkNameTree(root: PdfObject | undefined, resolver: PdfObjectResolver, sink: PdfDiagnosticSink): NameTreeEntry[];
|
|
10
|
+
//#endregion
|
|
11
|
+
export { NameTreeEntry, walkNameTree };
|
package/dist/names.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { asArray, asDict, dictGet } from "./objects.js";
|
|
2
|
+
import { decodePdfString } from "./pdf-text.js";
|
|
3
|
+
//#region src/names.ts
|
|
4
|
+
function walkNameTree(root, resolver, sink) {
|
|
5
|
+
const entries = [];
|
|
6
|
+
collectNameTreeEntries(root, resolver, sink, entries, /* @__PURE__ */ new Set());
|
|
7
|
+
return entries;
|
|
8
|
+
}
|
|
9
|
+
function collectNameTreeEntries(node, resolver, sink, entries, visited) {
|
|
10
|
+
const dict = asDict(resolver.resolve(node));
|
|
11
|
+
if (dict === void 0) {
|
|
12
|
+
if (node !== void 0) sink({
|
|
13
|
+
code: "pdf/name-tree-node-invalid",
|
|
14
|
+
severity: "warning",
|
|
15
|
+
message: "a name tree node did not resolve to a dictionary; skipping it"
|
|
16
|
+
});
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (visited.has(dict)) {
|
|
20
|
+
sink({
|
|
21
|
+
code: "pdf/name-tree-cycle",
|
|
22
|
+
severity: "warning",
|
|
23
|
+
message: "the name tree contains a cycle; stopping descent at the repeated node"
|
|
24
|
+
});
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
visited.add(dict);
|
|
28
|
+
const names = asArray(dictGet(dict, "Names"));
|
|
29
|
+
if (names !== void 0) for (let i = 0; i + 1 < names.length; i += 2) {
|
|
30
|
+
const key = names[i];
|
|
31
|
+
if (key?.kind === "string") entries.push({
|
|
32
|
+
name: decodePdfString(key.bytes),
|
|
33
|
+
value: names[i + 1]
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const kids = asArray(dictGet(dict, "Kids"));
|
|
37
|
+
if (kids !== void 0) for (const kid of kids) collectNameTreeEntries(kid, resolver, sink, entries, visited);
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { walkNameTree };
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_objects = require("./objects.cjs");
|
|
3
|
+
const require_pdf_text = require("./pdf-text.cjs");
|
|
4
|
+
const require_names = require("./names.cjs");
|
|
5
|
+
//#region src/navigation.ts
|
|
6
|
+
function coordinateAt(arr, index) {
|
|
7
|
+
return require_objects.asNumber(arr[index]);
|
|
8
|
+
}
|
|
9
|
+
function parseDestination(value, resolver, pageIndex, sink) {
|
|
10
|
+
const arr = require_objects.asArray(resolver.resolve(value));
|
|
11
|
+
if (arr === void 0 || arr.length < 2) {
|
|
12
|
+
sink({
|
|
13
|
+
code: "pdf/destination-invalid",
|
|
14
|
+
severity: "warning",
|
|
15
|
+
message: "a destination is not a display destination array; skipping it"
|
|
16
|
+
});
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const pageEl = arr[0];
|
|
20
|
+
const resolvedPageIndex = pageEl?.kind === "number" ? Number.isInteger(pageEl.value) && pageEl.value >= 0 ? pageEl.value : void 0 : pageIndex(pageEl);
|
|
21
|
+
if (resolvedPageIndex === void 0) {
|
|
22
|
+
sink({
|
|
23
|
+
code: "pdf/destination-invalid",
|
|
24
|
+
severity: "warning",
|
|
25
|
+
message: "a destination names a page that is not in the document's page tree; skipping it"
|
|
26
|
+
});
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const type = require_objects.asName(arr[1]);
|
|
30
|
+
if (type === "XYZ") return {
|
|
31
|
+
pageIndex: resolvedPageIndex,
|
|
32
|
+
target: {
|
|
33
|
+
kind: "xyz",
|
|
34
|
+
...optionalCoords(arr, [
|
|
35
|
+
["leftPt", 2],
|
|
36
|
+
["topPt", 3],
|
|
37
|
+
["zoom", 4]
|
|
38
|
+
])
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
if (type === "Fit") return {
|
|
42
|
+
pageIndex: resolvedPageIndex,
|
|
43
|
+
target: { kind: "fit" }
|
|
44
|
+
};
|
|
45
|
+
if (type === "FitH") return {
|
|
46
|
+
pageIndex: resolvedPageIndex,
|
|
47
|
+
target: {
|
|
48
|
+
kind: "fitH",
|
|
49
|
+
...optionalCoords(arr, [["topPt", 2]])
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
if (type === "FitV") return {
|
|
53
|
+
pageIndex: resolvedPageIndex,
|
|
54
|
+
target: {
|
|
55
|
+
kind: "fitV",
|
|
56
|
+
...optionalCoords(arr, [["leftPt", 2]])
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
if (type === "FitR") return {
|
|
60
|
+
pageIndex: resolvedPageIndex,
|
|
61
|
+
target: {
|
|
62
|
+
kind: "fitR",
|
|
63
|
+
...optionalCoords(arr, [
|
|
64
|
+
["leftPt", 2],
|
|
65
|
+
["bottomPt", 3],
|
|
66
|
+
["rightPt", 4],
|
|
67
|
+
["topPt", 5]
|
|
68
|
+
])
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
if (type === "FitB") return {
|
|
72
|
+
pageIndex: resolvedPageIndex,
|
|
73
|
+
target: { kind: "fitB" }
|
|
74
|
+
};
|
|
75
|
+
if (type === "FitBH") return {
|
|
76
|
+
pageIndex: resolvedPageIndex,
|
|
77
|
+
target: {
|
|
78
|
+
kind: "fitBH",
|
|
79
|
+
...optionalCoords(arr, [["topPt", 2]])
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
if (type === "FitBV") return {
|
|
83
|
+
pageIndex: resolvedPageIndex,
|
|
84
|
+
target: {
|
|
85
|
+
kind: "fitBV",
|
|
86
|
+
...optionalCoords(arr, [["leftPt", 2]])
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
sink({
|
|
90
|
+
code: "pdf/destination-invalid",
|
|
91
|
+
severity: "warning",
|
|
92
|
+
message: `a destination carries unknown display type /${type ?? "?"}; skipping it`
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function optionalCoords(arr, fields) {
|
|
96
|
+
const out = {};
|
|
97
|
+
for (const [field, index] of fields) {
|
|
98
|
+
const value = coordinateAt(arr, index);
|
|
99
|
+
if (value !== void 0) out[field] = value;
|
|
100
|
+
}
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
function createDestinationRegistry(catalog, resolver, pageIndex, sink) {
|
|
104
|
+
const entries = [];
|
|
105
|
+
const byName = /* @__PURE__ */ new Map();
|
|
106
|
+
const add = (name, parsed) => {
|
|
107
|
+
const entry = {
|
|
108
|
+
name,
|
|
109
|
+
pageIndex: parsed.pageIndex,
|
|
110
|
+
target: parsed.target
|
|
111
|
+
};
|
|
112
|
+
entries.push(entry);
|
|
113
|
+
byName.set(name, entry);
|
|
114
|
+
};
|
|
115
|
+
const destsDict = resolver.resolveDict(require_objects.dictGet(catalog, "Dests"));
|
|
116
|
+
if (destsDict !== void 0) for (const [name, value] of destsDict.entries) {
|
|
117
|
+
if (byName.has(name)) {
|
|
118
|
+
sink({
|
|
119
|
+
code: "pdf/destination-duplicate",
|
|
120
|
+
severity: "warning",
|
|
121
|
+
message: `destination name "${name}" is declared more than once; keeping the first`
|
|
122
|
+
});
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const parsed = parseDestination(value, resolver, pageIndex, sink);
|
|
126
|
+
if (parsed !== void 0) add(name, parsed);
|
|
127
|
+
}
|
|
128
|
+
const namesRoot = resolver.resolveDict(require_objects.dictGet(catalog, "Names"));
|
|
129
|
+
for (const entry of require_names.walkNameTree(namesRoot === void 0 ? void 0 : require_objects.dictGet(namesRoot, "Dests"), resolver, sink)) {
|
|
130
|
+
if (byName.has(entry.name)) {
|
|
131
|
+
sink({
|
|
132
|
+
code: "pdf/destination-duplicate",
|
|
133
|
+
severity: "warning",
|
|
134
|
+
message: `destination name "${entry.name}" is declared more than once; keeping the first`
|
|
135
|
+
});
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const parsed = parseDestination(entry.value, resolver, pageIndex, sink);
|
|
139
|
+
if (parsed !== void 0) add(entry.name, parsed);
|
|
140
|
+
}
|
|
141
|
+
const minted = (obj) => {
|
|
142
|
+
const parsed = parseDestination(obj, resolver, pageIndex, sink);
|
|
143
|
+
if (parsed === void 0) return;
|
|
144
|
+
let n = 1;
|
|
145
|
+
while (byName.has(`dest${n}`)) n++;
|
|
146
|
+
const name = `dest${n}`;
|
|
147
|
+
add(name, parsed);
|
|
148
|
+
return name;
|
|
149
|
+
};
|
|
150
|
+
return {
|
|
151
|
+
entries,
|
|
152
|
+
intern(obj) {
|
|
153
|
+
const resolved = resolver.resolve(obj);
|
|
154
|
+
if (resolved?.kind === "string") {
|
|
155
|
+
const name = require_pdf_text.decodePdfString(resolved.bytes);
|
|
156
|
+
if (byName.has(name)) return name;
|
|
157
|
+
sink({
|
|
158
|
+
code: "pdf/destination-unresolved",
|
|
159
|
+
severity: "warning",
|
|
160
|
+
message: `a destination names "${name}", which no /Dests or /Names /Dests entry declares`
|
|
161
|
+
});
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (resolved?.kind === "array") return minted(resolved);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function readOutline(catalog, registry, resolver, sink) {
|
|
169
|
+
const root = resolver.resolveDict(require_objects.dictGet(catalog, "Outlines"));
|
|
170
|
+
const first = root === void 0 ? void 0 : resolver.resolveDict(require_objects.dictGet(root, "First"));
|
|
171
|
+
if (first === void 0) return [];
|
|
172
|
+
const items = [];
|
|
173
|
+
walkOutlineSiblings(first, items, registry, resolver, sink, /* @__PURE__ */ new Set());
|
|
174
|
+
return items;
|
|
175
|
+
}
|
|
176
|
+
function walkOutlineSiblings(node, out, registry, resolver, sink, visited) {
|
|
177
|
+
let current = node;
|
|
178
|
+
while (current !== void 0) {
|
|
179
|
+
if (visited.has(current)) {
|
|
180
|
+
sink({
|
|
181
|
+
code: "pdf/outline-cycle",
|
|
182
|
+
severity: "warning",
|
|
183
|
+
message: "the outline contains a cycle; stopping the sibling chain at the repeated item"
|
|
184
|
+
});
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
visited.add(current);
|
|
188
|
+
const titleObj = require_objects.dictGet(current, "Title");
|
|
189
|
+
const children = [];
|
|
190
|
+
const childFirst = resolver.resolveDict(require_objects.dictGet(current, "First"));
|
|
191
|
+
if (childFirst !== void 0) walkOutlineSiblings(childFirst, children, registry, resolver, sink, visited);
|
|
192
|
+
const destination = internOutlineDestination(current, registry, resolver);
|
|
193
|
+
out.push({
|
|
194
|
+
title: titleObj?.kind === "string" ? require_pdf_text.decodePdfString(titleObj.bytes) : "",
|
|
195
|
+
...destination !== void 0 ? { destination } : {},
|
|
196
|
+
children
|
|
197
|
+
});
|
|
198
|
+
current = resolver.resolveDict(require_objects.dictGet(current, "Next"));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function internOutlineDestination(node, registry, resolver) {
|
|
202
|
+
const dest = require_objects.dictGet(node, "Dest");
|
|
203
|
+
if (dest !== void 0) return registry.intern(dest);
|
|
204
|
+
const action = resolver.resolveDict(require_objects.dictGet(node, "A"));
|
|
205
|
+
if (action !== void 0 && require_objects.asName(require_objects.dictGet(action, "S")) === "GoTo") return registry.intern(require_objects.dictGet(action, "D"));
|
|
206
|
+
}
|
|
207
|
+
//#endregion
|
|
208
|
+
exports.createDestinationRegistry = createDestinationRegistry;
|
|
209
|
+
exports.parseDestination = parseDestination;
|
|
210
|
+
exports.readOutline = readOutline;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PdfDiagnosticSink } from "./diagnostics.cjs";
|
|
2
|
+
import { PdfDict, PdfObject } from "./objects.cjs";
|
|
3
|
+
import { PdfObjectResolver } from "./interpret.cjs";
|
|
4
|
+
import { LayoutDestination, LayoutDestinationTarget, LayoutOutlineItem } from "./layout.cjs";
|
|
5
|
+
//#region src/navigation.d.ts
|
|
6
|
+
type PageIndexLookup = (obj: PdfObject | undefined) => number | undefined;
|
|
7
|
+
declare function parseDestination(value: PdfObject | undefined, resolver: PdfObjectResolver, pageIndex: PageIndexLookup, sink: PdfDiagnosticSink): {
|
|
8
|
+
pageIndex: number;
|
|
9
|
+
target: LayoutDestinationTarget;
|
|
10
|
+
} | undefined;
|
|
11
|
+
interface DestinationRegistry {
|
|
12
|
+
readonly entries: readonly LayoutDestination[];
|
|
13
|
+
intern(obj: PdfObject | undefined): string | undefined;
|
|
14
|
+
}
|
|
15
|
+
declare function createDestinationRegistry(catalog: PdfDict, resolver: PdfObjectResolver, pageIndex: PageIndexLookup, sink: PdfDiagnosticSink): DestinationRegistry;
|
|
16
|
+
declare function readOutline(catalog: PdfDict, registry: DestinationRegistry, resolver: PdfObjectResolver, sink: PdfDiagnosticSink): LayoutOutlineItem[];
|
|
17
|
+
//#endregion
|
|
18
|
+
export { DestinationRegistry, PageIndexLookup, createDestinationRegistry, parseDestination, readOutline };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PdfDiagnosticSink } from "./diagnostics.js";
|
|
2
|
+
import { PdfDict, PdfObject } from "./objects.js";
|
|
3
|
+
import { PdfObjectResolver } from "./interpret.js";
|
|
4
|
+
import { LayoutDestination, LayoutDestinationTarget, LayoutOutlineItem } from "./layout.js";
|
|
5
|
+
//#region src/navigation.d.ts
|
|
6
|
+
type PageIndexLookup = (obj: PdfObject | undefined) => number | undefined;
|
|
7
|
+
declare function parseDestination(value: PdfObject | undefined, resolver: PdfObjectResolver, pageIndex: PageIndexLookup, sink: PdfDiagnosticSink): {
|
|
8
|
+
pageIndex: number;
|
|
9
|
+
target: LayoutDestinationTarget;
|
|
10
|
+
} | undefined;
|
|
11
|
+
interface DestinationRegistry {
|
|
12
|
+
readonly entries: readonly LayoutDestination[];
|
|
13
|
+
intern(obj: PdfObject | undefined): string | undefined;
|
|
14
|
+
}
|
|
15
|
+
declare function createDestinationRegistry(catalog: PdfDict, resolver: PdfObjectResolver, pageIndex: PageIndexLookup, sink: PdfDiagnosticSink): DestinationRegistry;
|
|
16
|
+
declare function readOutline(catalog: PdfDict, registry: DestinationRegistry, resolver: PdfObjectResolver, sink: PdfDiagnosticSink): LayoutOutlineItem[];
|
|
17
|
+
//#endregion
|
|
18
|
+
export { DestinationRegistry, PageIndexLookup, createDestinationRegistry, parseDestination, readOutline };
|