passing height to the measure function

This diff:
* adds height as another parameter passed to the measure function, computed the same way width is
* adds tests for this extension, which has involved adding a new measure function to all of js, c, java and c# tests
This commit is contained in:
Martin Kralik
2015-11-17 18:50:42 +00:00
parent 53769ccbc5
commit f2aa5ba604
29 changed files with 1139 additions and 294 deletions

View File

@@ -14,7 +14,7 @@ namespace Facebook.CSSLayout
{
/**
* Calculates layouts based on CSS style. See {@link #layoutNode(CSSNode, float)}.
* Calculates layouts based on CSS style. See {@link #layoutNode(CSSNode, float, float)}.
*/
static class LayoutEngine
@@ -205,7 +205,7 @@ namespace Facebook.CSSLayout
return node.IsMeasureDefined;
}
static boolean needsRelayout(CSSNode node, float parentMaxWidth)
static boolean needsRelayout(CSSNode node, float parentMaxWidth, float parentMaxHeight)
{
return node.isDirty() ||
!FloatUtil.floatsEqual(
@@ -214,18 +214,20 @@ namespace Facebook.CSSLayout
!FloatUtil.floatsEqual(
node.lastLayout.requestedWidth,
node.layout.dimensions[DIMENSION_WIDTH]) ||
!FloatUtil.floatsEqual(node.lastLayout.parentMaxWidth, parentMaxWidth);
!FloatUtil.floatsEqual(node.lastLayout.parentMaxWidth, parentMaxWidth) ||
!FloatUtil.floatsEqual(node.lastLayout.parentMaxHeight, parentMaxHeight);
}
internal static void layoutNode(CSSLayoutContext layoutContext, CSSNode node, float parentMaxWidth, CSSDirection? parentDirection)
internal static void layoutNode(CSSLayoutContext layoutContext, CSSNode node, float parentMaxWidth, float parentMaxHeight, CSSDirection? parentDirection)
{
if (needsRelayout(node, parentMaxWidth))
if (needsRelayout(node, parentMaxWidth, parentMaxHeight))
{
node.lastLayout.requestedWidth = node.layout.dimensions[DIMENSION_WIDTH];
node.lastLayout.requestedHeight = node.layout.dimensions[DIMENSION_HEIGHT];
node.lastLayout.parentMaxWidth = parentMaxWidth;
node.lastLayout.parentMaxHeight = parentMaxHeight;
layoutNodeImpl(layoutContext, node, parentMaxWidth, parentDirection);
layoutNodeImpl(layoutContext, node, parentMaxWidth, parentMaxHeight, parentDirection);
node.lastLayout.copy(node.layout);
}
else
@@ -236,7 +238,7 @@ namespace Facebook.CSSLayout
node.markHasNewLayout();
}
static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float parentMaxWidth, CSSDirection? parentDirection)
static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float parentMaxWidth, float parentMaxHeight, CSSDirection? parentDirection)
{
var childCount_ = node.getChildCount();
for (int i_ = 0; i_ < childCount_; i_++)
@@ -274,6 +276,7 @@ namespace Facebook.CSSLayout
// invocations during the layout calculation.
int childCount = node.getChildCount();
float paddingAndBorderAxisResolvedRow = ((node.style.padding.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.border.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis])) + (node.style.padding.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]) + node.style.border.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis])));
float paddingAndBorderAxisColumn = ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])));
if (isMeasureDefined(node)) {
boolean isResolvedRowDimDefined = !float.IsNaN(node.layout.dimensions[dim[resolvedRowAxis]]);
@@ -289,6 +292,17 @@ namespace Facebook.CSSLayout
}
width -= paddingAndBorderAxisResolvedRow;
float height = CSSConstants.Undefined;
if ((!float.IsNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
height = node.style.dimensions[DIMENSION_HEIGHT];
} else if (!float.IsNaN(node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]])) {
height = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]];
} else {
height = parentMaxHeight -
(node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]));
}
height -= ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])));
// We only need to give a dimension for the text if we haven't got any
// for it computed yet. It can either be from the style attribute or because
// the element is flexible.
@@ -301,7 +315,8 @@ namespace Facebook.CSSLayout
MeasureOutput measureDim = node.measure(
layoutContext.measureOutput,
width
width,
height
);
if (isRowUndefined) {
node.layout.dimensions[DIMENSION_WIDTH] = measureDim.width +
@@ -309,7 +324,7 @@ namespace Facebook.CSSLayout
}
if (isColumnUndefined) {
node.layout.dimensions[DIMENSION_HEIGHT] = measureDim.height +
((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])));
paddingAndBorderAxisColumn;
}
}
if (childCount == 0) {
@@ -390,6 +405,7 @@ namespace Facebook.CSSLayout
float crossDim = 0;
float maxWidth;
float maxHeight;
for (i = startLine; i < childCount; ++i) {
child = node.getChildAt(i);
child.lineIndex = linesCount;
@@ -470,6 +486,8 @@ namespace Facebook.CSSLayout
} else {
maxWidth = CSSConstants.Undefined;
maxHeight = CSSConstants.Undefined;
if (!isMainRowDirection) {
if ((!float.IsNaN(node.style.dimensions[dim[resolvedRowAxis]]) && node.style.dimensions[dim[resolvedRowAxis]] >= 0.0)) {
maxWidth = node.layout.dimensions[dim[resolvedRowAxis]] -
@@ -479,11 +497,20 @@ namespace Facebook.CSSLayout
(node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis])) -
paddingAndBorderAxisResolvedRow;
}
} else {
if ((!float.IsNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
maxHeight = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] -
paddingAndBorderAxisColumn;
} else {
maxHeight = parentMaxHeight -
(node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])) -
paddingAndBorderAxisColumn;
}
}
// This is the main recursive call. We layout non flexible children.
if (alreadyComputedNextLayout == 0) {
layoutNode(layoutContext, child, maxWidth, direction);
layoutNode(layoutContext, child, maxWidth, maxHeight, direction);
}
// Absolute positioned elements do not take part of the layout, so we
@@ -613,9 +640,18 @@ namespace Facebook.CSSLayout
(node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis])) -
paddingAndBorderAxisResolvedRow;
}
maxHeight = CSSConstants.Undefined;
if ((!float.IsNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
maxHeight = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] -
paddingAndBorderAxisColumn;
} else if (isMainRowDirection) {
maxHeight = parentMaxHeight -
(node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])) -
paddingAndBorderAxisColumn;
}
// And we recursively call the layout algorithm for this child
layoutNode(layoutContext, currentFlexChild, maxWidth, direction);
layoutNode(layoutContext, currentFlexChild, maxWidth, maxHeight, direction);
child = currentFlexChild;
currentFlexChild = currentFlexChild.nextFlexChild;