@pdfme/schemas 6.0.3 → 6.0.5-dev.1
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/barcodes/constants.d.ts +4 -0
- package/dist/barcodes/helper.d.ts +21 -0
- package/dist/barcodes/index.d.ts +4 -0
- package/dist/barcodes/pdfRender.d.ts +3 -0
- package/dist/barcodes/propPanel.d.ts +3 -0
- package/{src/barcodes/types.ts → dist/barcodes/types.d.ts} +5 -7
- package/dist/barcodes/uiRender.d.ts +3 -0
- package/dist/builtins-CgaZ0UX3.js +613 -0
- package/dist/builtins-CgaZ0UX3.js.map +1 -0
- package/dist/builtins.d.ts +4 -0
- package/dist/builtins.js +2 -0
- package/dist/checkbox/index.d.ts +6 -0
- package/dist/constants.d.ts +2 -0
- package/dist/date/date.d.ts +2 -0
- package/dist/date/dateTime.d.ts +2 -0
- package/dist/date/helper.d.ts +20 -0
- package/dist/date/time.d.ts +2 -0
- package/dist/date/types.d.ts +17 -0
- package/dist/dynamicTemplate-D_DHR3-X.js +1128 -0
- package/dist/dynamicTemplate-D_DHR3-X.js.map +1 -0
- package/dist/graphics/image.d.ts +5 -0
- package/dist/graphics/imagehelper.d.ts +4 -0
- package/dist/graphics/signature.d.ts +4 -0
- package/dist/graphics/svg.d.ts +4 -0
- package/{src/index.ts → dist/index.d.ts} +1 -22
- package/dist/index.js +5383 -0
- package/dist/index.js.map +1 -0
- package/dist/multiVariableText/helper.d.ts +3 -0
- package/dist/multiVariableText/index.d.ts +4 -0
- package/dist/multiVariableText/pdfRender.d.ts +3 -0
- package/dist/multiVariableText/propPanel.d.ts +3 -0
- package/{src/multiVariableText/types.ts → dist/multiVariableText/types.d.ts} +2 -3
- package/dist/multiVariableText/uiRender.d.ts +3 -0
- package/dist/multiVariableText/variables.d.ts +10 -0
- package/dist/radioGroup/index.d.ts +7 -0
- package/dist/sanitize.d.ts +1 -0
- package/dist/select/index.d.ts +7 -0
- package/dist/shapes/line.d.ts +6 -0
- package/dist/shapes/rectAndEllipse.d.ts +11 -0
- package/dist/tables/cell.d.ts +4 -0
- package/dist/tables/classes.d.ts +69 -0
- package/dist/tables/dynamicTemplate.d.ts +7 -0
- package/dist/tables/helper.d.ts +265 -0
- package/dist/tables/index.d.ts +4 -0
- package/dist/tables/pdfRender.d.ts +3 -0
- package/dist/tables/propPanel.d.ts +3 -0
- package/dist/tables/tableHelper.d.ts +10 -0
- package/dist/tables/types.d.ts +88 -0
- package/dist/tables/uiRender.d.ts +3 -0
- package/dist/tables.js +2 -0
- package/dist/text/constants.d.ts +23 -0
- package/dist/text/extraFormatter.d.ts +25 -0
- package/dist/text/helper.d.ts +40 -0
- package/dist/text/icons/index.d.ts +9 -0
- package/dist/text/index.d.ts +4 -0
- package/dist/text/pdfRender.d.ts +3 -0
- package/dist/text/propPanel.d.ts +3 -0
- package/dist/text/types.d.ts +28 -0
- package/dist/text/uiRender.d.ts +11 -0
- package/dist/utils.d.ts +40 -0
- package/dist/utils.js +215 -0
- package/dist/utils.js.map +1 -0
- package/package.json +5 -1
- package/src/barcodes/constants.ts +0 -20
- package/src/barcodes/helper.ts +0 -187
- package/src/barcodes/index.ts +0 -23
- package/src/barcodes/pdfRender.ts +0 -37
- package/src/barcodes/propPanel.ts +0 -249
- package/src/barcodes/uiRender.ts +0 -94
- package/src/builtins.ts +0 -8
- package/src/checkbox/index.ts +0 -70
- package/src/constants.ts +0 -2
- package/src/date/date.ts +0 -9
- package/src/date/dateTime.ts +0 -9
- package/src/date/helper.ts +0 -544
- package/src/date/time.ts +0 -9
- package/src/date/types.ts +0 -19
- package/src/graphics/image.ts +0 -201
- package/src/graphics/imagehelper.ts +0 -156
- package/src/graphics/signature.ts +0 -136
- package/src/graphics/svg.ts +0 -121
- package/src/multiVariableText/helper.ts +0 -65
- package/src/multiVariableText/index.ts +0 -16
- package/src/multiVariableText/pdfRender.ts +0 -21
- package/src/multiVariableText/propPanel.ts +0 -169
- package/src/multiVariableText/uiRender.ts +0 -157
- package/src/multiVariableText/variables.ts +0 -63
- package/src/radioGroup/index.ts +0 -115
- package/src/sanitize.ts +0 -50
- package/src/select/index.ts +0 -205
- package/src/shapes/line.ts +0 -94
- package/src/shapes/rectAndEllipse.ts +0 -152
- package/src/tables/cell.ts +0 -152
- package/src/tables/classes.ts +0 -402
- package/src/tables/dynamicTemplate.ts +0 -88
- package/src/tables/helper.ts +0 -216
- package/src/tables/index.ts +0 -15
- package/src/tables/pdfRender.ts +0 -144
- package/src/tables/propPanel.ts +0 -111
- package/src/tables/tableHelper.ts +0 -289
- package/src/tables/types.ts +0 -87
- package/src/tables/uiRender.ts +0 -436
- package/src/text/constants.ts +0 -104
- package/src/text/extraFormatter.ts +0 -83
- package/src/text/helper.ts +0 -573
- package/src/text/icons/index.ts +0 -30
- package/src/text/index.ts +0 -16
- package/src/text/pdfRender.ts +0 -240
- package/src/text/propPanel.ts +0 -184
- package/src/text/types.ts +0 -30
- package/src/text/uiRender.ts +0 -292
- package/src/utils.ts +0 -354
- package/tsconfig.build.json +0 -14
- package/tsconfig.json +0 -16
- package/vite.config.mts +0 -51
- /package/{src/tables.ts → dist/tables.d.ts} +0 -0
|
@@ -0,0 +1,1128 @@
|
|
|
1
|
+
import { DEFAULT_FONT_NAME, b64toUint8Array, cloneDeep, getDefaultFont, getFallbackFontName, isBlankPdf, isUrlSafeToFetch, mm2pt, pt2mm, pt2px } from "@pdfme/common";
|
|
2
|
+
import * as fontkit from "fontkit";
|
|
3
|
+
import { Buffer } from "buffer";
|
|
4
|
+
//#region src/text/constants.ts
|
|
5
|
+
var ALIGN_LEFT = "left";
|
|
6
|
+
var ALIGN_CENTER = "center";
|
|
7
|
+
var ALIGN_RIGHT = "right";
|
|
8
|
+
var ALIGN_JUSTIFY = "justify";
|
|
9
|
+
var DEFAULT_ALIGNMENT = ALIGN_LEFT;
|
|
10
|
+
var VERTICAL_ALIGN_MIDDLE = "middle";
|
|
11
|
+
var VERTICAL_ALIGN_BOTTOM = "bottom";
|
|
12
|
+
var DEFAULT_FONT_COLOR = "#000000";
|
|
13
|
+
var PLACEHOLDER_FONT_COLOR = "#A0A0A0";
|
|
14
|
+
var DYNAMIC_FIT_VERTICAL = "vertical";
|
|
15
|
+
var DYNAMIC_FIT_HORIZONTAL = "horizontal";
|
|
16
|
+
var DEFAULT_DYNAMIC_FIT = DYNAMIC_FIT_VERTICAL;
|
|
17
|
+
var FONT_SIZE_ADJUSTMENT = .25;
|
|
18
|
+
var LINE_START_FORBIDDEN_CHARS = [
|
|
19
|
+
"、",
|
|
20
|
+
"。",
|
|
21
|
+
",",
|
|
22
|
+
".",
|
|
23
|
+
"」",
|
|
24
|
+
"』",
|
|
25
|
+
")",
|
|
26
|
+
"}",
|
|
27
|
+
"】",
|
|
28
|
+
">",
|
|
29
|
+
"≫",
|
|
30
|
+
"]",
|
|
31
|
+
"・",
|
|
32
|
+
"ー",
|
|
33
|
+
"―",
|
|
34
|
+
"-",
|
|
35
|
+
"!",
|
|
36
|
+
"!",
|
|
37
|
+
"?",
|
|
38
|
+
"?",
|
|
39
|
+
":",
|
|
40
|
+
":",
|
|
41
|
+
";",
|
|
42
|
+
";",
|
|
43
|
+
"/",
|
|
44
|
+
"/",
|
|
45
|
+
"ゝ",
|
|
46
|
+
"々",
|
|
47
|
+
"〃",
|
|
48
|
+
"ぁ",
|
|
49
|
+
"ぃ",
|
|
50
|
+
"ぅ",
|
|
51
|
+
"ぇ",
|
|
52
|
+
"ぉ",
|
|
53
|
+
"っ",
|
|
54
|
+
"ゃ",
|
|
55
|
+
"ゅ",
|
|
56
|
+
"ょ",
|
|
57
|
+
"ァ",
|
|
58
|
+
"ィ",
|
|
59
|
+
"ゥ",
|
|
60
|
+
"ェ",
|
|
61
|
+
"ォ",
|
|
62
|
+
"ッ",
|
|
63
|
+
"ャ",
|
|
64
|
+
"ュ",
|
|
65
|
+
"ョ"
|
|
66
|
+
];
|
|
67
|
+
var LINE_END_FORBIDDEN_CHARS = [
|
|
68
|
+
"「",
|
|
69
|
+
"『",
|
|
70
|
+
"(",
|
|
71
|
+
"{",
|
|
72
|
+
"【",
|
|
73
|
+
"<",
|
|
74
|
+
"≪",
|
|
75
|
+
"[",
|
|
76
|
+
"〘",
|
|
77
|
+
"〖",
|
|
78
|
+
"〝",
|
|
79
|
+
"‘",
|
|
80
|
+
"“",
|
|
81
|
+
"⦅",
|
|
82
|
+
"«"
|
|
83
|
+
];
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/text/helper.ts
|
|
86
|
+
var getBrowserVerticalFontAdjustments = (fontKitFont, fontSize, lineHeight, verticalAlignment) => {
|
|
87
|
+
const { ascent, descent, unitsPerEm } = fontKitFont;
|
|
88
|
+
const fontBaseLineHeight = (ascent - descent) / unitsPerEm;
|
|
89
|
+
const topAdjustment = (fontBaseLineHeight * fontSize - fontSize) / 2;
|
|
90
|
+
if (verticalAlignment === "top") return {
|
|
91
|
+
topAdj: pt2px(topAdjustment),
|
|
92
|
+
bottomAdj: 0
|
|
93
|
+
};
|
|
94
|
+
let bottomAdjustment = 0;
|
|
95
|
+
if (lineHeight < fontBaseLineHeight) bottomAdjustment = (fontBaseLineHeight - lineHeight) * fontSize / 2;
|
|
96
|
+
return {
|
|
97
|
+
topAdj: 0,
|
|
98
|
+
bottomAdj: pt2px(bottomAdjustment)
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
var getFontDescentInPt = (fontKitFont, fontSize) => {
|
|
102
|
+
const { descent, unitsPerEm } = fontKitFont;
|
|
103
|
+
return descent / unitsPerEm * fontSize;
|
|
104
|
+
};
|
|
105
|
+
var heightOfFontAtSize = (fontKitFont, fontSize) => {
|
|
106
|
+
const { ascent, descent, bbox, unitsPerEm } = fontKitFont;
|
|
107
|
+
const scale = 1e3 / unitsPerEm;
|
|
108
|
+
let height = (ascent || bbox.maxY) * scale - (descent || bbox.minY) * scale;
|
|
109
|
+
height -= Math.abs(descent * scale) || 0;
|
|
110
|
+
return height / 1e3 * fontSize;
|
|
111
|
+
};
|
|
112
|
+
var calculateCharacterSpacing = (textContent, textCharacterSpacing) => {
|
|
113
|
+
return (textContent.length - 1) * textCharacterSpacing;
|
|
114
|
+
};
|
|
115
|
+
var widthOfTextAtSize = (text, fontKitFont, fontSize, characterSpacing) => {
|
|
116
|
+
const { glyphs } = fontKitFont.layout(text);
|
|
117
|
+
const scale = 1e3 / fontKitFont.unitsPerEm;
|
|
118
|
+
return glyphs.reduce((totalWidth, glyph) => totalWidth + glyph.advanceWidth * scale, 0) * (fontSize / 1e3) + calculateCharacterSpacing(text, characterSpacing);
|
|
119
|
+
};
|
|
120
|
+
var getFallbackFont = (font) => {
|
|
121
|
+
return font[getFallbackFontName(font)];
|
|
122
|
+
};
|
|
123
|
+
var getCacheKey = (fontName) => `getFontKitFont-${fontName}`;
|
|
124
|
+
var fetchRemoteFontData = async (url) => {
|
|
125
|
+
if (!isUrlSafeToFetch(url)) throw Error("[@pdfme/schemas] Invalid or unsafe URL for font data. Only http: and https: URLs pointing to public hosts are allowed.");
|
|
126
|
+
try {
|
|
127
|
+
const response = await fetch(url);
|
|
128
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
129
|
+
return await response.arrayBuffer();
|
|
130
|
+
} catch (error) {
|
|
131
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
132
|
+
throw Error(`[@pdfme/schemas] Failed to fetch remote font data from ${url}. ${reason}`);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
var getFontKitFont = async (fontName, font, _cache) => {
|
|
136
|
+
const fntNm = fontName || getFallbackFontName(font);
|
|
137
|
+
const cacheKey = getCacheKey(fntNm);
|
|
138
|
+
if (_cache.has(cacheKey)) return _cache.get(cacheKey);
|
|
139
|
+
let fontData = (font[fntNm] || getFallbackFont(font) || getDefaultFont()[DEFAULT_FONT_NAME]).data;
|
|
140
|
+
if (typeof fontData === "string") if (fontData.startsWith("http")) fontData = await fetchRemoteFontData(fontData);
|
|
141
|
+
else fontData = b64toUint8Array(fontData);
|
|
142
|
+
let fontDataBuffer;
|
|
143
|
+
if (fontData instanceof Buffer) fontDataBuffer = fontData;
|
|
144
|
+
else fontDataBuffer = Buffer.from(fontData);
|
|
145
|
+
const fontKitFont = fontkit.create(fontDataBuffer);
|
|
146
|
+
_cache.set(cacheKey, fontKitFont);
|
|
147
|
+
return fontKitFont;
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* If using dynamic font size, iteratively increment or decrement the
|
|
151
|
+
* font size to fit the containing box.
|
|
152
|
+
* Calculating space usage involves splitting lines where they exceed
|
|
153
|
+
* the box width based on the proposed size.
|
|
154
|
+
*/
|
|
155
|
+
var calculateDynamicFontSize = ({ textSchema, fontKitFont, value, startingFontSize }) => {
|
|
156
|
+
const { fontSize: schemaFontSize, dynamicFontSize: dynamicFontSizeSetting, characterSpacing: schemaCharacterSpacing, width: boxWidth, height: boxHeight, lineHeight = 1 } = textSchema;
|
|
157
|
+
const fontSize = startingFontSize || schemaFontSize || 13;
|
|
158
|
+
if (!dynamicFontSizeSetting) return fontSize;
|
|
159
|
+
if (dynamicFontSizeSetting.max < dynamicFontSizeSetting.min) return fontSize;
|
|
160
|
+
const characterSpacing = schemaCharacterSpacing ?? 0;
|
|
161
|
+
const paragraphs = value.split("\n");
|
|
162
|
+
let dynamicFontSize = fontSize;
|
|
163
|
+
if (dynamicFontSize < dynamicFontSizeSetting.min) dynamicFontSize = dynamicFontSizeSetting.min;
|
|
164
|
+
else if (dynamicFontSize > dynamicFontSizeSetting.max) dynamicFontSize = dynamicFontSizeSetting.max;
|
|
165
|
+
const dynamicFontFit = dynamicFontSizeSetting.fit ?? "vertical";
|
|
166
|
+
const calculateConstraints = (size) => {
|
|
167
|
+
let totalWidthInMm = 0;
|
|
168
|
+
let totalHeightInMm = 0;
|
|
169
|
+
const boxWidthInPt = mm2pt(boxWidth);
|
|
170
|
+
const firstLineHeightInMm = pt2mm(heightOfFontAtSize(fontKitFont, size) * lineHeight);
|
|
171
|
+
const otherRowHeightInMm = pt2mm(size * lineHeight);
|
|
172
|
+
paragraphs.forEach((paragraph, paraIndex) => {
|
|
173
|
+
getSplittedLinesBySegmenter(paragraph, {
|
|
174
|
+
font: fontKitFont,
|
|
175
|
+
fontSize: size,
|
|
176
|
+
characterSpacing,
|
|
177
|
+
boxWidthInPt
|
|
178
|
+
}).forEach((line, lineIndex) => {
|
|
179
|
+
if (dynamicFontFit === "vertical") {
|
|
180
|
+
const textWidthInMm = pt2mm(widthOfTextAtSize(line.replace("\n", ""), fontKitFont, size, characterSpacing));
|
|
181
|
+
totalWidthInMm = Math.max(totalWidthInMm, textWidthInMm);
|
|
182
|
+
}
|
|
183
|
+
if (paraIndex + lineIndex === 0) totalHeightInMm += firstLineHeightInMm;
|
|
184
|
+
else totalHeightInMm += otherRowHeightInMm;
|
|
185
|
+
});
|
|
186
|
+
if (dynamicFontFit === "horizontal") {
|
|
187
|
+
const textWidthInMm = pt2mm(widthOfTextAtSize(paragraph, fontKitFont, size, characterSpacing));
|
|
188
|
+
totalWidthInMm = Math.max(totalWidthInMm, textWidthInMm);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
return {
|
|
192
|
+
totalWidthInMm,
|
|
193
|
+
totalHeightInMm
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
const shouldFontGrowToFit = (totalWidthInMm, totalHeightInMm) => {
|
|
197
|
+
if (dynamicFontSize >= dynamicFontSizeSetting.max) return false;
|
|
198
|
+
if (dynamicFontFit === "horizontal") return totalWidthInMm < boxWidth;
|
|
199
|
+
return totalHeightInMm < boxHeight;
|
|
200
|
+
};
|
|
201
|
+
const shouldFontShrinkToFit = (totalWidthInMm, totalHeightInMm) => {
|
|
202
|
+
if (dynamicFontSize <= dynamicFontSizeSetting.min || dynamicFontSize <= 0) return false;
|
|
203
|
+
return totalWidthInMm > boxWidth || totalHeightInMm > boxHeight;
|
|
204
|
+
};
|
|
205
|
+
let { totalWidthInMm, totalHeightInMm } = calculateConstraints(dynamicFontSize);
|
|
206
|
+
while (shouldFontGrowToFit(totalWidthInMm, totalHeightInMm)) {
|
|
207
|
+
dynamicFontSize += FONT_SIZE_ADJUSTMENT;
|
|
208
|
+
const { totalWidthInMm: newWidth, totalHeightInMm: newHeight } = calculateConstraints(dynamicFontSize);
|
|
209
|
+
if (newHeight < boxHeight) {
|
|
210
|
+
totalWidthInMm = newWidth;
|
|
211
|
+
totalHeightInMm = newHeight;
|
|
212
|
+
} else {
|
|
213
|
+
dynamicFontSize -= FONT_SIZE_ADJUSTMENT;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
while (shouldFontShrinkToFit(totalWidthInMm, totalHeightInMm)) {
|
|
218
|
+
dynamicFontSize -= FONT_SIZE_ADJUSTMENT;
|
|
219
|
+
({totalWidthInMm, totalHeightInMm} = calculateConstraints(dynamicFontSize));
|
|
220
|
+
}
|
|
221
|
+
return dynamicFontSize;
|
|
222
|
+
};
|
|
223
|
+
var splitTextToSize = (arg) => {
|
|
224
|
+
const { value, characterSpacing, fontSize, fontKitFont, boxWidthInPt } = arg;
|
|
225
|
+
const fontWidthCalcValues = {
|
|
226
|
+
font: fontKitFont,
|
|
227
|
+
fontSize,
|
|
228
|
+
characterSpacing,
|
|
229
|
+
boxWidthInPt
|
|
230
|
+
};
|
|
231
|
+
let lines = [];
|
|
232
|
+
value.split(/\r\n|\r|\n|\f|\v/g).forEach((line) => {
|
|
233
|
+
lines = lines.concat(getSplittedLinesBySegmenter(line, fontWidthCalcValues));
|
|
234
|
+
});
|
|
235
|
+
return lines;
|
|
236
|
+
};
|
|
237
|
+
var isFirefox = () => navigator.userAgent.toLowerCase().indexOf("firefox") > -1;
|
|
238
|
+
var getSplittedLinesBySegmenter = (line, calcValues) => {
|
|
239
|
+
if (line.trim() === "") return [""];
|
|
240
|
+
const { font, fontSize, characterSpacing, boxWidthInPt } = calcValues;
|
|
241
|
+
const iterator = new Intl.Segmenter(void 0, { granularity: "word" }).segment(line.trimEnd())[Symbol.iterator]();
|
|
242
|
+
let lines = [];
|
|
243
|
+
let lineCounter = 0;
|
|
244
|
+
let currentTextSize = 0;
|
|
245
|
+
while (true) {
|
|
246
|
+
const chunk = iterator.next();
|
|
247
|
+
if (chunk.done) break;
|
|
248
|
+
const segment = chunk.value.segment;
|
|
249
|
+
const textWidth = widthOfTextAtSize(segment, font, fontSize, characterSpacing);
|
|
250
|
+
if (currentTextSize + textWidth <= boxWidthInPt) if (lines[lineCounter]) {
|
|
251
|
+
lines[lineCounter] += segment;
|
|
252
|
+
currentTextSize += textWidth + characterSpacing;
|
|
253
|
+
} else {
|
|
254
|
+
lines[lineCounter] = segment;
|
|
255
|
+
currentTextSize = textWidth + characterSpacing;
|
|
256
|
+
}
|
|
257
|
+
else if (segment.trim() === "") {
|
|
258
|
+
lines[++lineCounter] = "";
|
|
259
|
+
currentTextSize = 0;
|
|
260
|
+
} else if (textWidth <= boxWidthInPt) {
|
|
261
|
+
lines[++lineCounter] = segment;
|
|
262
|
+
currentTextSize = textWidth + characterSpacing;
|
|
263
|
+
} else for (const char of segment) {
|
|
264
|
+
const size = widthOfTextAtSize(char, font, fontSize, characterSpacing);
|
|
265
|
+
if (currentTextSize + size <= boxWidthInPt) if (lines[lineCounter]) {
|
|
266
|
+
lines[lineCounter] += char;
|
|
267
|
+
currentTextSize += size + characterSpacing;
|
|
268
|
+
} else {
|
|
269
|
+
lines[lineCounter] = char;
|
|
270
|
+
currentTextSize = size + characterSpacing;
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
lines[++lineCounter] = char;
|
|
274
|
+
currentTextSize = size + characterSpacing;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (lines.some(containsJapanese)) return adjustEndOfLine(filterEndJP(filterStartJP(lines)));
|
|
279
|
+
else return adjustEndOfLine(lines);
|
|
280
|
+
};
|
|
281
|
+
var adjustEndOfLine = (lines) => {
|
|
282
|
+
return lines.map((line, index) => {
|
|
283
|
+
if (index === lines.length - 1) return line.trimEnd() + "\n";
|
|
284
|
+
else return line.trimEnd();
|
|
285
|
+
});
|
|
286
|
+
};
|
|
287
|
+
function containsJapanese(text) {
|
|
288
|
+
return /[\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Han}]/u.test(text);
|
|
289
|
+
}
|
|
290
|
+
var filterStartJP = (lines) => {
|
|
291
|
+
const filtered = [];
|
|
292
|
+
let charToAppend = null;
|
|
293
|
+
lines.slice().reverse().forEach((line) => {
|
|
294
|
+
if (line.trim().length === 0) filtered.push("");
|
|
295
|
+
else {
|
|
296
|
+
const charAtStart = line.charAt(0);
|
|
297
|
+
if (LINE_START_FORBIDDEN_CHARS.includes(charAtStart)) if (line.trim().length === 1) {
|
|
298
|
+
filtered.push(line);
|
|
299
|
+
charToAppend = null;
|
|
300
|
+
} else {
|
|
301
|
+
if (charToAppend) filtered.push(line.slice(1) + charToAppend);
|
|
302
|
+
else filtered.push(line.slice(1));
|
|
303
|
+
charToAppend = charAtStart;
|
|
304
|
+
}
|
|
305
|
+
else if (charToAppend) {
|
|
306
|
+
filtered.push(line + charToAppend);
|
|
307
|
+
charToAppend = null;
|
|
308
|
+
} else filtered.push(line);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
if (charToAppend) {
|
|
312
|
+
const firstItem = filtered.length > 0 ? filtered[0] : "";
|
|
313
|
+
return [String(charToAppend) + String(firstItem), ...filtered.slice(1)].reverse();
|
|
314
|
+
} else return filtered.reverse();
|
|
315
|
+
};
|
|
316
|
+
var filterEndJP = (lines) => {
|
|
317
|
+
const filtered = [];
|
|
318
|
+
let charToPrepend = null;
|
|
319
|
+
lines.forEach((line) => {
|
|
320
|
+
if (line.trim().length === 0) filtered.push("");
|
|
321
|
+
else {
|
|
322
|
+
const chartAtEnd = line.slice(-1);
|
|
323
|
+
if (LINE_END_FORBIDDEN_CHARS.includes(chartAtEnd)) if (line.trim().length === 1) {
|
|
324
|
+
filtered.push(line);
|
|
325
|
+
charToPrepend = null;
|
|
326
|
+
} else {
|
|
327
|
+
if (charToPrepend) filtered.push(charToPrepend + line.slice(0, -1));
|
|
328
|
+
else filtered.push(line.slice(0, -1));
|
|
329
|
+
charToPrepend = chartAtEnd;
|
|
330
|
+
}
|
|
331
|
+
else if (charToPrepend) {
|
|
332
|
+
filtered.push(charToPrepend + line);
|
|
333
|
+
charToPrepend = null;
|
|
334
|
+
} else filtered.push(line);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
if (charToPrepend) {
|
|
338
|
+
const lastItem = filtered.length > 0 ? filtered[filtered.length - 1] : "";
|
|
339
|
+
const combinedItem = String(lastItem) + String(charToPrepend);
|
|
340
|
+
return [...filtered.slice(0, -1), combinedItem];
|
|
341
|
+
} else return filtered;
|
|
342
|
+
};
|
|
343
|
+
//#endregion
|
|
344
|
+
//#region \0@oxc-project+runtime@0.122.0/helpers/typeof.js
|
|
345
|
+
function _typeof(o) {
|
|
346
|
+
"@babel/helpers - typeof";
|
|
347
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
348
|
+
return typeof o;
|
|
349
|
+
} : function(o) {
|
|
350
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
351
|
+
}, _typeof(o);
|
|
352
|
+
}
|
|
353
|
+
//#endregion
|
|
354
|
+
//#region \0@oxc-project+runtime@0.122.0/helpers/toPrimitive.js
|
|
355
|
+
function toPrimitive(t, r) {
|
|
356
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
357
|
+
var e = t[Symbol.toPrimitive];
|
|
358
|
+
if (void 0 !== e) {
|
|
359
|
+
var i = e.call(t, r || "default");
|
|
360
|
+
if ("object" != _typeof(i)) return i;
|
|
361
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
362
|
+
}
|
|
363
|
+
return ("string" === r ? String : Number)(t);
|
|
364
|
+
}
|
|
365
|
+
//#endregion
|
|
366
|
+
//#region \0@oxc-project+runtime@0.122.0/helpers/toPropertyKey.js
|
|
367
|
+
function toPropertyKey(t) {
|
|
368
|
+
var i = toPrimitive(t, "string");
|
|
369
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
370
|
+
}
|
|
371
|
+
//#endregion
|
|
372
|
+
//#region \0@oxc-project+runtime@0.122.0/helpers/defineProperty.js
|
|
373
|
+
function _defineProperty(e, r, t) {
|
|
374
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
375
|
+
value: t,
|
|
376
|
+
enumerable: !0,
|
|
377
|
+
configurable: !0,
|
|
378
|
+
writable: !0
|
|
379
|
+
}) : e[r] = t, e;
|
|
380
|
+
}
|
|
381
|
+
//#endregion
|
|
382
|
+
//#region src/tables/classes.ts
|
|
383
|
+
var Cell = class {
|
|
384
|
+
constructor(raw, styles, section) {
|
|
385
|
+
_defineProperty(this, "raw", void 0);
|
|
386
|
+
_defineProperty(this, "text", void 0);
|
|
387
|
+
_defineProperty(this, "styles", void 0);
|
|
388
|
+
_defineProperty(this, "section", void 0);
|
|
389
|
+
_defineProperty(this, "contentHeight", 0);
|
|
390
|
+
_defineProperty(this, "contentWidth", 0);
|
|
391
|
+
_defineProperty(this, "wrappedWidth", 0);
|
|
392
|
+
_defineProperty(this, "minReadableWidth", 0);
|
|
393
|
+
_defineProperty(this, "minWidth", 0);
|
|
394
|
+
_defineProperty(this, "width", 0);
|
|
395
|
+
_defineProperty(this, "height", 0);
|
|
396
|
+
_defineProperty(this, "x", 0);
|
|
397
|
+
_defineProperty(this, "y", 0);
|
|
398
|
+
this.styles = styles;
|
|
399
|
+
this.section = section;
|
|
400
|
+
this.raw = raw;
|
|
401
|
+
this.text = raw.split(/\r\n|\r|\n/g);
|
|
402
|
+
}
|
|
403
|
+
getContentHeight() {
|
|
404
|
+
const lineCount = Array.isArray(this.text) ? this.text.length : 1;
|
|
405
|
+
const lineHeight = pt2mm(this.styles.fontSize) * this.styles.lineHeight;
|
|
406
|
+
const vPadding = this.padding("top") + this.padding("bottom");
|
|
407
|
+
const height = lineCount * lineHeight + vPadding;
|
|
408
|
+
return Math.max(height, this.styles.minCellHeight);
|
|
409
|
+
}
|
|
410
|
+
padding(name) {
|
|
411
|
+
return this.styles.cellPadding[name];
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
var Column = class {
|
|
415
|
+
constructor(index) {
|
|
416
|
+
_defineProperty(this, "index", void 0);
|
|
417
|
+
_defineProperty(this, "wrappedWidth", 0);
|
|
418
|
+
_defineProperty(this, "minReadableWidth", 0);
|
|
419
|
+
_defineProperty(this, "minWidth", 0);
|
|
420
|
+
_defineProperty(this, "width", 0);
|
|
421
|
+
this.index = index;
|
|
422
|
+
}
|
|
423
|
+
getMaxCustomCellWidth(table) {
|
|
424
|
+
let max = 0;
|
|
425
|
+
for (const row of table.allRows()) {
|
|
426
|
+
const cell = row.cells[this.index];
|
|
427
|
+
max = Math.max(max, cell.styles.cellWidth);
|
|
428
|
+
}
|
|
429
|
+
return max;
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
var Row = class {
|
|
433
|
+
constructor(raw, index, section, cells) {
|
|
434
|
+
_defineProperty(this, "raw", void 0);
|
|
435
|
+
_defineProperty(this, "index", void 0);
|
|
436
|
+
_defineProperty(this, "section", void 0);
|
|
437
|
+
_defineProperty(this, "cells", void 0);
|
|
438
|
+
_defineProperty(this, "height", 0);
|
|
439
|
+
this.raw = raw;
|
|
440
|
+
this.index = index;
|
|
441
|
+
this.section = section;
|
|
442
|
+
this.cells = cells;
|
|
443
|
+
}
|
|
444
|
+
getMaxCellHeight(columns) {
|
|
445
|
+
return columns.reduce((acc, column) => Math.max(acc, this.cells[column.index]?.height || 0), 0);
|
|
446
|
+
}
|
|
447
|
+
getMinimumRowHeight(columns) {
|
|
448
|
+
return columns.reduce((acc, column) => {
|
|
449
|
+
const cell = this.cells[column.index];
|
|
450
|
+
if (!cell) return 0;
|
|
451
|
+
const oneRowHeight = cell.padding("top") + cell.padding("bottom") + cell.styles.lineHeight;
|
|
452
|
+
return oneRowHeight > acc ? oneRowHeight : acc;
|
|
453
|
+
}, 0);
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
var Table = class Table {
|
|
457
|
+
constructor(input, content) {
|
|
458
|
+
_defineProperty(this, "settings", void 0);
|
|
459
|
+
_defineProperty(this, "styles", void 0);
|
|
460
|
+
_defineProperty(this, "columns", void 0);
|
|
461
|
+
_defineProperty(this, "head", void 0);
|
|
462
|
+
_defineProperty(this, "body", void 0);
|
|
463
|
+
this.settings = input.settings;
|
|
464
|
+
this.styles = input.styles;
|
|
465
|
+
this.columns = content.columns;
|
|
466
|
+
this.head = content.head;
|
|
467
|
+
this.body = content.body;
|
|
468
|
+
}
|
|
469
|
+
static async create(arg) {
|
|
470
|
+
const { input, content, font, _cache } = arg;
|
|
471
|
+
const table = new Table(input, content);
|
|
472
|
+
await calculateWidths({
|
|
473
|
+
table,
|
|
474
|
+
font,
|
|
475
|
+
_cache
|
|
476
|
+
});
|
|
477
|
+
return table;
|
|
478
|
+
}
|
|
479
|
+
getHeadHeight() {
|
|
480
|
+
return this.head.reduce((acc, row) => acc + row.getMaxCellHeight(this.columns), 0);
|
|
481
|
+
}
|
|
482
|
+
getBodyHeight() {
|
|
483
|
+
return this.body.reduce((acc, row) => acc + row.getMaxCellHeight(this.columns), 0);
|
|
484
|
+
}
|
|
485
|
+
allRows() {
|
|
486
|
+
return this.head.concat(this.body);
|
|
487
|
+
}
|
|
488
|
+
getWidth() {
|
|
489
|
+
return this.settings.tableWidth;
|
|
490
|
+
}
|
|
491
|
+
getHeight() {
|
|
492
|
+
return (this.settings.showHead ? this.getHeadHeight() : 0) + this.getBodyHeight();
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
async function calculateWidths(arg) {
|
|
496
|
+
const { table, font, _cache } = arg;
|
|
497
|
+
const getFontKitFontByFontName = (fontName) => getFontKitFont(fontName, font, _cache);
|
|
498
|
+
await calculate(table, getFontKitFontByFontName);
|
|
499
|
+
const resizableColumns = [];
|
|
500
|
+
let initialTableWidth = 0;
|
|
501
|
+
table.columns.forEach((column) => {
|
|
502
|
+
const customWidth = column.getMaxCustomCellWidth(table);
|
|
503
|
+
if (customWidth) column.width = customWidth;
|
|
504
|
+
else {
|
|
505
|
+
column.width = column.wrappedWidth;
|
|
506
|
+
resizableColumns.push(column);
|
|
507
|
+
}
|
|
508
|
+
initialTableWidth += column.width;
|
|
509
|
+
});
|
|
510
|
+
let resizeWidth = table.getWidth() - initialTableWidth;
|
|
511
|
+
if (resizeWidth) resizeWidth = resizeColumns(resizableColumns, resizeWidth, (column) => Math.max(column.minReadableWidth, column.minWidth));
|
|
512
|
+
if (resizeWidth) resizeWidth = resizeColumns(resizableColumns, resizeWidth, (column) => column.minWidth);
|
|
513
|
+
resizeWidth = Math.abs(resizeWidth);
|
|
514
|
+
applyColSpans(table);
|
|
515
|
+
await fitContent(table, getFontKitFontByFontName);
|
|
516
|
+
applyRowSpans(table);
|
|
517
|
+
}
|
|
518
|
+
function applyRowSpans(table) {
|
|
519
|
+
const rowSpanCells = {};
|
|
520
|
+
let colRowSpansLeft = 1;
|
|
521
|
+
const all = table.allRows();
|
|
522
|
+
for (let rowIndex = 0; rowIndex < all.length; rowIndex++) {
|
|
523
|
+
const row = all[rowIndex];
|
|
524
|
+
for (const column of table.columns) {
|
|
525
|
+
const data = rowSpanCells[column.index];
|
|
526
|
+
if (colRowSpansLeft > 1) {
|
|
527
|
+
colRowSpansLeft--;
|
|
528
|
+
delete row.cells[column.index];
|
|
529
|
+
} else if (data) {
|
|
530
|
+
data.cell.height += row.height;
|
|
531
|
+
colRowSpansLeft = 1;
|
|
532
|
+
delete row.cells[column.index];
|
|
533
|
+
data.left--;
|
|
534
|
+
if (data.left <= 1) delete rowSpanCells[column.index];
|
|
535
|
+
} else {
|
|
536
|
+
const cell = row.cells[column.index];
|
|
537
|
+
if (!cell) continue;
|
|
538
|
+
cell.height = row.height;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
function applyColSpans(table) {
|
|
544
|
+
const all = table.allRows();
|
|
545
|
+
for (let rowIndex = 0; rowIndex < all.length; rowIndex++) {
|
|
546
|
+
const row = all[rowIndex];
|
|
547
|
+
let colSpanCell = null;
|
|
548
|
+
let combinedColSpanWidth = 0;
|
|
549
|
+
let colSpansLeft = 0;
|
|
550
|
+
for (let columnIndex = 0; columnIndex < table.columns.length; columnIndex++) {
|
|
551
|
+
const column = table.columns[columnIndex];
|
|
552
|
+
colSpansLeft -= 1;
|
|
553
|
+
if (colSpansLeft > 1 && table.columns[columnIndex + 1]) {
|
|
554
|
+
combinedColSpanWidth += column.width;
|
|
555
|
+
delete row.cells[column.index];
|
|
556
|
+
} else if (colSpanCell) {
|
|
557
|
+
const cell = colSpanCell;
|
|
558
|
+
delete row.cells[column.index];
|
|
559
|
+
colSpanCell = null;
|
|
560
|
+
cell.width = column.width + combinedColSpanWidth;
|
|
561
|
+
} else {
|
|
562
|
+
const cell = row.cells[column.index];
|
|
563
|
+
if (!cell) continue;
|
|
564
|
+
colSpansLeft = 1;
|
|
565
|
+
combinedColSpanWidth = 0;
|
|
566
|
+
cell.width = column.width + combinedColSpanWidth;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
async function fitContent(table, getFontKitFontByFontName) {
|
|
572
|
+
const rowSpanHeight = {
|
|
573
|
+
count: 0,
|
|
574
|
+
height: 0
|
|
575
|
+
};
|
|
576
|
+
for (const row of table.allRows()) {
|
|
577
|
+
for (const column of table.columns) {
|
|
578
|
+
const cell = row.cells[column.index];
|
|
579
|
+
if (!cell) continue;
|
|
580
|
+
const fontKitFont = await getFontKitFontByFontName(cell.styles.fontName);
|
|
581
|
+
cell.text = splitTextToSize({
|
|
582
|
+
value: cell.raw,
|
|
583
|
+
characterSpacing: cell.styles.characterSpacing,
|
|
584
|
+
boxWidthInPt: mm2pt(cell.width),
|
|
585
|
+
fontSize: cell.styles.fontSize,
|
|
586
|
+
fontKitFont
|
|
587
|
+
});
|
|
588
|
+
cell.contentHeight = cell.getContentHeight();
|
|
589
|
+
let realContentHeight = cell.contentHeight;
|
|
590
|
+
if (rowSpanHeight && rowSpanHeight.count > 0) {
|
|
591
|
+
if (rowSpanHeight.height > realContentHeight) realContentHeight = rowSpanHeight.height;
|
|
592
|
+
}
|
|
593
|
+
if (realContentHeight > row.height) row.height = realContentHeight;
|
|
594
|
+
}
|
|
595
|
+
rowSpanHeight.count--;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
function resizeColumns(columns, resizeWidth, getMinWidth) {
|
|
599
|
+
const initialResizeWidth = resizeWidth;
|
|
600
|
+
const sumWrappedWidth = columns.reduce((acc, column) => acc + column.wrappedWidth, 0);
|
|
601
|
+
for (let i = 0; i < columns.length; i++) {
|
|
602
|
+
const column = columns[i];
|
|
603
|
+
const suggestedChange = initialResizeWidth * (column.wrappedWidth / sumWrappedWidth);
|
|
604
|
+
const suggestedWidth = column.width + suggestedChange;
|
|
605
|
+
const minWidth = getMinWidth(column);
|
|
606
|
+
const newWidth = suggestedWidth < minWidth ? minWidth : suggestedWidth;
|
|
607
|
+
resizeWidth -= newWidth - column.width;
|
|
608
|
+
column.width = newWidth;
|
|
609
|
+
}
|
|
610
|
+
resizeWidth = Math.round(resizeWidth * 1e10) / 1e10;
|
|
611
|
+
if (resizeWidth) {
|
|
612
|
+
const resizableColumns = columns.filter((column) => {
|
|
613
|
+
return resizeWidth < 0 ? column.width > getMinWidth(column) : true;
|
|
614
|
+
});
|
|
615
|
+
if (resizableColumns.length) resizeWidth = resizeColumns(resizableColumns, resizeWidth, getMinWidth);
|
|
616
|
+
}
|
|
617
|
+
return resizeWidth;
|
|
618
|
+
}
|
|
619
|
+
async function calculate(table, getFontKitFontByFontName) {
|
|
620
|
+
for (const row of table.allRows()) for (const column of table.columns) {
|
|
621
|
+
const cell = row.cells[column.index];
|
|
622
|
+
if (!cell) continue;
|
|
623
|
+
const hPadding = cell.padding("right") + cell.padding("left");
|
|
624
|
+
const fontKitFont = await getFontKitFontByFontName(cell.styles.fontName);
|
|
625
|
+
cell.contentWidth = getStringWidth(cell, fontKitFont) + hPadding;
|
|
626
|
+
cell.minReadableWidth = getStringWidth(Object.assign(cell, { text: cell.text.join(" ").split(/\s+/) }), fontKitFont) + hPadding;
|
|
627
|
+
cell.minWidth = cell.styles.cellWidth;
|
|
628
|
+
cell.wrappedWidth = cell.styles.cellWidth;
|
|
629
|
+
}
|
|
630
|
+
for (const row of table.allRows()) for (const column of table.columns) {
|
|
631
|
+
const cell = row.cells[column.index];
|
|
632
|
+
if (cell) {
|
|
633
|
+
column.wrappedWidth = Math.max(column.wrappedWidth, cell.wrappedWidth);
|
|
634
|
+
column.minWidth = Math.max(column.minWidth, cell.minWidth);
|
|
635
|
+
column.minReadableWidth = Math.max(column.minReadableWidth, cell.minReadableWidth);
|
|
636
|
+
} else {
|
|
637
|
+
const columnStyles = table.styles.columnStyles[column.index] || {};
|
|
638
|
+
const cellWidth = columnStyles.cellWidth || columnStyles.minCellWidth;
|
|
639
|
+
if (cellWidth) {
|
|
640
|
+
column.minWidth = cellWidth;
|
|
641
|
+
column.wrappedWidth = cellWidth;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
function getStringWidth(cell, fontKitFont) {
|
|
647
|
+
const text = cell.text;
|
|
648
|
+
const textArr = Array.isArray(text) ? text : [text];
|
|
649
|
+
const fontSize = cell.styles.fontSize;
|
|
650
|
+
const characterSpacing = cell.styles.characterSpacing;
|
|
651
|
+
return textArr.map((text) => widthOfTextAtSize(text, fontKitFont, fontSize, characterSpacing)).reduce((a, b) => Math.max(a, b), 0);
|
|
652
|
+
}
|
|
653
|
+
//#endregion
|
|
654
|
+
//#region src/tables/tableHelper.ts
|
|
655
|
+
function parseSection(sectionName, sectionRows, columns, styleProps, fallbackFontName) {
|
|
656
|
+
const rowSpansLeftForColumn = {};
|
|
657
|
+
return sectionRows.map((rawRow, rowIndex) => {
|
|
658
|
+
let skippedRowForRowSpans = 0;
|
|
659
|
+
const cells = {};
|
|
660
|
+
let colSpansAdded = 0;
|
|
661
|
+
let columnSpansLeft = 0;
|
|
662
|
+
for (const column of columns) if (rowSpansLeftForColumn[column.index] == null || rowSpansLeftForColumn[column.index].left === 0) if (columnSpansLeft === 0) {
|
|
663
|
+
let rawCell;
|
|
664
|
+
if (Array.isArray(rawRow)) rawCell = rawRow[column.index - colSpansAdded - skippedRowForRowSpans];
|
|
665
|
+
else rawCell = rawRow[column.index];
|
|
666
|
+
const styles = cellStyles(sectionName, column, rowIndex, styleProps, fallbackFontName);
|
|
667
|
+
const cell = new Cell(rawCell, styles, sectionName);
|
|
668
|
+
cells[column.index] = cell;
|
|
669
|
+
columnSpansLeft = 0;
|
|
670
|
+
rowSpansLeftForColumn[column.index] = {
|
|
671
|
+
left: 0,
|
|
672
|
+
times: columnSpansLeft
|
|
673
|
+
};
|
|
674
|
+
} else {
|
|
675
|
+
columnSpansLeft--;
|
|
676
|
+
colSpansAdded++;
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
rowSpansLeftForColumn[column.index].left--;
|
|
680
|
+
columnSpansLeft = rowSpansLeftForColumn[column.index].times;
|
|
681
|
+
skippedRowForRowSpans++;
|
|
682
|
+
}
|
|
683
|
+
return new Row(rawRow, rowIndex, sectionName, cells);
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
function parseContent4Table(input, fallbackFontName) {
|
|
687
|
+
const content = input.content;
|
|
688
|
+
const columns = content.columns.map((index) => new Column(index));
|
|
689
|
+
const styles = input.styles;
|
|
690
|
+
return {
|
|
691
|
+
columns,
|
|
692
|
+
head: parseSection("head", content.head, columns, styles, fallbackFontName),
|
|
693
|
+
body: parseSection("body", content.body, columns, styles, fallbackFontName)
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
function cellStyles(sectionName, column, rowIndex, styles, fallbackFontName) {
|
|
697
|
+
let sectionStyles;
|
|
698
|
+
if (sectionName === "head") sectionStyles = styles.headStyles;
|
|
699
|
+
else if (sectionName === "body") sectionStyles = styles.bodyStyles;
|
|
700
|
+
const otherStyles = Object.assign({}, styles.styles, sectionStyles);
|
|
701
|
+
const colStyles = styles.columnStyles[column.index] || {};
|
|
702
|
+
const rowStyles = sectionName === "body" && rowIndex % 2 === 0 ? Object.assign({}, styles.alternateRowStyles) : {};
|
|
703
|
+
return Object.assign({
|
|
704
|
+
fontName: fallbackFontName,
|
|
705
|
+
backgroundColor: "",
|
|
706
|
+
textColor: "#000000",
|
|
707
|
+
lineHeight: 1,
|
|
708
|
+
characterSpacing: 0,
|
|
709
|
+
alignment: "left",
|
|
710
|
+
verticalAlignment: "middle",
|
|
711
|
+
fontSize: 10,
|
|
712
|
+
cellPadding: 5,
|
|
713
|
+
lineColor: "#000000",
|
|
714
|
+
lineWidth: 0,
|
|
715
|
+
minCellHeight: 0,
|
|
716
|
+
minCellWidth: 0
|
|
717
|
+
}, otherStyles, rowStyles, colStyles);
|
|
718
|
+
}
|
|
719
|
+
function mapCellStyle(style) {
|
|
720
|
+
return {
|
|
721
|
+
fontName: style.fontName,
|
|
722
|
+
alignment: style.alignment,
|
|
723
|
+
verticalAlignment: style.verticalAlignment,
|
|
724
|
+
fontSize: style.fontSize,
|
|
725
|
+
lineHeight: style.lineHeight,
|
|
726
|
+
characterSpacing: style.characterSpacing,
|
|
727
|
+
backgroundColor: style.backgroundColor,
|
|
728
|
+
textColor: style.fontColor,
|
|
729
|
+
lineColor: style.borderColor,
|
|
730
|
+
lineWidth: style.borderWidth,
|
|
731
|
+
cellPadding: style.padding
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
function getTableOptions(schema, body) {
|
|
735
|
+
const columnStylesWidth = schema.headWidthPercentages.reduce((acc, cur, i) => ({
|
|
736
|
+
...acc,
|
|
737
|
+
[i]: { cellWidth: schema.width * (cur / 100) }
|
|
738
|
+
}), {});
|
|
739
|
+
const columnStylesAlignment = Object.entries(schema.columnStyles.alignment || {}).reduce((acc, [key, value]) => ({
|
|
740
|
+
...acc,
|
|
741
|
+
[key]: { alignment: value }
|
|
742
|
+
}), {});
|
|
743
|
+
const allKeys = new Set([...Object.keys(columnStylesWidth).map(Number), ...Object.keys(columnStylesAlignment).map(Number)]);
|
|
744
|
+
const columnStyles = Array.from(allKeys).reduce((acc, key) => {
|
|
745
|
+
const widthStyle = columnStylesWidth[key] || {};
|
|
746
|
+
const alignmentStyle = columnStylesAlignment[key] || {};
|
|
747
|
+
return {
|
|
748
|
+
...acc,
|
|
749
|
+
[key]: {
|
|
750
|
+
...widthStyle,
|
|
751
|
+
...alignmentStyle
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
}, {});
|
|
755
|
+
return {
|
|
756
|
+
head: [schema.head],
|
|
757
|
+
body,
|
|
758
|
+
showHead: schema.showHead,
|
|
759
|
+
startY: schema.position.y,
|
|
760
|
+
tableWidth: schema.width,
|
|
761
|
+
tableLineColor: schema.tableStyles.borderColor,
|
|
762
|
+
tableLineWidth: schema.tableStyles.borderWidth,
|
|
763
|
+
headStyles: mapCellStyle(schema.headStyles),
|
|
764
|
+
bodyStyles: mapCellStyle(schema.bodyStyles),
|
|
765
|
+
alternateRowStyles: { backgroundColor: schema.bodyStyles.alternateBackgroundColor },
|
|
766
|
+
columnStyles,
|
|
767
|
+
margin: {
|
|
768
|
+
top: 0,
|
|
769
|
+
right: 0,
|
|
770
|
+
left: schema.position.x,
|
|
771
|
+
bottom: 0
|
|
772
|
+
}
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
function parseStyles(cInput) {
|
|
776
|
+
const styleOptions = {
|
|
777
|
+
styles: {},
|
|
778
|
+
headStyles: {},
|
|
779
|
+
bodyStyles: {},
|
|
780
|
+
alternateRowStyles: {},
|
|
781
|
+
columnStyles: {}
|
|
782
|
+
};
|
|
783
|
+
for (const prop of Object.keys(styleOptions)) if (prop === "columnStyles") {
|
|
784
|
+
const current = cInput[prop];
|
|
785
|
+
styleOptions.columnStyles = Object.assign({}, current);
|
|
786
|
+
} else {
|
|
787
|
+
const styles = [cInput].map((opts) => opts[prop] || {});
|
|
788
|
+
styleOptions[prop] = Object.assign({}, styles[0], styles[1], styles[2]);
|
|
789
|
+
}
|
|
790
|
+
return styleOptions;
|
|
791
|
+
}
|
|
792
|
+
function parseContent4Input(options) {
|
|
793
|
+
const head = options.head || [];
|
|
794
|
+
const body = options.body || [];
|
|
795
|
+
return {
|
|
796
|
+
columns: (head[0] || body[0] || []).map((_, index) => index),
|
|
797
|
+
head,
|
|
798
|
+
body
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
function parseInput(schema, body) {
|
|
802
|
+
const options = getTableOptions(schema, body);
|
|
803
|
+
const styles = parseStyles(options);
|
|
804
|
+
const settings = {
|
|
805
|
+
startY: options.startY,
|
|
806
|
+
margin: options.margin,
|
|
807
|
+
tableWidth: options.tableWidth,
|
|
808
|
+
showHead: options.showHead,
|
|
809
|
+
tableLineWidth: options.tableLineWidth ?? 0,
|
|
810
|
+
tableLineColor: options.tableLineColor ?? ""
|
|
811
|
+
};
|
|
812
|
+
return {
|
|
813
|
+
content: parseContent4Input(options),
|
|
814
|
+
styles,
|
|
815
|
+
settings
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
function createSingleTable(body, args) {
|
|
819
|
+
const { options, _cache, basePdf } = args;
|
|
820
|
+
if (!isBlankPdf(basePdf)) console.warn("[@pdfme/schema/table]When specifying a custom PDF for basePdf, you cannot use features such as page breaks or re-layout of other elements.To utilize these features, please define basePdf as follows:\n{ width: number; height: number; padding: [number, number, number, number]; }");
|
|
821
|
+
const schema = cloneDeep(args.schema);
|
|
822
|
+
const { start } = schema.__bodyRange || { start: 0 };
|
|
823
|
+
if (start % 2 === 1) {
|
|
824
|
+
const alternateBackgroundColor = schema.bodyStyles.alternateBackgroundColor;
|
|
825
|
+
schema.bodyStyles.alternateBackgroundColor = schema.bodyStyles.backgroundColor;
|
|
826
|
+
schema.bodyStyles.backgroundColor = alternateBackgroundColor;
|
|
827
|
+
}
|
|
828
|
+
schema.showHead = schema.showHead === false ? false : !schema.__isSplit || schema.repeatHead === true;
|
|
829
|
+
const input = parseInput(schema, body);
|
|
830
|
+
const font = options.font || getDefaultFont();
|
|
831
|
+
const content = parseContent4Table(input, getFallbackFontName(font));
|
|
832
|
+
return Table.create({
|
|
833
|
+
input,
|
|
834
|
+
content,
|
|
835
|
+
font,
|
|
836
|
+
_cache
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
//#endregion
|
|
840
|
+
//#region src/constants.ts
|
|
841
|
+
var HEX_COLOR_PATTERN = "^#(?:[A-Fa-f0-9]{6})$";
|
|
842
|
+
//#endregion
|
|
843
|
+
//#region src/tables/helper.ts
|
|
844
|
+
var getDefaultCellStyles = () => ({
|
|
845
|
+
fontName: void 0,
|
|
846
|
+
alignment: DEFAULT_ALIGNMENT,
|
|
847
|
+
verticalAlignment: VERTICAL_ALIGN_MIDDLE,
|
|
848
|
+
fontSize: 13,
|
|
849
|
+
lineHeight: 1,
|
|
850
|
+
characterSpacing: 0,
|
|
851
|
+
fontColor: DEFAULT_FONT_COLOR,
|
|
852
|
+
backgroundColor: "",
|
|
853
|
+
borderColor: "#888888",
|
|
854
|
+
borderWidth: {
|
|
855
|
+
top: .1,
|
|
856
|
+
bottom: .1,
|
|
857
|
+
left: .1,
|
|
858
|
+
right: .1
|
|
859
|
+
},
|
|
860
|
+
padding: {
|
|
861
|
+
top: 5,
|
|
862
|
+
bottom: 5,
|
|
863
|
+
left: 5,
|
|
864
|
+
right: 5
|
|
865
|
+
}
|
|
866
|
+
});
|
|
867
|
+
var getBoxDimensionProp = (step = 1) => {
|
|
868
|
+
const getCommonProp = () => ({
|
|
869
|
+
type: "number",
|
|
870
|
+
widget: "inputNumber",
|
|
871
|
+
props: {
|
|
872
|
+
min: 0,
|
|
873
|
+
step
|
|
874
|
+
},
|
|
875
|
+
span: 6
|
|
876
|
+
});
|
|
877
|
+
return {
|
|
878
|
+
top: {
|
|
879
|
+
title: "Top",
|
|
880
|
+
...getCommonProp()
|
|
881
|
+
},
|
|
882
|
+
right: {
|
|
883
|
+
title: "Right",
|
|
884
|
+
...getCommonProp()
|
|
885
|
+
},
|
|
886
|
+
bottom: {
|
|
887
|
+
title: "Bottom",
|
|
888
|
+
...getCommonProp()
|
|
889
|
+
},
|
|
890
|
+
left: {
|
|
891
|
+
title: "Left",
|
|
892
|
+
...getCommonProp()
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
};
|
|
896
|
+
var getCellPropPanelSchema = (arg) => {
|
|
897
|
+
const { i18n, fallbackFontName, fontNames, isBody } = arg;
|
|
898
|
+
return {
|
|
899
|
+
fontName: {
|
|
900
|
+
title: i18n("schemas.text.fontName"),
|
|
901
|
+
type: "string",
|
|
902
|
+
widget: "select",
|
|
903
|
+
default: fallbackFontName,
|
|
904
|
+
placeholder: fallbackFontName,
|
|
905
|
+
props: { options: fontNames.map((name) => ({
|
|
906
|
+
label: name,
|
|
907
|
+
value: name
|
|
908
|
+
})) },
|
|
909
|
+
span: 12
|
|
910
|
+
},
|
|
911
|
+
fontSize: {
|
|
912
|
+
title: i18n("schemas.text.size"),
|
|
913
|
+
type: "number",
|
|
914
|
+
widget: "inputNumber",
|
|
915
|
+
props: { min: 0 },
|
|
916
|
+
span: 6
|
|
917
|
+
},
|
|
918
|
+
characterSpacing: {
|
|
919
|
+
title: i18n("schemas.text.spacing"),
|
|
920
|
+
type: "number",
|
|
921
|
+
widget: "inputNumber",
|
|
922
|
+
props: { min: 0 },
|
|
923
|
+
span: 6
|
|
924
|
+
},
|
|
925
|
+
alignment: {
|
|
926
|
+
title: i18n("schemas.text.textAlign"),
|
|
927
|
+
type: "string",
|
|
928
|
+
widget: "select",
|
|
929
|
+
props: { options: [
|
|
930
|
+
{
|
|
931
|
+
label: i18n("schemas.left"),
|
|
932
|
+
value: ALIGN_LEFT
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
label: i18n("schemas.center"),
|
|
936
|
+
value: ALIGN_CENTER
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
label: i18n("schemas.right"),
|
|
940
|
+
value: ALIGN_RIGHT
|
|
941
|
+
}
|
|
942
|
+
] },
|
|
943
|
+
span: 8
|
|
944
|
+
},
|
|
945
|
+
verticalAlignment: {
|
|
946
|
+
title: i18n("schemas.text.verticalAlign"),
|
|
947
|
+
type: "string",
|
|
948
|
+
widget: "select",
|
|
949
|
+
props: { options: [
|
|
950
|
+
{
|
|
951
|
+
label: i18n("schemas.top"),
|
|
952
|
+
value: "top"
|
|
953
|
+
},
|
|
954
|
+
{
|
|
955
|
+
label: i18n("schemas.middle"),
|
|
956
|
+
value: VERTICAL_ALIGN_MIDDLE
|
|
957
|
+
},
|
|
958
|
+
{
|
|
959
|
+
label: i18n("schemas.bottom"),
|
|
960
|
+
value: VERTICAL_ALIGN_BOTTOM
|
|
961
|
+
}
|
|
962
|
+
] },
|
|
963
|
+
span: 8
|
|
964
|
+
},
|
|
965
|
+
lineHeight: {
|
|
966
|
+
title: i18n("schemas.text.lineHeight"),
|
|
967
|
+
type: "number",
|
|
968
|
+
widget: "inputNumber",
|
|
969
|
+
props: {
|
|
970
|
+
step: .1,
|
|
971
|
+
min: 0
|
|
972
|
+
},
|
|
973
|
+
span: 8
|
|
974
|
+
},
|
|
975
|
+
fontColor: {
|
|
976
|
+
title: i18n("schemas.textColor"),
|
|
977
|
+
type: "string",
|
|
978
|
+
widget: "color",
|
|
979
|
+
props: { disabledAlpha: true },
|
|
980
|
+
rules: [{
|
|
981
|
+
pattern: HEX_COLOR_PATTERN,
|
|
982
|
+
message: i18n("validation.hexColor")
|
|
983
|
+
}]
|
|
984
|
+
},
|
|
985
|
+
borderColor: {
|
|
986
|
+
title: i18n("schemas.borderColor"),
|
|
987
|
+
type: "string",
|
|
988
|
+
widget: "color",
|
|
989
|
+
props: { disabledAlpha: true },
|
|
990
|
+
rules: [{
|
|
991
|
+
pattern: HEX_COLOR_PATTERN,
|
|
992
|
+
message: i18n("validation.hexColor")
|
|
993
|
+
}]
|
|
994
|
+
},
|
|
995
|
+
backgroundColor: {
|
|
996
|
+
title: i18n("schemas.backgroundColor"),
|
|
997
|
+
type: "string",
|
|
998
|
+
widget: "color",
|
|
999
|
+
props: { disabledAlpha: true },
|
|
1000
|
+
rules: [{
|
|
1001
|
+
pattern: HEX_COLOR_PATTERN,
|
|
1002
|
+
message: i18n("validation.hexColor")
|
|
1003
|
+
}]
|
|
1004
|
+
},
|
|
1005
|
+
...isBody ? { alternateBackgroundColor: {
|
|
1006
|
+
title: i18n("schemas.table.alternateBackgroundColor"),
|
|
1007
|
+
type: "string",
|
|
1008
|
+
widget: "color",
|
|
1009
|
+
props: { disabledAlpha: true },
|
|
1010
|
+
rules: [{
|
|
1011
|
+
pattern: HEX_COLOR_PATTERN,
|
|
1012
|
+
message: i18n("validation.hexColor")
|
|
1013
|
+
}]
|
|
1014
|
+
} } : {},
|
|
1015
|
+
"-": {
|
|
1016
|
+
type: "void",
|
|
1017
|
+
widget: "Divider"
|
|
1018
|
+
},
|
|
1019
|
+
borderWidth: {
|
|
1020
|
+
title: i18n("schemas.borderWidth"),
|
|
1021
|
+
type: "object",
|
|
1022
|
+
widget: "lineTitle",
|
|
1023
|
+
span: 24,
|
|
1024
|
+
properties: getBoxDimensionProp(.1)
|
|
1025
|
+
},
|
|
1026
|
+
"--": {
|
|
1027
|
+
type: "void",
|
|
1028
|
+
widget: "Divider"
|
|
1029
|
+
},
|
|
1030
|
+
padding: {
|
|
1031
|
+
title: i18n("schemas.padding"),
|
|
1032
|
+
type: "object",
|
|
1033
|
+
widget: "lineTitle",
|
|
1034
|
+
span: 24,
|
|
1035
|
+
properties: getBoxDimensionProp()
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
};
|
|
1039
|
+
var getColumnStylesPropPanelSchema = ({ head, i18n }) => ({ alignment: {
|
|
1040
|
+
type: "object",
|
|
1041
|
+
widget: "lineTitle",
|
|
1042
|
+
title: i18n("schemas.text.textAlign"),
|
|
1043
|
+
column: 3,
|
|
1044
|
+
properties: head.reduce((acc, cur, i) => Object.assign(acc, { [i]: {
|
|
1045
|
+
title: cur || "Column " + String(i + 1),
|
|
1046
|
+
type: "string",
|
|
1047
|
+
widget: "select",
|
|
1048
|
+
props: { options: [
|
|
1049
|
+
{
|
|
1050
|
+
label: i18n("schemas.left"),
|
|
1051
|
+
value: ALIGN_LEFT
|
|
1052
|
+
},
|
|
1053
|
+
{
|
|
1054
|
+
label: i18n("schemas.center"),
|
|
1055
|
+
value: ALIGN_CENTER
|
|
1056
|
+
},
|
|
1057
|
+
{
|
|
1058
|
+
label: i18n("schemas.right"),
|
|
1059
|
+
value: ALIGN_RIGHT
|
|
1060
|
+
}
|
|
1061
|
+
] }
|
|
1062
|
+
} }), {})
|
|
1063
|
+
} });
|
|
1064
|
+
var getBody = (value) => {
|
|
1065
|
+
if (typeof value === "string") return JSON.parse(value || "[]");
|
|
1066
|
+
return value || [];
|
|
1067
|
+
};
|
|
1068
|
+
var getBodyWithRange = (value, range) => {
|
|
1069
|
+
const body = getBody(value);
|
|
1070
|
+
if (!range) return body;
|
|
1071
|
+
return body.slice(range.start, range.end);
|
|
1072
|
+
};
|
|
1073
|
+
//#endregion
|
|
1074
|
+
//#region src/tables/dynamicTemplate.ts
|
|
1075
|
+
var getDynamicHeightsForTable = async (value, args) => {
|
|
1076
|
+
if (args.schema.type !== "table") return Promise.resolve([args.schema.height]);
|
|
1077
|
+
const schema = args.schema;
|
|
1078
|
+
const table = await createSingleTable(schema.__bodyRange?.start === 0 ? getBody(value) : getBodyWithRange(value, schema.__bodyRange), args);
|
|
1079
|
+
const baseHeights = schema.showHead ? table.allRows().map((row) => row.height) : [0].concat(table.body.map((row) => row.height));
|
|
1080
|
+
const headerHeight = schema.showHead ? table.getHeadHeight() : 0;
|
|
1081
|
+
if (!(schema.repeatHead && isBlankPdf(args.basePdf) && headerHeight > 0)) return baseHeights;
|
|
1082
|
+
const basePdf = args.basePdf;
|
|
1083
|
+
const [paddingTop, , paddingBottom] = basePdf.padding;
|
|
1084
|
+
const pageContentHeight = basePdf.height - paddingTop - paddingBottom;
|
|
1085
|
+
const getPageStartY = (pageIndex) => pageIndex * pageContentHeight + paddingTop;
|
|
1086
|
+
const initialPageIndex = Math.max(0, Math.floor((schema.position.y - paddingTop) / pageContentHeight));
|
|
1087
|
+
const headRowCount = schema.showHead ? table.head.length : 0;
|
|
1088
|
+
const SAFETY_MARGIN = .5;
|
|
1089
|
+
let currentPageIndex = initialPageIndex;
|
|
1090
|
+
let currentPageY = schema.position.y;
|
|
1091
|
+
let rowsOnCurrentPage = 0;
|
|
1092
|
+
const result = [];
|
|
1093
|
+
for (let i = 0; i < baseHeights.length; i++) {
|
|
1094
|
+
const isBodyRow = i >= headRowCount;
|
|
1095
|
+
const rowHeight = baseHeights[i];
|
|
1096
|
+
while (true) {
|
|
1097
|
+
const currentPageStartY = getPageStartY(currentPageIndex);
|
|
1098
|
+
const remainingHeight = currentPageStartY + pageContentHeight - currentPageY;
|
|
1099
|
+
const totalRowHeight = rowHeight + (isBodyRow && rowsOnCurrentPage === 0 && currentPageIndex > initialPageIndex ? headerHeight : 0);
|
|
1100
|
+
if (totalRowHeight > remainingHeight - SAFETY_MARGIN) {
|
|
1101
|
+
if (rowsOnCurrentPage === 0 && Math.abs(currentPageY - currentPageStartY) < SAFETY_MARGIN) {
|
|
1102
|
+
result.push(totalRowHeight);
|
|
1103
|
+
currentPageY += totalRowHeight;
|
|
1104
|
+
rowsOnCurrentPage++;
|
|
1105
|
+
break;
|
|
1106
|
+
}
|
|
1107
|
+
currentPageIndex++;
|
|
1108
|
+
currentPageY = getPageStartY(currentPageIndex);
|
|
1109
|
+
rowsOnCurrentPage = 0;
|
|
1110
|
+
continue;
|
|
1111
|
+
}
|
|
1112
|
+
result.push(totalRowHeight);
|
|
1113
|
+
currentPageY += totalRowHeight;
|
|
1114
|
+
rowsOnCurrentPage++;
|
|
1115
|
+
if (currentPageY >= currentPageStartY + pageContentHeight - SAFETY_MARGIN) {
|
|
1116
|
+
currentPageIndex++;
|
|
1117
|
+
currentPageY = getPageStartY(currentPageIndex);
|
|
1118
|
+
rowsOnCurrentPage = 0;
|
|
1119
|
+
}
|
|
1120
|
+
break;
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
return result;
|
|
1124
|
+
};
|
|
1125
|
+
//#endregion
|
|
1126
|
+
export { DEFAULT_FONT_COLOR as C, VERTICAL_ALIGN_BOTTOM as D, PLACEHOLDER_FONT_COLOR as E, VERTICAL_ALIGN_MIDDLE as O, DEFAULT_DYNAMIC_FIT as S, DYNAMIC_FIT_VERTICAL as T, widthOfTextAtSize as _, getColumnStylesPropPanelSchema as a, ALIGN_RIGHT as b, createSingleTable as c, getBrowserVerticalFontAdjustments as d, getFontDescentInPt as f, splitTextToSize as g, isFirefox as h, getCellPropPanelSchema as i, calculateDynamicFontSize as l, heightOfFontAtSize as m, getBody as n, getDefaultCellStyles as o, getFontKitFont as p, getBodyWithRange as r, HEX_COLOR_PATTERN as s, getDynamicHeightsForTable as t, fetchRemoteFontData as u, ALIGN_CENTER as v, DYNAMIC_FIT_HORIZONTAL as w, DEFAULT_ALIGNMENT as x, ALIGN_JUSTIFY as y };
|
|
1127
|
+
|
|
1128
|
+
//# sourceMappingURL=dynamicTemplate-D_DHR3-X.js.map
|