@jasy/pdf 1.0.0-alpha.1 → 1.0.0-alpha.10
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 +35 -21
- 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 +20 -13
- package/dist/api/content.js +44 -29
- package/dist/api/descriptor.d.ts +2 -2
- package/dist/api/descriptor.js +121 -31
- package/dist/api/dimension.d.ts +76 -0
- package/dist/api/dimension.js +43 -0
- package/dist/api/font-url.d.ts +28 -0
- package/dist/api/font-url.js +134 -0
- package/dist/api/forms.d.ts +347 -0
- package/dist/api/forms.js +189 -0
- package/dist/api/gradient.d.ts +53 -0
- package/dist/api/gradient.js +97 -0
- package/dist/api/index.d.ts +13 -8
- package/dist/api/index.js +13 -24
- package/dist/api/insets.d.ts +19 -12
- package/dist/api/insets.js +19 -12
- package/dist/api/layout.d.ts +149 -25
- package/dist/api/layout.js +182 -51
- package/dist/api/page-builder.d.ts +40 -0
- package/dist/api/page-builder.js +44 -0
- package/dist/api/structure.d.ts +100 -13
- package/dist/api/structure.js +179 -88
- package/dist/api/table.d.ts +5 -5
- package/dist/api/table.js +38 -26
- package/dist/api/text.d.ts +90 -4
- package/dist/api/text.js +116 -31
- 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/legacy-handler.d.ts +43 -0
- package/dist/crypto/legacy-handler.js +145 -0
- package/dist/crypto/security-handler.d.ts +62 -0
- package/dist/crypto/security-handler.js +155 -0
- package/dist/crypto/webcrypto.d.ts +11 -0
- package/dist/crypto/webcrypto.js +62 -0
- package/dist/edit/acroform-reader.d.ts +70 -0
- package/dist/edit/acroform-reader.js +126 -0
- package/dist/edit/appearance.d.ts +47 -0
- package/dist/edit/appearance.js +171 -0
- package/dist/edit/document.d.ts +145 -0
- package/dist/edit/document.js +642 -0
- package/dist/edit/fill.d.ts +65 -0
- package/dist/edit/fill.js +424 -0
- package/dist/edit/flatten.d.ts +54 -0
- package/dist/edit/flatten.js +462 -0
- package/dist/edit/index.d.ts +20 -0
- package/dist/edit/index.js +18 -0
- package/dist/edit/lexer.d.ts +30 -0
- package/dist/edit/lexer.js +285 -0
- package/dist/edit/objects.d.ts +68 -0
- package/dist/edit/objects.js +83 -0
- package/dist/edit/writer.d.ts +60 -0
- package/dist/edit/writer.js +283 -0
- package/dist/elements/container-element.d.ts +50 -5
- package/dist/elements/container-element.js +100 -39
- package/dist/elements/forms/checkbox-element.d.ts +51 -0
- package/dist/elements/forms/checkbox-element.js +48 -0
- package/dist/elements/forms/choice-element.d.ts +53 -0
- package/dist/elements/forms/choice-element.js +59 -0
- package/dist/elements/forms/push-button-element.d.ts +56 -0
- package/dist/elements/forms/push-button-element.js +49 -0
- package/dist/elements/forms/radio-element.d.ts +52 -0
- package/dist/elements/forms/radio-element.js +49 -0
- package/dist/elements/forms/signature-element.d.ts +54 -0
- package/dist/elements/forms/signature-element.js +47 -0
- package/dist/elements/forms/text-field-element.d.ts +61 -0
- package/dist/elements/forms/text-field-element.js +54 -0
- package/dist/elements/image-element.d.ts +58 -6
- package/dist/elements/image-element.js +145 -111
- package/dist/elements/index.d.ts +26 -10
- package/dist/elements/index.js +26 -28
- package/dist/elements/layout/anchor-element.d.ts +23 -0
- package/dist/elements/layout/anchor-element.js +27 -0
- package/dist/elements/layout/bookmark-element.d.ts +27 -0
- package/dist/elements/layout/bookmark-element.js +30 -0
- 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 +6 -4
- package/dist/elements/layout/expanded-element.js +22 -17
- package/dist/elements/layout/keep-together-element.d.ts +42 -0
- package/dist/elements/layout/keep-together-element.js +85 -0
- package/dist/elements/layout/link-element.d.ts +33 -0
- package/dist/elements/layout/link-element.js +39 -0
- package/dist/elements/layout/padding-element.d.ts +10 -5
- package/dist/elements/layout/padding-element.js +25 -16
- package/dist/elements/layout/page-break-element.d.ts +17 -0
- package/dist/elements/layout/page-break-element.js +24 -0
- package/dist/elements/layout/page-builder-element.d.ts +32 -0
- package/dist/elements/layout/page-builder-element.js +45 -0
- package/dist/elements/layout/positioned-element.d.ts +47 -0
- package/dist/elements/layout/positioned-element.js +73 -0
- 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/rotated-box-element.d.ts +35 -0
- package/dist/elements/layout/rotated-box-element.js +54 -0
- package/dist/elements/layout/rotated-element.d.ts +32 -0
- package/dist/elements/layout/rotated-element.js +41 -0
- package/dist/elements/layout/sized-container-element.d.ts +2 -2
- package/dist/elements/layout/sized-container-element.js +6 -11
- package/dist/elements/layout/struct-group.d.ts +28 -0
- package/dist/elements/layout/struct-group.js +42 -0
- package/dist/elements/line-element.d.ts +3 -3
- package/dist/elements/line-element.js +5 -10
- package/dist/elements/page-element.d.ts +26 -6
- package/dist/elements/page-element.js +72 -27
- 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 +150 -4
- package/dist/elements/pdf-element.js +138 -20
- package/dist/elements/rectangle-element.d.ts +52 -11
- package/dist/elements/rectangle-element.js +129 -36
- package/dist/elements/row-element.d.ts +45 -4
- package/dist/elements/row-element.js +66 -18
- package/dist/elements/text-element.d.ts +132 -11
- package/dist/elements/text-element.js +206 -56
- package/dist/forms/acroform.d.ts +63 -0
- package/dist/forms/acroform.js +427 -0
- package/dist/forms/appearance.d.ts +58 -0
- package/dist/forms/appearance.js +204 -0
- package/dist/forms/field.d.ts +164 -0
- package/dist/forms/field.js +1 -0
- package/dist/forms/pdf.d.ts +19 -0
- package/dist/forms/pdf.js +28 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -19
- package/dist/ir/display-list.d.ts +197 -8
- package/dist/ir/display-list.js +8 -2
- package/dist/layout/alignment.d.ts +10 -0
- package/dist/layout/alignment.js +6 -0
- package/dist/layout/box-constraints.d.ts +61 -0
- package/dist/layout/box-constraints.js +88 -6
- package/dist/layout/collect-images.d.ts +9 -0
- package/dist/layout/collect-images.js +34 -0
- package/dist/layout/fragmentation.d.ts +20 -1
- package/dist/layout/fragmentation.js +74 -18
- package/dist/layout/insets.d.ts +28 -0
- package/dist/layout/insets.js +20 -0
- 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/anchor-renderer.d.ts +6 -0
- package/dist/renderer/anchor-renderer.js +11 -0
- package/dist/renderer/bookmark-renderer.d.ts +6 -0
- package/dist/renderer/bookmark-renderer.js +11 -0
- package/dist/renderer/container-renderer.d.ts +3 -3
- package/dist/renderer/container-renderer.js +11 -28
- 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/emoji-image.d.ts +9 -0
- package/dist/renderer/emoji-image.js +68 -0
- package/dist/renderer/expanded-renderer.d.ts +3 -3
- package/dist/renderer/expanded-renderer.js +6 -21
- package/dist/renderer/form-field-renderer.d.ts +20 -0
- package/dist/renderer/form-field-renderer.js +12 -0
- package/dist/renderer/image-renderer.d.ts +4 -4
- package/dist/renderer/image-renderer.js +86 -75
- package/dist/renderer/index.d.ts +10 -10
- package/dist/renderer/index.js +10 -26
- package/dist/renderer/keep-together-renderer.d.ts +10 -0
- package/dist/renderer/keep-together-renderer.js +12 -0
- package/dist/renderer/line-renderer.d.ts +3 -3
- package/dist/renderer/line-renderer.js +13 -28
- package/dist/renderer/link-renderer.d.ts +6 -0
- package/dist/renderer/link-renderer.js +11 -0
- package/dist/renderer/padding-renderer.d.ts +3 -3
- package/dist/renderer/padding-renderer.js +6 -21
- package/dist/renderer/page-break-renderer.d.ts +14 -0
- package/dist/renderer/page-break-renderer.js +15 -0
- package/dist/renderer/page-builder-renderer.d.ts +6 -0
- package/dist/renderer/page-builder-renderer.js +11 -0
- package/dist/renderer/page-renderer.d.ts +2 -2
- package/dist/renderer/page-renderer.js +115 -77
- package/dist/renderer/pdf-backend.d.ts +31 -4
- package/dist/renderer/pdf-backend.js +287 -49
- 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 +27 -41
- package/dist/renderer/pdf-document-renderer.d.ts +19 -10
- package/dist/renderer/pdf-document-renderer.js +135 -91
- package/dist/renderer/pdf-renderer.d.ts +2 -2
- package/dist/renderer/pdf-renderer.js +165 -90
- package/dist/renderer/positioned-renderer.d.ts +6 -0
- package/dist/renderer/positioned-renderer.js +10 -0
- package/dist/renderer/rectangle-renderer.d.ts +3 -3
- package/dist/renderer/rectangle-renderer.js +49 -44
- package/dist/renderer/repeating-header-renderer.d.ts +3 -3
- package/dist/renderer/repeating-header-renderer.js +10 -26
- package/dist/renderer/rotated-renderer.d.ts +7 -0
- package/dist/renderer/rotated-renderer.js +29 -0
- package/dist/renderer/row-renderer.d.ts +3 -3
- package/dist/renderer/row-renderer.js +11 -28
- package/dist/renderer/struct-group-renderer.d.ts +10 -0
- package/dist/renderer/struct-group-renderer.js +24 -0
- package/dist/renderer/text-renderer.d.ts +9 -5
- package/dist/renderer/text-renderer.js +437 -89
- package/dist/text/advance.d.ts +34 -0
- package/dist/text/advance.js +45 -0
- package/dist/text/arabic.d.ts +20 -0
- package/dist/text/arabic.js +101 -0
- package/dist/text/bidi.d.ts +33 -0
- package/dist/text/bidi.js +94 -0
- package/dist/text/emoji-codepoints.d.ts +1 -0
- package/dist/text/emoji-codepoints.js +29 -0
- package/dist/text/font-fallback.d.ts +25 -0
- package/dist/text/font-fallback.js +38 -0
- package/dist/text/line-breaker.d.ts +50 -12
- package/dist/text/line-breaker.js +158 -37
- package/dist/text/line-metrics.d.ts +49 -0
- package/dist/text/line-metrics.js +57 -0
- package/dist/text/orphans-widows.d.ts +27 -0
- package/dist/text/orphans-widows.js +53 -0
- package/dist/text/shape.d.ts +29 -0
- package/dist/text/shape.js +67 -0
- package/dist/text/text-decoration.d.ts +50 -0
- package/dist/text/text-decoration.js +62 -0
- package/dist/text/text-style.d.ts +60 -0
- package/dist/text/text-style.js +79 -0
- package/dist/utils/afm-parser.d.ts +34 -0
- package/dist/utils/afm-parser.js +76 -17
- package/dist/utils/bytes.d.ts +24 -0
- package/dist/utils/bytes.js +76 -0
- package/dist/utils/dest-registry.d.ts +22 -0
- package/dist/utils/dest-registry.js +32 -0
- package/dist/utils/flex-layout.d.ts +36 -9
- package/dist/utils/flex-layout.js +207 -30
- package/dist/utils/font-metrics.d.ts +20 -1
- package/dist/utils/font-metrics.js +1 -2
- package/dist/utils/font-path.js +3 -6
- package/dist/utils/gsub.d.ts +36 -0
- package/dist/utils/gsub.js +178 -0
- package/dist/utils/image-helper.d.ts +6 -5
- package/dist/utils/image-helper.js +101 -111
- package/dist/utils/inflate.d.ts +16 -0
- package/dist/utils/inflate.js +52 -0
- package/dist/utils/md5.d.ts +4 -0
- package/dist/utils/md5.js +79 -0
- package/dist/utils/outline.d.ts +21 -0
- package/dist/utils/outline.js +79 -0
- package/dist/utils/pdf-object-manager.d.ts +110 -8
- package/dist/utils/pdf-object-manager.js +583 -141
- package/dist/utils/renderer-registry.d.ts +13 -1
- package/dist/utils/renderer-registry.js +23 -6
- package/dist/utils/struct-tree.d.ts +44 -0
- package/dist/utils/struct-tree.js +129 -0
- package/dist/utils/ttf-parser.d.ts +134 -2
- package/dist/utils/ttf-parser.js +873 -50
- package/dist/utils/ttf-subsetter.d.ts +1 -1
- package/dist/utils/ttf-subsetter.js +40 -42
- package/dist/utils/ua-xmp.d.ts +9 -0
- package/dist/utils/ua-xmp.js +32 -0
- package/dist/utils/utf8-to-windows1252-encoder.d.ts +6 -0
- package/dist/utils/utf8-to-windows1252-encoder.js +11 -4
- package/dist/utils/woff.d.ts +10 -0
- package/dist/utils/woff.js +116 -0
- package/dist/validators/element-validator.d.ts +2 -2
- package/dist/validators/element-validator.js +31 -26
- package/package.json +22 -2
|
@@ -1,22 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { pageFormats, PageSize } 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";
|
|
5
|
+
/**
|
|
6
|
+
* The full page (media box) size in points, orientation applied. This is what a `PageBuilder` sees as
|
|
7
|
+
* `pageSize`; `resolvePageContentBox` below then subtracts the margins.
|
|
8
|
+
*/
|
|
9
|
+
export function resolvePageSize(config) {
|
|
10
|
+
// Defaults to A4 when the config is not fully resolved, matching what PageRenderer does for the MediaBox.
|
|
11
|
+
const [pageW, pageH] = config.customSize ?? pageFormats[config.pageSize ?? PageSize.A4];
|
|
12
|
+
return config.orientation === Orientation.landscape
|
|
13
|
+
? { width: pageH, height: pageW }
|
|
14
|
+
: { width: pageW, height: pageH };
|
|
15
|
+
}
|
|
10
16
|
/**
|
|
11
17
|
* The content box of a page (inside the margins, orientation applied) for a fully
|
|
12
18
|
* resolved config. Single source of truth, shared by `PageElement` layout and the page
|
|
13
19
|
* driver so they can never drift.
|
|
14
20
|
*/
|
|
15
|
-
function resolvePageContentBox(config) {
|
|
21
|
+
export function resolvePageContentBox(config) {
|
|
16
22
|
const margin = config.margin;
|
|
17
|
-
|
|
18
|
-
let
|
|
19
|
-
|
|
23
|
+
const [pageW, pageH] = config.customSize ?? pageFormats[config.pageSize];
|
|
24
|
+
let width = pageW - margin.left - margin.right;
|
|
25
|
+
let height = pageH - margin.top - margin.bottom;
|
|
26
|
+
if (config.orientation === Orientation.landscape) {
|
|
20
27
|
[width, height] = [height, width];
|
|
21
28
|
}
|
|
22
29
|
return { origin: { x: margin.left, y: margin.top }, width, height };
|
|
@@ -29,17 +36,35 @@ function resolvePageContentBox(config) {
|
|
|
29
36
|
* no header/footer the bands are zero and the body equals the full content box - identical
|
|
30
37
|
* to a page without them.
|
|
31
38
|
*/
|
|
32
|
-
|
|
39
|
+
/**
|
|
40
|
+
* The page's positioning frame: its CONTENT box (paper minus margins). Header, footer and body all
|
|
41
|
+
* resolve a `Positioned` against this same box, so `top`/`bottom` mean the same thing in each.
|
|
42
|
+
*
|
|
43
|
+
* `layoutPageBands` lays the bands out, so its caller must hand it a context carrying this frame -
|
|
44
|
+
* otherwise a `Positioned` in a band has nothing to resolve against (ISSUE-4). A caller that only
|
|
45
|
+
* wants the band HEIGHTS may throw the frame away without draining it: an out-of-flow child
|
|
46
|
+
* contributes no height.
|
|
47
|
+
*/
|
|
48
|
+
export function pageFrame(config) {
|
|
49
|
+
const { origin, width, height } = resolvePageContentBox(config);
|
|
50
|
+
return { origin, size: { width, height }, place: [] };
|
|
51
|
+
}
|
|
52
|
+
export function layoutPageBands(config, header, footer, ctx) {
|
|
33
53
|
const { origin, width, height } = resolvePageContentBox(config);
|
|
34
54
|
let headerHeight = 0;
|
|
35
55
|
if (header) {
|
|
36
|
-
headerHeight = header.calculateLayout(
|
|
56
|
+
headerHeight = header.calculateLayout(BoxConstraints.loose(width, Infinity), origin, ctx).height;
|
|
37
57
|
}
|
|
38
58
|
let footerHeight = 0;
|
|
39
59
|
if (footer) {
|
|
40
|
-
// Measure first to learn its height, then place it flush against the bottom edge.
|
|
41
|
-
|
|
42
|
-
|
|
60
|
+
// Measure first to learn its height, then place it flush against the bottom edge. The MEASURING
|
|
61
|
+
// pass gets a throwaway `place` list: an out-of-flow child registers a placement every time it is
|
|
62
|
+
// laid out, and this subtree is laid out twice. Only the second, real pass may register.
|
|
63
|
+
const measureCtx = ctx.frame
|
|
64
|
+
? { ...ctx, frame: { ...ctx.frame, place: [] } }
|
|
65
|
+
: ctx;
|
|
66
|
+
footerHeight = footer.calculateLayout(BoxConstraints.loose(width, Infinity), origin, measureCtx).height;
|
|
67
|
+
footer.calculateLayout(BoxConstraints.loose(width, Infinity), { x: origin.x, y: origin.y + height - footerHeight }, ctx);
|
|
43
68
|
}
|
|
44
69
|
return {
|
|
45
70
|
bodyOrigin: { x: origin.x, y: origin.y + headerHeight },
|
|
@@ -49,11 +74,11 @@ function layoutPageBands(config, header, footer, ctx) {
|
|
|
49
74
|
footerHeight,
|
|
50
75
|
};
|
|
51
76
|
}
|
|
52
|
-
class PageElement extends
|
|
77
|
+
export class PageElement extends PDFElement {
|
|
53
78
|
constructor({ children, config, header, footer }) {
|
|
54
79
|
super();
|
|
55
80
|
this.children = children;
|
|
56
|
-
this.config = config
|
|
81
|
+
this.config = config ?? {};
|
|
57
82
|
this.header = header;
|
|
58
83
|
this.footer = footer;
|
|
59
84
|
}
|
|
@@ -61,18 +86,39 @@ class PageElement extends pdf_element_1.PDFElement {
|
|
|
61
86
|
// Merge the document defaults (carried in the context) with this page's overrides,
|
|
62
87
|
// then hand descendants a context bound to THIS page's geometry. This is what
|
|
63
88
|
// fixes the old last-page-wins global page-config bug.
|
|
64
|
-
this.config =
|
|
89
|
+
this.config = { ...ctx.pageConfig, ...this.config };
|
|
65
90
|
const pageCtx = {
|
|
66
91
|
metrics: ctx.metrics,
|
|
67
92
|
pageConfig: this.config,
|
|
93
|
+
textStyle: ctx.textStyle,
|
|
94
|
+
onOverflow: ctx.onOverflow,
|
|
95
|
+
pageInfo: ctx.pageInfo, // the render pass supplies it; absent during pagination
|
|
68
96
|
};
|
|
97
|
+
// The PAGE is a positioning frame, and the frame is the content box - not the body region left
|
|
98
|
+
// over between the bands. So `Positioned` means the same thing in the header, in the footer and
|
|
99
|
+
// in the body, `bottom: 0` is the foot of the page rather than the top of the footer, and adding
|
|
100
|
+
// a header no longer shifts a page-level `Positioned` that nobody touched. A `relative` Box
|
|
101
|
+
// still overrides it for its own subtree.
|
|
102
|
+
//
|
|
103
|
+
// Built BEFORE the bands are laid out: they need to see it, and their heights are not known yet
|
|
104
|
+
// anyway. (That is the whole of ISSUE-4 - a `Positioned` in a band had no frame to resolve
|
|
105
|
+
// against, so it silently stayed at the page's top-left corner.)
|
|
106
|
+
const frame = pageFrame(this.config);
|
|
107
|
+
const frameCtx = { ...pageCtx, frame };
|
|
69
108
|
// Place the header/footer bands; the body gets the region left in between (the whole
|
|
70
109
|
// content box when there is neither - byte-identical to a plain page).
|
|
71
|
-
const bands = layoutPageBands(this.config, this.header, this.footer,
|
|
72
|
-
const childConstraints =
|
|
73
|
-
this.children.forEach((child) => child.calculateLayout(childConstraints, bands.bodyOrigin,
|
|
74
|
-
|
|
75
|
-
|
|
110
|
+
const bands = layoutPageBands(this.config, this.header, this.footer, frameCtx);
|
|
111
|
+
const childConstraints = BoxConstraints.loose(bands.bodyWidth, bands.bodyHeight);
|
|
112
|
+
this.children.forEach((child) => child.calculateLayout(childConstraints, bands.bodyOrigin, frameCtx));
|
|
113
|
+
// Drained last, once every band and the body have registered: an out-of-flow child is placed
|
|
114
|
+
// against the final frame box and paints on top of the flow content.
|
|
115
|
+
//
|
|
116
|
+
// The callback gets `frameCtx`, not `pageCtx`: a `Positioned` NESTED inside an out-of-flow child
|
|
117
|
+
// must still see a frame. It appends to `frame.place` while we walk it, and a `for..of` over an
|
|
118
|
+
// array visits what was appended, so nested placements drain in the same loop.
|
|
119
|
+
for (const place of frame.place)
|
|
120
|
+
place(frame, frameCtx);
|
|
121
|
+
return { width: frame.size.width, height: frame.size.height };
|
|
76
122
|
}
|
|
77
123
|
getProps() {
|
|
78
124
|
return {
|
|
@@ -87,4 +133,3 @@ class PageElement extends pdf_element_1.PDFElement {
|
|
|
87
133
|
return this;
|
|
88
134
|
}
|
|
89
135
|
}
|
|
90
|
-
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
|
-
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
|
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,17 +1,77 @@
|
|
|
1
|
-
import type { FontMetrics } from "../utils/font-metrics";
|
|
2
|
-
import type { PDFPageConfig } from "./page-element";
|
|
3
|
-
import type {
|
|
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";
|
|
6
|
+
import type { CrossAlign } from "../layout/alignment.js";
|
|
4
7
|
/**
|
|
5
8
|
* Everything the layout pass needs, threaded explicitly (no global singleton):
|
|
6
9
|
* font metrics for measuring, and the geometry of the page currently being laid out.
|
|
7
10
|
* `PageElement` sets `pageConfig` for its subtree, so each page flips against its own
|
|
8
11
|
* height. The PDF byte writer is deliberately absent - layout must not touch it.
|
|
9
12
|
*/
|
|
13
|
+
/**
|
|
14
|
+
* A positioning frame - the CSS "containing block" that `Positioned` children resolve their
|
|
15
|
+
* offsets against. A `relative` Box (later the page) creates one and threads it to its subtree;
|
|
16
|
+
* `Positioned` descendants register a placement closure in `place`, which the frame drains once it
|
|
17
|
+
* has finished sizing itself (so `right`/`bottom` can resolve against the final box).
|
|
18
|
+
*/
|
|
19
|
+
export interface PositioningFrame {
|
|
20
|
+
origin: Offset;
|
|
21
|
+
size: Size;
|
|
22
|
+
place: Array<(frame: {
|
|
23
|
+
origin: Offset;
|
|
24
|
+
size: Size;
|
|
25
|
+
}, ctx: LayoutContext) => void>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* What a `PageBuilder` learns about the page it landed on. `pageNumber` is 1-based and counts PHYSICAL
|
|
29
|
+
* pages across the whole document (a logical `Page` that overflows contributes several); `pageCount` is
|
|
30
|
+
* the document's final physical page total. `pageSize` is the media box in points, orientation applied.
|
|
31
|
+
*/
|
|
32
|
+
export interface PageInfo {
|
|
33
|
+
/** 1-based, counting PHYSICAL pages across the whole document. */
|
|
34
|
+
pageNumber: number;
|
|
35
|
+
/** Physical pages in the whole document. */
|
|
36
|
+
pageCount: number;
|
|
37
|
+
/**
|
|
38
|
+
* 1-based within the LOGICAL page this sheet came from - the `Page(...)` element the author wrote.
|
|
39
|
+
* A document of one `Page` has `subPageNumber === pageNumber`; a document of several (an invoice
|
|
40
|
+
* plus its attachment, say) restarts the count at each one.
|
|
41
|
+
*/
|
|
42
|
+
subPageNumber: number;
|
|
43
|
+
/** Physical pages this logical page produced. */
|
|
44
|
+
subPageTotalPages: number;
|
|
45
|
+
pageSize: {
|
|
46
|
+
width: number;
|
|
47
|
+
height: number;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
10
50
|
export interface LayoutContext {
|
|
11
51
|
metrics: FontMetrics;
|
|
12
52
|
pageConfig: PDFPageConfig;
|
|
53
|
+
/** The page a `PageBuilder` is being laid out on. Only the render pass knows the real numbers, so
|
|
54
|
+
* during pagination this is absent and a `PageBuilder` builds against a provisional "1 of 1". */
|
|
55
|
+
pageInfo?: PageInfo;
|
|
56
|
+
/** The nearest enclosing positioning frame, if any (set by a `relative` Box). */
|
|
57
|
+
frame?: PositioningFrame;
|
|
58
|
+
/** The cascaded text style descendants inherit (CSS/Flutter-style). Seeded at the document root
|
|
59
|
+
* from the built-in defaults + the `Document` defaults, and carried through page contexts; a
|
|
60
|
+
* `Text` resolves its own unset properties against it. Absent falls back to the built-in defaults. */
|
|
61
|
+
textStyle?: ResolvedTextStyle;
|
|
62
|
+
/** What to do when an element overflows a page region and cannot break (set from the render option;
|
|
63
|
+
* absent = clip silently). Evaluated in `packChildren` where the forced placement happens. */
|
|
64
|
+
onOverflow?: OverflowPolicy;
|
|
65
|
+
/** The FULL body height of the current page (between header and footer), set by the page driver. A
|
|
66
|
+
* `keepTogether` group reads it to decide the degrade rule: veto splitting only when the group would
|
|
67
|
+
* fit on a fresh page; a group taller than a whole page drops the veto and splits. */
|
|
68
|
+
pageBodyHeight?: number;
|
|
13
69
|
}
|
|
14
70
|
export declare abstract class PDFElement {
|
|
71
|
+
private _structId;
|
|
72
|
+
get structId(): number;
|
|
73
|
+
/** Make this element share `from`'s tagging identity - used by fragmentation clones. Returns this. */
|
|
74
|
+
adoptStructId(from: PDFElement): this;
|
|
15
75
|
abstract getProps(): unknown;
|
|
16
76
|
/**
|
|
17
77
|
* Lays the element out: `constraints` bound its size (flows DOWN), `offset` is the
|
|
@@ -20,6 +80,70 @@ export declare abstract class PDFElement {
|
|
|
20
80
|
* happens once at the IR -> backend seam.
|
|
21
81
|
*/
|
|
22
82
|
abstract calculateLayout(constraints: BoxConstraints, offset: Offset, ctx: LayoutContext): Size;
|
|
83
|
+
/**
|
|
84
|
+
* The relative-size fraction (0..1) this element asked for on the given axis, if any (`horizontal` =
|
|
85
|
+
* width). A flex parent reads it to resolve a percentage child against its OWN main size - e.g. a
|
|
86
|
+
* `Box({ width: "50%" })` inside a Row, where the child otherwise gets an unbounded main axis and the
|
|
87
|
+
* fraction would have nothing to resolve against. Default: the element is not relatively sized.
|
|
88
|
+
*/
|
|
89
|
+
relativeSizeFactor(_horizontal: boolean): number | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Whether this element needs a BOUNDED extent on the given axis to lay itself out (`true` for a
|
|
92
|
+
* horizontal axis = width). A flex parent measures its fixed children with an unbounded main axis, so
|
|
93
|
+
* they keep their natural size; but a stack holding an `Expanded`/`Spacer` has no leftover space to
|
|
94
|
+
* distribute unless it is told how much main axis it may occupy. Such a stack answers `true` here and
|
|
95
|
+
* the parent hands it the line's bounded main extent instead of `Infinity`. Default: no.
|
|
96
|
+
*/
|
|
97
|
+
needsBoundedMain(_horizontal: boolean): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Whether this element IS a forced page break (a `PageBreak`). The pagination packer cuts the flow
|
|
100
|
+
* at such a marker: everything before it stays, everything after starts a new page. Default: no.
|
|
101
|
+
*/
|
|
102
|
+
isPageBreak(): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Whether this element is, or CONTAINS anywhere in its subtree, a forced page break. A container
|
|
105
|
+
* that merely fits by height must still be fragmented when this is true, so a break nested inside
|
|
106
|
+
* it is honoured rather than swallowed. Containers override this to recurse into their children.
|
|
107
|
+
* Default: no.
|
|
108
|
+
*/
|
|
109
|
+
hasForcedBreak(): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Whether this element asks to START on a fresh page (CSS `break-before: page`, react-pdf's `break`
|
|
112
|
+
* prop). Read by the parent packer at the child boundary, not by the element itself; ignored when the
|
|
113
|
+
* element is already at the top of a region (nothing before it), so it never makes an empty page.
|
|
114
|
+
* Default: no.
|
|
115
|
+
*/
|
|
116
|
+
breaksBefore(): boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Whether everything AFTER this element must start a fresh page (CSS `break-after: page`). Read by the
|
|
119
|
+
* parent packer once this element has been placed whole. Default: no.
|
|
120
|
+
*/
|
|
121
|
+
breaksAfter(): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* This child's own cross-axis alignment inside its Column / Row (CSS `align-self`), overriding the
|
|
124
|
+
* container's `align`. Lives on the base element because any child of a stack may set it, not just
|
|
125
|
+
* the sized ones. `undefined` means "follow the container".
|
|
126
|
+
*/
|
|
127
|
+
alignSelf?: CrossAlign;
|
|
128
|
+
/** Sets `alignSelf` and returns the element, so a factory can thread it through in one expression. */
|
|
129
|
+
withAlignSelf(align: CrossAlign | undefined): this;
|
|
130
|
+
/**
|
|
131
|
+
* Where this child sits among its siblings (CSS `order`), lowest first, source order deciding ties.
|
|
132
|
+
* It moves the child in the LAYOUT only - the element tree, and therefore the reading order a tagged
|
|
133
|
+
* PDF exposes, is untouched. Default 0.
|
|
134
|
+
*/
|
|
135
|
+
order: number;
|
|
136
|
+
/**
|
|
137
|
+
* How willingly this child gives up main-axis space when the line overflows (CSS `flex-shrink`),
|
|
138
|
+
* weighted by its own size as CSS does. **Default 0, deliberately unlike CSS's 1**: shrinking is a
|
|
139
|
+
* change of what a document LOOKS like, and every document written before this existed must keep
|
|
140
|
+
* laying out exactly as it did. Opt in per child.
|
|
141
|
+
*/
|
|
142
|
+
flexShrink: number;
|
|
143
|
+
/** Sets `flexShrink` and returns the element. */
|
|
144
|
+
withFlexShrink(shrink: number | undefined): this;
|
|
145
|
+
/** Sets `order` and returns the element, so a factory can thread it through in one expression. */
|
|
146
|
+
withOrder(order: number | undefined): this;
|
|
23
147
|
}
|
|
24
148
|
export declare abstract class SizedPDFElement extends PDFElement {
|
|
25
149
|
protected x: number;
|
|
@@ -32,14 +156,32 @@ export declare abstract class SizedPDFElement extends PDFElement {
|
|
|
32
156
|
export declare abstract class FlexiblePDFElement extends PDFElement {
|
|
33
157
|
protected flex: number;
|
|
34
158
|
protected verticalChildAlignment: VerticalAlignment;
|
|
159
|
+
/** Points reserved before any leftover is shared out (CSS `flex-basis`); default 0. */
|
|
160
|
+
protected basis: number;
|
|
161
|
+
/** The same as a fraction of the line, for `flexBasis: "25%"`. */
|
|
162
|
+
protected basisFactor?: number;
|
|
35
163
|
constructor(data: FlexibleElement);
|
|
36
164
|
getFlex(): number;
|
|
165
|
+
/**
|
|
166
|
+
* The main extent this child starts from, before the leftover is shared out. `lineMain` is what the
|
|
167
|
+
* line offers its items (its extent minus the gaps), so a percentage basis resolves against the same
|
|
168
|
+
* base a percentage WIDTH already does - and falls back to 0 on an unbounded axis, where a fraction
|
|
169
|
+
* has no meaning.
|
|
170
|
+
*/
|
|
171
|
+
/** Whether a PERCENTAGE basis was given - it resolves to 0 on an unbounded axis, so asking for the
|
|
172
|
+
* number alone cannot tell "no basis" from "a basis that does not apply here". */
|
|
173
|
+
hasBasisFactor(): boolean;
|
|
174
|
+
getBasis(lineMain: number): number;
|
|
37
175
|
}
|
|
38
176
|
export declare enum HorizontalAlignment {
|
|
177
|
+
/** CSS `text-align: start` - the side the writing STARTS on: left in `ltr`, right in `rtl`. The
|
|
178
|
+
* default, so a right-to-left paragraph begins on the right without anyone asking for it. */
|
|
179
|
+
start = "START",
|
|
39
180
|
left = "LEFT",
|
|
40
181
|
right = "RIGHT",
|
|
41
182
|
center = "CENTER",
|
|
42
|
-
|
|
183
|
+
/** CSS `text-align: justify` - both edges line up, the last line of a paragraph excepted. */
|
|
184
|
+
justify = "JUSTIFY"
|
|
43
185
|
}
|
|
44
186
|
export declare enum VerticalAlignment {
|
|
45
187
|
top = "TOP",
|
|
@@ -54,6 +196,10 @@ export interface WithChild {
|
|
|
54
196
|
}
|
|
55
197
|
export interface FlexibleElement {
|
|
56
198
|
flex: number;
|
|
199
|
+
/** Points reserved before the leftover is shared out (CSS `flex-basis`). */
|
|
200
|
+
basis?: number;
|
|
201
|
+
/** The same as a fraction of the line, for `flexBasis: "25%"`. */
|
|
202
|
+
basisFactor?: number;
|
|
57
203
|
verticalChildAlignment?: VerticalAlignment;
|
|
58
204
|
}
|
|
59
205
|
export interface SizedElement {
|
|
@@ -1,13 +1,110 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
let _nextStructId = 0;
|
|
2
|
+
export class PDFElement {
|
|
3
|
+
constructor() {
|
|
4
|
+
// Stable identity for accessible (PDF/UA) tagging: assigned once at construction and carried through
|
|
5
|
+
// fragmentation copies (adoptStructId), so a paragraph or table split across pages stays ONE structure
|
|
6
|
+
// element. Only the elements that actually tag (Text, Image, StructGroup) read it.
|
|
7
|
+
this._structId = _nextStructId++;
|
|
8
|
+
/**
|
|
9
|
+
* Where this child sits among its siblings (CSS `order`), lowest first, source order deciding ties.
|
|
10
|
+
* It moves the child in the LAYOUT only - the element tree, and therefore the reading order a tagged
|
|
11
|
+
* PDF exposes, is untouched. Default 0.
|
|
12
|
+
*/
|
|
13
|
+
this.order = 0;
|
|
14
|
+
/**
|
|
15
|
+
* How willingly this child gives up main-axis space when the line overflows (CSS `flex-shrink`),
|
|
16
|
+
* weighted by its own size as CSS does. **Default 0, deliberately unlike CSS's 1**: shrinking is a
|
|
17
|
+
* change of what a document LOOKS like, and every document written before this existed must keep
|
|
18
|
+
* laying out exactly as it did. Opt in per child.
|
|
19
|
+
*/
|
|
20
|
+
this.flexShrink = 0;
|
|
21
|
+
}
|
|
22
|
+
get structId() {
|
|
23
|
+
return this._structId;
|
|
24
|
+
}
|
|
25
|
+
/** Make this element share `from`'s tagging identity - used by fragmentation clones. Returns this. */
|
|
26
|
+
adoptStructId(from) {
|
|
27
|
+
this._structId = from._structId;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The relative-size fraction (0..1) this element asked for on the given axis, if any (`horizontal` =
|
|
32
|
+
* width). A flex parent reads it to resolve a percentage child against its OWN main size - e.g. a
|
|
33
|
+
* `Box({ width: "50%" })` inside a Row, where the child otherwise gets an unbounded main axis and the
|
|
34
|
+
* fraction would have nothing to resolve against. Default: the element is not relatively sized.
|
|
35
|
+
*/
|
|
36
|
+
relativeSizeFactor(_horizontal) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Whether this element needs a BOUNDED extent on the given axis to lay itself out (`true` for a
|
|
41
|
+
* horizontal axis = width). A flex parent measures its fixed children with an unbounded main axis, so
|
|
42
|
+
* they keep their natural size; but a stack holding an `Expanded`/`Spacer` has no leftover space to
|
|
43
|
+
* distribute unless it is told how much main axis it may occupy. Such a stack answers `true` here and
|
|
44
|
+
* the parent hands it the line's bounded main extent instead of `Infinity`. Default: no.
|
|
45
|
+
*/
|
|
46
|
+
needsBoundedMain(_horizontal) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Whether this element IS a forced page break (a `PageBreak`). The pagination packer cuts the flow
|
|
51
|
+
* at such a marker: everything before it stays, everything after starts a new page. Default: no.
|
|
52
|
+
*/
|
|
53
|
+
isPageBreak() {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Whether this element is, or CONTAINS anywhere in its subtree, a forced page break. A container
|
|
58
|
+
* that merely fits by height must still be fragmented when this is true, so a break nested inside
|
|
59
|
+
* it is honoured rather than swallowed. Containers override this to recurse into their children.
|
|
60
|
+
* Default: no.
|
|
61
|
+
*/
|
|
62
|
+
hasForcedBreak() {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Whether this element asks to START on a fresh page (CSS `break-before: page`, react-pdf's `break`
|
|
67
|
+
* prop). Read by the parent packer at the child boundary, not by the element itself; ignored when the
|
|
68
|
+
* element is already at the top of a region (nothing before it), so it never makes an empty page.
|
|
69
|
+
* Default: no.
|
|
70
|
+
*/
|
|
71
|
+
breaksBefore() {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Whether everything AFTER this element must start a fresh page (CSS `break-after: page`). Read by the
|
|
76
|
+
* parent packer once this element has been placed whole. Default: no.
|
|
77
|
+
*/
|
|
78
|
+
breaksAfter() {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
/** Sets `alignSelf` and returns the element, so a factory can thread it through in one expression. */
|
|
82
|
+
withAlignSelf(align) {
|
|
83
|
+
if (align !== undefined)
|
|
84
|
+
this.alignSelf = align;
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
/** Sets `flexShrink` and returns the element. */
|
|
88
|
+
withFlexShrink(shrink) {
|
|
89
|
+
if (shrink !== undefined) {
|
|
90
|
+
if (!Number.isFinite(shrink) || shrink < 0) {
|
|
91
|
+
throw new Error(`Invalid flexShrink ${shrink}: it must be a number of at least 0.`);
|
|
92
|
+
}
|
|
93
|
+
this.flexShrink = shrink;
|
|
94
|
+
}
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
/** Sets `order` and returns the element, so a factory can thread it through in one expression. */
|
|
98
|
+
withOrder(order) {
|
|
99
|
+
if (order !== undefined) {
|
|
100
|
+
if (!Number.isFinite(order))
|
|
101
|
+
throw new Error(`Invalid order ${order}: it must be a number.`);
|
|
102
|
+
this.order = order;
|
|
103
|
+
}
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
8
106
|
}
|
|
9
|
-
|
|
10
|
-
class SizedPDFElement extends PDFElement {
|
|
107
|
+
export class SizedPDFElement extends PDFElement {
|
|
11
108
|
constructor(data) {
|
|
12
109
|
super();
|
|
13
110
|
this.x = data.x;
|
|
@@ -19,37 +116,58 @@ class SizedPDFElement extends PDFElement {
|
|
|
19
116
|
return { x: this.x, y: this.y, width: this.width, height: this.height };
|
|
20
117
|
}
|
|
21
118
|
}
|
|
22
|
-
|
|
23
|
-
class FlexiblePDFElement extends PDFElement {
|
|
119
|
+
export class FlexiblePDFElement extends PDFElement {
|
|
24
120
|
constructor(data) {
|
|
25
121
|
super();
|
|
26
122
|
this.flex = data.flex;
|
|
27
123
|
this.verticalChildAlignment = data.verticalChildAlignment || VerticalAlignment.middle;
|
|
124
|
+
this.basis = data.basis ?? 0;
|
|
125
|
+
this.basisFactor = data.basisFactor;
|
|
28
126
|
}
|
|
29
127
|
getFlex() {
|
|
30
128
|
return this.flex;
|
|
31
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* The main extent this child starts from, before the leftover is shared out. `lineMain` is what the
|
|
132
|
+
* line offers its items (its extent minus the gaps), so a percentage basis resolves against the same
|
|
133
|
+
* base a percentage WIDTH already does - and falls back to 0 on an unbounded axis, where a fraction
|
|
134
|
+
* has no meaning.
|
|
135
|
+
*/
|
|
136
|
+
/** Whether a PERCENTAGE basis was given - it resolves to 0 on an unbounded axis, so asking for the
|
|
137
|
+
* number alone cannot tell "no basis" from "a basis that does not apply here". */
|
|
138
|
+
hasBasisFactor() {
|
|
139
|
+
return this.basisFactor !== undefined;
|
|
140
|
+
}
|
|
141
|
+
getBasis(lineMain) {
|
|
142
|
+
if (this.basisFactor !== undefined) {
|
|
143
|
+
return Number.isFinite(lineMain) ? lineMain * this.basisFactor : 0;
|
|
144
|
+
}
|
|
145
|
+
return this.basis;
|
|
146
|
+
}
|
|
32
147
|
}
|
|
33
|
-
|
|
34
|
-
var HorizontalAlignment;
|
|
148
|
+
export var HorizontalAlignment;
|
|
35
149
|
(function (HorizontalAlignment) {
|
|
150
|
+
/** CSS `text-align: start` - the side the writing STARTS on: left in `ltr`, right in `rtl`. The
|
|
151
|
+
* default, so a right-to-left paragraph begins on the right without anyone asking for it. */
|
|
152
|
+
HorizontalAlignment["start"] = "START";
|
|
36
153
|
HorizontalAlignment["left"] = "LEFT";
|
|
37
154
|
HorizontalAlignment["right"] = "RIGHT";
|
|
38
155
|
HorizontalAlignment["center"] = "CENTER";
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
156
|
+
/** CSS `text-align: justify` - both edges line up, the last line of a paragraph excepted. */
|
|
157
|
+
HorizontalAlignment["justify"] = "JUSTIFY";
|
|
158
|
+
})(HorizontalAlignment || (HorizontalAlignment = {}));
|
|
159
|
+
export var VerticalAlignment;
|
|
42
160
|
(function (VerticalAlignment) {
|
|
43
161
|
VerticalAlignment["top"] = "TOP";
|
|
44
162
|
VerticalAlignment["middle"] = "MIDDLE";
|
|
45
163
|
VerticalAlignment["bottom"] = "BOTTOM";
|
|
46
|
-
})(VerticalAlignment || (
|
|
47
|
-
function isSizedElement(obj) {
|
|
164
|
+
})(VerticalAlignment || (VerticalAlignment = {}));
|
|
165
|
+
export function isSizedElement(obj) {
|
|
48
166
|
return typeof obj === "object" && obj !== null && "x" in obj && "y" in obj;
|
|
49
167
|
}
|
|
50
|
-
function hasChildrenProp(obj) {
|
|
168
|
+
export function hasChildrenProp(obj) {
|
|
51
169
|
return "children" in obj;
|
|
52
170
|
}
|
|
53
|
-
function hasChildProp(obj) {
|
|
171
|
+
export function hasChildProp(obj) {
|
|
54
172
|
return "child" in obj;
|
|
55
173
|
}
|