@pdfme/schemas 6.1.1 → 6.1.2-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/box.d.ts +45 -0
- package/dist/{builtins-CWHhKSVA.js → builtins-BB2DHceW.js} +482 -548
- package/dist/builtins-BB2DHceW.js.map +1 -0
- package/dist/builtins.d.ts +1 -1
- package/dist/builtins.js +1 -1
- package/dist/checkbox/index.d.ts +2 -2
- package/dist/dynamicLayout.d.ts +4 -0
- package/dist/dynamicLayout.js +20 -0
- package/dist/dynamicLayout.js.map +1 -0
- package/dist/{dynamicTemplate-DmuRoTw4.js → dynamicTemplate-B4GCNLF9.js} +19 -53
- package/dist/dynamicTemplate-B4GCNLF9.js.map +1 -0
- package/dist/{lists-B6dmgpkS.js → dynamicTemplate-BwzF9C1L.js} +3 -6
- package/dist/dynamicTemplate-BwzF9C1L.js.map +1 -0
- package/dist/dynamicTemplate-C7MdZxPm.js +75 -0
- package/dist/dynamicTemplate-C7MdZxPm.js.map +1 -0
- package/dist/graphics/image.d.ts +1 -1
- package/dist/graphics/signature.d.ts +1 -1
- package/dist/helper-CEme39Uo.js +40 -0
- package/dist/helper-CEme39Uo.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +268 -102
- package/dist/index.js.map +1 -1
- package/dist/list/types.d.ts +0 -5
- package/dist/lists.d.ts +2 -1
- package/dist/lists.js +3 -2
- package/dist/measure-L5diay3k.js +612 -0
- package/dist/measure-L5diay3k.js.map +1 -0
- package/dist/multiVariableText/dynamicTemplate.d.ts +2 -0
- package/dist/radioGroup/index.d.ts +2 -2
- package/dist/select/index.d.ts +2 -2
- package/dist/shapes/line.d.ts +1 -1
- package/dist/shapes/rectAndEllipse.d.ts +1 -2
- package/dist/{helper-M_MmV_d5.js → splitRange-DmVDtmzO.js} +132 -6
- package/dist/splitRange-DmVDtmzO.js.map +1 -0
- package/dist/splitRange.d.ts +16 -0
- package/dist/tables/helper.d.ts +12 -104
- package/dist/tables/types.d.ts +2 -6
- package/dist/tables.d.ts +1 -0
- package/dist/tables.js +3 -2
- package/dist/text/constants.d.ts +3 -0
- package/dist/text/dynamicTemplate.d.ts +2 -0
- package/dist/text/linkAnnotation.d.ts +14 -0
- package/dist/text/measure.d.ts +32 -0
- package/dist/text/overflow.d.ts +7 -0
- package/dist/text/richTextPdfRender.d.ts +3 -2
- package/dist/text/types.d.ts +7 -0
- package/dist/texts.d.ts +5 -0
- package/dist/texts.js +4 -0
- package/dist/types.d.ts +16 -0
- package/dist/types.js +0 -0
- package/dist/utils-zDZkqBnX.js +250 -0
- package/dist/utils-zDZkqBnX.js.map +1 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +3 -215
- package/package.json +16 -1
- package/dist/builtins-CWHhKSVA.js.map +0 -1
- package/dist/dynamicTemplate-DmuRoTw4.js.map +0 -1
- package/dist/helper-M_MmV_d5.js.map +0 -1
- package/dist/lists-B6dmgpkS.js.map +0 -1
- package/dist/utils.js.map +0 -1
|
@@ -1,437 +1,52 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { $ as VERTICAL_ALIGN_MIDDLE, A as ALIGN_RIGHT, B as DYNAMIC_FIT_VERTICAL, C as getBoxInsets, D as ALIGN_CENTER, E as hasBoxDimension, F as DEFAULT_FONT_COLOR, G as PLACEHOLDER_FONT_COLOR, H as FONT_VARIANT_FALLBACK_ERROR, I as DEFAULT_FONT_VARIANT_FALLBACK, J as TEXT_FORMAT_INLINE_MARKDOWN, K as SYNTHETIC_BOLD_CSS_TEXT_SHADOW, L as DEFAULT_TEXT_FORMAT, M as CODE_HORIZONTAL_PADDING, N as DEFAULT_ALIGNMENT, O as ALIGN_JUSTIFY, P as DEFAULT_DYNAMIC_FIT, Q as VERTICAL_ALIGN_BOTTOM, R as DEFAULT_TEXT_OVERFLOW, S as getBoxDimensionPropPanelSchema, U as FONT_VARIANT_FALLBACK_PLAIN, W as FONT_VARIANT_FALLBACK_SYNTHETIC, X as TEXT_OVERFLOW_EXPAND, Y as TEXT_FORMAT_PLAIN, Z as TEXT_OVERFLOW_VISIBLE, _ as isFirefox, b as createBoxDimension, d as calculateDynamicFontSize, f as fetchRemoteFontData, g as heightOfFontAtSize, h as getFontKitFont, j as CODE_BACKGROUND_COLOR, m as getFontDescentInPt, p as getBrowserVerticalFontAdjustments, q as SYNTHETIC_BOLD_OFFSET_RATIO, u as getTextLineRange, v as splitTextToSize, x as getBoxContentArea, y as widthOfTextAtSize, z as DYNAMIC_FIT_HORIZONTAL } from "./splitRange-DmVDtmzO.js";
|
|
2
|
+
import { _ as stripInlineMarkdown, d as isInlineMarkdownTextSchema, f as layoutRichTextLines, g as parseInlineMarkdown, l as calculateDynamicRichTextFontSize, m as resolveRichTextRuns, s as plainTextLinesToValue, t as applyTextLineRange, u as countRichTextLineGraphemes } from "./measure-L5diay3k.js";
|
|
3
|
+
import { c as HEX_COLOR_PATTERN } from "./dynamicTemplate-B4GCNLF9.js";
|
|
4
|
+
import { c as isEditable, i as createSvgStr, n as convertForPdfLayoutProps, o as hex2PrintingColor, u as rotatePoint } from "./utils-zDZkqBnX.js";
|
|
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/
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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;
|
|
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)
|
|
98
31
|
}
|
|
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;
|
|
157
|
-
}
|
|
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
|
-
var getRunWidth = (run, fontSize, characterSpacing) => widthOfTextAtSize(run.text, run.fontKitFont, fontSize, characterSpacing) + getSyntheticBoldWidth(run, fontSize) + getSyntheticItalicWidth(run, fontSize);
|
|
430
|
-
var
|
|
39
|
+
var getRunWidth = (run, fontSize, characterSpacing) => widthOfTextAtSize(run.text, run.fontKitFont, fontSize, characterSpacing) + getSyntheticBoldWidth(run, fontSize) + getSyntheticItalicWidth(run, fontSize) + (run.code ? CODE_HORIZONTAL_PADDING * 2 : 0);
|
|
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,13 +64,65 @@ 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);
|
|
120
|
+
const codePadding = run.code ? CODE_HORIZONTAL_PADDING : 0;
|
|
121
|
+
const textX = x + codePadding;
|
|
122
|
+
const textWidth = runWidth - codePadding * 2;
|
|
455
123
|
const textHeight = heightOfFontAtSize(run.fontKitFont, fontSize);
|
|
456
124
|
if (run.code) {
|
|
457
|
-
const
|
|
458
|
-
const bgX = x - padding;
|
|
125
|
+
const bgX = x;
|
|
459
126
|
const bgY = y - textHeight * .2;
|
|
460
127
|
const bgPoint = rotate.angle === 0 ? {
|
|
461
128
|
x: bgX,
|
|
@@ -467,7 +134,7 @@ var drawRun = (arg) => {
|
|
|
467
134
|
page.drawRectangle({
|
|
468
135
|
x: bgPoint.x,
|
|
469
136
|
y: bgPoint.y,
|
|
470
|
-
width: runWidth
|
|
137
|
+
width: runWidth,
|
|
471
138
|
height: textHeight * 1.2,
|
|
472
139
|
rotate,
|
|
473
140
|
color: hex2PrintingColor(CODE_BACKGROUND_COLOR, colorType),
|
|
@@ -476,9 +143,20 @@ var drawRun = (arg) => {
|
|
|
476
143
|
}
|
|
477
144
|
if (strikethrough && runWidth > 0) drawDecorationLine({
|
|
478
145
|
page,
|
|
479
|
-
x,
|
|
146
|
+
x: textX,
|
|
480
147
|
y: y + textHeight / 3,
|
|
481
|
-
width:
|
|
148
|
+
width: textWidth,
|
|
149
|
+
rotate,
|
|
150
|
+
pivotPoint,
|
|
151
|
+
fontSize,
|
|
152
|
+
color,
|
|
153
|
+
opacity
|
|
154
|
+
});
|
|
155
|
+
if (underline && runWidth > 0) drawDecorationLine({
|
|
156
|
+
page,
|
|
157
|
+
x: textX,
|
|
158
|
+
y: y - textHeight / 12,
|
|
159
|
+
width: textWidth,
|
|
482
160
|
rotate,
|
|
483
161
|
pivotPoint,
|
|
484
162
|
fontSize,
|
|
@@ -505,15 +183,15 @@ var drawRun = (arg) => {
|
|
|
505
183
|
...run.syntheticItalic ? { ySkew: pdfLib.degrees(12) } : {}
|
|
506
184
|
});
|
|
507
185
|
};
|
|
508
|
-
drawAt(
|
|
186
|
+
drawAt(textX);
|
|
509
187
|
if (run.syntheticBold) {
|
|
510
188
|
const offset = fontSize * SYNTHETIC_BOLD_OFFSET_RATIO;
|
|
511
|
-
for (let i = 1; i <= 2; i++) drawAt(
|
|
189
|
+
for (let i = 1; i <= 2; i++) drawAt(textX + offset * i);
|
|
512
190
|
}
|
|
513
191
|
};
|
|
514
192
|
var renderInlineMarkdownText = async (arg) => {
|
|
515
|
-
const { value, schema, font,
|
|
516
|
-
const
|
|
193
|
+
const { value, schema, font, embedPdfFont, fontKitFont, pdfDoc, page, pdfLib, _cache, colorType, fontSize, color, alignment, verticalAlignment, lineHeight, characterSpacing, x, y, width, height, pivotPoint, rotate, opacity } = arg;
|
|
194
|
+
const allLines = layoutRichTextLines({
|
|
517
195
|
runs: await resolveRichTextRuns({
|
|
518
196
|
runs: parseInlineMarkdown(value),
|
|
519
197
|
schema,
|
|
@@ -524,6 +202,10 @@ var renderInlineMarkdownText = async (arg) => {
|
|
|
524
202
|
characterSpacing,
|
|
525
203
|
boxWidthInPt: width
|
|
526
204
|
});
|
|
205
|
+
const lineRange = getTextLineRange(schema);
|
|
206
|
+
const lines = applyTextLineRange(allLines, lineRange);
|
|
207
|
+
const lineRangeStart = lineRange?.start ?? 0;
|
|
208
|
+
const pdfFontObj = await embedFontsForRuns(lines.flatMap((line) => line.runs), embedPdfFont);
|
|
527
209
|
const firstLineTextHeight = heightOfFontAtSize(fontKitFont, fontSize);
|
|
528
210
|
const descent = getFontDescentInPt(fontKitFont, fontSize);
|
|
529
211
|
const halfLineHeightAdjustment = lineHeight === 0 ? 0 : (lineHeight - 1) * fontSize / 2;
|
|
@@ -538,7 +220,7 @@ var renderInlineMarkdownText = async (arg) => {
|
|
|
538
220
|
if (line.runs.length === 0) return;
|
|
539
221
|
let textWidth = line.width;
|
|
540
222
|
let spacing = characterSpacing;
|
|
541
|
-
if (alignment === "justify" && !line.hardBreak && rowIndex <
|
|
223
|
+
if (alignment === "justify" && !line.hardBreak && lineRangeStart + rowIndex < allLines.length - 1) {
|
|
542
224
|
const graphemeCount = countRichTextLineGraphemes(line);
|
|
543
225
|
if (graphemeCount > 0) {
|
|
544
226
|
spacing += (width - textWidth) / graphemeCount;
|
|
@@ -548,7 +230,7 @@ var renderInlineMarkdownText = async (arg) => {
|
|
|
548
230
|
let xLine = x;
|
|
549
231
|
if (alignment === "center") xLine += (width - textWidth) / 2;
|
|
550
232
|
else if (alignment === "right") xLine += width - textWidth;
|
|
551
|
-
const yLine =
|
|
233
|
+
const yLine = y + height - yOffset - lineHeight * fontSize * rowIndex;
|
|
552
234
|
page.pushOperators(pdfLib.setCharacterSpacing(spacing));
|
|
553
235
|
if (schema.strikethrough || schema.underline) {
|
|
554
236
|
const textHeight = Math.max(...line.runs.map((run) => heightOfFontAtSize(run.fontKitFont, fontSize)));
|
|
@@ -581,7 +263,7 @@ var renderInlineMarkdownText = async (arg) => {
|
|
|
581
263
|
page,
|
|
582
264
|
pdfLib,
|
|
583
265
|
run,
|
|
584
|
-
pdfFont:
|
|
266
|
+
pdfFont: getPdfFontFromObj(run, pdfFontObj),
|
|
585
267
|
x: currentX,
|
|
586
268
|
y: yLine,
|
|
587
269
|
rotate,
|
|
@@ -592,28 +274,72 @@ var renderInlineMarkdownText = async (arg) => {
|
|
|
592
274
|
opacity,
|
|
593
275
|
colorType,
|
|
594
276
|
characterSpacing: spacing,
|
|
595
|
-
strikethrough: Boolean(run.strikethrough)
|
|
277
|
+
strikethrough: Boolean(run.strikethrough),
|
|
278
|
+
underline: Boolean(run.href) && !schema.underline
|
|
596
279
|
});
|
|
280
|
+
if (run.href) {
|
|
281
|
+
const rect = getLinkAnnotationRect({
|
|
282
|
+
run,
|
|
283
|
+
x: currentX,
|
|
284
|
+
y: yLine,
|
|
285
|
+
width: runWidth,
|
|
286
|
+
rotate,
|
|
287
|
+
pivotPoint,
|
|
288
|
+
fontSize
|
|
289
|
+
});
|
|
290
|
+
const targetName = getInternalLinkTarget(run.href);
|
|
291
|
+
if (targetName) registerInternalLinkAnnotation({
|
|
292
|
+
_cache,
|
|
293
|
+
page,
|
|
294
|
+
targetName,
|
|
295
|
+
rect
|
|
296
|
+
});
|
|
297
|
+
else addUriLinkAnnotation({
|
|
298
|
+
pdfDoc,
|
|
299
|
+
page,
|
|
300
|
+
uri: run.href,
|
|
301
|
+
rect
|
|
302
|
+
});
|
|
303
|
+
}
|
|
597
304
|
return currentX + runWidth + (runIndex === line.runs.length - 1 ? 0 : spacing);
|
|
598
305
|
}, xLine);
|
|
599
306
|
});
|
|
600
307
|
};
|
|
601
308
|
//#endregion
|
|
309
|
+
//#region src/text/overflow.ts
|
|
310
|
+
var TEXT_OVERFLOW_EXPAND_SCHEMA_TYPES = new Set(["text", "multiVariableText"]);
|
|
311
|
+
var isTextOverflowExpandSchema = (schema) => schema.type === void 0 || TEXT_OVERFLOW_EXPAND_SCHEMA_TYPES.has(schema.type);
|
|
312
|
+
var canUseTextOverflowExpand = (schema, basePdf) => !isTextOverflowExpandSchema(schema) || basePdf === void 0 || isBlankPdf(basePdf);
|
|
313
|
+
var isTextOverflowExpand = (schema, basePdf) => canUseTextOverflowExpand(schema, basePdf) && schema.overflow === "expand";
|
|
314
|
+
var shouldUseDynamicFontSize = (schema, basePdf) => Boolean(schema.dynamicFontSize) && !isTextOverflowExpand(schema, basePdf);
|
|
315
|
+
//#endregion
|
|
602
316
|
//#region src/text/pdfRender.ts
|
|
603
|
-
var
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
317
|
+
var PDF_FONT_CACHE_KEY = "text-pdf-font-cache";
|
|
318
|
+
var getPdfFontCache = (_cache) => {
|
|
319
|
+
let pdfFontCache = _cache.get(PDF_FONT_CACHE_KEY);
|
|
320
|
+
if (!pdfFontCache) {
|
|
321
|
+
pdfFontCache = {};
|
|
322
|
+
_cache.set(PDF_FONT_CACHE_KEY, pdfFontCache);
|
|
323
|
+
}
|
|
324
|
+
return pdfFontCache;
|
|
325
|
+
};
|
|
326
|
+
var embedAndGetFont = (arg) => {
|
|
327
|
+
const { pdfDoc, font, fontName, _cache } = arg;
|
|
328
|
+
const pdfFontCache = getPdfFontCache(_cache);
|
|
329
|
+
const cachedFont = pdfFontCache[fontName];
|
|
330
|
+
if (cachedFont) return cachedFont;
|
|
331
|
+
const fontValue = font[fontName];
|
|
332
|
+
if (!fontValue) return Promise.reject(/* @__PURE__ */ new Error(`[@pdfme/schemas] Font "${fontName}" is not found.`));
|
|
333
|
+
const pdfFontPromise = (async () => {
|
|
334
|
+
let fontData = fontValue.data;
|
|
608
335
|
if (typeof fontData === "string" && fontData.startsWith("http")) fontData = await fetchRemoteFontData(fontData);
|
|
609
|
-
return pdfDoc.embedFont(fontData, { subset: typeof
|
|
610
|
-
}));
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
return fontObj;
|
|
336
|
+
return pdfDoc.embedFont(fontData, { subset: typeof fontValue.subset === "undefined" ? true : fontValue.subset });
|
|
337
|
+
})();
|
|
338
|
+
pdfFontCache[fontName] = pdfFontPromise;
|
|
339
|
+
return pdfFontPromise;
|
|
614
340
|
};
|
|
615
|
-
var getFontProp = ({ value, fontKitFont, schema, colorType, fontSize: resolvedFontSize }) => {
|
|
616
|
-
const fontSize = resolvedFontSize ?? (schema
|
|
341
|
+
var getFontProp = ({ value, fontKitFont, schema, basePdf, colorType, fontSize: resolvedFontSize }) => {
|
|
342
|
+
const fontSize = resolvedFontSize ?? (shouldUseDynamicFontSize(schema, basePdf) ? calculateDynamicFontSize({
|
|
617
343
|
textSchema: schema,
|
|
618
344
|
fontKitFont,
|
|
619
345
|
value
|
|
@@ -628,71 +354,76 @@ var getFontProp = ({ value, fontKitFont, schema, colorType, fontSize: resolvedFo
|
|
|
628
354
|
color
|
|
629
355
|
};
|
|
630
356
|
};
|
|
357
|
+
var graphemeSegmenter;
|
|
358
|
+
var getGraphemeSegmenter = () => {
|
|
359
|
+
graphemeSegmenter ?? (graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" }));
|
|
360
|
+
return graphemeSegmenter;
|
|
361
|
+
};
|
|
631
362
|
var pdfRender = async (arg) => {
|
|
632
|
-
const { value, pdfDoc, pdfLib, page, options, schema, _cache } = arg;
|
|
633
|
-
if (!value) return;
|
|
363
|
+
const { value, pdfDoc, pdfLib, page, options, schema, basePdf, _cache } = arg;
|
|
634
364
|
const { font = getDefaultFont(), colorType } = options;
|
|
635
|
-
const
|
|
365
|
+
const pageHeight = page.getHeight();
|
|
366
|
+
const { width, height, rotate, position: { x, y }, opacity } = convertForPdfLayoutProps({
|
|
367
|
+
schema,
|
|
368
|
+
pageHeight,
|
|
369
|
+
applyRotateTranslate: false
|
|
370
|
+
});
|
|
371
|
+
const pivotPoint = {
|
|
372
|
+
x: x + width / 2,
|
|
373
|
+
y: pageHeight - mm2pt(schema.position.y) - height / 2
|
|
374
|
+
};
|
|
375
|
+
drawTextBoxDecoration({
|
|
376
|
+
page,
|
|
377
|
+
schema,
|
|
378
|
+
colorType,
|
|
379
|
+
x,
|
|
380
|
+
y,
|
|
381
|
+
width,
|
|
382
|
+
height,
|
|
383
|
+
rotate,
|
|
384
|
+
pivotPoint
|
|
385
|
+
});
|
|
386
|
+
if (!value) return;
|
|
387
|
+
const fontName = schema.fontName ? schema.fontName : getFallbackFontName(font);
|
|
388
|
+
const enableInlineMarkdown = isInlineMarkdownTextSchema(schema);
|
|
389
|
+
const contentArea = getBoxContentArea(schema);
|
|
390
|
+
const contentX = x + mm2pt(contentArea.leftInset);
|
|
391
|
+
const contentY = y + mm2pt(contentArea.bottomInset);
|
|
392
|
+
const contentWidth = mm2pt(contentArea.width);
|
|
393
|
+
const contentHeight = mm2pt(contentArea.height);
|
|
394
|
+
const pdfFontValuePromise = enableInlineMarkdown ? void 0 : embedAndGetFont({
|
|
636
395
|
pdfDoc,
|
|
637
396
|
font,
|
|
397
|
+
fontName,
|
|
638
398
|
_cache
|
|
639
|
-
})
|
|
640
|
-
const
|
|
399
|
+
});
|
|
400
|
+
const fontKitFont = await getFontKitFont(schema.fontName, font, _cache);
|
|
641
401
|
const { fontSize, color, alignment, verticalAlignment, lineHeight, characterSpacing } = getFontProp({
|
|
642
402
|
value: enableInlineMarkdown ? stripInlineMarkdown(value) : value,
|
|
643
403
|
fontKitFont,
|
|
644
404
|
schema,
|
|
405
|
+
basePdf,
|
|
645
406
|
colorType,
|
|
646
|
-
fontSize: enableInlineMarkdown && schema
|
|
407
|
+
fontSize: enableInlineMarkdown && shouldUseDynamicFontSize(schema, basePdf) ? await calculateDynamicRichTextFontSize({
|
|
647
408
|
value,
|
|
648
409
|
schema,
|
|
649
410
|
font,
|
|
650
411
|
_cache
|
|
651
412
|
}) : void 0
|
|
652
413
|
});
|
|
653
|
-
const fontName = schema.fontName ? schema.fontName : getFallbackFontName(font);
|
|
654
|
-
const pdfFontValue = pdfFontObj && pdfFontObj[fontName];
|
|
655
|
-
const pageHeight = page.getHeight();
|
|
656
|
-
const { width, height, rotate, position: { x, y }, opacity } = convertForPdfLayoutProps({
|
|
657
|
-
schema,
|
|
658
|
-
pageHeight,
|
|
659
|
-
applyRotateTranslate: false
|
|
660
|
-
});
|
|
661
|
-
const pivotPoint = {
|
|
662
|
-
x: x + width / 2,
|
|
663
|
-
y: pageHeight - mm2pt(schema.position.y) - height / 2
|
|
664
|
-
};
|
|
665
|
-
if (schema.backgroundColor) {
|
|
666
|
-
const color = hex2PrintingColor(schema.backgroundColor, colorType);
|
|
667
|
-
if (rotate.angle !== 0) {
|
|
668
|
-
const rotatedPoint = rotatePoint({
|
|
669
|
-
x,
|
|
670
|
-
y
|
|
671
|
-
}, pivotPoint, rotate.angle);
|
|
672
|
-
page.drawRectangle({
|
|
673
|
-
x: rotatedPoint.x,
|
|
674
|
-
y: rotatedPoint.y,
|
|
675
|
-
width,
|
|
676
|
-
height,
|
|
677
|
-
rotate,
|
|
678
|
-
color
|
|
679
|
-
});
|
|
680
|
-
} else page.drawRectangle({
|
|
681
|
-
x,
|
|
682
|
-
y,
|
|
683
|
-
width,
|
|
684
|
-
height,
|
|
685
|
-
rotate,
|
|
686
|
-
color
|
|
687
|
-
});
|
|
688
|
-
}
|
|
689
414
|
if (enableInlineMarkdown) {
|
|
690
415
|
await renderInlineMarkdownText({
|
|
691
416
|
value,
|
|
692
417
|
schema,
|
|
693
418
|
font,
|
|
694
|
-
|
|
419
|
+
embedPdfFont: (fontName) => embedAndGetFont({
|
|
420
|
+
pdfDoc,
|
|
421
|
+
font,
|
|
422
|
+
fontName,
|
|
423
|
+
_cache
|
|
424
|
+
}),
|
|
695
425
|
fontKitFont,
|
|
426
|
+
pdfDoc,
|
|
696
427
|
page,
|
|
697
428
|
pdfLib,
|
|
698
429
|
_cache,
|
|
@@ -703,44 +434,47 @@ var pdfRender = async (arg) => {
|
|
|
703
434
|
verticalAlignment,
|
|
704
435
|
lineHeight,
|
|
705
436
|
characterSpacing,
|
|
706
|
-
x,
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
437
|
+
x: contentX,
|
|
438
|
+
y: contentY,
|
|
439
|
+
width: contentWidth,
|
|
440
|
+
height: contentHeight,
|
|
710
441
|
pivotPoint,
|
|
711
442
|
rotate,
|
|
712
443
|
opacity
|
|
713
444
|
});
|
|
714
445
|
return;
|
|
715
446
|
}
|
|
447
|
+
if (!pdfFontValuePromise) throw new Error("[@pdfme/schemas] Failed to prepare PDF font for text rendering.");
|
|
448
|
+
const pdfFontValue = await pdfFontValuePromise;
|
|
716
449
|
const firstLineTextHeight = heightOfFontAtSize(fontKitFont, fontSize);
|
|
717
450
|
const descent = getFontDescentInPt(fontKitFont, fontSize);
|
|
718
451
|
const halfLineHeightAdjustment = lineHeight === 0 ? 0 : (lineHeight - 1) * fontSize / 2;
|
|
719
|
-
const lines = splitTextToSize({
|
|
452
|
+
const lines = applyTextLineRange(splitTextToSize({
|
|
720
453
|
value,
|
|
721
454
|
characterSpacing,
|
|
722
455
|
fontSize,
|
|
723
456
|
fontKitFont,
|
|
724
|
-
boxWidthInPt:
|
|
725
|
-
});
|
|
457
|
+
boxWidthInPt: contentWidth
|
|
458
|
+
}), getTextLineRange(schema));
|
|
459
|
+
const needsTextWidth = alignment !== "left" || Boolean(schema.strikethrough || schema.underline);
|
|
460
|
+
const needsTextHeight = Boolean(schema.strikethrough || schema.underline);
|
|
726
461
|
let yOffset = 0;
|
|
727
462
|
if (verticalAlignment === "top") yOffset = firstLineTextHeight + halfLineHeightAdjustment;
|
|
728
463
|
else {
|
|
729
464
|
const otherLinesHeight = lineHeight * fontSize * (lines.length - 1);
|
|
730
|
-
if (verticalAlignment === "bottom") yOffset =
|
|
731
|
-
else if (verticalAlignment === "middle") yOffset = (
|
|
465
|
+
if (verticalAlignment === "bottom") yOffset = contentHeight - otherLinesHeight + descent - halfLineHeightAdjustment;
|
|
466
|
+
else if (verticalAlignment === "middle") yOffset = (contentHeight - otherLinesHeight - firstLineTextHeight + descent) / 2 + firstLineTextHeight;
|
|
732
467
|
}
|
|
733
|
-
const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
734
468
|
lines.forEach((line, rowIndex) => {
|
|
735
469
|
const trimmed = line.replace("\n", "");
|
|
736
|
-
const textWidth = widthOfTextAtSize(trimmed, fontKitFont, fontSize, characterSpacing);
|
|
737
|
-
const textHeight = heightOfFontAtSize(fontKitFont, fontSize);
|
|
470
|
+
const textWidth = needsTextWidth ? widthOfTextAtSize(trimmed, fontKitFont, fontSize, characterSpacing) : 0;
|
|
471
|
+
const textHeight = needsTextHeight ? heightOfFontAtSize(fontKitFont, fontSize) : 0;
|
|
738
472
|
const rowYOffset = lineHeight * fontSize * rowIndex;
|
|
739
473
|
if (line === "") line = "\r\n";
|
|
740
|
-
let xLine =
|
|
741
|
-
if (alignment === "center") xLine += (
|
|
742
|
-
else if (alignment === "right") xLine +=
|
|
743
|
-
let yLine =
|
|
474
|
+
let xLine = contentX;
|
|
475
|
+
if (alignment === "center") xLine += (contentWidth - textWidth) / 2;
|
|
476
|
+
else if (alignment === "right") xLine += contentWidth - textWidth;
|
|
477
|
+
let yLine = contentY + contentHeight - yOffset - rowYOffset;
|
|
744
478
|
if (schema.strikethrough && textWidth > 0) {
|
|
745
479
|
const _x = xLine + textWidth + 1;
|
|
746
480
|
const _y = yLine + textHeight / 3;
|
|
@@ -785,9 +519,9 @@ var pdfRender = async (arg) => {
|
|
|
785
519
|
}
|
|
786
520
|
let spacing = characterSpacing;
|
|
787
521
|
if (alignment === "justify" && line.slice(-1) !== "\n") {
|
|
788
|
-
const iterator =
|
|
522
|
+
const iterator = getGraphemeSegmenter().segment(trimmed)[Symbol.iterator]();
|
|
789
523
|
const len = Array.from(iterator).length;
|
|
790
|
-
spacing += (
|
|
524
|
+
spacing += (contentWidth - textWidth) / len;
|
|
791
525
|
}
|
|
792
526
|
page.pushOperators(pdfLib.setCharacterSpacing(spacing));
|
|
793
527
|
page.drawText(trimmed, {
|
|
@@ -802,6 +536,75 @@ var pdfRender = async (arg) => {
|
|
|
802
536
|
});
|
|
803
537
|
});
|
|
804
538
|
};
|
|
539
|
+
var drawTextBoxDecoration = (arg) => {
|
|
540
|
+
const { page, schema, colorType, x, y, width, height, rotate, pivotPoint } = arg;
|
|
541
|
+
const { borderWidth } = getBoxInsets(schema);
|
|
542
|
+
const opacity = schema.opacity ?? 1;
|
|
543
|
+
const drawRectangle = (rect) => {
|
|
544
|
+
if (rect.width <= 0 || rect.height <= 0) return;
|
|
545
|
+
const point = rotate.angle === 0 ? {
|
|
546
|
+
x: rect.x,
|
|
547
|
+
y: rect.y
|
|
548
|
+
} : rotatePoint({
|
|
549
|
+
x: rect.x,
|
|
550
|
+
y: rect.y
|
|
551
|
+
}, pivotPoint, rotate.angle);
|
|
552
|
+
page.drawRectangle({
|
|
553
|
+
x: point.x,
|
|
554
|
+
y: point.y,
|
|
555
|
+
width: rect.width,
|
|
556
|
+
height: rect.height,
|
|
557
|
+
rotate,
|
|
558
|
+
color: rect.color,
|
|
559
|
+
opacity
|
|
560
|
+
});
|
|
561
|
+
};
|
|
562
|
+
if (schema.backgroundColor) {
|
|
563
|
+
const color = hex2PrintingColor(schema.backgroundColor, colorType);
|
|
564
|
+
if (color) drawRectangle({
|
|
565
|
+
x,
|
|
566
|
+
y,
|
|
567
|
+
width,
|
|
568
|
+
height,
|
|
569
|
+
color
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
if (!schema.borderColor || !hasBoxDimension(schema.borderWidth)) return;
|
|
573
|
+
const color = hex2PrintingColor(schema.borderColor, colorType);
|
|
574
|
+
if (!color) return;
|
|
575
|
+
const top = mm2pt(borderWidth.top);
|
|
576
|
+
const right = mm2pt(borderWidth.right);
|
|
577
|
+
const bottom = mm2pt(borderWidth.bottom);
|
|
578
|
+
const left = mm2pt(borderWidth.left);
|
|
579
|
+
drawRectangle({
|
|
580
|
+
x,
|
|
581
|
+
y: y + height - top,
|
|
582
|
+
width,
|
|
583
|
+
height: top,
|
|
584
|
+
color
|
|
585
|
+
});
|
|
586
|
+
drawRectangle({
|
|
587
|
+
x: x + width - right,
|
|
588
|
+
y,
|
|
589
|
+
width: right,
|
|
590
|
+
height,
|
|
591
|
+
color
|
|
592
|
+
});
|
|
593
|
+
drawRectangle({
|
|
594
|
+
x,
|
|
595
|
+
y,
|
|
596
|
+
width,
|
|
597
|
+
height: bottom,
|
|
598
|
+
color
|
|
599
|
+
});
|
|
600
|
+
drawRectangle({
|
|
601
|
+
x,
|
|
602
|
+
y,
|
|
603
|
+
width: left,
|
|
604
|
+
height,
|
|
605
|
+
color
|
|
606
|
+
});
|
|
607
|
+
};
|
|
805
608
|
//#endregion
|
|
806
609
|
//#region src/text/icons/index.ts
|
|
807
610
|
var TextStrikethroughIcon = createSvgStr(Strikethrough);
|
|
@@ -887,10 +690,12 @@ function getExtraFormatterSchema(i18n) {
|
|
|
887
690
|
//#endregion
|
|
888
691
|
//#region src/text/propPanel.ts
|
|
889
692
|
var UseDynamicFontSize = (props) => {
|
|
890
|
-
const { rootElement, changeSchemas, activeSchema, i18n } = props;
|
|
693
|
+
const { rootElement, changeSchemas, activeSchema, i18n, basePdf } = props;
|
|
694
|
+
const isExpand = isTextOverflowExpand(activeSchema, basePdf);
|
|
891
695
|
const checkbox = document.createElement("input");
|
|
892
696
|
checkbox.type = "checkbox";
|
|
893
|
-
checkbox.checked = Boolean(activeSchema?.dynamicFontSize);
|
|
697
|
+
checkbox.checked = !isExpand && Boolean(activeSchema?.dynamicFontSize);
|
|
698
|
+
checkbox.disabled = isExpand;
|
|
894
699
|
checkbox.onchange = (e) => {
|
|
895
700
|
changeSchemas([{
|
|
896
701
|
key: "dynamicFontSize",
|
|
@@ -907,6 +712,7 @@ var UseDynamicFontSize = (props) => {
|
|
|
907
712
|
span.innerText = i18n("schemas.text.dynamicFontSize") || "";
|
|
908
713
|
span.style.cssText = "margin-left: 0.5rem";
|
|
909
714
|
label.style.cssText = "display: flex; width: 100%;";
|
|
715
|
+
label.style.opacity = isExpand ? "0.5" : "1";
|
|
910
716
|
label.appendChild(checkbox);
|
|
911
717
|
label.appendChild(span);
|
|
912
718
|
rootElement.appendChild(label);
|
|
@@ -933,15 +739,16 @@ var UseInlineMarkdown = (props) => {
|
|
|
933
739
|
rootElement.appendChild(label);
|
|
934
740
|
};
|
|
935
741
|
var propPanel = {
|
|
936
|
-
schema: ({ options, activeSchema, i18n }) => {
|
|
742
|
+
schema: ({ options, activeSchema, i18n, basePdf }) => {
|
|
937
743
|
const font = options.font || { [DEFAULT_FONT_NAME]: {
|
|
938
744
|
data: "",
|
|
939
745
|
fallback: true
|
|
940
746
|
} };
|
|
941
747
|
const fontNames = Object.keys(font);
|
|
942
748
|
const fallbackFontName = getFallbackFontName(font);
|
|
943
|
-
const enableDynamicFont = Boolean(activeSchema?.dynamicFontSize);
|
|
944
749
|
const activeTextSchema = activeSchema;
|
|
750
|
+
const canExpandOverflow = canUseTextOverflowExpand(activeTextSchema, basePdf);
|
|
751
|
+
const enableDynamicFont = !isTextOverflowExpand(activeTextSchema, basePdf) && Boolean(activeSchema?.dynamicFontSize);
|
|
945
752
|
const hideTextFormat = activeTextSchema.type === "text" && activeTextSchema.readOnly !== true;
|
|
946
753
|
const enableInlineMarkdown = activeTextSchema.textFormat === "inline-markdown" && !hideTextFormat;
|
|
947
754
|
const baseFontName = activeTextSchema.fontName && font[activeTextSchema.fontName] ? activeTextSchema.fontName : fallbackFontName;
|
|
@@ -952,6 +759,13 @@ var propPanel = {
|
|
|
952
759
|
label: name,
|
|
953
760
|
value: name
|
|
954
761
|
}))];
|
|
762
|
+
const overflowOptions = [{
|
|
763
|
+
label: i18n("schemas.text.overflowVisible"),
|
|
764
|
+
value: TEXT_OVERFLOW_VISIBLE
|
|
765
|
+
}, ...canExpandOverflow ? [{
|
|
766
|
+
label: i18n("schemas.text.overflowExpand"),
|
|
767
|
+
value: TEXT_OVERFLOW_EXPAND
|
|
768
|
+
}] : []];
|
|
955
769
|
return {
|
|
956
770
|
fontName: {
|
|
957
771
|
title: i18n("schemas.text.fontName"),
|
|
@@ -991,6 +805,14 @@ var propPanel = {
|
|
|
991
805
|
},
|
|
992
806
|
span: 8
|
|
993
807
|
},
|
|
808
|
+
overflow: {
|
|
809
|
+
title: i18n("schemas.text.overflow"),
|
|
810
|
+
type: "string",
|
|
811
|
+
widget: "select",
|
|
812
|
+
default: DEFAULT_TEXT_OVERFLOW,
|
|
813
|
+
props: { options: overflowOptions },
|
|
814
|
+
span: 8
|
|
815
|
+
},
|
|
994
816
|
useDynamicFontSize: {
|
|
995
817
|
type: "boolean",
|
|
996
818
|
widget: "UseDynamicFontSize",
|
|
@@ -1051,6 +873,30 @@ var propPanel = {
|
|
|
1051
873
|
message: i18n("validation.hexColor")
|
|
1052
874
|
}]
|
|
1053
875
|
},
|
|
876
|
+
borderColor: {
|
|
877
|
+
title: i18n("schemas.borderColor"),
|
|
878
|
+
type: "string",
|
|
879
|
+
widget: "color",
|
|
880
|
+
props: { disabledAlpha: true },
|
|
881
|
+
rules: [{
|
|
882
|
+
pattern: HEX_COLOR_PATTERN,
|
|
883
|
+
message: i18n("validation.hexColor")
|
|
884
|
+
}]
|
|
885
|
+
},
|
|
886
|
+
borderWidth: {
|
|
887
|
+
title: i18n("schemas.borderWidth"),
|
|
888
|
+
type: "object",
|
|
889
|
+
widget: "lineTitle",
|
|
890
|
+
span: 24,
|
|
891
|
+
properties: getBoxDimensionPropPanelSchema(.1)
|
|
892
|
+
},
|
|
893
|
+
padding: {
|
|
894
|
+
title: i18n("schemas.padding"),
|
|
895
|
+
type: "object",
|
|
896
|
+
widget: "lineTitle",
|
|
897
|
+
span: 24,
|
|
898
|
+
properties: getBoxDimensionPropPanelSchema()
|
|
899
|
+
},
|
|
1054
900
|
useInlineMarkdown: {
|
|
1055
901
|
type: "boolean",
|
|
1056
902
|
widget: "UseInlineMarkdown",
|
|
@@ -1134,6 +980,7 @@ var propPanel = {
|
|
|
1134
980
|
verticalAlignment: "top",
|
|
1135
981
|
fontSize: 13,
|
|
1136
982
|
textFormat: DEFAULT_TEXT_FORMAT,
|
|
983
|
+
overflow: DEFAULT_TEXT_OVERFLOW,
|
|
1137
984
|
fontVariantFallback: DEFAULT_FONT_VARIANT_FALLBACK,
|
|
1138
985
|
lineHeight: 1,
|
|
1139
986
|
characterSpacing: 0,
|
|
@@ -1141,6 +988,9 @@ var propPanel = {
|
|
|
1141
988
|
fontColor: DEFAULT_FONT_COLOR,
|
|
1142
989
|
fontName: void 0,
|
|
1143
990
|
backgroundColor: "",
|
|
991
|
+
borderColor: "#000000",
|
|
992
|
+
borderWidth: createBoxDimension(0),
|
|
993
|
+
padding: createBoxDimension(0),
|
|
1144
994
|
opacity: 1,
|
|
1145
995
|
strikethrough: false,
|
|
1146
996
|
underline: false
|
|
@@ -1165,8 +1015,13 @@ var replaceUnsupportedChars = (text, fontKitFont) => {
|
|
|
1165
1015
|
}).join("");
|
|
1166
1016
|
};
|
|
1167
1017
|
var uiRender = async (arg) => {
|
|
1168
|
-
const { value, schema, mode, onChange, stopEditing, tabIndex, placeholder, options, _cache } = arg;
|
|
1169
|
-
const
|
|
1018
|
+
const { value, schema, basePdf, mode, onChange, stopEditing, tabIndex, placeholder, options, _cache } = arg;
|
|
1019
|
+
const hasInlineMarkdownFormat = schema.textFormat === TEXT_FORMAT_INLINE_MARKDOWN;
|
|
1020
|
+
const enableInlineMarkdown = isInlineMarkdownTextSchema(schema);
|
|
1021
|
+
const isReadOnlySplitInlineMarkdownFormChunk = mode === "form" && Boolean(getTextLineRange(schema)) && hasInlineMarkdownFormat;
|
|
1022
|
+
const renderInlineMarkdownReadOnlyChunk = enableInlineMarkdown || isReadOnlySplitInlineMarkdownFormChunk;
|
|
1023
|
+
const editable = isEditable(mode, schema) && !isReadOnlySplitInlineMarkdownFormChunk;
|
|
1024
|
+
const usePlaceholder = editable && placeholder && !value;
|
|
1170
1025
|
const getText = (element) => {
|
|
1171
1026
|
let text = element.innerText;
|
|
1172
1027
|
if (text.endsWith("\n")) text = text.slice(0, -1);
|
|
@@ -1174,18 +1029,26 @@ var uiRender = async (arg) => {
|
|
|
1174
1029
|
};
|
|
1175
1030
|
const font = options?.font || getDefaultFont();
|
|
1176
1031
|
const fontKitFont = await getFontKitFont(schema.fontName, font, _cache);
|
|
1177
|
-
const
|
|
1032
|
+
const enableDynamicFontSize = shouldUseDynamicFontSize(schema, basePdf);
|
|
1178
1033
|
const displayValue = enableInlineMarkdown ? stripInlineMarkdown(value) : value;
|
|
1179
|
-
const dynamicRichTextFontSize = enableInlineMarkdown &&
|
|
1034
|
+
const dynamicRichTextFontSize = enableInlineMarkdown && enableDynamicFontSize ? await calculateDynamicRichTextFontSize({
|
|
1180
1035
|
value: usePlaceholder ? placeholder : value,
|
|
1181
1036
|
schema,
|
|
1182
1037
|
font,
|
|
1183
1038
|
_cache
|
|
1184
1039
|
}) : void 0;
|
|
1185
|
-
const textBlock = buildStyledTextContainer(
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1040
|
+
const textBlock = buildStyledTextContainer(isReadOnlySplitInlineMarkdownFormChunk ? {
|
|
1041
|
+
...arg,
|
|
1042
|
+
mode: "viewer"
|
|
1043
|
+
} : arg, fontKitFont, usePlaceholder ? placeholder : displayValue, dynamicRichTextFontSize);
|
|
1044
|
+
const processedText = replaceUnsupportedChars(getRangedPlainTextValue({
|
|
1045
|
+
value,
|
|
1046
|
+
schema,
|
|
1047
|
+
fontKitFont,
|
|
1048
|
+
fontSize: schema.fontSize ?? 13
|
|
1049
|
+
}), fontKitFont);
|
|
1050
|
+
if (!editable) {
|
|
1051
|
+
if (renderInlineMarkdownReadOnlyChunk) {
|
|
1189
1052
|
await renderInlineMarkdownReadOnly({
|
|
1190
1053
|
textBlock,
|
|
1191
1054
|
value,
|
|
@@ -1211,7 +1074,7 @@ var uiRender = async (arg) => {
|
|
|
1211
1074
|
});
|
|
1212
1075
|
if (stopEditing) stopEditing();
|
|
1213
1076
|
});
|
|
1214
|
-
if (
|
|
1077
|
+
if (enableDynamicFontSize) {
|
|
1215
1078
|
let dynamicFontSize = void 0;
|
|
1216
1079
|
textBlock.addEventListener("keyup", () => {
|
|
1217
1080
|
setTimeout(() => {
|
|
@@ -1260,30 +1123,86 @@ var renderInlineMarkdownReadOnly = async (arg) => {
|
|
|
1260
1123
|
font,
|
|
1261
1124
|
_cache
|
|
1262
1125
|
});
|
|
1126
|
+
const lineRange = getTextLineRange(schema);
|
|
1127
|
+
if (lineRange) {
|
|
1128
|
+
const lines = applyTextLineRange(layoutRichTextLines({
|
|
1129
|
+
runs,
|
|
1130
|
+
fontSize: schema.fontSize ?? 13,
|
|
1131
|
+
characterSpacing: schema.characterSpacing ?? 0,
|
|
1132
|
+
boxWidthInPt: mm2pt(getBoxContentArea(schema).width)
|
|
1133
|
+
}), lineRange);
|
|
1134
|
+
textBlock.innerHTML = "";
|
|
1135
|
+
lines.forEach((line, lineIndex) => {
|
|
1136
|
+
line.runs.forEach((run) => {
|
|
1137
|
+
appendInlineMarkdownRun({
|
|
1138
|
+
textBlock,
|
|
1139
|
+
run,
|
|
1140
|
+
schema,
|
|
1141
|
+
font
|
|
1142
|
+
});
|
|
1143
|
+
});
|
|
1144
|
+
if (lineIndex < lines.length - 1) textBlock.appendChild(document.createElement("br"));
|
|
1145
|
+
});
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1263
1148
|
textBlock.innerHTML = "";
|
|
1264
1149
|
runs.forEach((run) => {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
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);
|
|
1150
|
+
appendInlineMarkdownRun({
|
|
1151
|
+
textBlock,
|
|
1152
|
+
run,
|
|
1153
|
+
schema,
|
|
1154
|
+
font
|
|
1155
|
+
});
|
|
1281
1156
|
});
|
|
1282
1157
|
};
|
|
1158
|
+
var appendInlineMarkdownRun = (arg) => {
|
|
1159
|
+
const { textBlock, run, schema, font } = arg;
|
|
1160
|
+
const href = run.href ? normalizeLinkHref(run.href) : void 0;
|
|
1161
|
+
const span = href ? document.createElement("a") : document.createElement("span");
|
|
1162
|
+
const processedText = replaceUnsupportedChars(run.text, run.fontKitFont);
|
|
1163
|
+
const textDecorations = [];
|
|
1164
|
+
span.textContent = processedText;
|
|
1165
|
+
if (href) {
|
|
1166
|
+
const anchor = span;
|
|
1167
|
+
anchor.href = href;
|
|
1168
|
+
if (!getInternalLinkTarget(href)) {
|
|
1169
|
+
anchor.target = "_blank";
|
|
1170
|
+
anchor.rel = "noopener noreferrer";
|
|
1171
|
+
}
|
|
1172
|
+
textDecorations.push("underline");
|
|
1173
|
+
}
|
|
1174
|
+
if (run.fontName) span.style.fontFamily = `'${run.fontName}'`;
|
|
1175
|
+
if (run.syntheticBold) {
|
|
1176
|
+
span.style.fontWeight = "800";
|
|
1177
|
+
span.style.textShadow = SYNTHETIC_BOLD_CSS_TEXT_SHADOW;
|
|
1178
|
+
}
|
|
1179
|
+
if (run.syntheticItalic) span.style.fontStyle = "italic";
|
|
1180
|
+
if (run.strikethrough) textDecorations.push("line-through");
|
|
1181
|
+
if (textDecorations.length > 0) span.style.textDecoration = textDecorations.join(" ");
|
|
1182
|
+
if (run.code) {
|
|
1183
|
+
span.style.backgroundColor = CODE_BACKGROUND_COLOR;
|
|
1184
|
+
span.style.borderRadius = "2px";
|
|
1185
|
+
span.style.padding = "0 0.15em";
|
|
1186
|
+
if (!schema.fontVariants?.code || !font[schema.fontVariants.code]) span.style.fontFamily = run.fontName ? `'${run.fontName}', monospace` : "monospace";
|
|
1187
|
+
}
|
|
1188
|
+
textBlock.appendChild(span);
|
|
1189
|
+
};
|
|
1190
|
+
var getRangedPlainTextValue = (arg) => {
|
|
1191
|
+
const { value, schema, fontKitFont, fontSize } = arg;
|
|
1192
|
+
const lineRange = getTextLineRange(schema);
|
|
1193
|
+
if (!lineRange) return value;
|
|
1194
|
+
return plainTextLinesToValue(applyTextLineRange(splitTextToSize({
|
|
1195
|
+
value,
|
|
1196
|
+
characterSpacing: schema.characterSpacing ?? 0,
|
|
1197
|
+
fontSize,
|
|
1198
|
+
fontKitFont,
|
|
1199
|
+
boxWidthInPt: mm2pt(getBoxContentArea(schema).width)
|
|
1200
|
+
}), lineRange));
|
|
1201
|
+
};
|
|
1283
1202
|
var buildStyledTextContainer = (arg, fontKitFont, value, resolvedDynamicFontSize) => {
|
|
1284
1203
|
const { schema, rootElement, mode } = arg;
|
|
1285
1204
|
let dynamicFontSize = resolvedDynamicFontSize;
|
|
1286
|
-
if (dynamicFontSize === void 0 && schema.
|
|
1205
|
+
if (dynamicFontSize === void 0 && shouldUseDynamicFontSize(schema, arg.basePdf) && value) dynamicFontSize = calculateDynamicFontSize({
|
|
1287
1206
|
textSchema: schema,
|
|
1288
1207
|
fontKitFont,
|
|
1289
1208
|
value,
|
|
@@ -1292,15 +1211,29 @@ var buildStyledTextContainer = (arg, fontKitFont, value, resolvedDynamicFontSize
|
|
|
1292
1211
|
const { topAdj, bottomAdj } = getBrowserVerticalFontAdjustments(fontKitFont, dynamicFontSize ?? schema.fontSize ?? 13, schema.lineHeight ?? 1, schema.verticalAlignment ?? "top");
|
|
1293
1212
|
const topAdjustment = topAdj.toString();
|
|
1294
1213
|
const bottomAdjustment = bottomAdj.toString();
|
|
1214
|
+
const verticalAlignment = schema.verticalAlignment ?? "top";
|
|
1215
|
+
const isTopAligned = verticalAlignment === "top";
|
|
1295
1216
|
const container = document.createElement("div");
|
|
1217
|
+
const { borderWidth, padding } = getBoxInsets(schema);
|
|
1218
|
+
const hasPadding = hasBoxDimension(schema.padding);
|
|
1219
|
+
const hasBorder = Boolean(schema.borderColor && hasBoxDimension(schema.borderWidth));
|
|
1296
1220
|
const containerStyle = {
|
|
1297
|
-
padding: 0,
|
|
1221
|
+
padding: hasPadding ? `${padding.top}mm ${padding.right}mm ${padding.bottom}mm ${padding.left}mm` : 0,
|
|
1298
1222
|
resize: "none",
|
|
1299
|
-
backgroundColor: getBackgroundColor(
|
|
1300
|
-
border: "none",
|
|
1223
|
+
backgroundColor: getBackgroundColor(schema),
|
|
1224
|
+
border: hasBorder ? void 0 : "none",
|
|
1225
|
+
...hasBorder ? {
|
|
1226
|
+
borderTopWidth: `${borderWidth.top}mm`,
|
|
1227
|
+
borderRightWidth: `${borderWidth.right}mm`,
|
|
1228
|
+
borderBottomWidth: `${borderWidth.bottom}mm`,
|
|
1229
|
+
borderLeftWidth: `${borderWidth.left}mm`,
|
|
1230
|
+
borderStyle: "solid",
|
|
1231
|
+
borderColor: schema.borderColor
|
|
1232
|
+
} : {},
|
|
1233
|
+
...hasPadding || hasBorder ? { boxSizing: "border-box" } : {},
|
|
1301
1234
|
display: "flex",
|
|
1302
1235
|
flexDirection: "column",
|
|
1303
|
-
justifyContent: mapVerticalAlignToFlex(
|
|
1236
|
+
justifyContent: mapVerticalAlignToFlex(verticalAlignment),
|
|
1304
1237
|
width: "100%",
|
|
1305
1238
|
height: "100%",
|
|
1306
1239
|
cursor: isEditable(mode, schema) ? "text" : "default"
|
|
@@ -1326,7 +1259,8 @@ var buildStyledTextContainer = (arg, fontKitFont, value, resolvedDynamicFontSize
|
|
|
1326
1259
|
marginBottom: `${bottomAdjustment}px`,
|
|
1327
1260
|
paddingTop: `${topAdjustment}px`,
|
|
1328
1261
|
backgroundColor: "transparent",
|
|
1329
|
-
textDecoration: textDecorations.join(" ")
|
|
1262
|
+
textDecoration: textDecorations.join(" "),
|
|
1263
|
+
...isTopAligned ? { height: "100%" } : {}
|
|
1330
1264
|
};
|
|
1331
1265
|
const textBlock = document.createElement("div");
|
|
1332
1266
|
textBlock.id = "text-" + String(schema.id);
|
|
@@ -1368,8 +1302,8 @@ var mapVerticalAlignToFlex = (verticalAlignmentValue) => {
|
|
|
1368
1302
|
}
|
|
1369
1303
|
return "flex-start";
|
|
1370
1304
|
};
|
|
1371
|
-
var getBackgroundColor = (
|
|
1372
|
-
if (!
|
|
1305
|
+
var getBackgroundColor = (schema) => {
|
|
1306
|
+
if (!schema.backgroundColor) return "transparent";
|
|
1373
1307
|
return schema.backgroundColor;
|
|
1374
1308
|
};
|
|
1375
1309
|
//#endregion
|
|
@@ -1384,6 +1318,6 @@ var textSchema = {
|
|
|
1384
1318
|
//#region src/builtins.ts
|
|
1385
1319
|
var builtInPlugins = { Text: textSchema };
|
|
1386
1320
|
//#endregion
|
|
1387
|
-
export { mapVerticalAlignToFlex as a, Formatter as c,
|
|
1321
|
+
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
1322
|
|
|
1389
|
-
//# sourceMappingURL=builtins-
|
|
1323
|
+
//# sourceMappingURL=builtins-BB2DHceW.js.map
|