@pdfme/schemas 6.1.0-dev.2 → 6.1.1-dev.10

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