@pdfme/schemas 6.1.0 → 6.1.1-dev.11

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 (62) hide show
  1. package/dist/{builtins-C0BvXHWr.js → builtins-Clh58o_b.js} +313 -483
  2. package/dist/builtins-Clh58o_b.js.map +1 -0
  3. package/dist/builtins.d.ts +1 -1
  4. package/dist/builtins.js +1 -1
  5. package/dist/checkbox/index.d.ts +2 -2
  6. package/dist/dynamicLayout.d.ts +4 -0
  7. package/dist/dynamicLayout.js +20 -0
  8. package/dist/dynamicLayout.js.map +1 -0
  9. package/dist/dynamicTemplate-CB2Hj9cN.js +65 -0
  10. package/dist/dynamicTemplate-CB2Hj9cN.js.map +1 -0
  11. package/dist/{dynamicTemplate-Dsrw11aL.js → dynamicTemplate-CjbGepw4.js} +24 -358
  12. package/dist/dynamicTemplate-CjbGepw4.js.map +1 -0
  13. package/dist/dynamicTemplate-Fn7mpUsu.js +114 -0
  14. package/dist/dynamicTemplate-Fn7mpUsu.js.map +1 -0
  15. package/dist/graphics/image.d.ts +1 -1
  16. package/dist/graphics/signature.d.ts +1 -1
  17. package/dist/helper-BJzBqIT4.js +40 -0
  18. package/dist/helper-BJzBqIT4.js.map +1 -0
  19. package/dist/index.d.ts +5 -2
  20. package/dist/index.js +847 -205
  21. package/dist/index.js.map +1 -1
  22. package/dist/list/constants.d.ts +10 -0
  23. package/dist/list/dynamicTemplate.d.ts +2 -0
  24. package/dist/list/helper.d.ts +15 -0
  25. package/dist/list/index.d.ts +4 -0
  26. package/dist/list/pdfRender.d.ts +3 -0
  27. package/dist/list/propPanel.d.ts +3 -0
  28. package/dist/list/types.d.ts +31 -0
  29. package/dist/list/uiRender.d.ts +3 -0
  30. package/dist/lists.d.ts +4 -0
  31. package/dist/lists.js +3 -0
  32. package/dist/measure-Bjmh9Ro3.js +585 -0
  33. package/dist/measure-Bjmh9Ro3.js.map +1 -0
  34. package/dist/multiVariableText/dynamicTemplate.d.ts +2 -0
  35. package/dist/radioGroup/index.d.ts +2 -2
  36. package/dist/select/index.d.ts +2 -2
  37. package/dist/shapes/line.d.ts +1 -1
  38. package/dist/shapes/rectAndEllipse.d.ts +1 -2
  39. package/dist/splitRange-CpXivbmJ.js +398 -0
  40. package/dist/splitRange-CpXivbmJ.js.map +1 -0
  41. package/dist/splitRange.d.ts +16 -0
  42. package/dist/tables/dynamicTemplate.d.ts +2 -1
  43. package/dist/tables/helper.d.ts +8 -8
  44. package/dist/tables.d.ts +2 -1
  45. package/dist/tables.js +3 -2
  46. package/dist/text/constants.d.ts +3 -0
  47. package/dist/text/dynamicTemplate.d.ts +2 -0
  48. package/dist/text/linkAnnotation.d.ts +14 -0
  49. package/dist/text/measure.d.ts +26 -0
  50. package/dist/text/overflow.d.ts +7 -0
  51. package/dist/text/richTextPdfRender.d.ts +2 -1
  52. package/dist/text/types.d.ts +3 -0
  53. package/dist/texts.d.ts +5 -0
  54. package/dist/texts.js +4 -0
  55. package/dist/types.d.ts +15 -0
  56. package/dist/types.js +0 -0
  57. package/dist/utils.d.ts +1 -0
  58. package/dist/utils.js +3 -2
  59. package/dist/utils.js.map +1 -1
  60. package/package.json +21 -1
  61. package/dist/builtins-C0BvXHWr.js.map +0 -1
  62. package/dist/dynamicTemplate-Dsrw11aL.js.map +0 -1
@@ -1,436 +1,52 @@
1
- import { A as FONT_SIZE_ADJUSTMENT, B as VERTICAL_ALIGN_MIDDLE, C as DEFAULT_ALIGNMENT, D as DEFAULT_TEXT_FORMAT, E as DEFAULT_FONT_VARIANT_FALLBACK, F as SYNTHETIC_BOLD_CSS_TEXT_SHADOW, I as SYNTHETIC_BOLD_OFFSET_RATIO, L as TEXT_FORMAT_INLINE_MARKDOWN, M as FONT_VARIANT_FALLBACK_PLAIN, N as FONT_VARIANT_FALLBACK_SYNTHETIC, O as DYNAMIC_FIT_HORIZONTAL, P as PLACEHOLDER_FONT_COLOR, R as TEXT_FORMAT_PLAIN, S as CODE_HORIZONTAL_PADDING, T as DEFAULT_FONT_COLOR, _ as widthOfTextAtSize, b as ALIGN_RIGHT, d as getBrowserVerticalFontAdjustments, f as getFontDescentInPt, g as splitTextToSize, h as isFirefox, j as FONT_VARIANT_FALLBACK_ERROR, k as DYNAMIC_FIT_VERTICAL, l as calculateDynamicFontSize, m as heightOfFontAtSize, p as getFontKitFont, s as HEX_COLOR_PATTERN, u as fetchRemoteFontData, v as ALIGN_CENTER, w as DEFAULT_DYNAMIC_FIT, x as CODE_BACKGROUND_COLOR, y as ALIGN_JUSTIFY, z as VERTICAL_ALIGN_BOTTOM } from "./dynamicTemplate-Dsrw11aL.js";
1
+ import { A as DEFAULT_TEXT_FORMAT, B as SYNTHETIC_BOLD_OFFSET_RATIO, C as ALIGN_RIGHT, D as DEFAULT_DYNAMIC_FIT, E as DEFAULT_ALIGNMENT, F as FONT_VARIANT_FALLBACK_ERROR, G as VERTICAL_ALIGN_BOTTOM, H as TEXT_FORMAT_PLAIN, I as FONT_VARIANT_FALLBACK_PLAIN, K as VERTICAL_ALIGN_MIDDLE, L as FONT_VARIANT_FALLBACK_SYNTHETIC, M as DYNAMIC_FIT_HORIZONTAL, N as DYNAMIC_FIT_VERTICAL, O as DEFAULT_FONT_COLOR, R as PLACEHOLDER_FONT_COLOR, T as CODE_HORIZONTAL_PADDING, U as TEXT_OVERFLOW_EXPAND, V as TEXT_FORMAT_INLINE_MARKDOWN, W as TEXT_OVERFLOW_VISIBLE, _ as isFirefox, b as ALIGN_CENTER, d as calculateDynamicFontSize, f as fetchRemoteFontData, g as heightOfFontAtSize, h as getFontKitFont, j as DEFAULT_TEXT_OVERFLOW, k as DEFAULT_FONT_VARIANT_FALLBACK, m as getFontDescentInPt, p as getBrowserVerticalFontAdjustments, u as getTextLineRange, v as splitTextToSize, w as CODE_BACKGROUND_COLOR, x as ALIGN_JUSTIFY, y as widthOfTextAtSize, z as SYNTHETIC_BOLD_CSS_TEXT_SHADOW } from "./splitRange-CpXivbmJ.js";
2
+ import { a as plainTextLinesToValue, c as countRichTextLineGraphemes, f as resolveRichTextRuns, h as stripInlineMarkdown, l as isInlineMarkdownTextSchema, m as parseInlineMarkdown, s as calculateDynamicRichTextFontSize, t as applyTextLineRange, u as layoutRichTextLines } from "./measure-Bjmh9Ro3.js";
3
+ import { c as HEX_COLOR_PATTERN } from "./dynamicTemplate-CjbGepw4.js";
2
4
  import { convertForPdfLayoutProps, createSvgStr, hex2PrintingColor, isEditable, rotatePoint } from "./utils.js";
3
- import { DEFAULT_FONT_NAME, getDefaultFont, getFallbackFontName, mm2pt, pt2mm } from "@pdfme/common";
5
+ import { DEFAULT_FONT_NAME, getDefaultFont, getFallbackFontName, getInternalLinkTarget, isBlankPdf, mm2pt, normalizeLinkHref, normalizeSafeLinkUri, registerInternalLinkAnnotation } from "@pdfme/common";
6
+ import { PDFName, PDFString } from "@pdfme/pdf-lib";
4
7
  import { AlignCenter, AlignJustify, AlignLeft, AlignRight, ArrowDownToLine, ArrowUpToLine, Strikethrough, TextCursorInput, Underline } from "lucide";
5
- //#region src/text/inlineMarkdown.ts
6
- var MARKDOWN_ESCAPABLE_CHARS = new Set([
7
- "\\",
8
- "*",
9
- "~",
10
- "`"
11
- ]);
12
- var MARKDOWN_ESCAPE_PATTERN = /[\\*~`]/g;
13
- var MARKDOWN_UNESCAPE_PATTERN = /\\([\\*~`])/g;
14
- 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);
15
- var appendRun = (runs, text, style) => {
16
- if (!text) return;
17
- const lastRun = runs.at(-1);
18
- if (lastRun && sameStyle(lastRun, style)) {
19
- lastRun.text += text;
20
- return;
21
- }
22
- runs.push({
23
- text,
24
- ...style.bold ? { bold: true } : {},
25
- ...style.italic ? { italic: true } : {},
26
- ...style.strikethrough ? { strikethrough: true } : {},
27
- ...style.code ? { code: true } : {}
28
- });
29
- };
30
- var findClosingDelimiter = (value, delimiter, from) => {
31
- for (let i = from; i < value.length; i++) {
32
- if (value[i] === "\\") {
33
- i += 1;
34
- continue;
35
- }
36
- if (delimiter !== "`" && value[i] === "`") {
37
- const codeEnd = findClosingDelimiter(value, "`", i + 1);
38
- if (codeEnd === -1) continue;
39
- i = codeEnd;
40
- continue;
41
- }
42
- if (value.startsWith(delimiter, i)) return i;
43
- }
44
- return -1;
45
- };
46
- var getDelimiter = (value, index) => {
47
- if (value[index] === "`") return "`";
48
- if (value.startsWith("***", index)) return "***";
49
- if (value.startsWith("**", index)) return "**";
50
- if (value.startsWith("~~", index)) return "~~";
51
- if (value[index] === "*") return "*";
52
- return "";
53
- };
54
- var mergeStyle = (style, delimiter) => {
55
- if (delimiter === "***") return {
56
- ...style,
57
- bold: true,
58
- italic: true
59
- };
60
- if (delimiter === "**") return {
61
- ...style,
62
- bold: true
63
- };
64
- if (delimiter === "*") return {
65
- ...style,
66
- italic: true
67
- };
68
- if (delimiter === "~~") return {
69
- ...style,
70
- strikethrough: true
71
- };
72
- return style;
73
- };
74
- var parseRange = (value, from, to, style) => {
75
- const runs = [];
76
- let buffer = "";
77
- const flush = () => {
78
- appendRun(runs, buffer, style);
79
- buffer = "";
80
- };
81
- for (let index = from; index < to; index++) {
82
- const char = value[index];
83
- if (char === "\\" && index + 1 < to && MARKDOWN_ESCAPABLE_CHARS.has(value[index + 1])) {
84
- buffer += value[index + 1];
85
- index += 1;
86
- continue;
87
- }
88
- const delimiter = getDelimiter(value, index);
89
- if (!delimiter) {
90
- buffer += char;
91
- continue;
92
- }
93
- const closingIndex = findClosingDelimiter(value, delimiter, index + delimiter.length);
94
- if (closingIndex === -1 || closingIndex + delimiter.length > to) {
95
- buffer += char;
96
- continue;
97
- }
98
- flush();
99
- if (delimiter === "`") appendRun(runs, value.slice(index + 1, closingIndex).replace(MARKDOWN_UNESCAPE_PATTERN, "$1"), {
100
- ...style,
101
- code: true
102
- });
103
- else parseRange(value, index + delimiter.length, closingIndex, mergeStyle(style, delimiter)).forEach((run) => appendRun(runs, run.text, run));
104
- index = closingIndex + delimiter.length - 1;
105
- }
106
- flush();
107
- return runs;
108
- };
109
- var parseInlineMarkdown = (value) => {
110
- if (!value) return [];
111
- return parseRange(value, 0, value.length, {});
112
- };
113
- var escapeInlineMarkdown = (value) => value.replace(MARKDOWN_ESCAPE_PATTERN, (char) => `\\${char}`);
114
- var stripInlineMarkdown = (value) => parseInlineMarkdown(value).map((run) => run.text).join("");
115
- //#endregion
116
- //#region src/text/richText.ts
117
- var richTextWordSegmenter = new Intl.Segmenter(void 0, { granularity: "word" });
118
- var richTextGraphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
119
- var getBaseFontName = (schema, font) => schema.fontName && font[schema.fontName] ? schema.fontName : getFallbackFontName(font);
120
- var getLoadedFontName = (font, fontName) => fontName && font[fontName] ? fontName : void 0;
121
- var isInlineMarkdownTextSchema = (schema) => schema.textFormat === "inline-markdown" && !(schema.type === "text" && schema.readOnly !== true);
122
- var resolveFontVariant = (run, schema, font) => {
123
- const baseFontName = getBaseFontName(schema, font);
124
- const variants = schema.fontVariants ?? {};
125
- const fallback = schema.fontVariantFallback ?? "synthetic";
126
- let fontName = baseFontName;
127
- let needsBold = Boolean(run.bold);
128
- let needsItalic = Boolean(run.italic);
129
- if (run.code) fontName = getLoadedFontName(font, variants.code) ?? baseFontName;
130
- else if (run.bold && run.italic) {
131
- const boldItalic = getLoadedFontName(font, variants.boldItalic);
132
- const italic = getLoadedFontName(font, variants.italic);
133
- const bold = getLoadedFontName(font, variants.bold);
134
- if (boldItalic) {
135
- fontName = boldItalic;
136
- needsBold = false;
137
- needsItalic = false;
138
- } else if (italic) {
139
- fontName = italic;
140
- needsItalic = false;
141
- } else if (bold) {
142
- fontName = bold;
143
- needsBold = false;
144
- }
145
- } else if (run.bold) {
146
- const bold = getLoadedFontName(font, variants.bold);
147
- if (bold) {
148
- fontName = bold;
149
- needsBold = false;
150
- }
151
- } else if (run.italic) {
152
- const italic = getLoadedFontName(font, variants.italic);
153
- if (italic) {
154
- fontName = italic;
155
- needsItalic = false;
8
+ //#region src/text/linkAnnotation.ts
9
+ var addUriLinkAnnotation = (arg) => {
10
+ const { pdfDoc, page, uri, rect, borderWidth = 0 } = arg;
11
+ const safeUri = normalizeSafeLinkUri(uri);
12
+ if (!safeUri || rect.width <= 0 || rect.height <= 0) return;
13
+ const annotationRef = pdfDoc.context.register(pdfDoc.context.obj({
14
+ Type: PDFName.of("Annot"),
15
+ Subtype: PDFName.of("Link"),
16
+ Rect: [
17
+ rect.x,
18
+ rect.y,
19
+ rect.x + rect.width,
20
+ rect.y + rect.height
21
+ ],
22
+ Border: [
23
+ 0,
24
+ 0,
25
+ borderWidth
26
+ ],
27
+ A: {
28
+ Type: PDFName.of("Action"),
29
+ S: PDFName.of("URI"),
30
+ URI: PDFString.of(safeUri)
156
31
  }
157
- }
158
- 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}".`);
159
- return {
160
- fontName,
161
- syntheticBold: fallback !== "plain" && needsBold,
162
- syntheticItalic: fallback !== "plain" && needsItalic
163
- };
164
- };
165
- var resolveRichTextRuns = async (arg) => {
166
- const { runs, schema, font, _cache } = arg;
167
- const fontKitCache = /* @__PURE__ */ new Map();
168
- const getResolvedFontKitFont = async (fontName) => {
169
- const cached = fontKitCache.get(fontName);
170
- if (cached) return cached;
171
- const fontKitFont = await getFontKitFont(fontName, font, _cache);
172
- fontKitCache.set(fontName, fontKitFont);
173
- return fontKitFont;
174
- };
175
- return Promise.all(runs.map(async (run) => {
176
- const resolution = resolveFontVariant(run, schema, font);
177
- return {
178
- ...run,
179
- ...resolution,
180
- fontKitFont: await getResolvedFontKitFont(resolution.fontName)
181
- };
182
32
  }));
183
- };
184
- var measureRunText = (run, text, fontSize, characterSpacing) => {
185
- const syntheticBoldWidth = run.syntheticBold ? fontSize * SYNTHETIC_BOLD_OFFSET_RATIO * 2 : 0;
186
- const syntheticItalicWidth = run.syntheticItalic ? heightOfFontAtSize(run.fontKitFont, fontSize) * Math.tan(12 * Math.PI / 180) : 0;
187
- return widthOfTextAtSize(text, run.fontKitFont, fontSize, characterSpacing) + syntheticBoldWidth + syntheticItalicWidth;
188
- };
189
- var createLine = () => ({
190
- runs: [],
191
- width: 0,
192
- hardBreak: false
193
- });
194
- var pushRunToLine = (line, run, text, fontSize, characterSpacing) => {
195
- if (!text) return;
196
- const width = measureRunText(run, text, fontSize, characterSpacing);
197
- if (line.runs.length > 0) line.width += characterSpacing;
198
- line.runs.push({
199
- ...run,
200
- text,
201
- width
202
- });
203
- line.width += width;
204
- };
205
- var measurePiecesWidth = (pieces, fontSize, characterSpacing) => {
206
- let width = 0;
207
- let hasText = false;
208
- pieces.forEach((piece) => {
209
- if (!piece.text) return;
210
- if (hasText) width += characterSpacing;
211
- width += measureRunText(piece.run, piece.text, fontSize, characterSpacing);
212
- hasText = true;
213
- });
214
- return width;
215
- };
216
- var sliceRunPieces = (pieces, startIndex, endIndex) => {
217
- const result = [];
218
- let offset = 0;
219
- pieces.forEach((piece) => {
220
- const pieceStart = offset;
221
- const pieceEnd = pieceStart + piece.text.length;
222
- const sliceStart = Math.max(startIndex, pieceStart);
223
- const sliceEnd = Math.min(endIndex, pieceEnd);
224
- if (sliceStart < sliceEnd) result.push({
225
- run: piece.run,
226
- text: piece.text.slice(sliceStart - pieceStart, sliceEnd - pieceStart)
227
- });
228
- offset = pieceEnd;
229
- });
230
- return result;
231
- };
232
- var segmentRunPiecesByWord = (runs, onSegment, onHardBreak) => {
233
- let paragraphPieces = [];
234
- const flushParagraph = () => {
235
- if (paragraphPieces.length === 0) return;
236
- const paragraphText = paragraphPieces.map((piece) => piece.text).join("");
237
- Array.from(richTextWordSegmenter.segment(paragraphText), ({ segment, index }) => {
238
- const pieces = sliceRunPieces(paragraphPieces, index, index + segment.length);
239
- if (pieces.length > 0) onSegment(pieces);
240
- });
241
- paragraphPieces = [];
242
- };
243
- runs.forEach((run) => {
244
- run.text.split(/(\r\n|\r|\n)/).forEach((part) => {
245
- if (part === "\r\n" || part === "\r" || part === "\n") {
246
- flushParagraph();
247
- onHardBreak();
248
- return;
249
- }
250
- if (part) paragraphPieces.push({
251
- run,
252
- text: part
253
- });
254
- });
255
- });
256
- flushParagraph();
257
- };
258
- var splitIntoGraphemes = (value) => Array.from(richTextGraphemeSegmenter.segment(value), ({ segment }) => segment);
259
- var countRichTextLineGraphemes = (line) => splitIntoGraphemes(line.runs.map((run) => run.text).join("")).length;
260
- var layoutRichTextLines = (arg) => {
261
- const { runs, fontSize, characterSpacing, boxWidthInPt } = arg;
262
- const lines = [];
263
- let currentLine = createLine();
264
- const pushCurrentLine = (hardBreak) => {
265
- currentLine.hardBreak = hardBreak;
266
- lines.push(currentLine);
267
- currentLine = createLine();
268
- };
269
- const pushPiecesToLine = (pieces) => {
270
- pieces.forEach((piece) => {
271
- pushRunToLine(currentLine, piece.run, piece.text, fontSize, characterSpacing);
272
- });
273
- };
274
- const pushOversizedText = (run, text) => {
275
- let remainingText = text;
276
- while (remainingText.length > 0) {
277
- const pendingSpacing = currentLine.runs.length > 0 ? characterSpacing : 0;
278
- const remainingWidth = Math.max(boxWidthInPt - currentLine.width - pendingSpacing, 0);
279
- const remainingTextWidth = measureRunText(run, remainingText, fontSize, characterSpacing);
280
- if (remainingTextWidth <= remainingWidth || currentLine.runs.length === 0 && remainingTextWidth <= boxWidthInPt) {
281
- pushRunToLine(currentLine, run, remainingText, fontSize, characterSpacing);
282
- return;
283
- }
284
- if (currentLine.runs.length > 0 && remainingTextWidth <= boxWidthInPt) {
285
- pushCurrentLine(false);
286
- continue;
287
- }
288
- const graphemes = splitIntoGraphemes(remainingText);
289
- let fittingText = "";
290
- let fittingLength = 0;
291
- for (const grapheme of graphemes) {
292
- const candidate = fittingText + grapheme;
293
- const candidateWidth = measureRunText(run, candidate, fontSize, characterSpacing);
294
- const maxWidth = currentLine.runs.length === 0 ? boxWidthInPt : remainingWidth;
295
- if (candidateWidth > maxWidth) {
296
- if (fittingText) break;
297
- if (currentLine.runs.length > 0) break;
298
- }
299
- fittingText = candidate;
300
- fittingLength += grapheme.length;
301
- if (candidateWidth > maxWidth) break;
302
- }
303
- if (!fittingText) {
304
- pushCurrentLine(false);
305
- continue;
306
- }
307
- pushRunToLine(currentLine, run, fittingText, fontSize, characterSpacing);
308
- remainingText = remainingText.slice(fittingLength);
309
- if (remainingText.length > 0) pushCurrentLine(false);
310
- }
311
- };
312
- const pushSegment = (pieces) => {
313
- const segmentWidth = measurePiecesWidth(pieces, fontSize, characterSpacing);
314
- const pendingSpacing = currentLine.runs.length > 0 ? characterSpacing : 0;
315
- if (segmentWidth <= Math.max(boxWidthInPt - currentLine.width - pendingSpacing, 0) || currentLine.runs.length === 0 && segmentWidth <= boxWidthInPt) {
316
- pushPiecesToLine(pieces);
317
- return;
318
- }
319
- if (currentLine.runs.length > 0) {
320
- pushCurrentLine(false);
321
- if (segmentWidth <= boxWidthInPt) {
322
- pushPiecesToLine(pieces);
323
- return;
324
- }
325
- }
326
- pieces.forEach((piece) => pushOversizedText(piece.run, piece.text));
327
- };
328
- segmentRunPiecesByWord(runs, pushSegment, () => pushCurrentLine(true));
329
- if (currentLine.runs.length > 0 || lines.length === 0) pushCurrentLine(false);
330
- return lines;
331
- };
332
- var measureParagraphWidths = (runs, fontSize, characterSpacing) => {
333
- const widths = [];
334
- let paragraphPieces = [];
335
- const pushWidth = () => {
336
- widths.push(measurePiecesWidth(paragraphPieces, fontSize, characterSpacing));
337
- paragraphPieces = [];
338
- };
339
- runs.forEach((run) => {
340
- run.text.split(/(\r\n|\r|\n)/).forEach((part) => {
341
- if (part === "\r\n" || part === "\r" || part === "\n") {
342
- pushWidth();
343
- return;
344
- }
345
- if (part) paragraphPieces.push({
346
- run,
347
- text: part
348
- });
349
- });
350
- });
351
- pushWidth();
352
- return widths;
353
- };
354
- var getLineHeightAtSize = (line, fontSize) => {
355
- if (line.runs.length === 0) return fontSize;
356
- return Math.max(...line.runs.map((run) => heightOfFontAtSize(run.fontKitFont, fontSize)));
357
- };
358
- var calculateDynamicRichTextFontSize = async (arg) => {
359
- const { value, schema, font, _cache, startingFontSize } = arg;
360
- const { fontSize: schemaFontSize, dynamicFontSize: dynamicFontSizeSetting, characterSpacing: schemaCharacterSpacing, width: boxWidth, height: boxHeight, lineHeight = 1 } = schema;
361
- const fontSize = startingFontSize || schemaFontSize || 13;
362
- if (!dynamicFontSizeSetting) return fontSize;
363
- if (dynamicFontSizeSetting.max < dynamicFontSizeSetting.min) return fontSize;
364
- const resolvedRuns = await resolveRichTextRuns({
365
- runs: parseInlineMarkdown(value),
366
- schema,
367
- font,
368
- _cache
369
- });
370
- const characterSpacing = schemaCharacterSpacing ?? 0;
371
- const dynamicFontFit = dynamicFontSizeSetting.fit ?? "vertical";
372
- const boxWidthInPt = mm2pt(boxWidth);
373
- let dynamicFontSize = fontSize;
374
- if (dynamicFontSize < dynamicFontSizeSetting.min) dynamicFontSize = dynamicFontSizeSetting.min;
375
- else if (dynamicFontSize > dynamicFontSizeSetting.max) dynamicFontSize = dynamicFontSizeSetting.max;
376
- const calculateConstraints = (size) => {
377
- let totalWidthInMm = 0;
378
- let totalHeightInMm = 0;
379
- layoutRichTextLines({
380
- runs: resolvedRuns,
381
- fontSize: size,
382
- characterSpacing,
383
- boxWidthInPt
384
- }).forEach((line, lineIndex) => {
385
- if (dynamicFontFit === "vertical") totalWidthInMm = Math.max(totalWidthInMm, pt2mm(line.width));
386
- if (lineIndex === 0) totalHeightInMm += pt2mm(getLineHeightAtSize(line, size) * lineHeight);
387
- else totalHeightInMm += pt2mm(size * lineHeight);
388
- });
389
- if (dynamicFontFit === "horizontal") measureParagraphWidths(resolvedRuns, size, characterSpacing).forEach((paragraphWidth) => {
390
- totalWidthInMm = Math.max(totalWidthInMm, pt2mm(paragraphWidth));
391
- });
392
- return {
393
- totalWidthInMm,
394
- totalHeightInMm
395
- };
396
- };
397
- const shouldFontGrowToFit = (totalWidthInMm, totalHeightInMm) => {
398
- if (dynamicFontSize >= dynamicFontSizeSetting.max) return false;
399
- if (dynamicFontFit === "horizontal") return totalWidthInMm < boxWidth;
400
- return totalHeightInMm < boxHeight;
401
- };
402
- const shouldFontShrinkToFit = (totalWidthInMm, totalHeightInMm) => {
403
- if (dynamicFontSize <= dynamicFontSizeSetting.min || dynamicFontSize <= 0) return false;
404
- return totalWidthInMm > boxWidth || totalHeightInMm > boxHeight;
405
- };
406
- let { totalWidthInMm, totalHeightInMm } = calculateConstraints(dynamicFontSize);
407
- while (shouldFontGrowToFit(totalWidthInMm, totalHeightInMm)) {
408
- dynamicFontSize += FONT_SIZE_ADJUSTMENT;
409
- const { totalWidthInMm: newWidth, totalHeightInMm: newHeight } = calculateConstraints(dynamicFontSize);
410
- if (newHeight < boxHeight) {
411
- totalWidthInMm = newWidth;
412
- totalHeightInMm = newHeight;
413
- } else {
414
- dynamicFontSize -= FONT_SIZE_ADJUSTMENT;
415
- break;
416
- }
417
- }
418
- while (shouldFontShrinkToFit(totalWidthInMm, totalHeightInMm)) {
419
- dynamicFontSize -= FONT_SIZE_ADJUSTMENT;
420
- ({totalWidthInMm, totalHeightInMm} = calculateConstraints(dynamicFontSize));
421
- }
422
- return dynamicFontSize;
33
+ page.node.addAnnot(annotationRef);
423
34
  };
424
35
  //#endregion
425
36
  //#region src/text/richTextPdfRender.ts
426
37
  var getSyntheticBoldWidth = (run, fontSize) => run.syntheticBold ? fontSize * SYNTHETIC_BOLD_OFFSET_RATIO * 2 : 0;
427
38
  var getSyntheticItalicWidth = (run, fontSize) => run.syntheticItalic ? heightOfFontAtSize(run.fontKitFont, fontSize) * Math.tan(12 * Math.PI / 180) : 0;
428
39
  var getRunWidth = (run, fontSize, characterSpacing) => widthOfTextAtSize(run.text, run.fontKitFont, fontSize, characterSpacing) + getSyntheticBoldWidth(run, fontSize) + getSyntheticItalicWidth(run, fontSize);
429
- var getPdfFont = (run, pdfFontObj) => {
40
+ var getPdfFontFromObj = (run, pdfFontObj) => {
430
41
  const pdfFont = pdfFontObj[run.fontName];
431
42
  if (!pdfFont) throw new Error(`[@pdfme/schemas] Missing embedded font "${run.fontName}".`);
432
43
  return pdfFont;
433
44
  };
45
+ var embedFontsForRuns = async (runs, embedPdfFont) => {
46
+ const fontNames = Array.from(new Set(runs.map((run) => run.fontName)));
47
+ const pdfFonts = await Promise.all(fontNames.map(async (fontName) => [fontName, await embedPdfFont(fontName)]));
48
+ return Object.fromEntries(pdfFonts);
49
+ };
434
50
  var drawDecorationLine = (arg) => {
435
51
  const { page, x, y, width, rotate, pivotPoint, fontSize, color, opacity } = arg;
436
52
  if (width <= 0) return;
@@ -448,8 +64,58 @@ var drawDecorationLine = (arg) => {
448
64
  opacity
449
65
  });
450
66
  };
67
+ var getAxisAlignedRect = (arg) => {
68
+ const { x, y, width, height, rotate, pivotPoint } = arg;
69
+ if (rotate.angle === 0) return {
70
+ x,
71
+ y,
72
+ width,
73
+ height
74
+ };
75
+ const points = [
76
+ {
77
+ x,
78
+ y
79
+ },
80
+ {
81
+ x: x + width,
82
+ y
83
+ },
84
+ {
85
+ x: x + width,
86
+ y: y + height
87
+ },
88
+ {
89
+ x,
90
+ y: y + height
91
+ }
92
+ ].map((point) => rotatePoint(point, pivotPoint, rotate.angle));
93
+ const xs = points.map((point) => point.x);
94
+ const ys = points.map((point) => point.y);
95
+ const minX = Math.min(...xs);
96
+ const minY = Math.min(...ys);
97
+ return {
98
+ x: minX,
99
+ y: minY,
100
+ width: Math.max(...xs) - minX,
101
+ height: Math.max(...ys) - minY
102
+ };
103
+ };
104
+ var getLinkAnnotationRect = (arg) => {
105
+ const { run, x, y, width, rotate, pivotPoint, fontSize } = arg;
106
+ const textHeight = heightOfFontAtSize(run.fontKitFont, fontSize);
107
+ const descent = getFontDescentInPt(run.fontKitFont, fontSize);
108
+ return getAxisAlignedRect({
109
+ x,
110
+ y: y + descent,
111
+ width,
112
+ height: textHeight - descent,
113
+ rotate,
114
+ pivotPoint
115
+ });
116
+ };
451
117
  var drawRun = (arg) => {
452
- const { page, pdfLib, run, pdfFont, x, y, rotate, pivotPoint, fontSize, lineHeight, color, opacity, colorType, characterSpacing, strikethrough } = arg;
118
+ const { page, pdfLib, run, pdfFont, x, y, rotate, pivotPoint, fontSize, lineHeight, color, opacity, colorType, characterSpacing, strikethrough, underline } = arg;
453
119
  const runWidth = getRunWidth(run, fontSize, characterSpacing);
454
120
  const textHeight = heightOfFontAtSize(run.fontKitFont, fontSize);
455
121
  if (run.code) {
@@ -484,6 +150,17 @@ var drawRun = (arg) => {
484
150
  color,
485
151
  opacity
486
152
  });
153
+ if (underline && runWidth > 0) drawDecorationLine({
154
+ page,
155
+ x,
156
+ y: y - textHeight / 12,
157
+ width: runWidth,
158
+ rotate,
159
+ pivotPoint,
160
+ fontSize,
161
+ color,
162
+ opacity
163
+ });
487
164
  const drawAt = (drawX) => {
488
165
  const point = rotate.angle === 0 ? {
489
166
  x: drawX,
@@ -511,8 +188,8 @@ var drawRun = (arg) => {
511
188
  }
512
189
  };
513
190
  var renderInlineMarkdownText = async (arg) => {
514
- const { value, schema, font, pdfFontObj, fontKitFont, page, pdfLib, _cache, colorType, fontSize, color, alignment, verticalAlignment, lineHeight, characterSpacing, x, width, height, pageHeight, pivotPoint, rotate, opacity } = arg;
515
- const lines = layoutRichTextLines({
191
+ const { value, schema, font, embedPdfFont, fontKitFont, pdfDoc, page, pdfLib, _cache, colorType, fontSize, color, alignment, verticalAlignment, lineHeight, characterSpacing, x, width, height, pageHeight, pivotPoint, rotate, opacity } = arg;
192
+ const allLines = layoutRichTextLines({
516
193
  runs: await resolveRichTextRuns({
517
194
  runs: parseInlineMarkdown(value),
518
195
  schema,
@@ -523,6 +200,10 @@ var renderInlineMarkdownText = async (arg) => {
523
200
  characterSpacing,
524
201
  boxWidthInPt: width
525
202
  });
203
+ const lineRange = getTextLineRange(schema);
204
+ const lines = applyTextLineRange(allLines, lineRange);
205
+ const lineRangeStart = lineRange?.start ?? 0;
206
+ const pdfFontObj = await embedFontsForRuns(lines.flatMap((line) => line.runs), embedPdfFont);
526
207
  const firstLineTextHeight = heightOfFontAtSize(fontKitFont, fontSize);
527
208
  const descent = getFontDescentInPt(fontKitFont, fontSize);
528
209
  const halfLineHeightAdjustment = lineHeight === 0 ? 0 : (lineHeight - 1) * fontSize / 2;
@@ -537,7 +218,7 @@ var renderInlineMarkdownText = async (arg) => {
537
218
  if (line.runs.length === 0) return;
538
219
  let textWidth = line.width;
539
220
  let spacing = characterSpacing;
540
- if (alignment === "justify" && !line.hardBreak && rowIndex < lines.length - 1) {
221
+ if (alignment === "justify" && !line.hardBreak && lineRangeStart + rowIndex < allLines.length - 1) {
541
222
  const graphemeCount = countRichTextLineGraphemes(line);
542
223
  if (graphemeCount > 0) {
543
224
  spacing += (width - textWidth) / graphemeCount;
@@ -580,7 +261,7 @@ var renderInlineMarkdownText = async (arg) => {
580
261
  page,
581
262
  pdfLib,
582
263
  run,
583
- pdfFont: getPdfFont(run, pdfFontObj),
264
+ pdfFont: getPdfFontFromObj(run, pdfFontObj),
584
265
  x: currentX,
585
266
  y: yLine,
586
267
  rotate,
@@ -591,28 +272,72 @@ var renderInlineMarkdownText = async (arg) => {
591
272
  opacity,
592
273
  colorType,
593
274
  characterSpacing: spacing,
594
- strikethrough: Boolean(run.strikethrough)
275
+ strikethrough: Boolean(run.strikethrough),
276
+ underline: Boolean(run.href) && !schema.underline
595
277
  });
278
+ if (run.href) {
279
+ const rect = getLinkAnnotationRect({
280
+ run,
281
+ x: currentX,
282
+ y: yLine,
283
+ width: runWidth,
284
+ rotate,
285
+ pivotPoint,
286
+ fontSize
287
+ });
288
+ const targetName = getInternalLinkTarget(run.href);
289
+ if (targetName) registerInternalLinkAnnotation({
290
+ _cache,
291
+ page,
292
+ targetName,
293
+ rect
294
+ });
295
+ else addUriLinkAnnotation({
296
+ pdfDoc,
297
+ page,
298
+ uri: run.href,
299
+ rect
300
+ });
301
+ }
596
302
  return currentX + runWidth + (runIndex === line.runs.length - 1 ? 0 : spacing);
597
303
  }, xLine);
598
304
  });
599
305
  };
600
306
  //#endregion
307
+ //#region src/text/overflow.ts
308
+ var TEXT_OVERFLOW_EXPAND_SCHEMA_TYPES = new Set(["text", "multiVariableText"]);
309
+ var isTextOverflowExpandSchema = (schema) => schema.type === void 0 || TEXT_OVERFLOW_EXPAND_SCHEMA_TYPES.has(schema.type);
310
+ var canUseTextOverflowExpand = (schema, basePdf) => !isTextOverflowExpandSchema(schema) || basePdf === void 0 || isBlankPdf(basePdf);
311
+ var isTextOverflowExpand = (schema, basePdf) => canUseTextOverflowExpand(schema, basePdf) && schema.overflow === "expand";
312
+ var shouldUseDynamicFontSize = (schema, basePdf) => Boolean(schema.dynamicFontSize) && !isTextOverflowExpand(schema, basePdf);
313
+ //#endregion
601
314
  //#region src/text/pdfRender.ts
602
- var embedAndGetFontObj = async (arg) => {
603
- const { pdfDoc, font, _cache } = arg;
604
- if (_cache.has(pdfDoc)) return _cache.get(pdfDoc);
605
- const fontValues = await Promise.all(Object.values(font).map(async (v) => {
606
- let fontData = v.data;
315
+ var PDF_FONT_CACHE_KEY = "text-pdf-font-cache";
316
+ var getPdfFontCache = (_cache) => {
317
+ let pdfFontCache = _cache.get(PDF_FONT_CACHE_KEY);
318
+ if (!pdfFontCache) {
319
+ pdfFontCache = {};
320
+ _cache.set(PDF_FONT_CACHE_KEY, pdfFontCache);
321
+ }
322
+ return pdfFontCache;
323
+ };
324
+ var embedAndGetFont = (arg) => {
325
+ const { pdfDoc, font, fontName, _cache } = arg;
326
+ const pdfFontCache = getPdfFontCache(_cache);
327
+ const cachedFont = pdfFontCache[fontName];
328
+ if (cachedFont) return cachedFont;
329
+ const fontValue = font[fontName];
330
+ if (!fontValue) return Promise.reject(/* @__PURE__ */ new Error(`[@pdfme/schemas] Font "${fontName}" is not found.`));
331
+ const pdfFontPromise = (async () => {
332
+ let fontData = fontValue.data;
607
333
  if (typeof fontData === "string" && fontData.startsWith("http")) fontData = await fetchRemoteFontData(fontData);
608
- return pdfDoc.embedFont(fontData, { subset: typeof v.subset === "undefined" ? true : v.subset });
609
- }));
610
- const fontObj = Object.keys(font).reduce((acc, cur, i) => Object.assign(acc, { [cur]: fontValues[i] }), {});
611
- _cache.set(pdfDoc, fontObj);
612
- return fontObj;
334
+ return pdfDoc.embedFont(fontData, { subset: typeof fontValue.subset === "undefined" ? true : fontValue.subset });
335
+ })();
336
+ pdfFontCache[fontName] = pdfFontPromise;
337
+ return pdfFontPromise;
613
338
  };
614
- var getFontProp = ({ value, fontKitFont, schema, colorType, fontSize: resolvedFontSize }) => {
615
- const fontSize = resolvedFontSize ?? (schema.dynamicFontSize ? calculateDynamicFontSize({
339
+ var getFontProp = ({ value, fontKitFont, schema, basePdf, colorType, fontSize: resolvedFontSize }) => {
340
+ const fontSize = resolvedFontSize ?? (shouldUseDynamicFontSize(schema, basePdf) ? calculateDynamicFontSize({
616
341
  textSchema: schema,
617
342
  fontKitFont,
618
343
  value
@@ -627,30 +352,37 @@ var getFontProp = ({ value, fontKitFont, schema, colorType, fontSize: resolvedFo
627
352
  color
628
353
  };
629
354
  };
355
+ var graphemeSegmenter;
356
+ var getGraphemeSegmenter = () => {
357
+ graphemeSegmenter ?? (graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" }));
358
+ return graphemeSegmenter;
359
+ };
630
360
  var pdfRender = async (arg) => {
631
- const { value, pdfDoc, pdfLib, page, options, schema, _cache } = arg;
361
+ const { value, pdfDoc, pdfLib, page, options, schema, basePdf, _cache } = arg;
632
362
  if (!value) return;
633
363
  const { font = getDefaultFont(), colorType } = options;
634
- const [pdfFontObj, fontKitFont] = await Promise.all([embedAndGetFontObj({
364
+ const fontName = schema.fontName ? schema.fontName : getFallbackFontName(font);
365
+ const enableInlineMarkdown = isInlineMarkdownTextSchema(schema);
366
+ const pdfFontValuePromise = enableInlineMarkdown ? void 0 : embedAndGetFont({
635
367
  pdfDoc,
636
368
  font,
369
+ fontName,
637
370
  _cache
638
- }), getFontKitFont(schema.fontName, font, _cache)]);
639
- const enableInlineMarkdown = isInlineMarkdownTextSchema(schema);
371
+ });
372
+ const fontKitFont = await getFontKitFont(schema.fontName, font, _cache);
640
373
  const { fontSize, color, alignment, verticalAlignment, lineHeight, characterSpacing } = getFontProp({
641
374
  value: enableInlineMarkdown ? stripInlineMarkdown(value) : value,
642
375
  fontKitFont,
643
376
  schema,
377
+ basePdf,
644
378
  colorType,
645
- fontSize: enableInlineMarkdown && schema.dynamicFontSize ? await calculateDynamicRichTextFontSize({
379
+ fontSize: enableInlineMarkdown && shouldUseDynamicFontSize(schema, basePdf) ? await calculateDynamicRichTextFontSize({
646
380
  value,
647
381
  schema,
648
382
  font,
649
383
  _cache
650
384
  }) : void 0
651
385
  });
652
- const fontName = schema.fontName ? schema.fontName : getFallbackFontName(font);
653
- const pdfFontValue = pdfFontObj && pdfFontObj[fontName];
654
386
  const pageHeight = page.getHeight();
655
387
  const { width, height, rotate, position: { x, y }, opacity } = convertForPdfLayoutProps({
656
388
  schema,
@@ -690,8 +422,14 @@ var pdfRender = async (arg) => {
690
422
  value,
691
423
  schema,
692
424
  font,
693
- pdfFontObj,
425
+ embedPdfFont: (fontName) => embedAndGetFont({
426
+ pdfDoc,
427
+ font,
428
+ fontName,
429
+ _cache
430
+ }),
694
431
  fontKitFont,
432
+ pdfDoc,
695
433
  page,
696
434
  pdfLib,
697
435
  _cache,
@@ -712,16 +450,20 @@ var pdfRender = async (arg) => {
712
450
  });
713
451
  return;
714
452
  }
453
+ if (!pdfFontValuePromise) throw new Error("[@pdfme/schemas] Failed to prepare PDF font for text rendering.");
454
+ const pdfFontValue = await pdfFontValuePromise;
715
455
  const firstLineTextHeight = heightOfFontAtSize(fontKitFont, fontSize);
716
456
  const descent = getFontDescentInPt(fontKitFont, fontSize);
717
457
  const halfLineHeightAdjustment = lineHeight === 0 ? 0 : (lineHeight - 1) * fontSize / 2;
718
- const lines = splitTextToSize({
458
+ const lines = applyTextLineRange(splitTextToSize({
719
459
  value,
720
460
  characterSpacing,
721
461
  fontSize,
722
462
  fontKitFont,
723
463
  boxWidthInPt: width
724
- });
464
+ }), getTextLineRange(schema));
465
+ const needsTextWidth = alignment !== "left" || Boolean(schema.strikethrough || schema.underline);
466
+ const needsTextHeight = Boolean(schema.strikethrough || schema.underline);
725
467
  let yOffset = 0;
726
468
  if (verticalAlignment === "top") yOffset = firstLineTextHeight + halfLineHeightAdjustment;
727
469
  else {
@@ -729,11 +471,10 @@ var pdfRender = async (arg) => {
729
471
  if (verticalAlignment === "bottom") yOffset = height - otherLinesHeight + descent - halfLineHeightAdjustment;
730
472
  else if (verticalAlignment === "middle") yOffset = (height - otherLinesHeight - firstLineTextHeight + descent) / 2 + firstLineTextHeight;
731
473
  }
732
- const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
733
474
  lines.forEach((line, rowIndex) => {
734
475
  const trimmed = line.replace("\n", "");
735
- const textWidth = widthOfTextAtSize(trimmed, fontKitFont, fontSize, characterSpacing);
736
- const textHeight = heightOfFontAtSize(fontKitFont, fontSize);
476
+ const textWidth = needsTextWidth ? widthOfTextAtSize(trimmed, fontKitFont, fontSize, characterSpacing) : 0;
477
+ const textHeight = needsTextHeight ? heightOfFontAtSize(fontKitFont, fontSize) : 0;
737
478
  const rowYOffset = lineHeight * fontSize * rowIndex;
738
479
  if (line === "") line = "\r\n";
739
480
  let xLine = x;
@@ -784,7 +525,7 @@ var pdfRender = async (arg) => {
784
525
  }
785
526
  let spacing = characterSpacing;
786
527
  if (alignment === "justify" && line.slice(-1) !== "\n") {
787
- const iterator = segmenter.segment(trimmed)[Symbol.iterator]();
528
+ const iterator = getGraphemeSegmenter().segment(trimmed)[Symbol.iterator]();
788
529
  const len = Array.from(iterator).length;
789
530
  spacing += (width - textWidth) / len;
790
531
  }
@@ -886,10 +627,12 @@ function getExtraFormatterSchema(i18n) {
886
627
  //#endregion
887
628
  //#region src/text/propPanel.ts
888
629
  var UseDynamicFontSize = (props) => {
889
- const { rootElement, changeSchemas, activeSchema, i18n } = props;
630
+ const { rootElement, changeSchemas, activeSchema, i18n, basePdf } = props;
631
+ const isExpand = isTextOverflowExpand(activeSchema, basePdf);
890
632
  const checkbox = document.createElement("input");
891
633
  checkbox.type = "checkbox";
892
- checkbox.checked = Boolean(activeSchema?.dynamicFontSize);
634
+ checkbox.checked = !isExpand && Boolean(activeSchema?.dynamicFontSize);
635
+ checkbox.disabled = isExpand;
893
636
  checkbox.onchange = (e) => {
894
637
  changeSchemas([{
895
638
  key: "dynamicFontSize",
@@ -906,6 +649,7 @@ var UseDynamicFontSize = (props) => {
906
649
  span.innerText = i18n("schemas.text.dynamicFontSize") || "";
907
650
  span.style.cssText = "margin-left: 0.5rem";
908
651
  label.style.cssText = "display: flex; width: 100%;";
652
+ label.style.opacity = isExpand ? "0.5" : "1";
909
653
  label.appendChild(checkbox);
910
654
  label.appendChild(span);
911
655
  rootElement.appendChild(label);
@@ -932,15 +676,16 @@ var UseInlineMarkdown = (props) => {
932
676
  rootElement.appendChild(label);
933
677
  };
934
678
  var propPanel = {
935
- schema: ({ options, activeSchema, i18n }) => {
679
+ schema: ({ options, activeSchema, i18n, basePdf }) => {
936
680
  const font = options.font || { [DEFAULT_FONT_NAME]: {
937
681
  data: "",
938
682
  fallback: true
939
683
  } };
940
684
  const fontNames = Object.keys(font);
941
685
  const fallbackFontName = getFallbackFontName(font);
942
- const enableDynamicFont = Boolean(activeSchema?.dynamicFontSize);
943
686
  const activeTextSchema = activeSchema;
687
+ const canExpandOverflow = canUseTextOverflowExpand(activeTextSchema, basePdf);
688
+ const enableDynamicFont = !isTextOverflowExpand(activeTextSchema, basePdf) && Boolean(activeSchema?.dynamicFontSize);
944
689
  const hideTextFormat = activeTextSchema.type === "text" && activeTextSchema.readOnly !== true;
945
690
  const enableInlineMarkdown = activeTextSchema.textFormat === "inline-markdown" && !hideTextFormat;
946
691
  const baseFontName = activeTextSchema.fontName && font[activeTextSchema.fontName] ? activeTextSchema.fontName : fallbackFontName;
@@ -951,6 +696,13 @@ var propPanel = {
951
696
  label: name,
952
697
  value: name
953
698
  }))];
699
+ const overflowOptions = [{
700
+ label: i18n("schemas.text.overflowVisible"),
701
+ value: TEXT_OVERFLOW_VISIBLE
702
+ }, ...canExpandOverflow ? [{
703
+ label: i18n("schemas.text.overflowExpand"),
704
+ value: TEXT_OVERFLOW_EXPAND
705
+ }] : []];
954
706
  return {
955
707
  fontName: {
956
708
  title: i18n("schemas.text.fontName"),
@@ -990,6 +742,14 @@ var propPanel = {
990
742
  },
991
743
  span: 8
992
744
  },
745
+ overflow: {
746
+ title: i18n("schemas.text.overflow"),
747
+ type: "string",
748
+ widget: "select",
749
+ default: DEFAULT_TEXT_OVERFLOW,
750
+ props: { options: overflowOptions },
751
+ span: 8
752
+ },
993
753
  useDynamicFontSize: {
994
754
  type: "boolean",
995
755
  widget: "UseDynamicFontSize",
@@ -1133,6 +893,7 @@ var propPanel = {
1133
893
  verticalAlignment: "top",
1134
894
  fontSize: 13,
1135
895
  textFormat: DEFAULT_TEXT_FORMAT,
896
+ overflow: DEFAULT_TEXT_OVERFLOW,
1136
897
  fontVariantFallback: DEFAULT_FONT_VARIANT_FALLBACK,
1137
898
  lineHeight: 1,
1138
899
  characterSpacing: 0,
@@ -1164,8 +925,13 @@ var replaceUnsupportedChars = (text, fontKitFont) => {
1164
925
  }).join("");
1165
926
  };
1166
927
  var uiRender = async (arg) => {
1167
- const { value, schema, mode, onChange, stopEditing, tabIndex, placeholder, options, _cache } = arg;
1168
- const usePlaceholder = isEditable(mode, schema) && placeholder && !value;
928
+ const { value, schema, basePdf, mode, onChange, stopEditing, tabIndex, placeholder, options, _cache } = arg;
929
+ const hasInlineMarkdownFormat = schema.textFormat === TEXT_FORMAT_INLINE_MARKDOWN;
930
+ const enableInlineMarkdown = isInlineMarkdownTextSchema(schema);
931
+ const isReadOnlySplitInlineMarkdownFormChunk = mode === "form" && Boolean(getTextLineRange(schema)) && hasInlineMarkdownFormat;
932
+ const renderInlineMarkdownReadOnlyChunk = enableInlineMarkdown || isReadOnlySplitInlineMarkdownFormChunk;
933
+ const editable = isEditable(mode, schema) && !isReadOnlySplitInlineMarkdownFormChunk;
934
+ const usePlaceholder = editable && placeholder && !value;
1169
935
  const getText = (element) => {
1170
936
  let text = element.innerText;
1171
937
  if (text.endsWith("\n")) text = text.slice(0, -1);
@@ -1173,18 +939,26 @@ var uiRender = async (arg) => {
1173
939
  };
1174
940
  const font = options?.font || getDefaultFont();
1175
941
  const fontKitFont = await getFontKitFont(schema.fontName, font, _cache);
1176
- const enableInlineMarkdown = isInlineMarkdownTextSchema(schema);
942
+ const enableDynamicFontSize = shouldUseDynamicFontSize(schema, basePdf);
1177
943
  const displayValue = enableInlineMarkdown ? stripInlineMarkdown(value) : value;
1178
- const dynamicRichTextFontSize = enableInlineMarkdown && schema.dynamicFontSize ? await calculateDynamicRichTextFontSize({
944
+ const dynamicRichTextFontSize = enableInlineMarkdown && enableDynamicFontSize ? await calculateDynamicRichTextFontSize({
1179
945
  value: usePlaceholder ? placeholder : value,
1180
946
  schema,
1181
947
  font,
1182
948
  _cache
1183
949
  }) : void 0;
1184
- const textBlock = buildStyledTextContainer(arg, fontKitFont, usePlaceholder ? placeholder : displayValue, dynamicRichTextFontSize);
1185
- const processedText = replaceUnsupportedChars(value, fontKitFont);
1186
- if (!isEditable(mode, schema)) {
1187
- if (enableInlineMarkdown) {
950
+ const textBlock = buildStyledTextContainer(isReadOnlySplitInlineMarkdownFormChunk ? {
951
+ ...arg,
952
+ mode: "viewer"
953
+ } : arg, fontKitFont, usePlaceholder ? placeholder : displayValue, dynamicRichTextFontSize);
954
+ const processedText = replaceUnsupportedChars(getRangedPlainTextValue({
955
+ value,
956
+ schema,
957
+ fontKitFont,
958
+ fontSize: schema.fontSize ?? 13
959
+ }), fontKitFont);
960
+ if (!editable) {
961
+ if (renderInlineMarkdownReadOnlyChunk) {
1188
962
  await renderInlineMarkdownReadOnly({
1189
963
  textBlock,
1190
964
  value,
@@ -1210,7 +984,7 @@ var uiRender = async (arg) => {
1210
984
  });
1211
985
  if (stopEditing) stopEditing();
1212
986
  });
1213
- if (schema.dynamicFontSize) {
987
+ if (enableDynamicFontSize) {
1214
988
  let dynamicFontSize = void 0;
1215
989
  textBlock.addEventListener("keyup", () => {
1216
990
  setTimeout(() => {
@@ -1259,30 +1033,86 @@ var renderInlineMarkdownReadOnly = async (arg) => {
1259
1033
  font,
1260
1034
  _cache
1261
1035
  });
1036
+ const lineRange = getTextLineRange(schema);
1037
+ if (lineRange) {
1038
+ const lines = applyTextLineRange(layoutRichTextLines({
1039
+ runs,
1040
+ fontSize: schema.fontSize ?? 13,
1041
+ characterSpacing: schema.characterSpacing ?? 0,
1042
+ boxWidthInPt: mm2pt(schema.width)
1043
+ }), lineRange);
1044
+ textBlock.innerHTML = "";
1045
+ lines.forEach((line, lineIndex) => {
1046
+ line.runs.forEach((run) => {
1047
+ appendInlineMarkdownRun({
1048
+ textBlock,
1049
+ run,
1050
+ schema,
1051
+ font
1052
+ });
1053
+ });
1054
+ if (lineIndex < lines.length - 1) textBlock.appendChild(document.createElement("br"));
1055
+ });
1056
+ return;
1057
+ }
1262
1058
  textBlock.innerHTML = "";
1263
1059
  runs.forEach((run) => {
1264
- const span = document.createElement("span");
1265
- span.textContent = replaceUnsupportedChars(run.text, run.fontKitFont);
1266
- if (run.fontName) span.style.fontFamily = `'${run.fontName}'`;
1267
- if (run.syntheticBold) {
1268
- span.style.fontWeight = "800";
1269
- span.style.textShadow = SYNTHETIC_BOLD_CSS_TEXT_SHADOW;
1270
- }
1271
- if (run.syntheticItalic) span.style.fontStyle = "italic";
1272
- if (run.strikethrough) span.style.textDecoration = "line-through";
1273
- if (run.code) {
1274
- span.style.backgroundColor = CODE_BACKGROUND_COLOR;
1275
- span.style.borderRadius = "2px";
1276
- span.style.padding = "0 0.15em";
1277
- if (!schema.fontVariants?.code || !font[schema.fontVariants.code]) span.style.fontFamily = run.fontName ? `'${run.fontName}', monospace` : "monospace";
1278
- }
1279
- textBlock.appendChild(span);
1060
+ appendInlineMarkdownRun({
1061
+ textBlock,
1062
+ run,
1063
+ schema,
1064
+ font
1065
+ });
1280
1066
  });
1281
1067
  };
1068
+ var appendInlineMarkdownRun = (arg) => {
1069
+ const { textBlock, run, schema, font } = arg;
1070
+ const href = run.href ? normalizeLinkHref(run.href) : void 0;
1071
+ const span = href ? document.createElement("a") : document.createElement("span");
1072
+ const processedText = replaceUnsupportedChars(run.text, run.fontKitFont);
1073
+ const textDecorations = [];
1074
+ span.textContent = processedText;
1075
+ if (href) {
1076
+ const anchor = span;
1077
+ anchor.href = href;
1078
+ if (!getInternalLinkTarget(href)) {
1079
+ anchor.target = "_blank";
1080
+ anchor.rel = "noopener noreferrer";
1081
+ }
1082
+ textDecorations.push("underline");
1083
+ }
1084
+ if (run.fontName) span.style.fontFamily = `'${run.fontName}'`;
1085
+ if (run.syntheticBold) {
1086
+ span.style.fontWeight = "800";
1087
+ span.style.textShadow = SYNTHETIC_BOLD_CSS_TEXT_SHADOW;
1088
+ }
1089
+ if (run.syntheticItalic) span.style.fontStyle = "italic";
1090
+ if (run.strikethrough) textDecorations.push("line-through");
1091
+ if (textDecorations.length > 0) span.style.textDecoration = textDecorations.join(" ");
1092
+ if (run.code) {
1093
+ span.style.backgroundColor = CODE_BACKGROUND_COLOR;
1094
+ span.style.borderRadius = "2px";
1095
+ span.style.padding = "0 0.15em";
1096
+ if (!schema.fontVariants?.code || !font[schema.fontVariants.code]) span.style.fontFamily = run.fontName ? `'${run.fontName}', monospace` : "monospace";
1097
+ }
1098
+ textBlock.appendChild(span);
1099
+ };
1100
+ var getRangedPlainTextValue = (arg) => {
1101
+ const { value, schema, fontKitFont, fontSize } = arg;
1102
+ const lineRange = getTextLineRange(schema);
1103
+ if (!lineRange) return value;
1104
+ return plainTextLinesToValue(applyTextLineRange(splitTextToSize({
1105
+ value,
1106
+ characterSpacing: schema.characterSpacing ?? 0,
1107
+ fontSize,
1108
+ fontKitFont,
1109
+ boxWidthInPt: mm2pt(schema.width)
1110
+ }), lineRange));
1111
+ };
1282
1112
  var buildStyledTextContainer = (arg, fontKitFont, value, resolvedDynamicFontSize) => {
1283
1113
  const { schema, rootElement, mode } = arg;
1284
1114
  let dynamicFontSize = resolvedDynamicFontSize;
1285
- if (dynamicFontSize === void 0 && schema.dynamicFontSize && value) dynamicFontSize = calculateDynamicFontSize({
1115
+ if (dynamicFontSize === void 0 && shouldUseDynamicFontSize(schema, arg.basePdf) && value) dynamicFontSize = calculateDynamicFontSize({
1286
1116
  textSchema: schema,
1287
1117
  fontKitFont,
1288
1118
  value,
@@ -1383,6 +1213,6 @@ var textSchema = {
1383
1213
  //#region src/builtins.ts
1384
1214
  var builtInPlugins = { Text: textSchema };
1385
1215
  //#endregion
1386
- export { mapVerticalAlignToFlex as a, Formatter as c, isInlineMarkdownTextSchema as d, resolveFontVariant as f, makeElementPlainTextContentEditable as i, getExtraFormatterSchema as l, parseInlineMarkdown as m, textSchema as n, uiRender as o, escapeInlineMarkdown as p, buildStyledTextContainer as r, propPanel as s, builtInPlugins as t, pdfRender as u };
1216
+ export { mapVerticalAlignToFlex as a, Formatter as c, makeElementPlainTextContentEditable as i, getExtraFormatterSchema as l, textSchema as n, uiRender as o, buildStyledTextContainer as r, propPanel as s, builtInPlugins as t, pdfRender as u };
1387
1217
 
1388
- //# sourceMappingURL=builtins-C0BvXHWr.js.map
1218
+ //# sourceMappingURL=builtins-Clh58o_b.js.map