@pdfme/schemas 6.1.1 → 6.1.2-dev.3

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 (60) hide show
  1. package/dist/box.d.ts +45 -0
  2. package/dist/{builtins-CWHhKSVA.js → builtins-BB2DHceW.js} +482 -548
  3. package/dist/builtins-BB2DHceW.js.map +1 -0
  4. package/dist/builtins.d.ts +1 -1
  5. package/dist/builtins.js +1 -1
  6. package/dist/checkbox/index.d.ts +2 -2
  7. package/dist/dynamicLayout.d.ts +4 -0
  8. package/dist/dynamicLayout.js +20 -0
  9. package/dist/dynamicLayout.js.map +1 -0
  10. package/dist/{dynamicTemplate-DmuRoTw4.js → dynamicTemplate-B4GCNLF9.js} +19 -53
  11. package/dist/dynamicTemplate-B4GCNLF9.js.map +1 -0
  12. package/dist/{lists-B6dmgpkS.js → dynamicTemplate-BwzF9C1L.js} +3 -6
  13. package/dist/dynamicTemplate-BwzF9C1L.js.map +1 -0
  14. package/dist/dynamicTemplate-C7MdZxPm.js +75 -0
  15. package/dist/dynamicTemplate-C7MdZxPm.js.map +1 -0
  16. package/dist/graphics/image.d.ts +1 -1
  17. package/dist/graphics/signature.d.ts +1 -1
  18. package/dist/helper-CEme39Uo.js +40 -0
  19. package/dist/helper-CEme39Uo.js.map +1 -0
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.js +268 -102
  22. package/dist/index.js.map +1 -1
  23. package/dist/list/types.d.ts +0 -5
  24. package/dist/lists.d.ts +2 -1
  25. package/dist/lists.js +3 -2
  26. package/dist/measure-L5diay3k.js +612 -0
  27. package/dist/measure-L5diay3k.js.map +1 -0
  28. package/dist/multiVariableText/dynamicTemplate.d.ts +2 -0
  29. package/dist/radioGroup/index.d.ts +2 -2
  30. package/dist/select/index.d.ts +2 -2
  31. package/dist/shapes/line.d.ts +1 -1
  32. package/dist/shapes/rectAndEllipse.d.ts +1 -2
  33. package/dist/{helper-M_MmV_d5.js → splitRange-DmVDtmzO.js} +132 -6
  34. package/dist/splitRange-DmVDtmzO.js.map +1 -0
  35. package/dist/splitRange.d.ts +16 -0
  36. package/dist/tables/helper.d.ts +12 -104
  37. package/dist/tables/types.d.ts +2 -6
  38. package/dist/tables.d.ts +1 -0
  39. package/dist/tables.js +3 -2
  40. package/dist/text/constants.d.ts +3 -0
  41. package/dist/text/dynamicTemplate.d.ts +2 -0
  42. package/dist/text/linkAnnotation.d.ts +14 -0
  43. package/dist/text/measure.d.ts +32 -0
  44. package/dist/text/overflow.d.ts +7 -0
  45. package/dist/text/richTextPdfRender.d.ts +3 -2
  46. package/dist/text/types.d.ts +7 -0
  47. package/dist/texts.d.ts +5 -0
  48. package/dist/texts.js +4 -0
  49. package/dist/types.d.ts +16 -0
  50. package/dist/types.js +0 -0
  51. package/dist/utils-zDZkqBnX.js +250 -0
  52. package/dist/utils-zDZkqBnX.js.map +1 -0
  53. package/dist/utils.d.ts +3 -0
  54. package/dist/utils.js +3 -215
  55. package/package.json +16 -1
  56. package/dist/builtins-CWHhKSVA.js.map +0 -1
  57. package/dist/dynamicTemplate-DmuRoTw4.js.map +0 -1
  58. package/dist/helper-M_MmV_d5.js.map +0 -1
  59. package/dist/lists-B6dmgpkS.js.map +0 -1
  60. package/dist/utils.js.map +0 -1
@@ -1,16 +1,11 @@
1
1
  import type { TextSchema } from '../text/types.js';
2
2
  export type LIST_STYLE = 'bullet' | 'ordered';
3
- export type ListRange = {
4
- start: number;
5
- end?: number;
6
- };
7
3
  export type ListSchema = TextSchema & {
8
4
  listStyle: LIST_STYLE;
9
5
  markerWidth: number;
10
6
  markerGap: number;
11
7
  indentSize?: number;
12
8
  itemSpacing: number;
13
- __itemRange?: ListRange;
14
9
  };
15
10
  export type ListItem = {
16
11
  text: string;
package/dist/lists.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { getDynamicLayoutForList } from './list/dynamicTemplate.js';
2
+ export { createListItemSplitRange, getListItemRange, LIST_ITEM_SPLIT_UNIT } from './splitRange.js';
2
3
  export { normalizeListItems, normalizeListItemEntries, serializeListItems, getListMarkers, calculateListLayout, } from './list/helper.js';
3
- export type { ListItem, ListSchema, ListLayout, ListItemLayout, ListRange, LIST_STYLE, } from './list/types.js';
4
+ export type { ListItem, ListSchema, ListLayout, ListItemLayout, LIST_STYLE } from './list/types.js';
package/dist/lists.js CHANGED
@@ -1,2 +1,3 @@
1
- import { a as normalizeListItems, i as normalizeListItemEntries, n as calculateListLayout, o as serializeListItems, r as getListMarkers, t as getDynamicLayoutForList } from "./lists-B6dmgpkS.js";
2
- export { calculateListLayout, getDynamicLayoutForList, getListMarkers, normalizeListItemEntries, normalizeListItems, serializeListItems };
1
+ import { a as createListItemSplitRange, c as getListItemRange, n as LIST_ITEM_SPLIT_UNIT } from "./splitRange-DmVDtmzO.js";
2
+ import { a as normalizeListItems, i as normalizeListItemEntries, n as calculateListLayout, o as serializeListItems, r as getListMarkers, t as getDynamicLayoutForList } from "./dynamicTemplate-BwzF9C1L.js";
3
+ export { LIST_ITEM_SPLIT_UNIT, calculateListLayout, createListItemSplitRange, getDynamicLayoutForList, getListItemRange, getListMarkers, normalizeListItemEntries, normalizeListItems, serializeListItems };
@@ -0,0 +1,612 @@
1
+ import { C as getBoxInsets, E as hasBoxDimension, M as CODE_HORIZONTAL_PADDING, T as getSplitBoxDimension, V as FONT_SIZE_ADJUSTMENT, d as calculateDynamicFontSize, g as heightOfFontAtSize, h as getFontKitFont, q as SYNTHETIC_BOLD_OFFSET_RATIO, u as getTextLineRange, v as splitTextToSize, w as getBoxVerticalInset, x as getBoxContentArea, y as widthOfTextAtSize } from "./splitRange-DmVDtmzO.js";
2
+ import { getDefaultFont, getFallbackFontName, mm2pt, normalizeLinkHref, pt2mm } from "@pdfme/common";
3
+ //#region src/text/inlineMarkdown.ts
4
+ var MARKDOWN_ESCAPABLE_CHARS = new Set([
5
+ "\\",
6
+ "*",
7
+ "~",
8
+ "`",
9
+ "[",
10
+ "]",
11
+ "(",
12
+ ")"
13
+ ]);
14
+ var MARKDOWN_ESCAPE_PATTERN = /[\\*~`[\]()]/g;
15
+ var MARKDOWN_UNESCAPE_PATTERN = /\\([\\*~`[\]()])/g;
16
+ var sameStyle = (a, b) => Boolean(a.bold) === Boolean(b.bold) && Boolean(a.italic) === Boolean(b.italic) && Boolean(a.strikethrough) === Boolean(b.strikethrough) && Boolean(a.code) === Boolean(b.code) && a.href === b.href;
17
+ var appendRun = (runs, text, style) => {
18
+ if (!text) return;
19
+ const lastRun = runs.at(-1);
20
+ if (lastRun && sameStyle(lastRun, style)) {
21
+ lastRun.text += text;
22
+ return;
23
+ }
24
+ runs.push({
25
+ text,
26
+ ...style.bold ? { bold: true } : {},
27
+ ...style.italic ? { italic: true } : {},
28
+ ...style.strikethrough ? { strikethrough: true } : {},
29
+ ...style.code ? { code: true } : {},
30
+ ...style.href ? { href: style.href } : {}
31
+ });
32
+ };
33
+ var findClosingDelimiter = (value, delimiter, from) => {
34
+ for (let i = from; i < value.length; i++) {
35
+ if (value[i] === "\\") {
36
+ i += 1;
37
+ continue;
38
+ }
39
+ if (delimiter !== "`" && value[i] === "`") {
40
+ const codeEnd = findClosingDelimiter(value, "`", i + 1);
41
+ if (codeEnd === -1) continue;
42
+ i = codeEnd;
43
+ continue;
44
+ }
45
+ if (value.startsWith(delimiter, i)) return i;
46
+ }
47
+ return -1;
48
+ };
49
+ var getDelimiter = (value, index) => {
50
+ if (value[index] === "`") return "`";
51
+ if (value.startsWith("***", index)) return "***";
52
+ if (value.startsWith("**", index)) return "**";
53
+ if (value.startsWith("~~", index)) return "~~";
54
+ if (value[index] === "*") return "*";
55
+ return "";
56
+ };
57
+ var findLinkLabelEnd = (value, from, to) => {
58
+ for (let index = from; index < to; index += 1) {
59
+ if (value[index] === "\\") {
60
+ index += 1;
61
+ continue;
62
+ }
63
+ if (value[index] === "]") return index;
64
+ }
65
+ return -1;
66
+ };
67
+ var findLinkDestinationEnd = (value, from, to) => {
68
+ let depth = 0;
69
+ for (let index = from; index < to; index += 1) {
70
+ if (value[index] === "\\") {
71
+ index += 1;
72
+ continue;
73
+ }
74
+ if (value[index] === "(") {
75
+ depth += 1;
76
+ continue;
77
+ }
78
+ if (value[index] === ")") {
79
+ if (depth === 0) return index;
80
+ depth -= 1;
81
+ }
82
+ }
83
+ return -1;
84
+ };
85
+ var parseLinkAt = (value, index, to) => {
86
+ if (value[index] !== "[") return void 0;
87
+ const labelEnd = findLinkLabelEnd(value, index + 1, to);
88
+ if (labelEnd === -1 || value[labelEnd + 1] !== "(") return void 0;
89
+ const destinationStart = labelEnd + 2;
90
+ const destinationEnd = findLinkDestinationEnd(value, destinationStart, to);
91
+ if (destinationEnd === -1) return void 0;
92
+ const safeHref = normalizeLinkHref(value.slice(destinationStart, destinationEnd).replace(MARKDOWN_UNESCAPE_PATTERN, "$1"));
93
+ if (!safeHref) return void 0;
94
+ return {
95
+ labelStart: index + 1,
96
+ labelEnd,
97
+ href: safeHref,
98
+ end: destinationEnd + 1
99
+ };
100
+ };
101
+ var mergeStyle = (style, delimiter) => {
102
+ if (delimiter === "***") return {
103
+ ...style,
104
+ bold: true,
105
+ italic: true
106
+ };
107
+ if (delimiter === "**") return {
108
+ ...style,
109
+ bold: true
110
+ };
111
+ if (delimiter === "*") return {
112
+ ...style,
113
+ italic: true
114
+ };
115
+ if (delimiter === "~~") return {
116
+ ...style,
117
+ strikethrough: true
118
+ };
119
+ return style;
120
+ };
121
+ var parseRange = (value, from, to, style) => {
122
+ const runs = [];
123
+ let buffer = "";
124
+ const flush = () => {
125
+ appendRun(runs, buffer, style);
126
+ buffer = "";
127
+ };
128
+ for (let index = from; index < to; index++) {
129
+ const char = value[index];
130
+ if (char === "\\" && index + 1 < to && MARKDOWN_ESCAPABLE_CHARS.has(value[index + 1])) {
131
+ buffer += value[index + 1];
132
+ index += 1;
133
+ continue;
134
+ }
135
+ const link = style.href ? void 0 : parseLinkAt(value, index, to);
136
+ if (link) {
137
+ flush();
138
+ parseRange(value, link.labelStart, link.labelEnd, {
139
+ ...style,
140
+ href: link.href
141
+ }).forEach((run) => appendRun(runs, run.text, run));
142
+ index = link.end - 1;
143
+ continue;
144
+ }
145
+ const delimiter = getDelimiter(value, index);
146
+ if (!delimiter) {
147
+ buffer += char;
148
+ continue;
149
+ }
150
+ const closingIndex = findClosingDelimiter(value, delimiter, index + delimiter.length);
151
+ if (closingIndex === -1 || closingIndex + delimiter.length > to) {
152
+ buffer += char;
153
+ continue;
154
+ }
155
+ flush();
156
+ if (delimiter === "`") appendRun(runs, value.slice(index + 1, closingIndex).replace(MARKDOWN_UNESCAPE_PATTERN, "$1"), {
157
+ ...style,
158
+ code: true
159
+ });
160
+ else parseRange(value, index + delimiter.length, closingIndex, mergeStyle(style, delimiter)).forEach((run) => appendRun(runs, run.text, run));
161
+ index = closingIndex + delimiter.length - 1;
162
+ }
163
+ flush();
164
+ return runs;
165
+ };
166
+ var parseInlineMarkdown = (value) => {
167
+ if (!value) return [];
168
+ return parseRange(value, 0, value.length, {});
169
+ };
170
+ var escapeInlineMarkdown = (value) => value.replace(MARKDOWN_ESCAPE_PATTERN, (char) => `\\${char}`);
171
+ var stripInlineMarkdown = (value) => parseInlineMarkdown(value).map((run) => run.text).join("");
172
+ //#endregion
173
+ //#region src/text/richText.ts
174
+ var richTextWordSegmenter = new Intl.Segmenter(void 0, { granularity: "word" });
175
+ var richTextGraphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
176
+ var getBaseFontName = (schema, font) => schema.fontName && font[schema.fontName] ? schema.fontName : getFallbackFontName(font);
177
+ var getLoadedFontName = (font, fontName) => fontName && font[fontName] ? fontName : void 0;
178
+ var isInlineMarkdownTextSchema = (schema) => schema.textFormat === "inline-markdown" && !(schema.type === "text" && schema.readOnly !== true);
179
+ var resolveFontVariant = (run, schema, font) => {
180
+ const baseFontName = getBaseFontName(schema, font);
181
+ const variants = schema.fontVariants ?? {};
182
+ const fallback = schema.fontVariantFallback ?? "synthetic";
183
+ let fontName = baseFontName;
184
+ let needsBold = Boolean(run.bold);
185
+ let needsItalic = Boolean(run.italic);
186
+ if (run.code) fontName = getLoadedFontName(font, variants.code) ?? baseFontName;
187
+ else if (run.bold && run.italic) {
188
+ const boldItalic = getLoadedFontName(font, variants.boldItalic);
189
+ const italic = getLoadedFontName(font, variants.italic);
190
+ const bold = getLoadedFontName(font, variants.bold);
191
+ if (boldItalic) {
192
+ fontName = boldItalic;
193
+ needsBold = false;
194
+ needsItalic = false;
195
+ } else if (italic) {
196
+ fontName = italic;
197
+ needsItalic = false;
198
+ } else if (bold) {
199
+ fontName = bold;
200
+ needsBold = false;
201
+ }
202
+ } else if (run.bold) {
203
+ const bold = getLoadedFontName(font, variants.bold);
204
+ if (bold) {
205
+ fontName = bold;
206
+ needsBold = false;
207
+ }
208
+ } else if (run.italic) {
209
+ const italic = getLoadedFontName(font, variants.italic);
210
+ if (italic) {
211
+ fontName = italic;
212
+ needsItalic = false;
213
+ }
214
+ }
215
+ if ((needsBold || needsItalic || run.code && !getLoadedFontName(font, variants.code)) && fallback === "error") throw new Error(`[@pdfme/schemas] Missing font variant for markdown text in field "${schema.name}".`);
216
+ return {
217
+ fontName,
218
+ syntheticBold: fallback !== "plain" && needsBold,
219
+ syntheticItalic: fallback !== "plain" && needsItalic
220
+ };
221
+ };
222
+ var resolveRichTextRuns = async (arg) => {
223
+ const { runs, schema, font, _cache } = arg;
224
+ const fontKitCache = /* @__PURE__ */ new Map();
225
+ const getResolvedFontKitFont = async (fontName) => {
226
+ const cached = fontKitCache.get(fontName);
227
+ if (cached) return cached;
228
+ const fontKitFont = await getFontKitFont(fontName, font, _cache);
229
+ fontKitCache.set(fontName, fontKitFont);
230
+ return fontKitFont;
231
+ };
232
+ return Promise.all(runs.map(async (run) => {
233
+ const resolution = resolveFontVariant(run, schema, font);
234
+ return {
235
+ ...run,
236
+ ...resolution,
237
+ fontKitFont: await getResolvedFontKitFont(resolution.fontName)
238
+ };
239
+ }));
240
+ };
241
+ var measureRunText = (run, text, fontSize, characterSpacing) => {
242
+ const syntheticBoldWidth = run.syntheticBold ? fontSize * SYNTHETIC_BOLD_OFFSET_RATIO * 2 : 0;
243
+ const syntheticItalicWidth = run.syntheticItalic ? heightOfFontAtSize(run.fontKitFont, fontSize) * Math.tan(12 * Math.PI / 180) : 0;
244
+ return widthOfTextAtSize(text, run.fontKitFont, fontSize, characterSpacing) + syntheticBoldWidth + syntheticItalicWidth + (run.code ? CODE_HORIZONTAL_PADDING * 2 : 0);
245
+ };
246
+ var createLine = () => ({
247
+ runs: [],
248
+ width: 0,
249
+ hardBreak: false
250
+ });
251
+ var pushRunToLine = (line, run, text, fontSize, characterSpacing) => {
252
+ if (!text) return;
253
+ const width = measureRunText(run, text, fontSize, characterSpacing);
254
+ const lastRun = line.runs[line.runs.length - 1];
255
+ if (lastRun && canMergeRichTextRuns(lastRun, run)) {
256
+ const previousWidth = lastRun.width;
257
+ lastRun.text += text;
258
+ lastRun.width = measureRunText(lastRun, lastRun.text, fontSize, characterSpacing);
259
+ line.width += lastRun.width - previousWidth;
260
+ return;
261
+ }
262
+ if (line.runs.length > 0) line.width += characterSpacing;
263
+ line.runs.push({
264
+ ...run,
265
+ text,
266
+ width
267
+ });
268
+ line.width += width;
269
+ };
270
+ var canMergeRichTextRuns = (a, b) => a.fontName === b.fontName && a.fontKitFont === b.fontKitFont && a.syntheticBold === b.syntheticBold && a.syntheticItalic === b.syntheticItalic && a.bold === b.bold && a.italic === b.italic && a.strikethrough === b.strikethrough && a.code === b.code && a.href === b.href;
271
+ var measurePiecesWidth = (pieces, fontSize, characterSpacing) => {
272
+ let width = 0;
273
+ let hasText = false;
274
+ pieces.forEach((piece) => {
275
+ if (!piece.text) return;
276
+ if (hasText) width += characterSpacing;
277
+ width += measureRunText(piece.run, piece.text, fontSize, characterSpacing);
278
+ hasText = true;
279
+ });
280
+ return width;
281
+ };
282
+ var sliceRunPieces = (pieces, startIndex, endIndex) => {
283
+ const result = [];
284
+ let offset = 0;
285
+ pieces.forEach((piece) => {
286
+ const pieceStart = offset;
287
+ const pieceEnd = pieceStart + piece.text.length;
288
+ const sliceStart = Math.max(startIndex, pieceStart);
289
+ const sliceEnd = Math.min(endIndex, pieceEnd);
290
+ if (sliceStart < sliceEnd) result.push({
291
+ run: piece.run,
292
+ text: piece.text.slice(sliceStart - pieceStart, sliceEnd - pieceStart)
293
+ });
294
+ offset = pieceEnd;
295
+ });
296
+ return result;
297
+ };
298
+ var segmentRunPiecesByWord = (runs, onSegment, onHardBreak) => {
299
+ let paragraphPieces = [];
300
+ const flushParagraph = () => {
301
+ if (paragraphPieces.length === 0) return;
302
+ const paragraphText = paragraphPieces.map((piece) => piece.text).join("");
303
+ Array.from(richTextWordSegmenter.segment(paragraphText), ({ segment, index }) => {
304
+ const pieces = sliceRunPieces(paragraphPieces, index, index + segment.length);
305
+ if (pieces.length > 0) onSegment(pieces);
306
+ });
307
+ paragraphPieces = [];
308
+ };
309
+ runs.forEach((run) => {
310
+ run.text.split(/(\r\n|\r|\n)/).forEach((part) => {
311
+ if (part === "\r\n" || part === "\r" || part === "\n") {
312
+ flushParagraph();
313
+ onHardBreak();
314
+ return;
315
+ }
316
+ if (part) paragraphPieces.push({
317
+ run,
318
+ text: part
319
+ });
320
+ });
321
+ });
322
+ flushParagraph();
323
+ };
324
+ var splitIntoGraphemes = (value) => Array.from(richTextGraphemeSegmenter.segment(value), ({ segment }) => segment);
325
+ var countRichTextLineGraphemes = (line) => splitIntoGraphemes(line.runs.map((run) => run.text).join("")).length;
326
+ var layoutRichTextLines = (arg) => {
327
+ const { runs, fontSize, characterSpacing, boxWidthInPt } = arg;
328
+ const lines = [];
329
+ let currentLine = createLine();
330
+ const pushCurrentLine = (hardBreak) => {
331
+ currentLine.hardBreak = hardBreak;
332
+ lines.push(currentLine);
333
+ currentLine = createLine();
334
+ };
335
+ const pushPiecesToLine = (pieces) => {
336
+ pieces.forEach((piece) => {
337
+ pushRunToLine(currentLine, piece.run, piece.text, fontSize, characterSpacing);
338
+ });
339
+ };
340
+ const pushOversizedText = (run, text) => {
341
+ let remainingText = text;
342
+ while (remainingText.length > 0) {
343
+ const pendingSpacing = currentLine.runs.length > 0 ? characterSpacing : 0;
344
+ const remainingWidth = Math.max(boxWidthInPt - currentLine.width - pendingSpacing, 0);
345
+ const remainingTextWidth = measureRunText(run, remainingText, fontSize, characterSpacing);
346
+ if (remainingTextWidth <= remainingWidth || currentLine.runs.length === 0 && remainingTextWidth <= boxWidthInPt) {
347
+ pushRunToLine(currentLine, run, remainingText, fontSize, characterSpacing);
348
+ return;
349
+ }
350
+ if (currentLine.runs.length > 0 && remainingTextWidth <= boxWidthInPt) {
351
+ pushCurrentLine(false);
352
+ continue;
353
+ }
354
+ const graphemes = splitIntoGraphemes(remainingText);
355
+ let fittingText = "";
356
+ let fittingLength = 0;
357
+ for (const grapheme of graphemes) {
358
+ const candidate = fittingText + grapheme;
359
+ const candidateWidth = measureRunText(run, candidate, fontSize, characterSpacing);
360
+ const maxWidth = currentLine.runs.length === 0 ? boxWidthInPt : remainingWidth;
361
+ if (candidateWidth > maxWidth) {
362
+ if (fittingText) break;
363
+ if (currentLine.runs.length > 0) break;
364
+ }
365
+ fittingText = candidate;
366
+ fittingLength += grapheme.length;
367
+ if (candidateWidth > maxWidth) break;
368
+ }
369
+ if (!fittingText) {
370
+ pushCurrentLine(false);
371
+ continue;
372
+ }
373
+ pushRunToLine(currentLine, run, fittingText, fontSize, characterSpacing);
374
+ remainingText = remainingText.slice(fittingLength);
375
+ if (remainingText.length > 0) pushCurrentLine(false);
376
+ }
377
+ };
378
+ const pushSegment = (pieces) => {
379
+ const segmentWidth = measurePiecesWidth(pieces, fontSize, characterSpacing);
380
+ const pendingSpacing = currentLine.runs.length > 0 ? characterSpacing : 0;
381
+ if (segmentWidth <= Math.max(boxWidthInPt - currentLine.width - pendingSpacing, 0) || currentLine.runs.length === 0 && segmentWidth <= boxWidthInPt) {
382
+ pushPiecesToLine(pieces);
383
+ return;
384
+ }
385
+ if (currentLine.runs.length > 0) {
386
+ pushCurrentLine(false);
387
+ if (segmentWidth <= boxWidthInPt) {
388
+ pushPiecesToLine(pieces);
389
+ return;
390
+ }
391
+ }
392
+ pieces.forEach((piece) => pushOversizedText(piece.run, piece.text));
393
+ };
394
+ segmentRunPiecesByWord(runs, pushSegment, () => pushCurrentLine(true));
395
+ if (currentLine.runs.length > 0 || lines.length === 0) pushCurrentLine(false);
396
+ return lines;
397
+ };
398
+ var measureParagraphWidths = (runs, fontSize, characterSpacing) => {
399
+ const widths = [];
400
+ let paragraphPieces = [];
401
+ const pushWidth = () => {
402
+ widths.push(measurePiecesWidth(paragraphPieces, fontSize, characterSpacing));
403
+ paragraphPieces = [];
404
+ };
405
+ runs.forEach((run) => {
406
+ run.text.split(/(\r\n|\r|\n)/).forEach((part) => {
407
+ if (part === "\r\n" || part === "\r" || part === "\n") {
408
+ pushWidth();
409
+ return;
410
+ }
411
+ if (part) paragraphPieces.push({
412
+ run,
413
+ text: part
414
+ });
415
+ });
416
+ });
417
+ pushWidth();
418
+ return widths;
419
+ };
420
+ var getLineHeightAtSize = (line, fontSize) => {
421
+ if (line.runs.length === 0) return fontSize;
422
+ return Math.max(...line.runs.map((run) => heightOfFontAtSize(run.fontKitFont, fontSize)));
423
+ };
424
+ var calculateDynamicRichTextFontSize = async (arg) => {
425
+ const { value, schema, font, _cache, startingFontSize } = arg;
426
+ const { fontSize: schemaFontSize, dynamicFontSize: dynamicFontSizeSetting, characterSpacing: schemaCharacterSpacing, lineHeight = 1 } = schema;
427
+ const { width: boxWidth, height: boxHeight } = getBoxContentArea(schema);
428
+ const fontSize = startingFontSize || schemaFontSize || 13;
429
+ if (!dynamicFontSizeSetting) return fontSize;
430
+ if (dynamicFontSizeSetting.max < dynamicFontSizeSetting.min) return fontSize;
431
+ const resolvedRuns = await resolveRichTextRuns({
432
+ runs: parseInlineMarkdown(value),
433
+ schema,
434
+ font,
435
+ _cache
436
+ });
437
+ const characterSpacing = schemaCharacterSpacing ?? 0;
438
+ const dynamicFontFit = dynamicFontSizeSetting.fit ?? "vertical";
439
+ const boxWidthInPt = mm2pt(boxWidth);
440
+ let dynamicFontSize = fontSize;
441
+ if (dynamicFontSize < dynamicFontSizeSetting.min) dynamicFontSize = dynamicFontSizeSetting.min;
442
+ else if (dynamicFontSize > dynamicFontSizeSetting.max) dynamicFontSize = dynamicFontSizeSetting.max;
443
+ const calculateConstraints = (size) => {
444
+ let totalWidthInMm = 0;
445
+ let totalHeightInMm = 0;
446
+ layoutRichTextLines({
447
+ runs: resolvedRuns,
448
+ fontSize: size,
449
+ characterSpacing,
450
+ boxWidthInPt
451
+ }).forEach((line, lineIndex) => {
452
+ if (dynamicFontFit === "vertical") totalWidthInMm = Math.max(totalWidthInMm, pt2mm(line.width));
453
+ if (lineIndex === 0) totalHeightInMm += pt2mm(getLineHeightAtSize(line, size) * lineHeight);
454
+ else totalHeightInMm += pt2mm(size * lineHeight);
455
+ });
456
+ if (dynamicFontFit === "horizontal") measureParagraphWidths(resolvedRuns, size, characterSpacing).forEach((paragraphWidth) => {
457
+ totalWidthInMm = Math.max(totalWidthInMm, pt2mm(paragraphWidth));
458
+ });
459
+ return {
460
+ totalWidthInMm,
461
+ totalHeightInMm
462
+ };
463
+ };
464
+ const shouldFontGrowToFit = (totalWidthInMm, totalHeightInMm) => {
465
+ if (dynamicFontSize >= dynamicFontSizeSetting.max) return false;
466
+ if (dynamicFontFit === "horizontal") return totalWidthInMm < boxWidth;
467
+ return totalHeightInMm < boxHeight;
468
+ };
469
+ const shouldFontShrinkToFit = (totalWidthInMm, totalHeightInMm) => {
470
+ if (dynamicFontSize <= dynamicFontSizeSetting.min || dynamicFontSize <= 0) return false;
471
+ return totalWidthInMm > boxWidth || totalHeightInMm > boxHeight;
472
+ };
473
+ let { totalWidthInMm, totalHeightInMm } = calculateConstraints(dynamicFontSize);
474
+ while (shouldFontGrowToFit(totalWidthInMm, totalHeightInMm)) {
475
+ dynamicFontSize += FONT_SIZE_ADJUSTMENT;
476
+ const { totalWidthInMm: newWidth, totalHeightInMm: newHeight } = calculateConstraints(dynamicFontSize);
477
+ if (newHeight < boxHeight) {
478
+ totalWidthInMm = newWidth;
479
+ totalHeightInMm = newHeight;
480
+ } else {
481
+ dynamicFontSize -= FONT_SIZE_ADJUSTMENT;
482
+ break;
483
+ }
484
+ }
485
+ while (shouldFontShrinkToFit(totalWidthInMm, totalHeightInMm)) {
486
+ dynamicFontSize -= FONT_SIZE_ADJUSTMENT;
487
+ ({totalWidthInMm, totalHeightInMm} = calculateConstraints(dynamicFontSize));
488
+ }
489
+ return dynamicFontSize;
490
+ };
491
+ //#endregion
492
+ //#region src/text/measure.ts
493
+ var applyTextLineRange = (lines, range) => {
494
+ if (!range) return lines;
495
+ return lines.slice(range.start, range.end ?? lines.length);
496
+ };
497
+ var plainTextLinesToValue = (lines) => lines.map((line) => line.replace(/[\r\n]+$/g, "")).join("\n");
498
+ var splitReplacementTextToLines = (value) => {
499
+ const lines = [];
500
+ let start = 0;
501
+ for (let i = 0; i < value.length; i += 1) {
502
+ const charCode = value.charCodeAt(i);
503
+ if (charCode !== 10 && charCode !== 13) continue;
504
+ lines.push(value.slice(start, i));
505
+ if (charCode === 13 && value.charCodeAt(i + 1) === 10) i += 1;
506
+ start = i + 1;
507
+ }
508
+ lines.push(value.slice(start));
509
+ return lines;
510
+ };
511
+ var measureTextLines = async ({ value, schema, font = getDefaultFont(), _cache = /* @__PURE__ */ new Map(), ignoreDynamicFontSize = false }) => {
512
+ const fontSize = schema.fontSize ?? 13;
513
+ const lineHeight = schema.lineHeight ?? 1;
514
+ const characterSpacing = schema.characterSpacing ?? 0;
515
+ const boxWidthInPt = mm2pt(getBoxContentArea(schema).width);
516
+ if (isInlineMarkdownTextSchema(schema)) {
517
+ const resolvedRuns = await resolveRichTextRuns({
518
+ runs: parseInlineMarkdown(value),
519
+ schema,
520
+ font,
521
+ _cache
522
+ });
523
+ const resolvedFontSize = schema.dynamicFontSize && schema.height > 0 && !ignoreDynamicFontSize ? await calculateDynamicRichTextFontSize({
524
+ value,
525
+ schema,
526
+ font,
527
+ _cache
528
+ }) : fontSize;
529
+ const lines = layoutRichTextLines({
530
+ runs: resolvedRuns,
531
+ fontSize: resolvedFontSize,
532
+ characterSpacing,
533
+ boxWidthInPt
534
+ });
535
+ return {
536
+ lines: lines.map((line) => line.runs.map((run) => run.text).join("")),
537
+ lineHeights: measureRichTextLineHeights(lines, resolvedFontSize, lineHeight)
538
+ };
539
+ }
540
+ const fontKitFont = await getFontKitFont(schema.fontName, font, _cache);
541
+ const resolvedFontSize = schema.dynamicFontSize && schema.height > 0 && !ignoreDynamicFontSize ? calculateDynamicFontSize({
542
+ textSchema: schema,
543
+ fontKitFont,
544
+ value
545
+ }) : fontSize;
546
+ const lines = splitTextToSize({
547
+ value,
548
+ characterSpacing,
549
+ fontSize: resolvedFontSize,
550
+ fontKitFont,
551
+ boxWidthInPt
552
+ });
553
+ return {
554
+ lines,
555
+ lineHeights: measurePlainTextLineHeights(lines, fontKitFont, resolvedFontSize, lineHeight)
556
+ };
557
+ };
558
+ var mergeTextLineRangeValue = async ({ value, replacement, schema, font = getDefaultFont(), _cache = /* @__PURE__ */ new Map() }) => {
559
+ const range = getTextLineRange(schema);
560
+ if (!range) return replacement;
561
+ const { lines } = await measureTextLines({
562
+ value,
563
+ schema,
564
+ font,
565
+ _cache,
566
+ ignoreDynamicFontSize: true
567
+ });
568
+ const { start, end = lines.length } = range;
569
+ const nextLines = [...lines];
570
+ nextLines.splice(start, end - start, ...splitReplacementTextToLines(replacement));
571
+ return plainTextLinesToValue(nextLines);
572
+ };
573
+ var measureTextHeight = async (args) => {
574
+ const { lineHeights } = await measureTextLines(args);
575
+ return sumLineHeights(lineHeights) + getBoxVerticalInset(args.schema);
576
+ };
577
+ var sumLineHeights = (lineHeights) => lineHeights.reduce((sum, height) => sum + height, 0);
578
+ var getTextLineHeightsWithBox = (lineHeights, schema) => lineHeights.map((height, index) => height + getTextBoxVerticalInsetForRange(schema, {
579
+ start: index,
580
+ end: index + 1
581
+ }, lineHeights.length));
582
+ var getTextSplitBoxStyle = (schema, range, totalLines) => {
583
+ const { borderWidth, padding } = getBoxInsets(schema);
584
+ return {
585
+ ...hasBoxDimension(schema.borderWidth) ? { borderWidth: getSplitBoxDimension(borderWidth, range, totalLines) } : {},
586
+ ...hasBoxDimension(schema.padding) ? { padding: getSplitBoxDimension(padding, range, totalLines) } : {}
587
+ };
588
+ };
589
+ var getTextBoxVerticalInsetForRange = (schema, range, totalLines) => {
590
+ const { borderWidth, padding } = getBoxInsets(schema);
591
+ const splitBorderWidth = getSplitBoxDimension(borderWidth, range, totalLines);
592
+ const splitPadding = getSplitBoxDimension(padding, range, totalLines);
593
+ return splitBorderWidth.top + splitBorderWidth.bottom + splitPadding.top + splitPadding.bottom;
594
+ };
595
+ var measurePlainTextLineHeights = (lines, fontKitFont, fontSize, lineHeight) => {
596
+ if (lines.length === 0) return [];
597
+ const firstLineHeight = heightOfFontAtSize(fontKitFont, fontSize) * lineHeight;
598
+ const otherLineHeight = fontSize * lineHeight;
599
+ return lines.map((_, index) => pt2mm(index === 0 ? firstLineHeight : otherLineHeight));
600
+ };
601
+ var measureRichTextLineHeights = (lines, fontSize, lineHeight) => {
602
+ if (lines.length === 0) return [];
603
+ return lines.map((line, index) => pt2mm((index === 0 ? getRichTextLineHeight(line, fontSize) : fontSize) * lineHeight));
604
+ };
605
+ var getRichTextLineHeight = (line, fontSize) => {
606
+ if (line.runs.length === 0) return fontSize;
607
+ return Math.max(...line.runs.map((run) => heightOfFontAtSize(run.fontKitFont, fontSize)));
608
+ };
609
+ //#endregion
610
+ export { stripInlineMarkdown as _, measureTextLines as a, sumLineHeights as c, isInlineMarkdownTextSchema as d, layoutRichTextLines as f, parseInlineMarkdown as g, escapeInlineMarkdown as h, measureTextHeight as i, calculateDynamicRichTextFontSize as l, resolveRichTextRuns as m, getTextLineHeightsWithBox as n, mergeTextLineRangeValue as o, resolveFontVariant as p, getTextSplitBoxStyle as r, plainTextLinesToValue as s, applyTextLineRange as t, countRichTextLineGraphemes as u };
611
+
612
+ //# sourceMappingURL=measure-L5diay3k.js.map