pdf-codec 4.1.0 → 4.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 +3 -3
- package/dist/content-write.d.cts +1 -1
- package/dist/content-write.d.ts +1 -1
- package/dist/{embedded-font-fREdbxnr.d.ts → embedded-font-B4p9a3O3.d.ts} +3 -1
- package/dist/{embedded-font-BU6Jgcof.d.cts → embedded-font-oc65VGlr.d.cts} +3 -1
- package/dist/embedded-font-write.d.cts +2 -2
- package/dist/embedded-font-write.d.ts +2 -2
- package/dist/embedded-font.cjs +46 -15
- package/dist/embedded-font.d.cts +1 -1
- package/dist/embedded-font.d.ts +1 -1
- package/dist/embedded-font.js +46 -15
- package/dist/font-registry.d.cts +1 -1
- package/dist/font-registry.d.ts +1 -1
- package/dist/gsub-table-BRTQ8EUW.d.ts +10 -0
- package/dist/gsub-table-URczLd85.d.cts +10 -0
- package/dist/gsub-table.cjs +225 -0
- package/dist/gsub-table.d.cts +2 -0
- package/dist/gsub-table.d.ts +2 -0
- package/dist/gsub-table.js +224 -0
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/math-font-write.cjs +1 -1
- package/dist/math-font-write.js +1 -1
- package/dist/sfnt-subset.cjs +10 -3
- package/dist/sfnt-subset.d.cts +1 -1
- package/dist/sfnt-subset.d.ts +1 -1
- package/dist/sfnt-subset.js +10 -3
- package/dist/tounicode.cjs +8 -3
- package/dist/tounicode.d.cts +1 -1
- package/dist/tounicode.d.ts +1 -1
- package/dist/tounicode.js +8 -3
- package/dist/write.cjs +97 -11
- package/dist/write.d.cts +1 -1
- package/dist/write.d.ts +1 -1
- package/dist/write.js +98 -12
- package/package.json +1 -1
package/dist/write.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as widthOfCode, p as winAnsiGlyphName, t as STANDARD_METRICS } from "./afm-widths-De_QMWgC.js";
|
|
2
2
|
import { NOTES_ANNOTATION_AUTHOR } from "./notes-annotation-author.js";
|
|
3
|
-
import { pdfArray, pdfDict, pdfHexString, pdfName, pdfNull, pdfNum, pdfRef, pdfStream } from "./objects.js";
|
|
3
|
+
import { pdfArray, pdfDict, pdfHexString, pdfLiteralString, pdfName, pdfNull, pdfNum, pdfRef, pdfStream } from "./objects.js";
|
|
4
4
|
import { ByteWriter, concatBytes } from "./bytes/writer.js";
|
|
5
5
|
import { writeObject } from "./serialize.js";
|
|
6
6
|
import { deflate } from "./bytes/flate.js";
|
|
@@ -201,11 +201,14 @@ function destinationViewArray(target) {
|
|
|
201
201
|
if (target.kind === "fitBV") return [pdfName("FitBV"), n(target.leftPt)];
|
|
202
202
|
return [pdfName(target.kind === "fitB" ? "FitB" : "Fit")];
|
|
203
203
|
}
|
|
204
|
-
function
|
|
205
|
-
const destination = doc.destinations?.find((d) => d.name ===
|
|
206
|
-
if (destination === void 0) throw new Error(
|
|
204
|
+
function resolveDestinationArray(doc, pageAllocs, name, what) {
|
|
205
|
+
const destination = doc.destinations?.find((d) => d.name === name);
|
|
206
|
+
if (destination === void 0) throw new Error(`${what} names destination "${name}", which the document's destinations table does not carry -- this is a caller-invariant violation`);
|
|
207
207
|
const targetPage = pageAllocs[destination.pageIndex];
|
|
208
|
-
if (targetPage === void 0) throw new Error(`destination "${
|
|
208
|
+
if (targetPage === void 0) throw new Error(`destination "${destination.name}" names page index ${destination.pageIndex}, which is beyond the document's own pages -- this is a caller-invariant violation`);
|
|
209
|
+
return [pdfRef(targetPage.pageNum, 0), ...destinationViewArray(destination.target)];
|
|
210
|
+
}
|
|
211
|
+
function buildInternalLinkAnnotDict(link, doc, pageAllocs) {
|
|
209
212
|
return pdfDict({
|
|
210
213
|
Type: pdfName("Annot"),
|
|
211
214
|
Subtype: pdfName("Link"),
|
|
@@ -220,7 +223,7 @@ function buildInternalLinkAnnotDict(link, doc, pageAllocs) {
|
|
|
220
223
|
0,
|
|
221
224
|
0
|
|
222
225
|
].map((v) => pdfNum(v))),
|
|
223
|
-
Dest: pdfArray(
|
|
226
|
+
Dest: pdfArray(resolveDestinationArray(doc, pageAllocs, link.destination, "internal link"))
|
|
224
227
|
});
|
|
225
228
|
}
|
|
226
229
|
function isLinkItem(item) {
|
|
@@ -321,13 +324,28 @@ function writePdf(doc, options = {}) {
|
|
|
321
324
|
contentsNum: nextObjNum++
|
|
322
325
|
}));
|
|
323
326
|
const encryptDictNum = options.encryption === void 0 ? void 0 : nextObjNum++;
|
|
327
|
+
const attachmentAllocs = (doc.attachments ?? []).map(() => ({
|
|
328
|
+
fileNum: nextObjNum++,
|
|
329
|
+
specNum: nextObjNum++
|
|
330
|
+
}));
|
|
331
|
+
const attachmentsNamesNum = attachmentAllocs.length > 0 ? nextObjNum++ : void 0;
|
|
332
|
+
const outlineRootNum = (doc.outline ?? []).length > 0 ? nextObjNum++ : void 0;
|
|
333
|
+
const outlineItemNums = [];
|
|
334
|
+
if (outlineRootNum !== void 0) {
|
|
335
|
+
const countItems = (items) => {
|
|
336
|
+
let n = 0;
|
|
337
|
+
for (const item of items) n += 1 + countItems(item.children);
|
|
338
|
+
return n;
|
|
339
|
+
};
|
|
340
|
+
for (let i = 0; i < countItems(doc.outline ?? []); i += 1) outlineItemNums.push(nextObjNum++);
|
|
341
|
+
}
|
|
324
342
|
const objects = [];
|
|
343
|
+
const catalogEntries = [["Type", pdfName("Catalog")], ["Pages", pdfRef(pagesNum, 0)]];
|
|
344
|
+
if (attachmentsNamesNum !== void 0) catalogEntries.push(["Names", pdfRef(attachmentsNamesNum, 0)]);
|
|
345
|
+
if (outlineRootNum !== void 0) catalogEntries.push(["Outlines", pdfRef(outlineRootNum, 0)]);
|
|
325
346
|
objects.push({
|
|
326
347
|
num: catalogNum,
|
|
327
|
-
value: pdfDict(
|
|
328
|
-
Type: pdfName("Catalog"),
|
|
329
|
-
Pages: pdfRef(pagesNum, 0)
|
|
330
|
-
})
|
|
348
|
+
value: pdfDict(Object.fromEntries(catalogEntries))
|
|
331
349
|
});
|
|
332
350
|
objects.push({
|
|
333
351
|
num: pagesNum,
|
|
@@ -341,6 +359,73 @@ function writePdf(doc, options = {}) {
|
|
|
341
359
|
num: infoNum,
|
|
342
360
|
value: buildInfoDict(doc)
|
|
343
361
|
});
|
|
362
|
+
for (const [index, attachment] of (doc.attachments ?? []).entries()) {
|
|
363
|
+
const alloc = attachmentAllocs[index];
|
|
364
|
+
const fileEntries = [["Type", pdfName("EmbeddedFile")]];
|
|
365
|
+
if (attachment.mimeType !== void 0) fileEntries.push(["Subtype", pdfName(attachment.mimeType)]);
|
|
366
|
+
objects.push({
|
|
367
|
+
num: alloc.fileNum,
|
|
368
|
+
value: pdfStream(pdfDict(Object.fromEntries(fileEntries)), base64ToBytes(attachment.base64))
|
|
369
|
+
});
|
|
370
|
+
const specEntries = [
|
|
371
|
+
["Type", pdfName("Filespec")],
|
|
372
|
+
["F", pdfLiteralString(new TextEncoder().encode(attachment.name))],
|
|
373
|
+
["EF", pdfDict({ F: pdfRef(alloc.fileNum, 0) })]
|
|
374
|
+
];
|
|
375
|
+
if (attachment.description !== void 0) specEntries.push(["Desc", pdfLiteralString(new TextEncoder().encode(attachment.description))]);
|
|
376
|
+
objects.push({
|
|
377
|
+
num: alloc.specNum,
|
|
378
|
+
value: pdfDict(Object.fromEntries(specEntries))
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
if (attachmentsNamesNum !== void 0) {
|
|
382
|
+
const names = [];
|
|
383
|
+
for (const [index, attachment] of (doc.attachments ?? []).entries()) {
|
|
384
|
+
names.push(pdfLiteralString(new TextEncoder().encode(attachment.name)));
|
|
385
|
+
names.push(pdfRef(attachmentAllocs[index].specNum, 0));
|
|
386
|
+
}
|
|
387
|
+
objects.push({
|
|
388
|
+
num: attachmentsNamesNum,
|
|
389
|
+
value: pdfDict({ EmbeddedFiles: pdfDict({ Names: pdfArray(names) }) })
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
if (outlineRootNum !== void 0 && (doc.outline ?? []).length > 0) {
|
|
393
|
+
let itemCursor = 0;
|
|
394
|
+
const emitItems = (items, parentNum) => {
|
|
395
|
+
const siblingNums = [];
|
|
396
|
+
let prevNum;
|
|
397
|
+
for (const item of items) {
|
|
398
|
+
const ownNum = outlineItemNums[itemCursor];
|
|
399
|
+
itemCursor += 1;
|
|
400
|
+
siblingNums.push(ownNum);
|
|
401
|
+
const childNums = emitItems(item.children, ownNum);
|
|
402
|
+
const entries = [["Title", pdfLiteralString(new TextEncoder().encode(item.title))], ["Parent", pdfRef(parentNum, 0)]];
|
|
403
|
+
if (item.destination !== void 0) entries.push(["Dest", pdfArray(resolveDestinationArray(doc, pageAllocs, item.destination, `outline item "${item.title}"`))]);
|
|
404
|
+
if (prevNum !== void 0) entries.push(["Prev", pdfRef(prevNum, 0)]);
|
|
405
|
+
if (siblingNums.length < items.length) entries.push(["Next", pdfRef(outlineItemNums[itemCursor], 0)]);
|
|
406
|
+
if (childNums.length > 0) {
|
|
407
|
+
entries.push(["First", pdfRef(childNums[0], 0)]);
|
|
408
|
+
entries.push(["Last", pdfRef(childNums[childNums.length - 1], 0)]);
|
|
409
|
+
entries.push(["Count", pdfNum(childNums.length)]);
|
|
410
|
+
}
|
|
411
|
+
objects.push({
|
|
412
|
+
num: ownNum,
|
|
413
|
+
value: pdfDict(Object.fromEntries(entries))
|
|
414
|
+
});
|
|
415
|
+
prevNum = ownNum;
|
|
416
|
+
}
|
|
417
|
+
return siblingNums;
|
|
418
|
+
};
|
|
419
|
+
const topLevelNums = emitItems(doc.outline ?? [], outlineRootNum);
|
|
420
|
+
objects.push({
|
|
421
|
+
num: outlineRootNum,
|
|
422
|
+
value: pdfDict({
|
|
423
|
+
Type: pdfName("Outlines"),
|
|
424
|
+
First: pdfRef(topLevelNums[0], 0),
|
|
425
|
+
Last: pdfRef(topLevelNums[topLevelNums.length - 1], 0)
|
|
426
|
+
})
|
|
427
|
+
});
|
|
428
|
+
}
|
|
344
429
|
for (const [standardName, alloc] of fontAllocs) {
|
|
345
430
|
const { font, descriptor } = buildFontObjects(standardName, pdfRef(alloc.descNum, 0));
|
|
346
431
|
objects.push({
|
|
@@ -396,9 +481,10 @@ function writePdf(doc, options = {}) {
|
|
|
396
481
|
});
|
|
397
482
|
}
|
|
398
483
|
for (const [face, alloc] of embeddedAllocs) {
|
|
399
|
-
const
|
|
484
|
+
const usedGlyphs = collectEmbeddedGlyphs(alloc.texts, face);
|
|
485
|
+
const subset = subsetSfnt(face.font, [...alloc.codePoints].sort((a, b) => a - b), [...usedGlyphs.keys()].sort((a, b) => a - b));
|
|
400
486
|
if (subset === void 0) throw new Error(`font "${face.postScriptName}" resolved to an embeddable face, but its glyph outlines could not be subsetted -- only TrueType-outline ('glyf') fonts can be embedded, so supply a TrueType face for this family or drop it from the registry`);
|
|
401
|
-
const built = buildEmbeddedFontObjects(face, subset,
|
|
487
|
+
const built = buildEmbeddedFontObjects(face, subset, usedGlyphs, {
|
|
402
488
|
cidFontRef: pdfRef(alloc.cidFontNum, 0),
|
|
403
489
|
descriptorRef: pdfRef(alloc.descriptorNum, 0),
|
|
404
490
|
fontFileRef: pdfRef(alloc.fontFileNum, 0),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pdf-codec",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "Hand-written, dependency-minimal PDF codec: parses arbitrary real-world PDFs and generates new ones, built on its own codec-owned LayoutDocument item model and Zod 4 codecs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|