modern-pdf-lib 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +1 -1
  2. package/dist/{batchOptimize-DtRwBOqR.mjs → batchOptimize-BCJEEN8J.mjs} +4 -4
  3. package/dist/{batchOptimize-Ba_pWw71.cjs → batchOptimize-C1W3O68Q.cjs} +3 -3
  4. package/dist/{bridge-DYCQzxF7.cjs → bridge-DMEuGtfn.cjs} +2 -2
  5. package/dist/{bridge-CcivG_Sm.mjs → bridge-DaS-gzEd.mjs} +3 -3
  6. package/dist/browser.cjs +31 -10
  7. package/dist/browser.d.cts +5 -5
  8. package/dist/browser.d.mts +5 -5
  9. package/dist/browser.mjs +12 -12
  10. package/dist/cli/index.cjs +2 -2
  11. package/dist/cli/index.mjs +3 -3
  12. package/dist/{compressionAnalysis-B84FPXaQ.cjs → compressionAnalysis-B-FPzgzw.cjs} +7 -7
  13. package/dist/{compressionAnalysis-DGs-MqTe.d.mts → compressionAnalysis-Ch7t-HXn.d.mts} +2 -2
  14. package/dist/{compressionAnalysis-DGs-MqTe.d.mts.map → compressionAnalysis-Ch7t-HXn.d.mts.map} +1 -1
  15. package/dist/{compressionAnalysis-odbHC7Uk.mjs → compressionAnalysis-CwknBtqx.mjs} +7 -7
  16. package/dist/{compressionAnalysis-VtYV9Zmq.d.cts → compressionAnalysis-Dgv1TtHJ.d.cts} +2 -2
  17. package/dist/{compressionAnalysis-VtYV9Zmq.d.cts.map → compressionAnalysis-Dgv1TtHJ.d.cts.map} +1 -1
  18. package/dist/create.cjs +3 -3
  19. package/dist/create.d.cts +2 -2
  20. package/dist/create.d.mts +2 -2
  21. package/dist/create.mjs +3 -3
  22. package/dist/{deduplicateImages-MfUDPxQz.mjs → deduplicateImages-DIon68zB.mjs} +2 -2
  23. package/dist/{fflateAdapter-PSiW_ML7.mjs → fflateAdapter-DuNiByKx.mjs} +2 -2
  24. package/dist/{fontEmbed-BN842wlb.d.cts → fontEmbed-3YhUPLFj.d.cts} +2 -2
  25. package/dist/{fontEmbed-BN842wlb.d.cts.map → fontEmbed-3YhUPLFj.d.cts.map} +1 -1
  26. package/dist/{fontEmbed-Dgq5K89o.d.mts → fontEmbed-DlVnVCZU.d.mts} +2 -2
  27. package/dist/{fontEmbed-Dgq5K89o.d.mts.map → fontEmbed-DlVnVCZU.d.mts.map} +1 -1
  28. package/dist/{fontSubset-D-vQQems.mjs → fontSubset-BGFDIMmT.mjs} +2 -2
  29. package/dist/forms.cjs +1 -1
  30. package/dist/forms.mjs +1 -1
  31. package/dist/{index-DCSbmXWh.d.mts → index-B4S61WjK.d.mts} +589 -21
  32. package/dist/index-B4S61WjK.d.mts.map +1 -0
  33. package/dist/{index-J1W3FdL8.d.cts → index-xfJP6Ycm.d.cts} +589 -21
  34. package/dist/index-xfJP6Ycm.d.cts.map +1 -0
  35. package/dist/index.cjs +31 -10
  36. package/dist/index.d.cts +5 -5
  37. package/dist/index.d.mts +5 -5
  38. package/dist/index.mjs +12 -12
  39. package/dist/{layout-D6EUKSP8.mjs → layout-CrqeJBMI.mjs} +3 -3
  40. package/dist/{layout-DH61a1iR.cjs → layout-DQh05VP-.cjs} +3 -3
  41. package/dist/{libdeflateWasm-8b91Vmia.mjs → libdeflateWasm-CcA1W04G.mjs} +3 -3
  42. package/dist/{libdeflateWasm-BdiDEJOj.cjs → libdeflateWasm-DLw-I1CY.cjs} +2 -2
  43. package/dist/{loader-C7B5dVCI.mjs → loader-CVB-c_3Z.mjs} +16 -6
  44. package/dist/{loader-I4zdkoWc.cjs → loader-DYCH3n7d.cjs} +15 -5
  45. package/dist/parse.cjs +2 -2
  46. package/dist/parse.d.cts +2 -2
  47. package/dist/parse.d.mts +2 -2
  48. package/dist/parse.mjs +2 -2
  49. package/dist/{pdfCatalog-CYy4NXEY.cjs → pdfCatalog-Bqq4FiLn.cjs} +2 -1
  50. package/dist/{pdfCatalog-3yMIhJtt.mjs → pdfCatalog-CnKMAtIo.mjs} +3 -2
  51. package/dist/{pdfDocument-CbU-2TjT.d.cts → pdfDocument-Bc_vAO74.d.cts} +257 -172
  52. package/dist/pdfDocument-Bc_vAO74.d.cts.map +1 -0
  53. package/dist/{pdfDocument-BgvEP5Po.d.mts → pdfDocument-Bi-NoyXv.d.mts} +257 -172
  54. package/dist/pdfDocument-Bi-NoyXv.d.mts.map +1 -0
  55. package/dist/{pdfDocument-B0_XwS4X.mjs → pdfDocument-D7aFSQEY.mjs} +219 -40
  56. package/dist/{pdfDocument-CEbbUP9i.cjs → pdfDocument-D9uYNSb-.cjs} +233 -36
  57. package/dist/{pdfForm-9gd40uz9.cjs → pdfForm-BpqDGp29.cjs} +7 -1
  58. package/dist/{pdfForm-Cn-cVicP.mjs → pdfForm-C3mC9FoQ.mjs} +2 -2
  59. package/dist/{pdfPage-B_d9HmkG.mjs → pdfPage-BJIE5hc6.mjs} +189 -24
  60. package/dist/{pdfPage-Cd8jOJp6.cjs → pdfPage-C_tjEjj1.cjs} +188 -23
  61. package/dist/{pngEmbed-BWAbEUKF.mjs → pngEmbed-CGi7cym7.mjs} +3 -3
  62. package/dist/{pngEmbed-D4X4ZN-3.cjs → pngEmbed-CTn9IeNB.cjs} +2 -2
  63. package/dist/{src-Db6Qknoz.mjs → src-QZWP21qF.mjs} +1738 -157
  64. package/dist/{src-B1iDGLCL.cjs → src-lFqJHb1C.cjs} +1874 -185
  65. package/package.json +2 -1
  66. package/dist/index-DCSbmXWh.d.mts.map +0 -1
  67. package/dist/index-J1W3FdL8.d.cts.map +0 -1
  68. package/dist/pdfDocument-BgvEP5Po.d.mts.map +0 -1
  69. package/dist/pdfDocument-CbU-2TjT.d.cts.map +0 -1
@@ -1,6 +1,6 @@
1
1
  const require_rolldown_runtime = require('./rolldown-runtime-CKhH4XqG.cjs');
2
2
  const require_pdfObjects = require('./pdfObjects-1veop1_d.cjs');
3
- const require_pdfCatalog = require('./pdfCatalog-CYy4NXEY.cjs');
3
+ const require_pdfCatalog = require('./pdfCatalog-Bqq4FiLn.cjs');
4
4
 
5
5
  //#region src/core/operators/text.ts
6
6
  /**
@@ -16,7 +16,7 @@ const require_pdfCatalog = require('./pdfCatalog-CYy4NXEY.cjs');
16
16
  * Escape a string for use inside a PDF literal string `(…)`.
17
17
  * Backslash, open-paren and close-paren must be escaped.
18
18
  */
19
- function escapePdfString(text) {
19
+ function escapePdfString$1(text) {
20
20
  return text.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)").replace(/\r/g, "\\r").replace(/\n/g, "\\n").replace(/\t/g, "\\t");
21
21
  }
22
22
  /**
@@ -168,7 +168,7 @@ function nextLine() {
168
168
  * @param text The text to display. Special characters are escaped.
169
169
  */
170
170
  function showText(text) {
171
- return `(${escapePdfString(text)}) Tj\n`;
171
+ return `(${escapePdfString$1(text)}) Tj\n`;
172
172
  }
173
173
  /**
174
174
  * Show a text string using a hex-encoded string (`<…> Tj`).
@@ -193,7 +193,7 @@ function showTextHex(hex) {
193
193
  */
194
194
  function showTextArray(items) {
195
195
  return `[${items.map((item) => {
196
- if (typeof item === "string") return `(${escapePdfString(item)})`;
196
+ if (typeof item === "string") return `(${escapePdfString$1(item)})`;
197
197
  return n$6(item);
198
198
  }).join(" ")}] TJ\n`;
199
199
  }
@@ -203,7 +203,7 @@ function showTextArray(items) {
203
203
  * Equivalent to `T*` followed by `string Tj`.
204
204
  */
205
205
  function showTextNextLine(text) {
206
- return `(${escapePdfString(text)}) '\n`;
206
+ return `(${escapePdfString$1(text)}) '\n`;
207
207
  }
208
208
  /**
209
209
  * Show a text string, set word and character spacing, and move to the
@@ -214,7 +214,7 @@ function showTextNextLine(text) {
214
214
  * @param text Text to show.
215
215
  */
216
216
  function showTextWithSpacing(wordSpacing, charSpacing, text) {
217
- return `${n$6(wordSpacing)} ${n$6(charSpacing)} (${escapePdfString(text)}) "\n`;
217
+ return `${n$6(wordSpacing)} ${n$6(charSpacing)} (${escapePdfString$1(text)}) "\n`;
218
218
  }
219
219
 
220
220
  //#endregion
@@ -1568,7 +1568,7 @@ function parseSvgColor(colorStr) {
1568
1568
  const r = parseInt(s.slice(1, 3), 16);
1569
1569
  const g = parseInt(s.slice(3, 5), 16);
1570
1570
  const b = parseInt(s.slice(5, 7), 16);
1571
- if (!isNaN(r) && !isNaN(g) && !isNaN(b)) {
1571
+ if (!Number.isNaN(r) && !Number.isNaN(g) && !Number.isNaN(b)) {
1572
1572
  const result = {
1573
1573
  r,
1574
1574
  g,
@@ -1582,7 +1582,7 @@ function parseSvgColor(colorStr) {
1582
1582
  const r = parseInt(s[1] + s[1], 16);
1583
1583
  const g = parseInt(s[2] + s[2], 16);
1584
1584
  const b = parseInt(s[3] + s[3], 16);
1585
- if (!isNaN(r) && !isNaN(g) && !isNaN(b)) {
1585
+ if (!Number.isNaN(r) && !Number.isNaN(g) && !Number.isNaN(b)) {
1586
1586
  const result = {
1587
1587
  r,
1588
1588
  g,
@@ -2167,7 +2167,7 @@ function numAttr(attrs, name, defaultVal = 0) {
2167
2167
  const v = attrs[name];
2168
2168
  if (v === void 0) return defaultVal;
2169
2169
  const n = parseFloat(v);
2170
- return isNaN(n) ? defaultVal : n;
2170
+ return Number.isNaN(n) ? defaultVal : n;
2171
2171
  }
2172
2172
  /** Generate drawing commands for a <rect> element. */
2173
2173
  function rectCommands(attrs) {
@@ -2304,7 +2304,7 @@ function lineCommands(attrs) {
2304
2304
  }
2305
2305
  /** Parse a space/comma-separated list of numbers. */
2306
2306
  function parseNumberList(str) {
2307
- return str.split(/[\s,]+/).filter(Boolean).map(Number).filter((n) => !isNaN(n));
2307
+ return str.split(/[\s,]+/).filter(Boolean).map(Number).filter((n) => !Number.isNaN(n));
2308
2308
  }
2309
2309
  /** Generate drawing commands for a <polyline> element. */
2310
2310
  function polylineCommands(attrs) {
@@ -2357,17 +2357,17 @@ function resolveStyles(el) {
2357
2357
  const sw = attrs["stroke-width"];
2358
2358
  if (sw !== void 0) {
2359
2359
  const v = parseFloat(sw);
2360
- if (!isNaN(v)) el.strokeWidth = v;
2360
+ if (!Number.isNaN(v)) el.strokeWidth = v;
2361
2361
  }
2362
2362
  const opStr = attrs["opacity"];
2363
2363
  if (opStr !== void 0) {
2364
2364
  const v = parseFloat(opStr);
2365
- if (!isNaN(v)) el.opacity = v;
2365
+ if (!Number.isNaN(v)) el.opacity = v;
2366
2366
  }
2367
2367
  const fillOpStr = attrs["fill-opacity"];
2368
2368
  if (fillOpStr !== void 0 && el.fill) {
2369
2369
  const v = parseFloat(fillOpStr);
2370
- if (!isNaN(v)) el.fill = {
2370
+ if (!Number.isNaN(v)) el.fill = {
2371
2371
  ...el.fill,
2372
2372
  a: v
2373
2373
  };
@@ -2375,11 +2375,46 @@ function resolveStyles(el) {
2375
2375
  const strokeOpStr = attrs["stroke-opacity"];
2376
2376
  if (strokeOpStr !== void 0 && el.stroke) {
2377
2377
  const v = parseFloat(strokeOpStr);
2378
- if (!isNaN(v)) el.stroke = {
2378
+ if (!Number.isNaN(v)) el.stroke = {
2379
2379
  ...el.stroke,
2380
2380
  a: v
2381
2381
  };
2382
2382
  }
2383
+ const fillRuleStr = attrs["fill-rule"];
2384
+ if (fillRuleStr === "evenodd") el.fillRule = "evenodd";
2385
+ else if (fillRuleStr === "nonzero") el.fillRule = "nonzero";
2386
+ const linecapStr = attrs["stroke-linecap"];
2387
+ if (linecapStr === "butt" || linecapStr === "round" || linecapStr === "square") el.strokeLinecap = linecapStr;
2388
+ const linejoinStr = attrs["stroke-linejoin"];
2389
+ if (linejoinStr === "miter" || linejoinStr === "round" || linejoinStr === "bevel") el.strokeLinejoin = linejoinStr;
2390
+ const miterStr = attrs["stroke-miterlimit"];
2391
+ if (miterStr !== void 0) {
2392
+ const v = parseFloat(miterStr);
2393
+ if (!Number.isNaN(v)) el.strokeMiterlimit = v;
2394
+ }
2395
+ const dashStr = attrs["stroke-dasharray"];
2396
+ if (dashStr !== void 0 && dashStr !== "none") {
2397
+ const dashes = dashStr.split(/[\s,]+/).filter(Boolean).map(Number).filter((x) => !Number.isNaN(x));
2398
+ if (dashes.length > 0) el.strokeDasharray = dashes;
2399
+ }
2400
+ const dashOffStr = attrs["stroke-dashoffset"];
2401
+ if (dashOffStr !== void 0) {
2402
+ const v = parseFloat(dashOffStr);
2403
+ if (!Number.isNaN(v)) el.strokeDashoffset = v;
2404
+ }
2405
+ const ffStr = attrs["font-family"];
2406
+ if (ffStr !== void 0) el.fontFamily = ffStr.replace(/^['"]|['"]$/g, "");
2407
+ const fsStr = attrs["font-size"];
2408
+ if (fsStr !== void 0) {
2409
+ const v = parseFloat(fsStr);
2410
+ if (!Number.isNaN(v)) el.fontSize = v;
2411
+ }
2412
+ const fwStr = attrs["font-weight"];
2413
+ if (fwStr !== void 0) el.fontWeight = fwStr;
2414
+ const fstStr = attrs["font-style"];
2415
+ if (fstStr !== void 0) el.fontStyle = fstStr;
2416
+ const taStr = attrs["text-anchor"];
2417
+ if (taStr === "start" || taStr === "middle" || taStr === "end") el.textAnchor = taStr;
2383
2418
  const transformStr = attrs["transform"];
2384
2419
  if (transformStr) el.transform = parseSvgTransform(transformStr);
2385
2420
  }
@@ -2424,7 +2459,11 @@ function parseSvg(svgString) {
2424
2459
  case "text":
2425
2460
  if (stack.length > 0) {
2426
2461
  const parent = stack.at(-1);
2427
- if (parent.tag === "text" || parent.tag === "tspan") parent.attributes["__text"] = token.text ?? "";
2462
+ if (parent.tag === "text" || parent.tag === "tspan") {
2463
+ const txt = token.text ?? "";
2464
+ parent.attributes["__text"] = txt;
2465
+ parent.textContent = txt;
2466
+ }
2428
2467
  }
2429
2468
  break;
2430
2469
  }
@@ -2468,6 +2507,12 @@ function n$1(value) {
2468
2507
  const s = value.toFixed(6).replace(/\.?0+$/, "");
2469
2508
  return s === "-0" ? "0" : s;
2470
2509
  }
2510
+ /**
2511
+ * Escape a string for use inside a PDF literal string `(...)`.
2512
+ */
2513
+ function escapePdfString(text) {
2514
+ return text.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)").replace(/\r/g, "\\r").replace(/\n/g, "\\n").replace(/\t/g, "\\t");
2515
+ }
2471
2516
  /** Magic constant for circular arc approximation: 4*(sqrt(2)-1)/3. */
2472
2517
  const KAPPA$1 = .5522847498;
2473
2518
  /**
@@ -2649,6 +2694,33 @@ function commandsToPathOps(commands) {
2649
2694
  }
2650
2695
  return ops;
2651
2696
  }
2697
+ /** Map SVG stroke-linecap value to PDF line cap integer. */
2698
+ function linecapToInt(cap) {
2699
+ switch (cap) {
2700
+ case "butt": return 0;
2701
+ case "round": return 1;
2702
+ case "square": return 2;
2703
+ }
2704
+ }
2705
+ /** Map SVG stroke-linejoin value to PDF line join integer. */
2706
+ function linejoinToInt(join) {
2707
+ switch (join) {
2708
+ case "miter": return 0;
2709
+ case "round": return 1;
2710
+ case "bevel": return 2;
2711
+ }
2712
+ }
2713
+ /**
2714
+ * Choose the correct PDF painting operator based on fill/stroke state
2715
+ * and fill-rule.
2716
+ */
2717
+ function paintingOperator(hasFill, hasStroke, fillRule) {
2718
+ const evenOdd = fillRule === "evenodd";
2719
+ if (hasFill && hasStroke) return evenOdd ? "B*\n" : "B\n";
2720
+ if (hasFill) return evenOdd ? "f*\n" : "f\n";
2721
+ if (hasStroke) return "S\n";
2722
+ return evenOdd ? "f*\n" : "f\n";
2723
+ }
2652
2724
  /**
2653
2725
  * Convert an SVG element tree into PDF content stream operators.
2654
2726
  *
@@ -2695,30 +2767,91 @@ function svgToPdfOperators(element, options) {
2695
2767
  function renderElement(el) {
2696
2768
  let ops = "";
2697
2769
  const tag = el.tag;
2698
- if (tag === "defs" || tag === "title" || tag === "desc" || tag === "metadata") return "";
2770
+ if (tag === "defs" || tag === "title" || tag === "desc" || tag === "metadata" || tag === "style" || tag === "clipPath" || tag === "mask" || tag === "symbol" || tag === "marker") return "";
2699
2771
  const needsState = el.transform !== void 0 || el.opacity !== void 0;
2700
2772
  if (needsState) ops += "q\n";
2701
2773
  if (el.transform) {
2702
2774
  const [a, b, c, d, e, f] = el.transform;
2703
2775
  ops += `${n$1(a)} ${n$1(b)} ${n$1(c)} ${n$1(d)} ${n$1(e)} ${n$1(f)} cm\n`;
2704
2776
  }
2777
+ if (tag === "text" || tag === "tspan") ops += renderTextElement(el);
2705
2778
  if (el.commands && el.commands.length > 0) {
2706
2779
  const hasFill = el.fill !== void 0;
2707
2780
  const hasStroke = el.stroke !== void 0;
2708
2781
  if (hasFill) ops += `${n$1(el.fill.r / 255)} ${n$1(el.fill.g / 255)} ${n$1(el.fill.b / 255)} rg\n`;
2709
2782
  if (hasStroke) ops += `${n$1(el.stroke.r / 255)} ${n$1(el.stroke.g / 255)} ${n$1(el.stroke.b / 255)} RG\n`;
2710
2783
  if (el.strokeWidth !== void 0) ops += `${n$1(el.strokeWidth)} w\n`;
2784
+ if (el.strokeLinecap !== void 0) ops += `${linecapToInt(el.strokeLinecap)} J\n`;
2785
+ if (el.strokeLinejoin !== void 0) ops += `${linejoinToInt(el.strokeLinejoin)} j\n`;
2786
+ if (el.strokeMiterlimit !== void 0) ops += `${n$1(el.strokeMiterlimit)} M\n`;
2787
+ if (el.strokeDasharray !== void 0) {
2788
+ const phase = el.strokeDashoffset ?? 0;
2789
+ const arr = `[${el.strokeDasharray.map(n$1).join(" ")}]`;
2790
+ ops += `${arr} ${n$1(phase)} d\n`;
2791
+ }
2711
2792
  ops += commandsToPathOps(el.commands);
2712
- if (hasFill && hasStroke) ops += "B\n";
2713
- else if (hasFill) ops += "f\n";
2714
- else if (hasStroke) ops += "S\n";
2715
- else ops += "f\n";
2793
+ ops += paintingOperator(hasFill, hasStroke, el.fillRule);
2716
2794
  }
2717
2795
  for (const child of el.children) ops += renderElement(child);
2718
2796
  if (needsState) ops += "Q\n";
2719
2797
  return ops;
2720
2798
  }
2721
2799
  /**
2800
+ * Render a `<text>` or `<tspan>` SVG element as PDF text operators.
2801
+ *
2802
+ * SVG text positioning uses `x` and `y` attributes. We emit a
2803
+ * text matrix (Tm) to position the text, using Helvetica as the
2804
+ * default font (since we cannot embed arbitrary fonts without the
2805
+ * full font pipeline).
2806
+ *
2807
+ * The font is referenced as `/Helvetica` which must exist in the
2808
+ * page's font resources. When drawn via `drawSvgOnPage`, the page
2809
+ * will need to have a Helvetica resource. For standalone operator
2810
+ * generation the caller is responsible for resource setup.
2811
+ */
2812
+ function renderTextElement(el) {
2813
+ const text = el.textContent ?? el.attributes["__text"] ?? "";
2814
+ if (!text) return "";
2815
+ let ops = "";
2816
+ const posX = parseFloat(el.attributes["x"] ?? "0") || 0;
2817
+ const posY = parseFloat(el.attributes["y"] ?? "0") || 0;
2818
+ const fontSize = el.fontSize ?? 16;
2819
+ const fontName = resolveStandardFont(el.fontFamily, el.fontWeight, el.fontStyle);
2820
+ if (el.fill) ops += `${n$1(el.fill.r / 255)} ${n$1(el.fill.g / 255)} ${n$1(el.fill.b / 255)} rg\n`;
2821
+ ops += "BT\n";
2822
+ ops += `/${fontName} ${n$1(fontSize)} Tf\n`;
2823
+ ops += `${n$1(posX)} ${n$1(posY)} Td\n`;
2824
+ ops += `(${escapePdfString(text)}) Tj\n`;
2825
+ ops += "ET\n";
2826
+ return ops;
2827
+ }
2828
+ /**
2829
+ * Resolve a font-family + weight + style to a PDF standard font name.
2830
+ *
2831
+ * PDF has 14 standard fonts; we map common CSS font families to them.
2832
+ */
2833
+ function resolveStandardFont(family, weight, style) {
2834
+ const isBold = weight === "bold" || weight !== void 0 && parseInt(weight, 10) >= 700;
2835
+ const isItalic = style === "italic" || style === "oblique";
2836
+ const lowerFamily = (family ?? "").toLowerCase();
2837
+ if (lowerFamily.includes("courier") || lowerFamily.includes("monospace")) {
2838
+ if (isBold && isItalic) return "Courier-BoldOblique";
2839
+ if (isBold) return "Courier-Bold";
2840
+ if (isItalic) return "Courier-Oblique";
2841
+ return "Courier";
2842
+ }
2843
+ if (lowerFamily.includes("times") || lowerFamily.includes("serif")) {
2844
+ if (isBold && isItalic) return "Times-BoldItalic";
2845
+ if (isBold) return "Times-Bold";
2846
+ if (isItalic) return "Times-Italic";
2847
+ return "Times-Roman";
2848
+ }
2849
+ if (isBold && isItalic) return "Helvetica-BoldOblique";
2850
+ if (isBold) return "Helvetica-Bold";
2851
+ if (isItalic) return "Helvetica-Oblique";
2852
+ return "Helvetica";
2853
+ }
2854
+ /**
2722
2855
  * Draw an SVG string onto a PDF page.
2723
2856
  *
2724
2857
  * Parses the SVG, converts it to PDF operators, and appends them
@@ -5326,7 +5459,7 @@ function rsEncode(data, numEC) {
5326
5459
  }
5327
5460
  function detectMode(data) {
5328
5461
  if (/^\d*$/.test(data)) return "numeric";
5329
- if (data.split("").every((ch) => ALPHANUMERIC_CHARS.includes(ch))) return "alphanumeric";
5462
+ if ([...data].every((ch) => ALPHANUMERIC_CHARS.includes(ch))) return "alphanumeric";
5330
5463
  return "byte";
5331
5464
  }
5332
5465
  /** Number of bits for the character count indicator. */
@@ -6607,6 +6740,17 @@ var PdfPage = class PdfPage {
6607
6740
  */
6608
6741
  rotation = 0;
6609
6742
  /**
6743
+ * Tab order for the page.
6744
+ * - `'S'` — Structure order (follows the logical structure tree)
6745
+ * - `'R'` — Row order
6746
+ * - `'C'` — Column order
6747
+ *
6748
+ * Written to the /Tabs entry in the page dictionary at save time.
6749
+ * PDF/UA requires `'S'` (structure order).
6750
+ * @internal
6751
+ */
6752
+ tabOrder;
6753
+ /**
6610
6754
  * Optional crop box `[llx, lly, urx, ury]`.
6611
6755
  * When set, written to the /CropBox entry in the page dictionary at save time.
6612
6756
  * @internal
@@ -7246,6 +7390,26 @@ var PdfPage = class PdfPage {
7246
7390
  setRotation(angle) {
7247
7391
  this.rotation = angle;
7248
7392
  }
7393
+ /**
7394
+ * Get the current tab order for this page.
7395
+ *
7396
+ * @returns `'S'` (structure), `'R'` (row), `'C'` (column), or
7397
+ * `undefined` if not set.
7398
+ */
7399
+ getTabOrder() {
7400
+ return this.tabOrder;
7401
+ }
7402
+ /**
7403
+ * Set the tab order for this page.
7404
+ *
7405
+ * PDF/UA requires `'S'` (structure order) so that assistive technology
7406
+ * follows the logical structure tree.
7407
+ *
7408
+ * @param order `'S'` (structure), `'R'` (row), or `'C'` (column).
7409
+ */
7410
+ setTabOrder(order) {
7411
+ this.tabOrder = order;
7412
+ }
7249
7413
  /** Get the page width in points. Alias for the `width` getter. */
7250
7414
  getWidth() {
7251
7415
  return this.mediaWidth;
@@ -8005,7 +8169,8 @@ var PdfPage = class PdfPage {
8005
8169
  bleedBox: this.bleedBox,
8006
8170
  artBox: this.artBox,
8007
8171
  trimBox: this.trimBox,
8008
- annotationRefs: annotRefs.length > 0 ? annotRefs : void 0
8172
+ annotationRefs: annotRefs.length > 0 ? annotRefs : void 0,
8173
+ tabOrder: this.tabOrder
8009
8174
  };
8010
8175
  }
8011
8176
  };
@@ -8725,4 +8890,4 @@ Object.defineProperty(exports, 'wrapText', {
8725
8890
  return wrapText;
8726
8891
  }
8727
8892
  });
8728
- //# sourceMappingURL=pdfPage-Cd8jOJp6.cjs.map
8893
+ //# sourceMappingURL=pdfPage-C_tjEjj1.cjs.map
@@ -1,4 +1,4 @@
1
- import { os as __exportAll } from "./index-DCSbmXWh.d.mts";
1
+ import { Gs as __exportAll } from "./index-B4S61WjK.d.mts";
2
2
  import { deflateSync, unzlibSync } from "fflate";
3
3
 
4
4
  //#region src/assets/image/pngEmbed.ts
@@ -146,7 +146,7 @@ async function initPngWasm(wasmSource) {
146
146
  const resp = await fetch(String(wasmSource));
147
147
  result = await WebAssembly.instantiateStreaming(resp, imports);
148
148
  } else {
149
- const { loadWasmModule } = await import("./loader-C7B5dVCI.mjs").then((n) => n.l);
149
+ const { loadWasmModule } = await import("./loader-CVB-c_3Z.mjs").then((n) => n.l);
150
150
  const bytes = await loadWasmModule("png");
151
151
  result = await WebAssembly.instantiate(bytes.buffer, imports);
152
152
  }
@@ -549,4 +549,4 @@ function embedComplexPng(ihdr, idatData, palette, transparency) {
549
549
 
550
550
  //#endregion
551
551
  export { pngEmbed_exports as n, embedPng as t };
552
- //# sourceMappingURL=pngEmbed-BWAbEUKF.mjs.map
552
+ //# sourceMappingURL=pngEmbed-CGi7cym7.mjs.map
@@ -146,7 +146,7 @@ async function initPngWasm(wasmSource) {
146
146
  const resp = await fetch(String(wasmSource));
147
147
  result = await WebAssembly.instantiateStreaming(resp, imports);
148
148
  } else {
149
- const { loadWasmModule } = await Promise.resolve().then(() => require("./loader-I4zdkoWc.cjs")).then((n) => n.loader_exports);
149
+ const { loadWasmModule } = await Promise.resolve().then(() => require("./loader-DYCH3n7d.cjs")).then((n) => n.loader_exports);
150
150
  const bytes = await loadWasmModule("png");
151
151
  result = await WebAssembly.instantiate(bytes.buffer, imports);
152
152
  }
@@ -560,4 +560,4 @@ Object.defineProperty(exports, 'pngEmbed_exports', {
560
560
  return pngEmbed_exports;
561
561
  }
562
562
  });
563
- //# sourceMappingURL=pngEmbed-D4X4ZN-3.cjs.map
563
+ //# sourceMappingURL=pngEmbed-CTn9IeNB.cjs.map