diff --git a/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp b/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp index 19a7210a7..8476bc1ba 100644 --- a/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp +++ b/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp @@ -202,7 +202,10 @@ void jni_YGNodeRemoveChild(alias_ref, jlong nativePointer, jlong childP YGNodeRemoveChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer)); } -void jni_YGNodeCalculateLayout(alias_ref, jlong nativePointer, jfloat width, jfloat height) { +void jni_YGNodeCalculateLayout(alias_ref, + jlong nativePointer, + jfloat width, + jfloat height) { const YGNodeRef root = _jlong2YGNodeRef(nativePointer); YGNodeCalculateLayout(root, static_cast(width), diff --git a/ReactCommon/yoga/yoga/YGEnums.h b/ReactCommon/yoga/yoga/YGEnums.h index 3e65e1035..b4efc9cc5 100644 --- a/ReactCommon/yoga/yoga/YGEnums.h +++ b/ReactCommon/yoga/yoga/YGEnums.h @@ -15,26 +15,21 @@ YG_EXTERN_C_BEGIN #define YGAlignCount 6 typedef YG_ENUM_BEGIN(YGAlign) { - YGAlignAuto, - YGAlignFlexStart, - YGAlignCenter, - YGAlignFlexEnd, - YGAlignStretch, - YGAlignBaseline, -} YG_ENUM_END(YGAlign); + YGAlignAuto, YGAlignFlexStart, YGAlignCenter, YGAlignFlexEnd, YGAlignStretch, YGAlignBaseline, +} +YG_ENUM_END(YGAlign); #define YGDimensionCount 2 typedef YG_ENUM_BEGIN(YGDimension) { - YGDimensionWidth, - YGDimensionHeight, -} YG_ENUM_END(YGDimension); + YGDimensionWidth, YGDimensionHeight, +} +YG_ENUM_END(YGDimension); #define YGDirectionCount 3 typedef YG_ENUM_BEGIN(YGDirection) { - YGDirectionInherit, - YGDirectionLTR, - YGDirectionRTL, -} YG_ENUM_END(YGDirection); + YGDirectionInherit, YGDirectionLTR, YGDirectionRTL, +} +YG_ENUM_END(YGDirection); #define YGDisplayCount 2 typedef YG_ENUM_BEGIN(YGDisplay) { @@ -44,87 +39,71 @@ typedef YG_ENUM_BEGIN(YGDisplay) { #define YGEdgeCount 9 typedef YG_ENUM_BEGIN(YGEdge) { - YGEdgeLeft, - YGEdgeTop, - YGEdgeRight, - YGEdgeBottom, - YGEdgeStart, - YGEdgeEnd, - YGEdgeHorizontal, - YGEdgeVertical, - YGEdgeAll, -} YG_ENUM_END(YGEdge); + YGEdgeLeft, YGEdgeTop, YGEdgeRight, YGEdgeBottom, YGEdgeStart, YGEdgeEnd, YGEdgeHorizontal, + YGEdgeVertical, YGEdgeAll, +} +YG_ENUM_END(YGEdge); #define YGExperimentalFeatureCount 2 typedef YG_ENUM_BEGIN(YGExperimentalFeature) { - YGExperimentalFeatureRounding, - YGExperimentalFeatureWebFlexBasis, -} YG_ENUM_END(YGExperimentalFeature); + YGExperimentalFeatureRounding, YGExperimentalFeatureWebFlexBasis, +} +YG_ENUM_END(YGExperimentalFeature); #define YGFlexDirectionCount 4 typedef YG_ENUM_BEGIN(YGFlexDirection) { - YGFlexDirectionColumn, - YGFlexDirectionColumnReverse, - YGFlexDirectionRow, - YGFlexDirectionRowReverse, -} YG_ENUM_END(YGFlexDirection); + YGFlexDirectionColumn, YGFlexDirectionColumnReverse, YGFlexDirectionRow, + YGFlexDirectionRowReverse, +} +YG_ENUM_END(YGFlexDirection); #define YGJustifyCount 5 typedef YG_ENUM_BEGIN(YGJustify) { - YGJustifyFlexStart, - YGJustifyCenter, - YGJustifyFlexEnd, - YGJustifySpaceBetween, - YGJustifySpaceAround, -} YG_ENUM_END(YGJustify); + YGJustifyFlexStart, YGJustifyCenter, YGJustifyFlexEnd, YGJustifySpaceBetween, + YGJustifySpaceAround, +} +YG_ENUM_END(YGJustify); #define YGLogLevelCount 5 typedef YG_ENUM_BEGIN(YGLogLevel) { - YGLogLevelError, - YGLogLevelWarn, - YGLogLevelInfo, - YGLogLevelDebug, - YGLogLevelVerbose, -} YG_ENUM_END(YGLogLevel); + YGLogLevelError, YGLogLevelWarn, YGLogLevelInfo, YGLogLevelDebug, YGLogLevelVerbose, +} +YG_ENUM_END(YGLogLevel); #define YGMeasureModeCount 3 typedef YG_ENUM_BEGIN(YGMeasureMode) { - YGMeasureModeUndefined, - YGMeasureModeExactly, - YGMeasureModeAtMost, -} YG_ENUM_END(YGMeasureMode); + YGMeasureModeUndefined, YGMeasureModeExactly, YGMeasureModeAtMost, +} +YG_ENUM_END(YGMeasureMode); #define YGOverflowCount 3 typedef YG_ENUM_BEGIN(YGOverflow) { - YGOverflowVisible, - YGOverflowHidden, - YGOverflowScroll, -} YG_ENUM_END(YGOverflow); + YGOverflowVisible, YGOverflowHidden, YGOverflowScroll, +} +YG_ENUM_END(YGOverflow); #define YGPositionTypeCount 2 typedef YG_ENUM_BEGIN(YGPositionType) { - YGPositionTypeRelative, - YGPositionTypeAbsolute, -} YG_ENUM_END(YGPositionType); + YGPositionTypeRelative, YGPositionTypeAbsolute, +} +YG_ENUM_END(YGPositionType); #define YGPrintOptionsCount 3 typedef YG_ENUM_BEGIN(YGPrintOptions) { - YGPrintOptionsLayout = 1, - YGPrintOptionsStyle = 2, - YGPrintOptionsChildren = 4, -} YG_ENUM_END(YGPrintOptions); + YGPrintOptionsLayout = 1, YGPrintOptionsStyle = 2, YGPrintOptionsChildren = 4, +} +YG_ENUM_END(YGPrintOptions); #define YGUnitCount 3 typedef YG_ENUM_BEGIN(YGUnit) { - YGUnitUndefined, - YGUnitPixel, - YGUnitPercent, -} YG_ENUM_END(YGUnit); + YGUnitUndefined, YGUnitPixel, YGUnitPercent, +} +YG_ENUM_END(YGUnit); #define YGWrapCount 2 typedef YG_ENUM_BEGIN(YGWrap) { - YGWrapNoWrap, - YGWrapWrap, -} YG_ENUM_END(YGWrap); + YGWrapNoWrap, YGWrapWrap, +} +YG_ENUM_END(YGWrap); YG_EXTERN_C_END diff --git a/ReactCommon/yoga/yoga/Yoga.c b/ReactCommon/yoga/yoga/Yoga.c index 4ab537a51..7e942d48b 100644 --- a/ReactCommon/yoga/yoga/Yoga.c +++ b/ReactCommon/yoga/yoga/Yoga.c @@ -111,6 +111,8 @@ typedef struct YGNode { bool isDirty; bool hasNewLayout; + + YGValue resolvedDimensions[2]; } YGNode; #define YG_UNDEFINED_VALUES \ @@ -136,6 +138,7 @@ static YGNode gYGNodeDefaults = { .children = NULL, .hasNewLayout = true, .isDirty = false, + .resolvedDimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT, .style = { @@ -636,6 +639,19 @@ static inline bool YGValueEqual(const YGValue a, const YGValue b) { 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) { if (YGFloatIsUndefined(a)) { return YGFloatIsUndefined(b); @@ -1081,11 +1097,11 @@ static inline float YGNodeDimWithMargin(const YGNodeRef node, static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node, const YGFlexDirection axis, const float parentSize) { - return !( - node->style.dimensions[dim[axis]].unit == YGUnitUndefined || - (node->style.dimensions[dim[axis]].unit == YGUnitPixel && - node->style.dimensions[dim[axis]].value < 0.0f) || - (node->style.dimensions[dim[axis]].unit == YGUnitPercent && YGFloatIsUndefined(parentSize))); + return !(node->resolvedDimensions[dim[axis]].unit == YGUnitUndefined || + (node->resolvedDimensions[dim[axis]].unit == YGUnitPixel && + node->resolvedDimensions[dim[axis]].value < 0.0f) || + (node->resolvedDimensions[dim[axis]].unit == YGUnitPercent && + YGFloatIsUndefined(parentSize))); } static inline bool YGNodeIsLayoutDimDefined(const YGNodeRef node, const YGFlexDirection axis) { @@ -1151,13 +1167,14 @@ static float YGNodeBoundAxisWithinMinAndMax(const YGNodeRef node, const float axisSize) { float min = YGUndefined; float max = YGUndefined; - - if (YGFlexDirectionIsColumn(axis)) { - min = YGValueResolve(&node->style.minDimensions[YGDimensionHeight], axisSize); - max = YGValueResolve(&node->style.maxDimensions[YGDimensionHeight], axisSize); - } else if (YGFlexDirectionIsRow(axis)) { - min = YGValueResolve(&node->style.minDimensions[YGDimensionWidth], axisSize); - max = YGValueResolve(&node->style.maxDimensions[YGDimensionWidth], axisSize); + if (!YGNodeIsStyleDimDefined(node, axis, axisSize)) { + if (YGFlexDirectionIsColumn(axis)) { + min = YGValueResolve(&node->style.minDimensions[YGDimensionHeight], axisSize); + max = YGValueResolve(&node->style.maxDimensions[YGDimensionHeight], axisSize); + } else if (YGFlexDirectionIsRow(axis)) { + min = YGValueResolve(&node->style.minDimensions[YGDimensionWidth], axisSize); + max = YGValueResolve(&node->style.maxDimensions[YGDimensionWidth], axisSize); + } } float boundValue = value; @@ -1272,12 +1289,12 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, } else if (isMainAxisRow && isRowStyleDimDefined) { // The width is definite, so use that as the flex basis. child->layout.computedFlexBasis = - fmaxf(YGValueResolve(&child->style.dimensions[YGDimensionWidth], parentWidth), + fmaxf(YGValueResolve(&child->resolvedDimensions[YGDimensionWidth], parentWidth), YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, parentWidth)); } else if (!isMainAxisRow && isColumnStyleDimDefined) { // The height is definite, so use that as the flex basis. child->layout.computedFlexBasis = - fmaxf(YGValueResolve(&child->style.dimensions[YGDimensionHeight], parentHeight), + fmaxf(YGValueResolve(&child->resolvedDimensions[YGDimensionHeight], parentHeight), YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn, parentWidth)); } else { // Compute the flex basis and hypothetical main size (i.e. the clamped @@ -1292,12 +1309,12 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, if (isRowStyleDimDefined) { childWidth = - YGValueResolve(&child->style.dimensions[YGDimensionWidth], parentWidth) + marginRow; + YGValueResolve(&child->resolvedDimensions[YGDimensionWidth], parentWidth) + marginRow; childWidthMeasureMode = YGMeasureModeExactly; } if (isColumnStyleDimDefined) { - childHeight = - YGValueResolve(&child->style.dimensions[YGDimensionHeight], parentHeight) + marginColumn; + childHeight = YGValueResolve(&child->resolvedDimensions[YGDimensionHeight], parentHeight) + + marginColumn; childHeightMeasureMode = YGMeasureModeExactly; } @@ -1396,7 +1413,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, const float marginColumn = YGNodeMarginForAxis(child, YGFlexDirectionColumn, width); if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) { - childWidth = YGValueResolve(&child->style.dimensions[YGDimensionWidth], width) + marginRow; + childWidth = YGValueResolve(&child->resolvedDimensions[YGDimensionWidth], width) + marginRow; } else { // If the child doesn't have a specified width, compute the width based // on the left/right @@ -1414,7 +1431,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) { childHeight = - YGValueResolve(&child->style.dimensions[YGDimensionHeight], height) + marginColumn; + YGValueResolve(&child->resolvedDimensions[YGDimensionHeight], height) + marginColumn; } else { // If the child doesn't have a specified height, compute the height // based on the top/bottom @@ -1949,6 +1966,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, child->isDirty = false; continue; } + YGResolveDimensions(child); if (performLayout) { // Set the initial position (relative to the parent). const YGDirection childDirection = YGNodeResolveDirection(child, direction); @@ -2282,9 +2300,10 @@ static void YGNodelayoutImpl(const YGNodeRef node, childHeightMeasureMode = YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined : YGMeasureModeAtMost; } else { - childHeight = YGValueResolve(¤tRelativeChild->style.dimensions[YGDimensionHeight], - availableInnerHeight) + - marginColumn; + childHeight = + YGValueResolve(¤tRelativeChild->resolvedDimensions[YGDimensionHeight], + availableInnerHeight) + + marginColumn; childHeightMeasureMode = YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined : YGMeasureModeExactly; } @@ -2307,7 +2326,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, childWidthMeasureMode = YGFloatIsUndefined(childWidth) ? YGMeasureModeUndefined : YGMeasureModeAtMost; } else { - childWidth = YGValueResolve(¤tRelativeChild->style.dimensions[YGDimensionWidth], + childWidth = YGValueResolve(¤tRelativeChild->resolvedDimensions[YGDimensionWidth], availableInnerWidth) + marginRow; childWidthMeasureMode = @@ -3164,10 +3183,12 @@ void YGNodeCalculateLayout(const YGNodeRef node, YGMeasureMode widthMeasureMode = YGMeasureModeUndefined; YGMeasureMode heightMeasureMode = YGMeasureModeUndefined; + YGResolveDimensions(node); + if (!YGFloatIsUndefined(width)) { widthMeasureMode = YGMeasureModeExactly; } 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); widthMeasureMode = YGMeasureModeExactly; } else if (YGValueResolve(&node->style.maxDimensions[YGDimensionWidth], availableWidth) >= 0.0f) { @@ -3178,8 +3199,9 @@ void YGNodeCalculateLayout(const YGNodeRef node, if (!YGFloatIsUndefined(height)) { heightMeasureMode = YGMeasureModeExactly; } else if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, availableHeight)) { - height = YGValueResolve(&node->style.dimensions[dim[YGFlexDirectionColumn]], availableHeight) + - YGNodeMarginForAxis(node, YGFlexDirectionColumn, availableWidth); + height = + YGValueResolve(&node->resolvedDimensions[dim[YGFlexDirectionColumn]], availableHeight) + + YGNodeMarginForAxis(node, YGFlexDirectionColumn, availableWidth); heightMeasureMode = YGMeasureModeExactly; } else if (YGValueResolve(&node->style.maxDimensions[YGDimensionHeight], availableHeight) >= 0.0f) {