@jasy/pdf 1.0.0-alpha.1 → 1.0.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +35 -21
- package/dist/api/args.d.ts +1 -1
- package/dist/api/args.js +2 -5
- package/dist/api/color.d.ts +4 -4
- package/dist/api/color.js +11 -17
- package/dist/api/content.d.ts +20 -13
- package/dist/api/content.js +44 -29
- package/dist/api/descriptor.d.ts +2 -2
- package/dist/api/descriptor.js +121 -31
- package/dist/api/dimension.d.ts +76 -0
- package/dist/api/dimension.js +43 -0
- package/dist/api/font-url.d.ts +28 -0
- package/dist/api/font-url.js +134 -0
- package/dist/api/forms.d.ts +347 -0
- package/dist/api/forms.js +189 -0
- package/dist/api/gradient.d.ts +53 -0
- package/dist/api/gradient.js +97 -0
- package/dist/api/index.d.ts +13 -8
- package/dist/api/index.js +13 -24
- package/dist/api/insets.d.ts +19 -12
- package/dist/api/insets.js +19 -12
- package/dist/api/layout.d.ts +149 -25
- package/dist/api/layout.js +182 -51
- package/dist/api/page-builder.d.ts +40 -0
- package/dist/api/page-builder.js +44 -0
- package/dist/api/structure.d.ts +107 -13
- package/dist/api/structure.js +187 -88
- package/dist/api/table.d.ts +5 -5
- package/dist/api/table.js +38 -26
- package/dist/api/text.d.ts +90 -4
- package/dist/api/text.js +116 -31
- package/dist/assets/font-data.d.ts +2 -0
- package/dist/assets/font-data.js +21 -0
- package/dist/assets/font-data.ts +37 -0
- package/dist/common/color.js +1 -5
- package/dist/constants/page-sizes.js +3 -6
- package/dist/constants/pdf-parts.js +1 -4
- package/dist/crypto/legacy-handler.d.ts +43 -0
- package/dist/crypto/legacy-handler.js +145 -0
- package/dist/crypto/security-handler.d.ts +62 -0
- package/dist/crypto/security-handler.js +155 -0
- package/dist/crypto/webcrypto.d.ts +11 -0
- package/dist/crypto/webcrypto.js +62 -0
- package/dist/edit/acroform-reader.d.ts +70 -0
- package/dist/edit/acroform-reader.js +126 -0
- package/dist/edit/appearance.d.ts +47 -0
- package/dist/edit/appearance.js +171 -0
- package/dist/edit/document.d.ts +145 -0
- package/dist/edit/document.js +642 -0
- package/dist/edit/fill.d.ts +65 -0
- package/dist/edit/fill.js +424 -0
- package/dist/edit/flatten.d.ts +54 -0
- package/dist/edit/flatten.js +462 -0
- package/dist/edit/index.d.ts +20 -0
- package/dist/edit/index.js +18 -0
- package/dist/edit/lexer.d.ts +30 -0
- package/dist/edit/lexer.js +285 -0
- package/dist/edit/objects.d.ts +68 -0
- package/dist/edit/objects.js +83 -0
- package/dist/edit/writer.d.ts +60 -0
- package/dist/edit/writer.js +283 -0
- package/dist/elements/container-element.d.ts +50 -5
- package/dist/elements/container-element.js +100 -39
- package/dist/elements/forms/checkbox-element.d.ts +51 -0
- package/dist/elements/forms/checkbox-element.js +48 -0
- package/dist/elements/forms/choice-element.d.ts +53 -0
- package/dist/elements/forms/choice-element.js +59 -0
- package/dist/elements/forms/push-button-element.d.ts +56 -0
- package/dist/elements/forms/push-button-element.js +49 -0
- package/dist/elements/forms/radio-element.d.ts +52 -0
- package/dist/elements/forms/radio-element.js +49 -0
- package/dist/elements/forms/signature-element.d.ts +54 -0
- package/dist/elements/forms/signature-element.js +47 -0
- package/dist/elements/forms/text-field-element.d.ts +61 -0
- package/dist/elements/forms/text-field-element.js +54 -0
- package/dist/elements/image-element.d.ts +58 -6
- package/dist/elements/image-element.js +145 -111
- package/dist/elements/index.d.ts +26 -10
- package/dist/elements/index.js +26 -28
- package/dist/elements/layout/anchor-element.d.ts +23 -0
- package/dist/elements/layout/anchor-element.js +27 -0
- package/dist/elements/layout/bookmark-element.d.ts +27 -0
- package/dist/elements/layout/bookmark-element.js +30 -0
- package/dist/elements/layout/default-text-style-element.d.ts +30 -0
- package/dist/elements/layout/default-text-style-element.js +47 -0
- package/dist/elements/layout/deferred-element.d.ts +3 -3
- package/dist/elements/layout/deferred-element.js +4 -8
- package/dist/elements/layout/expanded-element.d.ts +6 -4
- package/dist/elements/layout/expanded-element.js +22 -17
- package/dist/elements/layout/keep-together-element.d.ts +42 -0
- package/dist/elements/layout/keep-together-element.js +85 -0
- package/dist/elements/layout/link-element.d.ts +33 -0
- package/dist/elements/layout/link-element.js +39 -0
- package/dist/elements/layout/padding-element.d.ts +10 -5
- package/dist/elements/layout/padding-element.js +25 -16
- package/dist/elements/layout/page-break-element.d.ts +17 -0
- package/dist/elements/layout/page-break-element.js +24 -0
- package/dist/elements/layout/page-builder-element.d.ts +32 -0
- package/dist/elements/layout/page-builder-element.js +45 -0
- package/dist/elements/layout/positioned-element.d.ts +47 -0
- package/dist/elements/layout/positioned-element.js +73 -0
- package/dist/elements/layout/repeating-header-element.d.ts +3 -3
- package/dist/elements/layout/repeating-header-element.js +8 -12
- package/dist/elements/layout/rotated-box-element.d.ts +35 -0
- package/dist/elements/layout/rotated-box-element.js +54 -0
- package/dist/elements/layout/rotated-element.d.ts +32 -0
- package/dist/elements/layout/rotated-element.js +41 -0
- package/dist/elements/layout/sized-container-element.d.ts +2 -2
- package/dist/elements/layout/sized-container-element.js +6 -11
- package/dist/elements/layout/struct-group.d.ts +28 -0
- package/dist/elements/layout/struct-group.js +42 -0
- package/dist/elements/line-element.d.ts +3 -3
- package/dist/elements/line-element.js +5 -10
- package/dist/elements/page-element.d.ts +26 -6
- package/dist/elements/page-element.js +72 -27
- package/dist/elements/pdf-document-element.d.ts +10 -4
- package/dist/elements/pdf-document-element.js +11 -10
- package/dist/elements/pdf-element.d.ts +150 -4
- package/dist/elements/pdf-element.js +138 -20
- package/dist/elements/rectangle-element.d.ts +52 -11
- package/dist/elements/rectangle-element.js +129 -36
- package/dist/elements/row-element.d.ts +45 -4
- package/dist/elements/row-element.js +66 -18
- package/dist/elements/text-element.d.ts +139 -11
- package/dist/elements/text-element.js +234 -57
- package/dist/forms/acroform.d.ts +63 -0
- package/dist/forms/acroform.js +427 -0
- package/dist/forms/appearance.d.ts +58 -0
- package/dist/forms/appearance.js +204 -0
- package/dist/forms/field.d.ts +164 -0
- package/dist/forms/field.js +1 -0
- package/dist/forms/pdf.d.ts +19 -0
- package/dist/forms/pdf.js +28 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -19
- package/dist/ir/display-list.d.ts +197 -8
- package/dist/ir/display-list.js +8 -2
- package/dist/layout/alignment.d.ts +10 -0
- package/dist/layout/alignment.js +6 -0
- package/dist/layout/box-constraints.d.ts +61 -0
- package/dist/layout/box-constraints.js +88 -6
- package/dist/layout/collect-images.d.ts +9 -0
- package/dist/layout/collect-images.js +34 -0
- package/dist/layout/fragmentation.d.ts +20 -1
- package/dist/layout/fragmentation.js +74 -18
- package/dist/layout/insets.d.ts +28 -0
- package/dist/layout/insets.js +20 -0
- package/dist/platform/browser-fs.d.ts +2 -0
- package/dist/platform/browser-fs.js +9 -0
- package/dist/platform/browser-image.d.ts +5 -0
- package/dist/platform/browser-image.js +13 -0
- package/dist/platform/node-fs.d.ts +2 -0
- package/dist/platform/node-fs.js +10 -0
- package/dist/platform/node-image.d.ts +5 -0
- package/dist/platform/node-image.js +9 -0
- package/dist/renderer/anchor-renderer.d.ts +6 -0
- package/dist/renderer/anchor-renderer.js +11 -0
- package/dist/renderer/bookmark-renderer.d.ts +6 -0
- package/dist/renderer/bookmark-renderer.js +11 -0
- package/dist/renderer/container-renderer.d.ts +3 -3
- package/dist/renderer/container-renderer.js +11 -28
- package/dist/renderer/default-text-style-renderer.d.ts +6 -0
- package/dist/renderer/default-text-style-renderer.js +10 -0
- package/dist/renderer/deferred-renderer.d.ts +3 -3
- package/dist/renderer/deferred-renderer.js +8 -23
- package/dist/renderer/emoji-image.d.ts +9 -0
- package/dist/renderer/emoji-image.js +68 -0
- package/dist/renderer/expanded-renderer.d.ts +3 -3
- package/dist/renderer/expanded-renderer.js +6 -21
- package/dist/renderer/form-field-renderer.d.ts +20 -0
- package/dist/renderer/form-field-renderer.js +12 -0
- package/dist/renderer/image-renderer.d.ts +4 -4
- package/dist/renderer/image-renderer.js +86 -75
- package/dist/renderer/index.d.ts +10 -10
- package/dist/renderer/index.js +10 -26
- package/dist/renderer/keep-together-renderer.d.ts +10 -0
- package/dist/renderer/keep-together-renderer.js +12 -0
- package/dist/renderer/line-renderer.d.ts +3 -3
- package/dist/renderer/line-renderer.js +13 -28
- package/dist/renderer/link-renderer.d.ts +6 -0
- package/dist/renderer/link-renderer.js +11 -0
- package/dist/renderer/padding-renderer.d.ts +3 -3
- package/dist/renderer/padding-renderer.js +6 -21
- package/dist/renderer/page-break-renderer.d.ts +14 -0
- package/dist/renderer/page-break-renderer.js +15 -0
- package/dist/renderer/page-builder-renderer.d.ts +6 -0
- package/dist/renderer/page-builder-renderer.js +11 -0
- package/dist/renderer/page-renderer.d.ts +2 -2
- package/dist/renderer/page-renderer.js +115 -77
- package/dist/renderer/pdf-backend.d.ts +31 -4
- package/dist/renderer/pdf-backend.js +287 -49
- package/dist/renderer/pdf-config.js +4 -7
- package/dist/renderer/pdf-document-class.d.ts +5 -5
- package/dist/renderer/pdf-document-class.js +27 -41
- package/dist/renderer/pdf-document-renderer.d.ts +19 -10
- package/dist/renderer/pdf-document-renderer.js +135 -91
- package/dist/renderer/pdf-renderer.d.ts +2 -2
- package/dist/renderer/pdf-renderer.js +165 -90
- package/dist/renderer/positioned-renderer.d.ts +6 -0
- package/dist/renderer/positioned-renderer.js +10 -0
- package/dist/renderer/rectangle-renderer.d.ts +3 -3
- package/dist/renderer/rectangle-renderer.js +49 -44
- package/dist/renderer/repeating-header-renderer.d.ts +3 -3
- package/dist/renderer/repeating-header-renderer.js +10 -26
- package/dist/renderer/rotated-renderer.d.ts +7 -0
- package/dist/renderer/rotated-renderer.js +29 -0
- package/dist/renderer/row-renderer.d.ts +3 -3
- package/dist/renderer/row-renderer.js +11 -28
- package/dist/renderer/struct-group-renderer.d.ts +10 -0
- package/dist/renderer/struct-group-renderer.js +24 -0
- package/dist/renderer/text-renderer.d.ts +9 -5
- package/dist/renderer/text-renderer.js +437 -89
- package/dist/text/advance.d.ts +34 -0
- package/dist/text/advance.js +45 -0
- package/dist/text/arabic.d.ts +20 -0
- package/dist/text/arabic.js +101 -0
- package/dist/text/bidi.d.ts +33 -0
- package/dist/text/bidi.js +94 -0
- package/dist/text/emoji-codepoints.d.ts +1 -0
- package/dist/text/emoji-codepoints.js +29 -0
- package/dist/text/font-fallback.d.ts +25 -0
- package/dist/text/font-fallback.js +38 -0
- package/dist/text/glyph-coverage.d.ts +15 -0
- package/dist/text/glyph-coverage.js +77 -0
- package/dist/text/line-breaker.d.ts +50 -12
- package/dist/text/line-breaker.js +200 -54
- package/dist/text/line-metrics.d.ts +49 -0
- package/dist/text/line-metrics.js +57 -0
- package/dist/text/orphans-widows.d.ts +27 -0
- package/dist/text/orphans-widows.js +53 -0
- package/dist/text/shape.d.ts +29 -0
- package/dist/text/shape.js +67 -0
- package/dist/text/text-decoration.d.ts +50 -0
- package/dist/text/text-decoration.js +62 -0
- package/dist/text/text-style.d.ts +60 -0
- package/dist/text/text-style.js +79 -0
- package/dist/text/whitespace.d.ts +4 -0
- package/dist/text/whitespace.js +43 -0
- package/dist/utils/afm-parser.d.ts +34 -0
- package/dist/utils/afm-parser.js +76 -17
- package/dist/utils/bytes.d.ts +24 -0
- package/dist/utils/bytes.js +76 -0
- package/dist/utils/dest-registry.d.ts +22 -0
- package/dist/utils/dest-registry.js +32 -0
- package/dist/utils/flex-layout.d.ts +36 -9
- package/dist/utils/flex-layout.js +207 -30
- package/dist/utils/font-metrics.d.ts +26 -1
- package/dist/utils/font-metrics.js +1 -2
- package/dist/utils/font-path.js +3 -6
- package/dist/utils/gsub.d.ts +36 -0
- package/dist/utils/gsub.js +178 -0
- package/dist/utils/image-helper.d.ts +6 -5
- package/dist/utils/image-helper.js +101 -111
- package/dist/utils/inflate.d.ts +16 -0
- package/dist/utils/inflate.js +52 -0
- package/dist/utils/md5.d.ts +4 -0
- package/dist/utils/md5.js +79 -0
- package/dist/utils/outline.d.ts +21 -0
- package/dist/utils/outline.js +79 -0
- package/dist/utils/pdf-object-manager.d.ts +127 -8
- package/dist/utils/pdf-object-manager.js +615 -141
- package/dist/utils/renderer-registry.d.ts +13 -1
- package/dist/utils/renderer-registry.js +23 -6
- package/dist/utils/struct-tree.d.ts +44 -0
- package/dist/utils/struct-tree.js +129 -0
- package/dist/utils/ttf-parser.d.ts +134 -2
- package/dist/utils/ttf-parser.js +873 -50
- package/dist/utils/ttf-subsetter.d.ts +1 -1
- package/dist/utils/ttf-subsetter.js +40 -42
- package/dist/utils/ua-xmp.d.ts +9 -0
- package/dist/utils/ua-xmp.js +32 -0
- package/dist/utils/utf8-to-windows1252-encoder.d.ts +6 -0
- package/dist/utils/utf8-to-windows1252-encoder.js +11 -4
- package/dist/utils/woff.d.ts +10 -0
- package/dist/utils/woff.js +116 -0
- package/dist/validators/element-validator.d.ts +2 -2
- package/dist/validators/element-validator.js +31 -26
- package/package.json +22 -2
package/dist/api/layout.d.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
1
|
+
import { ExpandedElement } from "../elements/layout/expanded-element.js";
|
|
2
|
+
import { PaddingElement } from "../elements/layout/padding-element.js";
|
|
3
|
+
import { PageBreakElement } from "../elements/layout/page-break-element.js";
|
|
4
|
+
import { KeepTogetherElement } from "../elements/layout/keep-together-element.js";
|
|
5
|
+
import { PositionedElement, PositionedInsets } from "../elements/layout/positioned-element.js";
|
|
6
|
+
import { LinkElement } from "../elements/layout/link-element.js";
|
|
7
|
+
import { BookmarkElement } from "../elements/layout/bookmark-element.js";
|
|
8
|
+
import { AnchorElement } from "../elements/layout/anchor-element.js";
|
|
9
|
+
import { RotatedElement } from "../elements/layout/rotated-element.js";
|
|
10
|
+
import { RotatedBoxElement } from "../elements/layout/rotated-box-element.js";
|
|
11
|
+
import { PDFElement } from "../elements/pdf-element.js";
|
|
12
|
+
import { MainAlign, CrossAlign } from "../utils/flex-layout.js";
|
|
13
|
+
import { ColorInput } from "./color.js";
|
|
14
|
+
import { type GradientInput } from "./gradient.js";
|
|
15
|
+
import { Insets } from "./insets.js";
|
|
16
|
+
import { BoundsInput, SizeInput, RadiusInput } from "./dimension.js";
|
|
10
17
|
/** Options shared by the `Column` and `Row` stacks (locked §4). */
|
|
11
|
-
export interface StackOptions {
|
|
18
|
+
export interface StackOptions extends BoundsInput {
|
|
12
19
|
/** Space inserted between children, in points. */
|
|
13
20
|
gap?: number;
|
|
14
21
|
/** Distribution along the main axis (CSS `justify-content`): start (default) · center · end ·
|
|
@@ -16,18 +23,45 @@ export interface StackOptions {
|
|
|
16
23
|
justify?: MainAlign;
|
|
17
24
|
/** Position across the axis (CSS `align-items`): start (default) · center · end · stretch. */
|
|
18
25
|
align?: CrossAlign;
|
|
26
|
+
/** Size on each axis: points (fixed) or a percentage string like `"50%"` (a fraction of the offered
|
|
27
|
+
* space). Omit to fill the offered width / shrink-wrap to the children. A percentage needs a bounded
|
|
28
|
+
* axis (`height: "50%"` only resolves where the parent bounds the height). */
|
|
29
|
+
width?: SizeInput;
|
|
30
|
+
height?: SizeInput;
|
|
31
|
+
/** Start this stack on a fresh page (CSS `break-before: page`, react-pdf's `break`). Ignored at the
|
|
32
|
+
* top of a page. */
|
|
33
|
+
breakBefore?: boolean;
|
|
34
|
+
/** Start everything after this stack on a fresh page (CSS `break-after: page`). */
|
|
35
|
+
breakAfter?: boolean;
|
|
36
|
+
/** Try to keep this stack on one page (CSS `break-inside: avoid`). If it does not fit here but would
|
|
37
|
+
* fit on a fresh page, it moves there whole; if it is taller than a whole page, it splits anyway. */
|
|
38
|
+
keepTogether?: boolean;
|
|
39
|
+
/** Lay the children out backwards along the axis (CSS `row-reverse` / `column-reverse`). */
|
|
40
|
+
reverse?: boolean;
|
|
41
|
+
/** Let the children flow onto further lines when they do not fit (CSS `flex-wrap: wrap`). The `gap`
|
|
42
|
+
* is used BETWEEN the lines as well as between the items. */
|
|
43
|
+
wrap?: boolean;
|
|
44
|
+
/** How the block of wrapped lines sits across the axis (CSS `align-content`). Default `start`. */
|
|
45
|
+
alignContent?: MainAlign;
|
|
19
46
|
}
|
|
20
47
|
/** A vertical stack. `Column(children)` or `Column(opts, children)`. */
|
|
21
|
-
export declare function Column(children: PDFElement[]):
|
|
22
|
-
export declare function Column(opts: StackOptions, children: PDFElement[]):
|
|
48
|
+
export declare function Column(children: PDFElement[]): PDFElement;
|
|
49
|
+
export declare function Column(opts: StackOptions, children: PDFElement[]): PDFElement;
|
|
23
50
|
/** A horizontal stack. `Row(children)` or `Row(opts, children)`. */
|
|
24
|
-
export declare function Row(children: PDFElement[]):
|
|
25
|
-
export declare function Row(opts: StackOptions, children: PDFElement[]):
|
|
51
|
+
export declare function Row(children: PDFElement[]): PDFElement;
|
|
52
|
+
export declare function Row(opts: StackOptions, children: PDFElement[]): PDFElement;
|
|
53
|
+
/**
|
|
54
|
+
* Keep a group of elements on ONE page (CSS `break-inside: avoid`). `keepTogether([...])` stacks the
|
|
55
|
+
* children in a `Column` and refuses to split them across a page break - unless they do not fit on a
|
|
56
|
+
* fresh page at all, in which case they split anyway (so pagination always terminates). Equivalent to
|
|
57
|
+
* the `keepTogether` prop on `Box`/`Column`/`Row`.
|
|
58
|
+
*/
|
|
59
|
+
export declare function keepTogether(children: PDFElement[]): KeepTogetherElement;
|
|
26
60
|
/** A bordered / filled box that wraps its children (locked §4). */
|
|
27
|
-
export interface BoxOptions {
|
|
28
|
-
/** Border (stroke)
|
|
61
|
+
export interface BoxOptions extends BoundsInput {
|
|
62
|
+
/** Border (stroke) color. A box has a border only when `border` or `borderWidth` is set. */
|
|
29
63
|
border?: ColorInput;
|
|
30
|
-
/** Per-side border
|
|
64
|
+
/** Per-side border colors - override/add to `border`. Any of these makes the box draw
|
|
31
65
|
* individual side lines (sharp corners) instead of a uniform frame - this is how you get
|
|
32
66
|
* grid lines (e.g. a cell with only `borderBottom` + `borderRight`). */
|
|
33
67
|
borderTop?: ColorInput;
|
|
@@ -36,33 +70,123 @@ export interface BoxOptions {
|
|
|
36
70
|
borderLeft?: ColorInput;
|
|
37
71
|
/** Border thickness in points (default 1 when a border is present). */
|
|
38
72
|
borderWidth?: number;
|
|
39
|
-
/** Background
|
|
40
|
-
bg?: ColorInput;
|
|
73
|
+
/** Background: a colour, or a gradient from `linearGradient()` / `radialGradient()`. */
|
|
74
|
+
bg?: ColorInput | GradientInput;
|
|
41
75
|
/** Inner padding between the border and the children. */
|
|
42
76
|
padding?: Insets;
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
77
|
+
/** Size on each axis: a number of points (fixed) or a percentage string like `"50%"` (a fraction
|
|
78
|
+
* of the space the parent offers on that axis). Omit `width` to fill the offered width, omit
|
|
79
|
+
* `height` to shrink-wrap the content. A percentage only resolves in a bounded region. */
|
|
80
|
+
width?: SizeInput;
|
|
81
|
+
height?: SizeInput;
|
|
46
82
|
/** Corner radius in points. */
|
|
47
|
-
radius?:
|
|
83
|
+
radius?: RadiusInput;
|
|
84
|
+
/** Make this box a positioning frame: `Positioned` children placed inside it resolve their
|
|
85
|
+
* offsets against this box (CSS `position: relative`). */
|
|
86
|
+
relative?: boolean;
|
|
87
|
+
/** `"hidden"` crops children to the box (rounded corners included); `"visible"` (default) lets a
|
|
88
|
+
* `Positioned` child spill over the edge. */
|
|
89
|
+
overflow?: "hidden" | "visible";
|
|
90
|
+
/** Start this box on a fresh page (CSS `break-before: page`, react-pdf's `break`). Ignored at the top
|
|
91
|
+
* of a page. */
|
|
92
|
+
breakBefore?: boolean;
|
|
93
|
+
/** Start everything after this box on a fresh page (CSS `break-after: page`). */
|
|
94
|
+
breakAfter?: boolean;
|
|
95
|
+
/** Try to keep this box on one page (CSS `break-inside: avoid`). Moves whole to a fresh page if it
|
|
96
|
+
* would fit there; splits anyway if it is taller than a whole page. */
|
|
97
|
+
keepTogether?: boolean;
|
|
48
98
|
}
|
|
49
99
|
/**
|
|
50
100
|
* A box: maps to a `RectangleElement` (fill + border + radius) whose children are stacked
|
|
51
101
|
* inside it, optionally inset by `padding` (a `PaddingElement` wrapping a `Column` of the
|
|
52
102
|
* children). With no `border`/`borderWidth` the box has no outline (`borderWidth` 0).
|
|
53
103
|
*/
|
|
54
|
-
export declare function Box(children: PDFElement[]):
|
|
55
|
-
export declare function Box(opts: BoxOptions, children: PDFElement[]):
|
|
104
|
+
export declare function Box(children: PDFElement[]): PDFElement;
|
|
105
|
+
export declare function Box(opts: BoxOptions, children: PDFElement[]): PDFElement;
|
|
56
106
|
/** Insets a single child by `padding` (a number / `{x,y}` / `{top,…}` / 4-tuple). */
|
|
57
107
|
export declare function Padding(padding: Insets, child: PDFElement): PaddingElement;
|
|
108
|
+
/**
|
|
109
|
+
* Places a child OUT OF FLOW, relative to the nearest enclosing `relative` Box - or, with none, to
|
|
110
|
+
* the page's content box. Two ways, pick per axis: pin to EDGES - `Positioned({ top, left, right,
|
|
111
|
+
* bottom }, child)`, where a negative value pokes into / out of the corner (a badge, a tab, a
|
|
112
|
+
* ribbon) and pinning both sides stretches; or ANCHOR + nudge - `Positioned({ h: "center", v: "end",
|
|
113
|
+
* x: -10, y: -8 }, child)`, i.e. centered / end-aligned with a pixel offset. An edge wins over an
|
|
114
|
+
* anchor on the same axis.
|
|
115
|
+
*
|
|
116
|
+
* A `Positioned` in a `Page`'s `header` or `footer` repeats on EVERY page and takes no space in the
|
|
117
|
+
* band, which is how you draw a watermark, a draft stamp or a corner ribbon across a document. It
|
|
118
|
+
* anchors to the page, not to the band, so `bottom: 0` is the foot of the page.
|
|
119
|
+
*/
|
|
120
|
+
export declare function Positioned(opts: PositionedInsets, child: PDFElement): PositionedElement;
|
|
121
|
+
/**
|
|
122
|
+
* Makes any `child` a clickable hyperlink - the child's whole box is the clickable region (an image, a
|
|
123
|
+
* box, a row). Pass `href` for an external URL, or `to` for an internal jump to an `Anchor({ name })`
|
|
124
|
+
* elsewhere in the document (e.g. a clickable table-of-contents row). Exactly one of the two. The link
|
|
125
|
+
* draws nothing itself, so style the child - e.g. `Link({ href }, Text("jasy.dev", { color: "#1450aa" }))`
|
|
126
|
+
* or `Link({ to: "chapter-2" }, Text("Chapter 2 ....... 5"))`. For a link on part of a line, put `href`/
|
|
127
|
+
* `to` on a `span` instead (`Text([span("Visit "), span("jasy.dev", { href })])`), linking just that run.
|
|
128
|
+
*/
|
|
129
|
+
export declare function Link(opts: {
|
|
130
|
+
href?: string;
|
|
131
|
+
to?: string;
|
|
132
|
+
}, child: PDFElement): LinkElement;
|
|
133
|
+
/**
|
|
134
|
+
* Marks `child` as a named jump target that an internal `Link({ to: name })` can point at (a table of
|
|
135
|
+
* contents linking to sections, cross-references). Layout-transparent: `child` renders exactly as it
|
|
136
|
+
* would on its own, on whatever page it lands on. `name` must match the link's `to`.
|
|
137
|
+
* `Anchor({ name: "chapter-2" }, Text("Chapter 2", { size: 24 }))`.
|
|
138
|
+
*/
|
|
139
|
+
export declare function Anchor(opts: {
|
|
140
|
+
name: string;
|
|
141
|
+
}, child: PDFElement): AnchorElement;
|
|
142
|
+
/**
|
|
143
|
+
* Adds a bookmark to the document outline (the viewer's sidebar) that jumps to `child`. `title` is the
|
|
144
|
+
* label; `level` (1-based, default 1) nests it - a `level: 2` bookmark hangs under the nearest preceding
|
|
145
|
+
* `level: 1`, so you get a collapsible tree (chapters -> sections). It is layout-transparent: `child`
|
|
146
|
+
* renders exactly as it would on its own. `Bookmark({ title: "Chapter 2", level: 1 }, Text("Chapter 2"))`.
|
|
147
|
+
*/
|
|
148
|
+
export declare function Bookmark(opts: {
|
|
149
|
+
title: string;
|
|
150
|
+
level?: number;
|
|
151
|
+
}, child: PDFElement): BookmarkElement;
|
|
152
|
+
/**
|
|
153
|
+
* Rotates `child` at PAINT time by `angle` degrees (clockwise), around its center - like CSS
|
|
154
|
+
* `transform: rotate()` / Flutter `Transform.rotate`. The child keeps its normal, unrotated layout box,
|
|
155
|
+
* so siblings do NOT reflow around the spun shape and the drawing may overflow its slot. Pair it with a
|
|
156
|
+
* `relative` Box + `Positioned` for a diagonal watermark or a "PAID" stamp laid over a document.
|
|
157
|
+
*/
|
|
158
|
+
export declare function Rotated(opts: {
|
|
159
|
+
angle: number;
|
|
160
|
+
}, child: PDFElement): RotatedElement;
|
|
161
|
+
/**
|
|
162
|
+
* Rotates `child` by whole quarter-turns and, unlike `Rotated`, is LAYOUT-AWARE: a 90 / 270 turn swaps
|
|
163
|
+
* the box's width and height so siblings reflow around it (a tall label becomes a narrow, tall strip
|
|
164
|
+
* that reserves exactly that footprint). `turns` = clockwise 90-degree steps (1 = 90, 2 = 180, 3 = 270).
|
|
165
|
+
* Use it for a vertical label beside a table; use `Rotated` for a free-angle stamp / watermark.
|
|
166
|
+
*/
|
|
167
|
+
export declare function RotatedBox(opts: {
|
|
168
|
+
turns: number;
|
|
169
|
+
}, child: PDFElement): RotatedBoxElement;
|
|
58
170
|
/**
|
|
59
171
|
* A flexible empty gap that pushes its siblings apart - `Row([a, Spacer(), b])` sends `a`
|
|
60
172
|
* and `b` to the edges. `flex` weights it against other flex children (default 1).
|
|
61
173
|
*/
|
|
62
174
|
export declare function Spacer(flex?: number): ExpandedElement;
|
|
175
|
+
/**
|
|
176
|
+
* A forced page break. Put it in a `Column` (or any vertical flow) and everything AFTER it starts on
|
|
177
|
+
* a fresh page, no matter how much space is left: `Column([intro, PageBreak(), chapterTwo])`. It takes
|
|
178
|
+
* no space and draws nothing. Works nested, and a break wins over `keepTogether`.
|
|
179
|
+
*/
|
|
180
|
+
export declare function PageBreak(): PageBreakElement;
|
|
63
181
|
export interface ExpandedOptions {
|
|
64
182
|
/** Share of the leftover space vs other flex children (default 1). */
|
|
65
183
|
flex?: number;
|
|
184
|
+
/**
|
|
185
|
+
* Main-axis size reserved BEFORE the leftover is shared out (CSS `flex-basis`): points, or a
|
|
186
|
+
* percentage of what the line offers its items. The child ends up with `basis + its share of the
|
|
187
|
+
* rest`, so `flexBasis: 120` with `flex: 0` is simply a fixed 120pt slot. Default 0.
|
|
188
|
+
*/
|
|
189
|
+
flexBasis?: SizeInput;
|
|
66
190
|
}
|
|
67
191
|
/**
|
|
68
192
|
* Makes a child fill the leftover space along the stack's main axis (height in a Column,
|
package/dist/api/layout.js
CHANGED
|
@@ -1,74 +1,123 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import { ContainerElement } from "../elements/container-element.js";
|
|
2
|
+
import { RowElement } from "../elements/row-element.js";
|
|
3
|
+
import { RectangleElement } from "../elements/rectangle-element.js";
|
|
4
|
+
import { ExpandedElement } from "../elements/layout/expanded-element.js";
|
|
5
|
+
import { PaddingElement } from "../elements/layout/padding-element.js";
|
|
6
|
+
import { PageBreakElement } from "../elements/layout/page-break-element.js";
|
|
7
|
+
import { KeepTogetherElement } from "../elements/layout/keep-together-element.js";
|
|
8
|
+
import { PositionedElement } from "../elements/layout/positioned-element.js";
|
|
9
|
+
import { LinkElement } from "../elements/layout/link-element.js";
|
|
10
|
+
import { BookmarkElement } from "../elements/layout/bookmark-element.js";
|
|
11
|
+
import { AnchorElement } from "../elements/layout/anchor-element.js";
|
|
12
|
+
import { RotatedElement } from "../elements/layout/rotated-element.js";
|
|
13
|
+
import { RotatedBoxElement } from "../elements/layout/rotated-box-element.js";
|
|
14
|
+
import { toColor } from "./color.js";
|
|
15
|
+
import { isGradientInput } from "./gradient.js";
|
|
16
|
+
import { toEdges } from "./insets.js";
|
|
17
|
+
import { toBounds, toDimension, toRadius, } from "./dimension.js";
|
|
18
|
+
import { splitArgs } from "./args.js";
|
|
19
|
+
/** Splits `StackOptions` width/height into the fixed points + fraction the stack elements expect. */
|
|
20
|
+
function stackSize(opts) {
|
|
21
|
+
const w = opts.width !== undefined ? toDimension(opts.width) : undefined;
|
|
22
|
+
const h = opts.height !== undefined ? toDimension(opts.height) : undefined;
|
|
23
|
+
return {
|
|
24
|
+
width: w?.points,
|
|
25
|
+
height: h?.points,
|
|
26
|
+
widthFactor: w?.factor,
|
|
27
|
+
heightFactor: h?.factor,
|
|
28
|
+
...toBounds(opts),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
17
31
|
// The public default for `cross` is `start` (locked §5) - i.e. don't stretch a child unless
|
|
18
32
|
// asked. The engine default is `stretch`; the factory sets the friendlier public one.
|
|
19
33
|
const DEFAULT_CROSS = "start";
|
|
20
|
-
function Column(a, b) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return new container_element_1.ContainerElement({
|
|
34
|
+
export function Column(a, b) {
|
|
35
|
+
const { opts, children } = splitArgs(a, b);
|
|
36
|
+
return maybeKeepTogether(opts, new ContainerElement({
|
|
24
37
|
x: 0,
|
|
25
38
|
y: 0,
|
|
26
39
|
children,
|
|
27
40
|
gap: opts.gap,
|
|
28
41
|
main: opts.justify, // undefined → engine default `start` (matches §5)
|
|
29
|
-
cross:
|
|
30
|
-
|
|
42
|
+
cross: opts.align ?? DEFAULT_CROSS,
|
|
43
|
+
reverse: opts.reverse,
|
|
44
|
+
wrap: opts.wrap,
|
|
45
|
+
alignContent: opts.alignContent,
|
|
46
|
+
breakBefore: opts.breakBefore,
|
|
47
|
+
breakAfter: opts.breakAfter,
|
|
48
|
+
...stackSize(opts),
|
|
49
|
+
}));
|
|
31
50
|
}
|
|
32
|
-
function Row(a, b) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return new row_element_1.RowElement({
|
|
51
|
+
export function Row(a, b) {
|
|
52
|
+
const { opts, children } = splitArgs(a, b);
|
|
53
|
+
return maybeKeepTogether(opts, new RowElement({
|
|
36
54
|
children,
|
|
37
55
|
gap: opts.gap,
|
|
38
56
|
main: opts.justify,
|
|
39
|
-
cross:
|
|
40
|
-
|
|
57
|
+
cross: opts.align ?? DEFAULT_CROSS,
|
|
58
|
+
reverse: opts.reverse,
|
|
59
|
+
wrap: opts.wrap,
|
|
60
|
+
alignContent: opts.alignContent,
|
|
61
|
+
breakBefore: opts.breakBefore,
|
|
62
|
+
breakAfter: opts.breakAfter,
|
|
63
|
+
...stackSize(opts),
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
/** Wraps `element` in a `keepTogether` group when the `keepTogether` option is set; otherwise returns it
|
|
67
|
+
* unchanged (byte-identical). Shared by the `Box`/`Column`/`Row` prop shortcut. */
|
|
68
|
+
function maybeKeepTogether(opts, element) {
|
|
69
|
+
// alignSelf and order go on the OUTERMOST element - that is the one the surrounding stack places.
|
|
70
|
+
const wrapped = opts.keepTogether ? new KeepTogetherElement({ child: element }) : element;
|
|
71
|
+
return wrapped
|
|
72
|
+
.withAlignSelf(opts.alignSelf)
|
|
73
|
+
.withOrder(opts.order)
|
|
74
|
+
.withFlexShrink(opts.flexShrink);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Keep a group of elements on ONE page (CSS `break-inside: avoid`). `keepTogether([...])` stacks the
|
|
78
|
+
* children in a `Column` and refuses to split them across a page break - unless they do not fit on a
|
|
79
|
+
* fresh page at all, in which case they split anyway (so pagination always terminates). Equivalent to
|
|
80
|
+
* the `keepTogether` prop on `Box`/`Column`/`Row`.
|
|
81
|
+
*/
|
|
82
|
+
export function keepTogether(children) {
|
|
83
|
+
const child = children.length === 1 ? children[0] : Column(children);
|
|
84
|
+
return new KeepTogetherElement({ child });
|
|
41
85
|
}
|
|
42
|
-
function Box(a, b) {
|
|
43
|
-
|
|
44
|
-
const { opts, children } = (0, args_1.splitArgs)(a, b);
|
|
86
|
+
export function Box(a, b) {
|
|
87
|
+
const { opts, children } = splitArgs(a, b);
|
|
45
88
|
const content = opts.padding !== undefined && children.length > 0
|
|
46
89
|
? [
|
|
47
|
-
new
|
|
48
|
-
margin:
|
|
90
|
+
new PaddingElement({
|
|
91
|
+
margin: toEdges(opts.padding),
|
|
49
92
|
child: children.length === 1 ? children[0] : Column(children),
|
|
50
93
|
}),
|
|
51
94
|
]
|
|
52
95
|
: children;
|
|
53
96
|
// A side is set if it (or the uniform `border`) is given. If ANY differs from a plain
|
|
54
|
-
// uniform border, we hand the engine per-side
|
|
97
|
+
// uniform border, we hand the engine per-side colors (which draws individual lines).
|
|
55
98
|
const sideKeys = [opts.borderTop, opts.borderRight, opts.borderBottom, opts.borderLeft];
|
|
56
99
|
const hasPerSide = sideKeys.some((s) => s !== undefined);
|
|
57
100
|
const side = (s) => {
|
|
58
|
-
const c = s
|
|
59
|
-
return c !== undefined ?
|
|
101
|
+
const c = s ?? opts.border;
|
|
102
|
+
return c !== undefined ? toColor(c) : undefined;
|
|
60
103
|
};
|
|
61
104
|
const hasBorder = opts.border !== undefined || opts.borderWidth !== undefined || hasPerSide;
|
|
62
|
-
|
|
105
|
+
// A point size fills `width`/`height`; a percentage fills `widthFactor`/`heightFactor`.
|
|
106
|
+
const w = opts.width !== undefined ? toDimension(opts.width) : undefined;
|
|
107
|
+
const h = opts.height !== undefined ? toDimension(opts.height) : undefined;
|
|
108
|
+
return maybeKeepTogether(opts, new RectangleElement({
|
|
63
109
|
x: 0,
|
|
64
110
|
y: 0,
|
|
65
111
|
children: content,
|
|
66
|
-
color: opts.border !== undefined ?
|
|
67
|
-
backgroundColor: opts.bg
|
|
68
|
-
borderWidth: hasBorder ? (
|
|
69
|
-
width:
|
|
70
|
-
height:
|
|
71
|
-
|
|
112
|
+
color: opts.border !== undefined ? toColor(opts.border) : undefined,
|
|
113
|
+
backgroundColor: opts.bg === undefined ? undefined : isGradientInput(opts.bg) ? opts.bg : toColor(opts.bg),
|
|
114
|
+
borderWidth: hasBorder ? (opts.borderWidth ?? 1) : 0,
|
|
115
|
+
width: w?.points,
|
|
116
|
+
height: h?.points,
|
|
117
|
+
widthFactor: w?.factor,
|
|
118
|
+
heightFactor: h?.factor,
|
|
119
|
+
...toBounds(opts),
|
|
120
|
+
radius: opts.radius !== undefined ? toRadius(opts.radius) : undefined,
|
|
72
121
|
sideBorders: hasPerSide
|
|
73
122
|
? {
|
|
74
123
|
top: side(opts.borderTop),
|
|
@@ -77,23 +126,105 @@ function Box(a, b) {
|
|
|
77
126
|
left: side(opts.borderLeft),
|
|
78
127
|
}
|
|
79
128
|
: undefined,
|
|
80
|
-
|
|
129
|
+
relative: opts.relative,
|
|
130
|
+
overflow: opts.overflow,
|
|
131
|
+
breakBefore: opts.breakBefore,
|
|
132
|
+
breakAfter: opts.breakAfter,
|
|
133
|
+
}));
|
|
81
134
|
}
|
|
82
135
|
/** Insets a single child by `padding` (a number / `{x,y}` / `{top,…}` / 4-tuple). */
|
|
83
|
-
function Padding(padding, child) {
|
|
84
|
-
return new
|
|
136
|
+
export function Padding(padding, child) {
|
|
137
|
+
return new PaddingElement({ margin: toEdges(padding), child });
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Places a child OUT OF FLOW, relative to the nearest enclosing `relative` Box - or, with none, to
|
|
141
|
+
* the page's content box. Two ways, pick per axis: pin to EDGES - `Positioned({ top, left, right,
|
|
142
|
+
* bottom }, child)`, where a negative value pokes into / out of the corner (a badge, a tab, a
|
|
143
|
+
* ribbon) and pinning both sides stretches; or ANCHOR + nudge - `Positioned({ h: "center", v: "end",
|
|
144
|
+
* x: -10, y: -8 }, child)`, i.e. centered / end-aligned with a pixel offset. An edge wins over an
|
|
145
|
+
* anchor on the same axis.
|
|
146
|
+
*
|
|
147
|
+
* A `Positioned` in a `Page`'s `header` or `footer` repeats on EVERY page and takes no space in the
|
|
148
|
+
* band, which is how you draw a watermark, a draft stamp or a corner ribbon across a document. It
|
|
149
|
+
* anchors to the page, not to the band, so `bottom: 0` is the foot of the page.
|
|
150
|
+
*/
|
|
151
|
+
export function Positioned(opts, child) {
|
|
152
|
+
return new PositionedElement({ child, ...opts });
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Makes any `child` a clickable hyperlink - the child's whole box is the clickable region (an image, a
|
|
156
|
+
* box, a row). Pass `href` for an external URL, or `to` for an internal jump to an `Anchor({ name })`
|
|
157
|
+
* elsewhere in the document (e.g. a clickable table-of-contents row). Exactly one of the two. The link
|
|
158
|
+
* draws nothing itself, so style the child - e.g. `Link({ href }, Text("jasy.dev", { color: "#1450aa" }))`
|
|
159
|
+
* or `Link({ to: "chapter-2" }, Text("Chapter 2 ....... 5"))`. For a link on part of a line, put `href`/
|
|
160
|
+
* `to` on a `span` instead (`Text([span("Visit "), span("jasy.dev", { href })])`), linking just that run.
|
|
161
|
+
*/
|
|
162
|
+
export function Link(opts, child) {
|
|
163
|
+
if ((opts.href === undefined) === (opts.to === undefined)) {
|
|
164
|
+
throw new Error("Link needs exactly one of `href` (external URL) or `to` (internal Anchor name).");
|
|
165
|
+
}
|
|
166
|
+
return new LinkElement({ href: opts.href, dest: opts.to, child });
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Marks `child` as a named jump target that an internal `Link({ to: name })` can point at (a table of
|
|
170
|
+
* contents linking to sections, cross-references). Layout-transparent: `child` renders exactly as it
|
|
171
|
+
* would on its own, on whatever page it lands on. `name` must match the link's `to`.
|
|
172
|
+
* `Anchor({ name: "chapter-2" }, Text("Chapter 2", { size: 24 }))`.
|
|
173
|
+
*/
|
|
174
|
+
export function Anchor(opts, child) {
|
|
175
|
+
return new AnchorElement({ name: opts.name, child });
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Adds a bookmark to the document outline (the viewer's sidebar) that jumps to `child`. `title` is the
|
|
179
|
+
* label; `level` (1-based, default 1) nests it - a `level: 2` bookmark hangs under the nearest preceding
|
|
180
|
+
* `level: 1`, so you get a collapsible tree (chapters -> sections). It is layout-transparent: `child`
|
|
181
|
+
* renders exactly as it would on its own. `Bookmark({ title: "Chapter 2", level: 1 }, Text("Chapter 2"))`.
|
|
182
|
+
*/
|
|
183
|
+
export function Bookmark(opts, child) {
|
|
184
|
+
return new BookmarkElement({ title: opts.title, level: opts.level, child });
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Rotates `child` at PAINT time by `angle` degrees (clockwise), around its center - like CSS
|
|
188
|
+
* `transform: rotate()` / Flutter `Transform.rotate`. The child keeps its normal, unrotated layout box,
|
|
189
|
+
* so siblings do NOT reflow around the spun shape and the drawing may overflow its slot. Pair it with a
|
|
190
|
+
* `relative` Box + `Positioned` for a diagonal watermark or a "PAID" stamp laid over a document.
|
|
191
|
+
*/
|
|
192
|
+
export function Rotated(opts, child) {
|
|
193
|
+
return new RotatedElement({ angle: opts.angle, child });
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Rotates `child` by whole quarter-turns and, unlike `Rotated`, is LAYOUT-AWARE: a 90 / 270 turn swaps
|
|
197
|
+
* the box's width and height so siblings reflow around it (a tall label becomes a narrow, tall strip
|
|
198
|
+
* that reserves exactly that footprint). `turns` = clockwise 90-degree steps (1 = 90, 2 = 180, 3 = 270).
|
|
199
|
+
* Use it for a vertical label beside a table; use `Rotated` for a free-angle stamp / watermark.
|
|
200
|
+
*/
|
|
201
|
+
export function RotatedBox(opts, child) {
|
|
202
|
+
return new RotatedBoxElement({ turns: opts.turns, child });
|
|
85
203
|
}
|
|
86
204
|
/**
|
|
87
205
|
* A flexible empty gap that pushes its siblings apart - `Row([a, Spacer(), b])` sends `a`
|
|
88
206
|
* and `b` to the edges. `flex` weights it against other flex children (default 1).
|
|
89
207
|
*/
|
|
90
|
-
function Spacer(flex = 1) {
|
|
91
|
-
return new
|
|
208
|
+
export function Spacer(flex = 1) {
|
|
209
|
+
return new ExpandedElement({ flex, child: Column([]) });
|
|
92
210
|
}
|
|
93
|
-
|
|
94
|
-
|
|
211
|
+
/**
|
|
212
|
+
* A forced page break. Put it in a `Column` (or any vertical flow) and everything AFTER it starts on
|
|
213
|
+
* a fresh page, no matter how much space is left: `Column([intro, PageBreak(), chapterTwo])`. It takes
|
|
214
|
+
* no space and draws nothing. Works nested, and a break wins over `keepTogether`.
|
|
215
|
+
*/
|
|
216
|
+
export function PageBreak() {
|
|
217
|
+
return new PageBreakElement();
|
|
218
|
+
}
|
|
219
|
+
export function Expanded(a, b) {
|
|
95
220
|
const isOptsForm = b !== undefined;
|
|
96
221
|
const opts = (isOptsForm ? a : {});
|
|
97
222
|
const child = (isOptsForm ? b : a);
|
|
98
|
-
|
|
223
|
+
const basis = opts.flexBasis !== undefined ? toDimension(opts.flexBasis) : undefined;
|
|
224
|
+
return new ExpandedElement({
|
|
225
|
+
flex: opts.flex ?? 1,
|
|
226
|
+
basis: basis?.points,
|
|
227
|
+
basisFactor: basis?.factor,
|
|
228
|
+
child,
|
|
229
|
+
});
|
|
99
230
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { PageBuilderElement } from "../elements/layout/page-builder-element.js";
|
|
2
|
+
import { PageInfo, PDFElement } from "../elements/pdf-element.js";
|
|
3
|
+
import { TextOptions } from "./text.js";
|
|
4
|
+
export type { PageInfo };
|
|
5
|
+
/**
|
|
6
|
+
* Builds content from the page it ends up on - this is how you show `pageNumber` / `pageCount`. Place it
|
|
7
|
+
* anywhere: in a `Page`'s `header`/`footer`, in the body, in a table cell, several times on one page.
|
|
8
|
+
* Because you write the closure, formatting and conditions are yours:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* PageBuilder(({ pageNumber, pageCount }) => Text(`Seite ${pageNumber} von ${pageCount}`))
|
|
12
|
+
* PageBuilder(({ pageNumber }) => (pageNumber === 1 ? Logo() : Text("Fortsetzung")))
|
|
13
|
+
* PageBuilder(({ pageNumber, pageCount }) => Text(`${pageNumber - 1} / ${pageCount - 1}`)) // cover page
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* `pageNumber` is 1-based and counts PHYSICAL pages (an overflowing `Page` contributes several);
|
|
17
|
+
* `pageCount` is the document total; `pageSize` is the media box in points.
|
|
18
|
+
*
|
|
19
|
+
* `subPageNumber` / `subPageTotalPages` are the same counts WITHIN one logical `Page` element - what you
|
|
20
|
+
* want when a document is several sections and the footer should say "Attachment, page 1 of 4" beside
|
|
21
|
+
* "sheet 4 of 7". With a single `Page` they are identical to the document counts.
|
|
22
|
+
*
|
|
23
|
+
* The numbers themselves are always exact. Two sizing caveats, both from the same chicken-and-egg (the
|
|
24
|
+
* content decides the count that the content displays): in the flowing BODY the box is reserved before the
|
|
25
|
+
* total is known, so a much wider final string can paint slightly past it; and a conditional header may
|
|
26
|
+
* SHRINK on later pages but must not GROW, because the body band was measured against the first build.
|
|
27
|
+
*/
|
|
28
|
+
export declare function PageBuilder(build: (info: PageInfo) => PDFElement): PageBuilderElement;
|
|
29
|
+
/** `Text` options plus an `offset` added to the number (e.g. `-1` to not count a cover page). */
|
|
30
|
+
export interface PageNumberOptions extends TextOptions {
|
|
31
|
+
offset?: number;
|
|
32
|
+
}
|
|
33
|
+
/** The current page number as text. Sugar for `PageBuilder` - same thing, one word. */
|
|
34
|
+
export declare function PageNumber({ offset, ...style }?: PageNumberOptions): PageBuilderElement;
|
|
35
|
+
/** The document's total page count as text. Sugar for `PageBuilder`. */
|
|
36
|
+
export declare function PageCount({ offset, ...style }?: PageNumberOptions): PageBuilderElement;
|
|
37
|
+
/** The page number WITHIN its logical `Page` (a section), as text. Sugar for `PageBuilder`. */
|
|
38
|
+
export declare function SubPageNumber({ offset, ...style }?: PageNumberOptions): PageBuilderElement;
|
|
39
|
+
/** How many pages the surrounding logical `Page` produced, as text. Sugar for `PageBuilder`. */
|
|
40
|
+
export declare function SubPageCount({ offset, ...style }?: PageNumberOptions): PageBuilderElement;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { PageBuilderElement } from "../elements/layout/page-builder-element.js";
|
|
2
|
+
import { Text } from "./text.js";
|
|
3
|
+
/**
|
|
4
|
+
* Builds content from the page it ends up on - this is how you show `pageNumber` / `pageCount`. Place it
|
|
5
|
+
* anywhere: in a `Page`'s `header`/`footer`, in the body, in a table cell, several times on one page.
|
|
6
|
+
* Because you write the closure, formatting and conditions are yours:
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* PageBuilder(({ pageNumber, pageCount }) => Text(`Seite ${pageNumber} von ${pageCount}`))
|
|
10
|
+
* PageBuilder(({ pageNumber }) => (pageNumber === 1 ? Logo() : Text("Fortsetzung")))
|
|
11
|
+
* PageBuilder(({ pageNumber, pageCount }) => Text(`${pageNumber - 1} / ${pageCount - 1}`)) // cover page
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* `pageNumber` is 1-based and counts PHYSICAL pages (an overflowing `Page` contributes several);
|
|
15
|
+
* `pageCount` is the document total; `pageSize` is the media box in points.
|
|
16
|
+
*
|
|
17
|
+
* `subPageNumber` / `subPageTotalPages` are the same counts WITHIN one logical `Page` element - what you
|
|
18
|
+
* want when a document is several sections and the footer should say "Attachment, page 1 of 4" beside
|
|
19
|
+
* "sheet 4 of 7". With a single `Page` they are identical to the document counts.
|
|
20
|
+
*
|
|
21
|
+
* The numbers themselves are always exact. Two sizing caveats, both from the same chicken-and-egg (the
|
|
22
|
+
* content decides the count that the content displays): in the flowing BODY the box is reserved before the
|
|
23
|
+
* total is known, so a much wider final string can paint slightly past it; and a conditional header may
|
|
24
|
+
* SHRINK on later pages but must not GROW, because the body band was measured against the first build.
|
|
25
|
+
*/
|
|
26
|
+
export function PageBuilder(build) {
|
|
27
|
+
return new PageBuilderElement({ build });
|
|
28
|
+
}
|
|
29
|
+
/** The current page number as text. Sugar for `PageBuilder` - same thing, one word. */
|
|
30
|
+
export function PageNumber({ offset = 0, ...style } = {}) {
|
|
31
|
+
return PageBuilder(({ pageNumber }) => Text(String(pageNumber + offset), style));
|
|
32
|
+
}
|
|
33
|
+
/** The document's total page count as text. Sugar for `PageBuilder`. */
|
|
34
|
+
export function PageCount({ offset = 0, ...style } = {}) {
|
|
35
|
+
return PageBuilder(({ pageCount }) => Text(String(pageCount + offset), style));
|
|
36
|
+
}
|
|
37
|
+
/** The page number WITHIN its logical `Page` (a section), as text. Sugar for `PageBuilder`. */
|
|
38
|
+
export function SubPageNumber({ offset = 0, ...style } = {}) {
|
|
39
|
+
return PageBuilder(({ subPageNumber }) => Text(String(subPageNumber + offset), style));
|
|
40
|
+
}
|
|
41
|
+
/** How many pages the surrounding logical `Page` produced, as text. Sugar for `PageBuilder`. */
|
|
42
|
+
export function SubPageCount({ offset = 0, ...style } = {}) {
|
|
43
|
+
return PageBuilder(({ subPageTotalPages }) => Text(String(subPageTotalPages + offset), style));
|
|
44
|
+
}
|