pagyra-js 0.0.21 → 0.0.23
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/README.md +283 -264
- package/dist/browser/pagyra.min.js +30 -30
- package/dist/browser/pagyra.min.js.map +4 -4
- package/dist/src/css/apply-declarations.js +2 -1
- package/dist/src/css/clip-path-types.d.ts +9 -1
- package/dist/src/css/compute-style/overrides.js +10 -1
- package/dist/src/css/parsers/clip-path-parser.js +51 -0
- package/dist/src/css/parsers/register-parsers.js +21 -0
- package/dist/src/css/properties/visual.d.ts +2 -0
- package/dist/src/css/style.d.ts +5 -0
- package/dist/src/css/style.js +3 -0
- package/dist/src/css/ua-defaults/element-defaults.js +13 -0
- package/dist/src/dom/node.d.ts +2 -0
- package/dist/src/dom/node.js +1 -0
- package/dist/src/fonts/woff2/decoder.d.ts +1 -9
- package/dist/src/fonts/woff2/decoder.js +6 -565
- package/dist/src/fonts/woff2/glyf-reconstructor.d.ts +54 -0
- package/dist/src/fonts/woff2/glyf-reconstructor.js +357 -0
- package/dist/src/fonts/woff2/hmtx-reconstructor.d.ts +5 -0
- package/dist/src/fonts/woff2/hmtx-reconstructor.js +42 -0
- package/dist/src/fonts/woff2/sfnt-builder.d.ts +7 -0
- package/dist/src/fonts/woff2/sfnt-builder.js +55 -0
- package/dist/src/fonts/woff2/utils.d.ts +12 -0
- package/dist/src/fonts/woff2/utils.js +111 -0
- package/dist/src/html-to-pdf/render-finalize.js +5 -1
- package/dist/src/layout/inline/run-placer.js +1 -1
- package/dist/src/layout/strategies/flex/alignment.d.ts +10 -0
- package/dist/src/layout/strategies/flex/alignment.js +91 -0
- package/dist/src/layout/strategies/flex/distributor.d.ts +5 -0
- package/dist/src/layout/strategies/flex/distributor.js +56 -0
- package/dist/src/layout/strategies/flex/line-builder.d.ts +5 -0
- package/dist/src/layout/strategies/flex/line-builder.js +55 -0
- package/dist/src/layout/strategies/flex/types.d.ts +27 -0
- package/dist/src/layout/strategies/flex/types.js +2 -0
- package/dist/src/layout/strategies/flex/utils.d.ts +12 -0
- package/dist/src/layout/strategies/flex/utils.js +113 -0
- package/dist/src/layout/strategies/flex.js +4 -308
- package/dist/src/layout/strategies/grid.js +0 -3
- package/dist/src/layout/strategies/table.js +85 -58
- package/dist/src/layout/utils/text-metrics.js +16 -8
- package/dist/src/pdf/font/embedder.js +3 -3
- package/dist/src/pdf/font/font-subset.js +1 -3
- package/dist/src/pdf/font/to-unicode.js +16 -16
- package/dist/src/pdf/layout-tree-builder.js +15 -9
- package/dist/src/pdf/renderer/box-painter.js +74 -9
- package/dist/src/pdf/renderers/text-renderer.d.ts +4 -2
- package/dist/src/pdf/renderers/text-renderer.js +52 -2
- package/dist/src/pdf/types.d.ts +16 -1
- package/dist/src/pdf/utils/clip-path-resolver.js +28 -12
- package/dist/src/pdf/utils/mask-resolver.d.ts +7 -0
- package/dist/src/pdf/utils/mask-resolver.js +25 -0
- package/dist/src/pdf/utils/node-text-run-factory.d.ts +2 -1
- package/dist/src/pdf/utils/node-text-run-factory.js +5 -26
- package/dist/src/pdf/utils/rounded-rect-to-path.d.ts +7 -0
- package/dist/src/pdf/utils/rounded-rect-to-path.js +86 -0
- package/dist/src/render/offset.d.ts +5 -0
- package/dist/src/render/offset.js +93 -9
- package/dist/src/text/line-breaker.js +31 -0
- package/dist/tests/css/clip-path-parser.spec.js +15 -8
- package/dist/tests/environment/path-resolution.spec.js +2 -1
- package/dist/tests/helpers/ai-layout-diagnostics.js +6 -6
- package/dist/tests/layout/container-query-units.spec.js +0 -7
- package/dist/tests/layout/inline-background-alignment.spec.js +6 -6
- package/dist/tests/layout/table-image-cell.spec.js +95 -0
- package/dist/tests/pdf/alignments.spec.js +12 -12
- package/dist/tests/pdf/clip-path.spec.js +3 -1
- package/dist/tests/pdf/form-text-encoding.spec.js +1 -1
- package/dist/tests/pdf/svg-stroke-dash.spec.js +8 -8
- package/dist/tests/pdf/text-transform-matrix.spec.js +1 -1
- package/dist/tests/pdf/xref-integrity.spec.js +1 -1
- package/dist/tests/verify-subset-multi.spec.js +14 -14
- package/dist/tests/verify-subset.spec.js +12 -12
- package/package.json +89 -71
- package/dist/src/image/js-png-backend.d.ts +0 -7
- package/dist/src/image/js-png-backend.js +0 -9
- package/dist/src/image/png-backend.d.ts +0 -5
- package/dist/src/image/png-wasm-loader.d.ts +0 -5
- package/dist/src/image/png-wasm-loader.js +0 -59
- package/dist/src/image/wasm/png_decoder_wasm.d.ts +0 -8
- package/dist/src/image/wasm/png_decoder_wasm.js +0 -24
- package/dist/src/image/wasm/png_decoder_wasm_bg.js +0 -16
- package/dist/src/image/wasm-png-backend.d.ts +0 -6
- package/dist/src/image/wasm-png-backend.js +0 -17
- package/dist/src/layout/table/cell_layout.d.ts +0 -2
- package/dist/src/layout/table/cell_layout.js +0 -26
- package/dist/tests/image/png-backend.spec.d.ts +0 -1
- package/dist/tests/image/png-backend.spec.js +0 -34
- package/dist/tests/pdf/font-subset-registry-key.spec.d.ts +0 -1
- package/dist/tests/pdf/font-subset-registry-key.spec.js +0 -66
- package/dist/tests/pdf/header-footer.spec.d.ts +0 -1
- package/dist/tests/pdf/header-footer.spec.js +0 -46
- /package/dist/{src/image/png-backend.js → tests/layout/table-image-cell.spec.d.ts} +0 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { AlignItems, JustifyContent } from "../../../css/enums.js";
|
|
2
|
+
import { calculateLinesCrossSize } from "./line-builder.js";
|
|
3
|
+
export function resolveAlignContentLayout(lines, alignContent, containerCrossSize, crossAxisGap) {
|
|
4
|
+
const lineCrossSizes = lines.map((line) => line.crossSize);
|
|
5
|
+
if (lines.length === 0) {
|
|
6
|
+
return { lineCrossSizes, initialOffset: 0, additionalGap: 0 };
|
|
7
|
+
}
|
|
8
|
+
const naturalCross = calculateLinesCrossSize(lines, crossAxisGap);
|
|
9
|
+
const freeSpace = Math.max(0, containerCrossSize - naturalCross);
|
|
10
|
+
switch (alignContent) {
|
|
11
|
+
case "stretch":
|
|
12
|
+
if (freeSpace > 0) {
|
|
13
|
+
const extraPerLine = freeSpace / lines.length;
|
|
14
|
+
for (let i = 0; i < lineCrossSizes.length; i++) {
|
|
15
|
+
lineCrossSizes[i] += extraPerLine;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return { lineCrossSizes, initialOffset: 0, additionalGap: 0 };
|
|
19
|
+
case "flex-end":
|
|
20
|
+
return { lineCrossSizes, initialOffset: freeSpace, additionalGap: 0 };
|
|
21
|
+
case "center":
|
|
22
|
+
return { lineCrossSizes, initialOffset: freeSpace / 2, additionalGap: 0 };
|
|
23
|
+
case "space-between":
|
|
24
|
+
if (lines.length <= 1) {
|
|
25
|
+
return { lineCrossSizes, initialOffset: 0, additionalGap: 0 };
|
|
26
|
+
}
|
|
27
|
+
return { lineCrossSizes, initialOffset: 0, additionalGap: freeSpace / (lines.length - 1) };
|
|
28
|
+
case "space-around": {
|
|
29
|
+
const gap = freeSpace / lines.length;
|
|
30
|
+
return { lineCrossSizes, initialOffset: gap / 2, additionalGap: gap };
|
|
31
|
+
}
|
|
32
|
+
case "space-evenly": {
|
|
33
|
+
const gap = freeSpace / (lines.length + 1);
|
|
34
|
+
return { lineCrossSizes, initialOffset: gap, additionalGap: gap };
|
|
35
|
+
}
|
|
36
|
+
case "flex-start":
|
|
37
|
+
default:
|
|
38
|
+
return { lineCrossSizes, initialOffset: 0, additionalGap: 0 };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function resolveItemAlignment(alignSelf, containerAlign) {
|
|
42
|
+
if (alignSelf && alignSelf !== "auto") {
|
|
43
|
+
return alignSelf;
|
|
44
|
+
}
|
|
45
|
+
return containerAlign;
|
|
46
|
+
}
|
|
47
|
+
export function computeCrossOffset(alignment, containerSize, itemSize, marginStart, marginEnd) {
|
|
48
|
+
const total = itemSize + marginStart + marginEnd;
|
|
49
|
+
const reference = Number.isFinite(containerSize) ? containerSize : total;
|
|
50
|
+
const freeSpace = reference - total;
|
|
51
|
+
if (freeSpace <= 0) {
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
switch (alignment) {
|
|
55
|
+
case AlignItems.Center:
|
|
56
|
+
return freeSpace / 2;
|
|
57
|
+
case AlignItems.FlexEnd:
|
|
58
|
+
return freeSpace;
|
|
59
|
+
default:
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export function resolveJustifySpacing(justify, freeSpace, itemCount) {
|
|
64
|
+
if (itemCount <= 0) {
|
|
65
|
+
return { offset: 0, gap: 0 };
|
|
66
|
+
}
|
|
67
|
+
const clamped = Number.isFinite(freeSpace) ? Math.max(freeSpace, 0) : 0;
|
|
68
|
+
switch (justify) {
|
|
69
|
+
case JustifyContent.Center:
|
|
70
|
+
return { offset: clamped / 2, gap: 0 };
|
|
71
|
+
case JustifyContent.FlexEnd:
|
|
72
|
+
case JustifyContent.End:
|
|
73
|
+
case JustifyContent.Right:
|
|
74
|
+
return { offset: clamped, gap: 0 };
|
|
75
|
+
case JustifyContent.SpaceBetween:
|
|
76
|
+
if (itemCount === 1) {
|
|
77
|
+
return { offset: 0, gap: 0 };
|
|
78
|
+
}
|
|
79
|
+
return { offset: 0, gap: clamped / (itemCount - 1) };
|
|
80
|
+
case JustifyContent.SpaceAround: {
|
|
81
|
+
const gap = clamped / itemCount;
|
|
82
|
+
return { offset: gap / 2, gap };
|
|
83
|
+
}
|
|
84
|
+
case JustifyContent.SpaceEvenly: {
|
|
85
|
+
const gap = clamped / (itemCount + 1);
|
|
86
|
+
return { offset: gap, gap };
|
|
87
|
+
}
|
|
88
|
+
default:
|
|
89
|
+
return { offset: 0, gap: 0 };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LayoutNode } from "../../../dom/node.js";
|
|
2
|
+
import type { LayoutContext } from "../../pipeline/strategy.js";
|
|
3
|
+
import type { FlexItemMetrics, FlexLine } from "./types.js";
|
|
4
|
+
export declare function relayoutFlexItemForMainSize(container: LayoutNode, item: FlexItemMetrics, context: LayoutContext, targetMainSize: number, isRow: boolean): void;
|
|
5
|
+
export declare function distributeFlexGrowAcrossLines(lines: FlexLine[], container: LayoutNode, context: LayoutContext, containerMainSize: number, mainAxisGap: number, isRow: boolean): void;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { refreshFlexItemSizes, recomputeLineMetrics } from "./line-builder.js";
|
|
2
|
+
export function relayoutFlexItemForMainSize(container, item, context, targetMainSize, isRow) {
|
|
3
|
+
if (!Number.isFinite(targetMainSize) || targetMainSize < 0) {
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
const prevContainerWidth = container.box.contentWidth;
|
|
7
|
+
const prevContainerHeight = container.box.contentHeight;
|
|
8
|
+
const targetContribution = targetMainSize + item.mainMarginStart + item.mainMarginEnd;
|
|
9
|
+
let displayMutated = false;
|
|
10
|
+
if (item.node.style.display !== item.effectiveDisplay) {
|
|
11
|
+
item.node.style.display = item.effectiveDisplay;
|
|
12
|
+
displayMutated = true;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
if (isRow) {
|
|
16
|
+
container.box.contentWidth = Math.max(0, targetContribution);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
container.box.contentHeight = Math.max(0, targetContribution);
|
|
20
|
+
}
|
|
21
|
+
context.layoutChild(item.node);
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
container.box.contentWidth = prevContainerWidth;
|
|
25
|
+
container.box.contentHeight = prevContainerHeight;
|
|
26
|
+
if (displayMutated) {
|
|
27
|
+
item.node.style.display = item.originalDisplay;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function distributeFlexGrowAcrossLines(lines, container, context, containerMainSize, mainAxisGap, isRow) {
|
|
32
|
+
if (lines.length === 0 || !(containerMainSize > 0)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
for (const line of lines) {
|
|
36
|
+
const freeSpace = containerMainSize - line.mainSizeWithGaps;
|
|
37
|
+
if (!(freeSpace > 0)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const growItems = line.items.filter((item) => item.flexGrow > 0);
|
|
41
|
+
const totalGrow = growItems.reduce((sum, item) => sum + item.flexGrow, 0);
|
|
42
|
+
if (!(totalGrow > 0)) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
for (const item of growItems) {
|
|
46
|
+
const delta = (freeSpace * item.flexGrow) / totalGrow;
|
|
47
|
+
const targetMainSize = Math.max(0, item.mainSize + delta);
|
|
48
|
+
if (Math.abs(targetMainSize - item.mainSize) < 0.01) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
relayoutFlexItemForMainSize(container, item, context, targetMainSize, isRow);
|
|
52
|
+
refreshFlexItemSizes(item, isRow);
|
|
53
|
+
}
|
|
54
|
+
recomputeLineMetrics(line, mainAxisGap);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FlexItemMetrics, FlexLine } from "./types.js";
|
|
2
|
+
export declare function buildFlexLines(items: FlexItemMetrics[], containerMainSize: number, mainAxisGap: number): FlexLine[];
|
|
3
|
+
export declare function calculateLinesCrossSize(lines: FlexLine[], crossAxisGap: number): number;
|
|
4
|
+
export declare function refreshFlexItemSizes(item: FlexItemMetrics, isRow: boolean): void;
|
|
5
|
+
export declare function recomputeLineMetrics(line: FlexLine, mainAxisGap: number): void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { calculateTotalGap } from "../../utils/gap-calculator.js";
|
|
2
|
+
export function buildFlexLines(items, containerMainSize, mainAxisGap) {
|
|
3
|
+
if (items.length === 0) {
|
|
4
|
+
return [];
|
|
5
|
+
}
|
|
6
|
+
const lines = [];
|
|
7
|
+
let current = { items: [], mainSizeWithGaps: 0, crossSize: 0 };
|
|
8
|
+
for (const item of items) {
|
|
9
|
+
const addition = current.items.length === 0 ? item.mainContribution : mainAxisGap + item.mainContribution;
|
|
10
|
+
const shouldWrap = current.items.length > 0 &&
|
|
11
|
+
containerMainSize > 0 &&
|
|
12
|
+
current.mainSizeWithGaps + addition > containerMainSize + 0.01;
|
|
13
|
+
if (shouldWrap) {
|
|
14
|
+
lines.push(current);
|
|
15
|
+
current = { items: [], mainSizeWithGaps: 0, crossSize: 0 };
|
|
16
|
+
}
|
|
17
|
+
if (current.items.length > 0) {
|
|
18
|
+
current.mainSizeWithGaps += mainAxisGap;
|
|
19
|
+
}
|
|
20
|
+
current.items.push(item);
|
|
21
|
+
current.mainSizeWithGaps += item.mainContribution;
|
|
22
|
+
current.crossSize = Math.max(current.crossSize, item.crossContribution);
|
|
23
|
+
}
|
|
24
|
+
if (current.items.length > 0) {
|
|
25
|
+
lines.push(current);
|
|
26
|
+
}
|
|
27
|
+
return lines;
|
|
28
|
+
}
|
|
29
|
+
export function calculateLinesCrossSize(lines, crossAxisGap) {
|
|
30
|
+
if (lines.length === 0) {
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
const totalLines = lines.reduce((sum, line) => sum + line.crossSize, 0);
|
|
34
|
+
return totalLines + calculateTotalGap(crossAxisGap, lines.length);
|
|
35
|
+
}
|
|
36
|
+
export function refreshFlexItemSizes(item, isRow) {
|
|
37
|
+
item.mainSize = isRow ? item.node.box.borderBoxWidth : item.node.box.borderBoxHeight;
|
|
38
|
+
item.crossSize = isRow ? item.node.box.borderBoxHeight : item.node.box.borderBoxWidth;
|
|
39
|
+
item.mainContribution = item.mainSize + item.mainMarginStart + item.mainMarginEnd;
|
|
40
|
+
item.crossContribution = item.crossSize + item.crossMarginStart + item.crossMarginEnd;
|
|
41
|
+
}
|
|
42
|
+
export function recomputeLineMetrics(line, mainAxisGap) {
|
|
43
|
+
let mainSizeWithGaps = 0;
|
|
44
|
+
let crossSize = 0;
|
|
45
|
+
for (let i = 0; i < line.items.length; i++) {
|
|
46
|
+
const item = line.items[i];
|
|
47
|
+
if (i > 0) {
|
|
48
|
+
mainSizeWithGaps += mainAxisGap;
|
|
49
|
+
}
|
|
50
|
+
mainSizeWithGaps += item.mainContribution;
|
|
51
|
+
crossSize = Math.max(crossSize, item.crossContribution);
|
|
52
|
+
}
|
|
53
|
+
line.mainSizeWithGaps = mainSizeWithGaps;
|
|
54
|
+
line.crossSize = crossSize;
|
|
55
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Display } from "../../../css/enums.js";
|
|
2
|
+
import { LayoutNode } from "../../../dom/node.js";
|
|
3
|
+
export interface FlexItemMetrics {
|
|
4
|
+
node: LayoutNode;
|
|
5
|
+
originalDisplay: Display;
|
|
6
|
+
effectiveDisplay: Display;
|
|
7
|
+
mainMarginStart: number;
|
|
8
|
+
mainMarginEnd: number;
|
|
9
|
+
crossMarginStart: number;
|
|
10
|
+
crossMarginEnd: number;
|
|
11
|
+
mainSize: number;
|
|
12
|
+
crossSize: number;
|
|
13
|
+
mainContribution: number;
|
|
14
|
+
crossContribution: number;
|
|
15
|
+
flexGrow: number;
|
|
16
|
+
flexShrink: number;
|
|
17
|
+
}
|
|
18
|
+
export interface FlexLine {
|
|
19
|
+
items: FlexItemMetrics[];
|
|
20
|
+
mainSizeWithGaps: number;
|
|
21
|
+
crossSize: number;
|
|
22
|
+
}
|
|
23
|
+
export interface AlignContentResolution {
|
|
24
|
+
lineCrossSizes: number[];
|
|
25
|
+
initialOffset: number;
|
|
26
|
+
additionalGap: number;
|
|
27
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Display } from "../../../css/enums.js";
|
|
2
|
+
import type { LengthLike } from "../../../css/length.js";
|
|
3
|
+
import type { FlexDirection } from "../../../css/style.js";
|
|
4
|
+
import { LayoutNode } from "../../../dom/node.js";
|
|
5
|
+
export declare function blockifyFlexItemDisplay(display: Display): Display;
|
|
6
|
+
export declare function allowsPreferredShrink(originalDisplay: Display, effectiveDisplay: Display): boolean;
|
|
7
|
+
export declare function isRowDirection(direction: FlexDirection): boolean;
|
|
8
|
+
export declare function isAutoMainSize(value: LengthLike | undefined): boolean;
|
|
9
|
+
export declare function computePreferredInlineWidth(node: LayoutNode): number | undefined;
|
|
10
|
+
export declare function offsetLayoutSubtree(node: LayoutNode, deltaX: number, deltaY: number): void;
|
|
11
|
+
export declare function resolveInitialDimension(specified: number | undefined, fallback: number): number;
|
|
12
|
+
export declare function resolveFlexSize(value: LengthLike | undefined, reference: number, containerWidth?: number, containerHeight?: number): number | undefined;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Display } from "../../../css/enums.js";
|
|
2
|
+
import { isAutoLength, resolveLength } from "../../../css/length.js";
|
|
3
|
+
import { LayoutNode } from "../../../dom/node.js";
|
|
4
|
+
export function blockifyFlexItemDisplay(display) {
|
|
5
|
+
switch (display) {
|
|
6
|
+
case Display.Inline:
|
|
7
|
+
case Display.InlineBlock:
|
|
8
|
+
return Display.Block;
|
|
9
|
+
case Display.InlineFlex:
|
|
10
|
+
return Display.Flex;
|
|
11
|
+
case Display.InlineGrid:
|
|
12
|
+
return Display.Grid;
|
|
13
|
+
case Display.InlineTable:
|
|
14
|
+
return Display.Table;
|
|
15
|
+
default:
|
|
16
|
+
return display;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function allowsPreferredShrink(originalDisplay, effectiveDisplay) {
|
|
20
|
+
switch (effectiveDisplay) {
|
|
21
|
+
case Display.Flex:
|
|
22
|
+
case Display.InlineFlex:
|
|
23
|
+
case Display.Grid:
|
|
24
|
+
case Display.InlineGrid:
|
|
25
|
+
return false;
|
|
26
|
+
default:
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
if (effectiveDisplay === originalDisplay) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return originalDisplay === Display.Inline;
|
|
33
|
+
}
|
|
34
|
+
export function isRowDirection(direction) {
|
|
35
|
+
return direction === "row" || direction === "row-reverse";
|
|
36
|
+
}
|
|
37
|
+
export function isAutoMainSize(value) {
|
|
38
|
+
if (value === undefined) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (typeof value === "number") {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (value === "auto") {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return isAutoLength(value);
|
|
48
|
+
}
|
|
49
|
+
export function computePreferredInlineWidth(node) {
|
|
50
|
+
let maxWidth = 0;
|
|
51
|
+
node.walk((desc) => {
|
|
52
|
+
if (desc.inlineRuns && desc.inlineRuns.length > 0) {
|
|
53
|
+
const localMax = desc.inlineRuns.reduce((max, run) => Math.max(max, run.lineWidth ?? run.width), 0);
|
|
54
|
+
if (localMax > maxWidth) {
|
|
55
|
+
maxWidth = localMax;
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (!desc.lineBoxes || desc.lineBoxes.length === 0) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
for (const line of desc.lineBoxes) {
|
|
63
|
+
if (!line) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const width = typeof line.width === "number" ? line.width : 0;
|
|
67
|
+
if (width > maxWidth) {
|
|
68
|
+
maxWidth = width;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return maxWidth > 0 ? maxWidth : undefined;
|
|
73
|
+
}
|
|
74
|
+
export function offsetLayoutSubtree(node, deltaX, deltaY) {
|
|
75
|
+
if (deltaX === 0 && deltaY === 0) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
node.walk((desc) => {
|
|
79
|
+
if (desc !== node) {
|
|
80
|
+
desc.box.x += deltaX;
|
|
81
|
+
desc.box.y += deltaY;
|
|
82
|
+
}
|
|
83
|
+
desc.box.baseline += deltaY;
|
|
84
|
+
// Update inline runs if they exist
|
|
85
|
+
if (desc.inlineRuns && desc.inlineRuns.length > 0) {
|
|
86
|
+
for (const run of desc.inlineRuns) {
|
|
87
|
+
run.startX += deltaX;
|
|
88
|
+
run.baseline += deltaY;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
export function resolveInitialDimension(specified, fallback) {
|
|
94
|
+
if (specified !== undefined && Number.isFinite(specified)) {
|
|
95
|
+
return Math.max(specified, 0);
|
|
96
|
+
}
|
|
97
|
+
if (Number.isFinite(fallback)) {
|
|
98
|
+
return Math.max(fallback, 0);
|
|
99
|
+
}
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
export function resolveFlexSize(value, reference, containerWidth = reference, containerHeight = reference) {
|
|
103
|
+
if (value === undefined) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
if (typeof value === "number") {
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
109
|
+
if (value === "auto" || isAutoLength(value)) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
return resolveLength(value, reference, { auto: "reference", containerWidth, containerHeight });
|
|
113
|
+
}
|