@pdfme/generator 1.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ export declare const TOOL_NAME: "pdfme (https://github.com/hand-dot/pdfme)";
@@ -0,0 +1,3 @@
1
+ import type { GenerateProps } from '@pdfme/common';
2
+ declare const generate: (props: GenerateProps) => Promise<Uint8Array>;
3
+ export default generate;
@@ -0,0 +1,67 @@
1
+ import { PDFPage, PDFFont, PDFDocument, PDFImage, PDFEmbeddedPage } from 'pdf-lib';
2
+ import { Schema, Font, BasePdf, BarCodeType } from '@pdfme/common';
3
+ export interface InputImageCache {
4
+ [key: string]: PDFImage;
5
+ }
6
+ export declare const createBarCode: (arg: {
7
+ type: BarCodeType;
8
+ input: string;
9
+ width: number;
10
+ height: number;
11
+ backgroundColor?: string;
12
+ }) => Promise<Buffer>;
13
+ declare type EmbedPdfBox = {
14
+ mediaBox: {
15
+ x: number;
16
+ y: number;
17
+ width: number;
18
+ height: number;
19
+ };
20
+ bleedBox: {
21
+ x: number;
22
+ y: number;
23
+ width: number;
24
+ height: number;
25
+ };
26
+ trimBox: {
27
+ x: number;
28
+ y: number;
29
+ width: number;
30
+ height: number;
31
+ };
32
+ };
33
+ export declare const embedAndGetFontObj: (arg: {
34
+ pdfDoc: PDFDocument;
35
+ font: Font;
36
+ }) => Promise<{
37
+ [key: string]: PDFFont;
38
+ }>;
39
+ export declare const getEmbeddedPagesAndEmbedPdfBoxes: (arg: {
40
+ pdfDoc: PDFDocument;
41
+ basePdf: BasePdf;
42
+ }) => Promise<{
43
+ embeddedPages: PDFEmbeddedPage[];
44
+ embedPdfBoxes: EmbedPdfBox[];
45
+ }>;
46
+ interface TextSchemaSetting {
47
+ fontObj: {
48
+ [key: string]: PDFFont;
49
+ };
50
+ fallbackFontName: string;
51
+ splitThreshold: number;
52
+ }
53
+ export declare const drawInputByTemplateSchema: (arg: {
54
+ input: string;
55
+ templateSchema: Schema;
56
+ pdfDoc: PDFDocument;
57
+ page: PDFPage;
58
+ pageHeight: number;
59
+ textSchemaSetting: TextSchemaSetting;
60
+ inputImageCache: InputImageCache;
61
+ }) => Promise<void>;
62
+ export declare const drawEmbeddedPage: (arg: {
63
+ page: PDFPage;
64
+ embeddedPage: PDFEmbeddedPage;
65
+ embedPdfBox: EmbedPdfBox;
66
+ }) => void;
67
+ export {};
@@ -0,0 +1,4 @@
1
+ import generate from './generate';
2
+ export { generate };
3
+ export type { Lang, Size, Alignment, SchemaType, BarCodeType, TextSchema, ImageSchema, BarcodeSchema, Schema, SchemaForUI, Font, BasePdf, Template, CommonProps, GeneratorOptions, GenerateProps, UIOptions, UIProps, PreviewProps, DesignerProps, } from '@pdfme/common';
4
+ export { BLANK_PDF, isTextSchema, isImageSchema, isBarcodeSchema, checkTemplate, checkUIProps, checkPreviewProps, checkDesignerProps, checkGenerateProps, validateBarcodeInput, } from '@pdfme/common';
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@pdfme/generator",
3
+ "version": "1.0.0-beta.10",
4
+ "author": "hand-dot",
5
+ "license": "MIT",
6
+ "description": "TypeScript base PDF generator and React base UI. Open source, developed by the community, and completely free to use under the MIT license!",
7
+ "homepage": "https://pdfme.com",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git@github.com:pdfme/pdfme.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/pdfme/pdfme/issues"
14
+ },
15
+ "main": "dist/index.js",
16
+ "module": "dist/index.js",
17
+ "types": "dist/types/index.d.ts",
18
+ "engines": {
19
+ "node": ">=14"
20
+ },
21
+ "scripts": {
22
+ "develop": "webpack --watch --mode development",
23
+ "build": "NODE_ENV=production webpack --mode production",
24
+ "clean": "rimraf dist",
25
+ "lint": "tsc --noEmit",
26
+ "test": "jest",
27
+ "lint:watch": "tsc -w --noEmit",
28
+ "test:watch": "jest --coverage --watch",
29
+ "prune": "ts-prune src"
30
+ },
31
+ "dependencies": {
32
+ "@pdf-lib/fontkit": "^1.1.1",
33
+ "@pdfme/common": "^1.0.0-beta.10",
34
+ "bwip-js": "^2.1.3",
35
+ "pdf-lib": "^1.17.1"
36
+ },
37
+ "devDependencies": {
38
+ "@types/bwip-js": "^3.0.0",
39
+ "@types/pngjs": "^6.0.1",
40
+ "jsqr": "^1.4.0",
41
+ "node-polyfill-webpack-plugin": "^1.1.4",
42
+ "pdf2json": "^2.0.0",
43
+ "pngjs": "^6.0.0"
44
+ },
45
+ "jest": {
46
+ "moduleNameMapper": {
47
+ "\\.(ttf)$": "<rootDir>/../../fontTransformer.js"
48
+ },
49
+ "moduleFileExtensions": [
50
+ "js",
51
+ "ts"
52
+ ],
53
+ "transform": {
54
+ "^.+\\.ts$": "ts-jest"
55
+ },
56
+ "globals": {
57
+ "ts-jest": {
58
+ "tsconfig": "tsconfig.json"
59
+ }
60
+ },
61
+ "testMatch": [
62
+ "**/*.test.ts"
63
+ ]
64
+ },
65
+ "publishConfig": {
66
+ "access": "public"
67
+ }
68
+ }
@@ -0,0 +1 @@
1
+ export const TOOL_NAME = 'pdfme (https://github.com/hand-dot/pdfme)' as const;
@@ -0,0 +1,87 @@
1
+ import { PDFDocument } from 'pdf-lib';
2
+ import fontkit from '@pdf-lib/fontkit';
3
+ import type { GenerateProps, Template, Font } from '@pdfme/common';
4
+ import { getDefaultFont, getFallbackFontName, checkGenerateProps } from '@pdfme/common';
5
+ import {
6
+ getEmbeddedPagesAndEmbedPdfBoxes,
7
+ drawInputByTemplateSchema,
8
+ drawEmbeddedPage,
9
+ embedAndGetFontObj,
10
+ InputImageCache,
11
+ } from './helper';
12
+ import { TOOL_NAME } from './constants';
13
+
14
+ const preprocessing = async (arg: {
15
+ inputs: { [key: string]: string }[];
16
+ template: Template;
17
+ font: Font;
18
+ }) => {
19
+ const { template, font } = arg;
20
+
21
+ const { basePdf } = template;
22
+
23
+ const pdfDoc = await PDFDocument.create();
24
+ pdfDoc.registerFontkit(fontkit);
25
+
26
+ const fallbackFontName = getFallbackFontName(font);
27
+ const fontObj = await embedAndGetFontObj({ pdfDoc, font });
28
+
29
+ const pagesAndBoxes = await getEmbeddedPagesAndEmbedPdfBoxes({ pdfDoc, basePdf });
30
+ const { embeddedPages, embedPdfBoxes } = pagesAndBoxes;
31
+
32
+ return { pdfDoc, fontObj, fallbackFontName, embeddedPages, embedPdfBoxes };
33
+ };
34
+
35
+ const postProcessing = (pdfDoc: PDFDocument) => {
36
+ pdfDoc.setProducer(TOOL_NAME);
37
+ pdfDoc.setCreator(TOOL_NAME);
38
+ };
39
+
40
+ const generate = async (props: GenerateProps) => {
41
+ checkGenerateProps(props);
42
+ const { inputs, template, options = {} } = props;
43
+ const { font = getDefaultFont(), splitThreshold = 3 } = options;
44
+ const { schemas } = template;
45
+
46
+ const preRes = await preprocessing({ inputs, template, font });
47
+ const { pdfDoc, fontObj, fallbackFontName, embeddedPages, embedPdfBoxes } = preRes;
48
+
49
+ const inputImageCache: InputImageCache = {};
50
+ for (let i = 0; i < inputs.length; i += 1) {
51
+ const inputObj = inputs[i];
52
+ const keys = Object.keys(inputObj);
53
+ for (let j = 0; j < embeddedPages.length; j += 1) {
54
+ const embeddedPage = embeddedPages[j];
55
+ const { width: pageWidth, height: pageHeight } = embeddedPage;
56
+ const embedPdfBox = embedPdfBoxes[j];
57
+
58
+ const page = pdfDoc.addPage([pageWidth, pageHeight]);
59
+
60
+ drawEmbeddedPage({ page, embeddedPage, embedPdfBox });
61
+ for (let l = 0; l < keys.length; l += 1) {
62
+ const key = keys[l];
63
+ const schema = schemas[j];
64
+ const templateSchema = schema[key];
65
+ const input = inputObj[key];
66
+ const textSchemaSetting = { fontObj, fallbackFontName, splitThreshold };
67
+
68
+ // eslint-disable-next-line no-await-in-loop
69
+ await drawInputByTemplateSchema({
70
+ input,
71
+ templateSchema,
72
+ pdfDoc,
73
+ page,
74
+ pageHeight,
75
+ textSchemaSetting,
76
+ inputImageCache,
77
+ });
78
+ }
79
+ }
80
+ }
81
+
82
+ postProcessing(pdfDoc);
83
+
84
+ return pdfDoc.save();
85
+ };
86
+
87
+ export default generate;
package/src/helper.ts ADDED
@@ -0,0 +1,427 @@
1
+ import {
2
+ PDFPage,
3
+ PDFFont,
4
+ PDFDocument,
5
+ PDFImage,
6
+ PDFEmbeddedPage,
7
+ rgb,
8
+ degrees,
9
+ setCharacterSpacing,
10
+ TransformationMatrix,
11
+ } from 'pdf-lib';
12
+ import { ToBufferOptions } from "bwip-js";
13
+ import bwipjsNode from 'bwip-js/dist/node-bwipjs';
14
+ import bwipjsBrowser from 'bwip-js/dist/bwip-js';
15
+ import {
16
+ getB64BasePdf,
17
+ b64toUint8Array,
18
+ validateBarcodeInput,
19
+ Schema,
20
+ TextSchema,
21
+ isTextSchema,
22
+ ImageSchema,
23
+ isImageSchema,
24
+ BarcodeSchema,
25
+ isBarcodeSchema,
26
+ Font,
27
+ BasePdf,
28
+ BarCodeType,
29
+ Alignment,
30
+ DEFAULT_FONT_SIZE,
31
+ DEFAULT_ALIGNMENT,
32
+ DEFAULT_LINE_HEIGHT,
33
+ DEFAULT_CHARACTER_SPACING,
34
+ DEFAULT_FONT_COLOR,
35
+ } from '@pdfme/common';
36
+
37
+ export interface InputImageCache {
38
+ [key: string]: PDFImage;
39
+ }
40
+
41
+ const barCodeType2Bcid = (type: BarCodeType) => (type === 'nw7' ? 'rationalizedCodabar' : type);
42
+ export const createBarCode = async (arg: {
43
+ type: BarCodeType;
44
+ input: string;
45
+ width: number;
46
+ height: number;
47
+ backgroundColor?: string;
48
+ }): Promise<Buffer> => {
49
+ const { type, input, width, height, backgroundColor } = arg;
50
+ const bcid = barCodeType2Bcid(type);
51
+ const includetext = true;
52
+ const scale = 5;
53
+ const bwipjsArg: ToBufferOptions = { bcid, text: input, width, height, scale, includetext };
54
+
55
+ if (backgroundColor) {
56
+ bwipjsArg.backgroundcolor = backgroundColor;
57
+ }
58
+
59
+ let res: Buffer;
60
+
61
+ if (typeof window !== 'undefined') {
62
+ const canvas = document.createElement('canvas');
63
+ bwipjsBrowser.toCanvas(canvas, bwipjsArg);
64
+ const dataUrl = canvas.toDataURL('image/png');
65
+ res = b64toUint8Array(dataUrl).buffer as Buffer;
66
+ } else {
67
+ res = await bwipjsNode.toBuffer(bwipjsArg);
68
+ }
69
+
70
+ return res;
71
+ };
72
+
73
+ type EmbedPdfBox = {
74
+ mediaBox: { x: number; y: number; width: number; height: number };
75
+ bleedBox: { x: number; y: number; width: number; height: number };
76
+ trimBox: { x: number; y: number; width: number; height: number };
77
+ };
78
+
79
+ export const embedAndGetFontObj = async (arg: { pdfDoc: PDFDocument; font: Font }) => {
80
+ const { pdfDoc, font } = arg;
81
+ const fontValues = await Promise.all(
82
+ Object.values(font).map((v) =>
83
+ pdfDoc.embedFont(v.data, {
84
+ subset: typeof v.subset === 'undefined' ? true : v.subset,
85
+ })
86
+ )
87
+ );
88
+
89
+ return Object.keys(font).reduce(
90
+ (acc, cur, i) => Object.assign(acc, { [cur]: fontValues[i] }),
91
+ {} as { [key: string]: PDFFont }
92
+ );
93
+ };
94
+
95
+ export const getEmbeddedPagesAndEmbedPdfBoxes = async (arg: {
96
+ pdfDoc: PDFDocument;
97
+ basePdf: BasePdf;
98
+ }) => {
99
+ const { pdfDoc, basePdf } = arg;
100
+ let embeddedPages: PDFEmbeddedPage[] = [];
101
+ let embedPdfBoxes: EmbedPdfBox[] = [];
102
+ const willLoadPdf = typeof basePdf === 'string' ? await getB64BasePdf(basePdf) : basePdf;
103
+ const embedPdf = await PDFDocument.load(willLoadPdf);
104
+ const embedPdfPages = embedPdf.getPages();
105
+
106
+ embedPdfBoxes = embedPdfPages.map((p) => ({
107
+ mediaBox: p.getMediaBox(),
108
+ bleedBox: p.getBleedBox(),
109
+ trimBox: p.getTrimBox(),
110
+ }));
111
+
112
+ const boundingBoxes = embedPdfPages.map((p) => {
113
+ const { x, y, width, height } = p.getMediaBox();
114
+
115
+ return { left: x, bottom: y, right: width, top: height + y };
116
+ });
117
+
118
+ const transformationMatrices = embedPdfPages.map(
119
+ () => [1, 0, 0, 1, 0, 0] as TransformationMatrix
120
+ );
121
+
122
+ embeddedPages = await pdfDoc.embedPages(embedPdfPages, boundingBoxes, transformationMatrices);
123
+
124
+ return { embeddedPages, embedPdfBoxes };
125
+ };
126
+
127
+ const mm2pt = (mm: number): number => {
128
+ // https://www.ddc.co.jp/words/archives/20090701114500.html
129
+ const ptRatio = 2.8346;
130
+
131
+ return parseFloat(String(mm)) * ptRatio;
132
+ };
133
+
134
+ const getSchemaSizeAndRotate = (schema: Schema) => {
135
+ const width = mm2pt(schema.width);
136
+ const height = mm2pt(schema.height);
137
+ const rotate = degrees(schema.rotate ? schema.rotate : 0);
138
+
139
+ return { width, height, rotate };
140
+ };
141
+
142
+ const hex2rgb = (hex: string) => {
143
+ if (hex.slice(0, 1) === '#') hex = hex.slice(1);
144
+ if (hex.length === 3)
145
+ hex =
146
+ hex.slice(0, 1) +
147
+ hex.slice(0, 1) +
148
+ hex.slice(1, 2) +
149
+ hex.slice(1, 2) +
150
+ hex.slice(2, 3) +
151
+ hex.slice(2, 3);
152
+
153
+ return [hex.slice(0, 2), hex.slice(2, 4), hex.slice(4, 6)].map((str) => parseInt(str, 16));
154
+ };
155
+
156
+ const hex2RgbColor = (hexString: string | undefined) => {
157
+ if (hexString) {
158
+ const [r, g, b] = hex2rgb(hexString);
159
+
160
+ return rgb(r / 255, g / 255, b / 255);
161
+ }
162
+
163
+ // eslint-disable-next-line no-undefined
164
+ return undefined;
165
+ };
166
+
167
+ const getFontProp = (schema: TextSchema) => {
168
+ const size = schema.fontSize ?? DEFAULT_FONT_SIZE;
169
+ const color = hex2RgbColor(schema.fontColor ?? DEFAULT_FONT_COLOR);
170
+ const alignment = schema.alignment ?? DEFAULT_ALIGNMENT;
171
+ const lineHeight = schema.lineHeight ?? DEFAULT_LINE_HEIGHT;
172
+ const characterSpacing = schema.characterSpacing ?? DEFAULT_CHARACTER_SPACING;
173
+
174
+ return { size, color, alignment, lineHeight, characterSpacing };
175
+ };
176
+
177
+ const calcX = (x: number, alignment: Alignment, boxWidth: number, textWidth: number) => {
178
+ let addition = 0;
179
+ if (alignment === 'center') {
180
+ addition = (boxWidth - textWidth) / 2;
181
+ } else if (alignment === 'right') {
182
+ addition = boxWidth - textWidth;
183
+ }
184
+
185
+ return mm2pt(x) + addition;
186
+ };
187
+
188
+ const calcY = (y: number, height: number, itemHeight: number) => height - mm2pt(y) - itemHeight;
189
+
190
+ const drawBackgroundColor = (arg: {
191
+ templateSchema: TextSchema;
192
+ page: PDFPage;
193
+ pageHeight: number;
194
+ }) => {
195
+ const { templateSchema, page, pageHeight } = arg;
196
+ if (!templateSchema.backgroundColor) return;
197
+ const { width, height } = getSchemaSizeAndRotate(templateSchema);
198
+ const color = hex2RgbColor(templateSchema.backgroundColor);
199
+ page.drawRectangle({
200
+ x: calcX(templateSchema.position.x, 'left', width, width),
201
+ y: calcY(templateSchema.position.y, pageHeight, height),
202
+ width,
203
+ height,
204
+ color,
205
+ });
206
+ };
207
+
208
+ type IsOverEval = (testString: string) => boolean;
209
+ /**
210
+ * Incrementally check the current line for it's real length
211
+ * and return the position where it exceeds the box width.
212
+ *
213
+ * return `null` to indicate if inputLine is shorter as the available bbox
214
+ */
215
+ const getOverPosition = (inputLine: string, isOverEval: IsOverEval) => {
216
+ for (let i = 0; i <= inputLine.length; i += 1) {
217
+ if (isOverEval(inputLine.substr(0, i))) {
218
+ return i;
219
+ }
220
+ }
221
+
222
+ return null;
223
+ };
224
+
225
+ /**
226
+ * Get position of the split. Split the exceeding line at
227
+ * the last whitespace over it exceeds the bounding box width.
228
+ */
229
+ const getSplitPosition = (inputLine: string, isOverEval: IsOverEval) => {
230
+ const overPos = getOverPosition(inputLine, isOverEval);
231
+ /**
232
+ * if input line is shorter as the available space. We split at the end of the line
233
+ */
234
+ if (overPos === null) return inputLine.length;
235
+ let overPosTmp = overPos;
236
+ while (inputLine[overPosTmp] !== ' ' && overPosTmp >= 0) overPosTmp -= 1;
237
+ /**
238
+ * for very long lines with no whitespace use the original overPos and
239
+ * split one char over so we do not overfill the box
240
+ */
241
+
242
+ return overPosTmp > 0 ? overPosTmp : overPos - 1;
243
+ };
244
+
245
+ /**
246
+ * recursively split the line at getSplitPosition.
247
+ * If there is some leftover, split the rest again in the same manner.
248
+ */
249
+ const getSplittedLines = (inputLine: string, isOverEval: IsOverEval): string[] => {
250
+ const splitPos = getSplitPosition(inputLine, isOverEval);
251
+ const splittedLine = inputLine.substr(0, splitPos);
252
+ const rest = inputLine.slice(splitPos).trimLeft();
253
+ /**
254
+ * end recursion if there is no rest, return single splitted line in an array
255
+ * so we can join them over the recursion
256
+ */
257
+ if (rest.length === 0) {
258
+ return [splittedLine];
259
+ }
260
+
261
+ return [splittedLine, ...getSplittedLines(rest, isOverEval)];
262
+ };
263
+
264
+ interface TextSchemaSetting {
265
+ fontObj: {
266
+ [key: string]: PDFFont;
267
+ };
268
+ fallbackFontName: string;
269
+ splitThreshold: number;
270
+ }
271
+
272
+ const drawInputByTextSchema = (arg: {
273
+ input: string;
274
+ templateSchema: TextSchema;
275
+ pdfDoc: PDFDocument;
276
+ page: PDFPage;
277
+ pageHeight: number;
278
+ textSchemaSetting: TextSchemaSetting;
279
+ }) => {
280
+ const { input, templateSchema, page, pageHeight, textSchemaSetting } = arg;
281
+ const { fontObj, fallbackFontName, splitThreshold } = textSchemaSetting;
282
+
283
+ const fontValue = fontObj[templateSchema.fontName ? templateSchema.fontName : fallbackFontName];
284
+
285
+ drawBackgroundColor({ templateSchema, page, pageHeight });
286
+
287
+ const { width, rotate } = getSchemaSizeAndRotate(templateSchema);
288
+ const { size, color, alignment, lineHeight, characterSpacing } = getFontProp(templateSchema);
289
+ page.pushOperators(setCharacterSpacing(characterSpacing));
290
+
291
+ let beforeLineOver = 0;
292
+
293
+ input.split(/\r|\n|\r\n/g).forEach((inputLine, inputLineIndex) => {
294
+ const isOverEval = (testString: string) => {
295
+ const testStringWidth =
296
+ fontValue.widthOfTextAtSize(testString, size) + (testString.length - 1) * characterSpacing;
297
+ /**
298
+ * split if the difference is less then two pixel
299
+ * (found out / tested this threshold heuristically, most probably widthOfTextAtSize is unprecise)
300
+ **/
301
+
302
+ return width - testStringWidth <= splitThreshold;
303
+ };
304
+ const splitedLines = getSplittedLines(inputLine, isOverEval);
305
+ const drawLine = (splitedLine: string, splitedLineIndex: number) => {
306
+ const textWidth =
307
+ fontValue.widthOfTextAtSize(splitedLine, size) +
308
+ (splitedLine.length - 1) * characterSpacing;
309
+ page.drawText(splitedLine, {
310
+ x: calcX(templateSchema.position.x, alignment, width, textWidth),
311
+ y:
312
+ calcY(templateSchema.position.y, pageHeight, size) -
313
+ lineHeight * size * (inputLineIndex + splitedLineIndex + beforeLineOver) -
314
+ (lineHeight === 0 ? 0 : ((lineHeight - 1) * size) / 2),
315
+ rotate,
316
+ size,
317
+ color,
318
+ lineHeight: lineHeight * size,
319
+ maxWidth: width,
320
+ font: fontValue,
321
+ wordBreaks: [''],
322
+ });
323
+ if (splitedLines.length === splitedLineIndex + 1) beforeLineOver += splitedLineIndex;
324
+ };
325
+
326
+ splitedLines.forEach(drawLine);
327
+ });
328
+ };
329
+
330
+ const getCacheKey = (templateSchema: Schema, input: string) => `${templateSchema.type}${input}`;
331
+
332
+ const drawInputByImageSchema = async (arg: {
333
+ input: string;
334
+ templateSchema: ImageSchema;
335
+ pageHeight: number;
336
+ pdfDoc: PDFDocument;
337
+ page: PDFPage;
338
+ inputImageCache: InputImageCache;
339
+ }) => {
340
+ const { input, templateSchema, pageHeight, pdfDoc, page, inputImageCache } = arg;
341
+
342
+ const { width, height, rotate } = getSchemaSizeAndRotate(templateSchema);
343
+ const opt = {
344
+ x: calcX(templateSchema.position.x, 'left', width, width),
345
+ y: calcY(templateSchema.position.y, pageHeight, height),
346
+ rotate,
347
+ width,
348
+ height,
349
+ };
350
+ const inputImageCacheKey = getCacheKey(templateSchema, input);
351
+ let image = inputImageCache[inputImageCacheKey];
352
+ if (!image) {
353
+ const isPng = input.startsWith('data:image/png;');
354
+ image = await (isPng ? pdfDoc.embedPng(input) : pdfDoc.embedJpg(input));
355
+ }
356
+ inputImageCache[inputImageCacheKey] = image;
357
+ page.drawImage(image, opt);
358
+ };
359
+
360
+ const drawInputByBarcodeSchema = async (arg: {
361
+ input: string;
362
+ templateSchema: BarcodeSchema;
363
+ pageHeight: number;
364
+ pdfDoc: PDFDocument;
365
+ page: PDFPage;
366
+ inputImageCache: InputImageCache;
367
+ }) => {
368
+ const { input, templateSchema, pageHeight, pdfDoc, page, inputImageCache } = arg;
369
+
370
+ const { width, height, rotate } = getSchemaSizeAndRotate(templateSchema);
371
+ const opt = {
372
+ x: calcX(templateSchema.position.x, 'left', width, width),
373
+ y: calcY(templateSchema.position.y, pageHeight, height),
374
+ rotate,
375
+ width,
376
+ height,
377
+ };
378
+ const inputBarcodeCacheKey = getCacheKey(templateSchema, input);
379
+ let image = inputImageCache[inputBarcodeCacheKey];
380
+ if (!image && validateBarcodeInput(templateSchema.type as BarCodeType, input)) {
381
+ const imageBuf = await createBarCode({
382
+ ...{ ...templateSchema, type: templateSchema.type as BarCodeType },
383
+ input,
384
+ });
385
+ if (imageBuf) {
386
+ image = await pdfDoc.embedPng(imageBuf);
387
+ }
388
+ }
389
+ inputImageCache[inputBarcodeCacheKey] = image;
390
+ page.drawImage(image, opt);
391
+ };
392
+
393
+ export const drawInputByTemplateSchema = async (arg: {
394
+ input: string;
395
+ templateSchema: Schema;
396
+ pdfDoc: PDFDocument;
397
+ page: PDFPage;
398
+ pageHeight: number;
399
+ textSchemaSetting: TextSchemaSetting;
400
+ inputImageCache: InputImageCache;
401
+ }) => {
402
+ if (!arg.input || !arg.templateSchema) return;
403
+
404
+ if (isTextSchema(arg.templateSchema)) {
405
+ const templateSchema = arg.templateSchema as TextSchema;
406
+ drawInputByTextSchema({ ...arg, templateSchema });
407
+ } else if (isImageSchema(arg.templateSchema)) {
408
+ const templateSchema = arg.templateSchema as ImageSchema;
409
+ await drawInputByImageSchema({ ...arg, templateSchema });
410
+ } else if (isBarcodeSchema(arg.templateSchema)) {
411
+ const templateSchema = arg.templateSchema as BarcodeSchema;
412
+ await drawInputByBarcodeSchema({ ...arg, templateSchema });
413
+ }
414
+ };
415
+
416
+ export const drawEmbeddedPage = (arg: {
417
+ page: PDFPage;
418
+ embeddedPage: PDFEmbeddedPage;
419
+ embedPdfBox: EmbedPdfBox;
420
+ }) => {
421
+ const { page, embeddedPage, embedPdfBox } = arg;
422
+ page.drawPage(embeddedPage);
423
+ const { mediaBox: mb, bleedBox: bb, trimBox: tb } = embedPdfBox;
424
+ page.setMediaBox(mb.x, mb.y, mb.width, mb.height);
425
+ page.setBleedBox(bb.x, bb.y, bb.width, bb.height);
426
+ page.setTrimBox(tb.x, tb.y, tb.width, tb.height);
427
+ };
package/src/index.ts ADDED
@@ -0,0 +1,39 @@
1
+ import generate from './generate';
2
+
3
+ export { generate };
4
+
5
+ export type {
6
+ Lang,
7
+ Size,
8
+ Alignment,
9
+ SchemaType,
10
+ BarCodeType,
11
+ TextSchema,
12
+ ImageSchema,
13
+ BarcodeSchema,
14
+ Schema,
15
+ SchemaForUI,
16
+ Font,
17
+ BasePdf,
18
+ Template,
19
+ CommonProps,
20
+ GeneratorOptions,
21
+ GenerateProps,
22
+ UIOptions,
23
+ UIProps,
24
+ PreviewProps,
25
+ DesignerProps,
26
+ } from '@pdfme/common';
27
+
28
+ export {
29
+ BLANK_PDF,
30
+ isTextSchema,
31
+ isImageSchema,
32
+ isBarcodeSchema,
33
+ checkTemplate,
34
+ checkUIProps,
35
+ checkPreviewProps,
36
+ checkDesignerProps,
37
+ checkGenerateProps,
38
+ validateBarcodeInput,
39
+ } from '@pdfme/common';