@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,74 @@
1
+ import { Color } from "../common/color";
2
+ import { FontStyle } from "../utils/pdf-object-manager";
3
+ /**
4
+ * Display list - the seam between layout and the PDF backend.
5
+ *
6
+ * Everything above this line (components, layout) produces an `IRNode[]`; the PDF
7
+ * backend below consumes ONLY `IRNode`s and never sees a component. The primitives
8
+ * are intentionally "dumb": absolute geometry + semantic style, with no PDF
9
+ * operators, no font indices, and no object numbers - those are the backend's job.
10
+ *
11
+ * Coordinates are in PDF points (1/72"). Which origin they use is still the
12
+ * producer's concern for now; centralizing the Y-flip at this seam is Phase 3.
13
+ */
14
+ /**
15
+ * A single positioned run of text in one font / size / color. Line wrapping has
16
+ * already happened upstream: the producer emits one `TextRun` per laid-out line or
17
+ * per styled segment within a line.
18
+ */
19
+ export interface TextRun {
20
+ type: "text";
21
+ x: number;
22
+ y: number;
23
+ text: string;
24
+ fontFamily: string;
25
+ fontStyle: FontStyle;
26
+ fontSize: number;
27
+ color: Color;
28
+ }
29
+ /** An axis-aligned rectangle. An absent `fill` or `stroke` means that part is not drawn. */
30
+ export interface Rect {
31
+ type: "rect";
32
+ x: number;
33
+ y: number;
34
+ width: number;
35
+ height: number;
36
+ fill?: Color;
37
+ stroke?: Color;
38
+ strokeWidth: number;
39
+ /** Corner radius in points; absent/0 = sharp corners (plain `re`). */
40
+ radius?: number;
41
+ }
42
+ /** A straight line segment between two points. */
43
+ export interface Line {
44
+ type: "line";
45
+ x1: number;
46
+ y1: number;
47
+ x2: number;
48
+ y2: number;
49
+ stroke: Color;
50
+ strokeWidth: number;
51
+ }
52
+ /** A raster image, already resolved to bytes by the producer (no `CustomImage` here). */
53
+ export interface Image {
54
+ type: "image";
55
+ x: number;
56
+ y: number;
57
+ width: number;
58
+ height: number;
59
+ intrinsicWidth: number;
60
+ intrinsicHeight: number;
61
+ data: string;
62
+ imageType: string;
63
+ /** cover/contain fits clip the placement to the element's original frame. */
64
+ clip?: {
65
+ x: number;
66
+ y: number;
67
+ width: number;
68
+ height: number;
69
+ };
70
+ /** Corner radius in points for the image box; absent/0 = sharp corners. */
71
+ radius?: number;
72
+ }
73
+ /** The closed set of primitives the PDF backend knows how to draw. */
74
+ export type IRNode = TextRun | Rect | Line | Image;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The size constraints handed DOWN the tree during layout (Flutter's BoxConstraints
3
+ * model). Pure geometry: a min/max range per axis, no position. An element receives a
4
+ * `BoxConstraints`, chooses a `Size` within it, and returns that size UP.
5
+ *
6
+ * `Infinity` means "unbounded" on that side - the element may be as large as it wants
7
+ * and should size to its own content (e.g. text height, a shrink-wrapping padding).
8
+ * A *tight* axis (`min === max`) forces an exact size; a *loose* axis (`min === 0`)
9
+ * lets the element pick anything up to `max`.
10
+ *
11
+ * This is the contract the future fragmentation pass (roadmap Phase 5) reads: a page's
12
+ * remaining vertical space becomes a `maxHeight`, and "does this fit?" is a constraint
13
+ * check, not a special case.
14
+ */
15
+ export declare class BoxConstraints {
16
+ readonly minWidth: number;
17
+ readonly maxWidth: number;
18
+ readonly minHeight: number;
19
+ readonly maxHeight: number;
20
+ constructor(minWidth?: number, maxWidth?: number, minHeight?: number, maxHeight?: number);
21
+ /** Forces an exact size: the element has no choice but `width` x `height`. */
22
+ static tight(width: number, height: number): BoxConstraints;
23
+ /** Tight only on the axes given; the others stay unbounded (0..Infinity). */
24
+ static tightFor({ width, height }: {
25
+ width?: number;
26
+ height?: number;
27
+ }): BoxConstraints;
28
+ /** Caps each axis at `max` but allows anything down to zero (shrink-wrap). */
29
+ static loose(maxWidth: number, maxHeight: number): BoxConstraints;
30
+ get hasBoundedWidth(): boolean;
31
+ get hasBoundedHeight(): boolean;
32
+ get isTight(): boolean;
33
+ /** Clamps a desired width into [minWidth, maxWidth]. */
34
+ constrainWidth(width?: number): number;
35
+ /** Clamps a desired height into [minHeight, maxHeight]. */
36
+ constrainHeight(height?: number): number;
37
+ /** Clamps a desired size into this box on both axes. */
38
+ constrain(size: Size): Size;
39
+ /**
40
+ * Shrinks the box by `horizontal`/`vertical` on both bounds (never below zero) -
41
+ * what a padding/border element hands its child after reserving its own insets.
42
+ */
43
+ deflate(horizontal: number, vertical: number): BoxConstraints;
44
+ /** Returns the constraints clamped to lie within `parent` (Flutter's enforce). */
45
+ enforce(parent: BoxConstraints): BoxConstraints;
46
+ }
47
+ /** The size an element resolves to and returns UP the tree. */
48
+ export interface Size {
49
+ width: number;
50
+ height: number;
51
+ }
52
+ /** The absolute top-left position a parent assigns to a child (threaded DOWN). */
53
+ export interface Offset {
54
+ x: number;
55
+ y: number;
56
+ }
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BoxConstraints = void 0;
4
+ /**
5
+ * The size constraints handed DOWN the tree during layout (Flutter's BoxConstraints
6
+ * model). Pure geometry: a min/max range per axis, no position. An element receives a
7
+ * `BoxConstraints`, chooses a `Size` within it, and returns that size UP.
8
+ *
9
+ * `Infinity` means "unbounded" on that side - the element may be as large as it wants
10
+ * and should size to its own content (e.g. text height, a shrink-wrapping padding).
11
+ * A *tight* axis (`min === max`) forces an exact size; a *loose* axis (`min === 0`)
12
+ * lets the element pick anything up to `max`.
13
+ *
14
+ * This is the contract the future fragmentation pass (roadmap Phase 5) reads: a page's
15
+ * remaining vertical space becomes a `maxHeight`, and "does this fit?" is a constraint
16
+ * check, not a special case.
17
+ */
18
+ class BoxConstraints {
19
+ constructor(minWidth = 0, maxWidth = Infinity, minHeight = 0, maxHeight = Infinity) {
20
+ this.minWidth = minWidth;
21
+ this.maxWidth = maxWidth;
22
+ this.minHeight = minHeight;
23
+ this.maxHeight = maxHeight;
24
+ }
25
+ /** Forces an exact size: the element has no choice but `width` x `height`. */
26
+ static tight(width, height) {
27
+ return new BoxConstraints(width, width, height, height);
28
+ }
29
+ /** Tight only on the axes given; the others stay unbounded (0..Infinity). */
30
+ static tightFor({ width, height }) {
31
+ return new BoxConstraints(width !== null && width !== void 0 ? width : 0, width !== null && width !== void 0 ? width : Infinity, height !== null && height !== void 0 ? height : 0, height !== null && height !== void 0 ? height : Infinity);
32
+ }
33
+ /** Caps each axis at `max` but allows anything down to zero (shrink-wrap). */
34
+ static loose(maxWidth, maxHeight) {
35
+ return new BoxConstraints(0, maxWidth, 0, maxHeight);
36
+ }
37
+ get hasBoundedWidth() {
38
+ return this.maxWidth !== Infinity;
39
+ }
40
+ get hasBoundedHeight() {
41
+ return this.maxHeight !== Infinity;
42
+ }
43
+ get isTight() {
44
+ return this.minWidth === this.maxWidth && this.minHeight === this.maxHeight;
45
+ }
46
+ /** Clamps a desired width into [minWidth, maxWidth]. */
47
+ constrainWidth(width = Infinity) {
48
+ return Math.max(this.minWidth, Math.min(width, this.maxWidth));
49
+ }
50
+ /** Clamps a desired height into [minHeight, maxHeight]. */
51
+ constrainHeight(height = Infinity) {
52
+ return Math.max(this.minHeight, Math.min(height, this.maxHeight));
53
+ }
54
+ /** Clamps a desired size into this box on both axes. */
55
+ constrain(size) {
56
+ return {
57
+ width: this.constrainWidth(size.width),
58
+ height: this.constrainHeight(size.height),
59
+ };
60
+ }
61
+ /**
62
+ * Shrinks the box by `horizontal`/`vertical` on both bounds (never below zero) -
63
+ * what a padding/border element hands its child after reserving its own insets.
64
+ */
65
+ deflate(horizontal, vertical) {
66
+ return new BoxConstraints(Math.max(0, this.minWidth - horizontal), Math.max(0, this.maxWidth - horizontal), Math.max(0, this.minHeight - vertical), Math.max(0, this.maxHeight - vertical));
67
+ }
68
+ /** Returns the constraints clamped to lie within `parent` (Flutter's enforce). */
69
+ enforce(parent) {
70
+ return new BoxConstraints(Math.max(parent.minWidth, Math.min(this.minWidth, parent.maxWidth)), Math.max(parent.minWidth, Math.min(this.maxWidth, parent.maxWidth)), Math.max(parent.minHeight, Math.min(this.minHeight, parent.maxHeight)), Math.max(parent.minHeight, Math.min(this.maxHeight, parent.maxHeight)));
71
+ }
72
+ }
73
+ exports.BoxConstraints = BoxConstraints;
@@ -0,0 +1,42 @@
1
+ import { LayoutContext, PDFElement } from "../elements/pdf-element";
2
+ /**
3
+ * The result of splitting an element against a fragmentation region (a page, later a
4
+ * column). `fitted` is the part that fits in the region; `remainder` describes what did
5
+ * not and is re-fragmented in the NEXT region. Either side may be null:
6
+ * `fitted === null` means nothing fit, `remainder === null` means the element is done.
7
+ *
8
+ * Both sides are plain `PDFElement`s - the remainder is a normal element describing the
9
+ * rest, so no information flows back UP after a break. This one-way flow is what keeps
10
+ * fragmentation terminating (no overflow-cascade fixpoint).
11
+ */
12
+ export interface FragmentResult {
13
+ fitted: PDFElement | null;
14
+ remainder: PDFElement | null;
15
+ }
16
+ /**
17
+ * An element that knows how to split itself across regions. Width is already finalized
18
+ * by the measure step (width-stable); `fragment` only splits height, packing into
19
+ * `maxHeight`.
20
+ */
21
+ export interface Fragmentable {
22
+ fragment(maxHeight: number, width: number, ctx: LayoutContext): FragmentResult;
23
+ }
24
+ export declare function isFragmentable(element: PDFElement): element is PDFElement & Fragmentable;
25
+ /**
26
+ * Packs a vertical stack of children into `maxHeight`, in order. Children are measured
27
+ * against `width` (unbounded height) and added until one would overflow; that straddling
28
+ * child is itself fragmented if it can be, otherwise placed/deferred whole. Everything
29
+ * after the break spills. Progress is guaranteed: if nothing fit, the straddling child is
30
+ * forced on (it overflows) so the next region always advances.
31
+ *
32
+ * `gap` is the spacing the parent inserts BETWEEN children (a `Column` gap) - it must be
33
+ * counted here, otherwise the packed fragment renders taller than `maxHeight` (the gaps
34
+ * are added back at render time) and overflows the region.
35
+ *
36
+ * Shared by every element that lays out a vertical stack and can split it across regions
37
+ * (Container, and the decorated boxes Padding/Rectangle).
38
+ */
39
+ export declare function packChildren(children: PDFElement[], maxHeight: number, width: number, ctx: LayoutContext, gap?: number): {
40
+ fitted: PDFElement[];
41
+ remainder: PDFElement[];
42
+ };
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isFragmentable = isFragmentable;
4
+ exports.packChildren = packChildren;
5
+ const box_constraints_1 = require("./box-constraints");
6
+ function isFragmentable(element) {
7
+ return ("fragment" in element &&
8
+ typeof element.fragment === "function");
9
+ }
10
+ /**
11
+ * Packs a vertical stack of children into `maxHeight`, in order. Children are measured
12
+ * against `width` (unbounded height) and added until one would overflow; that straddling
13
+ * child is itself fragmented if it can be, otherwise placed/deferred whole. Everything
14
+ * after the break spills. Progress is guaranteed: if nothing fit, the straddling child is
15
+ * forced on (it overflows) so the next region always advances.
16
+ *
17
+ * `gap` is the spacing the parent inserts BETWEEN children (a `Column` gap) - it must be
18
+ * counted here, otherwise the packed fragment renders taller than `maxHeight` (the gaps
19
+ * are added back at render time) and overflows the region.
20
+ *
21
+ * Shared by every element that lays out a vertical stack and can split it across regions
22
+ * (Container, and the decorated boxes Padding/Rectangle).
23
+ */
24
+ function packChildren(children, maxHeight, width, ctx, gap = 0) {
25
+ const fitted = [];
26
+ const remainder = [];
27
+ let usedHeight = 0;
28
+ for (let i = 0; i < children.length; i++) {
29
+ const child = children[i];
30
+ const childHeight = child.calculateLayout(box_constraints_1.BoxConstraints.loose(width, Infinity), { x: 0, y: 0 }, ctx).height;
31
+ // A gap precedes every child except the first one placed in this region.
32
+ const lead = fitted.length > 0 ? gap : 0;
33
+ if (usedHeight + lead + childHeight <= maxHeight) {
34
+ fitted.push(child);
35
+ usedHeight += lead + childHeight;
36
+ continue;
37
+ }
38
+ // `child` straddles the boundary. Try to split it; otherwise place/defer it whole.
39
+ const remaining = maxHeight - usedHeight - lead;
40
+ let placedPart = false;
41
+ if (isFragmentable(child)) {
42
+ const split = child.fragment(Math.max(0, remaining), width, ctx);
43
+ if (split.fitted) {
44
+ fitted.push(split.fitted);
45
+ if (split.remainder)
46
+ remainder.push(split.remainder);
47
+ placedPart = true;
48
+ }
49
+ }
50
+ if (!placedPart) {
51
+ if (fitted.length === 0)
52
+ fitted.push(child);
53
+ else
54
+ remainder.push(child);
55
+ }
56
+ for (let j = i + 1; j < children.length; j++)
57
+ remainder.push(children[j]);
58
+ break;
59
+ }
60
+ return { fitted, remainder };
61
+ }
@@ -0,0 +1,6 @@
1
+ import { PDFObjectManager } from "../utils/pdf-object-manager";
2
+ import { ContainerElement } from "../elements/container-element";
3
+ import { IRNode } from "../ir/display-list";
4
+ export declare class ContainerRenderer {
5
+ static render(containerElement: ContainerElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
6
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ContainerRenderer = void 0;
13
+ const renderer_registry_1 = require("../utils/renderer-registry");
14
+ class ContainerRenderer {
15
+ static render(containerElement, objectManager) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ const { children } = containerElement.getProps();
18
+ const nodes = [];
19
+ if (children)
20
+ for (const child of children) {
21
+ const renderer = renderer_registry_1.RendererRegistry.getRenderer(child);
22
+ if (renderer) {
23
+ nodes.push(...(yield renderer(child, objectManager)));
24
+ }
25
+ }
26
+ return nodes;
27
+ });
28
+ }
29
+ }
30
+ exports.ContainerRenderer = ContainerRenderer;
@@ -0,0 +1,6 @@
1
+ import { PDFObjectManager } from "../utils/pdf-object-manager";
2
+ import { DeferredElement } from "../elements/layout/deferred-element";
3
+ import { IRNode } from "../ir/display-list";
4
+ export declare class DeferredRenderer {
5
+ static render(element: DeferredElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
6
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DeferredRenderer = void 0;
13
+ const renderer_registry_1 = require("../utils/renderer-registry");
14
+ class DeferredRenderer {
15
+ static render(element, objectManager) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ const { composed } = element.getProps();
18
+ if (!composed)
19
+ return [];
20
+ const renderer = renderer_registry_1.RendererRegistry.getRenderer(composed);
21
+ return renderer ? renderer(composed, objectManager) : [];
22
+ });
23
+ }
24
+ }
25
+ exports.DeferredRenderer = DeferredRenderer;
@@ -0,0 +1,6 @@
1
+ import { PDFObjectManager } from "../utils/pdf-object-manager";
2
+ import { ExpandedElement } from "../elements";
3
+ import { IRNode } from "../ir/display-list";
4
+ export declare class ExpandedRenderer {
5
+ static render(expandedElement: ExpandedElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
6
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ExpandedRenderer = void 0;
13
+ const renderer_registry_1 = require("../utils/renderer-registry");
14
+ class ExpandedRenderer {
15
+ static render(expandedElement, objectManager) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ const { child } = expandedElement.getProps();
18
+ const renderer = renderer_registry_1.RendererRegistry.getRenderer(child);
19
+ return renderer ? yield renderer(child, objectManager) : [];
20
+ });
21
+ }
22
+ }
23
+ exports.ExpandedRenderer = ExpandedRenderer;
@@ -0,0 +1,6 @@
1
+ import { ImageElement } from "../elements/image-element";
2
+ import { PDFObjectManager } from "../utils/pdf-object-manager";
3
+ import { IRNode } from "../ir/display-list";
4
+ export declare class ImageRenderer {
5
+ static render(imageElement: ImageElement, _objectManager: PDFObjectManager): Promise<IRNode[]>;
6
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ImageRenderer = void 0;
13
+ const image_element_1 = require("../elements/image-element");
14
+ const image_helper_1 = require("../utils/image-helper");
15
+ class ImageRenderer {
16
+ static render(imageElement, _objectManager) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ // Load the image and convert it in a binary string
19
+ let { x, y, width, height, image, fit, radius } = imageElement.getProps();
20
+ yield image.init(); // Load and initialize the image
21
+ const imageType = yield image.getImageType(); // For the moment we can handle `png` and `jpg/jpeg` files
22
+ const fileData = yield image.getFileData();
23
+ const dimensions = yield image.getImageDimensions();
24
+ if (!fileData) {
25
+ throw new Error("File data cannot be `null`");
26
+ }
27
+ // JPEG embeds raw (PDF decodes DCTDecode natively). PNG is not a valid Flate stream,
28
+ // so decode it to raw DeviceRGB samples that the FlateDecode XObject path expects.
29
+ const embedData = imageType === "FlateDecode"
30
+ ? (yield (0, image_helper_1.decodePngToRgbFlate)(Buffer.from(fileData, "binary"))).data
31
+ : fileData;
32
+ // Now we check the `fit` property and changing the dimensions of the image
33
+ // Optionally we must add an overflow container
34
+ let mustCreateOverflowContainer = false;
35
+ const containerDimensions = JSON.parse(JSON.stringify({ x, y, width, height })); // Deep clone images dimensions
36
+ switch (fit) {
37
+ case image_element_1.BoxFit.cover:
38
+ mustCreateOverflowContainer = true;
39
+ const fitCoverResult = (0, image_helper_1.applyCoverFit)(dimensions.width, dimensions.height, width !== null && width !== void 0 ? width : 0, height !== null && height !== void 0 ? height : 0);
40
+ x += fitCoverResult.offsetX;
41
+ y += fitCoverResult.offsetY;
42
+ width = fitCoverResult.width;
43
+ height = fitCoverResult.height;
44
+ break;
45
+ case image_element_1.BoxFit.contain:
46
+ mustCreateOverflowContainer = true;
47
+ const fitContainResult = (0, image_helper_1.applyContainFit)(dimensions.width, dimensions.height, width !== null && width !== void 0 ? width : 0, height !== null && height !== void 0 ? height : 0);
48
+ x += fitContainResult.offsetX;
49
+ y += fitContainResult.offsetY;
50
+ width = fitContainResult.width;
51
+ height = fitContainResult.height;
52
+ break;
53
+ case image_element_1.BoxFit.none:
54
+ const fitNoneResult = (0, image_helper_1.applyFitNone)(dimensions.width, dimensions.height, width !== null && width !== void 0 ? width : 0, height !== null && height !== void 0 ? height : 0);
55
+ x += fitNoneResult.offsetX;
56
+ y += fitNoneResult.offsetY;
57
+ width = fitNoneResult.width;
58
+ height = fitNoneResult.height;
59
+ break;
60
+ case image_element_1.BoxFit.fill:
61
+ const fitFillResult = (0, image_helper_1.applyFillFit)(width !== null && width !== void 0 ? width : 0, height !== null && height !== void 0 ? height : 0);
62
+ width = fitFillResult.width;
63
+ height = fitFillResult.height;
64
+ }
65
+ // A radius rounds the image BOX (the element frame), so it clips to that frame too -
66
+ // independent of the cover/contain overflow clip.
67
+ const wantsClip = mustCreateOverflowContainer || (radius !== null && radius !== void 0 ? radius : 0) > 0;
68
+ // The fitted geometry becomes a display-list primitive; the backend registers
69
+ // the XObject and emits the placement (+ clip, rounded when a radius is set).
70
+ const node = Object.assign(Object.assign({ type: "image", x,
71
+ y, width: width, height: height, intrinsicWidth: dimensions.width, intrinsicHeight: dimensions.height, data: embedData, imageType }, (radius ? { radius } : {})), (wantsClip
72
+ ? {
73
+ clip: {
74
+ x: containerDimensions.x,
75
+ y: containerDimensions.y,
76
+ width: containerDimensions.width,
77
+ height: containerDimensions.height,
78
+ },
79
+ }
80
+ : {}));
81
+ return [node];
82
+ });
83
+ }
84
+ }
85
+ exports.ImageRenderer = ImageRenderer;
@@ -0,0 +1,10 @@
1
+ export * from "./container-renderer";
2
+ export * from "./page-renderer";
3
+ export * from "./pdf-document-class";
4
+ export * from "./pdf-document-renderer";
5
+ export * from "./pdf-renderer";
6
+ export * from "./rectangle-renderer";
7
+ export * from "./text-renderer";
8
+ export * from "./expanded-renderer";
9
+ export * from "./line-renderer";
10
+ export * from "./row-renderer";
@@ -0,0 +1,26 @@
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
+ __exportStar(require("./container-renderer"), exports);
18
+ __exportStar(require("./page-renderer"), exports);
19
+ __exportStar(require("./pdf-document-class"), exports);
20
+ __exportStar(require("./pdf-document-renderer"), exports);
21
+ __exportStar(require("./pdf-renderer"), exports);
22
+ __exportStar(require("./rectangle-renderer"), exports);
23
+ __exportStar(require("./text-renderer"), exports);
24
+ __exportStar(require("./expanded-renderer"), exports);
25
+ __exportStar(require("./line-renderer"), exports);
26
+ __exportStar(require("./row-renderer"), exports);
@@ -0,0 +1,6 @@
1
+ import { PDFObjectManager } from "../utils/pdf-object-manager";
2
+ import { LineElement } from "../elements";
3
+ import { IRNode } from "../ir/display-list";
4
+ export declare class LineRenderer {
5
+ static render(lineElement: LineElement, _objectManager: PDFObjectManager): Promise<IRNode[]>;
6
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.LineRenderer = void 0;
13
+ class LineRenderer {
14
+ static render(lineElement, _objectManager) {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ const { x, y, xEnd, yEnd, color, strokeWidth } = lineElement.getProps();
17
+ const node = {
18
+ type: "line",
19
+ x1: x,
20
+ y1: y,
21
+ x2: xEnd,
22
+ y2: yEnd,
23
+ stroke: color,
24
+ strokeWidth: strokeWidth,
25
+ };
26
+ return [node];
27
+ });
28
+ }
29
+ }
30
+ exports.LineRenderer = LineRenderer;
@@ -0,0 +1,6 @@
1
+ import { PDFObjectManager } from "../utils/pdf-object-manager";
2
+ import { PaddingElement } from "../elements/layout/padding-element";
3
+ import { IRNode } from "../ir/display-list";
4
+ export declare class PaddingRenderer {
5
+ static render(paddingElement: PaddingElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
6
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PaddingRenderer = void 0;
13
+ const renderer_registry_1 = require("../utils/renderer-registry");
14
+ class PaddingRenderer {
15
+ static render(paddingElement, objectManager) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ const { child } = paddingElement.getProps();
18
+ const renderer = renderer_registry_1.RendererRegistry.getRenderer(child);
19
+ return renderer ? yield renderer(child, objectManager) : [];
20
+ });
21
+ }
22
+ }
23
+ exports.PaddingRenderer = PaddingRenderer;
@@ -0,0 +1,5 @@
1
+ import { PageElement } from "../elements/page-element";
2
+ import { PDFObjectManager } from "../utils/pdf-object-manager";
3
+ export declare class PageRenderer {
4
+ static render(page: PageElement, objectManager: PDFObjectManager): Promise<number>;
5
+ }