@jasy/pdf 1.0.0-beta.3 → 1.0.0-beta.5
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/color.d.ts +1 -24
- package/dist/api/color.js +2 -278
- package/dist/api/content.d.ts +10 -5
- package/dist/api/content.js +29 -13
- package/dist/api/descriptor.js +30 -3
- package/dist/api/flow.d.ts +55 -0
- package/dist/api/flow.js +71 -0
- package/dist/api/font-url.d.ts +1 -2
- package/dist/api/font-url.js +8 -74
- package/dist/api/forms.d.ts +3 -0
- package/dist/api/forms.js +3 -0
- package/dist/api/gradient.d.ts +1 -53
- package/dist/api/gradient.js +2 -97
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.js +3 -0
- package/dist/api/layout.d.ts +6 -0
- package/dist/api/layout.js +9 -3
- package/dist/api/page-builder.d.ts +4 -0
- package/dist/api/page-builder.js +4 -0
- package/dist/api/structure.d.ts +10 -2
- package/dist/api/structure.js +9 -6
- package/dist/api/table.d.ts +5 -3
- package/dist/api/table.js +101 -22
- package/dist/api/text.d.ts +8 -8
- package/dist/api/text.js +6 -0
- package/dist/canvas/painter.d.ts +2 -2
- package/dist/canvas/painter.js +2 -2
- package/dist/common/color-input.d.ts +24 -0
- package/dist/common/color-input.js +278 -0
- package/dist/common/diagnostics.d.ts +61 -0
- package/dist/common/diagnostics.js +77 -0
- package/dist/common/gradient.d.ts +53 -0
- package/dist/common/gradient.js +97 -0
- package/dist/edit/acroform-reader.js +7 -7
- package/dist/edit/appearance.js +3 -3
- package/dist/edit/attachments.d.ts +52 -0
- package/dist/edit/attachments.js +178 -0
- package/dist/edit/document.d.ts +38 -8
- package/dist/edit/document.js +208 -51
- package/dist/edit/fill.js +8 -23
- package/dist/edit/filters.d.ts +15 -0
- package/dist/edit/filters.js +157 -0
- package/dist/edit/index.d.ts +4 -1
- package/dist/edit/index.js +3 -1
- package/dist/edit/objects.d.ts +3 -4
- package/dist/edit/objects.js +5 -18
- package/dist/elements/canvas-element.d.ts +3 -0
- package/dist/elements/canvas-element.js +14 -3
- package/dist/elements/container-element.d.ts +8 -1
- package/dist/elements/container-element.js +49 -17
- package/dist/elements/forms/checkbox-element.d.ts +2 -0
- package/dist/elements/forms/checkbox-element.js +12 -3
- package/dist/elements/forms/choice-element.d.ts +6 -1
- package/dist/elements/forms/choice-element.js +17 -6
- package/dist/elements/forms/field-font.d.ts +8 -0
- package/dist/elements/forms/field-font.js +5 -0
- package/dist/elements/forms/push-button-element.d.ts +6 -1
- package/dist/elements/forms/push-button-element.js +16 -4
- package/dist/elements/forms/radio-element.d.ts +2 -0
- package/dist/elements/forms/radio-element.js +12 -3
- package/dist/elements/forms/signature-element.d.ts +6 -1
- package/dist/elements/forms/signature-element.js +16 -4
- package/dist/elements/forms/text-field-element.d.ts +6 -1
- package/dist/elements/forms/text-field-element.js +16 -4
- package/dist/elements/image-element.d.ts +70 -21
- package/dist/elements/image-element.js +173 -52
- package/dist/elements/index.d.ts +3 -0
- package/dist/elements/index.js +3 -0
- package/dist/elements/layout/anchor-element.d.ts +8 -10
- package/dist/elements/layout/anchor-element.js +10 -18
- package/dist/elements/layout/bookmark-element.d.ts +9 -11
- package/dist/elements/layout/bookmark-element.js +11 -20
- package/dist/elements/layout/column-break-element.d.ts +17 -0
- package/dist/elements/layout/column-break-element.js +26 -0
- package/dist/elements/layout/default-text-style-element.d.ts +11 -13
- package/dist/elements/layout/default-text-style-element.js +14 -31
- package/dist/elements/layout/deferred-element.d.ts +20 -4
- package/dist/elements/layout/deferred-element.js +41 -9
- package/dist/elements/layout/expanded-element.d.ts +11 -0
- package/dist/elements/layout/expanded-element.js +53 -18
- package/dist/elements/layout/flow-element.d.ts +109 -0
- package/dist/elements/layout/flow-element.js +317 -0
- package/dist/elements/layout/keep-together-element.d.ts +8 -18
- package/dist/elements/layout/keep-together-element.js +33 -45
- package/dist/elements/layout/link-element.d.ts +8 -13
- package/dist/elements/layout/link-element.js +9 -19
- package/dist/elements/layout/padding-element.d.ts +18 -1
- package/dist/elements/layout/padding-element.js +63 -28
- package/dist/elements/layout/page-break-element.d.ts +4 -1
- package/dist/elements/layout/page-break-element.js +6 -1
- package/dist/elements/layout/page-builder-element.d.ts +5 -0
- package/dist/elements/layout/page-builder-element.js +13 -2
- package/dist/elements/layout/positioned-element.d.ts +23 -4
- package/dist/elements/layout/positioned-element.js +42 -12
- package/dist/elements/layout/proxy-element.d.ts +47 -0
- package/dist/elements/layout/proxy-element.js +106 -0
- package/dist/elements/layout/region-element.d.ts +53 -0
- package/dist/elements/layout/region-element.js +108 -0
- package/dist/elements/layout/repeating-header-element.d.ts +9 -0
- package/dist/elements/layout/repeating-header-element.js +55 -13
- package/dist/elements/layout/rotated-box-element.d.ts +6 -0
- package/dist/elements/layout/rotated-box-element.js +27 -14
- package/dist/elements/layout/rotated-element.d.ts +9 -0
- package/dist/elements/layout/rotated-element.js +33 -2
- package/dist/elements/layout/struct-group.d.ts +9 -17
- package/dist/elements/layout/struct-group.js +10 -35
- package/dist/elements/line-element.d.ts +1 -0
- package/dist/elements/line-element.js +6 -0
- package/dist/elements/page-element.d.ts +10 -3
- package/dist/elements/page-element.js +39 -31
- package/dist/elements/pdf-document-element.d.ts +3 -0
- package/dist/elements/pdf-document-element.js +7 -0
- package/dist/elements/pdf-element.d.ts +105 -16
- package/dist/elements/pdf-element.js +118 -19
- package/dist/elements/rectangle-element.d.ts +22 -2
- package/dist/elements/rectangle-element.js +119 -55
- package/dist/elements/row-element.d.ts +17 -12
- package/dist/elements/row-element.js +89 -9
- package/dist/elements/svg-element.d.ts +30 -6
- package/dist/elements/svg-element.js +91 -26
- package/dist/elements/text-element.d.ts +48 -13
- package/dist/elements/text-element.js +161 -116
- package/dist/forms/acroform.d.ts +9 -1
- package/dist/forms/acroform.js +83 -34
- package/dist/forms/appearance.d.ts +17 -6
- package/dist/forms/appearance.js +18 -16
- package/dist/ir/display-list.d.ts +18 -3
- package/dist/layout/box-constraints.d.ts +17 -0
- package/dist/layout/box-constraints.js +31 -0
- package/dist/layout/collect-images.d.ts +6 -4
- package/dist/layout/collect-images.js +14 -8
- package/dist/layout/flex-item.d.ts +11 -0
- package/dist/layout/flex-item.js +51 -0
- package/dist/layout/fragmentation.d.ts +23 -9
- package/dist/layout/fragmentation.js +62 -19
- package/dist/layout/layout-cache.d.ts +53 -0
- package/dist/layout/layout-cache.js +110 -0
- package/dist/platform/browser-fs.d.ts +1 -2
- package/dist/platform/browser-fs.js +3 -6
- package/dist/platform/node-fs.d.ts +0 -1
- package/dist/platform/node-fs.js +0 -4
- package/dist/renderer/anchor-renderer.d.ts +2 -1
- package/dist/renderer/anchor-renderer.js +5 -4
- package/dist/renderer/bookmark-renderer.d.ts +2 -1
- package/dist/renderer/bookmark-renderer.js +5 -4
- package/dist/renderer/canvas-renderer.d.ts +2 -1
- package/dist/renderer/canvas-renderer.js +5 -2
- package/dist/renderer/column-break-renderer.d.ts +8 -0
- package/dist/renderer/column-break-renderer.js +15 -0
- package/dist/renderer/container-renderer.d.ts +2 -1
- package/dist/renderer/container-renderer.js +6 -5
- package/dist/renderer/default-text-style-renderer.d.ts +2 -1
- package/dist/renderer/default-text-style-renderer.js +2 -3
- package/dist/renderer/deferred-renderer.d.ts +2 -1
- package/dist/renderer/deferred-renderer.js +2 -3
- package/dist/renderer/emoji-image.js +3 -1
- package/dist/renderer/expanded-renderer.d.ts +2 -1
- package/dist/renderer/expanded-renderer.js +2 -3
- package/dist/renderer/flow-renderer.d.ts +16 -0
- package/dist/renderer/flow-renderer.js +21 -0
- package/dist/renderer/form-field-renderer.d.ts +2 -1
- package/dist/renderer/form-field-renderer.js +16 -3
- package/dist/renderer/image-renderer.d.ts +2 -1
- package/dist/renderer/image-renderer.js +33 -53
- package/dist/renderer/index.d.ts +2 -0
- package/dist/renderer/index.js +2 -0
- package/dist/renderer/keep-together-renderer.d.ts +2 -1
- package/dist/renderer/keep-together-renderer.js +2 -3
- package/dist/renderer/line-renderer.d.ts +2 -1
- package/dist/renderer/line-renderer.js +7 -2
- package/dist/renderer/link-renderer.d.ts +2 -1
- package/dist/renderer/link-renderer.js +36 -5
- package/dist/renderer/padding-renderer.d.ts +2 -1
- package/dist/renderer/padding-renderer.js +5 -5
- package/dist/renderer/page-break-renderer.d.ts +6 -5
- package/dist/renderer/page-break-renderer.js +14 -7
- package/dist/renderer/page-builder-renderer.d.ts +2 -1
- package/dist/renderer/page-builder-renderer.js +2 -3
- package/dist/renderer/page-renderer.js +30 -10
- package/dist/renderer/pdf-backend.d.ts +4 -3
- package/dist/renderer/pdf-backend.js +14 -7
- package/dist/renderer/pdf-document-renderer.d.ts +1 -8
- package/dist/renderer/pdf-document-renderer.js +17 -17
- package/dist/renderer/pdf-renderer.js +20 -11
- package/dist/renderer/positioned-renderer.d.ts +18 -1
- package/dist/renderer/positioned-renderer.js +43 -6
- package/dist/renderer/rectangle-renderer.d.ts +2 -1
- package/dist/renderer/rectangle-renderer.js +18 -8
- package/dist/renderer/repeating-header-renderer.d.ts +2 -1
- package/dist/renderer/repeating-header-renderer.js +6 -5
- package/dist/renderer/rotated-renderer.d.ts +2 -1
- package/dist/renderer/rotated-renderer.js +9 -5
- package/dist/renderer/row-renderer.d.ts +2 -1
- package/dist/renderer/row-renderer.js +6 -5
- package/dist/renderer/struct-group-renderer.d.ts +2 -1
- package/dist/renderer/struct-group-renderer.js +2 -3
- package/dist/renderer/svg-renderer.d.ts +2 -1
- package/dist/renderer/svg-renderer.js +8 -2
- package/dist/renderer/text-renderer.d.ts +4 -6
- package/dist/renderer/text-renderer.js +114 -127
- package/dist/svg/gradients.js +5 -0
- package/dist/svg/index.d.ts +1 -1
- package/dist/svg/index.js +36 -6
- package/dist/svg/style.d.ts +2 -0
- package/dist/svg/style.js +12 -1
- package/dist/text/advance.d.ts +4 -0
- package/dist/text/advance.js +17 -4
- package/dist/text/bidi.d.ts +0 -2
- package/dist/text/bidi.js +0 -10
- package/dist/text/glyph-coverage.d.ts +1 -1
- package/dist/text/glyph-coverage.js +7 -3
- package/dist/text/hyphen-breaks.d.ts +17 -0
- package/dist/text/hyphen-breaks.js +54 -0
- package/dist/text/line-breaker.d.ts +55 -29
- package/dist/text/line-breaker.js +453 -188
- package/dist/text/line-metrics.d.ts +8 -3
- package/dist/text/line-metrics.js +11 -2
- package/dist/text/pdf-text-string.d.ts +21 -0
- package/dist/text/pdf-text-string.js +114 -0
- package/dist/text/text-decoration.d.ts +5 -5
- package/dist/text/text-decoration.js +5 -5
- package/dist/text/word-splitting.d.ts +15 -2
- package/dist/text/word-splitting.js +45 -13
- package/dist/utils/afm-parser.d.ts +2 -0
- package/dist/utils/afm-parser.js +10 -1
- package/dist/utils/dest-registry.d.ts +1 -1
- package/dist/utils/dest-registry.js +3 -2
- package/dist/utils/fetch-bytes.d.ts +19 -0
- package/dist/utils/fetch-bytes.js +79 -0
- package/dist/utils/flex-layout.d.ts +16 -14
- package/dist/utils/flex-layout.js +427 -217
- package/dist/utils/font-metrics.d.ts +4 -3
- package/dist/utils/image-helper.d.ts +59 -11
- package/dist/utils/image-helper.js +209 -81
- package/dist/utils/pdf-object-manager.d.ts +17 -6
- package/dist/utils/pdf-object-manager.js +70 -20
- package/dist/utils/renderer-registry.d.ts +49 -2
- package/dist/utils/renderer-registry.js +40 -0
- package/dist/utils/struct-tree.d.ts +24 -0
- package/dist/utils/struct-tree.js +61 -9
- package/dist/utils/ttf-parser.d.ts +4 -0
- package/dist/utils/ttf-parser.js +30 -6
- package/dist/validators/element-validator.js +2 -1
- package/package.json +1 -1
- package/dist/elements/layout/sized-container-element.d.ts +0 -14
- package/dist/elements/layout/sized-container-element.js +0 -32
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { readFileBytes } from "../platform/node-fs.js";
|
|
2
2
|
import { SvgParseError, svgSize, svgToIr } from "../svg/index.js";
|
|
3
|
-
import { extentSpecs, resolveSize, } from "../layout/box-constraints.js";
|
|
3
|
+
import { extentSpecs, resolveSize, sizeAtOwnRatio, } from "../layout/box-constraints.js";
|
|
4
4
|
import { SizedPDFElement } from "./pdf-element.js";
|
|
5
|
+
import { IMAGE_FETCH_LIMITS, ImageUrlError, isImageUrl } from "./image-element.js";
|
|
6
|
+
import { fetchBytes } from "../utils/fetch-bytes.js";
|
|
5
7
|
/** Markup is recognised by its first non-space character - anything else is treated as a path. */
|
|
6
8
|
const looksLikeMarkup = (value) => /^\s*[<]/.test(value);
|
|
7
9
|
/**
|
|
@@ -24,30 +26,78 @@ function readSource(path) {
|
|
|
24
26
|
*
|
|
25
27
|
* Unlike a bitmap it needs no decoder, so its intrinsic size is known SYNCHRONOUSLY, in the
|
|
26
28
|
* constructor - which also means a broken file fails on the line that asked for it rather than deep
|
|
27
|
-
* inside a later render, the same bargain `addFont` makes.
|
|
29
|
+
* inside a later render, the same bargain `addFont` makes. An SVG from a URL is the exception: like
|
|
30
|
+
* an image from a URL it is fetched when the document renders (`resolveIntrinsicSize`, or the
|
|
31
|
+
* renderer for a subtree built during layout), and a dead link stops the render naming it.
|
|
28
32
|
*/
|
|
29
33
|
export class SvgElement extends SizedPDFElement {
|
|
30
34
|
constructor(params) {
|
|
31
35
|
super({ x: 0, y: 0, width: params.width, height: params.height });
|
|
36
|
+
this.failed = false;
|
|
32
37
|
const { source, alt, widthFactor, heightFactor, ...sizing } = params;
|
|
33
38
|
this.widthFactor = widthFactor;
|
|
34
39
|
this.heightFactor = heightFactor;
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
if (typeof source === "string" && isImageUrl(source))
|
|
41
|
+
this.url = source;
|
|
42
|
+
else
|
|
43
|
+
this.parse(typeof source === "string"
|
|
37
44
|
? looksLikeMarkup(source)
|
|
38
45
|
? source
|
|
39
46
|
: new TextDecoder().decode(readSource(source))
|
|
40
|
-
: new TextDecoder().decode(source);
|
|
41
|
-
// Parsed here on purpose: an unreadable file is an error where it was NAMED, not inside a render
|
|
42
|
-
// three call frames later. The whole document is walked, not just its root, so an element outside
|
|
43
|
-
// the subset surfaces here too - which is what makes the error predictable rather than a lottery
|
|
44
|
-
// between construction and render time. A logo parses in well under a millisecond.
|
|
45
|
-
this.intrinsic = svgSize(this.source);
|
|
46
|
-
svgToIr(this.source, { x: 0, y: 0, width: 1, height: 1 });
|
|
47
|
+
: new TextDecoder().decode(source));
|
|
47
48
|
this.alt = alt;
|
|
48
49
|
this.sizing = sizing;
|
|
49
50
|
this.requested = { width: params.width, height: params.height };
|
|
50
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Parsed on purpose where the source is given: an unreadable file is an error where it was NAMED,
|
|
54
|
+
* not inside a render three call frames later. The whole document is walked, not just its root, so
|
|
55
|
+
* an element outside the subset surfaces here too. A logo parses in well under a millisecond.
|
|
56
|
+
*/
|
|
57
|
+
parse(source) {
|
|
58
|
+
this.intrinsic = svgSize(source);
|
|
59
|
+
svgToIr(source, { x: 0, y: 0, width: 1, height: 1 });
|
|
60
|
+
this.source = source;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Fetches and parses an SVG from a URL - once per render, however often it is asked. A no-op
|
|
64
|
+
* otherwise. A failure sticks for that render only: `fresh` (a new render begins) asks again.
|
|
65
|
+
*/
|
|
66
|
+
async load(fresh = false) {
|
|
67
|
+
const url = this.url;
|
|
68
|
+
if (url === undefined)
|
|
69
|
+
return;
|
|
70
|
+
if (fresh && this.failed)
|
|
71
|
+
this.loading = undefined;
|
|
72
|
+
this.loading ?? (this.loading = fetchBytes(url, "SVG", ImageUrlError, IMAGE_FETCH_LIMITS)
|
|
73
|
+
.then((bytes) => {
|
|
74
|
+
try {
|
|
75
|
+
this.parse(new TextDecoder().decode(bytes));
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
throw new ImageUrlError(`the SVG at ${url} could not be read: ${String(e?.message ?? e)}`);
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
.then(() => {
|
|
82
|
+
this.failed = false;
|
|
83
|
+
}, (e) => {
|
|
84
|
+
this.failed = true;
|
|
85
|
+
throw e;
|
|
86
|
+
}));
|
|
87
|
+
await this.loading;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The pre-layout pass, as for an `ImageElement`: best-effort, so a failure leaves the size unknown
|
|
91
|
+
* and the renderer, which loads again, surfaces the real error.
|
|
92
|
+
*/
|
|
93
|
+
async resolveIntrinsicSize() {
|
|
94
|
+
try {
|
|
95
|
+
await this.load(true); // a render begins here
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// the renderer reports it
|
|
99
|
+
}
|
|
100
|
+
}
|
|
51
101
|
getProps() {
|
|
52
102
|
return {
|
|
53
103
|
x: this.x,
|
|
@@ -60,8 +110,18 @@ export class SvgElement extends SizedPDFElement {
|
|
|
60
110
|
};
|
|
61
111
|
}
|
|
62
112
|
calculateLayout(constraints, offset, _ctx) {
|
|
113
|
+
const size = this.sizeFor(constraints);
|
|
63
114
|
this.x = offset.x;
|
|
64
115
|
this.y = offset.y;
|
|
116
|
+
this.width = size.width;
|
|
117
|
+
this.height = size.height;
|
|
118
|
+
return size;
|
|
119
|
+
}
|
|
120
|
+
computeSize(constraints) {
|
|
121
|
+
return this.sizeFor(constraints);
|
|
122
|
+
}
|
|
123
|
+
/** Its size under these constraints - the one computation both `measure` and layout use. */
|
|
124
|
+
sizeFor(constraints) {
|
|
65
125
|
const specs = extentSpecs({
|
|
66
126
|
...this.sizing,
|
|
67
127
|
width: this.requested.width,
|
|
@@ -73,21 +133,26 @@ export class SvgElement extends SizedPDFElement {
|
|
|
73
133
|
let w = resolved.width;
|
|
74
134
|
let h = resolved.height;
|
|
75
135
|
const bounds = resolved.constraints;
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
136
|
+
// An SVG from a URL that was never fetched sits in content built DURING layout (a PageBuilder, an auto
|
|
137
|
+
// table column), which the pass before layout cannot reach. Its ratio is unknown here, so it needs
|
|
138
|
+
// its whole box - a named error instead of a drawing sized to nothing. A FAILED fetch is not this
|
|
139
|
+
// case: the renderer reports that one by its URL.
|
|
140
|
+
if (this.url !== undefined &&
|
|
141
|
+
this.loading === undefined &&
|
|
142
|
+
(w === undefined || h === undefined)) {
|
|
143
|
+
throw new ImageUrlError(`the SVG at ${this.url} sits in content built during layout (a PageBuilder or an auto table ` +
|
|
144
|
+
`column), where its size cannot be read before it is placed - give it both a width and a ` +
|
|
145
|
+
`height, or an aspectRatio`);
|
|
146
|
+
}
|
|
147
|
+
// Its own ratio fills an open axis, as for a bitmap - which needs a decode pass for it; an SVG
|
|
148
|
+
// knows it from its viewBox. Unsized, it is its own size scaled down to fit: a 24pt icon stays 24pt.
|
|
149
|
+
const intrinsic = this.intrinsic ?? { width: 0, height: 0 };
|
|
150
|
+
if (this.sizing.aspectRatio === undefined && intrinsic.width > 0 && intrinsic.height > 0) {
|
|
151
|
+
({ width: w, height: h } = sizeAtOwnRatio(w, h, intrinsic, bounds));
|
|
86
152
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return { width: this.width, height: this.height };
|
|
153
|
+
return {
|
|
154
|
+
width: w ?? bounds.constrainWidth(intrinsic.width),
|
|
155
|
+
height: h ?? bounds.constrainHeight(intrinsic.height),
|
|
156
|
+
};
|
|
92
157
|
}
|
|
93
158
|
}
|
|
@@ -4,7 +4,7 @@ import { BoxConstraints, Offset, Size } from "../layout/box-constraints.js";
|
|
|
4
4
|
import type { Direction } from "../text/bidi.js";
|
|
5
5
|
import { type TextTransform } from "../text/text-style.js";
|
|
6
6
|
import { Fragmentable, FragmentResult } from "../layout/fragmentation.js";
|
|
7
|
-
import { TextOverflow } from "../text/line-breaker.js";
|
|
7
|
+
import { type SegmentDefaults, TextOverflow } from "../text/line-breaker.js";
|
|
8
8
|
import { HorizontalAlignment, LayoutContext, SizedPDFElement } from "./pdf-element.js";
|
|
9
9
|
import type { Hyphenator } from "../text/word-splitting.js";
|
|
10
10
|
export interface TextSegment {
|
|
@@ -22,8 +22,16 @@ export interface TextSegment {
|
|
|
22
22
|
/** Unset inherits the Text's own setting; `true`/`false` overrides it for this run only. */
|
|
23
23
|
underline?: boolean;
|
|
24
24
|
strikethrough?: boolean;
|
|
25
|
+
skipInk?: boolean;
|
|
25
26
|
/** Extra space after every glyph, in points; unset inherits the Text's own value. */
|
|
26
27
|
letterSpacing?: number;
|
|
28
|
+
textTransform?: TextTransform;
|
|
29
|
+
wordSpacing?: number;
|
|
30
|
+
ligatures?: boolean;
|
|
31
|
+
/** How a word wider than the box splits, for the characters of THIS run (Chrome: a break after a
|
|
32
|
+
* character is allowed by that character's own `overflow-wrap`). */
|
|
33
|
+
breakWord?: boolean;
|
|
34
|
+
hyphenate?: Hyphenator;
|
|
27
35
|
/**
|
|
28
36
|
* CSS `vertical-align`, for a footnote marker or a formula index. Shifts THIS run's baseline;
|
|
29
37
|
* it does not resize the text, and it does not change the line's height - set `fontSize` yourself
|
|
@@ -83,6 +91,9 @@ interface TextElementParams {
|
|
|
83
91
|
hyphenate?: Hyphenator;
|
|
84
92
|
/** Accessibility role for the tagged structure tree (heading level or paragraph; default `"p"`). */
|
|
85
93
|
role?: TextRole;
|
|
94
|
+
/** Set by pagination, not by authors: this element is the first N lines of a paragraph that
|
|
95
|
+
* continues on the next page. See `LineOptions.shownLines`. */
|
|
96
|
+
shownLines?: number;
|
|
86
97
|
}
|
|
87
98
|
export declare class TextElement extends SizedPDFElement implements Fragmentable {
|
|
88
99
|
private readonly rawFontSize?;
|
|
@@ -116,6 +127,7 @@ export declare class TextElement extends SizedPDFElement implements Fragmentable
|
|
|
116
127
|
private direction;
|
|
117
128
|
private fontFallback;
|
|
118
129
|
private resolved?;
|
|
130
|
+
private broken;
|
|
119
131
|
private textTransform;
|
|
120
132
|
private wordSpacing;
|
|
121
133
|
private textIndent;
|
|
@@ -123,12 +135,17 @@ export declare class TextElement extends SizedPDFElement implements Fragmentable
|
|
|
123
135
|
private ligatures;
|
|
124
136
|
private hyphenate?;
|
|
125
137
|
private content;
|
|
138
|
+
/** What `covered` had to remove, reported where the text is laid out on its page (see
|
|
139
|
+
* `calculateLayout`). A split paragraph's first piece carries its parent's, as `lostBefore`. */
|
|
140
|
+
private lostGlyphs;
|
|
141
|
+
private lostBefore;
|
|
126
142
|
private maxLines?;
|
|
127
143
|
private orphans?;
|
|
128
144
|
private widows?;
|
|
129
145
|
private overflow;
|
|
130
146
|
private readonly role?;
|
|
131
|
-
|
|
147
|
+
private readonly shownLines?;
|
|
148
|
+
constructor({ fontSize, content, fontFamily, fontStyle, color, textAlignment, maxLines, orphans, widows, overflow, lineHeight, underline, strikethrough, skipInk, letterSpacing, direction, fontFallback, textTransform, wordSpacing, textIndent, breakWord, hyphenate, ligatures, role, shownLines, }: TextElementParams);
|
|
132
149
|
private resolveStyle;
|
|
133
150
|
/**
|
|
134
151
|
* The last `display(metrics)` result, with what it depended on - recasing, coverage and the fallback
|
|
@@ -153,7 +170,7 @@ export declare class TextElement extends SizedPDFElement implements Fragmentable
|
|
|
153
170
|
* back unchanged, so an ordinary document is byte-identical.
|
|
154
171
|
*/
|
|
155
172
|
private covered;
|
|
156
|
-
/** The content with `text-transform` applied, and nothing else. */
|
|
173
|
+
/** The content as spans, with `text-transform` applied, and nothing else. */
|
|
157
174
|
private recased;
|
|
158
175
|
private lineOptions;
|
|
159
176
|
private applyStyle;
|
|
@@ -161,23 +178,36 @@ export declare class TextElement extends SizedPDFElement implements Fragmentable
|
|
|
161
178
|
* Splits the paragraph at line boxes (Slice 1). The lines that fit in `maxHeight` stay;
|
|
162
179
|
* the rest become a remainder `TextElement` re-wrapped on the next page. If not even one
|
|
163
180
|
* line fits, nothing is forced here - the caller (the container) decides whether to move
|
|
164
|
-
* the whole element on for progress.
|
|
181
|
+
* the whole element on for progress.
|
|
165
182
|
*/
|
|
166
183
|
fragment(maxHeight: number, width: number, ctx: LayoutContext): FragmentResult;
|
|
167
|
-
|
|
168
|
-
private
|
|
184
|
+
/** How the text is broken: the knobs `textHeight` and the renderer pass too. */
|
|
185
|
+
private segmentDefaults;
|
|
169
186
|
/** The orphan/widow minimums for this paragraph; unset means the CSS default of 2 lines each. */
|
|
170
187
|
private breakRule;
|
|
171
188
|
private cloneWithContent;
|
|
172
189
|
calculateLayout(constraints: BoxConstraints, offset: Offset, ctx: LayoutContext): Size;
|
|
190
|
+
/**
|
|
191
|
+
* The size `calculateLayout` would take, without placing anything. Resolving the inherited style
|
|
192
|
+
* and filling the memos below are its only writes, and both are a pure function of the context:
|
|
193
|
+
* the same inputs leave the same state, which a later layout reads back unchanged.
|
|
194
|
+
*/
|
|
195
|
+
/** A text's size reads only the width it may take: it wraps to it, and a height bound never changes
|
|
196
|
+
* the lines (a box that is too short cuts them, it does not reflow them). */
|
|
197
|
+
protected sizeInputs(constraints: BoxConstraints): BoxConstraints;
|
|
198
|
+
protected computeSize(constraints: BoxConstraints, ctx: LayoutContext): Size;
|
|
199
|
+
/**
|
|
200
|
+
* The one sizing path, for measuring and layout alike: a bounded width wraps to it (in a Column), an
|
|
201
|
+
* unbounded one takes the natural single-line width (in a Row). The lines are what layout checks.
|
|
202
|
+
* The style is resolved here, as drawing reads it.
|
|
203
|
+
*/
|
|
204
|
+
/** The text broken at `width`: once per context and width, for measuring, layout and splitting. */
|
|
205
|
+
private linesAt;
|
|
206
|
+
private sizeWith;
|
|
173
207
|
/** The unwrapped single-line width of the content (used when width is unbounded, e.g. inside a Row).
|
|
174
|
-
* Must match the
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* into one term; we must group the same way. Adding word and space as two separate steps is
|
|
178
|
-
* algebraically equal but, because floating-point addition is not associative, drifts by a sub-ULP
|
|
179
|
-
* - enough to tip a borderline string (e.g. "20 Jun 2026", wider than "04 Jul 2026" only because
|
|
180
|
-
* 'n' beats 'l') one bit over its own width, dropping the last word onto a second line. */
|
|
208
|
+
* Must match the breaker's one-line sum BIT for bit - it adds `width + (space + word)`, and the same
|
|
209
|
+
* numbers grouped differently drift by a sub-ULP, enough to wrap a text inside its own natural-width
|
|
210
|
+
* box. `singleLineWidth` is that sum. */
|
|
181
211
|
private naturalWidth;
|
|
182
212
|
/**
|
|
183
213
|
* The widest piece of this text that cannot be broken - CSS's `min-content` width. A shrinking flex
|
|
@@ -198,6 +228,10 @@ export declare class TextElement extends SizedPDFElement implements Fragmentable
|
|
|
198
228
|
fontStyle: FontStyle;
|
|
199
229
|
color: Color;
|
|
200
230
|
content: string | TextSegment[];
|
|
231
|
+
/** The content as it is measured and drawn: spans, recased, split by font, drawable glyphs only. */
|
|
232
|
+
spans: TextSegment[];
|
|
233
|
+
/** How the text is broken - the settings it is measured with, so drawing breaks it the same. */
|
|
234
|
+
breaking: SegmentDefaults;
|
|
201
235
|
textAlignment: HorizontalAlignment;
|
|
202
236
|
maxLines: number | undefined;
|
|
203
237
|
orphans: number | undefined;
|
|
@@ -215,6 +249,7 @@ export declare class TextElement extends SizedPDFElement implements Fragmentable
|
|
|
215
249
|
ligatures: boolean;
|
|
216
250
|
hyphenate: Hyphenator | undefined;
|
|
217
251
|
role: TextRole | undefined;
|
|
252
|
+
shownLines: number | undefined;
|
|
218
253
|
};
|
|
219
254
|
}
|
|
220
255
|
export {};
|