@jasy/pdf 1.0.0-alpha.2 → 1.0.0-alpha.4

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 (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +24 -14
  3. package/dist/api/args.d.ts +1 -1
  4. package/dist/api/args.js +2 -5
  5. package/dist/api/color.d.ts +4 -4
  6. package/dist/api/color.js +11 -17
  7. package/dist/api/content.d.ts +8 -8
  8. package/dist/api/content.js +23 -24
  9. package/dist/api/descriptor.d.ts +2 -2
  10. package/dist/api/descriptor.js +75 -31
  11. package/dist/api/index.d.ts +8 -8
  12. package/dist/api/index.js +8 -24
  13. package/dist/api/insets.js +4 -8
  14. package/dist/api/layout.d.ts +18 -16
  15. package/dist/api/layout.js +41 -52
  16. package/dist/api/structure.d.ts +65 -13
  17. package/dist/api/structure.js +140 -88
  18. package/dist/api/table.d.ts +5 -5
  19. package/dist/api/table.js +28 -24
  20. package/dist/api/text.d.ts +27 -2
  21. package/dist/api/text.js +45 -27
  22. package/dist/assets/font-data.d.ts +2 -0
  23. package/dist/assets/font-data.js +21 -0
  24. package/dist/assets/font-data.ts +37 -0
  25. package/dist/common/color.js +1 -5
  26. package/dist/constants/page-sizes.js +3 -6
  27. package/dist/constants/pdf-parts.js +1 -4
  28. package/dist/crypto/security-handler.d.ts +46 -0
  29. package/dist/crypto/security-handler.js +129 -0
  30. package/dist/crypto/webcrypto.d.ts +11 -0
  31. package/dist/crypto/webcrypto.js +62 -0
  32. package/dist/elements/container-element.d.ts +4 -4
  33. package/dist/elements/container-element.js +9 -13
  34. package/dist/elements/image-element.d.ts +18 -2
  35. package/dist/elements/image-element.js +81 -105
  36. package/dist/elements/index.d.ts +12 -11
  37. package/dist/elements/index.js +12 -29
  38. package/dist/elements/layout/default-text-style-element.d.ts +30 -0
  39. package/dist/elements/layout/default-text-style-element.js +47 -0
  40. package/dist/elements/layout/deferred-element.d.ts +3 -3
  41. package/dist/elements/layout/deferred-element.js +4 -8
  42. package/dist/elements/layout/expanded-element.d.ts +3 -3
  43. package/dist/elements/layout/expanded-element.js +10 -14
  44. package/dist/elements/layout/padding-element.d.ts +3 -3
  45. package/dist/elements/layout/padding-element.js +9 -14
  46. package/dist/elements/layout/positioned-element.d.ts +17 -4
  47. package/dist/elements/layout/positioned-element.js +29 -25
  48. package/dist/elements/layout/repeating-header-element.d.ts +3 -3
  49. package/dist/elements/layout/repeating-header-element.js +8 -12
  50. package/dist/elements/layout/sized-container-element.d.ts +2 -2
  51. package/dist/elements/layout/sized-container-element.js +6 -11
  52. package/dist/elements/line-element.d.ts +3 -3
  53. package/dist/elements/line-element.js +5 -10
  54. package/dist/elements/page-element.d.ts +8 -6
  55. package/dist/elements/page-element.js +20 -23
  56. package/dist/elements/pdf-document-element.d.ts +10 -4
  57. package/dist/elements/pdf-document-element.js +11 -10
  58. package/dist/elements/pdf-element.d.ts +12 -3
  59. package/dist/elements/pdf-element.js +10 -19
  60. package/dist/elements/rectangle-element.d.ts +5 -5
  61. package/dist/elements/rectangle-element.js +19 -25
  62. package/dist/elements/row-element.d.ts +3 -3
  63. package/dist/elements/row-element.js +7 -11
  64. package/dist/elements/text-element.d.ts +37 -11
  65. package/dist/elements/text-element.js +64 -39
  66. package/dist/index.d.ts +3 -3
  67. package/dist/index.js +3 -19
  68. package/dist/ir/display-list.d.ts +4 -2
  69. package/dist/ir/display-list.js +1 -2
  70. package/dist/layout/box-constraints.js +2 -6
  71. package/dist/layout/fragmentation.d.ts +8 -1
  72. package/dist/layout/fragmentation.js +22 -10
  73. package/dist/platform/browser-fs.d.ts +2 -0
  74. package/dist/platform/browser-fs.js +9 -0
  75. package/dist/platform/browser-image.d.ts +5 -0
  76. package/dist/platform/browser-image.js +13 -0
  77. package/dist/platform/node-fs.d.ts +2 -0
  78. package/dist/platform/node-fs.js +10 -0
  79. package/dist/platform/node-image.d.ts +5 -0
  80. package/dist/platform/node-image.js +9 -0
  81. package/dist/renderer/container-renderer.d.ts +3 -3
  82. package/dist/renderer/container-renderer.js +12 -27
  83. package/dist/renderer/default-text-style-renderer.d.ts +6 -0
  84. package/dist/renderer/default-text-style-renderer.js +10 -0
  85. package/dist/renderer/deferred-renderer.d.ts +3 -3
  86. package/dist/renderer/deferred-renderer.js +8 -23
  87. package/dist/renderer/expanded-renderer.d.ts +3 -3
  88. package/dist/renderer/expanded-renderer.js +6 -21
  89. package/dist/renderer/image-renderer.d.ts +3 -3
  90. package/dist/renderer/image-renderer.js +77 -75
  91. package/dist/renderer/index.d.ts +10 -10
  92. package/dist/renderer/index.js +10 -26
  93. package/dist/renderer/line-renderer.d.ts +3 -3
  94. package/dist/renderer/line-renderer.js +13 -28
  95. package/dist/renderer/padding-renderer.d.ts +3 -3
  96. package/dist/renderer/padding-renderer.js +6 -21
  97. package/dist/renderer/page-renderer.d.ts +2 -2
  98. package/dist/renderer/page-renderer.js +61 -77
  99. package/dist/renderer/pdf-backend.d.ts +2 -2
  100. package/dist/renderer/pdf-backend.js +21 -19
  101. package/dist/renderer/pdf-config.js +4 -7
  102. package/dist/renderer/pdf-document-class.d.ts +5 -5
  103. package/dist/renderer/pdf-document-class.js +24 -41
  104. package/dist/renderer/pdf-document-renderer.d.ts +3 -3
  105. package/dist/renderer/pdf-document-renderer.js +71 -85
  106. package/dist/renderer/pdf-renderer.d.ts +2 -2
  107. package/dist/renderer/pdf-renderer.js +85 -93
  108. package/dist/renderer/positioned-renderer.d.ts +3 -3
  109. package/dist/renderer/positioned-renderer.js +8 -23
  110. package/dist/renderer/rectangle-renderer.d.ts +3 -3
  111. package/dist/renderer/rectangle-renderer.js +45 -52
  112. package/dist/renderer/repeating-header-renderer.d.ts +3 -3
  113. package/dist/renderer/repeating-header-renderer.js +11 -26
  114. package/dist/renderer/row-renderer.d.ts +3 -3
  115. package/dist/renderer/row-renderer.js +12 -27
  116. package/dist/renderer/text-renderer.d.ts +6 -5
  117. package/dist/renderer/text-renderer.js +33 -42
  118. package/dist/text/line-breaker.d.ts +8 -5
  119. package/dist/text/line-breaker.js +67 -16
  120. package/dist/text/text-style.d.ts +25 -0
  121. package/dist/text/text-style.js +29 -0
  122. package/dist/utils/afm-parser.js +3 -13
  123. package/dist/utils/bytes.d.ts +24 -0
  124. package/dist/utils/bytes.js +76 -0
  125. package/dist/utils/flex-layout.d.ts +2 -2
  126. package/dist/utils/flex-layout.js +15 -20
  127. package/dist/utils/font-metrics.d.ts +1 -1
  128. package/dist/utils/font-metrics.js +1 -2
  129. package/dist/utils/font-path.js +3 -6
  130. package/dist/utils/image-helper.d.ts +6 -5
  131. package/dist/utils/image-helper.js +101 -111
  132. package/dist/utils/md5.d.ts +4 -0
  133. package/dist/utils/md5.js +79 -0
  134. package/dist/utils/pdf-object-manager.d.ts +18 -6
  135. package/dist/utils/pdf-object-manager.js +0 -0
  136. package/dist/utils/renderer-registry.js +1 -5
  137. package/dist/utils/ttf-parser.d.ts +2 -2
  138. package/dist/utils/ttf-parser.js +32 -36
  139. package/dist/utils/ttf-subsetter.d.ts +1 -1
  140. package/dist/utils/ttf-subsetter.js +40 -42
  141. package/dist/utils/utf8-to-windows1252-encoder.js +1 -4
  142. package/dist/validators/element-validator.d.ts +2 -2
  143. package/dist/validators/element-validator.js +9 -13
  144. package/package.json +14 -2
@@ -1,74 +1,77 @@
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
1
+ import { BoxFit } from "../elements/image-element.js";
2
+ import { bytesFromLatin1 } from "../utils/bytes.js";
3
+ import { applyContainFit, applyCoverFit, applyFillFit, applyFitNone, decodePngToRgbFlate, } from "../utils/image-helper.js";
4
+ export class ImageRenderer {
5
+ static async render(imageElement, _objectManager) {
6
+ // Load the image and convert it in a binary string
7
+ let { x, y, width, height, image, fit, radius } = imageElement.getProps();
8
+ await image.init(); // Load and initialize the image
9
+ const imageType = await image.getImageType(); // For the moment we can handle `png` and `jpg/jpeg` files
10
+ const fileData = await image.getFileData();
11
+ const dimensions = await image.getImageDimensions();
12
+ if (!fileData) {
13
+ throw new Error("File data cannot be `null`");
14
+ }
15
+ // JPEG embeds raw (PDF decodes DCTDecode natively). PNG is not a valid Flate stream,
16
+ // so decode it to raw DeviceRGB samples that the FlateDecode XObject path expects.
17
+ let embedData = fileData;
18
+ let smask;
19
+ if (imageType === "FlateDecode") {
20
+ const decoded = await decodePngToRgbFlate(bytesFromLatin1(fileData));
21
+ embedData = decoded.data;
22
+ smask = decoded.smask;
23
+ }
24
+ // Now we check the `fit` property and changing the dimensions of the image
25
+ // Optionally we must add an overflow container
26
+ let mustCreateOverflowContainer = false;
27
+ const containerDimensions = JSON.parse(JSON.stringify({ x, y, width, height })); // Deep clone images dimensions
28
+ switch (fit) {
29
+ case BoxFit.cover:
30
+ mustCreateOverflowContainer = true;
31
+ const fitCoverResult = applyCoverFit(dimensions.width, dimensions.height, width ?? 0, height ?? 0);
32
+ x += fitCoverResult.offsetX;
33
+ y += fitCoverResult.offsetY;
34
+ width = fitCoverResult.width;
35
+ height = fitCoverResult.height;
36
+ break;
37
+ case BoxFit.contain:
38
+ mustCreateOverflowContainer = true;
39
+ const fitContainResult = applyContainFit(dimensions.width, dimensions.height, width ?? 0, height ?? 0);
40
+ x += fitContainResult.offsetX;
41
+ y += fitContainResult.offsetY;
42
+ width = fitContainResult.width;
43
+ height = fitContainResult.height;
44
+ break;
45
+ case BoxFit.none:
46
+ const fitNoneResult = applyFitNone(dimensions.width, dimensions.height, width ?? 0, height ?? 0);
47
+ x += fitNoneResult.offsetX;
48
+ y += fitNoneResult.offsetY;
49
+ width = fitNoneResult.width;
50
+ height = fitNoneResult.height;
51
+ break;
52
+ case BoxFit.fill:
53
+ const fitFillResult = applyFillFit(width ?? 0, height ?? 0);
54
+ width = fitFillResult.width;
55
+ height = fitFillResult.height;
56
+ }
57
+ // A radius rounds the image BOX (the element frame), so it clips to that frame too -
58
+ // independent of the cover/contain overflow clip.
59
+ const wantsClip = mustCreateOverflowContainer || (radius ?? 0) > 0;
60
+ // The fitted geometry becomes a display-list primitive; the backend registers
61
+ // the XObject and emits the placement (+ clip, rounded when a radius is set).
62
+ const node = {
63
+ type: "image",
64
+ x,
65
+ y,
66
+ width: width,
67
+ height: height,
68
+ intrinsicWidth: dimensions.width,
69
+ intrinsicHeight: dimensions.height,
70
+ data: embedData,
71
+ imageType,
72
+ ...(smask ? { smask } : {}),
73
+ ...(radius ? { radius } : {}),
74
+ ...(wantsClip
72
75
  ? {
73
76
  clip: {
74
77
  x: containerDimensions.x,
@@ -77,9 +80,8 @@ class ImageRenderer {
77
80
  height: containerDimensions.height,
78
81
  },
79
82
  }
80
- : {}));
81
- return [node];
82
- });
83
+ : {}),
84
+ };
85
+ return [node];
83
86
  }
84
87
  }
85
- exports.ImageRenderer = ImageRenderer;
@@ -1,10 +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";
1
+ export * from "./container-renderer.js";
2
+ export * from "./page-renderer.js";
3
+ export * from "./pdf-document-class.js";
4
+ export * from "./pdf-document-renderer.js";
5
+ export * from "./pdf-renderer.js";
6
+ export * from "./rectangle-renderer.js";
7
+ export * from "./text-renderer.js";
8
+ export * from "./expanded-renderer.js";
9
+ export * from "./line-renderer.js";
10
+ export * from "./row-renderer.js";
@@ -1,26 +1,10 @@
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);
1
+ export * from "./container-renderer.js";
2
+ export * from "./page-renderer.js";
3
+ export * from "./pdf-document-class.js";
4
+ export * from "./pdf-document-renderer.js";
5
+ export * from "./pdf-renderer.js";
6
+ export * from "./rectangle-renderer.js";
7
+ export * from "./text-renderer.js";
8
+ export * from "./expanded-renderer.js";
9
+ export * from "./line-renderer.js";
10
+ export * from "./row-renderer.js";
@@ -1,6 +1,6 @@
1
- import { PDFObjectManager } from "../utils/pdf-object-manager";
2
- import { LineElement } from "../elements";
3
- import { IRNode } from "../ir/display-list";
1
+ import { PDFObjectManager } from "../utils/pdf-object-manager.js";
2
+ import { LineElement } from "../elements/index.js";
3
+ import { IRNode } from "../ir/display-list.js";
4
4
  export declare class LineRenderer {
5
5
  static render(lineElement: LineElement, _objectManager: PDFObjectManager): Promise<IRNode[]>;
6
6
  }
@@ -1,30 +1,15 @@
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
- });
1
+ export class LineRenderer {
2
+ static async render(lineElement, _objectManager) {
3
+ const { x, y, xEnd, yEnd, color, strokeWidth } = lineElement.getProps();
4
+ const node = {
5
+ type: "line",
6
+ x1: x,
7
+ y1: y,
8
+ x2: xEnd,
9
+ y2: yEnd,
10
+ stroke: color,
11
+ strokeWidth: strokeWidth,
12
+ };
13
+ return [node];
28
14
  }
29
15
  }
30
- exports.LineRenderer = LineRenderer;
@@ -1,6 +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";
1
+ import { PDFObjectManager } from "../utils/pdf-object-manager.js";
2
+ import { PaddingElement } from "../elements/layout/padding-element.js";
3
+ import { IRNode } from "../ir/display-list.js";
4
4
  export declare class PaddingRenderer {
5
5
  static render(paddingElement: PaddingElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
6
6
  }
@@ -1,23 +1,8 @@
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
- });
1
+ import { RendererRegistry } from "../utils/renderer-registry.js";
2
+ export class PaddingRenderer {
3
+ static async render(paddingElement, objectManager) {
4
+ const { child } = paddingElement.getProps();
5
+ const renderer = RendererRegistry.getRenderer(child);
6
+ return renderer ? await renderer(child, objectManager) : [];
21
7
  }
22
8
  }
23
- exports.PaddingRenderer = PaddingRenderer;
@@ -1,5 +1,5 @@
1
- import { PageElement } from "../elements/page-element";
2
- import { PDFObjectManager } from "../utils/pdf-object-manager";
1
+ import { PageElement } from "../elements/page-element.js";
2
+ import { PDFObjectManager } from "../utils/pdf-object-manager.js";
3
3
  export declare class PageRenderer {
4
4
  static render(page: PageElement, objectManager: PDFObjectManager): Promise<number>;
5
5
  }
@@ -1,81 +1,65 @@
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.PageRenderer = void 0;
13
- const page_sizes_1 = require("../constants/page-sizes");
14
- const renderer_registry_1 = require("../utils/renderer-registry");
15
- const pdf_config_1 = require("./pdf-config");
16
- const pdf_backend_1 = require("./pdf-backend");
17
- class PageRenderer {
18
- static render(page, objectManager) {
19
- return __awaiter(this, void 0, void 0, function* () {
20
- var _a;
21
- const { children, config, header, footer } = page.getProps();
22
- // Header (top band) and footer (bottom band) sit around the body and repeat on every
23
- // physical page; they are placed by `PageElement.calculateLayout` / the page driver.
24
- const renderables = [...(header ? [header] : []), ...children, ...(footer ? [footer] : [])];
25
- // Page geometry (also the MediaBox below). Needed up front because flipping the
26
- // display list to PDF coordinates uses the page height. config is fully resolved
27
- // by the layout pass; fall back to the document default rather than asserting.
28
- let [width, height] = page_sizes_1.pageFormats[(_a = config === null || config === void 0 ? void 0 : config.pageSize) !== null && _a !== void 0 ? _a : page_sizes_1.PageSize.A4];
29
- if ((config === null || config === void 0 ? void 0 : config.orientation) === pdf_config_1.Orientation.landscape) {
30
- [width, height] = [height, width];
1
+ import { pageFormats, PageSize } from "../constants/page-sizes.js";
2
+ import { RendererRegistry } from "../utils/renderer-registry.js";
3
+ import { Orientation } from "./pdf-config.js";
4
+ import { PdfBackend } from "./pdf-backend.js";
5
+ export class PageRenderer {
6
+ static async render(page, objectManager) {
7
+ const { children, config, header, footer } = page.getProps();
8
+ // Header (top band) and footer (bottom band) sit around the body and repeat on every
9
+ // physical page; they are placed by `PageElement.calculateLayout` / the page driver.
10
+ const renderables = [...(header ? [header] : []), ...children, ...(footer ? [footer] : [])];
11
+ // Page geometry (also the MediaBox below). Needed up front because flipping the
12
+ // display list to PDF coordinates uses the page height. config is fully resolved
13
+ // by the layout pass; fall back to the document default rather than asserting.
14
+ let [width, height] = config?.customSize ?? pageFormats[config?.pageSize ?? PageSize.A4];
15
+ if (config?.orientation === Orientation.landscape) {
16
+ [width, height] = [height, width];
17
+ }
18
+ // Collect the whole page as a display list (top-left coordinates), flip it to PDF
19
+ // coordinates at this one seam, then serialize once. Serializing registers the
20
+ // fonts/images used below, so it must run before the resource section.
21
+ const nodes = [];
22
+ for (const element of renderables) {
23
+ const renderer = RendererRegistry.getRenderer(element);
24
+ if (renderer) {
25
+ nodes.push(...(await renderer(element, objectManager)));
31
26
  }
32
- // Collect the whole page as a display list (top-left coordinates), flip it to PDF
33
- // coordinates at this one seam, then serialize once. Serializing registers the
34
- // fonts/images used below, so it must run before the resource section.
35
- const nodes = [];
36
- for (const element of renderables) {
37
- const renderer = renderer_registry_1.RendererRegistry.getRenderer(element);
38
- if (renderer) {
39
- nodes.push(...(yield renderer(element, objectManager)));
40
- }
41
- }
42
- const pageContent = pdf_backend_1.PdfBackend.serialize(pdf_backend_1.PdfBackend.flipY(nodes, height), objectManager);
43
- // Add the page content as a new object (FlateDecode-compressed when enabled). The /Length is
44
- // computed inside, with an explicit EOL before `endstream` (PDF/A clause 6.1.7.1).
45
- const contentObjectNumber = objectManager.addContentStream(pageContent);
46
- // Get the parent object number dynamically (linked with the page object)
47
- const parentObjectNumber = objectManager.getParentObjectNumber(); // Get parent object number
48
- // Page object with MediaBox
49
- // - Get all fonts and add it to the page (reference)
50
- objectManager.registerFont("Helvetica");
51
- const fontReferences = [];
52
- objectManager.getAllFontsRaw().forEach((value, _key) => {
53
- const fontRef = `/F${value.fontIndex} ${value.resourceIndex} 0 R`;
54
- fontReferences.push(fontRef);
55
- });
56
- // - Get all images and add it to the page (reference)
57
- const imageReferences = [];
58
- objectManager.getAllImagesRaw().forEach((value) => {
59
- const imageRef = `/IM${value} ${value} 0 R`;
60
- imageReferences.push(imageRef);
61
- });
62
- const imageCode = imageReferences.length > 0
63
- ? "/ProcSet [/PDF /Text /ImageB /ImageC /ImageI] /XObject <<\n" +
64
- imageReferences.join("\n") +
65
- "\n>>\n"
66
- : "";
67
- // - Transparency (ExtGState) references, registered during serialize above
68
- const extGStateReferences = [];
69
- objectManager.getAllExtGStatesRaw().forEach((objectNumber, name) => {
70
- extGStateReferences.push(`/${name} ${objectNumber} 0 R`);
71
- });
72
- const extGStateCode = extGStateReferences.length > 0
73
- ? "/ExtGState <<\n" + extGStateReferences.join("\n") + "\n>>\n"
74
- : "";
75
- const pageObject = `<< /Type /Page /Parent ${parentObjectNumber} 0 R /Contents ${contentObjectNumber} 0 R /Resources <<\n/Font <<\n${fontReferences.join("\n")}\n>>\n${imageCode}${extGStateCode}>>\n/MediaBox [0 0 ${width} ${height}] >>`;
76
- // Add page as new object and return the page number
77
- return objectManager.addObject(pageObject);
27
+ }
28
+ const pageContent = PdfBackend.serialize(PdfBackend.flipY(nodes, height), objectManager);
29
+ // Add the page content as a new object (FlateDecode-compressed when enabled). The /Length is
30
+ // computed inside, with an explicit EOL before `endstream` (PDF/A clause 6.1.7.1).
31
+ const contentObjectNumber = objectManager.addContentStream(pageContent);
32
+ // Get the parent object number dynamically (linked with the page object)
33
+ const parentObjectNumber = objectManager.getParentObjectNumber(); // Get parent object number
34
+ // Page object with MediaBox
35
+ // - Get all fonts and add it to the page (reference)
36
+ objectManager.registerFont("Helvetica");
37
+ const fontReferences = [];
38
+ objectManager.getAllFontsRaw().forEach((value, _key) => {
39
+ const fontRef = `/F${value.fontIndex} ${value.resourceIndex} 0 R`;
40
+ fontReferences.push(fontRef);
41
+ });
42
+ // - Get all images and add it to the page (reference)
43
+ const imageReferences = [];
44
+ objectManager.getAllImagesRaw().forEach((value) => {
45
+ const imageRef = `/IM${value} ${value} 0 R`;
46
+ imageReferences.push(imageRef);
47
+ });
48
+ const imageCode = imageReferences.length > 0
49
+ ? "/ProcSet [/PDF /Text /ImageB /ImageC /ImageI] /XObject <<\n" +
50
+ imageReferences.join("\n") +
51
+ "\n>>\n"
52
+ : "";
53
+ // - Transparency (ExtGState) references, registered during serialize above
54
+ const extGStateReferences = [];
55
+ objectManager.getAllExtGStatesRaw().forEach((objectNumber, name) => {
56
+ extGStateReferences.push(`/${name} ${objectNumber} 0 R`);
78
57
  });
58
+ const extGStateCode = extGStateReferences.length > 0
59
+ ? "/ExtGState <<\n" + extGStateReferences.join("\n") + "\n>>\n"
60
+ : "";
61
+ const pageObject = `<< /Type /Page /Parent ${parentObjectNumber} 0 R /Contents ${contentObjectNumber} 0 R /Resources <<\n/Font <<\n${fontReferences.join("\n")}\n>>\n${imageCode}${extGStateCode}>>\n/MediaBox [0 0 ${width} ${height}] >>`;
62
+ // Add page as new object and return the page number
63
+ return objectManager.addObject(pageObject);
79
64
  }
80
65
  }
81
- exports.PageRenderer = PageRenderer;
@@ -1,5 +1,5 @@
1
- import { IRNode } from "../ir/display-list";
2
- import { PDFObjectManager } from "../utils/pdf-object-manager";
1
+ import { IRNode } from "../ir/display-list.js";
2
+ import { PDFObjectManager } from "../utils/pdf-object-manager.js";
3
3
  /**
4
4
  * PDF backend - turns display-list primitives into content-stream operators.
5
5
  *
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PdfBackend = void 0;
4
1
  /**
5
2
  * PDF backend - turns display-list primitives into content-stream operators.
6
3
  *
@@ -9,7 +6,7 @@ exports.PdfBackend = void 0;
9
6
  * emitted inline by the per-element renderers, so output stays byte-identical while
10
7
  * the renderers are migrated onto the IR one at a time.
11
8
  */
12
- class PdfBackend {
9
+ export class PdfBackend {
13
10
  /**
14
11
  * Flip a display list from the engine's top-left origin (y grows downward) to PDF's
15
12
  * bottom-left origin (y grows upward). This is the ONE place the Y axis is flipped -
@@ -21,23 +18,30 @@ class PdfBackend {
21
18
  return nodes.map((node) => {
22
19
  switch (node.type) {
23
20
  case "rect":
24
- return Object.assign(Object.assign({}, node), { y: pageHeight - node.y - node.height });
21
+ return { ...node, y: pageHeight - node.y - node.height };
25
22
  case "line":
26
- return Object.assign(Object.assign({}, node), { y1: pageHeight - node.y1, y2: pageHeight - node.y2 });
23
+ return {
24
+ ...node,
25
+ y1: pageHeight - node.y1,
26
+ y2: pageHeight - node.y2,
27
+ };
27
28
  case "text":
28
29
  // node.y is the baseline measured from the page top; flip it directly.
29
- return Object.assign(Object.assign({}, node), { y: pageHeight - node.y });
30
+ return { ...node, y: pageHeight - node.y };
30
31
  case "image": {
31
32
  // Flip the placement box (and the clip frame, if any) around its bottom edge.
32
- const flipped = Object.assign(Object.assign({}, node), { y: pageHeight - node.y - node.height });
33
+ const flipped = { ...node, y: pageHeight - node.y - node.height };
33
34
  if (node.clip) {
34
- flipped.clip = Object.assign(Object.assign({}, node.clip), { y: pageHeight - node.clip.y - node.clip.height });
35
+ flipped.clip = {
36
+ ...node.clip,
37
+ y: pageHeight - node.clip.y - node.clip.height,
38
+ };
35
39
  }
36
40
  return flipped;
37
41
  }
38
42
  case "clip-push":
39
43
  // Flip the clip rect around its bottom edge, like a rect.
40
- return Object.assign(Object.assign({}, node), { y: pageHeight - node.y - node.height });
44
+ return { ...node, y: pageHeight - node.y - node.height };
41
45
  case "clip-pop":
42
46
  return node;
43
47
  default: {
@@ -100,7 +104,6 @@ class PdfBackend {
100
104
  * `om` is used only by primitives that allocate PDF resources (images, fonts).
101
105
  */
102
106
  static serializeNode(node, om) {
103
- var _a, _b, _c, _d, _e, _f;
104
107
  switch (node.type) {
105
108
  case "line":
106
109
  // q/Q isolates the graphics state; "[] 0 d" resets the dash pattern to solid.
@@ -114,10 +117,10 @@ class PdfBackend {
114
117
  `S\n` +
115
118
  `Q\n`);
116
119
  case "rect": {
117
- // Stroke only with a stroke colour AND a positive width - a 0-width border means
120
+ // Stroke only with a stroke color AND a positive width - a 0-width border means
118
121
  // "no border" (e.g. a filled box with no outline). Nothing to paint at all (no
119
122
  // fill, no border) draws nothing. Paint: B = fill+stroke, f = fill, S = stroke.
120
- const doStroke = !!node.stroke && ((_a = node.strokeWidth) !== null && _a !== void 0 ? _a : 0) > 0;
123
+ const doStroke = !!node.stroke && (node.strokeWidth ?? 0) > 0;
121
124
  if (!node.fill && !doStroke)
122
125
  return "";
123
126
  let ops = "";
@@ -129,13 +132,13 @@ class PdfBackend {
129
132
  const paint = node.fill ? (doStroke ? "B" : "f") : "S";
130
133
  // Rounded corners emit a Bézier path; sharp corners keep the plain `re`
131
134
  // (byte-identical when no radius is set).
132
- const path = ((_b = node.radius) !== null && _b !== void 0 ? _b : 0) > 0
135
+ const path = (node.radius ?? 0) > 0
133
136
  ? PdfBackend.roundedRectPath(node.x, node.y, node.width, node.height, node.radius)
134
137
  : `${node.x} ${node.y} ${node.width} ${node.height} re`;
135
138
  const body = ops + `${path} ${paint}\n`;
136
139
  // Transparency needs an isolating q/Q so the state does not leak; opaque rects
137
140
  // keep their bare operators (byte-identical).
138
- const gs = PdfBackend.alphaPrefix(om, (_d = (_c = node.fill) === null || _c === void 0 ? void 0 : _c.getAlpha()) !== null && _d !== void 0 ? _d : 1, doStroke ? node.stroke.getAlpha() : 1);
141
+ const gs = PdfBackend.alphaPrefix(om, node.fill?.getAlpha() ?? 1, doStroke ? node.stroke.getAlpha() : 1);
139
142
  return gs ? `q\n${gs}${body}Q\n` : body;
140
143
  }
141
144
  case "text": {
@@ -166,14 +169,14 @@ class PdfBackend {
166
169
  case "image": {
167
170
  // The backend owns PDF resource creation: register the XObject (using the
168
171
  // source pixel dimensions) and then place it with a scaling matrix.
169
- const ref = om.registerImage(node.intrinsicWidth, node.intrinsicHeight, node.imageType, node.data);
172
+ const ref = om.registerImage(node.intrinsicWidth, node.intrinsicHeight, node.imageType, node.data, node.smask);
170
173
  const draw = `q\n${node.width} 0 0 ${node.height} ${node.x} ${node.y} cm\n` + `/IM${ref} Do\nQ\n`;
171
174
  if (!node.clip)
172
175
  return draw;
173
176
  // Clip to the frame (re … W n); rounded when a radius is set. The rectangular
174
177
  // path is byte-identical to before.
175
178
  const c = node.clip;
176
- const clipPath = ((_e = node.radius) !== null && _e !== void 0 ? _e : 0) > 0
179
+ const clipPath = (node.radius ?? 0) > 0
177
180
  ? PdfBackend.roundedRectPath(c.x, c.y, c.width, c.height, node.radius)
178
181
  : `${c.x} ${c.y} ${c.width} ${c.height} re `;
179
182
  return `q\n${clipPath}\nW n \n` + draw + `Q\n`;
@@ -181,7 +184,7 @@ class PdfBackend {
181
184
  case "clip-push": {
182
185
  // Save the graphics state and intersect the clip with this (rounded) rect. Everything
183
186
  // drawn until the matching clip-pop is cropped to it.
184
- const path = ((_f = node.radius) !== null && _f !== void 0 ? _f : 0) > 0
187
+ const path = (node.radius ?? 0) > 0
185
188
  ? PdfBackend.roundedRectPath(node.x, node.y, node.width, node.height, node.radius)
186
189
  : `${node.x} ${node.y} ${node.width} ${node.height} re`;
187
190
  return `q\n${path}\nW n\n`;
@@ -196,4 +199,3 @@ class PdfBackend {
196
199
  }
197
200
  }
198
201
  }
199
- exports.PdfBackend = PdfBackend;