@pdfme/generator 2.0.1 → 2.1.0

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/src/helper.ts CHANGED
@@ -32,7 +32,11 @@ import {
32
32
  DEFAULT_FONT_COLOR,
33
33
  calculateDynamicFontSize,
34
34
  heightOfFontAtSize,
35
- getFontKitFont
35
+ getFontKitFont,
36
+ getSplittedLines,
37
+ mm2pt,
38
+ widthOfTextAtSize,
39
+ FontWidthCalcValues,
36
40
  } from '@pdfme/common';
37
41
  import { Buffer } from 'buffer';
38
42
 
@@ -130,14 +134,7 @@ export const getEmbeddedPagesAndEmbedPdfBoxes = async (arg: {
130
134
  return { embeddedPages, embedPdfBoxes };
131
135
  };
132
136
 
133
- const mm2pt = (mm: number): number => {
134
- // https://www.ddc.co.jp/words/archives/20090701114500.html
135
- const ptRatio = 2.8346;
136
-
137
- return parseFloat(String(mm)) * ptRatio;
138
- };
139
-
140
- const getSchemaSizeAndRotate = (schema: Schema) => {
137
+ const convertSchemaDimensionsToPt = (schema: Schema) => {
141
138
  const width = mm2pt(schema.width);
142
139
  const height = mm2pt(schema.height);
143
140
  const rotate = degrees(schema.rotate ? schema.rotate : 0);
@@ -200,7 +197,7 @@ const drawBackgroundColor = (arg: {
200
197
  }) => {
201
198
  const { templateSchema, page, pageHeight } = arg;
202
199
  if (!templateSchema.backgroundColor) return;
203
- const { width, height } = getSchemaSizeAndRotate(templateSchema);
200
+ const { width, height } = convertSchemaDimensionsToPt(templateSchema);
204
201
  const color = hex2RgbColor(templateSchema.backgroundColor);
205
202
  page.drawRectangle({
206
203
  x: calcX(templateSchema.position.x, 'left', width, width),
@@ -211,57 +208,6 @@ const drawBackgroundColor = (arg: {
211
208
  });
212
209
  };
213
210
 
214
- type IsOverEval = (testString: string) => boolean;
215
-
216
- /**
217
- * Incrementally checks the current line for its real length
218
- * and returns the position where it exceeds the box width.
219
- * Returns `null` to indicate if inputLine is shorter as the available bbox.
220
- */
221
- const getOverPosition = (inputLine: string, isOverEval: IsOverEval) => {
222
- for (let i = 0; i <= inputLine.length; i++) {
223
- if (isOverEval(inputLine.slice(0, i))) {
224
- return i;
225
- }
226
- }
227
-
228
- return null;
229
- };
230
-
231
- /**
232
- * Gets the position of the split. Splits the exceeding line at
233
- * the last whitespace over it exceeds the bounding box width.
234
- */
235
- const getSplitPosition = (inputLine: string, isOverEval: IsOverEval) => {
236
- const overPos = getOverPosition(inputLine, isOverEval);
237
- if (overPos === null) return inputLine.length; // input line is shorter than the available space
238
-
239
- let overPosTmp = overPos;
240
- while (inputLine[overPosTmp] !== ' ' && overPosTmp >= 0) {
241
- overPosTmp--;
242
- }
243
-
244
- // For very long lines with no whitespace use the original overPos
245
- return overPosTmp > 0 ? overPosTmp : overPos - 1;
246
- };
247
-
248
- /**
249
- * Recursively splits the line at getSplitPosition.
250
- * If there is some leftover, split the rest again in the same manner.
251
- */
252
- const getSplittedLines = (inputLine: string, isOverEval: IsOverEval): string[] => {
253
- const splitPos = getSplitPosition(inputLine, isOverEval);
254
- const splittedLine = inputLine.substring(0, splitPos);
255
- const rest = inputLine.substring(splitPos).trimStart();
256
-
257
- if (rest.length === 0) {
258
- // end recursion if there is no rest
259
- return [splittedLine];
260
- }
261
-
262
- return [splittedLine, ...getSplittedLines(rest, isOverEval)];
263
- };
264
-
265
211
  interface FontSetting {
266
212
  font: Font;
267
213
  pdfFontObj: {
@@ -275,18 +221,18 @@ const drawInputByTextSchema = async (arg: {
275
221
  templateSchema: TextSchema;
276
222
  pdfDoc: PDFDocument;
277
223
  page: PDFPage;
278
- pageHeight: number;
279
224
  fontSetting: FontSetting;
280
225
  }) => {
281
- const { input, templateSchema, page, pageHeight, fontSetting } = arg;
226
+ const { input, templateSchema, page, fontSetting } = arg;
282
227
  const { font, pdfFontObj, fallbackFontName } = fontSetting;
283
228
 
284
229
  const pdfFontValue = pdfFontObj[templateSchema.fontName ? templateSchema.fontName : fallbackFontName];
285
- const fontKitFont = await getFontKitFont(templateSchema, font)
230
+ const fontKitFont = await getFontKitFont(templateSchema, font);
286
231
 
232
+ const pageHeight = page.getHeight();
287
233
  drawBackgroundColor({ templateSchema, page, pageHeight });
288
234
 
289
- const { width, height, rotate } = getSchemaSizeAndRotate(templateSchema);
235
+ const { width, height, rotate } = convertSchemaDimensionsToPt(templateSchema);
290
236
  const { size, color, alignment, lineHeight, characterSpacing } = await getFontProp({
291
237
  input,
292
238
  font,
@@ -297,16 +243,18 @@ const drawInputByTextSchema = async (arg: {
297
243
 
298
244
  let beforeLineOver = 0;
299
245
 
300
- const isOverEval = (testString: string) => {
301
- const testStringWidth =
302
- pdfFontValue.widthOfTextAtSize(testString, size) + (testString.length - 1) * characterSpacing;
303
- return width <= testStringWidth;
246
+ const fontWidthCalcValues: FontWidthCalcValues = {
247
+ font: fontKitFont,
248
+ fontSize: size,
249
+ characterSpacing,
250
+ boxWidthInPt: width,
304
251
  };
252
+
305
253
  input.split(/\r|\n|\r\n/g).forEach((inputLine, inputLineIndex) => {
306
- const splitLines = getSplittedLines(inputLine, isOverEval);
254
+ const splitLines = getSplittedLines(inputLine, fontWidthCalcValues);
307
255
 
308
256
  const drawLine = (line: string, lineIndex: number) => {
309
- const textWidth = pdfFontValue.widthOfTextAtSize(line, size) + (line.length - 1) * characterSpacing;
257
+ const textWidth = widthOfTextAtSize(line, fontKitFont, size, characterSpacing);
310
258
  const textHeight = heightOfFontAtSize(fontKitFont, size);
311
259
 
312
260
  page.drawText(line, {
@@ -337,17 +285,16 @@ const getCacheKey = (templateSchema: Schema, input: string) => `${templateSchema
337
285
  const drawInputByImageSchema = async (arg: {
338
286
  input: string;
339
287
  templateSchema: ImageSchema;
340
- pageHeight: number;
341
288
  pdfDoc: PDFDocument;
342
289
  page: PDFPage;
343
290
  inputImageCache: InputImageCache;
344
291
  }) => {
345
- const { input, templateSchema, pageHeight, pdfDoc, page, inputImageCache } = arg;
292
+ const { input, templateSchema, pdfDoc, page, inputImageCache } = arg;
346
293
 
347
- const { width, height, rotate } = getSchemaSizeAndRotate(templateSchema);
294
+ const { width, height, rotate } = convertSchemaDimensionsToPt(templateSchema);
348
295
  const opt = {
349
296
  x: calcX(templateSchema.position.x, 'left', width, width),
350
- y: calcY(templateSchema.position.y, pageHeight, height),
297
+ y: calcY(templateSchema.position.y, page.getHeight(), height),
351
298
  rotate,
352
299
  width,
353
300
  height,
@@ -365,18 +312,17 @@ const drawInputByImageSchema = async (arg: {
365
312
  const drawInputByBarcodeSchema = async (arg: {
366
313
  input: string;
367
314
  templateSchema: BarcodeSchema;
368
- pageHeight: number;
369
315
  pdfDoc: PDFDocument;
370
316
  page: PDFPage;
371
317
  inputImageCache: InputImageCache;
372
318
  }) => {
373
- const { input, templateSchema, pageHeight, pdfDoc, page, inputImageCache } = arg;
319
+ const { input, templateSchema, pdfDoc, page, inputImageCache } = arg;
374
320
  if (!validateBarcodeInput(templateSchema.type as BarCodeType, input)) return;
375
321
 
376
- const { width, height, rotate } = getSchemaSizeAndRotate(templateSchema);
322
+ const { width, height, rotate } = convertSchemaDimensionsToPt(templateSchema);
377
323
  const opt = {
378
324
  x: calcX(templateSchema.position.x, 'left', width, width),
379
- y: calcY(templateSchema.position.y, pageHeight, height),
325
+ y: calcY(templateSchema.position.y, page.getHeight(), height),
380
326
  rotate,
381
327
  width,
382
328
  height,
@@ -398,7 +344,6 @@ export const drawInputByTemplateSchema = async (arg: {
398
344
  templateSchema: Schema;
399
345
  pdfDoc: PDFDocument;
400
346
  page: PDFPage;
401
- pageHeight: number;
402
347
  fontSetting: FontSetting;
403
348
  inputImageCache: InputImageCache;
404
349
  }) => {