@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.
Files changed (139) hide show
  1. package/README.md +171 -0
  2. package/dist/api/args.d.ts +10 -0
  3. package/dist/api/args.js +13 -0
  4. package/dist/api/color.d.ts +24 -0
  5. package/dist/api/color.js +215 -0
  6. package/dist/api/content.d.ts +36 -0
  7. package/dist/api/content.js +50 -0
  8. package/dist/api/descriptor.d.ts +25 -0
  9. package/dist/api/descriptor.js +71 -0
  10. package/dist/api/index.d.ts +8 -0
  11. package/dist/api/index.js +27 -0
  12. package/dist/api/insets.d.ts +16 -0
  13. package/dist/api/insets.js +21 -0
  14. package/dist/api/layout.d.ts +72 -0
  15. package/dist/api/layout.js +99 -0
  16. package/dist/api/structure.d.ts +80 -0
  17. package/dist/api/structure.js +125 -0
  18. package/dist/api/table.d.ts +37 -0
  19. package/dist/api/table.js +87 -0
  20. package/dist/api/text.d.ts +28 -0
  21. package/dist/api/text.js +61 -0
  22. package/dist/assets/Courier-Bold.afm +342 -0
  23. package/dist/assets/Courier-BoldOblique.afm +342 -0
  24. package/dist/assets/Courier-Oblique.afm +342 -0
  25. package/dist/assets/Courier.afm +342 -0
  26. package/dist/assets/Helvetica-Bold.afm +2827 -0
  27. package/dist/assets/Helvetica-BoldOblique.afm +2827 -0
  28. package/dist/assets/Helvetica-Oblique.afm +3051 -0
  29. package/dist/assets/Helvetica.afm +3051 -0
  30. package/dist/assets/Symbol.afm +213 -0
  31. package/dist/assets/Times-Bold.afm +2588 -0
  32. package/dist/assets/Times-BoldItalic.afm +2384 -0
  33. package/dist/assets/Times-Italic.afm +2667 -0
  34. package/dist/assets/Times-Roman.afm +2419 -0
  35. package/dist/assets/ZapfDingbats.afm +225 -0
  36. package/dist/assets/agl.txt +695 -0
  37. package/dist/common/color.d.ts +37 -0
  38. package/dist/common/color.js +62 -0
  39. package/dist/constants/page-sizes.d.ts +44 -0
  40. package/dist/constants/page-sizes.js +92 -0
  41. package/dist/constants/pdf-parts.d.ts +5 -0
  42. package/dist/constants/pdf-parts.js +8 -0
  43. package/dist/elements/container-element.d.ts +35 -0
  44. package/dist/elements/container-element.js +91 -0
  45. package/dist/elements/image-element.d.ts +56 -0
  46. package/dist/elements/image-element.js +151 -0
  47. package/dist/elements/index.d.ts +10 -0
  48. package/dist/elements/index.js +28 -0
  49. package/dist/elements/layout/deferred-element.d.ts +19 -0
  50. package/dist/elements/layout/deferred-element.js +33 -0
  51. package/dist/elements/layout/expanded-element.d.ts +30 -0
  52. package/dist/elements/layout/expanded-element.js +68 -0
  53. package/dist/elements/layout/padding-element.d.ts +29 -0
  54. package/dist/elements/layout/padding-element.js +76 -0
  55. package/dist/elements/layout/repeating-header-element.d.ts +29 -0
  56. package/dist/elements/layout/repeating-header-element.js +60 -0
  57. package/dist/elements/layout/sized-container-element.d.ts +14 -0
  58. package/dist/elements/layout/sized-container-element.js +37 -0
  59. package/dist/elements/line-element.d.ts +31 -0
  60. package/dist/elements/line-element.js +44 -0
  61. package/dist/elements/page-element.d.ts +58 -0
  62. package/dist/elements/page-element.js +90 -0
  63. package/dist/elements/pdf-document-element.d.ts +13 -0
  64. package/dist/elements/pdf-document-element.js +22 -0
  65. package/dist/elements/pdf-element.d.ts +67 -0
  66. package/dist/elements/pdf-element.js +55 -0
  67. package/dist/elements/rectangle-element.d.ts +55 -0
  68. package/dist/elements/rectangle-element.js +120 -0
  69. package/dist/elements/row-element.d.ts +42 -0
  70. package/dist/elements/row-element.js +54 -0
  71. package/dist/elements/text-element.d.ts +59 -0
  72. package/dist/elements/text-element.js +137 -0
  73. package/dist/index.d.ts +3 -0
  74. package/dist/index.js +21 -0
  75. package/dist/ir/display-list.d.ts +74 -0
  76. package/dist/ir/display-list.js +2 -0
  77. package/dist/layout/box-constraints.d.ts +56 -0
  78. package/dist/layout/box-constraints.js +73 -0
  79. package/dist/layout/fragmentation.d.ts +42 -0
  80. package/dist/layout/fragmentation.js +61 -0
  81. package/dist/renderer/container-renderer.d.ts +6 -0
  82. package/dist/renderer/container-renderer.js +30 -0
  83. package/dist/renderer/deferred-renderer.d.ts +6 -0
  84. package/dist/renderer/deferred-renderer.js +25 -0
  85. package/dist/renderer/expanded-renderer.d.ts +6 -0
  86. package/dist/renderer/expanded-renderer.js +23 -0
  87. package/dist/renderer/image-renderer.d.ts +6 -0
  88. package/dist/renderer/image-renderer.js +85 -0
  89. package/dist/renderer/index.d.ts +10 -0
  90. package/dist/renderer/index.js +26 -0
  91. package/dist/renderer/line-renderer.d.ts +6 -0
  92. package/dist/renderer/line-renderer.js +30 -0
  93. package/dist/renderer/padding-renderer.d.ts +6 -0
  94. package/dist/renderer/padding-renderer.js +23 -0
  95. package/dist/renderer/page-renderer.d.ts +5 -0
  96. package/dist/renderer/page-renderer.js +81 -0
  97. package/dist/renderer/pdf-backend.d.ts +45 -0
  98. package/dist/renderer/pdf-backend.js +184 -0
  99. package/dist/renderer/pdf-config.d.ts +8 -0
  100. package/dist/renderer/pdf-config.js +17 -0
  101. package/dist/renderer/pdf-document-class.d.ts +42 -0
  102. package/dist/renderer/pdf-document-class.js +118 -0
  103. package/dist/renderer/pdf-document-renderer.d.ts +20 -0
  104. package/dist/renderer/pdf-document-renderer.js +104 -0
  105. package/dist/renderer/pdf-renderer.d.ts +5 -0
  106. package/dist/renderer/pdf-renderer.js +92 -0
  107. package/dist/renderer/rectangle-renderer.d.ts +8 -0
  108. package/dist/renderer/rectangle-renderer.js +61 -0
  109. package/dist/renderer/repeating-header-renderer.d.ts +6 -0
  110. package/dist/renderer/repeating-header-renderer.js +28 -0
  111. package/dist/renderer/row-renderer.d.ts +6 -0
  112. package/dist/renderer/row-renderer.js +30 -0
  113. package/dist/renderer/text-renderer.d.ts +9 -0
  114. package/dist/renderer/text-renderer.js +125 -0
  115. package/dist/text/line-breaker.d.ts +40 -0
  116. package/dist/text/line-breaker.js +106 -0
  117. package/dist/utils/afm-parser.d.ts +12 -0
  118. package/dist/utils/afm-parser.js +91 -0
  119. package/dist/utils/flex-layout.d.ts +53 -0
  120. package/dist/utils/flex-layout.js +119 -0
  121. package/dist/utils/font-metrics.d.ts +12 -0
  122. package/dist/utils/font-metrics.js +2 -0
  123. package/dist/utils/font-path.d.ts +1 -0
  124. package/dist/utils/font-path.js +19 -0
  125. package/dist/utils/image-helper.d.ts +43 -0
  126. package/dist/utils/image-helper.js +206 -0
  127. package/dist/utils/pdf-object-manager.d.ts +97 -0
  128. package/dist/utils/pdf-object-manager.js +645 -0
  129. package/dist/utils/renderer-registry.d.ts +6 -0
  130. package/dist/utils/renderer-registry.js +19 -0
  131. package/dist/utils/ttf-parser.d.ts +29 -0
  132. package/dist/utils/ttf-parser.js +191 -0
  133. package/dist/utils/ttf-subsetter.d.ts +1 -0
  134. package/dist/utils/ttf-subsetter.js +161 -0
  135. package/dist/utils/utf8-to-windows1252-encoder.d.ts +2 -0
  136. package/dist/utils/utf8-to-windows1252-encoder.js +55 -0
  137. package/dist/validators/element-validator.d.ts +8 -0
  138. package/dist/validators/element-validator.js +61 -0
  139. 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,5 @@
1
+ export declare const PDF_PARTS: {
2
+ HEADER: string;
3
+ TRAILER: (size: number) => string;
4
+ XREF: string;
5
+ };
@@ -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
+ }