@jasy/pdf 1.0.0-alpha.1
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/README.md +171 -0
- package/dist/api/args.d.ts +10 -0
- package/dist/api/args.js +13 -0
- package/dist/api/color.d.ts +24 -0
- package/dist/api/color.js +215 -0
- package/dist/api/content.d.ts +36 -0
- package/dist/api/content.js +50 -0
- package/dist/api/descriptor.d.ts +25 -0
- package/dist/api/descriptor.js +71 -0
- package/dist/api/index.d.ts +8 -0
- package/dist/api/index.js +27 -0
- package/dist/api/insets.d.ts +16 -0
- package/dist/api/insets.js +21 -0
- package/dist/api/layout.d.ts +72 -0
- package/dist/api/layout.js +99 -0
- package/dist/api/structure.d.ts +80 -0
- package/dist/api/structure.js +125 -0
- package/dist/api/table.d.ts +37 -0
- package/dist/api/table.js +87 -0
- package/dist/api/text.d.ts +28 -0
- package/dist/api/text.js +61 -0
- package/dist/assets/Courier-Bold.afm +342 -0
- package/dist/assets/Courier-BoldOblique.afm +342 -0
- package/dist/assets/Courier-Oblique.afm +342 -0
- package/dist/assets/Courier.afm +342 -0
- package/dist/assets/Helvetica-Bold.afm +2827 -0
- package/dist/assets/Helvetica-BoldOblique.afm +2827 -0
- package/dist/assets/Helvetica-Oblique.afm +3051 -0
- package/dist/assets/Helvetica.afm +3051 -0
- package/dist/assets/Symbol.afm +213 -0
- package/dist/assets/Times-Bold.afm +2588 -0
- package/dist/assets/Times-BoldItalic.afm +2384 -0
- package/dist/assets/Times-Italic.afm +2667 -0
- package/dist/assets/Times-Roman.afm +2419 -0
- package/dist/assets/ZapfDingbats.afm +225 -0
- package/dist/assets/agl.txt +695 -0
- package/dist/common/color.d.ts +37 -0
- package/dist/common/color.js +62 -0
- package/dist/constants/page-sizes.d.ts +44 -0
- package/dist/constants/page-sizes.js +92 -0
- package/dist/constants/pdf-parts.d.ts +5 -0
- package/dist/constants/pdf-parts.js +8 -0
- package/dist/elements/container-element.d.ts +35 -0
- package/dist/elements/container-element.js +91 -0
- package/dist/elements/image-element.d.ts +56 -0
- package/dist/elements/image-element.js +151 -0
- package/dist/elements/index.d.ts +10 -0
- package/dist/elements/index.js +28 -0
- package/dist/elements/layout/deferred-element.d.ts +19 -0
- package/dist/elements/layout/deferred-element.js +33 -0
- package/dist/elements/layout/expanded-element.d.ts +30 -0
- package/dist/elements/layout/expanded-element.js +68 -0
- package/dist/elements/layout/padding-element.d.ts +29 -0
- package/dist/elements/layout/padding-element.js +76 -0
- package/dist/elements/layout/repeating-header-element.d.ts +29 -0
- package/dist/elements/layout/repeating-header-element.js +60 -0
- package/dist/elements/layout/sized-container-element.d.ts +14 -0
- package/dist/elements/layout/sized-container-element.js +37 -0
- package/dist/elements/line-element.d.ts +31 -0
- package/dist/elements/line-element.js +44 -0
- package/dist/elements/page-element.d.ts +58 -0
- package/dist/elements/page-element.js +90 -0
- package/dist/elements/pdf-document-element.d.ts +13 -0
- package/dist/elements/pdf-document-element.js +22 -0
- package/dist/elements/pdf-element.d.ts +67 -0
- package/dist/elements/pdf-element.js +55 -0
- package/dist/elements/rectangle-element.d.ts +55 -0
- package/dist/elements/rectangle-element.js +120 -0
- package/dist/elements/row-element.d.ts +42 -0
- package/dist/elements/row-element.js +54 -0
- package/dist/elements/text-element.d.ts +59 -0
- package/dist/elements/text-element.js +137 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +21 -0
- package/dist/ir/display-list.d.ts +74 -0
- package/dist/ir/display-list.js +2 -0
- package/dist/layout/box-constraints.d.ts +56 -0
- package/dist/layout/box-constraints.js +73 -0
- package/dist/layout/fragmentation.d.ts +42 -0
- package/dist/layout/fragmentation.js +61 -0
- package/dist/renderer/container-renderer.d.ts +6 -0
- package/dist/renderer/container-renderer.js +30 -0
- package/dist/renderer/deferred-renderer.d.ts +6 -0
- package/dist/renderer/deferred-renderer.js +25 -0
- package/dist/renderer/expanded-renderer.d.ts +6 -0
- package/dist/renderer/expanded-renderer.js +23 -0
- package/dist/renderer/image-renderer.d.ts +6 -0
- package/dist/renderer/image-renderer.js +85 -0
- package/dist/renderer/index.d.ts +10 -0
- package/dist/renderer/index.js +26 -0
- package/dist/renderer/line-renderer.d.ts +6 -0
- package/dist/renderer/line-renderer.js +30 -0
- package/dist/renderer/padding-renderer.d.ts +6 -0
- package/dist/renderer/padding-renderer.js +23 -0
- package/dist/renderer/page-renderer.d.ts +5 -0
- package/dist/renderer/page-renderer.js +81 -0
- package/dist/renderer/pdf-backend.d.ts +45 -0
- package/dist/renderer/pdf-backend.js +184 -0
- package/dist/renderer/pdf-config.d.ts +8 -0
- package/dist/renderer/pdf-config.js +17 -0
- package/dist/renderer/pdf-document-class.d.ts +42 -0
- package/dist/renderer/pdf-document-class.js +118 -0
- package/dist/renderer/pdf-document-renderer.d.ts +20 -0
- package/dist/renderer/pdf-document-renderer.js +104 -0
- package/dist/renderer/pdf-renderer.d.ts +5 -0
- package/dist/renderer/pdf-renderer.js +92 -0
- package/dist/renderer/rectangle-renderer.d.ts +8 -0
- package/dist/renderer/rectangle-renderer.js +61 -0
- package/dist/renderer/repeating-header-renderer.d.ts +6 -0
- package/dist/renderer/repeating-header-renderer.js +28 -0
- package/dist/renderer/row-renderer.d.ts +6 -0
- package/dist/renderer/row-renderer.js +30 -0
- package/dist/renderer/text-renderer.d.ts +9 -0
- package/dist/renderer/text-renderer.js +125 -0
- package/dist/text/line-breaker.d.ts +40 -0
- package/dist/text/line-breaker.js +106 -0
- package/dist/utils/afm-parser.d.ts +12 -0
- package/dist/utils/afm-parser.js +91 -0
- package/dist/utils/flex-layout.d.ts +53 -0
- package/dist/utils/flex-layout.js +119 -0
- package/dist/utils/font-metrics.d.ts +12 -0
- package/dist/utils/font-metrics.js +2 -0
- package/dist/utils/font-path.d.ts +1 -0
- package/dist/utils/font-path.js +19 -0
- package/dist/utils/image-helper.d.ts +43 -0
- package/dist/utils/image-helper.js +206 -0
- package/dist/utils/pdf-object-manager.d.ts +97 -0
- package/dist/utils/pdf-object-manager.js +645 -0
- package/dist/utils/renderer-registry.d.ts +6 -0
- package/dist/utils/renderer-registry.js +19 -0
- package/dist/utils/ttf-parser.d.ts +29 -0
- package/dist/utils/ttf-parser.js +191 -0
- package/dist/utils/ttf-subsetter.d.ts +1 -0
- package/dist/utils/ttf-subsetter.js +161 -0
- package/dist/utils/utf8-to-windows1252-encoder.d.ts +2 -0
- package/dist/utils/utf8-to-windows1252-encoder.js +55 -0
- package/dist/validators/element-validator.d.ts +8 -0
- package/dist/validators/element-validator.js +61 -0
- package/package.json +50 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare class Color {
|
|
2
|
+
private r;
|
|
3
|
+
private g;
|
|
4
|
+
private b;
|
|
5
|
+
private alpha;
|
|
6
|
+
constructor(r: number, g: number, b: number, alpha?: number);
|
|
7
|
+
/** Opacity in 0..1 (1 = opaque). */
|
|
8
|
+
getAlpha(): number;
|
|
9
|
+
/** True when the color is not fully opaque and needs an ExtGState to render. */
|
|
10
|
+
isTransparent(): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Ensures that the color value is between 0 and 255. If the value is outside of this range,
|
|
13
|
+
* it is clamped to the nearest valid value (0 or 255), and a warning is logged.
|
|
14
|
+
*
|
|
15
|
+
* @param value The color value to be clamped.
|
|
16
|
+
* @param channel The color channel being adjusted ('r', 'g', or 'b').
|
|
17
|
+
* @returns The clamped value between 0 and 255.
|
|
18
|
+
*/
|
|
19
|
+
private clampColorValue;
|
|
20
|
+
/**
|
|
21
|
+
* Converts the current color to grayscale based on the perceived luminance of the color.
|
|
22
|
+
*
|
|
23
|
+
* The method uses a weighted sum to calculate the grayscale value, accounting for the
|
|
24
|
+
* human eye's sensitivity to different colors:
|
|
25
|
+
* - Red (R) contributes 30% to the overall brightness.
|
|
26
|
+
* - Green (G) contributes 59% to the overall brightness.
|
|
27
|
+
* - Blue (B) contributes 11% to the overall brightness.
|
|
28
|
+
*
|
|
29
|
+
* The resulting grayscale value is applied equally to the red, green, and blue channels,
|
|
30
|
+
* producing a shade of gray that represents the original color's perceived brightness.
|
|
31
|
+
*
|
|
32
|
+
* @returns {string} A PDF compatible color string
|
|
33
|
+
*/
|
|
34
|
+
toGrayscale(): string;
|
|
35
|
+
toArray(): [number, number, number];
|
|
36
|
+
toPDFColorString(): string;
|
|
37
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Color = void 0;
|
|
4
|
+
class Color {
|
|
5
|
+
constructor(r, g, b, alpha = 1) {
|
|
6
|
+
this.r = this.clampColorValue(r, "r");
|
|
7
|
+
this.g = this.clampColorValue(g, "g");
|
|
8
|
+
this.b = this.clampColorValue(b, "b");
|
|
9
|
+
this.alpha = Math.max(0, Math.min(1, alpha));
|
|
10
|
+
}
|
|
11
|
+
/** Opacity in 0..1 (1 = opaque). */
|
|
12
|
+
getAlpha() {
|
|
13
|
+
return this.alpha;
|
|
14
|
+
}
|
|
15
|
+
/** True when the color is not fully opaque and needs an ExtGState to render. */
|
|
16
|
+
isTransparent() {
|
|
17
|
+
return this.alpha < 1;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Ensures that the color value is between 0 and 255. If the value is outside of this range,
|
|
21
|
+
* it is clamped to the nearest valid value (0 or 255), and a warning is logged.
|
|
22
|
+
*
|
|
23
|
+
* @param value The color value to be clamped.
|
|
24
|
+
* @param channel The color channel being adjusted ('r', 'g', or 'b').
|
|
25
|
+
* @returns The clamped value between 0 and 255.
|
|
26
|
+
*/
|
|
27
|
+
clampColorValue(value, channel) {
|
|
28
|
+
if (value < 0 || value > 255) {
|
|
29
|
+
console.warn(`Warning: ${channel} value ${value} is out of range (0-255). Clamping to valid range.`);
|
|
30
|
+
}
|
|
31
|
+
return Math.max(0, Math.min(255, value));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Converts the current color to grayscale based on the perceived luminance of the color.
|
|
35
|
+
*
|
|
36
|
+
* The method uses a weighted sum to calculate the grayscale value, accounting for the
|
|
37
|
+
* human eye's sensitivity to different colors:
|
|
38
|
+
* - Red (R) contributes 30% to the overall brightness.
|
|
39
|
+
* - Green (G) contributes 59% to the overall brightness.
|
|
40
|
+
* - Blue (B) contributes 11% to the overall brightness.
|
|
41
|
+
*
|
|
42
|
+
* The resulting grayscale value is applied equally to the red, green, and blue channels,
|
|
43
|
+
* producing a shade of gray that represents the original color's perceived brightness.
|
|
44
|
+
*
|
|
45
|
+
* @returns {string} A PDF compatible color string
|
|
46
|
+
*/
|
|
47
|
+
toGrayscale() {
|
|
48
|
+
const [r, g, b] = JSON.parse(JSON.stringify(this.toArray())); // JSON because its better to deep clone it here
|
|
49
|
+
const gray = Math.round(0.3 * r + 0.59 * g + 0.11 * b);
|
|
50
|
+
return `${(gray / 255).toFixed(3)} ${(gray / 255).toFixed(3)} ${(gray / 255).toFixed(3)}`;
|
|
51
|
+
}
|
|
52
|
+
// Returns the color as array `[number, number, number]`
|
|
53
|
+
toArray() {
|
|
54
|
+
return [this.r, this.g, this.b];
|
|
55
|
+
}
|
|
56
|
+
// Returns a PDF compatible color string
|
|
57
|
+
toPDFColorString() {
|
|
58
|
+
const [r, g, b] = this.toArray();
|
|
59
|
+
return `${(r / 255).toFixed(3)} ${(g / 255).toFixed(3)} ${(b / 255).toFixed(3)}`;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.Color = Color;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare enum PageSize {
|
|
2
|
+
A0 = "a0",
|
|
3
|
+
A1 = "a1",
|
|
4
|
+
A2 = "a2",
|
|
5
|
+
A3 = "a3",
|
|
6
|
+
A4 = "a4",
|
|
7
|
+
A5 = "a5",
|
|
8
|
+
A6 = "a6",
|
|
9
|
+
A7 = "a7",
|
|
10
|
+
A8 = "a8",
|
|
11
|
+
A9 = "a9",
|
|
12
|
+
A10 = "a10",
|
|
13
|
+
B0 = "b0",
|
|
14
|
+
B1 = "b1",
|
|
15
|
+
B2 = "b2",
|
|
16
|
+
B3 = "b3",
|
|
17
|
+
B4 = "b4",
|
|
18
|
+
B5 = "b5",
|
|
19
|
+
B6 = "b6",
|
|
20
|
+
B7 = "b7",
|
|
21
|
+
B8 = "b8",
|
|
22
|
+
B9 = "b9",
|
|
23
|
+
B10 = "b10",
|
|
24
|
+
C0 = "c0",
|
|
25
|
+
C1 = "c1",
|
|
26
|
+
C2 = "c2",
|
|
27
|
+
C3 = "c3",
|
|
28
|
+
C4 = "c4",
|
|
29
|
+
C5 = "c5",
|
|
30
|
+
C6 = "c6",
|
|
31
|
+
C7 = "c7",
|
|
32
|
+
C8 = "c8",
|
|
33
|
+
C9 = "c9",
|
|
34
|
+
C10 = "c10",
|
|
35
|
+
DL = "dl",
|
|
36
|
+
LETTER = "letter",
|
|
37
|
+
GOVERNMENT_LETTER = "government-letter",
|
|
38
|
+
LEGAL = "legal",
|
|
39
|
+
JUNIOR_LEGAL = "junior-legal",
|
|
40
|
+
LEDGER = "ledger",
|
|
41
|
+
TABLOID = "tabloid",
|
|
42
|
+
CREDIT_CARD = "credit-card"
|
|
43
|
+
}
|
|
44
|
+
export declare const pageFormats: Record<PageSize, [number, number]>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pageFormats = exports.PageSize = void 0;
|
|
4
|
+
// Definition of all possible page sizes
|
|
5
|
+
var PageSize;
|
|
6
|
+
(function (PageSize) {
|
|
7
|
+
PageSize["A0"] = "a0";
|
|
8
|
+
PageSize["A1"] = "a1";
|
|
9
|
+
PageSize["A2"] = "a2";
|
|
10
|
+
PageSize["A3"] = "a3";
|
|
11
|
+
PageSize["A4"] = "a4";
|
|
12
|
+
PageSize["A5"] = "a5";
|
|
13
|
+
PageSize["A6"] = "a6";
|
|
14
|
+
PageSize["A7"] = "a7";
|
|
15
|
+
PageSize["A8"] = "a8";
|
|
16
|
+
PageSize["A9"] = "a9";
|
|
17
|
+
PageSize["A10"] = "a10";
|
|
18
|
+
PageSize["B0"] = "b0";
|
|
19
|
+
PageSize["B1"] = "b1";
|
|
20
|
+
PageSize["B2"] = "b2";
|
|
21
|
+
PageSize["B3"] = "b3";
|
|
22
|
+
PageSize["B4"] = "b4";
|
|
23
|
+
PageSize["B5"] = "b5";
|
|
24
|
+
PageSize["B6"] = "b6";
|
|
25
|
+
PageSize["B7"] = "b7";
|
|
26
|
+
PageSize["B8"] = "b8";
|
|
27
|
+
PageSize["B9"] = "b9";
|
|
28
|
+
PageSize["B10"] = "b10";
|
|
29
|
+
PageSize["C0"] = "c0";
|
|
30
|
+
PageSize["C1"] = "c1";
|
|
31
|
+
PageSize["C2"] = "c2";
|
|
32
|
+
PageSize["C3"] = "c3";
|
|
33
|
+
PageSize["C4"] = "c4";
|
|
34
|
+
PageSize["C5"] = "c5";
|
|
35
|
+
PageSize["C6"] = "c6";
|
|
36
|
+
PageSize["C7"] = "c7";
|
|
37
|
+
PageSize["C8"] = "c8";
|
|
38
|
+
PageSize["C9"] = "c9";
|
|
39
|
+
PageSize["C10"] = "c10";
|
|
40
|
+
PageSize["DL"] = "dl";
|
|
41
|
+
PageSize["LETTER"] = "letter";
|
|
42
|
+
PageSize["GOVERNMENT_LETTER"] = "government-letter";
|
|
43
|
+
PageSize["LEGAL"] = "legal";
|
|
44
|
+
PageSize["JUNIOR_LEGAL"] = "junior-legal";
|
|
45
|
+
PageSize["LEDGER"] = "ledger";
|
|
46
|
+
PageSize["TABLOID"] = "tabloid";
|
|
47
|
+
PageSize["CREDIT_CARD"] = "credit-card";
|
|
48
|
+
})(PageSize || (exports.PageSize = PageSize = {}));
|
|
49
|
+
// Definition of page formats
|
|
50
|
+
exports.pageFormats = {
|
|
51
|
+
[PageSize.A0]: [2383.94, 3370.39],
|
|
52
|
+
[PageSize.A1]: [1683.78, 2383.94],
|
|
53
|
+
[PageSize.A2]: [1190.55, 1683.78],
|
|
54
|
+
[PageSize.A3]: [841.89, 1190.55],
|
|
55
|
+
[PageSize.A4]: [595.28, 841.89],
|
|
56
|
+
[PageSize.A5]: [419.53, 595.28],
|
|
57
|
+
[PageSize.A6]: [297.64, 419.53],
|
|
58
|
+
[PageSize.A7]: [209.76, 297.64],
|
|
59
|
+
[PageSize.A8]: [147.4, 209.76],
|
|
60
|
+
[PageSize.A9]: [104.88, 147.4],
|
|
61
|
+
[PageSize.A10]: [73.7, 104.88],
|
|
62
|
+
[PageSize.B0]: [2834.65, 4008.19],
|
|
63
|
+
[PageSize.B1]: [2004.09, 2834.65],
|
|
64
|
+
[PageSize.B2]: [1417.32, 2004.09],
|
|
65
|
+
[PageSize.B3]: [1000.63, 1417.32],
|
|
66
|
+
[PageSize.B4]: [708.66, 1000.63],
|
|
67
|
+
[PageSize.B5]: [498.9, 708.66],
|
|
68
|
+
[PageSize.B6]: [354.33, 498.9],
|
|
69
|
+
[PageSize.B7]: [249.45, 354.33],
|
|
70
|
+
[PageSize.B8]: [175.75, 249.45],
|
|
71
|
+
[PageSize.B9]: [124.72, 175.75],
|
|
72
|
+
[PageSize.B10]: [87.87, 124.72],
|
|
73
|
+
[PageSize.C0]: [2599.37, 3676.54],
|
|
74
|
+
[PageSize.C1]: [1836.85, 2599.37],
|
|
75
|
+
[PageSize.C2]: [1298.27, 1836.85],
|
|
76
|
+
[PageSize.C3]: [918.43, 1298.27],
|
|
77
|
+
[PageSize.C4]: [649.13, 918.43],
|
|
78
|
+
[PageSize.C5]: [459.21, 649.13],
|
|
79
|
+
[PageSize.C6]: [323.15, 459.21],
|
|
80
|
+
[PageSize.C7]: [229.61, 323.15],
|
|
81
|
+
[PageSize.C8]: [161.57, 229.61],
|
|
82
|
+
[PageSize.C9]: [113.39, 161.57],
|
|
83
|
+
[PageSize.C10]: [79.37, 113.39],
|
|
84
|
+
[PageSize.DL]: [311.81, 623.62],
|
|
85
|
+
[PageSize.LETTER]: [612, 792],
|
|
86
|
+
[PageSize.GOVERNMENT_LETTER]: [576, 756],
|
|
87
|
+
[PageSize.LEGAL]: [612, 1008],
|
|
88
|
+
[PageSize.JUNIOR_LEGAL]: [576, 360],
|
|
89
|
+
[PageSize.LEDGER]: [1224, 792],
|
|
90
|
+
[PageSize.TABLOID]: [792, 1224],
|
|
91
|
+
[PageSize.CREDIT_CARD]: [153, 243],
|
|
92
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PDF_PARTS = void 0;
|
|
4
|
+
exports.PDF_PARTS = {
|
|
5
|
+
HEADER: "%PDF-1.3",
|
|
6
|
+
TRAILER: (size) => `trailer\n<< /Size ${size} >>\nstartxref\n%%EOF`,
|
|
7
|
+
XREF: "xref", // Placeholder for xref elements
|
|
8
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { MainAlign, CrossAlign } from "../utils/flex-layout";
|
|
2
|
+
import { BoxConstraints, Offset, Size } from "../layout/box-constraints";
|
|
3
|
+
import { Fragmentable, FragmentResult } from "../layout/fragmentation";
|
|
4
|
+
import { LayoutContext, SizedElement, SizedPDFElement, WithChildren } from "./pdf-element";
|
|
5
|
+
interface ContainerElementParams extends SizedElement, WithChildren {
|
|
6
|
+
/** Space between children. */
|
|
7
|
+
gap?: number;
|
|
8
|
+
/** Vertical distribution of the children (main axis). */
|
|
9
|
+
main?: MainAlign;
|
|
10
|
+
/** Horizontal alignment of each child (cross axis); defaults to `stretch`. */
|
|
11
|
+
cross?: CrossAlign;
|
|
12
|
+
}
|
|
13
|
+
export declare class ContainerElement extends SizedPDFElement implements Fragmentable {
|
|
14
|
+
private children;
|
|
15
|
+
private gap;
|
|
16
|
+
private main;
|
|
17
|
+
private cross;
|
|
18
|
+
constructor({ x, y, width, height, children, gap, main, cross }: ContainerElementParams);
|
|
19
|
+
/**
|
|
20
|
+
* Splits the vertical stack across pages. Children are measured against the content
|
|
21
|
+
* width and packed until one would exceed `maxHeight`. That straddling child is itself
|
|
22
|
+
* fragmented if it can be (Slice 1: a text paragraph splits at line boxes); otherwise
|
|
23
|
+
* it moves whole. Everything after the break spills into the remainder. Progress is
|
|
24
|
+
* guaranteed: if nothing fit on the page, the straddling child is forced on (it
|
|
25
|
+
* overflows) so the next region always makes headway.
|
|
26
|
+
*
|
|
27
|
+
* Flex children make the container absorb the leftover space, so it never overflows -
|
|
28
|
+
* in that case we don't fragment and hand the whole container back as `fitted`.
|
|
29
|
+
*/
|
|
30
|
+
fragment(maxHeight: number, width: number, ctx: LayoutContext): FragmentResult;
|
|
31
|
+
private cloneWithChildren;
|
|
32
|
+
calculateLayout(constraints: BoxConstraints, offset: Offset, ctx: LayoutContext): Size;
|
|
33
|
+
getProps(): ContainerElementParams;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContainerElement = void 0;
|
|
4
|
+
const flex_layout_1 = require("../utils/flex-layout");
|
|
5
|
+
const fragmentation_1 = require("../layout/fragmentation");
|
|
6
|
+
const pdf_element_1 = require("./pdf-element");
|
|
7
|
+
class ContainerElement extends pdf_element_1.SizedPDFElement {
|
|
8
|
+
constructor({ x, y, width, height, children, gap, main, cross }) {
|
|
9
|
+
super({ x, y, width, height });
|
|
10
|
+
this.children = children;
|
|
11
|
+
this.gap = gap !== null && gap !== void 0 ? gap : 0;
|
|
12
|
+
this.main = main !== null && main !== void 0 ? main : "start";
|
|
13
|
+
this.cross = cross !== null && cross !== void 0 ? cross : "stretch";
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Splits the vertical stack across pages. Children are measured against the content
|
|
17
|
+
* width and packed until one would exceed `maxHeight`. That straddling child is itself
|
|
18
|
+
* fragmented if it can be (Slice 1: a text paragraph splits at line boxes); otherwise
|
|
19
|
+
* it moves whole. Everything after the break spills into the remainder. Progress is
|
|
20
|
+
* guaranteed: if nothing fit on the page, the straddling child is forced on (it
|
|
21
|
+
* overflows) so the next region always makes headway.
|
|
22
|
+
*
|
|
23
|
+
* Flex children make the container absorb the leftover space, so it never overflows -
|
|
24
|
+
* in that case we don't fragment and hand the whole container back as `fitted`.
|
|
25
|
+
*/
|
|
26
|
+
fragment(maxHeight, width, ctx) {
|
|
27
|
+
const { fitted, remainder } = (0, fragmentation_1.packChildren)(this.children, maxHeight, width, ctx, this.gap);
|
|
28
|
+
// Fits as one region: hand the whole container back so the page renders unchanged
|
|
29
|
+
// (its normal layout distributes flex / fills the page).
|
|
30
|
+
if (remainder.length === 0)
|
|
31
|
+
return { fitted: this, remainder: null };
|
|
32
|
+
return {
|
|
33
|
+
fitted: this.cloneWithChildren(fitted),
|
|
34
|
+
remainder: this.cloneWithChildren(remainder),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
cloneWithChildren(children) {
|
|
38
|
+
return new ContainerElement({
|
|
39
|
+
x: this.x,
|
|
40
|
+
y: this.y,
|
|
41
|
+
width: this.width,
|
|
42
|
+
height: this.height,
|
|
43
|
+
children,
|
|
44
|
+
gap: this.gap,
|
|
45
|
+
main: this.main,
|
|
46
|
+
cross: this.cross,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
calculateLayout(constraints, offset, ctx) {
|
|
50
|
+
// The container fills the width/height it is offered; when an axis is unbounded it
|
|
51
|
+
// shrink-wraps to its children instead (mirrors how Row shrink-wraps). Width unbounded
|
|
52
|
+
// happens for a Column nested in a Row (the Row offers its fixed children unbounded
|
|
53
|
+
// width); passing 0 there would collapse every child to width 0.
|
|
54
|
+
if (constraints.hasBoundedWidth)
|
|
55
|
+
this.width = constraints.maxWidth;
|
|
56
|
+
if (constraints.hasBoundedHeight)
|
|
57
|
+
this.height = constraints.maxHeight;
|
|
58
|
+
this.x = offset.x;
|
|
59
|
+
this.y = offset.y;
|
|
60
|
+
const crossAvail = constraints.hasBoundedWidth ? this.width : Infinity;
|
|
61
|
+
const mainAvail = constraints.hasBoundedHeight ? this.height : Infinity;
|
|
62
|
+
let result = { mainUsed: 0, crossUsed: 0 };
|
|
63
|
+
if (this.children) {
|
|
64
|
+
// Vertical flex stack (main = height, cross = width). The shared helper measures
|
|
65
|
+
// fixed children, distributes the leftover to flex children, and places everything
|
|
66
|
+
// in source order.
|
|
67
|
+
result = flex_layout_1.FlexLayoutHelper.layout(this.children, flex_layout_1.VERTICAL_AXIS, mainAvail, crossAvail, this.y, this.x, { gap: this.gap, main: this.main, cross: this.cross }, ctx);
|
|
68
|
+
}
|
|
69
|
+
// Bounded: fill the offered extent. Unbounded: shrink to the children (height = the
|
|
70
|
+
// stack, width = the widest child). Top-left coordinates; the container draws nothing,
|
|
71
|
+
// and the Y-flip happens once at the IR -> backend seam.
|
|
72
|
+
const width = constraints.hasBoundedWidth ? this.width : result.crossUsed;
|
|
73
|
+
const height = constraints.hasBoundedHeight ? this.height : result.mainUsed;
|
|
74
|
+
this.width = width;
|
|
75
|
+
this.height = height;
|
|
76
|
+
return { width, height };
|
|
77
|
+
}
|
|
78
|
+
getProps() {
|
|
79
|
+
return {
|
|
80
|
+
x: this.x,
|
|
81
|
+
y: this.y,
|
|
82
|
+
width: this.width,
|
|
83
|
+
height: this.height,
|
|
84
|
+
children: this.children,
|
|
85
|
+
gap: this.gap,
|
|
86
|
+
main: this.main,
|
|
87
|
+
cross: this.cross,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.ContainerElement = ContainerElement;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { BoxConstraints, Offset, Size } from "../layout/box-constraints";
|
|
2
|
+
import { LayoutContext, SizedPDFElement } from "./pdf-element";
|
|
3
|
+
export declare enum BoxFit {
|
|
4
|
+
none = "NONE",
|
|
5
|
+
contain = "CONTAIN",
|
|
6
|
+
cover = "COVER",
|
|
7
|
+
fill = "FILL"
|
|
8
|
+
}
|
|
9
|
+
export declare abstract class CustomImage {
|
|
10
|
+
abstract init(): void | Promise<void>;
|
|
11
|
+
abstract getImageType(): string | Promise<string>;
|
|
12
|
+
abstract getFileData(): string | Promise<string>;
|
|
13
|
+
abstract getImageDimensions(): Promise<{
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
18
|
+
export declare class CustomLocalImage extends CustomImage {
|
|
19
|
+
private imagePath;
|
|
20
|
+
private fileBuffer;
|
|
21
|
+
private fileRawData;
|
|
22
|
+
constructor(imagePath: string);
|
|
23
|
+
init(): Promise<void>;
|
|
24
|
+
getImageType(): Promise<string>;
|
|
25
|
+
private loadImage;
|
|
26
|
+
getFileData(): string;
|
|
27
|
+
getImageDimensions(): Promise<{
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
32
|
+
interface ImageElementParams {
|
|
33
|
+
image: CustomImage;
|
|
34
|
+
width?: number;
|
|
35
|
+
height?: number;
|
|
36
|
+
fit?: BoxFit;
|
|
37
|
+
/** Corner radius in points; rounds the image box (0 = sharp, default). */
|
|
38
|
+
radius?: number;
|
|
39
|
+
}
|
|
40
|
+
export declare class ImageElement extends SizedPDFElement {
|
|
41
|
+
private image;
|
|
42
|
+
private fit;
|
|
43
|
+
private radius;
|
|
44
|
+
constructor({ image, width, height, fit, radius }: ImageElementParams);
|
|
45
|
+
calculateLayout(constraints: BoxConstraints, offset: Offset, _ctx: LayoutContext): Size;
|
|
46
|
+
getProps(): {
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
width: number | undefined;
|
|
50
|
+
height: number | undefined;
|
|
51
|
+
image: CustomImage;
|
|
52
|
+
fit: BoxFit;
|
|
53
|
+
radius: number;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.ImageElement = exports.CustomLocalImage = exports.CustomImage = exports.BoxFit = void 0;
|
|
46
|
+
const image_helper_1 = require("../utils/image-helper");
|
|
47
|
+
const pdf_element_1 = require("./pdf-element");
|
|
48
|
+
var BoxFit;
|
|
49
|
+
(function (BoxFit) {
|
|
50
|
+
BoxFit["none"] = "NONE";
|
|
51
|
+
BoxFit["contain"] = "CONTAIN";
|
|
52
|
+
BoxFit["cover"] = "COVER";
|
|
53
|
+
BoxFit["fill"] = "FILL";
|
|
54
|
+
})(BoxFit || (exports.BoxFit = BoxFit = {}));
|
|
55
|
+
class CustomImage {
|
|
56
|
+
}
|
|
57
|
+
exports.CustomImage = CustomImage;
|
|
58
|
+
class CustomLocalImage extends CustomImage {
|
|
59
|
+
constructor(imagePath) {
|
|
60
|
+
super();
|
|
61
|
+
this.imagePath = imagePath;
|
|
62
|
+
}
|
|
63
|
+
init() {
|
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
try {
|
|
66
|
+
// Loading image and convert it to base64
|
|
67
|
+
yield this.loadImage(this.imagePath);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
console.error("Error loading image:", error);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
getImageType() {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
const path = yield Promise.resolve().then(() => __importStar(require("path"))); // Dynamic import
|
|
77
|
+
const ext = path.extname(this.imagePath).toLowerCase();
|
|
78
|
+
switch (ext) {
|
|
79
|
+
case ".jpg":
|
|
80
|
+
case ".jpeg":
|
|
81
|
+
return "DCTDecode"; // For JPEG
|
|
82
|
+
case ".png":
|
|
83
|
+
return "FlateDecode"; // For PNG
|
|
84
|
+
case ".bmp":
|
|
85
|
+
throw new Error("BMP is not directly supported. Please convert to PNG or JPEG.");
|
|
86
|
+
case ".webp":
|
|
87
|
+
throw new Error("WebP is not directly supported. Please convert to PNG or JPEG.");
|
|
88
|
+
default:
|
|
89
|
+
throw new Error(`Unsupported image format: ${ext}`);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
loadImage(imagePath) {
|
|
94
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
95
|
+
const fs = yield Promise.resolve().then(() => __importStar(require("fs/promises"))); // Dynamic import
|
|
96
|
+
const result = yield fs.readFile(imagePath);
|
|
97
|
+
//const result = await convertImageToGrayscaleBuffer(imagePath);
|
|
98
|
+
this.fileBuffer = result;
|
|
99
|
+
this.fileRawData = result.toString("binary");
|
|
100
|
+
return result;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
getFileData() {
|
|
104
|
+
return this.fileRawData;
|
|
105
|
+
}
|
|
106
|
+
getImageDimensions() {
|
|
107
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
108
|
+
if (!this.fileBuffer) {
|
|
109
|
+
throw new Error("You must first call the `loadAndConvertImage` method");
|
|
110
|
+
}
|
|
111
|
+
// Since now (30.09.2024) we using "Jimp" - So we don't need our custom method to get the image dimension.
|
|
112
|
+
// But at the moment I let it still here...
|
|
113
|
+
const dimensions = yield (0, image_helper_1.getImageDimensions)(this.fileBuffer);
|
|
114
|
+
return dimensions;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.CustomLocalImage = CustomLocalImage;
|
|
119
|
+
class ImageElement extends pdf_element_1.SizedPDFElement {
|
|
120
|
+
constructor({ image, width, height, fit = BoxFit.none, radius }) {
|
|
121
|
+
super({ x: 0, y: 0, width });
|
|
122
|
+
this.image = image;
|
|
123
|
+
this.height = height;
|
|
124
|
+
this.fit = fit;
|
|
125
|
+
this.radius = radius !== null && radius !== void 0 ? radius : 0;
|
|
126
|
+
}
|
|
127
|
+
calculateLayout(constraints, offset, _ctx) {
|
|
128
|
+
var _a, _b;
|
|
129
|
+
this.x = offset.x;
|
|
130
|
+
this.y = offset.y;
|
|
131
|
+
// A bounded axis overrides the intrinsic/explicit size; otherwise keep our own.
|
|
132
|
+
if (constraints.hasBoundedWidth)
|
|
133
|
+
this.width = constraints.maxWidth;
|
|
134
|
+
if (constraints.hasBoundedHeight)
|
|
135
|
+
this.height = constraints.maxHeight;
|
|
136
|
+
// Top-left coordinates; the fit logic (renderer) and the Y-flip (seam) run later.
|
|
137
|
+
return { width: (_a = this.width) !== null && _a !== void 0 ? _a : 0, height: (_b = this.height) !== null && _b !== void 0 ? _b : 0 };
|
|
138
|
+
}
|
|
139
|
+
getProps() {
|
|
140
|
+
return {
|
|
141
|
+
x: this.x,
|
|
142
|
+
y: this.y,
|
|
143
|
+
width: this.width,
|
|
144
|
+
height: this.height,
|
|
145
|
+
image: this.image,
|
|
146
|
+
fit: this.fit,
|
|
147
|
+
radius: this.radius,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
exports.ImageElement = ImageElement;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { PDFElement } from "./pdf-element";
|
|
2
|
+
export * from "./text-element";
|
|
3
|
+
export * from "./pdf-document-element";
|
|
4
|
+
export * from "./page-element";
|
|
5
|
+
export * from "./rectangle-element";
|
|
6
|
+
export * from "./image-element";
|
|
7
|
+
export * from "./layout/expanded-element";
|
|
8
|
+
export * from "./layout/padding-element";
|
|
9
|
+
export * from "./line-element";
|
|
10
|
+
export * from "./row-element";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.PDFElement = void 0;
|
|
18
|
+
var pdf_element_1 = require("./pdf-element"); // the base element type - public for composing custom layouts
|
|
19
|
+
Object.defineProperty(exports, "PDFElement", { enumerable: true, get: function () { return pdf_element_1.PDFElement; } });
|
|
20
|
+
__exportStar(require("./text-element"), exports);
|
|
21
|
+
__exportStar(require("./pdf-document-element"), exports);
|
|
22
|
+
__exportStar(require("./page-element"), exports);
|
|
23
|
+
__exportStar(require("./rectangle-element"), exports);
|
|
24
|
+
__exportStar(require("./image-element"), exports);
|
|
25
|
+
__exportStar(require("./layout/expanded-element"), exports);
|
|
26
|
+
__exportStar(require("./layout/padding-element"), exports);
|
|
27
|
+
__exportStar(require("./line-element"), exports);
|
|
28
|
+
__exportStar(require("./row-element"), exports);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints";
|
|
2
|
+
import { Fragmentable, FragmentResult } from "../../layout/fragmentation";
|
|
3
|
+
import { LayoutContext, PDFElement } from "../pdf-element";
|
|
4
|
+
/**
|
|
5
|
+
* Builds its subtree at layout time via `resolve(ctx)`, so the tree can depend on font
|
|
6
|
+
* metrics (e.g. a Table resolving `"auto"` column widths from cell content). The engine
|
|
7
|
+
* stays table-agnostic - the closure comes from the API layer.
|
|
8
|
+
*/
|
|
9
|
+
export declare class DeferredElement extends PDFElement implements Fragmentable {
|
|
10
|
+
private resolve;
|
|
11
|
+
private composed?;
|
|
12
|
+
constructor(resolve: (ctx: LayoutContext) => PDFElement);
|
|
13
|
+
private build;
|
|
14
|
+
calculateLayout(constraints: BoxConstraints, offset: Offset, ctx: LayoutContext): Size;
|
|
15
|
+
fragment(maxHeight: number, width: number, ctx: LayoutContext): FragmentResult;
|
|
16
|
+
getProps(): {
|
|
17
|
+
composed: PDFElement | undefined;
|
|
18
|
+
};
|
|
19
|
+
}
|