152 lines
3.8 KiB
C
152 lines
3.8 KiB
C
|
/*
|
||
|
* Copyright (c) Facebook, Inc. and its 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 <algorithm>
|
||
|
#include <array>
|
||
|
#include <cmath>
|
||
|
#include <vector>
|
||
|
#include "CompactValue.h"
|
||
|
#include "Yoga.h"
|
||
|
|
||
|
using YGVector = std::vector<YGNodeRef>;
|
||
|
|
||
|
YG_EXTERN_C_BEGIN
|
||
|
|
||
|
void YGNodeCalculateLayoutWithContext(
|
||
|
YGNodeRef node,
|
||
|
float availableWidth,
|
||
|
float availableHeight,
|
||
|
YGDirection ownerDirection,
|
||
|
void* layoutContext);
|
||
|
|
||
|
YG_EXTERN_C_END
|
||
|
|
||
|
namespace facebook {
|
||
|
namespace yoga {
|
||
|
|
||
|
inline bool isUndefined(float value) {
|
||
|
return std::isnan(value);
|
||
|
}
|
||
|
|
||
|
} // namespace yoga
|
||
|
} // namespace facebook
|
||
|
|
||
|
using namespace facebook;
|
||
|
|
||
|
extern const std::array<YGEdge, 4> trailing;
|
||
|
extern const std::array<YGEdge, 4> leading;
|
||
|
extern const YGValue YGValueUndefined;
|
||
|
extern const YGValue YGValueAuto;
|
||
|
extern const YGValue YGValueZero;
|
||
|
|
||
|
struct YGCachedMeasurement {
|
||
|
float availableWidth;
|
||
|
float availableHeight;
|
||
|
YGMeasureMode widthMeasureMode;
|
||
|
YGMeasureMode heightMeasureMode;
|
||
|
|
||
|
float computedWidth;
|
||
|
float computedHeight;
|
||
|
|
||
|
YGCachedMeasurement()
|
||
|
: availableWidth(0),
|
||
|
availableHeight(0),
|
||
|
widthMeasureMode((YGMeasureMode) -1),
|
||
|
heightMeasureMode((YGMeasureMode) -1),
|
||
|
computedWidth(-1),
|
||
|
computedHeight(-1) {}
|
||
|
|
||
|
bool operator==(YGCachedMeasurement measurement) const {
|
||
|
bool isEqual = widthMeasureMode == measurement.widthMeasureMode &&
|
||
|
heightMeasureMode == measurement.heightMeasureMode;
|
||
|
|
||
|
if (!yoga::isUndefined(availableWidth) ||
|
||
|
!yoga::isUndefined(measurement.availableWidth)) {
|
||
|
isEqual = isEqual && availableWidth == measurement.availableWidth;
|
||
|
}
|
||
|
if (!yoga::isUndefined(availableHeight) ||
|
||
|
!yoga::isUndefined(measurement.availableHeight)) {
|
||
|
isEqual = isEqual && availableHeight == measurement.availableHeight;
|
||
|
}
|
||
|
if (!yoga::isUndefined(computedWidth) ||
|
||
|
!yoga::isUndefined(measurement.computedWidth)) {
|
||
|
isEqual = isEqual && computedWidth == measurement.computedWidth;
|
||
|
}
|
||
|
if (!yoga::isUndefined(computedHeight) ||
|
||
|
!yoga::isUndefined(measurement.computedHeight)) {
|
||
|
isEqual = isEqual && computedHeight == measurement.computedHeight;
|
||
|
}
|
||
|
|
||
|
return isEqual;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// This value was chosen based on empirical data:
|
||
|
// 98% of analyzed layouts require less than 8 entries.
|
||
|
#define YG_MAX_CACHED_RESULT_COUNT 8
|
||
|
|
||
|
namespace facebook {
|
||
|
namespace yoga {
|
||
|
namespace detail {
|
||
|
|
||
|
template <size_t Size>
|
||
|
class Values {
|
||
|
private:
|
||
|
std::array<CompactValue, Size> values_;
|
||
|
|
||
|
public:
|
||
|
Values() = default;
|
||
|
explicit Values(const YGValue& defaultValue) noexcept {
|
||
|
values_.fill(defaultValue);
|
||
|
}
|
||
|
|
||
|
const CompactValue& operator[](size_t i) const noexcept { return values_[i]; }
|
||
|
CompactValue& operator[](size_t i) noexcept { return values_[i]; }
|
||
|
|
||
|
template <size_t I>
|
||
|
YGValue get() const noexcept {
|
||
|
return std::get<I>(values_);
|
||
|
}
|
||
|
|
||
|
template <size_t I>
|
||
|
void set(YGValue& value) noexcept {
|
||
|
std::get<I>(values_) = value;
|
||
|
}
|
||
|
|
||
|
template <size_t I>
|
||
|
void set(YGValue&& value) noexcept {
|
||
|
set<I>(value);
|
||
|
}
|
||
|
|
||
|
bool operator==(const Values& other) const noexcept {
|
||
|
for (size_t i = 0; i < Size; ++i) {
|
||
|
if (values_[i] != other.values_[i]) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
Values& operator=(const Values& other) = default;
|
||
|
};
|
||
|
|
||
|
} // namespace detail
|
||
|
} // namespace yoga
|
||
|
} // namespace facebook
|
||
|
|
||
|
static const float kDefaultFlexGrow = 0.0f;
|
||
|
static const float kDefaultFlexShrink = 0.0f;
|
||
|
static const float kWebDefaultFlexShrink = 1.0f;
|
||
|
|
||
|
extern bool YGFloatsEqual(const float a, const float b);
|
||
|
extern facebook::yoga::detail::CompactValue YGComputedEdgeValue(
|
||
|
const facebook::yoga::detail::Values<
|
||
|
facebook::yoga::enums::count<YGEdge>()>& edges,
|
||
|
YGEdge edge,
|
||
|
facebook::yoga::detail::CompactValue defaultValue);
|