Files
yoga/yoga/algorithm/Baseline.cpp
Nick Gerleman a8566a0150 C++ style enums 16/N: Dimension (#1403)
Summary:
X-link: https://github.com/facebook/react-native/pull/39598

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

Replaces all usages of YGDimension with Dimension.

Adds `yoga::to_underlying` to act like `std::to_underlying`, added in C++ 23.

This enum is oddly only used internally, and is never an input to the public API, but it handled as any other public generated enum. Potentially some more cleanup to do there.

Changelog: [Internal]

Reviewed By: rshest

Differential Revision: D49475409

fbshipit-source-id: 7d4c31e8a84485baea0dab50b5cf16b86769fa07
2023-09-29 00:06:34 -07:00

83 lines
2.2 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/Align.h>
#include <yoga/algorithm/Baseline.h>
#include <yoga/debug/AssertFatal.h>
#include <yoga/event/event.h>
namespace facebook::yoga {
float calculateBaseline(const yoga::Node* node) {
if (node->hasBaselineFunc()) {
Event::publish<Event::NodeBaselineStart>(node);
const float baseline = node->baseline(
node->getLayout().measuredDimension(Dimension::Width),
node->getLayout().measuredDimension(Dimension::Height));
Event::publish<Event::NodeBaselineEnd>(node);
yoga::assertFatalWithNode(
node,
!std::isnan(baseline),
"Expect custom baseline function to not return NaN");
return baseline;
}
yoga::Node* baselineChild = nullptr;
const size_t childCount = node->getChildCount();
for (size_t i = 0; i < childCount; i++) {
auto child = node->getChild(i);
if (child->getLineIndex() > 0) {
break;
}
if (child->getStyle().positionType() == PositionType::Absolute) {
continue;
}
if (resolveChildAlignment(node, child) == Align::Baseline ||
child->isReferenceBaseline()) {
baselineChild = child;
break;
}
if (baselineChild == nullptr) {
baselineChild = child;
}
}
if (baselineChild == nullptr) {
return node->getLayout().measuredDimension(Dimension::Height);
}
const float baseline = calculateBaseline(baselineChild);
return baseline + baselineChild->getLayout().position[YGEdgeTop];
}
bool isBaselineLayout(const yoga::Node* node) {
if (isColumn(node->getStyle().flexDirection())) {
return false;
}
if (node->getStyle().alignItems() == Align::Baseline) {
return true;
}
const auto childCount = node->getChildCount();
for (size_t i = 0; i < childCount; i++) {
auto child = node->getChild(i);
if (child->getStyle().positionType() != PositionType::Absolute &&
child->getStyle().alignSelf() == Align::Baseline) {
return true;
}
}
return false;
}
} // namespace facebook::yoga