@pdfme/common 1.1.10 → 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/dist/cjs/__tests__/calculateDynamicFontSize.test.js +97 -0
- package/dist/cjs/__tests__/calculateDynamicFontSize.test.js.map +1 -0
- package/dist/cjs/src/calculateDynamicFontSize.js +103 -0
- package/dist/cjs/src/calculateDynamicFontSize.js.map +1 -0
- package/dist/cjs/src/constants.js +6 -2
- package/dist/cjs/src/constants.js.map +1 -1
- package/dist/cjs/src/helper.js +3 -10
- package/dist/cjs/src/helper.js.map +1 -1
- package/dist/cjs/src/index.js +8 -2
- package/dist/cjs/src/index.js.map +1 -1
- package/dist/cjs/src/schema.js +11 -6
- package/dist/cjs/src/schema.js.map +1 -1
- package/dist/cjs/src/type.js.map +1 -1
- package/dist/esm/__tests__/calculateDynamicFontSize.test.js +72 -0
- package/dist/esm/__tests__/calculateDynamicFontSize.test.js.map +1 -0
- package/dist/esm/src/calculateDynamicFontSize.js +76 -0
- package/dist/esm/src/calculateDynamicFontSize.js.map +1 -0
- package/dist/esm/src/constants.js +5 -1
- package/dist/esm/src/constants.js.map +1 -1
- package/dist/esm/src/helper.js +4 -11
- package/dist/esm/src/helper.js.map +1 -1
- package/dist/esm/src/index.js +3 -2
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/schema.js +10 -5
- package/dist/esm/src/schema.js.map +1 -1
- package/dist/esm/src/type.js.map +1 -1
- package/dist/types/__tests__/calculateDynamicFontSize.test.d.ts +1 -0
- package/dist/types/src/calculateDynamicFontSize.d.ts +6 -0
- package/dist/types/src/constants.d.ts +5 -1
- package/dist/types/src/index.d.ts +5 -4
- package/dist/types/src/schema.d.ts +386 -43
- package/dist/types/src/type.d.ts +6 -1
- package/package.json +7 -2
- package/src/calculateDynamicFontSize.ts +101 -0
- package/src/constants.ts +6 -2
- package/src/helper.ts +4 -11
- package/src/index.ts +14 -2
- package/src/schema.ts +12 -5
- package/src/type.ts +2 -0
- package/tsconfig.json +6 -0
package/dist/types/src/type.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { z } from 'zod';
|
2
|
-
import { Lang, Size, Alignment, BarcodeSchemaType, SchemaType, CommonSchema as _CommonSchema, TextSchema, ImageSchema, BarcodeSchema, Schema, SchemaForUI, Font, BasePdf, Template, CommonProps, GeneratorOptions, GenerateProps, UIOptions, UIProps, PreviewProps, PreviewReactProps, DesignerProps, DesignerReactProps } from './schema.js';
|
2
|
+
import { Lang, Size, Alignment, BarcodeSchemaType, SchemaType, CommonSchema as _CommonSchema, TextSchema, ImageSchema, BarcodeSchema, Schema, SchemaInputs, SchemaForUI, Font, BasePdf, Template, CommonProps, GeneratorOptions, GenerateProps, UIOptions, UIProps, PreviewProps, PreviewReactProps, DesignerProps, DesignerReactProps } from './schema.js';
|
3
3
|
declare type CommonSchema = z.infer<typeof _CommonSchema>;
|
4
4
|
export declare const schemaTypes: readonly ["text", "image", "qrcode", "japanpost", "ean13", "ean8", "code39", "code128", "nw7", "itf14", "upca", "upce"];
|
5
5
|
export declare const isTextSchema: (arg: CommonSchema) => arg is {
|
@@ -11,6 +11,10 @@ export declare const isTextSchema: (arg: CommonSchema) => arg is {
|
|
11
11
|
fontName?: string | undefined;
|
12
12
|
fontColor?: string | undefined;
|
13
13
|
characterSpacing?: number | undefined;
|
14
|
+
dynamicFontSize?: {
|
15
|
+
max: number;
|
16
|
+
min: number;
|
17
|
+
} | undefined;
|
14
18
|
type: "text";
|
15
19
|
height: number;
|
16
20
|
width: number;
|
@@ -48,6 +52,7 @@ export declare type TextSchema = z.infer<typeof TextSchema>;
|
|
48
52
|
export declare type ImageSchema = z.infer<typeof ImageSchema>;
|
49
53
|
export declare type BarcodeSchema = z.infer<typeof BarcodeSchema>;
|
50
54
|
export declare type Schema = z.infer<typeof Schema>;
|
55
|
+
export declare type SchemaInputs = z.infer<typeof SchemaInputs>;
|
51
56
|
export declare type SchemaForUI = z.infer<typeof SchemaForUI>;
|
52
57
|
export declare type Font = z.infer<typeof Font>;
|
53
58
|
export declare type BasePdf = z.infer<typeof BasePdf>;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@pdfme/common",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.2.0",
|
4
4
|
"sideEffects": false,
|
5
5
|
"author": "hand-dot",
|
6
6
|
"license": "MIT",
|
@@ -34,7 +34,7 @@
|
|
34
34
|
"node": ">=14"
|
35
35
|
},
|
36
36
|
"scripts": {
|
37
|
-
"develop": "tsc -w",
|
37
|
+
"develop": "tsc -p tsconfig.esm.json -w",
|
38
38
|
"build": "npm run build:cjs && npm run build:esm",
|
39
39
|
"build:cjs": "tsc -p tsconfig.cjs.json",
|
40
40
|
"build:esm": "tsc -p tsconfig.esm.json",
|
@@ -46,6 +46,8 @@
|
|
46
46
|
"prune": "ts-prune src"
|
47
47
|
},
|
48
48
|
"dependencies": {
|
49
|
+
"buffer": "^6.0.3",
|
50
|
+
"fontkit": "^2.0.2",
|
49
51
|
"zod": "^3.20.2"
|
50
52
|
},
|
51
53
|
"jest": {
|
@@ -68,5 +70,8 @@
|
|
68
70
|
},
|
69
71
|
"publishConfig": {
|
70
72
|
"access": "public"
|
73
|
+
},
|
74
|
+
"devDependencies": {
|
75
|
+
"@types/fontkit": "^2.0.3"
|
71
76
|
}
|
72
77
|
}
|
@@ -0,0 +1,101 @@
|
|
1
|
+
import * as fontkit from 'fontkit';
|
2
|
+
import { TextSchema, Font } from './type';
|
3
|
+
import { Buffer } from 'buffer';
|
4
|
+
import {
|
5
|
+
DEFAULT_FONT_VALUE,
|
6
|
+
DEFAULT_FONT_NAME,
|
7
|
+
DEFAULT_FONT_SIZE,
|
8
|
+
DEFAULT_CHARACTER_SPACING,
|
9
|
+
DEFAULT_TOLERANCE,
|
10
|
+
DEFAULT_FONT_SIZE_ADJUSTMENT,
|
11
|
+
DEFAULT_PT_TO_MM_RATIO
|
12
|
+
} from './constants';
|
13
|
+
import { b64toUint8Array } from "."
|
14
|
+
|
15
|
+
const widthOfTextAtSize = (input: string, fontKitFont: fontkit.Font, fontSize: number) => {
|
16
|
+
const { glyphs } = fontKitFont.layout(input);
|
17
|
+
const scale = 1000 / fontKitFont.unitsPerEm;
|
18
|
+
return glyphs.reduce((totalWidth, glyph) => totalWidth + glyph.advanceWidth * scale, 0) * (fontSize / 1000);
|
19
|
+
}
|
20
|
+
|
21
|
+
const calculateCharacterSpacing = (
|
22
|
+
textContent: string,
|
23
|
+
textCharacterSpacing: number
|
24
|
+
) => {
|
25
|
+
const numberOfCharacters = textContent.length;
|
26
|
+
return (numberOfCharacters - 1) * textCharacterSpacing;
|
27
|
+
};
|
28
|
+
|
29
|
+
const calculateTextWidthInMm = (textContent: string, textWidth: number, textCharacterSpacing: number) =>
|
30
|
+
(textWidth + calculateCharacterSpacing(textContent, textCharacterSpacing)) * DEFAULT_PT_TO_MM_RATIO;
|
31
|
+
|
32
|
+
const getLongestLine = (
|
33
|
+
textContentRows: string[],
|
34
|
+
fontKitFont: fontkit.Font,
|
35
|
+
fontSize: number,
|
36
|
+
characterSpacingCount: number
|
37
|
+
) => {
|
38
|
+
let longestLine = '';
|
39
|
+
let maxLineWidth = 0;
|
40
|
+
|
41
|
+
textContentRows.forEach((line) => {
|
42
|
+
const textWidth = widthOfTextAtSize(line, fontKitFont, fontSize);
|
43
|
+
const lineWidth = calculateTextWidthInMm(line, textWidth, characterSpacingCount);
|
44
|
+
|
45
|
+
if (lineWidth > maxLineWidth) {
|
46
|
+
longestLine = line;
|
47
|
+
maxLineWidth = lineWidth;
|
48
|
+
}
|
49
|
+
});
|
50
|
+
|
51
|
+
return longestLine;
|
52
|
+
};
|
53
|
+
|
54
|
+
|
55
|
+
const fontKitFontCache: { [fontName: string]: fontkit.Font } = {};
|
56
|
+
const createFontKitFont = async (font: Font, fontName: string = DEFAULT_FONT_NAME) => {
|
57
|
+
if (fontKitFontCache[fontName]) {
|
58
|
+
return fontKitFontCache[fontName];
|
59
|
+
}
|
60
|
+
|
61
|
+
let fontData = font[fontName]?.data || DEFAULT_FONT_VALUE;
|
62
|
+
if (typeof fontData === 'string') {
|
63
|
+
fontData = fontData.startsWith('http') ? await fetch(fontData).then((res) => res.arrayBuffer()) : b64toUint8Array(fontData);
|
64
|
+
}
|
65
|
+
|
66
|
+
const fontKitFont = fontkit.create(fontData instanceof Buffer ? fontData : Buffer.from(fontData as string));
|
67
|
+
fontKitFontCache[fontName] = fontKitFont
|
68
|
+
|
69
|
+
return fontKitFont;
|
70
|
+
}
|
71
|
+
|
72
|
+
const getTextContent = (input: string, fontKitFont: fontkit.Font, fontSize: number, characterSpacingCount: number): string => {
|
73
|
+
const textContentRows = input.split('\n');
|
74
|
+
return textContentRows.length > 1 ? getLongestLine(textContentRows, fontKitFont, fontSize, characterSpacingCount) : input;
|
75
|
+
}
|
76
|
+
|
77
|
+
export const calculateDynamicFontSize = async ({ textSchema, font, input }: { textSchema: TextSchema, font: Font, input: string }) => {
|
78
|
+
const { fontName, fontSize: _fontSize, dynamicFontSize: dynamicFontSizeSetting, characterSpacing, width } = textSchema;
|
79
|
+
const fontSize = _fontSize || DEFAULT_FONT_SIZE;
|
80
|
+
if (!dynamicFontSizeSetting) return fontSize;
|
81
|
+
|
82
|
+
const characterSpacingCount = characterSpacing ?? DEFAULT_CHARACTER_SPACING;
|
83
|
+
const fontKitFont = await createFontKitFont(font, fontName);
|
84
|
+
const textContent = getTextContent(input, fontKitFont, fontSize, characterSpacingCount);
|
85
|
+
const textWidth = widthOfTextAtSize(textContent, fontKitFont, fontSize);
|
86
|
+
|
87
|
+
let dynamicFontSize = fontSize;
|
88
|
+
let textWidthInMm = calculateTextWidthInMm(textContent, textWidth, characterSpacingCount);
|
89
|
+
|
90
|
+
while (textWidthInMm > width - DEFAULT_TOLERANCE && dynamicFontSize > dynamicFontSizeSetting.min) {
|
91
|
+
dynamicFontSize -= DEFAULT_FONT_SIZE_ADJUSTMENT;
|
92
|
+
textWidthInMm = calculateTextWidthInMm(textContent, widthOfTextAtSize(textContent, fontKitFont, dynamicFontSize), characterSpacingCount);
|
93
|
+
}
|
94
|
+
|
95
|
+
while (textWidthInMm < width - DEFAULT_TOLERANCE && dynamicFontSize < dynamicFontSizeSetting.max) {
|
96
|
+
dynamicFontSize += DEFAULT_FONT_SIZE_ADJUSTMENT;
|
97
|
+
textWidthInMm = calculateTextWidthInMm(textContent, widthOfTextAtSize(textContent, fontKitFont, dynamicFontSize), characterSpacingCount);
|
98
|
+
}
|
99
|
+
|
100
|
+
return dynamicFontSize;
|
101
|
+
};
|