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