@pdfme/schemas 6.1.13 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/barcodes/helper.d.ts +12 -2
- package/dist/{builtins-8En4EIAG.js → builtins-C-2wyB_3.js} +140 -83
- package/dist/builtins-C-2wyB_3.js.map +1 -0
- package/dist/builtins.js +1 -1
- package/dist/dynamicLayout.js +4 -4
- package/dist/{dynamicTemplate-DQF7c6NR.js → dynamicTemplate-CcnCXHfM.js} +2 -2
- package/dist/{dynamicTemplate-DQF7c6NR.js.map → dynamicTemplate-CcnCXHfM.js.map} +1 -1
- package/dist/{dynamicTemplate-DFk_de1Y.js → dynamicTemplate-DEwOv_DE.js} +7 -6
- package/dist/dynamicTemplate-DEwOv_DE.js.map +1 -0
- package/dist/{dynamicTemplate-CnK0nlnj.js → dynamicTemplate-DkTVIMNr.js} +2 -2
- package/dist/{dynamicTemplate-CnK0nlnj.js.map → dynamicTemplate-DkTVIMNr.js.map} +1 -1
- package/dist/graphics/image.d.ts +26 -1
- package/dist/graphics/orientation.d.ts +31 -0
- package/dist/{helper-VroN19Ci.js → helper-BR4_UZA5.js} +26 -3
- package/dist/helper-BR4_UZA5.js.map +1 -0
- package/dist/index.js +639 -140
- package/dist/index.js.map +1 -1
- package/dist/lists.js +2 -2
- package/dist/{measure-BC7tjAtT.js → measure-BarlRI1L.js} +71 -227
- package/dist/measure-BarlRI1L.js.map +1 -0
- package/dist/multiVariableText/helper.d.ts +8 -0
- package/dist/multiVariableText/types.d.ts +2 -0
- package/dist/pdfFont.d.ts +8 -0
- package/dist/splitRange-B6311Noc.js +10854 -0
- package/dist/splitRange-B6311Noc.js.map +1 -0
- package/dist/tables.js +2 -2
- package/dist/text/helper.d.ts +33 -1
- package/dist/text/lineBreak.d.ts +69 -0
- package/dist/text/lineBreakClasses.generated.d.ts +11 -0
- package/dist/text/richText.d.ts +2 -0
- package/dist/text/uiRender.d.ts +3 -1
- package/dist/text/wrap.d.ts +67 -0
- package/dist/texts.js +3 -3
- package/dist/{utils-D_sFXK0U.js → utils-CPYF2FY_.js} +18 -15
- package/dist/utils-CPYF2FY_.js.map +1 -0
- package/dist/utils.d.ts +3 -2
- package/dist/utils.js +3 -3
- package/package.json +3 -1
- package/dist/builtins-8En4EIAG.js.map +0 -1
- package/dist/dynamicTemplate-DFk_de1Y.js.map +0 -1
- package/dist/helper-VroN19Ci.js.map +0 -1
- package/dist/measure-BC7tjAtT.js.map +0 -1
- package/dist/splitRange-BHV0vb0Q.js +0 -504
- package/dist/splitRange-BHV0vb0Q.js.map +0 -1
- package/dist/utils-D_sFXK0U.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as measureTextLines,
|
|
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-
|
|
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-
|
|
5
|
-
import { c as isEditable, d as
|
|
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-
|
|
7
|
-
import { n as
|
|
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 {
|
|
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:
|
|
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 ?
|
|
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)
|
|
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:
|
|
695
|
-
y:
|
|
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/
|
|
1411
|
-
var
|
|
1412
|
-
var
|
|
1413
|
-
var
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
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
|
|
1423
|
-
|
|
1424
|
-
|
|
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;
|
|
1446
|
+
};
|
|
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;
|
|
1425
1451
|
};
|
|
1426
|
-
var
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
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
|
-
|
|
1477
|
+
return;
|
|
1478
|
+
} catch {
|
|
1479
|
+
return;
|
|
1439
1480
|
}
|
|
1440
1481
|
};
|
|
1441
|
-
var
|
|
1442
|
-
|
|
1443
|
-
var
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
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
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
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
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
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
|
-
|
|
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,40 +1641,166 @@ 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%"
|
|
1522
1652
|
};
|
|
1653
|
+
var IMAGE_OBJECT_FITS = ["contain", "cover"];
|
|
1654
|
+
var IMAGE_OBJECT_POSITIONS = [
|
|
1655
|
+
"left top",
|
|
1656
|
+
"center top",
|
|
1657
|
+
"right top",
|
|
1658
|
+
"left center",
|
|
1659
|
+
"center center",
|
|
1660
|
+
"right center",
|
|
1661
|
+
"left bottom",
|
|
1662
|
+
"center bottom",
|
|
1663
|
+
"right bottom"
|
|
1664
|
+
];
|
|
1665
|
+
var DEFAULT_IMAGE_OBJECT_FIT = "contain";
|
|
1666
|
+
var DEFAULT_IMAGE_OBJECT_POSITION = "center center";
|
|
1667
|
+
var imageObjectFitSet = new Set(IMAGE_OBJECT_FITS);
|
|
1668
|
+
var imageObjectPositionSet = new Set(IMAGE_OBJECT_POSITIONS);
|
|
1669
|
+
var normalizeObjectFit = (value) => typeof value === "string" && imageObjectFitSet.has(value) ? value : DEFAULT_IMAGE_OBJECT_FIT;
|
|
1670
|
+
var normalizeObjectPosition = (value) => typeof value === "string" && imageObjectPositionSet.has(value) ? value : DEFAULT_IMAGE_OBJECT_POSITION;
|
|
1671
|
+
var getEffectiveObjectPosition = (schema) => {
|
|
1672
|
+
return normalizeObjectFit(schema.objectFit) === "cover" ? DEFAULT_IMAGE_OBJECT_POSITION : normalizeObjectPosition(schema.objectPosition);
|
|
1673
|
+
};
|
|
1674
|
+
var alignOffset = (space, position) => {
|
|
1675
|
+
if (position === "right" || position === "bottom") return space;
|
|
1676
|
+
if (position === "center") return space / 2;
|
|
1677
|
+
return 0;
|
|
1678
|
+
};
|
|
1679
|
+
var getImageFitLayout = (arg) => {
|
|
1680
|
+
const { sourceWidth, sourceHeight, boxWidth, boxHeight } = arg;
|
|
1681
|
+
const objectFit = normalizeObjectFit(arg.objectFit);
|
|
1682
|
+
const objectPosition = objectFit === "cover" ? DEFAULT_IMAGE_OBJECT_POSITION : normalizeObjectPosition(arg.objectPosition);
|
|
1683
|
+
const scale = objectFit === "cover" ? Math.max(boxWidth / sourceWidth, boxHeight / sourceHeight) : Math.min(boxWidth / sourceWidth, boxHeight / sourceHeight);
|
|
1684
|
+
const width = sourceWidth * scale;
|
|
1685
|
+
const height = sourceHeight * scale;
|
|
1686
|
+
const [horizontal, vertical] = objectPosition.split(" ");
|
|
1687
|
+
return {
|
|
1688
|
+
objectFit,
|
|
1689
|
+
objectPosition,
|
|
1690
|
+
width,
|
|
1691
|
+
height,
|
|
1692
|
+
offsetX: alignOffset(boxWidth - width, horizontal),
|
|
1693
|
+
offsetY: alignOffset(boxHeight - height, vertical)
|
|
1694
|
+
};
|
|
1695
|
+
};
|
|
1696
|
+
var getClipPathCorners = (arg) => {
|
|
1697
|
+
const { schema, pageHeight } = arg;
|
|
1698
|
+
const clippingBox = convertForPdfLayoutProps({
|
|
1699
|
+
schema,
|
|
1700
|
+
pageHeight,
|
|
1701
|
+
applyRotateTranslate: false
|
|
1702
|
+
});
|
|
1703
|
+
const { x, y } = clippingBox.position;
|
|
1704
|
+
const width = clippingBox.width;
|
|
1705
|
+
const height = clippingBox.height;
|
|
1706
|
+
const rotateDegrees = schema.rotate ? -schema.rotate : 0;
|
|
1707
|
+
const corners = [
|
|
1708
|
+
{
|
|
1709
|
+
x,
|
|
1710
|
+
y
|
|
1711
|
+
},
|
|
1712
|
+
{
|
|
1713
|
+
x,
|
|
1714
|
+
y: y + height
|
|
1715
|
+
},
|
|
1716
|
+
{
|
|
1717
|
+
x: x + width,
|
|
1718
|
+
y: y + height
|
|
1719
|
+
},
|
|
1720
|
+
{
|
|
1721
|
+
x: x + width,
|
|
1722
|
+
y
|
|
1723
|
+
}
|
|
1724
|
+
];
|
|
1725
|
+
if (!rotateDegrees) return corners;
|
|
1726
|
+
const pivot = {
|
|
1727
|
+
x: x + width / 2,
|
|
1728
|
+
y: y + height / 2
|
|
1729
|
+
};
|
|
1730
|
+
return corners.map((corner) => rotatePoint(corner, pivot, rotateDegrees));
|
|
1731
|
+
};
|
|
1523
1732
|
var defaultValue = "data:image/png;base64,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";
|
|
1733
|
+
var getImagePropPanelSchema = ({ i18n, activeSchema }) => {
|
|
1734
|
+
const objectFit = normalizeObjectFit(activeSchema.objectFit);
|
|
1735
|
+
const positionOptions = IMAGE_OBJECT_POSITIONS.map((value) => ({
|
|
1736
|
+
value,
|
|
1737
|
+
label: i18n(`schemas.image.position.${value.replace(" ", ".")}`)
|
|
1738
|
+
}));
|
|
1739
|
+
return {
|
|
1740
|
+
objectFit: {
|
|
1741
|
+
title: i18n("schemas.image.objectFit"),
|
|
1742
|
+
type: "string",
|
|
1743
|
+
widget: "select",
|
|
1744
|
+
default: DEFAULT_IMAGE_OBJECT_FIT,
|
|
1745
|
+
props: { options: [{
|
|
1746
|
+
label: i18n("schemas.image.fit.contain"),
|
|
1747
|
+
value: "contain"
|
|
1748
|
+
}, {
|
|
1749
|
+
label: i18n("schemas.image.fit.cover"),
|
|
1750
|
+
value: "cover"
|
|
1751
|
+
}] },
|
|
1752
|
+
span: 8
|
|
1753
|
+
},
|
|
1754
|
+
objectPosition: {
|
|
1755
|
+
title: i18n("schemas.image.objectPosition"),
|
|
1756
|
+
type: "string",
|
|
1757
|
+
widget: "select",
|
|
1758
|
+
default: DEFAULT_IMAGE_OBJECT_POSITION,
|
|
1759
|
+
hidden: objectFit === "cover",
|
|
1760
|
+
props: { options: positionOptions },
|
|
1761
|
+
span: 16
|
|
1762
|
+
}
|
|
1763
|
+
};
|
|
1764
|
+
};
|
|
1524
1765
|
var imageSchema = {
|
|
1525
1766
|
pdf: async (arg) => {
|
|
1526
|
-
const { value, schema, pdfDoc, page, _cache } = arg;
|
|
1767
|
+
const { value, schema, pdfDoc, page, pdfLib, _cache } = arg;
|
|
1527
1768
|
if (!value) return;
|
|
1528
1769
|
const inputImageCacheKey = getCacheKey(schema, value);
|
|
1529
1770
|
let image = _cache.get(inputImageCacheKey);
|
|
1530
1771
|
if (!image) {
|
|
1531
|
-
|
|
1772
|
+
const originalBytes = dataUrlToBytes(value);
|
|
1773
|
+
const kind = detectImageFormat(originalBytes);
|
|
1774
|
+
let bytes = originalBytes;
|
|
1775
|
+
try {
|
|
1776
|
+
if (kind === "jpeg" || kind === "png") bytes = normalizeImageOrientation(originalBytes);
|
|
1777
|
+
} catch (error) {
|
|
1778
|
+
console.warn("[@pdfme/schemas] EXIF orientation bake failed; embedding original bytes:", error);
|
|
1779
|
+
bytes = originalBytes;
|
|
1780
|
+
}
|
|
1781
|
+
image = await (kind === "png" ? pdfDoc.embedPng(bytes) : pdfDoc.embedJpg(bytes));
|
|
1532
1782
|
_cache.set(inputImageCacheKey, image);
|
|
1533
1783
|
}
|
|
1534
1784
|
const _schema = {
|
|
1535
1785
|
...schema,
|
|
1536
1786
|
position: { ...schema.position }
|
|
1537
1787
|
};
|
|
1538
|
-
const
|
|
1539
|
-
const
|
|
1540
|
-
const imageHeight = px2mm(dimension.height);
|
|
1788
|
+
const imageWidth = px2mm(image.width);
|
|
1789
|
+
const imageHeight = px2mm(image.height);
|
|
1541
1790
|
const boxWidth = _schema.width;
|
|
1542
1791
|
const boxHeight = _schema.height;
|
|
1543
|
-
const
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
_schema.
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1792
|
+
const fitLayout = getImageFitLayout({
|
|
1793
|
+
sourceWidth: imageWidth,
|
|
1794
|
+
sourceHeight: imageHeight,
|
|
1795
|
+
boxWidth,
|
|
1796
|
+
boxHeight,
|
|
1797
|
+
objectFit: _schema.objectFit,
|
|
1798
|
+
objectPosition: _schema.objectPosition
|
|
1799
|
+
});
|
|
1800
|
+
_schema.width = fitLayout.width;
|
|
1801
|
+
_schema.height = fitLayout.height;
|
|
1802
|
+
_schema.position.x += fitLayout.offsetX;
|
|
1803
|
+
_schema.position.y += fitLayout.offsetY;
|
|
1553
1804
|
const pageHeight = page.getHeight();
|
|
1554
1805
|
const { width, height, rotate, position, opacity } = convertForPdfLayoutProps({
|
|
1555
1806
|
schema: _schema,
|
|
@@ -1564,20 +1815,30 @@ var imageSchema = {
|
|
|
1564
1815
|
height,
|
|
1565
1816
|
opacity
|
|
1566
1817
|
};
|
|
1818
|
+
if (fitLayout.objectFit === "cover") {
|
|
1819
|
+
const [firstCorner, ...corners] = getClipPathCorners({
|
|
1820
|
+
schema,
|
|
1821
|
+
pageHeight
|
|
1822
|
+
});
|
|
1823
|
+
page.pushOperators(pdfLib.pushGraphicsState(), pdfLib.moveTo(firstCorner.x, firstCorner.y), ...corners.map((corner) => pdfLib.lineTo(corner.x, corner.y)), pdfLib.closePath(), pdfLib.clip(), pdfLib.endPath());
|
|
1824
|
+
}
|
|
1567
1825
|
page.drawImage(image, drawOptions);
|
|
1826
|
+
if (fitLayout.objectFit === "cover") page.pushOperators(pdfLib.popGraphicsState());
|
|
1568
1827
|
},
|
|
1569
1828
|
ui: (arg) => {
|
|
1570
1829
|
const { value, rootElement, mode, onChange, stopEditing, tabIndex, placeholder, theme, schema } = arg;
|
|
1571
1830
|
const editable = isEditable(mode, schema);
|
|
1572
1831
|
const isDefault = value === defaultValue;
|
|
1832
|
+
const objectFit = normalizeObjectFit(schema.objectFit);
|
|
1833
|
+
const objectPosition = getEffectiveObjectPosition(schema);
|
|
1573
1834
|
const container = document.createElement("div");
|
|
1574
1835
|
const backgroundStyle = placeholder ? `url(${placeholder})` : "none";
|
|
1575
1836
|
const containerStyle = {
|
|
1576
1837
|
...fullSize$1,
|
|
1577
1838
|
backgroundImage: value ? "none" : backgroundStyle,
|
|
1578
|
-
backgroundSize:
|
|
1839
|
+
backgroundSize: objectFit,
|
|
1579
1840
|
backgroundRepeat: "no-repeat",
|
|
1580
|
-
backgroundPosition:
|
|
1841
|
+
backgroundPosition: objectPosition
|
|
1581
1842
|
};
|
|
1582
1843
|
Object.assign(container.style, containerStyle);
|
|
1583
1844
|
container.addEventListener("click", (e) => {
|
|
@@ -1586,12 +1847,14 @@ var imageSchema = {
|
|
|
1586
1847
|
rootElement.appendChild(container);
|
|
1587
1848
|
if (value) {
|
|
1588
1849
|
const img = document.createElement("img");
|
|
1589
|
-
|
|
1850
|
+
const imgStyle = {
|
|
1590
1851
|
height: "100%",
|
|
1591
1852
|
width: "100%",
|
|
1592
1853
|
borderRadius: 0,
|
|
1593
|
-
objectFit
|
|
1594
|
-
|
|
1854
|
+
objectFit,
|
|
1855
|
+
...objectPosition === "center center" ? {} : { objectPosition }
|
|
1856
|
+
};
|
|
1857
|
+
Object.assign(img.style, imgStyle);
|
|
1595
1858
|
img.src = value;
|
|
1596
1859
|
container.appendChild(img);
|
|
1597
1860
|
}
|
|
@@ -1668,7 +1931,10 @@ var imageSchema = {
|
|
|
1668
1931
|
}
|
|
1669
1932
|
},
|
|
1670
1933
|
propPanel: {
|
|
1671
|
-
schema: {}
|
|
1934
|
+
schema: ({ i18n, activeSchema }) => getImagePropPanelSchema({
|
|
1935
|
+
i18n,
|
|
1936
|
+
activeSchema
|
|
1937
|
+
}),
|
|
1672
1938
|
defaultSchema: {
|
|
1673
1939
|
name: "",
|
|
1674
1940
|
type: "image",
|
|
@@ -1679,6 +1945,8 @@ var imageSchema = {
|
|
|
1679
1945
|
},
|
|
1680
1946
|
width: 40,
|
|
1681
1947
|
height: 40,
|
|
1948
|
+
objectFit: DEFAULT_IMAGE_OBJECT_FIT,
|
|
1949
|
+
objectPosition: DEFAULT_IMAGE_OBJECT_POSITION,
|
|
1682
1950
|
rotate: 0,
|
|
1683
1951
|
opacity: 1
|
|
1684
1952
|
}
|
|
@@ -1870,6 +2138,145 @@ var isValidSVG = (svgString) => {
|
|
|
1870
2138
|
return false;
|
|
1871
2139
|
}
|
|
1872
2140
|
};
|
|
2141
|
+
var isWhitespace = (char) => char === " " || char === "\n" || char === "\r" || char === " " || char === "\f";
|
|
2142
|
+
var isAsciiAlpha = (char) => typeof char === "string" && (char >= "A" && char <= "Z" || char >= "a" && char <= "z");
|
|
2143
|
+
var isAttributeNameChar = (char) => typeof char === "string" && (isAsciiAlpha(char) || char >= "0" && char <= "9" || char === "_" || char === ":" || char === "-");
|
|
2144
|
+
var stripImportantSuffix = (value) => {
|
|
2145
|
+
const suffix = "!important";
|
|
2146
|
+
const trimmed = value.trim();
|
|
2147
|
+
return trimmed.toLowerCase().endsWith(suffix) ? trimmed.slice(0, -10).trimEnd() : trimmed;
|
|
2148
|
+
};
|
|
2149
|
+
var parseStyleAttribute = (style) => {
|
|
2150
|
+
if (!style) return {};
|
|
2151
|
+
return style.split(";").reduce((acc, declaration) => {
|
|
2152
|
+
const [key, ...valueParts] = declaration.split(":");
|
|
2153
|
+
const value = valueParts.join(":").trim();
|
|
2154
|
+
if (key && value) acc[key.trim()] = value;
|
|
2155
|
+
return acc;
|
|
2156
|
+
}, {});
|
|
2157
|
+
};
|
|
2158
|
+
var parseAttributes = (tag) => {
|
|
2159
|
+
const attributes = {};
|
|
2160
|
+
let index = 0;
|
|
2161
|
+
while (index < tag.length) {
|
|
2162
|
+
while (index < tag.length && !isAsciiAlpha(tag[index]) && tag[index] !== "_") index += 1;
|
|
2163
|
+
if (index >= tag.length) break;
|
|
2164
|
+
const nameStart = index;
|
|
2165
|
+
while (isAttributeNameChar(tag[index])) index += 1;
|
|
2166
|
+
const name = tag.slice(nameStart, index);
|
|
2167
|
+
while (isWhitespace(tag[index])) index += 1;
|
|
2168
|
+
if (tag[index] !== "=") continue;
|
|
2169
|
+
index += 1;
|
|
2170
|
+
while (isWhitespace(tag[index])) index += 1;
|
|
2171
|
+
const quote = tag[index];
|
|
2172
|
+
if (quote !== "\"" && quote !== "'") {
|
|
2173
|
+
index += 1;
|
|
2174
|
+
continue;
|
|
2175
|
+
}
|
|
2176
|
+
index += 1;
|
|
2177
|
+
const valueStart = index;
|
|
2178
|
+
while (index < tag.length && tag[index] !== quote) index += 1;
|
|
2179
|
+
attributes[name] = tag.slice(valueStart, index);
|
|
2180
|
+
if (tag[index] === quote) index += 1;
|
|
2181
|
+
}
|
|
2182
|
+
return attributes;
|
|
2183
|
+
};
|
|
2184
|
+
var splitFontFamilies = (fontFamily) => {
|
|
2185
|
+
if (!fontFamily) return [];
|
|
2186
|
+
const families = [];
|
|
2187
|
+
let current = "";
|
|
2188
|
+
let quote;
|
|
2189
|
+
for (const char of fontFamily) {
|
|
2190
|
+
if ((char === "\"" || char === "'") && (!quote || quote === char)) {
|
|
2191
|
+
quote = quote ? void 0 : char;
|
|
2192
|
+
continue;
|
|
2193
|
+
}
|
|
2194
|
+
if (char === "," && !quote) {
|
|
2195
|
+
if (current.trim()) families.push(current.trim());
|
|
2196
|
+
current = "";
|
|
2197
|
+
continue;
|
|
2198
|
+
}
|
|
2199
|
+
current += char;
|
|
2200
|
+
}
|
|
2201
|
+
if (current.trim()) families.push(current.trim());
|
|
2202
|
+
return families.map(stripImportantSuffix).filter(Boolean);
|
|
2203
|
+
};
|
|
2204
|
+
var findTagEnd = (svgString, startIndex) => {
|
|
2205
|
+
let index = startIndex;
|
|
2206
|
+
let quote;
|
|
2207
|
+
while (index < svgString.length) {
|
|
2208
|
+
const char = svgString[index];
|
|
2209
|
+
if ((char === "\"" || char === "'") && (!quote || quote === char)) quote = quote ? void 0 : char;
|
|
2210
|
+
else if (char === ">" && !quote) return index;
|
|
2211
|
+
index += 1;
|
|
2212
|
+
}
|
|
2213
|
+
return -1;
|
|
2214
|
+
};
|
|
2215
|
+
var isSelfClosingTag = (tag) => {
|
|
2216
|
+
let index = tag.length - 2;
|
|
2217
|
+
while (index >= 0 && isWhitespace(tag[index])) index -= 1;
|
|
2218
|
+
return tag[index] === "/";
|
|
2219
|
+
};
|
|
2220
|
+
var mergeFontStyle = (base, attributes) => {
|
|
2221
|
+
const style = parseStyleAttribute(attributes.style);
|
|
2222
|
+
return {
|
|
2223
|
+
fontFamily: style["font-family"] || attributes["font-family"] || base.fontFamily,
|
|
2224
|
+
fontStyle: style["font-style"] || attributes["font-style"] || base.fontStyle,
|
|
2225
|
+
fontWeight: style["font-weight"] || attributes["font-weight"] || base.fontWeight
|
|
2226
|
+
};
|
|
2227
|
+
};
|
|
2228
|
+
var getFontCandidates = (fontFamily, { fontStyle, fontWeight }) => {
|
|
2229
|
+
const isBold = fontWeight === "bold" || Number(fontWeight) >= 700;
|
|
2230
|
+
const isItalic = fontStyle === "italic";
|
|
2231
|
+
return Array.from(/* @__PURE__ */ new Set([
|
|
2232
|
+
`${fontFamily}${isBold ? "_bold" : ""}${isItalic ? "_italic" : ""}`,
|
|
2233
|
+
`${fontFamily}${isBold ? "_bold" : ""}`,
|
|
2234
|
+
`${fontFamily}${isItalic ? "_italic" : ""}`,
|
|
2235
|
+
fontFamily
|
|
2236
|
+
]));
|
|
2237
|
+
};
|
|
2238
|
+
var selectSvgFontNames = (svgString, font) => {
|
|
2239
|
+
const selectedFontNames = /* @__PURE__ */ new Set();
|
|
2240
|
+
const fontNames = Object.keys(font);
|
|
2241
|
+
const styleStack = [{}];
|
|
2242
|
+
let index = 0;
|
|
2243
|
+
while (index < svgString.length) {
|
|
2244
|
+
if (svgString[index] !== "<") {
|
|
2245
|
+
index += 1;
|
|
2246
|
+
continue;
|
|
2247
|
+
}
|
|
2248
|
+
let cursor = index + 1;
|
|
2249
|
+
const isClosingTag = svgString[cursor] === "/";
|
|
2250
|
+
if (isClosingTag) cursor += 1;
|
|
2251
|
+
if (!isAsciiAlpha(svgString[cursor])) {
|
|
2252
|
+
index += 1;
|
|
2253
|
+
continue;
|
|
2254
|
+
}
|
|
2255
|
+
const tagNameStart = cursor;
|
|
2256
|
+
while (isAttributeNameChar(svgString[cursor])) cursor += 1;
|
|
2257
|
+
const tagName = svgString.slice(tagNameStart, cursor).toLowerCase();
|
|
2258
|
+
const tagEnd = findTagEnd(svgString, cursor);
|
|
2259
|
+
if (tagEnd === -1) break;
|
|
2260
|
+
const tag = svgString.slice(index, tagEnd + 1);
|
|
2261
|
+
if (isClosingTag) {
|
|
2262
|
+
if (styleStack.length > 1) styleStack.pop();
|
|
2263
|
+
index = tagEnd + 1;
|
|
2264
|
+
continue;
|
|
2265
|
+
}
|
|
2266
|
+
const currentStyle = mergeFontStyle(styleStack[styleStack.length - 1], parseAttributes(tag));
|
|
2267
|
+
if (tagName === "text") {
|
|
2268
|
+
let selectedFontName;
|
|
2269
|
+
for (const family of splitFontFamilies(currentStyle.fontFamily)) {
|
|
2270
|
+
selectedFontName = getFontCandidates(family, currentStyle).find((fontName) => font[fontName]) || fontNames.find((fontName) => fontName.startsWith(family));
|
|
2271
|
+
if (selectedFontName) break;
|
|
2272
|
+
}
|
|
2273
|
+
if (selectedFontName) selectedFontNames.add(selectedFontName);
|
|
2274
|
+
}
|
|
2275
|
+
if (!isSelfClosingTag(tag)) styleStack.push(currentStyle);
|
|
2276
|
+
index = tagEnd + 1;
|
|
2277
|
+
}
|
|
2278
|
+
return Array.from(selectedFontNames);
|
|
2279
|
+
};
|
|
1873
2280
|
var svgSchema = {
|
|
1874
2281
|
ui: (arg) => {
|
|
1875
2282
|
const { rootElement, value, mode, onChange, theme, schema } = arg;
|
|
@@ -1922,20 +2329,45 @@ var svgSchema = {
|
|
|
1922
2329
|
}
|
|
1923
2330
|
},
|
|
1924
2331
|
pdf: async (arg) => {
|
|
1925
|
-
const { page, schema, value } = arg;
|
|
2332
|
+
const { page, pdfDoc, pdfLib, options, schema, value, _cache } = arg;
|
|
1926
2333
|
if (!value || !isValidSVG(value)) return;
|
|
1927
2334
|
const pageHeight = page.getHeight();
|
|
1928
2335
|
const { width, height, position } = convertForPdfLayoutProps({
|
|
1929
2336
|
schema,
|
|
1930
|
-
pageHeight
|
|
2337
|
+
pageHeight,
|
|
2338
|
+
applyRotateTranslate: false
|
|
1931
2339
|
});
|
|
1932
2340
|
const { x, y } = position;
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
2341
|
+
const font = options.font;
|
|
2342
|
+
const fontEntries = font ? await Promise.all(selectSvgFontNames(value, font).map(async (fontName) => [fontName, await embedAndGetFont({
|
|
2343
|
+
pdfDoc,
|
|
2344
|
+
font,
|
|
2345
|
+
fontName,
|
|
2346
|
+
_cache
|
|
2347
|
+
})])) : [];
|
|
2348
|
+
const fonts = fontEntries.length > 0 ? Object.fromEntries(fontEntries) : void 0;
|
|
2349
|
+
const mapColor = options.colorType?.toLowerCase() === "cmyk" ? ({ parsed }) => ({
|
|
2350
|
+
color: rgbColorToCmykColor(parsed.rgb),
|
|
2351
|
+
alpha: parsed.alpha
|
|
2352
|
+
}) : void 0;
|
|
2353
|
+
const rotateDegrees = schema.rotate ? -schema.rotate : 0;
|
|
2354
|
+
if (rotateDegrees) {
|
|
2355
|
+
const pivotX = x + width / 2;
|
|
2356
|
+
const pivotY = y + height / 2;
|
|
2357
|
+
page.pushOperators(pdfLib.pushGraphicsState(), pdfLib.translate(pivotX, pivotY), pdfLib.rotateDegrees(rotateDegrees), pdfLib.translate(-pivotX, -pivotY));
|
|
2358
|
+
}
|
|
2359
|
+
try {
|
|
2360
|
+
await page.drawSvg(value, {
|
|
2361
|
+
x,
|
|
2362
|
+
y: y + height,
|
|
2363
|
+
width,
|
|
2364
|
+
height,
|
|
2365
|
+
fonts,
|
|
2366
|
+
mapColor
|
|
2367
|
+
});
|
|
2368
|
+
} finally {
|
|
2369
|
+
if (rotateDegrees) page.pushOperators(pdfLib.popGraphicsState());
|
|
2370
|
+
}
|
|
1939
2371
|
},
|
|
1940
2372
|
propPanel: {
|
|
1941
2373
|
schema: {},
|
|
@@ -1952,7 +2384,8 @@ var svgSchema = {
|
|
|
1952
2384
|
y: 0
|
|
1953
2385
|
},
|
|
1954
2386
|
width: 40,
|
|
1955
|
-
height: 50
|
|
2387
|
+
height: 50,
|
|
2388
|
+
rotate: 0
|
|
1956
2389
|
}
|
|
1957
2390
|
},
|
|
1958
2391
|
icon: createSvgStr(Route)
|
|
@@ -2025,7 +2458,47 @@ var barCodeType2Bcid = (type) => type === "nw7" ? "rationalizedCodabar" : type;
|
|
|
2025
2458
|
* Strip hash from the beginning of HTML hex color codes for the bwip.js lib
|
|
2026
2459
|
*/
|
|
2027
2460
|
var mapHexColorForBwipJsLib = (color, fallback) => color ? color.replace("#", "") : fallback ? fallback.replace("#", "") : "000000";
|
|
2028
|
-
var
|
|
2461
|
+
var getBwipJsRenderer = () => bwipjs;
|
|
2462
|
+
var getDocument = () => globalThis.document;
|
|
2463
|
+
var getOffscreenCanvasCtor = () => globalThis.OffscreenCanvas;
|
|
2464
|
+
/**
|
|
2465
|
+
* Pick a barcode renderer from capabilities, not `typeof window`.
|
|
2466
|
+
* Browser Workers have neither `window` nor Node's `bwip-js.toBuffer()`.
|
|
2467
|
+
* OffscreenCanvas without `toCanvas()` (Node bwip-js export) falls back to `toBuffer()`.
|
|
2468
|
+
*/
|
|
2469
|
+
var resolveBarcodeRenderRuntime = () => {
|
|
2470
|
+
const doc = getDocument();
|
|
2471
|
+
const renderer = getBwipJsRenderer();
|
|
2472
|
+
if (doc && typeof doc.createElement === "function") return "document-canvas";
|
|
2473
|
+
if (typeof getOffscreenCanvasCtor() === "function" && typeof renderer.toCanvas === "function") return "offscreencanvas";
|
|
2474
|
+
if (typeof renderer.toBuffer === "function") return "node-buffer";
|
|
2475
|
+
throw new Error("[@pdfme/schemas] Barcode rendering requires a document canvas, OffscreenCanvas, or bwip-js toBuffer().");
|
|
2476
|
+
};
|
|
2477
|
+
var pngBufferFromDataUrl = (dataUrl) => Buffer$1.from(b64toUint8Array(dataUrl).buffer);
|
|
2478
|
+
var pngBufferFromBlob = async (blob) => Buffer$1.from(await blob.arrayBuffer());
|
|
2479
|
+
var renderBarcodeToCanvas = (canvas, options) => {
|
|
2480
|
+
const toCanvas = getBwipJsRenderer().toCanvas;
|
|
2481
|
+
if (typeof toCanvas !== "function") throw new Error("[@pdfme/schemas] bwip-js toCanvas() is not available in this environment.");
|
|
2482
|
+
toCanvas(canvas, options);
|
|
2483
|
+
};
|
|
2484
|
+
var renderBarcodeToDocumentCanvas = (options) => {
|
|
2485
|
+
const canvas = getDocument().createElement("canvas");
|
|
2486
|
+
renderBarcodeToCanvas(canvas, options);
|
|
2487
|
+
return pngBufferFromDataUrl(canvas.toDataURL("image/png"));
|
|
2488
|
+
};
|
|
2489
|
+
var renderBarcodeToOffscreenCanvas = async (options) => {
|
|
2490
|
+
const OffscreenCanvasCtor = getOffscreenCanvasCtor();
|
|
2491
|
+
if (typeof OffscreenCanvasCtor !== "function") throw new Error("[@pdfme/schemas] OffscreenCanvas is not available in this environment.");
|
|
2492
|
+
const canvas = new OffscreenCanvasCtor(1, 1);
|
|
2493
|
+
renderBarcodeToCanvas(canvas, options);
|
|
2494
|
+
return pngBufferFromBlob(await canvas.convertToBlob({ type: "image/png" }));
|
|
2495
|
+
};
|
|
2496
|
+
var renderBarcodeToNodeBuffer = async (options) => {
|
|
2497
|
+
const toBuffer = getBwipJsRenderer().toBuffer;
|
|
2498
|
+
if (typeof toBuffer !== "function") throw new Error("[@pdfme/schemas] bwip-js toBuffer() is not available in this environment.");
|
|
2499
|
+
return toBuffer(options);
|
|
2500
|
+
};
|
|
2501
|
+
var createBwipJsRenderOptions = (arg) => {
|
|
2029
2502
|
const { type, input, width, height, backgroundColor, barColor, textColor, includetext = true } = arg;
|
|
2030
2503
|
const bwipjsArg = {
|
|
2031
2504
|
bcid: barCodeType2Bcid(type),
|
|
@@ -2039,47 +2512,73 @@ var createBarCode = async (arg) => {
|
|
|
2039
2512
|
if (backgroundColor) bwipjsArg.backgroundcolor = mapHexColorForBwipJsLib(backgroundColor);
|
|
2040
2513
|
if (barColor) bwipjsArg.barcolor = mapHexColorForBwipJsLib(barColor);
|
|
2041
2514
|
if (textColor) bwipjsArg.textcolor = mapHexColorForBwipJsLib(textColor);
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2515
|
+
return bwipjsArg;
|
|
2516
|
+
};
|
|
2517
|
+
var createBarCodeSvg = (arg) => {
|
|
2518
|
+
const toSVG = getBwipJsRenderer().toSVG;
|
|
2519
|
+
if (typeof toSVG !== "function") throw new Error("[@pdfme/schemas] bwip-js toSVG() is not available in this environment.");
|
|
2520
|
+
const defaultFill = `#${mapHexColorForBwipJsLib(arg.barColor)}`;
|
|
2521
|
+
const svg = toSVG(createBwipJsRenderOptions(arg)).replace(/<svg\b(?![^>]*\sfill=)/, `<svg fill="${defaultFill}"`);
|
|
2522
|
+
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.`);
|
|
2523
|
+
return svg;
|
|
2524
|
+
};
|
|
2525
|
+
var createBarCode = async (arg) => {
|
|
2526
|
+
const bwipjsArg = createBwipJsRenderOptions(arg);
|
|
2527
|
+
const runtime = resolveBarcodeRenderRuntime();
|
|
2528
|
+
if (runtime === "document-canvas") return renderBarcodeToDocumentCanvas(bwipjsArg);
|
|
2529
|
+
if (runtime === "offscreencanvas") return renderBarcodeToOffscreenCanvas(bwipjsArg);
|
|
2530
|
+
return renderBarcodeToNodeBuffer(bwipjsArg);
|
|
2050
2531
|
};
|
|
2051
2532
|
//#endregion
|
|
2052
2533
|
//#region src/barcodes/pdfRender.ts
|
|
2053
2534
|
var getBarcodeCacheKey = (schema, value) => {
|
|
2054
|
-
return
|
|
2535
|
+
return `svg:${schema.type}:${schema.width}:${schema.height}:${schema.backgroundColor}:${schema.barColor}:${schema.textColor}:${schema.includetext}:${value}`;
|
|
2536
|
+
};
|
|
2537
|
+
var addSvgOpacity = (svg, opacity) => {
|
|
2538
|
+
return opacity === void 0 ? svg : svg.replace(/<svg\b/, `<svg opacity="${opacity}"`);
|
|
2539
|
+
};
|
|
2540
|
+
var getSvgColorMapper = (colorType = "") => {
|
|
2541
|
+
return colorType.toLowerCase() === "cmyk" ? ({ parsed }) => ({
|
|
2542
|
+
color: rgbColorToCmykColor(parsed.rgb),
|
|
2543
|
+
alpha: parsed.alpha
|
|
2544
|
+
}) : void 0;
|
|
2055
2545
|
};
|
|
2056
2546
|
var pdfRender$1 = async (arg) => {
|
|
2057
|
-
const { value, schema,
|
|
2547
|
+
const { value, schema, page, options, _cache } = arg;
|
|
2058
2548
|
if (!validateBarcodeInput(schema.type, value)) return;
|
|
2059
2549
|
const inputBarcodeCacheKey = getBarcodeCacheKey(schema, value);
|
|
2060
|
-
let
|
|
2061
|
-
if (!
|
|
2062
|
-
|
|
2550
|
+
let svg = _cache.get(inputBarcodeCacheKey);
|
|
2551
|
+
if (!svg) {
|
|
2552
|
+
svg = createBarCodeSvg({
|
|
2063
2553
|
...schema,
|
|
2064
2554
|
type: schema.type,
|
|
2065
2555
|
input: value
|
|
2066
2556
|
});
|
|
2067
|
-
|
|
2068
|
-
_cache.set(inputBarcodeCacheKey, image);
|
|
2557
|
+
_cache.set(inputBarcodeCacheKey, svg);
|
|
2069
2558
|
}
|
|
2070
2559
|
const pageHeight = page.getHeight();
|
|
2071
|
-
const { width, height,
|
|
2560
|
+
const { width, height, position: { x, y }, opacity } = convertForPdfLayoutProps({
|
|
2072
2561
|
schema,
|
|
2073
|
-
pageHeight
|
|
2074
|
-
|
|
2075
|
-
page.drawImage(image, {
|
|
2076
|
-
x,
|
|
2077
|
-
y,
|
|
2078
|
-
rotate,
|
|
2079
|
-
width,
|
|
2080
|
-
height,
|
|
2081
|
-
opacity
|
|
2562
|
+
pageHeight,
|
|
2563
|
+
applyRotateTranslate: false
|
|
2082
2564
|
});
|
|
2565
|
+
const pivot = {
|
|
2566
|
+
x: x + width / 2,
|
|
2567
|
+
y: y + height / 2
|
|
2568
|
+
};
|
|
2569
|
+
const rotate = schema.rotate ? -schema.rotate : 0;
|
|
2570
|
+
if (rotate) page.pushOperators(pushGraphicsState(), translate(pivot.x, pivot.y), rotateDegrees(rotate), translate(-pivot.x, -pivot.y));
|
|
2571
|
+
try {
|
|
2572
|
+
await page.drawSvg(addSvgOpacity(svg, opacity), {
|
|
2573
|
+
x,
|
|
2574
|
+
y: y + height,
|
|
2575
|
+
width,
|
|
2576
|
+
height,
|
|
2577
|
+
mapColor: getSvgColorMapper(options.colorType)
|
|
2578
|
+
});
|
|
2579
|
+
} finally {
|
|
2580
|
+
if (rotate) page.pushOperators(popGraphicsState());
|
|
2581
|
+
}
|
|
2083
2582
|
};
|
|
2084
2583
|
//#endregion
|
|
2085
2584
|
//#region src/barcodes/propPanel.ts
|