@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,22 +1,18 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PageElement = void 0;
4
- exports.resolvePageContentBox = resolvePageContentBox;
5
- exports.layoutPageBands = layoutPageBands;
6
- const page_sizes_1 = require("../constants/page-sizes");
7
- const pdf_config_1 = require("../renderer/pdf-config");
8
- const box_constraints_1 = require("../layout/box-constraints");
9
- const pdf_element_1 = require("./pdf-element");
1
+ import { pageFormats } from "../constants/page-sizes.js";
2
+ import { Orientation } from "../renderer/pdf-config.js";
3
+ import { BoxConstraints } from "../layout/box-constraints.js";
4
+ import { PDFElement } from "./pdf-element.js";
10
5
  /**
11
6
  * The content box of a page (inside the margins, orientation applied) for a fully
12
7
  * resolved config. Single source of truth, shared by `PageElement` layout and the page
13
8
  * driver so they can never drift.
14
9
  */
15
- function resolvePageContentBox(config) {
10
+ export function resolvePageContentBox(config) {
16
11
  const margin = config.margin;
17
- let width = page_sizes_1.pageFormats[config.pageSize][0] - margin.left - margin.right;
18
- let height = page_sizes_1.pageFormats[config.pageSize][1] - margin.top - margin.bottom;
19
- if (config.orientation === pdf_config_1.Orientation.landscape) {
12
+ const [pageW, pageH] = config.customSize ?? pageFormats[config.pageSize];
13
+ let width = pageW - margin.left - margin.right;
14
+ let height = pageH - margin.top - margin.bottom;
15
+ if (config.orientation === Orientation.landscape) {
20
16
  [width, height] = [height, width];
21
17
  }
22
18
  return { origin: { x: margin.left, y: margin.top }, width, height };
@@ -29,17 +25,17 @@ function resolvePageContentBox(config) {
29
25
  * no header/footer the bands are zero and the body equals the full content box - identical
30
26
  * to a page without them.
31
27
  */
32
- function layoutPageBands(config, header, footer, ctx) {
28
+ export function layoutPageBands(config, header, footer, ctx) {
33
29
  const { origin, width, height } = resolvePageContentBox(config);
34
30
  let headerHeight = 0;
35
31
  if (header) {
36
- headerHeight = header.calculateLayout(box_constraints_1.BoxConstraints.loose(width, Infinity), origin, ctx).height;
32
+ headerHeight = header.calculateLayout(BoxConstraints.loose(width, Infinity), origin, ctx).height;
37
33
  }
38
34
  let footerHeight = 0;
39
35
  if (footer) {
40
36
  // Measure first to learn its height, then place it flush against the bottom edge.
41
- footerHeight = footer.calculateLayout(box_constraints_1.BoxConstraints.loose(width, Infinity), origin, ctx).height;
42
- footer.calculateLayout(box_constraints_1.BoxConstraints.loose(width, Infinity), { x: origin.x, y: origin.y + height - footerHeight }, ctx);
37
+ footerHeight = footer.calculateLayout(BoxConstraints.loose(width, Infinity), origin, ctx).height;
38
+ footer.calculateLayout(BoxConstraints.loose(width, Infinity), { x: origin.x, y: origin.y + height - footerHeight }, ctx);
43
39
  }
44
40
  return {
45
41
  bodyOrigin: { x: origin.x, y: origin.y + headerHeight },
@@ -49,11 +45,11 @@ function layoutPageBands(config, header, footer, ctx) {
49
45
  footerHeight,
50
46
  };
51
47
  }
52
- class PageElement extends pdf_element_1.PDFElement {
48
+ export class PageElement extends PDFElement {
53
49
  constructor({ children, config, header, footer }) {
54
50
  super();
55
51
  this.children = children;
56
- this.config = config !== null && config !== void 0 ? config : {};
52
+ this.config = config ?? {};
57
53
  this.header = header;
58
54
  this.footer = footer;
59
55
  }
@@ -61,15 +57,17 @@ class PageElement extends pdf_element_1.PDFElement {
61
57
  // Merge the document defaults (carried in the context) with this page's overrides,
62
58
  // then hand descendants a context bound to THIS page's geometry. This is what
63
59
  // fixes the old last-page-wins global page-config bug.
64
- this.config = Object.assign(Object.assign({}, ctx.pageConfig), this.config);
60
+ this.config = { ...ctx.pageConfig, ...this.config };
65
61
  const pageCtx = {
66
62
  metrics: ctx.metrics,
67
63
  pageConfig: this.config,
64
+ textStyle: ctx.textStyle,
65
+ onOverflow: ctx.onOverflow,
68
66
  };
69
67
  // Place the header/footer bands; the body gets the region left in between (the whole
70
68
  // content box when there is neither - byte-identical to a plain page).
71
69
  const bands = layoutPageBands(this.config, this.header, this.footer, pageCtx);
72
- const childConstraints = box_constraints_1.BoxConstraints.loose(bands.bodyWidth, bands.bodyHeight);
70
+ const childConstraints = BoxConstraints.loose(bands.bodyWidth, bands.bodyHeight);
73
71
  // The page body is itself a positioning frame: a `Positioned` with no `relative` ancestor
74
72
  // resolves against the content box (a `relative` Box overrides it for its own subtree). Drained
75
73
  // after the body is laid out, so a page-level Positioned isn't a silent no-op.
@@ -78,7 +76,7 @@ class PageElement extends pdf_element_1.PDFElement {
78
76
  size: { width: bands.bodyWidth, height: bands.bodyHeight },
79
77
  place: [],
80
78
  };
81
- const bodyCtx = Object.assign(Object.assign({}, pageCtx), { frame });
79
+ const bodyCtx = { ...pageCtx, frame };
82
80
  this.children.forEach((child) => child.calculateLayout(childConstraints, bands.bodyOrigin, bodyCtx));
83
81
  for (const place of frame.place)
84
82
  place(frame, pageCtx);
@@ -98,4 +96,3 @@ class PageElement extends pdf_element_1.PDFElement {
98
96
  return this;
99
97
  }
100
98
  }
101
- exports.PageElement = PageElement;
@@ -1,12 +1,18 @@
1
- import { PageElement } from "./page-element";
2
- import { BoxConstraints, Offset, Size } from "../layout/box-constraints";
3
- import { LayoutContext, PDFElement, WithChildren } from "./pdf-element";
1
+ import { PageElement } from "./page-element.js";
2
+ import { BoxConstraints, Offset, Size } from "../layout/box-constraints.js";
3
+ import { LayoutContext, PDFElement, WithChildren } from "./pdf-element.js";
4
+ import type { ResolvedTextStyle } from "../text/text-style.js";
4
5
  interface PDFDocumentParams extends WithChildren {
5
6
  children: PageElement[];
7
+ /** Document-level text defaults descendants inherit (seeded into the layout-context root). */
8
+ defaultTextStyle?: Partial<ResolvedTextStyle>;
6
9
  }
7
10
  export declare class PDFDocumentElement extends PDFElement {
8
11
  private children;
9
- constructor({ children }: PDFDocumentParams);
12
+ private defaultTextStyle?;
13
+ constructor({ children, defaultTextStyle }: PDFDocumentParams);
14
+ /** The document-level text defaults; the renderer merges them into the cascade root. */
15
+ getDefaultTextStyle(): Partial<ResolvedTextStyle> | undefined;
10
16
  calculateLayout(_constraints: BoxConstraints, _offset: Offset, ctx: LayoutContext): Size;
11
17
  getProps(): PDFDocumentParams;
12
18
  }
@@ -1,22 +1,23 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PDFDocumentElement = void 0;
4
- const box_constraints_1 = require("../layout/box-constraints");
5
- const pdf_element_1 = require("./pdf-element");
6
- class PDFDocumentElement extends pdf_element_1.PDFElement {
7
- constructor({ children }) {
1
+ import { BoxConstraints } from "../layout/box-constraints.js";
2
+ import { PDFElement } from "./pdf-element.js";
3
+ export class PDFDocumentElement extends PDFElement {
4
+ constructor({ children, defaultTextStyle }) {
8
5
  super();
9
6
  this.children = children;
7
+ this.defaultTextStyle = defaultTextStyle;
8
+ }
9
+ /** The document-level text defaults; the renderer merges them into the cascade root. */
10
+ getDefaultTextStyle() {
11
+ return this.defaultTextStyle;
10
12
  }
11
13
  calculateLayout(_constraints, _offset, ctx) {
12
14
  // The document is the root: each page derives its own geometry, so it ignores the
13
15
  // incoming constraints/offset. It has no size of its own.
14
16
  const origin = { x: 0, y: 0 };
15
- this.children.forEach((child) => child.calculateLayout(new box_constraints_1.BoxConstraints(), origin, ctx));
17
+ this.children.forEach((child) => child.calculateLayout(new BoxConstraints(), origin, ctx));
16
18
  return { width: 0, height: 0 };
17
19
  }
18
20
  getProps() {
19
- return { children: this.children };
21
+ return { children: this.children, defaultTextStyle: this.defaultTextStyle };
20
22
  }
21
23
  }
22
- exports.PDFDocumentElement = PDFDocumentElement;
@@ -1,6 +1,8 @@
1
- import type { FontMetrics } from "../utils/font-metrics";
2
- import type { PDFPageConfig } from "./page-element";
3
- import type { BoxConstraints, Offset, Size } from "../layout/box-constraints";
1
+ import type { FontMetrics } from "../utils/font-metrics.js";
2
+ import type { PDFPageConfig } from "./page-element.js";
3
+ import type { ResolvedTextStyle } from "../text/text-style.js";
4
+ import type { OverflowPolicy } from "../layout/fragmentation.js";
5
+ import type { BoxConstraints, Offset, Size } from "../layout/box-constraints.js";
4
6
  /**
5
7
  * Everything the layout pass needs, threaded explicitly (no global singleton):
6
8
  * font metrics for measuring, and the geometry of the page currently being laid out.
@@ -26,6 +28,13 @@ export interface LayoutContext {
26
28
  pageConfig: PDFPageConfig;
27
29
  /** The nearest enclosing positioning frame, if any (set by a `relative` Box). */
28
30
  frame?: PositioningFrame;
31
+ /** The cascaded text style descendants inherit (CSS/Flutter-style). Seeded at the document root
32
+ * from the built-in defaults + the `Document` defaults, and carried through page contexts; a
33
+ * `Text` resolves its own unset properties against it. Absent falls back to the built-in defaults. */
34
+ textStyle?: ResolvedTextStyle;
35
+ /** What to do when an element overflows a page region and cannot break (set from the render option;
36
+ * absent = clip silently). Evaluated in `packChildren` where the forced placement happens. */
37
+ onOverflow?: OverflowPolicy;
29
38
  }
30
39
  export declare abstract class PDFElement {
31
40
  abstract getProps(): unknown;
@@ -1,13 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VerticalAlignment = exports.HorizontalAlignment = exports.FlexiblePDFElement = exports.SizedPDFElement = exports.PDFElement = void 0;
4
- exports.isSizedElement = isSizedElement;
5
- exports.hasChildrenProp = hasChildrenProp;
6
- exports.hasChildProp = hasChildProp;
7
- class PDFElement {
1
+ export class PDFElement {
8
2
  }
9
- exports.PDFElement = PDFElement;
10
- class SizedPDFElement extends PDFElement {
3
+ export class SizedPDFElement extends PDFElement {
11
4
  constructor(data) {
12
5
  super();
13
6
  this.x = data.x;
@@ -19,8 +12,7 @@ class SizedPDFElement extends PDFElement {
19
12
  return { x: this.x, y: this.y, width: this.width, height: this.height };
20
13
  }
21
14
  }
22
- exports.SizedPDFElement = SizedPDFElement;
23
- class FlexiblePDFElement extends PDFElement {
15
+ export class FlexiblePDFElement extends PDFElement {
24
16
  constructor(data) {
25
17
  super();
26
18
  this.flex = data.flex;
@@ -30,26 +22,25 @@ class FlexiblePDFElement extends PDFElement {
30
22
  return this.flex;
31
23
  }
32
24
  }
33
- exports.FlexiblePDFElement = FlexiblePDFElement;
34
- var HorizontalAlignment;
25
+ export var HorizontalAlignment;
35
26
  (function (HorizontalAlignment) {
36
27
  HorizontalAlignment["left"] = "LEFT";
37
28
  HorizontalAlignment["right"] = "RIGHT";
38
29
  HorizontalAlignment["center"] = "CENTER";
39
30
  HorizontalAlignment["block"] = "BLOCK";
40
- })(HorizontalAlignment || (exports.HorizontalAlignment = HorizontalAlignment = {}));
41
- var VerticalAlignment;
31
+ })(HorizontalAlignment || (HorizontalAlignment = {}));
32
+ export var VerticalAlignment;
42
33
  (function (VerticalAlignment) {
43
34
  VerticalAlignment["top"] = "TOP";
44
35
  VerticalAlignment["middle"] = "MIDDLE";
45
36
  VerticalAlignment["bottom"] = "BOTTOM";
46
- })(VerticalAlignment || (exports.VerticalAlignment = VerticalAlignment = {}));
47
- function isSizedElement(obj) {
37
+ })(VerticalAlignment || (VerticalAlignment = {}));
38
+ export function isSizedElement(obj) {
48
39
  return typeof obj === "object" && obj !== null && "x" in obj && "y" in obj;
49
40
  }
50
- function hasChildrenProp(obj) {
41
+ export function hasChildrenProp(obj) {
51
42
  return "children" in obj;
52
43
  }
53
- function hasChildProp(obj) {
44
+ export function hasChildProp(obj) {
54
45
  return "child" in obj;
55
46
  }
@@ -1,8 +1,8 @@
1
- import { Color } from "../common/color";
2
- import { BoxConstraints, Offset, Size } from "../layout/box-constraints";
3
- import { Fragmentable, FragmentResult } from "../layout/fragmentation";
4
- import { LayoutContext, PDFElement, SizedElement, SizedPDFElement, WithChildren } from "./pdf-element";
5
- /** Per-side border colours. When set, each present side is stroked individually (sharp
1
+ import { Color } from "../common/color.js";
2
+ import { BoxConstraints, Offset, Size } from "../layout/box-constraints.js";
3
+ import { Fragmentable, FragmentResult } from "../layout/fragmentation.js";
4
+ import { LayoutContext, PDFElement, SizedElement, SizedPDFElement, WithChildren } from "./pdf-element.js";
5
+ /** Per-side border colors. When set, each present side is stroked individually (sharp
6
6
  * corners), instead of the uniform `color` border - this is what enables grid lines. */
7
7
  export interface SideBorders {
8
8
  top?: Color;
@@ -1,23 +1,20 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RectangleElement = void 0;
4
- const color_1 = require("../common/color");
5
- const box_constraints_1 = require("../layout/box-constraints");
6
- const fragmentation_1 = require("../layout/fragmentation");
7
- const pdf_element_1 = require("./pdf-element");
8
- class RectangleElement extends pdf_element_1.SizedPDFElement {
9
- constructor({ children = [], color = new color_1.Color(0, 0, 0), backgroundColor, borderWidth, width, height, radius, sideBorders, relative, overflow, }) {
1
+ import { Color } from "../common/color.js";
2
+ import { BoxConstraints } from "../layout/box-constraints.js";
3
+ import { packChildren } from "../layout/fragmentation.js";
4
+ import { SizedPDFElement, } from "./pdf-element.js";
5
+ export class RectangleElement extends SizedPDFElement {
6
+ constructor({ children = [], color = new Color(0, 0, 0), backgroundColor, borderWidth, width, height, radius, sideBorders, relative, overflow, }) {
10
7
  super({ x: 0, y: 0, width, height });
11
8
  this.children = [];
12
9
  this.children = children;
13
10
  this.color = color;
14
11
  this.backgroundColor = backgroundColor;
15
12
  // `?? 1` (not `|| 1`) so an explicit `0` means "no border" instead of snapping to 1.
16
- this.borderWidth = borderWidth !== null && borderWidth !== void 0 ? borderWidth : 1;
17
- this.radius = radius !== null && radius !== void 0 ? radius : 0;
13
+ this.borderWidth = borderWidth ?? 1;
14
+ this.radius = radius ?? 0;
18
15
  this.sideBorders = sideBorders;
19
- this.relative = relative !== null && relative !== void 0 ? relative : false;
20
- this.overflow = overflow !== null && overflow !== void 0 ? overflow : "visible";
16
+ this.relative = relative ?? false;
17
+ this.overflow = overflow ?? "visible";
21
18
  this.sizeMemory = { x: 0, y: 0, width, height };
22
19
  }
23
20
  /**
@@ -29,17 +26,16 @@ class RectangleElement extends pdf_element_1.SizedPDFElement {
29
26
  * box is sized by what it actually holds on each page.
30
27
  */
31
28
  fragment(maxHeight, width, ctx) {
32
- var _a;
33
- const boxWidth = (_a = this.sizeMemory.width) !== null && _a !== void 0 ? _a : width;
29
+ const boxWidth = this.sizeMemory.width ?? width;
34
30
  const innerWidth = Math.max(0, boxWidth - 2 * this.borderWidth);
35
31
  // Border-box: the content is inset by the border on top and bottom, so a fragment
36
32
  // holding `c` of content is `c + 2*border` tall. (Derived, not a fudge factor.)
37
33
  const innerMaxHeight = maxHeight - 2 * this.borderWidth;
38
- const { fitted, remainder } = (0, fragmentation_1.packChildren)(this.children, innerMaxHeight, innerWidth, ctx);
34
+ const { fitted, remainder } = packChildren(this.children, innerMaxHeight, innerWidth, ctx);
39
35
  if (remainder.length === 0)
40
36
  return { fitted: this, remainder: null };
41
37
  const contentHeight = (kids) => kids.reduce((sum, child) => sum +
42
- child.calculateLayout(box_constraints_1.BoxConstraints.loose(innerWidth, Infinity), { x: 0, y: 0 }, ctx)
38
+ child.calculateLayout(BoxConstraints.loose(innerWidth, Infinity), { x: 0, y: 0 }, ctx)
43
39
  .height, 0);
44
40
  return {
45
41
  fitted: this.cloneWithChildren(fitted, contentHeight(fitted) + 2 * this.borderWidth),
@@ -63,7 +59,6 @@ class RectangleElement extends pdf_element_1.SizedPDFElement {
63
59
  });
64
60
  }
65
61
  calculateLayout(constraints, offset, ctx) {
66
- var _a, _b, _c, _d, _e;
67
62
  // Width: an explicit size wins (clamped), else fill the offered box. (Without this a
68
63
  // fixed box would balloon to the parent's size.)
69
64
  this.width =
@@ -93,17 +88,17 @@ class RectangleElement extends pdf_element_1.SizedPDFElement {
93
88
  const frame = this.relative
94
89
  ? { origin: { x: 0, y: 0 }, size: { width: 0, height: 0 }, place: [] }
95
90
  : undefined;
96
- const childCtx = frame ? Object.assign(Object.assign({}, ctx), { frame }) : ctx;
91
+ const childCtx = frame ? { ...ctx, frame } : ctx;
97
92
  // Lay out children stacked inside the border (inset by the border width). Width is
98
93
  // finalized here; height is left unbounded so each child sizes to its own content.
99
94
  const innerWidth = shrinkWrapWidth
100
95
  ? Infinity
101
- : Math.max(0, ((_a = this.width) !== null && _a !== void 0 ? _a : 0) - 2 * this.borderWidth);
96
+ : Math.max(0, (this.width ?? 0) - 2 * this.borderWidth);
102
97
  let contentWidth = 0;
103
98
  let contentHeight = 0;
104
99
  let yCursor = this.y + this.borderWidth;
105
100
  for (const child of this.children) {
106
- const childSize = child.calculateLayout(box_constraints_1.BoxConstraints.loose(innerWidth, Infinity), { x: this.x + this.borderWidth, y: yCursor }, childCtx);
101
+ const childSize = child.calculateLayout(BoxConstraints.loose(innerWidth, Infinity), { x: this.x + this.borderWidth, y: yCursor }, childCtx);
107
102
  yCursor += childSize.height;
108
103
  contentHeight += childSize.height;
109
104
  contentWidth = Math.max(contentWidth, childSize.width);
@@ -117,7 +112,7 @@ class RectangleElement extends pdf_element_1.SizedPDFElement {
117
112
  // The box is sized now: place any out-of-flow `Positioned` descendants against its box.
118
113
  if (frame) {
119
114
  frame.origin = { x: this.x, y: this.y };
120
- frame.size = { width: (_b = this.width) !== null && _b !== void 0 ? _b : 0, height: (_c = this.height) !== null && _c !== void 0 ? _c : 0 };
115
+ frame.size = { width: this.width ?? 0, height: this.height ?? 0 };
121
116
  for (const place of frame.place)
122
117
  place(frame, ctx);
123
118
  }
@@ -126,8 +121,8 @@ class RectangleElement extends pdf_element_1.SizedPDFElement {
126
121
  // border added on (that asymmetric "+border" was the source of the magic-3 fudge in
127
122
  // fragment). Top-left coordinates; the Y-flip happens at the IR -> backend seam.
128
123
  return {
129
- width: (_d = this.width) !== null && _d !== void 0 ? _d : 0,
130
- height: (_e = this.height) !== null && _e !== void 0 ? _e : 0,
124
+ width: this.width ?? 0,
125
+ height: this.height ?? 0,
131
126
  };
132
127
  }
133
128
  getProps() {
@@ -146,4 +141,3 @@ class RectangleElement extends pdf_element_1.SizedPDFElement {
146
141
  };
147
142
  }
148
143
  }
149
- exports.RectangleElement = RectangleElement;
@@ -1,6 +1,6 @@
1
- import { BoxConstraints, Offset, Size } from "../layout/box-constraints";
2
- import { MainAlign, CrossAlign } from "../utils/flex-layout";
3
- import { LayoutContext, PDFElement, SizedPDFElement, WithChildren } from "./pdf-element";
1
+ import { BoxConstraints, Offset, Size } from "../layout/box-constraints.js";
2
+ import { MainAlign, CrossAlign } from "../utils/flex-layout.js";
3
+ import { LayoutContext, PDFElement, SizedPDFElement, WithChildren } from "./pdf-element.js";
4
4
  interface RowElementParams extends WithChildren {
5
5
  /** Space inserted between children, in points. */
6
6
  gap?: number;
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RowElement = void 0;
4
- const flex_layout_1 = require("../utils/flex-layout");
5
- const pdf_element_1 = require("./pdf-element");
1
+ import { FlexLayoutHelper, HORIZONTAL_AXIS } from "../utils/flex-layout.js";
2
+ import { SizedPDFElement } from "./pdf-element.js";
6
3
  /**
7
4
  * Horizontal stack: the mirror of `ContainerElement` (Column). Children are laid out
8
5
  * left-to-right via the shared `FlexLayoutHelper` on the horizontal axis; fixed children
@@ -15,13 +12,13 @@ const pdf_element_1 = require("./pdf-element");
15
12
  * does not fit (handled by the parent's `packChildren`); synchronized cell splitting is a
16
13
  * Grid/Table concern.
17
14
  */
18
- class RowElement extends pdf_element_1.SizedPDFElement {
15
+ export class RowElement extends SizedPDFElement {
19
16
  constructor({ children, gap, main, cross }) {
20
17
  super({ x: 0, y: 0 });
21
18
  this.children = children;
22
- this.gap = gap !== null && gap !== void 0 ? gap : 0;
23
- this.main = main !== null && main !== void 0 ? main : "start";
24
- this.cross = cross !== null && cross !== void 0 ? cross : "stretch";
19
+ this.gap = gap ?? 0;
20
+ this.main = main ?? "start";
21
+ this.cross = cross ?? "stretch";
25
22
  }
26
23
  calculateLayout(constraints, offset, ctx) {
27
24
  this.x = offset.x;
@@ -32,7 +29,7 @@ class RowElement extends pdf_element_1.SizedPDFElement {
32
29
  const crossAvail = constraints.hasBoundedHeight ? constraints.maxHeight : Infinity;
33
30
  let result = { mainUsed: 0, crossUsed: 0 };
34
31
  if (this.children.length > 0) {
35
- result = flex_layout_1.FlexLayoutHelper.layout(this.children, flex_layout_1.HORIZONTAL_AXIS, mainAvail, crossAvail, this.x, this.y, { gap: this.gap, main: this.main, cross: this.cross }, ctx);
32
+ result = FlexLayoutHelper.layout(this.children, HORIZONTAL_AXIS, mainAvail, crossAvail, this.x, this.y, { gap: this.gap, main: this.main, cross: this.cross }, ctx);
36
33
  }
37
34
  this.width = constraints.hasBoundedWidth ? constraints.maxWidth : result.mainUsed;
38
35
  this.height = constraints.hasBoundedHeight ? constraints.maxHeight : result.crossUsed;
@@ -51,4 +48,3 @@ class RowElement extends pdf_element_1.SizedPDFElement {
51
48
  };
52
49
  }
53
50
  }
54
- exports.RowElement = RowElement;
@@ -1,8 +1,9 @@
1
- import { Color } from "../common/color";
2
- import { FontStyle } from "../utils/pdf-object-manager";
3
- import { BoxConstraints, Offset, Size } from "../layout/box-constraints";
4
- import { Fragmentable, FragmentResult } from "../layout/fragmentation";
5
- import { HorizontalAlignment, LayoutContext, SizedPDFElement } from "./pdf-element";
1
+ import { Color } from "../common/color.js";
2
+ import { FontStyle } from "../utils/pdf-object-manager.js";
3
+ import { BoxConstraints, Offset, Size } from "../layout/box-constraints.js";
4
+ import { Fragmentable, FragmentResult } from "../layout/fragmentation.js";
5
+ import { TextOverflow } from "../text/line-breaker.js";
6
+ import { HorizontalAlignment, LayoutContext, SizedPDFElement } from "./pdf-element.js";
6
7
  export interface TextSegment {
7
8
  content: string;
8
9
  fontStyle?: FontStyle;
@@ -12,21 +13,39 @@ export interface TextSegment {
12
13
  }
13
14
  interface TextElementParams {
14
15
  id?: string;
15
- fontSize: number;
16
+ /** Unset (undefined) inherits the cascaded size; see ResolvedTextStyle. */
17
+ fontSize?: number;
16
18
  fontFamily?: string;
17
19
  fontStyle?: FontStyle;
18
20
  content: string | TextSegment[];
19
21
  color?: Color;
20
22
  textAlignment?: HorizontalAlignment;
23
+ /** Cap the wrapped lines (default: unlimited / open-end). */
24
+ maxLines?: number;
25
+ /** What to do past `maxLines`: `"clip"` (default) drops them, `"ellipsis"` ends with "…". */
26
+ overflow?: TextOverflow;
27
+ /** Line-height multiplier: each line is `fontSize * lineHeight` tall (default `1`). */
28
+ lineHeight?: number;
21
29
  }
22
30
  export declare class TextElement extends SizedPDFElement implements Fragmentable {
31
+ private readonly rawFontSize?;
32
+ private readonly rawFontFamily?;
33
+ private readonly rawFontStyle?;
34
+ private readonly rawColor?;
35
+ private readonly rawTextAlignment?;
36
+ private readonly rawLineHeight?;
23
37
  private fontSize;
24
38
  private fontFamily;
25
39
  private fontStyle;
26
40
  private color;
27
- private content;
28
41
  private textAlignment;
29
- constructor({ fontSize, content, fontFamily, fontStyle, color, textAlignment, }: TextElementParams);
42
+ private lineHeight;
43
+ private content;
44
+ private maxLines?;
45
+ private overflow;
46
+ constructor({ fontSize, content, fontFamily, fontStyle, color, textAlignment, maxLines, overflow, lineHeight, }: TextElementParams);
47
+ private resolveStyle;
48
+ private applyStyle;
30
49
  /**
31
50
  * Splits the paragraph at line boxes (Slice 1). The lines that fit in `maxHeight` stay;
32
51
  * the rest become a remainder `TextElement` re-wrapped on the next page. If not even one
@@ -39,9 +58,13 @@ export declare class TextElement extends SizedPDFElement implements Fragmentable
39
58
  private cloneWithContent;
40
59
  calculateLayout(constraints: BoxConstraints, offset: Offset, ctx: LayoutContext): Size;
41
60
  /** The unwrapped single-line width of the content (used when width is unbounded, e.g. inside a Row).
42
- * Mirrors the renderer's advance EXACTLY: per-glyph, WITHOUT kerning. `getStringWidth` subtracts
43
- * kerning, so it under-reserves and the text would wrap inside its own natural-width box - the cause
44
- * of fixed Row children wrapping despite ample space. */
61
+ * Must match the LINE-BREAKER's one-line measure EXACTLY - not just algebraically but BIT-for-bit,
62
+ * so a text laid out at this width never re-wraps inside its own natural-width box. The breaker
63
+ * accumulates `currentWidth += wordWidth + spaceWidth`, grouping the word and its trailing space
64
+ * into one term; we must group the same way. Adding word and space as two separate steps is
65
+ * algebraically equal but, because floating-point addition is not associative, drifts by a sub-ULP
66
+ * - enough to tip a borderline string (e.g. "20 Jun 2026", wider than "04 Jul 2026" only because
67
+ * 'n' beats 'l') one bit over its own width, dropping the last word onto a second line. */
45
68
  private naturalWidth;
46
69
  getProps(): {
47
70
  x: number;
@@ -54,6 +77,9 @@ export declare class TextElement extends SizedPDFElement implements Fragmentable
54
77
  color: Color;
55
78
  content: string | TextSegment[];
56
79
  textAlignment: HorizontalAlignment;
80
+ maxLines: number | undefined;
81
+ overflow: TextOverflow;
82
+ lineHeight: number;
57
83
  };
58
84
  }
59
85
  export {};