@reportwright/viewer 0.11.0 → 0.12.1
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/CHANGELOG.md +81 -0
- package/README.md +27 -5
- package/dist/{chunk-KJTRZJHN.js → chunk-2BPBQMH2.js} +4 -3
- package/dist/chunk-2BPBQMH2.js.map +6 -0
- package/dist/{chunk-ODREGGKA.js → chunk-3D2KFKG2.js} +5 -4
- package/dist/chunk-3D2KFKG2.js.map +6 -0
- package/dist/chunk-6TPZ7G74.js +494 -0
- package/dist/chunk-6TPZ7G74.js.map +6 -0
- package/dist/chunk-BRB34AJ2.js +16 -0
- package/dist/{chunk-APRPSQOD.js → chunk-DPVJEFKP.js} +28 -9
- package/dist/chunk-DPVJEFKP.js.map +6 -0
- package/dist/{chunk-RYHJUQSV.js → chunk-DXHLIJEY.js} +2 -2
- package/dist/{chunk-SR2TQ2ZK.js → chunk-F6RMRXIN.js} +2 -2
- package/dist/chunk-F6RMRXIN.js.map +6 -0
- package/dist/{chunk-3D43XGIN.js → chunk-M6AYND5G.js} +8 -638
- package/dist/chunk-M6AYND5G.js.map +6 -0
- package/dist/{chunk-HAMBWF6C.js → chunk-NR2G4TMG.js} +39 -31
- package/dist/chunk-NR2G4TMG.js.map +6 -0
- package/dist/{chunk-66QZ3RDV.js → chunk-PGP3QA6L.js} +526 -508
- package/dist/chunk-PGP3QA6L.js.map +6 -0
- package/dist/{chunk-N5WHQ4DM.js → chunk-Q6MMPKQA.js} +14 -9
- package/dist/chunk-Q6MMPKQA.js.map +6 -0
- package/dist/{chunk-SBD55ZES.js → chunk-S2IUUI6N.js} +76 -32
- package/dist/chunk-S2IUUI6N.js.map +6 -0
- package/dist/chunk-ULKEEARQ.js +553 -0
- package/dist/chunk-ULKEEARQ.js.map +6 -0
- package/dist/{chunk-WQOBRZAL.js → chunk-VNOWPSE6.js} +579 -1484
- package/dist/chunk-VNOWPSE6.js.map +6 -0
- package/dist/chunk-Z7MKH66Z.js +642 -0
- package/dist/chunk-Z7MKH66Z.js.map +6 -0
- package/dist/designer.d.ts +10 -3
- package/dist/designer.js +28 -18
- package/dist/designer.js.map +1 -1
- package/dist/engine.worker.js +71 -0
- package/dist/engine.worker.js.map +6 -0
- package/dist/peer/chunk-2FZTYEDE.js +15 -0
- package/dist/peer/{chunk-776OR56A.js → chunk-6I2EAAVN.js} +39 -31
- package/dist/peer/chunk-6I2EAAVN.js.map +6 -0
- package/dist/peer/{chunk-IPU2YRL2.js → chunk-BMAXIBP2.js} +28 -9
- package/dist/peer/chunk-BMAXIBP2.js.map +6 -0
- package/dist/peer/chunk-BQFI3DHK.js +494 -0
- package/dist/peer/chunk-BQFI3DHK.js.map +6 -0
- package/dist/peer/{chunk-76ZABVTI.js → chunk-R4VX5UC7.js} +4 -3
- package/dist/peer/{chunk-5X4ZSSJT.js → chunk-TSC4RAH3.js} +526 -508
- package/dist/peer/chunk-TSC4RAH3.js.map +6 -0
- package/dist/peer/{chunk-M4AGFUWE.js → chunk-V42KN7HD.js} +2 -2
- package/dist/peer/{chunk-Y5CAHLXS.js → chunk-WQGENQZO.js} +5 -4
- package/dist/peer/{chunk-EKWTFHVE.js → chunk-WSNRD2AQ.js} +14 -9
- package/dist/peer/chunk-WSNRD2AQ.js.map +6 -0
- package/dist/peer/designer.js +28 -18
- package/dist/peer/designer.js.map +1 -1
- package/dist/peer/engine.worker.js +70 -0
- package/dist/peer/engine.worker.js.map +6 -0
- package/dist/peer/viewer.js +12 -5
- package/dist/peer/viewer.js.map +1 -1
- package/dist/viewer.d.ts +9 -1
- package/dist/viewer.js +12 -5
- package/dist/viewer.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-3D43XGIN.js.map +0 -6
- package/dist/chunk-66QZ3RDV.js.map +0 -6
- package/dist/chunk-AH47FS6Y.js +0 -13
- package/dist/chunk-APRPSQOD.js.map +0 -6
- package/dist/chunk-HAMBWF6C.js.map +0 -6
- package/dist/chunk-N5WHQ4DM.js.map +0 -6
- package/dist/chunk-SBD55ZES.js.map +0 -6
- package/dist/chunk-SR2TQ2ZK.js.map +0 -6
- package/dist/chunk-WQOBRZAL.js.map +0 -6
- package/dist/peer/chunk-5X4ZSSJT.js.map +0 -6
- package/dist/peer/chunk-6YO42ALN.js +0 -14777
- package/dist/peer/chunk-6YO42ALN.js.map +0 -6
- package/dist/peer/chunk-76ZABVTI.js.map +0 -6
- package/dist/peer/chunk-776OR56A.js.map +0 -6
- package/dist/peer/chunk-EKWTFHVE.js.map +0 -6
- package/dist/peer/chunk-IMQRHDR4.js +0 -12
- package/dist/peer/chunk-IPU2YRL2.js.map +0 -6
- package/dist/peer/chunk-Y5CAHLXS.js.map +0 -6
- /package/dist/{chunk-AH47FS6Y.js.map → chunk-BRB34AJ2.js.map} +0 -0
- /package/dist/{chunk-RYHJUQSV.js.map → chunk-DXHLIJEY.js.map} +0 -0
- /package/dist/peer/{chunk-IMQRHDR4.js.map → chunk-2FZTYEDE.js.map} +0 -0
- /package/dist/{chunk-KJTRZJHN.js.map → peer/chunk-R4VX5UC7.js.map} +0 -0
- /package/dist/peer/{chunk-M4AGFUWE.js.map → chunk-V42KN7HD.js.map} +0 -0
- /package/dist/{chunk-ODREGGKA.js.map → peer/chunk-WQGENQZO.js.map} +0 -0
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FORMAT_CHAR
|
|
3
|
+
} from "../chunk-ULKEEARQ.js";
|
|
1
4
|
import {
|
|
2
5
|
asciiUrl,
|
|
3
6
|
drillUrl,
|
|
@@ -9,24 +12,26 @@ import {
|
|
|
9
12
|
import {
|
|
10
13
|
needsTableData,
|
|
11
14
|
visualLines
|
|
12
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-F6RMRXIN.js";
|
|
13
16
|
import {
|
|
14
|
-
IMAGE_LIMITS,
|
|
15
17
|
altOf,
|
|
16
18
|
cellVisuals,
|
|
19
|
+
figures,
|
|
20
|
+
parseColor
|
|
21
|
+
} from "../chunk-M6AYND5G.js";
|
|
22
|
+
import {
|
|
23
|
+
IMAGE_LIMITS,
|
|
17
24
|
dataUriBytes,
|
|
18
25
|
dataUriBytesOf,
|
|
19
|
-
figures,
|
|
20
26
|
imageInfoOf,
|
|
21
|
-
parseColor,
|
|
22
27
|
svgLength,
|
|
23
28
|
svgRootAttrs,
|
|
24
29
|
xmlAttrs,
|
|
25
30
|
xmlTags
|
|
26
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-Z7MKH66Z.js";
|
|
27
32
|
|
|
28
33
|
// src/exporters/pdf.js
|
|
29
|
-
import { PDFDocument, PDFName as PDFName3, PDFString as PDFString4, PDFHexString as
|
|
34
|
+
import { PDFDocument, PDFName as PDFName3, PDFString as PDFString4, PDFHexString as PDFHexString5, PDFRawStream as PDFRawStream2, rgb as rgb3 } from "pdf-lib";
|
|
30
35
|
import fontkitModule from "@pdf-lib/fontkit";
|
|
31
36
|
|
|
32
37
|
// src/exporters/pdfa.js
|
|
@@ -743,11 +748,8 @@ function pngProblem(b) {
|
|
|
743
748
|
return null;
|
|
744
749
|
}
|
|
745
750
|
|
|
746
|
-
// src/exporters/
|
|
747
|
-
|
|
748
|
-
/** @type {any} */
|
|
749
|
-
fontkitModule.default || fontkitModule
|
|
750
|
-
);
|
|
751
|
+
// src/exporters/pdfpaint.js
|
|
752
|
+
import { PDFHexString as PDFHexString4, rgb as rgb2 } from "pdf-lib";
|
|
751
753
|
var colors = /* @__PURE__ */ new Map();
|
|
752
754
|
var col = (c) => {
|
|
753
755
|
if (colors.has(c)) return colors.get(c);
|
|
@@ -762,181 +764,503 @@ var n4 = (v) => Math.round(v * 1e4) / 1e4;
|
|
|
762
764
|
var hex4 = (id) => id.toString(16).padStart(4, "0");
|
|
763
765
|
var KAPPA = 4 * ((Math.SQRT2 - 1) / 3);
|
|
764
766
|
var cleanText = (t) => t.replace(/\t|\u0085|\u2028|\u2029/g, " ").replace(/[\b\v]/g, "");
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
const spans = /* @__PURE__ */ new WeakMap();
|
|
787
|
-
const chars = (key) => {
|
|
788
|
-
let c = used.get(key);
|
|
789
|
-
if (!c) {
|
|
790
|
-
c = /* @__PURE__ */ new Set([32]);
|
|
791
|
-
used.set(key, c);
|
|
792
|
-
}
|
|
793
|
-
return c;
|
|
767
|
+
var formatAt = (run, cl) => {
|
|
768
|
+
const cp = run.text.codePointAt(cl);
|
|
769
|
+
return cp !== void 0 && FORMAT_CHAR.test(String.fromCodePoint(cp));
|
|
770
|
+
};
|
|
771
|
+
function drawRun(c, run, x, y, size, pf, color, spans, texts) {
|
|
772
|
+
const f = pf.embedder.font;
|
|
773
|
+
const per = 1e3 / size;
|
|
774
|
+
const span = (text) => `/Span <</ActualText ${PDFHexString4.fromText(text).toString()}>> BDC
|
|
775
|
+
`;
|
|
776
|
+
c.et();
|
|
777
|
+
c.paint(color, null);
|
|
778
|
+
c.font(pf, size);
|
|
779
|
+
if (!run.rtl) c.s += span(run.text);
|
|
780
|
+
c.s += `BT ${n2(x)} ${n2(y)} Td
|
|
781
|
+
`;
|
|
782
|
+
let arr = "";
|
|
783
|
+
let pen = 0, rise = 0;
|
|
784
|
+
const flush = () => {
|
|
785
|
+
if (arr) c.s += `[${arr}] TJ
|
|
786
|
+
`;
|
|
787
|
+
arr = "";
|
|
794
788
|
};
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
for (
|
|
806
|
-
const c = chars(r.font);
|
|
807
|
-
for (const ch of r.text) c.add(
|
|
808
|
-
/** @type {number} */
|
|
809
|
-
ch.codePointAt(0)
|
|
810
|
-
);
|
|
811
|
-
let g = shaped.get(r.font);
|
|
812
|
-
if (!g) {
|
|
813
|
-
g = /* @__PURE__ */ new Map();
|
|
814
|
-
shaped.set(r.font, g);
|
|
815
|
-
}
|
|
816
|
-
glyphText(r, fontStore.get(r.font), g, spans);
|
|
817
|
-
}
|
|
789
|
+
const all = run.glyphs;
|
|
790
|
+
const adv = (id) => f.getGlyph(id).advanceWidth;
|
|
791
|
+
let g = all, quietAt = -1;
|
|
792
|
+
if (run.rtl) {
|
|
793
|
+
const hasBase = /* @__PURE__ */ new Set();
|
|
794
|
+
for (let i = 0; i < all.length; i += 4) if (adv(all[i]) > 0) hasBase.add(all[i + 3]);
|
|
795
|
+
const quiet = (i) => spans?.has(all[i + 3]) ? adv(all[i]) === 0 && hasBase.has(all[i + 3]) : texts?.get(all[i]) === "";
|
|
796
|
+
g = [];
|
|
797
|
+
for (const late of [false, true]) {
|
|
798
|
+
if (late) quietAt = g.length;
|
|
799
|
+
for (let i = 0; i < all.length; i += 4) if (quiet(i) === late) g.push(all[i], all[i + 1], all[i + 2], all[i + 3]);
|
|
818
800
|
}
|
|
801
|
+
if (quietAt === g.length) quietAt = -1;
|
|
819
802
|
}
|
|
820
|
-
const
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
if (
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
const sub = withPadding(await opt.subset(bytes, cps, glyphs ? { glyphs: glyphs.keys() } : void 0));
|
|
833
|
-
const f = fontkit.create(sub);
|
|
834
|
-
for (const cp of cps) void f.glyphForCodePoint(cp).advanceWidth;
|
|
835
|
-
for (const id of glyphs?.keys() || []) void f.getGlyph(id).advanceWidth;
|
|
836
|
-
bytes = sub;
|
|
837
|
-
} catch {
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
const pf = await doc.embedFont(bytes, { subset: false, customName: bytes === full ? void 0 : `${subsetTag(bytes)}+${fontStore.get(key).postscriptName || "Font"}` });
|
|
841
|
-
plainEncoding(pf);
|
|
842
|
-
if (glyphs) addGlyphs(pf, glyphs, !!opt.tagged);
|
|
843
|
-
const file = bytes, e = (
|
|
844
|
-
/** @type {any} */
|
|
845
|
-
pf.embedder
|
|
846
|
-
);
|
|
847
|
-
if (!e.isCFF()) e.embedFontStream = async (c) => c.register(PDFRawStream2.of(c.obj({ Filter: "FlateDecode", Length1: file.length }), await deflate(file)));
|
|
848
|
-
fonts.set(key, pf);
|
|
803
|
+
const starts = run.rtl ? [...new Set(all.filter((_, i) => i % 4 === 3))].sort((a, b) => a - b) : [];
|
|
804
|
+
let inSpan = false;
|
|
805
|
+
for (let i = 0; i < g.length; i += 4) {
|
|
806
|
+
const id = g[i], gx = g[i + 1], gy = g[i + 2], cl = g[i + 3];
|
|
807
|
+
if (i === quietAt) {
|
|
808
|
+
flush();
|
|
809
|
+
c.s += span("");
|
|
810
|
+
inSpan = true;
|
|
811
|
+
} else if (run.rtl && spans?.has(cl) && (quietAt < 0 || i < quietAt) && (i === 0 || g[i - 1] !== cl)) {
|
|
812
|
+
flush();
|
|
813
|
+
c.s += span(run.text.slice(cl, starts[starts.indexOf(cl) + 1] ?? run.text.length));
|
|
814
|
+
inSpan = true;
|
|
849
815
|
}
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
const out = await loadImage(src).catch((e) => ({ img: null, why: `it could not be embedded (${e?.message || e})` }));
|
|
856
|
-
images.set(src, out);
|
|
857
|
-
return out;
|
|
858
|
-
};
|
|
859
|
-
async function loadImage(src) {
|
|
860
|
-
const local = /^data:/i.test(src);
|
|
861
|
-
if (local && dataUriBytes(src) > IMAGE_LIMITS.bytes) return { img: null, why: "it is larger than the image size limit" };
|
|
862
|
-
if (!local && !opt.fetchImage) return { img: null, why: "it is a URL, and no fetchImage was given to load it" };
|
|
863
|
-
const bytes = local ? dataUriBytesOf(src) : await opt.fetchImage(src);
|
|
864
|
-
if (!bytes?.length) return { img: null, why: "it could not be loaded" };
|
|
865
|
-
if (bytes.length > IMAGE_LIMITS.bytes) return { img: null, why: "it is larger than the image size limit" };
|
|
866
|
-
const info = imageInfoOf(bytes);
|
|
867
|
-
if (info?.type === "svg") {
|
|
868
|
-
const svg = parseSvg(new TextDecoder().decode(bytes));
|
|
869
|
-
return svg ? { img: { svg, width: svg.w, height: svg.h } } : { img: null, why: "the SVG could not be read" };
|
|
816
|
+
if (gy !== rise) {
|
|
817
|
+
flush();
|
|
818
|
+
c.s += `${n4(gy)} Ts
|
|
819
|
+
`;
|
|
820
|
+
rise = gy;
|
|
870
821
|
}
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
822
|
+
const adj = Math.round((pen - gx) * per * 1e3) / 1e3;
|
|
823
|
+
if (id === 0 && (c.tagged || formatAt(run, cl))) pen = gx;
|
|
824
|
+
else {
|
|
825
|
+
arr += (adj ? `${adj}` : "") + `<${hex4(id)}>`;
|
|
826
|
+
pen = gx + adv(id) * size / f.unitsPerEm;
|
|
827
|
+
}
|
|
828
|
+
if (inSpan && (i + 4 >= g.length || (quietAt < 0 || i + 4 < quietAt) && g[i + 7] !== cl || i + 4 === quietAt)) {
|
|
829
|
+
flush();
|
|
830
|
+
c.s += "EMC\n";
|
|
831
|
+
inSpan = false;
|
|
875
832
|
}
|
|
876
|
-
if (info?.type === "jpeg") return { img: await doc.embedJpg(bytes) };
|
|
877
|
-
return { img: null, why: info ? `${info.type.toUpperCase()} is not embedded (PNG, JPEG and SVG are)` : "it is not a PNG, JPEG or SVG" };
|
|
878
833
|
}
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
834
|
+
flush();
|
|
835
|
+
if (rise) c.s += "0 Ts\n";
|
|
836
|
+
c.s += "ET\n";
|
|
837
|
+
if (!run.rtl) c.s += "EMC\n";
|
|
838
|
+
}
|
|
839
|
+
function glyphText(run, font, out, spans) {
|
|
840
|
+
const g = run.glyphs;
|
|
841
|
+
const starts = [...new Set(g.filter((_, i) => i % 4 === 3))].sort((a, b) => a - b);
|
|
842
|
+
for (let k = 0; k < starts.length; k++) {
|
|
843
|
+
const chars = [...run.text.slice(starts[k], starts[k + 1] ?? run.text.length)];
|
|
844
|
+
const ids = [];
|
|
845
|
+
for (let i = 0; i < g.length; i += 4) if (g[i + 3] === starts[k]) ids.push(g[i]);
|
|
846
|
+
const own = new Map(chars.map((ch) => [font.glyphForCodePoint(ch.codePointAt(0)).id, ch]));
|
|
847
|
+
const rest = chars.filter((ch) => !ids.includes(font.glyphForCodePoint(ch.codePointAt(0)).id)).join("");
|
|
848
|
+
const carrier = rest ? ids.find((id) => !own.has(id) && font.getGlyph(id).advanceWidth > 0) ?? ids.find((id) => !own.has(id)) : void 0;
|
|
849
|
+
let ok = !rest || carrier !== void 0;
|
|
850
|
+
const want = /* @__PURE__ */ new Map();
|
|
851
|
+
for (const id of ids) {
|
|
852
|
+
const t = own.get(id) ?? (id === carrier ? rest : "");
|
|
853
|
+
if (want.has(id) && want.get(id) !== t) ok = false;
|
|
854
|
+
want.set(id, t);
|
|
889
855
|
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
font: (pf) => nameOf("Font", pf, () => pf.ref),
|
|
894
|
-
gs: (ca, CA) => nameOf("ExtGState", `gs ${ca} ${CA}`, () => ctx.obj({ Type: "ExtGState", ca, CA })),
|
|
895
|
-
image: (img) => nameOf("XObject", img, () => img.ref)
|
|
896
|
-
};
|
|
897
|
-
const links = [];
|
|
898
|
-
const taken = /* @__PURE__ */ new Set();
|
|
899
|
-
const uniqueName = (n) => {
|
|
900
|
-
let name = n, i = 1;
|
|
901
|
-
while (taken.has(name)) name = `${n}_${++i}`;
|
|
902
|
-
taken.add(name);
|
|
903
|
-
return name;
|
|
904
|
-
};
|
|
905
|
-
const contents = [];
|
|
906
|
-
if (opt.tagged) needsTableData(model, "An accessible PDF");
|
|
907
|
-
const tags = opt.tagged ? createTagger(model, doc) : null;
|
|
908
|
-
let pi = -1;
|
|
909
|
-
const vm = /* @__PURE__ */ new Map();
|
|
910
|
-
const vmetrics = (key) => {
|
|
911
|
-
let m = vm.get(key);
|
|
912
|
-
if (!m) {
|
|
913
|
-
const f = fontStore.get(key), u = f?.unitsPerEm || 1e3;
|
|
914
|
-
vm.set(key, m = { asc: (f?.ascent ?? u) / u, desc: -(f?.descent ?? 0) / u });
|
|
856
|
+
for (const [id, t] of want) {
|
|
857
|
+
if (!out.has(id)) out.set(id, t);
|
|
858
|
+
else if (out.get(id) !== t) ok = false;
|
|
915
859
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
860
|
+
if (!ok && run.rtl && spans) {
|
|
861
|
+
let s = spans.get(run);
|
|
862
|
+
if (!s) spans.set(run, s = /* @__PURE__ */ new Set());
|
|
863
|
+
s.add(starts[k]);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
function insideClip(it, m) {
|
|
868
|
+
const k = it.clip, asc = m.asc * it.size, desc = m.desc * it.size;
|
|
869
|
+
return it.lines.every((l) => l.w != null && !l.runs && l.x >= k.x && l.x + l.w <= k.x + k.w && l.y - asc >= k.y && l.y + desc <= k.y + k.h);
|
|
870
|
+
}
|
|
871
|
+
var Content = class {
|
|
872
|
+
constructor(shared) {
|
|
873
|
+
this.shared = shared;
|
|
874
|
+
this._s = "";
|
|
875
|
+
this.bt = false;
|
|
876
|
+
this.tx = 0;
|
|
877
|
+
this.ty = 0;
|
|
878
|
+
this.st = { fill: "0 0 0", stroke: "0 0 0", lw: 1, dash: "[] 0", ca: 1, CA: 1, font: "", size: 0 };
|
|
879
|
+
this.saved = [];
|
|
880
|
+
this.lines = null;
|
|
881
|
+
this.tagged = false;
|
|
882
|
+
this.artLines = false;
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* The operators so far. Any other drawing reads or appends to it, so the lines waiting are drawn first: the text
|
|
886
|
+
* of a table's cells stays in one text object (relative moves, which compress to little) instead of one per cell.
|
|
887
|
+
*/
|
|
888
|
+
get s() {
|
|
889
|
+
this.flushLines();
|
|
890
|
+
return this._s;
|
|
891
|
+
}
|
|
892
|
+
set s(v) {
|
|
893
|
+
this._s = v;
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* A straight line. Untagged, it waits until something other than text is drawn (table borders between cell
|
|
897
|
+
* texts); collinear segments that touch, in the same stroke, become one (a row's border is one line).
|
|
898
|
+
* ponytail: lines move after the text drawn just after them; both are thin and do not cover each other.
|
|
899
|
+
*/
|
|
900
|
+
line(stroke, w, dash, x1, y1, x2, y2) {
|
|
901
|
+
if (this.tagged && !this.artLines) {
|
|
902
|
+
this.paint(null, stroke, w, dash);
|
|
903
|
+
this._s += `${n2(x1)} ${n2(y1)} m ${n2(x2)} ${n2(y2)} l S
|
|
904
|
+
`;
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
const key = `${stroke.rgb}|${stroke.opacity}|${w}|${(dash || []).join(" ")}`;
|
|
908
|
+
if (this.lines && this.lines.key !== key) this.flushLines();
|
|
909
|
+
this.lines || (this.lines = { key, stroke, w, dash, segs: [] });
|
|
910
|
+
const segs = this.lines.segs, last = segs[segs.length - 1];
|
|
911
|
+
const eq = (a, b) => Math.abs(a - b) < 5e-3;
|
|
912
|
+
if (last && eq(last[1], y1) && eq(last[3], y2) && eq(y1, y2) && eq(last[2], x1)) last[2] = x2;
|
|
913
|
+
else if (last && eq(last[0], x1) && eq(last[2], x2) && eq(x1, x2) && eq(last[3], y1)) last[3] = y2;
|
|
914
|
+
else segs.push([x1, y1, x2, y2]);
|
|
915
|
+
}
|
|
916
|
+
flushLines() {
|
|
917
|
+
const L = this.lines;
|
|
918
|
+
if (!L) return;
|
|
919
|
+
this.lines = null;
|
|
920
|
+
this.et();
|
|
921
|
+
const end = this.artLines ? "EMC\n" : "";
|
|
922
|
+
if (end) this._s += "/Artifact BMC\n";
|
|
923
|
+
this.paint(null, L.stroke, L.w, L.dash);
|
|
924
|
+
const g = L.segs;
|
|
925
|
+
const dy = g.length > 2 ? Math.round((g[1][1] - g[0][1]) * 100) : 0;
|
|
926
|
+
if (dy && g.every((q, i) => q[1] === q[3] && n2(q[0]) === n2(g[0][0]) && n2(q[2]) === n2(g[0][2]) && Math.abs(q[1] - (g[0][1] + i * dy / 100)) < 0.01)) {
|
|
927
|
+
const one = `${n2(g[0][0])} ${n2(g[0][1])} m ${n2(g[0][2])} ${n2(g[0][1])} l S
|
|
928
|
+
`;
|
|
929
|
+
this._s += `q
|
|
930
|
+
${one}${`1 0 0 1 0 ${dy / 100} cm ${one}`.repeat(g.length - 1)}Q
|
|
931
|
+
${end}`;
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n" + end;
|
|
935
|
+
}
|
|
936
|
+
q() {
|
|
937
|
+
this.et();
|
|
938
|
+
this._s += "q\n";
|
|
939
|
+
this.saved.push({ ...this.st });
|
|
940
|
+
}
|
|
941
|
+
Q() {
|
|
942
|
+
this.et();
|
|
943
|
+
this._s += "Q\n";
|
|
944
|
+
this.st = this.saved.pop();
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* A line of plain text at (x, y). Lines follow one another in one text object, each placed relative to the
|
|
948
|
+
* last (in whole hundredths, so nothing drifts): most of a table page is these.
|
|
949
|
+
* @param {string} str the glyphs, as a literal string's escaped body (array: a TJ array's body)
|
|
950
|
+
*/
|
|
951
|
+
text(pf, size, color, x, y, str, array = false) {
|
|
952
|
+
this.setPaint(color, null);
|
|
953
|
+
this.setFont(pf, size);
|
|
954
|
+
const X = Math.round(x * 10) * 10, Y = Math.round(y * 10) * 10;
|
|
955
|
+
if (!this.bt) {
|
|
956
|
+
this._s += "BT\n";
|
|
957
|
+
this.bt = true;
|
|
958
|
+
this.tx = 0;
|
|
959
|
+
this.ty = 0;
|
|
960
|
+
}
|
|
961
|
+
this._s += array ? `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td [${str}] TJ
|
|
962
|
+
` : `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td (${str}) Tj
|
|
963
|
+
`;
|
|
964
|
+
this.tx = X;
|
|
965
|
+
this.ty = Y;
|
|
966
|
+
}
|
|
967
|
+
/** end the open text object, if any: anything but text needs that (and draws the lines waiting) */
|
|
968
|
+
et() {
|
|
969
|
+
if (this.bt) {
|
|
970
|
+
this._s += "ET\n";
|
|
971
|
+
this.bt = false;
|
|
972
|
+
}
|
|
973
|
+
if (this.lines) this.flushLines();
|
|
974
|
+
}
|
|
975
|
+
lineWidth(w) {
|
|
976
|
+
if (this.lines) this.flushLines();
|
|
977
|
+
this.setLineWidth(w);
|
|
978
|
+
}
|
|
979
|
+
setLineWidth(w) {
|
|
980
|
+
if (this.st.lw !== w) {
|
|
981
|
+
this._s += `${n3(w)} w
|
|
982
|
+
`;
|
|
983
|
+
this.st.lw = w;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
/** the graphics state that sets these opacities, or undefined when they are set already */
|
|
987
|
+
gsFor(ca, CA) {
|
|
988
|
+
return ca === this.st.ca && CA === this.st.CA ? void 0 : this.shared.gs(ca, CA);
|
|
989
|
+
}
|
|
990
|
+
alpha(ca, CA) {
|
|
991
|
+
if (this.lines) this.flushLines();
|
|
992
|
+
this.setAlpha(ca, CA);
|
|
993
|
+
}
|
|
994
|
+
setAlpha(ca, CA) {
|
|
995
|
+
const g = this.gsFor(ca, CA);
|
|
996
|
+
if (g) {
|
|
997
|
+
this._s += `/${g} gs
|
|
998
|
+
`;
|
|
999
|
+
this.st.ca = ca;
|
|
1000
|
+
this.st.CA = CA;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
/** set up to fill with fill and/or stroke with stroke (width w, dash); the lines waiting are drawn first */
|
|
1004
|
+
paint(fill, stroke, w = 1, dash = null) {
|
|
1005
|
+
if (this.lines) this.flushLines();
|
|
1006
|
+
this.setPaint(fill, stroke, w, dash);
|
|
1007
|
+
}
|
|
1008
|
+
setPaint(fill, stroke, w = 1, dash = null) {
|
|
1009
|
+
const st = this.st;
|
|
1010
|
+
if (fill && fill.rgb !== st.fill) {
|
|
1011
|
+
this._s += `${fill.rgb} rg
|
|
1012
|
+
`;
|
|
1013
|
+
st.fill = fill.rgb;
|
|
1014
|
+
}
|
|
1015
|
+
if (stroke) {
|
|
1016
|
+
if (stroke.rgb !== st.stroke) {
|
|
1017
|
+
this._s += `${stroke.rgb} RG
|
|
1018
|
+
`;
|
|
1019
|
+
st.stroke = stroke.rgb;
|
|
1020
|
+
}
|
|
1021
|
+
this.setLineWidth(w);
|
|
1022
|
+
const d = `[${(dash || []).map(n3).join(" ")}] 0`;
|
|
1023
|
+
if (d !== st.dash) {
|
|
1024
|
+
this._s += `${d} d
|
|
1025
|
+
`;
|
|
1026
|
+
st.dash = d;
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
this.setAlpha(fill ? fill.opacity : st.ca, stroke ? stroke.opacity : st.CA);
|
|
1030
|
+
}
|
|
1031
|
+
font(pf, size) {
|
|
1032
|
+
if (this.lines) this.flushLines();
|
|
1033
|
+
this.setFont(pf, size);
|
|
1034
|
+
}
|
|
1035
|
+
setFont(pf, size) {
|
|
1036
|
+
const name = this.shared.font(pf);
|
|
1037
|
+
if (name !== this.st.font || size !== this.st.size) {
|
|
1038
|
+
this._s += `/${name} ${n3(size)} Tf
|
|
1039
|
+
`;
|
|
1040
|
+
this.st.font = name;
|
|
1041
|
+
this.st.size = size;
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
function latin1(s) {
|
|
1046
|
+
const B = (
|
|
1047
|
+
/** @type {any} */
|
|
1048
|
+
globalThis.Buffer
|
|
1049
|
+
);
|
|
1050
|
+
if (B) return B.from(s, "latin1");
|
|
1051
|
+
const out = new Uint8Array(s.length);
|
|
1052
|
+
for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i);
|
|
1053
|
+
return out;
|
|
1054
|
+
}
|
|
1055
|
+
async function deflate(bytes) {
|
|
1056
|
+
if (zslots.free > 0) zslots.free--;
|
|
1057
|
+
else await new Promise((ok) => zslots.wait.push(
|
|
1058
|
+
/** @type {() => void} */
|
|
1059
|
+
ok
|
|
1060
|
+
));
|
|
1061
|
+
try {
|
|
1062
|
+
return await deflateNow(bytes);
|
|
1063
|
+
} finally {
|
|
1064
|
+
const next = zslots.wait.shift();
|
|
1065
|
+
if (next) next();
|
|
1066
|
+
else zslots.free++;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
var zslots = { free: 4, wait: (
|
|
1070
|
+
/** @type {(() => void)[]} */
|
|
1071
|
+
[]
|
|
1072
|
+
) };
|
|
1073
|
+
var NODE_ZLIB = (
|
|
1074
|
+
/** @type {any} */
|
|
1075
|
+
globalThis.process?.getBuiltinModule?.("node:zlib")
|
|
1076
|
+
);
|
|
1077
|
+
async function deflateNow(bytes) {
|
|
1078
|
+
const zlib = NODE_ZLIB;
|
|
1079
|
+
if (zlib) return new Promise((ok, fail) => zlib.deflate(bytes, { level: 9 }, (e, z) => e ? fail(e) : ok(z)));
|
|
1080
|
+
if (typeof CompressionStream === "undefined") return (await import("fflate")).zlibSync(bytes);
|
|
1081
|
+
return new Uint8Array(await new Response(new Blob([bytes]).stream().pipeThrough(new CompressionStream("deflate"))).arrayBuffer());
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
// src/exporters/pdf.js
|
|
1085
|
+
var fontkit = (
|
|
1086
|
+
/** @type {any} */
|
|
1087
|
+
fontkitModule.default || fontkitModule
|
|
1088
|
+
);
|
|
1089
|
+
function exportPdf(model, fontStore, opt = {}) {
|
|
1090
|
+
return withDeadline(
|
|
1091
|
+
pdfOf(model, fontStore, opt),
|
|
1092
|
+
/** @type {any} */
|
|
1093
|
+
opt.timeoutMs
|
|
1094
|
+
);
|
|
1095
|
+
}
|
|
1096
|
+
async function pdfOf(model, fontStore, opt) {
|
|
1097
|
+
const fixed = fixedDate(opt);
|
|
1098
|
+
const when = fixed ?? /* @__PURE__ */ new Date();
|
|
1099
|
+
const fileId = fixed ? await contentId(model, opt, when) : void 0;
|
|
1100
|
+
const doc = await PDFDocument.create({ updateMetadata: false });
|
|
1101
|
+
doc.registerFontkit(fontkit);
|
|
1102
|
+
doc.setTitle(opt.title || "Report");
|
|
1103
|
+
doc.setProducer("ReportWright");
|
|
1104
|
+
doc.setCreator("ReportWright");
|
|
1105
|
+
if (opt.author) doc.setAuthor(opt.author);
|
|
1106
|
+
setInfoDates(doc, when);
|
|
1107
|
+
if (fileId) doc.context.trailerInfo.ID = doc.context.obj([PDFHexString5.of(fileId), PDFHexString5.of(fileId)]);
|
|
1108
|
+
const used = /* @__PURE__ */ new Map();
|
|
1109
|
+
const shaped = /* @__PURE__ */ new Map();
|
|
1110
|
+
const spans = /* @__PURE__ */ new WeakMap();
|
|
1111
|
+
const chars = (key) => {
|
|
1112
|
+
let c = used.get(key);
|
|
1113
|
+
if (!c) {
|
|
1114
|
+
c = /* @__PURE__ */ new Set([32]);
|
|
1115
|
+
used.set(key, c);
|
|
1116
|
+
}
|
|
1117
|
+
return c;
|
|
1118
|
+
};
|
|
1119
|
+
for (const pg of model.pages) for (const it of pg.items.flatMap((i) => i.t === "field" ? i.draw.filter((d) => d.t === "text") : i.t === "text" ? [i] : [])) {
|
|
1120
|
+
for (const l of it.lines) {
|
|
1121
|
+
if (!l.runs) {
|
|
1122
|
+
const c = chars(it.font);
|
|
1123
|
+
for (const ch of l.text) c.add(
|
|
1124
|
+
/** @type {number} */
|
|
1125
|
+
ch.codePointAt(0)
|
|
1126
|
+
);
|
|
1127
|
+
continue;
|
|
1128
|
+
}
|
|
1129
|
+
for (const r of l.runs) {
|
|
1130
|
+
const c = chars(r.font);
|
|
1131
|
+
for (const ch of r.text) c.add(
|
|
1132
|
+
/** @type {number} */
|
|
1133
|
+
ch.codePointAt(0)
|
|
1134
|
+
);
|
|
1135
|
+
let g = shaped.get(r.font);
|
|
1136
|
+
if (!g) {
|
|
1137
|
+
g = /* @__PURE__ */ new Map();
|
|
1138
|
+
shaped.set(r.font, g);
|
|
1139
|
+
}
|
|
1140
|
+
glyphText(r, fontStore.get(r.font), g, spans);
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
const fieldFonts = /* @__PURE__ */ new Set();
|
|
1145
|
+
for (const pg of model.pages) for (const it of pg.items) if (it.t === "field") fieldFonts.add(fieldFont(it));
|
|
1146
|
+
const fonts = /* @__PURE__ */ new Map();
|
|
1147
|
+
const font = async (key) => {
|
|
1148
|
+
if (!fonts.has(key)) {
|
|
1149
|
+
const full = fontStore.bytes.get(key);
|
|
1150
|
+
let bytes = full;
|
|
1151
|
+
if (!bytes) throw new Error(`Font "${key}" is not loaded`);
|
|
1152
|
+
const glyphs = shaped.get(key);
|
|
1153
|
+
if (opt.subset && !fieldFonts.has(key) && !fontStore.get(key)["OS/2"]?.fsType?.noSubsetting) {
|
|
1154
|
+
const cps = used.get(key) || /* @__PURE__ */ new Set([32]);
|
|
1155
|
+
try {
|
|
1156
|
+
const sub = withPadding(await opt.subset(bytes, cps, glyphs ? { glyphs: glyphs.keys() } : void 0));
|
|
1157
|
+
const f = fontkit.create(sub);
|
|
1158
|
+
for (const cp of cps) void f.glyphForCodePoint(cp).advanceWidth;
|
|
1159
|
+
for (const id of glyphs?.keys() || []) void f.getGlyph(id).advanceWidth;
|
|
1160
|
+
bytes = sub;
|
|
1161
|
+
} catch {
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
const pf = await doc.embedFont(bytes, { subset: false, customName: bytes === full ? void 0 : `${subsetTag(bytes)}+${fontStore.get(key).postscriptName || "Font"}` });
|
|
1165
|
+
plainEncoding(pf);
|
|
1166
|
+
if (glyphs) addGlyphs(pf, glyphs, !!opt.tagged);
|
|
1167
|
+
const file = bytes, e = (
|
|
1168
|
+
/** @type {any} */
|
|
1169
|
+
pf.embedder
|
|
1170
|
+
);
|
|
1171
|
+
if (!e.isCFF()) e.embedFontStream = async (c) => c.register(PDFRawStream2.of(c.obj({ Filter: "FlateDecode", Length1: file.length }), await deflate(file)));
|
|
1172
|
+
fonts.set(key, pf);
|
|
1173
|
+
}
|
|
1174
|
+
return fonts.get(key);
|
|
1175
|
+
};
|
|
1176
|
+
const images = /* @__PURE__ */ new Map();
|
|
1177
|
+
const image = async (src) => {
|
|
1178
|
+
if (images.has(src)) return images.get(src);
|
|
1179
|
+
const out = await loadImage(src).catch((e) => ({ img: null, why: `it could not be embedded (${e?.message || e})` }));
|
|
1180
|
+
images.set(src, out);
|
|
1181
|
+
return out;
|
|
1182
|
+
};
|
|
1183
|
+
async function loadImage(src) {
|
|
1184
|
+
const local = /^data:/i.test(src);
|
|
1185
|
+
if (local && dataUriBytes(src) > IMAGE_LIMITS.bytes) return { img: null, why: "it is larger than the image size limit" };
|
|
1186
|
+
if (!local && !opt.fetchImage) return { img: null, why: "it is a URL, and no fetchImage was given to load it" };
|
|
1187
|
+
const bytes = local ? dataUriBytesOf(src) : await opt.fetchImage(src);
|
|
1188
|
+
if (!bytes?.length) return { img: null, why: "it could not be loaded" };
|
|
1189
|
+
if (bytes.length > IMAGE_LIMITS.bytes) return { img: null, why: "it is larger than the image size limit" };
|
|
1190
|
+
const info = imageInfoOf(bytes);
|
|
1191
|
+
if (info?.type === "svg") {
|
|
1192
|
+
const svg = parseSvg(new TextDecoder().decode(bytes));
|
|
1193
|
+
return svg ? { img: { svg, width: svg.w, height: svg.h } } : { img: null, why: "the SVG could not be read" };
|
|
1194
|
+
}
|
|
1195
|
+
if (info?.type === "png") {
|
|
1196
|
+
const why = "w" in info && !/** @type {any} */
|
|
1197
|
+
info.suspect && info.w * info.h <= IMAGE_LIMITS.pixels ? pngProblem(bytes) : "too large or animated";
|
|
1198
|
+
return why ? { img: null, why: `the PNG is not usable (${why})` } : { img: await doc.embedPng(bytes) };
|
|
1199
|
+
}
|
|
1200
|
+
if (info?.type === "jpeg") return { img: await doc.embedJpg(bytes) };
|
|
1201
|
+
return { img: null, why: info ? `${info.type.toUpperCase()} is not embedded (PNG, JPEG and SVG are)` : "it is not a PNG, JPEG or SVG" };
|
|
1202
|
+
}
|
|
1203
|
+
const ctx = doc.context;
|
|
1204
|
+
const res = ctx.obj({ Font: {}, ExtGState: {}, XObject: {} });
|
|
1205
|
+
const resRef = ctx.register(res);
|
|
1206
|
+
const names = /* @__PURE__ */ new Map();
|
|
1207
|
+
const nameOf = (kind, key, value) => {
|
|
1208
|
+
let n = names.get(key);
|
|
1209
|
+
if (!n) {
|
|
1210
|
+
n = `${kind[0]}${names.size + 1}`;
|
|
1211
|
+
names.set(key, n);
|
|
1212
|
+
res.get(PDFName3.of(kind)).set(PDFName3.of(n), value());
|
|
1213
|
+
}
|
|
1214
|
+
return n;
|
|
1215
|
+
};
|
|
1216
|
+
const shared = {
|
|
1217
|
+
font: (pf) => nameOf("Font", pf, () => pf.ref),
|
|
1218
|
+
gs: (ca, CA) => nameOf("ExtGState", `gs ${ca} ${CA}`, () => ctx.obj({ Type: "ExtGState", ca, CA })),
|
|
1219
|
+
image: (img) => nameOf("XObject", img, () => img.ref)
|
|
1220
|
+
};
|
|
1221
|
+
const links = [];
|
|
1222
|
+
const taken = /* @__PURE__ */ new Set();
|
|
1223
|
+
const uniqueName = (n) => {
|
|
1224
|
+
let name = n, i = 1;
|
|
1225
|
+
while (taken.has(name)) name = `${n}_${++i}`;
|
|
1226
|
+
taken.add(name);
|
|
1227
|
+
return name;
|
|
1228
|
+
};
|
|
1229
|
+
const contents = [];
|
|
1230
|
+
if (opt.tagged) needsTableData(model, "An accessible PDF");
|
|
1231
|
+
const tags = opt.tagged ? createTagger(model, doc) : null;
|
|
1232
|
+
let pi = -1;
|
|
1233
|
+
const vm = /* @__PURE__ */ new Map();
|
|
1234
|
+
const vmetrics = (key) => {
|
|
1235
|
+
let m = vm.get(key);
|
|
1236
|
+
if (!m) {
|
|
1237
|
+
const f = fontStore.get(key), u = f?.unitsPerEm || 1e3;
|
|
1238
|
+
vm.set(key, m = { asc: (f?.ascent ?? u) / u, desc: -(f?.descent ?? 0) / u });
|
|
1239
|
+
}
|
|
1240
|
+
return m;
|
|
1241
|
+
};
|
|
1242
|
+
for (const pg of model.pages) {
|
|
1243
|
+
pi++;
|
|
1244
|
+
const H = pg.height ?? model.height;
|
|
1245
|
+
const p = doc.addPage([pg.width ?? model.width, H]);
|
|
1246
|
+
p.node.normalize();
|
|
1247
|
+
p.node.set(PDFName3.of("Resources"), resRef);
|
|
1248
|
+
const c = new Content(shared);
|
|
1249
|
+
if (tags) c.tagged = true;
|
|
1250
|
+
p.maybeEmbedGraphicsState = (o) => c.gsFor(o.opacity ?? 1, o.borderOpacity ?? 1);
|
|
1251
|
+
const viaPdfLib = (draw) => {
|
|
1252
|
+
c.et();
|
|
1253
|
+
c.lineWidth(1);
|
|
1254
|
+
draw();
|
|
1255
|
+
const ops = (
|
|
1256
|
+
/** @type {any} */
|
|
1257
|
+
p.getContentStream().operators
|
|
1258
|
+
);
|
|
1259
|
+
for (const op of ops) c.s += op.toString() + "\n";
|
|
1260
|
+
ops.length = 0;
|
|
1261
|
+
};
|
|
1262
|
+
for (let ii = 0; ii < pg.items.length; ii++) {
|
|
1263
|
+
const it = pg.items[ii];
|
|
940
1264
|
const mark = tags && tags.open(pi, ii, it);
|
|
941
1265
|
if (mark) {
|
|
942
1266
|
c.et();
|
|
@@ -1027,7 +1351,7 @@ async function pdfOf(model, fontStore, opt) {
|
|
|
1027
1351
|
const form = doc.getForm();
|
|
1028
1352
|
const f = await font(fieldFont(it));
|
|
1029
1353
|
const name = uniqueName(it.name);
|
|
1030
|
-
const box = { x: it.x, y: H - it.y - it.h, width: it.w, height: it.h, borderColor:
|
|
1354
|
+
const box = { x: it.x, y: H - it.y - it.h, width: it.w, height: it.h, borderColor: rgb3(0.61, 0.64, 0.69), borderWidth: 0.75, backgroundColor: rgb3(1, 1, 1) };
|
|
1031
1355
|
let field;
|
|
1032
1356
|
if (it.kind === "checkbox") {
|
|
1033
1357
|
field = form.createCheckBox(name);
|
|
@@ -1084,7 +1408,7 @@ async function pdfOf(model, fontStore, opt) {
|
|
|
1084
1408
|
if (it.required) field.enableRequired();
|
|
1085
1409
|
if (it.readOnly) field.enableReadOnly();
|
|
1086
1410
|
if (tags) {
|
|
1087
|
-
field.acroField.dict.set(PDFName3.of("TU"),
|
|
1411
|
+
field.acroField.dict.set(PDFName3.of("TU"), PDFHexString5.fromText(it.label || it.name || name));
|
|
1088
1412
|
const w = field.acroField.getWidgets()[0];
|
|
1089
1413
|
const ref2 = w && doc.context.getObjectRef(w.dict);
|
|
1090
1414
|
if (ref2) tags.annot(pi, ii, ref2, "field");
|
|
@@ -1158,7 +1482,7 @@ async function pdfOf(model, fontStore, opt) {
|
|
|
1158
1482
|
const to = l.href ? { A: { Type: "Action", S: "URI", URI: pdfLiteral(asciiUrl(l.href)) } } : { Dest: dest(l.to) };
|
|
1159
1483
|
if (!l.href && !to.Dest) continue;
|
|
1160
1484
|
const annot = doc.context.obj({ Type: "Annot", Subtype: "Link", F: 4, Rect: l.rect, Border: [0, 0, 0], ...to });
|
|
1161
|
-
if (tags) annot.set(PDFName3.of("Contents"),
|
|
1485
|
+
if (tags) annot.set(PDFName3.of("Contents"), PDFHexString5.fromText(String(l.text || l.tip || l.href || "Link")));
|
|
1162
1486
|
const ref = doc.context.register(annot);
|
|
1163
1487
|
if (tags) tags.annot(l.pi, l.ii, ref, "link");
|
|
1164
1488
|
const annots = l.page.node.lookup(PDFName3.of("Annots"));
|
|
@@ -1183,124 +1507,28 @@ async function pdfOf(model, fontStore, opt) {
|
|
|
1183
1507
|
function coveredText(items, box) {
|
|
1184
1508
|
const lines = [];
|
|
1185
1509
|
for (const t of items) if (t.t === "text" && t.lines) {
|
|
1186
|
-
for (const l of t.lines) if (l.text?.trim() && l.x >= box.x && l.x <= box.x + box.w && l.y >= box.y && l.y <= box.y + box.h) lines.push(l);
|
|
1187
|
-
}
|
|
1188
|
-
return lines.sort((a, b) => a.y - b.y || a.x - b.x).map((l) => l.text.trim()).join(" ");
|
|
1189
|
-
}
|
|
1190
|
-
function fixedDate(opt) {
|
|
1191
|
-
if (opt.creationDate !== void 0) {
|
|
1192
|
-
if (!(opt.creationDate instanceof Date) || Number.isNaN(opt.creationDate.getTime())) throw Object.assign(new Error("creationDate must be a valid Date"), { status: 400 });
|
|
1193
|
-
return opt.creationDate;
|
|
1194
|
-
}
|
|
1195
|
-
const epoch = globalThis.process?.env?.SOURCE_DATE_EPOCH;
|
|
1196
|
-
return epoch && /^\d+$/.test(epoch) ? new Date(Number(epoch) * 1e3) : null;
|
|
1197
|
-
}
|
|
1198
|
-
async function contentId(model, opt, when) {
|
|
1199
|
-
const bytes = new TextEncoder().encode(JSON.stringify([{ ...model, stats: void 0 }, opt.title || "Report", opt.author || "", when.toISOString()]));
|
|
1200
|
-
const digest = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", bytes));
|
|
1201
|
-
return Array.from(digest.subarray(0, 16), (b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
1202
|
-
}
|
|
1203
|
-
function fieldFont(it) {
|
|
1204
|
-
for (const d of it.draw) if (d.t === "text") {
|
|
1205
|
-
for (const l of d.lines) for (const r of l.runs || []) if (r.font !== it.font && r.text.trim()) return r.font;
|
|
1206
|
-
}
|
|
1207
|
-
return it.font;
|
|
1208
|
-
}
|
|
1209
|
-
function drawRun(c, run, x, y, size, pf, color, spans, texts) {
|
|
1210
|
-
const f = pf.embedder.font;
|
|
1211
|
-
const per = 1e3 / size;
|
|
1212
|
-
const span = (text) => `/Span <</ActualText ${PDFHexString4.fromText(text).toString()}>> BDC
|
|
1213
|
-
`;
|
|
1214
|
-
c.et();
|
|
1215
|
-
c.paint(color, null);
|
|
1216
|
-
c.font(pf, size);
|
|
1217
|
-
if (!run.rtl) c.s += span(run.text);
|
|
1218
|
-
c.s += `BT ${n2(x)} ${n2(y)} Td
|
|
1219
|
-
`;
|
|
1220
|
-
let arr = "";
|
|
1221
|
-
let pen = 0, rise = 0;
|
|
1222
|
-
const flush = () => {
|
|
1223
|
-
if (arr) c.s += `[${arr}] TJ
|
|
1224
|
-
`;
|
|
1225
|
-
arr = "";
|
|
1226
|
-
};
|
|
1227
|
-
const all = run.glyphs;
|
|
1228
|
-
const adv = (id) => f.getGlyph(id).advanceWidth;
|
|
1229
|
-
let g = all, quietAt = -1;
|
|
1230
|
-
if (run.rtl) {
|
|
1231
|
-
const hasBase = /* @__PURE__ */ new Set();
|
|
1232
|
-
for (let i = 0; i < all.length; i += 4) if (adv(all[i]) > 0) hasBase.add(all[i + 3]);
|
|
1233
|
-
const quiet = (i) => spans?.has(all[i + 3]) ? adv(all[i]) === 0 && hasBase.has(all[i + 3]) : texts?.get(all[i]) === "";
|
|
1234
|
-
g = [];
|
|
1235
|
-
for (const late of [false, true]) {
|
|
1236
|
-
if (late) quietAt = g.length;
|
|
1237
|
-
for (let i = 0; i < all.length; i += 4) if (quiet(i) === late) g.push(all[i], all[i + 1], all[i + 2], all[i + 3]);
|
|
1238
|
-
}
|
|
1239
|
-
if (quietAt === g.length) quietAt = -1;
|
|
1240
|
-
}
|
|
1241
|
-
const starts = run.rtl ? [...new Set(all.filter((_, i) => i % 4 === 3))].sort((a, b) => a - b) : [];
|
|
1242
|
-
let inSpan = false;
|
|
1243
|
-
for (let i = 0; i < g.length; i += 4) {
|
|
1244
|
-
const id = g[i], gx = g[i + 1], gy = g[i + 2], cl = g[i + 3];
|
|
1245
|
-
if (i === quietAt) {
|
|
1246
|
-
flush();
|
|
1247
|
-
c.s += span("");
|
|
1248
|
-
inSpan = true;
|
|
1249
|
-
} else if (run.rtl && spans?.has(cl) && (quietAt < 0 || i < quietAt) && (i === 0 || g[i - 1] !== cl)) {
|
|
1250
|
-
flush();
|
|
1251
|
-
c.s += span(run.text.slice(cl, starts[starts.indexOf(cl) + 1] ?? run.text.length));
|
|
1252
|
-
inSpan = true;
|
|
1253
|
-
}
|
|
1254
|
-
if (gy !== rise) {
|
|
1255
|
-
flush();
|
|
1256
|
-
c.s += `${n4(gy)} Ts
|
|
1257
|
-
`;
|
|
1258
|
-
rise = gy;
|
|
1259
|
-
}
|
|
1260
|
-
const adj = Math.round((pen - gx) * per * 1e3) / 1e3;
|
|
1261
|
-
if (id === 0 && c.tagged) pen = gx;
|
|
1262
|
-
else {
|
|
1263
|
-
arr += (adj ? `${adj}` : "") + `<${hex4(id)}>`;
|
|
1264
|
-
pen = gx + adv(id) * size / f.unitsPerEm;
|
|
1265
|
-
}
|
|
1266
|
-
if (inSpan && (i + 4 >= g.length || (quietAt < 0 || i + 4 < quietAt) && g[i + 7] !== cl || i + 4 === quietAt)) {
|
|
1267
|
-
flush();
|
|
1268
|
-
c.s += "EMC\n";
|
|
1269
|
-
inSpan = false;
|
|
1270
|
-
}
|
|
1510
|
+
for (const l of t.lines) if (l.text?.trim() && l.x >= box.x && l.x <= box.x + box.w && l.y >= box.y && l.y <= box.y + box.h) lines.push(l);
|
|
1271
1511
|
}
|
|
1272
|
-
|
|
1273
|
-
if (rise) c.s += "0 Ts\n";
|
|
1274
|
-
c.s += "ET\n";
|
|
1275
|
-
if (!run.rtl) c.s += "EMC\n";
|
|
1512
|
+
return lines.sort((a, b) => a.y - b.y || a.x - b.x).map((l) => l.text.trim()).join(" ");
|
|
1276
1513
|
}
|
|
1277
|
-
function
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
}
|
|
1294
|
-
for (const [id, t] of want) {
|
|
1295
|
-
if (!out.has(id)) out.set(id, t);
|
|
1296
|
-
else if (out.get(id) !== t) ok = false;
|
|
1297
|
-
}
|
|
1298
|
-
if (!ok && run.rtl && spans) {
|
|
1299
|
-
let s = spans.get(run);
|
|
1300
|
-
if (!s) spans.set(run, s = /* @__PURE__ */ new Set());
|
|
1301
|
-
s.add(starts[k]);
|
|
1302
|
-
}
|
|
1514
|
+
function fixedDate(opt) {
|
|
1515
|
+
if (opt.creationDate !== void 0) {
|
|
1516
|
+
if (!(opt.creationDate instanceof Date) || Number.isNaN(opt.creationDate.getTime())) throw Object.assign(new Error("creationDate must be a valid Date"), { status: 400 });
|
|
1517
|
+
return opt.creationDate;
|
|
1518
|
+
}
|
|
1519
|
+
const epoch = globalThis.process?.env?.SOURCE_DATE_EPOCH;
|
|
1520
|
+
return epoch && /^\d+$/.test(epoch) ? new Date(Number(epoch) * 1e3) : null;
|
|
1521
|
+
}
|
|
1522
|
+
async function contentId(model, opt, when) {
|
|
1523
|
+
const bytes = new TextEncoder().encode(JSON.stringify([{ ...model, stats: void 0 }, opt.title || "Report", opt.author || "", when.toISOString()]));
|
|
1524
|
+
const digest = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", bytes));
|
|
1525
|
+
return Array.from(digest.subarray(0, 16), (b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
1526
|
+
}
|
|
1527
|
+
function fieldFont(it) {
|
|
1528
|
+
for (const d of it.draw) if (d.t === "text") {
|
|
1529
|
+
for (const l of d.lines) for (const r of l.runs || []) if (r.font !== it.font && r.text.trim()) return r.font;
|
|
1303
1530
|
}
|
|
1531
|
+
return it.font;
|
|
1304
1532
|
}
|
|
1305
1533
|
var pdfLiteral = (s) => PDFString4.of(String(s).replace(/[\\()]/g, "\\$&"));
|
|
1306
1534
|
function plainEncoding(pf) {
|
|
@@ -1318,7 +1546,7 @@ function plainEncoding(pf) {
|
|
|
1318
1546
|
}
|
|
1319
1547
|
return hex2;
|
|
1320
1548
|
};
|
|
1321
|
-
e.encodeText = (text) =>
|
|
1549
|
+
e.encodeText = (text) => PDFHexString5.of(e.hexOf(text));
|
|
1322
1550
|
e.widthOfTextAtSize = (text, size) => {
|
|
1323
1551
|
let w = 0;
|
|
1324
1552
|
for (const ch of text) w += f.glyphForCodePoint(
|
|
@@ -1409,7 +1637,7 @@ function addOutline(doc, bookmarks, dest) {
|
|
|
1409
1637
|
if (!Dest) continue;
|
|
1410
1638
|
const level = Math.max(0, Math.min(9, Number(b.level) || 0));
|
|
1411
1639
|
while (stack[stack.length - 1].level >= level) stack.pop();
|
|
1412
|
-
const node2 = { ref: ctx.nextRef(), level, kids: [], Title:
|
|
1640
|
+
const node2 = { ref: ctx.nextRef(), level, kids: [], Title: PDFHexString5.fromText(b.label), Dest };
|
|
1413
1641
|
stack[stack.length - 1].kids.push(node2);
|
|
1414
1642
|
stack.push(node2);
|
|
1415
1643
|
}
|
|
@@ -1440,216 +1668,6 @@ function subsetTag(bytes) {
|
|
|
1440
1668
|
}
|
|
1441
1669
|
return tag;
|
|
1442
1670
|
}
|
|
1443
|
-
function insideClip(it, m) {
|
|
1444
|
-
const k = it.clip, asc = m.asc * it.size, desc = m.desc * it.size;
|
|
1445
|
-
return it.lines.every((l) => l.w != null && !l.runs && l.x >= k.x && l.x + l.w <= k.x + k.w && l.y - asc >= k.y && l.y + desc <= k.y + k.h);
|
|
1446
|
-
}
|
|
1447
|
-
var Content = class {
|
|
1448
|
-
constructor(shared) {
|
|
1449
|
-
this.shared = shared;
|
|
1450
|
-
this._s = "";
|
|
1451
|
-
this.bt = false;
|
|
1452
|
-
this.tx = 0;
|
|
1453
|
-
this.ty = 0;
|
|
1454
|
-
this.st = { fill: "0 0 0", stroke: "0 0 0", lw: 1, dash: "[] 0", ca: 1, CA: 1, font: "", size: 0 };
|
|
1455
|
-
this.saved = [];
|
|
1456
|
-
this.lines = null;
|
|
1457
|
-
this.tagged = false;
|
|
1458
|
-
}
|
|
1459
|
-
/**
|
|
1460
|
-
* The operators so far. Any other drawing reads or appends to it, so the lines waiting are drawn first: the text
|
|
1461
|
-
* of a table's cells stays in one text object (relative moves, which compress to little) instead of one per cell.
|
|
1462
|
-
*/
|
|
1463
|
-
get s() {
|
|
1464
|
-
this.flushLines();
|
|
1465
|
-
return this._s;
|
|
1466
|
-
}
|
|
1467
|
-
set s(v) {
|
|
1468
|
-
this._s = v;
|
|
1469
|
-
}
|
|
1470
|
-
/**
|
|
1471
|
-
* A straight line. Untagged, it waits until something other than text is drawn (table borders between cell
|
|
1472
|
-
* texts); collinear segments that touch, in the same stroke, become one (a row's border is one line).
|
|
1473
|
-
* ponytail: lines move after the text drawn just after them; both are thin and do not cover each other.
|
|
1474
|
-
*/
|
|
1475
|
-
line(stroke, w, dash, x1, y1, x2, y2) {
|
|
1476
|
-
if (this.tagged) {
|
|
1477
|
-
this.paint(null, stroke, w, dash);
|
|
1478
|
-
this._s += `${n2(x1)} ${n2(y1)} m ${n2(x2)} ${n2(y2)} l S
|
|
1479
|
-
`;
|
|
1480
|
-
return;
|
|
1481
|
-
}
|
|
1482
|
-
const key = `${stroke.rgb}|${stroke.opacity}|${w}|${(dash || []).join(" ")}`;
|
|
1483
|
-
if (this.lines && this.lines.key !== key) this.flushLines();
|
|
1484
|
-
this.lines || (this.lines = { key, stroke, w, dash, segs: [] });
|
|
1485
|
-
const segs = this.lines.segs, last = segs[segs.length - 1];
|
|
1486
|
-
const eq = (a, b) => Math.abs(a - b) < 5e-3;
|
|
1487
|
-
if (last && eq(last[1], y1) && eq(last[3], y2) && eq(y1, y2) && eq(last[2], x1)) last[2] = x2;
|
|
1488
|
-
else if (last && eq(last[0], x1) && eq(last[2], x2) && eq(x1, x2) && eq(last[3], y1)) last[3] = y2;
|
|
1489
|
-
else segs.push([x1, y1, x2, y2]);
|
|
1490
|
-
}
|
|
1491
|
-
flushLines() {
|
|
1492
|
-
const L = this.lines;
|
|
1493
|
-
if (!L) return;
|
|
1494
|
-
this.lines = null;
|
|
1495
|
-
this.et();
|
|
1496
|
-
this.paint(null, L.stroke, L.w, L.dash);
|
|
1497
|
-
const g = L.segs;
|
|
1498
|
-
const dy = g.length > 2 ? Math.round((g[1][1] - g[0][1]) * 100) : 0;
|
|
1499
|
-
if (dy && g.every((q, i) => q[1] === q[3] && n2(q[0]) === n2(g[0][0]) && n2(q[2]) === n2(g[0][2]) && Math.abs(q[1] - (g[0][1] + i * dy / 100)) < 0.01)) {
|
|
1500
|
-
const one = `${n2(g[0][0])} ${n2(g[0][1])} m ${n2(g[0][2])} ${n2(g[0][1])} l S
|
|
1501
|
-
`;
|
|
1502
|
-
this._s += `q
|
|
1503
|
-
${one}${`1 0 0 1 0 ${dy / 100} cm ${one}`.repeat(g.length - 1)}Q
|
|
1504
|
-
`;
|
|
1505
|
-
return;
|
|
1506
|
-
}
|
|
1507
|
-
this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n";
|
|
1508
|
-
}
|
|
1509
|
-
q() {
|
|
1510
|
-
this.et();
|
|
1511
|
-
this._s += "q\n";
|
|
1512
|
-
this.saved.push({ ...this.st });
|
|
1513
|
-
}
|
|
1514
|
-
Q() {
|
|
1515
|
-
this.et();
|
|
1516
|
-
this._s += "Q\n";
|
|
1517
|
-
this.st = this.saved.pop();
|
|
1518
|
-
}
|
|
1519
|
-
/**
|
|
1520
|
-
* A line of plain text at (x, y). Lines follow one another in one text object, each placed relative to the
|
|
1521
|
-
* last (in whole hundredths, so nothing drifts): most of a table page is these.
|
|
1522
|
-
* @param {string} str the glyphs, as a literal string's escaped body (array: a TJ array's body)
|
|
1523
|
-
*/
|
|
1524
|
-
text(pf, size, color, x, y, str, array = false) {
|
|
1525
|
-
this.setPaint(color, null);
|
|
1526
|
-
this.setFont(pf, size);
|
|
1527
|
-
const X = Math.round(x * 10) * 10, Y = Math.round(y * 10) * 10;
|
|
1528
|
-
if (!this.bt) {
|
|
1529
|
-
this._s += "BT\n";
|
|
1530
|
-
this.bt = true;
|
|
1531
|
-
this.tx = 0;
|
|
1532
|
-
this.ty = 0;
|
|
1533
|
-
}
|
|
1534
|
-
this._s += array ? `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td [${str}] TJ
|
|
1535
|
-
` : `${(X - this.tx) / 100} ${(Y - this.ty) / 100} Td (${str}) Tj
|
|
1536
|
-
`;
|
|
1537
|
-
this.tx = X;
|
|
1538
|
-
this.ty = Y;
|
|
1539
|
-
}
|
|
1540
|
-
/** end the open text object, if any: anything but text needs that (and draws the lines waiting) */
|
|
1541
|
-
et() {
|
|
1542
|
-
if (this.bt) {
|
|
1543
|
-
this._s += "ET\n";
|
|
1544
|
-
this.bt = false;
|
|
1545
|
-
}
|
|
1546
|
-
if (this.lines) this.flushLines();
|
|
1547
|
-
}
|
|
1548
|
-
lineWidth(w) {
|
|
1549
|
-
if (this.lines) this.flushLines();
|
|
1550
|
-
this.setLineWidth(w);
|
|
1551
|
-
}
|
|
1552
|
-
setLineWidth(w) {
|
|
1553
|
-
if (this.st.lw !== w) {
|
|
1554
|
-
this._s += `${n3(w)} w
|
|
1555
|
-
`;
|
|
1556
|
-
this.st.lw = w;
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
/** the graphics state that sets these opacities, or undefined when they are set already */
|
|
1560
|
-
gsFor(ca, CA) {
|
|
1561
|
-
return ca === this.st.ca && CA === this.st.CA ? void 0 : this.shared.gs(ca, CA);
|
|
1562
|
-
}
|
|
1563
|
-
alpha(ca, CA) {
|
|
1564
|
-
if (this.lines) this.flushLines();
|
|
1565
|
-
this.setAlpha(ca, CA);
|
|
1566
|
-
}
|
|
1567
|
-
setAlpha(ca, CA) {
|
|
1568
|
-
const g = this.gsFor(ca, CA);
|
|
1569
|
-
if (g) {
|
|
1570
|
-
this._s += `/${g} gs
|
|
1571
|
-
`;
|
|
1572
|
-
this.st.ca = ca;
|
|
1573
|
-
this.st.CA = CA;
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
/** set up to fill with fill and/or stroke with stroke (width w, dash); the lines waiting are drawn first */
|
|
1577
|
-
paint(fill, stroke, w = 1, dash = null) {
|
|
1578
|
-
if (this.lines) this.flushLines();
|
|
1579
|
-
this.setPaint(fill, stroke, w, dash);
|
|
1580
|
-
}
|
|
1581
|
-
setPaint(fill, stroke, w = 1, dash = null) {
|
|
1582
|
-
const st = this.st;
|
|
1583
|
-
if (fill && fill.rgb !== st.fill) {
|
|
1584
|
-
this._s += `${fill.rgb} rg
|
|
1585
|
-
`;
|
|
1586
|
-
st.fill = fill.rgb;
|
|
1587
|
-
}
|
|
1588
|
-
if (stroke) {
|
|
1589
|
-
if (stroke.rgb !== st.stroke) {
|
|
1590
|
-
this._s += `${stroke.rgb} RG
|
|
1591
|
-
`;
|
|
1592
|
-
st.stroke = stroke.rgb;
|
|
1593
|
-
}
|
|
1594
|
-
this.setLineWidth(w);
|
|
1595
|
-
const d = `[${(dash || []).map(n3).join(" ")}] 0`;
|
|
1596
|
-
if (d !== st.dash) {
|
|
1597
|
-
this._s += `${d} d
|
|
1598
|
-
`;
|
|
1599
|
-
st.dash = d;
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
this.setAlpha(fill ? fill.opacity : st.ca, stroke ? stroke.opacity : st.CA);
|
|
1603
|
-
}
|
|
1604
|
-
font(pf, size) {
|
|
1605
|
-
if (this.lines) this.flushLines();
|
|
1606
|
-
this.setFont(pf, size);
|
|
1607
|
-
}
|
|
1608
|
-
setFont(pf, size) {
|
|
1609
|
-
const name = this.shared.font(pf);
|
|
1610
|
-
if (name !== this.st.font || size !== this.st.size) {
|
|
1611
|
-
this._s += `/${name} ${n3(size)} Tf
|
|
1612
|
-
`;
|
|
1613
|
-
this.st.font = name;
|
|
1614
|
-
this.st.size = size;
|
|
1615
|
-
}
|
|
1616
|
-
}
|
|
1617
|
-
};
|
|
1618
|
-
function latin1(s) {
|
|
1619
|
-
const B = (
|
|
1620
|
-
/** @type {any} */
|
|
1621
|
-
globalThis.Buffer
|
|
1622
|
-
);
|
|
1623
|
-
if (B) return B.from(s, "latin1");
|
|
1624
|
-
const out = new Uint8Array(s.length);
|
|
1625
|
-
for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i);
|
|
1626
|
-
return out;
|
|
1627
|
-
}
|
|
1628
|
-
async function deflate(bytes) {
|
|
1629
|
-
if (zslots.free > 0) zslots.free--;
|
|
1630
|
-
else await new Promise((ok) => zslots.wait.push(ok));
|
|
1631
|
-
try {
|
|
1632
|
-
return await deflateNow(bytes);
|
|
1633
|
-
} finally {
|
|
1634
|
-
const next = zslots.wait.shift();
|
|
1635
|
-
if (next) next();
|
|
1636
|
-
else zslots.free++;
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
var zslots = { free: 4, wait: (
|
|
1640
|
-
/** @type {(() => void)[]} */
|
|
1641
|
-
[]
|
|
1642
|
-
) };
|
|
1643
|
-
var NODE_ZLIB = (
|
|
1644
|
-
/** @type {any} */
|
|
1645
|
-
globalThis.process?.getBuiltinModule?.("node:zlib")
|
|
1646
|
-
);
|
|
1647
|
-
async function deflateNow(bytes) {
|
|
1648
|
-
const zlib = NODE_ZLIB;
|
|
1649
|
-
if (zlib) return new Promise((ok, fail) => zlib.deflate(bytes, { level: 9 }, (e, z) => e ? fail(e) : ok(z)));
|
|
1650
|
-
if (typeof CompressionStream === "undefined") return (await import("fflate")).zlibSync(bytes);
|
|
1651
|
-
return new Uint8Array(await new Response(new Blob([bytes]).stream().pipeThrough(new CompressionStream("deflate"))).arrayBuffer());
|
|
1652
|
-
}
|
|
1653
1671
|
function roundRect(x, y, w, h, r) {
|
|
1654
1672
|
r = Math.min(r, w / 2, h / 2);
|
|
1655
1673
|
return `M ${x + r} ${y} H ${x + w - r} A ${r} ${r} 0 0 1 ${x + w} ${y + r} V ${y + h - r} A ${r} ${r} 0 0 1 ${x + w - r} ${y + h} H ${x + r} A ${r} ${r} 0 0 1 ${x} ${y + h - r} V ${y + r} A ${r} ${r} 0 0 1 ${x + r} ${y} Z`;
|
|
@@ -1657,4 +1675,4 @@ function roundRect(x, y, w, h, r) {
|
|
|
1657
1675
|
export {
|
|
1658
1676
|
exportPdf
|
|
1659
1677
|
};
|
|
1660
|
-
//# sourceMappingURL=chunk-
|
|
1678
|
+
//# sourceMappingURL=chunk-TSC4RAH3.js.map
|