@codehz/draw-call 0.5.0 → 0.5.2
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/browser/index.cjs +176 -103
- package/browser/index.d.cts +9 -4
- package/browser/index.d.ts +9 -4
- package/browser/index.js +175 -103
- package/node/index.cjs +176 -103
- package/node/index.d.cts +9 -4
- package/node/index.d.mts +9 -4
- package/node/index.mjs +175 -103
- package/package.json +2 -2
package/browser/index.js
CHANGED
|
@@ -81,6 +81,19 @@ function normalizeBorderRadius(value) {
|
|
|
81
81
|
|
|
82
82
|
//#endregion
|
|
83
83
|
//#region src/layout/components/box.ts
|
|
84
|
+
/**
|
|
85
|
+
* 安全获取元素的 margin
|
|
86
|
+
* Transform 元素没有 margin,返回默认 spacing
|
|
87
|
+
*/
|
|
88
|
+
function getElementMargin$2(element) {
|
|
89
|
+
if (element.type === "transform") return {
|
|
90
|
+
top: 0,
|
|
91
|
+
right: 0,
|
|
92
|
+
bottom: 0,
|
|
93
|
+
left: 0
|
|
94
|
+
};
|
|
95
|
+
return normalizeSpacing(element.margin);
|
|
96
|
+
}
|
|
84
97
|
function calcEffectiveSize(element, padding, availableWidth) {
|
|
85
98
|
return {
|
|
86
99
|
width: typeof element.width === "number" ? element.width - padding.left - padding.right : availableWidth > 0 ? availableWidth : 0,
|
|
@@ -90,7 +103,7 @@ function calcEffectiveSize(element, padding, availableWidth) {
|
|
|
90
103
|
function collectChildSizes(children, ctx, availableWidth, padding, measureChild) {
|
|
91
104
|
const childSizes = [];
|
|
92
105
|
for (const child of children) {
|
|
93
|
-
const childMargin =
|
|
106
|
+
const childMargin = getElementMargin$2(child);
|
|
94
107
|
const childSize = measureChild(child, ctx, availableWidth - padding.left - padding.right - childMargin.left - childMargin.right);
|
|
95
108
|
childSizes.push({
|
|
96
109
|
width: childSize.width,
|
|
@@ -159,7 +172,7 @@ function measureBoxSize(element, ctx, availableWidth, measureChild) {
|
|
|
159
172
|
contentHeight = wrapped.height;
|
|
160
173
|
} else for (let i = 0; i < children.length; i++) {
|
|
161
174
|
const child = children[i];
|
|
162
|
-
const childMargin =
|
|
175
|
+
const childMargin = getElementMargin$2(child);
|
|
163
176
|
const childSize = measureChild(child, ctx, availableWidth - padding.left - padding.right - childMargin.left - childMargin.right);
|
|
164
177
|
if (isRow) {
|
|
165
178
|
contentWidth += childSize.width + childMargin.left + childMargin.right;
|
|
@@ -393,6 +406,19 @@ function wrapRichText(ctx, spans, maxWidth, lineHeightScale = 1.2, elementStyle
|
|
|
393
406
|
//#endregion
|
|
394
407
|
//#region src/layout/components/stack.ts
|
|
395
408
|
/**
|
|
409
|
+
* 安全获取元素的 margin
|
|
410
|
+
* Transform 元素没有 margin,返回默认 spacing
|
|
411
|
+
*/
|
|
412
|
+
function getElementMargin$1(element) {
|
|
413
|
+
if (element.type === "transform") return {
|
|
414
|
+
top: 0,
|
|
415
|
+
right: 0,
|
|
416
|
+
bottom: 0,
|
|
417
|
+
left: 0
|
|
418
|
+
};
|
|
419
|
+
return normalizeSpacing(element.margin);
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
396
422
|
* 测量 Stack 元素的固有尺寸
|
|
397
423
|
*/
|
|
398
424
|
function measureStackSize(element, ctx, availableWidth, measureChild) {
|
|
@@ -401,7 +427,7 @@ function measureStackSize(element, ctx, availableWidth, measureChild) {
|
|
|
401
427
|
let contentHeight = 0;
|
|
402
428
|
const children = element.children ?? [];
|
|
403
429
|
for (const child of children) {
|
|
404
|
-
const childMargin =
|
|
430
|
+
const childMargin = getElementMargin$1(child);
|
|
405
431
|
const childSize = measureChild(child, ctx, availableWidth - padding.left - padding.right - childMargin.left - childMargin.right);
|
|
406
432
|
contentWidth = Math.max(contentWidth, childSize.width + childMargin.left + childMargin.right);
|
|
407
433
|
contentHeight = Math.max(contentHeight, childSize.height + childMargin.top + childMargin.bottom);
|
|
@@ -640,18 +666,79 @@ function sizeNeedsParent(size) {
|
|
|
640
666
|
|
|
641
667
|
//#endregion
|
|
642
668
|
//#region src/layout/engine.ts
|
|
669
|
+
/**
|
|
670
|
+
* 类型守卫:检查 Element 是否为 LayoutElement(非 Transform)
|
|
671
|
+
* 由于 Transform 元素在 computeLayoutImpl 开始时被处理,
|
|
672
|
+
* 此时只应处理 LayoutElement
|
|
673
|
+
*/
|
|
674
|
+
function assertLayoutElement(element) {
|
|
675
|
+
if (element.type === "transform") throw new Error("Transform elements should be handled at entry point");
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* 安全获取元素的 margin
|
|
679
|
+
* Transform 元素没有 margin,返回默认 spacing
|
|
680
|
+
*/
|
|
681
|
+
function getElementMargin(element) {
|
|
682
|
+
if (element.type === "transform") return {
|
|
683
|
+
top: 0,
|
|
684
|
+
right: 0,
|
|
685
|
+
bottom: 0,
|
|
686
|
+
left: 0
|
|
687
|
+
};
|
|
688
|
+
return normalizeSpacing(element.margin);
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* 安全获取元素的布局属性(width, height, flex等)
|
|
692
|
+
* Transform 元素这些属性为 undefined
|
|
693
|
+
*/
|
|
694
|
+
function getElementLayoutProps(element) {
|
|
695
|
+
if (element.type === "transform") return {
|
|
696
|
+
width: void 0,
|
|
697
|
+
height: void 0,
|
|
698
|
+
flex: void 0,
|
|
699
|
+
minWidth: void 0,
|
|
700
|
+
maxWidth: void 0,
|
|
701
|
+
minHeight: void 0,
|
|
702
|
+
maxHeight: void 0,
|
|
703
|
+
alignSelf: void 0
|
|
704
|
+
};
|
|
705
|
+
const le = element;
|
|
706
|
+
return {
|
|
707
|
+
width: le.width,
|
|
708
|
+
height: le.height,
|
|
709
|
+
flex: le.flex,
|
|
710
|
+
minWidth: le.minWidth,
|
|
711
|
+
maxWidth: le.maxWidth,
|
|
712
|
+
minHeight: le.minHeight,
|
|
713
|
+
maxHeight: le.maxHeight,
|
|
714
|
+
alignSelf: le.alignSelf
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* 布局计算主函数
|
|
719
|
+
* 内部使用 Element 类型以支持 Transform,外部通过 LayoutElement 约束类型
|
|
720
|
+
*/
|
|
643
721
|
function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
644
|
-
|
|
645
|
-
|
|
722
|
+
return computeLayoutImpl(element, ctx, constraints, x, y);
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* 内部实现函数,处理所有元素类型包括 Transform
|
|
726
|
+
*/
|
|
727
|
+
function computeLayoutImpl(element, ctx, constraints, x = 0, y = 0) {
|
|
728
|
+
if (element.type === "transform") return computeLayoutImpl(element.children, ctx, constraints, x, y);
|
|
729
|
+
assertLayoutElement(element);
|
|
730
|
+
const layoutElement = element;
|
|
731
|
+
const margin = normalizeSpacing(layoutElement.margin);
|
|
732
|
+
const padding = normalizeSpacing("padding" in layoutElement ? layoutElement.padding : void 0);
|
|
646
733
|
const availableWidth = constraints.maxWidth - margin.left - margin.right;
|
|
647
734
|
const availableHeight = constraints.maxHeight - margin.top - margin.bottom;
|
|
648
|
-
const intrinsic = measureIntrinsicSize(
|
|
649
|
-
let width = constraints.minWidth === constraints.maxWidth && constraints.minWidth > 0 ? constraints.maxWidth - margin.left - margin.right : resolveSize(
|
|
650
|
-
let height = constraints.minHeight === constraints.maxHeight && constraints.minHeight > 0 ? constraints.maxHeight - margin.top - margin.bottom : resolveSize(
|
|
651
|
-
if (
|
|
652
|
-
if (
|
|
653
|
-
if (
|
|
654
|
-
if (
|
|
735
|
+
const intrinsic = measureIntrinsicSize(layoutElement, ctx, availableWidth);
|
|
736
|
+
let width = constraints.minWidth === constraints.maxWidth && constraints.minWidth > 0 ? constraints.maxWidth - margin.left - margin.right : resolveSize(layoutElement.width, availableWidth, intrinsic.width);
|
|
737
|
+
let height = constraints.minHeight === constraints.maxHeight && constraints.minHeight > 0 ? constraints.maxHeight - margin.top - margin.bottom : resolveSize(layoutElement.height, availableHeight, intrinsic.height);
|
|
738
|
+
if (layoutElement.minWidth !== void 0) width = Math.max(width, layoutElement.minWidth);
|
|
739
|
+
if (layoutElement.maxWidth !== void 0) width = Math.min(width, layoutElement.maxWidth);
|
|
740
|
+
if (layoutElement.minHeight !== void 0) height = Math.max(height, layoutElement.minHeight);
|
|
741
|
+
if (layoutElement.maxHeight !== void 0) height = Math.min(height, layoutElement.maxHeight);
|
|
655
742
|
const actualX = x + margin.left;
|
|
656
743
|
const actualY = y + margin.top;
|
|
657
744
|
const contentX = actualX + padding.left;
|
|
@@ -659,7 +746,7 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
659
746
|
const contentWidth = width - padding.left - padding.right;
|
|
660
747
|
const contentHeight = height - padding.top - padding.bottom;
|
|
661
748
|
const node = {
|
|
662
|
-
element,
|
|
749
|
+
element: layoutElement,
|
|
663
750
|
layout: {
|
|
664
751
|
x: actualX,
|
|
665
752
|
y: actualY,
|
|
@@ -672,14 +759,14 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
672
759
|
},
|
|
673
760
|
children: []
|
|
674
761
|
};
|
|
675
|
-
if (
|
|
676
|
-
const font =
|
|
677
|
-
if (
|
|
678
|
-
let { lines, offsets } = wrapText(ctx,
|
|
679
|
-
if (
|
|
680
|
-
lines = lines.slice(0,
|
|
681
|
-
offsets = offsets.slice(0,
|
|
682
|
-
if (
|
|
762
|
+
if (layoutElement.type === "text") {
|
|
763
|
+
const font = layoutElement.font ?? {};
|
|
764
|
+
if (layoutElement.wrap && contentWidth > 0) {
|
|
765
|
+
let { lines, offsets } = wrapText(ctx, layoutElement.content, contentWidth, font);
|
|
766
|
+
if (layoutElement.maxLines && lines.length > layoutElement.maxLines) {
|
|
767
|
+
lines = lines.slice(0, layoutElement.maxLines);
|
|
768
|
+
offsets = offsets.slice(0, layoutElement.maxLines);
|
|
769
|
+
if (layoutElement.ellipsis && lines.length > 0) {
|
|
683
770
|
const lastIdx = lines.length - 1;
|
|
684
771
|
const truncated = truncateText(ctx, lines[lastIdx], contentWidth, font);
|
|
685
772
|
lines[lastIdx] = truncated.text;
|
|
@@ -689,17 +776,17 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
689
776
|
node.lines = lines;
|
|
690
777
|
node.lineOffsets = offsets;
|
|
691
778
|
} else {
|
|
692
|
-
const { text, offset } = truncateText(ctx,
|
|
779
|
+
const { text, offset } = truncateText(ctx, layoutElement.content, contentWidth > 0 && layoutElement.ellipsis ? contentWidth : Infinity, font);
|
|
693
780
|
node.lines = [text];
|
|
694
781
|
node.lineOffsets = [offset];
|
|
695
782
|
}
|
|
696
783
|
}
|
|
697
|
-
if (
|
|
698
|
-
const lineHeight =
|
|
699
|
-
let lines = wrapRichText(ctx,
|
|
700
|
-
if (
|
|
701
|
-
lines = lines.slice(0,
|
|
702
|
-
if (
|
|
784
|
+
if (layoutElement.type === "richtext") {
|
|
785
|
+
const lineHeight = layoutElement.lineHeight ?? 1.2;
|
|
786
|
+
let lines = wrapRichText(ctx, layoutElement.spans, contentWidth, lineHeight);
|
|
787
|
+
if (layoutElement.maxLines && lines.length > layoutElement.maxLines) {
|
|
788
|
+
lines = lines.slice(0, layoutElement.maxLines);
|
|
789
|
+
if (layoutElement.ellipsis && lines.length > 0) {
|
|
703
790
|
const lastLine = lines[lines.length - 1];
|
|
704
791
|
if (lastLine.segments.length > 0) {
|
|
705
792
|
const lastSeg = lastLine.segments[lastLine.segments.length - 1];
|
|
@@ -711,19 +798,19 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
711
798
|
}
|
|
712
799
|
node.richLines = lines;
|
|
713
800
|
}
|
|
714
|
-
if (
|
|
715
|
-
const children =
|
|
716
|
-
if (
|
|
717
|
-
const stackAlign =
|
|
718
|
-
const stackJustify =
|
|
801
|
+
if (layoutElement.type === "box" || layoutElement.type === "stack") {
|
|
802
|
+
const children = layoutElement.children ?? [];
|
|
803
|
+
if (layoutElement.type === "stack") {
|
|
804
|
+
const stackAlign = layoutElement.align ?? "start";
|
|
805
|
+
const stackJustify = layoutElement.justify ?? "start";
|
|
719
806
|
for (const child of children) {
|
|
720
|
-
const childNode =
|
|
807
|
+
const childNode = computeLayoutImpl(child, ctx, {
|
|
721
808
|
minWidth: 0,
|
|
722
809
|
maxWidth: contentWidth,
|
|
723
810
|
minHeight: 0,
|
|
724
811
|
maxHeight: contentHeight
|
|
725
812
|
}, contentX, contentY);
|
|
726
|
-
const childMargin =
|
|
813
|
+
const childMargin = getElementMargin(child);
|
|
727
814
|
const childOuterWidth = childNode.layout.width + childMargin.left + childMargin.right;
|
|
728
815
|
const childOuterHeight = childNode.layout.height + childMargin.top + childMargin.bottom;
|
|
729
816
|
let offsetX = 0;
|
|
@@ -736,19 +823,21 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
736
823
|
node.children.push(childNode);
|
|
737
824
|
}
|
|
738
825
|
} else {
|
|
739
|
-
const
|
|
740
|
-
const
|
|
741
|
-
const
|
|
742
|
-
const
|
|
743
|
-
const
|
|
826
|
+
const boxElement = layoutElement;
|
|
827
|
+
const direction = boxElement.direction ?? "row";
|
|
828
|
+
const justify = boxElement.justify ?? "start";
|
|
829
|
+
const align = boxElement.align ?? "stretch";
|
|
830
|
+
const gap = boxElement.gap ?? 0;
|
|
831
|
+
const wrap = boxElement.wrap ?? false;
|
|
744
832
|
const isRow = direction === "row" || direction === "row-reverse";
|
|
745
833
|
const isReverse = direction === "row-reverse" || direction === "column-reverse";
|
|
746
834
|
const getContentMainSize = () => isRow ? contentWidth : contentHeight;
|
|
747
835
|
const getContentCrossSize = () => isRow ? contentHeight : contentWidth;
|
|
748
836
|
const childInfos = [];
|
|
749
837
|
for (const child of children) {
|
|
750
|
-
const childMargin =
|
|
751
|
-
const
|
|
838
|
+
const childMargin = getElementMargin(child);
|
|
839
|
+
const childProps = getElementLayoutProps(child);
|
|
840
|
+
const childFlex = childProps.flex ?? 0;
|
|
752
841
|
if (childFlex > 0) childInfos.push({
|
|
753
842
|
element: child,
|
|
754
843
|
width: 0,
|
|
@@ -758,10 +847,10 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
758
847
|
});
|
|
759
848
|
else {
|
|
760
849
|
const size = measureIntrinsicSize(child, ctx, contentWidth - childMargin.left - childMargin.right);
|
|
761
|
-
const shouldStretchWidth = !isRow &&
|
|
762
|
-
const shouldStretchHeight = isRow &&
|
|
763
|
-
let w = sizeNeedsParent(
|
|
764
|
-
let h = sizeNeedsParent(
|
|
850
|
+
const shouldStretchWidth = !isRow && childProps.width === void 0 && align === "stretch";
|
|
851
|
+
const shouldStretchHeight = isRow && childProps.height === void 0 && align === "stretch";
|
|
852
|
+
let w = sizeNeedsParent(childProps.width) ? resolveSize(childProps.width, contentWidth - childMargin.left - childMargin.right, size.width) : resolveSize(childProps.width, 0, size.width);
|
|
853
|
+
let h = sizeNeedsParent(childProps.height) ? resolveSize(childProps.height, contentHeight - childMargin.top - childMargin.bottom, size.height) : resolveSize(childProps.height, 0, size.height);
|
|
765
854
|
if (shouldStretchWidth && !wrap) w = contentWidth - childMargin.left - childMargin.right;
|
|
766
855
|
if (shouldStretchHeight && !wrap) h = contentHeight - childMargin.top - childMargin.bottom;
|
|
767
856
|
childInfos.push({
|
|
@@ -802,14 +891,15 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
802
891
|
const availableForFlex = Math.max(0, mainAxisSize - totalFixed - totalGap);
|
|
803
892
|
for (const info of lineInfos) if (info.flex > 0) {
|
|
804
893
|
const flexSize = totalFlex > 0 ? availableForFlex * info.flex / totalFlex : 0;
|
|
894
|
+
const childProps = getElementLayoutProps(info.element);
|
|
805
895
|
if (isRow) {
|
|
806
896
|
info.width = flexSize;
|
|
807
897
|
const size = measureIntrinsicSize(info.element, ctx, flexSize);
|
|
808
|
-
info.height = sizeNeedsParent(
|
|
898
|
+
info.height = sizeNeedsParent(childProps.height) ? resolveSize(childProps.height, contentHeight - info.margin.top - info.margin.bottom, size.height) : resolveSize(childProps.height, 0, size.height);
|
|
809
899
|
} else {
|
|
810
900
|
info.height = flexSize;
|
|
811
901
|
const size = measureIntrinsicSize(info.element, ctx, contentWidth - info.margin.left - info.margin.right);
|
|
812
|
-
info.width = sizeNeedsParent(
|
|
902
|
+
info.width = sizeNeedsParent(childProps.width) ? resolveSize(childProps.width, contentWidth - info.margin.left - info.margin.right, size.width) : resolveSize(childProps.width, 0, size.width);
|
|
813
903
|
}
|
|
814
904
|
}
|
|
815
905
|
}
|
|
@@ -860,17 +950,18 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
860
950
|
const orderedInfos = isReverse ? [...lineInfos].reverse() : lineInfos;
|
|
861
951
|
for (let i = 0; i < orderedInfos.length; i++) {
|
|
862
952
|
const info = orderedInfos[i];
|
|
953
|
+
const childProps = getElementLayoutProps(info.element);
|
|
863
954
|
const crossAxisSize = wrap ? lineCrossSize : getContentCrossSize();
|
|
864
955
|
const childCrossSize = isRow ? info.height + info.margin.top + info.margin.bottom : info.width + info.margin.left + info.margin.right;
|
|
865
956
|
let itemCrossOffset = 0;
|
|
866
|
-
const effectiveAlign =
|
|
957
|
+
const effectiveAlign = childProps.alignSelf ?? align;
|
|
867
958
|
if (effectiveAlign === "start") itemCrossOffset = 0;
|
|
868
959
|
else if (effectiveAlign === "end") itemCrossOffset = crossAxisSize - childCrossSize;
|
|
869
960
|
else if (effectiveAlign === "center") itemCrossOffset = (crossAxisSize - childCrossSize) / 2;
|
|
870
961
|
else if (effectiveAlign === "stretch") {
|
|
871
962
|
itemCrossOffset = 0;
|
|
872
|
-
if (isRow &&
|
|
873
|
-
else if (!isRow &&
|
|
963
|
+
if (isRow && childProps.height === void 0) info.height = crossAxisSize - info.margin.top - info.margin.bottom;
|
|
964
|
+
else if (!isRow && childProps.width === void 0) info.width = crossAxisSize - info.margin.left - info.margin.right;
|
|
874
965
|
}
|
|
875
966
|
const childX = isRow ? contentX + mainOffset + info.margin.left : contentX + crossOffset + itemCrossOffset + info.margin.left;
|
|
876
967
|
const childY = isRow ? contentY + crossOffset + itemCrossOffset + info.margin.top : contentY + mainOffset + info.margin.top;
|
|
@@ -879,26 +970,29 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
879
970
|
let minHeight = 0;
|
|
880
971
|
let maxHeight = info.height;
|
|
881
972
|
let shouldStretchCross = false;
|
|
882
|
-
if (info.flex > 0)
|
|
883
|
-
|
|
884
|
-
if (
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
973
|
+
if (info.flex > 0) {
|
|
974
|
+
const childProps = getElementLayoutProps(info.element);
|
|
975
|
+
if (isRow) {
|
|
976
|
+
minWidth = maxWidth = info.width;
|
|
977
|
+
if (childProps.height === void 0 && align === "stretch") {
|
|
978
|
+
minHeight = info.height;
|
|
979
|
+
maxHeight = boxElement.height !== void 0 ? info.height : Infinity;
|
|
980
|
+
shouldStretchCross = true;
|
|
981
|
+
}
|
|
982
|
+
} else {
|
|
983
|
+
minHeight = maxHeight = info.height;
|
|
984
|
+
if (childProps.width === void 0 && align === "stretch") {
|
|
985
|
+
minWidth = info.width;
|
|
986
|
+
maxWidth = boxElement.width !== void 0 ? info.width : Infinity;
|
|
987
|
+
shouldStretchCross = true;
|
|
988
|
+
}
|
|
888
989
|
}
|
|
889
990
|
} else {
|
|
890
|
-
|
|
891
|
-
if (
|
|
892
|
-
|
|
893
|
-
maxWidth = element.width !== void 0 ? info.width : Infinity;
|
|
894
|
-
shouldStretchCross = true;
|
|
895
|
-
}
|
|
991
|
+
const childProps = getElementLayoutProps(info.element);
|
|
992
|
+
if (!isRow && childProps.width === void 0 && align === "stretch") minWidth = maxWidth = crossAxisSize - info.margin.left - info.margin.right;
|
|
993
|
+
if (isRow && childProps.height === void 0 && align === "stretch") minHeight = maxHeight = crossAxisSize - info.margin.top - info.margin.bottom;
|
|
896
994
|
}
|
|
897
|
-
|
|
898
|
-
if (!isRow && info.element.width === void 0 && align === "stretch") minWidth = maxWidth = crossAxisSize - info.margin.left - info.margin.right;
|
|
899
|
-
if (isRow && info.element.height === void 0 && align === "stretch") minHeight = maxHeight = crossAxisSize - info.margin.top - info.margin.bottom;
|
|
900
|
-
}
|
|
901
|
-
const childNode = computeLayout(info.element, ctx, {
|
|
995
|
+
const childNode = computeLayoutImpl(info.element, ctx, {
|
|
902
996
|
minWidth,
|
|
903
997
|
maxWidth,
|
|
904
998
|
minHeight,
|
|
@@ -921,12 +1015,12 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
921
1015
|
crossOffset += lineCrossSize;
|
|
922
1016
|
if (lineIndex < lines.length - 1) crossOffset += gap;
|
|
923
1017
|
}
|
|
924
|
-
if (wrap &&
|
|
1018
|
+
if (wrap && boxElement.height === void 0 && isRow) {
|
|
925
1019
|
const actualContentHeight = crossOffset;
|
|
926
1020
|
const actualHeight = actualContentHeight + padding.top + padding.bottom;
|
|
927
1021
|
node.layout.height = actualHeight;
|
|
928
1022
|
node.layout.contentHeight = actualContentHeight;
|
|
929
|
-
} else if (wrap &&
|
|
1023
|
+
} else if (wrap && boxElement.width === void 0 && !isRow) {
|
|
930
1024
|
const actualContentWidth = crossOffset;
|
|
931
1025
|
const actualWidth = actualContentWidth + padding.left + padding.right;
|
|
932
1026
|
node.layout.width = actualWidth;
|
|
@@ -935,7 +1029,7 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
935
1029
|
if (!wrap) {
|
|
936
1030
|
let maxChildCrossSize = 0;
|
|
937
1031
|
for (const childNode of node.children) {
|
|
938
|
-
const childMargin =
|
|
1032
|
+
const childMargin = getElementMargin(childNode.element);
|
|
939
1033
|
if (isRow) {
|
|
940
1034
|
const childOuterHeight = childNode.layout.height + childMargin.top + childMargin.bottom;
|
|
941
1035
|
maxChildCrossSize = Math.max(maxChildCrossSize, childOuterHeight);
|
|
@@ -944,13 +1038,13 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
944
1038
|
maxChildCrossSize = Math.max(maxChildCrossSize, childOuterWidth);
|
|
945
1039
|
}
|
|
946
1040
|
}
|
|
947
|
-
if (isRow &&
|
|
1041
|
+
if (isRow && boxElement.height === void 0) {
|
|
948
1042
|
const actualHeight = maxChildCrossSize + padding.top + padding.bottom;
|
|
949
1043
|
if (actualHeight > node.layout.height) {
|
|
950
1044
|
node.layout.height = actualHeight;
|
|
951
1045
|
node.layout.contentHeight = maxChildCrossSize;
|
|
952
1046
|
}
|
|
953
|
-
} else if (!isRow &&
|
|
1047
|
+
} else if (!isRow && boxElement.width === void 0) {
|
|
954
1048
|
const actualWidth = maxChildCrossSize + padding.left + padding.right;
|
|
955
1049
|
if (actualWidth > node.layout.width) {
|
|
956
1050
|
node.layout.width = actualWidth;
|
|
@@ -960,48 +1054,24 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
|
|
|
960
1054
|
}
|
|
961
1055
|
if (isReverse) node.children.reverse();
|
|
962
1056
|
}
|
|
963
|
-
} else if (
|
|
964
|
-
const child =
|
|
965
|
-
if (child) {
|
|
966
|
-
const childMargin = normalizeSpacing(child.margin);
|
|
967
|
-
const childNode = computeLayout(child, ctx, {
|
|
968
|
-
minWidth: 0,
|
|
969
|
-
maxWidth: contentWidth,
|
|
970
|
-
minHeight: 0,
|
|
971
|
-
maxHeight: contentHeight
|
|
972
|
-
}, contentX, contentY);
|
|
973
|
-
node.children.push(childNode);
|
|
974
|
-
if (element.width === void 0) {
|
|
975
|
-
const childOuterWidth = childNode.layout.width + childMargin.left + childMargin.right;
|
|
976
|
-
const actualWidth = childOuterWidth + padding.left + padding.right;
|
|
977
|
-
node.layout.width = actualWidth;
|
|
978
|
-
node.layout.contentWidth = childOuterWidth;
|
|
979
|
-
}
|
|
980
|
-
if (element.height === void 0) {
|
|
981
|
-
const childOuterHeight = childNode.layout.height + childMargin.top + childMargin.bottom;
|
|
982
|
-
const actualHeight = childOuterHeight + padding.top + padding.bottom;
|
|
983
|
-
node.layout.height = actualHeight;
|
|
984
|
-
node.layout.contentHeight = childOuterHeight;
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
} else if (element.type === "customdraw") {
|
|
988
|
-
const child = element.children;
|
|
1057
|
+
} else if (layoutElement.type === "customdraw") {
|
|
1058
|
+
const child = layoutElement.children;
|
|
989
1059
|
if (child) {
|
|
990
1060
|
const childMargin = normalizeSpacing(child.margin);
|
|
991
|
-
const childNode =
|
|
1061
|
+
const childNode = computeLayoutImpl(child, ctx, {
|
|
992
1062
|
minWidth: 0,
|
|
993
1063
|
maxWidth: contentWidth,
|
|
994
1064
|
minHeight: 0,
|
|
995
1065
|
maxHeight: contentHeight
|
|
996
1066
|
}, contentX, contentY);
|
|
997
1067
|
node.children.push(childNode);
|
|
998
|
-
if (
|
|
1068
|
+
if (layoutElement.width === void 0) {
|
|
999
1069
|
const childOuterWidth = childNode.layout.width + childMargin.left + childMargin.right;
|
|
1000
1070
|
const actualWidth = childOuterWidth + padding.left + padding.right;
|
|
1001
1071
|
node.layout.width = actualWidth;
|
|
1002
1072
|
node.layout.contentWidth = childOuterWidth;
|
|
1003
1073
|
}
|
|
1004
|
-
if (
|
|
1074
|
+
if (layoutElement.height === void 0) {
|
|
1005
1075
|
const childOuterHeight = childNode.layout.height + childMargin.top + childMargin.bottom;
|
|
1006
1076
|
const actualHeight = childOuterHeight + padding.top + padding.bottom;
|
|
1007
1077
|
node.layout.height = actualHeight;
|
|
@@ -2011,10 +2081,12 @@ function getElementType(element) {
|
|
|
2011
2081
|
switch (element.type) {
|
|
2012
2082
|
case "box": return "Box";
|
|
2013
2083
|
case "text": return `Text "${element.content.slice(0, 20)}${element.content.length > 20 ? "..." : ""}"`;
|
|
2084
|
+
case "richtext": return "RichText";
|
|
2014
2085
|
case "stack": return "Stack";
|
|
2015
2086
|
case "image": return "Image";
|
|
2016
2087
|
case "svg": return "Svg";
|
|
2017
|
-
|
|
2088
|
+
case "transform": return "Transform";
|
|
2089
|
+
case "customdraw": return "CustomDraw";
|
|
2018
2090
|
}
|
|
2019
2091
|
}
|
|
2020
2092
|
/**
|