pdf-codec 3.1.4 → 3.3.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 -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 +272 -72
- package/dist/read.d.cts +2 -4
- package/dist/read.d.ts +2 -4
- package/dist/read.js +269 -67
- 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/read.cjs
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("./notes-annotation-author.cjs");
|
|
3
|
+
const require_objects = require("./objects.cjs");
|
|
4
|
+
const require_pdf_text = require("./pdf-text.cjs");
|
|
5
|
+
const require_bytes_writer = require("./bytes/writer.cjs");
|
|
6
|
+
const require_serialize = require("./serialize.cjs");
|
|
7
|
+
const require_matrix = require("./matrix.cjs");
|
|
8
|
+
const require_annotations = require("./annotations.cjs");
|
|
9
|
+
const require_filters = require("./filters.cjs");
|
|
2
10
|
const require_util_base64 = require("./util/base64.cjs");
|
|
11
|
+
const require_attachments = require("./attachments.cjs");
|
|
3
12
|
const require_bytes_crc32 = require("./bytes/crc32.cjs");
|
|
4
|
-
const
|
|
13
|
+
const require_form = require("./form.cjs");
|
|
14
|
+
const require_xmp = require("./xmp.cjs");
|
|
15
|
+
const require_optional_content = require("./optional-content.cjs");
|
|
5
16
|
require("./layout.cjs");
|
|
6
17
|
const require_diagnostics = require("./diagnostics.cjs");
|
|
7
|
-
const require_objects = require("./objects.cjs");
|
|
8
|
-
const require_filters = require("./filters.cjs");
|
|
9
18
|
const require_document = require("./document.cjs");
|
|
10
19
|
const require_util_abort = require("./util/abort.cjs");
|
|
11
20
|
const require_font_read = require("./font-read.cjs");
|
|
12
21
|
const require_images_read = require("./images-read.cjs");
|
|
13
|
-
const require_matrix = require("./matrix.cjs");
|
|
14
22
|
const require_interpret = require("./interpret.cjs");
|
|
15
|
-
require("./
|
|
23
|
+
const require_navigation = require("./navigation.cjs");
|
|
16
24
|
//#region src/read.ts
|
|
17
25
|
const PDF_HEADER_BYTES = new TextEncoder().encode("%PDF-");
|
|
18
26
|
const HEADER_SEARCH_WINDOW = 1024;
|
|
@@ -38,29 +46,42 @@ function readPdf(bytes, options) {
|
|
|
38
46
|
});
|
|
39
47
|
const images = {};
|
|
40
48
|
const imageIdCache = /* @__PURE__ */ new Map();
|
|
41
|
-
const
|
|
49
|
+
const pageDicts = doc.pages();
|
|
50
|
+
const destinationRegistry = require_navigation.createDestinationRegistry(doc.catalog, doc, (obj) => doc.pageIndex(obj), sink);
|
|
51
|
+
const outline = require_navigation.readOutline(doc.catalog, destinationRegistry, doc, sink);
|
|
52
|
+
const attachments = require_attachments.readAttachments(doc.catalog, pageDicts, doc, sink);
|
|
53
|
+
const optionalContent = require_optional_content.readOptionalContent(doc.catalog, doc, sink);
|
|
54
|
+
const form = require_form.readAcroForm(doc.catalog, doc, (obj) => doc.pageIndex(obj), sink);
|
|
55
|
+
const source = readDocumentResidue(doc, sink);
|
|
56
|
+
const pageBoxRows = [];
|
|
57
|
+
const pages = pageDicts.map((pageDict, index) => {
|
|
42
58
|
require_util_abort.throwIfAborted(signal);
|
|
43
|
-
return readPage(pageDict, doc, fontResolver, images, imageIdCache, sink);
|
|
59
|
+
return readPage(index, pageDict, doc, fontResolver, images, imageIdCache, destinationRegistry, optionalContent.layerNameOf, pageBoxRows, sink);
|
|
44
60
|
});
|
|
61
|
+
if (pageBoxRows.length > 0) source["page-boxes"] = {
|
|
62
|
+
format: "pdf",
|
|
63
|
+
xml: require_serialize.serializeObjectToText(require_objects.pdfArray(pageBoxRows))
|
|
64
|
+
};
|
|
45
65
|
return {
|
|
46
66
|
formatVersion: 1,
|
|
47
|
-
metadata: readMetadata(doc.trailer, doc),
|
|
67
|
+
metadata: readMetadata(doc.trailer, doc, doc.catalog, sink),
|
|
48
68
|
pages,
|
|
49
|
-
images
|
|
69
|
+
images,
|
|
70
|
+
...destinationRegistry.entries.length > 0 ? { destinations: [...destinationRegistry.entries] } : {},
|
|
71
|
+
...outline.length > 0 ? { outline } : {},
|
|
72
|
+
...attachments.length > 0 ? { attachments } : {},
|
|
73
|
+
...optionalContent.layers.length > 0 ? { layers: [...optionalContent.layers] } : {},
|
|
74
|
+
...form.length > 0 ? { form } : {},
|
|
75
|
+
...Object.keys(source).length > 0 ? { source } : {}
|
|
50
76
|
};
|
|
51
77
|
}
|
|
52
|
-
function
|
|
53
|
-
const arr = require_objects.asArray(require_objects.dictGet(page,
|
|
54
|
-
if (arr === void 0) return
|
|
55
|
-
llx: 0,
|
|
56
|
-
lly: 0,
|
|
57
|
-
urx: DEFAULT_PAGE_WIDTH_PT,
|
|
58
|
-
ury: DEFAULT_PAGE_HEIGHT_PT
|
|
59
|
-
};
|
|
78
|
+
function readDeclaredPageBox(page, key) {
|
|
79
|
+
const arr = require_objects.asArray(require_objects.dictGet(page, key));
|
|
80
|
+
if (arr === void 0) return;
|
|
60
81
|
const a = require_objects.asNumber(arr[0]) ?? 0;
|
|
61
82
|
const b = require_objects.asNumber(arr[1]) ?? 0;
|
|
62
|
-
const c = require_objects.asNumber(arr[2]) ??
|
|
63
|
-
const d = require_objects.asNumber(arr[3]) ??
|
|
83
|
+
const c = require_objects.asNumber(arr[2]) ?? 0;
|
|
84
|
+
const d = require_objects.asNumber(arr[3]) ?? 0;
|
|
64
85
|
return {
|
|
65
86
|
llx: Math.min(a, c),
|
|
66
87
|
lly: Math.min(b, d),
|
|
@@ -68,6 +89,33 @@ function readMediaBox(page) {
|
|
|
68
89
|
ury: Math.max(b, d)
|
|
69
90
|
};
|
|
70
91
|
}
|
|
92
|
+
function readMediaBox(page) {
|
|
93
|
+
return readDeclaredPageBox(page, "MediaBox") ?? {
|
|
94
|
+
llx: 0,
|
|
95
|
+
lly: 0,
|
|
96
|
+
urx: DEFAULT_PAGE_WIDTH_PT,
|
|
97
|
+
ury: DEFAULT_PAGE_HEIGHT_PT
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function rotatedRectBounds(rect, matrix) {
|
|
101
|
+
const transformed = [
|
|
102
|
+
[rect.llx, rect.lly],
|
|
103
|
+
[rect.urx, rect.lly],
|
|
104
|
+
[rect.llx, rect.ury],
|
|
105
|
+
[rect.urx, rect.ury]
|
|
106
|
+
].map(([x, y]) => require_matrix.applyMatrix(matrix, {
|
|
107
|
+
x,
|
|
108
|
+
y
|
|
109
|
+
}));
|
|
110
|
+
const xs = transformed.map((point) => point.x);
|
|
111
|
+
const ys = transformed.map((point) => point.y);
|
|
112
|
+
return {
|
|
113
|
+
minX: Math.min(...xs),
|
|
114
|
+
minY: Math.min(...ys),
|
|
115
|
+
maxX: Math.max(...xs),
|
|
116
|
+
maxY: Math.max(...ys)
|
|
117
|
+
};
|
|
118
|
+
}
|
|
71
119
|
function normalizeRotation(rotate) {
|
|
72
120
|
if (rotate === void 0) return 0;
|
|
73
121
|
const normalized = (Math.round(rotate / 90) * 90 % 360 + 360) % 360;
|
|
@@ -136,35 +184,141 @@ function readPageContentBytes(page, resolver, sink) {
|
|
|
136
184
|
}
|
|
137
185
|
return /* @__PURE__ */ new Uint8Array(0);
|
|
138
186
|
}
|
|
139
|
-
function
|
|
187
|
+
function contentItemBounds(item) {
|
|
188
|
+
if (item.kind === "link" || item.kind === "internalLink") return;
|
|
189
|
+
const frameBounds = (xPt, yPt, widthPt, heightPt) => ({
|
|
190
|
+
minX: xPt,
|
|
191
|
+
minY: yPt,
|
|
192
|
+
maxX: xPt + widthPt,
|
|
193
|
+
maxY: yPt + heightPt
|
|
194
|
+
});
|
|
195
|
+
if (item.kind === "text" || item.kind === "image" || item.kind === "rect" || item.kind === "ellipse") {
|
|
196
|
+
if (item.kind !== "text" || item.rotationDeg === void 0 || item.rotationDeg % 180 === 0) return frameBounds(item.xPt, item.yPt, item.widthPt ?? 0, item.kind === "text" ? item.sizePt : item.heightPt);
|
|
197
|
+
const rotationDeg = item.rotationDeg;
|
|
198
|
+
const anchorX = item.xPt;
|
|
199
|
+
const anchorY = item.yPt;
|
|
200
|
+
const rotated = [
|
|
201
|
+
[0, 0],
|
|
202
|
+
[item.widthPt ?? 0, 0],
|
|
203
|
+
[0, item.sizePt],
|
|
204
|
+
[item.widthPt ?? 0, item.sizePt]
|
|
205
|
+
].map(([dx, dy]) => require_matrix.rotatePointAboutCenter({
|
|
206
|
+
x: anchorX + dx,
|
|
207
|
+
y: anchorY + dy
|
|
208
|
+
}, {
|
|
209
|
+
x: anchorX,
|
|
210
|
+
y: anchorY
|
|
211
|
+
}, rotationDeg));
|
|
212
|
+
const xs = rotated.map((point) => point.x);
|
|
213
|
+
const ys = rotated.map((point) => point.y);
|
|
214
|
+
return {
|
|
215
|
+
minX: Math.min(...xs),
|
|
216
|
+
minY: Math.min(...ys),
|
|
217
|
+
maxX: Math.max(...xs),
|
|
218
|
+
maxY: Math.max(...ys)
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
if (item.kind === "line") return {
|
|
222
|
+
minX: Math.min(item.x1Pt, item.x2Pt),
|
|
223
|
+
minY: Math.min(item.y1Pt, item.y2Pt),
|
|
224
|
+
maxX: Math.max(item.x1Pt, item.x2Pt),
|
|
225
|
+
maxY: Math.max(item.y1Pt, item.y2Pt)
|
|
226
|
+
};
|
|
227
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
228
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
229
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
230
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
231
|
+
const include = (x, y) => {
|
|
232
|
+
minX = Math.min(minX, x);
|
|
233
|
+
minY = Math.min(minY, y);
|
|
234
|
+
maxX = Math.max(maxX, x);
|
|
235
|
+
maxY = Math.max(maxY, y);
|
|
236
|
+
};
|
|
237
|
+
for (const subpath of item.subpaths) {
|
|
238
|
+
include(subpath.startXPt, subpath.startYPt);
|
|
239
|
+
for (const segment of subpath.segments) {
|
|
240
|
+
include(segment.xPt, segment.yPt);
|
|
241
|
+
if (segment.kind === "cubic") {
|
|
242
|
+
include(segment.c1xPt, segment.c1yPt);
|
|
243
|
+
include(segment.c2xPt, segment.c2yPt);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
minX,
|
|
249
|
+
minY,
|
|
250
|
+
maxX,
|
|
251
|
+
maxY
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function itemIntersectsVisibleRegion(item, widthPt, heightPt) {
|
|
255
|
+
if (item.kind === "link" || item.kind === "internalLink") return true;
|
|
256
|
+
const bounds = contentItemBounds(item);
|
|
257
|
+
if (bounds === void 0) return true;
|
|
258
|
+
return bounds.maxX >= 0 && bounds.minX <= widthPt && bounds.maxY >= 0 && bounds.minY <= heightPt;
|
|
259
|
+
}
|
|
260
|
+
function pageBoxResidueEntry(pageIndex, page, mediaBox, cropBox) {
|
|
261
|
+
const declaredBoxes = [
|
|
262
|
+
["MediaBox", require_objects.dictGet(page, "MediaBox")],
|
|
263
|
+
["CropBox", require_objects.dictGet(page, "CropBox")],
|
|
264
|
+
["BleedBox", require_objects.dictGet(page, "BleedBox")],
|
|
265
|
+
["TrimBox", require_objects.dictGet(page, "TrimBox")],
|
|
266
|
+
["ArtBox", require_objects.dictGet(page, "ArtBox")]
|
|
267
|
+
];
|
|
268
|
+
const cropDeclared = require_objects.dictGet(page, "CropBox") !== void 0;
|
|
269
|
+
const productionBoxDeclared = declaredBoxes.slice(2).some(([, value]) => value !== void 0);
|
|
270
|
+
if (!(cropDeclared && (cropBox.llx !== mediaBox.llx || cropBox.lly !== mediaBox.lly || cropBox.urx !== mediaBox.urx || cropBox.ury !== mediaBox.ury)) && !productionBoxDeclared) return;
|
|
271
|
+
const entries = { Page: require_objects.pdfNum(pageIndex) };
|
|
272
|
+
for (const [key, value] of declaredBoxes) if (value !== void 0) entries[key] = value;
|
|
273
|
+
return require_objects.pdfDict(entries);
|
|
274
|
+
}
|
|
275
|
+
function readPage(pageIndex, page, resolver, fontResolver, images, imageIdCache, destinationRegistry, layerNameOf, pageBoxRows, sink) {
|
|
140
276
|
const resources = resolver.resolveDict(require_objects.dictGet(page, "Resources"));
|
|
141
277
|
const mediaBox = readMediaBox(page);
|
|
278
|
+
let cropBox = readDeclaredPageBox(page, "CropBox") ?? mediaBox;
|
|
279
|
+
if (cropBox.urx - cropBox.llx <= 0 || cropBox.ury - cropBox.lly <= 0) {
|
|
280
|
+
sink({
|
|
281
|
+
code: "pdf/invalid-crop-box",
|
|
282
|
+
severity: "warning",
|
|
283
|
+
pageIndex,
|
|
284
|
+
message: "page /CropBox is degenerate (zero width or height); falling back to the /MediaBox as the visible region"
|
|
285
|
+
});
|
|
286
|
+
cropBox = mediaBox;
|
|
287
|
+
}
|
|
142
288
|
const rotationResult = pageRotationTransform(normalizeRotation(require_objects.asNumber(require_objects.dictGet(page, "Rotate"))), mediaBox.urx - mediaBox.llx, mediaBox.ury - mediaBox.lly);
|
|
143
|
-
const
|
|
289
|
+
const visibleRect = rotatedRectBounds(cropBox, rotationResult.matrix);
|
|
290
|
+
const widthPt = visibleRect.maxX - visibleRect.minX;
|
|
291
|
+
const heightPt = visibleRect.maxY - visibleRect.minY;
|
|
292
|
+
const pageMatrix = require_matrix.multiplyMatrices(rotationResult.matrix, require_matrix.translationMatrix(-visibleRect.minX, -visibleRect.minY));
|
|
293
|
+
const boxRow = pageBoxResidueEntry(pageIndex, page, mediaBox, cropBox);
|
|
294
|
+
if (boxRow !== void 0) pageBoxRows.push(boxRow);
|
|
144
295
|
const items = [];
|
|
145
296
|
if (resources !== void 0) {
|
|
146
297
|
const contentBytes = readPageContentBytes(page, resolver, sink);
|
|
147
298
|
const extracted = require_interpret.interpretContentStream(contentBytes, resources, {
|
|
148
299
|
fontMetrics: fontResolver.metrics,
|
|
149
300
|
resolver,
|
|
150
|
-
sink
|
|
301
|
+
sink,
|
|
302
|
+
layerNameOf
|
|
151
303
|
});
|
|
152
304
|
for (const item of extracted) {
|
|
153
305
|
const converted = convertExtractedItem(item, pageMatrix, fontResolver, images, imageIdCache, resolver, sink);
|
|
154
|
-
if (converted !== void 0) items.push(converted);
|
|
306
|
+
if (converted !== void 0 && itemIntersectsVisibleRegion(converted, widthPt, heightPt)) items.push(converted);
|
|
155
307
|
}
|
|
156
308
|
} else sink({
|
|
157
309
|
code: "pdf/object-missing-value",
|
|
158
310
|
severity: "warning",
|
|
159
311
|
message: "page has no /Resources dict; its content stream cannot be interpreted"
|
|
160
312
|
});
|
|
161
|
-
items.push(...readLinkAnnotations(page, pageMatrix, resolver));
|
|
313
|
+
items.push(...readLinkAnnotations(page, pageMatrix, resolver, destinationRegistry));
|
|
162
314
|
const notes = readPageNotes(page, resolver);
|
|
315
|
+
const annotations = require_annotations.readPageAnnotations(page, pageMatrix, resolver, sink);
|
|
163
316
|
return {
|
|
164
|
-
widthPt
|
|
165
|
-
heightPt
|
|
317
|
+
widthPt,
|
|
318
|
+
heightPt,
|
|
166
319
|
items,
|
|
167
|
-
...notes !== void 0 ? { notes } : {}
|
|
320
|
+
...notes !== void 0 ? { notes } : {},
|
|
321
|
+
...annotations.length > 0 ? { annotations } : {}
|
|
168
322
|
};
|
|
169
323
|
}
|
|
170
324
|
function convertExtractedItem(item, pageMatrix, fontResolver, images, imageIdCache, resolver, sink) {
|
|
@@ -199,7 +353,10 @@ function convertText(item, pageMatrix, fontResolver) {
|
|
|
199
353
|
sizePt: sizePt > 0 ? sizePt : item.sizePt,
|
|
200
354
|
color: item.color,
|
|
201
355
|
widthPt,
|
|
202
|
-
rotationDeg: rotationDeg !== 0 ? rotationDeg : void 0
|
|
356
|
+
rotationDeg: rotationDeg !== 0 ? rotationDeg : void 0,
|
|
357
|
+
...item.layerName !== void 0 ? { layer: item.layerName } : {},
|
|
358
|
+
...item.actualText !== void 0 ? { actualText: item.actualText } : {},
|
|
359
|
+
...item.alt !== void 0 ? { alt: item.alt } : {}
|
|
203
360
|
};
|
|
204
361
|
}
|
|
205
362
|
function paintFields(paint) {
|
|
@@ -228,14 +385,16 @@ function convertRect(item, pageMatrix) {
|
|
|
228
385
|
return {
|
|
229
386
|
kind: "rect",
|
|
230
387
|
...transformBox(item, pageMatrix),
|
|
231
|
-
...paintFields(item)
|
|
388
|
+
...paintFields(item),
|
|
389
|
+
...item.layerName !== void 0 ? { layer: item.layerName } : {}
|
|
232
390
|
};
|
|
233
391
|
}
|
|
234
392
|
function convertEllipse(item, pageMatrix) {
|
|
235
393
|
return {
|
|
236
394
|
kind: "ellipse",
|
|
237
395
|
...transformBox(item, pageMatrix),
|
|
238
|
-
...paintFields(item)
|
|
396
|
+
...paintFields(item),
|
|
397
|
+
...item.layerName !== void 0 ? { layer: item.layerName } : {}
|
|
239
398
|
};
|
|
240
399
|
}
|
|
241
400
|
function convertLine(item, pageMatrix) {
|
|
@@ -254,7 +413,8 @@ function convertLine(item, pageMatrix) {
|
|
|
254
413
|
x2Pt: p2.x,
|
|
255
414
|
y2Pt: p2.y,
|
|
256
415
|
color: item.color,
|
|
257
|
-
widthPt: item.widthPt
|
|
416
|
+
widthPt: item.widthPt,
|
|
417
|
+
...item.layerName !== void 0 ? { layer: item.layerName } : {}
|
|
258
418
|
};
|
|
259
419
|
}
|
|
260
420
|
function transformSubpath(subpath, pageMatrix) {
|
|
@@ -309,7 +469,8 @@ function convertPath(item, pageMatrix) {
|
|
|
309
469
|
subpaths: item.subpaths.map((subpath) => transformSubpath(subpath, pageMatrix)),
|
|
310
470
|
...item.fill !== void 0 ? { fill: item.fill } : {},
|
|
311
471
|
...item.fill !== void 0 && item.fillRule === "evenodd" ? { fillRule: "evenodd" } : {},
|
|
312
|
-
...item.stroke !== void 0 ? { stroke: item.stroke } : {}
|
|
472
|
+
...item.stroke !== void 0 ? { stroke: item.stroke } : {},
|
|
473
|
+
...item.layerName !== void 0 ? { layer: item.layerName } : {}
|
|
313
474
|
};
|
|
314
475
|
}
|
|
315
476
|
function imagePlacementFrom(matrix) {
|
|
@@ -352,7 +513,8 @@ function convertImage(item, pageMatrix, images, cache, resolver, sink) {
|
|
|
352
513
|
return {
|
|
353
514
|
kind: "image",
|
|
354
515
|
imageId,
|
|
355
|
-
...imagePlacementFrom(require_matrix.multiplyMatrices(item.matrix, pageMatrix))
|
|
516
|
+
...imagePlacementFrom(require_matrix.multiplyMatrices(item.matrix, pageMatrix)),
|
|
517
|
+
...item.layerName !== void 0 ? { layer: item.layerName } : {}
|
|
356
518
|
};
|
|
357
519
|
}
|
|
358
520
|
function convertInlineImage(item, pageMatrix, images, resolver, sink) {
|
|
@@ -361,19 +523,22 @@ function convertInlineImage(item, pageMatrix, images, resolver, sink) {
|
|
|
361
523
|
return {
|
|
362
524
|
kind: "image",
|
|
363
525
|
imageId: registerExtractedImage(decoded.format, decoded.bytes, decoded.widthPx, decoded.heightPx, images),
|
|
364
|
-
...imagePlacementFrom(require_matrix.multiplyMatrices(item.matrix, pageMatrix))
|
|
526
|
+
...imagePlacementFrom(require_matrix.multiplyMatrices(item.matrix, pageMatrix)),
|
|
527
|
+
...item.layerName !== void 0 ? { layer: item.layerName } : {}
|
|
365
528
|
};
|
|
366
529
|
}
|
|
367
|
-
function readLinkAnnotations(page, pageMatrix, resolver) {
|
|
530
|
+
function readLinkAnnotations(page, pageMatrix, resolver, destinationRegistry) {
|
|
368
531
|
const annotsArr = require_objects.asArray(require_objects.dictGet(page, "Annots"));
|
|
369
532
|
if (annotsArr === void 0) return [];
|
|
370
533
|
const links = [];
|
|
371
534
|
for (const annotRef of annotsArr) {
|
|
372
535
|
const annot = resolver.resolveDict(annotRef);
|
|
373
536
|
if (annot === void 0 || require_objects.asName(require_objects.dictGet(annot, "Subtype")) !== "Link") continue;
|
|
374
|
-
const uri = readLinkUri(annot, resolver);
|
|
375
537
|
const rectArr = require_objects.asArray(require_objects.dictGet(annot, "Rect"));
|
|
376
|
-
if (
|
|
538
|
+
if (rectArr === void 0) continue;
|
|
539
|
+
const uri = readLinkUri(annot, resolver);
|
|
540
|
+
const destination = uri === void 0 ? readInternalDestination(annot, resolver, destinationRegistry) : void 0;
|
|
541
|
+
if (uri === void 0 && destination === void 0) continue;
|
|
377
542
|
const x1 = require_objects.asNumber(rectArr[0]) ?? 0;
|
|
378
543
|
const y1 = require_objects.asNumber(rectArr[1]) ?? 0;
|
|
379
544
|
const x2 = require_objects.asNumber(rectArr[2]) ?? 0;
|
|
@@ -386,13 +551,24 @@ function readLinkAnnotations(page, pageMatrix, resolver) {
|
|
|
386
551
|
x: Math.max(x1, x2),
|
|
387
552
|
y: Math.max(y1, y2)
|
|
388
553
|
});
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
554
|
+
const contentsObj = require_objects.dictGet(annot, "Contents");
|
|
555
|
+
const title = contentsObj?.kind === "string" ? require_pdf_text.decodePdfString(contentsObj.bytes) : void 0;
|
|
556
|
+
const box = {
|
|
392
557
|
xPt: Math.min(p1.x, p2.x),
|
|
393
558
|
yPt: Math.min(p1.y, p2.y),
|
|
394
559
|
widthPt: Math.abs(p2.x - p1.x),
|
|
395
|
-
heightPt: Math.abs(p2.y - p1.y)
|
|
560
|
+
heightPt: Math.abs(p2.y - p1.y),
|
|
561
|
+
...title !== void 0 ? { title } : {}
|
|
562
|
+
};
|
|
563
|
+
if (uri !== void 0) links.push({
|
|
564
|
+
kind: "link",
|
|
565
|
+
uri,
|
|
566
|
+
...box
|
|
567
|
+
});
|
|
568
|
+
else if (destination !== void 0) links.push({
|
|
569
|
+
kind: "internalLink",
|
|
570
|
+
destination,
|
|
571
|
+
...box
|
|
396
572
|
});
|
|
397
573
|
}
|
|
398
574
|
return links;
|
|
@@ -401,7 +577,13 @@ function readLinkUri(annot, resolver) {
|
|
|
401
577
|
const action = resolver.resolveDict(require_objects.dictGet(annot, "A"));
|
|
402
578
|
if (action === void 0 || require_objects.asName(require_objects.dictGet(action, "S")) !== "URI") return;
|
|
403
579
|
const uriObj = require_objects.dictGet(action, "URI");
|
|
404
|
-
return uriObj?.kind === "string" ? decodePdfString(uriObj.bytes) : void 0;
|
|
580
|
+
return uriObj?.kind === "string" ? require_pdf_text.decodePdfString(uriObj.bytes) : void 0;
|
|
581
|
+
}
|
|
582
|
+
function readInternalDestination(annot, resolver, destinationRegistry) {
|
|
583
|
+
const dest = require_objects.dictGet(annot, "Dest");
|
|
584
|
+
if (dest !== void 0) return destinationRegistry.intern(dest);
|
|
585
|
+
const action = resolver.resolveDict(require_objects.dictGet(annot, "A"));
|
|
586
|
+
if (action !== void 0 && require_objects.asName(require_objects.dictGet(action, "S")) === "GoTo") return destinationRegistry.intern(require_objects.dictGet(action, "D"));
|
|
405
587
|
}
|
|
406
588
|
function readPageNotes(page, resolver) {
|
|
407
589
|
const annotsArr = require_objects.asArray(require_objects.dictGet(page, "Annots"));
|
|
@@ -410,49 +592,67 @@ function readPageNotes(page, resolver) {
|
|
|
410
592
|
const annot = resolver.resolveDict(annotRef);
|
|
411
593
|
if (annot === void 0 || require_objects.asName(require_objects.dictGet(annot, "Subtype")) !== "Text") continue;
|
|
412
594
|
const titleObj = require_objects.dictGet(annot, "T");
|
|
413
|
-
if ((titleObj?.kind === "string" ? decodePdfString(titleObj.bytes) : void 0) !== "documents.js:notes") continue;
|
|
595
|
+
if ((titleObj?.kind === "string" ? require_pdf_text.decodePdfString(titleObj.bytes) : void 0) !== "documents.js:notes") continue;
|
|
414
596
|
const contentsObj = require_objects.dictGet(annot, "Contents");
|
|
415
|
-
if (contentsObj?.kind === "string") return decodePdfString(contentsObj.bytes);
|
|
597
|
+
if (contentsObj?.kind === "string") return require_pdf_text.decodePdfString(contentsObj.bytes);
|
|
416
598
|
}
|
|
417
599
|
}
|
|
418
|
-
function
|
|
419
|
-
if (bytes.length >= 2 && bytes[0] === 254 && bytes[1] === 255) {
|
|
420
|
-
let out = "";
|
|
421
|
-
for (let i = 2; i + 1 < bytes.length; i += 2) out += String.fromCharCode((bytes[i] ?? 0) << 8 | (bytes[i + 1] ?? 0));
|
|
422
|
-
return out;
|
|
423
|
-
}
|
|
424
|
-
return Array.from(bytes, (b) => String.fromCharCode(b)).join("");
|
|
425
|
-
}
|
|
426
|
-
const PDF_DATE_PATTERN = /^D:(\d{4})(\d{2})?(\d{2})?(\d{2})?(\d{2})?(\d{2})?([+\-Z])?(\d{2})?'?(\d{2})?'?$/;
|
|
427
|
-
function parsePdfDate(raw) {
|
|
428
|
-
if (raw === void 0) return;
|
|
429
|
-
const match = PDF_DATE_PATTERN.exec(raw);
|
|
430
|
-
if (match === null) return;
|
|
431
|
-
const [, year, month = "01", day = "01", hour = "00", minute = "00", second = "00", tzSign, tzHour = "00", tzMinute = "00"] = match;
|
|
432
|
-
return `${year}-${month}-${day}T${hour}:${minute}:${second}${tzSign === void 0 || tzSign === "Z" ? "Z" : `${tzSign}${tzHour}:${tzMinute}`}`;
|
|
433
|
-
}
|
|
434
|
-
function readMetadata(trailer, resolver) {
|
|
600
|
+
function readMetadata(trailer, resolver, catalog, sink) {
|
|
435
601
|
const info = resolver.resolveDict(require_objects.dictGet(trailer, "Info"));
|
|
436
602
|
if (info === void 0) return {};
|
|
437
603
|
const stringField = (key) => {
|
|
438
604
|
const obj = require_objects.dictGet(info, key);
|
|
439
|
-
return obj?.kind === "string" ? decodePdfString(obj.bytes) : void 0;
|
|
605
|
+
return obj?.kind === "string" ? require_pdf_text.decodePdfString(obj.bytes) : void 0;
|
|
440
606
|
};
|
|
441
607
|
const keywords = stringField("Keywords")?.split(",").map((k) => k.trim()).filter((k) => k.length > 0);
|
|
608
|
+
const langObj = require_objects.dictGet(catalog, "Lang");
|
|
609
|
+
const xmp = xmpPacket(catalog, resolver, sink);
|
|
610
|
+
const mirrored = require_xmp.readXmpMetadata(xmp ?? "");
|
|
442
611
|
return {
|
|
443
|
-
title: stringField("Title"),
|
|
444
|
-
author: stringField("Author"),
|
|
445
|
-
subject: stringField("Subject"),
|
|
446
|
-
keywords: keywords !== void 0 && keywords.length > 0 ? keywords : void 0,
|
|
447
|
-
creator: stringField("Creator"),
|
|
448
|
-
producer: stringField("Producer"),
|
|
449
|
-
createdIso: parsePdfDate(stringField("CreationDate")),
|
|
450
|
-
modifiedIso: parsePdfDate(stringField("ModDate"))
|
|
612
|
+
title: stringField("Title") ?? mirrored.title,
|
|
613
|
+
author: stringField("Author") ?? mirrored.author,
|
|
614
|
+
subject: stringField("Subject") ?? mirrored.subject,
|
|
615
|
+
keywords: (keywords !== void 0 && keywords.length > 0 ? keywords : void 0) ?? mirrored.keywords,
|
|
616
|
+
creator: stringField("Creator") ?? mirrored.creator,
|
|
617
|
+
producer: stringField("Producer") ?? mirrored.producer,
|
|
618
|
+
createdIso: require_pdf_text.parsePdfDate(stringField("CreationDate")) ?? mirrored.createdIso,
|
|
619
|
+
modifiedIso: require_pdf_text.parsePdfDate(stringField("ModDate")) ?? mirrored.modifiedIso,
|
|
620
|
+
...langObj?.kind === "string" ? { language: require_pdf_text.decodePdfString(langObj.bytes) } : {}
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
function xmpPacket(catalog, resolver, sink) {
|
|
624
|
+
const metadataObj = resolver.resolve(require_objects.dictGet(catalog, "Metadata"));
|
|
625
|
+
if (metadataObj?.kind !== "stream") return;
|
|
626
|
+
const decoded = require_filters.decodeStream(metadataObj.raw, metadataObj.dict, sink);
|
|
627
|
+
return new TextDecoder().decode(decoded.bytes);
|
|
628
|
+
}
|
|
629
|
+
function readDocumentResidue(doc, sink) {
|
|
630
|
+
const source = {};
|
|
631
|
+
const residue = (key, obj) => {
|
|
632
|
+
if (obj !== void 0) source[key] = {
|
|
633
|
+
format: "pdf",
|
|
634
|
+
xml: require_serialize.serializeObjectToText(obj)
|
|
635
|
+
};
|
|
636
|
+
};
|
|
637
|
+
const catalog = doc.catalog;
|
|
638
|
+
const packet = xmpPacket(catalog, doc, sink);
|
|
639
|
+
if (packet !== void 0) source.xmp = {
|
|
640
|
+
format: "pdf",
|
|
641
|
+
xml: packet
|
|
451
642
|
};
|
|
643
|
+
residue("viewer-preferences", require_objects.dictGet(catalog, "ViewerPreferences"));
|
|
644
|
+
residue("page-mode", require_objects.dictGet(catalog, "PageMode"));
|
|
645
|
+
residue("page-layout", require_objects.dictGet(catalog, "PageLayout"));
|
|
646
|
+
residue("open-action", require_objects.dictGet(catalog, "OpenAction"));
|
|
647
|
+
const outputIntents = require_objects.asArray(require_objects.dictGet(catalog, "OutputIntents"));
|
|
648
|
+
if (outputIntents !== void 0) residue("output-intents", require_objects.pdfArray(outputIntents.map((intent) => doc.resolve(intent) ?? require_objects.pdfNull())));
|
|
649
|
+
residue("piece-info", require_objects.dictGet(catalog, "PieceInfo"));
|
|
650
|
+
residue("legal", require_objects.dictGet(catalog, "Legal"));
|
|
651
|
+
residue("collection", require_objects.dictGet(catalog, "Collection"));
|
|
652
|
+
residue("trailer-id", require_objects.dictGet(doc.trailer, "ID"));
|
|
653
|
+
return source;
|
|
452
654
|
}
|
|
453
655
|
//#endregion
|
|
454
|
-
exports.decodePdfString = decodePdfString;
|
|
455
656
|
exports.normalizeRotation = normalizeRotation;
|
|
456
657
|
exports.pageRotationTransform = pageRotationTransform;
|
|
457
|
-
exports.parsePdfDate = parsePdfDate;
|
|
458
658
|
exports.readPdf = readPdf;
|
package/dist/read.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.cjs";
|
|
2
|
-
import { LayoutDocument } from "./layout.cjs";
|
|
3
2
|
import { r as Matrix } from "./matrix-B7_SBKQ5.cjs";
|
|
3
|
+
import { LayoutDocument } from "./layout.cjs";
|
|
4
4
|
//#region src/read.d.ts
|
|
5
5
|
interface ReadPdfOptions {
|
|
6
6
|
readonly sink?: PdfDiagnosticSink;
|
|
@@ -15,7 +15,5 @@ interface PageRotationResult {
|
|
|
15
15
|
readonly heightPt: number;
|
|
16
16
|
}
|
|
17
17
|
declare function pageRotationTransform(rotation: PageRotation, w: number, h: number): PageRotationResult;
|
|
18
|
-
declare function decodePdfString(bytes: Uint8Array<ArrayBuffer>): string;
|
|
19
|
-
declare function parsePdfDate(raw: string | undefined): string | undefined;
|
|
20
18
|
//#endregion
|
|
21
|
-
export { ReadPdfOptions,
|
|
19
|
+
export { ReadPdfOptions, normalizeRotation, pageRotationTransform, readPdf };
|
package/dist/read.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.js";
|
|
2
|
-
import { LayoutDocument } from "./layout.js";
|
|
3
2
|
import { r as Matrix } from "./matrix-B7_SBKQ5.js";
|
|
3
|
+
import { LayoutDocument } from "./layout.js";
|
|
4
4
|
//#region src/read.d.ts
|
|
5
5
|
interface ReadPdfOptions {
|
|
6
6
|
readonly sink?: PdfDiagnosticSink;
|
|
@@ -15,7 +15,5 @@ interface PageRotationResult {
|
|
|
15
15
|
readonly heightPt: number;
|
|
16
16
|
}
|
|
17
17
|
declare function pageRotationTransform(rotation: PageRotation, w: number, h: number): PageRotationResult;
|
|
18
|
-
declare function decodePdfString(bytes: Uint8Array<ArrayBuffer>): string;
|
|
19
|
-
declare function parsePdfDate(raw: string | undefined): string | undefined;
|
|
20
18
|
//#endregion
|
|
21
|
-
export { ReadPdfOptions,
|
|
19
|
+
export { ReadPdfOptions, normalizeRotation, pageRotationTransform, readPdf };
|