pdfnative 1.4.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 +54 -16
- package/dist/index.cjs +550 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +289 -2
- package/dist/index.d.ts +289 -2
- package/dist/index.js +546 -15
- package/dist/index.js.map +1 -1
- 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 +18 -0
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.js +18 -0
- 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 +29 -3
package/dist/index.cjs
CHANGED
|
@@ -2324,6 +2324,16 @@ var MYANMAR_EXTENDED_A_END = 43647;
|
|
|
2324
2324
|
var MYANMAR_EXTENDED_B_START = 43488;
|
|
2325
2325
|
var MYANMAR_EXTENDED_B_END = 43519;
|
|
2326
2326
|
var MYANMAR_VIRAMA = 4153;
|
|
2327
|
+
var MATH_OPERATORS_START = 8704;
|
|
2328
|
+
var MATH_OPERATORS_END = 8959;
|
|
2329
|
+
var SUPPLEMENTAL_MATH_OPERATORS_START = 10752;
|
|
2330
|
+
var SUPPLEMENTAL_MATH_OPERATORS_END = 11007;
|
|
2331
|
+
var GEOMETRIC_SHAPES_START = 9632;
|
|
2332
|
+
var GEOMETRIC_SHAPES_END = 9727;
|
|
2333
|
+
var MISC_MATH_SYMBOLS_A_START = 10176;
|
|
2334
|
+
var MISC_MATH_SYMBOLS_A_END = 10223;
|
|
2335
|
+
var MISC_MATH_SYMBOLS_B_START = 10624;
|
|
2336
|
+
var MISC_MATH_SYMBOLS_B_END = 10751;
|
|
2327
2337
|
var EMOJI_RANGES = [
|
|
2328
2338
|
[127744, 128511],
|
|
2329
2339
|
// Miscellaneous Symbols and Pictographs
|
|
@@ -2402,6 +2412,9 @@ function isMyanmarCodepoint(cp) {
|
|
|
2402
2412
|
function isDevanagariCodepoint(cp) {
|
|
2403
2413
|
return cp >= DEVANAGARI_START && cp <= DEVANAGARI_END || cp >= DEVANAGARI_EXT_START && cp <= DEVANAGARI_EXT_END;
|
|
2404
2414
|
}
|
|
2415
|
+
function isMathCodepoint(cp) {
|
|
2416
|
+
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;
|
|
2417
|
+
}
|
|
2405
2418
|
function isEmojiCodepoint(cp) {
|
|
2406
2419
|
if (cp >= FITZPATRICK_START && cp <= FITZPATRICK_END) return true;
|
|
2407
2420
|
for (const [lo, hi] of EMOJI_RANGES) {
|
|
@@ -2488,10 +2501,16 @@ function containsDevanagari(str) {
|
|
|
2488
2501
|
}
|
|
2489
2502
|
return false;
|
|
2490
2503
|
}
|
|
2504
|
+
function containsMath(str) {
|
|
2505
|
+
for (let i = 0; i < str.length; i++) {
|
|
2506
|
+
if (isMathCodepoint(str.charCodeAt(i))) return true;
|
|
2507
|
+
}
|
|
2508
|
+
return false;
|
|
2509
|
+
}
|
|
2491
2510
|
|
|
2492
2511
|
// src/shaping/script-detect.ts
|
|
2493
2512
|
function needsUnicodeFont(lang) {
|
|
2494
|
-
return ["th", "ja", "zh", "ko", "el", "hi", "te", "tr", "vi", "pl", "ar", "he", "ru", "ka", "hy", "am", "si", "bo", "km", "my", "emoji"].includes(lang);
|
|
2513
|
+
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);
|
|
2495
2514
|
}
|
|
2496
2515
|
function detectFallbackLangs(texts, primaryLang) {
|
|
2497
2516
|
const needed = /* @__PURE__ */ new Set();
|
|
@@ -2592,6 +2611,10 @@ function detectFallbackLangs(texts, primaryLang) {
|
|
|
2592
2611
|
needed.add("hy");
|
|
2593
2612
|
continue;
|
|
2594
2613
|
}
|
|
2614
|
+
if (isMathCodepoint(cp)) {
|
|
2615
|
+
needed.add("math");
|
|
2616
|
+
continue;
|
|
2617
|
+
}
|
|
2595
2618
|
if (isEmojiCodepoint(cp)) {
|
|
2596
2619
|
needed.add("emoji");
|
|
2597
2620
|
continue;
|
|
@@ -2622,6 +2645,7 @@ function detectCharLang(cp) {
|
|
|
2622
2645
|
if (cp >= 1024 && cp <= 1279 || cp >= 1280 && cp <= 1327) return "ru";
|
|
2623
2646
|
if (cp >= 4256 && cp <= 4351 || cp >= 11520 && cp <= 11567) return "ka";
|
|
2624
2647
|
if (cp >= 1328 && cp <= 1423 || cp >= 64275 && cp <= 64279) return "hy";
|
|
2648
|
+
if (isMathCodepoint(cp)) return "math";
|
|
2625
2649
|
if (isEmojiCodepoint(cp)) return "emoji";
|
|
2626
2650
|
return null;
|
|
2627
2651
|
}
|
|
@@ -6251,6 +6275,10 @@ function buildTextRunsWithFallback(text, fontRef, fd, sz, trackGid, pdfA = false
|
|
|
6251
6275
|
for (let i = 0; i < text.length; ) {
|
|
6252
6276
|
const rawCp = text.codePointAt(i) ?? 0;
|
|
6253
6277
|
const charLen = rawCp > 65535 ? 2 : 1;
|
|
6278
|
+
if (rawCp < 32 || rawCp === 127) {
|
|
6279
|
+
i += charLen;
|
|
6280
|
+
continue;
|
|
6281
|
+
}
|
|
6254
6282
|
const cp = rawCp === 8239 || rawCp === 160 ? 32 : rawCp;
|
|
6255
6283
|
const char = text.substring(i, i + charLen);
|
|
6256
6284
|
const gid = fd.cmap[cp] ?? 0;
|
|
@@ -8794,6 +8822,61 @@ function buildViewerPreferences(prefs) {
|
|
|
8794
8822
|
// src/core/pdf-document.ts
|
|
8795
8823
|
init_pdf_encrypt();
|
|
8796
8824
|
|
|
8825
|
+
// src/core/pdf-layout-debug.ts
|
|
8826
|
+
function resolveDebugOptions(debug) {
|
|
8827
|
+
if (!debug) return null;
|
|
8828
|
+
if (debug === true) {
|
|
8829
|
+
return { showMargins: true, showContentBounds: true, showCells: true };
|
|
8830
|
+
}
|
|
8831
|
+
const showMargins = debug.showMargins === true;
|
|
8832
|
+
const showContentBounds = debug.showContentBounds === true;
|
|
8833
|
+
const showCells = debug.showCells === true;
|
|
8834
|
+
if (!showMargins && !showContentBounds && !showCells) return null;
|
|
8835
|
+
return { showMargins, showContentBounds, showCells };
|
|
8836
|
+
}
|
|
8837
|
+
var COL_MARGIN = "0 0.45 0.95";
|
|
8838
|
+
var COL_BLOCK = "0.90 0.20 0.30";
|
|
8839
|
+
var COL_CELL = "0 0.62 0.30";
|
|
8840
|
+
function rectOp(x, y, w, h, color, lineW) {
|
|
8841
|
+
return `q ${color} RG ${fmtNum(lineW)} w ${fmtNum(x)} ${fmtNum(y)} ${fmtNum(w)} ${fmtNum(h)} re S Q`;
|
|
8842
|
+
}
|
|
8843
|
+
function marginBoxOps(pgW, pgH, mg, footerH) {
|
|
8844
|
+
const x = mg.l;
|
|
8845
|
+
const yBottom = mg.b + footerH;
|
|
8846
|
+
const w = pgW - mg.l - mg.r;
|
|
8847
|
+
const h = pgH - mg.t - yBottom;
|
|
8848
|
+
return rectOp(x, yBottom, w, h, COL_MARGIN, 0.5);
|
|
8849
|
+
}
|
|
8850
|
+
function blockBoundsOps(x, width, yTop, yBottom) {
|
|
8851
|
+
const h = yTop - yBottom;
|
|
8852
|
+
if (h <= 0) return "";
|
|
8853
|
+
return rectOp(x, yBottom, width, h, COL_BLOCK, 0.4);
|
|
8854
|
+
}
|
|
8855
|
+
function tableCellOps(plan, slice, yTop) {
|
|
8856
|
+
const drawCaption = slice ? slice.drawCaption : true;
|
|
8857
|
+
const drawHeader = slice ? slice.drawHeader : true;
|
|
8858
|
+
const fromRow = slice ? slice.fromRow : 0;
|
|
8859
|
+
const toRow = slice ? slice.toRow : plan.rowHeights.length;
|
|
8860
|
+
const parts = [];
|
|
8861
|
+
let y = yTop - (drawCaption ? plan.captionHeight : 0);
|
|
8862
|
+
if (drawHeader) {
|
|
8863
|
+
const hBottom = y - plan.headerHeight;
|
|
8864
|
+
for (let c = 0; c < plan.cx.length; c++) {
|
|
8865
|
+
parts.push(rectOp(plan.cx[c], hBottom, plan.cwi[c], plan.headerHeight, COL_CELL, 0.3));
|
|
8866
|
+
}
|
|
8867
|
+
y = hBottom;
|
|
8868
|
+
}
|
|
8869
|
+
for (let r = fromRow; r < toRow; r++) {
|
|
8870
|
+
const rh = plan.rowHeights[r];
|
|
8871
|
+
const rBottom = y - rh;
|
|
8872
|
+
for (let c = 0; c < plan.cx.length; c++) {
|
|
8873
|
+
parts.push(rectOp(plan.cx[c], rBottom, plan.cwi[c], rh, COL_CELL, 0.3));
|
|
8874
|
+
}
|
|
8875
|
+
y = rBottom;
|
|
8876
|
+
}
|
|
8877
|
+
return parts.join("\n");
|
|
8878
|
+
}
|
|
8879
|
+
|
|
8797
8880
|
// src/core/pdf-form.ts
|
|
8798
8881
|
var DEFAULT_FIELD_HEIGHT_TEXT = 22;
|
|
8799
8882
|
var DEFAULT_FIELD_HEIGHT_MULTILINE = 60;
|
|
@@ -10928,6 +11011,51 @@ function getNum(attrs, name, def = 0) {
|
|
|
10928
11011
|
const v = getAttr(attrs, name);
|
|
10929
11012
|
return v !== void 0 ? +v : def;
|
|
10930
11013
|
}
|
|
11014
|
+
function getLen(attrs, name) {
|
|
11015
|
+
const v = getAttr(attrs, name);
|
|
11016
|
+
if (v === void 0) return void 0;
|
|
11017
|
+
const n2 = parseFloat(v);
|
|
11018
|
+
return Number.isFinite(n2) ? n2 : void 0;
|
|
11019
|
+
}
|
|
11020
|
+
function decodeSvgEntities(s) {
|
|
11021
|
+
return s.replace(/&(#x[0-9a-fA-F]+|#[0-9]+|[a-zA-Z]+);/g, (_m, ent) => {
|
|
11022
|
+
if (ent[0] === "#") {
|
|
11023
|
+
const cp = ent[1] === "x" || ent[1] === "X" ? parseInt(ent.slice(2), 16) : parseInt(ent.slice(1), 10);
|
|
11024
|
+
return Number.isFinite(cp) && cp >= 0 && cp <= 1114111 ? String.fromCodePoint(cp) : "";
|
|
11025
|
+
}
|
|
11026
|
+
switch (ent) {
|
|
11027
|
+
case "amp":
|
|
11028
|
+
return "&";
|
|
11029
|
+
case "lt":
|
|
11030
|
+
return "<";
|
|
11031
|
+
case "gt":
|
|
11032
|
+
return ">";
|
|
11033
|
+
case "quot":
|
|
11034
|
+
return '"';
|
|
11035
|
+
case "apos":
|
|
11036
|
+
return "'";
|
|
11037
|
+
case "nbsp":
|
|
11038
|
+
return "\xA0";
|
|
11039
|
+
default:
|
|
11040
|
+
return "";
|
|
11041
|
+
}
|
|
11042
|
+
});
|
|
11043
|
+
}
|
|
11044
|
+
function stripSvgTags(raw) {
|
|
11045
|
+
let out = "";
|
|
11046
|
+
let inTag = false;
|
|
11047
|
+
for (const ch2 of raw) {
|
|
11048
|
+
if (ch2 === "<") inTag = true;
|
|
11049
|
+
else if (ch2 === ">") inTag = false;
|
|
11050
|
+
else if (!inTag) out += ch2;
|
|
11051
|
+
}
|
|
11052
|
+
return out;
|
|
11053
|
+
}
|
|
11054
|
+
function sanitizeSvgText(raw) {
|
|
11055
|
+
const noTags = stripSvgTags(raw);
|
|
11056
|
+
const decoded = decodeSvgEntities(noTags);
|
|
11057
|
+
return decoded.replace(/[\u0000-\u001F\u007F-\u009F]+/g, " ").replace(/\s+/g, " ").trim();
|
|
11058
|
+
}
|
|
10931
11059
|
function rectToPath(x, y, w, h, rx, ry) {
|
|
10932
11060
|
if (w <= 0 || h <= 0) return "";
|
|
10933
11061
|
if (rx <= 0 && ry <= 0) {
|
|
@@ -11009,7 +11137,60 @@ function parseSvgMarkup(svg) {
|
|
|
11009
11137
|
});
|
|
11010
11138
|
}
|
|
11011
11139
|
}
|
|
11012
|
-
|
|
11140
|
+
const textElements = parseSvgText(svg);
|
|
11141
|
+
return { elements, textElements, viewBox };
|
|
11142
|
+
}
|
|
11143
|
+
function parseSvgText(svg) {
|
|
11144
|
+
const out = [];
|
|
11145
|
+
const textRe = /<text\b([^>]*)>([\s\S]*?)<\/text>/gi;
|
|
11146
|
+
let tm;
|
|
11147
|
+
while ((tm = textRe.exec(svg)) !== null) {
|
|
11148
|
+
const attrs = tm[1];
|
|
11149
|
+
const inner = tm[2];
|
|
11150
|
+
const baseX = getLen(attrs, "x") ?? 0;
|
|
11151
|
+
const baseY = getLen(attrs, "y") ?? 0;
|
|
11152
|
+
const baseSize = getLen(attrs, "font-size") ?? 16;
|
|
11153
|
+
const baseFillRaw = getAttr(attrs, "fill");
|
|
11154
|
+
const baseFill = baseFillRaw ? normalizeSvgColor(baseFillRaw) : void 0;
|
|
11155
|
+
const baseAnchor = normalizeAnchor(getAttr(attrs, "text-anchor"));
|
|
11156
|
+
const tspanRe = /<tspan\b([^>]*)>([\s\S]*?)<\/tspan>/gi;
|
|
11157
|
+
let sm;
|
|
11158
|
+
let penX = baseX;
|
|
11159
|
+
let penY = baseY;
|
|
11160
|
+
let found = false;
|
|
11161
|
+
while ((sm = tspanRe.exec(inner)) !== null) {
|
|
11162
|
+
found = true;
|
|
11163
|
+
const sa = sm[1];
|
|
11164
|
+
const text = sanitizeSvgText(sm[2]);
|
|
11165
|
+
const ax = getLen(sa, "x");
|
|
11166
|
+
const ay = getLen(sa, "y");
|
|
11167
|
+
const adx = getLen(sa, "dx");
|
|
11168
|
+
const ady = getLen(sa, "dy");
|
|
11169
|
+
penX = ax !== void 0 ? ax : penX + (adx ?? 0);
|
|
11170
|
+
penY = ay !== void 0 ? ay : penY + (ady ?? 0);
|
|
11171
|
+
if (!text) continue;
|
|
11172
|
+
const fillRaw = getAttr(sa, "fill");
|
|
11173
|
+
out.push({
|
|
11174
|
+
text,
|
|
11175
|
+
x: penX,
|
|
11176
|
+
y: penY,
|
|
11177
|
+
fontSize: getLen(sa, "font-size") ?? baseSize,
|
|
11178
|
+
fill: fillRaw ? normalizeSvgColor(fillRaw) : baseFill,
|
|
11179
|
+
anchor: normalizeAnchor(getAttr(sa, "text-anchor")) ?? baseAnchor
|
|
11180
|
+
});
|
|
11181
|
+
}
|
|
11182
|
+
if (!found) {
|
|
11183
|
+
const text = sanitizeSvgText(inner);
|
|
11184
|
+
if (text) {
|
|
11185
|
+
out.push({ text, x: baseX, y: baseY, fontSize: baseSize, fill: baseFill, anchor: baseAnchor });
|
|
11186
|
+
}
|
|
11187
|
+
}
|
|
11188
|
+
}
|
|
11189
|
+
return out;
|
|
11190
|
+
}
|
|
11191
|
+
function normalizeAnchor(v) {
|
|
11192
|
+
if (v === "middle" || v === "end" || v === "start") return v;
|
|
11193
|
+
return void 0;
|
|
11013
11194
|
}
|
|
11014
11195
|
var fn = (n2) => n2.toFixed(2);
|
|
11015
11196
|
function resolveColor(color, fallback) {
|
|
@@ -11045,36 +11226,62 @@ function buildPathOps(segments, fillRgb, strokeRgb, strokeWidth) {
|
|
|
11045
11226
|
ops.push("Q");
|
|
11046
11227
|
return ops.join("\n");
|
|
11047
11228
|
}
|
|
11048
|
-
function renderSvg(data, x, y, w, h, options) {
|
|
11229
|
+
function renderSvg(data, x, y, w, h, options, enc) {
|
|
11049
11230
|
if (!data || w <= 0 || h <= 0) return "";
|
|
11050
11231
|
const isSvgMarkup = data.trimStart().charAt(0) === "<";
|
|
11051
11232
|
let vb;
|
|
11052
11233
|
let elements;
|
|
11234
|
+
let textElements = [];
|
|
11053
11235
|
if (isSvgMarkup) {
|
|
11054
11236
|
const parsed = parseSvgMarkup(data);
|
|
11055
11237
|
vb = options?.viewBox ?? parsed.viewBox ?? [0, 0, w, h];
|
|
11056
11238
|
elements = parsed.elements;
|
|
11239
|
+
textElements = parsed.textElements;
|
|
11057
11240
|
} else {
|
|
11058
11241
|
vb = options?.viewBox ?? [0, 0, w, h];
|
|
11059
11242
|
elements = [{ pathData: data }];
|
|
11060
11243
|
}
|
|
11061
|
-
if (elements.length === 0 || vb[2] <= 0 || vb[3] <= 0) return "";
|
|
11244
|
+
if (elements.length === 0 && textElements.length === 0 || vb[2] <= 0 || vb[3] <= 0) return "";
|
|
11062
11245
|
const sx = w / vb[2];
|
|
11063
11246
|
const sy = h / vb[3];
|
|
11064
|
-
const
|
|
11247
|
+
const tx2 = x - vb[0] * sx;
|
|
11248
|
+
const ty = y + vb[1] * sy;
|
|
11249
|
+
const cmOp = `${fn(sx)} 0 0 ${fn(-sy)} ${fn(tx2)} ${fn(ty)} cm`;
|
|
11065
11250
|
const defaultFill = resolveColor(options?.fill, "0 0 0");
|
|
11066
11251
|
const defaultStroke = resolveColor(options?.stroke, null);
|
|
11067
11252
|
const defaultSw = options?.strokeWidth ?? 1;
|
|
11068
|
-
const
|
|
11253
|
+
const shapeOps = [];
|
|
11069
11254
|
for (const elem of elements) {
|
|
11070
11255
|
const segments = parseSvgPath(elem.pathData);
|
|
11071
11256
|
if (segments.length === 0) continue;
|
|
11072
11257
|
const fillRgb = resolveColor(elem.fill, defaultFill);
|
|
11073
11258
|
const strokeRgb = resolveColor(elem.stroke, defaultStroke);
|
|
11074
11259
|
const sw = elem.strokeWidth ?? defaultSw;
|
|
11075
|
-
|
|
11076
|
-
}
|
|
11077
|
-
|
|
11260
|
+
shapeOps.push(buildPathOps(segments, fillRgb, strokeRgb, sw));
|
|
11261
|
+
}
|
|
11262
|
+
const textOps = [];
|
|
11263
|
+
if (enc && textElements.length > 0) {
|
|
11264
|
+
for (const t of textElements) {
|
|
11265
|
+
const szPdf = t.fontSize * sy;
|
|
11266
|
+
if (szPdf <= 0 || !t.text) continue;
|
|
11267
|
+
const pdfBaseX = t.x * sx + tx2;
|
|
11268
|
+
const pdfBaseY = -sy * t.y + ty;
|
|
11269
|
+
const width = enc.tw(t.text, szPdf);
|
|
11270
|
+
const anchorOffset = t.anchor === "middle" ? width / 2 : t.anchor === "end" ? width : 0;
|
|
11271
|
+
const pdfX = pdfBaseX - anchorOffset;
|
|
11272
|
+
const fillRgb = resolveColor(t.fill, "0 0 0");
|
|
11273
|
+
textOps.push("q");
|
|
11274
|
+
if (fillRgb) textOps.push(`${fillRgb} rg`);
|
|
11275
|
+
textOps.push(txt(t.text, pdfX, pdfBaseY, enc.f1, szPdf, enc));
|
|
11276
|
+
textOps.push("Q");
|
|
11277
|
+
}
|
|
11278
|
+
}
|
|
11279
|
+
if (shapeOps.length === 0 && textOps.length === 0) return "";
|
|
11280
|
+
const allOps = [];
|
|
11281
|
+
if (shapeOps.length > 0) {
|
|
11282
|
+
allOps.push("q", cmOp, ...shapeOps, "Q");
|
|
11283
|
+
}
|
|
11284
|
+
allOps.push(...textOps);
|
|
11078
11285
|
return allOps.join("\n");
|
|
11079
11286
|
}
|
|
11080
11287
|
|
|
@@ -11380,7 +11587,7 @@ function planTable(block, enc, mgL, cw) {
|
|
|
11380
11587
|
headerLines.push(lines);
|
|
11381
11588
|
if (lines.length > headerMaxLines) headerMaxLines = lines.length;
|
|
11382
11589
|
}
|
|
11383
|
-
const headerHeight = headerMaxLines === 1 ? TH_H : Math.max(TH_H, headerMaxLines * fs.th * TABLE_LINE_HEIGHT +
|
|
11590
|
+
const headerHeight = headerMaxLines === 1 ? TH_H : Math.max(TH_H, headerMaxLines * fs.th * TABLE_LINE_HEIGHT + pad + 2);
|
|
11384
11591
|
const rowLines = [];
|
|
11385
11592
|
const rowHeights = [];
|
|
11386
11593
|
for (let r = 0; r < block.rows.length; r++) {
|
|
@@ -11393,7 +11600,7 @@ function planTable(block, enc, mgL, cw) {
|
|
|
11393
11600
|
if (lines.length > maxLines) maxLines = lines.length;
|
|
11394
11601
|
}
|
|
11395
11602
|
rowLines.push(cells);
|
|
11396
|
-
const h = maxLines === 1 ? minRowH : Math.max(minRowH, maxLines * fs.td * TABLE_LINE_HEIGHT +
|
|
11603
|
+
const h = maxLines === 1 ? minRowH : Math.max(minRowH, maxLines * fs.td * TABLE_LINE_HEIGHT + pad + 2);
|
|
11397
11604
|
rowHeights.push(h);
|
|
11398
11605
|
}
|
|
11399
11606
|
const captionLines = block.caption ? wrapText(block.caption, cw, CAPTION_FONT_SIZE, enc) : [];
|
|
@@ -11819,7 +12026,7 @@ function renderBarcodeBlock(block, y, mgL, cw, tagCtx, documentChildren) {
|
|
|
11819
12026
|
y = by - 6;
|
|
11820
12027
|
return { ops, y };
|
|
11821
12028
|
}
|
|
11822
|
-
function renderSvgBlock(block, y, mgL, cw, tagCtx, documentChildren) {
|
|
12029
|
+
function renderSvgBlock(block, y, mgL, cw, tagCtx, documentChildren, enc) {
|
|
11823
12030
|
const ops = [];
|
|
11824
12031
|
const w = block.width ?? DEFAULT_SVG_SIZE;
|
|
11825
12032
|
const h = block.height ?? DEFAULT_SVG_SIZE;
|
|
@@ -11835,7 +12042,7 @@ function renderSvgBlock(block, y, mgL, cw, tagCtx, documentChildren) {
|
|
|
11835
12042
|
stroke: block.stroke,
|
|
11836
12043
|
strokeWidth: block.strokeWidth,
|
|
11837
12044
|
viewBox: block.viewBox
|
|
11838
|
-
});
|
|
12045
|
+
}, enc);
|
|
11839
12046
|
if (svgOps) {
|
|
11840
12047
|
if (tagCtx?.tagged) {
|
|
11841
12048
|
const mcid = tagCtx.mcidAlloc.next(tagCtx.pageObjNum);
|
|
@@ -12017,6 +12224,7 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
12017
12224
|
if (watermarkOpts) {
|
|
12018
12225
|
validateWatermark(watermarkOpts, layout?.tagged);
|
|
12019
12226
|
}
|
|
12227
|
+
const debugOpts = resolveDebugOptions(layout?.debug);
|
|
12020
12228
|
const attachments = layout?.attachments;
|
|
12021
12229
|
validateAttachments(attachments, layout?.tagged);
|
|
12022
12230
|
const mcidAlloc = tagged ? createMCIDAllocator() : void 0;
|
|
@@ -12204,6 +12412,10 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
12204
12412
|
const tagCtx = tagged && mcidAlloc ? { tagged: true, mcidAlloc, pageObjNum} : void 0;
|
|
12205
12413
|
const ops = [];
|
|
12206
12414
|
let y = pgH - mg.t;
|
|
12415
|
+
const debugOps = [];
|
|
12416
|
+
if (debugOpts?.showMargins) {
|
|
12417
|
+
debugOps.push(marginBoxOps(pgW, pgH, mg, FT_H));
|
|
12418
|
+
}
|
|
12207
12419
|
if (headerTpl) {
|
|
12208
12420
|
const hOps = renderPageTemplate(
|
|
12209
12421
|
headerTpl,
|
|
@@ -12244,6 +12456,7 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
12244
12456
|
}
|
|
12245
12457
|
const blocks = pageBlocks[p] ?? [];
|
|
12246
12458
|
for (const block of blocks) {
|
|
12459
|
+
const yBefore = debugOpts ? y : 0;
|
|
12247
12460
|
switch (block.type) {
|
|
12248
12461
|
case "heading": {
|
|
12249
12462
|
if (headingDestIdx < headingDests.length) {
|
|
@@ -12324,7 +12537,7 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
12324
12537
|
break;
|
|
12325
12538
|
}
|
|
12326
12539
|
case "svg": {
|
|
12327
|
-
const result = renderSvgBlock(block, y, mg.l, cw, tagCtx, documentChildren);
|
|
12540
|
+
const result = renderSvgBlock(block, y, mg.l, cw, tagCtx, documentChildren, enc);
|
|
12328
12541
|
ops.push(...result.ops);
|
|
12329
12542
|
y = result.y;
|
|
12330
12543
|
break;
|
|
@@ -12336,6 +12549,19 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
12336
12549
|
break;
|
|
12337
12550
|
}
|
|
12338
12551
|
}
|
|
12552
|
+
if (debugOpts) {
|
|
12553
|
+
if (debugOpts.showContentBounds) {
|
|
12554
|
+
const bo = blockBoundsOps(mg.l, cw, yBefore, y);
|
|
12555
|
+
if (bo) debugOps.push(bo);
|
|
12556
|
+
}
|
|
12557
|
+
if (debugOpts.showCells) {
|
|
12558
|
+
if (block.type === "__tableSlice") {
|
|
12559
|
+
debugOps.push(tableCellOps(block.slice.plan, block.slice, yBefore));
|
|
12560
|
+
} else if (block.type === "table") {
|
|
12561
|
+
debugOps.push(tableCellOps(planTable(block, enc, mg.l, cw), void 0, yBefore));
|
|
12562
|
+
}
|
|
12563
|
+
}
|
|
12564
|
+
}
|
|
12339
12565
|
}
|
|
12340
12566
|
if (wmState?.foregroundOps) {
|
|
12341
12567
|
ops.push(wmState.foregroundOps);
|
|
@@ -12356,6 +12582,9 @@ function assembleDocumentParts(params, layoutOptions) {
|
|
|
12356
12582
|
documentChildren
|
|
12357
12583
|
);
|
|
12358
12584
|
ops.push(...ftOps);
|
|
12585
|
+
if (debugOps.length > 0) {
|
|
12586
|
+
ops.push(...debugOps);
|
|
12587
|
+
}
|
|
12359
12588
|
pageStreams.push(ops.join("\n"));
|
|
12360
12589
|
}
|
|
12361
12590
|
const annotsByPage = /* @__PURE__ */ new Map();
|
|
@@ -12953,6 +13182,173 @@ function autoOutlineFromHeadings(headings) {
|
|
|
12953
13182
|
return root;
|
|
12954
13183
|
}
|
|
12955
13184
|
|
|
13185
|
+
// src/core/pdf-layout-inspect.ts
|
|
13186
|
+
var TITLE_BAND_H = 22 + 12;
|
|
13187
|
+
function inspectDocumentLayout(params, layoutOptions) {
|
|
13188
|
+
if (!params || typeof params !== "object" || !Array.isArray(params.blocks)) {
|
|
13189
|
+
throw new Error("inspectDocumentLayout: params.blocks must be an array");
|
|
13190
|
+
}
|
|
13191
|
+
const layout = layoutOptions ?? params.layout;
|
|
13192
|
+
const pgW = layout?.pageWidth ?? PG_W;
|
|
13193
|
+
const pgH = layout?.pageHeight ?? PG_H;
|
|
13194
|
+
const mg = layout?.margins ?? { ...DEFAULT_MARGINS };
|
|
13195
|
+
const cw = pgW - mg.l - mg.r;
|
|
13196
|
+
const fontEntries = params.fontEntries ? [...params.fontEntries] : [];
|
|
13197
|
+
const tagged = resolvePdfAConfig(layout?.tagged).enabled;
|
|
13198
|
+
const enc = createEncodingContext(fontEntries, tagged, layout?.normalize ?? false);
|
|
13199
|
+
const headerH = layout?.headerTemplate ? HEADER_H : 0;
|
|
13200
|
+
const availableH = pgH - mg.t - mg.b - FT_H - headerH;
|
|
13201
|
+
const pages = [[]];
|
|
13202
|
+
let remainH = availableH;
|
|
13203
|
+
let curY = pgH - mg.t - headerH;
|
|
13204
|
+
if (params.title) {
|
|
13205
|
+
remainH -= TITLE_BAND_H;
|
|
13206
|
+
curY -= TITLE_BAND_H;
|
|
13207
|
+
}
|
|
13208
|
+
const newPage = () => {
|
|
13209
|
+
pages.push([]);
|
|
13210
|
+
remainH = availableH;
|
|
13211
|
+
curY = pgH - mg.t - headerH;
|
|
13212
|
+
};
|
|
13213
|
+
for (const block of params.blocks) {
|
|
13214
|
+
if (block.type === "pageBreak") {
|
|
13215
|
+
newPage();
|
|
13216
|
+
continue;
|
|
13217
|
+
}
|
|
13218
|
+
if (block.type === "table") {
|
|
13219
|
+
const plan = planTable(block, enc, mg.l, cw);
|
|
13220
|
+
const repeatHeader = block.repeatHeader !== false;
|
|
13221
|
+
const totalRows = block.rows.length;
|
|
13222
|
+
if (totalRows === 0) {
|
|
13223
|
+
const totalH = plan.captionHeight + plan.headerHeight + plan.trailerSpacing;
|
|
13224
|
+
if (totalH > remainH && pages[pages.length - 1].length > 0) newPage();
|
|
13225
|
+
pages[pages.length - 1].push({ type: "table", page: pages.length - 1, x: mg.l, top: curY, width: cw, height: totalH });
|
|
13226
|
+
remainH -= totalH;
|
|
13227
|
+
curY -= totalH;
|
|
13228
|
+
continue;
|
|
13229
|
+
}
|
|
13230
|
+
let rowIdx = 0;
|
|
13231
|
+
let isFirstSlice = true;
|
|
13232
|
+
while (rowIdx < totalRows) {
|
|
13233
|
+
const drawCaption = isFirstSlice;
|
|
13234
|
+
const drawHeader = isFirstSlice || repeatHeader;
|
|
13235
|
+
const tCapH = drawCaption ? plan.captionHeight : 0;
|
|
13236
|
+
const tHdrH = drawHeader ? plan.headerHeight : 0;
|
|
13237
|
+
const availableForRows = remainH - tCapH - tHdrH - plan.trailerSpacing;
|
|
13238
|
+
let usedH = 0;
|
|
13239
|
+
let count = 0;
|
|
13240
|
+
while (rowIdx + count < totalRows && usedH + plan.rowHeights[rowIdx + count] <= availableForRows) {
|
|
13241
|
+
usedH += plan.rowHeights[rowIdx + count];
|
|
13242
|
+
count++;
|
|
13243
|
+
}
|
|
13244
|
+
if (count === 0 && pages[pages.length - 1].length > 0) {
|
|
13245
|
+
newPage();
|
|
13246
|
+
continue;
|
|
13247
|
+
}
|
|
13248
|
+
if (count === 0) count = 1;
|
|
13249
|
+
rowIdx += count;
|
|
13250
|
+
const isFinalSlice = rowIdx >= totalRows;
|
|
13251
|
+
const sliceH = tCapH + tHdrH + usedH + (isFinalSlice ? plan.trailerSpacing : 0);
|
|
13252
|
+
pages[pages.length - 1].push({ type: "table", page: pages.length - 1, x: mg.l, top: curY, width: cw, height: sliceH });
|
|
13253
|
+
remainH -= sliceH;
|
|
13254
|
+
curY -= sliceH;
|
|
13255
|
+
isFirstSlice = false;
|
|
13256
|
+
if (!isFinalSlice) newPage();
|
|
13257
|
+
}
|
|
13258
|
+
continue;
|
|
13259
|
+
}
|
|
13260
|
+
const blockH = estimateBlockHeight(block, enc, cw);
|
|
13261
|
+
if (blockH > remainH && pages[pages.length - 1].length > 0) newPage();
|
|
13262
|
+
pages[pages.length - 1].push({ type: block.type, page: pages.length - 1, x: mg.l, top: curY, width: cw, height: blockH });
|
|
13263
|
+
remainH -= blockH;
|
|
13264
|
+
curY -= blockH;
|
|
13265
|
+
}
|
|
13266
|
+
const inspectedPages = pages.map((blocks, index) => ({ index, blocks }));
|
|
13267
|
+
return {
|
|
13268
|
+
pageWidth: pgW,
|
|
13269
|
+
pageHeight: pgH,
|
|
13270
|
+
margins: { t: mg.t, r: mg.r, b: mg.b, l: mg.l },
|
|
13271
|
+
totalPages: Math.max(1, pages.length),
|
|
13272
|
+
pages: inspectedPages
|
|
13273
|
+
};
|
|
13274
|
+
}
|
|
13275
|
+
|
|
13276
|
+
// src/core/pdf-annot-markup.ts
|
|
13277
|
+
var SUBTYPE = {
|
|
13278
|
+
text: "Text",
|
|
13279
|
+
highlight: "Highlight",
|
|
13280
|
+
underline: "Underline",
|
|
13281
|
+
strikeout: "StrikeOut",
|
|
13282
|
+
squiggly: "Squiggly",
|
|
13283
|
+
square: "Square",
|
|
13284
|
+
circle: "Circle",
|
|
13285
|
+
line: "Line",
|
|
13286
|
+
freetext: "FreeText"
|
|
13287
|
+
};
|
|
13288
|
+
function rectStr(r) {
|
|
13289
|
+
return `[${fmtNum(r[0])} ${fmtNum(r[1])} ${fmtNum(r[2])} ${fmtNum(r[3])}]`;
|
|
13290
|
+
}
|
|
13291
|
+
function quadFromRect(r) {
|
|
13292
|
+
const [x1, y1, x2, y2] = r;
|
|
13293
|
+
return [x1, y2, x2, y2, x1, y1, x2, y1];
|
|
13294
|
+
}
|
|
13295
|
+
function commonEntries(a) {
|
|
13296
|
+
const parts = [];
|
|
13297
|
+
if (a.contents !== void 0) parts.push(`/Contents ${encodePdfTextString(a.contents)}`);
|
|
13298
|
+
if (a.title !== void 0) parts.push(`/T ${encodePdfTextString(a.title)}`);
|
|
13299
|
+
if (a.color !== void 0) parts.push(`/C [${parseColor(a.color)}]`);
|
|
13300
|
+
if (a.opacity !== void 0) parts.push(`/CA ${fmtNum(a.opacity)}`);
|
|
13301
|
+
if (a.modified !== void 0) parts.push(`/M ${encodePdfTextString(a.modified)}`);
|
|
13302
|
+
parts.push(`/F ${a.flags ?? 4}`);
|
|
13303
|
+
return parts.join(" ");
|
|
13304
|
+
}
|
|
13305
|
+
function buildAnnotation(annot, objNum) {
|
|
13306
|
+
return `${objNum} 0 obj
|
|
13307
|
+
${buildAnnotationBody(annot)}
|
|
13308
|
+
endobj`;
|
|
13309
|
+
}
|
|
13310
|
+
function buildAnnotationBody(annot) {
|
|
13311
|
+
const entries = [
|
|
13312
|
+
`/Type /Annot`,
|
|
13313
|
+
`/Subtype /${SUBTYPE[annot.type]}`,
|
|
13314
|
+
`/Rect ${rectStr(annot.rect)}`,
|
|
13315
|
+
commonEntries(annot)
|
|
13316
|
+
];
|
|
13317
|
+
switch (annot.type) {
|
|
13318
|
+
case "text": {
|
|
13319
|
+
if (annot.open !== void 0) entries.push(`/Open ${annot.open ? "true" : "false"}`);
|
|
13320
|
+
if (annot.icon !== void 0) entries.push(`/Name /${annot.icon}`);
|
|
13321
|
+
break;
|
|
13322
|
+
}
|
|
13323
|
+
case "highlight":
|
|
13324
|
+
case "underline":
|
|
13325
|
+
case "strikeout":
|
|
13326
|
+
case "squiggly": {
|
|
13327
|
+
const quad = annot.quadPoints && annot.quadPoints.length >= 8 ? annot.quadPoints : quadFromRect(annot.rect);
|
|
13328
|
+
entries.push(`/QuadPoints [${quad.map(fmtNum).join(" ")}]`);
|
|
13329
|
+
break;
|
|
13330
|
+
}
|
|
13331
|
+
case "square":
|
|
13332
|
+
case "circle": {
|
|
13333
|
+
if (annot.interiorColor !== void 0) entries.push(`/IC [${parseColor(annot.interiorColor)}]`);
|
|
13334
|
+
entries.push(`/BS << /W ${fmtNum(annot.borderWidth ?? 1)} >>`);
|
|
13335
|
+
break;
|
|
13336
|
+
}
|
|
13337
|
+
case "line": {
|
|
13338
|
+
entries.push(`/L [${fmtNum(annot.start[0])} ${fmtNum(annot.start[1])} ${fmtNum(annot.end[0])} ${fmtNum(annot.end[1])}]`);
|
|
13339
|
+
entries.push(`/BS << /W ${fmtNum(annot.borderWidth ?? 1)} >>`);
|
|
13340
|
+
break;
|
|
13341
|
+
}
|
|
13342
|
+
case "freetext": {
|
|
13343
|
+
const sz = annot.fontSize ?? 12;
|
|
13344
|
+
const col = annot.color !== void 0 ? parseColor(annot.color) : "0 0 0";
|
|
13345
|
+
entries.push(`/DA (/Helv ${fmtNum(sz)} Tf ${col} rg)`);
|
|
13346
|
+
break;
|
|
13347
|
+
}
|
|
13348
|
+
}
|
|
13349
|
+
return `<< ${entries.filter(Boolean).join(" ")} >>`;
|
|
13350
|
+
}
|
|
13351
|
+
|
|
12956
13352
|
// src/core/pdf-signature.ts
|
|
12957
13353
|
init_sha();
|
|
12958
13354
|
|
|
@@ -14300,6 +14696,28 @@ function openPdf(bytes) {
|
|
|
14300
14696
|
if (!entry || entry.type === 0) return null;
|
|
14301
14697
|
return resolveRef({ num, gen: entry.gen });
|
|
14302
14698
|
}
|
|
14699
|
+
let _pageRefs;
|
|
14700
|
+
function collectPageRefs() {
|
|
14701
|
+
if (_pageRefs) return _pageRefs;
|
|
14702
|
+
const catalog = getCatalog();
|
|
14703
|
+
const refs = [];
|
|
14704
|
+
const walk = (nodeVal, depth) => {
|
|
14705
|
+
if (depth > 100) return;
|
|
14706
|
+
const node = resolveValue2(nodeVal);
|
|
14707
|
+
if (!isDict(node)) return;
|
|
14708
|
+
if (dictGetName(node, "Type") === "Page") {
|
|
14709
|
+
if (isRef(nodeVal)) refs.push(nodeVal);
|
|
14710
|
+
return;
|
|
14711
|
+
}
|
|
14712
|
+
const kids = node.get("Kids");
|
|
14713
|
+
if (isArray(kids)) {
|
|
14714
|
+
for (const k of kids) walk(k, depth + 1);
|
|
14715
|
+
}
|
|
14716
|
+
};
|
|
14717
|
+
walk(catalog.get("Pages") ?? null, 0);
|
|
14718
|
+
_pageRefs = refs;
|
|
14719
|
+
return refs;
|
|
14720
|
+
}
|
|
14303
14721
|
function decodeStreamData(stream) {
|
|
14304
14722
|
let data = stream.data;
|
|
14305
14723
|
const filterName = dictGetName(stream.dict, "Filter");
|
|
@@ -14351,10 +14769,107 @@ function openPdf(bytes) {
|
|
|
14351
14769
|
const info = resolveValue2(infoRef);
|
|
14352
14770
|
return isDict(info) ? info : null;
|
|
14353
14771
|
},
|
|
14772
|
+
getPageLabels() {
|
|
14773
|
+
const catalog = getCatalog();
|
|
14774
|
+
const plVal = resolveValue2(catalog.get("PageLabels") ?? null);
|
|
14775
|
+
if (!isDict(plVal)) return null;
|
|
14776
|
+
const entries = /* @__PURE__ */ new Map();
|
|
14777
|
+
collectNumberTree(plVal, resolveValue2, entries);
|
|
14778
|
+
if (entries.size === 0) return null;
|
|
14779
|
+
const ranges = [];
|
|
14780
|
+
for (const startPage of [...entries.keys()].sort((a, b) => a - b)) {
|
|
14781
|
+
const dict = resolveValue2(entries.get(startPage) ?? null);
|
|
14782
|
+
if (!isDict(dict)) continue;
|
|
14783
|
+
const range = { startPage };
|
|
14784
|
+
const sOp = dictGetName(dict, "S");
|
|
14785
|
+
range.style = sOp === void 0 ? "none" : STYLE_FROM_OP[sOp] ?? "none";
|
|
14786
|
+
const prefix = dict.get("P");
|
|
14787
|
+
if (typeof prefix === "string") range.prefix = prefix;
|
|
14788
|
+
const start = dictGetNum(dict, "St");
|
|
14789
|
+
if (start !== void 0) range.start = start;
|
|
14790
|
+
ranges.push(range);
|
|
14791
|
+
}
|
|
14792
|
+
return ranges.length > 0 ? ranges : null;
|
|
14793
|
+
},
|
|
14794
|
+
getAnnotations(pageIndex) {
|
|
14795
|
+
const pages = collectPages();
|
|
14796
|
+
if (pageIndex < 0 || pageIndex >= pages.length) return [];
|
|
14797
|
+
const annotsVal = resolveValue2(pages[pageIndex].get("Annots") ?? null);
|
|
14798
|
+
if (!isArray(annotsVal)) return [];
|
|
14799
|
+
const out = [];
|
|
14800
|
+
for (const a of annotsVal) {
|
|
14801
|
+
const d = resolveValue2(a);
|
|
14802
|
+
if (!isDict(d)) continue;
|
|
14803
|
+
const subtype = dictGetName(d, "Subtype") ?? "";
|
|
14804
|
+
const rectVal = resolveValue2(d.get("Rect") ?? null);
|
|
14805
|
+
let rect = null;
|
|
14806
|
+
if (isArray(rectVal) && rectVal.length === 4 && rectVal.every((n2) => typeof n2 === "number")) {
|
|
14807
|
+
rect = [rectVal[0], rectVal[1], rectVal[2], rectVal[3]];
|
|
14808
|
+
}
|
|
14809
|
+
const parsed = { subtype, rect };
|
|
14810
|
+
const contents = d.get("Contents");
|
|
14811
|
+
if (typeof contents === "string") parsed.contents = decodePdfTextString(contents);
|
|
14812
|
+
const title = d.get("T");
|
|
14813
|
+
if (typeof title === "string") parsed.title = decodePdfTextString(title);
|
|
14814
|
+
const c = resolveValue2(d.get("C") ?? null);
|
|
14815
|
+
if (isArray(c)) {
|
|
14816
|
+
const nums = c.filter((x) => typeof x === "number");
|
|
14817
|
+
if (nums.length > 0) parsed.color = nums;
|
|
14818
|
+
}
|
|
14819
|
+
const qp = resolveValue2(d.get("QuadPoints") ?? null);
|
|
14820
|
+
if (isArray(qp)) {
|
|
14821
|
+
parsed.quadPoints = qp.filter((x) => typeof x === "number");
|
|
14822
|
+
}
|
|
14823
|
+
const action = resolveValue2(d.get("A") ?? null);
|
|
14824
|
+
if (isDict(action)) {
|
|
14825
|
+
const uri = action.get("URI");
|
|
14826
|
+
if (typeof uri === "string") parsed.url = uri;
|
|
14827
|
+
}
|
|
14828
|
+
out.push(parsed);
|
|
14829
|
+
}
|
|
14830
|
+
return out;
|
|
14831
|
+
},
|
|
14832
|
+
getPageRef(pageIndex) {
|
|
14833
|
+
const refs = collectPageRefs();
|
|
14834
|
+
return pageIndex >= 0 && pageIndex < refs.length ? refs[pageIndex] : null;
|
|
14835
|
+
},
|
|
14354
14836
|
decodeStream: decodeStreamData,
|
|
14355
14837
|
getObject
|
|
14356
14838
|
};
|
|
14357
14839
|
}
|
|
14840
|
+
function decodePdfTextString(raw) {
|
|
14841
|
+
if (raw.length >= 2 && raw.charCodeAt(0) === 254 && raw.charCodeAt(1) === 255) {
|
|
14842
|
+
let out = "";
|
|
14843
|
+
for (let i = 2; i + 1 < raw.length; i += 2) {
|
|
14844
|
+
out += String.fromCharCode(raw.charCodeAt(i) << 8 | raw.charCodeAt(i + 1));
|
|
14845
|
+
}
|
|
14846
|
+
return out;
|
|
14847
|
+
}
|
|
14848
|
+
return raw;
|
|
14849
|
+
}
|
|
14850
|
+
var STYLE_FROM_OP = {
|
|
14851
|
+
D: "decimal",
|
|
14852
|
+
r: "roman",
|
|
14853
|
+
R: "Roman",
|
|
14854
|
+
a: "alpha",
|
|
14855
|
+
A: "Alpha"
|
|
14856
|
+
};
|
|
14857
|
+
function collectNumberTree(node, resolve, out) {
|
|
14858
|
+
const nums = resolve(node.get("Nums") ?? null);
|
|
14859
|
+
if (isArray(nums)) {
|
|
14860
|
+
for (let i = 0; i + 1 < nums.length; i += 2) {
|
|
14861
|
+
const key = resolve(nums[i]);
|
|
14862
|
+
if (typeof key === "number") out.set(key, nums[i + 1]);
|
|
14863
|
+
}
|
|
14864
|
+
}
|
|
14865
|
+
const kids = resolve(node.get("Kids") ?? null);
|
|
14866
|
+
if (isArray(kids)) {
|
|
14867
|
+
for (const kid of kids) {
|
|
14868
|
+
const kd = resolve(kid);
|
|
14869
|
+
if (isDict(kd)) collectNumberTree(kd, resolve, out);
|
|
14870
|
+
}
|
|
14871
|
+
}
|
|
14872
|
+
}
|
|
14358
14873
|
function flattenPageTree(node, resolve, pages) {
|
|
14359
14874
|
const type = dictGetName(node, "Type");
|
|
14360
14875
|
if (type === "Page") {
|
|
@@ -14489,6 +15004,21 @@ function createModifier(reader) {
|
|
|
14489
15004
|
if (modified.has(num)) return modified.get(num) ?? null;
|
|
14490
15005
|
return reader.getObject(num);
|
|
14491
15006
|
}
|
|
15007
|
+
function addAnnotation(pageIndex, annotationBody) {
|
|
15008
|
+
const pageRef = reader.getPageRef(pageIndex);
|
|
15009
|
+
if (!pageRef) throw new Error(`addAnnotation: no page at index ${pageIndex}`);
|
|
15010
|
+
const objNum = addRawObject(annotationBody);
|
|
15011
|
+
const page = getObject(pageRef.num);
|
|
15012
|
+
if (!isDict(page)) throw new Error(`addAnnotation: page ${pageIndex} is not a dictionary`);
|
|
15013
|
+
const clone = new Map(page);
|
|
15014
|
+
const existing = clone.get("Annots");
|
|
15015
|
+
const resolved = isRef(existing) ? reader.resolveValue(existing) : existing;
|
|
15016
|
+
const annots = isArray(resolved) ? [...resolved] : [];
|
|
15017
|
+
annots.push({ type: "ref", num: objNum, gen: 0 });
|
|
15018
|
+
clone.set("Annots", annots);
|
|
15019
|
+
setObject(pageRef.num, clone);
|
|
15020
|
+
return objNum;
|
|
15021
|
+
}
|
|
14492
15022
|
function save() {
|
|
14493
15023
|
if (modified.size === 0) {
|
|
14494
15024
|
return reader.bytes;
|
|
@@ -14534,6 +15064,7 @@ ${xrefOffset}
|
|
|
14534
15064
|
setObject,
|
|
14535
15065
|
addObject,
|
|
14536
15066
|
addRawObject,
|
|
15067
|
+
addAnnotation,
|
|
14537
15068
|
getObject,
|
|
14538
15069
|
save,
|
|
14539
15070
|
get nextObjNum() {
|
|
@@ -16173,6 +16704,8 @@ exports.WORKER_TIMEOUT_MS = WORKER_TIMEOUT_MS;
|
|
|
16173
16704
|
exports.addSignaturePlaceholder = addSignaturePlaceholder;
|
|
16174
16705
|
exports.applyDecodeFilter = applyDecodeFilter;
|
|
16175
16706
|
exports.buildAcroFormDict = buildAcroFormDict;
|
|
16707
|
+
exports.buildAnnotation = buildAnnotation;
|
|
16708
|
+
exports.buildAnnotationBody = buildAnnotationBody;
|
|
16176
16709
|
exports.buildAppearanceStreamDict = buildAppearanceStreamDict;
|
|
16177
16710
|
exports.buildCmsSignedData = buildCmsSignedData;
|
|
16178
16711
|
exports.buildDocumentPDF = buildDocumentPDF;
|
|
@@ -16207,6 +16740,7 @@ exports.containsDevanagari = containsDevanagari;
|
|
|
16207
16740
|
exports.containsEthiopic = containsEthiopic;
|
|
16208
16741
|
exports.containsHebrew = containsHebrew;
|
|
16209
16742
|
exports.containsKhmer = containsKhmer;
|
|
16743
|
+
exports.containsMath = containsMath;
|
|
16210
16744
|
exports.containsMyanmar = containsMyanmar;
|
|
16211
16745
|
exports.containsRTL = containsRTL;
|
|
16212
16746
|
exports.containsSinhala = containsSinhala;
|
|
@@ -16271,6 +16805,7 @@ exports.inflateSync = inflateSync;
|
|
|
16271
16805
|
exports.initCrypto = initCrypto;
|
|
16272
16806
|
exports.initNodeCompression = initNodeCompression;
|
|
16273
16807
|
exports.initNodeDecompression_parser = initNodeDecompression;
|
|
16808
|
+
exports.inspectDocumentLayout = inspectDocumentLayout;
|
|
16274
16809
|
exports.isArmenianCodepoint = isArmenianCodepoint;
|
|
16275
16810
|
exports.isArray = isArray;
|
|
16276
16811
|
exports.isBengaliCodepoint = isBengaliCodepoint;
|
|
@@ -16281,6 +16816,7 @@ exports.isEthiopicCodepoint = isEthiopicCodepoint;
|
|
|
16281
16816
|
exports.isGeorgianCodepoint = isGeorgianCodepoint;
|
|
16282
16817
|
exports.isKhmerCodepoint = isKhmerCodepoint;
|
|
16283
16818
|
exports.isLinkAnnotation = isLinkAnnotation;
|
|
16819
|
+
exports.isMathCodepoint = isMathCodepoint;
|
|
16284
16820
|
exports.isMyanmarCodepoint = isMyanmarCodepoint;
|
|
16285
16821
|
exports.isName = isName;
|
|
16286
16822
|
exports.isRef = isRef;
|