renderpdf-js 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +204 -0
- package/README.md +71 -10
- package/dist/compose-pdf.d.ts +26 -0
- package/dist/document-colors.d.ts +8 -0
- package/dist/document-page.d.ts +115 -0
- package/dist/document-types.d.ts +135 -0
- package/dist/document.d.ts +64 -0
- package/dist/fonts.d.ts +4 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +2051 -552
- package/dist/jspdf-adapter.d.ts +159 -0
- package/package.json +8 -3
package/dist/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import e from "@pdf-lib/fontkit";
|
|
2
|
-
import { PDFArray as t, PDFDict as n, PDFDocument as r, PDFHexString as i, PDFName as a,
|
|
3
|
-
import { toPng as
|
|
2
|
+
import { PDFArray as t, PDFDict as n, PDFDocument as r, PDFHexString as i, PDFName as a, PDFNumber as o, PDFRef as s, PDFString as c, StandardFonts as l, TextRenderingMode as u, appendBezierCurve as d, beginText as f, breakTextIntoLines as p, clip as m, clipEvenOdd as h, closePath as g, concatTransformationMatrix as _, degrees as v, drawObject as y, endPath as b, endText as x, fill as S, fillAndStroke as C, lineTo as w, moveTo as ee, popGraphicsState as T, pushGraphicsState as E, rectangle as te, rgb as ne, setFillingColor as re, setFontAndSize as ie, setGraphicsState as ae, setLineWidth as oe, setStrokingColor as se, setTextMatrix as ce, setTextRenderingMode as le, showText as ue, stroke as de } from "pdf-lib";
|
|
3
|
+
import { toPng as fe } from "html-to-image";
|
|
4
4
|
// src/diagnostics.ts
|
|
5
|
-
var
|
|
5
|
+
var D = class extends Error {
|
|
6
6
|
code;
|
|
7
7
|
constructor(e, t, n) {
|
|
8
8
|
super(t, n), this.code = e, this.name = "RenderPDFError";
|
|
9
9
|
}
|
|
10
10
|
};
|
|
11
|
-
function
|
|
11
|
+
function O(e) {
|
|
12
12
|
if (e?.aborted) throw new DOMException("PDF rendering was cancelled.", "AbortError");
|
|
13
13
|
}
|
|
14
14
|
// src/breaks.ts
|
|
15
|
-
var
|
|
15
|
+
var pe = /* @__PURE__ */ new Set([
|
|
16
16
|
"block",
|
|
17
17
|
"flow-root",
|
|
18
18
|
"flex",
|
|
@@ -24,14 +24,14 @@ var E = /* @__PURE__ */ new Set([
|
|
|
24
24
|
"table-header-group",
|
|
25
25
|
"table-footer-group"
|
|
26
26
|
]);
|
|
27
|
-
function
|
|
27
|
+
function me(e, t) {
|
|
28
28
|
let n = e.getPropertyValue(`break-${t}`).trim(), r = e.getPropertyValue(`page-break-${t}`).trim();
|
|
29
29
|
return n && n !== "auto" ? n : r || n || "auto";
|
|
30
30
|
}
|
|
31
|
-
function
|
|
32
|
-
if (e !== "auto" && e !== "avoid" && e !== "avoid-page" && (t === "inside" || e !== "page" && e !== "always")) throw new
|
|
31
|
+
function he(e, t) {
|
|
32
|
+
if (e !== "auto" && e !== "avoid" && e !== "avoid-page" && (t === "inside" || e !== "page" && e !== "always")) throw new D("UNSUPPORTED_CSS", `Unsupported CSS break-${t}: ${e}; only page/always boundaries and avoid/avoid-page preferences are supported.`);
|
|
33
33
|
}
|
|
34
|
-
function
|
|
34
|
+
function ge(e, t) {
|
|
35
35
|
let n = e.getBoundingClientRect();
|
|
36
36
|
return {
|
|
37
37
|
x: n.left - t.left,
|
|
@@ -40,20 +40,20 @@ function ee(e, t) {
|
|
|
40
40
|
height: n.height
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
function
|
|
43
|
+
function _e(e) {
|
|
44
44
|
let t = getComputedStyle(e), n = e.getBoundingClientRect();
|
|
45
|
-
return t.visibility === "visible" &&
|
|
45
|
+
return t.visibility === "visible" && pe.has(t.display) && n.width > 0 && n.height > 0;
|
|
46
46
|
}
|
|
47
|
-
function
|
|
47
|
+
function ve(e, t) {
|
|
48
48
|
let n = t === "previous" ? e.previousElementSibling : e.nextElementSibling;
|
|
49
49
|
for (; n;) {
|
|
50
50
|
if (!(n instanceof HTMLElement)) return;
|
|
51
51
|
let e = getComputedStyle(n);
|
|
52
|
-
if (e.display !== "none" && e.visibility === "visible") return
|
|
52
|
+
if (e.display !== "none" && e.visibility === "visible") return _e(n) ? n : void 0;
|
|
53
53
|
n = t === "previous" ? n.previousElementSibling : n.nextElementSibling;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
-
function
|
|
56
|
+
function ye(e, t) {
|
|
57
57
|
let n = Math.min(e.x, t.x), r = Math.min(e.y, t.y);
|
|
58
58
|
return {
|
|
59
59
|
x: n,
|
|
@@ -62,8 +62,8 @@ function re(e, t) {
|
|
|
62
62
|
height: Math.max(e.y + e.height, t.y + t.height) - r
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
|
-
function
|
|
66
|
-
if (!e.isConnected || e.ownerDocument !== document) throw new
|
|
65
|
+
function be(e, t) {
|
|
66
|
+
if (!e.isConnected || e.ownerDocument !== document) throw new D("INVALID_SOURCE", "CSS page-break collection requires a connected source in the current document.");
|
|
67
67
|
let n = e.getBoundingClientRect(), r = t.operations.filter((e) => e.kind === "raster"), i = /* @__PURE__ */ new Map(), a = [];
|
|
68
68
|
for (let t of [e, ...e.querySelectorAll("*")]) {
|
|
69
69
|
if (!(t instanceof HTMLElement)) continue;
|
|
@@ -71,25 +71,25 @@ function ie(e, t) {
|
|
|
71
71
|
if (e.display === "none" || e.visibility !== "visible") continue;
|
|
72
72
|
let o = t.getBoundingClientRect();
|
|
73
73
|
if (o.width === 0 && o.height === 0 && t.getClientRects().length === 0) continue;
|
|
74
|
-
let s =
|
|
75
|
-
|
|
74
|
+
let s = me(e, "before"), c = me(e, "after"), l = me(e, "inside");
|
|
75
|
+
he(s, "before"), he(c, "after"), he(l, "inside");
|
|
76
76
|
let u = r.find((e) => e.element.contains(t));
|
|
77
|
-
if (!u &&
|
|
77
|
+
if (!u && pe.has(e.display) && (e.widows && e.widows !== "2" || e.orphans && e.orphans !== "2")) throw new D("UNSUPPORTED_CSS", "Nondefault CSS widows/orphans are unsupported; this renderer preserves measured text lines without a line-count pagination policy.");
|
|
78
78
|
if (s === "auto" && c === "auto" && l === "auto") continue;
|
|
79
79
|
let d = s === "page" || s === "always", f = c === "page" || c === "always";
|
|
80
80
|
if (u && u.element !== t) {
|
|
81
|
-
if (d || f) throw new
|
|
81
|
+
if (d || f) throw new D("PAGINATION_FAILED", "A forced CSS page break lies inside an atomic raster region; move the break outside that region.");
|
|
82
82
|
continue;
|
|
83
83
|
}
|
|
84
|
-
if (!
|
|
85
|
-
let p =
|
|
84
|
+
if (!pe.has(e.display)) throw new D("UNSUPPORTED_CSS", "Explicit CSS page breaks require a block, table group or table row; inline fragments and table cells are unsupported.");
|
|
85
|
+
let p = ge(t, n);
|
|
86
86
|
d && a.push(p.y), f && a.push(p.y + p.height), l !== "auto" && !u && i.set(`${p.x}:${p.y}:${p.width}:${p.height}`, p);
|
|
87
87
|
for (let e of ["previous", "next"]) {
|
|
88
88
|
let r = e === "previous" ? s : c;
|
|
89
89
|
if (r !== "avoid" && r !== "avoid-page") continue;
|
|
90
|
-
let a =
|
|
90
|
+
let a = ve(t, e);
|
|
91
91
|
if (!a) continue;
|
|
92
|
-
let o =
|
|
92
|
+
let o = ye(p, ge(a, n));
|
|
93
93
|
i.set(`${o.x}:${o.y}:${o.width}:${o.height}`, o);
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -99,15 +99,15 @@ function ie(e, t) {
|
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
// src/export-options.ts
|
|
102
|
-
function
|
|
102
|
+
function k(e) {
|
|
103
103
|
if (e === void 0) return;
|
|
104
|
-
if (!e || typeof e != "object" || Array.isArray(e)) throw new
|
|
104
|
+
if (!e || typeof e != "object" || Array.isArray(e)) throw new D("INVALID_OPTIONS", "PDF metadata must be an object.");
|
|
105
105
|
let { title: t, author: n, subject: r, keywords: i } = e;
|
|
106
106
|
if ([
|
|
107
107
|
t,
|
|
108
108
|
n,
|
|
109
109
|
r
|
|
110
|
-
].some((e) => e !== void 0 && typeof e != "string") || i !== void 0 && (!Array.isArray(i) || Array.from(i).some((e) => typeof e != "string"))) throw new
|
|
110
|
+
].some((e) => e !== void 0 && typeof e != "string") || i !== void 0 && (!Array.isArray(i) || Array.from(i).some((e) => typeof e != "string"))) throw new D("INVALID_OPTIONS", "PDF metadata title, author and subject must be strings; keywords must be an array of strings.");
|
|
111
111
|
return Object.freeze({
|
|
112
112
|
...t === void 0 ? {} : { title: t },
|
|
113
113
|
...n === void 0 ? {} : { author: n },
|
|
@@ -115,11 +115,11 @@ function ae(e) {
|
|
|
115
115
|
...i === void 0 ? {} : { keywords: Object.freeze([...i]) }
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
|
-
function
|
|
118
|
+
function A(e, t) {
|
|
119
119
|
e.setTitle(t?.title ?? "RenderPDF.js"), t?.author !== void 0 && e.setAuthor(t.author), t?.subject !== void 0 && e.setSubject(t.subject), t?.keywords !== void 0 && e.setKeywords([...t.keywords]);
|
|
120
120
|
}
|
|
121
121
|
// src/fonts.ts
|
|
122
|
-
var
|
|
122
|
+
var xe = /* @__PURE__ */ new WeakMap(), Se = /* @__PURE__ */ new WeakMap(), Ce = /* @__PURE__ */ new Set([
|
|
123
123
|
"serif",
|
|
124
124
|
"sans-serif",
|
|
125
125
|
"monospace",
|
|
@@ -139,40 +139,40 @@ var se = /* @__PURE__ */ new WeakMap(), ce = /* @__PURE__ */ new WeakMap(), le =
|
|
|
139
139
|
"revert",
|
|
140
140
|
"revert-layer"
|
|
141
141
|
]);
|
|
142
|
-
function
|
|
143
|
-
if (e.byteLength < 12) throw new
|
|
142
|
+
function we(e) {
|
|
143
|
+
if (e.byteLength < 12) throw new D("FONT_LOAD_FAILED", "Provide a complete static TTF/OTF font program.");
|
|
144
144
|
let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n = t.getUint32(0);
|
|
145
|
-
if (n !== 65536 && n !== 1330926671) throw new
|
|
145
|
+
if (n !== 65536 && n !== 1330926671) throw new D("FONT_LOAD_FAILED", "Only static TTF/OTF programs are supported; WOFF fonts and font collections are unsupported.");
|
|
146
146
|
let r = t.getUint16(4);
|
|
147
|
-
if (r === 0 || 12 + r * 16 > e.byteLength) throw new
|
|
148
|
-
for (let e = 0; e < r; e += 1) if (t.getUint32(12 + e * 16) === 1719034226) throw new
|
|
147
|
+
if (r === 0 || 12 + r * 16 > e.byteLength) throw new D("FONT_LOAD_FAILED", "The TTF/OTF font table directory is incomplete.");
|
|
148
|
+
for (let e = 0; e < r; e += 1) if (t.getUint32(12 + e * 16) === 1719034226) throw new D("FONT_LOAD_FAILED", "Variable fonts are unsupported. Provide an explicitly generated static TTF/OTF instance.");
|
|
149
149
|
}
|
|
150
|
-
function
|
|
150
|
+
function Te(e, t, n, r, i) {
|
|
151
151
|
for (let a of e.fonts) {
|
|
152
152
|
if (a === i || a.family.replace(/^["']|["']$/g, "").toLowerCase() !== t.toLowerCase() || a.style !== r) continue;
|
|
153
153
|
let e = a.weight === "normal" ? [400] : a.weight === "bold" ? [700] : a.weight.split(/\s+/).map(Number);
|
|
154
|
-
if (e[0] === n || e.length === 2 && n >= e[0] && n <= e[1]) throw new
|
|
154
|
+
if (e[0] === n || e.length === 2 && n >= e[0] && n <= e[1]) throw new D("INVALID_OPTIONS", `Font ${t} ${n} ${r} conflicts with an existing browser font face. Choose a family owned by this registration.`);
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
|
-
function
|
|
157
|
+
function Ee(e) {
|
|
158
158
|
for (let t of e) {
|
|
159
|
-
let e = t && typeof t == "object" ?
|
|
160
|
-
if (!e || typeof document > "u" || e.document !== document || !document.fonts.has(e.face)) throw new
|
|
161
|
-
|
|
159
|
+
let e = t && typeof t == "object" ? Se.get(t) : void 0;
|
|
160
|
+
if (!e || typeof document > "u" || e.document !== document || !document.fonts.has(e.face)) throw new D("MISSING_FONT", "Provide font handles returned by registerFont() whose browser faces remain registered in the current document.");
|
|
161
|
+
Te(document, t.family, t.weight, t.style, e.face);
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
|
-
async function
|
|
165
|
-
if (!e || typeof e != "object" || typeof e.family != "string") throw new
|
|
164
|
+
async function De(e) {
|
|
165
|
+
if (!e || typeof e != "object" || typeof e.family != "string") throw new D("INVALID_OPTIONS", "Font registration requires a CSS family and font bytes.");
|
|
166
166
|
let t = e.family.trim(), n = e.weight ?? 400, r = e.style ?? "normal";
|
|
167
|
-
if (!t || !/^[\w -]+$/.test(t) ||
|
|
168
|
-
if (typeof document > "u" || typeof FontFace > "u" || !document.fonts) throw new
|
|
167
|
+
if (!t || !/^[\w -]+$/.test(t) || Ce.has(t.toLowerCase()) || !Number.isInteger(n) || n < 1 || n > 1e3 || r !== "normal" && r !== "italic" || !(e.data instanceof Uint8Array) && !(e.data instanceof ArrayBuffer) || e.data.byteLength === 0) throw new D("INVALID_OPTIONS", "Provide a plain custom CSS family (letters, digits, spaces, hyphens, or underscores), nonempty TTF/OTF bytes, integer weight from 1 to 1000, and normal or italic style.");
|
|
168
|
+
if (typeof document > "u" || typeof FontFace > "u" || !document.fonts) throw new D("FONT_LOAD_FAILED", "Font registration requires a browser document with FontFace support.");
|
|
169
169
|
let i = new Uint8Array(e.data instanceof Uint8Array ? e.data : new Uint8Array(e.data));
|
|
170
|
-
|
|
171
|
-
let a = `${t.toLowerCase()}:${n}:${r}`, o = document, s =
|
|
172
|
-
s || (s = /* @__PURE__ */ new Map(),
|
|
170
|
+
we(i);
|
|
171
|
+
let a = `${t.toLowerCase()}:${n}:${r}`, o = document, s = xe.get(o);
|
|
172
|
+
s || (s = /* @__PURE__ */ new Map(), xe.set(o, s));
|
|
173
173
|
let c = s.get(a);
|
|
174
|
-
if (
|
|
175
|
-
if (c.bytes.length !== i.length || c.bytes.some((e, t) => e !== i[t])) throw new
|
|
174
|
+
if (Te(o, t, n, r, c?.face), c) {
|
|
175
|
+
if (c.bytes.length !== i.length || c.bytes.some((e, t) => e !== i[t])) throw new D("INVALID_OPTIONS", `Font ${t} ${n} ${r} is already registered with different bytes.`);
|
|
176
176
|
return c.promise;
|
|
177
177
|
}
|
|
178
178
|
async function l() {
|
|
@@ -181,7 +181,7 @@ async function de(e) {
|
|
|
181
181
|
weight: String(n),
|
|
182
182
|
style: r
|
|
183
183
|
});
|
|
184
|
-
await e.load(),
|
|
184
|
+
await e.load(), Te(o, t, n, r), o.fonts.add(e), d.face = e;
|
|
185
185
|
let a = Object.freeze({
|
|
186
186
|
family: t,
|
|
187
187
|
weight: n,
|
|
@@ -190,12 +190,12 @@ async function de(e) {
|
|
|
190
190
|
return i.slice();
|
|
191
191
|
}
|
|
192
192
|
});
|
|
193
|
-
return
|
|
193
|
+
return Se.set(a, {
|
|
194
194
|
document: o,
|
|
195
195
|
face: e
|
|
196
196
|
}), a;
|
|
197
197
|
} catch (e) {
|
|
198
|
-
throw s.delete(a), e instanceof
|
|
198
|
+
throw s.delete(a), e instanceof D ? e : new D("FONT_LOAD_FAILED", `Could not load font ${t} ${n} ${r}.`, { cause: e });
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
201
|
let u = Promise.resolve().then(l), d = {
|
|
@@ -205,8 +205,8 @@ async function de(e) {
|
|
|
205
205
|
return s.set(a, d), u;
|
|
206
206
|
}
|
|
207
207
|
// src/planner.ts
|
|
208
|
-
var
|
|
209
|
-
function
|
|
208
|
+
var Oe = /^data:image\/(?:png|jpeg|gif|webp|avif);base64,[a-z\d+/=\s]+$/i;
|
|
209
|
+
function ke(e) {
|
|
210
210
|
let t = 0, n = "", r = 0, i = [];
|
|
211
211
|
for (let a = 0; a < e.length; a += 1) {
|
|
212
212
|
let o = e[a];
|
|
@@ -214,23 +214,23 @@ function pe(e) {
|
|
|
214
214
|
}
|
|
215
215
|
return i.push(e.slice(r).trim()), i;
|
|
216
216
|
}
|
|
217
|
-
function
|
|
217
|
+
function Ae(e) {
|
|
218
218
|
let t = [];
|
|
219
219
|
if (e.backgroundImage !== "none") {
|
|
220
|
-
for (let t of
|
|
220
|
+
for (let t of ke(e.backgroundImage)) {
|
|
221
221
|
if (/^(?:repeating-)?(?:linear|radial|conic)-gradient\(/i.test(t)) continue;
|
|
222
222
|
let e = t.match(/^url\(\s*(["']?)(.*?)\1\s*\)$/i)?.[2];
|
|
223
|
-
if (!e || !
|
|
223
|
+
if (!e || !Oe.test(e)) throw new D("UNSUPPORTED_CSS", "Unsupported CSS: automatic raster backgrounds require gradients or inline bitmap URLs.");
|
|
224
224
|
}
|
|
225
225
|
t.push("background-image");
|
|
226
226
|
}
|
|
227
227
|
if (e.borderRadius !== "0px" && t.push("border-radius"), e.boxShadow !== "none") {
|
|
228
|
-
if (
|
|
228
|
+
if (ke(e.boxShadow).some((e) => !/\binset\b/.test(e))) throw new D("UNSUPPORTED_CSS", "Unsupported CSS: outer shadows require expanded capture bounds; only inset shadows can fall back automatically.");
|
|
229
229
|
t.push("inset box-shadow");
|
|
230
230
|
}
|
|
231
231
|
return e.opacity !== "1" && t.push("opacity"), t.length ? t.join(", ") : void 0;
|
|
232
232
|
}
|
|
233
|
-
function
|
|
233
|
+
function je(e, t) {
|
|
234
234
|
if (!(e instanceof HTMLImageElement) && ![
|
|
235
235
|
"block",
|
|
236
236
|
"flow-root",
|
|
@@ -239,16 +239,16 @@ function he(e, t) {
|
|
|
239
239
|
"inline-flex",
|
|
240
240
|
"grid",
|
|
241
241
|
"inline-grid"
|
|
242
|
-
].includes(t.display)) throw new
|
|
243
|
-
if (Array.from(e.getClientRects()).filter((e) => e.width > 0 && e.height > 0).length !== 1) throw new
|
|
242
|
+
].includes(t.display)) throw new D("UNSUPPORTED_CSS", "Automatic raster fallback requires a rectangular block, flex, grid, inline-block, or image boundary; wrap inline or table-internal effects in a supported block.");
|
|
243
|
+
if (Array.from(e.getClientRects()).filter((e) => e.width > 0 && e.height > 0).length !== 1) throw new D("UNSUPPORTED_CSS", "Automatic raster fallback cannot capture fragmented inline or multi-column regions.");
|
|
244
244
|
}
|
|
245
245
|
// src/table-borders.ts
|
|
246
246
|
var j = .001;
|
|
247
|
-
function
|
|
247
|
+
function Me(e, t) {
|
|
248
248
|
let n = (e) => e.style === "hidden" ? 2 : +(e.style === "solid" && e.width > 0);
|
|
249
249
|
return n(e) - n(t) || e.width - t.width || Number(e.owner === "cell") - Number(t.owner === "cell") || (e.direction === t.direction ? e.direction === "vertical" ? t.column - e.column || t.row - e.row : t.row - e.row || t.column - e.column : Number(e.direction === "horizontal") - Number(t.direction === "horizontal"));
|
|
250
250
|
}
|
|
251
|
-
function
|
|
251
|
+
function Ne(e) {
|
|
252
252
|
let t = /* @__PURE__ */ new Map();
|
|
253
253
|
for (let n of e) {
|
|
254
254
|
if (![
|
|
@@ -256,7 +256,7 @@ function ge(e) {
|
|
|
256
256
|
n.start,
|
|
257
257
|
n.end,
|
|
258
258
|
n.width
|
|
259
|
-
].every(Number.isFinite) || n.width < 0 || n.end <= n.start) throw new
|
|
259
|
+
].every(Number.isFinite) || n.width < 0 || n.end <= n.start) throw new D("INVALID_SOURCE", "Collapsed border geometry must be finite and positive.");
|
|
260
260
|
let e = `${n.direction}:${n.position.toFixed(4)}`, r = t.get(e) ?? [];
|
|
261
261
|
r.push(n), t.set(e, r);
|
|
262
262
|
}
|
|
@@ -282,7 +282,7 @@ function ge(e) {
|
|
|
282
282
|
for (let e of s.starts) i.add(e);
|
|
283
283
|
if (o - a <= j) continue;
|
|
284
284
|
let c;
|
|
285
|
-
for (let e of i) (!c ||
|
|
285
|
+
for (let e of i) (!c || Me(e, c) > 0) && (c = e);
|
|
286
286
|
c?.style === "solid" && c.width > 0 && n.push({
|
|
287
287
|
...c,
|
|
288
288
|
start: a,
|
|
@@ -292,7 +292,7 @@ function ge(e) {
|
|
|
292
292
|
}
|
|
293
293
|
return n;
|
|
294
294
|
}
|
|
295
|
-
function
|
|
295
|
+
function Pe(e, t) {
|
|
296
296
|
let n = Math.max(e.x, t.x), r = Math.min(e.x + e.width, t.x + t.width), i = Math.max(e.y, t.y), a = Math.min(e.y + e.height, t.y + t.height);
|
|
297
297
|
return r <= n + j || a <= i + j ? [e] : [
|
|
298
298
|
{
|
|
@@ -321,7 +321,7 @@ function _e(e, t) {
|
|
|
321
321
|
}
|
|
322
322
|
].filter((e) => e.width > j && e.height > j);
|
|
323
323
|
}
|
|
324
|
-
function
|
|
324
|
+
function Fe(e) {
|
|
325
325
|
let t = [], n = /* @__PURE__ */ new Map();
|
|
326
326
|
for (let t of e) {
|
|
327
327
|
let e = `${t.direction}:${t.position.toFixed(4)}`, r = n.get(e) ?? [];
|
|
@@ -332,7 +332,7 @@ function ve(e) {
|
|
|
332
332
|
let t = [];
|
|
333
333
|
for (let n = Math.floor(e.x / 64); n <= Math.floor((e.x + e.width) / 64); n += 1) for (let r = Math.floor(e.y / 64); r <= Math.floor((e.y + e.height) / 64); r += 1) t.push(`${n}:${r}`);
|
|
334
334
|
return t;
|
|
335
|
-
}, a = [...e].sort((e, t) =>
|
|
335
|
+
}, a = [...e].sort((e, t) => Me(t, e));
|
|
336
336
|
for (let e of a) {
|
|
337
337
|
let a = (t) => {
|
|
338
338
|
let r = e.direction === "horizontal" ? "vertical" : "horizontal", i = n.get(`${r}:${t.toFixed(4)}`) ?? [], a = 0, o = i.length;
|
|
@@ -358,7 +358,7 @@ function ve(e) {
|
|
|
358
358
|
width: e.width,
|
|
359
359
|
height: s - o
|
|
360
360
|
}], l = new Set(i(c[0]).flatMap((e) => r.get(e) ?? []));
|
|
361
|
-
for (let e of l) if (c = c.flatMap((t) =>
|
|
361
|
+
for (let e of l) if (c = c.flatMap((t) => Pe(t, e.bounds)), c.length === 0) break;
|
|
362
362
|
for (let n of c) {
|
|
363
363
|
let a = {
|
|
364
364
|
kind: "border",
|
|
@@ -376,7 +376,7 @@ function ve(e) {
|
|
|
376
376
|
}
|
|
377
377
|
return t;
|
|
378
378
|
}
|
|
379
|
-
function
|
|
379
|
+
function Ie(e, t) {
|
|
380
380
|
if (![
|
|
381
381
|
"TABLE",
|
|
382
382
|
"THEAD",
|
|
@@ -391,7 +391,7 @@ function ye(e, t) {
|
|
|
391
391
|
let n = e instanceof HTMLTableElement ? e : e.closest("table");
|
|
392
392
|
return n && (e === n ? t : getComputedStyle(n)).borderCollapse === "collapse" ? n : void 0;
|
|
393
393
|
}
|
|
394
|
-
function
|
|
394
|
+
function Le(e, t) {
|
|
395
395
|
if (!{
|
|
396
396
|
TABLE: ["table", "inline-table"],
|
|
397
397
|
THEAD: ["table-header-group"],
|
|
@@ -402,7 +402,7 @@ function be(e, t) {
|
|
|
402
402
|
TH: ["table-cell"],
|
|
403
403
|
COL: ["table-column"],
|
|
404
404
|
COLGROUP: ["table-column-group"]
|
|
405
|
-
}[e.tagName]?.includes(t.display)) throw new
|
|
405
|
+
}[e.tagName]?.includes(t.display)) throw new D("UNSUPPORTED_CSS", "Collapsed table parts require their native table-cell, table-row and table-group display modes.");
|
|
406
406
|
for (let n of [
|
|
407
407
|
"Top",
|
|
408
408
|
"Right",
|
|
@@ -414,16 +414,16 @@ function be(e, t) {
|
|
|
414
414
|
"solid",
|
|
415
415
|
"none",
|
|
416
416
|
"hidden"
|
|
417
|
-
].includes(r)) throw new
|
|
417
|
+
].includes(r)) throw new D("UNSUPPORTED_CSS", "Collapsed tables support only solid, none and hidden border styles.");
|
|
418
418
|
if (![
|
|
419
419
|
"TABLE",
|
|
420
420
|
"TD",
|
|
421
421
|
"TH"
|
|
422
|
-
].includes(e.tagName) && (r === "hidden" || i > 0)) throw new
|
|
422
|
+
].includes(e.tagName) && (r === "hidden" || i > 0)) throw new D("UNSUPPORTED_CSS", "Collapsed row, row-group, column and column-group border contributions are unsupported; put borders on cells or the table.");
|
|
423
423
|
}
|
|
424
424
|
}
|
|
425
|
-
function
|
|
426
|
-
if (e.parentElement?.closest("table") || e.querySelector("table") || e.caption || !["table", "inline-table"].includes(getComputedStyle(e).display)) throw new
|
|
425
|
+
function Re(e, t) {
|
|
426
|
+
if (e.parentElement?.closest("table") || e.querySelector("table") || e.caption || !["table", "inline-table"].includes(getComputedStyle(e).display)) throw new D("UNSUPPORTED_ELEMENT", "Native collapsed borders require a table without nested tables or captions.");
|
|
427
427
|
let n = [], r = Array.from(e.rows).flatMap((e) => Array.from(e.cells).filter((e) => {
|
|
428
428
|
let t = e.getBoundingClientRect();
|
|
429
429
|
return t.width > 0 && t.height > 0;
|
|
@@ -466,7 +466,7 @@ function xe(e, t) {
|
|
|
466
466
|
}
|
|
467
467
|
};
|
|
468
468
|
o(e, a), r.forEach((e, t) => o(e, i[t]));
|
|
469
|
-
let s =
|
|
469
|
+
let s = Ne(n), c = Fe(s), l = e.tHead?.getBoundingClientRect();
|
|
470
470
|
if (!l || l.height <= 0) return {
|
|
471
471
|
operations: c,
|
|
472
472
|
repeatSafe: !0
|
|
@@ -503,14 +503,14 @@ function xe(e, t) {
|
|
|
503
503
|
};
|
|
504
504
|
}
|
|
505
505
|
// src/layout.ts
|
|
506
|
-
var
|
|
507
|
-
function
|
|
506
|
+
var ze = new Intl.Segmenter("en", { granularity: "grapheme" });
|
|
507
|
+
function M(e, t) {
|
|
508
508
|
if (![
|
|
509
509
|
e.x,
|
|
510
510
|
e.y,
|
|
511
511
|
e.width,
|
|
512
512
|
e.height
|
|
513
|
-
].every(Number.isFinite)) throw new
|
|
513
|
+
].every(Number.isFinite)) throw new D("INVALID_SOURCE", "Browser geometry must contain only finite CSS pixel values.");
|
|
514
514
|
return {
|
|
515
515
|
x: e.left - t.left,
|
|
516
516
|
y: e.top - t.top,
|
|
@@ -518,11 +518,11 @@ function N(e, t) {
|
|
|
518
518
|
height: e.height
|
|
519
519
|
};
|
|
520
520
|
}
|
|
521
|
-
function
|
|
521
|
+
function Be(e) {
|
|
522
522
|
let t = e.getRootNode();
|
|
523
523
|
return e.parentElement ?? (t instanceof ShadowRoot && t.host instanceof HTMLElement ? t.host : null);
|
|
524
524
|
}
|
|
525
|
-
function
|
|
525
|
+
function Ve(e, t, n = !1, r = !1) {
|
|
526
526
|
let i = e instanceof HTMLImageElement, a = [
|
|
527
527
|
t.position !== "static" && `position: ${t.position}`,
|
|
528
528
|
t.zIndex !== "auto" && `z-index: ${t.zIndex}`,
|
|
@@ -564,8 +564,8 @@ function F(e, t, n = !1, r = !1) {
|
|
|
564
564
|
let n = getComputedStyle(e, t).content;
|
|
565
565
|
n !== "none" && n !== "normal" && a.push(`generated content ${t}`);
|
|
566
566
|
}
|
|
567
|
-
if (a.length > 0) throw new
|
|
568
|
-
if (e instanceof HTMLTableElement && !["separate", "collapse"].includes(t.borderCollapse)) throw new
|
|
567
|
+
if (a.length > 0) throw new D("UNSUPPORTED_CSS", `Unsupported CSS on ${e.tagName}: ${a.join(", ")}. Use a bounded data-raster subtree when safe.`);
|
|
568
|
+
if (e instanceof HTMLTableElement && !["separate", "collapse"].includes(t.borderCollapse)) throw new D("UNSUPPORTED_CSS", "Native table snapshots require separate or collapsed borders.");
|
|
569
569
|
if ([
|
|
570
570
|
"THEAD",
|
|
571
571
|
"TBODY",
|
|
@@ -573,17 +573,17 @@ function F(e, t, n = !1, r = !1) {
|
|
|
573
573
|
"TR",
|
|
574
574
|
"COL",
|
|
575
575
|
"COLGROUP"
|
|
576
|
-
].includes(e.tagName) && t.backgroundColor !== "rgba(0, 0, 0, 0)") throw new
|
|
576
|
+
].includes(e.tagName) && t.backgroundColor !== "rgba(0, 0, 0, 0)") throw new D("UNSUPPORTED_CSS", "Native table snapshots require transparent row-group, row, and column backgrounds.");
|
|
577
577
|
let o = [
|
|
578
578
|
"Top",
|
|
579
579
|
"Right",
|
|
580
580
|
"Bottom",
|
|
581
581
|
"Left"
|
|
582
582
|
], s = o.map((e) => t[`border${e}Width`]), c = o.map((e) => t[`border${e}Color`]), l = o.map((e) => t[`border${e}Style`]);
|
|
583
|
-
if (r &&
|
|
584
|
-
if (!n && (t.backgroundColor !== "rgba(0, 0, 0, 0)" || s[0] !== "0px") && Array.from(e.getClientRects()).filter((e) => e.width > 0 && e.height > 0).length > 1) throw new
|
|
583
|
+
if (r && Le(e, t), !r && (s.some((e) => e !== s[0]) || s[0] !== "0px" && (c.some((e) => e !== c[0]) || l.some((e) => e !== "solid")))) throw new D("UNSUPPORTED_CSS", "Unsupported CSS: only uniform solid borders are supported.");
|
|
584
|
+
if (!n && (t.backgroundColor !== "rgba(0, 0, 0, 0)" || s[0] !== "0px") && Array.from(e.getClientRects()).filter((e) => e.width > 0 && e.height > 0).length > 1) throw new D("UNSUPPORTED_CSS", "Fragmented inline backgrounds and borders require an explicit containing raster region.");
|
|
585
585
|
}
|
|
586
|
-
function
|
|
586
|
+
function He(e, t) {
|
|
587
587
|
if (!(e instanceof HTMLImageElement) && ![
|
|
588
588
|
"block",
|
|
589
589
|
"flow-root",
|
|
@@ -603,34 +603,34 @@ function I(e, t) {
|
|
|
603
603
|
"table-cell",
|
|
604
604
|
"table-column-group",
|
|
605
605
|
"table-column"
|
|
606
|
-
].includes(t.display)) throw new
|
|
606
|
+
].includes(t.display)) throw new D("UNSUPPORTED_CSS", `Unsupported CSS display: ${t.display}.`);
|
|
607
607
|
}
|
|
608
|
-
function
|
|
608
|
+
function Ue(e, t, n, r, i) {
|
|
609
609
|
let a = e.parentElement;
|
|
610
610
|
if (!a || !e.data.replace(/[\t\n\r\f ]+/g, "")) return [];
|
|
611
611
|
let o = getComputedStyle(a), s = o.fontFamily.split(",")[0]?.trim().replace(/^['"]|['"]$/g, ""), c = Number(o.fontWeight), l = n.find((e) => e.family.toLowerCase() === s?.toLowerCase() && e.weight === c && e.style === o.fontStyle);
|
|
612
|
-
if (!l) throw new
|
|
613
|
-
if (o.direction !== "ltr" || o.writingMode !== "horizontal-tb" || o.textTransform !== "none" || o.whiteSpace !== "normal" || e.data.includes("") || o.hyphens === "auto" || o.letterSpacing !== "normal" && o.letterSpacing !== "0px" || o.wordSpacing !== "normal" && o.wordSpacing !== "0px" || o.fontVariantCaps !== "normal" || o.fontVariantAlternates !== "normal" || o.fontVariantLigatures !== "normal" || o.fontVariantNumeric !== "normal" || o.fontVariantEastAsian !== "normal" || o.fontVariantPosition !== "normal" || o.fontFeatureSettings !== "normal" || o.fontVariationSettings !== "normal" || o.fontStretch !== "100%" && o.fontStretch !== "normal" || o.fontSizeAdjust !== "none" && o.fontSizeAdjust !== void 0 || !["auto", "geometricPrecision"].includes(o.textRendering)) throw new
|
|
612
|
+
if (!l) throw new D("MISSING_FONT", `No exact registered font face for ${o.fontFamily} ${o.fontWeight} ${o.fontStyle}.`);
|
|
613
|
+
if (o.direction !== "ltr" || o.writingMode !== "horizontal-tb" || o.textTransform !== "none" || o.whiteSpace !== "normal" || e.data.includes("") || o.hyphens === "auto" || o.letterSpacing !== "normal" && o.letterSpacing !== "0px" || o.wordSpacing !== "normal" && o.wordSpacing !== "0px" || o.fontVariantCaps !== "normal" || o.fontVariantAlternates !== "normal" || o.fontVariantLigatures !== "normal" || o.fontVariantNumeric !== "normal" || o.fontVariantEastAsian !== "normal" || o.fontVariantPosition !== "normal" || o.fontFeatureSettings !== "normal" || o.fontVariationSettings !== "normal" || o.fontStretch !== "100%" && o.fontStretch !== "normal" || o.fontSizeAdjust !== "none" && o.fontSizeAdjust !== void 0 || !["auto", "geometricPrecision"].includes(o.textRendering)) throw new D("UNSUPPORTED_CSS", "Unsupported CSS: text requires horizontal LTR layout with normal whitespace, spacing, font variants and OpenType features, without automatic hyphenation or soft hyphens.");
|
|
614
614
|
let u = Number.parseFloat(o.fontSize), d = `${l.style} ${l.weight} ${u}px "${l.family}"`, f = r.fonts.get(d);
|
|
615
615
|
if (!f) {
|
|
616
616
|
if (!Array.from(document.fonts).some((e) => {
|
|
617
617
|
let t = e.weight === "normal" ? 400 : e.weight === "bold" ? 700 : Number(e.weight);
|
|
618
618
|
return e.family.replace(/^['"]|['"]$/g, "").toLowerCase() === l.family.toLowerCase() && t === l.weight && e.style === l.style && e.status === "loaded";
|
|
619
|
-
}) || !document.fonts.check(d, e.data)) throw new
|
|
619
|
+
}) || !document.fonts.check(d, e.data)) throw new D("MISSING_FONT", `Browser font is not loaded: ${d}.`);
|
|
620
620
|
r.context.font = d;
|
|
621
621
|
let t = r.context.measureText(e.data), n = t.fontBoundingBoxAscent, i = t.fontBoundingBoxDescent;
|
|
622
|
-
if (!Number.isFinite(n) || !Number.isFinite(i)) throw new
|
|
622
|
+
if (!Number.isFinite(n) || !Number.isFinite(i)) throw new D("UNSUPPORTED_CSS", "Font bounding metrics are unavailable in this browser.");
|
|
623
623
|
f = {
|
|
624
624
|
ascent: n,
|
|
625
625
|
descent: i
|
|
626
626
|
}, r.fonts.set(d, f);
|
|
627
627
|
}
|
|
628
|
-
let { ascent: p, descent: m } = f, h =
|
|
628
|
+
let { ascent: p, descent: m } = f, h = ze.segment(e.data), g = document.createRange(), _ = [];
|
|
629
629
|
for (let t of h) {
|
|
630
630
|
g.setStart(e, t.index), g.setEnd(e, t.index + t.segment.length);
|
|
631
631
|
let n = Array.from(g.getClientRects()), r = n.find((e) => e.width > 0 && e.height > 0);
|
|
632
632
|
if (!r) {
|
|
633
|
-
if (/[^\t\n\r\f ]/.test(t.segment) && n.some((e) => e.height > 0 && e.width === 0)) throw new
|
|
633
|
+
if (/[^\t\n\r\f ]/.test(t.segment) && n.some((e) => e.height > 0 && e.width === 0)) throw new D("UNSUPPORTED_CSS", "Text shaping crosses an inline boundary or uses an unsupported zero-width glyph. Keep each shaped word in one text node.");
|
|
634
634
|
continue;
|
|
635
635
|
}
|
|
636
636
|
let i = _.at(-1);
|
|
@@ -646,14 +646,14 @@ function Ce(e, t, n, r, i) {
|
|
|
646
646
|
for (; a > r && /[\t\n\r\f ]/.test(e.data[a - 1]);) --a;
|
|
647
647
|
if (r === a) return [];
|
|
648
648
|
g.setStart(e, r), g.setEnd(e, a);
|
|
649
|
-
let s = e.data.slice(r, a), c = s.replace(/[\t\n\r\f ]+/g, " "), d =
|
|
649
|
+
let s = e.data.slice(r, a), c = s.replace(/[\t\n\r\f ]+/g, " "), d = M(g.getBoundingClientRect(), t);
|
|
650
650
|
return [{
|
|
651
651
|
kind: "text",
|
|
652
652
|
bounds: d,
|
|
653
653
|
text: c,
|
|
654
654
|
runs: Array.from(s.matchAll(/[^\t\n\r\f ]+/g), (n) => {
|
|
655
655
|
g.setStart(e, r + n.index), g.setEnd(e, r + n.index + n[0].length);
|
|
656
|
-
let i =
|
|
656
|
+
let i = M(g.getBoundingClientRect(), t);
|
|
657
657
|
return {
|
|
658
658
|
text: n[0],
|
|
659
659
|
x: i.x,
|
|
@@ -671,36 +671,36 @@ function Ce(e, t, n, r, i) {
|
|
|
671
671
|
}];
|
|
672
672
|
});
|
|
673
673
|
}
|
|
674
|
-
function
|
|
675
|
-
if (n !== "auto" && n !== "strict") throw new
|
|
676
|
-
if (typeof r != "boolean") throw new
|
|
677
|
-
if (!(e instanceof HTMLElement) || e.ownerDocument !== document || !e.isConnected || t.length === 0) throw new
|
|
678
|
-
if (new Set(t.map((e) => `${e.family.toLowerCase()}:${e.weight}:${e.style}`)).size !== t.length) throw new
|
|
679
|
-
for (let t =
|
|
674
|
+
function We(e, t, n, r = !1) {
|
|
675
|
+
if (n !== "auto" && n !== "strict") throw new D("INVALID_OPTIONS", "Raster fallback must be auto or strict.");
|
|
676
|
+
if (typeof r != "boolean") throw new D("INVALID_OPTIONS", "Table header repetition must be a boolean.");
|
|
677
|
+
if (!(e instanceof HTMLElement) || e.ownerDocument !== document || !e.isConnected || t.length === 0) throw new D("INVALID_SOURCE", "A connected source root and registered fonts are required.");
|
|
678
|
+
if (new Set(t.map((e) => `${e.family.toLowerCase()}:${e.weight}:${e.style}`)).size !== t.length) throw new D("INVALID_OPTIONS", "Registered fonts require unique family/weight/style descriptors.");
|
|
679
|
+
for (let t = Be(e); t; t = Be(t)) {
|
|
680
680
|
let e = getComputedStyle(t);
|
|
681
|
-
if (e.transform !== "none" || e.filter !== "none" || e.opacity !== "1" || e.clipPath !== "none" || e.maskImage !== "none" || e.mixBlendMode !== "normal" || e.zoom !== "1" || e.overflowX !== "visible" || e.overflowY !== "visible") throw new
|
|
681
|
+
if (e.transform !== "none" || e.filter !== "none" || e.opacity !== "1" || e.clipPath !== "none" || e.maskImage !== "none" || e.mixBlendMode !== "normal" || e.zoom !== "1" || e.overflowX !== "visible" || e.overflowY !== "visible") throw new D("UNSUPPORTED_CSS", "Unsupported CSS: source ancestors must not transform, clip, blend, or fade the source.");
|
|
682
682
|
}
|
|
683
683
|
}
|
|
684
|
-
function
|
|
684
|
+
function Ge(e, t, n, r, i, a) {
|
|
685
685
|
let o = Array.from(e.querySelectorAll("table"));
|
|
686
686
|
e instanceof HTMLTableElement && o.unshift(e);
|
|
687
687
|
let s = [];
|
|
688
688
|
for (let c of o) {
|
|
689
689
|
let o = c.tHead;
|
|
690
690
|
if (!o || getComputedStyle(o).display === "none") continue;
|
|
691
|
-
let l = a.get(c), u = l?.headerBounds ??
|
|
691
|
+
let l = a.get(c), u = l?.headerBounds ?? M(o.getBoundingClientRect(), t);
|
|
692
692
|
if (u.width <= 0 || u.height <= 0) continue;
|
|
693
693
|
let d = Array.from(c.tBodies).flatMap((e) => Array.from(e.rows).filter((e) => e.getBoundingClientRect().height > 0));
|
|
694
694
|
if (d.length === 0) continue;
|
|
695
|
-
if (l && !l.repeatSafe) throw new
|
|
696
|
-
if (c.parentElement?.closest("table") || c.querySelector("table") || Array.from(c.children).filter((e) => e.tagName === "THEAD").length !== 1 || getComputedStyle(c).display !== "table" || getComputedStyle(o).display !== "table-header-group") throw new
|
|
697
|
-
if (Array.from(o.rows).some((e) => Array.from(e.cells).some((e) => e.rowSpan !== 1)) || n.some((e) => e.kind === "raster" && (e.element.contains(o) || o.contains(e.element)))) throw new
|
|
698
|
-
let f =
|
|
695
|
+
if (l && !l.repeatSafe) throw new D("UNSUPPORTED_CSS", "Repeated collapsed headers require matching horizontal border winners at the header/body boundary and all body row boundaries.");
|
|
696
|
+
if (c.parentElement?.closest("table") || c.querySelector("table") || Array.from(c.children).filter((e) => e.tagName === "THEAD").length !== 1 || getComputedStyle(c).display !== "table" || getComputedStyle(o).display !== "table-header-group") throw new D("UNSUPPORTED_ELEMENT", "Repeated headers require a standalone native table with one THEAD and no nested tables.");
|
|
697
|
+
if (Array.from(o.rows).some((e) => Array.from(e.cells).some((e) => e.rowSpan !== 1)) || n.some((e) => e.kind === "raster" && (e.element.contains(o) || o.contains(e.element)))) throw new D("UNSUPPORTED_ELEMENT", "Repeated table headers do not support header rowspans or rasterized headers and ancestors.");
|
|
698
|
+
let f = M(d[0].getBoundingClientRect(), t).y, p = M(d.at(-1).getBoundingClientRect(), t), m = p.y + p.height, h = r.get(o);
|
|
699
699
|
if (!h || f < u.y + u.height - .1 || m <= f || h.some((e) => e.kind !== "border" && (e.bounds.y < u.y - .1 || e.bounds.y + e.bounds.height > u.y + u.height + .1 || e.bounds.x < u.x - .1 || e.bounds.x + e.bounds.width > u.x + u.width + .1)) || d.some((e) => Array.from(e.cells).some((e) => {
|
|
700
|
-
let n =
|
|
700
|
+
let n = M(e.getBoundingClientRect(), t);
|
|
701
701
|
return n.y < f - .1 || n.y + n.height > m + .1;
|
|
702
|
-
}))) throw new
|
|
703
|
-
if (s.some((e) => Math.min(e.bodyEnd, m) - Math.max(e.bounds.y, u.y) > .01)) throw new
|
|
702
|
+
}))) throw new D("UNSUPPORTED_CSS", "Repeated table headers require a separate, ordered header band without overflowing paint or cells spanning header/body boundaries.");
|
|
703
|
+
if (s.some((e) => Math.min(e.bodyEnd, m) - Math.max(e.bounds.y, u.y) > .01)) throw new D("UNSUPPORTED_CSS", "Repeated headers do not support tables whose vertical continuation intervals overlap.");
|
|
704
704
|
let g = new Set(h);
|
|
705
705
|
for (let t = o.parentElement; t; t = t.parentElement) {
|
|
706
706
|
let n = i.get(t);
|
|
@@ -715,13 +715,13 @@ function Te(e, t, n, r, i, a) {
|
|
|
715
715
|
}
|
|
716
716
|
return s;
|
|
717
717
|
}
|
|
718
|
-
function
|
|
718
|
+
function Ke(e, t, n = {}) {
|
|
719
719
|
let r = n.fallback ?? "auto", i = n.repeatTableHeaders ?? !1;
|
|
720
|
-
|
|
720
|
+
We(e, t, r, i);
|
|
721
721
|
let a = e.getBoundingClientRect();
|
|
722
|
-
if (a.width <= 0 || a.height <= 0) throw new
|
|
722
|
+
if (a.width <= 0 || a.height <= 0) throw new D("INVALID_SOURCE", "The source root must have positive visible dimensions.");
|
|
723
723
|
let o = document.createElement("canvas").getContext("2d");
|
|
724
|
-
if (!o) throw new
|
|
724
|
+
if (!o) throw new D("INVALID_SOURCE", "Canvas font measurement is unavailable.");
|
|
725
725
|
let s = {
|
|
726
726
|
context: o,
|
|
727
727
|
fonts: /* @__PURE__ */ new Map()
|
|
@@ -732,31 +732,31 @@ function Ee(e, t, n = {}) {
|
|
|
732
732
|
function h(e, n, o = !1) {
|
|
733
733
|
let g = c.length, _ = getComputedStyle(e);
|
|
734
734
|
if (_.display === "none") return;
|
|
735
|
-
let v =
|
|
735
|
+
let v = Ie(e, _);
|
|
736
736
|
if (_.visibility !== "visible") {
|
|
737
|
-
if (!n || o) throw new
|
|
737
|
+
if (!n || o) throw new D("UNSUPPORTED_CSS", "Unsupported CSS: visibility overrides are not supported.");
|
|
738
738
|
m.push({
|
|
739
739
|
code: "RASTER_TEXT_OMITTED",
|
|
740
740
|
message: `Raster text extraction omitted for visibility-controlled subtree ${e.tagName}.`
|
|
741
741
|
});
|
|
742
742
|
return;
|
|
743
743
|
}
|
|
744
|
-
if ((!n || o) && !(/* @__PURE__ */ "MAIN.SECTION.ARTICLE.DIV.SPAN.P.H1.H2.H3.H4.H5.H6.STRONG.EM.B.I.IMG.FONT.CENTER.BR.HR.TABLE.THEAD.TBODY.TFOOT.TR.TH.TD.CAPTION.COLGROUP.COL".split(".")).includes(e.tagName)) throw new
|
|
745
|
-
let y = !n && e.hasAttribute("data-raster"), b = !n && !y && r === "auto" ?
|
|
746
|
-
if (x && (o &&
|
|
744
|
+
if ((!n || o) && !(/* @__PURE__ */ "MAIN.SECTION.ARTICLE.DIV.SPAN.P.H1.H2.H3.H4.H5.H6.STRONG.EM.B.I.IMG.FONT.CENTER.BR.HR.TABLE.THEAD.TBODY.TFOOT.TR.TH.TD.CAPTION.COLGROUP.COL".split(".")).includes(e.tagName)) throw new D("UNSUPPORTED_ELEMENT", `Native snapshots do not support ${e.tagName}.`);
|
|
745
|
+
let y = !n && e.hasAttribute("data-raster"), b = !n && !y && r === "auto" ? Ae(_) : void 0, x = o || b !== void 0;
|
|
746
|
+
if (x && (o && Ae(_), Ve(e, _, !0, v !== void 0), He(e, _)), n && (_.transform !== "none" || _.writingMode !== "horizontal-tb" || _.direction !== "ltr" || _.opacity === "0" || _.clipPath !== "none" || _.maskImage !== "none" || _.overflowX !== "visible" || _.overflowY !== "visible")) {
|
|
747
747
|
m.push({
|
|
748
748
|
code: "RASTER_TEXT_OMITTED",
|
|
749
749
|
message: `Raster text extraction omitted for transformed, clipped, hidden, masked, or non-LTR subtree ${e.tagName}.`
|
|
750
750
|
});
|
|
751
751
|
return;
|
|
752
752
|
}
|
|
753
|
-
let S =
|
|
754
|
-
if (!n && (S.x < -.1 || S.y < -.1 || S.x + S.width > a.width + .1 || S.y + S.height > a.height + .1)) throw new
|
|
753
|
+
let S = M(e.getBoundingClientRect(), a);
|
|
754
|
+
if (!n && (S.x < -.1 || S.y < -.1 || S.x + S.width > a.width + .1 || S.y + S.height > a.height + .1)) throw new D("SOURCE_OVERFLOW", "Source content must fit within the root border box.");
|
|
755
755
|
let C = y || b !== void 0;
|
|
756
|
-
if (C && v && !(e instanceof HTMLTableElement)) throw new
|
|
756
|
+
if (C && v && !(e instanceof HTMLTableElement)) throw new D("UNSUPPORTED_CSS", "Collapsed table cells and internal groups cannot be independently rasterized.");
|
|
757
757
|
if (C) {
|
|
758
|
-
if (_.position !== "static" || _.transform !== "none" || _.mixBlendMode !== "normal") throw new
|
|
759
|
-
if (b !== void 0 &&
|
|
758
|
+
if (_.position !== "static" || _.transform !== "none" || _.mixBlendMode !== "normal") throw new D("UNSUPPORTED_CSS", "A raster boundary must be static, untransformed, and independently compositable.");
|
|
759
|
+
if (b !== void 0 && je(e, _), c.push({
|
|
760
760
|
kind: "raster",
|
|
761
761
|
bounds: S,
|
|
762
762
|
element: e
|
|
@@ -771,18 +771,18 @@ function Ee(e, t, n = {}) {
|
|
|
771
771
|
return;
|
|
772
772
|
}
|
|
773
773
|
} else if (!n) {
|
|
774
|
-
if (
|
|
774
|
+
if (Ve(e, _, !1, v !== void 0), He(e, _), e instanceof HTMLTableRowElement || e instanceof HTMLTableCellElement && e.rowSpan !== 1) {
|
|
775
775
|
let t = { ...S };
|
|
776
776
|
f.push(t), e instanceof HTMLTableRowElement && p.set(e, t);
|
|
777
777
|
}
|
|
778
778
|
if (e instanceof HTMLImageElement) {
|
|
779
|
-
if (_.objectFit !== "fill" || _.borderTopWidth !== "0px") throw new
|
|
779
|
+
if (_.objectFit !== "fill" || _.borderTopWidth !== "0px") throw new D("UNSUPPORTED_CSS", "Image boxes require object-fit: fill without borders.");
|
|
780
780
|
if ([
|
|
781
781
|
"paddingTop",
|
|
782
782
|
"paddingRight",
|
|
783
783
|
"paddingBottom",
|
|
784
784
|
"paddingLeft"
|
|
785
|
-
].some((e) => Number.parseFloat(_.getPropertyValue(e.replace(/[A-Z]/g, (e) => `-${e.toLowerCase()}`))) !== 0) || _.backgroundColor !== "rgba(0, 0, 0, 0)") throw new
|
|
785
|
+
].some((e) => Number.parseFloat(_.getPropertyValue(e.replace(/[A-Z]/g, (e) => `-${e.toLowerCase()}`))) !== 0) || _.backgroundColor !== "rgba(0, 0, 0, 0)") throw new D("UNSUPPORTED_CSS", "Image boxes require zero padding and a transparent background.");
|
|
786
786
|
c.push({
|
|
787
787
|
kind: "image",
|
|
788
788
|
bounds: S,
|
|
@@ -803,25 +803,25 @@ function Ee(e, t, n = {}) {
|
|
|
803
803
|
c.push(t), i && u.set(e, t);
|
|
804
804
|
}
|
|
805
805
|
}
|
|
806
|
-
let
|
|
807
|
-
if (!
|
|
806
|
+
let w = n || C;
|
|
807
|
+
if (!w || x) {
|
|
808
808
|
let t = Array.from(e.children).filter((e) => e instanceof HTMLElement && !(v && ["COL", "COLGROUP"].includes(e.tagName)) && getComputedStyle(e).display !== "none" && getComputedStyle(e).visibility !== "hidden").map((e) => e.getBoundingClientRect());
|
|
809
809
|
for (let e = 0; e < t.length; e += 1) for (let n = e + 1; n < t.length; n += 1) {
|
|
810
810
|
let r = t[e], i = t[n];
|
|
811
|
-
if (Math.min(r.right, i.right) - Math.max(r.left, i.left) > .1 && Math.min(r.bottom, i.bottom) - Math.max(r.top, i.top) > .1) throw new
|
|
811
|
+
if (Math.min(r.right, i.right) - Math.max(r.left, i.left) > .1 && Math.min(r.bottom, i.bottom) - Math.max(r.top, i.top) > .1) throw new D("UNSUPPORTED_CSS", "Overlapping sibling boxes are unsupported; isolate them in one raster subtree.");
|
|
812
812
|
}
|
|
813
813
|
}
|
|
814
|
-
for (let n of e.childNodes) if (n instanceof Text) c.push(...
|
|
815
|
-
else if (n instanceof HTMLElement) h(n,
|
|
814
|
+
for (let n of e.childNodes) if (n instanceof Text) c.push(...Ue(n, a, t, s, w));
|
|
815
|
+
else if (n instanceof HTMLElement) h(n, w, x);
|
|
816
816
|
else if (n instanceof Element) {
|
|
817
|
-
if (
|
|
817
|
+
if (w) m.push({
|
|
818
818
|
code: "RASTER_TEXT_OMITTED",
|
|
819
819
|
message: `Raster text extraction omitted for ${n.tagName}.`
|
|
820
820
|
});
|
|
821
|
-
else throw new
|
|
821
|
+
else throw new D("UNSUPPORTED_ELEMENT", `Cannot snapshot ${n.tagName}; use a raster subtree.`);
|
|
822
822
|
}
|
|
823
|
-
if (i && e instanceof HTMLTableSectionElement && e.tagName === "THEAD" && l.set(e, c.slice(g)), !
|
|
824
|
-
let t =
|
|
823
|
+
if (i && e instanceof HTMLTableSectionElement && e.tagName === "THEAD" && l.set(e, c.slice(g)), !w && e instanceof HTMLTableElement && v) {
|
|
824
|
+
let t = Re(e, a);
|
|
825
825
|
d.set(e, t);
|
|
826
826
|
for (let e of t.operations) c.push(e);
|
|
827
827
|
let n = Array.from(e.rows).filter((e) => p.has(e)), r = n[0] ? p.get(n[0]) : void 0, o = n.at(-1) ? p.get(n.at(-1)) : void 0, s = t.operations.reduce((e, { bounds: t }) => ({
|
|
@@ -848,33 +848,33 @@ function Ee(e, t, n = {}) {
|
|
|
848
848
|
}
|
|
849
849
|
if (e.kind === "box" && (e.background.startsWith("rgba(") ? Number(e.background.slice(e.background.lastIndexOf(",") + 1, -1)) : 1) === 0 && e.borderWidth === 0) continue;
|
|
850
850
|
let t = e.bounds;
|
|
851
|
-
if (g.some((e) => Math.min(e.bounds.x + e.bounds.width, t.x + t.width) - Math.max(e.bounds.x, t.x) > .1 && Math.min(e.bounds.y + e.bounds.height, t.y + t.height) - Math.max(e.bounds.y, t.y) > .1)) throw new
|
|
851
|
+
if (g.some((e) => Math.min(e.bounds.x + e.bounds.width, t.x + t.width) - Math.max(e.bounds.x, t.x) > .1 && Math.min(e.bounds.y + e.bounds.height, t.y + t.height) - Math.max(e.bounds.y, t.y) > .1)) throw new D("UNSUPPORTED_CSS", "Text overlaps later visible paint whose CSS paint phases cannot be represented safely; use an explicit containing raster region.");
|
|
852
852
|
}
|
|
853
853
|
if (c.some((e) => {
|
|
854
854
|
if (e.kind === "text" && e.invisible) return !1;
|
|
855
855
|
let t = e.bounds;
|
|
856
856
|
return t.x < -.1 || t.y < -.1 || t.x + t.width > a.width + .1 || t.y + t.height > a.height + .1;
|
|
857
|
-
})) throw new
|
|
857
|
+
})) throw new D("SOURCE_OVERFLOW", "Visible source text or paint overflows the root border box.");
|
|
858
858
|
return {
|
|
859
859
|
width: a.width,
|
|
860
860
|
height: a.height,
|
|
861
861
|
operations: c,
|
|
862
862
|
warnings: m,
|
|
863
863
|
atomicBounds: f,
|
|
864
|
-
...i ? { tableHeaders:
|
|
864
|
+
...i ? { tableHeaders: Ge(e, a, c, l, u, d) } : {}
|
|
865
865
|
};
|
|
866
866
|
}
|
|
867
867
|
// src/page.ts
|
|
868
|
-
function
|
|
869
|
-
if (!e || typeof e != "object" || Array.isArray(e)) throw new
|
|
868
|
+
function qe(e) {
|
|
869
|
+
if (!e || typeof e != "object" || Array.isArray(e)) throw new D("INVALID_OPTIONS", "PDF page options must be an object.");
|
|
870
870
|
let t = {
|
|
871
871
|
A4: [595.28, 841.89],
|
|
872
872
|
A3: [841.89, 1190.55],
|
|
873
873
|
Letter: [612, 792]
|
|
874
874
|
}, n = e.format ?? "A4";
|
|
875
|
-
if (typeof n != "object" && !Object.hasOwn(t, n)) throw new
|
|
875
|
+
if (typeof n != "object" && !Object.hasOwn(t, n)) throw new D("INVALID_OPTIONS", `Unsupported page format: ${n}.`);
|
|
876
876
|
let r = e.orientation ?? "portrait";
|
|
877
|
-
if (r !== "portrait" && r !== "landscape") throw new
|
|
877
|
+
if (r !== "portrait" && r !== "landscape") throw new D("INVALID_OPTIONS", `Unsupported page orientation: ${r}.`);
|
|
878
878
|
let i = e.margin ?? 24, a = typeof i == "number" ? {
|
|
879
879
|
top: i,
|
|
880
880
|
right: i,
|
|
@@ -886,39 +886,39 @@ function L(e) {
|
|
|
886
886
|
bottom: i?.bottom,
|
|
887
887
|
left: i?.left
|
|
888
888
|
};
|
|
889
|
-
if (Object.values(a).some((e) => !Number.isFinite(e) || e < 0)) throw new
|
|
889
|
+
if (Object.values(a).some((e) => !Number.isFinite(e) || e < 0)) throw new D("INVALID_OPTIONS", "Every page margin must be finite and nonnegative.");
|
|
890
890
|
let o = typeof n == "object" ? [n?.width, n?.height] : t[n].map((e) => e / .75);
|
|
891
|
-
if (o.some((e) => !Number.isFinite(e) || e <= 0)) throw new
|
|
891
|
+
if (o.some((e) => !Number.isFinite(e) || e <= 0)) throw new D("INVALID_OPTIONS", "Custom page width and height must be finite positive CSS pixel values.");
|
|
892
892
|
let s = o[r === "portrait" ? 0 : 1], c = o[+(r === "portrait")];
|
|
893
|
-
if (a.left + a.right >= s || a.top + a.bottom >= c) throw new
|
|
893
|
+
if (a.left + a.right >= s || a.top + a.bottom >= c) throw new D("INVALID_OPTIONS", "Page margins leave no positive content area.");
|
|
894
894
|
return {
|
|
895
895
|
width: s,
|
|
896
896
|
height: c,
|
|
897
897
|
margin: a
|
|
898
898
|
};
|
|
899
899
|
}
|
|
900
|
-
function
|
|
901
|
-
if (!e || !Array.isArray(e.fonts) || e.fonts.length === 0) throw new
|
|
902
|
-
let t =
|
|
903
|
-
if (e.rasterScale !== void 0 && (!Number.isFinite(e.rasterScale) || e.rasterScale <= 0)) throw new
|
|
904
|
-
if (e.onWarning !== void 0 && typeof e.onWarning != "function") throw new
|
|
905
|
-
if (e.onProgress !== void 0 && typeof e.onProgress != "function") throw new
|
|
906
|
-
if (e.fallback !== void 0 && !["auto", "strict"].includes(e.fallback)) throw new
|
|
907
|
-
if (e.pageBreak !== void 0 && !["auto", "css"].includes(e.pageBreak)) throw new
|
|
908
|
-
if (e.repeatTableHeaders !== void 0 && typeof e.repeatTableHeaders != "boolean") throw new
|
|
909
|
-
if (e.signal !== void 0 && !(e.signal instanceof AbortSignal)) throw new
|
|
900
|
+
function Je(e) {
|
|
901
|
+
if (!e || !Array.isArray(e.fonts) || e.fonts.length === 0) throw new D("INVALID_OPTIONS", "Provide at least one explicitly registered font.");
|
|
902
|
+
let t = qe(e);
|
|
903
|
+
if (e.rasterScale !== void 0 && (!Number.isFinite(e.rasterScale) || e.rasterScale <= 0)) throw new D("INVALID_OPTIONS", "Raster scale must be a finite positive number.");
|
|
904
|
+
if (e.onWarning !== void 0 && typeof e.onWarning != "function") throw new D("INVALID_OPTIONS", "onWarning must be a function.");
|
|
905
|
+
if (e.onProgress !== void 0 && typeof e.onProgress != "function") throw new D("INVALID_OPTIONS", "onProgress must be a function.");
|
|
906
|
+
if (e.fallback !== void 0 && !["auto", "strict"].includes(e.fallback)) throw new D("INVALID_OPTIONS", "fallback must be auto or strict.");
|
|
907
|
+
if (e.pageBreak !== void 0 && !["auto", "css"].includes(e.pageBreak)) throw new D("INVALID_OPTIONS", "pageBreak must be auto or css.");
|
|
908
|
+
if (e.repeatTableHeaders !== void 0 && typeof e.repeatTableHeaders != "boolean") throw new D("INVALID_OPTIONS", "repeatTableHeaders must be a boolean.");
|
|
909
|
+
if (e.signal !== void 0 && !(e.signal instanceof AbortSignal)) throw new D("INVALID_OPTIONS", "signal must be an AbortSignal.");
|
|
910
910
|
return t;
|
|
911
911
|
}
|
|
912
912
|
// src/page-bands.ts
|
|
913
|
-
function
|
|
913
|
+
function Ye(e, t) {
|
|
914
914
|
if (e === void 0) return;
|
|
915
|
-
if (!e || typeof e != "object" || typeof e.text != "string" || !Number.isFinite(e.height) || e.height <= 0 || /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(e.text) || /[^\p{Script=Latin}\p{Script=Common}\p{Script=Inherited}]/u.test(e.text)) throw new
|
|
915
|
+
if (!e || typeof e != "object" || typeof e.text != "string" || !Number.isFinite(e.height) || e.height <= 0 || /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(e.text) || /[^\p{Script=Latin}\p{Script=Common}\p{Script=Inherited}]/u.test(e.text)) throw new D("INVALID_OPTIONS", "Page header/footer requires single-line Latin text and a finite positive reserved height.");
|
|
916
916
|
let n = e.font ?? t[0], r = e.fontSize ?? 12, i = e.align ?? "left";
|
|
917
917
|
if (!t.includes(n) || !Number.isFinite(r) || r <= 0 || ![
|
|
918
918
|
"left",
|
|
919
919
|
"center",
|
|
920
920
|
"right"
|
|
921
|
-
].includes(i)) throw new
|
|
921
|
+
].includes(i)) throw new D("INVALID_OPTIONS", "Page header/footer needs a font included in fonts, a positive fontSize and left/center/right alignment.");
|
|
922
922
|
return Object.freeze({
|
|
923
923
|
text: e.text,
|
|
924
924
|
height: e.height,
|
|
@@ -927,8 +927,8 @@ function R(e, t) {
|
|
|
927
927
|
align: i
|
|
928
928
|
});
|
|
929
929
|
}
|
|
930
|
-
function
|
|
931
|
-
let n =
|
|
930
|
+
function Xe(e, t) {
|
|
931
|
+
let n = Ye(t.header, t.fonts), r = Ye(t.footer, t.fonts), i = {
|
|
932
932
|
...e,
|
|
933
933
|
margin: {
|
|
934
934
|
...e.margin,
|
|
@@ -936,7 +936,7 @@ function Oe(e, t) {
|
|
|
936
936
|
bottom: e.margin.bottom + (r?.height ?? 0)
|
|
937
937
|
}
|
|
938
938
|
};
|
|
939
|
-
if (i.margin.top + i.margin.bottom >= i.height) throw new
|
|
939
|
+
if (i.margin.top + i.margin.bottom >= i.height) throw new D("INVALID_OPTIONS", "Page header/footer heights and margins leave no positive source content area.");
|
|
940
940
|
return {
|
|
941
941
|
content: i,
|
|
942
942
|
header: n,
|
|
@@ -944,52 +944,52 @@ function Oe(e, t) {
|
|
|
944
944
|
};
|
|
945
945
|
}
|
|
946
946
|
// src/pagination.ts
|
|
947
|
-
var
|
|
948
|
-
function
|
|
947
|
+
var N = .01;
|
|
948
|
+
function Ze(e, t, n) {
|
|
949
949
|
if (![
|
|
950
950
|
e.x,
|
|
951
951
|
e.y,
|
|
952
952
|
e.width,
|
|
953
953
|
e.height
|
|
954
|
-
].every(Number.isFinite) || e.width < 0 || e.height < 0 || e.y < -.01 || e.y + e.height > t +
|
|
954
|
+
].every(Number.isFinite) || e.width < 0 || e.height < 0 || e.y < -.01 || e.y + e.height > t + N) throw new D("PAGINATION_FAILED", `${n} geometry must be finite, nonnegative and within the source height.`);
|
|
955
955
|
}
|
|
956
|
-
function
|
|
957
|
-
return e.y < t -
|
|
956
|
+
function P(e, t) {
|
|
957
|
+
return e.y < t - N && e.y + e.height > t + N;
|
|
958
958
|
}
|
|
959
|
-
function
|
|
959
|
+
function Qe(e, t, n) {
|
|
960
960
|
let r = e;
|
|
961
961
|
for (;;) {
|
|
962
|
-
let e = n.reduce((e, t) =>
|
|
962
|
+
let e = n.reduce((e, t) => P(t, r) ? Math.min(e, t.y) : e, r);
|
|
963
963
|
if (e === r) return r;
|
|
964
|
-
if (e <= t +
|
|
964
|
+
if (e <= t + N) throw new D("PAGINATION_FAILED", "Overlapping atomic items cannot fit on one page.");
|
|
965
965
|
r = e;
|
|
966
966
|
}
|
|
967
967
|
}
|
|
968
|
-
function
|
|
969
|
-
if (!Number.isFinite(t) || t <= 0) throw new
|
|
970
|
-
if (!Number.isFinite(e.height) || e.height <= 0) throw new
|
|
968
|
+
function $e(e, t, n) {
|
|
969
|
+
if (!Number.isFinite(t) || t <= 0) throw new D("PAGINATION_FAILED", "Page content height must be finite and positive.");
|
|
970
|
+
if (!Number.isFinite(e.height) || e.height <= 0) throw new D("PAGINATION_FAILED", "Source height must be finite and positive.");
|
|
971
971
|
let r = [], i = [...e.operations.filter((e) => e.kind !== "box" && e.kind !== "border").map((e) => e.bounds), ...e.atomicBounds ?? []], a = e.tableHeaders ?? [];
|
|
972
972
|
for (let [n, r] of a.entries()) {
|
|
973
|
-
if (
|
|
974
|
-
if (a.slice(0, n).some((e) => Math.min(e.bodyEnd, r.bodyEnd) - Math.max(e.bounds.y, r.bounds.y) >
|
|
973
|
+
if (Ze(r.bounds, e.height, "Table header"), r.bounds.width <= 0 || r.bounds.height <= 0 || !Number.isFinite(r.bodyStart) || !Number.isFinite(r.bodyEnd) || r.bodyStart < r.bounds.y + r.bounds.height - N || r.bodyEnd <= r.bodyStart || r.bodyEnd > e.height + N) throw new D("PAGINATION_FAILED", "Repeated table headers require a positive header followed by finite body row bounds.");
|
|
974
|
+
if (a.slice(0, n).some((e) => Math.min(e.bodyEnd, r.bodyEnd) - Math.max(e.bounds.y, r.bounds.y) > N)) throw new D("PAGINATION_FAILED", "Repeated table header continuation intervals must not overlap.");
|
|
975
975
|
let o = r.bodyStart;
|
|
976
976
|
for (;;) {
|
|
977
|
-
let e = i.reduce((e, t) => t.y >= r.bodyStart -
|
|
977
|
+
let e = i.reduce((e, t) => t.y >= r.bodyStart - N && t.y < r.bodyEnd - N && (t.y <= r.bodyStart + N || t.y < o - N) ? Math.max(e, t.y + t.height) : e, o);
|
|
978
978
|
if (e === o) break;
|
|
979
979
|
o = e;
|
|
980
980
|
}
|
|
981
|
-
if (o <= r.bodyStart +
|
|
982
|
-
if (o - r.bounds.y > t +
|
|
981
|
+
if (o <= r.bodyStart + N) throw new D("PAGINATION_FAILED", "Repeated table headers require a measured atomic first body row.");
|
|
982
|
+
if (o - r.bounds.y > t + N) throw new D("PAGINATION_FAILED", "A table header and its first atomic body row cannot fit on one page.");
|
|
983
983
|
i.push({
|
|
984
984
|
...r.bounds,
|
|
985
985
|
height: o - r.bounds.y
|
|
986
986
|
});
|
|
987
987
|
}
|
|
988
|
-
for (let n of i) if (
|
|
988
|
+
for (let n of i) if (Ze(n, e.height, "Atomic"), n.height > t + N) throw new D("PAGINATION_FAILED", "An atomic item is taller than one page; this renderer cannot split it.");
|
|
989
989
|
let o = e.forcedBreaks ?? [];
|
|
990
|
-
for (let t of o) if (!Number.isFinite(t) || t < 0 || t > e.height) throw new
|
|
991
|
-
let s = [...new Set(o)].filter((t) => t >
|
|
992
|
-
for (let e of s) if (i.some((t) =>
|
|
990
|
+
for (let t of o) if (!Number.isFinite(t) || t < 0 || t > e.height) throw new D("PAGINATION_FAILED", "Forced page breaks must lie within the finite source height.");
|
|
991
|
+
let s = [...new Set(o)].filter((t) => t > N && t < e.height - N).sort((e, t) => e - t).filter((e, t, n) => t === 0 || e - n[t - 1] > N);
|
|
992
|
+
for (let e of s) if (i.some((t) => P(t, e))) throw new D("PAGINATION_FAILED", "A forced CSS page break crosses an atomic text, image, raster, table row or spanning cell.");
|
|
993
993
|
let c = !1;
|
|
994
994
|
function l() {
|
|
995
995
|
c || (c = !0, n?.({
|
|
@@ -998,26 +998,26 @@ function Ae(e, t, n) {
|
|
|
998
998
|
}));
|
|
999
999
|
}
|
|
1000
1000
|
let u = [];
|
|
1001
|
-
for (let n of e.avoidBreakBounds ?? [])
|
|
1001
|
+
for (let n of e.avoidBreakBounds ?? []) Ze(n, e.height, "Preferred break-avoid"), !s.some((e) => P(n, e)) && (n.height > t + N ? l() : u.push(n));
|
|
1002
1002
|
let d = [...i, ...u], f = 0, p = 0;
|
|
1003
1003
|
for (; f < e.height;) {
|
|
1004
|
-
let n = a.find((e) => f >= e.bodyStart -
|
|
1005
|
-
if (m <=
|
|
1006
|
-
for (; s[p] !== void 0 && s[p] <= f +
|
|
1004
|
+
let n = a.find((e) => f >= e.bodyStart - N && f < e.bodyEnd - N), o = n ? (e.atomicBounds ?? []).reduce((e, t) => t.y >= f - N && t.y < n.bodyEnd - N ? Math.min(e, t.y) : e, Infinity) : f, c = Number.isFinite(o) ? Math.max(0, o - f) : 0, u = n ? Math.max(n.bounds.height, n.bodyStart - n.bounds.y - c) : 0, m = t - u;
|
|
1005
|
+
if (m <= N) throw new D("PAGINATION_FAILED", "A repeated table header leaves no space for its body rows.");
|
|
1006
|
+
for (; s[p] !== void 0 && s[p] <= f + N;) p += 1;
|
|
1007
1007
|
let h = s[p] ?? e.height, g = Math.min(f + m, h, e.height);
|
|
1008
|
-
if (n && i.some((e) => e.y <= f +
|
|
1009
|
-
let _ =
|
|
1010
|
-
if (Math.abs(g - h) >
|
|
1011
|
-
let e = d.reduce((e, t) =>
|
|
1008
|
+
if (n && i.some((e) => e.y <= f + N && P(e, f + m))) throw new D("PAGINATION_FAILED", "A repeated table header and its atomic body row cannot fit on one page.");
|
|
1009
|
+
let _ = Qe(g, f, i), v = _;
|
|
1010
|
+
if (Math.abs(g - h) > N) for (;;) {
|
|
1011
|
+
let e = d.reduce((e, t) => P(t, v) ? Math.min(e, t.y) : e, v);
|
|
1012
1012
|
if (e === v) break;
|
|
1013
|
-
if (e <= f +
|
|
1013
|
+
if (e <= f + N) {
|
|
1014
1014
|
l(), v = _;
|
|
1015
1015
|
break;
|
|
1016
1016
|
}
|
|
1017
1017
|
v = e;
|
|
1018
1018
|
}
|
|
1019
|
-
if (v <= f +
|
|
1020
|
-
if (n && !(e.atomicBounds ?? []).some((e) => e.y >= f -
|
|
1019
|
+
if (v <= f + N) throw new D("PAGINATION_FAILED", "Page planning must advance through the source.");
|
|
1020
|
+
if (n && !(e.atomicBounds ?? []).some((e) => e.y >= f - N && e.y < n.bodyEnd - N && e.y + e.height <= v + N && e.y + e.height > f + N)) throw new D("PAGINATION_FAILED", "A repeated table header must share its page with a complete atomic body row.");
|
|
1021
1021
|
r.push({
|
|
1022
1022
|
start: f,
|
|
1023
1023
|
end: v,
|
|
@@ -1030,106 +1030,106 @@ function Ae(e, t, n) {
|
|
|
1030
1030
|
return r;
|
|
1031
1031
|
}
|
|
1032
1032
|
// src/images.ts
|
|
1033
|
-
function
|
|
1034
|
-
throw new
|
|
1033
|
+
function F() {
|
|
1034
|
+
throw new D("RESOURCE_LOAD_FAILED", "JPEG EXIF orientation must be 1 with valid metadata; normalize the image pixels and remove orientation metadata before exporting.");
|
|
1035
1035
|
}
|
|
1036
|
-
function
|
|
1036
|
+
function et(e, t, n) {
|
|
1037
1037
|
let r = new DataView(e.buffer, e.byteOffset + t, n - t);
|
|
1038
|
-
r.byteLength < 8 &&
|
|
1038
|
+
r.byteLength < 8 && F();
|
|
1039
1039
|
let i = r.getUint16(0);
|
|
1040
|
-
i !== 18761 && i !== 19789 &&
|
|
1040
|
+
i !== 18761 && i !== 19789 && F();
|
|
1041
1041
|
let a = i === 18761;
|
|
1042
|
-
r.getUint16(2, a) !== 42 &&
|
|
1042
|
+
r.getUint16(2, a) !== 42 && F();
|
|
1043
1043
|
let o = r.getUint32(4, a);
|
|
1044
|
-
(o < 8 || o + 2 > r.byteLength) &&
|
|
1044
|
+
(o < 8 || o + 2 > r.byteLength) && F();
|
|
1045
1045
|
let s = r.getUint16(o, a), c = o + 2 + s * 12;
|
|
1046
|
-
c + 4 > r.byteLength &&
|
|
1046
|
+
c + 4 > r.byteLength && F();
|
|
1047
1047
|
let l = !1;
|
|
1048
1048
|
for (let e = 0; e < s; e += 1) {
|
|
1049
1049
|
let t = o + 2 + e * 12;
|
|
1050
|
-
r.getUint16(t, a) === 274 && ((l || r.getUint16(t + 2, a) !== 3 || r.getUint32(t + 4, a) !== 1 || r.getUint16(t + 8, a) !== 1) &&
|
|
1050
|
+
r.getUint16(t, a) === 274 && ((l || r.getUint16(t + 2, a) !== 3 || r.getUint32(t + 4, a) !== 1 || r.getUint16(t + 8, a) !== 1) && F(), l = !0);
|
|
1051
1051
|
}
|
|
1052
1052
|
let u = r.getUint32(c, a);
|
|
1053
|
-
u !== 0 && (u < 8 || u + 2 > r.byteLength) &&
|
|
1053
|
+
u !== 0 && (u < 8 || u + 2 > r.byteLength) && F();
|
|
1054
1054
|
}
|
|
1055
|
-
function
|
|
1055
|
+
function tt(e) {
|
|
1056
1056
|
if (e[0] === 137 && e[1] === 80 && e[2] === 78 && e[3] === 71 && e[4] === 13 && e[5] === 10 && e[6] === 26 && e[7] === 10) return "png";
|
|
1057
|
-
if (e[0] !== 255 || e[1] !== 216) throw new
|
|
1057
|
+
if (e[0] !== 255 || e[1] !== 216) throw new D("RESOURCE_LOAD_FAILED", "Native PDF images require PNG or JPEG bytes.");
|
|
1058
1058
|
let t = 2;
|
|
1059
1059
|
for (; t < e.length;) {
|
|
1060
|
-
for (e[t] !== 255 &&
|
|
1060
|
+
for (e[t] !== 255 && F(); e[t] === 255;) t += 1;
|
|
1061
1061
|
let n = e[t];
|
|
1062
|
-
if ((n === void 0 || n === 0) &&
|
|
1062
|
+
if ((n === void 0 || n === 0) && F(), t += 1, n === 217) return "jpeg";
|
|
1063
1063
|
if (n === 1 || n >= 208 && n <= 215) continue;
|
|
1064
|
-
t + 2 > e.length &&
|
|
1064
|
+
t + 2 > e.length && F();
|
|
1065
1065
|
let r = e[t] * 256 + e[t + 1], i = t + r;
|
|
1066
|
-
if ((r < 2 || i > e.length) &&
|
|
1066
|
+
if ((r < 2 || i > e.length) && F(), n === 218) return "jpeg";
|
|
1067
1067
|
let a = t + 2;
|
|
1068
|
-
n === 225 && i - a >= 4 && e[a] === 69 && e[a + 1] === 120 && e[a + 2] === 105 && e[a + 3] === 102 && ((i - a < 6 || e[a + 4] !== 0 || e[a + 5] !== 0) &&
|
|
1068
|
+
n === 225 && i - a >= 4 && e[a] === 69 && e[a + 1] === 120 && e[a + 2] === 105 && e[a + 3] === 102 && ((i - a < 6 || e[a + 4] !== 0 || e[a + 5] !== 0) && F(), et(e, a + 6, i)), t = i;
|
|
1069
1069
|
}
|
|
1070
|
-
|
|
1070
|
+
F();
|
|
1071
1071
|
}
|
|
1072
1072
|
// src/raster.ts
|
|
1073
|
-
var
|
|
1074
|
-
function
|
|
1073
|
+
var nt = 16777216, rt = 8192, it = /^data:image\/(?:png|jpeg|gif|webp|avif);base64,[a-z\d+/=\s]+$/i;
|
|
1074
|
+
function at(e) {
|
|
1075
1075
|
let t = e.bytes;
|
|
1076
|
-
if (!/^[\w -]+$/.test(e.family) || t.byteLength === 0) throw new
|
|
1076
|
+
if (!/^[\w -]+$/.test(e.family) || t.byteLength === 0) throw new D("RASTER_FAILED", "Raster capture requires nonempty registered fonts with plain CSS family names.");
|
|
1077
1077
|
let n = "";
|
|
1078
1078
|
for (let e = 0; e < t.length; e += 8192) n += String.fromCharCode(...t.subarray(e, e + 8192));
|
|
1079
1079
|
let r = t[0] === 79 && t[1] === 84 && t[2] === 84 && t[3] === 79;
|
|
1080
1080
|
return `@font-face { font-family: "${e.family}"; font-weight: ${e.weight}; font-style: ${e.style}; src: url("data:font/${r ? "otf" : "ttf"};base64,${btoa(n)}") format("${r ? "opentype" : "truetype"}"); }`;
|
|
1081
1081
|
}
|
|
1082
|
-
function
|
|
1082
|
+
function ot(e) {
|
|
1083
1083
|
for (let t of e) {
|
|
1084
1084
|
let n = e.getPropertyValue(t);
|
|
1085
|
-
for (let e of n.matchAll(/url\(\s*(["']?)(.*?)\1\s*\)/gi)) if (!
|
|
1085
|
+
for (let e of n.matchAll(/url\(\s*(["']?)(.*?)\1\s*\)/gi)) if (!it.test(e[2] ?? "")) throw new D("RASTER_FAILED", `Raster capture requires inline bitmap resources (${t}).`);
|
|
1086
1086
|
}
|
|
1087
1087
|
}
|
|
1088
|
-
function
|
|
1088
|
+
function st(e, t) {
|
|
1089
1089
|
let n = e.getBoundingClientRect(), r = [e, ...e.querySelectorAll("*")];
|
|
1090
1090
|
for (let i of r) {
|
|
1091
|
-
if (!(i instanceof HTMLElement)) throw new
|
|
1092
|
-
if (i.shadowRoot || i.tagName.includes("-") || i.tagName === "SLOT") throw new
|
|
1093
|
-
if (/^(CANVAS|IFRAME|OBJECT|EMBED|VIDEO|AUDIO|INPUT|TEXTAREA|SELECT|SCRIPT|STYLE|LINK)$/.test(i.tagName)) throw new
|
|
1091
|
+
if (!(i instanceof HTMLElement)) throw new D("RASTER_FAILED", "Raster capture supports HTML subtrees only; inline SVG needs a separate experiment.");
|
|
1092
|
+
if (i.shadowRoot || i.tagName.includes("-") || i.tagName === "SLOT") throw new D("RASTER_FAILED", "Raster capture does not inspect shadow trees or distributed slot content in supported renderer.");
|
|
1093
|
+
if (/^(CANVAS|IFRAME|OBJECT|EMBED|VIDEO|AUDIO|INPUT|TEXTAREA|SELECT|SCRIPT|STYLE|LINK)$/.test(i.tagName)) throw new D("RASTER_FAILED", `Raster capture does not support ${i.tagName.toLowerCase()} elements.`);
|
|
1094
1094
|
let r = getComputedStyle(i);
|
|
1095
|
-
if (
|
|
1096
|
-
if (r.position === "fixed" || r.position === "sticky") throw new
|
|
1097
|
-
if (i !== e && r.position === "absolute") throw new
|
|
1095
|
+
if (ot(r), r.mixBlendMode !== "normal" || r.backdropFilter !== "none") throw new D("RASTER_FAILED", "Raster capture cannot reproduce blending with pixels outside its subtree.");
|
|
1096
|
+
if (r.position === "fixed" || r.position === "sticky") throw new D("RASTER_FAILED", "Raster capture does not reproduce viewport-dependent positioning.");
|
|
1097
|
+
if (i !== e && r.position === "absolute") throw new D("RASTER_FAILED", "Raster capture does not normalize external containing blocks for positioned descendants.");
|
|
1098
1098
|
let a = r.boxShadow.split(/,(?![^(]*\))/);
|
|
1099
|
-
if (r.filter !== "none" || r.boxShadow !== "none" && a.some((e) => !e.includes("inset"))) throw new
|
|
1100
|
-
if (r.textShadow !== "none" || r.outlineStyle !== "none" && Number.parseFloat(r.outlineWidth) > 0) throw new
|
|
1101
|
-
if (r.backgroundAttachment.includes("fixed")) throw new
|
|
1102
|
-
if (i === e && r.transform !== "none") throw new
|
|
1103
|
-
if (r.display === "list-item") throw new
|
|
1099
|
+
if (r.filter !== "none" || r.boxShadow !== "none" && a.some((e) => !e.includes("inset"))) throw new D("RASTER_FAILED", "Raster capture requires effects contained in the border box; outer shadows and filters need expanded bounds.");
|
|
1100
|
+
if (r.textShadow !== "none" || r.outlineStyle !== "none" && Number.parseFloat(r.outlineWidth) > 0) throw new D("RASTER_FAILED", "Raster capture requires expanded bounds before capturing text shadows or outlines.");
|
|
1101
|
+
if (r.backgroundAttachment.includes("fixed")) throw new D("RASTER_FAILED", "Raster capture does not preserve viewport-dependent background attachment.");
|
|
1102
|
+
if (i === e && r.transform !== "none") throw new D("RASTER_FAILED", "Raster capture does not normalize transformed region coordinates.");
|
|
1103
|
+
if (r.display === "list-item") throw new D("RASTER_FAILED", "Raster capture does not preserve generated list markers in supported renderer.");
|
|
1104
1104
|
for (let e of ["::before", "::after"]) {
|
|
1105
1105
|
let t = getComputedStyle(i, e).content;
|
|
1106
|
-
if (t !== "none" && t !== "normal") throw new
|
|
1106
|
+
if (t !== "none" && t !== "normal") throw new D("RASTER_FAILED", "Raster capture does not support generated pseudo-element content in supported renderer.");
|
|
1107
1107
|
}
|
|
1108
1108
|
if (i instanceof HTMLImageElement) {
|
|
1109
|
-
if (i.srcset || !
|
|
1110
|
-
if (!i.complete || i.naturalWidth === 0) throw new
|
|
1109
|
+
if (i.srcset || !it.test(i.currentSrc || i.src)) throw new D("RASTER_FAILED", "Raster capture requires inline bitmap images without srcset.");
|
|
1110
|
+
if (!i.complete || i.naturalWidth === 0) throw new D("RASTER_FAILED", "Raster capture requires successfully decoded images.");
|
|
1111
1111
|
}
|
|
1112
1112
|
if ([...i.childNodes].some((e) => e.nodeType === Node.TEXT_NODE && !!e.textContent?.trim())) {
|
|
1113
|
-
if (!r.font) throw new
|
|
1113
|
+
if (!r.font) throw new D("RASTER_FAILED", "Raster capture requires a serializable computed font shorthand to preserve exact font sizes.");
|
|
1114
1114
|
let e = r.fontFamily.split(",")[0]?.trim().replace(/^["']|["']$/g, "");
|
|
1115
|
-
if (!t.some((t) => t.family.toLowerCase() === e?.toLowerCase() && t.weight === Number(r.fontWeight) && t.style === r.fontStyle)) throw new
|
|
1115
|
+
if (!t.some((t) => t.family.toLowerCase() === e?.toLowerCase() && t.weight === Number(r.fontWeight) && t.style === r.fontStyle)) throw new D("RASTER_FAILED", "Raster capture text requires an explicitly registered matching font face.");
|
|
1116
1116
|
}
|
|
1117
1117
|
let o = i.getBoundingClientRect();
|
|
1118
|
-
if (o.width > 0 && o.height > 0 && (o.left < n.left - .5 || o.top < n.top - .5 || o.right > n.right + .5 || o.bottom > n.bottom + .5)) throw new
|
|
1118
|
+
if (o.width > 0 && o.height > 0 && (o.left < n.left - .5 || o.top < n.top - .5 || o.right > n.right + .5 || o.bottom > n.bottom + .5)) throw new D("RASTER_FAILED", "Raster capture descendants must stay inside the selected border box.");
|
|
1119
1119
|
}
|
|
1120
1120
|
}
|
|
1121
|
-
async function
|
|
1121
|
+
async function ct(e, t, n, r = {
|
|
1122
1122
|
x: 0,
|
|
1123
1123
|
y: 0
|
|
1124
1124
|
}) {
|
|
1125
|
-
if (!e.isConnected || e.ownerDocument !== document) throw new
|
|
1126
|
-
if (!Number.isFinite(n) || n <= 0) throw new
|
|
1127
|
-
if (!r || ![r.x, r.y].every((e) => Number.isFinite(e) && e >= 0 && e < 1)) throw new
|
|
1125
|
+
if (!e.isConnected || e.ownerDocument !== document) throw new D("RASTER_FAILED", "Raster capture requires a connected element in the current document.");
|
|
1126
|
+
if (!Number.isFinite(n) || n <= 0) throw new D("RASTER_FAILED", "Raster scale must be a finite positive number.");
|
|
1127
|
+
if (!r || ![r.x, r.y].every((e) => Number.isFinite(e) && e >= 0 && e < 1)) throw new D("RASTER_FAILED", "Raster offsets must be finite CSS pixel fractions from zero inclusive to one exclusive.");
|
|
1128
1128
|
await document.fonts.ready;
|
|
1129
1129
|
let { width: i, height: a } = e.getBoundingClientRect(), o = Math.ceil(i + r.x), s = Math.ceil(a + r.y), c = Math.ceil(o * n), l = Math.ceil(s * n);
|
|
1130
|
-
if (i <= 0 || a <= 0 || c < 1 || l < 1 || c >
|
|
1131
|
-
|
|
1132
|
-
let u = t.map(
|
|
1130
|
+
if (i <= 0 || a <= 0 || c < 1 || l < 1 || c > rt || l > rt || c * l > nt) throw new D("RASTER_FAILED", "Raster region exceeds the supported renderer canvas budget or has empty bounds.");
|
|
1131
|
+
st(e, t);
|
|
1132
|
+
let u = t.map(at).join("\n"), d = ["font", ...Array.from(getComputedStyle(e)).filter((e) => e !== "font-size")], f = (await fe(e, {
|
|
1133
1133
|
width: o,
|
|
1134
1134
|
height: s,
|
|
1135
1135
|
pixelRatio: n,
|
|
@@ -1148,12 +1148,12 @@ async function ze(e, t, n, r = {
|
|
|
1148
1148
|
transform: `translate(${r.x}px, ${r.y}px)`
|
|
1149
1149
|
}
|
|
1150
1150
|
})).match(/^data:image\/png;base64,(.+)$/)?.[1];
|
|
1151
|
-
if (!f) throw new
|
|
1151
|
+
if (!f) throw new D("RASTER_FAILED", "Raster capture produced an empty or invalid PNG.");
|
|
1152
1152
|
let p = atob(f);
|
|
1153
1153
|
return Uint8Array.from(p, (e) => e.charCodeAt(0));
|
|
1154
1154
|
}
|
|
1155
1155
|
// src/text.ts
|
|
1156
|
-
var
|
|
1156
|
+
var lt = class {
|
|
1157
1157
|
font;
|
|
1158
1158
|
program;
|
|
1159
1159
|
words = /* @__PURE__ */ new Map();
|
|
@@ -1167,11 +1167,11 @@ var Be = class {
|
|
|
1167
1167
|
let n = `${t ? "1" : "0"}:${e}`, r = this.words.get(n);
|
|
1168
1168
|
if (r) return r;
|
|
1169
1169
|
let a = this.program.layout(e, { kern: t }), o = this.font.encodeText(e).asString();
|
|
1170
|
-
if (o.length !== a.glyphs.length * 4) throw new
|
|
1170
|
+
if (o.length !== a.glyphs.length * 4) throw new D("PDF_WRITE_FAILED", "PDF font encoding disagrees with font shaping.");
|
|
1171
1171
|
let s = 0, c = 0, l = a.glyphs.map((e, t) => {
|
|
1172
1172
|
let n = o.slice(t * 4, t * 4 + 4);
|
|
1173
|
-
if (Number.parseInt(n, 16) !== e.id) throw new
|
|
1174
|
-
if (e.codePoints.length === 0) throw new
|
|
1173
|
+
if (Number.parseInt(n, 16) !== e.id) throw new D("PDF_WRITE_FAILED", "PDF glyph identifiers disagree with shaping.");
|
|
1174
|
+
if (e.codePoints.length === 0) throw new D("PDF_WRITE_FAILED", "The font produced a shaped glyph without a Unicode source mapping.");
|
|
1175
1175
|
let r = a.positions[t];
|
|
1176
1176
|
this.unicode.has(n) || this.unicode.set(n, [...e.codePoints]), this.widths.set(n, e.advanceWidth * 1e3 / this.unitsPerEm);
|
|
1177
1177
|
let l = {
|
|
@@ -1227,41 +1227,41 @@ var Be = class {
|
|
|
1227
1227
|
let c = s.lookup(a.of("DescendantFonts"), t).lookup(0, n), l = [...this.widths].sort(([e], [t]) => Number.parseInt(e, 16) - Number.parseInt(t, 16)).flatMap(([e, t]) => [Number.parseInt(e, 16), [t]]);
|
|
1228
1228
|
c.set(a.of("W"), e.context.obj(l));
|
|
1229
1229
|
}
|
|
1230
|
-
},
|
|
1231
|
-
function
|
|
1230
|
+
}, I = .75;
|
|
1231
|
+
function L(e) {
|
|
1232
1232
|
let t = e.match(/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/);
|
|
1233
|
-
if (!t) throw new
|
|
1233
|
+
if (!t) throw new D("UNSUPPORTED_CSS", `Unsupported computed color: ${e}`);
|
|
1234
1234
|
return {
|
|
1235
|
-
color:
|
|
1235
|
+
color: ne(Number(t[1]) / 255, Number(t[2]) / 255, Number(t[3]) / 255),
|
|
1236
1236
|
opacity: Number(t[4] ?? 1)
|
|
1237
1237
|
};
|
|
1238
1238
|
}
|
|
1239
|
-
function
|
|
1239
|
+
function R(e, t) {
|
|
1240
1240
|
let n = t.find(({ definition: t }) => t.family.toLowerCase() === e.family.toLowerCase() && t.weight === e.weight && t.style === e.style);
|
|
1241
|
-
if (!n) throw new
|
|
1242
|
-
for (let t of e.text) if (!n.characters.has(t.codePointAt(0))) throw new
|
|
1241
|
+
if (!n) throw new D("MISSING_FONT", `Unregistered font face: ${e.family} ${e.weight} ${e.style}`);
|
|
1242
|
+
for (let t of e.text) if (!n.characters.has(t.codePointAt(0))) throw new D("MISSING_GLYPH", `Missing glyph: ${t} (${e.family} ${e.weight} ${e.style})`);
|
|
1243
1243
|
return n;
|
|
1244
1244
|
}
|
|
1245
|
-
function
|
|
1246
|
-
let
|
|
1247
|
-
if (
|
|
1248
|
-
let t = a.opacity.get(
|
|
1245
|
+
function ut(e, t, n, r, i, a) {
|
|
1246
|
+
let o = L(t.color), s = a.fonts.get(n.font);
|
|
1247
|
+
if (s || (s = e.node.newFontDictionary(n.font.name, n.font.ref), a.fonts.set(n.font, s)), e.pushOperators(E(), re(o.color)), o.opacity !== 1) {
|
|
1248
|
+
let t = a.opacity.get(o.opacity);
|
|
1249
1249
|
t || (t = e.node.newExtGState("TextOpacity", e.doc.context.obj({
|
|
1250
1250
|
Type: "ExtGState",
|
|
1251
|
-
ca:
|
|
1252
|
-
})), a.opacity.set(
|
|
1251
|
+
ca: o.opacity
|
|
1252
|
+
})), a.opacity.set(o.opacity, t)), e.pushOperators(ae(t));
|
|
1253
1253
|
}
|
|
1254
|
-
e.pushOperators(
|
|
1255
|
-
let
|
|
1254
|
+
e.pushOperators(f(), ie(s, t.fontSize * I), le(t.invisible ? u.Invisible : u.Fill));
|
|
1255
|
+
let c = t.fontSize * I / n.positioned.unitsPerEm, l = (i.height - i.margin.top - (t.baseline - r)) * I;
|
|
1256
1256
|
for (let r of t.runs) {
|
|
1257
|
-
let a = (i.margin.left + r.x) *
|
|
1258
|
-
for (let i of n.positioned.shape(r.text, t.kerning ?? !0)) e.pushOperators(
|
|
1257
|
+
let a = (i.margin.left + r.x) * I;
|
|
1258
|
+
for (let i of n.positioned.shape(r.text, t.kerning ?? !0)) e.pushOperators(ce(1, 0, 0, 1, a + i.x * c, l + i.y * c), ue(i.encoded));
|
|
1259
1259
|
}
|
|
1260
|
-
e.pushOperators(
|
|
1260
|
+
e.pushOperators(x(), T());
|
|
1261
1261
|
}
|
|
1262
|
-
function
|
|
1262
|
+
function dt(e, t, n, r, i, a) {
|
|
1263
1263
|
let o = e.text.replaceAll("{pageNumber}", String(t)).replaceAll("{pageCount}", String(n)), s = a.find((t) => t.definition === e.font), c = e.fontSize / s.positioned.unitsPerEm, l = s.positioned.measure(o), u = (l.right - l.left) * c, d = (l.ascent + l.descent) * c, f = i.width - i.margin.left - i.margin.right;
|
|
1264
|
-
if (u > f + .01 || d > e.height + .01) throw new
|
|
1264
|
+
if (u > f + .01 || d > e.height + .01) throw new D("SOURCE_OVERFLOW", "Page header/footer text does not fit its reserved height or page content width; increase its area or reduce fontSize.");
|
|
1265
1265
|
let p = e.align === "right" ? f - u : e.align === "center" ? (f - u) / 2 : 0, m = p - l.left * c, h = r - i.margin.top + (e.height - d) / 2;
|
|
1266
1266
|
return {
|
|
1267
1267
|
kind: "text",
|
|
@@ -1286,7 +1286,7 @@ function Ve(e, t, n, r, i, a) {
|
|
|
1286
1286
|
invisible: !1
|
|
1287
1287
|
};
|
|
1288
1288
|
}
|
|
1289
|
-
function
|
|
1289
|
+
function ft(e) {
|
|
1290
1290
|
let t = Math.floor(e.x), n = Math.floor(e.y);
|
|
1291
1291
|
return {
|
|
1292
1292
|
x: t,
|
|
@@ -1295,10 +1295,10 @@ function He(e) {
|
|
|
1295
1295
|
height: Math.ceil(e.y + e.height) - n
|
|
1296
1296
|
};
|
|
1297
1297
|
}
|
|
1298
|
-
async function
|
|
1298
|
+
async function pt(e, t, n) {
|
|
1299
1299
|
let r = t.currentSrc || t.src;
|
|
1300
1300
|
try {
|
|
1301
|
-
|
|
1301
|
+
O(n);
|
|
1302
1302
|
let t = await fetch(r, {
|
|
1303
1303
|
mode: "cors",
|
|
1304
1304
|
credentials: "same-origin",
|
|
@@ -1306,65 +1306,65 @@ async function Ue(e, t, n) {
|
|
|
1306
1306
|
});
|
|
1307
1307
|
if (!t.ok) throw Error(`Image request returned HTTP ${t.status}.`);
|
|
1308
1308
|
let i = new Uint8Array(await t.arrayBuffer());
|
|
1309
|
-
return
|
|
1309
|
+
return O(n), tt(i) === "png" ? await e.embedPng(i) : await e.embedJpg(i);
|
|
1310
1310
|
} catch (e) {
|
|
1311
|
-
throw
|
|
1311
|
+
throw O(n), e instanceof D ? e : new D("RESOURCE_LOAD_FAILED", "The source image could not be embedded; provide a readable PNG/JPEG with same-origin or CORS access.", { cause: e });
|
|
1312
1312
|
}
|
|
1313
1313
|
}
|
|
1314
|
-
async function
|
|
1314
|
+
async function mt(t, n, i, a, o = {}) {
|
|
1315
1315
|
try {
|
|
1316
|
-
if (
|
|
1316
|
+
if (O(o.signal), t.width > i.width - i.margin.left - i.margin.right) throw new D("SOURCE_OVERFLOW", "Source is wider than the PDF content area.");
|
|
1317
1317
|
let s = await r.create();
|
|
1318
|
-
|
|
1319
|
-
let
|
|
1318
|
+
O(o.signal), s.registerFontkit(e), A(s, o.metadata);
|
|
1319
|
+
let c = o.reportProgress ? n.length + t.operations.filter((e) => e.kind === "image" || e.kind === "raster").length : 0, l = 0;
|
|
1320
1320
|
o.reportProgress && await o.reportProgress({
|
|
1321
1321
|
stage: "resources",
|
|
1322
1322
|
completed: 0,
|
|
1323
|
-
total:
|
|
1323
|
+
total: c
|
|
1324
1324
|
});
|
|
1325
|
-
let
|
|
1325
|
+
let u = [];
|
|
1326
1326
|
for (let e of n) {
|
|
1327
|
-
|
|
1327
|
+
O(o.signal);
|
|
1328
1328
|
let t = await s.embedFont(e.bytes);
|
|
1329
|
-
|
|
1329
|
+
u.push({
|
|
1330
1330
|
definition: e,
|
|
1331
1331
|
font: t,
|
|
1332
1332
|
characters: new Set(t.getCharacterSet()),
|
|
1333
|
-
positioned: new
|
|
1334
|
-
}),
|
|
1333
|
+
positioned: new lt(t, e.bytes)
|
|
1334
|
+
}), l += 1, o.reportProgress && await o.reportProgress({
|
|
1335
1335
|
stage: "resources",
|
|
1336
|
-
completed:
|
|
1337
|
-
total:
|
|
1336
|
+
completed: l,
|
|
1337
|
+
total: c
|
|
1338
1338
|
});
|
|
1339
1339
|
}
|
|
1340
|
-
for (let e of t.operations) e.kind !== "text" || e.invisible && o.includeRasterText === !1 ||
|
|
1341
|
-
let
|
|
1340
|
+
for (let e of t.operations) e.kind !== "text" || e.invisible && o.includeRasterText === !1 || R(e, u);
|
|
1341
|
+
let d = a.map((e, t) => {
|
|
1342
1342
|
let n = [];
|
|
1343
|
-
o.header && n.push(
|
|
1344
|
-
for (let e of n)
|
|
1343
|
+
o.header && n.push(dt(o.header, t + 1, a.length, i.margin.top, i, u)), o.footer && n.push(dt(o.footer, t + 1, a.length, i.height - i.margin.bottom - o.footer.height, i, u));
|
|
1344
|
+
for (let e of n) R(e, u);
|
|
1345
1345
|
return n;
|
|
1346
|
-
}),
|
|
1346
|
+
}), f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map();
|
|
1347
1347
|
for (let e of t.operations) {
|
|
1348
|
-
if (
|
|
1349
|
-
let t =
|
|
1348
|
+
if (O(o.signal), e.kind === "raster") {
|
|
1349
|
+
let t = ft(e.bounds);
|
|
1350
1350
|
try {
|
|
1351
|
-
let r = await
|
|
1351
|
+
let r = await ct(e.element, n, o.rasterScale ?? 2, {
|
|
1352
1352
|
x: e.bounds.x - t.x,
|
|
1353
1353
|
y: e.bounds.y - t.y
|
|
1354
1354
|
});
|
|
1355
|
-
|
|
1355
|
+
O(o.signal), f.set(e, await s.embedPng(r));
|
|
1356
1356
|
} catch (e) {
|
|
1357
|
-
throw
|
|
1357
|
+
throw O(o.signal), e instanceof D ? e : new D("RASTER_FAILED", "The selected local raster region could not be captured.", { cause: e });
|
|
1358
1358
|
}
|
|
1359
1359
|
}
|
|
1360
1360
|
if (e.kind === "image") {
|
|
1361
|
-
let t = e.element.currentSrc || e.element.src, n =
|
|
1362
|
-
n || (n = await
|
|
1361
|
+
let t = e.element.currentSrc || e.element.src, n = p.get(t);
|
|
1362
|
+
n || (n = await pt(s, e.element, o.signal), p.set(t, n)), f.set(e, n);
|
|
1363
1363
|
}
|
|
1364
|
-
(e.kind === "image" || e.kind === "raster") && (
|
|
1364
|
+
(e.kind === "image" || e.kind === "raster") && (l += 1, o.reportProgress && await o.reportProgress({
|
|
1365
1365
|
stage: "resources",
|
|
1366
|
-
completed:
|
|
1367
|
-
total:
|
|
1366
|
+
completed: l,
|
|
1367
|
+
total: c
|
|
1368
1368
|
}));
|
|
1369
1369
|
}
|
|
1370
1370
|
o.reportProgress && await o.reportProgress({
|
|
@@ -1373,12 +1373,12 @@ async function We(t, n, i, a, o = {}) {
|
|
|
1373
1373
|
total: a.length
|
|
1374
1374
|
});
|
|
1375
1375
|
for (let [e, n] of a.entries()) {
|
|
1376
|
-
|
|
1377
|
-
let r = s.addPage([i.width *
|
|
1376
|
+
O(o.signal);
|
|
1377
|
+
let r = s.addPage([i.width * I, i.height * I]), c = {
|
|
1378
1378
|
fonts: /* @__PURE__ */ new Map(),
|
|
1379
1379
|
opacity: /* @__PURE__ */ new Map()
|
|
1380
1380
|
};
|
|
1381
|
-
function
|
|
1381
|
+
function l(e, t, n) {
|
|
1382
1382
|
let a = {
|
|
1383
1383
|
...i,
|
|
1384
1384
|
margin: {
|
|
@@ -1386,67 +1386,67 @@ async function We(t, n, i, a, o = {}) {
|
|
|
1386
1386
|
top: n.y
|
|
1387
1387
|
}
|
|
1388
1388
|
};
|
|
1389
|
-
r.pushOperators(
|
|
1389
|
+
r.pushOperators(E(), te(n.x * I, (i.height - n.y - n.height) * I, n.width * I, n.height * I), m(), b());
|
|
1390
1390
|
for (let s of e) {
|
|
1391
1391
|
let e = s.bounds;
|
|
1392
1392
|
if (e.y >= t + n.height - .01 || e.y + e.height <= t + .01) continue;
|
|
1393
1393
|
if (s.kind === "text") {
|
|
1394
|
-
s.invisible && o.includeRasterText === !1 ||
|
|
1394
|
+
s.invisible && o.includeRasterText === !1 || ut(r, s, R(s, u), t, a, c);
|
|
1395
1395
|
continue;
|
|
1396
1396
|
}
|
|
1397
|
-
let
|
|
1398
|
-
x: (i.margin.left +
|
|
1399
|
-
y: (i.height - n.y - (
|
|
1400
|
-
width:
|
|
1401
|
-
height:
|
|
1397
|
+
let l = s.kind === "raster" ? ft(e) : e, d = {
|
|
1398
|
+
x: (i.margin.left + l.x) * I,
|
|
1399
|
+
y: (i.height - n.y - (l.y - t) - l.height) * I,
|
|
1400
|
+
width: l.width * I,
|
|
1401
|
+
height: l.height * I
|
|
1402
1402
|
};
|
|
1403
1403
|
if (s.kind === "box") {
|
|
1404
|
-
let e =
|
|
1404
|
+
let e = L(s.background), t = L(s.borderColor);
|
|
1405
1405
|
if (r.drawRectangle({
|
|
1406
|
-
...
|
|
1406
|
+
...d,
|
|
1407
1407
|
color: e.color,
|
|
1408
1408
|
opacity: e.opacity
|
|
1409
1409
|
}), s.borderWidth > 0) {
|
|
1410
|
-
let e = s.borderWidth *
|
|
1410
|
+
let e = s.borderWidth * I / 2;
|
|
1411
1411
|
r.drawRectangle({
|
|
1412
|
-
x:
|
|
1413
|
-
y:
|
|
1414
|
-
width:
|
|
1415
|
-
height:
|
|
1416
|
-
borderWidth: s.borderWidth *
|
|
1412
|
+
x: d.x + e,
|
|
1413
|
+
y: d.y + e,
|
|
1414
|
+
width: d.width - e * 2,
|
|
1415
|
+
height: d.height - e * 2,
|
|
1416
|
+
borderWidth: s.borderWidth * I,
|
|
1417
1417
|
borderColor: t.color,
|
|
1418
1418
|
borderOpacity: t.opacity
|
|
1419
1419
|
});
|
|
1420
1420
|
}
|
|
1421
1421
|
} else if (s.kind === "border") {
|
|
1422
|
-
let e =
|
|
1422
|
+
let e = L(s.color);
|
|
1423
1423
|
r.drawRectangle({
|
|
1424
|
-
...
|
|
1424
|
+
...d,
|
|
1425
1425
|
color: e.color,
|
|
1426
1426
|
opacity: e.opacity
|
|
1427
1427
|
});
|
|
1428
|
-
} else r.drawImage(
|
|
1428
|
+
} else r.drawImage(f.get(s), d);
|
|
1429
1429
|
}
|
|
1430
|
-
r.pushOperators(
|
|
1430
|
+
r.pushOperators(T());
|
|
1431
1431
|
}
|
|
1432
|
-
let
|
|
1432
|
+
let p = i.margin.top + (o.header?.height ?? 0), h = n.headerHeight ?? (n.header ? n.header.bodyStart - n.header.bounds.y : 0);
|
|
1433
1433
|
if (o.header) {
|
|
1434
|
-
let t =
|
|
1435
|
-
|
|
1434
|
+
let t = d[e][0];
|
|
1435
|
+
ut(r, t, R(t, u), 0, i, c);
|
|
1436
1436
|
}
|
|
1437
|
-
if (n.header &&
|
|
1437
|
+
if (n.header && l(n.header.operations, n.header.bounds.y, {
|
|
1438
1438
|
x: i.margin.left + n.header.bounds.x,
|
|
1439
|
-
y:
|
|
1439
|
+
y: p,
|
|
1440
1440
|
width: n.header.bounds.width,
|
|
1441
|
-
height:
|
|
1442
|
-
}),
|
|
1441
|
+
height: h
|
|
1442
|
+
}), l(t.operations, n.start, {
|
|
1443
1443
|
x: i.margin.left,
|
|
1444
|
-
y:
|
|
1444
|
+
y: p + h,
|
|
1445
1445
|
width: i.width - i.margin.left - i.margin.right,
|
|
1446
1446
|
height: n.end - n.start
|
|
1447
1447
|
}), o.footer) {
|
|
1448
|
-
let t =
|
|
1449
|
-
|
|
1448
|
+
let t = d[e].at(-1);
|
|
1449
|
+
ut(r, t, R(t, u), 0, i, c);
|
|
1450
1450
|
}
|
|
1451
1451
|
o.reportProgress && await o.reportProgress({
|
|
1452
1452
|
stage: "pages",
|
|
@@ -1454,34 +1454,34 @@ async function We(t, n, i, a, o = {}) {
|
|
|
1454
1454
|
total: a.length
|
|
1455
1455
|
});
|
|
1456
1456
|
}
|
|
1457
|
-
|
|
1457
|
+
O(o.signal), o.reportProgress && await o.reportProgress({
|
|
1458
1458
|
stage: "saving",
|
|
1459
1459
|
completed: 0,
|
|
1460
1460
|
total: 1
|
|
1461
1461
|
});
|
|
1462
|
-
for (let e of
|
|
1463
|
-
let
|
|
1464
|
-
return
|
|
1462
|
+
for (let e of u) await e.positioned.embedUnicode(s), O(o.signal);
|
|
1463
|
+
let h = Uint8Array.from(await s.save());
|
|
1464
|
+
return O(o.signal), o.reportProgress && await o.reportProgress({
|
|
1465
1465
|
stage: "saving",
|
|
1466
1466
|
completed: 1,
|
|
1467
1467
|
total: 1
|
|
1468
1468
|
}), {
|
|
1469
|
-
bytes:
|
|
1469
|
+
bytes: h,
|
|
1470
1470
|
slices: a
|
|
1471
1471
|
};
|
|
1472
1472
|
} catch (e) {
|
|
1473
|
-
throw
|
|
1473
|
+
throw O(o.signal), e instanceof D ? e : new D("PDF_WRITE_FAILED", "The measured content could not be serialized as a PDF.", { cause: e });
|
|
1474
1474
|
}
|
|
1475
1475
|
}
|
|
1476
1476
|
// src/prepare.ts
|
|
1477
|
-
async function
|
|
1478
|
-
return
|
|
1477
|
+
async function z(e, t) {
|
|
1478
|
+
return O(t), t ? new Promise((n, r) => {
|
|
1479
1479
|
let i = () => r(new DOMException("PDF rendering was cancelled.", "AbortError"));
|
|
1480
1480
|
t.addEventListener("abort", i, { once: !0 }), e.then(n, r).finally(() => t.removeEventListener("abort", i));
|
|
1481
1481
|
}) : e;
|
|
1482
1482
|
}
|
|
1483
|
-
function
|
|
1484
|
-
if (
|
|
1483
|
+
function ht(e, t) {
|
|
1484
|
+
if (O(t), typeof document > "u" || !(e instanceof HTMLElement) || !e.isConnected || e.ownerDocument !== document) throw new D("INVALID_SOURCE", "Provide a connected HTMLElement in the current document.");
|
|
1485
1485
|
let n = !1, r, i = /* @__PURE__ */ new Map(), a = new MutationObserver(() => {
|
|
1486
1486
|
n = !0;
|
|
1487
1487
|
}), o = [];
|
|
@@ -1531,18 +1531,18 @@ function Ge(e, t) {
|
|
|
1531
1531
|
return `${t >>> 0}:${n >>> 0}`;
|
|
1532
1532
|
}
|
|
1533
1533
|
function d() {
|
|
1534
|
-
if (
|
|
1534
|
+
if (O(t), a.takeRecords().length && (n = !0), !e.isConnected || n || r !== void 0 && u() !== r) throw new D("SOURCE_CHANGED", "The source or its styles changed during PDF rendering. Retry with a stable source.");
|
|
1535
1535
|
}
|
|
1536
1536
|
function f() {
|
|
1537
|
-
if (d(), [...e.getAnimations({ subtree: !0 }), ...o.flatMap((e) => e.getAnimations())].some((e) => e.playState === "running")) throw new
|
|
1537
|
+
if (d(), [...e.getAnimations({ subtree: !0 }), ...o.flatMap((e) => e.getAnimations())].some((e) => e.playState === "running")) throw new D("UNSUPPORTED_CSS", "Pause source animations before rendering a PDF.");
|
|
1538
1538
|
r = u();
|
|
1539
1539
|
}
|
|
1540
1540
|
async function p() {
|
|
1541
|
-
await
|
|
1541
|
+
await z(document.fonts.ready, t);
|
|
1542
1542
|
try {
|
|
1543
|
-
await
|
|
1543
|
+
await z(Promise.all([...e.querySelectorAll("img"), ...e instanceof HTMLImageElement ? [e] : []].map((e) => e.decode())), t);
|
|
1544
1544
|
} catch (e) {
|
|
1545
|
-
throw
|
|
1545
|
+
throw O(t), new D("RESOURCE_LOAD_FAILED", "A source image could not be decoded.", { cause: e });
|
|
1546
1546
|
}
|
|
1547
1547
|
d();
|
|
1548
1548
|
}
|
|
@@ -1554,25 +1554,25 @@ function Ge(e, t) {
|
|
|
1554
1554
|
};
|
|
1555
1555
|
}
|
|
1556
1556
|
// src/progress.ts
|
|
1557
|
-
function
|
|
1557
|
+
function gt(e, t) {
|
|
1558
1558
|
let n, r = 0;
|
|
1559
1559
|
return {
|
|
1560
1560
|
report: e ? async (i) => {
|
|
1561
|
-
|
|
1561
|
+
O(t);
|
|
1562
1562
|
try {
|
|
1563
1563
|
e(Object.freeze({ ...i }));
|
|
1564
1564
|
} catch (e) {
|
|
1565
1565
|
throw n = { error: e }, e;
|
|
1566
1566
|
}
|
|
1567
|
-
|
|
1567
|
+
O(t), i.stage !== "complete" && (i.completed === 0 || i.completed === i.total || performance.now() - r >= 32) && (await new Promise((e) => setTimeout(e, 0)), r = performance.now(), O(t));
|
|
1568
1568
|
} : void 0,
|
|
1569
1569
|
rethrow(e) {
|
|
1570
|
-
throw n ? n.error : (
|
|
1570
|
+
throw n ? n.error : (O(t), e);
|
|
1571
1571
|
}
|
|
1572
1572
|
};
|
|
1573
1573
|
}
|
|
1574
1574
|
// src/result.ts
|
|
1575
|
-
function
|
|
1575
|
+
function B(e, t, n) {
|
|
1576
1576
|
let r = Uint8Array.from(e), i = Object.freeze(n.map((e) => Object.freeze({ ...e })));
|
|
1577
1577
|
return Object.freeze({
|
|
1578
1578
|
pageCount: t,
|
|
@@ -1584,7 +1584,7 @@ function qe(e, t, n) {
|
|
|
1584
1584
|
return new Blob([r], { type: "application/pdf" });
|
|
1585
1585
|
},
|
|
1586
1586
|
async download(e = "document.pdf") {
|
|
1587
|
-
if (typeof e != "string" || !e.trim() || /[/\\]/.test(e) || [...e].some((e) => e.codePointAt(0) < 32)) throw new
|
|
1587
|
+
if (typeof e != "string" || !e.trim() || /[/\\]/.test(e) || [...e].some((e) => e.codePointAt(0) < 32)) throw new D("INVALID_OPTIONS", "Provide a nonempty PDF filename without path separators or control characters.");
|
|
1588
1588
|
let t = URL.createObjectURL(new Blob([r], { type: "application/pdf" }));
|
|
1589
1589
|
try {
|
|
1590
1590
|
let n = document.createElement("a");
|
|
@@ -1596,10 +1596,10 @@ function qe(e, t, n) {
|
|
|
1596
1596
|
});
|
|
1597
1597
|
}
|
|
1598
1598
|
// src/render-pdf.ts
|
|
1599
|
-
async function
|
|
1600
|
-
let r =
|
|
1601
|
-
|
|
1602
|
-
let { signal: s, onWarning: c, onProgress: l, rasterScale: u = 2, fallback: d = "auto", pageBreak: f = "css", repeatTableHeaders: p = !1 } = t, m =
|
|
1599
|
+
async function _t(e, t, n = !0) {
|
|
1600
|
+
let r = Je(t), i = Xe(r, t), a = k(t.metadata), o = [...t.fonts];
|
|
1601
|
+
Ee(o);
|
|
1602
|
+
let { signal: s, onWarning: c, onProgress: l, rasterScale: u = 2, fallback: d = "auto", pageBreak: f = "css", repeatTableHeaders: p = !1 } = t, m = ht(e, s), h = gt(l, s), g = h.report;
|
|
1603
1603
|
try {
|
|
1604
1604
|
g && await g({
|
|
1605
1605
|
stage: "preparing",
|
|
@@ -1614,7 +1614,7 @@ async function Je(e, t, n = !0) {
|
|
|
1614
1614
|
completed: 0,
|
|
1615
1615
|
total: 1
|
|
1616
1616
|
}), m.assertUnchanged();
|
|
1617
|
-
let t =
|
|
1617
|
+
let t = Ke(e, o, {
|
|
1618
1618
|
fallback: d,
|
|
1619
1619
|
repeatTableHeaders: p
|
|
1620
1620
|
});
|
|
@@ -1626,9 +1626,9 @@ async function Je(e, t, n = !0) {
|
|
|
1626
1626
|
stage: "pagination",
|
|
1627
1627
|
completed: 0,
|
|
1628
1628
|
total: 1
|
|
1629
|
-
}), g && m.assertUnchanged(), t.width > r.width - r.margin.left - r.margin.right) throw new
|
|
1630
|
-
f === "css" && Object.assign(t,
|
|
1631
|
-
let l = [], h =
|
|
1629
|
+
}), g && m.assertUnchanged(), t.width > r.width - r.margin.left - r.margin.right) throw new D("SOURCE_OVERFLOW", "Source is wider than the configured page content area. Set the source width explicitly; no implicit scaling is applied.");
|
|
1630
|
+
f === "css" && Object.assign(t, be(e, t));
|
|
1631
|
+
let l = [], h = $e(t, i.content.height - i.content.margin.top - i.content.margin.bottom, (e) => l.push(e));
|
|
1632
1632
|
g && await g({
|
|
1633
1633
|
stage: "pagination",
|
|
1634
1634
|
completed: 1,
|
|
@@ -1641,7 +1641,7 @@ async function Je(e, t, n = !0) {
|
|
|
1641
1641
|
});
|
|
1642
1642
|
for (let e of _) c?.(Object.freeze(e));
|
|
1643
1643
|
(c || g) && m.assertUnchanged();
|
|
1644
|
-
let v = await
|
|
1644
|
+
let v = await z(mt(t, o, r, h, {
|
|
1645
1645
|
rasterScale: u,
|
|
1646
1646
|
includeRasterText: n,
|
|
1647
1647
|
...i.header ? { header: i.header } : {},
|
|
@@ -1650,11 +1650,11 @@ async function Je(e, t, n = !0) {
|
|
|
1650
1650
|
...g ? { reportProgress: g } : {},
|
|
1651
1651
|
...s ? { signal: s } : {}
|
|
1652
1652
|
}), s);
|
|
1653
|
-
return m.assertUnchanged(),
|
|
1653
|
+
return m.assertUnchanged(), Ee(o), O(s), g && (await g({
|
|
1654
1654
|
stage: "complete",
|
|
1655
1655
|
completed: 1,
|
|
1656
1656
|
total: 1
|
|
1657
|
-
}), m.assertUnchanged(),
|
|
1657
|
+
}), m.assertUnchanged(), Ee(o)), {
|
|
1658
1658
|
...v,
|
|
1659
1659
|
snapshot: t,
|
|
1660
1660
|
warnings: _
|
|
@@ -1665,18 +1665,18 @@ async function Je(e, t, n = !0) {
|
|
|
1665
1665
|
m.dispose();
|
|
1666
1666
|
}
|
|
1667
1667
|
}
|
|
1668
|
-
async function
|
|
1669
|
-
let n = await
|
|
1670
|
-
return
|
|
1668
|
+
async function vt(e, t) {
|
|
1669
|
+
let n = await _t(e, t);
|
|
1670
|
+
return B(n.bytes, n.slices.length, n.warnings);
|
|
1671
1671
|
}
|
|
1672
1672
|
// src/image-geometry.ts
|
|
1673
|
-
var
|
|
1674
|
-
function
|
|
1675
|
-
if (!Number.isSafeInteger(e) || !Number.isSafeInteger(t) || e <= 0 || t <= 0) throw new
|
|
1676
|
-
if (e > 4e7 / t) throw new
|
|
1673
|
+
var yt = 4e7;
|
|
1674
|
+
function V(e, t) {
|
|
1675
|
+
if (!Number.isSafeInteger(e) || !Number.isSafeInteger(t) || e <= 0 || t <= 0) throw new D("INVALID_SOURCE", "Image dimensions must be positive safe integers.");
|
|
1676
|
+
if (e > 4e7 / t) throw new D("UNSUPPORTED_IMAGE", `Each image frame must contain at most ${yt} pixels.`);
|
|
1677
1677
|
}
|
|
1678
|
-
function
|
|
1679
|
-
if (
|
|
1678
|
+
function bt(e, t, n, r) {
|
|
1679
|
+
if (V(e, t), !Number.isInteger(n) || n < 1 || n > 8) throw new D("INVALID_SOURCE", "Image orientation must be an integer from 1 through 8.");
|
|
1680
1680
|
let i = n >= 5 ? t : e, a = n >= 5 ? e : t, o = r.width - r.margin.left - r.margin.right, s = r.height - r.margin.top - r.margin.bottom, c = Math.min(o / i, s / a), l = i * c, u = a * c, d = r.margin.left + (o - l) / 2, f = r.margin.bottom + (s - u) / 2, [p, m, h, g, _, v] = [
|
|
1681
1681
|
[
|
|
1682
1682
|
1,
|
|
@@ -1753,31 +1753,31 @@ function Ze(e, t, n, r) {
|
|
|
1753
1753
|
];
|
|
1754
1754
|
}
|
|
1755
1755
|
// src/image-input.ts
|
|
1756
|
-
function
|
|
1757
|
-
throw new
|
|
1756
|
+
function H(e) {
|
|
1757
|
+
throw new D("INVALID_SOURCE", e);
|
|
1758
1758
|
}
|
|
1759
|
-
var
|
|
1759
|
+
var xt = Uint32Array.from({ length: 256 }, (e, t) => {
|
|
1760
1760
|
let n = t;
|
|
1761
1761
|
for (let e = 0; e < 8; e += 1) n = n >>> 1 ^ (n & 1 ? 3988292384 : 0);
|
|
1762
1762
|
return n >>> 0;
|
|
1763
1763
|
});
|
|
1764
|
-
function
|
|
1764
|
+
function St(e, t, n) {
|
|
1765
1765
|
let r = 4294967295;
|
|
1766
|
-
for (let i = t; i < n; i += 1) r =
|
|
1766
|
+
for (let i = t; i < n; i += 1) r = xt[(r ^ e[i]) & 255] ^ r >>> 8;
|
|
1767
1767
|
return (r ^ 4294967295) >>> 0;
|
|
1768
1768
|
}
|
|
1769
|
-
function
|
|
1769
|
+
function Ct(e) {
|
|
1770
1770
|
let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n = 8, r = 0, i = 0, a = -1, o = 0, s = 0, c = !1, l = !1, u = 1, d = !1, f = !1, p = 0;
|
|
1771
1771
|
for (; n < e.length;) {
|
|
1772
|
-
n + 12 > e.length &&
|
|
1772
|
+
n + 12 > e.length && H("PNG contains a truncated chunk header.");
|
|
1773
1773
|
let m = t.getUint32(n), h = n + 12 + m;
|
|
1774
|
-
h > e.length &&
|
|
1774
|
+
h > e.length && H("PNG chunk data extends beyond the input.");
|
|
1775
1775
|
let g = e.subarray(n + 4, n + 8);
|
|
1776
|
-
g.some((e) => !(e >= 65 && e <= 90 || e >= 97 && e <= 122)) &&
|
|
1776
|
+
g.some((e) => !(e >= 65 && e <= 90 || e >= 97 && e <= 122)) && H("PNG chunk names must contain four ASCII letters.");
|
|
1777
1777
|
let _ = String.fromCharCode(...g);
|
|
1778
|
-
|
|
1778
|
+
St(e, n + 4, h - 4) !== t.getUint32(h - 4) && H(`PNG ${_} chunk checksum is invalid.`), n === 8 && _ !== "IHDR" && H("PNG must begin with its IHDR chunk.");
|
|
1779
1779
|
let v = n + 8;
|
|
1780
|
-
if (_ === "IHDR") (n !== 8 || m !== 13) &&
|
|
1780
|
+
if (_ === "IHDR") (n !== 8 || m !== 13) && H("PNG requires exactly one 13-byte IHDR chunk."), r = t.getUint32(v), i = t.getUint32(v + 4), V(r, i), o = e[v + 8], a = e[v + 9], {
|
|
1781
1781
|
0: [
|
|
1782
1782
|
1,
|
|
1783
1783
|
2,
|
|
@@ -1794,58 +1794,58 @@ function et(e) {
|
|
|
1794
1794
|
],
|
|
1795
1795
|
4: [8, 16],
|
|
1796
1796
|
6: [8, 16]
|
|
1797
|
-
}[a]?.includes(o) ||
|
|
1798
|
-
else if (_ === "acTL" || _ === "fcTL" || _ === "fdAT") throw new
|
|
1799
|
-
else if (_ === "PLTE") (s || d || m === 0 || m % 3 != 0 || m > 768 || a === 0 || a === 4) &&
|
|
1800
|
-
else if (_ === "tRNS") (c || d || !(a === 0 && m === 2 || a === 2 && m === 6 || a === 3 && m > 0 && m <= s)) &&
|
|
1801
|
-
else if (_ === "eXIf") l &&
|
|
1802
|
-
else if (_ === "IDAT") (f || a === 3 && s === 0) &&
|
|
1803
|
-
else if (_ === "IEND") return m === 0 && d && p !== 0 && h === e.length ||
|
|
1797
|
+
}[a]?.includes(o) || H("PNG bit depth and color type are incompatible."), (e[v + 10] !== 0 || e[v + 11] !== 0 || e[v + 12] > 1) && H("PNG compression, filtering or interlace settings are invalid.");
|
|
1798
|
+
else if (_ === "acTL" || _ === "fcTL" || _ === "fdAT") throw new D("UNSUPPORTED_IMAGE", "Animated PNG is unsupported; provide a static PNG or a multipage TIFF.");
|
|
1799
|
+
else if (_ === "PLTE") (s || d || m === 0 || m % 3 != 0 || m > 768 || a === 0 || a === 4) && H("PNG palette is invalid or appears after image data."), s = m / 3, a === 3 && s > 2 ** o && H("PNG palette exceeds its indexed bit depth.");
|
|
1800
|
+
else if (_ === "tRNS") (c || d || !(a === 0 && m === 2 || a === 2 && m === 6 || a === 3 && m > 0 && m <= s)) && H("PNG transparency is incompatible with its color type or palette."), c = !0;
|
|
1801
|
+
else if (_ === "eXIf") l && H("PNG requires at most one eXIf chunk."), u = wt(e, v, h - 4), l = !0;
|
|
1802
|
+
else if (_ === "IDAT") (f || a === 3 && s === 0) && H("PNG image data must be contiguous and follow its palette."), d = !0, p += m;
|
|
1803
|
+
else if (_ === "IEND") return m === 0 && d && p !== 0 && h === e.length || H("PNG must end with IEND after nonempty image data."), {
|
|
1804
1804
|
format: "png",
|
|
1805
1805
|
width: r,
|
|
1806
1806
|
height: i,
|
|
1807
1807
|
orientation: u
|
|
1808
1808
|
};
|
|
1809
|
-
else if (g[0] < 97) throw new
|
|
1809
|
+
else if (g[0] < 97) throw new D("UNSUPPORTED_IMAGE", `Unsupported critical PNG chunk: ${_}.`);
|
|
1810
1810
|
d && _ !== "IDAT" && (f = !0), n = h;
|
|
1811
1811
|
}
|
|
1812
|
-
|
|
1812
|
+
H("PNG is missing its final IEND chunk.");
|
|
1813
1813
|
}
|
|
1814
|
-
function
|
|
1814
|
+
function wt(e, t, n) {
|
|
1815
1815
|
let r = new DataView(e.buffer, e.byteOffset + t, n - t);
|
|
1816
|
-
r.byteLength < 8 &&
|
|
1816
|
+
r.byteLength < 8 && H("Image EXIF TIFF header is truncated.");
|
|
1817
1817
|
let i = r.getUint16(0);
|
|
1818
|
-
i !== 18761 && i !== 19789 &&
|
|
1818
|
+
i !== 18761 && i !== 19789 && H("Image EXIF byte order is invalid.");
|
|
1819
1819
|
let a = i === 18761;
|
|
1820
|
-
r.getUint16(2, a) !== 42 &&
|
|
1820
|
+
r.getUint16(2, a) !== 42 && H("Image EXIF requires a classic TIFF header.");
|
|
1821
1821
|
let o = r.getUint32(4, a);
|
|
1822
|
-
(o < 8 || o + 2 > r.byteLength) &&
|
|
1822
|
+
(o < 8 || o + 2 > r.byteLength) && H("Image EXIF IFD0 offset is outside its metadata segment.");
|
|
1823
1823
|
let s = r.getUint16(o, a), c = o + 2 + s * 12;
|
|
1824
|
-
c + 4 > r.byteLength &&
|
|
1824
|
+
c + 4 > r.byteLength && H("Image EXIF directory extends beyond its metadata segment.");
|
|
1825
1825
|
let l = 1, u = !1;
|
|
1826
1826
|
for (let e = 0; e < s; e += 1) {
|
|
1827
1827
|
let t = o + 2 + e * 12;
|
|
1828
1828
|
if (r.getUint16(t, a) !== 274) continue;
|
|
1829
1829
|
let n = r.getUint16(t + 8, a);
|
|
1830
|
-
(u || r.getUint16(t + 2, a) !== 3 || r.getUint32(t + 4, a) !== 1 || n < 1 || n > 8) &&
|
|
1830
|
+
(u || r.getUint16(t + 2, a) !== 3 || r.getUint32(t + 4, a) !== 1 || n < 1 || n > 8) && H("Image EXIF orientation must be one unambiguous SHORT value from 1 to 8."), l = n, u = !0;
|
|
1831
1831
|
}
|
|
1832
1832
|
let d = r.getUint32(c, a);
|
|
1833
|
-
return d !== 0 && (d < 8 || d + 2 > r.byteLength) &&
|
|
1833
|
+
return d !== 0 && (d < 8 || d + 2 > r.byteLength) && H("Image EXIF thumbnail directory is outside its metadata segment."), l;
|
|
1834
1834
|
}
|
|
1835
|
-
function
|
|
1835
|
+
function Tt(e) {
|
|
1836
1836
|
let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n = 2, r = 0, i = 0, a = 1, o = !1, s = 0, c = !1, l = /* @__PURE__ */ new Set();
|
|
1837
1837
|
for (; n < e.length;) {
|
|
1838
|
-
for (e[n] !== 255 &&
|
|
1838
|
+
for (e[n] !== 255 && H("JPEG marker structure is invalid."), n += 1; e[n] === 255;) n += 1;
|
|
1839
1839
|
let u = e[n++];
|
|
1840
|
-
if ((u === void 0 || u === 0 || u === 216) &&
|
|
1840
|
+
if ((u === void 0 || u === 0 || u === 216) && H("JPEG contains an invalid or truncated marker."), u === 217) return s && c && n === e.length || H("JPEG must end after a complete frame and scan."), {
|
|
1841
1841
|
format: "jpeg",
|
|
1842
1842
|
width: r,
|
|
1843
1843
|
height: i,
|
|
1844
1844
|
orientation: a
|
|
1845
1845
|
};
|
|
1846
|
-
(u === 1 || u >= 208 && u <= 215) &&
|
|
1846
|
+
(u === 1 || u >= 208 && u <= 215) && H("JPEG standalone markers are only supported inside scan data."), n + 2 > e.length && H("JPEG segment length is truncated.");
|
|
1847
1847
|
let d = t.getUint16(n), f = n + d;
|
|
1848
|
-
(d < 2 || f > e.length) &&
|
|
1848
|
+
(d < 2 || f > e.length) && H("JPEG segment extends beyond the input.");
|
|
1849
1849
|
let p = n + 2;
|
|
1850
1850
|
if (u >= 192 && u <= 207 && ![
|
|
1851
1851
|
196,
|
|
@@ -1856,31 +1856,31 @@ function tt(e) {
|
|
|
1856
1856
|
192,
|
|
1857
1857
|
193,
|
|
1858
1858
|
194
|
|
1859
|
-
].includes(u)) throw new
|
|
1860
|
-
(s || d < 8) &&
|
|
1859
|
+
].includes(u)) throw new D("UNSUPPORTED_IMAGE", "JPEG requires baseline, extended sequential or progressive Huffman encoding.");
|
|
1860
|
+
(s || d < 8) && H("JPEG contains an invalid or duplicate frame header.");
|
|
1861
1861
|
let n = e[p + 5];
|
|
1862
|
-
if (d !== 8 + n * 3 &&
|
|
1862
|
+
if (d !== 8 + n * 3 && H("JPEG frame components are truncated."), e[p] !== 8 || ![
|
|
1863
1863
|
1,
|
|
1864
1864
|
3,
|
|
1865
1865
|
4
|
|
1866
|
-
].includes(n)) throw new
|
|
1867
|
-
i = t.getUint16(p + 1), r = t.getUint16(p + 3),
|
|
1866
|
+
].includes(n)) throw new D("UNSUPPORTED_IMAGE", "JPEG requires 8-bit grayscale, RGB or CMYK pixels.");
|
|
1867
|
+
i = t.getUint16(p + 1), r = t.getUint16(p + 3), V(r, i);
|
|
1868
1868
|
for (let t = 0; t < n; t += 1) {
|
|
1869
1869
|
let n = p + 6 + t * 3, r = e[n], i = e[n + 1];
|
|
1870
|
-
(l.has(r) || !(i >> 4) || i >> 4 > 4 || !(i & 15) || (i & 15) > 4 || e[n + 2] > 3) &&
|
|
1870
|
+
(l.has(r) || !(i >> 4) || i >> 4 > 4 || !(i & 15) || (i & 15) > 4 || e[n + 2] > 3) && H("JPEG frame component identifiers or sampling settings are invalid."), l.add(r);
|
|
1871
1871
|
}
|
|
1872
1872
|
s = u;
|
|
1873
|
-
} else if (u === 225 && d >= 6 && e[p] === 69 && e[p + 1] === 120 && e[p + 2] === 105 && e[p + 3] === 102) (o || d < 8 || e[p + 4] !== 0 || e[p + 5] !== 0) &&
|
|
1873
|
+
} else if (u === 225 && d >= 6 && e[p] === 69 && e[p + 1] === 120 && e[p + 2] === 105 && e[p + 3] === 102) (o || d < 8 || e[p + 4] !== 0 || e[p + 5] !== 0) && H("JPEG contains ambiguous or malformed EXIF APP1 metadata."), a = wt(e, p + 6, f), o = !0;
|
|
1874
1874
|
else if (u === 218) {
|
|
1875
1875
|
let t = e[p];
|
|
1876
|
-
(!s || t === void 0 || t < 1 || t > l.size || d !== 6 + t * 2) &&
|
|
1876
|
+
(!s || t === void 0 || t < 1 || t > l.size || d !== 6 + t * 2) && H("JPEG scan header must follow a complete frame and select its components.");
|
|
1877
1877
|
let r = /* @__PURE__ */ new Set();
|
|
1878
1878
|
for (let n = 0; n < t; n += 1) {
|
|
1879
1879
|
let t = e[p + 1 + n * 2], i = e[p + 2 + n * 2];
|
|
1880
|
-
(!l.has(t) || r.has(t) || i >> 4 > 3 || (i & 15) > 3) &&
|
|
1880
|
+
(!l.has(t) || r.has(t) || i >> 4 > 3 || (i & 15) > 3) && H("JPEG scan components or Huffman table selectors are invalid."), r.add(t);
|
|
1881
1881
|
}
|
|
1882
1882
|
let i = p + 1 + t * 2;
|
|
1883
|
-
(e[i] > e[i + 1] || e[i + 1] > 63 || e[i + 2] >> 4 > 13 || (e[i + 2] & 15) > 13 || s !== 194 && (e[i] !== 0 || e[i + 1] !== 63 || e[i + 2] !== 0)) &&
|
|
1883
|
+
(e[i] > e[i + 1] || e[i + 1] > 63 || e[i + 2] >> 4 > 13 || (e[i + 2] & 15) > 13 || s !== 194 && (e[i] !== 0 || e[i + 1] !== 63 || e[i + 2] !== 0)) && H("JPEG scan spectral settings are invalid."), c = !0, n = f;
|
|
1884
1884
|
let a = 0;
|
|
1885
1885
|
for (; n < e.length;) {
|
|
1886
1886
|
if (e[n] !== 255) {
|
|
@@ -1896,18 +1896,18 @@ function tt(e) {
|
|
|
1896
1896
|
break;
|
|
1897
1897
|
}
|
|
1898
1898
|
}
|
|
1899
|
-
a === 0 &&
|
|
1899
|
+
a === 0 && H("JPEG scan data is empty or truncated.");
|
|
1900
1900
|
continue;
|
|
1901
1901
|
} else if ([
|
|
1902
1902
|
220,
|
|
1903
1903
|
222,
|
|
1904
1904
|
223
|
|
1905
|
-
].includes(u)) throw new
|
|
1905
|
+
].includes(u)) throw new D("UNSUPPORTED_IMAGE", "JPEG deferred-height and hierarchical frames are unsupported.");
|
|
1906
1906
|
n = f;
|
|
1907
1907
|
}
|
|
1908
|
-
|
|
1908
|
+
H("JPEG is missing its final EOI marker.");
|
|
1909
1909
|
}
|
|
1910
|
-
function
|
|
1910
|
+
function Et(e) {
|
|
1911
1911
|
if (e.length >= 8 && [
|
|
1912
1912
|
137,
|
|
1913
1913
|
80,
|
|
@@ -1917,14 +1917,14 @@ function nt(e) {
|
|
|
1917
1917
|
10,
|
|
1918
1918
|
26,
|
|
1919
1919
|
10
|
|
1920
|
-
].every((t, n) => e[n] === t)) return
|
|
1921
|
-
if (e[0] === 255 && e[1] === 216) return
|
|
1922
|
-
throw new
|
|
1923
|
-
}
|
|
1924
|
-
async function
|
|
1925
|
-
|
|
1926
|
-
let n = e.buffer instanceof ArrayBuffer ? new Uint8Array(e.buffer, e.byteOffset, e.byteLength) : Uint8Array.from(e), r =
|
|
1927
|
-
if (r.format !== "png" &&
|
|
1920
|
+
].every((t, n) => e[n] === t)) return Ct(e);
|
|
1921
|
+
if (e[0] === 255 && e[1] === 216) return Tt(e);
|
|
1922
|
+
throw new D("UNSUPPORTED_IMAGE", "Provide PNG, JPEG or classic TIFF image bytes.");
|
|
1923
|
+
}
|
|
1924
|
+
async function Dt(e, t) {
|
|
1925
|
+
O(t);
|
|
1926
|
+
let n = e.buffer instanceof ArrayBuffer ? new Uint8Array(e.buffer, e.byteOffset, e.byteLength) : Uint8Array.from(e), r = Et(n);
|
|
1927
|
+
if (r.format !== "png" && H("PNG data validation requires PNG bytes."), typeof DecompressionStream != "function") throw new D("UNSUPPORTED_IMAGE", "PNG validation requires DecompressionStream support.");
|
|
1928
1928
|
let i = {
|
|
1929
1929
|
0: 1,
|
|
1930
1930
|
2: 3,
|
|
@@ -2003,27 +2003,27 @@ async function rt(e, t) {
|
|
|
2003
2003
|
let p = !1, m = 0, h = 0, g = a[0]?.rows ?? 0, _ = 0;
|
|
2004
2004
|
try {
|
|
2005
2005
|
for (;;) {
|
|
2006
|
-
|
|
2006
|
+
O(t);
|
|
2007
2007
|
let e = await d.read();
|
|
2008
|
-
if (
|
|
2009
|
-
m += e.value.length, m > o &&
|
|
2008
|
+
if (O(t), e.done) break;
|
|
2009
|
+
m += e.value.length, m > o && H("PNG decompressed data exceeds its declared scanline dimensions.");
|
|
2010
2010
|
let n = 0;
|
|
2011
2011
|
for (; n < e.value.length;) {
|
|
2012
2012
|
let t = a[h];
|
|
2013
|
-
t ||
|
|
2013
|
+
t || H("PNG decompressed data contains unexpected image rows."), _ === 0 && (e.value[n] > 4 && H("PNG scanline filter must be between zero and four."), n += 1, _ = 1);
|
|
2014
2014
|
let r = Math.min(e.value.length - n, t.stride - _);
|
|
2015
2015
|
n += r, _ += r, _ === t.stride && (_ = 0, --g, g === 0 && (h += 1, g = a[h]?.rows ?? 0));
|
|
2016
2016
|
}
|
|
2017
2017
|
}
|
|
2018
|
-
(m !== o || h !== a.length || _ !== 0) &&
|
|
2018
|
+
(m !== o || h !== a.length || _ !== 0) && H("PNG decompressed data is shorter than its declared scanline dimensions."), p = !0;
|
|
2019
2019
|
} catch (e) {
|
|
2020
|
-
throw
|
|
2020
|
+
throw O(t), e instanceof D ? e : new D("INVALID_SOURCE", "PNG compressed data or zlib checksum is invalid.", { cause: e });
|
|
2021
2021
|
} finally {
|
|
2022
2022
|
t?.removeEventListener("abort", f), p || await d.cancel().catch(() => {}), d.releaseLock();
|
|
2023
2023
|
}
|
|
2024
2024
|
}
|
|
2025
2025
|
// src/tiff.ts
|
|
2026
|
-
var
|
|
2026
|
+
var Ot = 1e3, kt = [
|
|
2027
2027
|
0,
|
|
2028
2028
|
1,
|
|
2029
2029
|
1,
|
|
@@ -2038,7 +2038,7 @@ var it = 1e3, at = [
|
|
|
2038
2038
|
4,
|
|
2039
2039
|
8,
|
|
2040
2040
|
4
|
|
2041
|
-
],
|
|
2041
|
+
], At = /* @__PURE__ */ new Set([
|
|
2042
2042
|
256,
|
|
2043
2043
|
257,
|
|
2044
2044
|
258,
|
|
@@ -2063,22 +2063,22 @@ var it = 1e3, at = [
|
|
|
2063
2063
|
338,
|
|
2064
2064
|
339
|
|
2065
2065
|
]);
|
|
2066
|
-
function
|
|
2067
|
-
throw new
|
|
2066
|
+
function U(e) {
|
|
2067
|
+
throw new D("INVALID_SOURCE", `Invalid TIFF: ${e}`);
|
|
2068
2068
|
}
|
|
2069
|
-
function
|
|
2070
|
-
throw new
|
|
2069
|
+
function W(e) {
|
|
2070
|
+
throw new D("UNSUPPORTED_IMAGE", `Unsupported TIFF: ${e}`);
|
|
2071
2071
|
}
|
|
2072
|
-
function
|
|
2072
|
+
function G(e, t, n) {
|
|
2073
2073
|
let r = e[`t${t}`];
|
|
2074
|
-
return !r && n !== void 0 ? n : (r && r.length === 1 && Number.isSafeInteger(r[0]) ||
|
|
2075
|
-
}
|
|
2076
|
-
function
|
|
2077
|
-
let n =
|
|
2078
|
-
|
|
2079
|
-
let i =
|
|
2080
|
-
(i < 1 || i > 8) &&
|
|
2081
|
-
let a =
|
|
2074
|
+
return !r && n !== void 0 ? n : (r && r.length === 1 && Number.isSafeInteger(r[0]) || U(`tag ${t} requires one integer value.`), r[0]);
|
|
2075
|
+
}
|
|
2076
|
+
function jt(e, t) {
|
|
2077
|
+
let n = G(e, 256), r = G(e, 257);
|
|
2078
|
+
V(n, r);
|
|
2079
|
+
let i = G(e, 274, 1);
|
|
2080
|
+
(i < 1 || i > 8) && U("orientation must be between 1 and 8.");
|
|
2081
|
+
let a = G(e, 259, 1);
|
|
2082
2082
|
[
|
|
2083
2083
|
1,
|
|
2084
2084
|
2,
|
|
@@ -2088,16 +2088,16 @@ function st(e, t) {
|
|
|
2088
2088
|
8,
|
|
2089
2089
|
32946,
|
|
2090
2090
|
32773
|
|
2091
|
-
].includes(a) ||
|
|
2091
|
+
].includes(a) || W(`compression ${a}; use uncompressed, CCITT, LZW, Deflate or PackBits strips.`), [
|
|
2092
2092
|
322,
|
|
2093
2093
|
323,
|
|
2094
2094
|
324,
|
|
2095
2095
|
325,
|
|
2096
2096
|
330
|
|
2097
|
-
].some((t) => e[`t${t}`]) &&
|
|
2098
|
-
let o =
|
|
2099
|
-
(![1, o].includes(s.length) || s.some((e) => e !== c) || ![1, o].includes(l.length) || l.some((e) => e !== 1)) &&
|
|
2100
|
-
let u =
|
|
2097
|
+
].some((t) => e[`t${t}`]) && W("tiled images and SubIFDs are not supported."), G(e, 284, 1) !== 1 && W("separate planar samples are not supported.");
|
|
2098
|
+
let o = G(e, 277, 1), s = e.t258 ?? [1], c = s[0], l = e.t339 ?? [1];
|
|
2099
|
+
(![1, o].includes(s.length) || s.some((e) => e !== c) || ![1, o].includes(l.length) || l.some((e) => e !== 1)) && W("sample depths must match and samples must be unsigned integers.");
|
|
2100
|
+
let u = G(e, 262), d = o === 1 && (u === 0 && [
|
|
2101
2101
|
1,
|
|
2102
2102
|
4,
|
|
2103
2103
|
8
|
|
@@ -2111,30 +2111,30 @@ function st(e, t) {
|
|
|
2111
2111
|
4,
|
|
2112
2112
|
8
|
|
2113
2113
|
].includes(c);
|
|
2114
|
-
d || f || p ||
|
|
2114
|
+
d || f || p || W("photometric interpretation, channels or bit depth.");
|
|
2115
2115
|
let m = e.t338 ?? [];
|
|
2116
|
-
o !== 4 || m.length === 1 && [1, 2].includes(m[0]) ||
|
|
2117
|
-
let h =
|
|
2116
|
+
o !== 4 || m.length === 1 && [1, 2].includes(m[0]) || W("four-channel RGB requires an explicit associated or unassociated alpha sample."), o !== 4 && m.length > 0 && W("extra samples are unsupported in this pixel mode."), p && e.t320?.length !== 3 * (1 << c) && U("the palette has an invalid size."), p && e.t320.some((e) => e > 65535) && U("palette entries must be sixteen-bit values.");
|
|
2117
|
+
let h = G(e, 266, 1), g = [
|
|
2118
2118
|
2,
|
|
2119
2119
|
3,
|
|
2120
2120
|
4
|
|
2121
2121
|
].includes(a);
|
|
2122
|
-
[1, 2].includes(h) ||
|
|
2123
|
-
let _ =
|
|
2122
|
+
[1, 2].includes(h) || U("fill order must be 1 or 2."), h === 2 && !g && W("reversed fill order is supported only for CCITT scans."), g && (!d || c !== 1 || o !== 1) && W("CCITT compression requires bilevel grayscale."), a === 3 && ![0, 1].includes(G(e, 292, 0)) && W("unsupported Group 3 options."), a === 4 && G(e, 293, 0) !== 0 && W("uncompressed Group 4 extension mode.");
|
|
2123
|
+
let _ = G(e, 317, 1);
|
|
2124
2124
|
_ !== 1 && !(_ === 2 && c === 8 && [
|
|
2125
2125
|
1,
|
|
2126
2126
|
5,
|
|
2127
2127
|
8,
|
|
2128
2128
|
32946,
|
|
2129
2129
|
32773
|
|
2130
|
-
].includes(a)) &&
|
|
2131
|
-
let v = Math.min(
|
|
2132
|
-
v <= 0 &&
|
|
2130
|
+
].includes(a)) && W("only normal and eight-bit horizontal differencing predictors are supported.");
|
|
2131
|
+
let v = Math.min(G(e, 278, r), r);
|
|
2132
|
+
v <= 0 && U("RowsPerStrip must be positive.");
|
|
2133
2133
|
let y = e.t273, b = e.t279;
|
|
2134
|
-
y && b && y.length === b.length && y.length === Math.ceil(r / v) ||
|
|
2134
|
+
y && b && y.length === b.length && y.length === Math.ceil(r / v) || U("strip offsets and byte counts must cover exactly the declared rows.");
|
|
2135
2135
|
for (let e = 0; e < y.length; e += 1) {
|
|
2136
2136
|
let n = y[e], r = b[e];
|
|
2137
|
-
(n < 8 || r <= 0 || n > t - r) &&
|
|
2137
|
+
(n < 8 || r <= 0 || n > t - r) && U("a strip extends outside the input.");
|
|
2138
2138
|
}
|
|
2139
2139
|
return {
|
|
2140
2140
|
tags: e,
|
|
@@ -2150,45 +2150,45 @@ function st(e, t) {
|
|
|
2150
2150
|
associatedAlpha: o === 4 && m[0] === 1
|
|
2151
2151
|
};
|
|
2152
2152
|
}
|
|
2153
|
-
function
|
|
2154
|
-
e.byteLength < 8 &&
|
|
2153
|
+
function Mt(e) {
|
|
2154
|
+
e.byteLength < 8 && U("the header is truncated.");
|
|
2155
2155
|
let t = e[0] === 73 && e[1] === 73;
|
|
2156
|
-
t || e[0] === 77 && e[1] === 77 ||
|
|
2156
|
+
t || e[0] === 77 && e[1] === 77 || U("byte order must be II or MM.");
|
|
2157
2157
|
let n = new DataView(e.buffer, e.byteOffset, e.byteLength), r = n.getUint16(2, t);
|
|
2158
|
-
r === 43 &&
|
|
2158
|
+
r === 43 && W("BigTIFF is not supported."), r !== 42 && U("the classic TIFF signature is missing.");
|
|
2159
2159
|
let i = n.getUint32(4, t), a = /* @__PURE__ */ new Set(), o = [];
|
|
2160
2160
|
for (; i !== 0;) {
|
|
2161
|
-
a.has(i) &&
|
|
2161
|
+
a.has(i) && U("the main IFD chain contains a cycle."), o.length >= Ot && W("the file exceeds the 1000 frame limit."), a.add(i), (i < 8 || i > e.length - 2) && U("an IFD offset is outside the input.");
|
|
2162
2162
|
let r = n.getUint16(i, t), s = i + 2 + r * 12;
|
|
2163
|
-
s > e.length - 4 &&
|
|
2163
|
+
s > e.length - 4 && U("an IFD directory is truncated.");
|
|
2164
2164
|
let c = {};
|
|
2165
2165
|
for (let a = 0; a < r; a += 1) {
|
|
2166
|
-
let r = i + 2 + a * 12, o = n.getUint16(r, t), s = n.getUint16(r + 2, t), l = n.getUint32(r + 4, t), u =
|
|
2167
|
-
u && l !== 0 ||
|
|
2166
|
+
let r = i + 2 + a * 12, o = n.getUint16(r, t), s = n.getUint16(r + 2, t), l = n.getUint32(r + 4, t), u = kt[s];
|
|
2167
|
+
u && l !== 0 || U("an IFD field has an invalid type or count.");
|
|
2168
2168
|
let d = u * l, f = d <= 4 ? r + 8 : n.getUint32(r + 8, t);
|
|
2169
|
-
if (f > e.length - d &&
|
|
2170
|
-
[3, 4].includes(s) ||
|
|
2169
|
+
if (f > e.length - d && U("an IFD value extends outside the input."), !At.has(o)) continue;
|
|
2170
|
+
[3, 4].includes(s) || W(`rendering tag ${o} must use SHORT or LONG values.`), c[`t${o}`] && U(`rendering tag ${o} occurs more than once.`), l > 1e6 && W("a rendering tag contains too many values.");
|
|
2171
2171
|
let p = [];
|
|
2172
2172
|
for (let e = 0; e < l; e += 1) p.push(s === 3 ? n.getUint16(f + e * 2, t) : n.getUint32(f + e * 4, t));
|
|
2173
2173
|
c[`t${o}`] = p;
|
|
2174
2174
|
}
|
|
2175
|
-
o.push(
|
|
2175
|
+
o.push(jt(c, e.length)), i = n.getUint32(s, t);
|
|
2176
2176
|
}
|
|
2177
|
-
return o.length === 0 &&
|
|
2177
|
+
return o.length === 0 && U("no main image IFD exists."), o;
|
|
2178
2178
|
}
|
|
2179
|
-
function
|
|
2179
|
+
function Nt(e, t) {
|
|
2180
2180
|
let n = 0, r = 0;
|
|
2181
2181
|
for (; n < e.length;) {
|
|
2182
2182
|
let i = e[n++];
|
|
2183
2183
|
if (i <= 127) {
|
|
2184
2184
|
let t = i + 1;
|
|
2185
|
-
n + t > e.length &&
|
|
2186
|
-
} else i !== 128 && (n >= e.length &&
|
|
2187
|
-
r > t &&
|
|
2185
|
+
n + t > e.length && U("a PackBits literal is truncated."), n += t, r += t;
|
|
2186
|
+
} else i !== 128 && (n >= e.length && U("a PackBits repeat is truncated."), n += 1, r += 257 - i);
|
|
2187
|
+
r > t && U("PackBits output exceeds the declared strip size.");
|
|
2188
2188
|
}
|
|
2189
|
-
r !== t &&
|
|
2189
|
+
r !== t && U("PackBits output does not cover the declared strip.");
|
|
2190
2190
|
}
|
|
2191
|
-
function
|
|
2191
|
+
function Pt(e, t) {
|
|
2192
2192
|
let n = /* @__PURE__ */ new Uint32Array(4096);
|
|
2193
2193
|
for (let e = 0; e < 256; e += 1) n[e] = 1;
|
|
2194
2194
|
let r = 0, i = 9, a = 258, o = 0, s = 0, c = !1;
|
|
@@ -2199,56 +2199,56 @@ function ut(e, t) {
|
|
|
2199
2199
|
i = 9, a = 258, o = 0, c = !0;
|
|
2200
2200
|
continue;
|
|
2201
2201
|
}
|
|
2202
|
-
if (c ||
|
|
2203
|
-
s !== t &&
|
|
2202
|
+
if (c || U("an LZW strip must start with its clear code."), l === 257) {
|
|
2203
|
+
s !== t && U("LZW output does not cover the declared strip.");
|
|
2204
2204
|
return;
|
|
2205
2205
|
}
|
|
2206
2206
|
let u = l < a ? n[l] : l === a && o > 0 ? o + 1 : 0;
|
|
2207
|
-
u ||
|
|
2207
|
+
u || U("an LZW strip contains an invalid dictionary reference."), s += u, s > t && U("LZW output exceeds the declared strip size."), o > 0 && a < 4096 && (n[a++] = o + 1, i < 12 && a === (1 << i) - 1 && (i += 1)), o = u;
|
|
2208
2208
|
}
|
|
2209
|
-
|
|
2209
|
+
U("an LZW strip is missing its end code.");
|
|
2210
2210
|
}
|
|
2211
|
-
async function
|
|
2212
|
-
typeof DecompressionStream != "function" &&
|
|
2211
|
+
async function Ft(e, t, n) {
|
|
2212
|
+
typeof DecompressionStream != "function" && W("Deflate requires DecompressionStream support.");
|
|
2213
2213
|
let r = new Blob([Uint8Array.from(e)]).stream().pipeThrough(new DecompressionStream("deflate")).getReader(), i = 0;
|
|
2214
2214
|
try {
|
|
2215
2215
|
for (;;) {
|
|
2216
|
-
|
|
2216
|
+
O(n);
|
|
2217
2217
|
let { value: e, done: a } = await r.read();
|
|
2218
2218
|
if (a) break;
|
|
2219
|
-
i += e.byteLength, i > t &&
|
|
2219
|
+
i += e.byteLength, i > t && U("Deflate output exceeds the declared strip size.");
|
|
2220
2220
|
}
|
|
2221
|
-
i !== t &&
|
|
2221
|
+
i !== t && U("Deflate output does not cover the declared strip.");
|
|
2222
2222
|
} catch (e) {
|
|
2223
|
-
throw await r.cancel().catch(() => void 0),
|
|
2223
|
+
throw await r.cancel().catch(() => void 0), O(n), e instanceof D ? e : new D("INVALID_SOURCE", "Invalid TIFF: a Deflate strip is corrupt or truncated.", { cause: e });
|
|
2224
2224
|
} finally {
|
|
2225
2225
|
r.releaseLock();
|
|
2226
2226
|
}
|
|
2227
2227
|
}
|
|
2228
|
-
async function
|
|
2229
|
-
|
|
2230
|
-
let n = Uint8Array.from(e), r =
|
|
2231
|
-
return
|
|
2228
|
+
async function It(e, t) {
|
|
2229
|
+
O(t);
|
|
2230
|
+
let n = Uint8Array.from(e), r = Mt(n);
|
|
2231
|
+
return O(t), {
|
|
2232
2232
|
pageCount: r.length,
|
|
2233
2233
|
async decodeFrame(e) {
|
|
2234
|
-
|
|
2234
|
+
O(t), (!Number.isSafeInteger(e) || e < 0 || e >= r.length) && U("frame index is outside the document.");
|
|
2235
2235
|
let i = r[e], a = Math.ceil(i.width * i.samples * i.bits / 8);
|
|
2236
2236
|
for (let e = 0; e < i.offsets.length; e += 1) {
|
|
2237
2237
|
let r = Math.min(i.rowsPerStrip, i.height - e * i.rowsPerStrip) * a, o = i.offsets[e], s = i.counts[e];
|
|
2238
|
-
i.compression === 1 && s !== r &&
|
|
2238
|
+
i.compression === 1 && s !== r && U("an uncompressed strip has the wrong byte length."), i.compression === 5 && Pt(n.subarray(o, o + s), r), i.compression === 32773 && Nt(n.subarray(o, o + s), r), [8, 32946].includes(i.compression) && await Ft(n.subarray(o, o + s), r, t);
|
|
2239
2239
|
}
|
|
2240
2240
|
let o = Object.fromEntries(Object.entries(i.tags).map(([e, t]) => [e, [...t]])), s;
|
|
2241
2241
|
try {
|
|
2242
2242
|
let e = (await import("utif2")).default;
|
|
2243
|
-
|
|
2243
|
+
O(t), e.decodeImage(n.buffer, o), o.data instanceof Uint8Array && o.data.length === a * i.height || U("the decoder returned an incomplete raster."), s = e.toRGBA8(o);
|
|
2244
2244
|
} catch (e) {
|
|
2245
|
-
throw
|
|
2245
|
+
throw O(t), e instanceof D ? e : new D("RESOURCE_LOAD_FAILED", "The TIFF frame could not be decoded.", { cause: e });
|
|
2246
2246
|
}
|
|
2247
|
-
if (s.length !== i.width * i.height * 4 &&
|
|
2247
|
+
if (s.length !== i.width * i.height * 4 && U("the decoder returned an invalid RGBA raster."), i.associatedAlpha) for (let e = 0; e < s.length; e += 4) {
|
|
2248
2248
|
let t = s[e + 3];
|
|
2249
2249
|
for (let n = 0; n < 3; n += 1) s[e + n] = t === 0 ? 0 : Math.min(255, Math.round(s[e + n] * 255 / t));
|
|
2250
2250
|
}
|
|
2251
|
-
return
|
|
2251
|
+
return O(t), {
|
|
2252
2252
|
width: i.width,
|
|
2253
2253
|
height: i.height,
|
|
2254
2254
|
rgba: s,
|
|
@@ -2258,11 +2258,11 @@ async function ft(e, t) {
|
|
|
2258
2258
|
};
|
|
2259
2259
|
}
|
|
2260
2260
|
// src/image-pdf.ts
|
|
2261
|
-
function
|
|
2261
|
+
function Lt(e, t) {
|
|
2262
2262
|
let { width: n, height: r, rgba: i, orientation: a } = t;
|
|
2263
|
-
|
|
2263
|
+
V(n, r);
|
|
2264
2264
|
let o = n * r;
|
|
2265
|
-
if (i.length !== o * 4) throw new
|
|
2265
|
+
if (i.length !== o * 4) throw new D("RESOURCE_LOAD_FAILED", "Decoded TIFF pixels do not match the frame dimensions.");
|
|
2266
2266
|
let s = new Uint8Array(o * 3), c;
|
|
2267
2267
|
for (let e = 0; e < o; e += 1) {
|
|
2268
2268
|
s[e * 3] = i[e * 4], s[e * 3 + 1] = i[e * 4 + 1], s[e * 3 + 2] = i[e * 4 + 2];
|
|
@@ -2292,97 +2292,1596 @@ function pt(e, t) {
|
|
|
2292
2292
|
orientation: a
|
|
2293
2293
|
};
|
|
2294
2294
|
}
|
|
2295
|
-
async function
|
|
2295
|
+
async function Rt(e, t) {
|
|
2296
2296
|
try {
|
|
2297
|
-
return new Uint8Array(await
|
|
2297
|
+
return new Uint8Array(await z(e.arrayBuffer(), t));
|
|
2298
2298
|
} catch (e) {
|
|
2299
|
-
throw
|
|
2299
|
+
throw O(t), new D("RESOURCE_LOAD_FAILED", "The source image file could not be read.", { cause: e });
|
|
2300
2300
|
}
|
|
2301
2301
|
}
|
|
2302
|
-
async function
|
|
2303
|
-
let n =
|
|
2304
|
-
if (o !== void 0 && typeof o != "function") throw new
|
|
2305
|
-
if (a !== void 0 && !(a instanceof AbortSignal)) throw new
|
|
2306
|
-
|
|
2302
|
+
async function zt(e, t = {}) {
|
|
2303
|
+
let n = qe(t), i = k(t.metadata), { signal: a, onProgress: o } = t;
|
|
2304
|
+
if (o !== void 0 && typeof o != "function") throw new D("INVALID_OPTIONS", "onProgress must be a function.");
|
|
2305
|
+
if (a !== void 0 && !(a instanceof AbortSignal)) throw new D("INVALID_OPTIONS", "signal must be an AbortSignal.");
|
|
2306
|
+
O(a);
|
|
2307
2307
|
let s = e instanceof Uint8Array ? Uint8Array.from(e) : e instanceof ArrayBuffer ? new Uint8Array(e.slice(0)) : void 0, c = typeof Blob < "u" && e instanceof Blob ? e : void 0;
|
|
2308
|
-
if (!s && !c) throw new
|
|
2309
|
-
let
|
|
2308
|
+
if (!s && !c) throw new D("INVALID_SOURCE", "Provide image bytes, an ArrayBuffer, or a File/Blob.");
|
|
2309
|
+
let l = gt(o, a), u = l.report;
|
|
2310
2310
|
try {
|
|
2311
|
-
|
|
2311
|
+
u && await u({
|
|
2312
2312
|
stage: "preparing",
|
|
2313
2313
|
completed: 0,
|
|
2314
2314
|
total: 1
|
|
2315
2315
|
});
|
|
2316
|
-
let e = s ?? await
|
|
2317
|
-
if (e.length === 0) throw new
|
|
2318
|
-
let t = e.length >= 4 && (e[0] === 73 && e[1] === 73 && (e[2] === 42 || e[2] === 43) && e[3] === 0 || e[0] === 77 && e[1] === 77 && e[2] === 0 && (e[3] === 42 || e[3] === 43)) ? await
|
|
2319
|
-
|
|
2316
|
+
let e = s ?? await Rt(c, a);
|
|
2317
|
+
if (e.length === 0) throw new D("INVALID_SOURCE", "The source image is empty.");
|
|
2318
|
+
let t = e.length >= 4 && (e[0] === 73 && e[1] === 73 && (e[2] === 42 || e[2] === 43) && e[3] === 0 || e[0] === 77 && e[1] === 77 && e[2] === 0 && (e[3] === 42 || e[3] === 43)) ? await z(It(e, a), a) : void 0, o = t ? void 0 : Et(e), l = t?.pageCount ?? 1;
|
|
2319
|
+
u && await u({
|
|
2320
2320
|
stage: "preparing",
|
|
2321
2321
|
completed: 1,
|
|
2322
2322
|
total: 1
|
|
2323
2323
|
});
|
|
2324
|
-
let
|
|
2325
|
-
|
|
2326
|
-
let
|
|
2327
|
-
|
|
2324
|
+
let d = await r.create();
|
|
2325
|
+
A(d, i);
|
|
2326
|
+
let f = [];
|
|
2327
|
+
u && await u({
|
|
2328
2328
|
stage: "resources",
|
|
2329
2329
|
completed: 0,
|
|
2330
|
-
total:
|
|
2330
|
+
total: l
|
|
2331
2331
|
});
|
|
2332
|
-
for (let n = 0; n <
|
|
2333
|
-
if (
|
|
2334
|
-
let e = await
|
|
2335
|
-
|
|
2332
|
+
for (let n = 0; n < l; n += 1) {
|
|
2333
|
+
if (O(a), t) {
|
|
2334
|
+
let e = await z(t.decodeFrame(n), a);
|
|
2335
|
+
f.push(Lt(d, e));
|
|
2336
2336
|
} else try {
|
|
2337
|
-
o.format === "png" && await
|
|
2338
|
-
let t = o.format === "png" ? await
|
|
2339
|
-
if (t.width !== o.width || t.height !== o.height) throw new
|
|
2340
|
-
|
|
2337
|
+
o.format === "png" && await Dt(e, a);
|
|
2338
|
+
let t = o.format === "png" ? await d.embedPng(e) : await d.embedJpg(e);
|
|
2339
|
+
if (t.width !== o.width || t.height !== o.height) throw new D("INVALID_SOURCE", "Decoded image dimensions disagree with its header.");
|
|
2340
|
+
f.push({
|
|
2341
2341
|
ref: t.ref,
|
|
2342
2342
|
width: t.width,
|
|
2343
2343
|
height: t.height,
|
|
2344
2344
|
orientation: o.orientation
|
|
2345
2345
|
});
|
|
2346
2346
|
} catch (e) {
|
|
2347
|
-
throw e instanceof
|
|
2347
|
+
throw e instanceof D ? e : new D("RESOURCE_LOAD_FAILED", "The PNG/JPEG image could not be embedded.", { cause: e });
|
|
2348
2348
|
}
|
|
2349
|
-
|
|
2349
|
+
u && await u({
|
|
2350
2350
|
stage: "resources",
|
|
2351
2351
|
completed: n + 1,
|
|
2352
|
-
total:
|
|
2352
|
+
total: l
|
|
2353
2353
|
});
|
|
2354
2354
|
}
|
|
2355
|
-
|
|
2355
|
+
u && await u({
|
|
2356
2356
|
stage: "pages",
|
|
2357
2357
|
completed: 0,
|
|
2358
|
-
total:
|
|
2358
|
+
total: l
|
|
2359
2359
|
});
|
|
2360
|
-
for (let [e, t] of
|
|
2361
|
-
|
|
2362
|
-
let r =
|
|
2363
|
-
r.pushOperators(
|
|
2360
|
+
for (let [e, t] of f.entries()) {
|
|
2361
|
+
O(a);
|
|
2362
|
+
let r = d.addPage([n.width * .75, n.height * .75]), i = bt(t.width, t.height, t.orientation, n), o = r.node.newXObject("Image", t.ref);
|
|
2363
|
+
r.pushOperators(E(), _(i[0] * .75, i[1] * .75, i[2] * .75, i[3] * .75, i[4] * .75, i[5] * .75), y(o), T()), u && await u({
|
|
2364
2364
|
stage: "pages",
|
|
2365
2365
|
completed: e + 1,
|
|
2366
|
-
total:
|
|
2366
|
+
total: l
|
|
2367
2367
|
});
|
|
2368
2368
|
}
|
|
2369
|
-
|
|
2369
|
+
u && await u({
|
|
2370
2370
|
stage: "saving",
|
|
2371
2371
|
completed: 0,
|
|
2372
2372
|
total: 1
|
|
2373
2373
|
});
|
|
2374
|
-
let
|
|
2375
|
-
return
|
|
2374
|
+
let p = await z(d.save(), a);
|
|
2375
|
+
return O(a), u && await u({
|
|
2376
2376
|
stage: "saving",
|
|
2377
2377
|
completed: 1,
|
|
2378
2378
|
total: 1
|
|
2379
|
-
}),
|
|
2379
|
+
}), u && await u({
|
|
2380
|
+
stage: "complete",
|
|
2381
|
+
completed: 1,
|
|
2382
|
+
total: 1
|
|
2383
|
+
}), O(a), B(p, l, []);
|
|
2384
|
+
} catch (e) {
|
|
2385
|
+
return l.rethrow(e instanceof D ? e : new D("PDF_WRITE_FAILED", "The standalone image could not be written as PDF.", { cause: e }));
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
// src/compose-pdf.ts
|
|
2389
|
+
var K = 1e3, Bt = 134217728, Vt = 268435456;
|
|
2390
|
+
function Ht(e) {
|
|
2391
|
+
if (!e || typeof e != "object" || Array.isArray(e)) throw new D("INVALID_OPTIONS", "PDF composition options must be an object.");
|
|
2392
|
+
let { signal: t, onProgress: n } = e;
|
|
2393
|
+
if (n !== void 0 && typeof n != "function") throw new D("INVALID_OPTIONS", "onProgress must be a function.");
|
|
2394
|
+
if (t !== void 0 && (!t || typeof t.aborted != "boolean" || typeof t.addEventListener != "function" || typeof t.removeEventListener != "function")) throw new D("INVALID_OPTIONS", "signal must be an AbortSignal.");
|
|
2395
|
+
return O(t), {
|
|
2396
|
+
signal: t,
|
|
2397
|
+
onProgress: n,
|
|
2398
|
+
metadata: k(e.metadata)
|
|
2399
|
+
};
|
|
2400
|
+
}
|
|
2401
|
+
function Ut(e) {
|
|
2402
|
+
if (!Number.isSafeInteger(e) || e <= 0 || e > Bt) throw new D("INVALID_SOURCE", "Each source PDF must contain 1 byte to 128 MiB.");
|
|
2403
|
+
}
|
|
2404
|
+
function Wt(e) {
|
|
2405
|
+
if (!Array.isArray(e) || e.length === 0 || e.length > K) throw new D("INVALID_SOURCE", "Provide between 1 and 1,000 source PDFs.");
|
|
2406
|
+
let t = 0;
|
|
2407
|
+
return Array.from(e, (e) => {
|
|
2408
|
+
if (e instanceof Uint8Array || e instanceof ArrayBuffer) {
|
|
2409
|
+
if (Ut(e.byteLength), t += e.byteLength, t > Vt) throw new D("INVALID_SOURCE", "Combined source PDFs must not exceed 256 MiB.");
|
|
2410
|
+
return Uint8Array.from(e instanceof Uint8Array ? e : new Uint8Array(e));
|
|
2411
|
+
}
|
|
2412
|
+
if (typeof Blob < "u" && e instanceof Blob) {
|
|
2413
|
+
if (Ut(e.size), t += e.size, t > Vt) throw new D("INVALID_SOURCE", "Combined source PDFs must not exceed 256 MiB.");
|
|
2414
|
+
return e;
|
|
2415
|
+
}
|
|
2416
|
+
if (e && typeof e == "object" && "toUint8Array" in e && typeof e.toUint8Array == "function") {
|
|
2417
|
+
let t = e.toUint8Array.bind(e);
|
|
2418
|
+
return async () => {
|
|
2419
|
+
let e = await t();
|
|
2420
|
+
if (!(e instanceof Uint8Array)) throw new D("INVALID_SOURCE", "The PDF result must return Uint8Array bytes.");
|
|
2421
|
+
return Ut(e.byteLength), Uint8Array.from(e);
|
|
2422
|
+
};
|
|
2423
|
+
}
|
|
2424
|
+
throw new D("INVALID_SOURCE", "Provide PDF bytes, a File/Blob or a PDF export result.");
|
|
2425
|
+
});
|
|
2426
|
+
}
|
|
2427
|
+
function Gt(e) {
|
|
2428
|
+
let r = e.catalog.lookupMaybe(a.of("AcroForm"), n);
|
|
2429
|
+
if (r?.has(a.of("XFA")) || r?.lookupMaybe(a.of("Fields"), t)?.size()) throw new D("INVALID_SOURCE", "Interactive PDF forms must be flattened before page composition.");
|
|
2430
|
+
let i = e.getPages(), o = new Map(i.map((e, t) => [e.ref.toString(), t]));
|
|
2431
|
+
return i.map((r) => {
|
|
2432
|
+
let i = [], c = r.node.Annots();
|
|
2433
|
+
for (let r = 0; r < (c?.size() ?? 0); r += 1) {
|
|
2434
|
+
let l = c.lookup(r, n);
|
|
2435
|
+
if (l.get(a.of("Subtype"))?.toString() === "/Widget") throw new D("INVALID_SOURCE", "PDF widget annotations must be flattened first.");
|
|
2436
|
+
let u = l.lookupMaybe(a.of("A"), n), d = u?.get(a.of("S"))?.toString();
|
|
2437
|
+
if (u && d !== "/URI" && d !== "/GoTo") throw new D("INVALID_SOURCE", "This PDF annotation action cannot be preserved.");
|
|
2438
|
+
let f = l.get(a.of("Dest")), p = f ?? (d === "/GoTo" ? u.get(a.of("D")) : void 0);
|
|
2439
|
+
if (p) {
|
|
2440
|
+
let n = e.context.lookup(p), a = n instanceof t ? n.get(0) : void 0, c = a instanceof s ? o.get(a.toString()) : void 0;
|
|
2441
|
+
if (c === void 0) throw new D("INVALID_SOURCE", "Named or invalid PDF link destinations cannot be preserved during page composition.");
|
|
2442
|
+
i.push({
|
|
2443
|
+
annotation: r,
|
|
2444
|
+
target: c,
|
|
2445
|
+
action: f === void 0
|
|
2446
|
+
});
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
return i;
|
|
2450
|
+
});
|
|
2451
|
+
}
|
|
2452
|
+
async function Kt(e, t) {
|
|
2453
|
+
try {
|
|
2454
|
+
let n = await z(r.load(e, {
|
|
2455
|
+
updateMetadata: !1,
|
|
2456
|
+
throwOnInvalidObject: !0
|
|
2457
|
+
}), t), i = n.getPageCount();
|
|
2458
|
+
if (i === 0 || i > K) throw new D("INVALID_SOURCE", "Each source PDF must contain 1 to 1,000 pages.");
|
|
2459
|
+
return {
|
|
2460
|
+
pdf: n,
|
|
2461
|
+
links: Gt(n)
|
|
2462
|
+
};
|
|
2463
|
+
} catch (e) {
|
|
2464
|
+
throw O(t), e instanceof D ? e : new D("INVALID_SOURCE", "The source PDF is malformed, encrypted or contains unsupported page structures.", { cause: e });
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
async function qt(e, t) {
|
|
2468
|
+
O(t);
|
|
2469
|
+
try {
|
|
2470
|
+
return typeof e == "function" ? await z(e(), t) : e instanceof Uint8Array ? e : new Uint8Array(await z(e.arrayBuffer(), t));
|
|
2471
|
+
} catch (e) {
|
|
2472
|
+
throw O(t), e instanceof D ? e : new D("INVALID_SOURCE", "The source PDF bytes could not be read.", { cause: e });
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2475
|
+
async function Jt(e, t) {
|
|
2476
|
+
O(t);
|
|
2477
|
+
let n = Wt([e])[0];
|
|
2478
|
+
return (await Kt(await qt(n, t), t)).pdf;
|
|
2479
|
+
}
|
|
2480
|
+
function Yt(e, r, i, o) {
|
|
2481
|
+
let s = e.node.Annots();
|
|
2482
|
+
if (!s) return;
|
|
2483
|
+
let c = e.doc.context, l = c.obj([]);
|
|
2484
|
+
for (let r = 0; r < s.size(); r += 1) {
|
|
2485
|
+
let i = s.lookup(r, n).clone(c);
|
|
2486
|
+
i.set(a.of("P"), e.ref);
|
|
2487
|
+
let o = i.lookupMaybe(a.of("Dest"), t);
|
|
2488
|
+
o && i.set(a.of("Dest"), o.clone(c));
|
|
2489
|
+
let u = i.lookupMaybe(a.of("A"), n);
|
|
2490
|
+
if (u) {
|
|
2491
|
+
let e = u.clone(c);
|
|
2492
|
+
u.get(a.of("S"))?.toString() === "/GoTo" && e.set(a.of("D"), u.lookup(a.of("D"), t).clone(c)), i.set(a.of("A"), e);
|
|
2493
|
+
}
|
|
2494
|
+
l.push(c.register(i));
|
|
2495
|
+
}
|
|
2496
|
+
e.node.set(a.of("Annots"), l);
|
|
2497
|
+
for (let s of r) {
|
|
2498
|
+
let r = l.lookup(s.annotation, n);
|
|
2499
|
+
(s.action ? r.lookup(a.of("A"), n) : r).lookup(a.of(s.action ? "D" : "Dest"), t).set(0, s.target === o ? e.ref : i.get(s.target).ref);
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
async function Xt(e, t, n, r) {
|
|
2503
|
+
if (O(r), n !== void 0 && !Array.isArray(n)) throw new D("INVALID_OPTIONS", "pageNumbers must be an array of one-based numbers.");
|
|
2504
|
+
let i = n === void 0 ? t.getPageIndices() : Array.from(n, (e) => e - 1);
|
|
2505
|
+
if (i.length === 0 || e.getPageCount() + i.length > K || i.some((e) => !Number.isSafeInteger(e) || e < 0 || e >= t.getPageCount())) throw new D("INVALID_OPTIONS", "Select valid one-based pages within the 1,000-page limit.");
|
|
2506
|
+
let a = Gt(t), o = new Set(i);
|
|
2507
|
+
for (let e of i) if (a[e].some((e) => !o.has(e.target))) throw new D("INVALID_OPTIONS", "A selected page links to a page absent from its output document.");
|
|
2508
|
+
let s = await e.copyPages(t, i);
|
|
2509
|
+
O(r);
|
|
2510
|
+
let c = /* @__PURE__ */ new Map();
|
|
2511
|
+
for (let [t, n] of i.entries()) {
|
|
2512
|
+
let r = s[t];
|
|
2513
|
+
e.addPage(r), c.has(n) || c.set(n, r);
|
|
2514
|
+
}
|
|
2515
|
+
for (let [e, t] of i.entries()) Yt(s[e], a[t], c, t);
|
|
2516
|
+
return Object.freeze(s);
|
|
2517
|
+
}
|
|
2518
|
+
async function Zt(e, t, n, i) {
|
|
2519
|
+
let { signal: a, onProgress: o, metadata: s } = Ht(i);
|
|
2520
|
+
if (t !== void 0 && (t.length === 0 || t.length > K)) throw new D("INVALID_OPTIONS", "Select 1 to 1,000 one-based integer page numbers.");
|
|
2521
|
+
let c = t === void 0 ? void 0 : Array.from(t);
|
|
2522
|
+
if (c && (c.length === 0 || c.length > K || c.some((e) => !Number.isSafeInteger(e) || e < 1))) throw new D("INVALID_OPTIONS", "Select 1 to 1,000 one-based integer page numbers.");
|
|
2523
|
+
let l = Wt(e), u = gt(o, a), d = u.report;
|
|
2524
|
+
try {
|
|
2525
|
+
d && await d({
|
|
2526
|
+
stage: "preparing",
|
|
2527
|
+
completed: 0,
|
|
2528
|
+
total: l.length
|
|
2529
|
+
});
|
|
2530
|
+
let e = [], t = 0, i = 0;
|
|
2531
|
+
for (let [n, r] of l.entries()) {
|
|
2532
|
+
O(a);
|
|
2533
|
+
let o = await qt(r, a);
|
|
2534
|
+
if (t += o.byteLength, t > Vt) throw new D("INVALID_SOURCE", "Combined source PDFs must not exceed 256 MiB.");
|
|
2535
|
+
let s = await Kt(o, a);
|
|
2536
|
+
if (i += c?.length ?? s.pdf.getPageCount(), i > K) throw new D("INVALID_OPTIONS", "A composition may produce at most 1,000 pages.");
|
|
2537
|
+
e.push(s), d && await d({
|
|
2538
|
+
stage: "preparing",
|
|
2539
|
+
completed: n + 1,
|
|
2540
|
+
total: l.length
|
|
2541
|
+
});
|
|
2542
|
+
}
|
|
2543
|
+
let o = e.map((e) => ({
|
|
2544
|
+
...e,
|
|
2545
|
+
indices: c ? c.map((e) => e - 1) : e.pdf.getPageIndices()
|
|
2546
|
+
})), u = o.reduce((e, t) => e + t.indices.length, 0);
|
|
2547
|
+
if (u > K) throw new D("INVALID_OPTIONS", "A composition may produce at most 1,000 pages.");
|
|
2548
|
+
for (let e of o) {
|
|
2549
|
+
let t = new Set(e.indices);
|
|
2550
|
+
for (let r of e.indices) {
|
|
2551
|
+
if (r >= e.pdf.getPageCount()) throw new D("INVALID_OPTIONS", "A selected page number exceeds the source PDF.");
|
|
2552
|
+
if (e.links[r].some((e) => !t.has(e.target) || n && e.target !== r)) throw new D("INVALID_OPTIONS", "A selected page links to a page absent from its output document.");
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
let f = n ? u : 1;
|
|
2556
|
+
d && await d({
|
|
2557
|
+
stage: "resources",
|
|
2558
|
+
completed: 0,
|
|
2559
|
+
total: f
|
|
2560
|
+
});
|
|
2561
|
+
let p = [];
|
|
2562
|
+
for (let e = 0; e < f; e += 1) {
|
|
2563
|
+
let t = await z(r.create(), a);
|
|
2564
|
+
A(t, s), p.push(t), d && await d({
|
|
2565
|
+
stage: "resources",
|
|
2566
|
+
completed: e + 1,
|
|
2567
|
+
total: f
|
|
2568
|
+
});
|
|
2569
|
+
}
|
|
2570
|
+
d && await d({
|
|
2571
|
+
stage: "pages",
|
|
2572
|
+
completed: 0,
|
|
2573
|
+
total: u
|
|
2574
|
+
});
|
|
2575
|
+
let m = 0;
|
|
2576
|
+
for (let e of o) {
|
|
2577
|
+
O(a);
|
|
2578
|
+
let t = p[0], r = n ? void 0 : await z(t.copyPages(e.pdf, e.indices), a), i = /* @__PURE__ */ new Map(), o = [];
|
|
2579
|
+
for (let [s, c] of e.indices.entries()) {
|
|
2580
|
+
O(a);
|
|
2581
|
+
let l = n ? p[m] : t, f = r?.[s] ?? (await z(l.copyPages(e.pdf, [c]), a))[0];
|
|
2582
|
+
l.addPage(f), i.has(c) || i.set(c, f), n ? Yt(f, e.links[c], /* @__PURE__ */ new Map([[c, f]]), c) : o.push({
|
|
2583
|
+
page: f,
|
|
2584
|
+
index: c
|
|
2585
|
+
}), m += 1, d && await d({
|
|
2586
|
+
stage: "pages",
|
|
2587
|
+
completed: m,
|
|
2588
|
+
total: u
|
|
2589
|
+
});
|
|
2590
|
+
}
|
|
2591
|
+
for (let t of o) Yt(t.page, e.links[t.index], i, t.index);
|
|
2592
|
+
}
|
|
2593
|
+
d && await d({
|
|
2594
|
+
stage: "saving",
|
|
2595
|
+
completed: 0,
|
|
2596
|
+
total: p.length
|
|
2597
|
+
});
|
|
2598
|
+
let h = [];
|
|
2599
|
+
for (let [e, t] of p.entries()) {
|
|
2600
|
+
O(a);
|
|
2601
|
+
let n = await z(t.save({ addDefaultPage: !1 }), a);
|
|
2602
|
+
h.push(B(n, t.getPageCount(), [])), d && await d({
|
|
2603
|
+
stage: "saving",
|
|
2604
|
+
completed: e + 1,
|
|
2605
|
+
total: p.length
|
|
2606
|
+
});
|
|
2607
|
+
}
|
|
2608
|
+
return d && await d({
|
|
2380
2609
|
stage: "complete",
|
|
2381
2610
|
completed: 1,
|
|
2382
2611
|
total: 1
|
|
2383
|
-
}),
|
|
2612
|
+
}), O(a), Object.freeze(h);
|
|
2613
|
+
} catch (e) {
|
|
2614
|
+
return u.rethrow(e instanceof D ? e : new D("PDF_WRITE_FAILED", "PDF pages could not be composed.", { cause: e }));
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
async function Qt(e, t = {}) {
|
|
2618
|
+
return (await Zt(e, void 0, !1, t))[0];
|
|
2619
|
+
}
|
|
2620
|
+
async function $t(e, t, n = {}) {
|
|
2621
|
+
if (!Array.isArray(t)) throw new D("INVALID_OPTIONS", "pageNumbers must be an array of one-based numbers.");
|
|
2622
|
+
return (await Zt([e], t, !1, n))[0];
|
|
2623
|
+
}
|
|
2624
|
+
async function en(e, t = {}) {
|
|
2625
|
+
return Zt([e], void 0, !0, t);
|
|
2626
|
+
}
|
|
2627
|
+
// src/document-colors.ts
|
|
2628
|
+
function q(e) {
|
|
2629
|
+
if (typeof e != "string") throw new D("INVALID_OPTIONS", "A drawing color must be a CSS color string.");
|
|
2630
|
+
let t = {
|
|
2631
|
+
black: "#000000",
|
|
2632
|
+
white: "#ffffff",
|
|
2633
|
+
red: "#ff0000",
|
|
2634
|
+
green: "#008000",
|
|
2635
|
+
blue: "#0000ff",
|
|
2636
|
+
yellow: "#ffff00",
|
|
2637
|
+
cyan: "#00ffff",
|
|
2638
|
+
aqua: "#00ffff",
|
|
2639
|
+
magenta: "#ff00ff",
|
|
2640
|
+
fuchsia: "#ff00ff",
|
|
2641
|
+
gray: "#808080",
|
|
2642
|
+
grey: "#808080",
|
|
2643
|
+
silver: "#c0c0c0",
|
|
2644
|
+
maroon: "#800000",
|
|
2645
|
+
olive: "#808000",
|
|
2646
|
+
lime: "#00ff00",
|
|
2647
|
+
teal: "#008080",
|
|
2648
|
+
navy: "#000080",
|
|
2649
|
+
purple: "#800080",
|
|
2650
|
+
orange: "#ffa500",
|
|
2651
|
+
transparent: "#00000000"
|
|
2652
|
+
}, n = e.trim().toLowerCase(), r = t[n] ?? n, i = /^#([\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/.exec(r)?.[1];
|
|
2653
|
+
if (i) {
|
|
2654
|
+
let e = i.length <= 4 ? i.split("").map((e) => e + e).join("") : i, t = (t) => Number.parseInt(e.slice(t, t + 2), 16) / 255;
|
|
2655
|
+
return {
|
|
2656
|
+
color: ne(t(0), t(2), t(4)),
|
|
2657
|
+
opacity: e.length === 8 ? t(6) : 1
|
|
2658
|
+
};
|
|
2659
|
+
}
|
|
2660
|
+
let a = (/^rgba?\(([^()]*)\)$/.exec(r)?.[1])?.trim().replace(/\s*\/\s*/, ",").split(/\s*[,\s]\s*/);
|
|
2661
|
+
if (a && (a.length === 3 || a.length === 4) && a.every((e) => /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)%?$/.test(e))) {
|
|
2662
|
+
let e = a.map((e, t) => Number.parseFloat(e) / (e.endsWith("%") ? 100 : t === 3 ? 1 : 255));
|
|
2663
|
+
if (e.every((e) => Number.isFinite(e) && e >= 0 && e <= 1)) return {
|
|
2664
|
+
color: ne(e[0], e[1], e[2]),
|
|
2665
|
+
opacity: e[3] ?? 1
|
|
2666
|
+
};
|
|
2667
|
+
}
|
|
2668
|
+
throw new D("INVALID_OPTIONS", "Use a CSS hex color, rgb()/rgba(), or a supported basic color name.");
|
|
2669
|
+
}
|
|
2670
|
+
// src/document-page.ts
|
|
2671
|
+
var tn = /* @__PURE__ */ new WeakMap();
|
|
2672
|
+
function J(e, t) {
|
|
2673
|
+
if (typeof e != "number" || !Number.isFinite(e)) throw new D("INVALID_OPTIONS", `${t} must be a finite number.`);
|
|
2674
|
+
}
|
|
2675
|
+
function Y(e, t, n = !1) {
|
|
2676
|
+
if (J(e, t), n ? e < 0 : e <= 0) throw new D("INVALID_OPTIONS", `${t} must be ${n ? "nonnegative" : "positive"}.`);
|
|
2677
|
+
}
|
|
2678
|
+
function X(e) {
|
|
2679
|
+
if (!e || typeof e != "object") throw new D("INVALID_OPTIONS", "Provide a rectangle with x, y, width and height.");
|
|
2680
|
+
J(e.x, "x"), J(e.y, "y"), Y(e.width, "width"), Y(e.height, "height");
|
|
2681
|
+
}
|
|
2682
|
+
function Z(e = 1) {
|
|
2683
|
+
if (J(e, "opacity"), e < 0 || e > 1) throw new D("INVALID_OPTIONS", "Opacity must be between 0 and 1.");
|
|
2684
|
+
return e;
|
|
2685
|
+
}
|
|
2686
|
+
function nn(e) {
|
|
2687
|
+
if (typeof e != "string" || !e.trim() || Array.from(e).some((e) => e.charCodeAt(0) < 32 || e.charCodeAt(0) === 127)) throw new D("INVALID_OPTIONS", "Provide an absolute HTTP, HTTPS, mailto or tel link.");
|
|
2688
|
+
let t;
|
|
2689
|
+
try {
|
|
2690
|
+
t = new URL(e);
|
|
2691
|
+
} catch (e) {
|
|
2692
|
+
throw new D("INVALID_OPTIONS", "The link URL is invalid.", { cause: e });
|
|
2693
|
+
}
|
|
2694
|
+
if (![
|
|
2695
|
+
"http:",
|
|
2696
|
+
"https:",
|
|
2697
|
+
"mailto:",
|
|
2698
|
+
"tel:"
|
|
2699
|
+
].includes(t.protocol)) throw new D("INVALID_OPTIONS", "Links support HTTP, HTTPS, mailto and tel URLs.");
|
|
2700
|
+
return t.href;
|
|
2701
|
+
}
|
|
2702
|
+
function rn(e, t) {
|
|
2703
|
+
let n = tn.get(e);
|
|
2704
|
+
n || (n = new Set(e.getCharacterSet()), tn.set(e, n));
|
|
2705
|
+
for (let e of t) {
|
|
2706
|
+
if (e === "\r" || e === "\n") continue;
|
|
2707
|
+
let t = e.codePointAt(0);
|
|
2708
|
+
if (!n.has(t)) throw new D("MISSING_GLYPH", `The selected font cannot encode U+${t.toString(16).toUpperCase()}.`);
|
|
2709
|
+
}
|
|
2710
|
+
try {
|
|
2711
|
+
e.encodeText(t.replace(/[\r\n]/g, ""));
|
|
2712
|
+
} catch (e) {
|
|
2713
|
+
throw new D("MISSING_GLYPH", "The selected font cannot encode this text.", { cause: e });
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
var an = class {
|
|
2717
|
+
page;
|
|
2718
|
+
context;
|
|
2719
|
+
pathOpen = !1;
|
|
2720
|
+
pendingImages = 0;
|
|
2721
|
+
matrix = [
|
|
2722
|
+
1,
|
|
2723
|
+
0,
|
|
2724
|
+
0,
|
|
2725
|
+
1,
|
|
2726
|
+
0,
|
|
2727
|
+
0
|
|
2728
|
+
];
|
|
2729
|
+
stack = [];
|
|
2730
|
+
userUnit;
|
|
2731
|
+
scale;
|
|
2732
|
+
constructor(e, t) {
|
|
2733
|
+
this.page = e, this.context = t;
|
|
2734
|
+
let n = e.node.lookup(a.of("UserUnit")), r = n instanceof o ? n.asNumber() : 1;
|
|
2735
|
+
this.userUnit = Number.isFinite(r) && r > 0 ? r : 1, this.scale = t.scale / this.userUnit;
|
|
2736
|
+
}
|
|
2737
|
+
get width() {
|
|
2738
|
+
return this.page.getWidth() / this.scale;
|
|
2739
|
+
}
|
|
2740
|
+
get height() {
|
|
2741
|
+
return this.page.getHeight() / this.scale;
|
|
2742
|
+
}
|
|
2743
|
+
get rotation() {
|
|
2744
|
+
return this.page.getRotation().angle;
|
|
2745
|
+
}
|
|
2746
|
+
setRotation(e) {
|
|
2747
|
+
if (this.ready(), J(e, "rotation"), e % 90 != 0) throw new D("INVALID_OPTIONS", "Page rotation must be a multiple of 90 degrees.");
|
|
2748
|
+
return this.page.setRotation(v((e % 360 + 360) % 360)), this;
|
|
2749
|
+
}
|
|
2750
|
+
ready(e = !1) {
|
|
2751
|
+
if (this.context.assertActive(), this.pendingImages) throw new D("INVALID_OPTIONS", "Await drawImage before drawing or saving this page.");
|
|
2752
|
+
if (this.pathOpen && !e) throw new D("INVALID_OPTIONS", "Paint, clip or discard the current path before another drawing operation.");
|
|
2753
|
+
}
|
|
2754
|
+
assertComplete() {
|
|
2755
|
+
if (this.ready(), this.stack.length) throw new D("INVALID_OPTIONS", "Restore every saved graphics state before saving the PDF.");
|
|
2756
|
+
}
|
|
2757
|
+
point(e, t) {
|
|
2758
|
+
J(e, "x"), J(t, "y");
|
|
2759
|
+
let n = this.page.getMediaBox();
|
|
2760
|
+
return [n.x + e * this.scale, n.y + n.height - t * this.scale];
|
|
2761
|
+
}
|
|
2762
|
+
drawText(e, t) {
|
|
2763
|
+
if (this.ready(), !t || typeof t != "object") throw new D("INVALID_OPTIONS", "Provide text drawing options.");
|
|
2764
|
+
if (typeof e != "string") throw new D("INVALID_OPTIONS", "Text must be a string.");
|
|
2765
|
+
let [n, r] = this.point(t.x, t.y), i = (t.fontSize ?? 12) / this.userUnit, a = t.lineHeight ?? 1.15, o = t.rotation ?? 0;
|
|
2766
|
+
Y(i, "fontSize"), Y(a, "lineHeight"), J(o, "rotation");
|
|
2767
|
+
let s = t.align ?? "left";
|
|
2768
|
+
if (![
|
|
2769
|
+
"left",
|
|
2770
|
+
"center",
|
|
2771
|
+
"right"
|
|
2772
|
+
].includes(s)) throw new D("INVALID_OPTIONS", "Text alignment must be left, center or right.");
|
|
2773
|
+
t.maxWidth !== void 0 && Y(t.maxWidth, "maxWidth");
|
|
2774
|
+
let c = q(t.color ?? "black"), l = Z(t.opacity) * c.opacity, u = t.link === void 0 ? void 0 : nn(t.link), d = this.context.resolveFont(t), f = (e) => d.widthOfTextAtSize(e, i), m;
|
|
2775
|
+
try {
|
|
2776
|
+
rn(d, e), m = t.maxWidth === void 0 ? e.replace(/\r\n?/g, "\n").split("\n") : p(e, [" "], t.maxWidth * this.scale, f);
|
|
2777
|
+
} catch (e) {
|
|
2778
|
+
throw new D("MISSING_GLYPH", "The selected font cannot encode this text.", { cause: e });
|
|
2779
|
+
}
|
|
2780
|
+
let h = o * Math.PI / 180, g = Math.cos(h), _ = Math.sin(h), [y, b] = this.point(0, 0);
|
|
2781
|
+
for (let [e, t] of m.entries()) {
|
|
2782
|
+
let p = f(t), m = s === "center" ? p / 2 : s === "right" ? p : 0, h = e * i * a, x = n - m * g - h * _, S = r + m * _ - h * g;
|
|
2783
|
+
if (this.page.drawText(t, {
|
|
2784
|
+
x,
|
|
2785
|
+
y: S,
|
|
2786
|
+
font: d,
|
|
2787
|
+
size: i,
|
|
2788
|
+
color: c.color,
|
|
2789
|
+
opacity: l,
|
|
2790
|
+
rotate: v(-o)
|
|
2791
|
+
}), u && p > 0) {
|
|
2792
|
+
let e = d.heightAtSize(i, { descender: !1 }), t = d.heightAtSize(i) - e, n = [
|
|
2793
|
+
[0, -e],
|
|
2794
|
+
[p, -e],
|
|
2795
|
+
[p, t],
|
|
2796
|
+
[0, t]
|
|
2797
|
+
].map(([e, t]) => ({
|
|
2798
|
+
x: (x + e * g - t * _ - y) / this.scale,
|
|
2799
|
+
y: (b - S + e * _ + t * g) / this.scale
|
|
2800
|
+
})), r = Math.min(...n.map((e) => e.x)), a = Math.min(...n.map((e) => e.y));
|
|
2801
|
+
this.addLink(u, {
|
|
2802
|
+
x: r,
|
|
2803
|
+
y: a,
|
|
2804
|
+
width: Math.max(...n.map((e) => e.x)) - r,
|
|
2805
|
+
height: Math.max(...n.map((e) => e.y)) - a
|
|
2806
|
+
});
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
return this;
|
|
2810
|
+
}
|
|
2811
|
+
drawLine(e) {
|
|
2812
|
+
if (this.ready(), !e || typeof e != "object") throw new D("INVALID_OPTIONS", "Provide line drawing options.");
|
|
2813
|
+
let [t, n] = this.point(e.x1, e.y1), [r, i] = this.point(e.x2, e.y2), a = e.width ?? 1;
|
|
2814
|
+
Y(a, "width", !0);
|
|
2815
|
+
let o = q(e.color ?? "black");
|
|
2816
|
+
return this.page.drawLine({
|
|
2817
|
+
start: {
|
|
2818
|
+
x: t,
|
|
2819
|
+
y: n
|
|
2820
|
+
},
|
|
2821
|
+
end: {
|
|
2822
|
+
x: r,
|
|
2823
|
+
y: i
|
|
2824
|
+
},
|
|
2825
|
+
thickness: a * this.scale,
|
|
2826
|
+
color: o.color,
|
|
2827
|
+
opacity: Z(e.opacity) * o.opacity
|
|
2828
|
+
}), this;
|
|
2829
|
+
}
|
|
2830
|
+
paint(e) {
|
|
2831
|
+
let t = e.fill === void 0 ? void 0 : q(e.fill), n = e.stroke === void 0 ? t ? void 0 : q("black") : q(e.stroke), r = e.strokeWidth ?? 1;
|
|
2832
|
+
Y(r, "strokeWidth", !0);
|
|
2833
|
+
let i = Z(e.opacity);
|
|
2834
|
+
return {
|
|
2835
|
+
...t ? { color: t.color } : {},
|
|
2836
|
+
...n ? { borderColor: n.color } : {},
|
|
2837
|
+
borderWidth: n ? r * this.scale : 0,
|
|
2838
|
+
opacity: i * (t?.opacity ?? 1),
|
|
2839
|
+
borderOpacity: i * (n?.opacity ?? 1)
|
|
2840
|
+
};
|
|
2841
|
+
}
|
|
2842
|
+
drawRectangle(e) {
|
|
2843
|
+
this.ready(), X(e);
|
|
2844
|
+
let t = this.paint(e), [n, r] = this.point(e.x, e.y + e.height);
|
|
2845
|
+
return this.page.drawRectangle({
|
|
2846
|
+
x: n,
|
|
2847
|
+
y: r,
|
|
2848
|
+
width: e.width * this.scale,
|
|
2849
|
+
height: e.height * this.scale,
|
|
2850
|
+
...t
|
|
2851
|
+
}), this;
|
|
2852
|
+
}
|
|
2853
|
+
drawEllipse(e) {
|
|
2854
|
+
this.ready(), X(e);
|
|
2855
|
+
let t = this.paint(e), [n, r] = this.point(e.x + e.width / 2, e.y + e.height / 2);
|
|
2856
|
+
return this.page.drawEllipse({
|
|
2857
|
+
x: n,
|
|
2858
|
+
y: r,
|
|
2859
|
+
xScale: e.width * this.scale / 2,
|
|
2860
|
+
yScale: e.height * this.scale / 2,
|
|
2861
|
+
...t
|
|
2862
|
+
}), this;
|
|
2863
|
+
}
|
|
2864
|
+
drawCircle(e) {
|
|
2865
|
+
if (this.ready(), !e || typeof e != "object") throw new D("INVALID_OPTIONS", "Provide circle drawing options.");
|
|
2866
|
+
return Y(e.radius, "radius"), this.drawEllipse({
|
|
2867
|
+
...e,
|
|
2868
|
+
x: e.x - e.radius,
|
|
2869
|
+
y: e.y - e.radius,
|
|
2870
|
+
width: e.radius * 2,
|
|
2871
|
+
height: e.radius * 2
|
|
2872
|
+
});
|
|
2873
|
+
}
|
|
2874
|
+
drawSvgPath(e, t) {
|
|
2875
|
+
if (this.ready(), !t || typeof t != "object") throw new D("INVALID_OPTIONS", "Provide SVG path drawing options.");
|
|
2876
|
+
if (typeof e != "string" || !e.trim()) throw new D("INVALID_OPTIONS", "Provide SVG path geometry.");
|
|
2877
|
+
let [n, r] = this.point(t.x, t.y), i = this.paint(t), a = t.scale ?? 1, o = t.rotation ?? 0;
|
|
2878
|
+
Y(a, "scale"), J(o, "rotation");
|
|
2879
|
+
try {
|
|
2880
|
+
this.page.drawSvgPath(e, {
|
|
2881
|
+
x: n,
|
|
2882
|
+
y: r,
|
|
2883
|
+
scale: a * this.scale,
|
|
2884
|
+
rotate: v(-o),
|
|
2885
|
+
...i,
|
|
2886
|
+
borderWidth: i.borderWidth / (a * this.scale)
|
|
2887
|
+
});
|
|
2888
|
+
} catch (e) {
|
|
2889
|
+
throw new D("INVALID_OPTIONS", "The SVG path is invalid.", { cause: e });
|
|
2890
|
+
}
|
|
2891
|
+
return this;
|
|
2892
|
+
}
|
|
2893
|
+
saveGraphicsState() {
|
|
2894
|
+
return this.ready(!0), this.page.pushOperators(E()), this.stack.push([...this.matrix]), this;
|
|
2895
|
+
}
|
|
2896
|
+
restoreGraphicsState() {
|
|
2897
|
+
this.ready(!0);
|
|
2898
|
+
let e = this.stack.pop();
|
|
2899
|
+
if (!e) throw new D("INVALID_OPTIONS", "No saved graphics state is available.");
|
|
2900
|
+
return this.page.pushOperators(T()), this.matrix = e, this;
|
|
2901
|
+
}
|
|
2902
|
+
transform(e) {
|
|
2903
|
+
if (this.ready(!0), !Array.isArray(e) || e.length !== 6) throw new D("INVALID_OPTIONS", "A transform requires six finite coefficients.");
|
|
2904
|
+
for (let t of e) J(t, "transform coefficient");
|
|
2905
|
+
let [t, n, r, i, a, o] = e;
|
|
2906
|
+
if (Math.abs(t * i - n * r) < 1e-12) throw new D("INVALID_OPTIONS", "A transform must be invertible.");
|
|
2907
|
+
let [s, c, l, u, d, f] = this.matrix, [p, m] = this.point(0, 0), h = this.scale;
|
|
2908
|
+
return this.page.pushOperators(_(t, -n, -r, i, (1 - t) * p + r * m + a * h, (1 - i) * m + n * p - o * h)), this.matrix = [
|
|
2909
|
+
s * t + l * n,
|
|
2910
|
+
c * t + u * n,
|
|
2911
|
+
s * r + l * i,
|
|
2912
|
+
c * r + u * i,
|
|
2913
|
+
s * a + l * o + d,
|
|
2914
|
+
c * a + u * o + f
|
|
2915
|
+
], this;
|
|
2916
|
+
}
|
|
2917
|
+
moveTo(e, t) {
|
|
2918
|
+
return this.ready(!0), this.page.pushOperators(ee(...this.point(e, t))), this.pathOpen = !0, this;
|
|
2919
|
+
}
|
|
2920
|
+
lineTo(e, t) {
|
|
2921
|
+
return this.ready(!0), this.requirePath(), this.page.pushOperators(w(...this.point(e, t))), this;
|
|
2922
|
+
}
|
|
2923
|
+
curveTo(e, t, n, r, i, a) {
|
|
2924
|
+
this.ready(!0), this.requirePath();
|
|
2925
|
+
let o = this.point(e, t), s = this.point(n, r), c = this.point(i, a);
|
|
2926
|
+
return this.page.pushOperators(d(...o, ...s, ...c)), this;
|
|
2927
|
+
}
|
|
2928
|
+
closePath() {
|
|
2929
|
+
return this.ready(!0), this.requirePath(), this.page.pushOperators(g()), this;
|
|
2930
|
+
}
|
|
2931
|
+
requirePath() {
|
|
2932
|
+
if (!this.pathOpen) throw new D("INVALID_OPTIONS", "Start a path with moveTo before painting or clipping it.");
|
|
2933
|
+
}
|
|
2934
|
+
clip(e = "nonzero") {
|
|
2935
|
+
if (this.ready(!0), this.requirePath(), e !== "nonzero" && e !== "evenodd") throw new D("INVALID_OPTIONS", "The clipping rule must be nonzero or evenodd.");
|
|
2936
|
+
return this.page.pushOperators(e === "evenodd" ? h() : m()), this;
|
|
2937
|
+
}
|
|
2938
|
+
clipRectangle(e) {
|
|
2939
|
+
this.ready(), X(e);
|
|
2940
|
+
let [t, n] = this.point(e.x, e.y + e.height);
|
|
2941
|
+
return this.page.pushOperators(te(t, n, e.width * this.scale, e.height * this.scale), m(), b()), this;
|
|
2942
|
+
}
|
|
2943
|
+
discardPath() {
|
|
2944
|
+
return this.ready(!0), this.requirePath(), this.page.pushOperators(b()), this.pathOpen = !1, this;
|
|
2945
|
+
}
|
|
2946
|
+
stroke(e = {}) {
|
|
2947
|
+
return this.paintPath({
|
|
2948
|
+
stroke: e.color ?? "black",
|
|
2949
|
+
...e.width === void 0 ? {} : { strokeWidth: e.width },
|
|
2950
|
+
...e.opacity === void 0 ? {} : { opacity: e.opacity }
|
|
2951
|
+
}, "stroke");
|
|
2952
|
+
}
|
|
2953
|
+
fill(e = {}) {
|
|
2954
|
+
return this.paintPath({
|
|
2955
|
+
fill: e.color ?? "black",
|
|
2956
|
+
...e.opacity === void 0 ? {} : { opacity: e.opacity }
|
|
2957
|
+
}, "fill");
|
|
2958
|
+
}
|
|
2959
|
+
fillAndStroke(e = {}) {
|
|
2960
|
+
return this.paintPath({
|
|
2961
|
+
...e,
|
|
2962
|
+
fill: e.fill ?? "black",
|
|
2963
|
+
stroke: e.stroke ?? "black"
|
|
2964
|
+
}, "both");
|
|
2965
|
+
}
|
|
2966
|
+
paintPath(e, t) {
|
|
2967
|
+
this.ready(!0), this.requirePath();
|
|
2968
|
+
let n = this.paint(e), r = this.context.pdf.context.register(this.context.pdf.context.obj({
|
|
2969
|
+
Type: "ExtGState",
|
|
2970
|
+
ca: n.opacity,
|
|
2971
|
+
CA: n.borderOpacity
|
|
2972
|
+
})), i = this.page.node.newExtGState("PathAlpha", r);
|
|
2973
|
+
return this.page.pushOperators(E(), ae(i), oe(n.borderWidth), ...n.color ? [re(n.color)] : [], ...n.borderColor ? [se(n.borderColor)] : [], t === "fill" ? S() : t === "stroke" ? de() : C(), T()), this.pathOpen = !1, this;
|
|
2974
|
+
}
|
|
2975
|
+
async imageBytes(e) {
|
|
2976
|
+
if (e instanceof Uint8Array) return Uint8Array.from(e);
|
|
2977
|
+
if (e instanceof ArrayBuffer) return new Uint8Array(e.slice(0));
|
|
2978
|
+
if (typeof Blob < "u" && e instanceof Blob) return new Uint8Array(await e.arrayBuffer());
|
|
2979
|
+
if (typeof e == "object" && e && "tagName" in e) {
|
|
2980
|
+
if ("toDataURL" in e) return V(e.width, e.height), this.imageBytes(e.toDataURL("image/png"));
|
|
2981
|
+
if ("naturalWidth" in e) {
|
|
2982
|
+
let t = e.currentSrc || e.src;
|
|
2983
|
+
if (e.complete && e.naturalWidth || await e.decode(), this.context.assertActive(), (e.currentSrc || e.src) !== t) throw new D("SOURCE_CHANGED", "The browser image source changed while decoding.");
|
|
2984
|
+
V(e.naturalWidth, e.naturalHeight);
|
|
2985
|
+
let n = e.ownerDocument.createElement("canvas");
|
|
2986
|
+
n.width = e.naturalWidth, n.height = e.naturalHeight;
|
|
2987
|
+
let r = n.getContext("2d");
|
|
2988
|
+
if (!r) throw new D("RESOURCE_LOAD_FAILED", "A canvas context is required to read this image.");
|
|
2989
|
+
return r.drawImage(e, 0, 0), this.imageBytes(n.toDataURL("image/png"));
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
if (typeof e == "string") {
|
|
2993
|
+
let t = /^data:image\/(?:png|jpe?g);base64,([a-z\d+/=\s]+)$/i.exec(e)?.[1];
|
|
2994
|
+
if (!t) throw new D("UNSUPPORTED_IMAGE", "Image strings must be PNG/JPEG base64 data URLs.");
|
|
2995
|
+
try {
|
|
2996
|
+
return Uint8Array.from(atob(t), (e) => e.charCodeAt(0));
|
|
2997
|
+
} catch (e) {
|
|
2998
|
+
throw new D("INVALID_SOURCE", "The image data URL contains invalid base64.", { cause: e });
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
throw new D("INVALID_SOURCE", "Provide PNG/JPEG bytes, a File/Blob, a data URL or a browser image/canvas.");
|
|
3002
|
+
}
|
|
3003
|
+
async drawImage(e, t) {
|
|
3004
|
+
this.ready(), X(t), t = { ...t };
|
|
3005
|
+
let n = Z(t.opacity), r = t.rotation ?? 0;
|
|
3006
|
+
J(r, "rotation"), this.pendingImages += 1;
|
|
3007
|
+
try {
|
|
3008
|
+
let i = await this.imageBytes(e);
|
|
3009
|
+
this.context.assertActive();
|
|
3010
|
+
let a = Et(i);
|
|
3011
|
+
a.format === "png" && await Dt(i);
|
|
3012
|
+
let o = a.format === "png" ? await this.context.pdf.embedPng(i) : await this.context.pdf.embedJpg(i);
|
|
3013
|
+
this.context.assertActive();
|
|
3014
|
+
let s = a.orientation >= 5 ? a.height : a.width, c = a.orientation >= 5 ? a.width : a.height, l = bt(a.width, a.height, a.orientation, {
|
|
3015
|
+
width: s,
|
|
3016
|
+
height: c,
|
|
3017
|
+
margin: {
|
|
3018
|
+
top: 0,
|
|
3019
|
+
right: 0,
|
|
3020
|
+
bottom: 0,
|
|
3021
|
+
left: 0
|
|
3022
|
+
}
|
|
3023
|
+
}), u = t.width * this.scale / s, d = t.height * this.scale / c, f = -r * Math.PI / 180, [p, m] = this.point(t.x, t.y);
|
|
3024
|
+
this.page.pushOperators(E(), _(Math.cos(f), Math.sin(f), -Math.sin(f), Math.cos(f), p, m), _(1, 0, 0, 1, 0, -t.height * this.scale), _(l[0] * u, l[1] * d, l[2] * u, l[3] * d, l[4] * u, l[5] * d));
|
|
3025
|
+
try {
|
|
3026
|
+
this.page.drawImage(o, {
|
|
3027
|
+
x: 0,
|
|
3028
|
+
y: 0,
|
|
3029
|
+
width: 1,
|
|
3030
|
+
height: 1,
|
|
3031
|
+
opacity: n
|
|
3032
|
+
});
|
|
3033
|
+
} finally {
|
|
3034
|
+
this.page.pushOperators(T());
|
|
3035
|
+
}
|
|
3036
|
+
return this;
|
|
3037
|
+
} catch (e) {
|
|
3038
|
+
throw this.context.assertActive(), e instanceof D ? e : new D("RESOURCE_LOAD_FAILED", "The PNG/JPEG image could not be drawn. Check that browser image resources are loaded and CORS-readable.", { cause: e });
|
|
3039
|
+
} finally {
|
|
3040
|
+
--this.pendingImages;
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
annotationRectangle(e) {
|
|
3044
|
+
X(e);
|
|
3045
|
+
let [t, n, r, i, a, o] = this.matrix, s = [
|
|
3046
|
+
[e.x, e.y],
|
|
3047
|
+
[e.x + e.width, e.y],
|
|
3048
|
+
[e.x, e.y + e.height],
|
|
3049
|
+
[e.x + e.width, e.y + e.height]
|
|
3050
|
+
].map(([e, s]) => this.point(t * e + r * s + a, n * e + i * s + o));
|
|
3051
|
+
return [
|
|
3052
|
+
Math.min(...s.map(([e]) => e)),
|
|
3053
|
+
Math.min(...s.map(([, e]) => e)),
|
|
3054
|
+
Math.max(...s.map(([e]) => e)),
|
|
3055
|
+
Math.max(...s.map(([, e]) => e))
|
|
3056
|
+
];
|
|
3057
|
+
}
|
|
3058
|
+
addLink(e, t) {
|
|
3059
|
+
this.ready();
|
|
3060
|
+
let n = nn(e), r = this.annotationRectangle(t), i = this.context.pdf.context.obj({
|
|
3061
|
+
Type: "Annot",
|
|
3062
|
+
Subtype: "Link",
|
|
3063
|
+
Rect: r,
|
|
3064
|
+
Border: [
|
|
3065
|
+
0,
|
|
3066
|
+
0,
|
|
3067
|
+
0
|
|
3068
|
+
],
|
|
3069
|
+
F: 4,
|
|
3070
|
+
A: {
|
|
3071
|
+
Type: "Action",
|
|
3072
|
+
S: "URI",
|
|
3073
|
+
URI: c.of(n)
|
|
3074
|
+
}
|
|
3075
|
+
});
|
|
3076
|
+
return this.page.node.addAnnot(this.context.pdf.context.register(i)), this;
|
|
3077
|
+
}
|
|
3078
|
+
addNote(e, t, n = {}) {
|
|
3079
|
+
if (this.ready(), typeof e != "string" || n.title !== void 0 && typeof n.title != "string") throw new D("INVALID_OPTIONS", "Note content and title must be strings.");
|
|
3080
|
+
let r = this.context.pdf.context.obj({
|
|
3081
|
+
Type: "Annot",
|
|
3082
|
+
Subtype: "Text",
|
|
3083
|
+
Rect: this.annotationRectangle(t),
|
|
3084
|
+
Contents: i.fromText(e),
|
|
3085
|
+
T: i.fromText(n.title ?? ""),
|
|
3086
|
+
Name: "Note",
|
|
3087
|
+
Open: !1,
|
|
3088
|
+
C: [
|
|
3089
|
+
1,
|
|
3090
|
+
1,
|
|
3091
|
+
0
|
|
3092
|
+
],
|
|
3093
|
+
F: 4
|
|
3094
|
+
});
|
|
3095
|
+
return this.page.node.addAnnot(this.context.pdf.context.register(r)), this;
|
|
3096
|
+
}
|
|
3097
|
+
fieldOptions(e, t, n) {
|
|
3098
|
+
if (this.ready(), X(t), !n || typeof n != "object") throw new D("INVALID_OPTIONS", "Provide a form field options object.");
|
|
3099
|
+
if (typeof e != "string" || !e.trim() || /(^\.|\.\.|\.$)/.test(e)) throw new D("INVALID_OPTIONS", "Provide a nonempty, valid form field name.");
|
|
3100
|
+
if (this.matrix.some((e, t) => e !== [
|
|
3101
|
+
1,
|
|
3102
|
+
0,
|
|
3103
|
+
0,
|
|
3104
|
+
1,
|
|
3105
|
+
0,
|
|
3106
|
+
0
|
|
3107
|
+
][t])) throw new D("INVALID_OPTIONS", "Create form fields outside transformed graphics states.");
|
|
3108
|
+
for (let e of [n.readOnly, n.required]) if (e !== void 0 && typeof e != "boolean") throw new D("INVALID_OPTIONS", "Form flags must be booleans.");
|
|
3109
|
+
Y(n.fontSize ?? 12, "fontSize"), Y(n.borderWidth ?? 1, "borderWidth", !0);
|
|
3110
|
+
let r = q(n.textColor ?? "black"), i = q(n.borderColor ?? "black"), a = q(n.backgroundColor ?? "white");
|
|
3111
|
+
if ([
|
|
3112
|
+
r,
|
|
3113
|
+
i,
|
|
3114
|
+
a
|
|
3115
|
+
].some((e) => e.opacity !== 1)) throw new D("INVALID_OPTIONS", "Interactive field colors must be opaque.");
|
|
3116
|
+
let [o, s] = this.point(t.x, t.y + t.height), c = this.context.resolveFont(n), l = this.context.pdf.getForm();
|
|
3117
|
+
if (l.getFields().some((t) => t.getName().startsWith(`${e}.`))) throw new D("INVALID_OPTIONS", "A form field cannot replace an existing field group.");
|
|
3118
|
+
let u = e.split(".");
|
|
3119
|
+
for (let e = 1; e <= u.length; e += 1) if (l.getFieldMaybe(u.slice(0, e).join("."))) throw new D("INVALID_OPTIONS", "A form field with this name or parent name already exists.");
|
|
3120
|
+
return {
|
|
3121
|
+
x: o,
|
|
3122
|
+
y: s,
|
|
3123
|
+
width: t.width * this.scale,
|
|
3124
|
+
height: t.height * this.scale,
|
|
3125
|
+
font: c,
|
|
3126
|
+
textColor: r.color,
|
|
3127
|
+
borderColor: i.color,
|
|
3128
|
+
backgroundColor: a.color,
|
|
3129
|
+
borderWidth: (n.borderWidth ?? 1) * this.scale
|
|
3130
|
+
};
|
|
3131
|
+
}
|
|
3132
|
+
fieldFlags(e, t) {
|
|
3133
|
+
t.readOnly && e.enableReadOnly(), t.required && e.enableRequired();
|
|
3134
|
+
}
|
|
3135
|
+
addTextField(e, t, n = {}) {
|
|
3136
|
+
let r = this.fieldOptions(e, t, n), i = n.value ?? "";
|
|
3137
|
+
if (typeof i != "string" || n.multiline !== void 0 && typeof n.multiline != "boolean") throw new D("INVALID_OPTIONS", "Text field value must be text and multiline must be boolean.");
|
|
3138
|
+
if (n.maxLength !== void 0 && (!Number.isSafeInteger(n.maxLength) || n.maxLength <= 0 || i.length > n.maxLength)) throw new D("INVALID_OPTIONS", "The text field maximum length must be positive and fit its value.");
|
|
3139
|
+
rn(r.font, i);
|
|
3140
|
+
let a = this.context.pdf.getForm().createTextField(e);
|
|
3141
|
+
return n.multiline && a.enableMultiline(), n.maxLength !== void 0 && a.setMaxLength(n.maxLength), a.setText(i), this.fieldFlags(a, n), a.addToPage(this.page, r), a.setFontSize((n.fontSize ?? 12) / this.userUnit), a.updateAppearances(r.font), this;
|
|
3142
|
+
}
|
|
3143
|
+
addCheckBox(e, t, n = {}) {
|
|
3144
|
+
let r = this.fieldOptions(e, t, n);
|
|
3145
|
+
if (n.checked !== void 0 && typeof n.checked != "boolean") throw new D("INVALID_OPTIONS", "The checkbox state must be boolean.");
|
|
3146
|
+
let i = this.context.pdf.getForm().createCheckBox(e);
|
|
3147
|
+
return n.checked && i.check(), this.fieldFlags(i, n), i.addToPage(this.page, r), i.updateAppearances(), this;
|
|
3148
|
+
}
|
|
3149
|
+
addDropdown(e, t, n, r = {}) {
|
|
3150
|
+
let i = this.fieldOptions(e, t, r);
|
|
3151
|
+
if (!Array.isArray(n) || n.some((e) => typeof e != "string") || new Set(n).size !== n.length) throw new D("INVALID_OPTIONS", "Dropdown choices must be unique strings.");
|
|
3152
|
+
for (let e of [r.editable, r.multiselect]) if (e !== void 0 && typeof e != "boolean") throw new D("INVALID_OPTIONS", "Dropdown flags must be booleans.");
|
|
3153
|
+
let a = typeof r.value == "string" ? [r.value] : r.value ?? [];
|
|
3154
|
+
if (!Array.isArray(a) || a.some((e) => typeof e != "string" || !r.editable && !n.includes(e)) || !r.multiselect && a.length > 1) throw new D("INVALID_OPTIONS", "The dropdown selection must match its choices and selection mode.");
|
|
3155
|
+
for (let e of [...n, ...a]) rn(i.font, e);
|
|
3156
|
+
let o = this.context.pdf.getForm().createDropdown(e);
|
|
3157
|
+
return o.setOptions([...n]), r.editable && o.enableEditing(), r.multiselect && o.enableMultiselect(), a.length && o.select([...a]), this.fieldFlags(o, r), o.addToPage(this.page, i), o.setFontSize((r.fontSize ?? 12) / this.userUnit), o.updateAppearances(i.font), this;
|
|
3158
|
+
}
|
|
3159
|
+
}, on = {
|
|
3160
|
+
A4: [595.28, 841.89],
|
|
3161
|
+
A3: [841.89, 1190.55],
|
|
3162
|
+
Letter: [612, 792]
|
|
3163
|
+
};
|
|
3164
|
+
function sn(e = {}) {
|
|
3165
|
+
if (!e || typeof e != "object" || Array.isArray(e) || e.font !== void 0 && (typeof e.font != "string" || !e.font.trim())) throw new D("INVALID_OPTIONS", "Provide a nonempty font family and font options.");
|
|
3166
|
+
let t = e.font?.trim().toLowerCase() || "helvetica";
|
|
3167
|
+
t === "times-roman" && (t = "times");
|
|
3168
|
+
let n = e.fontWeight ?? 400, r = e.fontStyle ?? "normal";
|
|
3169
|
+
if (!Number.isInteger(n) || n < 1 || n > 1e3 || !["normal", "italic"].includes(r)) throw new D("INVALID_OPTIONS", "Provide an exact static font weight and normal/italic style.");
|
|
3170
|
+
return `${t}:${n}:${r}`;
|
|
3171
|
+
}
|
|
3172
|
+
function cn(e, t) {
|
|
3173
|
+
if (!e || typeof e != "object" || Array.isArray(e)) throw new D("INVALID_OPTIONS", "Page options must be an object.");
|
|
3174
|
+
let n = e.format ?? "A4", r = e.orientation ?? "portrait";
|
|
3175
|
+
if (!["portrait", "landscape"].includes(r)) throw new D("INVALID_OPTIONS", "Page orientation must be portrait or landscape.");
|
|
3176
|
+
let i;
|
|
3177
|
+
if (typeof n == "string" && Object.hasOwn(on, n)) i = on[n];
|
|
3178
|
+
else if (n && typeof n == "object") i = [n.width * t, n.height * t];
|
|
3179
|
+
else throw new D("INVALID_OPTIONS", "Provide A4, A3, Letter or explicit page dimensions.");
|
|
3180
|
+
if (i.some((e) => !Number.isFinite(e) || e <= 0)) throw new D("INVALID_OPTIONS", "Page dimensions must be finite and positive.");
|
|
3181
|
+
return r === "landscape" ? [i[1], i[0]] : [i[0], i[1]];
|
|
3182
|
+
}
|
|
3183
|
+
var ln = class o {
|
|
3184
|
+
pdf;
|
|
3185
|
+
fonts;
|
|
3186
|
+
fontNames;
|
|
3187
|
+
defaults;
|
|
3188
|
+
signal;
|
|
3189
|
+
unitScale;
|
|
3190
|
+
unit;
|
|
3191
|
+
pages = [];
|
|
3192
|
+
activePages = /* @__PURE__ */ new Set();
|
|
3193
|
+
characterSets = /* @__PURE__ */ new WeakMap();
|
|
3194
|
+
bookmarks = /* @__PURE__ */ new Map();
|
|
3195
|
+
roots = [];
|
|
3196
|
+
outlines;
|
|
3197
|
+
finished = !1;
|
|
3198
|
+
pending = !1;
|
|
3199
|
+
output;
|
|
3200
|
+
constructor(e, t, n, r, i, a) {
|
|
3201
|
+
this.pdf = e, this.fonts = t, this.fontNames = n, this.defaults = r, this.signal = a, this.unit = i, this.unitScale = i === "mm" ? 72 / 25.4 : i === "px" ? .75 : 1, this.outlines = e.context.register(e.context.obj({ Type: "Outlines" }));
|
|
3202
|
+
}
|
|
3203
|
+
static async create(t = {}) {
|
|
3204
|
+
if (!t || typeof t != "object" || Array.isArray(t)) throw new D("INVALID_OPTIONS", "Document options must be an object.");
|
|
3205
|
+
let n = t.unit ?? "pt";
|
|
3206
|
+
if (![
|
|
3207
|
+
"pt",
|
|
3208
|
+
"mm",
|
|
3209
|
+
"px"
|
|
3210
|
+
].includes(n)) throw new D("INVALID_OPTIONS", "Document coordinates use pt, mm or px.");
|
|
3211
|
+
let i = {
|
|
3212
|
+
format: typeof t.format == "object" ? { ...t.format } : t.format ?? "A4",
|
|
3213
|
+
orientation: t.orientation ?? "portrait"
|
|
3214
|
+
};
|
|
3215
|
+
cn(i, n === "mm" ? 72 / 25.4 : n === "px" ? .75 : 1);
|
|
3216
|
+
let a = k(t.metadata), s = t.signal;
|
|
3217
|
+
if (s !== void 0 && (typeof s != "object" || !s || typeof s.aborted != "boolean" || typeof s.addEventListener != "function")) throw new D("INVALID_OPTIONS", "Provide an AbortSignal for document cancellation.");
|
|
3218
|
+
if (O(s), t.fonts !== void 0 && !Array.isArray(t.fonts)) throw new D("INVALID_OPTIONS", "Document fonts must be an array of static font sources.");
|
|
3219
|
+
let c = (t.fonts ?? []).map((e) => {
|
|
3220
|
+
if (!e || typeof e.family != "string" || !e.family.trim() || !(e.data instanceof Uint8Array) && !(e.data instanceof ArrayBuffer)) throw new D("INVALID_OPTIONS", "Provide a font family and static TTF/OTF bytes.");
|
|
3221
|
+
let t = Uint8Array.from(e.data instanceof Uint8Array ? e.data : new Uint8Array(e.data));
|
|
3222
|
+
we(t);
|
|
3223
|
+
let n = {
|
|
3224
|
+
family: e.family.trim(),
|
|
3225
|
+
data: t,
|
|
3226
|
+
weight: e.weight ?? 400,
|
|
3227
|
+
style: e.style ?? "normal"
|
|
3228
|
+
};
|
|
3229
|
+
return sn({
|
|
3230
|
+
font: n.family,
|
|
3231
|
+
fontWeight: n.weight,
|
|
3232
|
+
fontStyle: n.style
|
|
3233
|
+
}), n;
|
|
3234
|
+
}), u = await r.create();
|
|
3235
|
+
u.registerFontkit(e), A(u, a);
|
|
3236
|
+
let d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Set(), p = [
|
|
3237
|
+
[
|
|
3238
|
+
"Helvetica",
|
|
3239
|
+
l.Helvetica,
|
|
3240
|
+
l.HelveticaBold,
|
|
3241
|
+
l.HelveticaOblique,
|
|
3242
|
+
l.HelveticaBoldOblique
|
|
3243
|
+
],
|
|
3244
|
+
[
|
|
3245
|
+
"Times",
|
|
3246
|
+
l.TimesRoman,
|
|
3247
|
+
l.TimesRomanBold,
|
|
3248
|
+
l.TimesRomanItalic,
|
|
3249
|
+
l.TimesRomanBoldItalic
|
|
3250
|
+
],
|
|
3251
|
+
[
|
|
3252
|
+
"Courier",
|
|
3253
|
+
l.Courier,
|
|
3254
|
+
l.CourierBold,
|
|
3255
|
+
l.CourierOblique,
|
|
3256
|
+
l.CourierBoldOblique
|
|
3257
|
+
]
|
|
3258
|
+
];
|
|
3259
|
+
for (let [e, t, n, r, i] of p) {
|
|
3260
|
+
for (let [a, o, c] of [
|
|
3261
|
+
[
|
|
3262
|
+
t,
|
|
3263
|
+
400,
|
|
3264
|
+
"normal"
|
|
3265
|
+
],
|
|
3266
|
+
[
|
|
3267
|
+
n,
|
|
3268
|
+
700,
|
|
3269
|
+
"normal"
|
|
3270
|
+
],
|
|
3271
|
+
[
|
|
3272
|
+
r,
|
|
3273
|
+
400,
|
|
3274
|
+
"italic"
|
|
3275
|
+
],
|
|
3276
|
+
[
|
|
3277
|
+
i,
|
|
3278
|
+
700,
|
|
3279
|
+
"italic"
|
|
3280
|
+
]
|
|
3281
|
+
]) O(s), d.set(sn({
|
|
3282
|
+
font: e,
|
|
3283
|
+
fontWeight: o,
|
|
3284
|
+
fontStyle: c
|
|
3285
|
+
}), await u.embedFont(a));
|
|
3286
|
+
f.add(e);
|
|
3287
|
+
}
|
|
3288
|
+
for (let e of c) {
|
|
3289
|
+
O(s);
|
|
3290
|
+
let t = sn({
|
|
3291
|
+
font: e.family,
|
|
3292
|
+
fontWeight: e.weight ?? 400,
|
|
3293
|
+
fontStyle: e.style ?? "normal"
|
|
3294
|
+
});
|
|
3295
|
+
if (d.has(t)) throw new D("INVALID_OPTIONS", "Each font family, weight and style must be unique.");
|
|
3296
|
+
try {
|
|
3297
|
+
d.set(t, await u.embedFont(e.data, { subset: !0 })), f.add(e.family);
|
|
3298
|
+
} catch (t) {
|
|
3299
|
+
throw new D("FONT_LOAD_FAILED", `Could not embed font ${e.family}.`, { cause: t });
|
|
3300
|
+
}
|
|
3301
|
+
}
|
|
3302
|
+
return O(s), new o(u, d, Object.freeze([...f]), i, n, s);
|
|
3303
|
+
}
|
|
3304
|
+
get pageCount() {
|
|
3305
|
+
return this.pages.length;
|
|
3306
|
+
}
|
|
3307
|
+
getFontNames() {
|
|
3308
|
+
return this.fontNames;
|
|
3309
|
+
}
|
|
3310
|
+
assertMutable() {
|
|
3311
|
+
if (O(this.signal), this.finished) throw new D("INVALID_OPTIONS", "The document has been finalized; create another document to edit it.");
|
|
3312
|
+
}
|
|
3313
|
+
assertActive() {
|
|
3314
|
+
if (this.assertMutable(), this.pending) throw new D("INVALID_OPTIONS", "Await the pending document operation before drawing or saving.");
|
|
3315
|
+
}
|
|
3316
|
+
resolveFont(e = {}) {
|
|
3317
|
+
let t = this.fonts.get(sn(e));
|
|
3318
|
+
if (!t) throw new D("MISSING_FONT", `Register the requested ${e.font ?? "Helvetica"} weight and style before drawing.`);
|
|
3319
|
+
return t;
|
|
3320
|
+
}
|
|
3321
|
+
wrapPage(e, t = this.pages.length) {
|
|
3322
|
+
this.activePages.add(e.ref);
|
|
3323
|
+
let n = new an(e, {
|
|
3324
|
+
pdf: this.pdf,
|
|
3325
|
+
scale: this.unitScale,
|
|
3326
|
+
resolveFont: (e) => this.resolveFont(e),
|
|
3327
|
+
assertActive: () => {
|
|
3328
|
+
if (this.assertActive(), !this.activePages.has(e.ref)) throw new D("INVALID_OPTIONS", "This page has been removed from its document.");
|
|
3329
|
+
}
|
|
3330
|
+
});
|
|
3331
|
+
return this.pages.splice(t, 0, n), n;
|
|
3332
|
+
}
|
|
3333
|
+
addPage(e = {}) {
|
|
3334
|
+
if (this.assertActive(), !e || typeof e != "object" || Array.isArray(e)) throw new D("INVALID_OPTIONS", "Page options must be an object.");
|
|
3335
|
+
if (this.pages.length >= 1e3) throw new D("INVALID_OPTIONS", "A document is limited to 1000 pages.");
|
|
3336
|
+
return this.wrapPage(this.pdf.addPage(cn({
|
|
3337
|
+
...this.defaults,
|
|
3338
|
+
...e
|
|
3339
|
+
}, this.unitScale)));
|
|
3340
|
+
}
|
|
3341
|
+
insertPage(e, t = {}) {
|
|
3342
|
+
if (this.assertActive(), !t || typeof t != "object" || Array.isArray(t)) throw new D("INVALID_OPTIONS", "Page options must be an object.");
|
|
3343
|
+
if (!Number.isInteger(e) || e < 1 || e > this.pageCount + 1 || this.pageCount >= 1e3) throw new D("INVALID_OPTIONS", "Insertion position must be within this document and its 1000-page limit.");
|
|
3344
|
+
return this.wrapPage(this.pdf.insertPage(e - 1, cn({
|
|
3345
|
+
...this.defaults,
|
|
3346
|
+
...t
|
|
3347
|
+
}, this.unitScale)), e - 1);
|
|
3348
|
+
}
|
|
3349
|
+
movePage(e, t) {
|
|
3350
|
+
this.assertActive();
|
|
3351
|
+
let n = this.getPage(e);
|
|
3352
|
+
if (this.getPage(t), e === t) return this;
|
|
3353
|
+
let r = this.pdf.getPage(e - 1);
|
|
3354
|
+
return this.pdf.removePage(e - 1), this.pdf.insertPage(t - 1, r), this.pages.splice(e - 1, 1), this.pages.splice(t - 1, 0, n), this;
|
|
3355
|
+
}
|
|
3356
|
+
removePage(e) {
|
|
3357
|
+
this.assertActive(), this.getPage(e).assertComplete();
|
|
3358
|
+
let r = this.pdf.getPage(e - 1).ref;
|
|
3359
|
+
for (let e of this.bookmarks.values()) if (e.dict.lookup(a.of("Dest"), t).get(0) === r) throw new D("INVALID_OPTIONS", "Cannot remove a bookmarked page.");
|
|
3360
|
+
for (let e of this.pdf.getPages()) for (let i of e.node.Annots()?.asArray() ?? []) {
|
|
3361
|
+
let o = this.pdf.context.lookup(i, n);
|
|
3362
|
+
if (e.ref === r && o.get(a.of("Subtype")) === a.of("Widget")) throw new D("INVALID_OPTIONS", "Flatten form fields before removing their page.");
|
|
3363
|
+
let s = o.lookupMaybe(a.of("A"), n);
|
|
3364
|
+
if ((o.lookupMaybe(a.of("Dest"), t) ?? s?.lookupMaybe(a.of("D"), t))?.get(0) === r) throw new D("INVALID_OPTIONS", "Cannot remove a page targeted by an internal link.");
|
|
3365
|
+
}
|
|
3366
|
+
return this.pdf.removePage(e - 1), this.activePages.delete(r), this.pages.splice(e - 1, 1), this;
|
|
3367
|
+
}
|
|
3368
|
+
getPage(e) {
|
|
3369
|
+
if (!Number.isInteger(e) || e < 1 || e > this.pageCount) throw new D("INVALID_OPTIONS", "Page number is outside this document.");
|
|
3370
|
+
return this.pages[e - 1];
|
|
3371
|
+
}
|
|
3372
|
+
getPages() {
|
|
3373
|
+
return Object.freeze([...this.pages]);
|
|
3374
|
+
}
|
|
3375
|
+
measureText(e, t = {}) {
|
|
3376
|
+
if (this.assertActive(), !t || typeof t != "object" || Array.isArray(t)) throw new D("INVALID_OPTIONS", "Text measurement options must be an object.");
|
|
3377
|
+
if (typeof e != "string") throw new D("INVALID_OPTIONS", "Text must be a string.");
|
|
3378
|
+
let n = t.fontSize ?? 12, r = t.lineHeight ?? 1.15;
|
|
3379
|
+
if (!Number.isFinite(n) || n <= 0 || !Number.isFinite(r) || r <= 0) throw new D("INVALID_OPTIONS", "Font size and line height must be finite and positive.");
|
|
3380
|
+
let i = this.resolveFont(t), a = this.characterSets.get(i);
|
|
3381
|
+
a || (a = new Set(i.getCharacterSet()), this.characterSets.set(i, a));
|
|
3382
|
+
for (let t of e.replace(/[\r\n]/g, "")) if (!a.has(t.codePointAt(0))) throw new D("MISSING_GLYPH", `The selected font has no glyph for ${t}.`);
|
|
3383
|
+
let o = e.split(/\r\n|\r|\n/), s = i.heightAtSize(n, { descender: !1 }), c = Math.max(0, i.heightAtSize(n) - s), l = 0;
|
|
3384
|
+
for (let e of o) l = Math.max(l, i.widthOfTextAtSize(e, n));
|
|
3385
|
+
return {
|
|
3386
|
+
width: l / this.unitScale,
|
|
3387
|
+
height: (e ? o.length * n * r : 0) / this.unitScale,
|
|
3388
|
+
ascent: s / this.unitScale,
|
|
3389
|
+
descent: c / this.unitScale
|
|
3390
|
+
};
|
|
3391
|
+
}
|
|
3392
|
+
async appendPDF(e, t) {
|
|
3393
|
+
if (this.assertActive(), t !== void 0 && (!Array.isArray(t) || t.length === 0 || t.length > 1e3 || t.some((e) => !Number.isSafeInteger(e) || e < 1))) throw new D("INVALID_OPTIONS", "Provide a nonempty array of positive integer page numbers.");
|
|
3394
|
+
let n = t === void 0 ? void 0 : [...t];
|
|
3395
|
+
this.pending = !0;
|
|
3396
|
+
try {
|
|
3397
|
+
let t = await Jt(e, this.signal);
|
|
3398
|
+
this.assertMutable();
|
|
3399
|
+
let r = await Xt(this.pdf, t, n, this.signal);
|
|
3400
|
+
for (let e of r) this.wrapPage(e);
|
|
3401
|
+
return this;
|
|
3402
|
+
} finally {
|
|
3403
|
+
this.pending = !1;
|
|
3404
|
+
}
|
|
3405
|
+
}
|
|
3406
|
+
flattenForms() {
|
|
3407
|
+
this.assertActive();
|
|
3408
|
+
for (let e of this.pages) e.assertComplete();
|
|
3409
|
+
this.pdf.getForm().flatten({ updateFieldAppearances: !1 });
|
|
3410
|
+
for (let e of this.pdf.getPages()) {
|
|
3411
|
+
let t = e.node.Annots();
|
|
3412
|
+
if (t) for (let e = t.size() - 1; e >= 0; --e) this.pdf.context.lookup(t.get(e)) || t.remove(e);
|
|
3413
|
+
}
|
|
3414
|
+
return this;
|
|
3415
|
+
}
|
|
3416
|
+
addBookmark(e, t) {
|
|
3417
|
+
if (this.assertActive(), !t || typeof t != "object" || Array.isArray(t)) throw new D("INVALID_OPTIONS", "Provide bookmark destination options.");
|
|
3418
|
+
if (typeof e != "string" || !e.trim()) throw new D("INVALID_OPTIONS", "Bookmark title must be nonempty.");
|
|
3419
|
+
this.getPage(t.pageNumber);
|
|
3420
|
+
let n = t.parent ? this.bookmarks.get(t.parent) : void 0;
|
|
3421
|
+
if (t.parent && !n) throw new D("INVALID_OPTIONS", "Bookmark parent belongs to another document.");
|
|
3422
|
+
let r = this.pdf.getPage(t.pageNumber - 1).ref, o = this.pdf, s = Object.freeze({
|
|
3423
|
+
title: e,
|
|
3424
|
+
get pageNumber() {
|
|
3425
|
+
return o.getPages().findIndex((e) => e.ref === r) + 1;
|
|
3426
|
+
}
|
|
3427
|
+
}), c = this.pdf.context.obj({
|
|
3428
|
+
Title: i.fromText(e),
|
|
3429
|
+
Parent: n?.ref ?? this.outlines,
|
|
3430
|
+
Dest: [this.pdf.getPage(t.pageNumber - 1).ref, a.of("Fit")]
|
|
3431
|
+
}), l = {
|
|
3432
|
+
handle: s,
|
|
3433
|
+
dict: c,
|
|
3434
|
+
ref: this.pdf.context.register(c),
|
|
3435
|
+
children: []
|
|
3436
|
+
};
|
|
3437
|
+
return this.bookmarks.set(s, l), (n?.children ?? this.roots).push(l), s;
|
|
3438
|
+
}
|
|
3439
|
+
writeBookmarks() {
|
|
3440
|
+
if (!this.roots.length) return;
|
|
3441
|
+
let e = (t, n) => {
|
|
3442
|
+
let r = 0;
|
|
3443
|
+
for (let [t, i] of n.entries()) t > 0 && i.dict.set(a.of("Prev"), n[t - 1].ref), t + 1 < n.length && i.dict.set(a.of("Next"), n[t + 1].ref), r += 1 + e(i.dict, i.children);
|
|
3444
|
+
return n.length && (t.set(a.of("First"), n[0].ref), t.set(a.of("Last"), n[n.length - 1].ref), t.set(a.of("Count"), this.pdf.context.obj(r))), r;
|
|
3445
|
+
};
|
|
3446
|
+
e(this.pdf.context.lookup(this.outlines, n), this.roots), this.pdf.catalog.set(a.of("Outlines"), this.outlines);
|
|
3447
|
+
}
|
|
3448
|
+
async toResult() {
|
|
3449
|
+
if (this.output) return this.output;
|
|
3450
|
+
if (this.assertActive(), !this.pageCount) throw new D("INVALID_OPTIONS", "Add at least one page before finalizing the document.");
|
|
3451
|
+
for (let e of this.pages) e.assertComplete();
|
|
3452
|
+
return this.writeBookmarks(), this.finished = !0, this.output = this.pdf.save({ updateFieldAppearances: !1 }).then((e) => (O(this.signal), B(e, this.pageCount, []))).catch((e) => {
|
|
3453
|
+
throw e instanceof D || e instanceof Error && e.name === "AbortError" ? e : new D("PDF_WRITE_FAILED", "The document could not be serialized.", { cause: e });
|
|
3454
|
+
}), this.output;
|
|
3455
|
+
}
|
|
3456
|
+
};
|
|
3457
|
+
async function un(e = {}) {
|
|
3458
|
+
return ln.create(e);
|
|
3459
|
+
}
|
|
3460
|
+
// src/jspdf-adapter.ts
|
|
3461
|
+
function Q(e, t, n = !1) {
|
|
3462
|
+
if (!Number.isFinite(e) || (n ? e < 0 : e <= 0)) throw new D("INVALID_OPTIONS", `${t} must be a finite ${n ? "nonnegative" : "positive"} number.`);
|
|
3463
|
+
return e;
|
|
3464
|
+
}
|
|
3465
|
+
function dn(e) {
|
|
3466
|
+
if (typeof e == "string") return e.split(/\r?\n/);
|
|
3467
|
+
if (typeof e == "number" && Number.isFinite(e)) return [String(e)];
|
|
3468
|
+
if (Array.isArray(e) && e.every((e) => typeof e == "string")) return e.flatMap((e) => e.split(/\r?\n/));
|
|
3469
|
+
throw new D("INVALID_OPTIONS", "Text must be a string, finite number or array of strings.");
|
|
3470
|
+
}
|
|
3471
|
+
function fn(e) {
|
|
3472
|
+
if (e instanceof Uint8Array) return Uint8Array.from(e);
|
|
3473
|
+
if (e instanceof ArrayBuffer) return e.slice(0);
|
|
3474
|
+
if (typeof e != "object" || !e || !("tagName" in e)) return e;
|
|
3475
|
+
let t = "naturalWidth" in e ? e.naturalWidth : e.width, n = "naturalHeight" in e ? e.naturalHeight : e.height;
|
|
3476
|
+
if ("complete" in e && (!e.complete || t === 0 || n === 0)) throw new D("RESOURCE_LOAD_FAILED", "Await image.decode() before adding a browser image.");
|
|
3477
|
+
if (!Number.isSafeInteger(t) || !Number.isSafeInteger(n) || t <= 0 || n <= 0 || t * n > 4e7) throw new D("UNSUPPORTED_IMAGE", "Browser images must contain 1 to 40 million pixels.");
|
|
3478
|
+
try {
|
|
3479
|
+
if ("toDataURL" in e) return e.toDataURL("image/png");
|
|
3480
|
+
let r = e.ownerDocument.createElement("canvas");
|
|
3481
|
+
r.width = t, r.height = n;
|
|
3482
|
+
let i = r.getContext("2d");
|
|
3483
|
+
if (!i) throw new D("RESOURCE_LOAD_FAILED", "A canvas context is required to snapshot browser image pixels.");
|
|
3484
|
+
return i.drawImage(e, 0, 0), r.toDataURL("image/png");
|
|
2384
3485
|
} catch (e) {
|
|
2385
|
-
|
|
3486
|
+
throw e instanceof D ? e : new D("RESOURCE_LOAD_FAILED", "Browser image pixels could not be read. Use a same-origin or CORS-readable image.", { cause: e });
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3489
|
+
function pn(e, t, n) {
|
|
3490
|
+
if (typeof e != "string" || !e.trim() || typeof t != "string") throw new D("INVALID_OPTIONS", "Provide a nonempty font family and a supported style.");
|
|
3491
|
+
let r = t.replace(/[- ]/g, "").toLowerCase();
|
|
3492
|
+
if (![
|
|
3493
|
+
"normal",
|
|
3494
|
+
"bold",
|
|
3495
|
+
"italic",
|
|
3496
|
+
"bolditalic"
|
|
3497
|
+
].includes(r)) throw new D("INVALID_OPTIONS", `Unsupported adapter font style: ${t}`);
|
|
3498
|
+
let i = n ?? (r.includes("bold") ? 700 : 400);
|
|
3499
|
+
return Q(i, "Font weight"), Object.freeze({
|
|
3500
|
+
fontName: e,
|
|
3501
|
+
fontStyle: r,
|
|
3502
|
+
fontWeight: i
|
|
3503
|
+
});
|
|
3504
|
+
}
|
|
3505
|
+
function $(e) {
|
|
3506
|
+
return {
|
|
3507
|
+
font: e.fontName,
|
|
3508
|
+
fontWeight: e.fontWeight,
|
|
3509
|
+
fontStyle: e.fontStyle.includes("italic") ? "italic" : "normal"
|
|
3510
|
+
};
|
|
3511
|
+
}
|
|
3512
|
+
function mn(e) {
|
|
3513
|
+
if (/^#[\da-f]{6}$/i.test(e)) return e.toLowerCase();
|
|
3514
|
+
let t = e.trim().split(/\s+/), n = t.pop()?.toLowerCase(), r = t.map(Number), i;
|
|
3515
|
+
if (n === "g" && r.length === 1) i = [
|
|
3516
|
+
r[0],
|
|
3517
|
+
r[0],
|
|
3518
|
+
r[0]
|
|
3519
|
+
];
|
|
3520
|
+
else if (n === "rg" && r.length === 3) i = r;
|
|
3521
|
+
else if (n === "k" && r.length === 4) i = r.slice(0, 3).map((e) => (1 - e) * (1 - r[3]));
|
|
3522
|
+
else throw new D("INVALID_OPTIONS", "Unsupported adapter color token.");
|
|
3523
|
+
if (i.some((e) => !Number.isFinite(e) || e < 0 || e > 1)) throw new D("INVALID_OPTIONS", "Color channels must be between zero and one.");
|
|
3524
|
+
return `#${i.map((e) => Math.floor(e * 255 + 1e-8).toString(16).padStart(2, "0")).join("")}`;
|
|
3525
|
+
}
|
|
3526
|
+
function hn(e) {
|
|
3527
|
+
let t = typeof e == "string" ? { ch1: e } : e;
|
|
3528
|
+
if (!t || typeof t.ch1 != "number" && typeof t.ch1 != "string") throw new D("INVALID_OPTIONS", "A color needs at least one channel.");
|
|
3529
|
+
let n = {
|
|
3530
|
+
black: "#000000",
|
|
3531
|
+
white: "#ffffff",
|
|
3532
|
+
red: "#ff0000",
|
|
3533
|
+
green: "#008000",
|
|
3534
|
+
blue: "#0000ff",
|
|
3535
|
+
yellow: "#ffff00",
|
|
3536
|
+
gray: "#808080",
|
|
3537
|
+
grey: "#808080",
|
|
3538
|
+
silver: "#c0c0c0",
|
|
3539
|
+
maroon: "#800000",
|
|
3540
|
+
purple: "#800080",
|
|
3541
|
+
fuchsia: "#ff00ff",
|
|
3542
|
+
lime: "#00ff00",
|
|
3543
|
+
olive: "#808000",
|
|
3544
|
+
navy: "#000080",
|
|
3545
|
+
teal: "#008080",
|
|
3546
|
+
aqua: "#00ffff",
|
|
3547
|
+
orange: "#ffa500",
|
|
3548
|
+
transparent: "#ffffff"
|
|
3549
|
+
}, { ch1: r, ch2: i, ch3: a } = t, { ch4: o } = t;
|
|
3550
|
+
if (typeof r == "string") {
|
|
3551
|
+
let e = n[r.toLowerCase()] ?? r, t = /^#([\da-f]{3}|[\da-f]{6})$/i.exec(e)?.[1];
|
|
3552
|
+
if (t) {
|
|
3553
|
+
if (i !== void 0 || a !== void 0 || o !== void 0) throw new D("INVALID_OPTIONS", "Hex colors cannot include numeric channels.");
|
|
3554
|
+
let e = t.length === 3 ? t.split("").map((e) => e + e).join("") : t;
|
|
3555
|
+
r = Number.parseInt(e.slice(0, 2), 16), i = Number.parseInt(e.slice(2, 4), 16), a = Number.parseInt(e.slice(4, 6), 16);
|
|
3556
|
+
} else if (!/^\d*\.?\d+$/.test(r)) throw new D("INVALID_OPTIONS", `Unsupported adapter color: ${r}`);
|
|
3557
|
+
}
|
|
3558
|
+
let s = [
|
|
3559
|
+
r,
|
|
3560
|
+
i,
|
|
3561
|
+
a,
|
|
3562
|
+
o
|
|
3563
|
+
].filter((e) => e !== void 0);
|
|
3564
|
+
if (![
|
|
3565
|
+
1,
|
|
3566
|
+
3,
|
|
3567
|
+
4
|
|
3568
|
+
].includes(s.length)) throw new D("INVALID_OPTIONS", "Provide one gray, three RGB or four CMYK channels.");
|
|
3569
|
+
let c = s.length === 4, l = s.map((e) => {
|
|
3570
|
+
let t = typeof e == "string" || c ? Number(e) : e / 255;
|
|
3571
|
+
if (!Number.isFinite(t) || t < 0 || t > 1) throw new D("INVALID_OPTIONS", "Color channel is outside the supported range.");
|
|
3572
|
+
return t;
|
|
3573
|
+
}), u = t.precision ?? 3;
|
|
3574
|
+
if (!Number.isInteger(u) || u < 0 || u > 6) throw new D("INVALID_OPTIONS", "Color precision must be an integer from zero to six.");
|
|
3575
|
+
let d = s.length === 1 ? "g" : c ? "k" : "rg";
|
|
3576
|
+
return `${l.map((e) => e.toFixed(u)).join(" ")} ${d}`;
|
|
3577
|
+
}
|
|
3578
|
+
var gn = class {
|
|
3579
|
+
document;
|
|
3580
|
+
internal;
|
|
3581
|
+
__private__ = Object.freeze({
|
|
3582
|
+
encodeColorString: hn,
|
|
3583
|
+
decodeColorString: mn
|
|
3584
|
+
});
|
|
3585
|
+
currentPage;
|
|
3586
|
+
state = {
|
|
3587
|
+
font: pn("Helvetica", "normal"),
|
|
3588
|
+
fontSize: 16,
|
|
3589
|
+
lineHeight: 1.15,
|
|
3590
|
+
lineWidth: .200025,
|
|
3591
|
+
textColor: "#000000",
|
|
3592
|
+
drawColor: "#000000",
|
|
3593
|
+
fillColor: "#000000"
|
|
3594
|
+
};
|
|
3595
|
+
commands = [];
|
|
3596
|
+
savedStates = /* @__PURE__ */ new Map();
|
|
3597
|
+
activePaths = /* @__PURE__ */ new Set();
|
|
3598
|
+
completion;
|
|
3599
|
+
constructor(e) {
|
|
3600
|
+
this.document = e, this.currentPage = e.addPage(), this.internal = Object.freeze({
|
|
3601
|
+
scaleFactor: e.unitScale,
|
|
3602
|
+
pageSize: Object.freeze({
|
|
3603
|
+
getWidth: () => this.currentPage.width,
|
|
3604
|
+
getHeight: () => this.currentPage.height
|
|
3605
|
+
}),
|
|
3606
|
+
getNumberOfPages: () => this.document.pageCount
|
|
3607
|
+
});
|
|
3608
|
+
}
|
|
3609
|
+
assertMutable() {
|
|
3610
|
+
if (this.completion) throw new D("INVALID_OPTIONS", "This adapter has already been finalized. Create a new document.");
|
|
3611
|
+
}
|
|
3612
|
+
enqueue(e) {
|
|
3613
|
+
return this.assertMutable(), this.commands.push(e), this;
|
|
3614
|
+
}
|
|
3615
|
+
getFont(e, t) {
|
|
3616
|
+
if (e == null && t == null) return this.state.font;
|
|
3617
|
+
let n = pn(e ?? this.state.font.fontName, t ?? this.state.font.fontStyle);
|
|
3618
|
+
return this.document.measureText(" ", $(n)), n;
|
|
3619
|
+
}
|
|
3620
|
+
setFont(e, t = "normal", n) {
|
|
3621
|
+
this.assertMutable();
|
|
3622
|
+
let r = pn(e, t, n);
|
|
3623
|
+
return this.document.measureText(" ", $(r)), this.state.font = r, this;
|
|
3624
|
+
}
|
|
3625
|
+
setFontSize(e) {
|
|
3626
|
+
return this.assertMutable(), this.state.fontSize = Q(e, "Font size"), this;
|
|
3627
|
+
}
|
|
3628
|
+
getFontSize() {
|
|
3629
|
+
return this.state.fontSize;
|
|
3630
|
+
}
|
|
3631
|
+
setLineHeightFactor(e) {
|
|
3632
|
+
return this.assertMutable(), this.state.lineHeight = Q(e, "Line height"), this;
|
|
3633
|
+
}
|
|
3634
|
+
getLineHeightFactor() {
|
|
3635
|
+
return this.state.lineHeight;
|
|
3636
|
+
}
|
|
3637
|
+
setLineWidth(e) {
|
|
3638
|
+
return this.assertMutable(), this.state.lineWidth = Q(e, "Line width", !0), this;
|
|
3639
|
+
}
|
|
3640
|
+
getLineWidth() {
|
|
3641
|
+
return this.state.lineWidth;
|
|
3642
|
+
}
|
|
3643
|
+
color(e, t, n, r, i = 3) {
|
|
3644
|
+
return mn(hn({
|
|
3645
|
+
ch1: e,
|
|
3646
|
+
...t === void 0 ? {} : { ch2: t },
|
|
3647
|
+
...n === void 0 ? {} : { ch3: n },
|
|
3648
|
+
...r === void 0 ? {} : { ch4: r },
|
|
3649
|
+
precision: i
|
|
3650
|
+
}));
|
|
3651
|
+
}
|
|
3652
|
+
setTextColor(e, t, n, r) {
|
|
3653
|
+
return this.assertMutable(), this.state.textColor = this.color(e, t, n, r), this;
|
|
3654
|
+
}
|
|
3655
|
+
getTextColor() {
|
|
3656
|
+
return this.state.textColor;
|
|
3657
|
+
}
|
|
3658
|
+
setDrawColor(e, t, n, r) {
|
|
3659
|
+
return this.assertMutable(), this.state.drawColor = this.color(e, t, n, r, 2), this;
|
|
3660
|
+
}
|
|
3661
|
+
getDrawColor() {
|
|
3662
|
+
return this.state.drawColor;
|
|
3663
|
+
}
|
|
3664
|
+
setFillColor(e, t, n, r) {
|
|
3665
|
+
return this.assertMutable(), this.state.fillColor = this.color(e, t, n, r, 2), this;
|
|
3666
|
+
}
|
|
3667
|
+
getFillColor() {
|
|
3668
|
+
return this.state.fillColor;
|
|
3669
|
+
}
|
|
3670
|
+
getTextDimensions(e, t = {}) {
|
|
3671
|
+
let n = t.font ?? this.getFont(t.fontName, t.fontStyle), r = Q(t.fontSize ?? this.state.fontSize, "Font size"), i = t.maxWidth && t.maxWidth > 0 ? this.splitTextToSize(e, t.maxWidth, t) : dn(e), a = i.map((e) => this.document.measureText(e, {
|
|
3672
|
+
...$(n),
|
|
3673
|
+
fontSize: r
|
|
3674
|
+
}).width).reduce((e, t) => Math.max(e, t), 0);
|
|
3675
|
+
return {
|
|
3676
|
+
w: a,
|
|
3677
|
+
h: a === 0 ? 0 : r * (1 + (i.length - 1) * this.state.lineHeight) / this.internal.scaleFactor
|
|
3678
|
+
};
|
|
3679
|
+
}
|
|
3680
|
+
getTextWidth(e) {
|
|
3681
|
+
return this.getTextDimensions(e).w;
|
|
2386
3682
|
}
|
|
3683
|
+
splitTextToSize(e, t, n = {}) {
|
|
3684
|
+
Q(t, "Text width");
|
|
3685
|
+
let r = n.font ?? this.getFont(n.fontName, n.fontStyle), i = Q(n.fontSize ?? this.state.fontSize, "Font size"), a = (e) => this.document.measureText(e, {
|
|
3686
|
+
...$(r),
|
|
3687
|
+
fontSize: i
|
|
3688
|
+
}).width, o = [];
|
|
3689
|
+
for (let n of dn(e)) {
|
|
3690
|
+
let e = "";
|
|
3691
|
+
for (let r of n.split(/\s+/).filter(Boolean)) {
|
|
3692
|
+
let n = e ? `${e} ${r}` : r;
|
|
3693
|
+
if (a(n) <= t) e = n;
|
|
3694
|
+
else {
|
|
3695
|
+
e &&= (o.push(e), "");
|
|
3696
|
+
for (let n of r) e && a(e + n) > t && (o.push(e), e = ""), e += n;
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
o.push(e);
|
|
3700
|
+
}
|
|
3701
|
+
return o;
|
|
3702
|
+
}
|
|
3703
|
+
text(e, t, n, r = {}) {
|
|
3704
|
+
if (r.isInputRtl || r.isOutputRtl || r.isInputVisual || r.isOutputVisual) throw new D("INVALID_OPTIONS", "Bidirectional jsPDF text options are unsupported by this adapter.");
|
|
3705
|
+
if (r.rotationDirection !== void 0 && r.rotationDirection !== 0 && r.rotationDirection !== 1) throw new D("INVALID_OPTIONS", "rotationDirection must be zero (clockwise) or one (counterclockwise).");
|
|
3706
|
+
let i = this.state.fontSize, a = Q(r.lineHeightFactor ?? this.state.lineHeight, "Line height"), o = i / this.internal.scaleFactor, s = o * (a - 1), c = r.baseline ?? "alphabetic", l = {
|
|
3707
|
+
alphabetic: 0,
|
|
3708
|
+
ideographic: 0,
|
|
3709
|
+
bottom: -s,
|
|
3710
|
+
top: o - s,
|
|
3711
|
+
middle: o / 2 - s,
|
|
3712
|
+
hanging: o - 2 * s
|
|
3713
|
+
};
|
|
3714
|
+
if (!(c in l)) throw new D("INVALID_OPTIONS", "Unsupported text baseline.");
|
|
3715
|
+
let u = r.maxWidth && r.maxWidth > 0 ? this.splitTextToSize(e, r.maxWidth).join("\n") : dn(e).join("\n"), d = this.currentPage, f = {
|
|
3716
|
+
x: t,
|
|
3717
|
+
y: n + l[c],
|
|
3718
|
+
...$(this.state.font),
|
|
3719
|
+
fontSize: i,
|
|
3720
|
+
color: this.state.textColor,
|
|
3721
|
+
align: r.align ?? "left",
|
|
3722
|
+
lineHeight: a,
|
|
3723
|
+
...r.angle === void 0 ? {} : { rotation: r.angle * (r.rotationDirection === 0 ? 1 : -1) }
|
|
3724
|
+
};
|
|
3725
|
+
return this.enqueue(() => d.drawText(u, f));
|
|
3726
|
+
}
|
|
3727
|
+
line(e, t, n, r) {
|
|
3728
|
+
let i = this.currentPage, a = {
|
|
3729
|
+
x1: e,
|
|
3730
|
+
y1: t,
|
|
3731
|
+
x2: n,
|
|
3732
|
+
y2: r,
|
|
3733
|
+
color: this.state.drawColor,
|
|
3734
|
+
width: this.state.lineWidth
|
|
3735
|
+
};
|
|
3736
|
+
return this.enqueue(() => i.drawLine(a));
|
|
3737
|
+
}
|
|
3738
|
+
rect(e, t, n, r, i = "S") {
|
|
3739
|
+
let a = i.toUpperCase();
|
|
3740
|
+
if (![
|
|
3741
|
+
"S",
|
|
3742
|
+
"D",
|
|
3743
|
+
"F",
|
|
3744
|
+
"FD",
|
|
3745
|
+
"DF",
|
|
3746
|
+
"B"
|
|
3747
|
+
].includes(a)) throw new D("INVALID_OPTIONS", "Unsupported rectangle style.");
|
|
3748
|
+
let o = [
|
|
3749
|
+
"F",
|
|
3750
|
+
"FD",
|
|
3751
|
+
"DF",
|
|
3752
|
+
"B"
|
|
3753
|
+
].includes(a), s = a !== "F", c = this.currentPage, l = {
|
|
3754
|
+
x: e,
|
|
3755
|
+
y: t,
|
|
3756
|
+
width: n,
|
|
3757
|
+
height: r,
|
|
3758
|
+
...o ? { fill: this.state.fillColor } : {},
|
|
3759
|
+
...s ? {
|
|
3760
|
+
stroke: this.state.drawColor,
|
|
3761
|
+
strokeWidth: this.state.lineWidth
|
|
3762
|
+
} : {}
|
|
3763
|
+
};
|
|
3764
|
+
return this.enqueue(() => c.drawRectangle(l));
|
|
3765
|
+
}
|
|
3766
|
+
saveGraphicsState() {
|
|
3767
|
+
this.assertMutable();
|
|
3768
|
+
let e = this.currentPage, t = this.savedStates.get(e) ?? [];
|
|
3769
|
+
return t.push({ ...this.state }), this.savedStates.set(e, t), this.enqueue(() => e.saveGraphicsState());
|
|
3770
|
+
}
|
|
3771
|
+
restoreGraphicsState() {
|
|
3772
|
+
this.assertMutable();
|
|
3773
|
+
let e = this.currentPage, t = this.savedStates.get(e)?.pop();
|
|
3774
|
+
if (!t) throw new D("INVALID_OPTIONS", "There is no saved graphics state on this page.");
|
|
3775
|
+
return this.state = t, this.enqueue(() => e.restoreGraphicsState());
|
|
3776
|
+
}
|
|
3777
|
+
moveTo(e, t) {
|
|
3778
|
+
this.assertMutable();
|
|
3779
|
+
let n = this.currentPage;
|
|
3780
|
+
return this.activePaths.add(n), this.enqueue(() => n.moveTo(e, t));
|
|
3781
|
+
}
|
|
3782
|
+
lineTo(e, t) {
|
|
3783
|
+
let n = this.currentPage;
|
|
3784
|
+
return this.enqueue(() => n.lineTo(e, t));
|
|
3785
|
+
}
|
|
3786
|
+
close() {
|
|
3787
|
+
if (!this.activePaths.has(this.currentPage)) return this;
|
|
3788
|
+
let e = this.currentPage;
|
|
3789
|
+
return this.enqueue(() => e.closePath());
|
|
3790
|
+
}
|
|
3791
|
+
clip() {
|
|
3792
|
+
let e = this.currentPage;
|
|
3793
|
+
return this.enqueue(() => e.clip());
|
|
3794
|
+
}
|
|
3795
|
+
discardPath() {
|
|
3796
|
+
this.assertMutable();
|
|
3797
|
+
let e = this.currentPage;
|
|
3798
|
+
return this.activePaths.delete(e), this.enqueue(() => e.discardPath());
|
|
3799
|
+
}
|
|
3800
|
+
addPage(e, t) {
|
|
3801
|
+
if (this.assertMutable(), t !== void 0 && ![
|
|
3802
|
+
"p",
|
|
3803
|
+
"l",
|
|
3804
|
+
"portrait",
|
|
3805
|
+
"landscape"
|
|
3806
|
+
].includes(t)) throw new D("INVALID_OPTIONS", "Page orientation must be portrait or landscape.");
|
|
3807
|
+
let n = t === "l" || t === "landscape" ? "landscape" : t === "p" || t === "portrait" ? "portrait" : void 0, r, i = Array.isArray(e) ? e : void 0;
|
|
3808
|
+
if (e === void 0 || i !== void 0) {
|
|
3809
|
+
let e = i?.[0] ?? this.currentPage.width, t = i?.[1] ?? this.currentPage.height;
|
|
3810
|
+
(n === "landscape" && e < t || n === "portrait" && e > t) && ([e, t] = [t, e]), r = {
|
|
3811
|
+
format: {
|
|
3812
|
+
width: e,
|
|
3813
|
+
height: t
|
|
3814
|
+
},
|
|
3815
|
+
orientation: "portrait"
|
|
3816
|
+
};
|
|
3817
|
+
} else r = {
|
|
3818
|
+
format: e,
|
|
3819
|
+
...n ? { orientation: n } : {}
|
|
3820
|
+
};
|
|
3821
|
+
return this.currentPage = this.document.addPage(r), this;
|
|
3822
|
+
}
|
|
3823
|
+
setPage(e) {
|
|
3824
|
+
return this.assertMutable(), this.currentPage = this.document.getPage(e), this;
|
|
3825
|
+
}
|
|
3826
|
+
getNumberOfPages() {
|
|
3827
|
+
return this.document.pageCount;
|
|
3828
|
+
}
|
|
3829
|
+
addImage(e, t, n, r, i, a) {
|
|
3830
|
+
if (this.assertMutable(), ![
|
|
3831
|
+
"PNG",
|
|
3832
|
+
"JPEG",
|
|
3833
|
+
"JPG"
|
|
3834
|
+
].includes(t.toUpperCase())) throw new D("UNSUPPORTED_IMAGE", "The adapter accepts PNG/JPEG image placement.");
|
|
3835
|
+
let o = fn(e), s = this.currentPage;
|
|
3836
|
+
return this.enqueue(async () => {
|
|
3837
|
+
await s.drawImage(o, {
|
|
3838
|
+
x: n,
|
|
3839
|
+
y: r,
|
|
3840
|
+
width: i,
|
|
3841
|
+
height: a
|
|
3842
|
+
});
|
|
3843
|
+
});
|
|
3844
|
+
}
|
|
3845
|
+
toResult() {
|
|
3846
|
+
return this.completion ??= (async () => {
|
|
3847
|
+
try {
|
|
3848
|
+
for (let e of this.commands) await e();
|
|
3849
|
+
return this.document.toResult();
|
|
3850
|
+
} finally {
|
|
3851
|
+
this.commands.length = 0;
|
|
3852
|
+
}
|
|
3853
|
+
})(), this.completion;
|
|
3854
|
+
}
|
|
3855
|
+
async toBlob() {
|
|
3856
|
+
return (await this.toResult()).toBlob();
|
|
3857
|
+
}
|
|
3858
|
+
async toUint8Array() {
|
|
3859
|
+
return (await this.toResult()).toUint8Array();
|
|
3860
|
+
}
|
|
3861
|
+
async save(e = "document.pdf") {
|
|
3862
|
+
await (await this.toResult()).download(e);
|
|
3863
|
+
}
|
|
3864
|
+
async download(e = "document.pdf") {
|
|
3865
|
+
await this.save(e);
|
|
3866
|
+
}
|
|
3867
|
+
async output(e) {
|
|
3868
|
+
if (![
|
|
3869
|
+
"blob",
|
|
3870
|
+
"arraybuffer",
|
|
3871
|
+
"uint8array"
|
|
3872
|
+
].includes(e)) throw new D("INVALID_OPTIONS", "Supported adapter output types are blob, arraybuffer and uint8array.");
|
|
3873
|
+
if (e === "blob") return this.toBlob();
|
|
3874
|
+
let t = await this.toUint8Array();
|
|
3875
|
+
if (e === "uint8array") return t;
|
|
3876
|
+
if (e === "arraybuffer") return t.buffer;
|
|
3877
|
+
throw new D("INVALID_OPTIONS", "Supported adapter output types are blob, arraybuffer and uint8array.");
|
|
3878
|
+
}
|
|
3879
|
+
};
|
|
3880
|
+
async function _n(e = {}) {
|
|
3881
|
+
if (!e || typeof e != "object" || Array.isArray(e)) throw new D("INVALID_OPTIONS", "Adapter options must be an object.");
|
|
3882
|
+
return new gn(await un({
|
|
3883
|
+
...e,
|
|
3884
|
+
unit: e.unit ?? "mm"
|
|
3885
|
+
}));
|
|
2387
3886
|
}
|
|
2388
|
-
export {
|
|
3887
|
+
export { gn as JsPDFAdapter, ln as PDFBuilder, an as PDFPageBuilder, D as RenderPDFError, un as createDocument, _n as createJsPDFAdapter, $t as extractPDFPages, zt as imageToPDF, Qt as mergePDFs, De as registerFont, vt as renderPDF, en as splitPDF };
|