Setting min=max dimension is treated as setting dimension

Reviewed By: emilsjolander

Differential Revision: D4492395

fbshipit-source-id: 3f4293548399e006aa808b9586d24e77c7df1f21
This commit is contained in:
Antonio Corrado 2017-02-06 14:36:27 -08:00 committed by Facebook Github Bot
parent 61ae070444
commit 4c3f03e4c5
3 changed files with 97 additions and 93 deletions

View File

@ -202,7 +202,10 @@ void jni_YGNodeRemoveChild(alias_ref<jobject>, jlong nativePointer, jlong childP
YGNodeRemoveChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer)); YGNodeRemoveChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer));
} }
void jni_YGNodeCalculateLayout(alias_ref<jobject>, jlong nativePointer, jfloat width, jfloat height) { void jni_YGNodeCalculateLayout(alias_ref<jobject>,
jlong nativePointer,
jfloat width,
jfloat height) {
const YGNodeRef root = _jlong2YGNodeRef(nativePointer); const YGNodeRef root = _jlong2YGNodeRef(nativePointer);
YGNodeCalculateLayout(root, YGNodeCalculateLayout(root,
static_cast<float>(width), static_cast<float>(width),

View File

@ -15,26 +15,21 @@ YG_EXTERN_C_BEGIN
#define YGAlignCount 6 #define YGAlignCount 6
typedef YG_ENUM_BEGIN(YGAlign) { typedef YG_ENUM_BEGIN(YGAlign) {
YGAlignAuto, YGAlignAuto, YGAlignFlexStart, YGAlignCenter, YGAlignFlexEnd, YGAlignStretch, YGAlignBaseline,
YGAlignFlexStart, }
YGAlignCenter, YG_ENUM_END(YGAlign);
YGAlignFlexEnd,
YGAlignStretch,
YGAlignBaseline,
} YG_ENUM_END(YGAlign);
#define YGDimensionCount 2 #define YGDimensionCount 2
typedef YG_ENUM_BEGIN(YGDimension) { typedef YG_ENUM_BEGIN(YGDimension) {
YGDimensionWidth, YGDimensionWidth, YGDimensionHeight,
YGDimensionHeight, }
} YG_ENUM_END(YGDimension); YG_ENUM_END(YGDimension);
#define YGDirectionCount 3 #define YGDirectionCount 3
typedef YG_ENUM_BEGIN(YGDirection) { typedef YG_ENUM_BEGIN(YGDirection) {
YGDirectionInherit, YGDirectionInherit, YGDirectionLTR, YGDirectionRTL,
YGDirectionLTR, }
YGDirectionRTL, YG_ENUM_END(YGDirection);
} YG_ENUM_END(YGDirection);
#define YGDisplayCount 2 #define YGDisplayCount 2
typedef YG_ENUM_BEGIN(YGDisplay) { typedef YG_ENUM_BEGIN(YGDisplay) {
@ -44,87 +39,71 @@ typedef YG_ENUM_BEGIN(YGDisplay) {
#define YGEdgeCount 9 #define YGEdgeCount 9
typedef YG_ENUM_BEGIN(YGEdge) { typedef YG_ENUM_BEGIN(YGEdge) {
YGEdgeLeft, YGEdgeLeft, YGEdgeTop, YGEdgeRight, YGEdgeBottom, YGEdgeStart, YGEdgeEnd, YGEdgeHorizontal,
YGEdgeTop, YGEdgeVertical, YGEdgeAll,
YGEdgeRight, }
YGEdgeBottom, YG_ENUM_END(YGEdge);
YGEdgeStart,
YGEdgeEnd,
YGEdgeHorizontal,
YGEdgeVertical,
YGEdgeAll,
} YG_ENUM_END(YGEdge);
#define YGExperimentalFeatureCount 2 #define YGExperimentalFeatureCount 2
typedef YG_ENUM_BEGIN(YGExperimentalFeature) { typedef YG_ENUM_BEGIN(YGExperimentalFeature) {
YGExperimentalFeatureRounding, YGExperimentalFeatureRounding, YGExperimentalFeatureWebFlexBasis,
YGExperimentalFeatureWebFlexBasis, }
} YG_ENUM_END(YGExperimentalFeature); YG_ENUM_END(YGExperimentalFeature);
#define YGFlexDirectionCount 4 #define YGFlexDirectionCount 4
typedef YG_ENUM_BEGIN(YGFlexDirection) { typedef YG_ENUM_BEGIN(YGFlexDirection) {
YGFlexDirectionColumn, YGFlexDirectionColumn, YGFlexDirectionColumnReverse, YGFlexDirectionRow,
YGFlexDirectionColumnReverse, YGFlexDirectionRowReverse,
YGFlexDirectionRow, }
YGFlexDirectionRowReverse, YG_ENUM_END(YGFlexDirection);
} YG_ENUM_END(YGFlexDirection);
#define YGJustifyCount 5 #define YGJustifyCount 5
typedef YG_ENUM_BEGIN(YGJustify) { typedef YG_ENUM_BEGIN(YGJustify) {
YGJustifyFlexStart, YGJustifyFlexStart, YGJustifyCenter, YGJustifyFlexEnd, YGJustifySpaceBetween,
YGJustifyCenter, YGJustifySpaceAround,
YGJustifyFlexEnd, }
YGJustifySpaceBetween, YG_ENUM_END(YGJustify);
YGJustifySpaceAround,
} YG_ENUM_END(YGJustify);
#define YGLogLevelCount 5 #define YGLogLevelCount 5
typedef YG_ENUM_BEGIN(YGLogLevel) { typedef YG_ENUM_BEGIN(YGLogLevel) {
YGLogLevelError, YGLogLevelError, YGLogLevelWarn, YGLogLevelInfo, YGLogLevelDebug, YGLogLevelVerbose,
YGLogLevelWarn, }
YGLogLevelInfo, YG_ENUM_END(YGLogLevel);
YGLogLevelDebug,
YGLogLevelVerbose,
} YG_ENUM_END(YGLogLevel);
#define YGMeasureModeCount 3 #define YGMeasureModeCount 3
typedef YG_ENUM_BEGIN(YGMeasureMode) { typedef YG_ENUM_BEGIN(YGMeasureMode) {
YGMeasureModeUndefined, YGMeasureModeUndefined, YGMeasureModeExactly, YGMeasureModeAtMost,
YGMeasureModeExactly, }
YGMeasureModeAtMost, YG_ENUM_END(YGMeasureMode);
} YG_ENUM_END(YGMeasureMode);
#define YGOverflowCount 3 #define YGOverflowCount 3
typedef YG_ENUM_BEGIN(YGOverflow) { typedef YG_ENUM_BEGIN(YGOverflow) {
YGOverflowVisible, YGOverflowVisible, YGOverflowHidden, YGOverflowScroll,
YGOverflowHidden, }
YGOverflowScroll, YG_ENUM_END(YGOverflow);
} YG_ENUM_END(YGOverflow);
#define YGPositionTypeCount 2 #define YGPositionTypeCount 2
typedef YG_ENUM_BEGIN(YGPositionType) { typedef YG_ENUM_BEGIN(YGPositionType) {
YGPositionTypeRelative, YGPositionTypeRelative, YGPositionTypeAbsolute,
YGPositionTypeAbsolute, }
} YG_ENUM_END(YGPositionType); YG_ENUM_END(YGPositionType);
#define YGPrintOptionsCount 3 #define YGPrintOptionsCount 3
typedef YG_ENUM_BEGIN(YGPrintOptions) { typedef YG_ENUM_BEGIN(YGPrintOptions) {
YGPrintOptionsLayout = 1, YGPrintOptionsLayout = 1, YGPrintOptionsStyle = 2, YGPrintOptionsChildren = 4,
YGPrintOptionsStyle = 2, }
YGPrintOptionsChildren = 4, YG_ENUM_END(YGPrintOptions);
} YG_ENUM_END(YGPrintOptions);
#define YGUnitCount 3 #define YGUnitCount 3
typedef YG_ENUM_BEGIN(YGUnit) { typedef YG_ENUM_BEGIN(YGUnit) {
YGUnitUndefined, YGUnitUndefined, YGUnitPixel, YGUnitPercent,
YGUnitPixel, }
YGUnitPercent, YG_ENUM_END(YGUnit);
} YG_ENUM_END(YGUnit);
#define YGWrapCount 2 #define YGWrapCount 2
typedef YG_ENUM_BEGIN(YGWrap) { typedef YG_ENUM_BEGIN(YGWrap) {
YGWrapNoWrap, YGWrapNoWrap, YGWrapWrap,
YGWrapWrap, }
} YG_ENUM_END(YGWrap); YG_ENUM_END(YGWrap);
YG_EXTERN_C_END YG_EXTERN_C_END

View File

@ -111,6 +111,8 @@ typedef struct YGNode {
bool isDirty; bool isDirty;
bool hasNewLayout; bool hasNewLayout;
YGValue resolvedDimensions[2];
} YGNode; } YGNode;
#define YG_UNDEFINED_VALUES \ #define YG_UNDEFINED_VALUES \
@ -136,6 +138,7 @@ static YGNode gYGNodeDefaults = {
.children = NULL, .children = NULL,
.hasNewLayout = true, .hasNewLayout = true,
.isDirty = false, .isDirty = false,
.resolvedDimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT,
.style = .style =
{ {
@ -636,6 +639,19 @@ static inline bool YGValueEqual(const YGValue a, const YGValue b) {
return fabs(a.value - b.value) < 0.0001f; return fabs(a.value - b.value) < 0.0001f;
} }
static inline void YGResolveDimensions(YGNodeRef node) {
for (YGDimension dim = YGDimensionWidth; dim <= YGDimensionHeight; dim++) {
if (node->style.dimensions[dim].unit != YGUnitUndefined) {
node->resolvedDimensions[dim] = node->style.dimensions[dim];
} else {
if (node->style.maxDimensions[dim].unit != YGUnitUndefined &&
YGValueEqual(node->style.maxDimensions[dim], node->style.minDimensions[dim])) {
node->resolvedDimensions[dim] = node->style.maxDimensions[dim];
}
}
}
}
static inline bool YGFloatsEqual(const float a, const float b) { static inline bool YGFloatsEqual(const float a, const float b) {
if (YGFloatIsUndefined(a)) { if (YGFloatIsUndefined(a)) {
return YGFloatIsUndefined(b); return YGFloatIsUndefined(b);
@ -1081,11 +1097,11 @@ static inline float YGNodeDimWithMargin(const YGNodeRef node,
static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node, static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node,
const YGFlexDirection axis, const YGFlexDirection axis,
const float parentSize) { const float parentSize) {
return !( return !(node->resolvedDimensions[dim[axis]].unit == YGUnitUndefined ||
node->style.dimensions[dim[axis]].unit == YGUnitUndefined || (node->resolvedDimensions[dim[axis]].unit == YGUnitPixel &&
(node->style.dimensions[dim[axis]].unit == YGUnitPixel && node->resolvedDimensions[dim[axis]].value < 0.0f) ||
node->style.dimensions[dim[axis]].value < 0.0f) || (node->resolvedDimensions[dim[axis]].unit == YGUnitPercent &&
(node->style.dimensions[dim[axis]].unit == YGUnitPercent && YGFloatIsUndefined(parentSize))); YGFloatIsUndefined(parentSize)));
} }
static inline bool YGNodeIsLayoutDimDefined(const YGNodeRef node, const YGFlexDirection axis) { static inline bool YGNodeIsLayoutDimDefined(const YGNodeRef node, const YGFlexDirection axis) {
@ -1151,13 +1167,14 @@ static float YGNodeBoundAxisWithinMinAndMax(const YGNodeRef node,
const float axisSize) { const float axisSize) {
float min = YGUndefined; float min = YGUndefined;
float max = YGUndefined; float max = YGUndefined;
if (!YGNodeIsStyleDimDefined(node, axis, axisSize)) {
if (YGFlexDirectionIsColumn(axis)) { if (YGFlexDirectionIsColumn(axis)) {
min = YGValueResolve(&node->style.minDimensions[YGDimensionHeight], axisSize); min = YGValueResolve(&node->style.minDimensions[YGDimensionHeight], axisSize);
max = YGValueResolve(&node->style.maxDimensions[YGDimensionHeight], axisSize); max = YGValueResolve(&node->style.maxDimensions[YGDimensionHeight], axisSize);
} else if (YGFlexDirectionIsRow(axis)) { } else if (YGFlexDirectionIsRow(axis)) {
min = YGValueResolve(&node->style.minDimensions[YGDimensionWidth], axisSize); min = YGValueResolve(&node->style.minDimensions[YGDimensionWidth], axisSize);
max = YGValueResolve(&node->style.maxDimensions[YGDimensionWidth], axisSize); max = YGValueResolve(&node->style.maxDimensions[YGDimensionWidth], axisSize);
}
} }
float boundValue = value; float boundValue = value;
@ -1272,12 +1289,12 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
} else if (isMainAxisRow && isRowStyleDimDefined) { } else if (isMainAxisRow && isRowStyleDimDefined) {
// The width is definite, so use that as the flex basis. // The width is definite, so use that as the flex basis.
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(YGValueResolve(&child->style.dimensions[YGDimensionWidth], parentWidth), fmaxf(YGValueResolve(&child->resolvedDimensions[YGDimensionWidth], parentWidth),
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, parentWidth)); YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, parentWidth));
} else if (!isMainAxisRow && isColumnStyleDimDefined) { } else if (!isMainAxisRow && isColumnStyleDimDefined) {
// The height is definite, so use that as the flex basis. // The height is definite, so use that as the flex basis.
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(YGValueResolve(&child->style.dimensions[YGDimensionHeight], parentHeight), fmaxf(YGValueResolve(&child->resolvedDimensions[YGDimensionHeight], parentHeight),
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn, parentWidth)); YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn, parentWidth));
} else { } else {
// Compute the flex basis and hypothetical main size (i.e. the clamped // Compute the flex basis and hypothetical main size (i.e. the clamped
@ -1292,12 +1309,12 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
if (isRowStyleDimDefined) { if (isRowStyleDimDefined) {
childWidth = childWidth =
YGValueResolve(&child->style.dimensions[YGDimensionWidth], parentWidth) + marginRow; YGValueResolve(&child->resolvedDimensions[YGDimensionWidth], parentWidth) + marginRow;
childWidthMeasureMode = YGMeasureModeExactly; childWidthMeasureMode = YGMeasureModeExactly;
} }
if (isColumnStyleDimDefined) { if (isColumnStyleDimDefined) {
childHeight = childHeight = YGValueResolve(&child->resolvedDimensions[YGDimensionHeight], parentHeight) +
YGValueResolve(&child->style.dimensions[YGDimensionHeight], parentHeight) + marginColumn; marginColumn;
childHeightMeasureMode = YGMeasureModeExactly; childHeightMeasureMode = YGMeasureModeExactly;
} }
@ -1396,7 +1413,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
const float marginColumn = YGNodeMarginForAxis(child, YGFlexDirectionColumn, width); const float marginColumn = YGNodeMarginForAxis(child, YGFlexDirectionColumn, width);
if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) { if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) {
childWidth = YGValueResolve(&child->style.dimensions[YGDimensionWidth], width) + marginRow; childWidth = YGValueResolve(&child->resolvedDimensions[YGDimensionWidth], width) + marginRow;
} else { } else {
// If the child doesn't have a specified width, compute the width based // If the child doesn't have a specified width, compute the width based
// on the left/right // on the left/right
@ -1414,7 +1431,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) { if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) {
childHeight = childHeight =
YGValueResolve(&child->style.dimensions[YGDimensionHeight], height) + marginColumn; YGValueResolve(&child->resolvedDimensions[YGDimensionHeight], height) + marginColumn;
} else { } else {
// If the child doesn't have a specified height, compute the height // If the child doesn't have a specified height, compute the height
// based on the top/bottom // based on the top/bottom
@ -1949,6 +1966,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
child->isDirty = false; child->isDirty = false;
continue; continue;
} }
YGResolveDimensions(child);
if (performLayout) { if (performLayout) {
// Set the initial position (relative to the parent). // Set the initial position (relative to the parent).
const YGDirection childDirection = YGNodeResolveDirection(child, direction); const YGDirection childDirection = YGNodeResolveDirection(child, direction);
@ -2282,9 +2300,10 @@ static void YGNodelayoutImpl(const YGNodeRef node,
childHeightMeasureMode = childHeightMeasureMode =
YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined : YGMeasureModeAtMost; YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined : YGMeasureModeAtMost;
} else { } else {
childHeight = YGValueResolve(&currentRelativeChild->style.dimensions[YGDimensionHeight], childHeight =
availableInnerHeight) + YGValueResolve(&currentRelativeChild->resolvedDimensions[YGDimensionHeight],
marginColumn; availableInnerHeight) +
marginColumn;
childHeightMeasureMode = childHeightMeasureMode =
YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined : YGMeasureModeExactly; YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined : YGMeasureModeExactly;
} }
@ -2307,7 +2326,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
childWidthMeasureMode = childWidthMeasureMode =
YGFloatIsUndefined(childWidth) ? YGMeasureModeUndefined : YGMeasureModeAtMost; YGFloatIsUndefined(childWidth) ? YGMeasureModeUndefined : YGMeasureModeAtMost;
} else { } else {
childWidth = YGValueResolve(&currentRelativeChild->style.dimensions[YGDimensionWidth], childWidth = YGValueResolve(&currentRelativeChild->resolvedDimensions[YGDimensionWidth],
availableInnerWidth) + availableInnerWidth) +
marginRow; marginRow;
childWidthMeasureMode = childWidthMeasureMode =
@ -3164,10 +3183,12 @@ void YGNodeCalculateLayout(const YGNodeRef node,
YGMeasureMode widthMeasureMode = YGMeasureModeUndefined; YGMeasureMode widthMeasureMode = YGMeasureModeUndefined;
YGMeasureMode heightMeasureMode = YGMeasureModeUndefined; YGMeasureMode heightMeasureMode = YGMeasureModeUndefined;
YGResolveDimensions(node);
if (!YGFloatIsUndefined(width)) { if (!YGFloatIsUndefined(width)) {
widthMeasureMode = YGMeasureModeExactly; widthMeasureMode = YGMeasureModeExactly;
} else if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, availableWidth)) { } else if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, availableWidth)) {
width = YGValueResolve(&node->style.dimensions[dim[YGFlexDirectionRow]], availableWidth) + width = YGValueResolve(&node->resolvedDimensions[dim[YGFlexDirectionRow]], availableWidth) +
YGNodeMarginForAxis(node, YGFlexDirectionRow, availableWidth); YGNodeMarginForAxis(node, YGFlexDirectionRow, availableWidth);
widthMeasureMode = YGMeasureModeExactly; widthMeasureMode = YGMeasureModeExactly;
} else if (YGValueResolve(&node->style.maxDimensions[YGDimensionWidth], availableWidth) >= 0.0f) { } else if (YGValueResolve(&node->style.maxDimensions[YGDimensionWidth], availableWidth) >= 0.0f) {
@ -3178,8 +3199,9 @@ void YGNodeCalculateLayout(const YGNodeRef node,
if (!YGFloatIsUndefined(height)) { if (!YGFloatIsUndefined(height)) {
heightMeasureMode = YGMeasureModeExactly; heightMeasureMode = YGMeasureModeExactly;
} else if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, availableHeight)) { } else if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, availableHeight)) {
height = YGValueResolve(&node->style.dimensions[dim[YGFlexDirectionColumn]], availableHeight) + height =
YGNodeMarginForAxis(node, YGFlexDirectionColumn, availableWidth); YGValueResolve(&node->resolvedDimensions[dim[YGFlexDirectionColumn]], availableHeight) +
YGNodeMarginForAxis(node, YGFlexDirectionColumn, availableWidth);
heightMeasureMode = YGMeasureModeExactly; heightMeasureMode = YGMeasureModeExactly;
} else if (YGValueResolve(&node->style.maxDimensions[YGDimensionHeight], availableHeight) >= } else if (YGValueResolve(&node->style.maxDimensions[YGDimensionHeight], availableHeight) >=
0.0f) { 0.0f) {