@pdfme/schemas 6.2.3-dev.5 → 6.2.3-dev.7
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/{builtins-Dtp1IM7M.js → builtins-Cj3XtvrX.js} +3 -3
- package/dist/{builtins-Dtp1IM7M.js.map → builtins-Cj3XtvrX.js.map} +1 -1
- package/dist/builtins.js +1 -1
- package/dist/dynamicLayout.js +1 -1
- package/dist/{dynamicTemplate-Zqt6kNsE.js → dynamicTemplate-BJxwjEWl.js} +489 -26
- package/dist/dynamicTemplate-BJxwjEWl.js.map +1 -0
- package/dist/graphics/imagehelper.d.ts +6 -1
- package/dist/index.js +71 -239
- package/dist/index.js.map +1 -1
- package/dist/tables/classes.d.ts +5 -3
- package/dist/tables/constants.d.ts +5 -0
- package/dist/tables/imageCell.d.ts +27 -0
- package/dist/tables/types.d.ts +23 -1
- package/dist/tables.js +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/{utils-DvBaBoME.js → utils-DU1bG5sa.js} +2 -2
- package/dist/{utils-DvBaBoME.js.map → utils-DU1bG5sa.js.map} +1 -1
- package/dist/utils.js +1 -1
- package/package.json +1 -1
- package/dist/dynamicTemplate-Zqt6kNsE.js.map +0 -1
|
@@ -1,5 +1,394 @@
|
|
|
1
1
|
import { A as getBoxVerticalInset, D as getBoxContentArea, E as createBoxDimension, F as ALIGN_LEFT, I as ALIGN_RIGHT, N as ALIGN_CENTER, O as getBoxDimensionPropPanelSchema, V as DEFAULT_FONT_COLOR, b as splitTextToSize, g as getFontKitFont, it as VERTICAL_ALIGN_MIDDLE, l as getTableBodyRange, o as createTableBodySplitRange, rt as VERTICAL_ALIGN_BOTTOM, x as widthOfTextAtSize, z as DEFAULT_ALIGNMENT } from "./splitRange-B6311Noc.js";
|
|
2
2
|
import { cloneDeep, getDefaultFont, getFallbackFontName, isBlankPdf, mm2pt, pt2mm } from "@pdfme/common";
|
|
3
|
+
import { Buffer } from "buffer";
|
|
4
|
+
import jpegJsModule from "jpeg-js";
|
|
5
|
+
import UPNGModule from "@pdf-lib/upng";
|
|
6
|
+
//#region src/graphics/imagehelper.ts
|
|
7
|
+
var decoder = new TextDecoder();
|
|
8
|
+
var toUTF8String = (input, start = 0, end = input.length) => decoder.decode(input.slice(start, end));
|
|
9
|
+
var toHexString = (input, start = 0, end = input.length) => input.slice(start, end).reduce((memo, i) => memo + ("0" + i.toString(16)).slice(-2), "");
|
|
10
|
+
var readUInt16BE = (input, offset = 0) => input[offset] * 256 + input[offset + 1];
|
|
11
|
+
var readUInt32BE = (input, offset = 0) => input[offset] * 2 ** 24 + input[offset + 1] * 2 ** 16 + input[offset + 2] * 256 + input[offset + 3];
|
|
12
|
+
var extractSize = (input, index) => {
|
|
13
|
+
return {
|
|
14
|
+
height: readUInt16BE(input, index),
|
|
15
|
+
width: readUInt16BE(input, index + 2)
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
var validateInput = (input, index) => {
|
|
19
|
+
if (index > input.length) throw new TypeError("Corrupt JPG, exceeded buffer limits");
|
|
20
|
+
if (input[index] !== 255) throw new TypeError("Invalid JPG, marker table corrupted");
|
|
21
|
+
};
|
|
22
|
+
var JPG = {
|
|
23
|
+
validate: (input) => toHexString(input, 0, 2) === "ffd8",
|
|
24
|
+
calculate(input) {
|
|
25
|
+
input = input.slice(4);
|
|
26
|
+
let next;
|
|
27
|
+
while (input.length) {
|
|
28
|
+
const i = readUInt16BE(input, 0);
|
|
29
|
+
validateInput(input, i);
|
|
30
|
+
next = input[i + 1];
|
|
31
|
+
if (next === 192 || next === 193 || next === 194) return extractSize(input, i + 5);
|
|
32
|
+
input = input.slice(i + 2);
|
|
33
|
+
}
|
|
34
|
+
throw new TypeError("Invalid JPG, no size found");
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var pngSignature = "PNG\r\n\n";
|
|
38
|
+
var pngImageHeaderChunkName = "IHDR";
|
|
39
|
+
var pngFriedChunkName = "CgBI";
|
|
40
|
+
var typeHandlers = {
|
|
41
|
+
jpg: JPG,
|
|
42
|
+
png: {
|
|
43
|
+
validate(input) {
|
|
44
|
+
if (pngSignature === toUTF8String(input, 1, 8)) {
|
|
45
|
+
let chunkName = toUTF8String(input, 12, 16);
|
|
46
|
+
if (chunkName === pngFriedChunkName) chunkName = toUTF8String(input, 28, 32);
|
|
47
|
+
if (chunkName !== pngImageHeaderChunkName) throw new TypeError("Invalid PNG");
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
},
|
|
52
|
+
calculate(input) {
|
|
53
|
+
if (toUTF8String(input, 12, 16) === pngFriedChunkName) return {
|
|
54
|
+
height: readUInt32BE(input, 36),
|
|
55
|
+
width: readUInt32BE(input, 32)
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
height: readUInt32BE(input, 20),
|
|
59
|
+
width: readUInt32BE(input, 16)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
function detector(input) {
|
|
65
|
+
const firstBytes = {
|
|
66
|
+
137: "png",
|
|
67
|
+
255: "jpg"
|
|
68
|
+
};
|
|
69
|
+
const byte = input[0];
|
|
70
|
+
if (byte in firstBytes) {
|
|
71
|
+
const type = firstBytes[byte];
|
|
72
|
+
if (type && typeHandlers[type].validate(input)) return type;
|
|
73
|
+
}
|
|
74
|
+
return Object.keys(typeHandlers).find((key) => typeHandlers[key].validate(input));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* FNV-1a 32-bit fingerprint of an image data URL.
|
|
78
|
+
* Image embed cache keys are `${type}:${length}:${hash}` and must keep this hash.
|
|
79
|
+
*/
|
|
80
|
+
var hashImageDataUrl = (value) => {
|
|
81
|
+
let hash = 2166136261;
|
|
82
|
+
for (let i = 0; i < value.length; i++) {
|
|
83
|
+
hash ^= value.charCodeAt(i);
|
|
84
|
+
hash = Math.imul(hash, 16777619);
|
|
85
|
+
}
|
|
86
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
87
|
+
};
|
|
88
|
+
var getImageDimension = (value) => {
|
|
89
|
+
if (typeof value !== "string") return imageSize(Buffer.from(value));
|
|
90
|
+
const idx = value.indexOf(";base64,");
|
|
91
|
+
const imgBase64 = value.substring(idx + 8, value.length);
|
|
92
|
+
return imageSize(Buffer.from(imgBase64, "base64"));
|
|
93
|
+
};
|
|
94
|
+
var imageSize = (imgBuffer) => {
|
|
95
|
+
const type = detector(imgBuffer);
|
|
96
|
+
if (typeof type !== "undefined" && type in typeHandlers) {
|
|
97
|
+
const size = typeHandlers[type].calculate(imgBuffer);
|
|
98
|
+
if (size !== void 0) return size;
|
|
99
|
+
}
|
|
100
|
+
throw new TypeError("[@pdfme/schemas/images] Unsupported file type: " + (type === void 0 ? "undefined" : type));
|
|
101
|
+
};
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/graphics/orientation.ts
|
|
104
|
+
var isJpegJsApi = (value) => !!value && typeof value === "object" && typeof value.decode === "function" && typeof value.encode === "function";
|
|
105
|
+
var isUPNGApi = (value) => !!value && typeof value === "object" && typeof value.decode === "function" && typeof value.toRGBA8 === "function" && typeof value.encode === "function";
|
|
106
|
+
var resolveExport = (value, guard, label) => {
|
|
107
|
+
let current = value;
|
|
108
|
+
while (current && typeof current === "object") {
|
|
109
|
+
if (guard(current)) return current;
|
|
110
|
+
current = current.default;
|
|
111
|
+
}
|
|
112
|
+
throw new TypeError(`Failed to resolve ${label} exports`);
|
|
113
|
+
};
|
|
114
|
+
var jpegJs = resolveExport(jpegJsModule, isJpegJsApi, "jpeg-js");
|
|
115
|
+
var UPNG = resolveExport(UPNGModule, isUPNGApi, "@pdf-lib/upng");
|
|
116
|
+
var JPEG_ENCODE_QUALITY = 90;
|
|
117
|
+
var JPEG_MAX_MEMORY_MB = 512;
|
|
118
|
+
var JPEG_SOI_0 = 255;
|
|
119
|
+
var JPEG_SOI_1 = 216;
|
|
120
|
+
var PNG_SIGNATURE = new Uint8Array([
|
|
121
|
+
137,
|
|
122
|
+
80,
|
|
123
|
+
78,
|
|
124
|
+
71,
|
|
125
|
+
13,
|
|
126
|
+
10,
|
|
127
|
+
26,
|
|
128
|
+
10
|
|
129
|
+
]);
|
|
130
|
+
var toArrayBuffer = (bytes) => {
|
|
131
|
+
const copy = new Uint8Array(bytes.byteLength);
|
|
132
|
+
copy.set(bytes);
|
|
133
|
+
return copy.buffer;
|
|
134
|
+
};
|
|
135
|
+
var isPngSignature = (bytes) => {
|
|
136
|
+
if (bytes.length < PNG_SIGNATURE.length) return false;
|
|
137
|
+
for (let i = 0; i < PNG_SIGNATURE.length; i++) if (bytes[i] !== PNG_SIGNATURE[i]) return false;
|
|
138
|
+
return true;
|
|
139
|
+
};
|
|
140
|
+
var detectImageFormat = (bytes) => {
|
|
141
|
+
if (bytes.length >= 2 && bytes[0] === JPEG_SOI_0 && bytes[1] === JPEG_SOI_1) return "jpeg";
|
|
142
|
+
if (isPngSignature(bytes)) return "png";
|
|
143
|
+
return "other";
|
|
144
|
+
};
|
|
145
|
+
/** TIFF/IFD0: returns 1..8 or undefined. Never throws. */
|
|
146
|
+
var parseTiffOrientation = (tiff) => {
|
|
147
|
+
try {
|
|
148
|
+
if (tiff.length < 8) return void 0;
|
|
149
|
+
const le = tiff[0] === 73 && tiff[1] === 73;
|
|
150
|
+
if (!le && !(tiff[0] === 77 && tiff[1] === 77)) return void 0;
|
|
151
|
+
const view = new DataView(tiff.buffer, tiff.byteOffset, tiff.byteLength);
|
|
152
|
+
if (view.getUint16(2, le) !== 42) return void 0;
|
|
153
|
+
const ifd = view.getUint32(4, le);
|
|
154
|
+
if (ifd + 2 > tiff.length) return void 0;
|
|
155
|
+
const n = view.getUint16(ifd, le);
|
|
156
|
+
for (let i = 0; i < n; i++) {
|
|
157
|
+
const entry = ifd + 2 + i * 12;
|
|
158
|
+
if (entry + 12 > tiff.length) return void 0;
|
|
159
|
+
if (view.getUint16(entry, le) !== 274) continue;
|
|
160
|
+
if (view.getUint16(entry + 2, le) !== 3) return void 0;
|
|
161
|
+
if (view.getUint32(entry + 4, le) !== 1) return void 0;
|
|
162
|
+
const val = view.getUint16(entry + 8, le);
|
|
163
|
+
return val >= 1 && val <= 8 ? val : void 0;
|
|
164
|
+
}
|
|
165
|
+
return;
|
|
166
|
+
} catch {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
var isExifApp1Payload = (segment) => segment.length >= 6 && segment[0] === 69 && segment[1] === 120 && segment[2] === 105 && segment[3] === 102 && segment[4] === 0 && segment[5] === 0;
|
|
171
|
+
/** Standalone JPEG markers have no length field (TEM, RST0–7, SOI). */
|
|
172
|
+
var isStandaloneJpegMarker = (marker) => marker === 1 || marker >= 208 && marker <= 216;
|
|
173
|
+
/**
|
|
174
|
+
* JPEG: scan APP1 'Exif\0\0' segments; stop at SOS/EOI.
|
|
175
|
+
* Skips 0xFF fill/padding and standalone markers. If an Exif APP1 has no
|
|
176
|
+
* valid Orientation, keep scanning for a later one.
|
|
177
|
+
*/
|
|
178
|
+
var getJpegOrientation = (bytes) => {
|
|
179
|
+
if (bytes.length < 2 || bytes[0] !== JPEG_SOI_0 || bytes[1] !== JPEG_SOI_1) return void 0;
|
|
180
|
+
let pos = 2;
|
|
181
|
+
while (pos < bytes.length) {
|
|
182
|
+
if (bytes[pos] !== 255) return void 0;
|
|
183
|
+
while (pos < bytes.length && bytes[pos] === 255) pos++;
|
|
184
|
+
if (pos >= bytes.length) return void 0;
|
|
185
|
+
const marker = bytes[pos++];
|
|
186
|
+
if (isStandaloneJpegMarker(marker)) continue;
|
|
187
|
+
if (marker === 218 || marker === 217) return void 0;
|
|
188
|
+
if (pos + 2 > bytes.length) return void 0;
|
|
189
|
+
const size = bytes[pos] << 8 | bytes[pos + 1];
|
|
190
|
+
if (size < 2 || pos + size > bytes.length) return void 0;
|
|
191
|
+
if (marker === 225 && size >= 8) {
|
|
192
|
+
const segment = bytes.subarray(pos + 2, pos + size);
|
|
193
|
+
if (isExifApp1Payload(segment)) {
|
|
194
|
+
const orientation = parseTiffOrientation(segment.subarray(6));
|
|
195
|
+
if (orientation !== void 0) return orientation;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
pos += size;
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* PNG: scan chunks for eXIf (raw TIFF payload). Skip IDAT and other
|
|
203
|
+
* ancillary chunks; eXIf may appear after image data. Stop at IEND.
|
|
204
|
+
*/
|
|
205
|
+
var getPngOrientation = (bytes) => {
|
|
206
|
+
if (!isPngSignature(bytes)) return void 0;
|
|
207
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
208
|
+
let pos = 8;
|
|
209
|
+
while (pos + 12 <= bytes.length) {
|
|
210
|
+
const length = view.getUint32(pos);
|
|
211
|
+
if (pos + 12 + length > bytes.length) return void 0;
|
|
212
|
+
const type = String.fromCharCode(bytes[pos + 4], bytes[pos + 5], bytes[pos + 6], bytes[pos + 7]);
|
|
213
|
+
if (type === "eXIf") return parseTiffOrientation(bytes.subarray(pos + 8, pos + 8 + length));
|
|
214
|
+
if (type === "IEND") return void 0;
|
|
215
|
+
pos += 12 + length;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
var orientationSwapsDimensions = (orientation) => orientation >= 5;
|
|
219
|
+
/**
|
|
220
|
+
* Map source (x, y) into destination (dx, dy) for EXIF orientations 2–8.
|
|
221
|
+
* Orientations 5–8 swap width and height.
|
|
222
|
+
*/
|
|
223
|
+
var transformRgba = (src, width, height, orientation) => {
|
|
224
|
+
const swap = orientationSwapsDimensions(orientation);
|
|
225
|
+
const destWidth = swap ? height : width;
|
|
226
|
+
const destHeight = swap ? width : height;
|
|
227
|
+
const dest = new Uint8Array(destWidth * destHeight * 4);
|
|
228
|
+
for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
|
|
229
|
+
let dx = x;
|
|
230
|
+
let dy = y;
|
|
231
|
+
switch (orientation) {
|
|
232
|
+
case 2:
|
|
233
|
+
dx = width - 1 - x;
|
|
234
|
+
dy = y;
|
|
235
|
+
break;
|
|
236
|
+
case 3:
|
|
237
|
+
dx = width - 1 - x;
|
|
238
|
+
dy = height - 1 - y;
|
|
239
|
+
break;
|
|
240
|
+
case 4:
|
|
241
|
+
dx = x;
|
|
242
|
+
dy = height - 1 - y;
|
|
243
|
+
break;
|
|
244
|
+
case 5:
|
|
245
|
+
dx = y;
|
|
246
|
+
dy = x;
|
|
247
|
+
break;
|
|
248
|
+
case 6:
|
|
249
|
+
dx = height - 1 - y;
|
|
250
|
+
dy = x;
|
|
251
|
+
break;
|
|
252
|
+
case 7:
|
|
253
|
+
dx = height - 1 - y;
|
|
254
|
+
dy = width - 1 - x;
|
|
255
|
+
break;
|
|
256
|
+
case 8:
|
|
257
|
+
dx = y;
|
|
258
|
+
dy = width - 1 - x;
|
|
259
|
+
}
|
|
260
|
+
const srcIndex = (y * width + x) * 4;
|
|
261
|
+
const destIndex = (dy * destWidth + dx) * 4;
|
|
262
|
+
dest[destIndex] = src[srcIndex];
|
|
263
|
+
dest[destIndex + 1] = src[srcIndex + 1];
|
|
264
|
+
dest[destIndex + 2] = src[srcIndex + 2];
|
|
265
|
+
dest[destIndex + 3] = src[srcIndex + 3];
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
data: dest,
|
|
269
|
+
width: destWidth,
|
|
270
|
+
height: destHeight
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
var bakeJpegOrientation = (bytes) => {
|
|
274
|
+
const orientation = getJpegOrientation(bytes);
|
|
275
|
+
if (!orientation || orientation === 1) return bytes;
|
|
276
|
+
const raw = jpegJs.decode(bytes, {
|
|
277
|
+
useTArray: true,
|
|
278
|
+
formatAsRGBA: true,
|
|
279
|
+
maxMemoryUsageInMB: JPEG_MAX_MEMORY_MB
|
|
280
|
+
});
|
|
281
|
+
const transformed = transformRgba(raw.data, raw.width, raw.height, orientation);
|
|
282
|
+
return new Uint8Array(jpegJs.encode({
|
|
283
|
+
data: transformed.data,
|
|
284
|
+
width: transformed.width,
|
|
285
|
+
height: transformed.height
|
|
286
|
+
}, JPEG_ENCODE_QUALITY).data);
|
|
287
|
+
};
|
|
288
|
+
var bakePngOrientation = (bytes) => {
|
|
289
|
+
const orientation = getPngOrientation(bytes);
|
|
290
|
+
if (!orientation || orientation === 1) return bytes;
|
|
291
|
+
const img = UPNG.decode(toArrayBuffer(bytes));
|
|
292
|
+
const transformed = transformRgba(new Uint8Array(UPNG.toRGBA8(img)[0]), img.width, img.height, orientation);
|
|
293
|
+
return new Uint8Array(UPNG.encode([toArrayBuffer(transformed.data)], transformed.width, transformed.height, 0));
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* One normalize path for JPEG and PNG. Tag absent/1 is a byte-identical
|
|
297
|
+
* passthrough. Tag 2–8 decodes, transforms pixels, and re-encodes without
|
|
298
|
+
* an orientation tag. May throw on decode/encode failure — callers fall back.
|
|
299
|
+
*/
|
|
300
|
+
var normalizeImageOrientation = (bytes) => {
|
|
301
|
+
const kind = detectImageFormat(bytes);
|
|
302
|
+
if (kind === "jpeg") return bakeJpegOrientation(bytes);
|
|
303
|
+
if (kind === "png") return bakePngOrientation(bytes);
|
|
304
|
+
return bytes;
|
|
305
|
+
};
|
|
306
|
+
var TABLE_IMAGE_DATA_URL_PATTERN = /^data:image\/(png|jpe?g);base64,/i;
|
|
307
|
+
//#endregion
|
|
308
|
+
//#region src/tables/types.ts
|
|
309
|
+
var TABLE_CELL_TYPES = ["text", "image"];
|
|
310
|
+
//#endregion
|
|
311
|
+
//#region src/tables/imageCell.ts
|
|
312
|
+
var DIMENSION_CACHE_PREFIX = "tableImageDim:";
|
|
313
|
+
var WARN_CACHE_PREFIX = "tableImageWarned:";
|
|
314
|
+
var FAILED_DIMENSION = null;
|
|
315
|
+
var isTableCellType = (value) => typeof value === "string" && TABLE_CELL_TYPES.some((cellType) => cellType === value);
|
|
316
|
+
var isDimension = (value) => {
|
|
317
|
+
if (!value || typeof value !== "object") return false;
|
|
318
|
+
const record = value;
|
|
319
|
+
return typeof record.width === "number" && typeof record.height === "number";
|
|
320
|
+
};
|
|
321
|
+
var dataUrlToBytes = (value) => {
|
|
322
|
+
const index = value.indexOf(";base64,");
|
|
323
|
+
const base64 = index >= 0 ? value.slice(index + 8) : value;
|
|
324
|
+
return new Uint8Array(Buffer.from(base64, "base64"));
|
|
325
|
+
};
|
|
326
|
+
var applyOrientation = (dimension, bytes) => {
|
|
327
|
+
const format = detectImageFormat(bytes);
|
|
328
|
+
const orientation = format === "jpeg" ? getJpegOrientation(bytes) : format === "png" ? getPngOrientation(bytes) : void 0;
|
|
329
|
+
if (orientation !== void 0 && orientationSwapsDimensions(orientation)) return {
|
|
330
|
+
width: dimension.height,
|
|
331
|
+
height: dimension.width
|
|
332
|
+
};
|
|
333
|
+
return dimension;
|
|
334
|
+
};
|
|
335
|
+
var isTableImageDataUrl = (value) => TABLE_IMAGE_DATA_URL_PATTERN.test(value);
|
|
336
|
+
var imageCacheSuffix = (value) => `${value.length}:${hashImageDataUrl(value)}`;
|
|
337
|
+
var resolveImageDimension = (value, cache) => {
|
|
338
|
+
if (!isTableImageDataUrl(value)) return void 0;
|
|
339
|
+
const key = `${DIMENSION_CACHE_PREFIX}${imageCacheSuffix(value)}`;
|
|
340
|
+
const cached = cache.get(key);
|
|
341
|
+
if (cached === FAILED_DIMENSION) return void 0;
|
|
342
|
+
if (isDimension(cached)) return cached;
|
|
343
|
+
try {
|
|
344
|
+
const bytes = dataUrlToBytes(value);
|
|
345
|
+
const dimension = applyOrientation(getImageDimension(bytes), bytes);
|
|
346
|
+
cache.set(key, dimension);
|
|
347
|
+
return dimension;
|
|
348
|
+
} catch {
|
|
349
|
+
cache.set(key, FAILED_DIMENSION);
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
var warnInvalidTableImageOnce = (value, columnIndex, cache) => {
|
|
354
|
+
if (value == null || value === "") return;
|
|
355
|
+
const key = `${WARN_CACHE_PREFIX}${imageCacheSuffix(value)}`;
|
|
356
|
+
if (cache.has(key)) return;
|
|
357
|
+
cache.set(key, true);
|
|
358
|
+
console.warn(`[@pdfme/schemas/table] unsupported image in column ${columnIndex}; only PNG/JPEG data URL is supported`);
|
|
359
|
+
};
|
|
360
|
+
var normalizeTableCellType = (value, columnIndex, cache) => {
|
|
361
|
+
if (value == null) return void 0;
|
|
362
|
+
if (isTableCellType(value)) return value;
|
|
363
|
+
const warnKey = `tableCellTypeWarned:${String(value)}`;
|
|
364
|
+
if (!cache.has(warnKey)) {
|
|
365
|
+
cache.set(warnKey, true);
|
|
366
|
+
console.warn(`[@pdfme/schemas/table] unsupported cell type "${String(value)}" in column ${columnIndex}; treating as text`);
|
|
367
|
+
}
|
|
368
|
+
return "text";
|
|
369
|
+
};
|
|
370
|
+
var normalizeTableImageHeightMode = (value) => value === "fixed" || value === "auto" ? value : void 0;
|
|
371
|
+
var normalizeTableImageHeight = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
372
|
+
var getTableImageObjectPosition = (alignment, verticalAlignment) => {
|
|
373
|
+
return `${alignment === "center" || alignment === "right" ? alignment : "left"} ${verticalAlignment === "top" ? "top" : verticalAlignment === "bottom" ? "bottom" : "center"}`;
|
|
374
|
+
};
|
|
375
|
+
var resolveFixedTableImageHeight = (imageHeight) => typeof imageHeight === "number" && Number.isFinite(imageHeight) && imageHeight > 0 ? imageHeight : 20;
|
|
376
|
+
/**
|
|
377
|
+
* Fixed height is kept for empty and invalid values so rows in the column stay aligned.
|
|
378
|
+
* Auto height is 0 unless a PNG/JPEG data URL resolves.
|
|
379
|
+
*/
|
|
380
|
+
var resolveTableImageContentHeight = (arg) => {
|
|
381
|
+
const mode = arg.mode ?? "fixed";
|
|
382
|
+
if (!arg.value) return mode === "auto" ? 0 : resolveFixedTableImageHeight(arg.imageHeight);
|
|
383
|
+
const dimension = resolveImageDimension(arg.value, arg.cache);
|
|
384
|
+
if (!dimension || dimension.width <= 0) {
|
|
385
|
+
warnInvalidTableImageOnce(arg.value, arg.columnIndex, arg.cache);
|
|
386
|
+
return mode === "auto" ? 0 : resolveFixedTableImageHeight(arg.imageHeight);
|
|
387
|
+
}
|
|
388
|
+
if (mode === "auto") return arg.contentWidth * dimension.height / dimension.width;
|
|
389
|
+
return resolveFixedTableImageHeight(arg.imageHeight);
|
|
390
|
+
};
|
|
391
|
+
//#endregion
|
|
3
392
|
//#region \0@oxc-project+runtime@0.151.0/helpers/esm/typeof.js
|
|
4
393
|
function _typeof(o) {
|
|
5
394
|
"@babel/helpers - typeof";
|
|
@@ -50,6 +439,7 @@ var Cell = class {
|
|
|
50
439
|
_defineProperty(this, "wrappedWidth", 0);
|
|
51
440
|
_defineProperty(this, "minReadableWidth", 0);
|
|
52
441
|
_defineProperty(this, "minWidth", 0);
|
|
442
|
+
_defineProperty(this, "imageContentHeight", 0);
|
|
53
443
|
_defineProperty(this, "width", 0);
|
|
54
444
|
_defineProperty(this, "height", 0);
|
|
55
445
|
_defineProperty(this, "x", 0);
|
|
@@ -60,8 +450,13 @@ var Cell = class {
|
|
|
60
450
|
const splitRegex = /\r\n|\r|\n/g;
|
|
61
451
|
this.text = raw.split(splitRegex);
|
|
62
452
|
}
|
|
453
|
+
isImage() {
|
|
454
|
+
return this.section !== "head" && this.styles.cellType === "image";
|
|
455
|
+
}
|
|
63
456
|
getContentHeight() {
|
|
64
|
-
const
|
|
457
|
+
const verticalInset = getBoxVerticalInset(getCellBoxStyle(this));
|
|
458
|
+
if (this.isImage()) return Math.max(this.imageContentHeight + verticalInset, this.styles.minCellHeight);
|
|
459
|
+
const height = (Array.isArray(this.text) ? this.text.length : 1) * (pt2mm(this.styles.fontSize) * this.styles.lineHeight) + verticalInset;
|
|
65
460
|
return Math.max(height, this.styles.minCellHeight);
|
|
66
461
|
}
|
|
67
462
|
padding(name) {
|
|
@@ -128,11 +523,12 @@ var Table = class Table {
|
|
|
128
523
|
this.body = content.body;
|
|
129
524
|
}
|
|
130
525
|
static async create(arg) {
|
|
131
|
-
const { input, content, font, _cache } = arg;
|
|
526
|
+
const { input, content, font, basePdf, _cache } = arg;
|
|
132
527
|
const table = new Table(input, content);
|
|
133
528
|
await calculateWidths({
|
|
134
529
|
table,
|
|
135
530
|
font,
|
|
531
|
+
basePdf,
|
|
136
532
|
_cache
|
|
137
533
|
});
|
|
138
534
|
return table;
|
|
@@ -154,7 +550,7 @@ var Table = class Table {
|
|
|
154
550
|
}
|
|
155
551
|
};
|
|
156
552
|
async function calculateWidths(arg) {
|
|
157
|
-
const { table, font, _cache } = arg;
|
|
553
|
+
const { table, font, basePdf, _cache } = arg;
|
|
158
554
|
const getFontKitFontByFontName = (fontName) => getFontKitFont(fontName, font, _cache);
|
|
159
555
|
await calculate(table, getFontKitFontByFontName);
|
|
160
556
|
const resizableColumns = [];
|
|
@@ -173,7 +569,7 @@ async function calculateWidths(arg) {
|
|
|
173
569
|
if (resizeWidth) resizeWidth = resizeColumns(resizableColumns, resizeWidth, (column) => column.minWidth);
|
|
174
570
|
resizeWidth = Math.abs(resizeWidth);
|
|
175
571
|
applyColSpans(table);
|
|
176
|
-
await fitContent(table, getFontKitFontByFontName);
|
|
572
|
+
await fitContent(table, getFontKitFontByFontName, basePdf, _cache);
|
|
177
573
|
applyRowSpans(table);
|
|
178
574
|
}
|
|
179
575
|
function applyRowSpans(table) {
|
|
@@ -229,7 +625,15 @@ function applyColSpans(table) {
|
|
|
229
625
|
}
|
|
230
626
|
}
|
|
231
627
|
}
|
|
232
|
-
|
|
628
|
+
var autoImageHeightLimit = (table, cell, basePdf) => {
|
|
629
|
+
if (!isBlankPdf(basePdf)) return void 0;
|
|
630
|
+
const [paddingTop, , paddingBottom] = basePdf.padding;
|
|
631
|
+
const pageContentHeight = basePdf.height - paddingTop - paddingBottom;
|
|
632
|
+
const headHeight = table.settings.templateShowHead ? table.head.reduce((sum, row) => sum + row.height, 0) : 0;
|
|
633
|
+
const verticalInset = getBoxVerticalInset(getCellBoxStyle(cell));
|
|
634
|
+
return pageContentHeight - headHeight - verticalInset - 1;
|
|
635
|
+
};
|
|
636
|
+
async function fitContent(table, getFontKitFontByFontName, basePdf, cache) {
|
|
233
637
|
const rowSpanHeight = {
|
|
234
638
|
count: 0,
|
|
235
639
|
height: 0
|
|
@@ -238,7 +642,6 @@ async function fitContent(table, getFontKitFontByFontName) {
|
|
|
238
642
|
for (const column of table.columns) {
|
|
239
643
|
const cell = row.cells[column.index];
|
|
240
644
|
if (!cell) continue;
|
|
241
|
-
const fontKitFont = await getFontKitFontByFontName(cell.styles.fontName);
|
|
242
645
|
const contentArea = getBoxContentArea({
|
|
243
646
|
position: {
|
|
244
647
|
x: 0,
|
|
@@ -248,13 +651,31 @@ async function fitContent(table, getFontKitFontByFontName) {
|
|
|
248
651
|
height: cell.height,
|
|
249
652
|
...getCellBoxStyle(cell)
|
|
250
653
|
});
|
|
251
|
-
cell.
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
654
|
+
if (cell.isImage()) {
|
|
655
|
+
cell.text = [];
|
|
656
|
+
let imageContentHeight = resolveTableImageContentHeight({
|
|
657
|
+
value: cell.raw,
|
|
658
|
+
mode: cell.styles.imageHeightMode,
|
|
659
|
+
imageHeight: cell.styles.imageHeight,
|
|
660
|
+
contentWidth: contentArea.width,
|
|
661
|
+
columnIndex: column.index,
|
|
662
|
+
cache
|
|
663
|
+
});
|
|
664
|
+
if ((cell.styles.imageHeightMode ?? "fixed") === "auto") {
|
|
665
|
+
const limit = autoImageHeightLimit(table, cell, basePdf);
|
|
666
|
+
if (limit !== void 0) imageContentHeight = Math.min(imageContentHeight, Math.max(0, limit));
|
|
667
|
+
}
|
|
668
|
+
cell.imageContentHeight = imageContentHeight;
|
|
669
|
+
} else {
|
|
670
|
+
const fontKitFont = await getFontKitFontByFontName(cell.styles.fontName);
|
|
671
|
+
cell.text = splitTextToSize({
|
|
672
|
+
value: cell.raw,
|
|
673
|
+
characterSpacing: cell.styles.characterSpacing,
|
|
674
|
+
boxWidthInPt: mm2pt(contentArea.width),
|
|
675
|
+
fontSize: cell.styles.fontSize,
|
|
676
|
+
fontKitFont
|
|
677
|
+
});
|
|
678
|
+
}
|
|
258
679
|
cell.contentHeight = cell.getContentHeight();
|
|
259
680
|
let realContentHeight = cell.contentHeight;
|
|
260
681
|
if (rowSpanHeight && rowSpanHeight.count > 0) {
|
|
@@ -291,6 +712,13 @@ async function calculate(table, getFontKitFontByFontName) {
|
|
|
291
712
|
const cell = row.cells[column.index];
|
|
292
713
|
if (!cell) continue;
|
|
293
714
|
const hPadding = cell.padding("right") + cell.padding("left");
|
|
715
|
+
if (cell.isImage()) {
|
|
716
|
+
cell.contentWidth = hPadding;
|
|
717
|
+
cell.minReadableWidth = hPadding;
|
|
718
|
+
cell.minWidth = cell.styles.cellWidth;
|
|
719
|
+
cell.wrappedWidth = cell.styles.cellWidth;
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
294
722
|
const fontKitFont = await getFontKitFontByFontName(cell.styles.fontName);
|
|
295
723
|
cell.contentWidth = getStringWidth(cell, fontKitFont) + hPadding;
|
|
296
724
|
cell.minReadableWidth = getStringWidth(Object.assign(cell, { text: cell.text.join(" ").split(/\s+/) }), fontKitFont) + hPadding;
|
|
@@ -404,24 +832,43 @@ function mapCellStyle(style) {
|
|
|
404
832
|
};
|
|
405
833
|
return Object.fromEntries(Object.entries(mapping).filter(([, value]) => value !== void 0));
|
|
406
834
|
}
|
|
407
|
-
function getTableOptions(schema, body) {
|
|
835
|
+
function getTableOptions(schema, body, cache) {
|
|
408
836
|
const columnStylesWidth = schema.headWidthPercentages.reduce((acc, cur, i) => ({
|
|
409
837
|
...acc,
|
|
410
838
|
[i]: { cellWidth: schema.width * (cur / 100) }
|
|
411
839
|
}), {});
|
|
412
|
-
const
|
|
840
|
+
const alignmentMap = schema.columnStyles.alignment || {};
|
|
841
|
+
const cellTypeMap = schema.columnStyles.cellType || {};
|
|
842
|
+
const imageHeightModeMap = schema.columnStyles.imageHeightMode || {};
|
|
843
|
+
const imageHeightMap = schema.columnStyles.imageHeight || {};
|
|
844
|
+
const columnStylesAlignment = Object.entries(alignmentMap).reduce((acc, [key, value]) => ({
|
|
413
845
|
...acc,
|
|
414
846
|
[key]: { alignment: value }
|
|
415
847
|
}), {});
|
|
416
|
-
const allKeys = /* @__PURE__ */ new Set([
|
|
848
|
+
const allKeys = /* @__PURE__ */ new Set([
|
|
849
|
+
...Object.keys(columnStylesWidth).map(Number),
|
|
850
|
+
...Object.keys(columnStylesAlignment).map(Number),
|
|
851
|
+
...Object.keys(cellTypeMap).map(Number),
|
|
852
|
+
...Object.keys(imageHeightModeMap).map(Number),
|
|
853
|
+
...Object.keys(imageHeightMap).map(Number)
|
|
854
|
+
]);
|
|
417
855
|
const columnStyles = Array.from(allKeys).reduce((acc, key) => {
|
|
418
856
|
const widthStyle = columnStylesWidth[key] || {};
|
|
419
857
|
const alignmentStyle = columnStylesAlignment[key] || {};
|
|
858
|
+
const cellType = normalizeTableCellType(cellTypeMap[key], key, cache);
|
|
859
|
+
const imageHeightMode = normalizeTableImageHeightMode(imageHeightModeMap[key]);
|
|
860
|
+
const imageHeight = normalizeTableImageHeight(imageHeightMap[key]);
|
|
861
|
+
const imageStyle = {
|
|
862
|
+
...cellType ? { cellType } : {},
|
|
863
|
+
...imageHeightMode ? { imageHeightMode } : {},
|
|
864
|
+
...imageHeight !== void 0 ? { imageHeight } : {}
|
|
865
|
+
};
|
|
420
866
|
return {
|
|
421
867
|
...acc,
|
|
422
868
|
[key]: {
|
|
423
869
|
...widthStyle,
|
|
424
|
-
...alignmentStyle
|
|
870
|
+
...alignmentStyle,
|
|
871
|
+
...imageStyle
|
|
425
872
|
}
|
|
426
873
|
};
|
|
427
874
|
}, {});
|
|
@@ -471,14 +918,15 @@ function parseContent4Input(options) {
|
|
|
471
918
|
body
|
|
472
919
|
};
|
|
473
920
|
}
|
|
474
|
-
function parseInput(schema, body) {
|
|
475
|
-
const options = getTableOptions(schema, body);
|
|
921
|
+
function parseInput(schema, body, cache, templateShowHead) {
|
|
922
|
+
const options = getTableOptions(schema, body, cache);
|
|
476
923
|
const styles = parseStyles(options);
|
|
477
924
|
const settings = {
|
|
478
925
|
startY: options.startY,
|
|
479
926
|
margin: options.margin,
|
|
480
927
|
tableWidth: options.tableWidth,
|
|
481
928
|
showHead: options.showHead,
|
|
929
|
+
templateShowHead,
|
|
482
930
|
tableLineWidth: options.tableLineWidth ?? 0,
|
|
483
931
|
tableLineColor: options.tableLineColor ?? ""
|
|
484
932
|
};
|
|
@@ -498,14 +946,16 @@ function createSingleTable(body, args) {
|
|
|
498
946
|
schema.bodyStyles.alternateBackgroundColor = schema.bodyStyles.backgroundColor;
|
|
499
947
|
schema.bodyStyles.backgroundColor = alternateBackgroundColor;
|
|
500
948
|
}
|
|
949
|
+
const templateShowHead = schema.showHead !== false;
|
|
501
950
|
schema.showHead = schema.showHead === false ? false : !schema.__isSplit || schema.repeatHead === true;
|
|
502
|
-
const input = parseInput(schema, body);
|
|
951
|
+
const input = parseInput(schema, body, _cache, templateShowHead);
|
|
503
952
|
const font = options.font || getDefaultFont();
|
|
504
953
|
const content = parseContent4Table(input, getFallbackFontName(font));
|
|
505
954
|
return Table.create({
|
|
506
955
|
input,
|
|
507
956
|
content,
|
|
508
957
|
font,
|
|
958
|
+
basePdf,
|
|
509
959
|
_cache
|
|
510
960
|
});
|
|
511
961
|
}
|
|
@@ -750,9 +1200,11 @@ var getDynamicHeightsForTable = async (value, args) => {
|
|
|
750
1200
|
const initialPageIndex = Math.max(0, Math.floor((schema.position.y - paddingTop) / pageContentHeight));
|
|
751
1201
|
const headRowCount = schema.showHead ? table.head.length : 0;
|
|
752
1202
|
const SAFETY_MARGIN = .5;
|
|
1203
|
+
const EPSILON = .01;
|
|
753
1204
|
let currentPageIndex = initialPageIndex;
|
|
754
1205
|
let currentPageY = schema.position.y;
|
|
755
1206
|
let rowsOnCurrentPage = 0;
|
|
1207
|
+
let headerTravelsWithBody = false;
|
|
756
1208
|
const result = [];
|
|
757
1209
|
for (let i = 0; i < baseHeights.length; i++) {
|
|
758
1210
|
const isBodyRow = i >= headRowCount;
|
|
@@ -760,26 +1212,37 @@ var getDynamicHeightsForTable = async (value, args) => {
|
|
|
760
1212
|
while (true) {
|
|
761
1213
|
const currentPageStartY = getPageStartY(currentPageIndex);
|
|
762
1214
|
const remainingHeight = currentPageStartY + pageContentHeight - currentPageY;
|
|
763
|
-
const totalRowHeight = rowHeight + (isBodyRow && rowsOnCurrentPage === 0 && currentPageIndex > initialPageIndex ? headerHeight : 0);
|
|
764
|
-
if (totalRowHeight > remainingHeight - SAFETY_MARGIN) {
|
|
1215
|
+
const totalRowHeight = rowHeight + (isBodyRow && rowsOnCurrentPage === 0 && currentPageIndex > initialPageIndex && !headerTravelsWithBody ? headerHeight : 0);
|
|
1216
|
+
if (totalRowHeight > remainingHeight - SAFETY_MARGIN + EPSILON) {
|
|
765
1217
|
if (rowsOnCurrentPage === 0 && Math.abs(currentPageY - currentPageStartY) < SAFETY_MARGIN) {
|
|
766
1218
|
result.push(totalRowHeight);
|
|
767
1219
|
currentPageY += totalRowHeight;
|
|
768
1220
|
rowsOnCurrentPage++;
|
|
1221
|
+
headerTravelsWithBody = false;
|
|
769
1222
|
break;
|
|
770
1223
|
}
|
|
1224
|
+
const headerWouldBeAlone = !headerTravelsWithBody && currentPageIndex === initialPageIndex && isBodyRow && headRowCount > 0 && result.length === headRowCount && rowsOnCurrentPage === headRowCount;
|
|
771
1225
|
currentPageIndex++;
|
|
772
|
-
|
|
773
|
-
|
|
1226
|
+
if (headerWouldBeAlone) {
|
|
1227
|
+
headerTravelsWithBody = true;
|
|
1228
|
+
currentPageY = getPageStartY(currentPageIndex) + headerHeight;
|
|
1229
|
+
rowsOnCurrentPage = headRowCount;
|
|
1230
|
+
} else {
|
|
1231
|
+
headerTravelsWithBody = false;
|
|
1232
|
+
currentPageY = getPageStartY(currentPageIndex);
|
|
1233
|
+
rowsOnCurrentPage = 0;
|
|
1234
|
+
}
|
|
774
1235
|
continue;
|
|
775
1236
|
}
|
|
776
1237
|
result.push(totalRowHeight);
|
|
777
1238
|
currentPageY += totalRowHeight;
|
|
778
1239
|
rowsOnCurrentPage++;
|
|
1240
|
+
if (isBodyRow) headerTravelsWithBody = false;
|
|
779
1241
|
if (currentPageY >= currentPageStartY + pageContentHeight - SAFETY_MARGIN) {
|
|
780
1242
|
currentPageIndex++;
|
|
781
1243
|
currentPageY = getPageStartY(currentPageIndex);
|
|
782
1244
|
rowsOnCurrentPage = 0;
|
|
1245
|
+
headerTravelsWithBody = false;
|
|
783
1246
|
}
|
|
784
1247
|
break;
|
|
785
1248
|
}
|
|
@@ -803,6 +1266,6 @@ var getDynamicLayoutForTable = async (value, args) => {
|
|
|
803
1266
|
};
|
|
804
1267
|
};
|
|
805
1268
|
//#endregion
|
|
806
|
-
export { getCellPropPanelSchema as a, remapColumnStylesOnRemove as c, createSingleTable as d, getBodyWithSchemaRange as i, HEX_COLOR_PATTERN as l, getDynamicLayoutForTable as n, getColumnStylesPropPanelSchema as o, getBody as r, getDefaultCellStyles as s, getDynamicHeightsForTable as t, OPAQUE_HEX_COLOR_PATTERN as u };
|
|
1269
|
+
export { hashImageDataUrl as _, getCellPropPanelSchema as a, remapColumnStylesOnRemove as c, createSingleTable as d, getTableImageObjectPosition as f, normalizeImageOrientation as g, detectImageFormat as h, getBodyWithSchemaRange as i, HEX_COLOR_PATTERN as l, warnInvalidTableImageOnce as m, getDynamicLayoutForTable as n, getColumnStylesPropPanelSchema as o, resolveImageDimension as p, getBody as r, getDefaultCellStyles as s, getDynamicHeightsForTable as t, OPAQUE_HEX_COLOR_PATTERN as u };
|
|
807
1270
|
|
|
808
|
-
//# sourceMappingURL=dynamicTemplate-
|
|
1271
|
+
//# sourceMappingURL=dynamicTemplate-BJxwjEWl.js.map
|