@reportwright/pdf 0.1.0-beta.3 → 0.1.0-beta.4
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 +6 -4
- package/dist/index.js +133 -61
- package/index.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -322,7 +322,7 @@ PDF/A levels and the reader. The most used:
|
|
|
322
322
|
| `createPdf(sink, o)` / `toBytes(build, o)` | `title`, `author`, `creationDate`, `compress`, `metadata`, `pdfa`, `tagged`, `encrypt`, `sign`, `form.flatten`, `signal`, `timeoutMs`, `id` ([table](#createpdfsink-options)) |
|
|
323
323
|
| `pdf.embedFont(bytes, o)` | `subset`, `shaper`, `textMapping` ([Fonts](#fonts), [Shaping](#shaping)) |
|
|
324
324
|
| `page.text` / `page.textBox` | `x`, `y`, `font`, `size`, `color`, `width`, `align`, `maxLines`, `fallback`, `direction`, `kerning` ([Text options](#pages)) |
|
|
325
|
-
| `pdf.embedImage` / `page.image` | `colorSpace`, `maxDecodedBytes` / `width`, `height`, `fit`, `opacity`, `alt` ([Images](#images)) |
|
|
325
|
+
| `pdf.embedImage` / `page.image` | `colorSpace`, `maxDecodedBytes`, `compression` / `width`, `height`, `fit`, `opacity`, `alt` ([Images](#images)) |
|
|
326
326
|
| `page.fill` / `stroke` | `fill`, `stroke`, `width`, `dash`, `cap`, `join`, `opacity`, `blendMode`, `rule` ([Vector graphics](#vector-graphics)) |
|
|
327
327
|
| `encrypt` | `userPassword`, `ownerPassword`, `algorithm`, `permissions`, `encryptMetadata` ([Encryption](#encryption-1)) |
|
|
328
328
|
| `pdf.sign(field, o)` | `signer`, `reason`, `location`, `name`, `certify`, `timestamp`, `subFilter`, `reserve` ([Signatures](#signatures)) |
|
|
@@ -573,10 +573,12 @@ const logo = await pdf.embedImage(fs.readFileSync('logo.png')); // alpha
|
|
|
573
573
|
for (const y of [400, 500, 600]) page.image(logo, { x: 40, y, height: 24, opacity: 0.6 }); // written once
|
|
574
574
|
```
|
|
575
575
|
|
|
576
|
-
- `await pdf.embedImage(bytes, { colorSpace, maxDecodedBytes })` — a JPEG or PNG, written to the file at once as an image XObject;
|
|
576
|
+
- `await pdf.embedImage(bytes, { colorSpace, maxDecodedBytes, compression })` — a JPEG or PNG, written to the file at once as an image XObject;
|
|
577
577
|
returns a handle with `width` and `height` (pixels, after the EXIF orientation). `colorSpace`: an ICC colour space
|
|
578
578
|
(`pdf.iccColorSpace`) with the image's number of components, instead of the device space. `maxDecodedBytes`: the
|
|
579
|
-
decoded size allowed for a PNG that needs decoding (default 64 MB, 67,108,864 bytes).
|
|
579
|
+
decoded size allowed for a PNG that needs decoding (default 64 MB, 67,108,864 bytes). `compression`: the zlib level
|
|
580
|
+
for a PNG that is re-compressed (alpha or interlacing): `'default'` is 6, or 3 above 2 megapixels (about half the
|
|
581
|
+
time for 2–3% more bytes on photos); `'fast'` is 1; or a level 1–9. JPEGs and passed-through PNGs are not affected.
|
|
580
582
|
- **JPEG**: baseline and progressive, gray, RGB and CMYK, embedded unchanged (DCTDecode, no re-encoding). Adobe's
|
|
581
583
|
inverted CMYK (an APP14 "Adobe" segment) is drawn with `/Decode [1 0 1 0 1 0 1 0]`. The EXIF orientation (1–8)
|
|
582
584
|
is honoured. 12-bit, lossless, hierarchical and arithmetic-coded JPEGs are refused.
|
|
@@ -596,7 +598,7 @@ for (const y of [400, 500, 600]) page.image(logo, { x: 40, y, height: 24, opacit
|
|
|
596
598
|
PDFs: `alt` makes the image a `Figure` with that alternate text; without `alt` it is an artifact (decoration).
|
|
597
599
|
- Images are deduplicated automatically: `embedImage` called again with the same bytes (and the same options) in the
|
|
598
600
|
same document returns the same handle and writes nothing new (keyed by a SHA-256 of the bytes; Node's `node:crypto`,
|
|
599
|
-
else WebCrypto, else a fast hash confirmed byte for byte). A different option (`colorSpace`, `maxDecodedBytes`)
|
|
601
|
+
else WebCrypto, else a fast hash confirmed byte for byte). A different option (`colorSpace`, `maxDecodedBytes`, `compression`)
|
|
600
602
|
embeds it again.
|
|
601
603
|
- An image drawn any number of times, on any pages, is one XObject in the file. Images are always XObjects, never
|
|
602
604
|
inline images: an inline image would be repeated in every content stream and cannot have a soft mask.
|
package/dist/index.js
CHANGED
|
@@ -957,29 +957,32 @@ var init_browser = __esm({
|
|
|
957
957
|
});
|
|
958
958
|
|
|
959
959
|
// src/core/deflate.js
|
|
960
|
-
async function deflate(bytes) {
|
|
960
|
+
async function deflate(bytes, level = 6) {
|
|
961
961
|
if (slots.free > 0) slots.free--;
|
|
962
962
|
else await new Promise((ok) => slots.wait.push(
|
|
963
963
|
/** @type {() => void} */
|
|
964
964
|
ok
|
|
965
965
|
));
|
|
966
966
|
try {
|
|
967
|
-
return await now(bytes);
|
|
967
|
+
return await now(bytes, level);
|
|
968
968
|
} finally {
|
|
969
969
|
const next = slots.wait.shift();
|
|
970
970
|
if (next) next();
|
|
971
971
|
else slots.free++;
|
|
972
972
|
}
|
|
973
973
|
}
|
|
974
|
-
async function now(bytes) {
|
|
975
|
-
if (NODE_ZLIB) return new Promise((ok, fail2) => NODE_ZLIB.deflate(bytes, { level
|
|
976
|
-
if (typeof CompressionStream === "undefined") return zlibSync(bytes, { level:
|
|
974
|
+
async function now(bytes, level) {
|
|
975
|
+
if (NODE_ZLIB) return new Promise((ok, fail2) => NODE_ZLIB.deflate(bytes, { level }, (e, z) => e ? fail2(e) : ok(z)));
|
|
976
|
+
if (typeof CompressionStream === "undefined" || level !== 6) return zlibSync(bytes, { level: (
|
|
977
|
+
/** @type {any} */
|
|
978
|
+
level
|
|
979
|
+
) });
|
|
977
980
|
return new Uint8Array(await new Response(new Blob([
|
|
978
981
|
/** @type {any} */
|
|
979
982
|
bytes
|
|
980
983
|
]).stream().pipeThrough(new CompressionStream("deflate"))).arrayBuffer());
|
|
981
984
|
}
|
|
982
|
-
function deflateStream() {
|
|
985
|
+
function deflateStream(level = 6) {
|
|
983
986
|
const out = [];
|
|
984
987
|
const join = () => {
|
|
985
988
|
let n = 0;
|
|
@@ -993,7 +996,7 @@ function deflateStream() {
|
|
|
993
996
|
return z;
|
|
994
997
|
};
|
|
995
998
|
if (NODE_ZLIB) {
|
|
996
|
-
const z = NODE_ZLIB.createDeflate({ level:
|
|
999
|
+
const z = NODE_ZLIB.createDeflate({ level, chunkSize: 1 << 20 });
|
|
997
1000
|
const ended = new Promise((ok, fail2) => {
|
|
998
1001
|
z.on("data", (c) => out.push(c));
|
|
999
1002
|
z.on("end", ok);
|
|
@@ -1017,7 +1020,19 @@ function deflateStream() {
|
|
|
1017
1020
|
if (typeof CompressionStream === "undefined") return { async push(b) {
|
|
1018
1021
|
out.push(b.slice());
|
|
1019
1022
|
}, async end() {
|
|
1020
|
-
return zlibSync(join(), { level:
|
|
1023
|
+
return zlibSync(join(), { level: (
|
|
1024
|
+
/** @type {any} */
|
|
1025
|
+
level
|
|
1026
|
+
) });
|
|
1027
|
+
}, abort() {
|
|
1028
|
+
} };
|
|
1029
|
+
if (level !== 6) return { async push(b) {
|
|
1030
|
+
out.push(b.slice());
|
|
1031
|
+
}, async end() {
|
|
1032
|
+
return zlibSync(join(), { level: (
|
|
1033
|
+
/** @type {any} */
|
|
1034
|
+
level
|
|
1035
|
+
) });
|
|
1021
1036
|
}, abort() {
|
|
1022
1037
|
} };
|
|
1023
1038
|
const cs = new CompressionStream("deflate"), w = cs.writable.getWriter();
|
|
@@ -3432,6 +3447,7 @@ var init_links = __esm({
|
|
|
3432
3447
|
|
|
3433
3448
|
// src/images/png.js
|
|
3434
3449
|
function crc32(b, from, to) {
|
|
3450
|
+
if (NODE_ZLIB2?.crc32) return NODE_ZLIB2.crc32(b.subarray(from, to));
|
|
3435
3451
|
if (!CRC_TABLE) {
|
|
3436
3452
|
CRC_TABLE = new Uint32Array(256);
|
|
3437
3453
|
for (let n = 0; n < 256; n++) {
|
|
@@ -3572,16 +3588,24 @@ function unfilterRow(f, c, p, bpp) {
|
|
|
3572
3588
|
}
|
|
3573
3589
|
for (let i2 = 0; i2 < bpp; i2++) c[i2] += p[i2];
|
|
3574
3590
|
for (let i2 = bpp; i2 < rb; i2++) {
|
|
3575
|
-
const a = c[i2 - bpp], u = p[i2], cc = p[i2 - bpp]
|
|
3576
|
-
|
|
3591
|
+
const a = c[i2 - bpp], u = p[i2], cc = p[i2 - bpp];
|
|
3592
|
+
let pa = u - cc, pb = a - cc, pc = pa + pb, k;
|
|
3593
|
+
k = pa >> 31;
|
|
3594
|
+
pa = (pa ^ k) - k;
|
|
3595
|
+
k = pb >> 31;
|
|
3596
|
+
pb = (pb ^ k) - k;
|
|
3597
|
+
k = pc >> 31;
|
|
3598
|
+
pc = (pc ^ k) - k;
|
|
3599
|
+
c[i2] += a ^ (a ^ (u ^ (u ^ cc) & pc - pb >> 31)) & (pb - pa | pc - pa) >> 31;
|
|
3577
3600
|
}
|
|
3578
3601
|
}
|
|
3579
3602
|
function filterRow(x2, up, bpp, out, o, t) {
|
|
3580
3603
|
const rb = x2.length, m = Math.min(bpp, rb);
|
|
3581
|
-
let best = 0, sum = 0;
|
|
3604
|
+
let best = 0, sum = 0, s, k;
|
|
3582
3605
|
for (let i2 = 0; i2 < rb; i2++) {
|
|
3583
|
-
|
|
3584
|
-
|
|
3606
|
+
s = x2[i2] << 24 >> 24;
|
|
3607
|
+
k = s >> 31;
|
|
3608
|
+
sum += (s ^ k) - k;
|
|
3585
3609
|
}
|
|
3586
3610
|
out[o] = 0;
|
|
3587
3611
|
out.set(x2, o + 1);
|
|
@@ -3590,12 +3614,15 @@ function filterRow(x2, up, bpp, out, o, t) {
|
|
|
3590
3614
|
for (let i2 = 0; i2 < m; i2++) {
|
|
3591
3615
|
const v = x2[i2];
|
|
3592
3616
|
t[i2] = v;
|
|
3593
|
-
|
|
3617
|
+
s = v << 24 >> 24;
|
|
3618
|
+
k = s >> 31;
|
|
3619
|
+
sum += (s ^ k) - k;
|
|
3594
3620
|
}
|
|
3595
3621
|
for (let i2 = m; i2 < rb; i2++) {
|
|
3596
|
-
|
|
3597
|
-
t[i2] =
|
|
3598
|
-
|
|
3622
|
+
s = x2[i2] - x2[i2 - bpp] << 24 >> 24;
|
|
3623
|
+
t[i2] = s;
|
|
3624
|
+
k = s >> 31;
|
|
3625
|
+
sum += (s ^ k) - k;
|
|
3599
3626
|
}
|
|
3600
3627
|
if (sum < best) {
|
|
3601
3628
|
best = sum;
|
|
@@ -3605,9 +3632,10 @@ function filterRow(x2, up, bpp, out, o, t) {
|
|
|
3605
3632
|
if (!up) return;
|
|
3606
3633
|
sum = 0;
|
|
3607
3634
|
for (let i2 = 0; i2 < rb; i2++) {
|
|
3608
|
-
|
|
3609
|
-
t[i2] =
|
|
3610
|
-
|
|
3635
|
+
s = x2[i2] - up[i2] << 24 >> 24;
|
|
3636
|
+
t[i2] = s;
|
|
3637
|
+
k = s >> 31;
|
|
3638
|
+
sum += (s ^ k) - k;
|
|
3611
3639
|
}
|
|
3612
3640
|
if (sum < best) {
|
|
3613
3641
|
best = sum;
|
|
@@ -3616,15 +3644,25 @@ function filterRow(x2, up, bpp, out, o, t) {
|
|
|
3616
3644
|
}
|
|
3617
3645
|
sum = 0;
|
|
3618
3646
|
for (let i2 = 0; i2 < m; i2++) {
|
|
3619
|
-
|
|
3620
|
-
t[i2] =
|
|
3621
|
-
|
|
3647
|
+
s = x2[i2] - up[i2] << 24 >> 24;
|
|
3648
|
+
t[i2] = s;
|
|
3649
|
+
k = s >> 31;
|
|
3650
|
+
sum += (s ^ k) - k;
|
|
3622
3651
|
}
|
|
3623
3652
|
for (let i2 = m; i2 < rb; i2++) {
|
|
3624
|
-
const a = x2[i2 - bpp], u = up[i2], c = up[i2 - bpp]
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3653
|
+
const a = x2[i2 - bpp], u = up[i2], c = up[i2 - bpp];
|
|
3654
|
+
let pa = u - c, pb = a - c, pc = pa + pb;
|
|
3655
|
+
k = pa >> 31;
|
|
3656
|
+
pa = (pa ^ k) - k;
|
|
3657
|
+
k = pb >> 31;
|
|
3658
|
+
pb = (pb ^ k) - k;
|
|
3659
|
+
k = pc >> 31;
|
|
3660
|
+
pc = (pc ^ k) - k;
|
|
3661
|
+
const notA = (pb - pa | pc - pa) >> 31, uc = u ^ (u ^ c) & pc - pb >> 31;
|
|
3662
|
+
s = x2[i2] - (a ^ (a ^ uc) & notA) << 24 >> 24;
|
|
3663
|
+
t[i2] = s;
|
|
3664
|
+
k = s >> 31;
|
|
3665
|
+
sum += (s ^ k) - k;
|
|
3628
3666
|
}
|
|
3629
3667
|
if (sum < best) {
|
|
3630
3668
|
out[o] = 4;
|
|
@@ -3857,13 +3895,14 @@ async function embedImage(doc, bytes, opt = {}) {
|
|
|
3857
3895
|
/** @type {any} */
|
|
3858
3896
|
opt[k2]
|
|
3859
3897
|
) : void 0;
|
|
3860
|
-
const o = { colorSpace: own2("colorSpace"), maxDecodedBytes: own2("maxDecodedBytes") ?? MAX_DECODED };
|
|
3898
|
+
const o = { colorSpace: own2("colorSpace"), maxDecodedBytes: own2("maxDecodedBytes") ?? MAX_DECODED, compression: own2("compression") ?? "default" };
|
|
3899
|
+
if (!(o.compression === "default" || o.compression === "fast" || Number.isInteger(o.compression) && o.compression >= 1 && o.compression <= 9)) throw new TypeError("embedImage: compression is 'default', 'fast' or a zlib level 1–9");
|
|
3861
3900
|
if (!(Number.isSafeInteger(o.maxDecodedBytes) && o.maxDecodedBytes > 0)) throw new TypeError("embedImage: maxDecodedBytes is a whole number of bytes > 0");
|
|
3862
3901
|
if (b.length > MAX_INPUT) throw new RangeError(`embedImage: at most ${MAX_INPUT >> 20} MB`);
|
|
3863
3902
|
let seen = SEEN.get(doc);
|
|
3864
3903
|
if (!seen) SEEN.set(doc, seen = /* @__PURE__ */ new Map());
|
|
3865
3904
|
const { key, copy } = await digest(b);
|
|
3866
|
-
const k = `${key} ${o.colorSpace == null ? "-" : idOf(o.colorSpace)} ${o.maxDecodedBytes}`;
|
|
3905
|
+
const k = `${key} ${o.colorSpace == null ? "-" : idOf(o.colorSpace)} ${o.maxDecodedBytes} ${o.compression}`;
|
|
3867
3906
|
const hit = seen.get(k);
|
|
3868
3907
|
if (hit && (!hit.copy || same(hit.copy, b))) return hit.img;
|
|
3869
3908
|
const img = embed(doc, b, o);
|
|
@@ -3921,7 +3960,8 @@ async function embed(doc, b, o) {
|
|
|
3921
3960
|
let color, a = null;
|
|
3922
3961
|
if (p.filtered) color = [p.data, parms(ch, p.bpc)];
|
|
3923
3962
|
else {
|
|
3924
|
-
const
|
|
3963
|
+
const lv = o.compression === "fast" ? 1 : o.compression === "default" ? w * h > 2e6 ? 3 : 6 : o.compression;
|
|
3964
|
+
const ce = encoder(h, rb, bpp, parms(ch, p.bpc), lv), ae = p.alpha ? encoder(h, arb, Math.max(1, abpc >> 3), parms(1, abpc), lv) : null;
|
|
3925
3965
|
try {
|
|
3926
3966
|
await p.rows(async (c, al) => {
|
|
3927
3967
|
await Promise.all([ce.row(c), ae && al ? ae.row(al) : null]);
|
|
@@ -3957,8 +3997,8 @@ async function embed(doc, b, o) {
|
|
|
3957
3997
|
{ ref, w: turned ? h : w, h: turned ? w : h, orient: ORIENT[orientation], alpha }
|
|
3958
3998
|
);
|
|
3959
3999
|
}
|
|
3960
|
-
function encoder(rows, rb, bpp, dp) {
|
|
3961
|
-
const z = deflateStream(), per = Math.max(1, Math.floor((1 << 20) / (rb + 1))), t = new Uint8Array(rb);
|
|
4000
|
+
function encoder(rows, rb, bpp, dp, level) {
|
|
4001
|
+
const z = deflateStream(level), per = Math.max(1, Math.floor((1 << 20) / (rb + 1))), t = new Uint8Array(rb);
|
|
3962
4002
|
const plain2 = rows * rb <= 256 << 10 ? new Uint8Array(rows * rb) : null;
|
|
3963
4003
|
const strips = [new Uint8Array(per * (rb + 1)), new Uint8Array(per * (rb + 1))], busy = [Promise.resolve(), Promise.resolve()];
|
|
3964
4004
|
let s = 0, strip = strips[0], k = 0, y = 0;
|
|
@@ -3982,7 +4022,7 @@ function encoder(rows, rb, bpp, dp) {
|
|
|
3982
4022
|
await busy[s ^ 1];
|
|
3983
4023
|
const f = await z.end();
|
|
3984
4024
|
if (!plain2) return [f, dp];
|
|
3985
|
-
const p = await deflate(plain2);
|
|
4025
|
+
const p = await deflate(plain2, level);
|
|
3986
4026
|
return p.length <= f.length + dp.length ? [p, ""] : [f, dp];
|
|
3987
4027
|
},
|
|
3988
4028
|
abort: () => z.abort()
|
|
@@ -12364,13 +12404,13 @@ function createForm(doc, opt = {}) {
|
|
|
12364
12404
|
if (!Array.isArray(list) || list.length > MAX_OPTIONS) throw new RangeError(`${who}: options is an array of at most ${MAX_OPTIONS} options`);
|
|
12365
12405
|
const P = placeOf(o, who), L = lookOf(o, who, { border: 1 }), tip = tipOf(o, who);
|
|
12366
12406
|
const { t, da } = textOf(P.page, o, who), q = qOf(o.align, who);
|
|
12367
|
-
let
|
|
12407
|
+
let chars3 = 0;
|
|
12368
12408
|
const index = /* @__PURE__ */ new Map();
|
|
12369
12409
|
const opts = list.map((it, i2) => {
|
|
12370
12410
|
const pair = Array.isArray(it) ? it : [it, it];
|
|
12371
12411
|
if (pair.length !== 2) throw new TypeError(`${who}: an option is a string or [export, display]`);
|
|
12372
12412
|
const [ex, dp] = pair.map((v) => str2(v, "an option", MAX_TOOLTIP, who));
|
|
12373
|
-
if ((
|
|
12413
|
+
if ((chars3 += ex.length + dp.length) > MAX_OPTION_CHARS) throw new RangeError(`${who}: the options have more than ${MAX_OPTION_CHARS} characters in all`);
|
|
12374
12414
|
if (index.has(ex)) throw new TypeError(`${who}: two options have the export value ${JSON.stringify(ex.slice(0, 80))}`);
|
|
12375
12415
|
index.set(ex, i2);
|
|
12376
12416
|
return { ex, dp };
|
|
@@ -13233,8 +13273,9 @@ function indexOf(buf, needle, from, to = buf.length) {
|
|
|
13233
13273
|
to = Math.min(to, buf.length);
|
|
13234
13274
|
if (to - from > 64) {
|
|
13235
13275
|
if (NodeBuffer) {
|
|
13236
|
-
|
|
13237
|
-
|
|
13276
|
+
let v = VIEWS.get(buf);
|
|
13277
|
+
if (!v) VIEWS.set(buf, v = NodeBuffer.from(buf.buffer, buf.byteOffset, buf.length));
|
|
13278
|
+
return (to === v.length ? v : v.subarray(0, to)).indexOf(needle, from, "latin1");
|
|
13238
13279
|
}
|
|
13239
13280
|
for (let i2 = buf.indexOf(n0, from); i2 >= 0 && i2 + L <= to; i2 = buf.indexOf(n0, i2 + 1)) {
|
|
13240
13281
|
let j = 1;
|
|
@@ -13258,7 +13299,7 @@ function lastIndexOf(buf, needle, to, span = to) {
|
|
|
13258
13299
|
}
|
|
13259
13300
|
return -1;
|
|
13260
13301
|
}
|
|
13261
|
-
var MAX_DEPTH4, MAX_ITEMS, Ref, PdfString, PdfStream, Op, CLASS, T, HEX, Lexer, parseValueEnd, NodeBuffer;
|
|
13302
|
+
var MAX_DEPTH4, MAX_ITEMS, Ref, PdfString, PdfStream, Op, CLASS, T, HEX, Lexer, parseValueEnd, NodeBuffer, VIEWS;
|
|
13262
13303
|
var init_lexer = __esm({
|
|
13263
13304
|
"src/reader/lexer.js"() {
|
|
13264
13305
|
init_budget();
|
|
@@ -13429,7 +13470,7 @@ var init_lexer = __esm({
|
|
|
13429
13470
|
}
|
|
13430
13471
|
this.budget.tick(1 + (n >> 10));
|
|
13431
13472
|
this.pos = i2;
|
|
13432
|
-
this.val = new PdfString(out.slice(0, n), false);
|
|
13473
|
+
this.val = new PdfString(n === out.length ? out : out.slice(0, n), false);
|
|
13433
13474
|
return T.STR;
|
|
13434
13475
|
}
|
|
13435
13476
|
/** @param {number} i after "<" */
|
|
@@ -13451,7 +13492,7 @@ var init_lexer = __esm({
|
|
|
13451
13492
|
if (hi >= 0) out[n++] = hi << 4;
|
|
13452
13493
|
this.budget.tick(1 + (n >> 10));
|
|
13453
13494
|
this.pos = j < e ? j + 1 : j;
|
|
13454
|
-
this.val = new PdfString(out.slice(0, n), true);
|
|
13495
|
+
this.val = new PdfString(n === out.length ? out : out.slice(0, n), true);
|
|
13455
13496
|
return T.STR;
|
|
13456
13497
|
}
|
|
13457
13498
|
/** @param {number} i after "/" */
|
|
@@ -13483,6 +13524,8 @@ var init_lexer = __esm({
|
|
|
13483
13524
|
parseValueEnd = () => void 0;
|
|
13484
13525
|
NodeBuffer = /** @type {any} */
|
|
13485
13526
|
globalThis.Buffer;
|
|
13527
|
+
VIEWS = /** @type {WeakMap<Uint8Array, any>} */
|
|
13528
|
+
/* @__PURE__ */ new WeakMap();
|
|
13486
13529
|
}
|
|
13487
13530
|
});
|
|
13488
13531
|
|
|
@@ -14644,14 +14687,26 @@ function decodeText(v) {
|
|
|
14644
14687
|
if (!(v instanceof PdfString)) return typeof v === "string" ? v : v == null ? "" : String(v);
|
|
14645
14688
|
const b = v.bytes;
|
|
14646
14689
|
if (b.length >= 2 && b[0] === 254 && b[1] === 255) {
|
|
14647
|
-
|
|
14648
|
-
for (let
|
|
14649
|
-
return
|
|
14690
|
+
const u2 = new Uint16Array(b.length - 2 >> 1);
|
|
14691
|
+
for (let i3 = 0; i3 < u2.length; i3++) u2[i3] = b[2 + 2 * i3] << 8 | b[3 + 2 * i3];
|
|
14692
|
+
return chars2(u2);
|
|
14650
14693
|
}
|
|
14651
14694
|
if (b.length >= 3 && b[0] === 239 && b[1] === 187 && b[2] === 191) return new TextDecoder().decode(b.subarray(3));
|
|
14652
|
-
let
|
|
14653
|
-
|
|
14654
|
-
return
|
|
14695
|
+
let i2 = 0;
|
|
14696
|
+
while (i2 < b.length && DOC_T[b[i2]] === b[i2]) i2++;
|
|
14697
|
+
if (i2 === b.length) return latin12(b);
|
|
14698
|
+
const u = new Uint16Array(b.length);
|
|
14699
|
+
for (i2 = 0; i2 < b.length; i2++) u[i2] = DOC_T[b[i2]];
|
|
14700
|
+
return chars2(u);
|
|
14701
|
+
}
|
|
14702
|
+
function chars2(u) {
|
|
14703
|
+
const parts = [];
|
|
14704
|
+
for (let i2 = 0; i2 < u.length; i2 += 8192) parts.push(String.fromCharCode.apply(
|
|
14705
|
+
null,
|
|
14706
|
+
/** @type {any} */
|
|
14707
|
+
u.subarray(i2, i2 + 8192)
|
|
14708
|
+
));
|
|
14709
|
+
return parts.join("");
|
|
14655
14710
|
}
|
|
14656
14711
|
function glyphText(n) {
|
|
14657
14712
|
if (Object.hasOwn(NAMES2, n)) return NAMES2[n];
|
|
@@ -14689,11 +14744,11 @@ function parseCMap(data, budget, held = { n: 0 }) {
|
|
|
14689
14744
|
for (let i2 = 0; i2 + 1 < b.length; i2 += 2) u.push(b[i2] << 8 | b[i2 + 1]);
|
|
14690
14745
|
return String.fromCharCode(...u);
|
|
14691
14746
|
};
|
|
14692
|
-
let
|
|
14747
|
+
let chars3 = 0;
|
|
14693
14748
|
const set2 = (c, t) => {
|
|
14694
|
-
|
|
14749
|
+
chars3 += t.length;
|
|
14695
14750
|
held.n += 8 + t.length;
|
|
14696
|
-
if (
|
|
14751
|
+
if (chars3 > MAX_CMAP_CHARS) fail("E_BUDGET", `A CMap maps codes to more than ${MAX_CMAP_CHARS.toLocaleString("en")} characters`);
|
|
14697
14752
|
if (held.n > MAX_HELD) fail("E_BUDGET", `A page's fonts hold more than ${MAX_HELD.toLocaleString("en")} units of code mappings (an entry 8, a character 1)`);
|
|
14698
14753
|
map.set(c, t);
|
|
14699
14754
|
};
|
|
@@ -15012,12 +15067,12 @@ function pageText(src, pageDict, resources, raw = false) {
|
|
|
15012
15067
|
const PX = [], PY = [], PE = [], PS = [], PG = [];
|
|
15013
15068
|
const PA = [], PAE = [], PC = [], PD = [];
|
|
15014
15069
|
const PT = [];
|
|
15015
|
-
let
|
|
15070
|
+
let chars3 = 0;
|
|
15016
15071
|
let moved = true;
|
|
15017
15072
|
const fonts = /* @__PURE__ */ new Map();
|
|
15018
15073
|
const add2 = (x2, y, end, size, text3, d0, d1, d2, d3) => {
|
|
15019
15074
|
if (PT.length >= budget.maxTextItems) throw new PdfReadError("E_BUDGET", `A page has more than ${budget.maxTextItems.toLocaleString("en")} pieces of text (budget.maxTextItems)`);
|
|
15020
|
-
if ((
|
|
15075
|
+
if ((chars3 += text3.length) > MAX_TEXT_CHARS) throw new PdfReadError("E_BUDGET", `A page makes more than ${MAX_TEXT_CHARS.toLocaleString("en")} characters of text`);
|
|
15021
15076
|
if (raw) {
|
|
15022
15077
|
PX.push(x2);
|
|
15023
15078
|
PY.push(y);
|
|
@@ -15273,7 +15328,7 @@ function pageText(src, pageDict, resources, raw = false) {
|
|
|
15273
15328
|
}
|
|
15274
15329
|
return out.join("");
|
|
15275
15330
|
}
|
|
15276
|
-
var MAX_FORMS, MAX_CMAP, MAX_MARKS, MAX_ACTUAL, MAX_TEXT_CHARS, MAX_DST, MAX_CMAP_CHARS, MAX_HELD, MAX_W, MAX_DO, TEXT_TIMEOUT_MS, DOC, WIN, WIN_T, MAC_HIGH, BASE, STD_HIGH, NAMES2, ACCENT, own, STD_ALIAS, NONE, stops, MAX_CMAP_FONTS, mul6, mul2, ID, matrixOf, C0, G0, G1, RTL2, STRONG_L, NUM, rev2;
|
|
15331
|
+
var MAX_FORMS, MAX_CMAP, MAX_MARKS, MAX_ACTUAL, MAX_TEXT_CHARS, MAX_DST, MAX_CMAP_CHARS, MAX_HELD, MAX_W, MAX_DO, TEXT_TIMEOUT_MS, DOC, DOC_T, WIN, WIN_T, MAC_HIGH, BASE, STD_HIGH, NAMES2, ACCENT, own, STD_ALIAS, NONE, stops, MAX_CMAP_FONTS, mul6, mul2, ID, matrixOf, C0, G0, G1, RTL2, STRONG_L, NUM, rev2;
|
|
15277
15332
|
var init_text2 = __esm({
|
|
15278
15333
|
"src/reader/text.js"() {
|
|
15279
15334
|
init_lexer();
|
|
@@ -15333,6 +15388,7 @@ var init_text2 = __esm({
|
|
|
15333
15388
|
[158, 382],
|
|
15334
15389
|
[160, 8364]
|
|
15335
15390
|
]);
|
|
15391
|
+
DOC_T = new Uint16Array(256).map((_, c) => DOC.get(c) ?? c);
|
|
15336
15392
|
WIN = /* @__PURE__ */ new Map();
|
|
15337
15393
|
{
|
|
15338
15394
|
const p = ENCODINGS.WinAnsi;
|
|
@@ -15732,9 +15788,15 @@ function numText(v) {
|
|
|
15732
15788
|
return Math.abs(v) < 1 ? v.toFixed(10).replace(/\.?0+$/, "") || "0" : v.toFixed(0);
|
|
15733
15789
|
}
|
|
15734
15790
|
function hexText(b) {
|
|
15735
|
-
|
|
15736
|
-
|
|
15737
|
-
|
|
15791
|
+
if (NodeBuffer2 && b.length > 64) return `<${NodeBuffer2.from(b.buffer, b.byteOffset, b.length).toString("hex")}>`;
|
|
15792
|
+
const parts = ["<"];
|
|
15793
|
+
for (let i2 = 0; i2 < b.length; i2 += 4096) {
|
|
15794
|
+
let s = "";
|
|
15795
|
+
for (let k = i2; k < Math.min(b.length, i2 + 4096); k++) s += HEXD[b[k] >> 4] + HEXD[b[k] & 15];
|
|
15796
|
+
parts.push(s);
|
|
15797
|
+
}
|
|
15798
|
+
parts.push(">");
|
|
15799
|
+
return parts.join("");
|
|
15738
15800
|
}
|
|
15739
15801
|
function createCopier(t) {
|
|
15740
15802
|
const maps = /* @__PURE__ */ new Map();
|
|
@@ -16136,7 +16198,7 @@ function createCopier(t) {
|
|
|
16136
16198
|
}
|
|
16137
16199
|
};
|
|
16138
16200
|
}
|
|
16139
|
-
var SHARE, GRAY, HEXD, Raw, Foreign, AUDIT, OPEN_A, CLOSE_A, OPEN_D, CLOSE_D;
|
|
16201
|
+
var SHARE, GRAY, HEXD, NodeBuffer2, Raw, Foreign, AUDIT, OPEN_A, CLOSE_A, OPEN_D, CLOSE_D;
|
|
16140
16202
|
var init_copy = __esm({
|
|
16141
16203
|
"src/reader/copy.js"() {
|
|
16142
16204
|
init_lexer();
|
|
@@ -16147,6 +16209,8 @@ var init_copy = __esm({
|
|
|
16147
16209
|
SHARE = /* @__PURE__ */ new Set(["Font", "FontDescriptor", "ExtGState", "Encoding", "Pattern", "Shading", "Halftone", "Function", "XObject", "Mask", "CMap", "OutputIntent", "Filespec", "EmbeddedFile"]);
|
|
16148
16210
|
GRAY = -2;
|
|
16149
16211
|
HEXD = "0123456789abcdef";
|
|
16212
|
+
NodeBuffer2 = /** @type {any} */
|
|
16213
|
+
globalThis.Buffer;
|
|
16150
16214
|
Raw = class {
|
|
16151
16215
|
/** @param {string} s */
|
|
16152
16216
|
constructor(s) {
|
|
@@ -16451,6 +16515,13 @@ async function run(self, sink, o) {
|
|
|
16451
16515
|
warn("the source's output intent profile was not usable; the bundled sRGB profile was written instead");
|
|
16452
16516
|
}
|
|
16453
16517
|
}
|
|
16518
|
+
const infoText = (k) => {
|
|
16519
|
+
const v = info[k];
|
|
16520
|
+
if (v == null) return void 0;
|
|
16521
|
+
if (v.length <= INFO_MAX) return v;
|
|
16522
|
+
warn(`the source's ${k} (${v.length.toLocaleString("en")} characters) was cut to ${INFO_MAX.toLocaleString("en")}`);
|
|
16523
|
+
return v.slice(0, INFO_MAX);
|
|
16524
|
+
};
|
|
16454
16525
|
const pdf = (
|
|
16455
16526
|
/** @type {any} */
|
|
16456
16527
|
createPdf(sink, {
|
|
@@ -16461,10 +16532,10 @@ async function run(self, sink, o) {
|
|
|
16461
16532
|
creationDate: created,
|
|
16462
16533
|
metadata: !!(level || self.edits.xmp != null || self.xmp() != null),
|
|
16463
16534
|
// an XMP packet only when the source had one or PDF/A needs one: a file split into pages is not a kilobyte of XMP each
|
|
16464
|
-
title:
|
|
16465
|
-
author:
|
|
16466
|
-
subject:
|
|
16467
|
-
keywords:
|
|
16535
|
+
title: infoText("title"),
|
|
16536
|
+
author: infoText("author"),
|
|
16537
|
+
subject: infoText("subject"),
|
|
16538
|
+
keywords: infoText("keywords"),
|
|
16468
16539
|
...level ? { pdfa: { part: level.part, conformance: "b", ...intentOpt ? { outputIntent: intentOpt } : {} } } : {}
|
|
16469
16540
|
})
|
|
16470
16541
|
);
|
|
@@ -16775,7 +16846,7 @@ function sameBytes(a, b) {
|
|
|
16775
16846
|
for (let i2 = 0; i2 < a.length; i2++) if (a[i2] !== b[i2]) return false;
|
|
16776
16847
|
return true;
|
|
16777
16848
|
}
|
|
16778
|
-
var MAX_OPEN, KEYS2, OWN;
|
|
16849
|
+
var INFO_MAX, MAX_OPEN, KEYS2, OWN;
|
|
16779
16850
|
var init_save = __esm({
|
|
16780
16851
|
"src/reader/save.js"() {
|
|
16781
16852
|
init_index();
|
|
@@ -16789,6 +16860,7 @@ var init_save = __esm({
|
|
|
16789
16860
|
init_pdf();
|
|
16790
16861
|
init_text2();
|
|
16791
16862
|
init_budget();
|
|
16863
|
+
INFO_MAX = 65536;
|
|
16792
16864
|
MAX_OPEN = 256;
|
|
16793
16865
|
KEYS2 = ["compress", "keepActiveContent", "encrypt", "pdfa", "creationDate", "signal", "timeoutMs", "keepStructure"];
|
|
16794
16866
|
OWN = /* @__PURE__ */ new Set(["Type", "Parent", "Contents", "Resources", "Annots", "MediaBox", "CropBox", "Rotate", "B"]);
|
package/index.d.ts
CHANGED
|
@@ -650,7 +650,7 @@ export interface Pdf {
|
|
|
650
650
|
* textMapping: 'carrier' (default: Firefox, pdf.js, search) or 'actualText' (a shaped cluster's text only in its ActualText: MuPDF, AI pipelines) */
|
|
651
651
|
embedFont(bytes: Uint8Array | ArrayBuffer, o?: { subset?: boolean | Subsetter; shaper?: Shaper; textMapping?: 'carrier' | 'actualText' }): Promise<Font>;
|
|
652
652
|
/** a JPEG or PNG, written now as an image XObject. colorSpace: an ICC colour space with the image's component count */
|
|
653
|
-
embedImage(bytes: Uint8Array | ArrayBuffer, o?: { colorSpace?: IccColorSpace; /** the decoded size a PNG with alpha or interlacing may have; default 64 MB */ maxDecodedBytes?: number }): Promise<Image>;
|
|
653
|
+
embedImage(bytes: Uint8Array | ArrayBuffer, o?: { colorSpace?: IccColorSpace; /** the decoded size a PNG with alpha or interlacing may have; default 64 MB */ maxDecodedBytes?: number; /** zlib level for a re-compressed PNG (alpha, interlacing): 'default' = 6, or 3 above 2 megapixels; 'fast' = 1; or 1–9 */ compression?: 'default' | 'fast' | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 }): Promise<Image>;
|
|
654
654
|
/** a spot colour: its name and the device colour (gray, RGB, CMYK) shown for it at full tint. One definition per name */
|
|
655
655
|
spotColor(name: string, alternate: number | string | readonly number[]): SpotColor;
|
|
656
656
|
/** an ICC-based colour space from a gray, RGB or CMYK profile (its header is checked) */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reportwright/pdf",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.4",
|
|
4
4
|
"description": "A streaming PDF writer for Node and browsers with no runtime dependencies: flat memory, PDF/A-1b to 3a, PDF/UA-1, Factur-X, embedded TrueType with Unicode text.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|