@reportwright/viewer 0.12.1 → 0.13.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.
Files changed (101) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +18 -1
  3. package/THIRD-PARTY-NOTICES.md +52 -0
  4. package/dist/{chunk-DXHLIJEY.js → chunk-47ZAKRVN.js} +6 -6
  5. package/dist/{chunk-NR2G4TMG.js → chunk-B5ZCT3UK.js} +47 -26
  6. package/dist/chunk-B5ZCT3UK.js.map +6 -0
  7. package/dist/chunk-BR5K6SBL.js +324 -0
  8. package/dist/chunk-BR5K6SBL.js.map +6 -0
  9. package/dist/chunk-CCH7CFU5.js +5026 -0
  10. package/dist/chunk-CCH7CFU5.js.map +6 -0
  11. package/dist/{peer/chunk-BQFI3DHK.js → chunk-ES2LYZ6S.js} +292 -25
  12. package/dist/chunk-ES2LYZ6S.js.map +6 -0
  13. package/dist/{chunk-S2IUUI6N.js → chunk-GOCWG6FG.js} +67 -49
  14. package/dist/chunk-GOCWG6FG.js.map +6 -0
  15. package/dist/{chunk-3D2KFKG2.js → chunk-GRYITZPG.js} +11 -9
  16. package/dist/chunk-GRYITZPG.js.map +6 -0
  17. package/dist/{chunk-2BPBQMH2.js → chunk-H422SRD3.js} +8 -8
  18. package/dist/chunk-JD6EJ3LI.js +18 -0
  19. package/dist/{chunk-Z7MKH66Z.js → chunk-MS2LQC2O.js} +236 -12
  20. package/dist/chunk-MS2LQC2O.js.map +6 -0
  21. package/dist/{chunk-Q6MMPKQA.js → chunk-PF4RFKX2.js} +13 -12
  22. package/dist/chunk-PF4RFKX2.js.map +6 -0
  23. package/dist/{chunk-PGP3QA6L.js → chunk-PKXTMC4J.js} +1351 -75
  24. package/dist/chunk-PKXTMC4J.js.map +6 -0
  25. package/dist/{chunk-M6AYND5G.js → chunk-U2ZY2NPQ.js} +16 -7
  26. package/dist/chunk-U2ZY2NPQ.js.map +6 -0
  27. package/dist/{chunk-DPVJEFKP.js → chunk-WOBRKNIA.js} +13 -13
  28. package/dist/{chunk-DPVJEFKP.js.map → chunk-WOBRKNIA.js.map} +1 -1
  29. package/dist/chunk-XXTAPZO4.js +34 -0
  30. package/dist/{chunk-VNOWPSE6.js → chunk-ZGRJJ6OW.js} +1226 -887
  31. package/dist/chunk-ZGRJJ6OW.js.map +6 -0
  32. package/dist/designer.d.ts +11 -3
  33. package/dist/designer.js +598 -390
  34. package/dist/designer.js.map +3 -3
  35. package/dist/engine.worker.bwip.js +51422 -0
  36. package/dist/engine.worker.bwip.js.map +6 -0
  37. package/dist/engine.worker.js +59582 -26
  38. package/dist/engine.worker.js.map +3 -3
  39. package/dist/peer/{chunk-WSNRD2AQ.js → chunk-3EYYRJR4.js} +13 -12
  40. package/dist/{chunk-Q6MMPKQA.js.map → peer/chunk-3EYYRJR4.js.map} +1 -1
  41. package/dist/peer/{chunk-TSC4RAH3.js → chunk-3XZY54LM.js} +1351 -75
  42. package/dist/peer/chunk-3XZY54LM.js.map +6 -0
  43. package/dist/peer/chunk-5RUNOIS7.js +33 -0
  44. package/dist/peer/chunk-5RUNOIS7.js.map +6 -0
  45. package/dist/peer/{chunk-6I2EAAVN.js → chunk-7IP67PA6.js} +47 -26
  46. package/dist/peer/chunk-7IP67PA6.js.map +6 -0
  47. package/dist/peer/{chunk-R4VX5UC7.js → chunk-A6UXBSTP.js} +8 -8
  48. package/dist/peer/{chunk-V42KN7HD.js → chunk-CFTFTV2O.js} +6 -6
  49. package/dist/peer/chunk-JQTRDHQP.js +866 -0
  50. package/dist/peer/chunk-JQTRDHQP.js.map +6 -0
  51. package/dist/peer/chunk-KD6CDYGE.js +5024 -0
  52. package/dist/peer/chunk-KD6CDYGE.js.map +6 -0
  53. package/dist/peer/chunk-MXR6JBMP.js +546 -0
  54. package/dist/peer/chunk-MXR6JBMP.js.map +6 -0
  55. package/dist/peer/chunk-N42DCZZA.js +378 -0
  56. package/dist/peer/chunk-N42DCZZA.js.map +6 -0
  57. package/dist/{chunk-6TPZ7G74.js → peer/chunk-RKFP7SDY.js} +292 -25
  58. package/dist/peer/chunk-RKFP7SDY.js.map +6 -0
  59. package/dist/peer/{chunk-BMAXIBP2.js → chunk-WABYQWMT.js} +13 -13
  60. package/dist/peer/{chunk-BMAXIBP2.js.map → chunk-WABYQWMT.js.map} +1 -1
  61. package/dist/peer/chunk-WVQQCD4M.js +14211 -0
  62. package/dist/peer/chunk-WVQQCD4M.js.map +6 -0
  63. package/dist/peer/chunk-XHCRHVRK.js +17 -0
  64. package/dist/peer/chunk-XHCRHVRK.js.map +6 -0
  65. package/dist/peer/{chunk-WQGENQZO.js → chunk-ZS3J4WBH.js} +11 -9
  66. package/dist/peer/chunk-ZS3J4WBH.js.map +6 -0
  67. package/dist/peer/designer.js +455 -247
  68. package/dist/peer/designer.js.map +3 -3
  69. package/dist/peer/engine.worker.bwip.js +51422 -0
  70. package/dist/peer/engine.worker.bwip.js.map +6 -0
  71. package/dist/peer/engine.worker.js +59582 -25
  72. package/dist/peer/engine.worker.js.map +3 -3
  73. package/dist/peer/viewer.js +16 -12
  74. package/dist/peer/viewer.js.map +1 -1
  75. package/dist/viewer.d.ts +2 -1
  76. package/dist/viewer.js +16 -12
  77. package/dist/viewer.js.map +1 -1
  78. package/package.json +3 -2
  79. package/dist/chunk-3D2KFKG2.js.map +0 -6
  80. package/dist/chunk-6TPZ7G74.js.map +0 -6
  81. package/dist/chunk-BRB34AJ2.js +0 -16
  82. package/dist/chunk-M6AYND5G.js.map +0 -6
  83. package/dist/chunk-NR2G4TMG.js.map +0 -6
  84. package/dist/chunk-PGP3QA6L.js.map +0 -6
  85. package/dist/chunk-S2IUUI6N.js.map +0 -6
  86. package/dist/chunk-ULKEEARQ.js +0 -553
  87. package/dist/chunk-ULKEEARQ.js.map +0 -6
  88. package/dist/chunk-VNOWPSE6.js.map +0 -6
  89. package/dist/chunk-Z7MKH66Z.js.map +0 -6
  90. package/dist/peer/chunk-2FZTYEDE.js +0 -15
  91. package/dist/peer/chunk-6I2EAAVN.js.map +0 -6
  92. package/dist/peer/chunk-BQFI3DHK.js.map +0 -6
  93. package/dist/peer/chunk-TSC4RAH3.js.map +0 -6
  94. package/dist/peer/chunk-WQGENQZO.js.map +0 -6
  95. package/dist/peer/chunk-WSNRD2AQ.js.map +0 -6
  96. /package/dist/{chunk-DXHLIJEY.js.map → chunk-47ZAKRVN.js.map} +0 -0
  97. /package/dist/{chunk-2BPBQMH2.js.map → chunk-H422SRD3.js.map} +0 -0
  98. /package/dist/{chunk-BRB34AJ2.js.map → chunk-JD6EJ3LI.js.map} +0 -0
  99. /package/dist/{peer/chunk-2FZTYEDE.js.map → chunk-XXTAPZO4.js.map} +0 -0
  100. /package/dist/peer/{chunk-R4VX5UC7.js.map → chunk-A6UXBSTP.js.map} +0 -0
  101. /package/dist/peer/{chunk-V42KN7HD.js.map → chunk-CFTFTV2O.js.map} +0 -0
@@ -1,11 +1,7 @@
1
1
  import {
2
2
  FORMAT_CHAR
3
- } from "../chunk-ULKEEARQ.js";
4
- import {
5
- asciiUrl,
6
- drillUrl,
7
- safeUrl
8
- } from "../chunk-72S6DETS.js";
3
+ } from "./chunk-WVQQCD4M.js";
4
+ import "../chunk-BR5K6SBL.js";
9
5
  import {
10
6
  withDeadline
11
7
  } from "../chunk-D2NTLAKL.js";
@@ -18,24 +14,46 @@ import {
18
14
  cellVisuals,
19
15
  figures,
20
16
  parseColor
21
- } from "../chunk-M6AYND5G.js";
17
+ } from "./chunk-MXR6JBMP.js";
18
+ import {
19
+ asciiUrl,
20
+ drillUrl,
21
+ safeUrl
22
+ } from "../chunk-72S6DETS.js";
22
23
  import {
23
24
  IMAGE_LIMITS,
25
+ PDFArray,
26
+ PDFBool,
27
+ PDFDict,
28
+ PDFDocument,
29
+ PDFHexString,
30
+ PDFName,
31
+ PDFNumber,
32
+ PDFRawStream,
33
+ PDFStream,
34
+ PDFString,
35
+ concatTransformationMatrix,
24
36
  dataUriBytes,
25
37
  dataUriBytesOf,
38
+ embeddedFace,
39
+ fontCss,
40
+ fontkit,
26
41
  imageInfoOf,
42
+ isStandard,
43
+ loadFontkit,
44
+ loadPdfLib,
45
+ modelFontKeys,
46
+ popGraphicsState,
47
+ pushGraphicsState,
48
+ rgb,
27
49
  svgLength,
28
50
  svgRootAttrs,
29
51
  xmlAttrs,
30
52
  xmlTags
31
- } from "../chunk-Z7MKH66Z.js";
32
-
33
- // src/exporters/pdf.js
34
- import { PDFDocument, PDFName as PDFName3, PDFString as PDFString4, PDFHexString as PDFHexString5, PDFRawStream as PDFRawStream2, rgb as rgb3 } from "pdf-lib";
35
- import fontkitModule from "@pdf-lib/fontkit";
53
+ } from "./chunk-JQTRDHQP.js";
54
+ import "../chunk-GJS242RR.js";
36
55
 
37
56
  // src/exporters/pdfa.js
38
- import { PDFName, PDFNumber, PDFString, PDFHexString, PDFArray, PDFDict } from "pdf-lib";
39
57
  var xml = (s) => String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
40
58
  function makePdfA(doc, { icc, title = "Report", author, created = /* @__PURE__ */ new Date(), conformance = "B", ua = false, id } = {}) {
41
59
  if (!icc?.length) throw new Error("PDF/A needs an sRGB colour profile: pass pdfa.icc (public/icc/sRGB-v2-magic.icc)");
@@ -106,7 +124,6 @@ function setUaMetadata(doc, { title = "Report", author = void 0, created = /* @_
106
124
  }
107
125
 
108
126
  // src/exporters/svgimage.js
109
- import { pushGraphicsState, popGraphicsState, concatTransformationMatrix, rgb } from "pdf-lib";
110
127
  var mul = (a, b) => [a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], a[0] * b[4] + a[2] * b[5] + a[4], a[1] * b[4] + a[3] * b[5] + a[5]];
111
128
  var I = [1, 0, 0, 1, 0, 0];
112
129
  var TRANSFORMS = /* @__PURE__ */ new Set(["matrix", "translate", "scale", "rotate", "skewX", "skewY"]);
@@ -263,7 +280,6 @@ function drawSvg(page, svg, at) {
263
280
  }
264
281
 
265
282
  // src/exporters/encrypt.js
266
- import { PDFArray as PDFArray2, PDFDict as PDFDict2, PDFNumber as PDFNumber2, PDFString as PDFString2, PDFHexString as PDFHexString2, PDFRawStream, PDFStream, PDFBool } from "pdf-lib";
267
283
  var subtle = () => {
268
284
  const s = globalThis.crypto?.subtle;
269
285
  if (!s) throw new Error("PDF encryption needs WebCrypto (a browser, or Node 20 or later)");
@@ -337,12 +353,12 @@ async function encryptPdf(doc, opt) {
337
353
  };
338
354
  const seen = /* @__PURE__ */ new Set();
339
355
  const walk = async (obj) => {
340
- if (obj instanceof PDFString2 || obj instanceof PDFHexString2) return PDFHexString2.of(hex(await enc(obj.asBytes())));
341
- if (obj instanceof PDFArray2) {
356
+ if (obj instanceof PDFString || obj instanceof PDFHexString) return PDFHexString.of(hex(await enc(obj.asBytes())));
357
+ if (obj instanceof PDFArray) {
342
358
  for (let i = 0; i < obj.size(); i++) obj.set(i, await walk(obj.get(i)));
343
359
  return obj;
344
360
  }
345
- if (obj instanceof PDFDict2) {
361
+ if (obj instanceof PDFDict) {
346
362
  if (seen.has(obj)) return obj;
347
363
  seen.add(obj);
348
364
  for (const [k, v] of obj.entries()) obj.set(k, await walk(v));
@@ -367,21 +383,20 @@ async function encryptPdf(doc, opt) {
367
383
  CF: { StdCF: { AuthEvent: "DocOpen", CFM: "AESV3", Length: 32 } },
368
384
  StmF: "StdCF",
369
385
  StrF: "StdCF",
370
- O: PDFHexString2.of(hex(O)),
371
- U: PDFHexString2.of(hex(U)),
372
- OE: PDFHexString2.of(hex(OE)),
373
- UE: PDFHexString2.of(hex(UE)),
374
- P: PDFNumber2.of(P),
375
- Perms: PDFHexString2.of(hex(Perms)),
386
+ O: PDFHexString.of(hex(O)),
387
+ U: PDFHexString.of(hex(U)),
388
+ OE: PDFHexString.of(hex(OE)),
389
+ UE: PDFHexString.of(hex(UE)),
390
+ P: PDFNumber.of(P),
391
+ Perms: PDFHexString.of(hex(Perms)),
376
392
  EncryptMetadata: PDFBool.True
377
393
  });
378
394
  ctx.trailerInfo.Encrypt = ctx.register(encrypt);
379
- const id = PDFHexString2.of(hex(random(16)));
395
+ const id = PDFHexString.of(hex(random(16)));
380
396
  ctx.trailerInfo.ID = ctx.obj([id, id]);
381
397
  }
382
398
 
383
399
  // src/exporters/pdfua.js
384
- import { PDFName as PDFName2, PDFNumber as PDFNumber3, PDFHexString as PDFHexString3, PDFDict as PDFDict3, PDFArray as PDFArray3, PDFString as PDFString3 } from "pdf-lib";
385
400
  var MARKER = /^\s*(?:[•◦▪▫‣·○●■□–—-]|\d{1,4}[.)]|[a-zA-Z][.)]|[ivxlcdmIVXLCDM]{1,6}[.)])\s*$/;
386
401
  function createTagger(model, doc) {
387
402
  const ctx = doc.context;
@@ -411,6 +426,11 @@ function createTagger(model, doc) {
411
426
  /** A link annotation of item ii (or a field's widget): its structure element; returns its StructParent key. */
412
427
  annot(pi, ii, ref, kind) {
413
428
  const p = plans[pi].get(ii);
429
+ if (p?.link) {
430
+ p.link.kids.push({ objr: ref, pi });
431
+ annots.push({ ref, el: p.link, pi });
432
+ return;
433
+ }
414
434
  const el = node(kind === "field" ? "Form" : "Link");
415
435
  (p?.near || root).kids.push(el);
416
436
  el.parent = p?.near || root;
@@ -435,14 +455,14 @@ function createTagger(model, doc) {
435
455
  let key = 0;
436
456
  pages.forEach((pg, pi) => {
437
457
  if (!mcids[pi].length) return;
438
- pg.node.set(PDFName2.of("StructParents"), PDFNumber3.of(key));
439
- nums.push(PDFNumber3.of(key++), ctx.obj(mcids[pi].map((n) => refOf.get(n))));
458
+ pg.node.set(PDFName.of("StructParents"), PDFNumber.of(key));
459
+ nums.push(PDFNumber.of(key++), ctx.obj(mcids[pi].map((n) => refOf.get(n))));
440
460
  });
441
461
  for (const a of annots) {
442
462
  const d = ctx.lookup(a.ref);
443
- if (d instanceof PDFDict3) d.set(PDFName2.of("StructParent"), PDFNumber3.of(key));
444
- nums.push(PDFNumber3.of(key++), refOf.get(a.el));
445
- pages[a.pi]?.node.set(PDFName2.of("Tabs"), PDFName2.of("S"));
463
+ if (d instanceof PDFDict) d.set(PDFName.of("StructParent"), PDFNumber.of(key));
464
+ nums.push(PDFNumber.of(key++), refOf.get(a.el));
465
+ pages[a.pi]?.node.set(PDFName.of("Tabs"), PDFName.of("S"));
446
466
  }
447
467
  const treeRef = ctx.nextRef();
448
468
  for (const n of all) {
@@ -450,20 +470,20 @@ function createTagger(model, doc) {
450
470
  const K = n.kids.map((k) => {
451
471
  if (k.S) return refOf.get(k);
452
472
  if (k.objr) return ctx.obj({ Type: "OBJR", Obj: k.objr, Pg: pages[k.pi].ref });
453
- return k.pi === pgOf ? PDFNumber3.of(k.mcid) : ctx.obj({ Type: "MCR", Pg: pages[k.pi].ref, MCID: k.mcid });
473
+ return k.pi === pgOf ? PDFNumber.of(k.mcid) : ctx.obj({ Type: "MCR", Pg: pages[k.pi].ref, MCID: k.mcid });
454
474
  });
455
475
  const d = ctx.obj({ Type: "StructElem", S: n.S, P: n === root ? treeRef : refOf.get(n.parent || root), K });
456
- if (pgOf != null) d.set(PDFName2.of("Pg"), pages[pgOf].ref);
457
- if (n.alt != null) d.set(PDFName2.of("Alt"), PDFHexString3.fromText(n.alt));
458
- if (n.attrs) d.set(PDFName2.of("A"), ctx.obj(n.attrs));
476
+ if (pgOf != null) d.set(PDFName.of("Pg"), pages[pgOf].ref);
477
+ if (n.alt != null) d.set(PDFName.of("Alt"), PDFHexString.fromText(n.alt));
478
+ if (n.attrs) d.set(PDFName.of("A"), ctx.obj(n.attrs));
459
479
  ctx.assign(refOf.get(n), d);
460
480
  }
461
481
  ctx.assign(treeRef, ctx.obj({ Type: "StructTreeRoot", K: refOf.get(root), ParentTree: ctx.obj({ Nums: nums }), ParentTreeNextKey: key }));
462
482
  const cat2 = doc.catalog;
463
- cat2.set(PDFName2.of("StructTreeRoot"), treeRef);
464
- cat2.set(PDFName2.of("MarkInfo"), ctx.obj({ Marked: true }));
465
- cat2.set(PDFName2.of("Lang"), PDFString3.of(String(lang).replace(/[^A-Za-z0-9-]/g, "") || "en"));
466
- cat2.set(PDFName2.of("ViewerPreferences"), ctx.obj({ DisplayDocTitle: true }));
483
+ cat2.set(PDFName.of("StructTreeRoot"), treeRef);
484
+ cat2.set(PDFName.of("MarkInfo"), ctx.obj({ Marked: true }));
485
+ cat2.set(PDFName.of("Lang"), PDFString.of(String(lang).replace(/[^A-Za-z0-9-]/g, "") || "en"));
486
+ cat2.set(PDFName.of("ViewerPreferences"), ctx.obj({ DisplayDocTitle: true }));
467
487
  doc.setTitle(title, { showInWindowTitleBar: true });
468
488
  }
469
489
  };
@@ -515,8 +535,38 @@ function plan(model, pg, pi, root) {
515
535
  return el;
516
536
  };
517
537
  let lastText = null;
538
+ const tocLink = (e) => {
539
+ const toc = root.toc || (root.toc = { el: null, last: -1, entries: /* @__PURE__ */ new Map() });
540
+ if (!toc.el || e < toc.last) {
541
+ toc.el = add(node("TOC"));
542
+ toc.entries = /* @__PURE__ */ new Map();
543
+ }
544
+ toc.last = Math.max(toc.last, e);
545
+ let link = toc.entries.get(e);
546
+ if (!link) {
547
+ const toci = node("TOCI"), ref = node("Reference");
548
+ link = node("Link");
549
+ toci.parent = toc.el;
550
+ toc.el.kids.push(toci);
551
+ ref.parent = toci;
552
+ toci.kids.push(ref);
553
+ link.parent = ref;
554
+ ref.kids.push(link);
555
+ toc.entries.set(e, link);
556
+ }
557
+ return link;
558
+ };
518
559
  items.forEach((it, i) => {
519
560
  if (it.t === "bookmark") return;
561
+ if (it.tocEntry != null && (it.t === "text" || it.t === "link") && !it.art) {
562
+ const link = tocLink(it.tocEntry);
563
+ out.set(i, it.t === "link" ? { link } : { el: link });
564
+ return;
565
+ }
566
+ if (it.tocTitle && it.t === "text" && it.lines?.length) {
567
+ out.set(i, { el: add(node("H1")) });
568
+ return;
569
+ }
520
570
  if (it.t === "link" || it.t === "field") {
521
571
  out.set(i, { near: lastText && overlaps(lastText.it, it) ? lastText.el : null });
522
572
  return;
@@ -748,8 +798,293 @@ function pngProblem(b) {
748
798
  return null;
749
799
  }
750
800
 
801
+ // src/exporters/pdfstream.js
802
+ import { Zlib, deflateSync, inflateSync } from "fflate";
803
+
804
+ // src/exporters/pdfstreamtags.js
805
+ function createStreamTagger(w, { maxElements = Infinity } = {}) {
806
+ let count = 0;
807
+ const made = () => {
808
+ if (++count > maxElements) throw Object.assign(new Error(`The tagged PDF has more than ${maxElements.toLocaleString("en-US")} structure elements (tagged.maxElements). Filter the data, or export it untagged.`), { status: 413 });
809
+ };
810
+ const rootRef = w.reserve(), docRef = w.reserve();
811
+ const docKids = [];
812
+ let table = (
813
+ /** @type {null | { ref: number, cols: number, rows: Int32Array, n: number }} */
814
+ null
815
+ );
816
+ let headerDone = false;
817
+ let nums = new Int32Array(1024), nn = 0, key = 0;
818
+ const num3 = (k, ref) => {
819
+ if (nn + 2 > nums.length) {
820
+ const b = new Int32Array(nums.length * 2);
821
+ b.set(nums);
822
+ nums = b;
823
+ }
824
+ nums[nn++] = k;
825
+ nums[nn++] = ref;
826
+ };
827
+ const addRow = (ref) => {
828
+ const t = (
829
+ /** @type {any} */
830
+ table
831
+ );
832
+ if (t.n === t.rows.length) {
833
+ const b = new Int32Array(t.n * 2);
834
+ b.set(t.rows);
835
+ t.rows = b;
836
+ }
837
+ t.rows[t.n++] = ref;
838
+ };
839
+ let mcids = (
840
+ /** @type {number[]} */
841
+ []
842
+ );
843
+ let rows = /* @__PURE__ */ new Map();
844
+ let els = (
845
+ /** @type {any[]} */
846
+ []
847
+ );
848
+ let last = (
849
+ /** @type {any} */
850
+ null
851
+ );
852
+ let links = false, win = 0;
853
+ const el = (S, parent, attrs2) => {
854
+ made();
855
+ const e = { ref: w.reserve(), S, parent, mcid: (
856
+ /** @type {number[]} */
857
+ []
858
+ ), kids: (
859
+ /** @type {any[]} */
860
+ []
861
+ ), attrs: attrs2 };
862
+ els.push(e);
863
+ return e;
864
+ };
865
+ const mark = (e) => {
866
+ const m = mcids.length;
867
+ mcids.push(e.ref);
868
+ e.mcid.push(m);
869
+ return `/${e.S} <</MCID ${m}>> BDC
870
+ `;
871
+ };
872
+ return {
873
+ /** structure elements so far */
874
+ get count() {
875
+ return count;
876
+ },
877
+ /** elements of the page being drawn, held until it ends */
878
+ get held() {
879
+ return els.length + rows.size + mcids.length;
880
+ },
881
+ /** a new page (window: the paged window it came from; row ids are its own) @param {number} window */
882
+ page(window) {
883
+ mcids = [];
884
+ rows = /* @__PURE__ */ new Map();
885
+ els = [];
886
+ last = null;
887
+ links = false;
888
+ win = window;
889
+ },
890
+ /**
891
+ * The marked content that opens item it: a structure element's MCID, or an artifact; null for a link.
892
+ * @param {any} it
893
+ */
894
+ open(it) {
895
+ if (it.t === "link" || it.t === "bookmark") return null;
896
+ if (it.art) return "/Artifact <</Type /Pagination>> BDC\n";
897
+ if (it.t !== "text" || !it.lines?.some((l) => String(l.text).trim())) return "/Artifact BMC\n";
898
+ const c = it.cell;
899
+ if (!c) {
900
+ const h = it.tag?.h ? Math.min(6, Math.max(1, it.tag.h)) : 0;
901
+ const e = el(h ? `H${h}` : "P", docRef);
902
+ docKids.push(e.ref);
903
+ last = { e, it };
904
+ return mark(e);
905
+ }
906
+ if (c.kind === "header" && headerDone) return "/Artifact <</Type /Pagination>> BDC\n";
907
+ if (!table) {
908
+ table = { ref: w.reserve(), cols: c.cols.length, rows: new Int32Array(4096), n: 0 };
909
+ docKids.push(table.ref);
910
+ }
911
+ const rk = `${win}:${c.row}`;
912
+ let r = rows.get(rk);
913
+ if (!r) {
914
+ made();
915
+ r = { ref: w.reserve(), kind: c.kind, cells: /* @__PURE__ */ new Map() };
916
+ rows.set(rk, r);
917
+ addRow(r.ref);
918
+ }
919
+ let cell = r.cells.get(c.col);
920
+ if (!cell) {
921
+ const attrs2 = c.kind === "header" || c.span > 1 ? { O: "/Table", ...c.kind === "header" ? { Scope: "/Column" } : {}, ...c.span > 1 ? { ColSpan: c.span } : {} } : null;
922
+ cell = el(c.kind === "header" ? "TH" : "TD", r.ref, attrs2);
923
+ r.cells.set(c.col, cell);
924
+ }
925
+ last = { e: cell, it };
926
+ return mark(cell);
927
+ },
928
+ /**
929
+ * A link annotation of the page: its Link element (in the element of the text it covers, else the Document).
930
+ * @returns {number} the annotation's StructParent
931
+ * @param {any} it @param {number} annot the annotation's object number
932
+ */
933
+ link(it, annot) {
934
+ const near = last && overlaps2(last.it, it) ? last.e : null;
935
+ const e = el("Link", near ? near.ref : docRef);
936
+ e.kids.push(`<< /Type /OBJR /Obj ${annot} 0 R >>`);
937
+ (near ? near.kids : docKids).push(near ? `${e.ref} 0 R` : e.ref);
938
+ links = true;
939
+ num3(key, e.ref);
940
+ return key++;
941
+ },
942
+ /**
943
+ * The page is drawn: its elements and parent-tree array are written. @returns {Promise<string>} the page's entries
944
+ * @param {number} pageRef
945
+ */
946
+ async end(pageRef) {
947
+ for (const r of rows.values()) {
948
+ const kids = [];
949
+ for (let col2 = 0; col2 < /** @type {any} */
950
+ table.cols; ) {
951
+ let cell = r.cells.get(col2);
952
+ if (!cell) {
953
+ cell = el(r.kind === "header" ? "TH" : "TD", r.ref, r.kind === "header" ? { O: "/Table", Scope: "/Column" } : null);
954
+ }
955
+ kids.push(cell.ref);
956
+ col2 += Math.max(1, cell.attrs?.ColSpan || 1);
957
+ }
958
+ for (const [col2, cell] of r.cells) if (!kids.includes(cell.ref)) {
959
+ void col2;
960
+ kids.push(cell.ref);
961
+ }
962
+ await w.objectAt(r.ref, `<< /S /TR /P ${/** @type {any} */
963
+ table.ref} 0 R /K [${kids.map((k) => `${k} 0 R`).join(" ")}] >>`);
964
+ }
965
+ if (rows.size && [...rows.values()].some((r) => r.kind === "header")) headerDone = true;
966
+ for (const e of els) {
967
+ const K = [...e.mcid.map(String), ...e.kids].join(" ");
968
+ const A = e.attrs ? ` /A << ${Object.entries(e.attrs).map(([k, v]) => `/${k} ${v}`).join(" ")} >>` : "";
969
+ const P = e.parent === docRef ? docRef : e.parent;
970
+ await w.objectAt(e.ref, `<< /S /${e.S} /P ${P} 0 R${e.mcid.length || e.S === "Link" ? ` /Pg ${pageRef} 0 R` : ""} /K [${K}]${A} >>`);
971
+ }
972
+ let extra = "";
973
+ if (mcids.length) {
974
+ const arr = await w.object(`[${mcids.map((r) => `${r} 0 R`).join(" ")}]`);
975
+ num3(key, arr);
976
+ extra += ` /StructParents ${key++}`;
977
+ }
978
+ if (links) extra += " /Tabs /S";
979
+ mcids = [];
980
+ rows = /* @__PURE__ */ new Map();
981
+ els = [];
982
+ last = null;
983
+ return extra;
984
+ },
985
+ /**
986
+ * The tree's top: Table, Document, the parent tree, the root. @returns {Promise<string>} the catalog's entries
987
+ * @param {{ lang?: string }} o
988
+ */
989
+ async finish({ lang = "en" } = {}) {
990
+ const t = table;
991
+ if (t) await w.bigObject(t.ref, `<< /Type /StructElem /S /Table /P ${docRef} 0 R /K [`, refs(t.rows, t.n), "] >>");
992
+ await w.objectAt(docRef, `<< /Type /StructElem /S /Document /P ${rootRef} 0 R /K [${docKids.map((k) => typeof k === "string" ? k : `${k} 0 R`).join(" ")}] >>`);
993
+ const pt = w.reserve();
994
+ await w.bigObject(pt, "<< /Nums [", pairs(nums, nn), "] >>");
995
+ await w.objectAt(rootRef, `<< /Type /StructTreeRoot /K ${docRef} 0 R /ParentTree ${pt} 0 R /ParentTreeNextKey ${key} >>`);
996
+ return ` /StructTreeRoot ${rootRef} 0 R /MarkInfo << /Marked true >> /Lang (${String(lang).replace(/[^A-Za-z0-9-]/g, "") || "en"}) /ViewerPreferences << /DisplayDocTitle true >>`;
997
+ }
998
+ };
999
+ }
1000
+ function* refs(a, n) {
1001
+ for (let i = 0; i < n; i += 4096) {
1002
+ let s = "";
1003
+ for (let j = i; j < Math.min(n, i + 4096); j++) s += `${a[j]} 0 R `;
1004
+ yield s;
1005
+ }
1006
+ }
1007
+ function* pairs(a, n) {
1008
+ for (let i = 0; i < n; i += 4096) {
1009
+ let s = "";
1010
+ for (let j = i; j < Math.min(n, i + 4096); j += 2) s += `${a[j]} ${a[j + 1]} 0 R `;
1011
+ yield s;
1012
+ }
1013
+ }
1014
+ function overlaps2(t, l) {
1015
+ const c = t.clip || { x: t.lines[0].x, y: t.lines[0].y - t.size, w: t.lines[0].w || 0, h: t.size * 1.3 };
1016
+ return l.x < c.x + c.w && c.x < l.x + l.w && l.y < c.y + c.h && c.y < l.y + l.h;
1017
+ }
1018
+
1019
+ // src/exporters/pdfstandard.js
1020
+ function standardFontEntries(f) {
1021
+ return {
1022
+ Type: "Font",
1023
+ Subtype: "Type1",
1024
+ BaseFont: f.postscriptName,
1025
+ ...f.winAnsi ? { Encoding: "WinAnsiEncoding" } : {},
1026
+ FirstChar: 32,
1027
+ LastChar: 255,
1028
+ Widths: f.widths.slice(32, 256)
1029
+ };
1030
+ }
1031
+ function standardFontDict(f) {
1032
+ const e = standardFontEntries(f);
1033
+ return `<< /Type /Font /Subtype /Type1 /BaseFont /${e.BaseFont}${e.Encoding ? ` /Encoding /${e.Encoding}` : ""} /FirstChar 32 /LastChar 255 /Widths [${e.Widths.join(" ")}] >>`;
1034
+ }
1035
+ var standIns = (store) => [...new Set([...store.fonts.keys()].filter(isStandard).map(embeddedFace))];
1036
+ var esc = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
1037
+ function standardLiteral(f, text) {
1038
+ let out = "";
1039
+ for (const ch of text) out += esc(f.glyphForCodePoint(
1040
+ /** @type {number} */
1041
+ ch.codePointAt(0)
1042
+ ).id);
1043
+ return out;
1044
+ }
1045
+ function embeddedPage(pg, fontOf, families) {
1046
+ const line = (l, key, size) => {
1047
+ const runs = l.runs || [{ font: key, x: 0, text: l.text, glyphs: null }];
1048
+ if (!runs.some((r) => isStandard(r.font))) return l;
1049
+ return { ...l, runs: runs.map((r) => {
1050
+ if (!isStandard(r.font)) return r;
1051
+ families.add(fontCss(r.font).family);
1052
+ const std = fontOf(r.font), sub = embeddedFace(r.font), emb = fontOf(sub);
1053
+ const glyphs = [];
1054
+ if (r.glyphs) {
1055
+ for (let i = 0; i < r.glyphs.length; i += 4) glyphs.push(emb.glyphForCodePoint(r.text.codePointAt(r.glyphs[i + 3])).id, r.glyphs[i + 1], r.glyphs[i + 2], r.glyphs[i + 3]);
1056
+ return { ...r, font: sub, glyphs };
1057
+ }
1058
+ let pen = 0;
1059
+ for (let i = 0; i < r.text.length; ) {
1060
+ const cp = (
1061
+ /** @type {number} */
1062
+ r.text.codePointAt(i)
1063
+ );
1064
+ glyphs.push(emb.glyphForCodePoint(cp).id, pen, 0, i);
1065
+ pen += std.glyphForCodePoint(cp).advanceWidth * size / 1e3;
1066
+ i += cp > 65535 ? 2 : 1;
1067
+ }
1068
+ return { ...r, font: sub, w: pen, glyphs };
1069
+ }) };
1070
+ };
1071
+ const item = (it) => {
1072
+ if (it.t === "field") {
1073
+ const draw = it.draw.map(item);
1074
+ return draw.some((d, i) => d !== it.draw[i]) ? { ...it, draw } : it;
1075
+ }
1076
+ if (it.t !== "text") return it;
1077
+ const lines = it.lines.map((l) => line(l, it.font, it.size));
1078
+ return lines.some((l, i) => l !== it.lines[i]) ? { ...it, lines } : it;
1079
+ };
1080
+ const items = pg.items.map(item);
1081
+ return items.some((x, i) => x !== pg.items[i]) ? { ...pg, items } : pg;
1082
+ }
1083
+ function embeddedWarnings(families) {
1084
+ return [...families].map((f) => `PDF/A and PDF/UA need embedded fonts, and "${f}" is a standard font that is not embedded: its text is drawn in ${fontCss(embeddedFace(f)).family} at ${f}'s spacing (no metric-compatible font ships, so the letters' widths differ).`);
1085
+ }
1086
+
751
1087
  // src/exporters/pdfpaint.js
752
- import { PDFHexString as PDFHexString4, rgb as rgb2 } from "pdf-lib";
753
1088
  var colors = /* @__PURE__ */ new Map();
754
1089
  var col = (c) => {
755
1090
  if (colors.has(c)) return colors.get(c);
@@ -758,6 +1093,17 @@ var col = (c) => {
758
1093
  return v;
759
1094
  };
760
1095
  var BLACK = { color: rgb2(0, 0, 0), opacity: 1, rgb: "0 0 0" };
1096
+ function rgb2(red, green, blue) {
1097
+ return { type: (
1098
+ /** @type {any} */
1099
+ "RGB"
1100
+ ), red, green, blue };
1101
+ }
1102
+ var hexText = (s) => {
1103
+ let h = "<FEFF";
1104
+ for (let i = 0; i < s.length; i++) h += s.charCodeAt(i).toString(16).toUpperCase().padStart(4, "0");
1105
+ return `${h}>`;
1106
+ };
761
1107
  var n2 = (v) => Math.round(v * 100) / 100;
762
1108
  var n3 = (v) => Math.round(v * 1e3) / 1e3;
763
1109
  var n4 = (v) => Math.round(v * 1e4) / 1e4;
@@ -771,7 +1117,7 @@ var formatAt = (run, cl) => {
771
1117
  function drawRun(c, run, x, y, size, pf, color, spans, texts) {
772
1118
  const f = pf.embedder.font;
773
1119
  const per = 1e3 / size;
774
- const span = (text) => `/Span <</ActualText ${PDFHexString4.fromText(text).toString()}>> BDC
1120
+ const span = (text) => `/Span <</ActualText ${hexText(text)}>> BDC
775
1121
  `;
776
1122
  c.et();
777
1123
  c.paint(color, null);
@@ -822,7 +1168,7 @@ function drawRun(c, run, x, y, size, pf, color, spans, texts) {
822
1168
  const adj = Math.round((pen - gx) * per * 1e3) / 1e3;
823
1169
  if (id === 0 && (c.tagged || formatAt(run, cl))) pen = gx;
824
1170
  else {
825
- arr += (adj ? `${adj}` : "") + `<${hex4(id)}>`;
1171
+ arr += (adj ? `${adj}` : "") + `<${f.standard ? id.toString(16).padStart(2, "0") : hex4(id)}>`;
826
1172
  pen = gx + adv(id) * size / f.unitsPerEm;
827
1173
  }
828
1174
  if (inSpan && (i + 4 >= g.length || (quietAt < 0 || i + 4 < quietAt) && g[i + 7] !== cl || i + 4 === quietAt)) {
@@ -1081,11 +1427,885 @@ async function deflateNow(bytes) {
1081
1427
  return new Uint8Array(await new Response(new Blob([bytes]).stream().pipeThrough(new CompressionStream("deflate"))).arrayBuffer());
1082
1428
  }
1083
1429
 
1430
+ // src/exporters/pdfstream.js
1431
+ var CHUNK = 64 * 1024;
1432
+ var LEAF = 64;
1433
+ var OBJSTM = 100;
1434
+ var XBITS = 14;
1435
+ var XB = 1 << XBITS;
1436
+ var TAGGED_LARGE = 1e6;
1437
+ var IN_FLIGHT = 8;
1438
+ var hex42 = (id) => id.toString(16).padStart(4, "0");
1439
+ var num2 = (v) => String(Math.round(v * 1e3) / 1e3);
1440
+ var fontRes = (key) => `F_${key.replace(/[^A-Za-z0-9.-]/g, "_")}`;
1441
+ var esc2 = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
1442
+ function written(sink, r) {
1443
+ const s = (
1444
+ /** @type {any} */
1445
+ sink
1446
+ );
1447
+ if (r !== false || !s.once) return Promise.resolve(r);
1448
+ return new Promise((ok, fail) => {
1449
+ const off = () => {
1450
+ s.off?.("drain", onDrain);
1451
+ s.off?.("error", onError);
1452
+ s.off?.("close", onClose);
1453
+ };
1454
+ const onDrain = () => {
1455
+ off();
1456
+ ok(void 0);
1457
+ };
1458
+ const onError = (e) => {
1459
+ off();
1460
+ fail(e);
1461
+ };
1462
+ const onClose = () => {
1463
+ off();
1464
+ fail(Object.assign(new Error("The sink closed before the PDF was written"), { code: "ERR_STREAM_PREMATURE_CLOSE" }));
1465
+ };
1466
+ s.once("drain", onDrain);
1467
+ s.once("error", onError);
1468
+ s.once("close", onClose);
1469
+ });
1470
+ }
1471
+ function raced(p, signal) {
1472
+ if (!signal) return p;
1473
+ if (signal.aborted) {
1474
+ p.catch(() => {
1475
+ });
1476
+ return Promise.reject(signal.reason);
1477
+ }
1478
+ return new Promise((ok, fail) => {
1479
+ const on = () => fail(signal.reason);
1480
+ signal.addEventListener("abort", on, { once: true });
1481
+ p.then((v) => {
1482
+ signal.removeEventListener("abort", on);
1483
+ ok(v);
1484
+ }, (e) => {
1485
+ signal.removeEventListener("abort", on);
1486
+ fail(e);
1487
+ });
1488
+ });
1489
+ }
1490
+ function createPdfStream(sink, opt) {
1491
+ const { fontStore } = opt;
1492
+ let pos = 0, nextNum = 0;
1493
+ const blocks = [];
1494
+ const late = /* @__PURE__ */ new Map();
1495
+ let packed = 0;
1496
+ const place = (n, k, l, i = 0) => {
1497
+ const b = blocks[n >>> XBITS];
1498
+ if (b instanceof Uint8Array) {
1499
+ late.set(n, k * 2 ** 48 + l * 2 ** 16 + i);
1500
+ return;
1501
+ }
1502
+ const j = n & XB - 1;
1503
+ b.kind[j] = k;
1504
+ b.loc[j] = l;
1505
+ b.idx[j] = i;
1506
+ };
1507
+ const reserve = () => {
1508
+ const n = nextNum++;
1509
+ if (!(n & XB - 1)) {
1510
+ blocks.push({ kind: new Uint8Array(XB), loc: new Uint32Array(XB), idx: new Uint16Array(XB) });
1511
+ const old = blocks.length - 3, b = blocks[old];
1512
+ if (old > 0 && !(b instanceof Uint8Array)) {
1513
+ for (let j = 0; j < XB; j++) if (b.kind[j] !== 1 && b.kind[j] !== 2) late.set(old * XB + j, b.kind[j] * 2 ** 48);
1514
+ const raw = new Uint8Array(XB * 7);
1515
+ raw.set(b.kind);
1516
+ raw.set(new Uint8Array(b.loc.buffer), XB);
1517
+ raw.set(new Uint8Array(b.idx.buffer), XB * 5);
1518
+ packed += (blocks[old] = deflateSync(raw, { level: 1 })).length;
1519
+ }
1520
+ }
1521
+ return n;
1522
+ };
1523
+ let reading = [-1, null];
1524
+ const where = (n) => {
1525
+ const v = late.get(n);
1526
+ if (v !== void 0) return [Math.floor(v / 2 ** 48), Math.floor(v / 2 ** 16) % 2 ** 32, v % 2 ** 16];
1527
+ const bi = n >>> XBITS, j = n & XB - 1;
1528
+ const z = blocks[bi];
1529
+ if (z instanceof Uint8Array && reading[0] !== bi) {
1530
+ const raw = inflateSync(z);
1531
+ reading = [bi, { kind: raw.subarray(0, XB), loc: new Uint32Array(raw.buffer, raw.byteOffset + XB, XB), idx: new Uint16Array(raw.buffer, raw.byteOffset + XB * 5, XB) }];
1532
+ }
1533
+ const b = z instanceof Uint8Array ? reading[1] : z;
1534
+ return [b.kind[j], b.loc[j], b.idx[j]];
1535
+ };
1536
+ reserve();
1537
+ let parts = [];
1538
+ let size = 0;
1539
+ const flush = async () => {
1540
+ if (!size) return;
1541
+ const all = new Uint8Array(size);
1542
+ let at = 0;
1543
+ for (const p of parts) {
1544
+ all.set(p, at);
1545
+ at += p.length;
1546
+ }
1547
+ parts = [];
1548
+ size = 0;
1549
+ await raced(written(sink, sink.write(all)), opt.signal);
1550
+ };
1551
+ const put = (x) => {
1552
+ const u8 = typeof x === "string" ? latin12(x) : x;
1553
+ parts.push(u8);
1554
+ size += u8.length;
1555
+ pos += u8.length;
1556
+ return size >= CHUNK ? flush() : void 0;
1557
+ };
1558
+ let batch = [];
1559
+ const writeBatch = async () => {
1560
+ if (!batch.length) return;
1561
+ const b = batch;
1562
+ batch = [];
1563
+ const sn = reserve();
1564
+ let head = "", body = "";
1565
+ b.forEach(([n, d], i) => {
1566
+ head += `${n} ${body.length} `;
1567
+ body += `${d}
1568
+ `;
1569
+ place(n, 2, sn, i);
1570
+ });
1571
+ const raw = latin12(head + body);
1572
+ await writeObj(sn, `<< /Type /ObjStm /N ${b.length} /First ${head.length} /Filter /FlateDecode >>`, await deflate(raw));
1573
+ };
1574
+ const writeObj = async (n, dict, stream) => {
1575
+ if (!stream) {
1576
+ batch.push([n, dict]);
1577
+ place(n, 3, 0);
1578
+ return batch.length >= OBJSTM ? writeBatch() : void 0;
1579
+ }
1580
+ place(n, 1, pos);
1581
+ await put(`${n} 0 obj
1582
+ ${dict.replace(/>>\s*$/, `/Length ${stream.length} >>`)}
1583
+ stream
1584
+ `);
1585
+ await put(stream);
1586
+ return put("\nendstream\nendobj\n");
1587
+ };
1588
+ put("%PDF-1.7\n%âãÏÓ\n");
1589
+ const fonts = /* @__PURE__ */ new Map();
1590
+ let pages = 0, done = false;
1591
+ const inFlight = [];
1592
+ const fontOf = (key) => {
1593
+ let f = fonts.get(key);
1594
+ if (!f) {
1595
+ if (done) throw new Error("The PDF is finished");
1596
+ fonts.set(key, f = { name: fontRes(key), ref: reserve(), font: fontStore.get(key), cps: /* @__PURE__ */ new Set([32]), glyphs: /* @__PURE__ */ new Map(), memo: /* @__PURE__ */ new Map(), lit: /* @__PURE__ */ new Map() });
1597
+ }
1598
+ return f;
1599
+ };
1600
+ const resRef = reserve();
1601
+ for (const key of opt.fonts || []) fontOf(key);
1602
+ const res = /* @__PURE__ */ new Map();
1603
+ const totals = [];
1604
+ const pageRefs = [];
1605
+ const leaves = [];
1606
+ const w = {
1607
+ /** @param {string} key @returns {string} the font's resource name (F1…) */
1608
+ fontName: (key) => fontOf(key).name,
1609
+ /**
1610
+ * The text's glyphs, one per character (as the engine measured it: no layout features), as hex for <…> Tj, with
1611
+ * the glyphs recorded for the subset, W and ToUnicode.
1612
+ * @param {string} key @param {string} text
1613
+ */
1614
+ encode(key, text) {
1615
+ const F = fontOf(key);
1616
+ let out = "";
1617
+ for (const ch of text) {
1618
+ const cp = (
1619
+ /** @type {number} */
1620
+ ch.codePointAt(0)
1621
+ );
1622
+ let h = F.memo.get(cp);
1623
+ if (h === void 0) {
1624
+ const id = F.font.glyphForCodePoint(cp).id;
1625
+ F.memo.set(cp, h = F.font.standard ? id.toString(16).padStart(2, "0") : hex42(id));
1626
+ F.cps.add(cp);
1627
+ if (!F.glyphs.has(id)) F.glyphs.set(id, ch);
1628
+ }
1629
+ out += h;
1630
+ }
1631
+ return out;
1632
+ },
1633
+ /**
1634
+ * The same glyphs as a literal string's body, two bytes each, escaped (as pdf.js draws plain text): ( … ) Tj.
1635
+ * @param {string} key @param {string} text
1636
+ */
1637
+ literal(key, text) {
1638
+ const F = fontOf(key);
1639
+ let out = "";
1640
+ for (const ch of text) {
1641
+ const cp = (
1642
+ /** @type {number} */
1643
+ ch.codePointAt(0)
1644
+ );
1645
+ let b = F.lit.get(cp);
1646
+ if (b === void 0) {
1647
+ const id = parseInt(w.encode(key, ch), 16);
1648
+ F.lit.set(cp, b = F.font.standard ? esc2(id) : esc2(id >> 8) + esc2(id & 255));
1649
+ }
1650
+ out += b;
1651
+ }
1652
+ return out;
1653
+ },
1654
+ /**
1655
+ * Shaped glyphs drawn by ID (conjuncts, joined forms): [glyph ID, the text it stands for ('' for none)].
1656
+ * @param {string} key @param {Iterable<[number, string]>} glyphs
1657
+ */
1658
+ addGlyphs(key, glyphs) {
1659
+ const F = fontOf(key);
1660
+ for (const [id, text] of glyphs) if (!F.glyphs.has(id)) F.glyphs.set(id, text);
1661
+ },
1662
+ /**
1663
+ * A name in the shared Resources dictionary for a value (an indirect ref "12 0 R" or an inline dictionary).
1664
+ * @param {'ExtGState'|'XObject'|'Pattern'|'Shading'|'ColorSpace'} kind @param {string} value
1665
+ */
1666
+ resource(kind, value, name = void 0) {
1667
+ let m = res.get(kind);
1668
+ if (!m) res.set(kind, m = /* @__PURE__ */ new Map());
1669
+ let n = m.get(value);
1670
+ if (!n) m.set(value, n = name || `${kind === "ExtGState" ? "GS" : kind[0]}${m.size + 1}`);
1671
+ return n;
1672
+ },
1673
+ /**
1674
+ * The ExtGState name for fill and stroke opacity, named by its values (the same name in every writer: pages
1675
+ * painted elsewhere, parallel.js, use it too). @param {number} ca @param {number} CA
1676
+ */
1677
+ gs: (ca, CA) => w.resource("ExtGState", `<< /Type /ExtGState /ca ${num2(ca)} /CA ${num2(CA)} >>`, `GS${num2(ca)}_${num2(CA)}`),
1678
+ /** What this writer's pages used, for another writer to take over (pages painted elsewhere). */
1679
+ used: () => ({ fonts: [...fonts].map(([key, F]) => [key, [...F.cps], [...F.glyphs]]), gs: [...res.get("ExtGState")?.keys() || []] }),
1680
+ /** Take over what pages painted elsewhere used (used() of their writer). @param {any} u */
1681
+ take(u) {
1682
+ for (const [key, cps, glyphs] of u.fonts) {
1683
+ const F = fontOf(key);
1684
+ for (const cp of cps) F.cps.add(cp);
1685
+ for (const [id, t] of glyphs) if (!F.glyphs.has(id)) F.glyphs.set(id, t);
1686
+ }
1687
+ for (const v of u.gs) {
1688
+ const m = (
1689
+ /** @type {any} */
1690
+ v.match(/\/ca (\S+) \/CA (\S+)/)
1691
+ );
1692
+ w.gs(Number(m[1]), Number(m[2]));
1693
+ }
1694
+ },
1695
+ /**
1696
+ * Write an object now (an image: its dictionary and its stream, already filtered). @returns {Promise<number>} its number
1697
+ * @param {string} dict @param {Uint8Array} [stream]
1698
+ */
1699
+ async object(dict, stream) {
1700
+ const n = reserve();
1701
+ await writeObj(n, dict, stream);
1702
+ return n;
1703
+ },
1704
+ /** Bytes held for the cross-reference: the open blocks, the deflated ones, the late entries (a Map's ~40 each). */
1705
+ get xrefBytes() {
1706
+ return blocks.reduce((t, b) => t + (b instanceof Uint8Array ? 0 : XB * 7), packed + late.size * 40);
1707
+ },
1708
+ /** An object number to write later (objectAt). */
1709
+ reserve: () => reserve(),
1710
+ /** Write a reserved object. @param {number} n @param {string} dict @param {Uint8Array} [stream] */
1711
+ objectAt: (n, dict, stream) => writeObj(n, dict, stream),
1712
+ /**
1713
+ * Write a reserved object whose text may be long (an array of every row's element): head, the parts as they come,
1714
+ * tail; written out in place, never held whole. @param {number} n @param {string} head @param {Iterable<string>} parts @param {string} tail
1715
+ */
1716
+ async bigObject(n, head, parts2, tail) {
1717
+ place(n, 1, pos);
1718
+ await put(`${n} 0 obj
1719
+ ${head}`);
1720
+ for (const x of parts2) await put(x);
1721
+ await put(`${tail}
1722
+ endobj
1723
+ `);
1724
+ },
1725
+ /** The object number of page i (0-based), written or not: links and outline entries may point ahead. @param {number} i */
1726
+ pageRef(i) {
1727
+ return pageRefs[i] ?? (pageRefs[i] = reserve());
1728
+ },
1729
+ /**
1730
+ * The total page count, drawn at the end: a Form XObject whose origin is the text's baseline at the box's left;
1731
+ * draw it with `q 1 0 0 1 x y cm /<name> Do Q`. align: within width.
1732
+ * @param {{ font: string, size: number, width: number, align?: 'left'|'center'|'right', color?: string }} o
1733
+ */
1734
+ totalPages(o) {
1735
+ fontOf(o.font);
1736
+ const ref = reserve();
1737
+ totals.push({ ref, font: o.font, size: o.size, width: o.width, align: o.align || "left", color: o.color || "0 0 0" });
1738
+ return w.resource("XObject", `${ref} 0 R`);
1739
+ },
1740
+ /**
1741
+ * Write a page: its content stream (deflated) and its dictionary, now. Nothing of it stays but two offsets.
1742
+ * @param {{ width: number, height: number, content?: string | Uint8Array, deflated?: Uint8Array, annots?: (string | { ref: number, dict: string })[], extra?: string }} p
1743
+ * deflated: the content stream already compressed (zlib), as pages painted elsewhere come.
1744
+ * content: the page's operators (a string holds bytes 0–255, as pdf.js's Content makes). annots: annotation
1745
+ * dictionaries (with a reserved number: { ref, dict }). extra: more entries for the page dictionary (/StructParents 3).
1746
+ */
1747
+ async addPage(p) {
1748
+ if (done) throw new Error("The PDF is finished");
1749
+ const i = pages++;
1750
+ const ref = w.pageRef(i);
1751
+ if (i % LEAF === 0) leaves.push(reserve());
1752
+ const contents = reserve(), parent = leaves[leaves.length - 1];
1753
+ const z = p.deflated ? Promise.resolve(p.deflated) : deflate(typeof p.content === "string" ? latin12(p.content) : p.content);
1754
+ z.catch(() => {
1755
+ });
1756
+ inFlight.push({ ref, contents, parent, p: { width: p.width, height: p.height, annots: p.annots, extra: p.extra }, z });
1757
+ while (inFlight.length > IN_FLIGHT) await writeNext();
1758
+ },
1759
+ /**
1760
+ * The end of the file: totals, fonts, resources, page tree, outline, catalog, Info, xref, trailer.
1761
+ * @param {{ outline?: OutlineEntry[], info?: { title?: string, author?: string, subject?: string, creationDate?: Date }, catalog?: string }} [o]
1762
+ * catalog: more entries for the catalog (the structure tree, metadata, output intents).
1763
+ * @returns {Promise<{ pages: number, bytes: number }>}
1764
+ */
1765
+ async finish(o = {}) {
1766
+ if (done) throw new Error("The PDF is finished");
1767
+ if (!pages) await w.addPage({ width: 595.28, height: 841.89, content: "" });
1768
+ while (inFlight.length) await writeNext();
1769
+ done = true;
1770
+ for (const t of totals) {
1771
+ const F = fontOf(t.font), text = String(pages), hex2 = w.encode(t.font, text);
1772
+ let adv = 0;
1773
+ for (const ch of text) adv += F.font.glyphForCodePoint(
1774
+ /** @type {number} */
1775
+ ch.codePointAt(0)
1776
+ ).advanceWidth;
1777
+ const tw = adv * t.size / F.font.unitsPerEm;
1778
+ const dx = t.align === "right" ? t.width - tw : t.align === "center" ? (t.width - tw) / 2 : 0;
1779
+ await writeObj(
1780
+ t.ref,
1781
+ `<< /Type /XObject /Subtype /Form /BBox [${num2(Math.min(0, dx))} ${num2(-t.size)} ${num2(Math.max(t.width, dx + tw))} ${num2(2 * t.size)}] /Resources << /Font << /${F.name} ${F.ref} 0 R >> >> /Filter /FlateDecode >>`,
1782
+ await deflate(latin12(`${t.color} rg BT /${F.name} ${num2(t.size)} Tf ${num2(dx)} 0 Td <${hex2}> Tj ET`))
1783
+ );
1784
+ }
1785
+ const fontDict = [];
1786
+ for (const [key, F] of fonts) {
1787
+ if (F.glyphs.size) {
1788
+ await writeFont(key, F);
1789
+ fontDict.push(`/${F.name} ${F.ref} 0 R`);
1790
+ }
1791
+ }
1792
+ let resDict = `<< /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] /Font << ${fontDict.join(" ")} >>`;
1793
+ for (const [kind, m] of res) resDict += ` /${kind} << ${[...m].map(([v, n]) => `/${n} ${v}`).join(" ")} >>`;
1794
+ await writeObj(resRef, resDict + " >>");
1795
+ let level = leaves.map((ref, k) => ({ ref, kids: pageRefs.slice(k * LEAF, Math.min(pages, (k + 1) * LEAF)), count: Math.min(LEAF, pages - k * LEAF) }));
1796
+ while (level.length > 1) {
1797
+ const up = [];
1798
+ for (let k = 0; k < level.length; k += LEAF) {
1799
+ const kids = level.slice(k, k + LEAF);
1800
+ up.push({ ref: reserve(), kids: kids.map((x) => x.ref), count: kids.reduce((s, x) => s + x.count, 0), below: kids });
1801
+ }
1802
+ for (const node2 of up) for (const kid of node2.below) kid.parent = node2.ref;
1803
+ await writeNodes(level);
1804
+ level = /** @type {any} */
1805
+ up;
1806
+ }
1807
+ await writeNodes(level);
1808
+ const pagesRoot = level[0].ref;
1809
+ const outline = await writeOutline(o.outline || []);
1810
+ const catalog = reserve();
1811
+ await writeObj(catalog, `<< /Type /Catalog /Pages ${pagesRoot} 0 R /PageLabels << /Nums [0 << /S /D /St 1 >>] >>${outline ? ` /Outlines ${outline} 0 R /PageMode /UseOutlines` : ""}${o.catalog || ""} >>`);
1812
+ const info = reserve(), I2 = o.info || {};
1813
+ await writeObj(info, `<< /Producer ${pdfText("ReportWright")} /Creator ${pdfText("ReportWright")} /Title ${pdfText(I2.title || "Report")}${I2.author ? ` /Author ${pdfText(I2.author)}` : ""}${I2.subject ? ` /Subject ${pdfText(I2.subject)}` : ""} /CreationDate ${pdfDate(I2.creationDate || /* @__PURE__ */ new Date())} /ModDate ${pdfDate(I2.creationDate || /* @__PURE__ */ new Date())} >>`);
1814
+ for (let n = 1; n < nextNum; n++) if (!where(n)[0]) await writeObj(n, "null");
1815
+ await writeBatch();
1816
+ const xn = reserve(), size2 = nextNum, xref = pos;
1817
+ place(xn, 1, xref);
1818
+ const out = (
1819
+ /** @type {Uint8Array[]} */
1820
+ []
1821
+ );
1822
+ const zs = new Zlib({ level: 6 }, (d) => {
1823
+ out.push(d);
1824
+ });
1825
+ const prev = new Uint8Array(7), row = new Uint8Array(7);
1826
+ for (let from = 0; from < size2; from += 65536) {
1827
+ const to = Math.min(size2, from + 65536), rows = new Uint8Array((to - from) * 8);
1828
+ for (let n = from; n < to; n++) {
1829
+ row.fill(0);
1830
+ if (n === 0) {
1831
+ row[5] = 255;
1832
+ row[6] = 255;
1833
+ } else {
1834
+ const [k, l, i] = where(n);
1835
+ row[0] = k;
1836
+ row[1] = l >>> 24 & 255;
1837
+ row[2] = l >>> 16 & 255;
1838
+ row[3] = l >>> 8 & 255;
1839
+ row[4] = l & 255;
1840
+ if (k === 2) {
1841
+ row[5] = i >> 8;
1842
+ row[6] = i & 255;
1843
+ }
1844
+ }
1845
+ const at = (n - from) * 8;
1846
+ rows[at] = 2;
1847
+ for (let b = 0; b < 7; b++) {
1848
+ rows[at + 1 + b] = row[b] - prev[b] & 255;
1849
+ prev[b] = row[b];
1850
+ }
1851
+ }
1852
+ zs.push(rows, to === size2);
1853
+ }
1854
+ let zn = 0;
1855
+ for (const c of out) zn += c.length;
1856
+ const z = new Uint8Array(zn);
1857
+ zn = 0;
1858
+ for (const c of out) {
1859
+ z.set(c, zn);
1860
+ zn += c.length;
1861
+ }
1862
+ const id = opt.id || [...globalThis.crypto.getRandomValues(new Uint8Array(16))].map((b) => b.toString(16).padStart(2, "0")).join("");
1863
+ await put(`${xn} 0 obj
1864
+ << /Type /XRef /Size ${size2} /W [1 4 2] /DecodeParms << /Columns 7 /Predictor 12 >> /Root ${catalog} 0 R /Info ${info} 0 R /ID [<${id}> <${id}>] /Filter /FlateDecode /Length ${z.length} >>
1865
+ stream
1866
+ `);
1867
+ await put(z);
1868
+ await put(`
1869
+ endstream
1870
+ endobj
1871
+ startxref
1872
+ ${xref}
1873
+ %%EOF
1874
+ `);
1875
+ await flush();
1876
+ return { pages, bytes: pos };
1877
+ }
1878
+ };
1879
+ async function writeNext() {
1880
+ const { ref, contents, parent, p, z } = (
1881
+ /** @type {any} */
1882
+ inFlight.shift()
1883
+ );
1884
+ await writeObj(contents, "<< /Filter /FlateDecode >>", await z);
1885
+ const annots = [];
1886
+ for (const a of p.annots || []) annots.push(typeof a === "string" ? await w.object(a) : (await writeObj(a.ref, a.dict), a.ref));
1887
+ await writeObj(ref, `<< /Type /Page /Parent ${parent} 0 R /MediaBox [0 0 ${num2(p.width)} ${num2(p.height)}] /Resources ${resRef} 0 R /Contents ${contents} 0 R${annots.length ? ` /Annots [${annots.map((a) => `${a} 0 R`).join(" ")}]` : ""}${p.extra || ""} >>`);
1888
+ }
1889
+ async function writeNodes(nodes) {
1890
+ for (const n of nodes) await writeObj(n.ref, `<< /Type /Pages${n.parent ? ` /Parent ${n.parent} 0 R` : ""} /Kids [${n.kids.map((k) => `${k} 0 R`).join(" ")}] /Count ${n.count} >>`);
1891
+ }
1892
+ async function writeFont(key, F) {
1893
+ if (F.font.standard) {
1894
+ await writeObj(F.ref, standardFontDict(F.font));
1895
+ return;
1896
+ }
1897
+ await loadFontkit();
1898
+ const f = F.font, full = (
1899
+ /** @type {Uint8Array} */
1900
+ fontStore.bytes.get(key)
1901
+ );
1902
+ let bytes = full, psName = f.postscriptName;
1903
+ if (opt.subset && !f["OS/2"]?.fsType?.noSubsetting) {
1904
+ try {
1905
+ const sub = await opt.subset(full, F.cps, { glyphs: F.glyphs.keys() });
1906
+ const padded = new Uint8Array(sub.length + 16);
1907
+ padded.set(sub);
1908
+ const check = fontkit.create(padded);
1909
+ for (const id of F.glyphs.keys()) void check.getGlyph(id).advanceWidth;
1910
+ bytes = sub;
1911
+ psName = check.postscriptName || psName;
1912
+ } catch {
1913
+ }
1914
+ }
1915
+ const cff = "CFF " in f.directory.tables || "CFF2" in f.directory.tables;
1916
+ const base = `${bytes === full ? "" : `${subsetTag(bytes)}+`}${String(psName || "Font").replace(/[^A-Za-z0-9_.-]/g, "")}`;
1917
+ const k = 1e3 / f.unitsPerEm, s = (v) => String(v * k);
1918
+ const desc = reserve(), file = reserve(), cid = reserve(), cmap = reserve();
1919
+ const fileDict = cff ? "<< /Subtype /OpenType /Filter /FlateDecode >>" : `<< /Length1 ${bytes.length} /Filter /FlateDecode >>`;
1920
+ await writeObj(file, fileDict, await deflate(bytes));
1921
+ const bb = f.bbox, italic = f.italicAngle || 0;
1922
+ const flags = (f.post?.isFixedPitch ? 1 : 0) | 4 | (italic ? 64 : 0);
1923
+ await writeObj(desc, `<< /Type /FontDescriptor /FontName /${base} /Flags ${flags} /FontBBox [${s(bb.minX)} ${s(bb.minY)} ${s(bb.maxX)} ${s(bb.maxY)}] /ItalicAngle ${num2(italic)} /Ascent ${s(f.ascent)} /Descent ${s(f.descent)} /CapHeight ${s(f.capHeight || f.ascent)} /XHeight ${s(f.xHeight || 0)} /StemV 0 /${cff ? "FontFile3" : "FontFile2"} ${file} 0 R >>`);
1924
+ const ids = [...F.glyphs.keys()].sort((a, b) => a - b);
1925
+ let W = "";
1926
+ for (let i = 0; i < ids.length; ) {
1927
+ let j = i;
1928
+ while (j + 1 < ids.length && ids[j + 1] === ids[j] + 1) j++;
1929
+ W += `${ids[i]} [${ids.slice(i, j + 1).map((id) => s(f.getGlyph(id).advanceWidth)).join(" ")}] `;
1930
+ i = j + 1;
1931
+ }
1932
+ await writeObj(cid, `<< /Type /Font /Subtype /${cff ? "CIDFontType0" : "CIDFontType2"} /BaseFont /${base} /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor ${desc} 0 R /W [${W}]${cff ? "" : " /CIDToGIDMap /Identity"} >>`);
1933
+ await writeObj(cmap, "<< /Filter /FlateDecode >>", await deflate(latin12(toUnicode(F.glyphs))));
1934
+ await writeObj(F.ref, `<< /Type /Font /Subtype /Type0 /BaseFont /${base} /Encoding /Identity-H /DescendantFonts [${cid} 0 R] /ToUnicode ${cmap} 0 R >>`);
1935
+ }
1936
+ async function writeOutline(entries) {
1937
+ const root = { ref: 0, level: -1, kids: [] };
1938
+ const stack = [root];
1939
+ for (const e of entries) {
1940
+ if (!(e.page >= 1 && e.page <= pages)) continue;
1941
+ const level = Math.max(0, Math.min(9, Number(e.level) || 0));
1942
+ while (stack[stack.length - 1].level >= level) stack.pop();
1943
+ const node2 = { ref: reserve(), level, kids: [], title: e.title, dest: `[${pageRefs[e.page - 1]} 0 R ${e.top == null ? "/Fit" : `/XYZ null ${num2(e.top)} null`}]` };
1944
+ stack[stack.length - 1].kids.push(node2);
1945
+ stack.push(node2);
1946
+ }
1947
+ if (!root.kids.length) return 0;
1948
+ root.ref = reserve();
1949
+ const count = (n) => n.kids.reduce((t, c) => t + 1 + count(c), 0);
1950
+ const children = (n) => n.kids.length ? ` /First ${n.kids[0].ref} 0 R /Last ${n.kids[n.kids.length - 1].ref} 0 R /Count ${count(n)}` : "";
1951
+ const write = async (n) => {
1952
+ for (let i = 0; i < n.kids.length; i++) {
1953
+ const c = n.kids[i];
1954
+ await writeObj(c.ref, `<< /Title ${pdfText(c.title)} /Parent ${n.ref} 0 R /Dest ${c.dest}${i ? ` /Prev ${n.kids[i - 1].ref} 0 R` : ""}${i < n.kids.length - 1 ? ` /Next ${n.kids[i + 1].ref} 0 R` : ""}${children(c)} >>`);
1955
+ await write(c);
1956
+ }
1957
+ };
1958
+ await write(root);
1959
+ await writeObj(root.ref, `<< /Type /Outlines${children(root)} >>`);
1960
+ return root.ref;
1961
+ }
1962
+ return w;
1963
+ }
1964
+ function toUnicode(glyphs) {
1965
+ const entries = [...glyphs].filter(([, t]) => t).sort((a, b) => a[0] - b[0]);
1966
+ let body = "";
1967
+ for (let i = 0; i < entries.length; i += 100) {
1968
+ const chunk = entries.slice(i, i + 100);
1969
+ body += `${chunk.length} beginbfchar
1970
+ ${chunk.map(([id, t]) => `<${hex42(id)}> <${utf16(t)}>`).join("\n")}
1971
+ endbfchar
1972
+ `;
1973
+ }
1974
+ return `/CIDInit /ProcSet findresource begin
1975
+ 12 dict begin
1976
+ begincmap
1977
+ /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def
1978
+ /CMapName /Adobe-Identity-UCS def
1979
+ /CMapType 2 def
1980
+ 1 begincodespacerange
1981
+ <0000> <ffff>
1982
+ endcodespacerange
1983
+ ${body}endcmap
1984
+ CMapName currentdict /CMap defineresource pop
1985
+ end
1986
+ end
1987
+ `;
1988
+ }
1989
+ var utf16 = (t) => {
1990
+ let h = "";
1991
+ for (let i = 0; i < t.length; i++) h += hex42(t.charCodeAt(i));
1992
+ return h;
1993
+ };
1994
+ var pdfText = (t) => `<feff${utf16(String(t ?? ""))}>`;
1995
+ var pdfDate = (d) => `(D:${d.toISOString().replace(/\D/g, "").slice(0, 14)}+00'00')`;
1996
+ function subsetTag(bytes) {
1997
+ let h = 2166136261;
1998
+ for (let i = 0; i < bytes.length; i++) h = Math.imul(h ^ bytes[i], 16777619);
1999
+ let tag = "";
2000
+ for (let i = 0; i < 6; i++) {
2001
+ tag += String.fromCharCode(65 + (h >>> 0) % 26);
2002
+ h = Math.imul(h ^ i, 16777619) >>> 0;
2003
+ }
2004
+ return tag;
2005
+ }
2006
+ function latin12(s) {
2007
+ const B = (
2008
+ /** @type {any} */
2009
+ globalThis.Buffer
2010
+ );
2011
+ if (B) return B.from(s, "latin1");
2012
+ const out = new Uint8Array(s.length);
2013
+ for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i);
2014
+ return out;
2015
+ }
2016
+ async function writePagedPdf(plan2, opts, sink) {
2017
+ const { fontStore } = opts;
2018
+ if (opts.pdfa || opts.tagged) await fontStore.load(standIns(fontStore));
2019
+ const w = createPdfStream(sink, { fontStore, subset: opts.subset, id: opts.id, signal: opts.signal });
2020
+ const { info, pages } = (
2021
+ /** @type {any} */
2022
+ plan2
2023
+ );
2024
+ const tags = opts.tagged ? createStreamTagger(w, { maxElements: Number(opts.tagged.maxElements) || Infinity }) : null;
2025
+ const env = paintEnv(w, fontStore, { drillBase: opts.drillBase, tags, embedAll: !!(opts.pdfa || tags) });
2026
+ const { shaped } = env;
2027
+ const pool = !tags && Number(opts.parallel) > 1 ? paintPool(Number(opts.parallel), fontStore, opts, info) : null;
2028
+ let pi = -1;
2029
+ const it = pages(pool ? { run: pool.run, parallel: pool.size } : {})[Symbol.asyncIterator]();
2030
+ let pending = false;
2031
+ try {
2032
+ for (; ; ) {
2033
+ opts.signal?.throwIfAborted();
2034
+ pending = true;
2035
+ const x = await raced(it.next(), opts.signal);
2036
+ pending = false;
2037
+ if (x.done) break;
2038
+ const pg = x.value;
2039
+ pi++;
2040
+ const H = pg.height ?? info.height;
2041
+ if (pg.deflated) {
2042
+ for (const f of pg.embedded || []) env.embedded?.add(f);
2043
+ if (pg.used) {
2044
+ w.take(pg.used);
2045
+ for (const [k, g] of pg.shaped) {
2046
+ const m = env.shapedOf(k);
2047
+ for (const [id, t] of g) if (!m.has(id)) m.set(id, t);
2048
+ }
2049
+ }
2050
+ const annots2 = pg.annots.map((a) => a.replace(/@@P(\d+)@@/g, (_, i) => String(w.pageRef(Number(i)))));
2051
+ await w.addPage({ width: pg.width ?? info.width, height: H, deflated: pg.deflated, annots: annots2 });
2052
+ continue;
2053
+ }
2054
+ const { content, annots } = paintPage(pg, H, env);
2055
+ await w.addPage({ width: pg.width ?? info.width, height: H, content, annots, extra: tags ? await tags.end(w.pageRef(pi)) : void 0 });
2056
+ }
2057
+ } finally {
2058
+ if (pending) it.return?.(void 0)?.catch(() => {
2059
+ });
2060
+ else await it.return?.(void 0);
2061
+ await pool?.close();
2062
+ }
2063
+ for (const [key, g] of shaped) w.addGlyphs(key, g);
2064
+ const seen = /* @__PURE__ */ new Set();
2065
+ const outline = [...info.bookmarks, ...info.headings].map((b, i) => ({ b, i })).sort((p, q) => p.b.page - q.b.page || (p.b.y ?? 0) - (q.b.y ?? 0) || p.i - q.i).map(({ b }) => b).filter((b) => {
2066
+ const k = `${b.page}|${Math.round(b.y ?? 0)}|${b.label}`;
2067
+ if (seen.has(k)) return false;
2068
+ seen.add(k);
2069
+ return true;
2070
+ }).map((b) => ({ title: b.label, page: b.page, top: info.height - b.y + 4, level: b.level }));
2071
+ const title = opts.title || "Report", when = new Date(Math.floor((opts.creationDate || /* @__PURE__ */ new Date()).getTime() / 1e3) * 1e3);
2072
+ let catalog = tags ? await tags.finish({ lang: opts.tagged.lang }) : "";
2073
+ if (opts.pdfa || tags) {
2074
+ const xmp = new TextEncoder().encode(xmpPacket({ title, author: opts.author, stamp: when.toISOString().replace(".000Z", "Z"), pdfa: opts.pdfa ? tags ? "A" : "B" : null, ua: !!tags }));
2075
+ catalog += ` /Metadata ${await w.object("<< /Type /Metadata /Subtype /XML >>", xmp)} 0 R`;
2076
+ }
2077
+ if (opts.pdfa) {
2078
+ const icc = await w.object("<< /N 3 /Filter /FlateDecode >>", await deflate(opts.pdfa.icc));
2079
+ catalog += ` /OutputIntents [${await w.object(`<< /Type /OutputIntent /S /GTS_PDFA1 /OutputConditionIdentifier (sRGB) /Info (sRGB IEC61966-2.1) /DestOutputProfile ${icc} 0 R >>`)} 0 R]`;
2080
+ }
2081
+ const res = await w.finish({ outline, catalog, info: { title, author: opts.author, creationDate: when } });
2082
+ for (const x of env.embedded ? embeddedWarnings(env.embedded) : []) info.warnings.push(x);
2083
+ if (tags && tags.count > TAGGED_LARGE) info.warnings.push(`The tagged PDF has ${tags.count.toLocaleString("en-US")} structure elements (${res.pages.toLocaleString("en-US")} pages): readers open it, but tools that load every object of a file (qpdf, pikepdf) may run out of memory on it. tagged.maxElements caps it.`);
2084
+ return { pages: res.pages, warnings: info.warnings };
2085
+ }
2086
+ var lit = (v) => `(${String(v).replace(/[\\()]/g, "\\$&")})`;
2087
+ function coveredText(items, box) {
2088
+ const lines = [];
2089
+ for (const t of items) if (t.t === "text" && t.lines) {
2090
+ 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);
2091
+ }
2092
+ return lines.sort((a, b) => a.y - b.y || a.x - b.x).map((l) => l.text.trim()).join(" ");
2093
+ }
2094
+ function paintPage(pg, H, env) {
2095
+ if (env.embedded) pg = embeddedPage(pg, env.font, env.embedded);
2096
+ const annots = [];
2097
+ const c = new Content(env.shared);
2098
+ const { tags } = env;
2099
+ if (tags) {
2100
+ c.tagged = true;
2101
+ c.artLines = true;
2102
+ tags.page(pg.win ?? 0);
2103
+ }
2104
+ for (const it of pg.items) {
2105
+ const mark = tags && it.t !== "line" && tags.open(it);
2106
+ const inText = mark && it.t === "text" && !it.rotate && it.lines.every((l) => !l.runs) && !(it.clip && !insideClip(it, env.vmetrics(it.font)));
2107
+ if (inText) {
2108
+ if (!c.bt) {
2109
+ c._s += "BT\n";
2110
+ c.bt = true;
2111
+ c.tx = 0;
2112
+ c.ty = 0;
2113
+ }
2114
+ c._s += mark;
2115
+ } else if (mark) {
2116
+ c.et();
2117
+ c.s += mark;
2118
+ }
2119
+ if (it.t !== "text" && it.t !== "line" || it.rotate) c.et();
2120
+ if (it.rotate) {
2121
+ const t = -it.rotate.a * Math.PI / 180, cs = Math.cos(t), sn = Math.sin(t);
2122
+ const px = it.rotate.cx, py = H - it.rotate.cy;
2123
+ c.q();
2124
+ c.s += `${n4(cs)} ${n4(sn)} ${n4(-sn)} ${n4(cs)} ${n2(px - px * cs + py * sn)} ${n2(py - px * sn - py * cs)} cm
2125
+ `;
2126
+ }
2127
+ switch (it.t) {
2128
+ case "rect": {
2129
+ const fill = col(it.fill), stroke = col(it.stroke);
2130
+ if (!fill && !stroke) break;
2131
+ if (it.radius) throw new Error("rounded boxes do not stream yet");
2132
+ c.paint(fill, stroke, it.strokeWidth || 1, it.dash);
2133
+ const x = n2(it.x), y = n2(H - it.y - it.h), rw = n2(it.w), rh = n2(it.h);
2134
+ c.s += (stroke && it.dash?.length ? `${x} ${y} m ${x} ${n2(y + rh)} l ${n2(x + rw)} ${n2(y + rh)} l ${n2(x + rw)} ${y} l h` : `${x} ${y} ${rw} ${rh} re`) + (fill && stroke ? " B\n" : fill ? " f\n" : " S\n");
2135
+ break;
2136
+ }
2137
+ case "ellipse": {
2138
+ const fill = col(it.fill), stroke = col(it.stroke);
2139
+ if (!fill && !stroke) break;
2140
+ c.paint(fill, stroke, it.strokeWidth || 1, it.dash);
2141
+ const cx = it.cx, cy = H - it.cy, rx = it.rx, ry = it.ry, ox = rx * KAPPA, oy = ry * KAPPA;
2142
+ c.s += `${n2(cx - rx)} ${n2(cy)} m ${n2(cx - rx)} ${n2(cy - oy)} ${n2(cx - ox)} ${n2(cy - ry)} ${n2(cx)} ${n2(cy - ry)} c ${n2(cx + ox)} ${n2(cy - ry)} ${n2(cx + rx)} ${n2(cy - oy)} ${n2(cx + rx)} ${n2(cy)} c ${n2(cx + rx)} ${n2(cy + oy)} ${n2(cx + ox)} ${n2(cy + ry)} ${n2(cx)} ${n2(cy + ry)} c ${n2(cx - ox)} ${n2(cy + ry)} ${n2(cx - rx)} ${n2(cy + oy)} ${n2(cx - rx)} ${n2(cy)} c h ${fill &&
2143
+ stroke ? "B" : fill ? "f" : "S"}
2144
+ `;
2145
+ break;
2146
+ }
2147
+ case "line": {
2148
+ const st = col(it.stroke);
2149
+ if (st) c.line(st, it.strokeWidth || 1, it.dash, it.x1, H - it.y1, it.x2, H - it.y2);
2150
+ break;
2151
+ }
2152
+ case "text": {
2153
+ const color = col(it.color) || BLACK;
2154
+ const clipped = it.clip && !insideClip(it, env.vmetrics(it.font));
2155
+ if (clipped) {
2156
+ c.q();
2157
+ c.s += `${n2(it.clip.x)} ${n2(H - it.clip.y - it.clip.h)} ${n2(it.clip.w)} ${n2(it.clip.h)} re W n
2158
+ `;
2159
+ }
2160
+ for (const l of it.lines) {
2161
+ if (!l.runs) {
2162
+ c.text(env.pf(it.font), it.size, color, l.x, H - l.y, env.literal(it.font, cleanText(l.text)));
2163
+ continue;
2164
+ }
2165
+ for (const r of l.runs) {
2166
+ const g = env.shapedOf(r.font), spans = /* @__PURE__ */ new WeakMap();
2167
+ glyphText(r, env.font(r.font), g, spans);
2168
+ if (r.text.trim()) drawRun(c, r, l.x + r.x, H - l.y, it.size, env.pf(r.font), color, spans.get(r), g);
2169
+ }
2170
+ }
2171
+ if (clipped) c.Q();
2172
+ break;
2173
+ }
2174
+ case "link": {
2175
+ const rect = `[${[it.x, H - it.y - it.h, it.x + it.w, H - it.y].map(n2).join(" ")}]`;
2176
+ const a = it.action;
2177
+ const href = a?.type === "url" && safeUrl(a.href) ? a.href : a?.type === "drill" ? drillUrl(env.drillBase, a) : null;
2178
+ const to = href ? `/A << /Type /Action /S /URI /URI ${lit(asciiUrl(href))} >>` : a?.type === "bookmark" && a.page ? `/Dest [${env.pageRef(a.page - 1)} 0 R /XYZ null ${n2(H - a.y + 4)} null]` : null;
2179
+ if (!to) break;
2180
+ if (!tags) {
2181
+ annots.push(`<< /Type /Annot /Subtype /Link /F 4 /Rect ${rect} /Border [0 0 0] ${to} >>`);
2182
+ break;
2183
+ }
2184
+ const ref = env.reserve(), key = tags.link(it, ref);
2185
+ const say = coveredText(pg.items, it) || it.tip || href || (a.target ? `Go to ${a.target}` : `Go to page ${a.page}`);
2186
+ annots.push({ ref, dict: `<< /Type /Annot /Subtype /Link /F 4 /Rect ${rect} /Border [0 0 0] ${to} /Contents ${pdfText(say)} /StructParent ${key} >>` });
2187
+ break;
2188
+ }
2189
+ default:
2190
+ throw new Error(`A ${it.t} item does not stream yet`);
2191
+ }
2192
+ if (it.rotate) c.Q();
2193
+ if (inText) c._s += "EMC\n";
2194
+ else if (mark) {
2195
+ c.et();
2196
+ c.s += "EMC\n";
2197
+ }
2198
+ }
2199
+ c.et();
2200
+ return { content: c.s, annots };
2201
+ }
2202
+ function paintEnv(w, fontStore, o = {}) {
2203
+ const pfs = /* @__PURE__ */ new Map();
2204
+ const shaped = /* @__PURE__ */ new Map();
2205
+ const vm = /* @__PURE__ */ new Map();
2206
+ return {
2207
+ shared: { font: (f) => w.fontName(f.key), gs: (ca, CA) => w.gs(ca, CA), image: () => {
2208
+ throw new Error("images do not stream yet");
2209
+ } },
2210
+ pf: (key) => {
2211
+ let f = pfs.get(key);
2212
+ if (!f) pfs.set(key, f = { key, embedder: { font: fontStore.get(key) } });
2213
+ return f;
2214
+ },
2215
+ font: (key) => fontStore.get(key),
2216
+ shaped,
2217
+ shapedOf: (key) => {
2218
+ let g = shaped.get(key);
2219
+ if (!g) shaped.set(key, g = /* @__PURE__ */ new Map());
2220
+ return g;
2221
+ },
2222
+ vmetrics: (key) => {
2223
+ let m = vm.get(key);
2224
+ if (!m) {
2225
+ const f = fontStore.get(key), u = f?.unitsPerEm || 1e3;
2226
+ vm.set(key, m = { asc: (f?.ascent ?? u) / u, desc: -(f?.descent ?? 0) / u });
2227
+ }
2228
+ return m;
2229
+ },
2230
+ literal: (key, text) => w.literal(key, text),
2231
+ pageRef: o.pageRef || ((i) => w.pageRef(i)),
2232
+ reserve: () => w.reserve(),
2233
+ drillBase: o.drillBase,
2234
+ tags: o.tags || null,
2235
+ /** PDF/A, PDF/UA: standard fonts drawn in embedded stand-ins; the families that were @type {Set<string>|null} */
2236
+ embedded: o.embedAll ? /* @__PURE__ */ new Set() : null
2237
+ };
2238
+ }
2239
+ function paintPool(size, fontStore, opts, info) {
2240
+ const wt = (
2241
+ /** @type {any} */
2242
+ globalThis.process?.getBuiltinModule?.("node:worker_threads")
2243
+ );
2244
+ if (!wt) return null;
2245
+ let workers = [];
2246
+ let seq = 0, turn = 0;
2247
+ const waiting = /* @__PURE__ */ new Map();
2248
+ const clean = (r) => {
2249
+ if (!r) return r;
2250
+ const { __i, ...o } = r;
2251
+ return o;
2252
+ };
2253
+ const start = async () => {
2254
+ const fonts = [...fontStore.bytes];
2255
+ if (fontStore.shaper) fonts.push(["harfbuzz", await fontStore.loader("harfbuzz")]);
2256
+ workers = Array.from({ length: size }, () => {
2257
+ const w = new wt.Worker(new URL("./pdfstreamworker.js", import.meta.url), { workerData: { fonts } });
2258
+ w.on("message", (m) => {
2259
+ const p = waiting.get(m.id);
2260
+ waiting.delete(m.id);
2261
+ if (m.error) p.fail(Object.assign(new Error(m.error.message), { status: m.error.status, timeout: m.error.timeout }));
2262
+ else p.ok(m);
2263
+ });
2264
+ w.on("error", (e) => {
2265
+ for (const p of waiting.values()) p.fail(e);
2266
+ waiting.clear();
2267
+ });
2268
+ return w;
2269
+ });
2270
+ };
2271
+ let started = null;
2272
+ const pick = ["parameters", "now", "timeZone", "state", "target", "deadline", "timeoutMs"];
2273
+ return {
2274
+ size,
2275
+ /** @param {any} job */
2276
+ async run(job) {
2277
+ await (started || (started = start()));
2278
+ const id = ++seq;
2279
+ const pw = job.pageWindow;
2280
+ const msg = {
2281
+ id,
2282
+ def: job.def,
2283
+ rows: job.rows.map(clean),
2284
+ keep: job.keep,
2285
+ drillBase: opts.drillBase,
2286
+ embedAll: !!opts.pdfa,
2287
+ height: info.height,
2288
+ opts: Object.fromEntries(pick.filter((k) => opts[k] !== void 0).map((k) => [k, opts[k]])),
2289
+ pageWindow: { ...pw, first: clean(pw.first), cont: pw.cont.map((c) => c && { first: clean(c.first), before: c.before }) }
2290
+ };
2291
+ const r = await new Promise((ok, fail) => {
2292
+ waiting.set(id, { ok, fail });
2293
+ workers[turn++ % workers.length].postMessage(msg);
2294
+ });
2295
+ if (r.pages.length) {
2296
+ r.pages[0].used = r.used;
2297
+ r.pages[0].shaped = r.shaped;
2298
+ r.pages[0].embedded = r.embedded;
2299
+ }
2300
+ return r;
2301
+ },
2302
+ async close() {
2303
+ await Promise.all(workers.map((w) => w.terminate()));
2304
+ }
2305
+ };
2306
+ }
2307
+
1084
2308
  // src/exporters/pdf.js
1085
- var fontkit = (
1086
- /** @type {any} */
1087
- fontkitModule.default || fontkitModule
1088
- );
1089
2309
  function exportPdf(model, fontStore, opt = {}) {
1090
2310
  return withDeadline(
1091
2311
  pdfOf(model, fontStore, opt),
@@ -1094,6 +2314,9 @@ function exportPdf(model, fontStore, opt = {}) {
1094
2314
  );
1095
2315
  }
1096
2316
  async function pdfOf(model, fontStore, opt) {
2317
+ await fontStore.load(modelFontKeys(model));
2318
+ if (ownWriterFits(model, opt)) return ownWriter(model, fontStore, opt);
2319
+ await loadPdfLib();
1097
2320
  const fixed = fixedDate(opt);
1098
2321
  const when = fixed ?? /* @__PURE__ */ new Date();
1099
2322
  const fileId = fixed ? await contentId(model, opt, when) : void 0;
@@ -1104,7 +2327,13 @@ async function pdfOf(model, fontStore, opt) {
1104
2327
  doc.setCreator("ReportWright");
1105
2328
  if (opt.author) doc.setAuthor(opt.author);
1106
2329
  setInfoDates(doc, when);
1107
- if (fileId) doc.context.trailerInfo.ID = doc.context.obj([PDFHexString5.of(fileId), PDFHexString5.of(fileId)]);
2330
+ if (fileId) doc.context.trailerInfo.ID = doc.context.obj([PDFHexString.of(fileId), PDFHexString.of(fileId)]);
2331
+ if (opt.pdfa || opt.tagged || model.pages.some((pg) => pg.items.some((i) => i.t === "field"))) await fontStore.load(standIns(fontStore));
2332
+ if (opt.pdfa || opt.tagged) {
2333
+ const families = /* @__PURE__ */ new Set();
2334
+ model = { ...model, pages: model.pages.map((pg) => embeddedPage(pg, (k) => fontStore.get(k), families)) };
2335
+ for (const w of embeddedWarnings(families)) opt.onWarning?.(w);
2336
+ }
1108
2337
  const used = /* @__PURE__ */ new Map();
1109
2338
  const shaped = /* @__PURE__ */ new Map();
1110
2339
  const spans = /* @__PURE__ */ new WeakMap();
@@ -1145,10 +2374,18 @@ async function pdfOf(model, fontStore, opt) {
1145
2374
  for (const pg of model.pages) for (const it of pg.items) if (it.t === "field") fieldFonts.add(fieldFont(it));
1146
2375
  const fonts = /* @__PURE__ */ new Map();
1147
2376
  const font = async (key) => {
2377
+ if (!fonts.has(key) && isStandard(key)) {
2378
+ const f = fontStore.get(key);
2379
+ fonts.set(key, { ref: doc.context.register(doc.context.obj(
2380
+ /** @type {any} */
2381
+ standardFontEntries(f)
2382
+ )), embedder: { font: f, literalOf: (t) => standardLiteral(f, t), tjOf: () => null } });
2383
+ }
1148
2384
  if (!fonts.has(key)) {
1149
2385
  const full = fontStore.bytes.get(key);
1150
2386
  let bytes = full;
1151
2387
  if (!bytes) throw new Error(`Font "${key}" is not loaded`);
2388
+ let psName = fontStore.get(key).postscriptName;
1152
2389
  const glyphs = shaped.get(key);
1153
2390
  if (opt.subset && !fieldFonts.has(key) && !fontStore.get(key)["OS/2"]?.fsType?.noSubsetting) {
1154
2391
  const cps = used.get(key) || /* @__PURE__ */ new Set([32]);
@@ -1158,17 +2395,18 @@ async function pdfOf(model, fontStore, opt) {
1158
2395
  for (const cp of cps) void f.glyphForCodePoint(cp).advanceWidth;
1159
2396
  for (const id of glyphs?.keys() || []) void f.getGlyph(id).advanceWidth;
1160
2397
  bytes = sub;
2398
+ psName = f.postscriptName || psName;
1161
2399
  } catch {
1162
2400
  }
1163
2401
  }
1164
- const pf = await doc.embedFont(bytes, { subset: false, customName: bytes === full ? void 0 : `${subsetTag(bytes)}+${fontStore.get(key).postscriptName || "Font"}` });
2402
+ const pf = await doc.embedFont(bytes, { subset: false, customName: bytes === full ? void 0 : `${subsetTag2(bytes)}+${psName || "Font"}` });
1165
2403
  plainEncoding(pf);
1166
2404
  if (glyphs) addGlyphs(pf, glyphs, !!opt.tagged);
1167
2405
  const file = bytes, e = (
1168
2406
  /** @type {any} */
1169
2407
  pf.embedder
1170
2408
  );
1171
- if (!e.isCFF()) e.embedFontStream = async (c) => c.register(PDFRawStream2.of(c.obj({ Filter: "FlateDecode", Length1: file.length }), await deflate(file)));
2409
+ if (!e.isCFF()) e.embedFontStream = async (c) => c.register(PDFRawStream.of(c.obj({ Filter: "FlateDecode", Length1: file.length }), await deflate(file)));
1172
2410
  fonts.set(key, pf);
1173
2411
  }
1174
2412
  return fonts.get(key);
@@ -1209,7 +2447,7 @@ async function pdfOf(model, fontStore, opt) {
1209
2447
  if (!n) {
1210
2448
  n = `${kind[0]}${names.size + 1}`;
1211
2449
  names.set(key, n);
1212
- res.get(PDFName3.of(kind)).set(PDFName3.of(n), value());
2450
+ res.get(PDFName.of(kind)).set(PDFName.of(n), value());
1213
2451
  }
1214
2452
  return n;
1215
2453
  };
@@ -1244,7 +2482,7 @@ async function pdfOf(model, fontStore, opt) {
1244
2482
  const H = pg.height ?? model.height;
1245
2483
  const p = doc.addPage([pg.width ?? model.width, H]);
1246
2484
  p.node.normalize();
1247
- p.node.set(PDFName3.of("Resources"), resRef);
2485
+ p.node.set(PDFName.of("Resources"), resRef);
1248
2486
  const c = new Content(shared);
1249
2487
  if (tags) c.tagged = true;
1250
2488
  p.maybeEmbedGraphicsState = (o) => c.gsFor(o.opacity ?? 1, o.borderOpacity ?? 1);
@@ -1351,7 +2589,7 @@ async function pdfOf(model, fontStore, opt) {
1351
2589
  const form = doc.getForm();
1352
2590
  const f = await font(fieldFont(it));
1353
2591
  const name = uniqueName(it.name);
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) };
2592
+ const box = { x: it.x, y: H - it.y - it.h, width: it.w, height: it.h, borderColor: rgb(0.61, 0.64, 0.69), borderWidth: 0.75, backgroundColor: rgb(1, 1, 1) };
1355
2593
  let field;
1356
2594
  if (it.kind === "checkbox") {
1357
2595
  field = form.createCheckBox(name);
@@ -1408,7 +2646,8 @@ async function pdfOf(model, fontStore, opt) {
1408
2646
  if (it.required) field.enableRequired();
1409
2647
  if (it.readOnly) field.enableReadOnly();
1410
2648
  if (tags) {
1411
- field.acroField.dict.set(PDFName3.of("TU"), PDFHexString5.fromText(it.label || it.name || name));
2649
+ if (!it.label) opt.onWarning?.(`Form field "${name}" has no label, so a screen reader announces its name; give it a label`);
2650
+ field.acroField.dict.set(PDFName.of("TU"), PDFHexString.fromText(it.label || it.name || name));
1412
2651
  const w = field.acroField.getWidgets()[0];
1413
2652
  const ref2 = w && doc.context.getObjectRef(w.dict);
1414
2653
  if (ref2) tags.annot(pi, ii, ref2, "field");
@@ -1417,7 +2656,7 @@ async function pdfOf(model, fontStore, opt) {
1417
2656
  }
1418
2657
  case "link": {
1419
2658
  const rect = [it.x, H - it.y - it.h, it.x + it.w, H - it.y];
1420
- const text = tags ? coveredText(pg.items, it) : "";
2659
+ const text = tags ? coveredText2(pg.items, it) : "";
1421
2660
  if (it.action?.type === "url" && safeUrl(it.action.href)) links.push({ page: p, rect, href: it.action.href, pi, ii, tip: it.tip, text });
1422
2661
  else if (it.action?.type === "drill") {
1423
2662
  const href = drillUrl(opt.drillBase, it.action);
@@ -1470,24 +2709,24 @@ async function pdfOf(model, fontStore, opt) {
1470
2709
  );
1471
2710
  if (own) ctx.delete(own);
1472
2711
  const ref = ctx.nextRef();
1473
- p.node.set(PDFName3.of("Contents"), ref);
1474
- contents.push(deflate(latin1(c.s)).then((z) => ctx.assign(ref, PDFRawStream2.of(ctx.obj({ Filter: "FlateDecode" }), z))));
2712
+ p.node.set(PDFName.of("Contents"), ref);
2713
+ contents.push(deflate(latin1(c.s)).then((z) => ctx.assign(ref, PDFRawStream.of(ctx.obj({ Filter: "FlateDecode" }), z))));
1475
2714
  if (NODE_ZLIB && contents.length > 8) await contents[contents.length - 9];
1476
2715
  }
1477
2716
  await Promise.all(contents);
1478
2717
  const pageH = (n) => model.pages[n - 1]?.height ?? model.height;
1479
2718
  const pages = doc.getPages();
1480
- const dest = (b) => pages[b.page - 1] && [pages[b.page - 1].ref, PDFName3.of("XYZ"), null, pageH(b.page) - b.y + 4, null];
2719
+ const dest = (b) => pages[b.page - 1] && [pages[b.page - 1].ref, PDFName.of("XYZ"), null, pageH(b.page) - b.y + 4, null];
1481
2720
  for (const l of links) {
1482
2721
  const to = l.href ? { A: { Type: "Action", S: "URI", URI: pdfLiteral(asciiUrl(l.href)) } } : { Dest: dest(l.to) };
1483
2722
  if (!l.href && !to.Dest) continue;
1484
2723
  const annot = doc.context.obj({ Type: "Annot", Subtype: "Link", F: 4, Rect: l.rect, Border: [0, 0, 0], ...to });
1485
- if (tags) annot.set(PDFName3.of("Contents"), PDFHexString5.fromText(String(l.text || l.tip || l.href || "Link")));
2724
+ if (tags) annot.set(PDFName.of("Contents"), PDFHexString.fromText(String(l.text || l.tip || l.href || "Link")));
1486
2725
  const ref = doc.context.register(annot);
1487
2726
  if (tags) tags.annot(l.pi, l.ii, ref, "link");
1488
- const annots = l.page.node.lookup(PDFName3.of("Annots"));
2727
+ const annots = l.page.node.lookup(PDFName.of("Annots"));
1489
2728
  if (annots) annots.push(ref);
1490
- else l.page.node.set(PDFName3.of("Annots"), doc.context.obj([ref]));
2729
+ else l.page.node.set(PDFName.of("Annots"), doc.context.obj([ref]));
1491
2730
  }
1492
2731
  const marks = outlineEntries(model);
1493
2732
  if (marks.length) addOutline(doc, marks, dest);
@@ -1504,7 +2743,44 @@ async function pdfOf(model, fontStore, opt) {
1504
2743
  }
1505
2744
  return doc.save({ updateFieldAppearances: false, ...opt.save || {} });
1506
2745
  }
1507
- function coveredText(items, box) {
2746
+ function ownWriterFits(model, opt) {
2747
+ if (opt.pdfa || opt.tagged || opt.encrypt || opt.prepare || opt.save || !model.pages.length) return false;
2748
+ if ((model.pageStarts || []).some((i) => i > 0)) return false;
2749
+ for (const pg of model.pages) {
2750
+ if ((pg.height ?? model.height) !== model.height) return false;
2751
+ for (const it of pg.items) {
2752
+ if (it.t === "text") {
2753
+ if (!isStandard(it.font) || it.lines.some((l) => l.runs)) return false;
2754
+ } else if (it.t === "link") {
2755
+ const a = it.action;
2756
+ if (a?.type === "bookmark" && !(a.page >= 1 && a.page <= model.pages.length)) return false;
2757
+ } else if (!(it.t === "line" || it.t === "ellipse" || it.t === "rect" && !it.radius)) return false;
2758
+ }
2759
+ }
2760
+ return true;
2761
+ }
2762
+ async function ownWriter(model, fontStore, opt) {
2763
+ const fixed = fixedDate(opt), when = fixed ?? /* @__PURE__ */ new Date();
2764
+ const parts = [];
2765
+ const info = { width: model.width, height: model.height, bookmarks: model.bookmarks || [], headings: model.headings || [], warnings: [] };
2766
+ await writePagedPdf(
2767
+ { info, pages: async function* () {
2768
+ yield* model.pages;
2769
+ } },
2770
+ { fontStore, subset: opt.subset, id: fixed ? await contentId(model, opt, when) : void 0, title: opt.title, author: opt.author, creationDate: when, drillBase: opt.drillBase },
2771
+ { write: (u8) => {
2772
+ parts.push(u8);
2773
+ } }
2774
+ );
2775
+ const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));
2776
+ let at = 0;
2777
+ for (const p of parts) {
2778
+ out.set(p, at);
2779
+ at += p.length;
2780
+ }
2781
+ return out;
2782
+ }
2783
+ function coveredText2(items, box) {
1508
2784
  const lines = [];
1509
2785
  for (const t of items) if (t.t === "text" && t.lines) {
1510
2786
  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);
@@ -1526,11 +2802,11 @@ async function contentId(model, opt, when) {
1526
2802
  }
1527
2803
  function fieldFont(it) {
1528
2804
  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;
2805
+ for (const l of d.lines) for (const r of l.runs || []) if (r.font !== it.font && r.text.trim()) return embeddedFace(r.font);
1530
2806
  }
1531
- return it.font;
2807
+ return embeddedFace(it.font);
1532
2808
  }
1533
- var pdfLiteral = (s) => PDFString4.of(String(s).replace(/[\\()]/g, "\\$&"));
2809
+ var pdfLiteral = (s) => PDFString.of(String(s).replace(/[\\()]/g, "\\$&"));
1534
2810
  function plainEncoding(pf) {
1535
2811
  const e = pf.embedder, f = e.font, memo = /* @__PURE__ */ new Map();
1536
2812
  e.hexOf = (text) => {
@@ -1546,7 +2822,7 @@ function plainEncoding(pf) {
1546
2822
  }
1547
2823
  return hex2;
1548
2824
  };
1549
- e.encodeText = (text) => PDFHexString5.of(e.hexOf(text));
2825
+ e.encodeText = (text) => PDFHexString.of(e.hexOf(text));
1550
2826
  e.widthOfTextAtSize = (text, size) => {
1551
2827
  let w = 0;
1552
2828
  for (const ch of text) w += f.glyphForCodePoint(
@@ -1555,8 +2831,8 @@ function plainEncoding(pf) {
1555
2831
  ).advanceWidth || 0;
1556
2832
  return w * size / f.unitsPerEm;
1557
2833
  };
1558
- const lit = /* @__PURE__ */ new Map();
1559
- const esc = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
2834
+ const lit2 = /* @__PURE__ */ new Map();
2835
+ const esc3 = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
1560
2836
  e.tjOf = (text) => {
1561
2837
  let out = "", cur = "", any = false;
1562
2838
  for (const ch of text) {
@@ -1582,10 +2858,10 @@ function plainEncoding(pf) {
1582
2858
  /** @type {number} */
1583
2859
  ch.codePointAt(0)
1584
2860
  );
1585
- let b = lit.get(cp);
2861
+ let b = lit2.get(cp);
1586
2862
  if (b === void 0) {
1587
2863
  const id = f.glyphForCodePoint(cp).id;
1588
- lit.set(cp, b = esc(id >> 8) + esc(id & 255));
2864
+ lit2.set(cp, b = esc3(id >> 8) + esc3(id & 255));
1589
2865
  }
1590
2866
  out += b;
1591
2867
  }
@@ -1623,7 +2899,7 @@ function pageLabels(doc, model) {
1623
2899
  const starts = [.../* @__PURE__ */ new Set([0, ...model.pageStarts || []])].filter((i) => i >= 0 && i < n).sort((a, b) => a - b);
1624
2900
  const ctx = doc.context;
1625
2901
  const nums = starts.flatMap((i) => [i, ctx.obj({ S: "D", St: 1 })]);
1626
- doc.catalog.set(PDFName3.of("PageLabels"), ctx.obj({ Nums: nums }));
2902
+ doc.catalog.set(PDFName.of("PageLabels"), ctx.obj({ Nums: nums }));
1627
2903
  }
1628
2904
  function addOutline(doc, bookmarks, dest) {
1629
2905
  const ctx = doc.context;
@@ -1637,7 +2913,7 @@ function addOutline(doc, bookmarks, dest) {
1637
2913
  if (!Dest) continue;
1638
2914
  const level = Math.max(0, Math.min(9, Number(b.level) || 0));
1639
2915
  while (stack[stack.length - 1].level >= level) stack.pop();
1640
- const node2 = { ref: ctx.nextRef(), level, kids: [], Title: PDFHexString5.fromText(b.label), Dest };
2916
+ const node2 = { ref: ctx.nextRef(), level, kids: [], Title: PDFHexString.fromText(b.label), Dest };
1641
2917
  stack[stack.length - 1].kids.push(node2);
1642
2918
  stack.push(node2);
1643
2919
  }
@@ -1650,15 +2926,15 @@ function addOutline(doc, bookmarks, dest) {
1650
2926
  });
1651
2927
  write(root);
1652
2928
  ctx.assign(root.ref, ctx.obj({ Type: "Outlines", ...children(root) }));
1653
- doc.catalog.set(PDFName3.of("Outlines"), root.ref);
1654
- doc.catalog.set(PDFName3.of("PageMode"), PDFName3.of("UseOutlines"));
2929
+ doc.catalog.set(PDFName.of("Outlines"), root.ref);
2930
+ doc.catalog.set(PDFName.of("PageMode"), PDFName.of("UseOutlines"));
1655
2931
  }
1656
2932
  function withPadding(font) {
1657
2933
  const out = new Uint8Array(font.length + 16);
1658
2934
  out.set(font);
1659
2935
  return out;
1660
2936
  }
1661
- function subsetTag(bytes) {
2937
+ function subsetTag2(bytes) {
1662
2938
  let h = 2166136261;
1663
2939
  for (let i = 0; i < bytes.length; i++) h = Math.imul(h ^ bytes[i], 16777619);
1664
2940
  let tag = "";
@@ -1675,4 +2951,4 @@ function roundRect(x, y, w, h, r) {
1675
2951
  export {
1676
2952
  exportPdf
1677
2953
  };
1678
- //# sourceMappingURL=chunk-TSC4RAH3.js.map
2954
+ //# sourceMappingURL=chunk-3XZY54LM.js.map