@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.
- package/LICENSE +21 -0
- package/README.md +24 -14
- package/dist/api/args.d.ts +1 -1
- package/dist/api/args.js +2 -5
- package/dist/api/color.d.ts +4 -4
- package/dist/api/color.js +11 -17
- package/dist/api/content.d.ts +8 -8
- package/dist/api/content.js +23 -24
- package/dist/api/descriptor.d.ts +2 -2
- package/dist/api/descriptor.js +75 -31
- package/dist/api/index.d.ts +8 -8
- package/dist/api/index.js +8 -24
- package/dist/api/insets.js +4 -8
- package/dist/api/layout.d.ts +18 -16
- package/dist/api/layout.js +41 -52
- package/dist/api/structure.d.ts +65 -13
- package/dist/api/structure.js +140 -88
- package/dist/api/table.d.ts +5 -5
- package/dist/api/table.js +28 -24
- package/dist/api/text.d.ts +27 -2
- package/dist/api/text.js +45 -27
- package/dist/assets/font-data.d.ts +2 -0
- package/dist/assets/font-data.js +21 -0
- package/dist/assets/font-data.ts +37 -0
- package/dist/common/color.js +1 -5
- package/dist/constants/page-sizes.js +3 -6
- package/dist/constants/pdf-parts.js +1 -4
- package/dist/crypto/security-handler.d.ts +46 -0
- package/dist/crypto/security-handler.js +129 -0
- package/dist/crypto/webcrypto.d.ts +11 -0
- package/dist/crypto/webcrypto.js +62 -0
- package/dist/elements/container-element.d.ts +4 -4
- package/dist/elements/container-element.js +9 -13
- package/dist/elements/image-element.d.ts +18 -2
- package/dist/elements/image-element.js +81 -105
- package/dist/elements/index.d.ts +12 -11
- package/dist/elements/index.js +12 -29
- package/dist/elements/layout/default-text-style-element.d.ts +30 -0
- package/dist/elements/layout/default-text-style-element.js +47 -0
- package/dist/elements/layout/deferred-element.d.ts +3 -3
- package/dist/elements/layout/deferred-element.js +4 -8
- package/dist/elements/layout/expanded-element.d.ts +3 -3
- package/dist/elements/layout/expanded-element.js +10 -14
- package/dist/elements/layout/padding-element.d.ts +3 -3
- package/dist/elements/layout/padding-element.js +9 -14
- package/dist/elements/layout/positioned-element.d.ts +17 -4
- package/dist/elements/layout/positioned-element.js +29 -25
- package/dist/elements/layout/repeating-header-element.d.ts +3 -3
- package/dist/elements/layout/repeating-header-element.js +8 -12
- package/dist/elements/layout/sized-container-element.d.ts +2 -2
- package/dist/elements/layout/sized-container-element.js +6 -11
- package/dist/elements/line-element.d.ts +3 -3
- package/dist/elements/line-element.js +5 -10
- package/dist/elements/page-element.d.ts +8 -6
- package/dist/elements/page-element.js +20 -23
- package/dist/elements/pdf-document-element.d.ts +10 -4
- package/dist/elements/pdf-document-element.js +11 -10
- package/dist/elements/pdf-element.d.ts +12 -3
- package/dist/elements/pdf-element.js +10 -19
- package/dist/elements/rectangle-element.d.ts +5 -5
- package/dist/elements/rectangle-element.js +19 -25
- package/dist/elements/row-element.d.ts +3 -3
- package/dist/elements/row-element.js +7 -11
- package/dist/elements/text-element.d.ts +37 -11
- package/dist/elements/text-element.js +64 -39
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -19
- package/dist/ir/display-list.d.ts +4 -2
- package/dist/ir/display-list.js +1 -2
- package/dist/layout/box-constraints.js +2 -6
- package/dist/layout/fragmentation.d.ts +8 -1
- package/dist/layout/fragmentation.js +22 -10
- package/dist/platform/browser-fs.d.ts +2 -0
- package/dist/platform/browser-fs.js +9 -0
- package/dist/platform/browser-image.d.ts +5 -0
- package/dist/platform/browser-image.js +13 -0
- package/dist/platform/node-fs.d.ts +2 -0
- package/dist/platform/node-fs.js +10 -0
- package/dist/platform/node-image.d.ts +5 -0
- package/dist/platform/node-image.js +9 -0
- package/dist/renderer/container-renderer.d.ts +3 -3
- package/dist/renderer/container-renderer.js +12 -27
- package/dist/renderer/default-text-style-renderer.d.ts +6 -0
- package/dist/renderer/default-text-style-renderer.js +10 -0
- package/dist/renderer/deferred-renderer.d.ts +3 -3
- package/dist/renderer/deferred-renderer.js +8 -23
- package/dist/renderer/expanded-renderer.d.ts +3 -3
- package/dist/renderer/expanded-renderer.js +6 -21
- package/dist/renderer/image-renderer.d.ts +3 -3
- package/dist/renderer/image-renderer.js +77 -75
- package/dist/renderer/index.d.ts +10 -10
- package/dist/renderer/index.js +10 -26
- package/dist/renderer/line-renderer.d.ts +3 -3
- package/dist/renderer/line-renderer.js +13 -28
- package/dist/renderer/padding-renderer.d.ts +3 -3
- package/dist/renderer/padding-renderer.js +6 -21
- package/dist/renderer/page-renderer.d.ts +2 -2
- package/dist/renderer/page-renderer.js +61 -77
- package/dist/renderer/pdf-backend.d.ts +2 -2
- package/dist/renderer/pdf-backend.js +21 -19
- package/dist/renderer/pdf-config.js +4 -7
- package/dist/renderer/pdf-document-class.d.ts +5 -5
- package/dist/renderer/pdf-document-class.js +24 -41
- package/dist/renderer/pdf-document-renderer.d.ts +3 -3
- package/dist/renderer/pdf-document-renderer.js +71 -85
- package/dist/renderer/pdf-renderer.d.ts +2 -2
- package/dist/renderer/pdf-renderer.js +85 -93
- package/dist/renderer/positioned-renderer.d.ts +3 -3
- package/dist/renderer/positioned-renderer.js +8 -23
- package/dist/renderer/rectangle-renderer.d.ts +3 -3
- package/dist/renderer/rectangle-renderer.js +45 -52
- package/dist/renderer/repeating-header-renderer.d.ts +3 -3
- package/dist/renderer/repeating-header-renderer.js +11 -26
- package/dist/renderer/row-renderer.d.ts +3 -3
- package/dist/renderer/row-renderer.js +12 -27
- package/dist/renderer/text-renderer.d.ts +6 -5
- package/dist/renderer/text-renderer.js +33 -42
- package/dist/text/line-breaker.d.ts +8 -5
- package/dist/text/line-breaker.js +67 -16
- package/dist/text/text-style.d.ts +25 -0
- package/dist/text/text-style.js +29 -0
- package/dist/utils/afm-parser.js +3 -13
- package/dist/utils/bytes.d.ts +24 -0
- package/dist/utils/bytes.js +76 -0
- package/dist/utils/flex-layout.d.ts +2 -2
- package/dist/utils/flex-layout.js +15 -20
- package/dist/utils/font-metrics.d.ts +1 -1
- package/dist/utils/font-metrics.js +1 -2
- package/dist/utils/font-path.js +3 -6
- package/dist/utils/image-helper.d.ts +6 -5
- package/dist/utils/image-helper.js +101 -111
- package/dist/utils/md5.d.ts +4 -0
- package/dist/utils/md5.js +79 -0
- package/dist/utils/pdf-object-manager.d.ts +18 -6
- package/dist/utils/pdf-object-manager.js +0 -0
- package/dist/utils/renderer-registry.js +1 -5
- package/dist/utils/ttf-parser.d.ts +2 -2
- package/dist/utils/ttf-parser.js +32 -36
- package/dist/utils/ttf-subsetter.d.ts +1 -1
- package/dist/utils/ttf-subsetter.js +40 -42
- package/dist/utils/utf8-to-windows1252-encoder.js +1 -4
- package/dist/validators/element-validator.d.ts +2 -2
- package/dist/validators/element-validator.js +9 -13
- package/package.json +14 -2
package/dist/elements/index.js
CHANGED
|
@@ -1,29 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.PDFElement = void 0;
|
|
18
|
-
var pdf_element_1 = require("./pdf-element"); // the base element type - public for composing custom layouts
|
|
19
|
-
Object.defineProperty(exports, "PDFElement", { enumerable: true, get: function () { return pdf_element_1.PDFElement; } });
|
|
20
|
-
__exportStar(require("./text-element"), exports);
|
|
21
|
-
__exportStar(require("./pdf-document-element"), exports);
|
|
22
|
-
__exportStar(require("./page-element"), exports);
|
|
23
|
-
__exportStar(require("./rectangle-element"), exports);
|
|
24
|
-
__exportStar(require("./image-element"), exports);
|
|
25
|
-
__exportStar(require("./layout/expanded-element"), exports);
|
|
26
|
-
__exportStar(require("./layout/padding-element"), exports);
|
|
27
|
-
__exportStar(require("./layout/positioned-element"), exports);
|
|
28
|
-
__exportStar(require("./line-element"), exports);
|
|
29
|
-
__exportStar(require("./row-element"), exports);
|
|
1
|
+
export { PDFElement } from "./pdf-element.js"; // the base element type - public for composing custom layouts
|
|
2
|
+
export * from "./text-element.js";
|
|
3
|
+
export * from "./pdf-document-element.js";
|
|
4
|
+
export * from "./page-element.js";
|
|
5
|
+
export * from "./rectangle-element.js";
|
|
6
|
+
export * from "./image-element.js";
|
|
7
|
+
export * from "./layout/expanded-element.js";
|
|
8
|
+
export * from "./layout/padding-element.js";
|
|
9
|
+
export * from "./layout/default-text-style-element.js";
|
|
10
|
+
export * from "./layout/positioned-element.js";
|
|
11
|
+
export * from "./line-element.js";
|
|
12
|
+
export * from "./row-element.js";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PDFElement, LayoutContext, WithChild, SizedPDFElement } from "../pdf-element.js";
|
|
2
|
+
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints.js";
|
|
3
|
+
import { Fragmentable, FragmentResult } from "../../layout/fragmentation.js";
|
|
4
|
+
import { ResolvedTextStyle } from "../../text/text-style.js";
|
|
5
|
+
interface DefaultTextStyleParams extends WithChild {
|
|
6
|
+
style: Partial<ResolvedTextStyle>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Provides default text properties (font/size/color/lineHeight/align/weight) to its whole subtree -
|
|
10
|
+
* Flutter's `DefaultTextStyle`. Transparent to layout: the child takes the same constraints, offset
|
|
11
|
+
* and size; only the inherited TextStyle changes. A `Text` below still wins per property, and these
|
|
12
|
+
* overrides layer onto whatever the element already inherited from above.
|
|
13
|
+
*/
|
|
14
|
+
export declare class DefaultTextStyleElement extends SizedPDFElement implements Fragmentable {
|
|
15
|
+
private child;
|
|
16
|
+
private style;
|
|
17
|
+
constructor({ child, style }: DefaultTextStyleParams);
|
|
18
|
+
private childCtx;
|
|
19
|
+
fragment(maxHeight: number, width: number, ctx: LayoutContext): FragmentResult;
|
|
20
|
+
private cloneWithChild;
|
|
21
|
+
calculateLayout(constraints: BoxConstraints, offset: Offset, ctx: LayoutContext): Size;
|
|
22
|
+
getProps(): {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
width: number | undefined;
|
|
26
|
+
height: number | undefined;
|
|
27
|
+
child: PDFElement;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { SizedPDFElement } from "../pdf-element.js";
|
|
2
|
+
import { isFragmentable } from "../../layout/fragmentation.js";
|
|
3
|
+
import { DEFAULT_TEXT_STYLE, mergeTextStyle } from "../../text/text-style.js";
|
|
4
|
+
/**
|
|
5
|
+
* Provides default text properties (font/size/color/lineHeight/align/weight) to its whole subtree -
|
|
6
|
+
* Flutter's `DefaultTextStyle`. Transparent to layout: the child takes the same constraints, offset
|
|
7
|
+
* and size; only the inherited TextStyle changes. A `Text` below still wins per property, and these
|
|
8
|
+
* overrides layer onto whatever the element already inherited from above.
|
|
9
|
+
*/
|
|
10
|
+
export class DefaultTextStyleElement extends SizedPDFElement {
|
|
11
|
+
constructor({ child, style }) {
|
|
12
|
+
super({ x: 0, y: 0 });
|
|
13
|
+
this.child = child;
|
|
14
|
+
this.style = style;
|
|
15
|
+
}
|
|
16
|
+
childCtx(ctx) {
|
|
17
|
+
return {
|
|
18
|
+
...ctx,
|
|
19
|
+
textStyle: mergeTextStyle(ctx.textStyle ?? DEFAULT_TEXT_STYLE, this.style),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
// Transparent to fragmentation too: split the child against the merged context, re-wrapping each
|
|
23
|
+
// half so the remainder on the next page keeps the same defaults.
|
|
24
|
+
fragment(maxHeight, width, ctx) {
|
|
25
|
+
if (!isFragmentable(this.child))
|
|
26
|
+
return { fitted: null, remainder: this };
|
|
27
|
+
const split = this.child.fragment(maxHeight, width, this.childCtx(ctx));
|
|
28
|
+
return {
|
|
29
|
+
fitted: split.fitted ? this.cloneWithChild(split.fitted) : null,
|
|
30
|
+
remainder: split.remainder ? this.cloneWithChild(split.remainder) : null,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
cloneWithChild(child) {
|
|
34
|
+
return new DefaultTextStyleElement({ child, style: this.style });
|
|
35
|
+
}
|
|
36
|
+
calculateLayout(constraints, offset, ctx) {
|
|
37
|
+
this.x = offset.x;
|
|
38
|
+
this.y = offset.y;
|
|
39
|
+
const size = this.child.calculateLayout(constraints, offset, this.childCtx(ctx));
|
|
40
|
+
this.width = size.width;
|
|
41
|
+
this.height = size.height;
|
|
42
|
+
return size;
|
|
43
|
+
}
|
|
44
|
+
getProps() {
|
|
45
|
+
return { x: this.x, y: this.y, width: this.width, height: this.height, child: this.child };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints";
|
|
2
|
-
import { Fragmentable, FragmentResult } from "../../layout/fragmentation";
|
|
3
|
-
import { LayoutContext, PDFElement } from "../pdf-element";
|
|
1
|
+
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints.js";
|
|
2
|
+
import { Fragmentable, FragmentResult } from "../../layout/fragmentation.js";
|
|
3
|
+
import { LayoutContext, PDFElement } from "../pdf-element.js";
|
|
4
4
|
/**
|
|
5
5
|
* Builds its subtree at layout time via `resolve(ctx)`, so the tree can depend on font
|
|
6
6
|
* metrics (e.g. a Table resolving `"auto"` column widths from cell content). The engine
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.DeferredElement = void 0;
|
|
4
|
-
const fragmentation_1 = require("../../layout/fragmentation");
|
|
5
|
-
const pdf_element_1 = require("../pdf-element");
|
|
1
|
+
import { isFragmentable } from "../../layout/fragmentation.js";
|
|
2
|
+
import { PDFElement } from "../pdf-element.js";
|
|
6
3
|
/**
|
|
7
4
|
* Builds its subtree at layout time via `resolve(ctx)`, so the tree can depend on font
|
|
8
5
|
* metrics (e.g. a Table resolving `"auto"` column widths from cell content). The engine
|
|
9
6
|
* stays table-agnostic - the closure comes from the API layer.
|
|
10
7
|
*/
|
|
11
|
-
class DeferredElement extends
|
|
8
|
+
export class DeferredElement extends PDFElement {
|
|
12
9
|
constructor(resolve) {
|
|
13
10
|
super();
|
|
14
11
|
this.resolve = resolve;
|
|
@@ -22,7 +19,7 @@ class DeferredElement extends pdf_element_1.PDFElement {
|
|
|
22
19
|
}
|
|
23
20
|
fragment(maxHeight, width, ctx) {
|
|
24
21
|
const c = this.build(ctx);
|
|
25
|
-
return
|
|
22
|
+
return isFragmentable(c)
|
|
26
23
|
? c.fragment(maxHeight, width, ctx)
|
|
27
24
|
: { fitted: this, remainder: null };
|
|
28
25
|
}
|
|
@@ -30,4 +27,3 @@ class DeferredElement extends pdf_element_1.PDFElement {
|
|
|
30
27
|
return { composed: this.composed };
|
|
31
28
|
}
|
|
32
29
|
}
|
|
33
|
-
exports.DeferredElement = DeferredElement;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFElement, LayoutContext, FlexiblePDFElement, WithChild, FlexibleElement } from "../pdf-element";
|
|
2
|
-
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints";
|
|
3
|
-
import { Fragmentable, FragmentResult } from "../../layout/fragmentation";
|
|
1
|
+
import { PDFElement, LayoutContext, FlexiblePDFElement, WithChild, FlexibleElement } from "../pdf-element.js";
|
|
2
|
+
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints.js";
|
|
3
|
+
import { Fragmentable, FragmentResult } from "../../layout/fragmentation.js";
|
|
4
4
|
interface ExpandedElementParams extends FlexibleElement, WithChild {
|
|
5
5
|
}
|
|
6
6
|
export declare class ExpandedElement extends FlexiblePDFElement implements Fragmentable {
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const box_constraints_1 = require("../../layout/box-constraints");
|
|
7
|
-
const fragmentation_1 = require("../../layout/fragmentation");
|
|
8
|
-
class ExpandedElement extends pdf_element_1.FlexiblePDFElement {
|
|
1
|
+
import { Validator } from "../../validators/element-validator.js";
|
|
2
|
+
import { FlexiblePDFElement, } from "../pdf-element.js";
|
|
3
|
+
import { BoxConstraints } from "../../layout/box-constraints.js";
|
|
4
|
+
import { isFragmentable } from "../../layout/fragmentation.js";
|
|
5
|
+
export class ExpandedElement extends FlexiblePDFElement {
|
|
9
6
|
constructor({ flex, child }) {
|
|
10
7
|
super({ flex });
|
|
11
8
|
this.x = 0;
|
|
@@ -20,17 +17,17 @@ class ExpandedElement extends pdf_element_1.FlexiblePDFElement {
|
|
|
20
17
|
// Absolute placement from the parent; assignment (not +=) so re-layout is idempotent.
|
|
21
18
|
this.x = offset.x;
|
|
22
19
|
this.y = offset.y;
|
|
23
|
-
|
|
20
|
+
Validator.validateFlexElement(this);
|
|
24
21
|
if (constraints.hasBoundedHeight) {
|
|
25
|
-
// A bounded region: fill it - the normal flex
|
|
22
|
+
// A bounded region: fill it - the normal flex behavior.
|
|
26
23
|
this.height = constraints.maxHeight;
|
|
27
|
-
this.child.calculateLayout(
|
|
24
|
+
this.child.calculateLayout(BoxConstraints.loose(this.width, this.height), { x: this.x, y: this.y }, ctx);
|
|
28
25
|
}
|
|
29
26
|
else {
|
|
30
27
|
// Unbounded (measuring while paginating): there's no leftover space to fill, so
|
|
31
28
|
// collapse to the child's natural height. This lets an overflowing column flow
|
|
32
29
|
// instead of the flex silently hiding the overflow.
|
|
33
|
-
const childSize = this.child.calculateLayout(
|
|
30
|
+
const childSize = this.child.calculateLayout(BoxConstraints.loose(this.width, Infinity), { x: this.x, y: this.y }, ctx);
|
|
34
31
|
this.height = childSize.height;
|
|
35
32
|
}
|
|
36
33
|
// Top-left coordinates; the Y-flip now happens once at the IR -> backend seam.
|
|
@@ -43,7 +40,7 @@ class ExpandedElement extends pdf_element_1.FlexiblePDFElement {
|
|
|
43
40
|
* whole Expanded moves on.
|
|
44
41
|
*/
|
|
45
42
|
fragment(maxHeight, width, ctx) {
|
|
46
|
-
if (!
|
|
43
|
+
if (!isFragmentable(this.child)) {
|
|
47
44
|
return { fitted: null, remainder: this };
|
|
48
45
|
}
|
|
49
46
|
const split = this.child.fragment(maxHeight, width, ctx);
|
|
@@ -65,4 +62,3 @@ class ExpandedElement extends pdf_element_1.FlexiblePDFElement {
|
|
|
65
62
|
};
|
|
66
63
|
}
|
|
67
64
|
}
|
|
68
|
-
exports.ExpandedElement = ExpandedElement;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFElement, LayoutContext, WithChild, SizedPDFElement } from "../pdf-element";
|
|
2
|
-
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints";
|
|
3
|
-
import { Fragmentable, FragmentResult } from "../../layout/fragmentation";
|
|
1
|
+
import { PDFElement, LayoutContext, WithChild, SizedPDFElement } from "../pdf-element.js";
|
|
2
|
+
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints.js";
|
|
3
|
+
import { Fragmentable, FragmentResult } from "../../layout/fragmentation.js";
|
|
4
4
|
interface PaddingElementParams extends WithChild {
|
|
5
5
|
margin: [number, number, number, number];
|
|
6
6
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const box_constraints_1 = require("../../layout/box-constraints");
|
|
7
|
-
const fragmentation_1 = require("../../layout/fragmentation");
|
|
8
|
-
class PaddingElement extends pdf_element_1.SizedPDFElement {
|
|
1
|
+
import { Validator } from "../../validators/element-validator.js";
|
|
2
|
+
import { SizedPDFElement } from "../pdf-element.js";
|
|
3
|
+
import { BoxConstraints } from "../../layout/box-constraints.js";
|
|
4
|
+
import { isFragmentable } from "../../layout/fragmentation.js";
|
|
5
|
+
export class PaddingElement extends SizedPDFElement {
|
|
9
6
|
constructor({ margin, child }) {
|
|
10
7
|
super({ x: 0, y: 0 });
|
|
11
8
|
this.child = child;
|
|
@@ -18,7 +15,7 @@ class PaddingElement extends pdf_element_1.SizedPDFElement {
|
|
|
18
15
|
* child can't be split, the whole padding moves on as the remainder.
|
|
19
16
|
*/
|
|
20
17
|
fragment(maxHeight, width, ctx) {
|
|
21
|
-
if (!
|
|
18
|
+
if (!isFragmentable(this.child)) {
|
|
22
19
|
return { fitted: null, remainder: this };
|
|
23
20
|
}
|
|
24
21
|
const [marginTop, marginRight, marginBottom, marginLeft] = this.margin;
|
|
@@ -34,7 +31,6 @@ class PaddingElement extends pdf_element_1.SizedPDFElement {
|
|
|
34
31
|
return new PaddingElement({ margin: this.margin, child });
|
|
35
32
|
}
|
|
36
33
|
calculateLayout(constraints, offset, ctx) {
|
|
37
|
-
var _a;
|
|
38
34
|
// Padding takes the width it is offered; its height shrink-wraps the child.
|
|
39
35
|
if (constraints.hasBoundedWidth)
|
|
40
36
|
this.width = constraints.maxWidth;
|
|
@@ -50,7 +46,7 @@ class PaddingElement extends pdf_element_1.SizedPDFElement {
|
|
|
50
46
|
const childWidth = constraints.hasBoundedWidth
|
|
51
47
|
? Math.max(0, constraints.maxWidth - marginLeft - marginRight)
|
|
52
48
|
: Infinity;
|
|
53
|
-
const childConstraints =
|
|
49
|
+
const childConstraints = BoxConstraints.loose(childWidth, Infinity);
|
|
54
50
|
const childSize = this.child.calculateLayout(childConstraints, childOffset, ctx);
|
|
55
51
|
this.height = childSize.height + marginTop + marginBottom;
|
|
56
52
|
// Unbounded width (e.g. a fixed child in a Row): shrink-wrap to the child + insets,
|
|
@@ -58,9 +54,9 @@ class PaddingElement extends pdf_element_1.SizedPDFElement {
|
|
|
58
54
|
if (!constraints.hasBoundedWidth) {
|
|
59
55
|
this.width = childSize.width + marginLeft + marginRight;
|
|
60
56
|
}
|
|
61
|
-
|
|
57
|
+
Validator.validateSizedElement(this);
|
|
62
58
|
// Top-left coordinates; the Y-flip now happens once at the IR -> backend seam.
|
|
63
|
-
return { width:
|
|
59
|
+
return { width: this.width ?? 0, height: this.height };
|
|
64
60
|
}
|
|
65
61
|
getProps() {
|
|
66
62
|
return {
|
|
@@ -73,4 +69,3 @@ class PaddingElement extends pdf_element_1.SizedPDFElement {
|
|
|
73
69
|
};
|
|
74
70
|
}
|
|
75
71
|
}
|
|
76
|
-
exports.PaddingElement = PaddingElement;
|
|
@@ -1,11 +1,24 @@
|
|
|
1
|
-
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints";
|
|
2
|
-
import { LayoutContext, PDFElement, WithChild } from "../pdf-element";
|
|
3
|
-
/**
|
|
1
|
+
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints.js";
|
|
2
|
+
import { LayoutContext, PDFElement, WithChild } from "../pdf-element.js";
|
|
3
|
+
/** A position anchor along one axis: `start` (left/top), `center`, or `end` (right/bottom). */
|
|
4
|
+
export type PositionAnchor = "start" | "center" | "end";
|
|
5
|
+
/**
|
|
6
|
+
* How a `Positioned` child sits in its frame. Two ways, pick per axis:
|
|
7
|
+
* - EDGE pinning: `top`/`right`/`bottom`/`left` (points from that edge; negative pokes outside).
|
|
8
|
+
* Pinning BOTH sides of an axis stretches the child to fill between them.
|
|
9
|
+
* - ANCHOR + nudge: `h`/`v` anchor the child (start/center/end) and `x`/`y` nudge it from there
|
|
10
|
+
* (e.g. `{ h: "center", x: -10 }` = centered minus 10pt). The child shrink-wraps to its content.
|
|
11
|
+
* An edge wins over an anchor on the same axis. With nothing set the child sits at the top-left.
|
|
12
|
+
*/
|
|
4
13
|
export interface PositionedInsets {
|
|
5
14
|
top?: number;
|
|
6
15
|
right?: number;
|
|
7
16
|
bottom?: number;
|
|
8
17
|
left?: number;
|
|
18
|
+
h?: PositionAnchor;
|
|
19
|
+
v?: PositionAnchor;
|
|
20
|
+
x?: number;
|
|
21
|
+
y?: number;
|
|
9
22
|
}
|
|
10
23
|
interface PositionedElementParams extends WithChild, PositionedInsets {
|
|
11
24
|
}
|
|
@@ -22,7 +35,7 @@ interface PositionedElementParams extends WithChild, PositionedInsets {
|
|
|
22
35
|
export declare class PositionedElement extends PDFElement {
|
|
23
36
|
private child;
|
|
24
37
|
private insets;
|
|
25
|
-
constructor({ child, top, right, bottom, left }: PositionedElementParams);
|
|
38
|
+
constructor({ child, top, right, bottom, left, h, v, x, y }: PositionedElementParams);
|
|
26
39
|
calculateLayout(_constraints: BoxConstraints, _offset: Offset, ctx: LayoutContext): Size;
|
|
27
40
|
/** Lays the child out at the resolved position inside (or overflowing) the frame box. */
|
|
28
41
|
private placeInFrame;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.PositionedElement = void 0;
|
|
4
|
-
const box_constraints_1 = require("../../layout/box-constraints");
|
|
5
|
-
const pdf_element_1 = require("../pdf-element");
|
|
1
|
+
import { BoxConstraints } from "../../layout/box-constraints.js";
|
|
2
|
+
import { PDFElement } from "../pdf-element.js";
|
|
6
3
|
/**
|
|
7
4
|
* An out-of-flow child, placed relative to the nearest enclosing positioning frame (a `relative`
|
|
8
5
|
* Box). It takes ZERO space in the normal flow - `calculateLayout` returns `Size(0,0)` and instead
|
|
@@ -13,45 +10,52 @@ const pdf_element_1 = require("../pdf-element");
|
|
|
13
10
|
* With no frame in scope the element is a no-op (nothing is drawn) - `Positioned` only makes sense
|
|
14
11
|
* inside a `relative` Box.
|
|
15
12
|
*/
|
|
16
|
-
class PositionedElement extends
|
|
17
|
-
constructor({ child, top, right, bottom, left }) {
|
|
13
|
+
export class PositionedElement extends PDFElement {
|
|
14
|
+
constructor({ child, top, right, bottom, left, h, v, x, y }) {
|
|
18
15
|
super();
|
|
19
16
|
this.child = child;
|
|
20
|
-
this.insets = { top, right, bottom, left };
|
|
17
|
+
this.insets = { top, right, bottom, left, h, v, x, y };
|
|
21
18
|
}
|
|
22
19
|
calculateLayout(_constraints, _offset, ctx) {
|
|
23
|
-
var _a;
|
|
24
20
|
// Defer to the frame: it calls back once it has sized itself. Out of flow either way.
|
|
25
|
-
|
|
21
|
+
ctx.frame?.place.push((frame, frameCtx) => this.placeInFrame(frame, frameCtx));
|
|
26
22
|
return { width: 0, height: 0 };
|
|
27
23
|
}
|
|
28
24
|
/** Lays the child out at the resolved position inside (or overflowing) the frame box. */
|
|
29
25
|
placeInFrame(frame, ctx) {
|
|
30
|
-
const { top, right, bottom, left } = this.insets;
|
|
31
|
-
// An axis is PINNED (stretched) only when BOTH of its
|
|
32
|
-
// shrink-wraps its content (unbounded), the CSS rule for an absolutely-positioned element.
|
|
26
|
+
const { top, right, bottom, left, h, v, x: nudgeX, y: nudgeY } = this.insets;
|
|
27
|
+
// An axis is PINNED (stretched) only when BOTH of its EDGES are given; otherwise the child
|
|
28
|
+
// shrink-wraps its content (unbounded), the CSS rule for an absolutely-positioned element. An
|
|
29
|
+
// anchor never stretches - it positions a content-sized child.
|
|
33
30
|
const width = left !== undefined && right !== undefined
|
|
34
31
|
? Math.max(0, frame.size.width - left - right)
|
|
35
32
|
: Infinity;
|
|
36
33
|
const height = top !== undefined && bottom !== undefined
|
|
37
34
|
? Math.max(0, frame.size.height - top - bottom)
|
|
38
35
|
: Infinity;
|
|
39
|
-
const constraints =
|
|
40
|
-
// Measure first (so right/bottom
|
|
36
|
+
const constraints = BoxConstraints.loose(width, height);
|
|
37
|
+
// Measure first (so end/center anchors and right/bottom edges resolve against the child's size).
|
|
41
38
|
const measured = this.child.calculateLayout(constraints, { x: 0, y: 0 }, ctx);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
39
|
+
// Resolve one axis: a near-edge pins to origin, a far-edge pins to the far side; otherwise the
|
|
40
|
+
// anchor (default `start`) positions the child and the nudge shifts it from there.
|
|
41
|
+
const place = (origin, frameExtent, childExtent, nearEdge, farEdge, anchor, nudge) => {
|
|
42
|
+
if (nearEdge !== undefined)
|
|
43
|
+
return origin + nearEdge;
|
|
44
|
+
if (farEdge !== undefined)
|
|
45
|
+
return origin + frameExtent - childExtent - farEdge;
|
|
46
|
+
const base = anchor === "center"
|
|
47
|
+
? (frameExtent - childExtent) / 2
|
|
48
|
+
: anchor === "end"
|
|
49
|
+
? frameExtent - childExtent
|
|
50
|
+
: 0; // start (default)
|
|
51
|
+
return origin + base + (nudge ?? 0);
|
|
52
|
+
};
|
|
53
|
+
const x = place(frame.origin.x, frame.size.width, measured.width, left, right, h, nudgeX);
|
|
54
|
+
const y = place(frame.origin.y, frame.size.height, measured.height, top, bottom, v, nudgeY);
|
|
55
|
+
// Place it for real at the resolved position.
|
|
51
56
|
this.child.calculateLayout(constraints, { x, y }, ctx);
|
|
52
57
|
}
|
|
53
58
|
getProps() {
|
|
54
59
|
return { child: this.child };
|
|
55
60
|
}
|
|
56
61
|
}
|
|
57
|
-
exports.PositionedElement = PositionedElement;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints";
|
|
2
|
-
import { Fragmentable, FragmentResult } from "../../layout/fragmentation";
|
|
3
|
-
import { LayoutContext, PDFElement } from "../pdf-element";
|
|
1
|
+
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints.js";
|
|
2
|
+
import { Fragmentable, FragmentResult } from "../../layout/fragmentation.js";
|
|
3
|
+
import { LayoutContext, PDFElement } from "../pdf-element.js";
|
|
4
4
|
/**
|
|
5
5
|
* Stacks a `header` above a `body` and, when it paginates, **repeats the header on every
|
|
6
6
|
* fragment**. Used by `Table` so column headings reappear at the top of each page. Layout
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const box_constraints_1 = require("../../layout/box-constraints");
|
|
5
|
-
const fragmentation_1 = require("../../layout/fragmentation");
|
|
6
|
-
const pdf_element_1 = require("../pdf-element");
|
|
1
|
+
import { BoxConstraints } from "../../layout/box-constraints.js";
|
|
2
|
+
import { isFragmentable } from "../../layout/fragmentation.js";
|
|
3
|
+
import { PDFElement } from "../pdf-element.js";
|
|
7
4
|
/**
|
|
8
5
|
* Stacks a `header` above a `body` and, when it paginates, **repeats the header on every
|
|
9
6
|
* fragment**. Used by `Table` so column headings reappear at the top of each page. Layout
|
|
10
7
|
* is just header-then-body (like a 2-row Column); the magic is in `fragment`: it splits the
|
|
11
8
|
* body and re-wraps each piece with the same header, so every physical page gets its own.
|
|
12
9
|
*/
|
|
13
|
-
class RepeatingHeaderElement extends
|
|
10
|
+
export class RepeatingHeaderElement extends PDFElement {
|
|
14
11
|
constructor(header, body, gap = 0) {
|
|
15
12
|
super();
|
|
16
13
|
this.header = header;
|
|
@@ -25,16 +22,16 @@ class RepeatingHeaderElement extends pdf_element_1.PDFElement {
|
|
|
25
22
|
this.x = offset.x;
|
|
26
23
|
this.y = offset.y;
|
|
27
24
|
const width = constraints.hasBoundedWidth ? constraints.maxWidth : 0;
|
|
28
|
-
const h = this.header.calculateLayout(
|
|
29
|
-
const b = this.body.calculateLayout(
|
|
25
|
+
const h = this.header.calculateLayout(BoxConstraints.loose(width, Infinity), { x: this.x, y: this.y }, ctx);
|
|
26
|
+
const b = this.body.calculateLayout(BoxConstraints.loose(width, Infinity), { x: this.x, y: this.y + h.height + this.gap }, ctx);
|
|
30
27
|
this.width = width;
|
|
31
28
|
this.height = h.height + this.gap + b.height;
|
|
32
29
|
return { width: this.width, height: this.height };
|
|
33
30
|
}
|
|
34
31
|
fragment(maxHeight, width, ctx) {
|
|
35
32
|
// Reserve the header's height on every page; the body flows in what's left.
|
|
36
|
-
const headerHeight = this.header.calculateLayout(
|
|
37
|
-
if (!
|
|
33
|
+
const headerHeight = this.header.calculateLayout(BoxConstraints.loose(width, Infinity), { x: 0, y: 0 }, ctx).height;
|
|
34
|
+
if (!isFragmentable(this.body))
|
|
38
35
|
return { fitted: this, remainder: null };
|
|
39
36
|
const split = this.body.fragment(Math.max(0, maxHeight - headerHeight - this.gap), width, ctx);
|
|
40
37
|
// Body fits whole → the whole thing fits on this page.
|
|
@@ -57,4 +54,3 @@ class RepeatingHeaderElement extends pdf_element_1.PDFElement {
|
|
|
57
54
|
};
|
|
58
55
|
}
|
|
59
56
|
}
|
|
60
|
-
exports.RepeatingHeaderElement = RepeatingHeaderElement;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SizedElement, WithChildren, SizedPDFElement, LayoutContext } from "../pdf-element";
|
|
2
|
-
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints";
|
|
1
|
+
import { SizedElement, WithChildren, SizedPDFElement, LayoutContext } from "../pdf-element.js";
|
|
2
|
+
import { BoxConstraints, Offset, Size } from "../../layout/box-constraints.js";
|
|
3
3
|
interface ContainerElementParams extends SizedElement, WithChildren {
|
|
4
4
|
color?: [number, number, number];
|
|
5
5
|
backgroundColor?: [number, number, number];
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const pdf_element_1 = require("../pdf-element");
|
|
5
|
-
const box_constraints_1 = require("../../layout/box-constraints");
|
|
6
|
-
class SizedContainerElement extends pdf_element_1.SizedPDFElement {
|
|
1
|
+
import { SizedPDFElement, } from "../pdf-element.js";
|
|
2
|
+
import { BoxConstraints } from "../../layout/box-constraints.js";
|
|
3
|
+
export class SizedContainerElement extends SizedPDFElement {
|
|
7
4
|
constructor({ width, height, children }) {
|
|
8
5
|
super({ x: 0, y: 0, width, height });
|
|
9
6
|
this.children = children;
|
|
10
7
|
}
|
|
11
8
|
calculateLayout(constraints, offset, ctx) {
|
|
12
|
-
var _a, _b;
|
|
13
9
|
if (constraints.hasBoundedWidth)
|
|
14
10
|
this.width = constraints.maxWidth;
|
|
15
11
|
if (constraints.hasBoundedHeight)
|
|
@@ -17,10 +13,10 @@ class SizedContainerElement extends pdf_element_1.SizedPDFElement {
|
|
|
17
13
|
// Absolute placement from the parent; assignment (not +=) so re-layout is idempotent.
|
|
18
14
|
this.x = offset.x;
|
|
19
15
|
this.y = offset.y;
|
|
20
|
-
const width =
|
|
21
|
-
const height =
|
|
16
|
+
const width = this.width ?? 0;
|
|
17
|
+
const height = this.height ?? 0;
|
|
22
18
|
if (this.children)
|
|
23
|
-
this.children.forEach((child) => child.calculateLayout(
|
|
19
|
+
this.children.forEach((child) => child.calculateLayout(BoxConstraints.loose(width, height), { x: this.x, y: this.y }, ctx));
|
|
24
20
|
// Top-left coordinates; the Y-flip now happens once at the IR -> backend seam.
|
|
25
21
|
return { width, height };
|
|
26
22
|
}
|
|
@@ -34,4 +30,3 @@ class SizedContainerElement extends pdf_element_1.SizedPDFElement {
|
|
|
34
30
|
};
|
|
35
31
|
}
|
|
36
32
|
}
|
|
37
|
-
exports.SizedContainerElement = SizedContainerElement;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Color } from "../common/color";
|
|
2
|
-
import { BoxConstraints, Offset, Size } from "../layout/box-constraints";
|
|
3
|
-
import { LayoutContext, SizedElement, SizedPDFElement } from "./pdf-element";
|
|
1
|
+
import { Color } from "../common/color.js";
|
|
2
|
+
import { BoxConstraints, Offset, Size } from "../layout/box-constraints.js";
|
|
3
|
+
import { LayoutContext, SizedElement, SizedPDFElement } from "./pdf-element.js";
|
|
4
4
|
interface LineElementParams extends SizedElement {
|
|
5
5
|
color?: Color;
|
|
6
6
|
strokeWidth?: number;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const pdf_element_1 = require("./pdf-element");
|
|
6
|
-
class LineElement extends pdf_element_1.SizedPDFElement {
|
|
7
|
-
constructor({ color = new color_1.Color(0, 0, 0), strokeWidth, x, y, xEnd, yEnd }) {
|
|
1
|
+
import { Color } from "../common/color.js";
|
|
2
|
+
import { SizedPDFElement } from "./pdf-element.js";
|
|
3
|
+
export class LineElement extends SizedPDFElement {
|
|
4
|
+
constructor({ color = new Color(0, 0, 0), strokeWidth, x, y, xEnd, yEnd }) {
|
|
8
5
|
super({ x: x, y: y, width: xEnd, height: y + yEnd });
|
|
9
6
|
this.color = color;
|
|
10
7
|
this.strokeWidth = strokeWidth ? strokeWidth : 1;
|
|
@@ -15,7 +12,6 @@ class LineElement extends pdf_element_1.SizedPDFElement {
|
|
|
15
12
|
this.sizeMemory = { x, y, width: xEnd, height: yEnd };
|
|
16
13
|
}
|
|
17
14
|
calculateLayout(constraints, offset, _ctx) {
|
|
18
|
-
var _a, _b;
|
|
19
15
|
// Set relative to parent
|
|
20
16
|
this.x = this.sizeMemory.x + offset.x;
|
|
21
17
|
this.y = this.sizeMemory.y + offset.y;
|
|
@@ -26,7 +22,7 @@ class LineElement extends pdf_element_1.SizedPDFElement {
|
|
|
26
22
|
this.xEnd = offset.x + constraints.maxWidth - this.sizeMemory.width;
|
|
27
23
|
this.yEnd = offset.y + this.sizeMemory.height;
|
|
28
24
|
// Top-left coordinates; the Y-flip happens once at the IR -> backend seam.
|
|
29
|
-
return { width:
|
|
25
|
+
return { width: this.width ?? 0, height: this.height ?? 0 };
|
|
30
26
|
}
|
|
31
27
|
getProps() {
|
|
32
28
|
return {
|
|
@@ -41,4 +37,3 @@ class LineElement extends pdf_element_1.SizedPDFElement {
|
|
|
41
37
|
};
|
|
42
38
|
}
|
|
43
39
|
}
|
|
44
|
-
exports.LineElement = LineElement;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { PageSize } from "../constants/page-sizes";
|
|
2
|
-
import { Orientation } from "../renderer/pdf-config";
|
|
3
|
-
import type { ColorMode, DefaultFont, Margin } from "../renderer";
|
|
4
|
-
import { BoxConstraints, Offset, Size } from "../layout/box-constraints";
|
|
5
|
-
import { LayoutContext, PDFElement, WithChildren } from "./pdf-element";
|
|
6
|
-
import { TextElement } from "./text-element";
|
|
1
|
+
import { PageSize } from "../constants/page-sizes.js";
|
|
2
|
+
import { Orientation } from "../renderer/pdf-config.js";
|
|
3
|
+
import type { ColorMode, DefaultFont, Margin } from "../renderer/index.js";
|
|
4
|
+
import { BoxConstraints, Offset, Size } from "../layout/box-constraints.js";
|
|
5
|
+
import { LayoutContext, PDFElement, WithChildren } from "./pdf-element.js";
|
|
6
|
+
import { TextElement } from "./text-element.js";
|
|
7
7
|
export interface PDFPageConfig {
|
|
8
8
|
pageSize?: PageSize;
|
|
9
|
+
/** Explicit [width, height] in points; overrides `pageSize` (e.g. a custom label format). */
|
|
10
|
+
customSize?: [number, number];
|
|
9
11
|
orientation?: Orientation;
|
|
10
12
|
margin?: Margin;
|
|
11
13
|
colorMode?: ColorMode;
|