@jasy/pdf 1.0.0-alpha.5 → 1.0.0-alpha.7
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/dist/api/content.d.ts +6 -3
- package/dist/api/content.js +12 -3
- package/dist/api/descriptor.js +24 -1
- package/dist/api/dimension.d.ts +20 -0
- package/dist/api/dimension.js +16 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/layout.d.ts +112 -17
- package/dist/api/layout.js +118 -13
- package/dist/api/page-builder.d.ts +32 -0
- package/dist/api/page-builder.js +32 -0
- package/dist/api/structure.d.ts +5 -0
- package/dist/api/structure.js +1 -0
- package/dist/api/text.d.ts +24 -2
- package/dist/api/text.js +46 -4
- package/dist/elements/container-element.d.ts +26 -1
- package/dist/elements/container-element.js +79 -29
- package/dist/elements/image-element.d.ts +19 -1
- package/dist/elements/image-element.js +52 -11
- package/dist/elements/index.d.ts +8 -0
- package/dist/elements/index.js +8 -0
- 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/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 +3 -0
- package/dist/elements/layout/padding-element.js +12 -0
- 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 +43 -0
- package/dist/elements/layout/positioned-element.d.ts +10 -7
- package/dist/elements/layout/positioned-element.js +21 -9
- 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/page-element.d.ts +19 -1
- package/dist/elements/page-element.js +54 -17
- package/dist/elements/pdf-element.d.ts +59 -0
- package/dist/elements/pdf-element.js +51 -0
- package/dist/elements/rectangle-element.d.ts +20 -1
- package/dist/elements/rectangle-element.js +75 -18
- package/dist/elements/row-element.d.ts +19 -1
- package/dist/elements/row-element.js +45 -8
- package/dist/elements/text-element.d.ts +34 -4
- package/dist/elements/text-element.js +40 -17
- package/dist/ir/display-list.d.ts +60 -1
- package/dist/layout/box-constraints.d.ts +8 -0
- package/dist/layout/box-constraints.js +14 -0
- package/dist/layout/collect-images.d.ts +9 -0
- package/dist/layout/collect-images.js +34 -0
- package/dist/layout/fragmentation.d.ts +12 -0
- package/dist/layout/fragmentation.js +45 -8
- 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/keep-together-renderer.d.ts +10 -0
- package/dist/renderer/keep-together-renderer.js +12 -0
- package/dist/renderer/link-renderer.d.ts +6 -0
- package/dist/renderer/link-renderer.js +11 -0
- 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.js +37 -2
- package/dist/renderer/pdf-backend.d.ts +17 -0
- package/dist/renderer/pdf-backend.js +117 -7
- package/dist/renderer/pdf-document-class.js +3 -0
- package/dist/renderer/pdf-document-renderer.d.ts +16 -7
- package/dist/renderer/pdf-document-renderer.js +87 -36
- package/dist/renderer/pdf-renderer.js +53 -2
- package/dist/renderer/rotated-renderer.d.ts +7 -0
- package/dist/renderer/rotated-renderer.js +29 -0
- package/dist/renderer/text-renderer.d.ts +1 -1
- package/dist/renderer/text-renderer.js +123 -54
- package/dist/text/advance.d.ts +34 -0
- package/dist/text/advance.js +42 -0
- package/dist/text/line-breaker.d.ts +9 -8
- package/dist/text/line-breaker.js +28 -21
- package/dist/text/line-metrics.d.ts +49 -0
- package/dist/text/line-metrics.js +57 -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 +13 -3
- package/dist/text/text-style.js +10 -3
- package/dist/utils/afm-parser.d.ts +34 -0
- package/dist/utils/afm-parser.js +73 -4
- package/dist/utils/dest-registry.d.ts +19 -0
- package/dist/utils/dest-registry.js +32 -0
- package/dist/utils/flex-layout.d.ts +10 -3
- package/dist/utils/flex-layout.js +26 -6
- package/dist/utils/font-metrics.d.ts +14 -0
- package/dist/utils/outline.d.ts +21 -0
- package/dist/utils/outline.js +80 -0
- package/dist/utils/pdf-object-manager.d.ts +33 -1
- package/dist/utils/pdf-object-manager.js +0 -0
- package/dist/utils/ttf-parser.d.ts +53 -0
- package/dist/utils/ttf-parser.js +368 -0
- package/package.json +1 -1
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
import { pageFormats } from "../constants/page-sizes.js";
|
|
1
|
+
import { pageFormats, PageSize } from "../constants/page-sizes.js";
|
|
2
2
|
import { Orientation } from "../renderer/pdf-config.js";
|
|
3
3
|
import { BoxConstraints } from "../layout/box-constraints.js";
|
|
4
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
|
+
}
|
|
5
16
|
/**
|
|
6
17
|
* The content box of a page (inside the margins, orientation applied) for a fully
|
|
7
18
|
* resolved config. Single source of truth, shared by `PageElement` layout and the page
|
|
@@ -25,6 +36,19 @@ export function resolvePageContentBox(config) {
|
|
|
25
36
|
* no header/footer the bands are zero and the body equals the full content box - identical
|
|
26
37
|
* to a page without them.
|
|
27
38
|
*/
|
|
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
|
+
}
|
|
28
52
|
export function layoutPageBands(config, header, footer, ctx) {
|
|
29
53
|
const { origin, width, height } = resolvePageContentBox(config);
|
|
30
54
|
let headerHeight = 0;
|
|
@@ -33,8 +57,13 @@ export function layoutPageBands(config, header, footer, ctx) {
|
|
|
33
57
|
}
|
|
34
58
|
let footerHeight = 0;
|
|
35
59
|
if (footer) {
|
|
36
|
-
// Measure first to learn its height, then place it flush against the bottom edge.
|
|
37
|
-
|
|
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;
|
|
38
67
|
footer.calculateLayout(BoxConstraints.loose(width, Infinity), { x: origin.x, y: origin.y + height - footerHeight }, ctx);
|
|
39
68
|
}
|
|
40
69
|
return {
|
|
@@ -63,25 +92,33 @@ export class PageElement extends PDFElement {
|
|
|
63
92
|
pageConfig: this.config,
|
|
64
93
|
textStyle: ctx.textStyle,
|
|
65
94
|
onOverflow: ctx.onOverflow,
|
|
95
|
+
pageInfo: ctx.pageInfo, // the render pass supplies it; absent during pagination
|
|
66
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 };
|
|
67
108
|
// Place the header/footer bands; the body gets the region left in between (the whole
|
|
68
109
|
// content box when there is neither - byte-identical to a plain page).
|
|
69
|
-
const bands = layoutPageBands(this.config, this.header, this.footer,
|
|
110
|
+
const bands = layoutPageBands(this.config, this.header, this.footer, frameCtx);
|
|
70
111
|
const childConstraints = BoxConstraints.loose(bands.bodyWidth, bands.bodyHeight);
|
|
71
|
-
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
};
|
|
79
|
-
const bodyCtx = { ...pageCtx, frame };
|
|
80
|
-
this.children.forEach((child) => child.calculateLayout(childConstraints, bands.bodyOrigin, bodyCtx));
|
|
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.
|
|
81
119
|
for (const place of frame.place)
|
|
82
|
-
place(frame,
|
|
83
|
-
|
|
84
|
-
return { width, height };
|
|
120
|
+
place(frame, frameCtx);
|
|
121
|
+
return { width: frame.size.width, height: frame.size.height };
|
|
85
122
|
}
|
|
86
123
|
getProps() {
|
|
87
124
|
return {
|
|
@@ -23,9 +23,25 @@ export interface PositioningFrame {
|
|
|
23
23
|
size: Size;
|
|
24
24
|
}, ctx: LayoutContext) => void>;
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* What a `PageBuilder` learns about the page it landed on. `pageNumber` is 1-based and counts PHYSICAL
|
|
28
|
+
* pages across the whole document (a logical `Page` that overflows contributes several); `pageCount` is
|
|
29
|
+
* the document's final physical page total. `pageSize` is the media box in points, orientation applied.
|
|
30
|
+
*/
|
|
31
|
+
export interface PageInfo {
|
|
32
|
+
pageNumber: number;
|
|
33
|
+
pageCount: number;
|
|
34
|
+
pageSize: {
|
|
35
|
+
width: number;
|
|
36
|
+
height: number;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
26
39
|
export interface LayoutContext {
|
|
27
40
|
metrics: FontMetrics;
|
|
28
41
|
pageConfig: PDFPageConfig;
|
|
42
|
+
/** The page a `PageBuilder` is being laid out on. Only the render pass knows the real numbers, so
|
|
43
|
+
* during pagination this is absent and a `PageBuilder` builds against a provisional "1 of 1". */
|
|
44
|
+
pageInfo?: PageInfo;
|
|
29
45
|
/** The nearest enclosing positioning frame, if any (set by a `relative` Box). */
|
|
30
46
|
frame?: PositioningFrame;
|
|
31
47
|
/** The cascaded text style descendants inherit (CSS/Flutter-style). Seeded at the document root
|
|
@@ -35,6 +51,10 @@ export interface LayoutContext {
|
|
|
35
51
|
/** What to do when an element overflows a page region and cannot break (set from the render option;
|
|
36
52
|
* absent = clip silently). Evaluated in `packChildren` where the forced placement happens. */
|
|
37
53
|
onOverflow?: OverflowPolicy;
|
|
54
|
+
/** The FULL body height of the current page (between header and footer), set by the page driver. A
|
|
55
|
+
* `keepTogether` group reads it to decide the degrade rule: veto splitting only when the group would
|
|
56
|
+
* fit on a fresh page; a group taller than a whole page drops the veto and splits. */
|
|
57
|
+
pageBodyHeight?: number;
|
|
38
58
|
}
|
|
39
59
|
export declare abstract class PDFElement {
|
|
40
60
|
private _structId;
|
|
@@ -49,6 +69,45 @@ export declare abstract class PDFElement {
|
|
|
49
69
|
* happens once at the IR -> backend seam.
|
|
50
70
|
*/
|
|
51
71
|
abstract calculateLayout(constraints: BoxConstraints, offset: Offset, ctx: LayoutContext): Size;
|
|
72
|
+
/**
|
|
73
|
+
* The relative-size fraction (0..1) this element asked for on the given axis, if any (`horizontal` =
|
|
74
|
+
* width). A flex parent reads it to resolve a percentage child against its OWN main size - e.g. a
|
|
75
|
+
* `Box({ width: "50%" })` inside a Row, where the child otherwise gets an unbounded main axis and the
|
|
76
|
+
* fraction would have nothing to resolve against. Default: the element is not relatively sized.
|
|
77
|
+
*/
|
|
78
|
+
relativeSizeFactor(_horizontal: boolean): number | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Whether this element needs a BOUNDED extent on the given axis to lay itself out (`true` for a
|
|
81
|
+
* horizontal axis = width). A flex parent measures its fixed children with an unbounded main axis, so
|
|
82
|
+
* they keep their natural size; but a stack holding an `Expanded`/`Spacer` has no leftover space to
|
|
83
|
+
* distribute unless it is told how much main axis it may occupy. Such a stack answers `true` here and
|
|
84
|
+
* the parent hands it the line's bounded main extent instead of `Infinity`. Default: no.
|
|
85
|
+
*/
|
|
86
|
+
needsBoundedMain(_horizontal: boolean): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Whether this element IS a forced page break (a `PageBreak`). The pagination packer cuts the flow
|
|
89
|
+
* at such a marker: everything before it stays, everything after starts a new page. Default: no.
|
|
90
|
+
*/
|
|
91
|
+
isPageBreak(): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Whether this element is, or CONTAINS anywhere in its subtree, a forced page break. A container
|
|
94
|
+
* that merely fits by height must still be fragmented when this is true, so a break nested inside
|
|
95
|
+
* it is honoured rather than swallowed. Containers override this to recurse into their children.
|
|
96
|
+
* Default: no.
|
|
97
|
+
*/
|
|
98
|
+
hasForcedBreak(): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Whether this element asks to START on a fresh page (CSS `break-before: page`, react-pdf's `break`
|
|
101
|
+
* prop). Read by the parent packer at the child boundary, not by the element itself; ignored when the
|
|
102
|
+
* element is already at the top of a region (nothing before it), so it never makes an empty page.
|
|
103
|
+
* Default: no.
|
|
104
|
+
*/
|
|
105
|
+
breaksBefore(): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Whether everything AFTER this element must start a fresh page (CSS `break-after: page`). Read by the
|
|
108
|
+
* parent packer once this element has been placed whole. Default: no.
|
|
109
|
+
*/
|
|
110
|
+
breaksAfter(): boolean;
|
|
52
111
|
}
|
|
53
112
|
export declare abstract class SizedPDFElement extends PDFElement {
|
|
54
113
|
protected x: number;
|
|
@@ -14,6 +14,57 @@ export class PDFElement {
|
|
|
14
14
|
this._structId = from._structId;
|
|
15
15
|
return this;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* The relative-size fraction (0..1) this element asked for on the given axis, if any (`horizontal` =
|
|
19
|
+
* width). A flex parent reads it to resolve a percentage child against its OWN main size - e.g. a
|
|
20
|
+
* `Box({ width: "50%" })` inside a Row, where the child otherwise gets an unbounded main axis and the
|
|
21
|
+
* fraction would have nothing to resolve against. Default: the element is not relatively sized.
|
|
22
|
+
*/
|
|
23
|
+
relativeSizeFactor(_horizontal) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether this element needs a BOUNDED extent on the given axis to lay itself out (`true` for a
|
|
28
|
+
* horizontal axis = width). A flex parent measures its fixed children with an unbounded main axis, so
|
|
29
|
+
* they keep their natural size; but a stack holding an `Expanded`/`Spacer` has no leftover space to
|
|
30
|
+
* distribute unless it is told how much main axis it may occupy. Such a stack answers `true` here and
|
|
31
|
+
* the parent hands it the line's bounded main extent instead of `Infinity`. Default: no.
|
|
32
|
+
*/
|
|
33
|
+
needsBoundedMain(_horizontal) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Whether this element IS a forced page break (a `PageBreak`). The pagination packer cuts the flow
|
|
38
|
+
* at such a marker: everything before it stays, everything after starts a new page. Default: no.
|
|
39
|
+
*/
|
|
40
|
+
isPageBreak() {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Whether this element is, or CONTAINS anywhere in its subtree, a forced page break. A container
|
|
45
|
+
* that merely fits by height must still be fragmented when this is true, so a break nested inside
|
|
46
|
+
* it is honoured rather than swallowed. Containers override this to recurse into their children.
|
|
47
|
+
* Default: no.
|
|
48
|
+
*/
|
|
49
|
+
hasForcedBreak() {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Whether this element asks to START on a fresh page (CSS `break-before: page`, react-pdf's `break`
|
|
54
|
+
* prop). Read by the parent packer at the child boundary, not by the element itself; ignored when the
|
|
55
|
+
* element is already at the top of a region (nothing before it), so it never makes an empty page.
|
|
56
|
+
* Default: no.
|
|
57
|
+
*/
|
|
58
|
+
breaksBefore() {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Whether everything AFTER this element must start a fresh page (CSS `break-after: page`). Read by the
|
|
63
|
+
* parent packer once this element has been placed whole. Default: no.
|
|
64
|
+
*/
|
|
65
|
+
breaksAfter() {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
17
68
|
}
|
|
18
69
|
export class SizedPDFElement extends PDFElement {
|
|
19
70
|
constructor(data) {
|
|
@@ -23,6 +23,15 @@ interface RectangleElementParams extends SizedElement, WithChildren {
|
|
|
23
23
|
/** `"hidden"` crops children to the box (CSS `overflow: hidden`); `"visible"` (default) lets a
|
|
24
24
|
* `Positioned` child spill over the edge. */
|
|
25
25
|
overflow?: "hidden" | "visible";
|
|
26
|
+
/** Width as a fraction (0..1) of the offered width, instead of a fixed `width` (CSS `50%`). Only
|
|
27
|
+
* resolves in a bounded region; an explicit `width` wins over it. */
|
|
28
|
+
widthFactor?: number;
|
|
29
|
+
/** Height as a fraction (0..1) of the offered height; see `widthFactor`. */
|
|
30
|
+
heightFactor?: number;
|
|
31
|
+
/** Start this box on a fresh page (CSS `break-before: page`). */
|
|
32
|
+
breakBefore?: boolean;
|
|
33
|
+
/** Start everything after this box on a fresh page (CSS `break-after: page`). */
|
|
34
|
+
breakAfter?: boolean;
|
|
26
35
|
}
|
|
27
36
|
export declare class RectangleElement extends SizedPDFElement implements Fragmentable {
|
|
28
37
|
private children;
|
|
@@ -33,8 +42,12 @@ export declare class RectangleElement extends SizedPDFElement implements Fragmen
|
|
|
33
42
|
private sideBorders?;
|
|
34
43
|
private relative;
|
|
35
44
|
private overflow;
|
|
45
|
+
private breakBefore;
|
|
46
|
+
private breakAfter;
|
|
36
47
|
private sizeMemory;
|
|
37
|
-
constructor({ children, color, backgroundColor, borderWidth, width, height, radius, sideBorders, relative, overflow, }: RectangleElementParams);
|
|
48
|
+
constructor({ children, color, backgroundColor, borderWidth, width, height, radius, sideBorders, relative, overflow, widthFactor, heightFactor, breakBefore, breakAfter, }: RectangleElementParams);
|
|
49
|
+
breaksBefore(): boolean;
|
|
50
|
+
breaksAfter(): boolean;
|
|
38
51
|
/**
|
|
39
52
|
* Splits the bordered box across pages (box-decoration-break: clone - every fragment
|
|
40
53
|
* gets its own full border). The children stack is packed into the space left after
|
|
@@ -44,7 +57,13 @@ export declare class RectangleElement extends SizedPDFElement implements Fragmen
|
|
|
44
57
|
* box is sized by what it actually holds on each page.
|
|
45
58
|
*/
|
|
46
59
|
fragment(maxHeight: number, width: number, ctx: LayoutContext): FragmentResult;
|
|
60
|
+
hasForcedBreak(): boolean;
|
|
47
61
|
private cloneWithChildren;
|
|
62
|
+
relativeSizeFactor(horizontal: boolean): number | undefined;
|
|
63
|
+
/** A box has no flex children of its own, but it must not swallow the need of the stack inside it: a
|
|
64
|
+
* `Spacer` in a box can only resolve if the box itself was given a bounded extent to pass down. With an
|
|
65
|
+
* explicit size on an axis the box already knows its extent there and asks for nothing. */
|
|
66
|
+
needsBoundedMain(horizontal: boolean): boolean;
|
|
48
67
|
calculateLayout(constraints: BoxConstraints, offset: Offset, ctx: LayoutContext): Size;
|
|
49
68
|
getProps(): {
|
|
50
69
|
x: number;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Color } from "../common/color.js";
|
|
2
|
-
import { BoxConstraints } from "../layout/box-constraints.js";
|
|
3
|
-
import { packChildren } from "../layout/fragmentation.js";
|
|
2
|
+
import { BoxConstraints, resolveExtent } from "../layout/box-constraints.js";
|
|
3
|
+
import { childrenForceBreak, packChildren, } from "../layout/fragmentation.js";
|
|
4
4
|
import { SizedPDFElement, } from "./pdf-element.js";
|
|
5
5
|
export class RectangleElement extends SizedPDFElement {
|
|
6
|
-
constructor({ children = [], color = new Color(0, 0, 0), backgroundColor, borderWidth, width, height, radius, sideBorders, relative, overflow, }) {
|
|
6
|
+
constructor({ children = [], color = new Color(0, 0, 0), backgroundColor, borderWidth, width, height, radius, sideBorders, relative, overflow, widthFactor, heightFactor, breakBefore, breakAfter, }) {
|
|
7
7
|
super({ x: 0, y: 0, width, height });
|
|
8
8
|
this.children = [];
|
|
9
9
|
this.children = children;
|
|
@@ -15,7 +15,15 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
15
15
|
this.sideBorders = sideBorders;
|
|
16
16
|
this.relative = relative ?? false;
|
|
17
17
|
this.overflow = overflow ?? "visible";
|
|
18
|
-
this.
|
|
18
|
+
this.breakBefore = breakBefore ?? false;
|
|
19
|
+
this.breakAfter = breakAfter ?? false;
|
|
20
|
+
this.sizeMemory = { x: 0, y: 0, width, height, widthFactor, heightFactor };
|
|
21
|
+
}
|
|
22
|
+
breaksBefore() {
|
|
23
|
+
return this.breakBefore;
|
|
24
|
+
}
|
|
25
|
+
breaksAfter() {
|
|
26
|
+
return this.breakAfter;
|
|
19
27
|
}
|
|
20
28
|
/**
|
|
21
29
|
* Splits the bordered box across pages (box-decoration-break: clone - every fragment
|
|
@@ -26,27 +34,45 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
26
34
|
* box is sized by what it actually holds on each page.
|
|
27
35
|
*/
|
|
28
36
|
fragment(maxHeight, width, ctx) {
|
|
29
|
-
|
|
37
|
+
// A percentage width resolves against the region width the page driver hands us, so a
|
|
38
|
+
// paginating %-box keeps its fraction on every page.
|
|
39
|
+
const boxWidth = this.sizeMemory.width ??
|
|
40
|
+
(this.sizeMemory.widthFactor !== undefined ? width * this.sizeMemory.widthFactor : width);
|
|
30
41
|
const innerWidth = Math.max(0, boxWidth - 2 * this.borderWidth);
|
|
31
42
|
// Border-box: the content is inset by the border on top and bottom, so a fragment
|
|
32
43
|
// holding `c` of content is `c + 2*border` tall. (Derived, not a fudge factor.)
|
|
33
44
|
const innerMaxHeight = maxHeight - 2 * this.borderWidth;
|
|
34
|
-
const { fitted, remainder } = packChildren(this.children, innerMaxHeight, innerWidth, ctx);
|
|
35
|
-
|
|
45
|
+
const { fitted, remainder, forceBreak } = packChildren(this.children, innerMaxHeight, innerWidth, ctx);
|
|
46
|
+
// Fits with no forced cut: return the whole box unchanged. A trailing forced break is the
|
|
47
|
+
// exception - fall through so the box is rebuilt from the packed children (without the consumed
|
|
48
|
+
// break marker), rather than handing back the original that still holds it.
|
|
49
|
+
if (remainder.length === 0 && !forceBreak)
|
|
36
50
|
return { fitted: this, remainder: null };
|
|
37
51
|
const contentHeight = (kids) => kids.reduce((sum, child) => sum +
|
|
38
52
|
child.calculateLayout(BoxConstraints.loose(innerWidth, Infinity), { x: 0, y: 0 }, ctx)
|
|
39
53
|
.height, 0);
|
|
40
54
|
return {
|
|
41
55
|
fitted: this.cloneWithChildren(fitted, contentHeight(fitted) + 2 * this.borderWidth),
|
|
42
|
-
|
|
56
|
+
// A trailing forced break leaves nothing to carry over: no remainder box, no extra page.
|
|
57
|
+
// Only the CONTINUATION carries `breakAfter` (a box that splits still breaks after its LAST
|
|
58
|
+
// fragment, not its first); `breakBefore` is dropped, already honoured before the split.
|
|
59
|
+
remainder: remainder.length === 0
|
|
60
|
+
? null
|
|
61
|
+
: this.cloneWithChildren(remainder, contentHeight(remainder) + 2 * this.borderWidth, this.breakAfter),
|
|
62
|
+
forceBreak,
|
|
43
63
|
};
|
|
44
64
|
}
|
|
45
|
-
|
|
65
|
+
hasForcedBreak() {
|
|
66
|
+
return childrenForceBreak(this.children);
|
|
67
|
+
}
|
|
68
|
+
cloneWithChildren(children, height, breakAfter = false) {
|
|
46
69
|
return new RectangleElement({
|
|
47
70
|
x: 0,
|
|
48
71
|
y: 0,
|
|
49
72
|
width: this.sizeMemory.width,
|
|
73
|
+
widthFactor: this.sizeMemory.widthFactor,
|
|
74
|
+
// A split box is sized by its per-page content (height passed in), so the height factor
|
|
75
|
+
// is intentionally dropped here - box-decoration-break, same as an explicit height.
|
|
50
76
|
height,
|
|
51
77
|
children,
|
|
52
78
|
color: this.color,
|
|
@@ -56,27 +82,46 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
56
82
|
sideBorders: this.sideBorders,
|
|
57
83
|
relative: this.relative,
|
|
58
84
|
overflow: this.overflow,
|
|
85
|
+
breakAfter,
|
|
59
86
|
});
|
|
60
87
|
}
|
|
88
|
+
relativeSizeFactor(horizontal) {
|
|
89
|
+
return horizontal ? this.sizeMemory.widthFactor : this.sizeMemory.heightFactor;
|
|
90
|
+
}
|
|
91
|
+
/** A box has no flex children of its own, but it must not swallow the need of the stack inside it: a
|
|
92
|
+
* `Spacer` in a box can only resolve if the box itself was given a bounded extent to pass down. With an
|
|
93
|
+
* explicit size on an axis the box already knows its extent there and asks for nothing. */
|
|
94
|
+
needsBoundedMain(horizontal) {
|
|
95
|
+
const requested = horizontal
|
|
96
|
+
? [this.sizeMemory.width, this.sizeMemory.widthFactor]
|
|
97
|
+
: [this.sizeMemory.height, this.sizeMemory.heightFactor];
|
|
98
|
+
if (requested.some((v) => v !== undefined))
|
|
99
|
+
return false;
|
|
100
|
+
return this.children.some((c) => c.needsBoundedMain(horizontal));
|
|
101
|
+
}
|
|
61
102
|
calculateLayout(constraints, offset, ctx) {
|
|
103
|
+
// An explicit extent is a fixed point size or a fraction of the offered box (relative sizing);
|
|
104
|
+
// the fraction only resolves in a bounded region. `undefined` = fill / shrink-wrap below.
|
|
105
|
+
const explicitWidth = resolveExtent(this.sizeMemory.width, this.sizeMemory.widthFactor, constraints.maxWidth, constraints.hasBoundedWidth);
|
|
106
|
+
const explicitHeight = resolveExtent(this.sizeMemory.height, this.sizeMemory.heightFactor, constraints.maxHeight, constraints.hasBoundedHeight);
|
|
62
107
|
// Width: an explicit size wins (clamped), else fill the offered box. (Without this a
|
|
63
108
|
// fixed box would balloon to the parent's size.)
|
|
64
109
|
this.width =
|
|
65
|
-
|
|
66
|
-
? constraints.constrainWidth(
|
|
110
|
+
explicitWidth !== undefined
|
|
111
|
+
? constraints.constrainWidth(explicitWidth)
|
|
67
112
|
: constraints.hasBoundedWidth
|
|
68
113
|
? constraints.maxWidth
|
|
69
114
|
: this.width;
|
|
70
115
|
// Width shrink-wrap: no explicit width AND an unbounded region (e.g. a `Box` badge inside a
|
|
71
116
|
// `Positioned`). Resolved after the children are measured, just below.
|
|
72
|
-
const shrinkWrapWidth =
|
|
117
|
+
const shrinkWrapWidth = explicitWidth === undefined && !constraints.hasBoundedWidth;
|
|
73
118
|
// Height: explicit wins; otherwise FILL a bounded region (e.g. inside an Expanded) but
|
|
74
119
|
// SHRINK-WRAP the content in an unbounded one (a note box in a stack). Shrink-wrap is
|
|
75
120
|
// resolved after the children are measured, just below.
|
|
76
|
-
const shrinkWrapHeight =
|
|
121
|
+
const shrinkWrapHeight = explicitHeight === undefined && !constraints.hasBoundedHeight;
|
|
77
122
|
this.height =
|
|
78
|
-
|
|
79
|
-
? constraints.constrainHeight(
|
|
123
|
+
explicitHeight !== undefined
|
|
124
|
+
? constraints.constrainHeight(explicitHeight)
|
|
80
125
|
: constraints.hasBoundedHeight
|
|
81
126
|
? constraints.maxHeight
|
|
82
127
|
: this.height;
|
|
@@ -89,16 +134,28 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
89
134
|
? { origin: { x: 0, y: 0 }, size: { width: 0, height: 0 }, place: [] }
|
|
90
135
|
: undefined;
|
|
91
136
|
const childCtx = frame ? { ...ctx, frame } : ctx;
|
|
92
|
-
// Lay out children stacked inside the border (inset by the border width). Width is
|
|
93
|
-
//
|
|
137
|
+
// Lay out children stacked inside the border (inset by the border width). Width is finalized here;
|
|
138
|
+
// height is left unbounded so each child sizes to its own content - EXCEPT for a child that cannot
|
|
139
|
+
// lay itself out without a bound (a stack holding an `Expanded`/`Spacer`). That one gets the height
|
|
140
|
+
// still free inside the box, so its flex child has real leftover space instead of an infinite one.
|
|
94
141
|
const innerWidth = shrinkWrapWidth
|
|
95
142
|
? Infinity
|
|
96
143
|
: Math.max(0, (this.width ?? 0) - 2 * this.borderWidth);
|
|
144
|
+
const innerHeight = shrinkWrapHeight
|
|
145
|
+
? Infinity
|
|
146
|
+
: Math.max(0, (this.height ?? 0) - 2 * this.borderWidth);
|
|
97
147
|
let contentWidth = 0;
|
|
98
148
|
let contentHeight = 0;
|
|
99
149
|
let yCursor = this.y + this.borderWidth;
|
|
100
150
|
for (const child of this.children) {
|
|
101
|
-
const
|
|
151
|
+
const consumed = yCursor - (this.y + this.borderWidth);
|
|
152
|
+
// Same rule the flex helper applies: a child gets a finite main extent when it cannot lay itself
|
|
153
|
+
// out without one - a stack holding an `Expanded`/`Spacer`, or a child sized as a percentage of us.
|
|
154
|
+
const needsBound = child.needsBoundedMain(false) || child.relativeSizeFactor(false) !== undefined;
|
|
155
|
+
const childHeight = needsBound
|
|
156
|
+
? Math.max(0, innerHeight - consumed) // Infinity - consumed stays Infinity, as it should
|
|
157
|
+
: Infinity;
|
|
158
|
+
const childSize = child.calculateLayout(BoxConstraints.loose(innerWidth, childHeight), { x: this.x + this.borderWidth, y: yCursor }, childCtx);
|
|
102
159
|
yCursor += childSize.height;
|
|
103
160
|
contentHeight += childSize.height;
|
|
104
161
|
contentWidth = Math.max(contentWidth, childSize.width);
|
|
@@ -8,6 +8,15 @@ interface RowElementParams extends WithChildren {
|
|
|
8
8
|
main?: MainAlign;
|
|
9
9
|
/** Vertical alignment of each child (cross axis); defaults to `stretch`. */
|
|
10
10
|
cross?: CrossAlign;
|
|
11
|
+
/** Width/height as points (fixed) or a fraction (0..1) of the offered box (relative sizing). */
|
|
12
|
+
width?: number;
|
|
13
|
+
height?: number;
|
|
14
|
+
widthFactor?: number;
|
|
15
|
+
heightFactor?: number;
|
|
16
|
+
/** Start this row on a fresh page (CSS `break-before: page`). */
|
|
17
|
+
breakBefore?: boolean;
|
|
18
|
+
/** Start everything after this row on a fresh page (CSS `break-after: page`). */
|
|
19
|
+
breakAfter?: boolean;
|
|
11
20
|
}
|
|
12
21
|
/**
|
|
13
22
|
* Horizontal stack: the mirror of `ContainerElement` (Column). Children are laid out
|
|
@@ -26,7 +35,16 @@ export declare class RowElement extends SizedPDFElement {
|
|
|
26
35
|
private gap;
|
|
27
36
|
private main;
|
|
28
37
|
private cross;
|
|
29
|
-
|
|
38
|
+
private breakBefore;
|
|
39
|
+
private breakAfter;
|
|
40
|
+
private requested;
|
|
41
|
+
constructor({ children, gap, main, cross, width, height, widthFactor, heightFactor, breakBefore, breakAfter, }: RowElementParams);
|
|
42
|
+
breaksBefore(): boolean;
|
|
43
|
+
breaksAfter(): boolean;
|
|
44
|
+
relativeSizeFactor(horizontal: boolean): number | undefined;
|
|
45
|
+
/** The mirror of `ContainerElement`: a Row's OWN flex child needs a bounded width, and the need of any
|
|
46
|
+
* descendant propagates on both axes (see the Column for the reasoning). */
|
|
47
|
+
needsBoundedMain(horizontal: boolean): boolean;
|
|
30
48
|
calculateLayout(constraints: BoxConstraints, offset: Offset, ctx: LayoutContext): Size;
|
|
31
49
|
getProps(): {
|
|
32
50
|
x: number;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { resolveExtent } from "../layout/box-constraints.js";
|
|
1
2
|
import { FlexLayoutHelper, HORIZONTAL_AXIS } from "../utils/flex-layout.js";
|
|
2
|
-
import { SizedPDFElement } from "./pdf-element.js";
|
|
3
|
+
import { FlexiblePDFElement, SizedPDFElement, } from "./pdf-element.js";
|
|
3
4
|
/**
|
|
4
5
|
* Horizontal stack: the mirror of `ContainerElement` (Column). Children are laid out
|
|
5
6
|
* left-to-right via the shared `FlexLayoutHelper` on the horizontal axis; fixed children
|
|
@@ -13,26 +14,62 @@ import { SizedPDFElement } from "./pdf-element.js";
|
|
|
13
14
|
* Grid/Table concern.
|
|
14
15
|
*/
|
|
15
16
|
export class RowElement extends SizedPDFElement {
|
|
16
|
-
constructor({ children, gap, main, cross }) {
|
|
17
|
+
constructor({ children, gap, main, cross, width, height, widthFactor, heightFactor, breakBefore, breakAfter, }) {
|
|
17
18
|
super({ x: 0, y: 0 });
|
|
18
19
|
this.children = children;
|
|
19
20
|
this.gap = gap ?? 0;
|
|
20
21
|
this.main = main ?? "start";
|
|
21
22
|
this.cross = cross ?? "stretch";
|
|
23
|
+
this.requested = { width, height, widthFactor, heightFactor };
|
|
24
|
+
this.breakBefore = breakBefore ?? false;
|
|
25
|
+
this.breakAfter = breakAfter ?? false;
|
|
26
|
+
}
|
|
27
|
+
breaksBefore() {
|
|
28
|
+
return this.breakBefore;
|
|
29
|
+
}
|
|
30
|
+
breaksAfter() {
|
|
31
|
+
return this.breakAfter;
|
|
32
|
+
}
|
|
33
|
+
relativeSizeFactor(horizontal) {
|
|
34
|
+
return horizontal ? this.requested.widthFactor : this.requested.heightFactor;
|
|
35
|
+
}
|
|
36
|
+
/** The mirror of `ContainerElement`: a Row's OWN flex child needs a bounded width, and the need of any
|
|
37
|
+
* descendant propagates on both axes (see the Column for the reasoning). */
|
|
38
|
+
needsBoundedMain(horizontal) {
|
|
39
|
+
const requested = horizontal
|
|
40
|
+
? [this.requested.width, this.requested.widthFactor]
|
|
41
|
+
: [this.requested.height, this.requested.heightFactor];
|
|
42
|
+
if (requested.some((v) => v !== undefined))
|
|
43
|
+
return false;
|
|
44
|
+
const ownFlexChild = horizontal && this.children.some((c) => c instanceof FlexiblePDFElement);
|
|
45
|
+
return ownFlexChild || this.children.some((c) => c.needsBoundedMain(horizontal));
|
|
22
46
|
}
|
|
23
47
|
calculateLayout(constraints, offset, ctx) {
|
|
24
48
|
this.x = offset.x;
|
|
25
49
|
this.y = offset.y;
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
const
|
|
29
|
-
const
|
|
50
|
+
// Relative sizing: a pinned extent (fixed or a fraction of the offered box, clamped) wins; else
|
|
51
|
+
// width fills the offered space (flex children split the leftover) and height is the tallest child.
|
|
52
|
+
const explicitWidth = resolveExtent(this.requested.width, this.requested.widthFactor, constraints.maxWidth, constraints.hasBoundedWidth);
|
|
53
|
+
const explicitHeight = resolveExtent(this.requested.height, this.requested.heightFactor, constraints.maxHeight, constraints.hasBoundedHeight);
|
|
54
|
+
const boundedWidth = explicitWidth !== undefined
|
|
55
|
+
? constraints.constrainWidth(explicitWidth)
|
|
56
|
+
: constraints.hasBoundedWidth
|
|
57
|
+
? constraints.maxWidth
|
|
58
|
+
: undefined;
|
|
59
|
+
const boundedHeight = explicitHeight !== undefined
|
|
60
|
+
? constraints.constrainHeight(explicitHeight)
|
|
61
|
+
: constraints.hasBoundedHeight
|
|
62
|
+
? constraints.maxHeight
|
|
63
|
+
: undefined;
|
|
64
|
+
// Horizontal stack: main = width (children fill it), cross = height (children can stretch to it).
|
|
65
|
+
const mainAvail = boundedWidth ?? Infinity;
|
|
66
|
+
const crossAvail = boundedHeight ?? Infinity;
|
|
30
67
|
let result = { mainUsed: 0, crossUsed: 0 };
|
|
31
68
|
if (this.children.length > 0) {
|
|
32
69
|
result = FlexLayoutHelper.layout(this.children, HORIZONTAL_AXIS, mainAvail, crossAvail, this.x, this.y, { gap: this.gap, main: this.main, cross: this.cross }, ctx);
|
|
33
70
|
}
|
|
34
|
-
this.width =
|
|
35
|
-
this.height =
|
|
71
|
+
this.width = boundedWidth ?? result.mainUsed;
|
|
72
|
+
this.height = boundedHeight ?? result.crossUsed;
|
|
36
73
|
return { width: this.width, height: this.height };
|
|
37
74
|
}
|
|
38
75
|
getProps() {
|
|
@@ -10,6 +10,15 @@ export interface TextSegment {
|
|
|
10
10
|
fontColor?: Color;
|
|
11
11
|
fontFamily?: string;
|
|
12
12
|
fontSize?: number;
|
|
13
|
+
/** External URL: this segment becomes an inline hyperlink (a /Link annotation over its glyphs). */
|
|
14
|
+
href?: string;
|
|
15
|
+
/** Internal named destination (an `Anchor`): this segment links to it (a /GoTo /Link annotation). */
|
|
16
|
+
dest?: string;
|
|
17
|
+
/** Unset inherits the Text's own setting; `true`/`false` overrides it for this run only. */
|
|
18
|
+
underline?: boolean;
|
|
19
|
+
strikethrough?: boolean;
|
|
20
|
+
/** Extra space after every glyph, in points; unset inherits the Text's own value. */
|
|
21
|
+
letterSpacing?: number;
|
|
13
22
|
}
|
|
14
23
|
/** Accessibility role for the tagged structure tree: a heading level or a paragraph (the default). */
|
|
15
24
|
export type TextRole = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p";
|
|
@@ -26,8 +35,17 @@ interface TextElementParams {
|
|
|
26
35
|
maxLines?: number;
|
|
27
36
|
/** What to do past `maxLines`: `"clip"` (default) drops them, `"ellipsis"` ends with "…". */
|
|
28
37
|
overflow?: TextOverflow;
|
|
29
|
-
/** Line-height multiplier: each line is `fontSize * lineHeight` tall
|
|
38
|
+
/** Line-height multiplier: each line is `fontSize * lineHeight` tall. Unset means the font's
|
|
39
|
+
* natural line height (`ascent + descent + lineGap`), like CSS `line-height: normal`. */
|
|
30
40
|
lineHeight?: number;
|
|
41
|
+
/** Draw a line under the text, at the position and thickness the font declares. */
|
|
42
|
+
underline?: boolean;
|
|
43
|
+
/** Draw a line through the text, at half its x-height. */
|
|
44
|
+
strikethrough?: boolean;
|
|
45
|
+
/** Let the underline step around descenders. Needs an embedded font. */
|
|
46
|
+
skipInk?: boolean;
|
|
47
|
+
/** Extra space after every glyph, in points (CSS `letter-spacing`). Default 0. */
|
|
48
|
+
letterSpacing?: number;
|
|
31
49
|
/** Accessibility role for the tagged structure tree (heading level or paragraph; default `"p"`). */
|
|
32
50
|
role?: TextRole;
|
|
33
51
|
}
|
|
@@ -38,17 +56,25 @@ export declare class TextElement extends SizedPDFElement implements Fragmentable
|
|
|
38
56
|
private readonly rawColor?;
|
|
39
57
|
private readonly rawTextAlignment?;
|
|
40
58
|
private readonly rawLineHeight?;
|
|
59
|
+
private readonly rawUnderline?;
|
|
60
|
+
private readonly rawStrikethrough?;
|
|
61
|
+
private readonly rawSkipInk?;
|
|
62
|
+
private readonly rawLetterSpacing?;
|
|
41
63
|
private fontSize;
|
|
42
64
|
private fontFamily;
|
|
43
65
|
private fontStyle;
|
|
44
66
|
private color;
|
|
45
67
|
private textAlignment;
|
|
46
|
-
private lineHeight
|
|
68
|
+
private lineHeight?;
|
|
69
|
+
private underline;
|
|
70
|
+
private strikethrough;
|
|
71
|
+
private skipInk;
|
|
72
|
+
private letterSpacing;
|
|
47
73
|
private content;
|
|
48
74
|
private maxLines?;
|
|
49
75
|
private overflow;
|
|
50
76
|
private readonly role?;
|
|
51
|
-
constructor({ fontSize, content, fontFamily, fontStyle, color, textAlignment, maxLines, overflow, lineHeight, role, }: TextElementParams);
|
|
77
|
+
constructor({ fontSize, content, fontFamily, fontStyle, color, textAlignment, maxLines, overflow, lineHeight, underline, strikethrough, skipInk, letterSpacing, role, }: TextElementParams);
|
|
52
78
|
private resolveStyle;
|
|
53
79
|
private applyStyle;
|
|
54
80
|
/**
|
|
@@ -84,7 +110,11 @@ export declare class TextElement extends SizedPDFElement implements Fragmentable
|
|
|
84
110
|
textAlignment: HorizontalAlignment;
|
|
85
111
|
maxLines: number | undefined;
|
|
86
112
|
overflow: TextOverflow;
|
|
87
|
-
lineHeight: number;
|
|
113
|
+
lineHeight: number | undefined;
|
|
114
|
+
underline: boolean;
|
|
115
|
+
strikethrough: boolean;
|
|
116
|
+
skipInk: boolean;
|
|
117
|
+
letterSpacing: number;
|
|
88
118
|
role: TextRole | undefined;
|
|
89
119
|
};
|
|
90
120
|
}
|