Files
yoga/yoga/algorithm/FlexLine.cpp
Nick Gerleman 03d0523996 C++ style enums 13/N: Wrap (#1400)
Summary:
X-link: https://github.com/facebook/react-native/pull/39539

Pull Request resolved: https://github.com/facebook/yoga/pull/1400

Moves internal usages of YGPositionType to PositionType

bypass-github-export-checks

Changelog: [Internal]

Reviewed By: rshest

Differential Revision: D49361746

fbshipit-source-id: ccc77b4c77753b5f41e11f1849d4c02153c190b7
2023-09-19 16:30:02 -07:00

108 lines
3.6 KiB
C++

/*
* 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.
*/
#include <yoga/Yoga.h>
#include <yoga/algorithm/BoundAxis.h>
#include <yoga/algorithm/FlexDirection.h>
#include <yoga/algorithm/FlexLine.h>
namespace facebook::yoga {
FlexLine calculateFlexLine(
yoga::Node* const node,
const Direction ownerDirection,
const float mainAxisownerSize,
const float availableInnerWidth,
const float availableInnerMainDim,
const size_t startOfLineIndex,
const size_t lineCount) {
std::vector<yoga::Node*> itemsInFlow;
itemsInFlow.reserve(node->getChildren().size());
float sizeConsumed = 0.0f;
float totalFlexGrowFactors = 0.0f;
float totalFlexShrinkScaledFactors = 0.0f;
size_t endOfLineIndex = startOfLineIndex;
float sizeConsumedIncludingMinConstraint = 0;
const FlexDirection mainAxis = resolveDirection(
node->getStyle().flexDirection(), node->resolveDirection(ownerDirection));
const bool isNodeFlexWrap = node->getStyle().flexWrap() != Wrap::NoWrap;
const float gap = node->getGapForAxis(mainAxis, availableInnerWidth).unwrap();
// Add items to the current line until it's full or we run out of items.
for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) {
auto child = node->getChild(endOfLineIndex);
if (child->getStyle().display() == YGDisplayNone ||
child->getStyle().positionType() == PositionType::Absolute) {
continue;
}
const bool isFirstElementInLine = (endOfLineIndex - startOfLineIndex) == 0;
child->setLineIndex(lineCount);
const float childMarginMainAxis =
child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap();
const float childLeadingGapMainAxis = isFirstElementInLine ? 0.0f : gap;
const float flexBasisWithMinAndMaxConstraints =
boundAxisWithinMinAndMax(
child,
mainAxis,
child->getLayout().computedFlexBasis,
mainAxisownerSize)
.unwrap();
// If this is a multi-line flow and this item pushes us over the available
// size, we've hit the end of the current line. Break out of the loop and
// lay out the current line.
if (sizeConsumedIncludingMinConstraint + flexBasisWithMinAndMaxConstraints +
childMarginMainAxis + childLeadingGapMainAxis >
availableInnerMainDim &&
isNodeFlexWrap && itemsInFlow.size() > 0) {
break;
}
sizeConsumedIncludingMinConstraint += flexBasisWithMinAndMaxConstraints +
childMarginMainAxis + childLeadingGapMainAxis;
sizeConsumed += flexBasisWithMinAndMaxConstraints + childMarginMainAxis +
childLeadingGapMainAxis;
if (child->isNodeFlexible()) {
totalFlexGrowFactors += child->resolveFlexGrow();
// Unlike the grow factor, the shrink factor is scaled relative to the
// child dimension.
totalFlexShrinkScaledFactors += -child->resolveFlexShrink() *
child->getLayout().computedFlexBasis.unwrap();
}
itemsInFlow.push_back(child);
}
// The total flex factor needs to be floored to 1.
if (totalFlexGrowFactors > 0 && totalFlexGrowFactors < 1) {
totalFlexGrowFactors = 1;
}
// The total flex shrink factor needs to be floored to 1.
if (totalFlexShrinkScaledFactors > 0 && totalFlexShrinkScaledFactors < 1) {
totalFlexShrinkScaledFactors = 1;
}
return FlexLine{
std::move(itemsInFlow),
sizeConsumed,
endOfLineIndex,
FlexLineRunningLayout{
totalFlexGrowFactors,
totalFlexShrinkScaledFactors,
}};
}
} // namespace facebook::yoga