pdfnative 1.3.0 → 1.5.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 +163 -40
- package/dist/index.cjs +1577 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +800 -10
- package/dist/index.d.ts +800 -10
- package/dist/index.js +1566 -67
- package/dist/index.js.map +1 -1
- package/dist/tools/build-emoji-font.js +1139 -0
- package/dist/tools/index.cjs +657 -0
- package/dist/tools/index.cjs.map +1 -0
- package/dist/tools/index.d.cts +110 -0
- package/dist/tools/index.d.ts +110 -0
- package/dist/tools/index.js +654 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/worker/index.cjs +110 -11
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.js +110 -11
- package/dist/worker/index.js.map +1 -1
- package/fonts/noto-sans-math-data.d.ts +13 -0
- package/fonts/noto-sans-math-data.js +64 -0
- package/package.json +45 -5
package/dist/index.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
-
var __esm = (fn2, res) => function __init() {
|
|
4
|
-
|
|
3
|
+
var __esm = (fn2, res, err) => function __init() {
|
|
4
|
+
if (err) throw err[0];
|
|
5
|
+
try {
|
|
6
|
+
return fn2 && (res = (0, fn2[__getOwnPropNames(fn2)[0]])(fn2 = 0)), res;
|
|
7
|
+
} catch (e) {
|
|
8
|
+
throw err = [e], e;
|
|
9
|
+
}
|
|
5
10
|
};
|
|
6
11
|
var __export = (target, all) => {
|
|
7
12
|
for (var name in all)
|
|
@@ -2317,6 +2322,16 @@ var MYANMAR_EXTENDED_A_END = 43647;
|
|
|
2317
2322
|
var MYANMAR_EXTENDED_B_START = 43488;
|
|
2318
2323
|
var MYANMAR_EXTENDED_B_END = 43519;
|
|
2319
2324
|
var MYANMAR_VIRAMA = 4153;
|
|
2325
|
+
var MATH_OPERATORS_START = 8704;
|
|
2326
|
+
var MATH_OPERATORS_END = 8959;
|
|
2327
|
+
var SUPPLEMENTAL_MATH_OPERATORS_START = 10752;
|
|
2328
|
+
var SUPPLEMENTAL_MATH_OPERATORS_END = 11007;
|
|
2329
|
+
var GEOMETRIC_SHAPES_START = 9632;
|
|
2330
|
+
var GEOMETRIC_SHAPES_END = 9727;
|
|
2331
|
+
var MISC_MATH_SYMBOLS_A_START = 10176;
|
|
2332
|
+
var MISC_MATH_SYMBOLS_A_END = 10223;
|
|
2333
|
+
var MISC_MATH_SYMBOLS_B_START = 10624;
|
|
2334
|
+
var MISC_MATH_SYMBOLS_B_END = 10751;
|
|
2320
2335
|
var EMOJI_RANGES = [
|
|
2321
2336
|
[127744, 128511],
|
|
2322
2337
|
// Miscellaneous Symbols and Pictographs
|
|
@@ -2395,6 +2410,9 @@ function isMyanmarCodepoint(cp) {
|
|
|
2395
2410
|
function isDevanagariCodepoint(cp) {
|
|
2396
2411
|
return cp >= DEVANAGARI_START && cp <= DEVANAGARI_END || cp >= DEVANAGARI_EXT_START && cp <= DEVANAGARI_EXT_END;
|
|
2397
2412
|
}
|
|
2413
|
+
function isMathCodepoint(cp) {
|
|
2414
|
+
return cp >= MATH_OPERATORS_START && cp <= MATH_OPERATORS_END || cp >= SUPPLEMENTAL_MATH_OPERATORS_START && cp <= SUPPLEMENTAL_MATH_OPERATORS_END || cp >= GEOMETRIC_SHAPES_START && cp <= GEOMETRIC_SHAPES_END || cp >= MISC_MATH_SYMBOLS_A_START && cp <= MISC_MATH_SYMBOLS_A_END || cp >= MISC_MATH_SYMBOLS_B_START && cp <= MISC_MATH_SYMBOLS_B_END;
|
|
2415
|
+
}
|
|
2398
2416
|
function isEmojiCodepoint(cp) {
|
|
2399
2417
|
if (cp >= FITZPATRICK_START && cp <= FITZPATRICK_END) return true;
|
|
2400
2418
|
for (const [lo, hi] of EMOJI_RANGES) {
|
|
@@ -2481,10 +2499,16 @@ function containsDevanagari(str) {
|
|
|
2481
2499
|
}
|
|
2482
2500
|
return false;
|
|
2483
2501
|
}
|
|
2502
|
+
function containsMath(str) {
|
|
2503
|
+
for (let i = 0; i < str.length; i++) {
|
|
2504
|
+
if (isMathCodepoint(str.charCodeAt(i))) return true;
|
|
2505
|
+
}
|
|
2506
|
+
return false;
|
|
2507
|
+
}
|
|
2484
2508
|
|
|
2485
2509
|
// src/shaping/script-detect.ts
|
|
2486
2510
|
function needsUnicodeFont(lang) {
|
|
2487
|
-
return ["th", "ja", "zh", "ko", "el", "hi", "te", "tr", "vi", "pl", "ar", "he", "ru", "ka", "hy", "am", "si", "bo", "km", "my", "emoji"].includes(lang);
|
|
2511
|
+
return ["th", "ja", "zh", "ko", "el", "hi", "te", "tr", "vi", "pl", "ar", "he", "ru", "ka", "hy", "am", "si", "bo", "km", "my", "math", "emoji"].includes(lang);
|
|
2488
2512
|
}
|
|
2489
2513
|
function detectFallbackLangs(texts, primaryLang) {
|
|
2490
2514
|
const needed = /* @__PURE__ */ new Set();
|
|
@@ -2585,6 +2609,10 @@ function detectFallbackLangs(texts, primaryLang) {
|
|
|
2585
2609
|
needed.add("hy");
|
|
2586
2610
|
continue;
|
|
2587
2611
|
}
|
|
2612
|
+
if (isMathCodepoint(cp)) {
|
|
2613
|
+
needed.add("math");
|
|
2614
|
+
continue;
|
|
2615
|
+
}
|
|
2588
2616
|
if (isEmojiCodepoint(cp)) {
|
|
2589
2617
|
needed.add("emoji");
|
|
2590
2618
|
continue;
|
|
@@ -2615,6 +2643,7 @@ function detectCharLang(cp) {
|
|
|
2615
2643
|
if (cp >= 1024 && cp <= 1279 || cp >= 1280 && cp <= 1327) return "ru";
|
|
2616
2644
|
if (cp >= 4256 && cp <= 4351 || cp >= 11520 && cp <= 11567) return "ka";
|
|
2617
2645
|
if (cp >= 1328 && cp <= 1423 || cp >= 64275 && cp <= 64279) return "hy";
|
|
2646
|
+
if (isMathCodepoint(cp)) return "math";
|
|
2618
2647
|
if (isEmojiCodepoint(cp)) return "emoji";
|
|
2619
2648
|
return null;
|
|
2620
2649
|
}
|
|
@@ -5979,15 +6008,86 @@ function radialShadingDict(p, m) {
|
|
|
5979
6008
|
const s = (sx + sy) / 2 || 1;
|
|
5980
6009
|
return `<< /ShadingType 3 /ColorSpace /DeviceRGB /Coords [${n(x0)} ${n(y0)} ${n(p.r0 * s)} ${n(x1)} ${n(y1)} ${n(p.r1 * s)}] /Function ${buildGradientFunction(p.stops)} /Extend ${extendFlags(p.extend)} >>`;
|
|
5981
6010
|
}
|
|
6011
|
+
function colorAtOffset(stops, t) {
|
|
6012
|
+
if (stops.length === 0) return [0, 0, 0, 255];
|
|
6013
|
+
const sorted = stops.slice().sort((a, b) => a.offset - b.offset);
|
|
6014
|
+
if (t <= sorted[0].offset) return sorted[0].color;
|
|
6015
|
+
const last = sorted[sorted.length - 1];
|
|
6016
|
+
if (t >= last.offset) return last.color;
|
|
6017
|
+
for (let i = 0; i < sorted.length - 1; i++) {
|
|
6018
|
+
const a = sorted[i], b = sorted[i + 1];
|
|
6019
|
+
if (t >= a.offset && t <= b.offset) {
|
|
6020
|
+
const span = b.offset - a.offset || 1;
|
|
6021
|
+
const f = (t - a.offset) / span;
|
|
6022
|
+
return [
|
|
6023
|
+
Math.round(a.color[0] + (b.color[0] - a.color[0]) * f),
|
|
6024
|
+
Math.round(a.color[1] + (b.color[1] - a.color[1]) * f),
|
|
6025
|
+
Math.round(a.color[2] + (b.color[2] - a.color[2]) * f),
|
|
6026
|
+
Math.round(a.color[3] + (b.color[3] - a.color[3]) * f)
|
|
6027
|
+
];
|
|
6028
|
+
}
|
|
6029
|
+
}
|
|
6030
|
+
return last.color;
|
|
6031
|
+
}
|
|
6032
|
+
function emitSweep(p, cx, cy, maxR, body, gsFor, blendMode) {
|
|
6033
|
+
const start = p.startAngle;
|
|
6034
|
+
const end = p.endAngle;
|
|
6035
|
+
const span = end - start;
|
|
6036
|
+
if (Math.abs(span) < 0.01) {
|
|
6037
|
+
const c = colorAtOffset(p.stops, 0);
|
|
6038
|
+
const gs = gsFor(c[3] / 255, blendMode);
|
|
6039
|
+
if (gs) body.push(`/${gs} gs`);
|
|
6040
|
+
body.push(`${ch(c[0])} ${ch(c[1])} ${ch(c[2])} rg`);
|
|
6041
|
+
body.push(`${n(cx - maxR)} ${n(cy - maxR)} ${n(2 * maxR)} ${n(2 * maxR)} re`);
|
|
6042
|
+
body.push("f");
|
|
6043
|
+
return;
|
|
6044
|
+
}
|
|
6045
|
+
const steps = Math.max(12, Math.min(180, Math.ceil(Math.abs(span) / 3)));
|
|
6046
|
+
const r = maxR * 1.5;
|
|
6047
|
+
const rad = Math.PI / 180;
|
|
6048
|
+
for (let i = 0; i < steps; i++) {
|
|
6049
|
+
const a0 = start + span * i / steps;
|
|
6050
|
+
const a1 = start + span * (i + 1) / steps;
|
|
6051
|
+
const tMid = (i + 0.5) / steps;
|
|
6052
|
+
const c = colorAtOffset(p.stops, tMid);
|
|
6053
|
+
const gs = gsFor(c[3] / 255, blendMode);
|
|
6054
|
+
body.push("q");
|
|
6055
|
+
if (gs) body.push(`/${gs} gs`);
|
|
6056
|
+
body.push(`${ch(c[0])} ${ch(c[1])} ${ch(c[2])} rg`);
|
|
6057
|
+
const x0 = cx + r * Math.cos(a0 * rad), y0 = cy + r * Math.sin(a0 * rad);
|
|
6058
|
+
const x1 = cx + r * Math.cos(a1 * rad), y1 = cy + r * Math.sin(a1 * rad);
|
|
6059
|
+
body.push(`${n(cx)} ${n(cy)} m ${n(x0)} ${n(y0)} l ${n(x1)} ${n(y1)} l h`);
|
|
6060
|
+
body.push("f");
|
|
6061
|
+
body.push("Q");
|
|
6062
|
+
}
|
|
6063
|
+
}
|
|
5982
6064
|
function renderColorGlyph(glyph, outlines, unitsPerEm) {
|
|
5983
6065
|
const body = [];
|
|
5984
6066
|
const shadings = [];
|
|
5985
6067
|
const extGStates = [];
|
|
5986
|
-
const
|
|
6068
|
+
const gsMap = /* @__PURE__ */ new Map();
|
|
5987
6069
|
let shadingIdx = 0;
|
|
6070
|
+
const gsFor = (alpha, bm) => {
|
|
6071
|
+
const a = Math.max(0, Math.min(1, alpha));
|
|
6072
|
+
const needAlpha = a < 0.999;
|
|
6073
|
+
const needBm = bm !== void 0 && bm !== "Normal";
|
|
6074
|
+
if (!needAlpha && !needBm) return "";
|
|
6075
|
+
const key = `${needAlpha ? a.toFixed(3) : "1"}|${needBm ? bm : ""}`;
|
|
6076
|
+
let name = gsMap.get(key);
|
|
6077
|
+
if (!name) {
|
|
6078
|
+
name = `Gs${gsMap.size}`;
|
|
6079
|
+
gsMap.set(key, name);
|
|
6080
|
+
const parts = [];
|
|
6081
|
+
if (needAlpha) parts.push(`/ca ${n(a)}`, `/CA ${n(a)}`);
|
|
6082
|
+
if (needBm) parts.push(`/BM /${bm}`);
|
|
6083
|
+
extGStates.push({ name, dict: `<< ${parts.join(" ")} >>` });
|
|
6084
|
+
}
|
|
6085
|
+
return name;
|
|
6086
|
+
};
|
|
5988
6087
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
5989
6088
|
for (const layer of glyph.layers) {
|
|
5990
6089
|
const m = layer.transform ?? ID;
|
|
6090
|
+
const bm = layer.blendMode;
|
|
5991
6091
|
const contours = outlines(layer.glyphId);
|
|
5992
6092
|
if (contours.length === 0) continue;
|
|
5993
6093
|
const path = contoursToPath(contours, m);
|
|
@@ -6002,26 +6102,36 @@ function renderColorGlyph(glyph, outlines, unitsPerEm) {
|
|
|
6002
6102
|
}
|
|
6003
6103
|
if (layer.paint.kind === "solid") {
|
|
6004
6104
|
const c = layer.paint.color;
|
|
6005
|
-
const alpha = c[3] / 255;
|
|
6006
6105
|
body.push("q");
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
if (!gs) {
|
|
6010
|
-
gs = `GsA${alphaMap.size}`;
|
|
6011
|
-
alphaMap.set(c[3], gs);
|
|
6012
|
-
extGStates.push({ name: gs, dict: `<< /ca ${n(alpha)} /CA ${n(alpha)} >>` });
|
|
6013
|
-
}
|
|
6014
|
-
body.push(`/${gs} gs`);
|
|
6015
|
-
}
|
|
6106
|
+
const gs = gsFor(c[3] / 255, bm);
|
|
6107
|
+
if (gs) body.push(`/${gs} gs`);
|
|
6016
6108
|
body.push(`${ch(c[0])} ${ch(c[1])} ${ch(c[2])} rg`);
|
|
6017
6109
|
body.push(path);
|
|
6018
6110
|
body.push("f");
|
|
6019
6111
|
body.push("Q");
|
|
6112
|
+
} else if (layer.paint.kind === "sweep") {
|
|
6113
|
+
const [cx, cy] = tx(m, layer.paint.center[0], layer.paint.center[1]);
|
|
6114
|
+
let r2 = 0;
|
|
6115
|
+
for (const contour of contours) {
|
|
6116
|
+
for (const pt of contour) {
|
|
6117
|
+
const [px, py] = tx(m, pt.x, pt.y);
|
|
6118
|
+
const d = (px - cx) * (px - cx) + (py - cy) * (py - cy);
|
|
6119
|
+
if (d > r2) r2 = d;
|
|
6120
|
+
}
|
|
6121
|
+
}
|
|
6122
|
+
const maxR = Math.sqrt(r2) || 1;
|
|
6123
|
+
body.push("q");
|
|
6124
|
+
body.push(path);
|
|
6125
|
+
body.push("W n");
|
|
6126
|
+
emitSweep(layer.paint, cx, cy, maxR, body, gsFor, bm);
|
|
6127
|
+
body.push("Q");
|
|
6020
6128
|
} else {
|
|
6021
6129
|
const name = `Sh${shadingIdx++}`;
|
|
6022
6130
|
const dict = layer.paint.kind === "linear" ? linearShadingDict(layer.paint, m) : radialShadingDict(layer.paint, m);
|
|
6023
6131
|
shadings.push({ name, dict });
|
|
6024
6132
|
body.push("q");
|
|
6133
|
+
const gs = gsFor(1, bm);
|
|
6134
|
+
if (gs) body.push(`/${gs} gs`);
|
|
6025
6135
|
body.push(path);
|
|
6026
6136
|
body.push("W n");
|
|
6027
6137
|
body.push(`/${name} sh`);
|
|
@@ -6163,6 +6273,10 @@ function buildTextRunsWithFallback(text, fontRef, fd, sz, trackGid, pdfA = false
|
|
|
6163
6273
|
for (let i = 0; i < text.length; ) {
|
|
6164
6274
|
const rawCp = text.codePointAt(i) ?? 0;
|
|
6165
6275
|
const charLen = rawCp > 65535 ? 2 : 1;
|
|
6276
|
+
if (rawCp < 32 || rawCp === 127) {
|
|
6277
|
+
i += charLen;
|
|
6278
|
+
continue;
|
|
6279
|
+
}
|
|
6166
6280
|
const cp = rawCp === 8239 || rawCp === 160 ? 32 : rawCp;
|
|
6167
6281
|
const char = text.substring(i, i + charLen);
|
|
6168
6282
|
const gid = fd.cmap[cp] ?? 0;
|
|
@@ -8529,9 +8643,238 @@ function buildPDFBytes(params, layoutOptions) {
|
|
|
8529
8643
|
return toBytes(buildPDF(params, layoutOptions));
|
|
8530
8644
|
}
|
|
8531
8645
|
|
|
8646
|
+
// src/core/pdf-outline.ts
|
|
8647
|
+
function buildOutlineObjects(items, startObjNum, pageObjNumFor, defaultY, fmtNum3, pageCount) {
|
|
8648
|
+
const rootObjNum = startObjNum;
|
|
8649
|
+
const nodes = [];
|
|
8650
|
+
let nextObj = startObjNum + 1;
|
|
8651
|
+
function alloc(list, parentObjNum, depth) {
|
|
8652
|
+
let first = 0;
|
|
8653
|
+
let last = 0;
|
|
8654
|
+
let prev = 0;
|
|
8655
|
+
let visibleCount = 0;
|
|
8656
|
+
const siblingNodes = [];
|
|
8657
|
+
for (const item of list) {
|
|
8658
|
+
const objNum = nextObj++;
|
|
8659
|
+
const open = item.open !== false;
|
|
8660
|
+
const node = {
|
|
8661
|
+
item,
|
|
8662
|
+
objNum,
|
|
8663
|
+
parentObjNum,
|
|
8664
|
+
depth,
|
|
8665
|
+
firstChildObjNum: 0,
|
|
8666
|
+
lastChildObjNum: 0,
|
|
8667
|
+
prevObjNum: prev,
|
|
8668
|
+
nextObjNum: 0,
|
|
8669
|
+
openDescendantCount: 0,
|
|
8670
|
+
open
|
|
8671
|
+
};
|
|
8672
|
+
if (prev !== 0) {
|
|
8673
|
+
const prevNode = siblingNodes[siblingNodes.length - 1];
|
|
8674
|
+
prevNode.nextObjNum = objNum;
|
|
8675
|
+
}
|
|
8676
|
+
nodes.push(node);
|
|
8677
|
+
siblingNodes.push(node);
|
|
8678
|
+
if (first === 0) first = objNum;
|
|
8679
|
+
last = objNum;
|
|
8680
|
+
prev = objNum;
|
|
8681
|
+
visibleCount++;
|
|
8682
|
+
const children = item.children;
|
|
8683
|
+
if (children && children.length > 0) {
|
|
8684
|
+
const sub = alloc(children, objNum, depth + 1);
|
|
8685
|
+
node.firstChildObjNum = sub.first;
|
|
8686
|
+
node.lastChildObjNum = sub.last;
|
|
8687
|
+
node.openDescendantCount = sub.visibleCount;
|
|
8688
|
+
if (open) visibleCount += sub.visibleCount;
|
|
8689
|
+
}
|
|
8690
|
+
}
|
|
8691
|
+
return { first, last, visibleCount };
|
|
8692
|
+
}
|
|
8693
|
+
const top = alloc(items, rootObjNum, 0);
|
|
8694
|
+
const objects = [];
|
|
8695
|
+
objects.push([
|
|
8696
|
+
rootObjNum,
|
|
8697
|
+
`<< /Type /Outlines /First ${top.first} 0 R /Last ${top.last} 0 R /Count ${top.visibleCount} >>`
|
|
8698
|
+
]);
|
|
8699
|
+
for (const node of nodes) {
|
|
8700
|
+
const it = node.item;
|
|
8701
|
+
const pageIdx = Math.max(0, Math.min(pageCount - 1, it.pageIndex | 0));
|
|
8702
|
+
const pageObj = pageObjNumFor(pageIdx);
|
|
8703
|
+
const y = it.y ?? defaultY;
|
|
8704
|
+
const parts = [
|
|
8705
|
+
`/Title ${encodePdfTextString(it.title)}`,
|
|
8706
|
+
`/Parent ${node.parentObjNum} 0 R`
|
|
8707
|
+
];
|
|
8708
|
+
if (node.prevObjNum !== 0) parts.push(`/Prev ${node.prevObjNum} 0 R`);
|
|
8709
|
+
if (node.nextObjNum !== 0) parts.push(`/Next ${node.nextObjNum} 0 R`);
|
|
8710
|
+
if (node.firstChildObjNum !== 0) {
|
|
8711
|
+
parts.push(`/First ${node.firstChildObjNum} 0 R`);
|
|
8712
|
+
parts.push(`/Last ${node.lastChildObjNum} 0 R`);
|
|
8713
|
+
const count = node.open ? node.openDescendantCount : -node.openDescendantCount;
|
|
8714
|
+
parts.push(`/Count ${count}`);
|
|
8715
|
+
}
|
|
8716
|
+
parts.push(`/Dest [${pageObj} 0 R /XYZ 0 ${fmtNum3(y)} null]`);
|
|
8717
|
+
const flags = (it.bold ? 2 : 0) | (it.italic ? 1 : 0);
|
|
8718
|
+
if (flags !== 0) parts.push(`/F ${flags}`);
|
|
8719
|
+
if (it.color) parts.push(`/C [${it.color}]`);
|
|
8720
|
+
objects.push([node.objNum, `<< ${parts.join(" ")} >>`]);
|
|
8721
|
+
}
|
|
8722
|
+
return { objects, rootObjNum, totalObjects: nodes.length + 1 };
|
|
8723
|
+
}
|
|
8724
|
+
|
|
8725
|
+
// src/core/pdf-page-labels.ts
|
|
8726
|
+
var STYLE_OP = {
|
|
8727
|
+
decimal: "D",
|
|
8728
|
+
roman: "r",
|
|
8729
|
+
Roman: "R",
|
|
8730
|
+
alpha: "a",
|
|
8731
|
+
Alpha: "A"
|
|
8732
|
+
};
|
|
8733
|
+
function escapePdfLiteral(s) {
|
|
8734
|
+
return s.replace(/[\\()]/g, (c) => "\\" + c);
|
|
8735
|
+
}
|
|
8736
|
+
function buildPageLabelsDict(ranges, pageCount) {
|
|
8737
|
+
if (ranges.length === 0) {
|
|
8738
|
+
throw new Error("pageLabels must contain at least one range");
|
|
8739
|
+
}
|
|
8740
|
+
const sorted = [...ranges].sort((a, b) => a.startPage - b.startPage);
|
|
8741
|
+
let prev = -1;
|
|
8742
|
+
const nums = [];
|
|
8743
|
+
for (const r of sorted) {
|
|
8744
|
+
const idx = r.startPage | 0;
|
|
8745
|
+
if (idx < 0 || idx >= pageCount) {
|
|
8746
|
+
throw new Error(`pageLabels range startPage ${idx} out of bounds (0-${pageCount - 1})`);
|
|
8747
|
+
}
|
|
8748
|
+
if (idx <= prev) {
|
|
8749
|
+
throw new Error(`pageLabels ranges must have strictly increasing, unique startPage values (got ${idx} after ${prev})`);
|
|
8750
|
+
}
|
|
8751
|
+
prev = idx;
|
|
8752
|
+
const entryParts = [];
|
|
8753
|
+
const style = r.style ?? "decimal";
|
|
8754
|
+
if (style !== "none") {
|
|
8755
|
+
entryParts.push(`/S /${STYLE_OP[style]}`);
|
|
8756
|
+
}
|
|
8757
|
+
if (r.prefix !== void 0 && r.prefix !== "") {
|
|
8758
|
+
entryParts.push(`/P (${escapePdfLiteral(r.prefix)})`);
|
|
8759
|
+
}
|
|
8760
|
+
if (r.start !== void 0 && r.start !== 1) {
|
|
8761
|
+
if (!Number.isInteger(r.start) || r.start < 1) {
|
|
8762
|
+
throw new Error(`pageLabels range start must be a positive integer (got ${r.start})`);
|
|
8763
|
+
}
|
|
8764
|
+
entryParts.push(`/St ${r.start}`);
|
|
8765
|
+
}
|
|
8766
|
+
nums.push(`${idx} << ${entryParts.join(" ")} >>`);
|
|
8767
|
+
}
|
|
8768
|
+
return `<< /Nums [${nums.join(" ")}] >>`;
|
|
8769
|
+
}
|
|
8770
|
+
|
|
8771
|
+
// src/core/pdf-viewer-prefs.ts
|
|
8772
|
+
var PAGE_LAYOUT = {
|
|
8773
|
+
singlePage: "SinglePage",
|
|
8774
|
+
oneColumn: "OneColumn",
|
|
8775
|
+
twoColumnLeft: "TwoColumnLeft",
|
|
8776
|
+
twoColumnRight: "TwoColumnRight",
|
|
8777
|
+
twoPageLeft: "TwoPageLeft",
|
|
8778
|
+
twoPageRight: "TwoPageRight"
|
|
8779
|
+
};
|
|
8780
|
+
var PAGE_MODE = {
|
|
8781
|
+
useNone: "UseNone",
|
|
8782
|
+
useOutlines: "UseOutlines",
|
|
8783
|
+
useThumbs: "UseThumbs",
|
|
8784
|
+
fullScreen: "FullScreen",
|
|
8785
|
+
useOC: "UseOC",
|
|
8786
|
+
useAttachments: "UseAttachments"
|
|
8787
|
+
};
|
|
8788
|
+
var NON_FS_PAGE_MODE = {
|
|
8789
|
+
useNone: "UseNone",
|
|
8790
|
+
useOutlines: "UseOutlines",
|
|
8791
|
+
useThumbs: "UseThumbs",
|
|
8792
|
+
useOC: "UseOC"
|
|
8793
|
+
};
|
|
8794
|
+
function buildViewerPreferences(prefs) {
|
|
8795
|
+
const pageLayout = prefs.pageLayout ? PAGE_LAYOUT[prefs.pageLayout] : void 0;
|
|
8796
|
+
const pageMode = prefs.pageMode ? PAGE_MODE[prefs.pageMode] : void 0;
|
|
8797
|
+
const entries = [];
|
|
8798
|
+
const bool = (key, v) => {
|
|
8799
|
+
if (v !== void 0) entries.push(`/${key} ${v ? "true" : "false"}`);
|
|
8800
|
+
};
|
|
8801
|
+
bool("HideToolbar", prefs.hideToolbar);
|
|
8802
|
+
bool("HideMenubar", prefs.hideMenubar);
|
|
8803
|
+
bool("HideWindowUI", prefs.hideWindowUI);
|
|
8804
|
+
bool("FitWindow", prefs.fitWindow);
|
|
8805
|
+
bool("CenterWindow", prefs.centerWindow);
|
|
8806
|
+
bool("DisplayDocTitle", prefs.displayDocTitle);
|
|
8807
|
+
if (prefs.nonFullScreenPageMode) {
|
|
8808
|
+
entries.push(`/NonFullScreenPageMode /${NON_FS_PAGE_MODE[prefs.nonFullScreenPageMode]}`);
|
|
8809
|
+
}
|
|
8810
|
+
if (prefs.direction) {
|
|
8811
|
+
entries.push(`/Direction /${prefs.direction === "r2l" ? "R2L" : "L2R"}`);
|
|
8812
|
+
}
|
|
8813
|
+
if (prefs.printScaling) {
|
|
8814
|
+
entries.push(`/PrintScaling /${prefs.printScaling === "none" ? "None" : "AppDefault"}`);
|
|
8815
|
+
}
|
|
8816
|
+
const dict = entries.length > 0 ? ` /ViewerPreferences << ${entries.join(" ")} >>` : "";
|
|
8817
|
+
return { pageLayout, pageMode, dict };
|
|
8818
|
+
}
|
|
8819
|
+
|
|
8532
8820
|
// src/core/pdf-document.ts
|
|
8533
8821
|
init_pdf_encrypt();
|
|
8534
8822
|
|
|
8823
|
+
// src/core/pdf-layout-debug.ts
|
|
8824
|
+
function resolveDebugOptions(debug) {
|
|
8825
|
+
if (!debug) return null;
|
|
8826
|
+
if (debug === true) {
|
|
8827
|
+
return { showMargins: true, showContentBounds: true, showCells: true };
|
|
8828
|
+
}
|
|
8829
|
+
const showMargins = debug.showMargins === true;
|
|
8830
|
+
const showContentBounds = debug.showContentBounds === true;
|
|
8831
|
+
const showCells = debug.showCells === true;
|
|
8832
|
+
if (!showMargins && !showContentBounds && !showCells) return null;
|
|
8833
|
+
return { showMargins, showContentBounds, showCells };
|
|
8834
|
+
}
|
|
8835
|
+
var COL_MARGIN = "0 0.45 0.95";
|
|
8836
|
+
var COL_BLOCK = "0.90 0.20 0.30";
|
|
8837
|
+
var COL_CELL = "0 0.62 0.30";
|
|
8838
|
+
function rectOp(x, y, w, h, color, lineW) {
|
|
8839
|
+
return `q ${color} RG ${fmtNum(lineW)} w ${fmtNum(x)} ${fmtNum(y)} ${fmtNum(w)} ${fmtNum(h)} re S Q`;
|
|
8840
|
+
}
|
|
8841
|
+
function marginBoxOps(pgW, pgH, mg, footerH) {
|
|
8842
|
+
const x = mg.l;
|
|
8843
|
+
const yBottom = mg.b + footerH;
|
|
8844
|
+
const w = pgW - mg.l - mg.r;
|
|
8845
|
+
const h = pgH - mg.t - yBottom;
|
|
8846
|
+
return rectOp(x, yBottom, w, h, COL_MARGIN, 0.5);
|
|
8847
|
+
}
|
|
8848
|
+
function blockBoundsOps(x, width, yTop, yBottom) {
|
|
8849
|
+
const h = yTop - yBottom;
|
|
8850
|
+
if (h <= 0) return "";
|
|
8851
|
+
return rectOp(x, yBottom, width, h, COL_BLOCK, 0.4);
|
|
8852
|
+
}
|
|
8853
|
+
function tableCellOps(plan, slice, yTop) {
|
|
8854
|
+
const drawCaption = slice ? slice.drawCaption : true;
|
|
8855
|
+
const drawHeader = slice ? slice.drawHeader : true;
|
|
8856
|
+
const fromRow = slice ? slice.fromRow : 0;
|
|
8857
|
+
const toRow = slice ? slice.toRow : plan.rowHeights.length;
|
|
8858
|
+
const parts = [];
|
|
8859
|
+
let y = yTop - (drawCaption ? plan.captionHeight : 0);
|
|
8860
|
+
if (drawHeader) {
|
|
8861
|
+
const hBottom = y - plan.headerHeight;
|
|
8862
|
+
for (let c = 0; c < plan.cx.length; c++) {
|
|
8863
|
+
parts.push(rectOp(plan.cx[c], hBottom, plan.cwi[c], plan.headerHeight, COL_CELL, 0.3));
|
|
8864
|
+
}
|
|
8865
|
+
y = hBottom;
|
|
8866
|
+
}
|
|
8867
|
+
for (let r = fromRow; r < toRow; r++) {
|
|
8868
|
+
const rh = plan.rowHeights[r];
|
|
8869
|
+
const rBottom = y - rh;
|
|
8870
|
+
for (let c = 0; c < plan.cx.length; c++) {
|
|
8871
|
+
parts.push(rectOp(plan.cx[c], rBottom, plan.cwi[c], rh, COL_CELL, 0.3));
|
|
8872
|
+
}
|
|
8873
|
+
y = rBottom;
|
|
8874
|
+
}
|
|
8875
|
+
return parts.join("\n");
|
|
8876
|
+
}
|
|
8877
|
+
|
|
8535
8878
|
// src/core/pdf-form.ts
|
|
8536
8879
|
var DEFAULT_FIELD_HEIGHT_TEXT = 22;
|
|
8537
8880
|
var DEFAULT_FIELD_HEIGHT_MULTILINE = 60;
|
|
@@ -10666,6 +11009,51 @@ function getNum(attrs, name, def = 0) {
|
|
|
10666
11009
|
const v = getAttr(attrs, name);
|
|
10667
11010
|
return v !== void 0 ? +v : def;
|
|
10668
11011
|
}
|
|
11012
|
+
function getLen(attrs, name) {
|
|
11013
|
+
const v = getAttr(attrs, name);
|
|
11014
|
+
if (v === void 0) return void 0;
|
|
11015
|
+
const n2 = parseFloat(v);
|
|
11016
|
+
return Number.isFinite(n2) ? n2 : void 0;
|
|
11017
|
+
}
|
|
11018
|
+
function decodeSvgEntities(s) {
|
|
11019
|
+
return s.replace(/&(#x[0-9a-fA-F]+|#[0-9]+|[a-zA-Z]+);/g, (_m, ent) => {
|
|
11020
|
+
if (ent[0] === "#") {
|
|
11021
|
+
const cp = ent[1] === "x" || ent[1] === "X" ? parseInt(ent.slice(2), 16) : parseInt(ent.slice(1), 10);
|
|
11022
|
+
return Number.isFinite(cp) && cp >= 0 && cp <= 1114111 ? String.fromCodePoint(cp) : "";
|
|
11023
|
+
}
|
|
11024
|
+
switch (ent) {
|
|
11025
|
+
case "amp":
|
|
11026
|
+
return "&";
|
|
11027
|
+
case "lt":
|
|
11028
|
+
return "<";
|
|
11029
|
+
case "gt":
|
|
11030
|
+
return ">";
|
|
11031
|
+
case "quot":
|
|
11032
|
+
return '"';
|
|
11033
|
+
case "apos":
|
|
11034
|
+
return "'";
|
|
11035
|
+
case "nbsp":
|
|
11036
|
+
return "\xA0";
|
|
11037
|
+
default:
|
|
11038
|
+
return "";
|
|
11039
|
+
}
|
|
11040
|
+
});
|
|
11041
|
+
}
|
|
11042
|
+
function stripSvgTags(raw) {
|
|
11043
|
+
let out = "";
|
|
11044
|
+
let inTag = false;
|
|
11045
|
+
for (const ch2 of raw) {
|
|
11046
|
+
if (ch2 === "<") inTag = true;
|
|
11047
|
+
else if (ch2 === ">") inTag = false;
|
|
11048
|
+
else if (!inTag) out += ch2;
|
|
11049
|
+
}
|
|
11050
|
+
return out;
|
|
11051
|
+
}
|
|
11052
|
+
function sanitizeSvgText(raw) {
|
|
11053
|
+
const noTags = stripSvgTags(raw);
|
|
11054
|
+
const decoded = decodeSvgEntities(noTags);
|
|
11055
|
+
return decoded.replace(/[\u0000-\u001F\u007F-\u009F]+/g, " ").replace(/\s+/g, " ").trim();
|
|
11056
|
+
}
|
|
10669
11057
|
function rectToPath(x, y, w, h, rx, ry) {
|
|
10670
11058
|
if (w <= 0 || h <= 0) return "";
|
|
10671
11059
|
if (rx <= 0 && ry <= 0) {
|
|
@@ -10747,7 +11135,60 @@ function parseSvgMarkup(svg) {
|
|
|
10747
11135
|
});
|
|
10748
11136
|
}
|
|
10749
11137
|
}
|
|
10750
|
-
|
|
11138
|
+
const textElements = parseSvgText(svg);
|
|
11139
|
+
return { elements, textElements, viewBox };
|
|
11140
|
+
}
|
|
11141
|
+
function parseSvgText(svg) {
|
|
11142
|
+
const out = [];
|
|
11143
|
+
const textRe = /<text\b([^>]*)>([\s\S]*?)<\/text>/gi;
|
|
11144
|
+
let tm;
|
|
11145
|
+
while ((tm = textRe.exec(svg)) !== null) {
|
|
11146
|
+
const attrs = tm[1];
|
|
11147
|
+
const inner = tm[2];
|
|
11148
|
+
const baseX = getLen(attrs, "x") ?? 0;
|
|
11149
|
+
const baseY = getLen(attrs, "y") ?? 0;
|
|
11150
|
+
const baseSize = getLen(attrs, "font-size") ?? 16;
|
|
11151
|
+
const baseFillRaw = getAttr(attrs, "fill");
|
|
11152
|
+
const baseFill = baseFillRaw ? normalizeSvgColor(baseFillRaw) : void 0;
|
|
11153
|
+
const baseAnchor = normalizeAnchor(getAttr(attrs, "text-anchor"));
|
|
11154
|
+
const tspanRe = /<tspan\b([^>]*)>([\s\S]*?)<\/tspan>/gi;
|
|
11155
|
+
let sm;
|
|
11156
|
+
let penX = baseX;
|
|
11157
|
+
let penY = baseY;
|
|
11158
|
+
let found = false;
|
|
11159
|
+
while ((sm = tspanRe.exec(inner)) !== null) {
|
|
11160
|
+
found = true;
|
|
11161
|
+
const sa = sm[1];
|
|
11162
|
+
const text = sanitizeSvgText(sm[2]);
|
|
11163
|
+
const ax = getLen(sa, "x");
|
|
11164
|
+
const ay = getLen(sa, "y");
|
|
11165
|
+
const adx = getLen(sa, "dx");
|
|
11166
|
+
const ady = getLen(sa, "dy");
|
|
11167
|
+
penX = ax !== void 0 ? ax : penX + (adx ?? 0);
|
|
11168
|
+
penY = ay !== void 0 ? ay : penY + (ady ?? 0);
|
|
11169
|
+
if (!text) continue;
|
|
11170
|
+
const fillRaw = getAttr(sa, "fill");
|
|
11171
|
+
out.push({
|
|
11172
|
+
text,
|
|
11173
|
+
x: penX,
|
|
11174
|
+
y: penY,
|
|
11175
|
+
fontSize: getLen(sa, "font-size") ?? baseSize,
|
|
11176
|
+
fill: fillRaw ? normalizeSvgColor(fillRaw) : baseFill,
|
|
11177
|
+
anchor: normalizeAnchor(getAttr(sa, "text-anchor")) ?? baseAnchor
|
|
11178
|
+
});
|
|
11179
|
+
}
|
|
11180
|
+
if (!found) {
|
|
11181
|
+
const text = sanitizeSvgText(inner);
|
|
11182
|
+
if (text) {
|
|
11183
|
+
out.push({ text, x: baseX, y: baseY, fontSize: baseSize, fill: baseFill, anchor: baseAnchor });
|
|
11184
|
+
}
|
|
11185
|
+
}
|
|
11186
|
+
}
|
|
11187
|
+
return out;
|
|
11188
|
+
}
|
|
11189
|
+
function normalizeAnchor(v) {
|
|
11190
|
+
if (v === "middle" || v === "end" || v === "start") return v;
|
|
11191
|
+
return void 0;
|
|
10751
11192
|
}
|
|
10752
11193
|
var fn = (n2) => n2.toFixed(2);
|
|
10753
11194
|
function resolveColor(color, fallback) {
|
|
@@ -10783,36 +11224,62 @@ function buildPathOps(segments, fillRgb, strokeRgb, strokeWidth) {
|
|
|
10783
11224
|
ops.push("Q");
|
|
10784
11225
|
return ops.join("\n");
|
|
10785
11226
|
}
|
|
10786
|
-
function renderSvg(data, x, y, w, h, options) {
|
|
11227
|
+
function renderSvg(data, x, y, w, h, options, enc) {
|
|
10787
11228
|
if (!data || w <= 0 || h <= 0) return "";
|
|
10788
11229
|
const isSvgMarkup = data.trimStart().charAt(0) === "<";
|
|
10789
11230
|
let vb;
|
|
10790
11231
|
let elements;
|
|
11232
|
+
let textElements = [];
|
|
10791
11233
|
if (isSvgMarkup) {
|
|
10792
11234
|
const parsed = parseSvgMarkup(data);
|
|
10793
11235
|
vb = options?.viewBox ?? parsed.viewBox ?? [0, 0, w, h];
|
|
10794
11236
|
elements = parsed.elements;
|
|
11237
|
+
textElements = parsed.textElements;
|
|
10795
11238
|
} else {
|
|
10796
11239
|
vb = options?.viewBox ?? [0, 0, w, h];
|
|
10797
11240
|
elements = [{ pathData: data }];
|
|
10798
11241
|
}
|
|
10799
|
-
if (elements.length === 0 || vb[2] <= 0 || vb[3] <= 0) return "";
|
|
11242
|
+
if (elements.length === 0 && textElements.length === 0 || vb[2] <= 0 || vb[3] <= 0) return "";
|
|
10800
11243
|
const sx = w / vb[2];
|
|
10801
11244
|
const sy = h / vb[3];
|
|
10802
|
-
const
|
|
11245
|
+
const tx2 = x - vb[0] * sx;
|
|
11246
|
+
const ty = y + vb[1] * sy;
|
|
11247
|
+
const cmOp = `${fn(sx)} 0 0 ${fn(-sy)} ${fn(tx2)} ${fn(ty)} cm`;
|
|
10803
11248
|
const defaultFill = resolveColor(options?.fill, "0 0 0");
|
|
10804
11249
|
const defaultStroke = resolveColor(options?.stroke, null);
|
|
10805
11250
|
const defaultSw = options?.strokeWidth ?? 1;
|
|
10806
|
-
const
|
|
11251
|
+
const shapeOps = [];
|
|
10807
11252
|
for (const elem of elements) {
|
|
10808
11253
|
const segments = parseSvgPath(elem.pathData);
|
|
10809
11254
|
if (segments.length === 0) continue;
|
|
10810
11255
|
const fillRgb = resolveColor(elem.fill, defaultFill);
|
|
10811
11256
|
const strokeRgb = resolveColor(elem.stroke, defaultStroke);
|
|
10812
11257
|
const sw = elem.strokeWidth ?? defaultSw;
|
|
10813
|
-
|
|
10814
|
-
}
|
|
10815
|
-
|
|
11258
|
+
shapeOps.push(buildPathOps(segments, fillRgb, strokeRgb, sw));
|
|
11259
|
+
}
|
|
11260
|
+
const textOps = [];
|
|
11261
|
+
if (enc && textElements.length > 0) {
|
|
11262
|
+
for (const t of textElements) {
|
|
11263
|
+
const szPdf = t.fontSize * sy;
|
|
11264
|
+
if (szPdf <= 0 || !t.text) continue;
|
|
11265
|
+
const pdfBaseX = t.x * sx + tx2;
|
|
11266
|
+
const pdfBaseY = -sy * t.y + ty;
|
|
11267
|
+
const width = enc.tw(t.text, szPdf);
|
|
11268
|
+
const anchorOffset = t.anchor === "middle" ? width / 2 : t.anchor === "end" ? width : 0;
|
|
11269
|
+
const pdfX = pdfBaseX - anchorOffset;
|
|
11270
|
+
const fillRgb = resolveColor(t.fill, "0 0 0");
|
|
11271
|
+
textOps.push("q");
|
|
11272
|
+
if (fillRgb) textOps.push(`${fillRgb} rg`);
|
|
11273
|
+
textOps.push(txt(t.text, pdfX, pdfBaseY, enc.f1, szPdf, enc));
|
|
11274
|
+
textOps.push("Q");
|
|
11275
|
+
}
|
|
11276
|
+
}
|
|
11277
|
+
if (shapeOps.length === 0 && textOps.length === 0) return "";
|
|
11278
|
+
const allOps = [];
|
|
11279
|
+
if (shapeOps.length > 0) {
|
|
11280
|
+
allOps.push("q", cmOp, ...shapeOps, "Q");
|
|
11281
|
+
}
|
|
11282
|
+
allOps.push(...textOps);
|
|
10816
11283
|
return allOps.join("\n");
|
|
10817
11284
|
}
|
|
10818
11285
|
|
|
@@ -11020,23 +11487,36 @@ function renderList(block, y, enc, mgL, cw, tagCtx, documentChildren) {
|
|
|
11020
11487
|
const sz = block.fontSize ?? DEFAULT_LIST_SIZE;
|
|
11021
11488
|
const lineH = sz * DEFAULT_LINE_HEIGHT;
|
|
11022
11489
|
const color = "0.216 0.255 0.318";
|
|
11023
|
-
const availW = cw - LIST_INDENT - BULLET_MARK_WIDTH;
|
|
11024
11490
|
ops.push(`${color} rg`);
|
|
11025
|
-
const
|
|
11026
|
-
|
|
11027
|
-
|
|
11028
|
-
|
|
11029
|
-
|
|
11491
|
+
const root = renderListLevel(block.items, block.style, 0, y, sz, lineH, enc, mgL, cw, tagCtx);
|
|
11492
|
+
ops.push(...root.ops);
|
|
11493
|
+
if (tagCtx?.tagged && root.struct && root.struct.children.length > 0) {
|
|
11494
|
+
documentChildren.push(root.struct);
|
|
11495
|
+
}
|
|
11496
|
+
return { ops, y: root.y };
|
|
11497
|
+
}
|
|
11498
|
+
function renderListLevel(items, style, depth, y, sz, lineH, enc, mgL, cw, tagCtx) {
|
|
11499
|
+
const ops = [];
|
|
11500
|
+
const indent = LIST_INDENT * (depth + 1);
|
|
11501
|
+
const markerX = mgL + indent;
|
|
11502
|
+
const xOffset = markerX + BULLET_MARK_WIDTH;
|
|
11503
|
+
const availW = cw - indent - BULLET_MARK_WIDTH;
|
|
11504
|
+
const levelChildren = [];
|
|
11505
|
+
for (let idx = 0; idx < items.length; idx++) {
|
|
11506
|
+
const entry = items[idx];
|
|
11507
|
+
const text = typeof entry === "string" ? entry : entry.text;
|
|
11508
|
+
const children = typeof entry === "string" ? void 0 : entry.items;
|
|
11509
|
+
const marker = style === "bullet" ? "\u2022" : `${idx + 1}.`;
|
|
11510
|
+
const lines = wrapText(text, availW, sz, enc);
|
|
11030
11511
|
const liChildren = [];
|
|
11031
11512
|
if (tagCtx?.tagged) {
|
|
11032
11513
|
const mcid = tagCtx.mcidAlloc.next(tagCtx.pageObjNum);
|
|
11033
11514
|
liChildren.push({ mcid, pageObjNum: tagCtx.pageObjNum });
|
|
11034
|
-
ops.push(txtTagged(marker,
|
|
11515
|
+
ops.push(txtTagged(marker, markerX, y - sz, enc.f1, sz, enc, mcid));
|
|
11035
11516
|
} else {
|
|
11036
|
-
ops.push(txt(marker,
|
|
11517
|
+
ops.push(txt(marker, markerX, y - sz, enc.f1, sz, enc));
|
|
11037
11518
|
}
|
|
11038
11519
|
for (let li = 0; li < lines.length; li++) {
|
|
11039
|
-
const xOffset = mgL + LIST_INDENT + BULLET_MARK_WIDTH;
|
|
11040
11520
|
if (li === 0) {
|
|
11041
11521
|
if (tagCtx?.tagged) {
|
|
11042
11522
|
const mcid = tagCtx.mcidAlloc.next(tagCtx.pageObjNum);
|
|
@@ -11057,14 +11537,20 @@ function renderList(block, y, enc, mgL, cw, tagCtx, documentChildren) {
|
|
|
11057
11537
|
}
|
|
11058
11538
|
}
|
|
11059
11539
|
y -= lineH + LIST_ITEM_SPACING;
|
|
11540
|
+
if (children && children.length > 0) {
|
|
11541
|
+
const sub = renderListLevel(children, style, depth + 1, y, sz, lineH, enc, mgL, cw, tagCtx);
|
|
11542
|
+
ops.push(...sub.ops);
|
|
11543
|
+
y = sub.y;
|
|
11544
|
+
if (tagCtx?.tagged && sub.struct && sub.struct.children.length > 0) {
|
|
11545
|
+
liChildren.push(sub.struct);
|
|
11546
|
+
}
|
|
11547
|
+
}
|
|
11060
11548
|
if (tagCtx?.tagged && liChildren.length > 0) {
|
|
11061
|
-
|
|
11549
|
+
levelChildren.push({ type: "LI", children: liChildren });
|
|
11062
11550
|
}
|
|
11063
11551
|
}
|
|
11064
|
-
|
|
11065
|
-
|
|
11066
|
-
}
|
|
11067
|
-
return { ops, y };
|
|
11552
|
+
const struct = tagCtx?.tagged ? { type: "L", children: levelChildren } : void 0;
|
|
11553
|
+
return { ops, y, struct };
|
|
11068
11554
|
}
|
|
11069
11555
|
var DEFAULT_ZEBRA_COLOR = "0.969 0.973 0.984";
|
|
11070
11556
|
var CAPTION_FONT_SIZE = 9;
|
|
@@ -11099,7 +11585,7 @@ function planTable(block, enc, mgL, cw) {
|
|
|
11099
11585
|
headerLines.push(lines);
|
|
11100
11586
|
if (lines.length > headerMaxLines) headerMaxLines = lines.length;
|
|
11101
11587
|
}
|
|
11102
|
-
const headerHeight = headerMaxLines === 1 ? TH_H : Math.max(TH_H, headerMaxLines * fs.th * TABLE_LINE_HEIGHT +
|
|
11588
|
+
const headerHeight = headerMaxLines === 1 ? TH_H : Math.max(TH_H, headerMaxLines * fs.th * TABLE_LINE_HEIGHT + pad + 2);
|
|
11103
11589
|
const rowLines = [];
|
|
11104
11590
|
const rowHeights = [];
|
|
11105
11591
|
for (let r = 0; r < block.rows.length; r++) {
|
|
@@ -11112,7 +11598,7 @@ function planTable(block, enc, mgL, cw) {
|
|
|
11112
11598
|
if (lines.length > maxLines) maxLines = lines.length;
|
|
11113
11599
|
}
|
|
11114
11600
|
rowLines.push(cells);
|
|
11115
|
-
const h = maxLines === 1 ? minRowH : Math.max(minRowH, maxLines * fs.td * TABLE_LINE_HEIGHT +
|
|
11601
|
+
const h = maxLines === 1 ? minRowH : Math.max(minRowH, maxLines * fs.td * TABLE_LINE_HEIGHT + pad + 2);
|
|
11116
11602
|
rowHeights.push(h);
|
|
11117
11603
|
}
|
|
11118
11604
|
const captionLines = block.caption ? wrapText(block.caption, cw, CAPTION_FONT_SIZE, enc) : [];
|
|
@@ -11152,6 +11638,30 @@ function renderTable(block, y, enc, mgL, mgR, pgW, cw, tagCtx, documentChildren,
|
|
|
11152
11638
|
const clip = block.clipCells !== false;
|
|
11153
11639
|
const zebraColor = resolveZebraColor(block.zebra);
|
|
11154
11640
|
const wrapMode = block.wrap ?? "auto";
|
|
11641
|
+
const borders = block.cellBorders;
|
|
11642
|
+
const borderSides = borders ? {
|
|
11643
|
+
top: borders.all === true || borders.top === true,
|
|
11644
|
+
right: borders.all === true || borders.right === true,
|
|
11645
|
+
bottom: borders.all === true || borders.bottom === true,
|
|
11646
|
+
left: borders.all === true || borders.left === true
|
|
11647
|
+
} : null;
|
|
11648
|
+
const borderColor = borders?.color ? parseColor(borders.color) : "0.8 0.8 0.8";
|
|
11649
|
+
const borderWidth = borders?.width ?? 0.5;
|
|
11650
|
+
const borderDash = borders?.style === "dashed" ? "[3] 0 d" : borders?.style === "dotted" ? `[${fmtNum(borderWidth)} ${fmtNum(borderWidth * 2)}] 0 d` : null;
|
|
11651
|
+
const cellBorderOps = (cellX, cellW, top, h) => {
|
|
11652
|
+
if (!borderSides || !borderSides.top && !borderSides.right && !borderSides.bottom && !borderSides.left) {
|
|
11653
|
+
return [];
|
|
11654
|
+
}
|
|
11655
|
+
const o = [];
|
|
11656
|
+
o.push(`${fmtNum(borderWidth)} w ${borderColor} RG${borderDash ? " " + borderDash : ""}`);
|
|
11657
|
+
const x0 = cellX, x1 = cellX + cellW, y0 = top - h, y1 = top;
|
|
11658
|
+
if (borderSides.top) o.push(`${fmtNum(x0)} ${fmtNum(y1)} m ${fmtNum(x1)} ${fmtNum(y1)} l S`);
|
|
11659
|
+
if (borderSides.bottom) o.push(`${fmtNum(x0)} ${fmtNum(y0)} m ${fmtNum(x1)} ${fmtNum(y0)} l S`);
|
|
11660
|
+
if (borderSides.left) o.push(`${fmtNum(x0)} ${fmtNum(y0)} m ${fmtNum(x0)} ${fmtNum(y1)} l S`);
|
|
11661
|
+
if (borderSides.right) o.push(`${fmtNum(x1)} ${fmtNum(y0)} m ${fmtNum(x1)} ${fmtNum(y1)} l S`);
|
|
11662
|
+
if (borderDash) o.push("[] 0 d");
|
|
11663
|
+
return o;
|
|
11664
|
+
};
|
|
11155
11665
|
const clipCell = (op, i, top, h) => clip ? `q ${fmtNum(cx[i])} ${fmtNum(top - h)} ${fmtNum(cwi[i])} ${fmtNum(h)} re W n
|
|
11156
11666
|
${op}
|
|
11157
11667
|
Q` : op;
|
|
@@ -11160,9 +11670,21 @@ Q` : op;
|
|
|
11160
11670
|
const out = [];
|
|
11161
11671
|
const lineH = sz * TABLE_LINE_HEIGHT;
|
|
11162
11672
|
const padBottom = isHeader ? HEADER_PAD_BOTTOM : CELL_PAD_BOTTOM;
|
|
11673
|
+
const vAlign = col.vAlign ?? block.cellVAlign;
|
|
11163
11674
|
for (let li = 0; li < lines.length; li++) {
|
|
11164
11675
|
const t = lines.length === 1 && wrapMode === "never" ? truncate(lines[li], isHeader && col.mxH !== void 0 ? col.mxH : col.mx) : lines[li];
|
|
11165
|
-
|
|
11676
|
+
let baselineY;
|
|
11677
|
+
if (vAlign) {
|
|
11678
|
+
const blockH = lines.length * lineH;
|
|
11679
|
+
let offset;
|
|
11680
|
+
if (vAlign === "top") offset = pad;
|
|
11681
|
+
else if (vAlign === "bottom") offset = rowH - blockH - pad;
|
|
11682
|
+
else offset = (rowH - blockH) / 2;
|
|
11683
|
+
if (offset < pad) offset = pad;
|
|
11684
|
+
baselineY = rowTop - offset - li * lineH - sz + sz * 0.2;
|
|
11685
|
+
} else {
|
|
11686
|
+
baselineY = lines.length === 1 ? rowTop - rowH + padBottom : rowTop - pad - sz + sz * 0.2 - li * lineH;
|
|
11687
|
+
}
|
|
11166
11688
|
let op;
|
|
11167
11689
|
if (mcRefsOut !== null && tagCtx?.tagged) {
|
|
11168
11690
|
const mcid = tagCtx.mcidAlloc.next(tagCtx.pageObjNum);
|
|
@@ -11217,6 +11739,7 @@ Q` : op;
|
|
|
11217
11739
|
for (let i = 0; i < block.headers.length && i < columns.length; i++) {
|
|
11218
11740
|
const cellRefs = tagCtx?.tagged ? [] : null;
|
|
11219
11741
|
ops.push(...emitCell(headerLines[i] ?? [""], i, y, headerHeight, enc.f2, fs.th, cellRefs, true));
|
|
11742
|
+
ops.push(...cellBorderOps(cx[i], cwi[i], y, headerHeight));
|
|
11220
11743
|
if (cellRefs && cellRefs.length > 0) {
|
|
11221
11744
|
thChildren.push({ type: "TH", children: cellRefs });
|
|
11222
11745
|
}
|
|
@@ -11244,6 +11767,7 @@ Q` : op;
|
|
|
11244
11767
|
ops.push(`${color} rg`);
|
|
11245
11768
|
const cellRefs = tagCtx?.tagged ? [] : null;
|
|
11246
11769
|
ops.push(...emitCell(cells[i] ?? [""], i, y, rowH, font, fs.td, cellRefs, false));
|
|
11770
|
+
ops.push(...cellBorderOps(cx[i], cwi[i], y, rowH));
|
|
11247
11771
|
if (cellRefs && cellRefs.length > 0) {
|
|
11248
11772
|
tdChildren.push({ type: "TD", children: cellRefs });
|
|
11249
11773
|
}
|
|
@@ -11500,7 +12024,7 @@ function renderBarcodeBlock(block, y, mgL, cw, tagCtx, documentChildren) {
|
|
|
11500
12024
|
y = by - 6;
|
|
11501
12025
|
return { ops, y };
|
|
11502
12026
|
}
|
|
11503
|
-
function renderSvgBlock(block, y, mgL, cw, tagCtx, documentChildren) {
|
|
12027
|
+
function renderSvgBlock(block, y, mgL, cw, tagCtx, documentChildren, enc) {
|
|
11504
12028
|
const ops = [];
|
|
11505
12029
|
const w = block.width ?? DEFAULT_SVG_SIZE;
|
|
11506
12030
|
const h = block.height ?? DEFAULT_SVG_SIZE;
|
|
@@ -11516,7 +12040,7 @@ function renderSvgBlock(block, y, mgL, cw, tagCtx, documentChildren) {
|
|
|
11516
12040
|
stroke: block.stroke,
|
|
11517
12041
|
strokeWidth: block.strokeWidth,
|
|
11518
12042
|
viewBox: block.viewBox
|
|
11519
|
-
});
|
|
12043
|
+
}, enc);
|
|
11520
12044
|
if (svgOps) {
|
|
11521
12045
|
if (tagCtx?.tagged) {
|
|
11522
12046
|
const mcid = tagCtx.mcidAlloc.next(tagCtx.pageObjNum);
|
|
@@ -11615,13 +12139,20 @@ function estimateBlockHeight(block, enc, cw, headings) {
|
|
|
11615
12139
|
case "list": {
|
|
11616
12140
|
const sz = block.fontSize ?? DEFAULT_LIST_SIZE;
|
|
11617
12141
|
const lineH = sz * DEFAULT_LINE_HEIGHT;
|
|
11618
|
-
const
|
|
11619
|
-
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
|
|
11623
|
-
|
|
11624
|
-
|
|
12142
|
+
const measureLevel = (items, depth) => {
|
|
12143
|
+
const availW = cw - LIST_INDENT * (depth + 1) - BULLET_MARK_WIDTH;
|
|
12144
|
+
let acc = 0;
|
|
12145
|
+
for (const entry of items) {
|
|
12146
|
+
const text = typeof entry === "string" ? entry : entry.text;
|
|
12147
|
+
const lines = wrapText(text, availW, sz, enc);
|
|
12148
|
+
acc += lineH + (lines.length - 1) * lineH + LIST_ITEM_SPACING;
|
|
12149
|
+
if (typeof entry !== "string" && entry.items && entry.items.length > 0) {
|
|
12150
|
+
acc += measureLevel(entry.items, depth + 1);
|
|
12151
|
+
}
|
|
12152
|
+
}
|
|
12153
|
+
return acc;
|
|
12154
|
+
};
|
|
12155
|
+
return measureLevel(block.items, 0);
|
|
11625
12156
|
}
|
|
11626
12157
|
case "table": {
|
|
11627
12158
|
return TH_H + block.rows.length * ROW_H + 6;
|
|
@@ -11691,6 +12222,7 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
11691
12222
|
if (watermarkOpts) {
|
|
11692
12223
|
validateWatermark(watermarkOpts, layout?.tagged);
|
|
11693
12224
|
}
|
|
12225
|
+
const debugOpts = resolveDebugOptions(layout?.debug);
|
|
11694
12226
|
const attachments = layout?.attachments;
|
|
11695
12227
|
validateAttachments(attachments, layout?.tagged);
|
|
11696
12228
|
const mcidAlloc = tagged ? createMCIDAllocator() : void 0;
|
|
@@ -11878,6 +12410,10 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
11878
12410
|
const tagCtx = tagged && mcidAlloc ? { tagged: true, mcidAlloc, pageObjNum} : void 0;
|
|
11879
12411
|
const ops = [];
|
|
11880
12412
|
let y = pgH - mg.t;
|
|
12413
|
+
const debugOps = [];
|
|
12414
|
+
if (debugOpts?.showMargins) {
|
|
12415
|
+
debugOps.push(marginBoxOps(pgW, pgH, mg, FT_H));
|
|
12416
|
+
}
|
|
11881
12417
|
if (headerTpl) {
|
|
11882
12418
|
const hOps = renderPageTemplate(
|
|
11883
12419
|
headerTpl,
|
|
@@ -11918,6 +12454,7 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
11918
12454
|
}
|
|
11919
12455
|
const blocks = pageBlocks[p] ?? [];
|
|
11920
12456
|
for (const block of blocks) {
|
|
12457
|
+
const yBefore = debugOpts ? y : 0;
|
|
11921
12458
|
switch (block.type) {
|
|
11922
12459
|
case "heading": {
|
|
11923
12460
|
if (headingDestIdx < headingDests.length) {
|
|
@@ -11998,7 +12535,7 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
11998
12535
|
break;
|
|
11999
12536
|
}
|
|
12000
12537
|
case "svg": {
|
|
12001
|
-
const result = renderSvgBlock(block, y, mg.l, cw, tagCtx, documentChildren);
|
|
12538
|
+
const result = renderSvgBlock(block, y, mg.l, cw, tagCtx, documentChildren, enc);
|
|
12002
12539
|
ops.push(...result.ops);
|
|
12003
12540
|
y = result.y;
|
|
12004
12541
|
break;
|
|
@@ -12010,6 +12547,19 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
12010
12547
|
break;
|
|
12011
12548
|
}
|
|
12012
12549
|
}
|
|
12550
|
+
if (debugOpts) {
|
|
12551
|
+
if (debugOpts.showContentBounds) {
|
|
12552
|
+
const bo = blockBoundsOps(mg.l, cw, yBefore, y);
|
|
12553
|
+
if (bo) debugOps.push(bo);
|
|
12554
|
+
}
|
|
12555
|
+
if (debugOpts.showCells) {
|
|
12556
|
+
if (block.type === "__tableSlice") {
|
|
12557
|
+
debugOps.push(tableCellOps(block.slice.plan, block.slice, yBefore));
|
|
12558
|
+
} else if (block.type === "table") {
|
|
12559
|
+
debugOps.push(tableCellOps(planTable(block, enc, mg.l, cw), void 0, yBefore));
|
|
12560
|
+
}
|
|
12561
|
+
}
|
|
12562
|
+
}
|
|
12013
12563
|
}
|
|
12014
12564
|
if (wmState?.foregroundOps) {
|
|
12015
12565
|
ops.push(wmState.foregroundOps);
|
|
@@ -12030,6 +12580,9 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
12030
12580
|
documentChildren
|
|
12031
12581
|
);
|
|
12032
12582
|
ops.push(...ftOps);
|
|
12583
|
+
if (debugOps.length > 0) {
|
|
12584
|
+
ops.push(...debugOps);
|
|
12585
|
+
}
|
|
12033
12586
|
pageStreams.push(ops.join("\n"));
|
|
12034
12587
|
}
|
|
12035
12588
|
const annotsByPage = /* @__PURE__ */ new Map();
|
|
@@ -12479,6 +13032,41 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
12479
13032
|
totalObjs += efResult.totalObjects;
|
|
12480
13033
|
}
|
|
12481
13034
|
}
|
|
13035
|
+
let pageLabelsStr = "";
|
|
13036
|
+
if (params.pageLabels && params.pageLabels.length > 0) {
|
|
13037
|
+
pageLabelsStr = ` /PageLabels ${buildPageLabelsDict(params.pageLabels, totalPages)}`;
|
|
13038
|
+
}
|
|
13039
|
+
const viewerPrefs = layout?.viewerPreferences ? buildViewerPreferences(layout.viewerPreferences) : void 0;
|
|
13040
|
+
let viewerPrefsStr = viewerPrefs?.dict ?? "";
|
|
13041
|
+
if (viewerPrefs?.pageLayout) {
|
|
13042
|
+
viewerPrefsStr = ` /PageLayout /${viewerPrefs.pageLayout}${viewerPrefsStr}`;
|
|
13043
|
+
}
|
|
13044
|
+
let outlineCatalogStr = "";
|
|
13045
|
+
if (params.outline) {
|
|
13046
|
+
const items = params.outline === "auto" ? autoOutlineFromHeadings(headingDests) : params.outline.map(mapOutlineItem);
|
|
13047
|
+
if (items.length > 0) {
|
|
13048
|
+
const outlineStart = totalObjs + 1;
|
|
13049
|
+
const built = buildOutlineObjects(
|
|
13050
|
+
items,
|
|
13051
|
+
outlineStart,
|
|
13052
|
+
(pageIndex) => pageObjStart + pageIndex * 2,
|
|
13053
|
+
pgH - mg.t,
|
|
13054
|
+
fmtNum,
|
|
13055
|
+
totalPages
|
|
13056
|
+
);
|
|
13057
|
+
for (const [objNum, content] of built.objects) {
|
|
13058
|
+
emitObj(objNum, content);
|
|
13059
|
+
}
|
|
13060
|
+
totalObjs = outlineStart + built.totalObjects - 1;
|
|
13061
|
+
outlineCatalogStr = ` /Outlines ${built.rootObjNum} 0 R`;
|
|
13062
|
+
if (!viewerPrefs?.pageMode) {
|
|
13063
|
+
outlineCatalogStr += " /PageMode /UseOutlines";
|
|
13064
|
+
}
|
|
13065
|
+
}
|
|
13066
|
+
}
|
|
13067
|
+
if (viewerPrefs?.pageMode) {
|
|
13068
|
+
viewerPrefsStr = ` /PageMode /${viewerPrefs.pageMode}${viewerPrefsStr}`;
|
|
13069
|
+
}
|
|
12482
13070
|
let destsStr = "";
|
|
12483
13071
|
if (hasToc && headingDests.length > 0) {
|
|
12484
13072
|
const destEntries = headingDests.map((h) => {
|
|
@@ -12508,7 +13096,7 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
12508
13096
|
acroFormStr = ` ${buildAcroFormDict(fieldObjNums, formFontObjNum)}`;
|
|
12509
13097
|
}
|
|
12510
13098
|
if (tagged) {
|
|
12511
|
-
let catalogContent = `<< /Type /Catalog /Pages 2 0 R /MarkInfo << /Marked true >> /StructTreeRoot ${structTreeRootObjNum} 0 R /Metadata ${xmpObjNum} 0 R /OutputIntents [${outputIntentObjNum} 0 R]${destsStr}${acroFormStr}`;
|
|
13099
|
+
let catalogContent = `<< /Type /Catalog /Pages 2 0 R /MarkInfo << /Marked true >> /StructTreeRoot ${structTreeRootObjNum} 0 R /Metadata ${xmpObjNum} 0 R /OutputIntents [${outputIntentObjNum} 0 R]${destsStr}${acroFormStr}${outlineCatalogStr}${pageLabelsStr}${viewerPrefsStr}`;
|
|
12512
13100
|
if (afArrayStr) {
|
|
12513
13101
|
catalogContent += ` /AF [${afArrayStr}] ${embeddedFilesNamesDict}`;
|
|
12514
13102
|
}
|
|
@@ -12530,8 +13118,8 @@ endobj
|
|
|
12530
13118
|
}
|
|
12531
13119
|
}
|
|
12532
13120
|
}
|
|
12533
|
-
} else if (destsStr || acroFormStr) {
|
|
12534
|
-
const catalogContent = `<< /Type /Catalog /Pages 2 0 R${destsStr}${acroFormStr} >>`;
|
|
13121
|
+
} else if (destsStr || acroFormStr || outlineCatalogStr || pageLabelsStr || viewerPrefsStr) {
|
|
13122
|
+
const catalogContent = `<< /Type /Catalog /Pages 2 0 R${destsStr}${acroFormStr}${outlineCatalogStr}${pageLabelsStr}${viewerPrefsStr} >>`;
|
|
12535
13123
|
const oldCatalog = "1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n\n";
|
|
12536
13124
|
const newCatalog = `1 0 obj
|
|
12537
13125
|
${catalogContent}
|
|
@@ -12557,6 +13145,207 @@ endobj
|
|
|
12557
13145
|
function buildDocumentPDFBytes(params, layoutOptions) {
|
|
12558
13146
|
return toBytes(buildDocumentPDF(params, layoutOptions));
|
|
12559
13147
|
}
|
|
13148
|
+
function mapOutlineItem(item) {
|
|
13149
|
+
return {
|
|
13150
|
+
title: item.title,
|
|
13151
|
+
pageIndex: item.pageIndex,
|
|
13152
|
+
y: item.y,
|
|
13153
|
+
bold: item.bold,
|
|
13154
|
+
italic: item.italic,
|
|
13155
|
+
open: item.open,
|
|
13156
|
+
color: item.color !== void 0 ? parseColor(item.color) : void 0,
|
|
13157
|
+
children: item.children ? item.children.map(mapOutlineItem) : void 0
|
|
13158
|
+
};
|
|
13159
|
+
}
|
|
13160
|
+
function autoOutlineFromHeadings(headings) {
|
|
13161
|
+
const root = [];
|
|
13162
|
+
const stack = [];
|
|
13163
|
+
for (const h of headings) {
|
|
13164
|
+
const node = {
|
|
13165
|
+
title: h.text,
|
|
13166
|
+
pageIndex: h.pageIndex,
|
|
13167
|
+
y: h.y,
|
|
13168
|
+
children: []
|
|
13169
|
+
};
|
|
13170
|
+
while (stack.length > 0 && stack[stack.length - 1].level >= h.level) {
|
|
13171
|
+
stack.pop();
|
|
13172
|
+
}
|
|
13173
|
+
if (stack.length === 0) {
|
|
13174
|
+
root.push(node);
|
|
13175
|
+
} else {
|
|
13176
|
+
stack[stack.length - 1].children.push(node);
|
|
13177
|
+
}
|
|
13178
|
+
stack.push({ level: h.level, children: node.children });
|
|
13179
|
+
}
|
|
13180
|
+
return root;
|
|
13181
|
+
}
|
|
13182
|
+
|
|
13183
|
+
// src/core/pdf-layout-inspect.ts
|
|
13184
|
+
var TITLE_BAND_H = 22 + 12;
|
|
13185
|
+
function inspectDocumentLayout(params, layoutOptions) {
|
|
13186
|
+
if (!params || typeof params !== "object" || !Array.isArray(params.blocks)) {
|
|
13187
|
+
throw new Error("inspectDocumentLayout: params.blocks must be an array");
|
|
13188
|
+
}
|
|
13189
|
+
const layout = layoutOptions ?? params.layout;
|
|
13190
|
+
const pgW = layout?.pageWidth ?? PG_W;
|
|
13191
|
+
const pgH = layout?.pageHeight ?? PG_H;
|
|
13192
|
+
const mg = layout?.margins ?? { ...DEFAULT_MARGINS };
|
|
13193
|
+
const cw = pgW - mg.l - mg.r;
|
|
13194
|
+
const fontEntries = params.fontEntries ? [...params.fontEntries] : [];
|
|
13195
|
+
const tagged = resolvePdfAConfig(layout?.tagged).enabled;
|
|
13196
|
+
const enc = createEncodingContext(fontEntries, tagged, layout?.normalize ?? false);
|
|
13197
|
+
const headerH = layout?.headerTemplate ? HEADER_H : 0;
|
|
13198
|
+
const availableH = pgH - mg.t - mg.b - FT_H - headerH;
|
|
13199
|
+
const pages = [[]];
|
|
13200
|
+
let remainH = availableH;
|
|
13201
|
+
let curY = pgH - mg.t - headerH;
|
|
13202
|
+
if (params.title) {
|
|
13203
|
+
remainH -= TITLE_BAND_H;
|
|
13204
|
+
curY -= TITLE_BAND_H;
|
|
13205
|
+
}
|
|
13206
|
+
const newPage = () => {
|
|
13207
|
+
pages.push([]);
|
|
13208
|
+
remainH = availableH;
|
|
13209
|
+
curY = pgH - mg.t - headerH;
|
|
13210
|
+
};
|
|
13211
|
+
for (const block of params.blocks) {
|
|
13212
|
+
if (block.type === "pageBreak") {
|
|
13213
|
+
newPage();
|
|
13214
|
+
continue;
|
|
13215
|
+
}
|
|
13216
|
+
if (block.type === "table") {
|
|
13217
|
+
const plan = planTable(block, enc, mg.l, cw);
|
|
13218
|
+
const repeatHeader = block.repeatHeader !== false;
|
|
13219
|
+
const totalRows = block.rows.length;
|
|
13220
|
+
if (totalRows === 0) {
|
|
13221
|
+
const totalH = plan.captionHeight + plan.headerHeight + plan.trailerSpacing;
|
|
13222
|
+
if (totalH > remainH && pages[pages.length - 1].length > 0) newPage();
|
|
13223
|
+
pages[pages.length - 1].push({ type: "table", page: pages.length - 1, x: mg.l, top: curY, width: cw, height: totalH });
|
|
13224
|
+
remainH -= totalH;
|
|
13225
|
+
curY -= totalH;
|
|
13226
|
+
continue;
|
|
13227
|
+
}
|
|
13228
|
+
let rowIdx = 0;
|
|
13229
|
+
let isFirstSlice = true;
|
|
13230
|
+
while (rowIdx < totalRows) {
|
|
13231
|
+
const drawCaption = isFirstSlice;
|
|
13232
|
+
const drawHeader = isFirstSlice || repeatHeader;
|
|
13233
|
+
const tCapH = drawCaption ? plan.captionHeight : 0;
|
|
13234
|
+
const tHdrH = drawHeader ? plan.headerHeight : 0;
|
|
13235
|
+
const availableForRows = remainH - tCapH - tHdrH - plan.trailerSpacing;
|
|
13236
|
+
let usedH = 0;
|
|
13237
|
+
let count = 0;
|
|
13238
|
+
while (rowIdx + count < totalRows && usedH + plan.rowHeights[rowIdx + count] <= availableForRows) {
|
|
13239
|
+
usedH += plan.rowHeights[rowIdx + count];
|
|
13240
|
+
count++;
|
|
13241
|
+
}
|
|
13242
|
+
if (count === 0 && pages[pages.length - 1].length > 0) {
|
|
13243
|
+
newPage();
|
|
13244
|
+
continue;
|
|
13245
|
+
}
|
|
13246
|
+
if (count === 0) count = 1;
|
|
13247
|
+
rowIdx += count;
|
|
13248
|
+
const isFinalSlice = rowIdx >= totalRows;
|
|
13249
|
+
const sliceH = tCapH + tHdrH + usedH + (isFinalSlice ? plan.trailerSpacing : 0);
|
|
13250
|
+
pages[pages.length - 1].push({ type: "table", page: pages.length - 1, x: mg.l, top: curY, width: cw, height: sliceH });
|
|
13251
|
+
remainH -= sliceH;
|
|
13252
|
+
curY -= sliceH;
|
|
13253
|
+
isFirstSlice = false;
|
|
13254
|
+
if (!isFinalSlice) newPage();
|
|
13255
|
+
}
|
|
13256
|
+
continue;
|
|
13257
|
+
}
|
|
13258
|
+
const blockH = estimateBlockHeight(block, enc, cw);
|
|
13259
|
+
if (blockH > remainH && pages[pages.length - 1].length > 0) newPage();
|
|
13260
|
+
pages[pages.length - 1].push({ type: block.type, page: pages.length - 1, x: mg.l, top: curY, width: cw, height: blockH });
|
|
13261
|
+
remainH -= blockH;
|
|
13262
|
+
curY -= blockH;
|
|
13263
|
+
}
|
|
13264
|
+
const inspectedPages = pages.map((blocks, index) => ({ index, blocks }));
|
|
13265
|
+
return {
|
|
13266
|
+
pageWidth: pgW,
|
|
13267
|
+
pageHeight: pgH,
|
|
13268
|
+
margins: { t: mg.t, r: mg.r, b: mg.b, l: mg.l },
|
|
13269
|
+
totalPages: Math.max(1, pages.length),
|
|
13270
|
+
pages: inspectedPages
|
|
13271
|
+
};
|
|
13272
|
+
}
|
|
13273
|
+
|
|
13274
|
+
// src/core/pdf-annot-markup.ts
|
|
13275
|
+
var SUBTYPE = {
|
|
13276
|
+
text: "Text",
|
|
13277
|
+
highlight: "Highlight",
|
|
13278
|
+
underline: "Underline",
|
|
13279
|
+
strikeout: "StrikeOut",
|
|
13280
|
+
squiggly: "Squiggly",
|
|
13281
|
+
square: "Square",
|
|
13282
|
+
circle: "Circle",
|
|
13283
|
+
line: "Line",
|
|
13284
|
+
freetext: "FreeText"
|
|
13285
|
+
};
|
|
13286
|
+
function rectStr(r) {
|
|
13287
|
+
return `[${fmtNum(r[0])} ${fmtNum(r[1])} ${fmtNum(r[2])} ${fmtNum(r[3])}]`;
|
|
13288
|
+
}
|
|
13289
|
+
function quadFromRect(r) {
|
|
13290
|
+
const [x1, y1, x2, y2] = r;
|
|
13291
|
+
return [x1, y2, x2, y2, x1, y1, x2, y1];
|
|
13292
|
+
}
|
|
13293
|
+
function commonEntries(a) {
|
|
13294
|
+
const parts = [];
|
|
13295
|
+
if (a.contents !== void 0) parts.push(`/Contents ${encodePdfTextString(a.contents)}`);
|
|
13296
|
+
if (a.title !== void 0) parts.push(`/T ${encodePdfTextString(a.title)}`);
|
|
13297
|
+
if (a.color !== void 0) parts.push(`/C [${parseColor(a.color)}]`);
|
|
13298
|
+
if (a.opacity !== void 0) parts.push(`/CA ${fmtNum(a.opacity)}`);
|
|
13299
|
+
if (a.modified !== void 0) parts.push(`/M ${encodePdfTextString(a.modified)}`);
|
|
13300
|
+
parts.push(`/F ${a.flags ?? 4}`);
|
|
13301
|
+
return parts.join(" ");
|
|
13302
|
+
}
|
|
13303
|
+
function buildAnnotation(annot, objNum) {
|
|
13304
|
+
return `${objNum} 0 obj
|
|
13305
|
+
${buildAnnotationBody(annot)}
|
|
13306
|
+
endobj`;
|
|
13307
|
+
}
|
|
13308
|
+
function buildAnnotationBody(annot) {
|
|
13309
|
+
const entries = [
|
|
13310
|
+
`/Type /Annot`,
|
|
13311
|
+
`/Subtype /${SUBTYPE[annot.type]}`,
|
|
13312
|
+
`/Rect ${rectStr(annot.rect)}`,
|
|
13313
|
+
commonEntries(annot)
|
|
13314
|
+
];
|
|
13315
|
+
switch (annot.type) {
|
|
13316
|
+
case "text": {
|
|
13317
|
+
if (annot.open !== void 0) entries.push(`/Open ${annot.open ? "true" : "false"}`);
|
|
13318
|
+
if (annot.icon !== void 0) entries.push(`/Name /${annot.icon}`);
|
|
13319
|
+
break;
|
|
13320
|
+
}
|
|
13321
|
+
case "highlight":
|
|
13322
|
+
case "underline":
|
|
13323
|
+
case "strikeout":
|
|
13324
|
+
case "squiggly": {
|
|
13325
|
+
const quad = annot.quadPoints && annot.quadPoints.length >= 8 ? annot.quadPoints : quadFromRect(annot.rect);
|
|
13326
|
+
entries.push(`/QuadPoints [${quad.map(fmtNum).join(" ")}]`);
|
|
13327
|
+
break;
|
|
13328
|
+
}
|
|
13329
|
+
case "square":
|
|
13330
|
+
case "circle": {
|
|
13331
|
+
if (annot.interiorColor !== void 0) entries.push(`/IC [${parseColor(annot.interiorColor)}]`);
|
|
13332
|
+
entries.push(`/BS << /W ${fmtNum(annot.borderWidth ?? 1)} >>`);
|
|
13333
|
+
break;
|
|
13334
|
+
}
|
|
13335
|
+
case "line": {
|
|
13336
|
+
entries.push(`/L [${fmtNum(annot.start[0])} ${fmtNum(annot.start[1])} ${fmtNum(annot.end[0])} ${fmtNum(annot.end[1])}]`);
|
|
13337
|
+
entries.push(`/BS << /W ${fmtNum(annot.borderWidth ?? 1)} >>`);
|
|
13338
|
+
break;
|
|
13339
|
+
}
|
|
13340
|
+
case "freetext": {
|
|
13341
|
+
const sz = annot.fontSize ?? 12;
|
|
13342
|
+
const col = annot.color !== void 0 ? parseColor(annot.color) : "0 0 0";
|
|
13343
|
+
entries.push(`/DA (/Helv ${fmtNum(sz)} Tf ${col} rg)`);
|
|
13344
|
+
break;
|
|
13345
|
+
}
|
|
13346
|
+
}
|
|
13347
|
+
return `<< ${entries.filter(Boolean).join(" ")} >>`;
|
|
13348
|
+
}
|
|
12560
13349
|
|
|
12561
13350
|
// src/core/pdf-signature.ts
|
|
12562
13351
|
init_sha();
|
|
@@ -12566,6 +13355,17 @@ init_asn1();
|
|
|
12566
13355
|
init_sha();
|
|
12567
13356
|
init_rsa();
|
|
12568
13357
|
init_ecdsa();
|
|
13358
|
+
|
|
13359
|
+
// src/crypto/crypto-provider.ts
|
|
13360
|
+
var _cryptoProvider = null;
|
|
13361
|
+
function setCryptoProvider(provider) {
|
|
13362
|
+
_cryptoProvider = provider;
|
|
13363
|
+
}
|
|
13364
|
+
function getCryptoProvider() {
|
|
13365
|
+
return _cryptoProvider;
|
|
13366
|
+
}
|
|
13367
|
+
|
|
13368
|
+
// src/crypto/cms.ts
|
|
12569
13369
|
var OID_SIGNED_DATA = new Uint8Array([42, 134, 72, 134, 247, 13, 1, 7, 2]);
|
|
12570
13370
|
var OID_DATA = new Uint8Array([42, 134, 72, 134, 247, 13, 1, 7, 1]);
|
|
12571
13371
|
var OID_SHA256 = new Uint8Array([96, 134, 72, 1, 101, 3, 4, 2, 1]);
|
|
@@ -12625,18 +13425,26 @@ function buildSignerInfo(options) {
|
|
|
12625
13425
|
const signedAttrsContent = concatUint8Arrays(attrContentType, attrMessageDigest, attrSigningTime);
|
|
12626
13426
|
const signedAttrsImplicit = derWrap(160, signedAttrsContent);
|
|
12627
13427
|
const signedAttrsForSig = derSet(attrContentType, attrMessageDigest, attrSigningTime);
|
|
12628
|
-
const
|
|
13428
|
+
const provider = options.provider ?? getCryptoProvider();
|
|
12629
13429
|
let sigAlgId;
|
|
12630
13430
|
let signatureValue;
|
|
12631
13431
|
if (algorithm === "rsa-sha256") {
|
|
12632
|
-
if (!options.rsaKey) throw new Error("RSA private key required for rsa-sha256");
|
|
12633
13432
|
sigAlgId = derSequence(derOid(OID_SHA256_RSA), derNull());
|
|
12634
|
-
|
|
13433
|
+
if (provider) {
|
|
13434
|
+
signatureValue = provider.sign(signedAttrsForSig, algorithm);
|
|
13435
|
+
} else {
|
|
13436
|
+
if (!options.rsaKey) throw new Error("RSA private key (or a crypto provider) required for rsa-sha256");
|
|
13437
|
+
signatureValue = rsaSignHash(sha256(signedAttrsForSig), options.rsaKey);
|
|
13438
|
+
}
|
|
12635
13439
|
} else if (algorithm === "ecdsa-sha256") {
|
|
12636
|
-
if (!options.ecKey) throw new Error("ECDSA private key required for ecdsa-sha256");
|
|
12637
13440
|
sigAlgId = derSequence(derOid(OID_ECDSA_SHA256));
|
|
12638
|
-
|
|
12639
|
-
|
|
13441
|
+
if (provider) {
|
|
13442
|
+
signatureValue = provider.sign(signedAttrsForSig, algorithm);
|
|
13443
|
+
} else {
|
|
13444
|
+
if (!options.ecKey) throw new Error("ECDSA private key (or a crypto provider) required for ecdsa-sha256");
|
|
13445
|
+
const { r, s } = ecdsaSignHash(sha256(signedAttrsForSig), options.ecKey);
|
|
13446
|
+
signatureValue = encodeDerSignature(r, s);
|
|
13447
|
+
}
|
|
12640
13448
|
} else {
|
|
12641
13449
|
throw new Error(`Unsupported algorithm: ${algorithm}`);
|
|
12642
13450
|
}
|
|
@@ -12715,7 +13523,8 @@ function signPdfBytes(pdfBytes, options) {
|
|
|
12715
13523
|
rsaKey: options.rsaKey,
|
|
12716
13524
|
ecKey: options.ecKey,
|
|
12717
13525
|
algorithm,
|
|
12718
|
-
signingTime: options.signingTime
|
|
13526
|
+
signingTime: options.signingTime,
|
|
13527
|
+
provider: options.provider
|
|
12719
13528
|
};
|
|
12720
13529
|
const cms = buildCmsSignedData(cmsOptions);
|
|
12721
13530
|
if (cms.length * 2 > hexLen) {
|
|
@@ -13885,6 +14694,28 @@ function openPdf(bytes) {
|
|
|
13885
14694
|
if (!entry || entry.type === 0) return null;
|
|
13886
14695
|
return resolveRef({ num, gen: entry.gen });
|
|
13887
14696
|
}
|
|
14697
|
+
let _pageRefs;
|
|
14698
|
+
function collectPageRefs() {
|
|
14699
|
+
if (_pageRefs) return _pageRefs;
|
|
14700
|
+
const catalog = getCatalog();
|
|
14701
|
+
const refs = [];
|
|
14702
|
+
const walk = (nodeVal, depth) => {
|
|
14703
|
+
if (depth > 100) return;
|
|
14704
|
+
const node = resolveValue2(nodeVal);
|
|
14705
|
+
if (!isDict(node)) return;
|
|
14706
|
+
if (dictGetName(node, "Type") === "Page") {
|
|
14707
|
+
if (isRef(nodeVal)) refs.push(nodeVal);
|
|
14708
|
+
return;
|
|
14709
|
+
}
|
|
14710
|
+
const kids = node.get("Kids");
|
|
14711
|
+
if (isArray(kids)) {
|
|
14712
|
+
for (const k of kids) walk(k, depth + 1);
|
|
14713
|
+
}
|
|
14714
|
+
};
|
|
14715
|
+
walk(catalog.get("Pages") ?? null, 0);
|
|
14716
|
+
_pageRefs = refs;
|
|
14717
|
+
return refs;
|
|
14718
|
+
}
|
|
13888
14719
|
function decodeStreamData(stream) {
|
|
13889
14720
|
let data = stream.data;
|
|
13890
14721
|
const filterName = dictGetName(stream.dict, "Filter");
|
|
@@ -13936,10 +14767,107 @@ function openPdf(bytes) {
|
|
|
13936
14767
|
const info = resolveValue2(infoRef);
|
|
13937
14768
|
return isDict(info) ? info : null;
|
|
13938
14769
|
},
|
|
14770
|
+
getPageLabels() {
|
|
14771
|
+
const catalog = getCatalog();
|
|
14772
|
+
const plVal = resolveValue2(catalog.get("PageLabels") ?? null);
|
|
14773
|
+
if (!isDict(plVal)) return null;
|
|
14774
|
+
const entries = /* @__PURE__ */ new Map();
|
|
14775
|
+
collectNumberTree(plVal, resolveValue2, entries);
|
|
14776
|
+
if (entries.size === 0) return null;
|
|
14777
|
+
const ranges = [];
|
|
14778
|
+
for (const startPage of [...entries.keys()].sort((a, b) => a - b)) {
|
|
14779
|
+
const dict = resolveValue2(entries.get(startPage) ?? null);
|
|
14780
|
+
if (!isDict(dict)) continue;
|
|
14781
|
+
const range = { startPage };
|
|
14782
|
+
const sOp = dictGetName(dict, "S");
|
|
14783
|
+
range.style = sOp === void 0 ? "none" : STYLE_FROM_OP[sOp] ?? "none";
|
|
14784
|
+
const prefix = dict.get("P");
|
|
14785
|
+
if (typeof prefix === "string") range.prefix = prefix;
|
|
14786
|
+
const start = dictGetNum(dict, "St");
|
|
14787
|
+
if (start !== void 0) range.start = start;
|
|
14788
|
+
ranges.push(range);
|
|
14789
|
+
}
|
|
14790
|
+
return ranges.length > 0 ? ranges : null;
|
|
14791
|
+
},
|
|
14792
|
+
getAnnotations(pageIndex) {
|
|
14793
|
+
const pages = collectPages();
|
|
14794
|
+
if (pageIndex < 0 || pageIndex >= pages.length) return [];
|
|
14795
|
+
const annotsVal = resolveValue2(pages[pageIndex].get("Annots") ?? null);
|
|
14796
|
+
if (!isArray(annotsVal)) return [];
|
|
14797
|
+
const out = [];
|
|
14798
|
+
for (const a of annotsVal) {
|
|
14799
|
+
const d = resolveValue2(a);
|
|
14800
|
+
if (!isDict(d)) continue;
|
|
14801
|
+
const subtype = dictGetName(d, "Subtype") ?? "";
|
|
14802
|
+
const rectVal = resolveValue2(d.get("Rect") ?? null);
|
|
14803
|
+
let rect = null;
|
|
14804
|
+
if (isArray(rectVal) && rectVal.length === 4 && rectVal.every((n2) => typeof n2 === "number")) {
|
|
14805
|
+
rect = [rectVal[0], rectVal[1], rectVal[2], rectVal[3]];
|
|
14806
|
+
}
|
|
14807
|
+
const parsed = { subtype, rect };
|
|
14808
|
+
const contents = d.get("Contents");
|
|
14809
|
+
if (typeof contents === "string") parsed.contents = decodePdfTextString(contents);
|
|
14810
|
+
const title = d.get("T");
|
|
14811
|
+
if (typeof title === "string") parsed.title = decodePdfTextString(title);
|
|
14812
|
+
const c = resolveValue2(d.get("C") ?? null);
|
|
14813
|
+
if (isArray(c)) {
|
|
14814
|
+
const nums = c.filter((x) => typeof x === "number");
|
|
14815
|
+
if (nums.length > 0) parsed.color = nums;
|
|
14816
|
+
}
|
|
14817
|
+
const qp = resolveValue2(d.get("QuadPoints") ?? null);
|
|
14818
|
+
if (isArray(qp)) {
|
|
14819
|
+
parsed.quadPoints = qp.filter((x) => typeof x === "number");
|
|
14820
|
+
}
|
|
14821
|
+
const action = resolveValue2(d.get("A") ?? null);
|
|
14822
|
+
if (isDict(action)) {
|
|
14823
|
+
const uri = action.get("URI");
|
|
14824
|
+
if (typeof uri === "string") parsed.url = uri;
|
|
14825
|
+
}
|
|
14826
|
+
out.push(parsed);
|
|
14827
|
+
}
|
|
14828
|
+
return out;
|
|
14829
|
+
},
|
|
14830
|
+
getPageRef(pageIndex) {
|
|
14831
|
+
const refs = collectPageRefs();
|
|
14832
|
+
return pageIndex >= 0 && pageIndex < refs.length ? refs[pageIndex] : null;
|
|
14833
|
+
},
|
|
13939
14834
|
decodeStream: decodeStreamData,
|
|
13940
14835
|
getObject
|
|
13941
14836
|
};
|
|
13942
14837
|
}
|
|
14838
|
+
function decodePdfTextString(raw) {
|
|
14839
|
+
if (raw.length >= 2 && raw.charCodeAt(0) === 254 && raw.charCodeAt(1) === 255) {
|
|
14840
|
+
let out = "";
|
|
14841
|
+
for (let i = 2; i + 1 < raw.length; i += 2) {
|
|
14842
|
+
out += String.fromCharCode(raw.charCodeAt(i) << 8 | raw.charCodeAt(i + 1));
|
|
14843
|
+
}
|
|
14844
|
+
return out;
|
|
14845
|
+
}
|
|
14846
|
+
return raw;
|
|
14847
|
+
}
|
|
14848
|
+
var STYLE_FROM_OP = {
|
|
14849
|
+
D: "decimal",
|
|
14850
|
+
r: "roman",
|
|
14851
|
+
R: "Roman",
|
|
14852
|
+
a: "alpha",
|
|
14853
|
+
A: "Alpha"
|
|
14854
|
+
};
|
|
14855
|
+
function collectNumberTree(node, resolve, out) {
|
|
14856
|
+
const nums = resolve(node.get("Nums") ?? null);
|
|
14857
|
+
if (isArray(nums)) {
|
|
14858
|
+
for (let i = 0; i + 1 < nums.length; i += 2) {
|
|
14859
|
+
const key = resolve(nums[i]);
|
|
14860
|
+
if (typeof key === "number") out.set(key, nums[i + 1]);
|
|
14861
|
+
}
|
|
14862
|
+
}
|
|
14863
|
+
const kids = resolve(node.get("Kids") ?? null);
|
|
14864
|
+
if (isArray(kids)) {
|
|
14865
|
+
for (const kid of kids) {
|
|
14866
|
+
const kd = resolve(kid);
|
|
14867
|
+
if (isDict(kd)) collectNumberTree(kd, resolve, out);
|
|
14868
|
+
}
|
|
14869
|
+
}
|
|
14870
|
+
}
|
|
13943
14871
|
function flattenPageTree(node, resolve, pages) {
|
|
13944
14872
|
const type = dictGetName(node, "Type");
|
|
13945
14873
|
if (type === "Page") {
|
|
@@ -14074,6 +15002,21 @@ function createModifier(reader) {
|
|
|
14074
15002
|
if (modified.has(num)) return modified.get(num) ?? null;
|
|
14075
15003
|
return reader.getObject(num);
|
|
14076
15004
|
}
|
|
15005
|
+
function addAnnotation(pageIndex, annotationBody) {
|
|
15006
|
+
const pageRef = reader.getPageRef(pageIndex);
|
|
15007
|
+
if (!pageRef) throw new Error(`addAnnotation: no page at index ${pageIndex}`);
|
|
15008
|
+
const objNum = addRawObject(annotationBody);
|
|
15009
|
+
const page = getObject(pageRef.num);
|
|
15010
|
+
if (!isDict(page)) throw new Error(`addAnnotation: page ${pageIndex} is not a dictionary`);
|
|
15011
|
+
const clone = new Map(page);
|
|
15012
|
+
const existing = clone.get("Annots");
|
|
15013
|
+
const resolved = isRef(existing) ? reader.resolveValue(existing) : existing;
|
|
15014
|
+
const annots = isArray(resolved) ? [...resolved] : [];
|
|
15015
|
+
annots.push({ type: "ref", num: objNum, gen: 0 });
|
|
15016
|
+
clone.set("Annots", annots);
|
|
15017
|
+
setObject(pageRef.num, clone);
|
|
15018
|
+
return objNum;
|
|
15019
|
+
}
|
|
14077
15020
|
function save() {
|
|
14078
15021
|
if (modified.size === 0) {
|
|
14079
15022
|
return reader.bytes;
|
|
@@ -14119,6 +15062,7 @@ ${xrefOffset}
|
|
|
14119
15062
|
setObject,
|
|
14120
15063
|
addObject,
|
|
14121
15064
|
addRawObject,
|
|
15065
|
+
addAnnotation,
|
|
14122
15066
|
getObject,
|
|
14123
15067
|
save,
|
|
14124
15068
|
get nextObjNum() {
|
|
@@ -14532,6 +15476,68 @@ async function streamByteLength(stream) {
|
|
|
14532
15476
|
}
|
|
14533
15477
|
return total;
|
|
14534
15478
|
}
|
|
15479
|
+
async function streamToFile(stream, filePath, opts) {
|
|
15480
|
+
let fs;
|
|
15481
|
+
try {
|
|
15482
|
+
fs = await import('fs');
|
|
15483
|
+
} catch {
|
|
15484
|
+
throw new Error("streamToFile requires a Node.js environment (node:fs is unavailable)");
|
|
15485
|
+
}
|
|
15486
|
+
const signal = opts?.signal;
|
|
15487
|
+
if (signal?.aborted) throw new Error("streamToFile aborted before start");
|
|
15488
|
+
const ws = fs.createWriteStream(filePath);
|
|
15489
|
+
let bytesWritten = 0;
|
|
15490
|
+
const onAbort = () => {
|
|
15491
|
+
ws.destroy(new Error("streamToFile aborted"));
|
|
15492
|
+
};
|
|
15493
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
15494
|
+
try {
|
|
15495
|
+
await new Promise((resolve, reject) => {
|
|
15496
|
+
ws.on("error", reject);
|
|
15497
|
+
ws.on("open", () => resolve());
|
|
15498
|
+
});
|
|
15499
|
+
for await (const chunk of stream) {
|
|
15500
|
+
if (signal?.aborted) throw new Error("streamToFile aborted");
|
|
15501
|
+
bytesWritten += chunk.length;
|
|
15502
|
+
const ok = ws.write(chunk);
|
|
15503
|
+
if (!ok) {
|
|
15504
|
+
await new Promise((resolve, reject) => {
|
|
15505
|
+
const onErr = (e) => {
|
|
15506
|
+
ws.off("drain", onDrain);
|
|
15507
|
+
reject(e);
|
|
15508
|
+
};
|
|
15509
|
+
const onDrain = () => {
|
|
15510
|
+
ws.off("error", onErr);
|
|
15511
|
+
resolve();
|
|
15512
|
+
};
|
|
15513
|
+
ws.once("drain", onDrain);
|
|
15514
|
+
ws.once("error", onErr);
|
|
15515
|
+
});
|
|
15516
|
+
}
|
|
15517
|
+
}
|
|
15518
|
+
if (signal?.aborted) throw new Error("streamToFile aborted");
|
|
15519
|
+
await new Promise((resolve, reject) => {
|
|
15520
|
+
ws.end((err) => err ? reject(err) : resolve());
|
|
15521
|
+
});
|
|
15522
|
+
} catch (err) {
|
|
15523
|
+
await new Promise((resolve) => {
|
|
15524
|
+
if (ws.closed) {
|
|
15525
|
+
resolve();
|
|
15526
|
+
return;
|
|
15527
|
+
}
|
|
15528
|
+
ws.once("close", () => resolve());
|
|
15529
|
+
ws.destroy();
|
|
15530
|
+
});
|
|
15531
|
+
try {
|
|
15532
|
+
fs.rmSync(filePath, { force: true });
|
|
15533
|
+
} catch {
|
|
15534
|
+
}
|
|
15535
|
+
throw err;
|
|
15536
|
+
} finally {
|
|
15537
|
+
signal?.removeEventListener("abort", onAbort);
|
|
15538
|
+
}
|
|
15539
|
+
return { bytesWritten, path: filePath };
|
|
15540
|
+
}
|
|
14535
15541
|
var DEFAULT_CHUNK_SIZE = 65536;
|
|
14536
15542
|
var MIN_CHUNK_SIZE = 1024;
|
|
14537
15543
|
var MAX_CHUNK_SIZE = 16777216;
|
|
@@ -14747,6 +15753,123 @@ async function initCrypto() {
|
|
|
14747
15753
|
initEcdsaAsn12(asn1);
|
|
14748
15754
|
}
|
|
14749
15755
|
|
|
15756
|
+
// src/fonts/font-validator.ts
|
|
15757
|
+
var SFNT_MAGIC = /* @__PURE__ */ new Set([
|
|
15758
|
+
65536,
|
|
15759
|
+
// TrueType outlines
|
|
15760
|
+
1330926671,
|
|
15761
|
+
// 'OTTO' — CFF/OpenType outlines
|
|
15762
|
+
1953658213,
|
|
15763
|
+
// 'true' — legacy Apple TrueType
|
|
15764
|
+
1953784678
|
|
15765
|
+
// 'ttcf' — TrueType Collection
|
|
15766
|
+
]);
|
|
15767
|
+
function decodeBase64Prefix(b64, maxBytes) {
|
|
15768
|
+
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(b64)) return null;
|
|
15769
|
+
if (b64.length % 4 !== 0) return null;
|
|
15770
|
+
const g = globalThis;
|
|
15771
|
+
try {
|
|
15772
|
+
const atobFn = g["atob"];
|
|
15773
|
+
if (typeof atobFn === "function") {
|
|
15774
|
+
const need = Math.ceil(maxBytes / 3 * 4 / 4) * 4;
|
|
15775
|
+
const slice = b64.slice(0, Math.min(b64.length, need));
|
|
15776
|
+
const bin = atobFn(slice);
|
|
15777
|
+
const out = new Uint8Array(Math.min(bin.length, maxBytes));
|
|
15778
|
+
for (let i = 0; i < out.length; i++) out[i] = bin.charCodeAt(i) & 255;
|
|
15779
|
+
return out;
|
|
15780
|
+
}
|
|
15781
|
+
const bufCtor = g["Buffer"];
|
|
15782
|
+
if (bufCtor?.from) {
|
|
15783
|
+
return bufCtor.from(b64, "base64").subarray(0, maxBytes);
|
|
15784
|
+
}
|
|
15785
|
+
} catch {
|
|
15786
|
+
return null;
|
|
15787
|
+
}
|
|
15788
|
+
return null;
|
|
15789
|
+
}
|
|
15790
|
+
function validateFontData(data) {
|
|
15791
|
+
const errors = [];
|
|
15792
|
+
const warnings = [];
|
|
15793
|
+
if (data === null || typeof data !== "object") {
|
|
15794
|
+
return { valid: false, errors: ["font data must be a non-null object"], warnings };
|
|
15795
|
+
}
|
|
15796
|
+
const f = data;
|
|
15797
|
+
const m = f.metrics;
|
|
15798
|
+
if (!m || typeof m !== "object") {
|
|
15799
|
+
errors.push("missing or invalid `metrics` object");
|
|
15800
|
+
} else {
|
|
15801
|
+
const finiteFields = ["unitsPerEm", "numGlyphs", "ascent", "descent", "capHeight", "stemV"];
|
|
15802
|
+
const mRec = m;
|
|
15803
|
+
for (const k of finiteFields) {
|
|
15804
|
+
const v = mRec[k];
|
|
15805
|
+
if (typeof v !== "number" || !Number.isFinite(v)) {
|
|
15806
|
+
errors.push(`metrics.${String(k)} must be a finite number`);
|
|
15807
|
+
}
|
|
15808
|
+
}
|
|
15809
|
+
if (typeof m.unitsPerEm === "number" && m.unitsPerEm <= 0) {
|
|
15810
|
+
errors.push("metrics.unitsPerEm must be positive");
|
|
15811
|
+
}
|
|
15812
|
+
if (!Array.isArray(m.bbox) || m.bbox.length !== 4 || !m.bbox.every((n2) => typeof n2 === "number" && Number.isFinite(n2))) {
|
|
15813
|
+
errors.push("metrics.bbox must be a 4-number array [xMin yMin xMax yMax]");
|
|
15814
|
+
}
|
|
15815
|
+
}
|
|
15816
|
+
if (typeof f.fontName !== "string" || f.fontName.length === 0) {
|
|
15817
|
+
errors.push("`fontName` must be a non-empty string");
|
|
15818
|
+
}
|
|
15819
|
+
const cmap = f.cmap;
|
|
15820
|
+
let cmapEntries = 0;
|
|
15821
|
+
if (!cmap || typeof cmap !== "object") {
|
|
15822
|
+
errors.push("missing or invalid `cmap` (codepoint \u2192 glyph id map)");
|
|
15823
|
+
} else {
|
|
15824
|
+
cmapEntries = Object.keys(cmap).length;
|
|
15825
|
+
if (cmapEntries === 0) {
|
|
15826
|
+
errors.push("`cmap` is empty \u2014 the font maps no characters");
|
|
15827
|
+
}
|
|
15828
|
+
}
|
|
15829
|
+
const widths = f.widths;
|
|
15830
|
+
if (!widths || typeof widths !== "object") {
|
|
15831
|
+
errors.push("missing or invalid `widths` (glyph id \u2192 advance map)");
|
|
15832
|
+
}
|
|
15833
|
+
if (cmap && typeof cmap === "object" && widths && typeof widths === "object") {
|
|
15834
|
+
const numGlyphs = m && typeof m.numGlyphs === "number" ? m.numGlyphs : Infinity;
|
|
15835
|
+
let missingWidth = 0;
|
|
15836
|
+
let outOfRange = 0;
|
|
15837
|
+
for (const gid of Object.values(cmap)) {
|
|
15838
|
+
if (typeof gid !== "number" || !Number.isInteger(gid) || gid < 0) {
|
|
15839
|
+
outOfRange++;
|
|
15840
|
+
continue;
|
|
15841
|
+
}
|
|
15842
|
+
if (Number.isFinite(numGlyphs) && gid >= numGlyphs) outOfRange++;
|
|
15843
|
+
if (widths[gid] === void 0) missingWidth++;
|
|
15844
|
+
}
|
|
15845
|
+
if (outOfRange > 0) {
|
|
15846
|
+
errors.push(`${outOfRange} cmap entr${outOfRange === 1 ? "y maps" : "ies map"} to an out-of-range glyph id`);
|
|
15847
|
+
}
|
|
15848
|
+
if (missingWidth > 0) {
|
|
15849
|
+
warnings.push(`${missingWidth} cmap glyph id(s) have no explicit width (defaultWidth will be used)`);
|
|
15850
|
+
}
|
|
15851
|
+
}
|
|
15852
|
+
if (typeof f.pdfWidthArray !== "string" || f.pdfWidthArray.length === 0) {
|
|
15853
|
+
errors.push("`pdfWidthArray` must be a non-empty PDF /W array string");
|
|
15854
|
+
} else if (!/^\s*\d/.test(f.pdfWidthArray)) {
|
|
15855
|
+
warnings.push("`pdfWidthArray` does not begin with a glyph index \u2014 verify the /W array format");
|
|
15856
|
+
}
|
|
15857
|
+
if (typeof f.ttfBase64 !== "string" || f.ttfBase64.length === 0) {
|
|
15858
|
+
errors.push("`ttfBase64` must be a non-empty base64 string");
|
|
15859
|
+
} else {
|
|
15860
|
+
const head = decodeBase64Prefix(f.ttfBase64, 4);
|
|
15861
|
+
if (!head || head.length < 4) {
|
|
15862
|
+
errors.push("`ttfBase64` is not valid base64");
|
|
15863
|
+
} else {
|
|
15864
|
+
const magic = (head[0] << 24 | head[1] << 16 | head[2] << 8 | head[3]) >>> 0;
|
|
15865
|
+
if (!SFNT_MAGIC.has(magic)) {
|
|
15866
|
+
errors.push(`\`ttfBase64\` is not an SFNT font (unexpected magic 0x${magic.toString(16).padStart(8, "0")})`);
|
|
15867
|
+
}
|
|
15868
|
+
}
|
|
15869
|
+
}
|
|
15870
|
+
return { valid: errors.length === 0, errors, warnings };
|
|
15871
|
+
}
|
|
15872
|
+
|
|
14750
15873
|
// src/fonts/colr-parser.ts
|
|
14751
15874
|
var IDENTITY = [1, 0, 0, 1, 0, 0];
|
|
14752
15875
|
function compose(outer, inner) {
|
|
@@ -14863,6 +15986,22 @@ function resolveFill(ctx, offset, m) {
|
|
|
14863
15986
|
const s = avgScale(m);
|
|
14864
15987
|
return { kind: "radial", c0: apply(m, x0, y0), r0: r0 * s, c1: apply(m, x1, y1), r1: r1 * s, stops, extend };
|
|
14865
15988
|
}
|
|
15989
|
+
case 8: {
|
|
15990
|
+
const colorLineOffset = getUint24(view, offset + 1);
|
|
15991
|
+
const cx = view.getInt16(offset + 4), cy = view.getInt16(offset + 6);
|
|
15992
|
+
const startAngle = f2dot14(view, offset + 8) * 180;
|
|
15993
|
+
const endAngle = f2dot14(view, offset + 10) * 180;
|
|
15994
|
+
const { stops, extend } = readColorLine(ctx, offset + colorLineOffset);
|
|
15995
|
+
const rot = Math.atan2(m[1], m[0]) * 180 / Math.PI;
|
|
15996
|
+
return {
|
|
15997
|
+
kind: "sweep",
|
|
15998
|
+
center: apply(m, cx, cy),
|
|
15999
|
+
startAngle: startAngle + rot,
|
|
16000
|
+
endAngle: endAngle + rot,
|
|
16001
|
+
stops,
|
|
16002
|
+
extend
|
|
16003
|
+
};
|
|
16004
|
+
}
|
|
14866
16005
|
case 12: {
|
|
14867
16006
|
const subOffset = getUint24(view, offset + 1);
|
|
14868
16007
|
const transformOffset = getUint24(view, offset + 4);
|
|
@@ -14892,7 +16031,7 @@ function readAffine(view, pos) {
|
|
|
14892
16031
|
const dy = fixed(view, pos + 20);
|
|
14893
16032
|
return [xx, yx, xy, yy, dx, dy];
|
|
14894
16033
|
}
|
|
14895
|
-
function collectLayers(ctx, offset, m, out, depth) {
|
|
16034
|
+
function collectLayers(ctx, offset, m, out, depth, blendMode) {
|
|
14896
16035
|
if (depth > 16) throw new UnsupportedPaint("paint recursion too deep");
|
|
14897
16036
|
const { view } = ctx;
|
|
14898
16037
|
const format = view.getUint8(offset);
|
|
@@ -14904,7 +16043,7 @@ function collectLayers(ctx, offset, m, out, depth) {
|
|
|
14904
16043
|
for (let i = 0; i < numLayers; i++) {
|
|
14905
16044
|
const idx = firstLayerIndex + i;
|
|
14906
16045
|
const paintOffset = view.getUint32(ctx.layerListBase + 4 + idx * 4);
|
|
14907
|
-
collectLayers(ctx, ctx.layerListBase + paintOffset, m, out, depth + 1);
|
|
16046
|
+
collectLayers(ctx, ctx.layerListBase + paintOffset, m, out, depth + 1, blendMode);
|
|
14908
16047
|
}
|
|
14909
16048
|
return;
|
|
14910
16049
|
}
|
|
@@ -14912,39 +16051,91 @@ function collectLayers(ctx, offset, m, out, depth) {
|
|
|
14912
16051
|
const subOffset = getUint24(view, offset + 1);
|
|
14913
16052
|
const glyphId = view.getUint16(offset + 4);
|
|
14914
16053
|
const paint = resolveFill(ctx, offset + subOffset, IDENTITY);
|
|
14915
|
-
|
|
16054
|
+
const layer = m === IDENTITY ? { glyphId, paint } : { glyphId, paint, transform: m };
|
|
16055
|
+
out.push(blendMode ? { ...layer, blendMode } : layer);
|
|
14916
16056
|
return;
|
|
14917
16057
|
}
|
|
14918
16058
|
case 11: {
|
|
14919
16059
|
const glyphId = view.getUint16(offset + 1);
|
|
14920
16060
|
const paintOffset = baseGlyphPaintOffset(ctx, glyphId);
|
|
14921
16061
|
if (paintOffset === null) throw new UnsupportedPaint("PaintColrGlyph missing base");
|
|
14922
|
-
collectLayers(ctx, paintOffset, m, out, depth + 1);
|
|
16062
|
+
collectLayers(ctx, paintOffset, m, out, depth + 1, blendMode);
|
|
14923
16063
|
return;
|
|
14924
16064
|
}
|
|
14925
16065
|
case 12: {
|
|
14926
16066
|
const subOffset = getUint24(view, offset + 1);
|
|
14927
16067
|
const transformOffset = getUint24(view, offset + 4);
|
|
14928
16068
|
const t = readAffine(view, offset + transformOffset);
|
|
14929
|
-
collectLayers(ctx, offset + subOffset, compose(m, t), out, depth + 1);
|
|
16069
|
+
collectLayers(ctx, offset + subOffset, compose(m, t), out, depth + 1, blendMode);
|
|
14930
16070
|
return;
|
|
14931
16071
|
}
|
|
14932
16072
|
case 14: {
|
|
14933
16073
|
const subOffset = getUint24(view, offset + 1);
|
|
14934
16074
|
const dx = view.getInt16(offset + 4), dy = view.getInt16(offset + 6);
|
|
14935
|
-
collectLayers(ctx, offset + subOffset, compose(m, [1, 0, 0, 1, dx, dy]), out, depth + 1);
|
|
16075
|
+
collectLayers(ctx, offset + subOffset, compose(m, [1, 0, 0, 1, dx, dy]), out, depth + 1, blendMode);
|
|
14936
16076
|
return;
|
|
14937
16077
|
}
|
|
14938
16078
|
case 16: {
|
|
14939
16079
|
const subOffset = getUint24(view, offset + 1);
|
|
14940
16080
|
const sx = f2dot14(view, offset + 4), sy = f2dot14(view, offset + 6);
|
|
14941
|
-
collectLayers(ctx, offset + subOffset, compose(m, [sx, 0, 0, sy, 0, 0]), out, depth + 1);
|
|
16081
|
+
collectLayers(ctx, offset + subOffset, compose(m, [sx, 0, 0, sy, 0, 0]), out, depth + 1, blendMode);
|
|
16082
|
+
return;
|
|
16083
|
+
}
|
|
16084
|
+
case 32: {
|
|
16085
|
+
const sourceOffset = getUint24(view, offset + 1);
|
|
16086
|
+
const mode = view.getUint8(offset + 4);
|
|
16087
|
+
const backdropOffset = getUint24(view, offset + 5);
|
|
16088
|
+
const bm = compositeModeToBlendMode(mode);
|
|
16089
|
+
if (bm === null) throw new UnsupportedPaint(`composite mode ${mode}`);
|
|
16090
|
+
collectLayers(ctx, offset + backdropOffset, m, out, depth + 1, blendMode);
|
|
16091
|
+
collectLayers(ctx, offset + sourceOffset, m, out, depth + 1, bm === "Normal" ? blendMode : bm);
|
|
14942
16092
|
return;
|
|
14943
16093
|
}
|
|
14944
16094
|
default:
|
|
14945
16095
|
throw new UnsupportedPaint(`structural paint format ${format}`);
|
|
14946
16096
|
}
|
|
14947
16097
|
}
|
|
16098
|
+
function compositeModeToBlendMode(mode) {
|
|
16099
|
+
switch (mode) {
|
|
16100
|
+
case 3:
|
|
16101
|
+
return "Normal";
|
|
16102
|
+
// SRC_OVER
|
|
16103
|
+
case 13:
|
|
16104
|
+
return "Screen";
|
|
16105
|
+
case 14:
|
|
16106
|
+
return "Overlay";
|
|
16107
|
+
case 15:
|
|
16108
|
+
return "Darken";
|
|
16109
|
+
case 16:
|
|
16110
|
+
return "Lighten";
|
|
16111
|
+
case 17:
|
|
16112
|
+
return "ColorDodge";
|
|
16113
|
+
case 18:
|
|
16114
|
+
return "ColorBurn";
|
|
16115
|
+
case 19:
|
|
16116
|
+
return "HardLight";
|
|
16117
|
+
case 20:
|
|
16118
|
+
return "SoftLight";
|
|
16119
|
+
case 21:
|
|
16120
|
+
return "Difference";
|
|
16121
|
+
case 22:
|
|
16122
|
+
return "Exclusion";
|
|
16123
|
+
case 23:
|
|
16124
|
+
return "Multiply";
|
|
16125
|
+
case 24:
|
|
16126
|
+
return "Hue";
|
|
16127
|
+
case 25:
|
|
16128
|
+
return "Saturation";
|
|
16129
|
+
case 26:
|
|
16130
|
+
return "Color";
|
|
16131
|
+
case 27:
|
|
16132
|
+
return "Luminosity";
|
|
16133
|
+
// 0 CLEAR, 1 SRC, 2 DEST, 4 DEST_OVER, 5 SRC_IN, 6 DEST_IN, 7 SRC_OUT,
|
|
16134
|
+
// 8 DEST_OUT, 9 SRC_ATOP, 10 DEST_ATOP, 11 XOR, 12 PLUS → unsupported.
|
|
16135
|
+
default:
|
|
16136
|
+
return null;
|
|
16137
|
+
}
|
|
16138
|
+
}
|
|
14948
16139
|
function baseGlyphPaintOffset(ctx, glyphId) {
|
|
14949
16140
|
const { view, colrBase } = ctx;
|
|
14950
16141
|
const baseGlyphListOffset = view.getUint32(colrBase + 14);
|
|
@@ -15020,6 +16211,314 @@ function parseColrCpal(bytes) {
|
|
|
15020
16211
|
return Object.keys(result).length ? result : null;
|
|
15021
16212
|
}
|
|
15022
16213
|
|
|
16214
|
+
// src/parser/pdf-pagetree.ts
|
|
16215
|
+
init_pdf_encrypt();
|
|
16216
|
+
var MAX_MERGE_SOURCES = 50;
|
|
16217
|
+
var DEFAULT_MEDIA_BOX = "[0 0 612 792]";
|
|
16218
|
+
var INHERITABLE_KEYS = ["MediaBox", "CropBox", "Rotate"];
|
|
16219
|
+
var MAX_COPY_DEPTH = 2e3;
|
|
16220
|
+
var DEFAULT_MAX_OUTPUT_SIZE = 256 * 1024 * 1024;
|
|
16221
|
+
function resolveMaxOutputSize(value) {
|
|
16222
|
+
if (value === void 0) return DEFAULT_MAX_OUTPUT_SIZE;
|
|
16223
|
+
if (typeof value !== "number" || Number.isNaN(value) || value <= 0) {
|
|
16224
|
+
throw new Error(
|
|
16225
|
+
`maxOutputSize must be a positive number or Infinity (got ${String(value)})`
|
|
16226
|
+
);
|
|
16227
|
+
}
|
|
16228
|
+
return value;
|
|
16229
|
+
}
|
|
16230
|
+
function mergePdfs(sources, opts) {
|
|
16231
|
+
if (sources.length === 0) throw new Error("mergePdfs requires at least one source PDF");
|
|
16232
|
+
if (sources.length > MAX_MERGE_SOURCES) {
|
|
16233
|
+
throw new Error(`mergePdfs supports at most ${MAX_MERGE_SOURCES} sources (got ${sources.length})`);
|
|
16234
|
+
}
|
|
16235
|
+
resolveMaxOutputSize(opts?.maxOutputSize);
|
|
16236
|
+
const specs = [];
|
|
16237
|
+
for (const src of sources) {
|
|
16238
|
+
const reader = openPdf(src);
|
|
16239
|
+
assertNotEncrypted(reader);
|
|
16240
|
+
const count = reader.pageCount;
|
|
16241
|
+
for (let i = 0; i < count; i++) specs.push({ reader, pageIndex: i });
|
|
16242
|
+
}
|
|
16243
|
+
return assemble(specs, opts ?? {});
|
|
16244
|
+
}
|
|
16245
|
+
function extractPages(src, pageIndices, opts) {
|
|
16246
|
+
if (pageIndices.length === 0) throw new Error("extractPages requires at least one page index");
|
|
16247
|
+
resolveMaxOutputSize(opts?.maxOutputSize);
|
|
16248
|
+
const reader = openPdf(src);
|
|
16249
|
+
assertNotEncrypted(reader);
|
|
16250
|
+
const count = reader.pageCount;
|
|
16251
|
+
const specs = [];
|
|
16252
|
+
for (const idx of pageIndices) {
|
|
16253
|
+
if (!Number.isInteger(idx) || idx < 0 || idx >= count) {
|
|
16254
|
+
throw new Error(`extractPages page index ${idx} out of range (0-${count - 1})`);
|
|
16255
|
+
}
|
|
16256
|
+
specs.push({ reader, pageIndex: idx });
|
|
16257
|
+
}
|
|
16258
|
+
return assemble(specs, opts ?? {});
|
|
16259
|
+
}
|
|
16260
|
+
function splitPdf(src, ranges, opts) {
|
|
16261
|
+
if (ranges.length === 0) throw new Error("splitPdf requires at least one range");
|
|
16262
|
+
resolveMaxOutputSize(opts?.maxOutputSize);
|
|
16263
|
+
const reader = openPdf(src);
|
|
16264
|
+
assertNotEncrypted(reader);
|
|
16265
|
+
const count = reader.pageCount;
|
|
16266
|
+
const out = [];
|
|
16267
|
+
for (const range of ranges) {
|
|
16268
|
+
const start = range.start | 0;
|
|
16269
|
+
const end = (range.end ?? range.start) | 0;
|
|
16270
|
+
if (start < 0 || end < start || end >= count) {
|
|
16271
|
+
throw new Error(`splitPdf range [${start}, ${end}] invalid for ${count}-page document`);
|
|
16272
|
+
}
|
|
16273
|
+
const specs = [];
|
|
16274
|
+
for (let i = start; i <= end; i++) specs.push({ reader, pageIndex: i });
|
|
16275
|
+
out.push(assemble(specs, opts ?? {}));
|
|
16276
|
+
}
|
|
16277
|
+
return out;
|
|
16278
|
+
}
|
|
16279
|
+
function assertNotEncrypted(reader) {
|
|
16280
|
+
if (reader.trailer.get("Encrypt") !== void 0) {
|
|
16281
|
+
throw new Error("Encrypted PDFs are not supported by the page-tree API (decrypt first)");
|
|
16282
|
+
}
|
|
16283
|
+
}
|
|
16284
|
+
function resolveInherited(reader, page, key) {
|
|
16285
|
+
let node = page;
|
|
16286
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16287
|
+
while (node && !seen.has(node)) {
|
|
16288
|
+
seen.add(node);
|
|
16289
|
+
const v = node.get(key);
|
|
16290
|
+
if (v !== void 0) return v;
|
|
16291
|
+
const parent = node.get("Parent");
|
|
16292
|
+
if (parent === void 0) break;
|
|
16293
|
+
const resolved = reader.resolveValue(parent);
|
|
16294
|
+
node = isDict(resolved) ? resolved : void 0;
|
|
16295
|
+
}
|
|
16296
|
+
return void 0;
|
|
16297
|
+
}
|
|
16298
|
+
function assemble(specs, opts) {
|
|
16299
|
+
const ctx = {
|
|
16300
|
+
nextNum: 3,
|
|
16301
|
+
bodies: /* @__PURE__ */ new Map(),
|
|
16302
|
+
memo: /* @__PURE__ */ new Map(),
|
|
16303
|
+
maxOutputSize: resolveMaxOutputSize(opts.maxOutputSize),
|
|
16304
|
+
totalBytes: 0
|
|
16305
|
+
};
|
|
16306
|
+
const pageNums = [];
|
|
16307
|
+
for (const spec of specs) {
|
|
16308
|
+
pageNums.push(copyPage(ctx, spec, opts));
|
|
16309
|
+
}
|
|
16310
|
+
const kids = pageNums.map((n2) => `${n2} 0 R`).join(" ");
|
|
16311
|
+
setBody(ctx, 2, `<< /Type /Pages /Kids [${kids}] /Count ${pageNums.length} >>`);
|
|
16312
|
+
setBody(ctx, 1, "<< /Type /Catalog /Pages 2 0 R >>");
|
|
16313
|
+
return serializeDocument(ctx);
|
|
16314
|
+
}
|
|
16315
|
+
function accountBytes(ctx, n2) {
|
|
16316
|
+
ctx.totalBytes += n2;
|
|
16317
|
+
if (ctx.totalBytes > ctx.maxOutputSize) {
|
|
16318
|
+
throw new Error(
|
|
16319
|
+
`page-tree output exceeded the ${ctx.maxOutputSize}-byte maxOutputSize limit (raise MergeOptions.maxOutputSize or pass Infinity to disable)`
|
|
16320
|
+
);
|
|
16321
|
+
}
|
|
16322
|
+
}
|
|
16323
|
+
function setBody(ctx, num, body) {
|
|
16324
|
+
accountBytes(ctx, body.length);
|
|
16325
|
+
ctx.bodies.set(num, body);
|
|
16326
|
+
}
|
|
16327
|
+
function memoFor(ctx, reader) {
|
|
16328
|
+
let m = ctx.memo.get(reader);
|
|
16329
|
+
if (!m) {
|
|
16330
|
+
m = /* @__PURE__ */ new Map();
|
|
16331
|
+
ctx.memo.set(reader, m);
|
|
16332
|
+
}
|
|
16333
|
+
return m;
|
|
16334
|
+
}
|
|
16335
|
+
function copyPage(ctx, spec, opts) {
|
|
16336
|
+
const { reader, pageIndex } = spec;
|
|
16337
|
+
const page = reader.getPage(pageIndex);
|
|
16338
|
+
const pageNum = ctx.nextNum++;
|
|
16339
|
+
const parts = ["/Type /Page", "/Parent 2 0 R"];
|
|
16340
|
+
for (const key of INHERITABLE_KEYS) {
|
|
16341
|
+
const v = resolveInherited(reader, page, key);
|
|
16342
|
+
if (v !== void 0) {
|
|
16343
|
+
parts.push(`/${key} ${serializeValue2(rewrite(ctx, reader, v))}`);
|
|
16344
|
+
} else if (key === "MediaBox") {
|
|
16345
|
+
parts.push(`/MediaBox ${DEFAULT_MEDIA_BOX}`);
|
|
16346
|
+
}
|
|
16347
|
+
}
|
|
16348
|
+
const res = resolveInherited(reader, page, "Resources");
|
|
16349
|
+
parts.push(`/Resources ${res !== void 0 ? serializeValue2(rewrite(ctx, reader, res)) : "<< >>"}`);
|
|
16350
|
+
const contents = page.get("Contents");
|
|
16351
|
+
if (contents !== void 0) {
|
|
16352
|
+
parts.push(`/Contents ${serializeValue2(rewrite(ctx, reader, contents))}`);
|
|
16353
|
+
}
|
|
16354
|
+
if (!opts.dropAnnotations) {
|
|
16355
|
+
const annots = filterAnnotations(ctx, reader, page);
|
|
16356
|
+
if (annots) parts.push(`/Annots ${annots}`);
|
|
16357
|
+
}
|
|
16358
|
+
setBody(ctx, pageNum, `<< ${parts.join(" ")} >>`);
|
|
16359
|
+
return pageNum;
|
|
16360
|
+
}
|
|
16361
|
+
function filterAnnotations(ctx, reader, page) {
|
|
16362
|
+
const annotsVal = page.get("Annots");
|
|
16363
|
+
if (annotsVal === void 0) return void 0;
|
|
16364
|
+
const arr = reader.resolveValue(annotsVal);
|
|
16365
|
+
if (!isArray(arr)) return void 0;
|
|
16366
|
+
const kept = [];
|
|
16367
|
+
for (const a of arr) {
|
|
16368
|
+
const ad = reader.resolveValue(a);
|
|
16369
|
+
if (!isDict(ad)) continue;
|
|
16370
|
+
if (dictGetName(ad, "Subtype") !== "Link") continue;
|
|
16371
|
+
const action = reader.resolveValue(ad.get("A") ?? null);
|
|
16372
|
+
if (!isDict(action) || dictGetName(action, "S") !== "URI") continue;
|
|
16373
|
+
const clean = /* @__PURE__ */ new Map();
|
|
16374
|
+
for (const [k, v] of ad) {
|
|
16375
|
+
if (k === "P" || k === "Parent") continue;
|
|
16376
|
+
clean.set(k, rewrite(ctx, reader, v));
|
|
16377
|
+
}
|
|
16378
|
+
kept.push(serializeValue2(clean));
|
|
16379
|
+
}
|
|
16380
|
+
return kept.length > 0 ? `[${kept.join(" ")}]` : void 0;
|
|
16381
|
+
}
|
|
16382
|
+
function copyObject(ctx, reader, srcNum, srcGen, depth = 0) {
|
|
16383
|
+
const memo = memoFor(ctx, reader);
|
|
16384
|
+
const existing = memo.get(srcNum);
|
|
16385
|
+
if (existing !== void 0) return existing;
|
|
16386
|
+
const newNum = ctx.nextNum++;
|
|
16387
|
+
memo.set(srcNum, newNum);
|
|
16388
|
+
const resolved = reader.resolve({ type: "ref", num: srcNum, gen: srcGen });
|
|
16389
|
+
if (isStream(resolved)) {
|
|
16390
|
+
ctx.bodies.set(newNum, serializeStreamBody(ctx, reader, resolved, depth));
|
|
16391
|
+
} else {
|
|
16392
|
+
const body = serializeValue2(rewrite(ctx, reader, resolved, depth));
|
|
16393
|
+
setBody(ctx, newNum, body);
|
|
16394
|
+
}
|
|
16395
|
+
return newNum;
|
|
16396
|
+
}
|
|
16397
|
+
function rewrite(ctx, reader, val, depth = 0) {
|
|
16398
|
+
if (depth > MAX_COPY_DEPTH) {
|
|
16399
|
+
throw new Error(
|
|
16400
|
+
`page-tree copy exceeded maximum object nesting depth (${MAX_COPY_DEPTH}) \u2014 malformed or adversarial PDF`
|
|
16401
|
+
);
|
|
16402
|
+
}
|
|
16403
|
+
if (isRef(val)) {
|
|
16404
|
+
const entry = reader.xref.entries.get(val.num);
|
|
16405
|
+
if (!entry || entry.type === 0) return null;
|
|
16406
|
+
const newNum = copyObject(ctx, reader, val.num, val.gen, depth + 1);
|
|
16407
|
+
return { type: "ref", num: newNum, gen: 0 };
|
|
16408
|
+
}
|
|
16409
|
+
if (isArray(val)) return val.map((v) => rewrite(ctx, reader, v, depth + 1));
|
|
16410
|
+
if (isStream(val)) {
|
|
16411
|
+
return val;
|
|
16412
|
+
}
|
|
16413
|
+
if (isDict(val)) {
|
|
16414
|
+
const out = /* @__PURE__ */ new Map();
|
|
16415
|
+
for (const [k, v] of val) out.set(k, rewrite(ctx, reader, v, depth + 1));
|
|
16416
|
+
return out;
|
|
16417
|
+
}
|
|
16418
|
+
return val;
|
|
16419
|
+
}
|
|
16420
|
+
function serializeStreamBody(ctx, reader, stream, depth = 0) {
|
|
16421
|
+
accountBytes(ctx, stream.data.length);
|
|
16422
|
+
const dict = /* @__PURE__ */ new Map();
|
|
16423
|
+
for (const [k, v] of stream.dict) {
|
|
16424
|
+
if (k === "Length") continue;
|
|
16425
|
+
dict.set(k, rewrite(ctx, reader, v, depth + 1));
|
|
16426
|
+
}
|
|
16427
|
+
dict.set("Length", stream.data.length);
|
|
16428
|
+
let body = serializeDict2(dict);
|
|
16429
|
+
body += "\nstream\n";
|
|
16430
|
+
body += bytesToLatin1(stream.data);
|
|
16431
|
+
body += "\nendstream";
|
|
16432
|
+
accountBytes(ctx, body.length - stream.data.length);
|
|
16433
|
+
return body;
|
|
16434
|
+
}
|
|
16435
|
+
function serializeValue2(val) {
|
|
16436
|
+
if (val === null) return "null";
|
|
16437
|
+
if (typeof val === "boolean") return val ? "true" : "false";
|
|
16438
|
+
if (typeof val === "number") {
|
|
16439
|
+
if (Number.isInteger(val)) return String(val);
|
|
16440
|
+
return val.toFixed(4).replace(/\.?0+$/, "");
|
|
16441
|
+
}
|
|
16442
|
+
if (typeof val === "string") return `(${escapePdfStr2(val)})`;
|
|
16443
|
+
if (isName(val)) return `/${val.value}`;
|
|
16444
|
+
if (isRef(val)) return `${val.num} ${val.gen} R`;
|
|
16445
|
+
if (isArray(val)) return "[" + val.map(serializeValue2).join(" ") + "]";
|
|
16446
|
+
if (isStream(val)) return serializeDict2(val.dict);
|
|
16447
|
+
if (isDict(val)) return serializeDict2(val);
|
|
16448
|
+
return "null";
|
|
16449
|
+
}
|
|
16450
|
+
function serializeDict2(dict) {
|
|
16451
|
+
let s = "<<";
|
|
16452
|
+
for (const [key, val] of dict) s += ` /${key} ${serializeValue2(val)}`;
|
|
16453
|
+
s += " >>";
|
|
16454
|
+
return s;
|
|
16455
|
+
}
|
|
16456
|
+
function escapePdfStr2(s) {
|
|
16457
|
+
return s.replace(/[\\()]/g, (c) => "\\" + c);
|
|
16458
|
+
}
|
|
16459
|
+
function bytesToLatin1(bytes) {
|
|
16460
|
+
let s = "";
|
|
16461
|
+
const CHUNK = 32768;
|
|
16462
|
+
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
16463
|
+
s += String.fromCharCode(...bytes.subarray(i, i + CHUNK));
|
|
16464
|
+
}
|
|
16465
|
+
return s;
|
|
16466
|
+
}
|
|
16467
|
+
function serializeDocument(ctx) {
|
|
16468
|
+
const maxNum = ctx.nextNum - 1;
|
|
16469
|
+
const parts = [];
|
|
16470
|
+
const offsets = new Array(maxNum + 1).fill(0);
|
|
16471
|
+
let offset = 0;
|
|
16472
|
+
function push(s) {
|
|
16473
|
+
parts.push(s);
|
|
16474
|
+
offset += s.length;
|
|
16475
|
+
}
|
|
16476
|
+
push("%PDF-1.7\n");
|
|
16477
|
+
push("%\xE2\xE3\xCF\xD3\n");
|
|
16478
|
+
for (let num = 1; num <= maxNum; num++) {
|
|
16479
|
+
const body = ctx.bodies.get(num);
|
|
16480
|
+
if (body === void 0) continue;
|
|
16481
|
+
offsets[num] = offset;
|
|
16482
|
+
push(`${num} 0 obj
|
|
16483
|
+
${body}
|
|
16484
|
+
endobj
|
|
16485
|
+
`);
|
|
16486
|
+
}
|
|
16487
|
+
const xrefOffset = offset;
|
|
16488
|
+
const size = maxNum + 1;
|
|
16489
|
+
let xref = `xref
|
|
16490
|
+
0 ${size}
|
|
16491
|
+
0000000000 65535 f
|
|
16492
|
+
`;
|
|
16493
|
+
for (let num = 1; num <= maxNum; num++) {
|
|
16494
|
+
xref += `${String(offsets[num]).padStart(10, "0")} 00000 n
|
|
16495
|
+
`;
|
|
16496
|
+
}
|
|
16497
|
+
push(xref);
|
|
16498
|
+
const id = bytesToHex(md5(latin1ToBytes(parts.join(""))));
|
|
16499
|
+
push(`trailer
|
|
16500
|
+
<< /Size ${size} /Root 1 0 R /ID [<${id}> <${id}>] >>
|
|
16501
|
+
`);
|
|
16502
|
+
push(`startxref
|
|
16503
|
+
${xrefOffset}
|
|
16504
|
+
%%EOF
|
|
16505
|
+
`);
|
|
16506
|
+
const full = parts.join("");
|
|
16507
|
+
const out = new Uint8Array(full.length);
|
|
16508
|
+
for (let i = 0; i < full.length; i++) out[i] = full.charCodeAt(i) & 255;
|
|
16509
|
+
return out;
|
|
16510
|
+
}
|
|
16511
|
+
function latin1ToBytes(s) {
|
|
16512
|
+
const out = new Uint8Array(s.length);
|
|
16513
|
+
for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i) & 255;
|
|
16514
|
+
return out;
|
|
16515
|
+
}
|
|
16516
|
+
function bytesToHex(bytes) {
|
|
16517
|
+
let s = "";
|
|
16518
|
+
for (let i = 0; i < bytes.length; i++) s += bytes[i].toString(16).padStart(2, "0");
|
|
16519
|
+
return s;
|
|
16520
|
+
}
|
|
16521
|
+
|
|
15023
16522
|
// src/parser/pdf-ua-validator.ts
|
|
15024
16523
|
function pageContentText(reader, page) {
|
|
15025
16524
|
const contents = page.get("Contents");
|
|
@@ -15177,6 +16676,6 @@ async function createPDF(pdfParams, options) {
|
|
|
15177
16676
|
return generatePDFMainThread(pdfParams, options?.layoutOptions);
|
|
15178
16677
|
}
|
|
15179
16678
|
|
|
15180
|
-
export { BAL_H, DEFAULT_COLORS, DEFAULT_COLUMNS, DEFAULT_CW, DEFAULT_FONT_SIZES, DEFAULT_MARGINS, DEFAULT_MAX_BLOCKS, DEFAULT_MAX_INFLATE_OUTPUT, FT_H, HEADER_H, INFO_LN, KNOWN_DECODE_FILTERS, MAX_PARSE_DEPTH, MAX_XREF_CHAIN, PAGE_SIZES, PDF_A_CONFORMANCE_TARGETS, PG_H, PG_W, ROW_H, TH_H, TITLE_LN, WORKER_THRESHOLD, WORKER_TIMEOUT_MS, addSignaturePlaceholder, applyDecodeFilter, buildAcroFormDict, buildAppearanceStreamDict, buildCmsSignedData, buildDocumentPDF, buildDocumentPDFBytes, buildDocumentPDFStream, buildDocumentPDFStreamPageByPage, buildDocumentPDFStreamTrue, buildEmbeddedFiles, buildFormWidget, buildImageOperators, buildImageXObject, buildInternalLinkAnnotation, buildLinkAnnotation, buildPDF, buildPDFBytes, buildPDFStream, buildPDFStreamPageByPage, buildPDFStreamTrue, buildRadioGroupParent, buildSMaskXObject, buildSigDict, buildWatermarkState, chunkBinaryString, classifyClusters, classifyUseCategory, clearFontCache, computeColumnPositions, concatChunks, containsArabic, containsBengali, containsDevanagari, containsEthiopic, containsHebrew, containsKhmer, containsMyanmar, containsRTL, containsSinhala, containsTamil, containsTelugu, containsThai, containsTibetan, contoursToPath, createEncodingContext, createModifier, createPDF, createTokenizer, decodeASCII85, decodeASCIIHex, decodeEcPublicKey, decodeLZW, decodeRunLength, defaultFieldHeight, derBitString, derDecode, derInteger, derOctetString, derOid, derSequence, detectCharLang, detectFallbackLangs, detectImageFormat, dictGet, dictGetArray, dictGetDict, dictGetName, dictGetNum, dictGetRef, downloadBlob, ean13CheckDigit, ecPublicKeyFromPrivate, ecdsaSign, ecdsaVerify, encodeCode128, encodeEcPublicKey, encodePDF417, encodePdfTextString, estimateCmsSize, estimateContentsSize, extractGlyphContours, findStartxref, generateDataMatrix, generatePDFInWorker, generatePDFMainThread, generateQR, getMaxInflateOutputSize, getRegisteredLangs, getTrailerRef, getTrailerValue, hasFontLoader, helveticaBoldWidth, helveticaWidth, hmacSha256, inflateSync, initCrypto, initNodeCompression, initNodeDecompression as initNodeDecompression_parser, isArmenianCodepoint, isArray, isBengaliCodepoint, isCyrillicCodepoint, isDevanagariCodepoint, isDict, isEthiopicCodepoint, isGeorgianCodepoint, isKhmerCodepoint, isLinkAnnotation, isMyanmarCodepoint, isName, isRef, isSelfSigned, isSinhalaCodepoint, isStream, isTamilCodepoint, isTeluguCodepoint, isTibetanCodepoint, isValidPdfRgb, loadFontData, nameValue, needsUnicodeFont, normalizeBidiEmbeddings, normalizeColors, openPdf, parseCertificate, parseColor, parseColrCpal, parseCpal, parseGlyfFont, parseImage, parseIndirectObject, parseJPEG, parsePNG, parseRsaPrivateKey, parseRsaPublicKey, parseSvgPath, parseValue, parseXrefTable, pdfString, registerFont, registerFonts, renderBarcode, renderCode128, renderColorGlyph, renderDataMatrix, renderEAN13, renderPDF417, renderQR, renderSvg, resetFontRegistry, resolveBidiRuns, resolveLayout, resolvePdfAConfig, resolveTemplate, rsaSign, rsaSignHash, rsaVerify, rsaVerifyHash, setDeflateImpl, setInflateImpl, setMaxInflateOutputSize, sha384, sha512, shapeArabicText, shapeBengaliText, shapeDevanagariText, shapeKhmerText, shapeMyanmarText, shapeSinhalaText, shapeTamilText, shapeTeluguText, shapeThaiText, shapeTibetanText, signPdfBytes, slugify, splitTextByFont, streamByteLength, stripBidiControls, toBytes, toWinAnsi, truncate, truncateToWidth, validateAttachments, validateDocumentStreamable, validatePdfUA, validateTableStreamable, validateURL, validateWatermark, verifyCertSignature, wrapText };
|
|
16679
|
+
export { BAL_H, DEFAULT_COLORS, DEFAULT_COLUMNS, DEFAULT_CW, DEFAULT_FONT_SIZES, DEFAULT_MARGINS, DEFAULT_MAX_BLOCKS, DEFAULT_MAX_INFLATE_OUTPUT, FT_H, HEADER_H, INFO_LN, KNOWN_DECODE_FILTERS, MAX_PARSE_DEPTH, MAX_XREF_CHAIN, PAGE_SIZES, PDF_A_CONFORMANCE_TARGETS, PG_H, PG_W, ROW_H, TH_H, TITLE_LN, WORKER_THRESHOLD, WORKER_TIMEOUT_MS, addSignaturePlaceholder, applyDecodeFilter, buildAcroFormDict, buildAnnotation, buildAnnotationBody, buildAppearanceStreamDict, buildCmsSignedData, buildDocumentPDF, buildDocumentPDFBytes, buildDocumentPDFStream, buildDocumentPDFStreamPageByPage, buildDocumentPDFStreamTrue, buildEmbeddedFiles, buildFormWidget, buildImageOperators, buildImageXObject, buildInternalLinkAnnotation, buildLinkAnnotation, buildPDF, buildPDFBytes, buildPDFStream, buildPDFStreamPageByPage, buildPDFStreamTrue, buildRadioGroupParent, buildSMaskXObject, buildSigDict, buildWatermarkState, chunkBinaryString, classifyClusters, classifyUseCategory, clearFontCache, computeColumnPositions, concatChunks, containsArabic, containsBengali, containsDevanagari, containsEthiopic, containsHebrew, containsKhmer, containsMath, containsMyanmar, containsRTL, containsSinhala, containsTamil, containsTelugu, containsThai, containsTibetan, contoursToPath, createEncodingContext, createModifier, createPDF, createTokenizer, decodeASCII85, decodeASCIIHex, decodeEcPublicKey, decodeLZW, decodeRunLength, defaultFieldHeight, derBitString, derDecode, derInteger, derOctetString, derOid, derSequence, detectCharLang, detectFallbackLangs, detectImageFormat, dictGet, dictGetArray, dictGetDict, dictGetName, dictGetNum, dictGetRef, downloadBlob, ean13CheckDigit, ecPublicKeyFromPrivate, ecdsaSign, ecdsaVerify, encodeCode128, encodeEcPublicKey, encodePDF417, encodePdfTextString, estimateCmsSize, estimateContentsSize, extractGlyphContours, extractPages, findStartxref, generateDataMatrix, generatePDFInWorker, generatePDFMainThread, generateQR, getCryptoProvider, getMaxInflateOutputSize, getRegisteredLangs, getTrailerRef, getTrailerValue, hasFontLoader, helveticaBoldWidth, helveticaWidth, hmacSha256, inflateSync, initCrypto, initNodeCompression, initNodeDecompression as initNodeDecompression_parser, inspectDocumentLayout, isArmenianCodepoint, isArray, isBengaliCodepoint, isCyrillicCodepoint, isDevanagariCodepoint, isDict, isEthiopicCodepoint, isGeorgianCodepoint, isKhmerCodepoint, isLinkAnnotation, isMathCodepoint, isMyanmarCodepoint, isName, isRef, isSelfSigned, isSinhalaCodepoint, isStream, isTamilCodepoint, isTeluguCodepoint, isTibetanCodepoint, isValidPdfRgb, loadFontData, mergePdfs, nameValue, needsUnicodeFont, normalizeBidiEmbeddings, normalizeColors, openPdf, parseCertificate, parseColor, parseColrCpal, parseCpal, parseGlyfFont, parseImage, parseIndirectObject, parseJPEG, parsePNG, parseRsaPrivateKey, parseRsaPublicKey, parseSvgPath, parseValue, parseXrefTable, pdfString, registerFont, registerFonts, renderBarcode, renderCode128, renderColorGlyph, renderDataMatrix, renderEAN13, renderPDF417, renderQR, renderSvg, resetFontRegistry, resolveBidiRuns, resolveLayout, resolvePdfAConfig, resolveTemplate, rsaSign, rsaSignHash, rsaVerify, rsaVerifyHash, setCryptoProvider, setDeflateImpl, setInflateImpl, setMaxInflateOutputSize, sha384, sha512, shapeArabicText, shapeBengaliText, shapeDevanagariText, shapeKhmerText, shapeMyanmarText, shapeSinhalaText, shapeTamilText, shapeTeluguText, shapeThaiText, shapeTibetanText, signPdfBytes, slugify, splitPdf, splitTextByFont, streamByteLength, streamToFile, stripBidiControls, toBytes, toWinAnsi, truncate, truncateToWidth, validateAttachments, validateDocumentStreamable, validateFontData, validatePdfUA, validateTableStreamable, validateURL, validateWatermark, verifyCertSignature, wrapText };
|
|
15181
16680
|
//# sourceMappingURL=index.js.map
|
|
15182
16681
|
//# sourceMappingURL=index.js.map
|