@pdfme/generator 1.1.9 → 1.2.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
@@ -8,7 +8,7 @@ import {
8
8
  degrees,
9
9
  setCharacterSpacing,
10
10
  TransformationMatrix,
11
- } from 'pdf-lib';
11
+ } from '@pdfme/pdf-lib';
12
12
  import bwipjs, { ToBufferOptions } from 'bwip-js';
13
13
  import {
14
14
  getB64BasePdf,
@@ -30,6 +30,7 @@ import {
30
30
  DEFAULT_LINE_HEIGHT,
31
31
  DEFAULT_CHARACTER_SPACING,
32
32
  DEFAULT_FONT_COLOR,
33
+ calculateDynamicFontSize,
33
34
  } from '@pdfme/common';
34
35
 
35
36
  export interface InputImageCache {
@@ -166,8 +167,8 @@ const hex2RgbColor = (hexString: string | undefined) => {
166
167
  return undefined;
167
168
  };
168
169
 
169
- const getFontProp = (schema: TextSchema) => {
170
- const size = schema.fontSize ?? DEFAULT_FONT_SIZE;
170
+ const getFontProp = async ({ input, font, schema }: { input: string, font: Font, schema: TextSchema }) => {
171
+ const size = schema.dynamicFontSize ? await calculateDynamicFontSize({ textSchema: schema, font, input }) : schema.fontSize ?? DEFAULT_FONT_SIZE;
171
172
  const color = hex2RgbColor(schema.fontColor ?? DEFAULT_FONT_COLOR);
172
173
  const alignment = schema.alignment ?? DEFAULT_ALIGNMENT;
173
174
  const lineHeight = schema.lineHeight ?? DEFAULT_LINE_HEIGHT;
@@ -208,15 +209,15 @@ const drawBackgroundColor = (arg: {
208
209
  };
209
210
 
210
211
  type IsOverEval = (testString: string) => boolean;
212
+
211
213
  /**
212
- * Incrementally check the current line for it's real length
213
- * and return the position where it exceeds the box width.
214
- *
215
- * return `null` to indicate if inputLine is shorter as the available bbox
214
+ * Incrementally checks the current line for its real length
215
+ * and returns the position where it exceeds the box width.
216
+ * Returns `null` to indicate if inputLine is shorter as the available bbox.
216
217
  */
217
218
  const getOverPosition = (inputLine: string, isOverEval: IsOverEval) => {
218
- for (let i = 0; i <= inputLine.length; i += 1) {
219
- if (isOverEval(inputLine.substr(0, i))) {
219
+ for (let i = 0; i <= inputLine.length; i++) {
220
+ if (isOverEval(inputLine.slice(0, i))) {
220
221
  return i;
221
222
  }
222
223
  }
@@ -225,69 +226,64 @@ const getOverPosition = (inputLine: string, isOverEval: IsOverEval) => {
225
226
  };
226
227
 
227
228
  /**
228
- * Get position of the split. Split the exceeding line at
229
+ * Gets the position of the split. Splits the exceeding line at
229
230
  * the last whitespace over it exceeds the bounding box width.
230
231
  */
231
232
  const getSplitPosition = (inputLine: string, isOverEval: IsOverEval) => {
232
233
  const overPos = getOverPosition(inputLine, isOverEval);
233
- /**
234
- * if input line is shorter as the available space. We split at the end of the line
235
- */
236
- if (overPos === null) return inputLine.length;
234
+ if (overPos === null) return inputLine.length; // input line is shorter than the available space
235
+
237
236
  let overPosTmp = overPos;
238
- while (inputLine[overPosTmp] !== ' ' && overPosTmp >= 0) overPosTmp -= 1;
239
- /**
240
- * for very long lines with no whitespace use the original overPos and
241
- * split one char over so we do not overfill the box
242
- */
237
+ while (inputLine[overPosTmp] !== ' ' && overPosTmp >= 0) {
238
+ overPosTmp--;
239
+ }
243
240
 
241
+ // For very long lines with no whitespace use the original overPos
244
242
  return overPosTmp > 0 ? overPosTmp : overPos - 1;
245
243
  };
246
244
 
247
245
  /**
248
- * recursively split the line at getSplitPosition.
246
+ * Recursively splits the line at getSplitPosition.
249
247
  * If there is some leftover, split the rest again in the same manner.
250
248
  */
251
249
  const getSplittedLines = (inputLine: string, isOverEval: IsOverEval): string[] => {
252
250
  const splitPos = getSplitPosition(inputLine, isOverEval);
253
- const splittedLine = inputLine.substr(0, splitPos);
254
- const rest = inputLine.slice(splitPos).trimLeft();
255
- /**
256
- * end recursion if there is no rest, return single splitted line in an array
257
- * so we can join them over the recursion
258
- */
259
- if (rest.length === 0) {
251
+ const splittedLine = inputLine.substring(0, splitPos);
252
+ const rest = inputLine.substring(splitPos).trimStart();
253
+
254
+ if (rest.length === 0) { // end recursion if there is no rest
260
255
  return [splittedLine];
261
256
  }
262
257
 
263
258
  return [splittedLine, ...getSplittedLines(rest, isOverEval)];
264
259
  };
265
260
 
266
- interface TextSchemaSetting {
267
- fontObj: {
261
+ interface FontSetting {
262
+ font: Font;
263
+ pdfFontObj: {
268
264
  [key: string]: PDFFont;
269
265
  };
270
266
  fallbackFontName: string;
271
- splitThreshold: number;
272
267
  }
273
268
 
274
- const drawInputByTextSchema = (arg: {
269
+ const drawInputByTextSchema = async (arg: {
275
270
  input: string;
276
271
  templateSchema: TextSchema;
277
272
  pdfDoc: PDFDocument;
278
273
  page: PDFPage;
279
274
  pageHeight: number;
280
- textSchemaSetting: TextSchemaSetting;
275
+ fontSetting: FontSetting;
281
276
  }) => {
282
- const { input, templateSchema, page, pageHeight, textSchemaSetting } = arg;
283
- const { fontObj, fallbackFontName, splitThreshold } = textSchemaSetting;
277
+ const { input, templateSchema, page, pageHeight, fontSetting } = arg;
278
+ const { font, pdfFontObj, fallbackFontName } = fontSetting;
284
279
 
285
- const fontValue = fontObj[templateSchema.fontName ? templateSchema.fontName : fallbackFontName];
280
+ const pdfFontValue = pdfFontObj[templateSchema.fontName ? templateSchema.fontName : fallbackFontName];
286
281
 
287
282
  drawBackgroundColor({ templateSchema, page, pageHeight });
288
283
 
289
284
  const { width, rotate } = getSchemaSizeAndRotate(templateSchema);
290
- const { size, color, alignment, lineHeight, characterSpacing } = getFontProp(templateSchema);
285
+ const { size, color, alignment, lineHeight, characterSpacing } = await getFontProp({ input, font, schema: templateSchema });
286
+
291
287
  page.pushOperators(setCharacterSpacing(characterSpacing));
292
288
 
293
289
  let beforeLineOver = 0;
@@ -295,18 +291,13 @@ const drawInputByTextSchema = (arg: {
295
291
  input.split(/\r|\n|\r\n/g).forEach((inputLine, inputLineIndex) => {
296
292
  const isOverEval = (testString: string) => {
297
293
  const testStringWidth =
298
- fontValue.widthOfTextAtSize(testString, size) + (testString.length - 1) * characterSpacing;
299
- /**
300
- * split if the difference is less then two pixel
301
- * (found out / tested this threshold heuristically, most probably widthOfTextAtSize is unprecise)
302
- **/
303
-
304
- return width - testStringWidth <= splitThreshold;
294
+ pdfFontValue.widthOfTextAtSize(testString, size) + (testString.length - 1) * characterSpacing;
295
+ return width <= testStringWidth;
305
296
  };
306
297
  const splitedLines = getSplittedLines(inputLine, isOverEval);
307
298
  const drawLine = (splitedLine: string, splitedLineIndex: number) => {
308
299
  const textWidth =
309
- fontValue.widthOfTextAtSize(splitedLine, size) +
300
+ pdfFontValue.widthOfTextAtSize(splitedLine, size) +
310
301
  (splitedLine.length - 1) * characterSpacing;
311
302
  page.drawText(splitedLine, {
312
303
  x: calcX(templateSchema.position.x, alignment, width, textWidth),
@@ -319,7 +310,7 @@ const drawInputByTextSchema = (arg: {
319
310
  color,
320
311
  lineHeight: lineHeight * size,
321
312
  maxWidth: width,
322
- font: fontValue,
313
+ font: pdfFontValue,
323
314
  wordBreaks: [''],
324
315
  });
325
316
  if (splitedLines.length === splitedLineIndex + 1) beforeLineOver += splitedLineIndex;
@@ -396,14 +387,14 @@ export const drawInputByTemplateSchema = async (arg: {
396
387
  pdfDoc: PDFDocument;
397
388
  page: PDFPage;
398
389
  pageHeight: number;
399
- textSchemaSetting: TextSchemaSetting;
390
+ fontSetting: FontSetting;
400
391
  inputImageCache: InputImageCache;
401
392
  }) => {
402
393
  if (!arg.input || !arg.templateSchema) return;
403
394
 
404
395
  if (isTextSchema(arg.templateSchema)) {
405
396
  const templateSchema = arg.templateSchema as TextSchema;
406
- drawInputByTextSchema({ ...arg, templateSchema });
397
+ await drawInputByTextSchema({ ...arg, templateSchema });
407
398
  } else if (isImageSchema(arg.templateSchema)) {
408
399
  const templateSchema = arg.templateSchema as ImageSchema;
409
400
  await drawInputByImageSchema({ ...arg, templateSchema });
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import generate from './generate.js';
2
2
  import {
3
3
  BLANK_PDF,
4
- HELVETICA,
4
+ DEFAULT_FONT_VALUE,
5
5
  isTextSchema,
6
6
  isImageSchema,
7
7
  isBarcodeSchema,
@@ -38,7 +38,7 @@ import type {
38
38
  export {
39
39
  generate,
40
40
  BLANK_PDF,
41
- HELVETICA,
41
+ DEFAULT_FONT_VALUE,
42
42
  isTextSchema,
43
43
  isImageSchema,
44
44
  isBarcodeSchema,
package/tsconfig.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "./tsconfig.esm",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ }
6
+ }
package/type.d.ts ADDED
@@ -0,0 +1 @@
1
+ declare module 'fontkit';