@pdfme/schemas 6.1.13-dev.4 → 6.1.13-dev.46

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 (44) hide show
  1. package/dist/barcodes/helper.d.ts +12 -2
  2. package/dist/{builtins-8En4EIAG.js → builtins-C-2wyB_3.js} +140 -83
  3. package/dist/builtins-C-2wyB_3.js.map +1 -0
  4. package/dist/builtins.js +1 -1
  5. package/dist/dynamicLayout.js +4 -4
  6. package/dist/{dynamicTemplate-DQF7c6NR.js → dynamicTemplate-CcnCXHfM.js} +2 -2
  7. package/dist/{dynamicTemplate-DQF7c6NR.js.map → dynamicTemplate-CcnCXHfM.js.map} +1 -1
  8. package/dist/{dynamicTemplate-DFk_de1Y.js → dynamicTemplate-DEwOv_DE.js} +7 -6
  9. package/dist/dynamicTemplate-DEwOv_DE.js.map +1 -0
  10. package/dist/{dynamicTemplate-CnK0nlnj.js → dynamicTemplate-DkTVIMNr.js} +2 -2
  11. package/dist/{dynamicTemplate-CnK0nlnj.js.map → dynamicTemplate-DkTVIMNr.js.map} +1 -1
  12. package/dist/graphics/orientation.d.ts +31 -0
  13. package/dist/{helper-VroN19Ci.js → helper-BR4_UZA5.js} +26 -3
  14. package/dist/helper-BR4_UZA5.js.map +1 -0
  15. package/dist/index.js +492 -123
  16. package/dist/index.js.map +1 -1
  17. package/dist/lists.js +2 -2
  18. package/dist/{measure-BC7tjAtT.js → measure-BarlRI1L.js} +71 -227
  19. package/dist/measure-BarlRI1L.js.map +1 -0
  20. package/dist/multiVariableText/helper.d.ts +8 -0
  21. package/dist/multiVariableText/types.d.ts +2 -0
  22. package/dist/pdfFont.d.ts +8 -0
  23. package/dist/splitRange-B6311Noc.js +10854 -0
  24. package/dist/splitRange-B6311Noc.js.map +1 -0
  25. package/dist/tables.js +2 -2
  26. package/dist/text/helper.d.ts +33 -1
  27. package/dist/text/lineBreak.d.ts +69 -0
  28. package/dist/text/lineBreakClasses.generated.d.ts +11 -0
  29. package/dist/text/richText.d.ts +2 -0
  30. package/dist/text/uiRender.d.ts +3 -1
  31. package/dist/text/wrap.d.ts +67 -0
  32. package/dist/texts.js +3 -3
  33. package/dist/{utils-D_sFXK0U.js → utils-CPYF2FY_.js} +18 -15
  34. package/dist/utils-CPYF2FY_.js.map +1 -0
  35. package/dist/utils.d.ts +3 -2
  36. package/dist/utils.js +3 -3
  37. package/package.json +3 -1
  38. package/dist/builtins-8En4EIAG.js.map +0 -1
  39. package/dist/dynamicTemplate-DFk_de1Y.js.map +0 -1
  40. package/dist/helper-VroN19Ci.js.map +0 -1
  41. package/dist/measure-BC7tjAtT.js.map +0 -1
  42. package/dist/splitRange-BHV0vb0Q.js +0 -504
  43. package/dist/splitRange-BHV0vb0Q.js.map +0 -1
  44. package/dist/utils-D_sFXK0U.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,16 +1,18 @@
1
- import { $ as VERTICAL_ALIGN_MIDDLE, F as DEFAULT_FONT_COLOR, G as PLACEHOLDER_FONT_COLOR, K as SYNTHETIC_BOLD_CSS_TEXT_SHADOW, N as DEFAULT_ALIGNMENT, a as createListItemSplitRange, b as createBoxDimension, c as getListItemRange, h as getFontKitFont, i as TEXT_LINE_SPLIT_UNIT, j as CODE_BACKGROUND_COLOR, l as getTableBodyRange, n as LIST_ITEM_SPLIT_UNIT, o as createTableBodySplitRange, r as TABLE_BODY_SPLIT_UNIT, s as createTextLineSplitRange, t as BUILT_IN_DYNAMIC_LAYOUT_SPLIT_UNITS, u as getTextLineRange, x as getBoxContentArea } from "./splitRange-BHV0vb0Q.js";
2
- import { a as measureTextLines, d as isInlineMarkdownTextSchema, g as parseInlineMarkdown, p as resolveFontVariant } from "./measure-BC7tjAtT.js";
3
- import { a as mapVerticalAlignToFlex, c as Formatter, i as makeElementPlainTextContentEditable, l as getExtraFormatterSchema, n as textSchema, o as uiRender$4, r as buildStyledTextContainer, s as propPanel$3, t as builtInPlugins, u as pdfRender$4 } from "./builtins-8En4EIAG.js";
4
- import { a as getCellPropPanelSchema, c as HEX_COLOR_PATTERN, i as getBodyWithSchemaRange, l as createSingleTable, n as getDynamicLayoutForTable, o as getColumnStylesPropPanelSchema, r as getBody, s as getDefaultCellStyles, t as getDynamicHeightsForTable } from "./dynamicTemplate-CnK0nlnj.js";
5
- import { c as isEditable, d as countUniqueVariableNames, f as getVariableNames, i as createSvgStr, l as readFile, n as convertForPdfLayoutProps, o as hex2PrintingColor, p as visitVariables, r as createErrorElm, t as addAlphaToHex, u as rotatePoint } from "./utils-D_sFXK0U.js";
6
- import { a as normalizeListItems, c as LIST_STYLE_BULLET, i as normalizeListItemEntries, l as LIST_STYLE_ORDERED, n as calculateListLayout, o as serializeListItems, s as DEFAULT_LIST_STYLE, t as getDynamicLayoutForList } from "./dynamicTemplate-DQF7c6NR.js";
7
- import { n as substituteVariablesAsInlineMarkdownLiterals, r as validateVariables, t as substituteVariables } from "./helper-VroN19Ci.js";
1
+ import { D as getBoxContentArea, E as createBoxDimension, L as CODE_BACKGROUND_COLOR, V as DEFAULT_FONT_COLOR, X as PLACEHOLDER_FONT_COLOR, Z as SYNTHETIC_BOLD_CSS_TEXT_SHADOW, a as createListItemSplitRange, c as getListItemRange, g as getFontKitFont, i as TEXT_LINE_SPLIT_UNIT, it as VERTICAL_ALIGN_MIDDLE, l as getTableBodyRange, n as LIST_ITEM_SPLIT_UNIT, o as createTableBodySplitRange, r as TABLE_BODY_SPLIT_UNIT, s as createTextLineSplitRange, t as BUILT_IN_DYNAMIC_LAYOUT_SPLIT_UNITS, u as getTextLineRange, z as DEFAULT_ALIGNMENT } from "./splitRange-B6311Noc.js";
2
+ import { a as measureTextLines, f as resolveFontVariant, h as parseInlineMarkdown, u as isInlineMarkdownTextSchema } from "./measure-BarlRI1L.js";
3
+ import { a as mapVerticalAlignToFlex, c as Formatter, d as embedAndGetFont, i as makeElementPlainTextContentEditable, l as getExtraFormatterSchema, n as textSchema, o as uiRender$4, r as buildStyledTextContainer, s as propPanel$3, t as builtInPlugins, u as pdfRender$4 } from "./builtins-C-2wyB_3.js";
4
+ import { a as getCellPropPanelSchema, c as HEX_COLOR_PATTERN, i as getBodyWithSchemaRange, l as createSingleTable, n as getDynamicLayoutForTable, o as getColumnStylesPropPanelSchema, r as getBody, s as getDefaultCellStyles, t as getDynamicHeightsForTable } from "./dynamicTemplate-DkTVIMNr.js";
5
+ import { c as isEditable, d as rotatePoint, f as countUniqueVariableNames, i as createSvgStr, l as readFile, m as visitVariables, n as convertForPdfLayoutProps, o as hex2PrintingColor, p as getVariableNames, r as createErrorElm, t as addAlphaToHex, u as rgbColorToCmykColor } from "./utils-CPYF2FY_.js";
6
+ import { a as normalizeListItems, c as LIST_STYLE_BULLET, i as normalizeListItemEntries, l as LIST_STYLE_ORDERED, n as calculateListLayout, o as serializeListItems, s as DEFAULT_LIST_STYLE, t as getDynamicLayoutForList } from "./dynamicTemplate-CcnCXHfM.js";
7
+ import { i as validateVariables, n as substituteVariables, r as substituteVariablesAsInlineMarkdownLiterals, t as resolveReadOnlyMultiVariableText } from "./helper-BR4_UZA5.js";
8
8
  import "./tables.js";
9
9
  import "./lists.js";
10
10
  import { DEFAULT_FONT_NAME, ZOOM, b64toUint8Array, getDefaultFont, getFallbackFontName, getInternalLinkTarget, mm2pt, normalizeLinkHref, px2mm } from "@pdfme/common";
11
11
  import { Buffer as Buffer$1 } from "buffer";
12
- import { toRadians } from "@pdfme/pdf-lib";
12
+ import { popGraphicsState, pushGraphicsState, rotateDegrees, translate } from "@pdfme/pdf-lib";
13
13
  import { Barcode, Calendar, CalendarClock, ChevronDown, Circle, CircleDot, Clock, Image, List, Minus, QrCode, Route, Square, SquareCheck, Table, Type } from "lucide";
14
+ import jpegJsModule from "jpeg-js";
15
+ import UPNGModule from "@pdf-lib/upng";
14
16
  import DOMPurify from "dompurify";
15
17
  import bwipjs from "bwip-js";
16
18
  import AirDatepicker from "air-datepicker";
@@ -43,9 +45,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
43
45
  var pdfRender$3 = async (arg) => {
44
46
  const { value, schema, ...rest } = arg;
45
47
  if (schema.readOnly) {
46
- const readOnlyValue = schema.variables.length > 0 ? value : schema.text || "";
47
48
  await pdfRender$4({
48
- value: readOnlyValue,
49
+ value: resolveReadOnlyMultiVariableText(schema, value),
49
50
  schema,
50
51
  ...rest
51
52
  });
@@ -211,7 +212,7 @@ var uiRender$3 = async (arg) => {
211
212
  let text = schema.text;
212
213
  let numVariables = schema.variables.length;
213
214
  const renderResolvedValue = schema.readOnly === true && mode !== "designer";
214
- const renderValue = renderResolvedValue ? numVariables > 0 ? value : text || "" : isInlineMarkdownTextSchema(schema) ? substituteVariablesAsInlineMarkdownLiterals(text, value) : substituteVariables(text, value);
215
+ const renderValue = renderResolvedValue ? resolveReadOnlyMultiVariableText(schema, value) : isInlineMarkdownTextSchema(schema) ? substituteVariablesAsInlineMarkdownLiterals(text, value) : substituteVariables(text, value);
215
216
  if (mode === "form" && numVariables > 0 && !renderResolvedValue) {
216
217
  await formUiRender(arg);
217
218
  return;
@@ -232,7 +233,7 @@ var uiRender$3 = async (arg) => {
232
233
  ...rest
233
234
  });
234
235
  const textBlock = rootElement.querySelector("#text-" + String(schema.id));
235
- if (!textBlock) throw new Error("Text block not found. Ensure the text block has an id of \"text-\" + schema.id");
236
+ if (!textBlock) return;
236
237
  if (mode === "designer") textBlock.addEventListener("keyup", (event) => {
237
238
  text = textBlock.innerText || "";
238
239
  if (keyPressShouldBeChecked(event)) {
@@ -690,9 +691,13 @@ var shape = {
690
691
  });
691
692
  else if (schema.type === "rectangle") {
692
693
  const radius = schema.radius ?? 0;
694
+ const inset = rotatePoint({
695
+ x: position.x + borderWidth / 2,
696
+ y: position.y + borderWidth / 2
697
+ }, position, rotate.angle);
693
698
  page.drawRectangle({
694
- x: position.x + borderWidth * ((1 - Math.sin(toRadians(rotate))) / 2) + Math.tan(toRadians(rotate)) * Math.PI ** 2,
695
- y: position.y + borderWidth * ((1 + Math.sin(toRadians(rotate))) / 2) + Math.tan(toRadians(rotate)) * Math.PI ** 2,
699
+ x: inset.x,
700
+ y: inset.y,
696
701
  width: width - borderWidth,
697
702
  height: height - borderWidth,
698
703
  ...radius ? { radius: mm2pt(radius) } : {},
@@ -1407,88 +1412,208 @@ var listSchema = {
1407
1412
  icon: createSvgStr(List)
1408
1413
  };
1409
1414
  //#endregion
1410
- //#region src/graphics/imagehelper.ts
1411
- var decoder = new TextDecoder();
1412
- var toUTF8String = (input, start = 0, end = input.length) => decoder.decode(input.slice(start, end));
1413
- var toHexString = (input, start = 0, end = input.length) => input.slice(start, end).reduce((memo, i) => memo + ("0" + i.toString(16)).slice(-2), "");
1414
- var readUInt16BE = (input, offset = 0) => input[offset] * 256 + input[offset + 1];
1415
- var readUInt32BE = (input, offset = 0) => input[offset] * 2 ** 24 + input[offset + 1] * 2 ** 16 + input[offset + 2] * 256 + input[offset + 3];
1416
- var extractSize = (input, index) => {
1417
- return {
1418
- height: readUInt16BE(input, index),
1419
- width: readUInt16BE(input, index + 2)
1420
- };
1415
+ //#region src/graphics/orientation.ts
1416
+ var isJpegJsApi = (value) => !!value && typeof value === "object" && typeof value.decode === "function" && typeof value.encode === "function";
1417
+ var isUPNGApi = (value) => !!value && typeof value === "object" && typeof value.decode === "function" && typeof value.toRGBA8 === "function" && typeof value.encode === "function";
1418
+ var resolveExport = (value, guard, label) => {
1419
+ let current = value;
1420
+ while (current && typeof current === "object") {
1421
+ if (guard(current)) return current;
1422
+ current = current.default;
1423
+ }
1424
+ throw new TypeError(`Failed to resolve ${label} exports`);
1421
1425
  };
1422
- var validateInput = (input, index) => {
1423
- if (index > input.length) throw new TypeError("Corrupt JPG, exceeded buffer limits");
1424
- if (input[index] !== 255) throw new TypeError("Invalid JPG, marker table corrupted");
1426
+ var jpegJs = resolveExport(jpegJsModule, isJpegJsApi, "jpeg-js");
1427
+ var UPNG = resolveExport(UPNGModule, isUPNGApi, "@pdf-lib/upng");
1428
+ var JPEG_ENCODE_QUALITY = 90;
1429
+ var JPEG_MAX_MEMORY_MB = 512;
1430
+ var JPEG_SOI_0 = 255;
1431
+ var JPEG_SOI_1 = 216;
1432
+ var PNG_SIGNATURE = new Uint8Array([
1433
+ 137,
1434
+ 80,
1435
+ 78,
1436
+ 71,
1437
+ 13,
1438
+ 10,
1439
+ 26,
1440
+ 10
1441
+ ]);
1442
+ var toArrayBuffer = (bytes) => {
1443
+ const copy = new Uint8Array(bytes.byteLength);
1444
+ copy.set(bytes);
1445
+ return copy.buffer;
1425
1446
  };
1426
- var JPG = {
1427
- validate: (input) => toHexString(input, 0, 2) === "ffd8",
1428
- calculate(input) {
1429
- input = input.slice(4);
1430
- let next;
1431
- while (input.length) {
1432
- const i = readUInt16BE(input, 0);
1433
- validateInput(input, i);
1434
- next = input[i + 1];
1435
- if (next === 192 || next === 193 || next === 194) return extractSize(input, i + 5);
1436
- input = input.slice(i + 2);
1447
+ var isPngSignature = (bytes) => {
1448
+ if (bytes.length < PNG_SIGNATURE.length) return false;
1449
+ for (let i = 0; i < PNG_SIGNATURE.length; i++) if (bytes[i] !== PNG_SIGNATURE[i]) return false;
1450
+ return true;
1451
+ };
1452
+ var detectImageFormat = (bytes) => {
1453
+ if (bytes.length >= 2 && bytes[0] === JPEG_SOI_0 && bytes[1] === JPEG_SOI_1) return "jpeg";
1454
+ if (isPngSignature(bytes)) return "png";
1455
+ return "other";
1456
+ };
1457
+ /** TIFF/IFD0: returns 1..8 or undefined. Never throws. */
1458
+ var parseTiffOrientation = (tiff) => {
1459
+ try {
1460
+ if (tiff.length < 8) return void 0;
1461
+ const le = tiff[0] === 73 && tiff[1] === 73;
1462
+ if (!le && !(tiff[0] === 77 && tiff[1] === 77)) return void 0;
1463
+ const view = new DataView(tiff.buffer, tiff.byteOffset, tiff.byteLength);
1464
+ if (view.getUint16(2, le) !== 42) return void 0;
1465
+ const ifd = view.getUint32(4, le);
1466
+ if (ifd + 2 > tiff.length) return void 0;
1467
+ const n = view.getUint16(ifd, le);
1468
+ for (let i = 0; i < n; i++) {
1469
+ const entry = ifd + 2 + i * 12;
1470
+ if (entry + 12 > tiff.length) return void 0;
1471
+ if (view.getUint16(entry, le) !== 274) continue;
1472
+ if (view.getUint16(entry + 2, le) !== 3) return void 0;
1473
+ if (view.getUint32(entry + 4, le) !== 1) return void 0;
1474
+ const val = view.getUint16(entry + 8, le);
1475
+ return val >= 1 && val <= 8 ? val : void 0;
1437
1476
  }
1438
- throw new TypeError("Invalid JPG, no size found");
1477
+ return;
1478
+ } catch {
1479
+ return;
1439
1480
  }
1440
1481
  };
1441
- var pngSignature = "PNG\r\n\n";
1442
- var pngImageHeaderChunkName = "IHDR";
1443
- var pngFriedChunkName = "CgBI";
1444
- var typeHandlers = {
1445
- jpg: JPG,
1446
- png: {
1447
- validate(input) {
1448
- if (pngSignature === toUTF8String(input, 1, 8)) {
1449
- let chunkName = toUTF8String(input, 12, 16);
1450
- if (chunkName === pngFriedChunkName) chunkName = toUTF8String(input, 28, 32);
1451
- if (chunkName !== pngImageHeaderChunkName) throw new TypeError("Invalid PNG");
1452
- return true;
1482
+ var isExifApp1Payload = (segment) => segment.length >= 6 && segment[0] === 69 && segment[1] === 120 && segment[2] === 105 && segment[3] === 102 && segment[4] === 0 && segment[5] === 0;
1483
+ /** Standalone JPEG markers have no length field (TEM, RST0–7, SOI). */
1484
+ var isStandaloneJpegMarker = (marker) => marker === 1 || marker >= 208 && marker <= 216;
1485
+ /**
1486
+ * JPEG: scan APP1 'Exif\0\0' segments; stop at SOS/EOI.
1487
+ * Skips 0xFF fill/padding and standalone markers. If an Exif APP1 has no
1488
+ * valid Orientation, keep scanning for a later one.
1489
+ */
1490
+ var getJpegOrientation = (bytes) => {
1491
+ if (bytes.length < 2 || bytes[0] !== JPEG_SOI_0 || bytes[1] !== JPEG_SOI_1) return void 0;
1492
+ let pos = 2;
1493
+ while (pos < bytes.length) {
1494
+ if (bytes[pos] !== 255) return void 0;
1495
+ while (pos < bytes.length && bytes[pos] === 255) pos++;
1496
+ if (pos >= bytes.length) return void 0;
1497
+ const marker = bytes[pos++];
1498
+ if (isStandaloneJpegMarker(marker)) continue;
1499
+ if (marker === 218 || marker === 217) return void 0;
1500
+ if (pos + 2 > bytes.length) return void 0;
1501
+ const size = bytes[pos] << 8 | bytes[pos + 1];
1502
+ if (size < 2 || pos + size > bytes.length) return void 0;
1503
+ if (marker === 225 && size >= 8) {
1504
+ const segment = bytes.subarray(pos + 2, pos + size);
1505
+ if (isExifApp1Payload(segment)) {
1506
+ const orientation = parseTiffOrientation(segment.subarray(6));
1507
+ if (orientation !== void 0) return orientation;
1453
1508
  }
1454
- return false;
1455
- },
1456
- calculate(input) {
1457
- if (toUTF8String(input, 12, 16) === pngFriedChunkName) return {
1458
- height: readUInt32BE(input, 36),
1459
- width: readUInt32BE(input, 32)
1460
- };
1461
- return {
1462
- height: readUInt32BE(input, 20),
1463
- width: readUInt32BE(input, 16)
1464
- };
1465
1509
  }
1510
+ pos += size;
1466
1511
  }
1467
1512
  };
1468
- function detector(input) {
1469
- const firstBytes = {
1470
- 137: "png",
1471
- 255: "jpg"
1472
- };
1473
- const byte = input[0];
1474
- if (byte in firstBytes) {
1475
- const type = firstBytes[byte];
1476
- if (type && typeHandlers[type].validate(input)) return type;
1513
+ /**
1514
+ * PNG: scan chunks for eXIf (raw TIFF payload). Skip IDAT and other
1515
+ * ancillary chunks; eXIf may appear after image data. Stop at IEND.
1516
+ */
1517
+ var getPngOrientation = (bytes) => {
1518
+ if (!isPngSignature(bytes)) return void 0;
1519
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
1520
+ let pos = 8;
1521
+ while (pos + 12 <= bytes.length) {
1522
+ const length = view.getUint32(pos);
1523
+ if (pos + 12 + length > bytes.length) return void 0;
1524
+ const type = String.fromCharCode(bytes[pos + 4], bytes[pos + 5], bytes[pos + 6], bytes[pos + 7]);
1525
+ if (type === "eXIf") return parseTiffOrientation(bytes.subarray(pos + 8, pos + 8 + length));
1526
+ if (type === "IEND") return void 0;
1527
+ pos += 12 + length;
1477
1528
  }
1478
- return Object.keys(typeHandlers).find((key) => typeHandlers[key].validate(input));
1479
- }
1480
- var getImageDimension = (value) => {
1481
- const idx = value.indexOf(";base64,");
1482
- const imgBase64 = value.substring(idx + 8, value.length);
1483
- return imageSize(Buffer$1.from(imgBase64, "base64"));
1484
1529
  };
1485
- var imageSize = (imgBuffer) => {
1486
- const type = detector(imgBuffer);
1487
- if (typeof type !== "undefined" && type in typeHandlers) {
1488
- const size = typeHandlers[type].calculate(imgBuffer);
1489
- if (size !== void 0) return size;
1530
+ var orientationSwapsDimensions = (orientation) => orientation >= 5;
1531
+ /**
1532
+ * Map source (x, y) into destination (dx, dy) for EXIF orientations 2–8.
1533
+ * Orientations 5–8 swap width and height.
1534
+ */
1535
+ var transformRgba = (src, width, height, orientation) => {
1536
+ const swap = orientationSwapsDimensions(orientation);
1537
+ const destWidth = swap ? height : width;
1538
+ const destHeight = swap ? width : height;
1539
+ const dest = new Uint8Array(destWidth * destHeight * 4);
1540
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
1541
+ let dx = x;
1542
+ let dy = y;
1543
+ switch (orientation) {
1544
+ case 2:
1545
+ dx = width - 1 - x;
1546
+ dy = y;
1547
+ break;
1548
+ case 3:
1549
+ dx = width - 1 - x;
1550
+ dy = height - 1 - y;
1551
+ break;
1552
+ case 4:
1553
+ dx = x;
1554
+ dy = height - 1 - y;
1555
+ break;
1556
+ case 5:
1557
+ dx = y;
1558
+ dy = x;
1559
+ break;
1560
+ case 6:
1561
+ dx = height - 1 - y;
1562
+ dy = x;
1563
+ break;
1564
+ case 7:
1565
+ dx = height - 1 - y;
1566
+ dy = width - 1 - x;
1567
+ break;
1568
+ case 8:
1569
+ dx = y;
1570
+ dy = width - 1 - x;
1571
+ }
1572
+ const srcIndex = (y * width + x) * 4;
1573
+ const destIndex = (dy * destWidth + dx) * 4;
1574
+ dest[destIndex] = src[srcIndex];
1575
+ dest[destIndex + 1] = src[srcIndex + 1];
1576
+ dest[destIndex + 2] = src[srcIndex + 2];
1577
+ dest[destIndex + 3] = src[srcIndex + 3];
1490
1578
  }
1491
- throw new TypeError("[@pdfme/schemas/images] Unsupported file type: " + (type === void 0 ? "undefined" : type));
1579
+ return {
1580
+ data: dest,
1581
+ width: destWidth,
1582
+ height: destHeight
1583
+ };
1584
+ };
1585
+ var bakeJpegOrientation = (bytes) => {
1586
+ const orientation = getJpegOrientation(bytes);
1587
+ if (!orientation || orientation === 1) return bytes;
1588
+ const raw = jpegJs.decode(bytes, {
1589
+ useTArray: true,
1590
+ formatAsRGBA: true,
1591
+ maxMemoryUsageInMB: JPEG_MAX_MEMORY_MB
1592
+ });
1593
+ const transformed = transformRgba(raw.data, raw.width, raw.height, orientation);
1594
+ return new Uint8Array(jpegJs.encode({
1595
+ data: transformed.data,
1596
+ width: transformed.width,
1597
+ height: transformed.height
1598
+ }, JPEG_ENCODE_QUALITY).data);
1599
+ };
1600
+ var bakePngOrientation = (bytes) => {
1601
+ const orientation = getPngOrientation(bytes);
1602
+ if (!orientation || orientation === 1) return bytes;
1603
+ const img = UPNG.decode(toArrayBuffer(bytes));
1604
+ const transformed = transformRgba(new Uint8Array(UPNG.toRGBA8(img)[0]), img.width, img.height, orientation);
1605
+ return new Uint8Array(UPNG.encode([toArrayBuffer(transformed.data)], transformed.width, transformed.height, 0));
1606
+ };
1607
+ /**
1608
+ * One normalize path for JPEG and PNG. Tag absent/1 is a byte-identical
1609
+ * passthrough. Tag 2–8 decodes, transforms pixels, and re-encodes without
1610
+ * an orientation tag. May throw on decode/encode failure — callers fall back.
1611
+ */
1612
+ var normalizeImageOrientation = (bytes) => {
1613
+ const kind = detectImageFormat(bytes);
1614
+ if (kind === "jpeg") return bakeJpegOrientation(bytes);
1615
+ if (kind === "png") return bakePngOrientation(bytes);
1616
+ return bytes;
1492
1617
  };
1493
1618
  //#endregion
1494
1619
  //#region src/graphics/image.ts
@@ -1516,6 +1641,11 @@ var getCacheKey = (schema, input) => {
1516
1641
  const hex = (hash >>> 0).toString(16).padStart(8, "0");
1517
1642
  return `${schema.type}:${input.length}:${hex}`;
1518
1643
  };
1644
+ var dataUrlToBytes = (value) => {
1645
+ const idx = value.indexOf(";base64,");
1646
+ const base64 = idx >= 0 ? value.slice(idx + 8) : value;
1647
+ return new Uint8Array(Buffer$1.from(base64, "base64"));
1648
+ };
1519
1649
  var fullSize$1 = {
1520
1650
  width: "100%",
1521
1651
  height: "100%"
@@ -1528,16 +1658,24 @@ var imageSchema = {
1528
1658
  const inputImageCacheKey = getCacheKey(schema, value);
1529
1659
  let image = _cache.get(inputImageCacheKey);
1530
1660
  if (!image) {
1531
- image = await (value.startsWith("data:image/png;") ? pdfDoc.embedPng(value) : pdfDoc.embedJpg(value));
1661
+ const originalBytes = dataUrlToBytes(value);
1662
+ const kind = detectImageFormat(originalBytes);
1663
+ let bytes = originalBytes;
1664
+ try {
1665
+ if (kind === "jpeg" || kind === "png") bytes = normalizeImageOrientation(originalBytes);
1666
+ } catch (error) {
1667
+ console.warn("[@pdfme/schemas] EXIF orientation bake failed; embedding original bytes:", error);
1668
+ bytes = originalBytes;
1669
+ }
1670
+ image = await (kind === "png" ? pdfDoc.embedPng(bytes) : pdfDoc.embedJpg(bytes));
1532
1671
  _cache.set(inputImageCacheKey, image);
1533
1672
  }
1534
1673
  const _schema = {
1535
1674
  ...schema,
1536
1675
  position: { ...schema.position }
1537
1676
  };
1538
- const dimension = getImageDimension(value);
1539
- const imageWidth = px2mm(dimension.width);
1540
- const imageHeight = px2mm(dimension.height);
1677
+ const imageWidth = px2mm(image.width);
1678
+ const imageHeight = px2mm(image.height);
1541
1679
  const boxWidth = _schema.width;
1542
1680
  const boxHeight = _schema.height;
1543
1681
  const imageRatio = imageWidth / imageHeight;
@@ -1870,6 +2008,145 @@ var isValidSVG = (svgString) => {
1870
2008
  return false;
1871
2009
  }
1872
2010
  };
2011
+ var isWhitespace = (char) => char === " " || char === "\n" || char === "\r" || char === " " || char === "\f";
2012
+ var isAsciiAlpha = (char) => typeof char === "string" && (char >= "A" && char <= "Z" || char >= "a" && char <= "z");
2013
+ var isAttributeNameChar = (char) => typeof char === "string" && (isAsciiAlpha(char) || char >= "0" && char <= "9" || char === "_" || char === ":" || char === "-");
2014
+ var stripImportantSuffix = (value) => {
2015
+ const suffix = "!important";
2016
+ const trimmed = value.trim();
2017
+ return trimmed.toLowerCase().endsWith(suffix) ? trimmed.slice(0, -10).trimEnd() : trimmed;
2018
+ };
2019
+ var parseStyleAttribute = (style) => {
2020
+ if (!style) return {};
2021
+ return style.split(";").reduce((acc, declaration) => {
2022
+ const [key, ...valueParts] = declaration.split(":");
2023
+ const value = valueParts.join(":").trim();
2024
+ if (key && value) acc[key.trim()] = value;
2025
+ return acc;
2026
+ }, {});
2027
+ };
2028
+ var parseAttributes = (tag) => {
2029
+ const attributes = {};
2030
+ let index = 0;
2031
+ while (index < tag.length) {
2032
+ while (index < tag.length && !isAsciiAlpha(tag[index]) && tag[index] !== "_") index += 1;
2033
+ if (index >= tag.length) break;
2034
+ const nameStart = index;
2035
+ while (isAttributeNameChar(tag[index])) index += 1;
2036
+ const name = tag.slice(nameStart, index);
2037
+ while (isWhitespace(tag[index])) index += 1;
2038
+ if (tag[index] !== "=") continue;
2039
+ index += 1;
2040
+ while (isWhitespace(tag[index])) index += 1;
2041
+ const quote = tag[index];
2042
+ if (quote !== "\"" && quote !== "'") {
2043
+ index += 1;
2044
+ continue;
2045
+ }
2046
+ index += 1;
2047
+ const valueStart = index;
2048
+ while (index < tag.length && tag[index] !== quote) index += 1;
2049
+ attributes[name] = tag.slice(valueStart, index);
2050
+ if (tag[index] === quote) index += 1;
2051
+ }
2052
+ return attributes;
2053
+ };
2054
+ var splitFontFamilies = (fontFamily) => {
2055
+ if (!fontFamily) return [];
2056
+ const families = [];
2057
+ let current = "";
2058
+ let quote;
2059
+ for (const char of fontFamily) {
2060
+ if ((char === "\"" || char === "'") && (!quote || quote === char)) {
2061
+ quote = quote ? void 0 : char;
2062
+ continue;
2063
+ }
2064
+ if (char === "," && !quote) {
2065
+ if (current.trim()) families.push(current.trim());
2066
+ current = "";
2067
+ continue;
2068
+ }
2069
+ current += char;
2070
+ }
2071
+ if (current.trim()) families.push(current.trim());
2072
+ return families.map(stripImportantSuffix).filter(Boolean);
2073
+ };
2074
+ var findTagEnd = (svgString, startIndex) => {
2075
+ let index = startIndex;
2076
+ let quote;
2077
+ while (index < svgString.length) {
2078
+ const char = svgString[index];
2079
+ if ((char === "\"" || char === "'") && (!quote || quote === char)) quote = quote ? void 0 : char;
2080
+ else if (char === ">" && !quote) return index;
2081
+ index += 1;
2082
+ }
2083
+ return -1;
2084
+ };
2085
+ var isSelfClosingTag = (tag) => {
2086
+ let index = tag.length - 2;
2087
+ while (index >= 0 && isWhitespace(tag[index])) index -= 1;
2088
+ return tag[index] === "/";
2089
+ };
2090
+ var mergeFontStyle = (base, attributes) => {
2091
+ const style = parseStyleAttribute(attributes.style);
2092
+ return {
2093
+ fontFamily: style["font-family"] || attributes["font-family"] || base.fontFamily,
2094
+ fontStyle: style["font-style"] || attributes["font-style"] || base.fontStyle,
2095
+ fontWeight: style["font-weight"] || attributes["font-weight"] || base.fontWeight
2096
+ };
2097
+ };
2098
+ var getFontCandidates = (fontFamily, { fontStyle, fontWeight }) => {
2099
+ const isBold = fontWeight === "bold" || Number(fontWeight) >= 700;
2100
+ const isItalic = fontStyle === "italic";
2101
+ return Array.from(/* @__PURE__ */ new Set([
2102
+ `${fontFamily}${isBold ? "_bold" : ""}${isItalic ? "_italic" : ""}`,
2103
+ `${fontFamily}${isBold ? "_bold" : ""}`,
2104
+ `${fontFamily}${isItalic ? "_italic" : ""}`,
2105
+ fontFamily
2106
+ ]));
2107
+ };
2108
+ var selectSvgFontNames = (svgString, font) => {
2109
+ const selectedFontNames = /* @__PURE__ */ new Set();
2110
+ const fontNames = Object.keys(font);
2111
+ const styleStack = [{}];
2112
+ let index = 0;
2113
+ while (index < svgString.length) {
2114
+ if (svgString[index] !== "<") {
2115
+ index += 1;
2116
+ continue;
2117
+ }
2118
+ let cursor = index + 1;
2119
+ const isClosingTag = svgString[cursor] === "/";
2120
+ if (isClosingTag) cursor += 1;
2121
+ if (!isAsciiAlpha(svgString[cursor])) {
2122
+ index += 1;
2123
+ continue;
2124
+ }
2125
+ const tagNameStart = cursor;
2126
+ while (isAttributeNameChar(svgString[cursor])) cursor += 1;
2127
+ const tagName = svgString.slice(tagNameStart, cursor).toLowerCase();
2128
+ const tagEnd = findTagEnd(svgString, cursor);
2129
+ if (tagEnd === -1) break;
2130
+ const tag = svgString.slice(index, tagEnd + 1);
2131
+ if (isClosingTag) {
2132
+ if (styleStack.length > 1) styleStack.pop();
2133
+ index = tagEnd + 1;
2134
+ continue;
2135
+ }
2136
+ const currentStyle = mergeFontStyle(styleStack[styleStack.length - 1], parseAttributes(tag));
2137
+ if (tagName === "text") {
2138
+ let selectedFontName;
2139
+ for (const family of splitFontFamilies(currentStyle.fontFamily)) {
2140
+ selectedFontName = getFontCandidates(family, currentStyle).find((fontName) => font[fontName]) || fontNames.find((fontName) => fontName.startsWith(family));
2141
+ if (selectedFontName) break;
2142
+ }
2143
+ if (selectedFontName) selectedFontNames.add(selectedFontName);
2144
+ }
2145
+ if (!isSelfClosingTag(tag)) styleStack.push(currentStyle);
2146
+ index = tagEnd + 1;
2147
+ }
2148
+ return Array.from(selectedFontNames);
2149
+ };
1873
2150
  var svgSchema = {
1874
2151
  ui: (arg) => {
1875
2152
  const { rootElement, value, mode, onChange, theme, schema } = arg;
@@ -1922,20 +2199,45 @@ var svgSchema = {
1922
2199
  }
1923
2200
  },
1924
2201
  pdf: async (arg) => {
1925
- const { page, schema, value } = arg;
2202
+ const { page, pdfDoc, pdfLib, options, schema, value, _cache } = arg;
1926
2203
  if (!value || !isValidSVG(value)) return;
1927
2204
  const pageHeight = page.getHeight();
1928
2205
  const { width, height, position } = convertForPdfLayoutProps({
1929
2206
  schema,
1930
- pageHeight
2207
+ pageHeight,
2208
+ applyRotateTranslate: false
1931
2209
  });
1932
2210
  const { x, y } = position;
1933
- await page.drawSvg(value, {
1934
- x,
1935
- y: y + height,
1936
- width,
1937
- height
1938
- });
2211
+ const font = options.font;
2212
+ const fontEntries = font ? await Promise.all(selectSvgFontNames(value, font).map(async (fontName) => [fontName, await embedAndGetFont({
2213
+ pdfDoc,
2214
+ font,
2215
+ fontName,
2216
+ _cache
2217
+ })])) : [];
2218
+ const fonts = fontEntries.length > 0 ? Object.fromEntries(fontEntries) : void 0;
2219
+ const mapColor = options.colorType?.toLowerCase() === "cmyk" ? ({ parsed }) => ({
2220
+ color: rgbColorToCmykColor(parsed.rgb),
2221
+ alpha: parsed.alpha
2222
+ }) : void 0;
2223
+ const rotateDegrees = schema.rotate ? -schema.rotate : 0;
2224
+ if (rotateDegrees) {
2225
+ const pivotX = x + width / 2;
2226
+ const pivotY = y + height / 2;
2227
+ page.pushOperators(pdfLib.pushGraphicsState(), pdfLib.translate(pivotX, pivotY), pdfLib.rotateDegrees(rotateDegrees), pdfLib.translate(-pivotX, -pivotY));
2228
+ }
2229
+ try {
2230
+ await page.drawSvg(value, {
2231
+ x,
2232
+ y: y + height,
2233
+ width,
2234
+ height,
2235
+ fonts,
2236
+ mapColor
2237
+ });
2238
+ } finally {
2239
+ if (rotateDegrees) page.pushOperators(pdfLib.popGraphicsState());
2240
+ }
1939
2241
  },
1940
2242
  propPanel: {
1941
2243
  schema: {},
@@ -1952,7 +2254,8 @@ var svgSchema = {
1952
2254
  y: 0
1953
2255
  },
1954
2256
  width: 40,
1955
- height: 50
2257
+ height: 50,
2258
+ rotate: 0
1956
2259
  }
1957
2260
  },
1958
2261
  icon: createSvgStr(Route)
@@ -2025,7 +2328,47 @@ var barCodeType2Bcid = (type) => type === "nw7" ? "rationalizedCodabar" : type;
2025
2328
  * Strip hash from the beginning of HTML hex color codes for the bwip.js lib
2026
2329
  */
2027
2330
  var mapHexColorForBwipJsLib = (color, fallback) => color ? color.replace("#", "") : fallback ? fallback.replace("#", "") : "000000";
2028
- var createBarCode = async (arg) => {
2331
+ var getBwipJsRenderer = () => bwipjs;
2332
+ var getDocument = () => globalThis.document;
2333
+ var getOffscreenCanvasCtor = () => globalThis.OffscreenCanvas;
2334
+ /**
2335
+ * Pick a barcode renderer from capabilities, not `typeof window`.
2336
+ * Browser Workers have neither `window` nor Node's `bwip-js.toBuffer()`.
2337
+ * OffscreenCanvas without `toCanvas()` (Node bwip-js export) falls back to `toBuffer()`.
2338
+ */
2339
+ var resolveBarcodeRenderRuntime = () => {
2340
+ const doc = getDocument();
2341
+ const renderer = getBwipJsRenderer();
2342
+ if (doc && typeof doc.createElement === "function") return "document-canvas";
2343
+ if (typeof getOffscreenCanvasCtor() === "function" && typeof renderer.toCanvas === "function") return "offscreencanvas";
2344
+ if (typeof renderer.toBuffer === "function") return "node-buffer";
2345
+ throw new Error("[@pdfme/schemas] Barcode rendering requires a document canvas, OffscreenCanvas, or bwip-js toBuffer().");
2346
+ };
2347
+ var pngBufferFromDataUrl = (dataUrl) => Buffer$1.from(b64toUint8Array(dataUrl).buffer);
2348
+ var pngBufferFromBlob = async (blob) => Buffer$1.from(await blob.arrayBuffer());
2349
+ var renderBarcodeToCanvas = (canvas, options) => {
2350
+ const toCanvas = getBwipJsRenderer().toCanvas;
2351
+ if (typeof toCanvas !== "function") throw new Error("[@pdfme/schemas] bwip-js toCanvas() is not available in this environment.");
2352
+ toCanvas(canvas, options);
2353
+ };
2354
+ var renderBarcodeToDocumentCanvas = (options) => {
2355
+ const canvas = getDocument().createElement("canvas");
2356
+ renderBarcodeToCanvas(canvas, options);
2357
+ return pngBufferFromDataUrl(canvas.toDataURL("image/png"));
2358
+ };
2359
+ var renderBarcodeToOffscreenCanvas = async (options) => {
2360
+ const OffscreenCanvasCtor = getOffscreenCanvasCtor();
2361
+ if (typeof OffscreenCanvasCtor !== "function") throw new Error("[@pdfme/schemas] OffscreenCanvas is not available in this environment.");
2362
+ const canvas = new OffscreenCanvasCtor(1, 1);
2363
+ renderBarcodeToCanvas(canvas, options);
2364
+ return pngBufferFromBlob(await canvas.convertToBlob({ type: "image/png" }));
2365
+ };
2366
+ var renderBarcodeToNodeBuffer = async (options) => {
2367
+ const toBuffer = getBwipJsRenderer().toBuffer;
2368
+ if (typeof toBuffer !== "function") throw new Error("[@pdfme/schemas] bwip-js toBuffer() is not available in this environment.");
2369
+ return toBuffer(options);
2370
+ };
2371
+ var createBwipJsRenderOptions = (arg) => {
2029
2372
  const { type, input, width, height, backgroundColor, barColor, textColor, includetext = true } = arg;
2030
2373
  const bwipjsArg = {
2031
2374
  bcid: barCodeType2Bcid(type),
@@ -2039,47 +2382,73 @@ var createBarCode = async (arg) => {
2039
2382
  if (backgroundColor) bwipjsArg.backgroundcolor = mapHexColorForBwipJsLib(backgroundColor);
2040
2383
  if (barColor) bwipjsArg.barcolor = mapHexColorForBwipJsLib(barColor);
2041
2384
  if (textColor) bwipjsArg.textcolor = mapHexColorForBwipJsLib(textColor);
2042
- let res;
2043
- if (typeof window !== "undefined") {
2044
- const canvas = document.createElement("canvas");
2045
- bwipjs.toCanvas(canvas, bwipjsArg);
2046
- const dataUrl = canvas.toDataURL("image/png");
2047
- res = Buffer$1.from(b64toUint8Array(dataUrl).buffer);
2048
- } else res = await bwipjs.toBuffer(bwipjsArg);
2049
- return res;
2385
+ return bwipjsArg;
2386
+ };
2387
+ var createBarCodeSvg = (arg) => {
2388
+ const toSVG = getBwipJsRenderer().toSVG;
2389
+ if (typeof toSVG !== "function") throw new Error("[@pdfme/schemas] bwip-js toSVG() is not available in this environment.");
2390
+ const defaultFill = `#${mapHexColorForBwipJsLib(arg.barColor)}`;
2391
+ const svg = toSVG(createBwipJsRenderOptions(arg)).replace(/<svg\b(?![^>]*\sfill=)/, `<svg fill="${defaultFill}"`);
2392
+ if (/<image\b/i.test(svg)) throw new Error(`[@pdfme/schemas] bwip-js emitted an embedded image for ${arg.type}; vector barcode PDF rendering requires path-based SVG.`);
2393
+ return svg;
2394
+ };
2395
+ var createBarCode = async (arg) => {
2396
+ const bwipjsArg = createBwipJsRenderOptions(arg);
2397
+ const runtime = resolveBarcodeRenderRuntime();
2398
+ if (runtime === "document-canvas") return renderBarcodeToDocumentCanvas(bwipjsArg);
2399
+ if (runtime === "offscreencanvas") return renderBarcodeToOffscreenCanvas(bwipjsArg);
2400
+ return renderBarcodeToNodeBuffer(bwipjsArg);
2050
2401
  };
2051
2402
  //#endregion
2052
2403
  //#region src/barcodes/pdfRender.ts
2053
2404
  var getBarcodeCacheKey = (schema, value) => {
2054
- return `${schema.type}${schema.backgroundColor}${schema.barColor}${schema.textColor}${value}${schema.includetext}`;
2405
+ return `svg:${schema.type}:${schema.width}:${schema.height}:${schema.backgroundColor}:${schema.barColor}:${schema.textColor}:${schema.includetext}:${value}`;
2406
+ };
2407
+ var addSvgOpacity = (svg, opacity) => {
2408
+ return opacity === void 0 ? svg : svg.replace(/<svg\b/, `<svg opacity="${opacity}"`);
2409
+ };
2410
+ var getSvgColorMapper = (colorType = "") => {
2411
+ return colorType.toLowerCase() === "cmyk" ? ({ parsed }) => ({
2412
+ color: rgbColorToCmykColor(parsed.rgb),
2413
+ alpha: parsed.alpha
2414
+ }) : void 0;
2055
2415
  };
2056
2416
  var pdfRender$1 = async (arg) => {
2057
- const { value, schema, pdfDoc, page, _cache } = arg;
2417
+ const { value, schema, page, options, _cache } = arg;
2058
2418
  if (!validateBarcodeInput(schema.type, value)) return;
2059
2419
  const inputBarcodeCacheKey = getBarcodeCacheKey(schema, value);
2060
- let image = _cache.get(inputBarcodeCacheKey);
2061
- if (!image) {
2062
- const imageBuf = await createBarCode({
2420
+ let svg = _cache.get(inputBarcodeCacheKey);
2421
+ if (!svg) {
2422
+ svg = createBarCodeSvg({
2063
2423
  ...schema,
2064
2424
  type: schema.type,
2065
2425
  input: value
2066
2426
  });
2067
- image = await pdfDoc.embedPng(imageBuf);
2068
- _cache.set(inputBarcodeCacheKey, image);
2427
+ _cache.set(inputBarcodeCacheKey, svg);
2069
2428
  }
2070
2429
  const pageHeight = page.getHeight();
2071
- const { width, height, rotate, position: { x, y }, opacity } = convertForPdfLayoutProps({
2430
+ const { width, height, position: { x, y }, opacity } = convertForPdfLayoutProps({
2072
2431
  schema,
2073
- pageHeight
2074
- });
2075
- page.drawImage(image, {
2076
- x,
2077
- y,
2078
- rotate,
2079
- width,
2080
- height,
2081
- opacity
2432
+ pageHeight,
2433
+ applyRotateTranslate: false
2082
2434
  });
2435
+ const pivot = {
2436
+ x: x + width / 2,
2437
+ y: y + height / 2
2438
+ };
2439
+ const rotate = schema.rotate ? -schema.rotate : 0;
2440
+ if (rotate) page.pushOperators(pushGraphicsState(), translate(pivot.x, pivot.y), rotateDegrees(rotate), translate(-pivot.x, -pivot.y));
2441
+ try {
2442
+ await page.drawSvg(addSvgOpacity(svg, opacity), {
2443
+ x,
2444
+ y: y + height,
2445
+ width,
2446
+ height,
2447
+ mapColor: getSvgColorMapper(options.colorType)
2448
+ });
2449
+ } finally {
2450
+ if (rotate) page.pushOperators(popGraphicsState());
2451
+ }
2083
2452
  };
2084
2453
  //#endregion
2085
2454
  //#region src/barcodes/propPanel.ts