Files
yoga/yoga/algorithm/Cache.cpp
Nick Gerleman a121483e81 Use CSS terminology for sizing rules (#1460)
Summary:
X-link: https://github.com/facebook/react-native/pull/41390

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

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.

Reviewed By: joevilches

Differential Revision: D51068417

fbshipit-source-id: 0a76266a4e7e0cc39996164607229c3c41de2818
2023-11-25 20:41:22 -08:00

122 lines
4.4 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/algorithm/Cache.h>
#include <yoga/algorithm/PixelGrid.h>
#include <yoga/numeric/Comparison.h>
namespace facebook::yoga {
static inline bool sizeIsExactAndMatchesOldMeasuredSize(
SizingMode sizeMode,
float size,
float lastComputedSize) {
return sizeMode == SizingMode::StretchFit &&
yoga::inexactEquals(size, lastComputedSize);
}
static inline bool oldSizeIsMaxContentAndStillFits(
SizingMode sizeMode,
float size,
SizingMode lastSizeMode,
float lastComputedSize) {
return sizeMode == SizingMode::FitContent &&
lastSizeMode == SizingMode::MaxContent &&
(size >= lastComputedSize || yoga::inexactEquals(size, lastComputedSize));
}
static inline bool newSizeIsStricterAndStillValid(
SizingMode sizeMode,
float size,
SizingMode lastSizeMode,
float lastSize,
float lastComputedSize) {
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 SizingMode widthMode,
const float availableWidth,
const SizingMode heightMode,
const float availableHeight,
const SizingMode lastWidthMode,
const float lastAvailableWidth,
const SizingMode lastHeightMode,
const float lastAvailableHeight,
const float lastComputedWidth,
const float lastComputedHeight,
const float marginRow,
const float marginColumn,
const yoga::Config* const config) {
if ((yoga::isDefined(lastComputedHeight) && lastComputedHeight < 0) ||
((yoga::isDefined(lastComputedWidth)) && lastComputedWidth < 0)) {
return false;
}
const float pointScaleFactor = config->getPointScaleFactor();
bool useRoundedComparison = config != nullptr && pointScaleFactor != 0;
const float effectiveWidth = useRoundedComparison
? roundValueToPixelGrid(availableWidth, pointScaleFactor, false, false)
: availableWidth;
const float effectiveHeight = useRoundedComparison
? roundValueToPixelGrid(availableHeight, pointScaleFactor, false, false)
: availableHeight;
const float effectiveLastWidth = useRoundedComparison
? roundValueToPixelGrid(
lastAvailableWidth, pointScaleFactor, false, false)
: lastAvailableWidth;
const float effectiveLastHeight = useRoundedComparison
? roundValueToPixelGrid(
lastAvailableHeight, pointScaleFactor, false, false)
: lastAvailableHeight;
const bool hasSameWidthSpec = lastWidthMode == widthMode &&
yoga::inexactEquals(effectiveLastWidth, effectiveWidth);
const bool hasSameHeightSpec = lastHeightMode == heightMode &&
yoga::inexactEquals(effectiveLastHeight, effectiveHeight);
const bool widthIsCompatible =
hasSameWidthSpec ||
sizeIsExactAndMatchesOldMeasuredSize(
widthMode, availableWidth - marginRow, lastComputedWidth) ||
oldSizeIsMaxContentAndStillFits(
widthMode,
availableWidth - marginRow,
lastWidthMode,
lastComputedWidth) ||
newSizeIsStricterAndStillValid(
widthMode,
availableWidth - marginRow,
lastWidthMode,
lastAvailableWidth,
lastComputedWidth);
const bool heightIsCompatible = hasSameHeightSpec ||
sizeIsExactAndMatchesOldMeasuredSize(
heightMode,
availableHeight - marginColumn,
lastComputedHeight) ||
oldSizeIsMaxContentAndStillFits(heightMode,
availableHeight - marginColumn,
lastHeightMode,
lastComputedHeight) ||
newSizeIsStricterAndStillValid(heightMode,
availableHeight - marginColumn,
lastHeightMode,
lastAvailableHeight,
lastComputedHeight);
return widthIsCompatible && heightIsCompatible;
}
} // namespace facebook::yoga