@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,8 +1,11 @@
|
|
|
1
|
+
import { widthRules } from "../layout/box-constraints.js";
|
|
1
2
|
import { Color } from "../common/color.js";
|
|
2
3
|
import { BoxConstraints, extentSpecs, resolveSize, } from "../layout/box-constraints.js";
|
|
3
4
|
import { stackMinIntrinsic, withDeclaredExtent } from "../layout/min-intrinsic.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
5
|
+
import { positionedIn } from "./layout/positioned-element.js";
|
|
6
|
+
import { PaddingElement } from "./layout/padding-element.js";
|
|
7
|
+
import { childrenForceBreak, insetContext, packChildren, packedUnchanged, } from "../layout/fragmentation.js";
|
|
8
|
+
import { SizedPDFElement, withPaddingBase, } from "./pdf-element.js";
|
|
6
9
|
export class RectangleElement extends SizedPDFElement {
|
|
7
10
|
constructor({ children = [], color = new Color(0, 0, 0), backgroundColor, borderWidth, width, height, radius, sideBorders, relative, overflow, breakBefore, breakAfter, ...sizing }) {
|
|
8
11
|
super({ x: 0, y: 0, width, height });
|
|
@@ -20,8 +23,10 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
20
23
|
this.breakAfter = breakAfter ?? false;
|
|
21
24
|
this.sizeMemory = { ...sizing, x: 0, y: 0, width, height };
|
|
22
25
|
}
|
|
26
|
+
// A break before the FIRST child is a break before this stack (CSS propagates it): the whole stack
|
|
27
|
+
// moves to the next page, instead of leaving an empty piece - or an empty border - behind.
|
|
23
28
|
breaksBefore() {
|
|
24
|
-
return this.breakBefore;
|
|
29
|
+
return this.breakBefore || (this.children[0]?.breaksBefore() ?? false);
|
|
25
30
|
}
|
|
26
31
|
breaksAfter() {
|
|
27
32
|
return this.breakAfter;
|
|
@@ -35,31 +40,39 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
35
40
|
* box is sized by what it actually holds on each page.
|
|
36
41
|
*/
|
|
37
42
|
fragment(maxHeight, width, ctx) {
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
const boxWidth = this.
|
|
41
|
-
(this.sizeMemory.widthFactor !== undefined ? width * this.sizeMemory.widthFactor : width);
|
|
43
|
+
// The box's own width rules (fixed, %, min/max) resolved against the region - the same sizing
|
|
44
|
+
// path as `measure`, so the content is packed at the width it will be drawn at.
|
|
45
|
+
const boxWidth = this.measure(BoxConstraints.loose(width, Infinity), ctx).width;
|
|
42
46
|
const innerWidth = Math.max(0, boxWidth - 2 * this.borderWidth);
|
|
43
47
|
// Border-box: the content is inset by the border on top and bottom, so a fragment
|
|
44
48
|
// holding `c` of content is `c + 2*border` tall. (Derived, not a fudge factor.)
|
|
45
49
|
const innerMaxHeight = maxHeight - 2 * this.borderWidth;
|
|
46
|
-
const { fitted, remainder, forceBreak } = packChildren(this.children, innerMaxHeight, innerWidth, ctx);
|
|
50
|
+
const { fitted, remainder, forceBreak } = packChildren(this.children, innerMaxHeight, innerWidth, insetContext(this.paddingContext(ctx, width), 2 * this.borderWidth));
|
|
47
51
|
// Fits with no forced cut: return the whole box unchanged. A trailing forced break is the
|
|
48
52
|
// exception - fall through so the box is rebuilt from the packed children (without the consumed
|
|
49
53
|
// break marker), rather than handing back the original that still holds it.
|
|
50
|
-
if (remainder.length === 0 && !forceBreak)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
if (remainder.length === 0 && !forceBreak && packedUnchanged(this.children, fitted)) {
|
|
55
|
+
// The content fits, but a fixed height may not - such a box cannot shrink, so it moves on whole.
|
|
56
|
+
const own = this.measure(BoxConstraints.loose(width, Infinity), ctx).height;
|
|
57
|
+
return own <= maxHeight
|
|
58
|
+
? { fitted: this, remainder: null }
|
|
59
|
+
: { fitted: null, remainder: this };
|
|
60
|
+
}
|
|
61
|
+
// Nothing fit below the content above: move on whole, not as an empty bordered box.
|
|
62
|
+
if (fitted.length === 0 && !forceBreak)
|
|
63
|
+
return { fitted: null, remainder: this };
|
|
64
|
+
const childCtx = this.paddingContext(ctx, width);
|
|
65
|
+
const contentHeight = (kids) => kids.reduce((sum, child) => sum + child.measure(BoxConstraints.loose(innerWidth, Infinity), childCtx).height, 0);
|
|
55
66
|
return {
|
|
56
67
|
fitted: this.cloneWithChildren(fitted, contentHeight(fitted) + 2 * this.borderWidth),
|
|
57
68
|
// A trailing forced break leaves nothing to carry over: no remainder box, no extra page.
|
|
58
69
|
// Only the CONTINUATION carries `breakAfter` (a box that splits still breaks after its LAST
|
|
59
|
-
// fragment, not its first); `breakBefore` is dropped, already
|
|
70
|
+
// fragment, not its first); `breakBefore` is dropped, already honored before the split.
|
|
71
|
+
// It gets no height, as a Column's piece does: it is sized where it lands, which may be a
|
|
72
|
+
// narrower or wider region (a Flow's), or one that gives a region-sized rest its height.
|
|
60
73
|
remainder: remainder.length === 0
|
|
61
74
|
? null
|
|
62
|
-
: this.cloneWithChildren(remainder,
|
|
75
|
+
: this.cloneWithChildren(remainder, undefined, this.breakAfter),
|
|
63
76
|
forceBreak,
|
|
64
77
|
};
|
|
65
78
|
}
|
|
@@ -70,10 +83,9 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
70
83
|
return new RectangleElement({
|
|
71
84
|
x: 0,
|
|
72
85
|
y: 0,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
//
|
|
76
|
-
// is intentionally dropped here - box-decoration-break, same as an explicit height.
|
|
86
|
+
...widthRules(this.sizeMemory),
|
|
87
|
+
// A split box is sized by its per-page content (height passed in), so the height rules are
|
|
88
|
+
// intentionally dropped here - box-decoration-break, same as an explicit height.
|
|
77
89
|
height,
|
|
78
90
|
children,
|
|
79
91
|
color: this.color,
|
|
@@ -84,11 +96,14 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
84
96
|
relative: this.relative,
|
|
85
97
|
overflow: this.overflow,
|
|
86
98
|
breakAfter,
|
|
87
|
-
});
|
|
99
|
+
}).asPieceOf(this);
|
|
88
100
|
}
|
|
89
101
|
relativeSizeFactor(horizontal) {
|
|
90
102
|
return horizontal ? this.sizeMemory.widthFactor : this.sizeMemory.heightFactor;
|
|
91
103
|
}
|
|
104
|
+
maxExtent(horizontal) {
|
|
105
|
+
return (horizontal ? this.sizeMemory.maxWidth : this.sizeMemory.maxHeight) ?? Infinity;
|
|
106
|
+
}
|
|
92
107
|
/** A box has no flex children of its own, but it must not swallow the need of the stack inside it: a
|
|
93
108
|
* `Spacer` in a box can only resolve if the box itself was given a bounded extent to pass down. With an
|
|
94
109
|
* explicit size on an axis the box already knows its extent there and asks for nothing. */
|
|
@@ -100,12 +115,41 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
100
115
|
return false;
|
|
101
116
|
return this.children.some((c) => c.needsBoundedMain(horizontal));
|
|
102
117
|
}
|
|
118
|
+
/** As a Column: a height of its own is the region; without one, a region-sized child needs the page's. */
|
|
119
|
+
needsRegion() {
|
|
120
|
+
if (this.sizeMemory.height !== undefined || this.sizeMemory.heightFactor !== undefined) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
return this.children.some((c) => c.needsRegion());
|
|
124
|
+
}
|
|
125
|
+
/** A Box's own padding resolves a percentage against its containing block, not against the inner
|
|
126
|
+
* width it hands its children - so it is told: the base a surrounding Row set, else what the Box was
|
|
127
|
+
* offered. Neither (an unbounded offer outside a Row) leaves the Box's own width. */
|
|
128
|
+
paddingContext(ctx, offered) {
|
|
129
|
+
if (!this.hasPercentPadding())
|
|
130
|
+
return withPaddingBase(ctx, undefined);
|
|
131
|
+
return withPaddingBase(ctx, ctx.boxPaddingBase ?? (Number.isFinite(offered) ? offered : undefined));
|
|
132
|
+
}
|
|
133
|
+
hasPercentPadding() {
|
|
134
|
+
const own = this.children[0];
|
|
135
|
+
return own instanceof PaddingElement && own.ofBox && own.hasPercentSide;
|
|
136
|
+
}
|
|
103
137
|
/** A Box stacks its children vertically inside its border, which is on both sides of the axis. */
|
|
104
138
|
minIntrinsicMain(horizontal, ctx) {
|
|
105
139
|
const content = stackMinIntrinsic(this.children, 0, !horizontal, horizontal, ctx) + 2 * this.borderWidth;
|
|
106
140
|
return withDeclaredExtent(content, horizontal ? this.sizeMemory.width : this.sizeMemory.height, horizontal ? this.sizeMemory.minWidth : this.sizeMemory.minHeight);
|
|
107
141
|
}
|
|
108
142
|
calculateLayout(constraints, offset, ctx) {
|
|
143
|
+
return this.sizeWith(constraints, ctx, offset);
|
|
144
|
+
}
|
|
145
|
+
computeSize(constraints, ctx) {
|
|
146
|
+
return this.sizeWith(constraints, ctx, null);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* The one sizing path. With an `offset` it lays the children out and keeps its geometry; with
|
|
150
|
+
* `null` it only measures - no field written, no child placed, no frame drained.
|
|
151
|
+
*/
|
|
152
|
+
sizeWith(constraints, ctx, offset) {
|
|
109
153
|
// An explicit extent is a fixed point size or a fraction of the offered box (relative sizing);
|
|
110
154
|
// the fraction only resolves in a bounded region. `undefined` = fill / shrink-wrap below.
|
|
111
155
|
const specs = extentSpecs(this.sizeMemory);
|
|
@@ -118,12 +162,11 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
118
162
|
// fixed box would balloon to the parent's size.)
|
|
119
163
|
// Whether there is a region to fill is decided by the constraints we were GIVEN: a `maxWidth` caps
|
|
120
164
|
// a box, it does not turn a shrink-wrapping one into a filling one (CSS `max-width` does not either).
|
|
121
|
-
|
|
122
|
-
explicitWidth
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
: this.width;
|
|
165
|
+
let width = explicitWidth !== undefined
|
|
166
|
+
? bounds.constrainWidth(explicitWidth)
|
|
167
|
+
: constraints.hasBoundedWidth
|
|
168
|
+
? bounds.maxWidth
|
|
169
|
+
: undefined;
|
|
127
170
|
// Width shrink-wrap: no explicit width AND an unbounded region (e.g. a `Box` badge inside a
|
|
128
171
|
// `Positioned`). Resolved after the children are measured, just below.
|
|
129
172
|
const shrinkWrapWidth = explicitWidth === undefined && !constraints.hasBoundedWidth;
|
|
@@ -131,43 +174,46 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
131
174
|
// SHRINK-WRAP the content in an unbounded one (a note box in a stack). Shrink-wrap is
|
|
132
175
|
// resolved after the children are measured, just below.
|
|
133
176
|
const shrinkWrapHeight = explicitHeight === undefined && !constraints.hasBoundedHeight;
|
|
134
|
-
|
|
135
|
-
explicitHeight
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
? { origin: { x: 0, y: 0 }, size: { width: 0, height: 0 }, place: [] }
|
|
177
|
+
let height = explicitHeight !== undefined
|
|
178
|
+
? bounds.constrainHeight(explicitHeight)
|
|
179
|
+
: constraints.hasBoundedHeight
|
|
180
|
+
? bounds.maxHeight
|
|
181
|
+
: undefined;
|
|
182
|
+
const x = this.sizeMemory.x + (offset?.x ?? 0);
|
|
183
|
+
const y = this.sizeMemory.y + (offset?.y ?? 0);
|
|
184
|
+
// A `relative` box is a positioning frame: its subtree is told it has one, and once the box is
|
|
185
|
+
// sized it lays out the `Positioned` descendants against itself (below). Measuring places
|
|
186
|
+
// nothing, so it needs no frame. A plain box leaves `ctx` untouched.
|
|
187
|
+
const frame = this.relative && offset
|
|
188
|
+
? { origin: { x: 0, y: 0 }, size: { width: 0, height: 0 } }
|
|
147
189
|
: undefined;
|
|
148
|
-
const childCtx = frame ? { ...ctx, frame } : ctx;
|
|
190
|
+
const childCtx = this.paddingContext(frame ? { ...ctx, frame } : ctx, constraints.maxWidth);
|
|
149
191
|
// Lay out children stacked inside the border (inset by the border width). Width is finalized here;
|
|
150
192
|
// height is left unbounded so each child sizes to its own content - EXCEPT for a child that cannot
|
|
151
193
|
// lay itself out without a bound (a stack holding an `Expanded`/`Spacer`). That one gets the height
|
|
152
194
|
// still free inside the box, so its flex child has real leftover space instead of an infinite one.
|
|
153
195
|
const innerWidth = shrinkWrapWidth
|
|
154
196
|
? Infinity
|
|
155
|
-
: Math.max(0, (
|
|
197
|
+
: Math.max(0, (width ?? 0) - 2 * this.borderWidth);
|
|
156
198
|
const innerHeight = shrinkWrapHeight
|
|
157
199
|
? Infinity
|
|
158
|
-
: Math.max(0, (
|
|
200
|
+
: Math.max(0, (height ?? 0) - 2 * this.borderWidth);
|
|
159
201
|
let contentWidth = 0;
|
|
160
202
|
let contentHeight = 0;
|
|
161
|
-
|
|
203
|
+
// Children are placed relative to this box's top-left, inside the border.
|
|
204
|
+
let yCursor = this.borderWidth;
|
|
162
205
|
for (const child of this.children) {
|
|
163
|
-
const consumed = yCursor -
|
|
206
|
+
const consumed = yCursor - this.borderWidth;
|
|
164
207
|
// Same rule the flex helper applies: a child gets a finite main extent when it cannot lay itself
|
|
165
208
|
// out without one - a stack holding an `Expanded`/`Spacer`, or a child sized as a percentage of us.
|
|
166
209
|
const needsBound = child.needsBoundedMain(false) || child.relativeSizeFactor(false) !== undefined;
|
|
167
210
|
const childHeight = needsBound
|
|
168
211
|
? Math.max(0, innerHeight - consumed) // Infinity - consumed stays Infinity, as it should
|
|
169
212
|
: Infinity;
|
|
170
|
-
const
|
|
213
|
+
const childConstraints = BoxConstraints.loose(innerWidth, childHeight);
|
|
214
|
+
const childSize = offset
|
|
215
|
+
? child.calculateLayout(childConstraints, { x: this.borderWidth, y: yCursor }, childCtx)
|
|
216
|
+
: child.measure(childConstraints, childCtx);
|
|
171
217
|
yCursor += childSize.height;
|
|
172
218
|
contentHeight += childSize.height;
|
|
173
219
|
contentWidth = Math.max(contentWidth, childSize.width);
|
|
@@ -175,32 +221,49 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
175
221
|
// No explicit width and no bounded region: shrink-wrap to the widest child.
|
|
176
222
|
// Clamped, so a min/max still applies to a box that sized itself to its content.
|
|
177
223
|
if (shrinkWrapWidth)
|
|
178
|
-
|
|
224
|
+
width = bounds.constrainWidth(contentWidth + 2 * this.borderWidth);
|
|
179
225
|
// A ratio on a shrink-wrapping box can only be applied HERE: before the children were measured
|
|
180
226
|
// there was no width to derive the height from.
|
|
181
227
|
const ratio = this.sizeMemory.aspectRatio;
|
|
182
228
|
const ratioSizesHeight = ratio !== undefined && ratio > 0 && shrinkWrapWidth && shrinkWrapHeight;
|
|
183
229
|
// No explicit height and no bounded region: the border hugs its content.
|
|
184
230
|
if (ratioSizesHeight)
|
|
185
|
-
|
|
231
|
+
height = bounds.constrainHeight((width ?? 0) / ratio);
|
|
186
232
|
else if (shrinkWrapHeight)
|
|
187
|
-
|
|
188
|
-
|
|
233
|
+
height = bounds.constrainHeight(contentHeight + 2 * this.borderWidth);
|
|
234
|
+
if (offset) {
|
|
235
|
+
this.x = x;
|
|
236
|
+
this.y = y;
|
|
237
|
+
this.width = width;
|
|
238
|
+
this.height = height;
|
|
239
|
+
}
|
|
240
|
+
// The box is sized now: place its out-of-flow `Positioned` descendants, relative to its own
|
|
241
|
+
// top-left. Each is drawn at its own place in the tree (tree order).
|
|
189
242
|
if (frame) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
place(frame, ctx);
|
|
243
|
+
const box = { width: width ?? 0, height: height ?? 0 };
|
|
244
|
+
for (const p of positionedIn(this.children))
|
|
245
|
+
p.placeIn(box, childCtx);
|
|
194
246
|
}
|
|
195
247
|
// Border-box model: width/height ARE the outer box (the rect we draw); the content
|
|
196
248
|
// is inset by the border on every side. Report the honest box size - no phantom
|
|
197
249
|
// border added on (that asymmetric "+border" was the source of the magic-3 fudge in
|
|
198
250
|
// fragment). Top-left coordinates; the Y-flip happens at the IR -> backend seam.
|
|
199
251
|
return {
|
|
200
|
-
width:
|
|
201
|
-
height:
|
|
252
|
+
width: width ?? 0,
|
|
253
|
+
height: height ?? 0,
|
|
202
254
|
};
|
|
203
255
|
}
|
|
256
|
+
isPositioningFrame() {
|
|
257
|
+
return this.relative;
|
|
258
|
+
}
|
|
259
|
+
/** Sorts the `zIndex` of the `Positioned` below it: a frame does, and so does a clip - what it crops
|
|
260
|
+
* stays cropped, whatever its `zIndex`. */
|
|
261
|
+
isStackingContext() {
|
|
262
|
+
return this.relative || this.overflow === "hidden";
|
|
263
|
+
}
|
|
264
|
+
layoutChildren() {
|
|
265
|
+
return this.children ?? [];
|
|
266
|
+
}
|
|
204
267
|
getProps() {
|
|
205
268
|
return {
|
|
206
269
|
x: this.x,
|
|
@@ -214,6 +277,7 @@ export class RectangleElement extends SizedPDFElement {
|
|
|
214
277
|
radius: this.radius,
|
|
215
278
|
sideBorders: this.sideBorders,
|
|
216
279
|
overflow: this.overflow,
|
|
280
|
+
relative: this.relative,
|
|
217
281
|
};
|
|
218
282
|
}
|
|
219
283
|
}
|
|
@@ -35,18 +35,6 @@ interface RowElementParams extends WithChildren {
|
|
|
35
35
|
/** Start everything after this row on a fresh page (CSS `break-after: page`). */
|
|
36
36
|
breakAfter?: boolean;
|
|
37
37
|
}
|
|
38
|
-
/**
|
|
39
|
-
* Horizontal stack: the mirror of `ContainerElement` (Column). Children are laid out
|
|
40
|
-
* left-to-right via the shared `FlexLayoutHelper` on the horizontal axis; fixed children
|
|
41
|
-
* take their natural width, `ExpandedElement`/Spacer children split the leftover width by
|
|
42
|
-
* `flex`, and `gap` is inserted between them. The row fills the width it is offered and
|
|
43
|
-
* shrink-wraps its height to the tallest child (unless a height is forced on it).
|
|
44
|
-
*
|
|
45
|
-
* Cross/main alignment is the next foundation slice; today children sit at the top-left
|
|
46
|
-
* (cross start, main start). The row is atomic w.r.t. pagination - it reflows whole if it
|
|
47
|
-
* does not fit (handled by the parent's `packChildren`); synchronized cell splitting is a
|
|
48
|
-
* Grid/Table concern.
|
|
49
|
-
*/
|
|
50
38
|
export declare class RowElement extends SizedPDFElement {
|
|
51
39
|
private children;
|
|
52
40
|
private gap;
|
|
@@ -62,12 +50,29 @@ export declare class RowElement extends SizedPDFElement {
|
|
|
62
50
|
breaksBefore(): boolean;
|
|
63
51
|
breaksAfter(): boolean;
|
|
64
52
|
relativeSizeFactor(horizontal: boolean): number | undefined;
|
|
53
|
+
maxExtent(horizontal: boolean): number;
|
|
65
54
|
/** The mirror of `ContainerElement`: a Row's OWN flex child needs a bounded width, and the need of any
|
|
66
55
|
* descendant propagates on both axes (see the Column for the reasoning). */
|
|
67
56
|
needsBoundedMain(horizontal: boolean): boolean;
|
|
68
57
|
/** A Row lays out side by side, so widths add up (gaps included) and heights overlap. */
|
|
69
58
|
minIntrinsicMain(horizontal: boolean, ctx: LayoutContext): number;
|
|
70
59
|
calculateLayout(constraints: BoxConstraints, offset: Offset, ctx: LayoutContext): Size;
|
|
60
|
+
protected computeSize(constraints: BoxConstraints, ctx: LayoutContext): Size;
|
|
61
|
+
/** The first element inside this row that asks for a page break by flag, once found (or `null`). */
|
|
62
|
+
private declaredBreak?;
|
|
63
|
+
/**
|
|
64
|
+
* A row is one line: nothing inside it starts a new page. A `breakBefore` / `breakAfter` in a cell
|
|
65
|
+
* (a table row is a Row too) is therefore ignored - say so. A `PageBreak` reports itself.
|
|
66
|
+
*/
|
|
67
|
+
private reportIgnoredBreak;
|
|
68
|
+
/** The one sizing path: `layout` places the children (relative to this box), `measure` only sizes them. */
|
|
69
|
+
private sizeWith;
|
|
70
|
+
private percentPaddingChild?;
|
|
71
|
+
/** A child's `%` padding resolves against this Row's width (CSS: the containing block), which the Row
|
|
72
|
+
* never offers - its children get their natural size - so it is told. Only when a child uses it,
|
|
73
|
+
* since every key below would otherwise change with the Row's width. */
|
|
74
|
+
private childContext;
|
|
75
|
+
layoutChildren(): readonly PDFElement[];
|
|
71
76
|
getProps(): {
|
|
72
77
|
x: number;
|
|
73
78
|
y: number;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { flexibleOf, hasPercentPaddingItem } from "../layout/flex-item.js";
|
|
1
2
|
import { extentSpecs, resolveSize, } from "../layout/box-constraints.js";
|
|
2
|
-
import { FlexLayoutHelper, HORIZONTAL_AXIS } from "../utils/flex-layout.js";
|
|
3
|
+
import { FlexLayoutHelper, HORIZONTAL_AXIS, } from "../utils/flex-layout.js";
|
|
3
4
|
import { stackMinIntrinsic, withDeclaredExtent } from "../layout/min-intrinsic.js";
|
|
4
|
-
import {
|
|
5
|
+
import { diagnose, pageOf } from "../common/diagnostics.js";
|
|
6
|
+
import { SizedPDFElement, withPaddingBase, } from "./pdf-element.js";
|
|
5
7
|
/**
|
|
6
8
|
* Horizontal stack: the mirror of `ContainerElement` (Column). Children are laid out
|
|
7
9
|
* left-to-right via the shared `FlexLayoutHelper` on the horizontal axis; fixed children
|
|
@@ -14,6 +16,8 @@ import { FlexiblePDFElement, SizedPDFElement, } from "./pdf-element.js";
|
|
|
14
16
|
* does not fit (handled by the parent's `packChildren`); synchronized cell splitting is a
|
|
15
17
|
* Grid/Table concern.
|
|
16
18
|
*/
|
|
19
|
+
/** How far a line may run past its box before it is reported, in points (floating-point slack). */
|
|
20
|
+
const WIDE_EPSILON = 0.01;
|
|
17
21
|
export class RowElement extends SizedPDFElement {
|
|
18
22
|
constructor({ children, gap, main, cross, reverse, wrap, alignContent, width, height, breakBefore, breakAfter, ...sizing }) {
|
|
19
23
|
super({ x: 0, y: 0 });
|
|
@@ -37,6 +41,9 @@ export class RowElement extends SizedPDFElement {
|
|
|
37
41
|
relativeSizeFactor(horizontal) {
|
|
38
42
|
return horizontal ? this.requested.widthFactor : this.requested.heightFactor;
|
|
39
43
|
}
|
|
44
|
+
maxExtent(horizontal) {
|
|
45
|
+
return (horizontal ? this.requested.maxWidth : this.requested.maxHeight) ?? Infinity;
|
|
46
|
+
}
|
|
40
47
|
/** The mirror of `ContainerElement`: a Row's OWN flex child needs a bounded width, and the need of any
|
|
41
48
|
* descendant propagates on both axes (see the Column for the reasoning). */
|
|
42
49
|
needsBoundedMain(horizontal) {
|
|
@@ -45,7 +52,7 @@ export class RowElement extends SizedPDFElement {
|
|
|
45
52
|
: [this.requested.height, this.requested.heightFactor];
|
|
46
53
|
if (requested.some((v) => v !== undefined))
|
|
47
54
|
return false;
|
|
48
|
-
const ownFlexChild = horizontal && this.children.some((c) => c
|
|
55
|
+
const ownFlexChild = horizontal && this.children.some((c) => flexibleOf(c) !== undefined);
|
|
49
56
|
return ownFlexChild || this.children.some((c) => c.needsBoundedMain(horizontal));
|
|
50
57
|
}
|
|
51
58
|
/** A Row lays out side by side, so widths add up (gaps included) and heights overlap. */
|
|
@@ -56,6 +63,53 @@ export class RowElement extends SizedPDFElement {
|
|
|
56
63
|
calculateLayout(constraints, offset, ctx) {
|
|
57
64
|
this.x = offset.x;
|
|
58
65
|
this.y = offset.y;
|
|
66
|
+
this.reportIgnoredBreak(ctx);
|
|
67
|
+
const size = this.sizeWith(constraints, ctx, "layout");
|
|
68
|
+
this.width = size.width;
|
|
69
|
+
this.height = size.height;
|
|
70
|
+
return size;
|
|
71
|
+
}
|
|
72
|
+
computeSize(constraints, ctx) {
|
|
73
|
+
return this.sizeWith(constraints, ctx, "measure");
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A row is one line: nothing inside it starts a new page. A `breakBefore` / `breakAfter` in a cell
|
|
77
|
+
* (a table row is a Row too) is therefore ignored - say so. A `PageBreak` reports itself.
|
|
78
|
+
*/
|
|
79
|
+
reportIgnoredBreak(ctx) {
|
|
80
|
+
if (this.declaredBreak === undefined) {
|
|
81
|
+
const find = (el, depth) => {
|
|
82
|
+
if (el.breaksBefore() || el.breaksAfter())
|
|
83
|
+
return el;
|
|
84
|
+
if (depth > 64)
|
|
85
|
+
return null;
|
|
86
|
+
for (const child of el.layoutChildren()) {
|
|
87
|
+
const hit = find(child, depth + 1);
|
|
88
|
+
if (hit)
|
|
89
|
+
return hit;
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
};
|
|
93
|
+
this.declaredBreak = null;
|
|
94
|
+
for (const child of this.layoutChildren()) {
|
|
95
|
+
this.declaredBreak = find(child, 0);
|
|
96
|
+
if (this.declaredBreak)
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (!this.declaredBreak)
|
|
101
|
+
return;
|
|
102
|
+
diagnose(ctx.diagnostics, {
|
|
103
|
+
code: "break-ignored",
|
|
104
|
+
severity: "warning",
|
|
105
|
+
message: "breakBefore / breakAfter inside a Row (or a table row) has no effect: a row is one line and " +
|
|
106
|
+
"never starts a new page. Put the break on the Row itself, or on a child of a Column.",
|
|
107
|
+
about: this.declaredBreak,
|
|
108
|
+
page: pageOf(ctx),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/** The one sizing path: `layout` places the children (relative to this box), `measure` only sizes them. */
|
|
112
|
+
sizeWith(constraints, ctx, mode) {
|
|
59
113
|
// Relative sizing: a pinned extent (fixed or a fraction of the offered box, clamped) wins; else
|
|
60
114
|
// width fills the offered space (flex children split the leftover) and height is the tallest child.
|
|
61
115
|
const specs = extentSpecs(this.requested);
|
|
@@ -75,20 +129,46 @@ export class RowElement extends SizedPDFElement {
|
|
|
75
129
|
// Horizontal stack: main = width (children fill it), cross = height (children can stretch to it).
|
|
76
130
|
const mainAvail = boundedWidth ?? Infinity;
|
|
77
131
|
const crossAvail = boundedHeight ?? Infinity;
|
|
78
|
-
let result = {
|
|
132
|
+
let result = {
|
|
133
|
+
mainUsed: 0,
|
|
134
|
+
crossUsed: 0,
|
|
135
|
+
};
|
|
79
136
|
if (this.children.length > 0) {
|
|
80
|
-
result = FlexLayoutHelper.layout(this.children, HORIZONTAL_AXIS, mainAvail, crossAvail,
|
|
137
|
+
result = FlexLayoutHelper.layout(this.children, HORIZONTAL_AXIS, mainAvail, crossAvail, {
|
|
81
138
|
gap: this.gap,
|
|
82
139
|
main: this.main,
|
|
83
140
|
cross: this.cross,
|
|
84
141
|
reverse: this.reverse,
|
|
85
142
|
wrap: this.wrap,
|
|
86
143
|
alignContent: this.alignContent,
|
|
87
|
-
}, ctx);
|
|
144
|
+
}, this.childContext(ctx, mainAvail), mode);
|
|
145
|
+
}
|
|
146
|
+
const used = result.widestLine ?? result.mainUsed;
|
|
147
|
+
if (mode === "layout" && used > mainAvail + WIDE_EPSILON) {
|
|
148
|
+
diagnose(ctx.diagnostics, {
|
|
149
|
+
code: "overflow-wide",
|
|
150
|
+
severity: "warning",
|
|
151
|
+
message: `A Row's children need ${Math.round(used)}pt but it is ` +
|
|
152
|
+
`${Math.round(mainAvail)}pt wide; they are drawn past its edge. Let them wrap ` +
|
|
153
|
+
'(`breakWord`, `wrap`), make room, or clip with a Box\'s `overflow: "hidden"`.',
|
|
154
|
+
about: this,
|
|
155
|
+
page: pageOf(ctx),
|
|
156
|
+
fallback: "silent",
|
|
157
|
+
});
|
|
88
158
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
159
|
+
return { width: boundedWidth ?? result.mainUsed, height: boundedHeight ?? result.crossUsed };
|
|
160
|
+
}
|
|
161
|
+
/** A child's `%` padding resolves against this Row's width (CSS: the containing block), which the Row
|
|
162
|
+
* never offers - its children get their natural size - so it is told. Only when a child uses it,
|
|
163
|
+
* since every key below would otherwise change with the Row's width. */
|
|
164
|
+
childContext(ctx, mainAvail) {
|
|
165
|
+
this.percentPaddingChild ?? (this.percentPaddingChild = this.children.some(hasPercentPaddingItem));
|
|
166
|
+
if (!this.percentPaddingChild)
|
|
167
|
+
return ctx;
|
|
168
|
+
return withPaddingBase(ctx, Number.isFinite(mainAvail) ? mainAvail : undefined);
|
|
169
|
+
}
|
|
170
|
+
layoutChildren() {
|
|
171
|
+
return this.children;
|
|
92
172
|
}
|
|
93
173
|
getProps() {
|
|
94
174
|
return {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type SvgSize } from "../svg/index.js";
|
|
2
2
|
import { BoxConstraints, Offset, Size, SizingParams } from "../layout/box-constraints.js";
|
|
3
3
|
import { LayoutContext, SizedPDFElement } from "./pdf-element.js";
|
|
4
|
-
/** Markup, a file path (Node only), or the file's bytes. */
|
|
4
|
+
/** Markup, a URL (`http(s):`, `data:`), a file path (Node only), or the file's bytes. */
|
|
5
5
|
export type SvgSource = string | Uint8Array;
|
|
6
6
|
interface SvgElementParams extends SizingParams {
|
|
7
7
|
source: SvgSource;
|
|
@@ -16,26 +16,50 @@ interface SvgElementParams extends SizingParams {
|
|
|
16
16
|
*
|
|
17
17
|
* Unlike a bitmap it needs no decoder, so its intrinsic size is known SYNCHRONOUSLY, in the
|
|
18
18
|
* constructor - which also means a broken file fails on the line that asked for it rather than deep
|
|
19
|
-
* inside a later render, the same bargain `addFont` makes.
|
|
19
|
+
* inside a later render, the same bargain `addFont` makes. An SVG from a URL is the exception: like
|
|
20
|
+
* an image from a URL it is fetched when the document renders (`resolveIntrinsicSize`, or the
|
|
21
|
+
* renderer for a subtree built during layout), and a dead link stops the render naming it.
|
|
20
22
|
*/
|
|
21
23
|
export declare class SvgElement extends SizedPDFElement {
|
|
22
|
-
private source
|
|
23
|
-
private intrinsic
|
|
24
|
+
private source?;
|
|
25
|
+
private intrinsic?;
|
|
26
|
+
private readonly url?;
|
|
27
|
+
private loading?;
|
|
28
|
+
private failed;
|
|
24
29
|
private alt?;
|
|
25
30
|
private requested;
|
|
26
31
|
private sizing;
|
|
27
32
|
private widthFactor?;
|
|
28
33
|
private heightFactor?;
|
|
29
34
|
constructor(params: SvgElementParams);
|
|
35
|
+
/**
|
|
36
|
+
* Parsed on purpose where the source is given: an unreadable file is an error where it was NAMED,
|
|
37
|
+
* not inside a render three call frames later. The whole document is walked, not just its root, so
|
|
38
|
+
* an element outside the subset surfaces here too. A logo parses in well under a millisecond.
|
|
39
|
+
*/
|
|
40
|
+
private parse;
|
|
41
|
+
/**
|
|
42
|
+
* Fetches and parses an SVG from a URL - once per render, however often it is asked. A no-op
|
|
43
|
+
* otherwise. A failure sticks for that render only: `fresh` (a new render begins) asks again.
|
|
44
|
+
*/
|
|
45
|
+
load(fresh?: boolean): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* The pre-layout pass, as for an `ImageElement`: best-effort, so a failure leaves the size unknown
|
|
48
|
+
* and the renderer, which loads again, surfaces the real error.
|
|
49
|
+
*/
|
|
50
|
+
resolveIntrinsicSize(): Promise<void>;
|
|
30
51
|
getProps(): {
|
|
31
52
|
x: number;
|
|
32
53
|
y: number;
|
|
33
54
|
width: number | undefined;
|
|
34
55
|
height: number | undefined;
|
|
35
|
-
source: string;
|
|
36
|
-
intrinsic: SvgSize;
|
|
56
|
+
source: string | undefined;
|
|
57
|
+
intrinsic: SvgSize | undefined;
|
|
37
58
|
alt: string | undefined;
|
|
38
59
|
};
|
|
39
60
|
calculateLayout(constraints: BoxConstraints, offset: Offset, _ctx: LayoutContext): Size;
|
|
61
|
+
protected computeSize(constraints: BoxConstraints): Size;
|
|
62
|
+
/** Its size under these constraints - the one computation both `measure` and layout use. */
|
|
63
|
+
private sizeFor;
|
|
40
64
|
}
|
|
41
65
|
export {};
|