From fdb742a602aa162d11df38020bbf66d161086d6b Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Thu, 9 Nov 2023 07:59:18 -0800 Subject: [PATCH] Use CSS terminology for box sizing Summary: Yoga passes `MeasureMode`/`YGMeasureMode` to express constraints in how a box should be measured, given definite or indefinite available space. This is modeled after Android [MeasureSpec](https://developer.android.com/reference/android/view/View.MeasureSpec), with a table above `calculateLayoutImpl()` explaining the CSS terms they map to. This can be confusing when flipping between the spec, and code. This switches internal usages to the CSS terms, but leaves around `YGMeasureMode` since it is the public API passed to measure functions. Differential Revision: D51068417 fbshipit-source-id: 4031e2a14fa96b4a81009933750f4b5d44d9f9f8 --- yoga/YGNode.cpp | 8 +- yoga/YGNode.h | 13 + yoga/algorithm/Cache.cpp | 70 ++--- yoga/algorithm/Cache.h | 10 +- yoga/algorithm/CalculateLayout.cpp | 428 ++++++++++++++--------------- yoga/algorithm/SizingMode.h | 73 +++++ yoga/node/CachedMeasurement.h | 10 +- 7 files changed, 346 insertions(+), 266 deletions(-) create mode 100644 yoga/algorithm/SizingMode.h diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 38d8f31916..50cfd98f20 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -351,13 +351,13 @@ bool YGNodeCanUseCachedMeasurement( float marginColumn, YGConfigRef config) { return yoga::canUseCachedMeasurement( - scopedEnum(widthMode), + sizingMode(scopedEnum(widthMode)), availableWidth, - scopedEnum(heightMode), + sizingMode(scopedEnum(heightMode)), availableHeight, - scopedEnum(lastWidthMode), + sizingMode(scopedEnum(lastWidthMode)), lastAvailableWidth, - scopedEnum(lastHeightMode), + sizingMode(scopedEnum(lastHeightMode)), lastAvailableHeight, lastComputedWidth, lastComputedHeight, diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 01ee143fd5..b66dd1bf1f 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -186,6 +186,19 @@ typedef struct YGSize { } YGSize; /** + * Returns the computed dimensions of the node, following the contraints of + * `widthMode` and `heightMode`: + * + * YGMeasureModeUndefined: The parent has not imposed any constraint on the + * child. It can be whatever size it wants. + * + * YGMeasureModeAtMost: The child can be as large as it wants up to the + * specified size. + * + * YGMeasureModeExactly: The parent has determined an exact size for the + * child. The child is going to be given those bounds regardless of how big it + * wants to be. + * * @returns the size of the leaf node, measured under the given contraints */ typedef YGSize (*YGMeasureFunc)( diff --git a/yoga/algorithm/Cache.cpp b/yoga/algorithm/Cache.cpp index 7496e873e0..9154fc6ce9 100644 --- a/yoga/algorithm/Cache.cpp +++ b/yoga/algorithm/Cache.cpp @@ -12,51 +12,52 @@ namespace facebook::yoga { static inline bool sizeIsExactAndMatchesOldMeasuredSize( - MeasureMode sizeMode, + SizingMode sizeMode, float size, float lastComputedSize) { - return sizeMode == MeasureMode::Exactly && + return sizeMode == SizingMode::StretchFit && yoga::inexactEquals(size, lastComputedSize); } -static inline bool oldSizeIsUnspecifiedAndStillFits( - MeasureMode sizeMode, +static inline bool oldSizeIsMaxContentAndStillFits( + SizingMode sizeMode, float size, - MeasureMode lastSizeMode, + SizingMode lastSizeMode, float lastComputedSize) { - return sizeMode == MeasureMode::AtMost && - lastSizeMode == MeasureMode::Undefined && + return sizeMode == SizingMode::FitContent && + lastSizeMode == SizingMode::MaxContent && (size >= lastComputedSize || yoga::inexactEquals(size, lastComputedSize)); } -static inline bool newMeasureSizeIsStricterAndStillValid( - MeasureMode sizeMode, +static inline bool newSizeIsStricterAndStillValid( + SizingMode sizeMode, float size, - MeasureMode lastSizeMode, + SizingMode lastSizeMode, float lastSize, float lastComputedSize) { - return lastSizeMode == MeasureMode::AtMost && - sizeMode == MeasureMode::AtMost && !std::isnan(lastSize) && - !std::isnan(size) && !std::isnan(lastComputedSize) && lastSize > size && + return lastSizeMode == SizingMode::FitContent && + sizeMode == SizingMode::FitContent && yoga::isDefined(lastSize) && + yoga::isDefined(size) && yoga::isDefined(lastComputedSize) && + lastSize > size && (lastComputedSize <= size || yoga::inexactEquals(size, lastComputedSize)); } bool canUseCachedMeasurement( - const MeasureMode widthMode, + const SizingMode widthMode, const float availableWidth, - const MeasureMode heightMode, + const SizingMode heightMode, const float availableHeight, - const MeasureMode lastWidthMode, + const SizingMode lastWidthMode, const float lastAvailableWidth, - const MeasureMode lastHeightMode, + const SizingMode lastHeightMode, const float lastAvailableHeight, const float lastComputedWidth, const float lastComputedHeight, const float marginRow, const float marginColumn, const yoga::Config* const config) { - if ((!std::isnan(lastComputedHeight) && lastComputedHeight < 0) || - (!std::isnan(lastComputedWidth) && lastComputedWidth < 0)) { + if ((yoga::isDefined(lastComputedHeight) && lastComputedHeight < 0) || + ((yoga::isDefined(lastComputedWidth)) && lastComputedWidth < 0)) { return false; } @@ -87,33 +88,32 @@ bool canUseCachedMeasurement( hasSameWidthSpec || sizeIsExactAndMatchesOldMeasuredSize( widthMode, availableWidth - marginRow, lastComputedWidth) || - oldSizeIsUnspecifiedAndStillFits( + oldSizeIsMaxContentAndStillFits( widthMode, availableWidth - marginRow, lastWidthMode, lastComputedWidth) || - newMeasureSizeIsStricterAndStillValid( + newSizeIsStricterAndStillValid( widthMode, availableWidth - marginRow, lastWidthMode, lastAvailableWidth, lastComputedWidth); - const bool heightIsCompatible = - hasSameHeightSpec || + const bool heightIsCompatible = hasSameHeightSpec || sizeIsExactAndMatchesOldMeasuredSize( - heightMode, availableHeight - marginColumn, lastComputedHeight) || - oldSizeIsUnspecifiedAndStillFits( - heightMode, - availableHeight - marginColumn, - lastHeightMode, - lastComputedHeight) || - newMeasureSizeIsStricterAndStillValid( - heightMode, - availableHeight - marginColumn, - lastHeightMode, - lastAvailableHeight, - lastComputedHeight); + heightMode, + availableHeight - marginColumn, + lastComputedHeight) || + oldSizeIsMaxContentAndStillFits(heightMode, + availableHeight - marginColumn, + lastHeightMode, + lastComputedHeight) || + newSizeIsStricterAndStillValid(heightMode, + availableHeight - marginColumn, + lastHeightMode, + lastAvailableHeight, + lastComputedHeight); return widthIsCompatible && heightIsCompatible; } diff --git a/yoga/algorithm/Cache.h b/yoga/algorithm/Cache.h index 31b91d5f79..f8857eaf35 100644 --- a/yoga/algorithm/Cache.h +++ b/yoga/algorithm/Cache.h @@ -7,19 +7,19 @@ #pragma once +#include #include -#include namespace facebook::yoga { bool canUseCachedMeasurement( - MeasureMode widthMode, + SizingMode widthMode, float availableWidth, - MeasureMode heightMode, + SizingMode heightMode, float availableHeight, - MeasureMode lastWidthMode, + SizingMode lastWidthMode, float lastAvailableWidth, - MeasureMode lastHeightMode, + SizingMode lastHeightMode, float lastAvailableHeight, float lastComputedWidth, float lastComputedHeight, diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index c1026c9adc..f066dbdfc4 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -39,8 +40,8 @@ bool calculateLayoutInternal( const float availableWidth, const float availableHeight, const Direction ownerDirection, - const MeasureMode widthMeasureMode, - const MeasureMode heightMeasureMode, + const SizingMode widthSizingMode, + const SizingMode heightSizingMode, const float ownerWidth, const float ownerHeight, const bool performLayout, @@ -97,22 +98,22 @@ static void constrainMaxSizeForMode( const enum FlexDirection axis, const float ownerAxisSize, const float ownerWidth, - MeasureMode* mode, + SizingMode* mode, float* size) { const FloatOptional maxSize = yoga::resolveValue( node->getStyle().maxDimension(dimension(axis)), ownerAxisSize) + FloatOptional(node->getMarginForAxis(axis, ownerWidth)); switch (*mode) { - case MeasureMode::Exactly: - case MeasureMode::AtMost: + case SizingMode::StretchFit: + case SizingMode::FitContent: *size = (maxSize.isUndefined() || *size < maxSize.unwrap()) ? *size : maxSize.unwrap(); break; - case MeasureMode::Undefined: + case SizingMode::MaxContent: if (maxSize.isDefined()) { - *mode = MeasureMode::AtMost; + *mode = SizingMode::FitContent; *size = maxSize.unwrap(); } break; @@ -123,11 +124,11 @@ static void computeFlexBasisForChild( const yoga::Node* const node, yoga::Node* const child, const float width, - const MeasureMode widthMode, + const SizingMode widthMode, const float height, const float ownerWidth, const float ownerHeight, - const MeasureMode heightMode, + const SizingMode heightMode, const Direction direction, LayoutData& layoutMarkerData, const uint32_t depth, @@ -140,8 +141,8 @@ static void computeFlexBasisForChild( float childWidth; float childHeight; - MeasureMode childWidthMeasureMode; - MeasureMode childHeightMeasureMode; + SizingMode childWidthSizingMode; + SizingMode childHeightSizingMode; const FloatOptional resolvedFlexBasis = yoga::resolveValue(child->resolveFlexBasisPtr(), mainAxisownerSize); @@ -182,8 +183,8 @@ static void computeFlexBasisForChild( // basis). childWidth = YGUndefined; childHeight = YGUndefined; - childWidthMeasureMode = MeasureMode::Undefined; - childHeightMeasureMode = MeasureMode::Undefined; + childWidthSizingMode = SizingMode::MaxContent; + childHeightSizingMode = SizingMode::MaxContent; auto marginRow = child->getMarginForAxis(FlexDirection::Row, ownerWidth); auto marginColumn = @@ -195,7 +196,7 @@ static void computeFlexBasisForChild( child->getResolvedDimension(Dimension::Width), ownerWidth) .unwrap() + marginRow; - childWidthMeasureMode = MeasureMode::Exactly; + childWidthSizingMode = SizingMode::StretchFit; } if (isColumnStyleDimDefined) { childHeight = @@ -203,7 +204,7 @@ static void computeFlexBasisForChild( child->getResolvedDimension(Dimension::Height), ownerHeight) .unwrap() + marginColumn; - childHeightMeasureMode = MeasureMode::Exactly; + childHeightSizingMode = SizingMode::StretchFit; } // The W3C spec doesn't say anything about the 'overflow' property, but all @@ -212,7 +213,7 @@ static void computeFlexBasisForChild( node->getStyle().overflow() != Overflow::Scroll) { if (yoga::isUndefined(childWidth) && yoga::isDefined(width)) { childWidth = width; - childWidthMeasureMode = MeasureMode::AtMost; + childWidthSizingMode = SizingMode::FitContent; } } @@ -220,21 +221,21 @@ static void computeFlexBasisForChild( node->getStyle().overflow() != Overflow::Scroll) { if (yoga::isUndefined(childHeight) && yoga::isDefined(height)) { childHeight = height; - childHeightMeasureMode = MeasureMode::AtMost; + childHeightSizingMode = SizingMode::FitContent; } } const auto& childStyle = child->getStyle(); if (childStyle.aspectRatio().isDefined()) { - if (!isMainAxisRow && childWidthMeasureMode == MeasureMode::Exactly) { + if (!isMainAxisRow && childWidthSizingMode == SizingMode::StretchFit) { childHeight = marginColumn + (childWidth - marginRow) / childStyle.aspectRatio().unwrap(); - childHeightMeasureMode = MeasureMode::Exactly; + childHeightSizingMode = SizingMode::StretchFit; } else if ( - isMainAxisRow && childHeightMeasureMode == MeasureMode::Exactly) { + isMainAxisRow && childHeightSizingMode == SizingMode::StretchFit) { childWidth = marginRow + (childHeight - marginColumn) * childStyle.aspectRatio().unwrap(); - childWidthMeasureMode = MeasureMode::Exactly; + childWidthSizingMode = SizingMode::StretchFit; } } @@ -242,35 +243,35 @@ static void computeFlexBasisForChild( // the cross axis to be measured exactly with the available inner width const bool hasExactWidth = - yoga::isDefined(width) && widthMode == MeasureMode::Exactly; + yoga::isDefined(width) && widthMode == SizingMode::StretchFit; const bool childWidthStretch = resolveChildAlignment(node, child) == Align::Stretch && - childWidthMeasureMode != MeasureMode::Exactly; + childWidthSizingMode != SizingMode::StretchFit; if (!isMainAxisRow && !isRowStyleDimDefined && hasExactWidth && childWidthStretch) { childWidth = width; - childWidthMeasureMode = MeasureMode::Exactly; + childWidthSizingMode = SizingMode::StretchFit; if (childStyle.aspectRatio().isDefined()) { childHeight = (childWidth - marginRow) / childStyle.aspectRatio().unwrap(); - childHeightMeasureMode = MeasureMode::Exactly; + childHeightSizingMode = SizingMode::StretchFit; } } const bool hasExactHeight = - yoga::isDefined(height) && heightMode == MeasureMode::Exactly; + yoga::isDefined(height) && heightMode == SizingMode::StretchFit; const bool childHeightStretch = resolveChildAlignment(node, child) == Align::Stretch && - childHeightMeasureMode != MeasureMode::Exactly; + childHeightSizingMode != SizingMode::StretchFit; if (isMainAxisRow && !isColumnStyleDimDefined && hasExactHeight && childHeightStretch) { childHeight = height; - childHeightMeasureMode = MeasureMode::Exactly; + childHeightSizingMode = SizingMode::StretchFit; if (childStyle.aspectRatio().isDefined()) { childWidth = (childHeight - marginColumn) * childStyle.aspectRatio().unwrap(); - childWidthMeasureMode = MeasureMode::Exactly; + childWidthSizingMode = SizingMode::StretchFit; } } @@ -279,14 +280,14 @@ static void computeFlexBasisForChild( FlexDirection::Row, ownerWidth, ownerWidth, - &childWidthMeasureMode, + &childWidthSizingMode, &childWidth); constrainMaxSizeForMode( child, FlexDirection::Column, ownerHeight, ownerWidth, - &childHeightMeasureMode, + &childHeightSizingMode, &childHeight); // Measure the child @@ -295,8 +296,8 @@ static void computeFlexBasisForChild( childWidth, childHeight, direction, - childWidthMeasureMode, - childHeightMeasureMode, + childWidthSizingMode, + childHeightSizingMode, ownerWidth, ownerHeight, false, @@ -316,7 +317,7 @@ static void layoutAbsoluteChild( const yoga::Node* const node, yoga::Node* const child, const float width, - const MeasureMode widthMode, + const SizingMode widthMode, const float height, const Direction direction, LayoutData& layoutMarkerData, @@ -329,8 +330,8 @@ static void layoutAbsoluteChild( float childWidth = YGUndefined; float childHeight = YGUndefined; - MeasureMode childWidthMeasureMode = MeasureMode::Undefined; - MeasureMode childHeightMeasureMode = MeasureMode::Undefined; + SizingMode childWidthSizingMode = SizingMode::MaxContent; + SizingMode childHeightSizingMode = SizingMode::MaxContent; auto marginRow = child->getMarginForAxis(FlexDirection::Row, width); auto marginColumn = child->getMarginForAxis(FlexDirection::Column, width); @@ -395,22 +396,22 @@ static void layoutAbsoluteChild( // If we're still missing one or the other dimension, measure the content. if (yoga::isUndefined(childWidth) || yoga::isUndefined(childHeight)) { - childWidthMeasureMode = yoga::isUndefined(childWidth) - ? MeasureMode::Undefined - : MeasureMode::Exactly; - childHeightMeasureMode = yoga::isUndefined(childHeight) - ? MeasureMode::Undefined - : MeasureMode::Exactly; + childWidthSizingMode = yoga::isUndefined(childWidth) + ? SizingMode::MaxContent + : SizingMode::StretchFit; + childHeightSizingMode = yoga::isUndefined(childHeight) + ? SizingMode::MaxContent + : SizingMode::StretchFit; // If the size of the owner is defined then try to constrain the absolute // child to that size as well. This allows text within the absolute child to // wrap to the size of its owner. This is the same behavior as many browsers // implement. if (!isMainAxisRow && yoga::isUndefined(childWidth) && - widthMode != MeasureMode::Undefined && yoga::isDefined(width) && + widthMode != SizingMode::MaxContent && yoga::isDefined(width) && width > 0) { childWidth = width; - childWidthMeasureMode = MeasureMode::AtMost; + childWidthSizingMode = SizingMode::FitContent; } calculateLayoutInternal( @@ -418,8 +419,8 @@ static void layoutAbsoluteChild( childWidth, childHeight, direction, - childWidthMeasureMode, - childHeightMeasureMode, + childWidthSizingMode, + childHeightSizingMode, childWidth, childHeight, false, @@ -438,8 +439,8 @@ static void layoutAbsoluteChild( childWidth, childHeight, direction, - MeasureMode::Exactly, - MeasureMode::Exactly, + SizingMode::StretchFit, + SizingMode::StretchFit, childWidth, childHeight, true, @@ -534,8 +535,8 @@ static void measureNodeWithMeasureFunc( yoga::Node* const node, float availableWidth, float availableHeight, - const MeasureMode widthMeasureMode, - const MeasureMode heightMeasureMode, + const SizingMode widthSizingMode, + const SizingMode heightSizingMode, const float ownerWidth, const float ownerHeight, LayoutData& layoutMarkerData, @@ -545,10 +546,10 @@ static void measureNodeWithMeasureFunc( node->hasMeasureFunc(), "Expected node to have custom measure function"); - if (widthMeasureMode == MeasureMode::Undefined) { + if (widthSizingMode == SizingMode::MaxContent) { availableWidth = YGUndefined; } - if (heightMeasureMode == MeasureMode::Undefined) { + if (heightSizingMode == SizingMode::MaxContent) { availableHeight = YGUndefined; } @@ -567,8 +568,8 @@ static void measureNodeWithMeasureFunc( ? availableHeight : yoga::maxOrDefined(0.0f, availableHeight - paddingAndBorderAxisColumn); - if (widthMeasureMode == MeasureMode::Exactly && - heightMeasureMode == MeasureMode::Exactly) { + if (widthSizingMode == SizingMode::StretchFit && + heightSizingMode == SizingMode::StretchFit) { // Don't bother sizing the text if both dimensions are already defined. node->setLayoutMeasuredDimension( boundAxis( @@ -587,7 +588,10 @@ static void measureNodeWithMeasureFunc( // Measure the text under the current constraints. const YGSize measuredSize = node->measure( - innerWidth, widthMeasureMode, innerHeight, heightMeasureMode); + innerWidth, + measureMode(widthSizingMode), + innerHeight, + measureMode(heightSizingMode)); layoutMarkerData.measureCallbacks += 1; layoutMarkerData.measureCallbackReasonsCount[static_cast(reason)] += @@ -596,9 +600,9 @@ static void measureNodeWithMeasureFunc( Event::publish( node, {innerWidth, - unscopedEnum(widthMeasureMode), + unscopedEnum(measureMode(widthSizingMode)), innerHeight, - unscopedEnum(heightMeasureMode), + unscopedEnum(measureMode(heightSizingMode)), measuredSize.width, measuredSize.height, reason}); @@ -607,8 +611,8 @@ static void measureNodeWithMeasureFunc( boundAxis( node, FlexDirection::Row, - (widthMeasureMode == MeasureMode::Undefined || - widthMeasureMode == MeasureMode::AtMost) + (widthSizingMode == SizingMode::MaxContent || + widthSizingMode == SizingMode::FitContent) ? measuredSize.width + paddingAndBorderAxisRow : availableWidth, ownerWidth, @@ -619,8 +623,8 @@ static void measureNodeWithMeasureFunc( boundAxis( node, FlexDirection::Column, - (heightMeasureMode == MeasureMode::Undefined || - heightMeasureMode == MeasureMode::AtMost) + (heightSizingMode == SizingMode::MaxContent || + heightSizingMode == SizingMode::FitContent) ? measuredSize.height + paddingAndBorderAxisColumn : availableHeight, ownerHeight, @@ -635,16 +639,16 @@ static void measureNodeWithoutChildren( yoga::Node* const node, const float availableWidth, const float availableHeight, - const MeasureMode widthMeasureMode, - const MeasureMode heightMeasureMode, + const SizingMode widthSizingMode, + const SizingMode heightSizingMode, const float ownerWidth, const float ownerHeight) { const auto& padding = node->getLayout().padding; const auto& border = node->getLayout().border; float width = availableWidth; - if (widthMeasureMode == MeasureMode::Undefined || - widthMeasureMode == MeasureMode::AtMost) { + if (widthSizingMode == SizingMode::MaxContent || + widthSizingMode == SizingMode::FitContent) { width = padding[YGEdgeLeft] + padding[YGEdgeRight] + border[YGEdgeLeft] + border[YGEdgeRight]; } @@ -653,8 +657,8 @@ static void measureNodeWithoutChildren( Dimension::Width); float height = availableHeight; - if (heightMeasureMode == MeasureMode::Undefined || - heightMeasureMode == MeasureMode::AtMost) { + if (heightSizingMode == SizingMode::MaxContent || + heightSizingMode == SizingMode::FitContent) { height = padding[YGEdgeTop] + padding[YGEdgeBottom] + border[YGEdgeTop] + border[YGEdgeBottom]; } @@ -667,22 +671,22 @@ static bool measureNodeWithFixedSize( yoga::Node* const node, const float availableWidth, const float availableHeight, - const MeasureMode widthMeasureMode, - const MeasureMode heightMeasureMode, + const SizingMode widthSizingMode, + const SizingMode heightSizingMode, const float ownerWidth, const float ownerHeight) { if ((yoga::isDefined(availableWidth) && - widthMeasureMode == MeasureMode::AtMost && availableWidth <= 0.0f) || + widthSizingMode == SizingMode::FitContent && availableWidth <= 0.0f) || (yoga::isDefined(availableHeight) && - heightMeasureMode == MeasureMode::AtMost && availableHeight <= 0.0f) || - (widthMeasureMode == MeasureMode::Exactly && - heightMeasureMode == MeasureMode::Exactly)) { + heightSizingMode == SizingMode::FitContent && availableHeight <= 0.0f) || + (widthSizingMode == SizingMode::StretchFit && + heightSizingMode == SizingMode::StretchFit)) { node->setLayoutMeasuredDimension( boundAxis( node, FlexDirection::Row, yoga::isUndefined(availableWidth) || - (widthMeasureMode == MeasureMode::AtMost && + (widthSizingMode == SizingMode::FitContent && availableWidth < 0.0f) ? 0.0f : availableWidth, @@ -695,7 +699,7 @@ static bool measureNodeWithFixedSize( node, FlexDirection::Column, yoga::isUndefined(availableHeight) || - (heightMeasureMode == MeasureMode::AtMost && + (heightSizingMode == SizingMode::FitContent && availableHeight < 0.0f) ? 0.0f : availableHeight, @@ -755,8 +759,8 @@ static float computeFlexBasisForChildren( yoga::Node* const node, const float availableInnerWidth, const float availableInnerHeight, - MeasureMode widthMeasureMode, - MeasureMode heightMeasureMode, + SizingMode widthSizingMode, + SizingMode heightSizingMode, Direction direction, FlexDirection mainAxis, bool performLayout, @@ -766,12 +770,12 @@ static float computeFlexBasisForChildren( float totalOuterFlexBasis = 0.0f; YGNodeRef singleFlexChild = nullptr; const auto& children = node->getChildren(); - MeasureMode measureModeMainDim = - isRow(mainAxis) ? widthMeasureMode : heightMeasureMode; + SizingMode sizingModeMainDim = + isRow(mainAxis) ? widthSizingMode : heightSizingMode; // If there is only one child with flexGrow + flexShrink it means we can set // the computedFlexBasis to 0 instead of measuring and shrinking / flexing the // child to exactly match the remaining space - if (measureModeMainDim == MeasureMode::Exactly) { + if (sizingModeMainDim == SizingMode::StretchFit) { for (auto child : children) { if (child->isNodeFlexible()) { if (singleFlexChild != nullptr || @@ -818,11 +822,11 @@ static float computeFlexBasisForChildren( node, child, availableInnerWidth, - widthMeasureMode, + widthSizingMode, availableInnerHeight, availableInnerWidth, availableInnerHeight, - heightMeasureMode, + heightSizingMode, direction, layoutMarkerData, depth, @@ -852,7 +856,7 @@ static float distributeFreeSpaceSecondPass( const float availableInnerWidth, const float availableInnerHeight, const bool mainAxisOverflows, - const MeasureMode measureModeCrossDim, + const SizingMode sizingModeCrossDim, const bool performLayout, LayoutData& layoutMarkerData, const uint32_t depth, @@ -925,35 +929,35 @@ static float distributeFreeSpaceSecondPass( float childCrossSize; float childMainSize = updatedMainSize + marginMain; - MeasureMode childCrossMeasureMode; - MeasureMode childMainMeasureMode = MeasureMode::Exactly; + SizingMode childCrossSizingMode; + SizingMode childMainSizingMode = SizingMode::StretchFit; const auto& childStyle = currentLineChild->getStyle(); if (childStyle.aspectRatio().isDefined()) { childCrossSize = isMainAxisRow ? (childMainSize - marginMain) / childStyle.aspectRatio().unwrap() : (childMainSize - marginMain) * childStyle.aspectRatio().unwrap(); - childCrossMeasureMode = MeasureMode::Exactly; + childCrossSizingMode = SizingMode::StretchFit; childCrossSize += marginCross; } else if ( !std::isnan(availableInnerCrossDim) && !styleDefinesDimension( currentLineChild, crossAxis, availableInnerCrossDim) && - measureModeCrossDim == MeasureMode::Exactly && + sizingModeCrossDim == SizingMode::StretchFit && !(isNodeFlexWrap && mainAxisOverflows) && resolveChildAlignment(node, currentLineChild) == Align::Stretch && currentLineChild->getFlexStartMarginValue(crossAxis).unit != YGUnitAuto && currentLineChild->marginTrailingValue(crossAxis).unit != YGUnitAuto) { childCrossSize = availableInnerCrossDim; - childCrossMeasureMode = MeasureMode::Exactly; + childCrossSizingMode = SizingMode::StretchFit; } else if (!styleDefinesDimension( currentLineChild, crossAxis, availableInnerCrossDim)) { childCrossSize = availableInnerCrossDim; - childCrossMeasureMode = yoga::isUndefined(childCrossSize) - ? MeasureMode::Undefined - : MeasureMode::AtMost; + childCrossSizingMode = yoga::isUndefined(childCrossSize) + ? SizingMode::MaxContent + : SizingMode::FitContent; } else { childCrossSize = yoga::resolveValue( @@ -964,11 +968,11 @@ static float distributeFreeSpaceSecondPass( const bool isLoosePercentageMeasurement = currentLineChild->getResolvedDimension(dimension(crossAxis)).unit == YGUnitPercent && - measureModeCrossDim != MeasureMode::Exactly; - childCrossMeasureMode = + sizingModeCrossDim != SizingMode::StretchFit; + childCrossSizingMode = yoga::isUndefined(childCrossSize) || isLoosePercentageMeasurement - ? MeasureMode::Undefined - : MeasureMode::Exactly; + ? SizingMode::MaxContent + : SizingMode::StretchFit; } constrainMaxSizeForMode( @@ -976,14 +980,14 @@ static float distributeFreeSpaceSecondPass( mainAxis, availableInnerMainDim, availableInnerWidth, - &childMainMeasureMode, + &childMainSizingMode, &childMainSize); constrainMaxSizeForMode( currentLineChild, crossAxis, availableInnerCrossDim, availableInnerWidth, - &childCrossMeasureMode, + &childCrossSizingMode, &childCrossSize); const bool requiresStretchLayout = @@ -997,10 +1001,10 @@ static float distributeFreeSpaceSecondPass( const float childWidth = isMainAxisRow ? childMainSize : childCrossSize; const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize; - const MeasureMode childWidthMeasureMode = - isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode; - const MeasureMode childHeightMeasureMode = - !isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode; + const SizingMode childWidthSizingMode = + isMainAxisRow ? childMainSizingMode : childCrossSizingMode; + const SizingMode childHeightSizingMode = + !isMainAxisRow ? childMainSizingMode : childCrossSizingMode; const bool isLayoutPass = performLayout && !requiresStretchLayout; // Recursively call the layout algorithm for this child with the updated @@ -1010,8 +1014,8 @@ static float distributeFreeSpaceSecondPass( childWidth, childHeight, node->getLayout().direction(), - childWidthMeasureMode, - childHeightMeasureMode, + childWidthSizingMode, + childHeightSizingMode, availableInnerWidth, availableInnerHeight, isLayoutPass, @@ -1144,7 +1148,7 @@ static void resolveFlexibleLength( const float availableInnerWidth, const float availableInnerHeight, const bool mainAxisOverflows, - const MeasureMode measureModeCrossDim, + const SizingMode sizingModeCrossDim, const bool performLayout, LayoutData& layoutMarkerData, const uint32_t depth, @@ -1170,7 +1174,7 @@ static void resolveFlexibleLength( availableInnerWidth, availableInnerHeight, mainAxisOverflows, - measureModeCrossDim, + sizingModeCrossDim, performLayout, layoutMarkerData, depth, @@ -1186,8 +1190,8 @@ static void justifyMainAxis( const FlexDirection mainAxis, const FlexDirection crossAxis, const Direction direction, - const MeasureMode measureModeMainDim, - const MeasureMode measureModeCrossDim, + const SizingMode sizingModeMainDim, + const SizingMode sizingModeCrossDim, const float mainAxisownerSize, const float ownerWidth, const float availableInnerMainDim, @@ -1208,7 +1212,7 @@ static void justifyMainAxis( const float gap = node->getGapForAxis(mainAxis); // If we are using "at most" rules in the main axis, make sure that // remainingFreeSpace is 0 when min main dimension is not given - if (measureModeMainDim == MeasureMode::AtMost && + if (sizingModeMainDim == SizingMode::FitContent && flexLine.layout.remainingFreeSpace > 0) { if (style.minDimension(dimension(mainAxis)).isDefined() && yoga::resolveValue( @@ -1340,7 +1344,7 @@ static void justifyMainAxis( static_cast(numberOfAutoMarginsOnCurrentLine); } bool canSkipFlex = - !performLayout && measureModeCrossDim == MeasureMode::Exactly; + !performLayout && sizingModeCrossDim == SizingMode::StretchFit; if (canSkipFlex) { // If we skipped the flex step, then we can't rely on the measuredDims // because they weren't computed. This means we can't call @@ -1432,9 +1436,9 @@ static void justifyMainAxis( // depends on layout flags // - ownerDirection: the inline (text) direction within the owner // (left-to-right or right-to-left) -// - widthMeasureMode: indicates the sizing rules for the width (see below +// - widthSizingMode: indicates the sizing rules for the width (see below // for explanation) -// - heightMeasureMode: indicates the sizing rules for the height (see below +// - heightSizingMode: indicates the sizing rules for the height (see below // for explanation) // - performLayout: specifies whether the caller is interested in just the // dimensions of the node or it requires the entire node and its subtree to @@ -1449,26 +1453,17 @@ static void justifyMainAxis( // layout.measuredDimensions field includes any border or padding for the // node but does not include margins. // -// The spec describes four different layout modes: "fill available", "max -// content", "min content", and "fit content". Of these, we don't use "min -// content" because we don't support default minimum main sizes (see above -// for details). Each of our measure modes maps to a layout mode from the -// spec (https://www.w3.org/TR/CSS3-sizing/#terms): -// - MeasureMode::Undefined: max content -// - MeasureMode::Exactly: fill available -// - MeasureMode::AtMost: fit content -// // When calling calculateLayoutImpl and calculateLayoutInternal, if the // caller passes an available size of undefined then it must also pass a -// measure mode of MeasureMode::Undefined in that dimension. +// measure mode of SizingMode::MaxContent in that dimension. // static void calculateLayoutImpl( yoga::Node* const node, const float availableWidth, const float availableHeight, const Direction ownerDirection, - const MeasureMode widthMeasureMode, - const MeasureMode heightMeasureMode, + const SizingMode widthSizingMode, + const SizingMode heightSizingMode, const float ownerWidth, const float ownerHeight, const bool performLayout, @@ -1479,17 +1474,17 @@ static void calculateLayoutImpl( yoga::assertFatalWithNode( node, yoga::isUndefined(availableWidth) - ? widthMeasureMode == MeasureMode::Undefined + ? widthSizingMode == SizingMode::MaxContent : true, - "availableWidth is indefinite so widthMeasureMode must be " - "MeasureMode::Undefined"); + "availableWidth is indefinite so widthSizingMode must be " + "SizingMode::MaxContent"); yoga::assertFatalWithNode( node, yoga::isUndefined(availableHeight) - ? heightMeasureMode == MeasureMode::Undefined + ? heightSizingMode == SizingMode::MaxContent : true, - "availableHeight is indefinite so heightMeasureMode must be " - "MeasureMode::Undefined"); + "availableHeight is indefinite so heightSizingMode must be " + "SizingMode::MaxContent"); (performLayout ? layoutMarkerData.layouts : layoutMarkerData.measures) += 1; @@ -1549,8 +1544,8 @@ static void calculateLayoutImpl( node, availableWidth - marginAxisRow, availableHeight - marginAxisColumn, - widthMeasureMode, - heightMeasureMode, + widthSizingMode, + heightSizingMode, ownerWidth, ownerHeight, layoutMarkerData, @@ -1564,8 +1559,8 @@ static void calculateLayoutImpl( node, availableWidth - marginAxisRow, availableHeight - marginAxisColumn, - widthMeasureMode, - heightMeasureMode, + widthSizingMode, + heightSizingMode, ownerWidth, ownerHeight); return; @@ -1578,8 +1573,8 @@ static void calculateLayoutImpl( node, availableWidth - marginAxisRow, availableHeight - marginAxisColumn, - widthMeasureMode, - heightMeasureMode, + widthSizingMode, + heightSizingMode, ownerWidth, ownerHeight)) { return; @@ -1608,10 +1603,10 @@ static void calculateLayoutImpl( const float leadingPaddingAndBorderCross = node->getInlineStartPaddingAndBorder(crossAxis, direction, ownerWidth); - MeasureMode measureModeMainDim = - isMainAxisRow ? widthMeasureMode : heightMeasureMode; - MeasureMode measureModeCrossDim = - isMainAxisRow ? heightMeasureMode : widthMeasureMode; + SizingMode sizingModeMainDim = + isMainAxisRow ? widthSizingMode : heightSizingMode; + SizingMode sizingModeCrossDim = + isMainAxisRow ? heightSizingMode : widthSizingMode; const float paddingAndBorderAxisRow = isMainAxisRow ? paddingAndBorderAxisMain : paddingAndBorderAxisCross; @@ -1646,8 +1641,8 @@ static void calculateLayoutImpl( node, availableInnerWidth, availableInnerHeight, - widthMeasureMode, - heightMeasureMode, + widthSizingMode, + heightSizingMode, direction, mainAxis, performLayout, @@ -1661,12 +1656,12 @@ static void calculateLayoutImpl( } const bool mainAxisOverflows = - (measureModeMainDim != MeasureMode::Undefined) && + (sizingModeMainDim != SizingMode::MaxContent) && totalMainDim > availableInnerMainDim; if (isNodeFlexWrap && mainAxisOverflows && - measureModeMainDim == MeasureMode::AtMost) { - measureModeMainDim = MeasureMode::Exactly; + sizingModeMainDim == SizingMode::FitContent) { + sizingModeMainDim = SizingMode::StretchFit; } // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES @@ -1700,7 +1695,7 @@ static void calculateLayoutImpl( // If we don't need to measure the cross axis, we can skip the entire flex // step. const bool canSkipFlex = - !performLayout && measureModeCrossDim == MeasureMode::Exactly; + !performLayout && sizingModeCrossDim == SizingMode::StretchFit; // STEP 5: RESOLVING FLEXIBLE LENGTHS ON MAIN AXIS // Calculate the remaining available space that needs to be allocated. If @@ -1710,7 +1705,7 @@ static void calculateLayoutImpl( bool sizeBasedOnContent = false; // If we don't measure with exact main dimension we want to ensure we don't // violate min and max - if (measureModeMainDim != MeasureMode::Exactly) { + if (sizingModeMainDim != SizingMode::StretchFit) { const auto& style = node->getStyle(); const float minInnerWidth = yoga::resolveValue(style.minDimension(Dimension::Width), ownerWidth) @@ -1783,7 +1778,7 @@ static void calculateLayoutImpl( availableInnerWidth, availableInnerHeight, mainAxisOverflows, - measureModeCrossDim, + sizingModeCrossDim, performLayout, layoutMarkerData, depth, @@ -1808,8 +1803,8 @@ static void calculateLayoutImpl( mainAxis, crossAxis, direction, - measureModeMainDim, - measureModeCrossDim, + sizingModeMainDim, + sizingModeCrossDim, mainAxisownerSize, ownerWidth, availableInnerMainDim, @@ -1818,8 +1813,8 @@ static void calculateLayoutImpl( performLayout); float containerCrossAxis = availableInnerCrossDim; - if (measureModeCrossDim == MeasureMode::Undefined || - measureModeCrossDim == MeasureMode::AtMost) { + if (sizingModeCrossDim == SizingMode::MaxContent || + sizingModeCrossDim == SizingMode::FitContent) { // Compute the cross axis from the max cross dimension of the children. containerCrossAxis = boundAxis( @@ -1832,7 +1827,7 @@ static void calculateLayoutImpl( } // If there's no flex wrap, the cross dimension is defined by the container. - if (!isNodeFlexWrap && measureModeCrossDim == MeasureMode::Exactly) { + if (!isNodeFlexWrap && sizingModeCrossDim == SizingMode::StretchFit) { flexLine.layout.crossDim = availableInnerCrossDim; } @@ -1911,21 +1906,21 @@ static void calculateLayoutImpl( childMainSize += child->getMarginForAxis(mainAxis, availableInnerWidth); - MeasureMode childMainMeasureMode = MeasureMode::Exactly; - MeasureMode childCrossMeasureMode = MeasureMode::Exactly; + SizingMode childMainSizingMode = SizingMode::StretchFit; + SizingMode childCrossSizingMode = SizingMode::StretchFit; constrainMaxSizeForMode( child, mainAxis, availableInnerMainDim, availableInnerWidth, - &childMainMeasureMode, + &childMainSizingMode, &childMainSize); constrainMaxSizeForMode( child, crossAxis, availableInnerCrossDim, availableInnerWidth, - &childCrossMeasureMode, + &childCrossSizingMode, &childCrossSize); const float childWidth = @@ -1936,24 +1931,24 @@ static void calculateLayoutImpl( auto alignContent = node->getStyle().alignContent(); auto crossAxisDoesNotGrow = alignContent != Align::Stretch && isNodeFlexWrap; - const MeasureMode childWidthMeasureMode = + const SizingMode childWidthSizingMode = yoga::isUndefined(childWidth) || (!isMainAxisRow && crossAxisDoesNotGrow) - ? MeasureMode::Undefined - : MeasureMode::Exactly; - const MeasureMode childHeightMeasureMode = + ? SizingMode::MaxContent + : SizingMode::StretchFit; + const SizingMode childHeightSizingMode = yoga::isUndefined(childHeight) || (isMainAxisRow && crossAxisDoesNotGrow) - ? MeasureMode::Undefined - : MeasureMode::Exactly; + ? SizingMode::MaxContent + : SizingMode::StretchFit; calculateLayoutInternal( child, childWidth, childHeight, direction, - childWidthMeasureMode, - childHeightMeasureMode, + childWidthSizingMode, + childHeightSizingMode, availableInnerWidth, availableInnerHeight, true, @@ -2174,8 +2169,8 @@ static void calculateLayoutImpl( childWidth, childHeight, direction, - MeasureMode::Exactly, - MeasureMode::Exactly, + SizingMode::StretchFit, + SizingMode::StretchFit, availableInnerWidth, availableInnerHeight, true, @@ -2234,9 +2229,9 @@ static void calculateLayoutImpl( // If the user didn't specify a width or height for the node, set the // dimensions based on the children. - if (measureModeMainDim == MeasureMode::Undefined || + if (sizingModeMainDim == SizingMode::MaxContent || (node->getStyle().overflow() != Overflow::Scroll && - measureModeMainDim == MeasureMode::AtMost)) { + sizingModeMainDim == SizingMode::FitContent)) { // Clamp the size to the min/max size, if specified, and make sure it // doesn't go below the padding and border amount. node->setLayoutMeasuredDimension( @@ -2245,7 +2240,7 @@ static void calculateLayoutImpl( dimension(mainAxis)); } else if ( - measureModeMainDim == MeasureMode::AtMost && + sizingModeMainDim == SizingMode::FitContent && node->getStyle().overflow() == Overflow::Scroll) { node->setLayoutMeasuredDimension( yoga::maxOrDefined( @@ -2261,9 +2256,9 @@ static void calculateLayoutImpl( dimension(mainAxis)); } - if (measureModeCrossDim == MeasureMode::Undefined || + if (sizingModeCrossDim == SizingMode::MaxContent || (node->getStyle().overflow() != Overflow::Scroll && - measureModeCrossDim == MeasureMode::AtMost)) { + sizingModeCrossDim == SizingMode::FitContent)) { // Clamp the size to the min/max size, if specified, and make sure it // doesn't go below the padding and border amount. node->setLayoutMeasuredDimension( @@ -2276,7 +2271,7 @@ static void calculateLayoutImpl( dimension(crossAxis)); } else if ( - measureModeCrossDim == MeasureMode::AtMost && + sizingModeCrossDim == SizingMode::FitContent && node->getStyle().overflow() == Overflow::Scroll) { node->setLayoutMeasuredDimension( yoga::maxOrDefined( @@ -2325,7 +2320,7 @@ static void calculateLayoutImpl( absolutePercentageAgainstPaddingEdge ? node->getLayout().measuredDimension(Dimension::Width) : availableInnerWidth, - isMainAxisRow ? measureModeMainDim : measureModeCrossDim, + isMainAxisRow ? sizingModeMainDim : sizingModeCrossDim, absolutePercentageAgainstPaddingEdge ? node->getLayout().measuredDimension(Dimension::Height) : availableInnerHeight, @@ -2375,15 +2370,15 @@ static const char* spacerWithLength(const unsigned long level) { } } -static const char* measureModeName( - const MeasureMode mode, +static const char* sizingModeName( + const SizingMode mode, const bool performLayout) { switch (mode) { - case MeasureMode::Undefined: + case SizingMode::MaxContent: return performLayout ? "LAY_UNDEFINED" : "UNDEFINED"; - case MeasureMode::Exactly: + case SizingMode::StretchFit: return performLayout ? "LAY_EXACTLY" : "EXACTLY"; - case MeasureMode::AtMost: + case SizingMode::FitContent: return performLayout ? "LAY_AT_MOST" : "AT_MOST"; } return ""; @@ -2402,8 +2397,8 @@ bool calculateLayoutInternal( const float availableWidth, const float availableHeight, const Direction ownerDirection, - const MeasureMode widthMeasureMode, - const MeasureMode heightMeasureMode, + const SizingMode widthSizingMode, + const SizingMode heightSizingMode, const float ownerWidth, const float ownerHeight, const bool performLayout, @@ -2424,8 +2419,8 @@ bool calculateLayoutInternal( layout->nextCachedMeasurementsIndex = 0; layout->cachedLayout.availableWidth = -1; layout->cachedLayout.availableHeight = -1; - layout->cachedLayout.widthMeasureMode = MeasureMode::Undefined; - layout->cachedLayout.heightMeasureMode = MeasureMode::Undefined; + layout->cachedLayout.widthSizingMode = SizingMode::MaxContent; + layout->cachedLayout.heightSizingMode = SizingMode::MaxContent; layout->cachedLayout.computedWidth = -1; layout->cachedLayout.computedHeight = -1; } @@ -2448,13 +2443,13 @@ bool calculateLayoutInternal( // First, try to use the layout cache. if (canUseCachedMeasurement( - widthMeasureMode, + widthSizingMode, availableWidth, - heightMeasureMode, + heightSizingMode, availableHeight, - layout->cachedLayout.widthMeasureMode, + layout->cachedLayout.widthSizingMode, layout->cachedLayout.availableWidth, - layout->cachedLayout.heightMeasureMode, + layout->cachedLayout.heightSizingMode, layout->cachedLayout.availableHeight, layout->cachedLayout.computedWidth, layout->cachedLayout.computedHeight, @@ -2466,13 +2461,13 @@ bool calculateLayoutInternal( // Try to use the measurement cache. for (size_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { if (canUseCachedMeasurement( - widthMeasureMode, + widthSizingMode, availableWidth, - heightMeasureMode, + heightSizingMode, availableHeight, - layout->cachedMeasurements[i].widthMeasureMode, + layout->cachedMeasurements[i].widthSizingMode, layout->cachedMeasurements[i].availableWidth, - layout->cachedMeasurements[i].heightMeasureMode, + layout->cachedMeasurements[i].heightSizingMode, layout->cachedMeasurements[i].availableHeight, layout->cachedMeasurements[i].computedWidth, layout->cachedMeasurements[i].computedHeight, @@ -2489,8 +2484,8 @@ bool calculateLayoutInternal( layout->cachedLayout.availableWidth, availableWidth) && yoga::inexactEquals( layout->cachedLayout.availableHeight, availableHeight) && - layout->cachedLayout.widthMeasureMode == widthMeasureMode && - layout->cachedLayout.heightMeasureMode == heightMeasureMode) { + layout->cachedLayout.widthSizingMode == widthSizingMode && + layout->cachedLayout.heightSizingMode == heightSizingMode) { cachedResults = &layout->cachedLayout; } } else { @@ -2499,9 +2494,8 @@ bool calculateLayoutInternal( layout->cachedMeasurements[i].availableWidth, availableWidth) && yoga::inexactEquals( layout->cachedMeasurements[i].availableHeight, availableHeight) && - layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode && - layout->cachedMeasurements[i].heightMeasureMode == - heightMeasureMode) { + layout->cachedMeasurements[i].widthSizingMode == widthSizingMode && + layout->cachedMeasurements[i].heightSizingMode == heightSizingMode) { cachedResults = &layout->cachedMeasurements[i]; break; } @@ -2529,8 +2523,8 @@ bool calculateLayoutInternal( node, LogLevel::Verbose, "wm: %s, hm: %s, aw: %f ah: %f => d: (%f, %f) %s\n", - measureModeName(widthMeasureMode, performLayout), - measureModeName(heightMeasureMode, performLayout), + sizingModeName(widthSizingMode, performLayout), + sizingModeName(heightSizingMode, performLayout), availableWidth, availableHeight, cachedResults->computedWidth, @@ -2551,8 +2545,8 @@ bool calculateLayoutInternal( node, LogLevel::Verbose, "wm: %s, hm: %s, aw: %f ah: %f %s\n", - measureModeName(widthMeasureMode, performLayout), - measureModeName(heightMeasureMode, performLayout), + sizingModeName(widthSizingMode, performLayout), + sizingModeName(heightSizingMode, performLayout), availableWidth, availableHeight, LayoutPassReasonToString(reason)); @@ -2563,8 +2557,8 @@ bool calculateLayoutInternal( availableWidth, availableHeight, ownerDirection, - widthMeasureMode, - heightMeasureMode, + widthSizingMode, + heightSizingMode, ownerWidth, ownerHeight, performLayout, @@ -2586,8 +2580,8 @@ bool calculateLayoutInternal( node, LogLevel::Verbose, "wm: %s, hm: %s, d: (%f, %f) %s\n", - measureModeName(widthMeasureMode, performLayout), - measureModeName(heightMeasureMode, performLayout), + sizingModeName(widthSizingMode, performLayout), + sizingModeName(heightSizingMode, performLayout), layout->measuredDimension(Dimension::Width), layout->measuredDimension(Dimension::Height), LayoutPassReasonToString(reason)); @@ -2621,8 +2615,8 @@ bool calculateLayoutInternal( newCacheEntry->availableWidth = availableWidth; newCacheEntry->availableHeight = availableHeight; - newCacheEntry->widthMeasureMode = widthMeasureMode; - newCacheEntry->heightMeasureMode = heightMeasureMode; + newCacheEntry->widthSizingMode = widthSizingMode; + newCacheEntry->heightSizingMode = heightSizingMode; newCacheEntry->computedWidth = layout->measuredDimension(Dimension::Width); newCacheEntry->computedHeight = @@ -2672,7 +2666,7 @@ void calculateLayout( gCurrentGenerationCount.fetch_add(1, std::memory_order_relaxed); node->resolveDimension(); float width = YGUndefined; - MeasureMode widthMeasureMode = MeasureMode::Undefined; + SizingMode widthSizingMode = SizingMode::MaxContent; const auto& style = node->getStyle(); if (styleDefinesDimension(node, FlexDirection::Row, ownerWidth)) { width = @@ -2681,21 +2675,21 @@ void calculateLayout( ownerWidth) .unwrap() + node->getMarginForAxis(FlexDirection::Row, ownerWidth)); - widthMeasureMode = MeasureMode::Exactly; + widthSizingMode = SizingMode::StretchFit; } else if (yoga::resolveValue( style.maxDimension(Dimension::Width), ownerWidth) .isDefined()) { width = yoga::resolveValue(style.maxDimension(Dimension::Width), ownerWidth) .unwrap(); - widthMeasureMode = MeasureMode::AtMost; + widthSizingMode = SizingMode::FitContent; } else { width = ownerWidth; - widthMeasureMode = yoga::isUndefined(width) ? MeasureMode::Undefined - : MeasureMode::Exactly; + widthSizingMode = yoga::isUndefined(width) ? SizingMode::MaxContent + : SizingMode::StretchFit; } float height = YGUndefined; - MeasureMode heightMeasureMode = MeasureMode::Undefined; + SizingMode heightSizingMode = SizingMode::MaxContent; if (styleDefinesDimension(node, FlexDirection::Column, ownerHeight)) { height = (yoga::resolveValue( @@ -2703,26 +2697,26 @@ void calculateLayout( ownerHeight) .unwrap() + node->getMarginForAxis(FlexDirection::Column, ownerWidth)); - heightMeasureMode = MeasureMode::Exactly; + heightSizingMode = SizingMode::StretchFit; } else if (yoga::resolveValue( style.maxDimension(Dimension::Height), ownerHeight) .isDefined()) { height = yoga::resolveValue(style.maxDimension(Dimension::Height), ownerHeight) .unwrap(); - heightMeasureMode = MeasureMode::AtMost; + heightSizingMode = SizingMode::FitContent; } else { height = ownerHeight; - heightMeasureMode = yoga::isUndefined(height) ? MeasureMode::Undefined - : MeasureMode::Exactly; + heightSizingMode = yoga::isUndefined(height) ? SizingMode::MaxContent + : SizingMode::StretchFit; } if (calculateLayoutInternal( node, width, height, ownerDirection, - widthMeasureMode, - heightMeasureMode, + widthSizingMode, + heightSizingMode, ownerWidth, ownerHeight, true, diff --git a/yoga/algorithm/SizingMode.h b/yoga/algorithm/SizingMode.h new file mode 100644 index 0000000000..bd725df13a --- /dev/null +++ b/yoga/algorithm/SizingMode.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook::yoga { + +/** + * Corresponds to a CSS auto box sizes. Missing "min-content", as Yoga does not + * current support automatic minimum sizes. + * https://www.w3.org/TR/css-sizing-3/#auto-box-sizes + * https://www.w3.org/TR/css-flexbox-1/#min-size-auto + */ +enum class SizingMode { + /** + * The size a box would take if its outer size filled the available space in + * the given axis; in other words, the stretch fit into the available space, + * if that is definite. Undefined if the available space is indefinite. + */ + StretchFit, + + /** + * A box’s “ideal” size in a given axis when given infinite available space. + * Usually this is the smallest size the box could take in that axis while + * still fitting around its contents, i.e. minimizing unfilled space while + * avoiding overflow. + */ + MaxContent, + + /** + * If the available space in a given axis is definite, equal to + * clamp(min-content size, stretch-fit size, max-content size) (i.e. + * max(min-content size, min(max-content size, stretch-fit size))). When + * sizing under a min-content constraint, equal to the min-content size. + * Otherwise, equal to the max-content size in that axis. + */ + FitContent, +}; + +inline MeasureMode measureMode(SizingMode mode) { + switch (mode) { + case SizingMode::StretchFit: + return MeasureMode::Exactly; + case SizingMode::MaxContent: + return MeasureMode::Undefined; + case SizingMode::FitContent: + return MeasureMode::AtMost; + } + + fatalWithMessage("Invalid SizingMode"); +} + +inline SizingMode sizingMode(MeasureMode mode) { + switch (mode) { + case MeasureMode::Exactly: + return SizingMode::StretchFit; + case MeasureMode::Undefined: + return SizingMode::MaxContent; + case MeasureMode::AtMost: + return SizingMode::FitContent; + } + + fatalWithMessage("Invalid MeasureMode"); +} + +} // namespace facebook::yoga diff --git a/yoga/node/CachedMeasurement.h b/yoga/node/CachedMeasurement.h index 4d2c222600..9c76280acf 100644 --- a/yoga/node/CachedMeasurement.h +++ b/yoga/node/CachedMeasurement.h @@ -11,7 +11,7 @@ #include -#include +#include #include namespace facebook::yoga { @@ -19,15 +19,15 @@ namespace facebook::yoga { struct CachedMeasurement { float availableWidth{-1}; float availableHeight{-1}; - MeasureMode widthMeasureMode{MeasureMode::Undefined}; - MeasureMode heightMeasureMode{MeasureMode::Undefined}; + SizingMode widthSizingMode{SizingMode::MaxContent}; + SizingMode heightSizingMode{SizingMode::MaxContent}; float computedWidth{-1}; float computedHeight{-1}; bool operator==(CachedMeasurement measurement) const { - bool isEqual = widthMeasureMode == measurement.widthMeasureMode && - heightMeasureMode == measurement.heightMeasureMode; + bool isEqual = widthSizingMode == measurement.widthSizingMode && + heightSizingMode == measurement.heightSizingMode; if (!yoga::isUndefined(availableWidth) || !yoga::isUndefined(measurement.availableWidth)) {