Change NaN with large number
Reviewed By: emilsjolander Differential Revision: D6969537 fbshipit-source-id: bdc09eaf703e0d313ca65c25a4fb44c99203d9bf
This commit is contained in:
parent
af9d6479e5
commit
d174ab8a7a
|
@ -9,12 +9,29 @@ package com.facebook.yoga;
|
||||||
|
|
||||||
public class YogaConstants {
|
public class YogaConstants {
|
||||||
|
|
||||||
public static final float UNDEFINED = Float.NaN;
|
/**
|
||||||
|
* Large positive number signifies that the property(float) is undefined. Earlier we used to have
|
||||||
|
* YGundefined as NAN, but the downside of this is that we can't use -ffast-math compiler flag as
|
||||||
|
* it assumes all floating-point calculation involve and result into finite numbers. For more
|
||||||
|
* information regarding -ffast-math compiler flag in clang, have a look at
|
||||||
|
* https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math
|
||||||
|
*/
|
||||||
|
public static final float UNDEFINED = (float) (10E20);
|
||||||
|
|
||||||
public static boolean shouldUseFastMath = false;
|
public static boolean shouldUseFastMath = false;
|
||||||
|
|
||||||
public static boolean isUndefined(float value) {
|
public static boolean isUndefined(float value) {
|
||||||
return Float.compare(value, UNDEFINED) == 0;
|
// Value of a float in the case of it being not defined is 10.1E20. Earlier it used to be NAN,
|
||||||
|
// the benefit of which
|
||||||
|
// was that if NAN is involved in any mathematical expression the result was NAN. But since we
|
||||||
|
// want to have `-ffast-math`
|
||||||
|
// flag being used by compiler which assumes that the floating point values are not NAN and Inf,
|
||||||
|
// we represent YGUndefined as 10.1E20.
|
||||||
|
// But now if YGUndefined is involved in any mathematical operations this value(10.1E20) would
|
||||||
|
// change.
|
||||||
|
// So the following check makes sure that if the value is outside a range (-10E8, 10E8) then it
|
||||||
|
// is undefined.
|
||||||
|
return (Float.compare(value, (float) 10E8) >= 0 || Float.compare(value, (float) -10E8) <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isUndefined(YogaValue value) {
|
public static boolean isUndefined(YogaValue value) {
|
||||||
|
|
|
@ -342,8 +342,10 @@ struct JYogaValue : public JavaClass<JYogaValue> {
|
||||||
return (javatype)YGNodeStyleGet##name(_jlong2YGNodeRef(nativePointer)); \
|
return (javatype)YGNodeStyleGet##name(_jlong2YGNodeRef(nativePointer)); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
void jni_YGNodeStyleSet##name(alias_ref<jobject>, jlong nativePointer, javatype value) { \
|
void jni_YGNodeStyleSet##name( \
|
||||||
YGNodeStyleSet##name(_jlong2YGNodeRef(nativePointer), static_cast<type>(value)); \
|
alias_ref<jobject>, jlong nativePointer, javatype value) { \
|
||||||
|
YGNodeStyleSet##name( \
|
||||||
|
_jlong2YGNodeRef(nativePointer), static_cast<type>(value)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define YG_NODE_JNI_STYLE_UNIT_PROP(name) \
|
#define YG_NODE_JNI_STYLE_UNIT_PROP(name) \
|
||||||
|
|
|
@ -15,15 +15,37 @@ YGFlexDirection YGFlexDirectionCross(
|
||||||
: YGFlexDirectionColumn;
|
: YGFlexDirectionColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float YGFloatMax(const float a, const float b) {
|
||||||
|
if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) {
|
||||||
|
return fmaxf(a, b);
|
||||||
|
}
|
||||||
|
return YGFloatIsUndefined(a) ? b : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
float YGFloatMin(const float a, const float b) {
|
||||||
|
if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) {
|
||||||
|
return fminf(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
return YGFloatIsUndefined(a) ? b : a;
|
||||||
|
}
|
||||||
|
|
||||||
bool YGValueEqual(const YGValue a, const YGValue b) {
|
bool YGValueEqual(const YGValue a, const YGValue b) {
|
||||||
if (a.unit != b.unit) {
|
if (a.unit != b.unit) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.unit == YGUnitUndefined ||
|
if (a.unit == YGUnitUndefined ||
|
||||||
(std::isnan(a.value) && std::isnan(b.value))) {
|
(YGFloatIsUndefined(a.value) && YGFloatIsUndefined(b.value))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fabs(a.value - b.value) < 0.0001f;
|
return fabs(a.value - b.value) < 0.0001f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool YGFloatsEqual(const float a, const float b) {
|
||||||
|
if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) {
|
||||||
|
return fabs(a - b) < 0.0001f;
|
||||||
|
}
|
||||||
|
return YGFloatIsUndefined(a) && YGFloatIsUndefined(b);
|
||||||
|
}
|
||||||
|
|
|
@ -54,6 +54,38 @@ struct YGCollectFlexItemsRowValues {
|
||||||
|
|
||||||
bool YGValueEqual(const YGValue a, const YGValue b);
|
bool YGValueEqual(const YGValue a, const YGValue b);
|
||||||
|
|
||||||
|
// This custom float equality function returns true if either absolute
|
||||||
|
// difference between two floats is less than 0.0001f or both are undefined.
|
||||||
|
bool YGFloatsEqual(const float a, const float b);
|
||||||
|
|
||||||
|
// We need custom max function, since we want that, if one argument is
|
||||||
|
// YGUndefined then the max funtion should return the other argument as the max
|
||||||
|
// value. We wouldn't have needed a custom max function if YGUndefined was NAN
|
||||||
|
// as fmax has the same behaviour, but with NAN we cannot use `-ffast-math`
|
||||||
|
// compiler flag.
|
||||||
|
float YGFloatMax(const float a, const float b);
|
||||||
|
|
||||||
|
// We need custom min function, since we want that, if one argument is
|
||||||
|
// YGUndefined then the min funtion should return the other argument as the min
|
||||||
|
// value. We wouldn't have needed a custom min function if YGUndefined was NAN
|
||||||
|
// as fmin has the same behaviour, but with NAN we cannot use `-ffast-math`
|
||||||
|
// compiler flag.
|
||||||
|
float YGFloatMin(const float a, const float b);
|
||||||
|
|
||||||
|
// This custom float comparision function compares the array of float with
|
||||||
|
// YGFloatsEqual, as the default float comparision operator will not work(Look
|
||||||
|
// at the comments of YGFloatsEqual function).
|
||||||
|
template <std::size_t size>
|
||||||
|
bool YGFloatArrayEqual(
|
||||||
|
const std::array<float, size>& val1,
|
||||||
|
const std::array<float, size>& val2) {
|
||||||
|
bool areEqual = true;
|
||||||
|
for (std::size_t i = 0; i < size && areEqual; ++i) {
|
||||||
|
areEqual = YGFloatsEqual(val1[i], val2[i]);
|
||||||
|
}
|
||||||
|
return areEqual;
|
||||||
|
}
|
||||||
|
|
||||||
YGFlexDirection YGFlexDirectionCross(
|
YGFlexDirection YGFlexDirectionCross(
|
||||||
const YGFlexDirection flexDirection,
|
const YGFlexDirection flexDirection,
|
||||||
const YGDirection direction);
|
const YGDirection direction);
|
||||||
|
@ -71,7 +103,7 @@ inline float YGResolveValue(const YGValue value, const float parentSize) {
|
||||||
case YGUnitPoint:
|
case YGUnitPoint:
|
||||||
return value.value;
|
return value.value;
|
||||||
case YGUnitPercent:
|
case YGUnitPercent:
|
||||||
return value.value * parentSize / 100.0f;
|
return value.value * parentSize * 0.01;
|
||||||
}
|
}
|
||||||
return YGUndefined;
|
return YGUndefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*/
|
*/
|
||||||
#include "YGLayout.h"
|
#include "YGLayout.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
const std::array<float, 2> kYGDefaultDimensionValues = {
|
const std::array<float, 2> kYGDefaultDimensionValues = {
|
||||||
{YGUndefined, YGUndefined}};
|
{YGUndefined, YGUndefined}};
|
||||||
|
@ -31,9 +32,11 @@ YGLayout::YGLayout()
|
||||||
doesLegacyStretchFlagAffectsLayout(false) {}
|
doesLegacyStretchFlagAffectsLayout(false) {}
|
||||||
|
|
||||||
bool YGLayout::operator==(YGLayout layout) const {
|
bool YGLayout::operator==(YGLayout layout) const {
|
||||||
bool isEqual = position == layout.position &&
|
bool isEqual = YGFloatArrayEqual(position, layout.position) &&
|
||||||
dimensions == layout.dimensions && margin == layout.margin &&
|
YGFloatArrayEqual(dimensions, layout.dimensions) &&
|
||||||
border == layout.border && padding == layout.padding &&
|
YGFloatArrayEqual(margin, layout.margin) &&
|
||||||
|
YGFloatArrayEqual(border, layout.border) &&
|
||||||
|
YGFloatArrayEqual(padding, layout.padding) &&
|
||||||
direction == layout.direction && hadOverflow == layout.hadOverflow &&
|
direction == layout.direction && hadOverflow == layout.hadOverflow &&
|
||||||
lastParentDirection == layout.lastParentDirection &&
|
lastParentDirection == layout.lastParentDirection &&
|
||||||
nextCachedMeasurementsIndex == layout.nextCachedMeasurementsIndex &&
|
nextCachedMeasurementsIndex == layout.nextCachedMeasurementsIndex &&
|
||||||
|
|
|
@ -624,26 +624,28 @@ bool YGNode::isNodeFlexible() {
|
||||||
float YGNode::getLeadingBorder(const YGFlexDirection axis) {
|
float YGNode::getLeadingBorder(const YGFlexDirection axis) {
|
||||||
if (YGFlexDirectionIsRow(axis) &&
|
if (YGFlexDirectionIsRow(axis) &&
|
||||||
style_.border[YGEdgeStart].unit != YGUnitUndefined &&
|
style_.border[YGEdgeStart].unit != YGUnitUndefined &&
|
||||||
|
!YGFloatIsUndefined(style_.border[YGEdgeStart].value) &&
|
||||||
style_.border[YGEdgeStart].value >= 0.0f) {
|
style_.border[YGEdgeStart].value >= 0.0f) {
|
||||||
return style_.border[YGEdgeStart].value;
|
return style_.border[YGEdgeStart].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmaxf(
|
float computedEdgeValue =
|
||||||
YGComputedEdgeValue(style_.border, leading[axis], &YGValueZero)->value,
|
YGComputedEdgeValue(style_.border, leading[axis], &YGValueZero)->value;
|
||||||
0.0f);
|
return YGFloatMax(computedEdgeValue, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) {
|
float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) {
|
||||||
if (YGFlexDirectionIsRow(flexDirection) &&
|
if (YGFlexDirectionIsRow(flexDirection) &&
|
||||||
style_.border[YGEdgeEnd].unit != YGUnitUndefined &&
|
style_.border[YGEdgeEnd].unit != YGUnitUndefined &&
|
||||||
|
!YGFloatIsUndefined(style_.border[YGEdgeEnd].value) &&
|
||||||
style_.border[YGEdgeEnd].value >= 0.0f) {
|
style_.border[YGEdgeEnd].value >= 0.0f) {
|
||||||
return style_.border[YGEdgeEnd].value;
|
return style_.border[YGEdgeEnd].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmaxf(
|
float computedEdgeValue =
|
||||||
YGComputedEdgeValue(style_.border, trailing[flexDirection], &YGValueZero)
|
YGComputedEdgeValue(style_.border, trailing[flexDirection], &YGValueZero)
|
||||||
->value,
|
->value;
|
||||||
0.0f);
|
return YGFloatMax(computedEdgeValue, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float YGNode::getLeadingPadding(
|
float YGNode::getLeadingPadding(
|
||||||
|
@ -651,14 +653,16 @@ float YGNode::getLeadingPadding(
|
||||||
const float widthSize) {
|
const float widthSize) {
|
||||||
if (YGFlexDirectionIsRow(axis) &&
|
if (YGFlexDirectionIsRow(axis) &&
|
||||||
style_.padding[YGEdgeStart].unit != YGUnitUndefined &&
|
style_.padding[YGEdgeStart].unit != YGUnitUndefined &&
|
||||||
YGResolveValue(style_.padding[YGEdgeStart], widthSize) >= 0.0f) {
|
!YGFloatIsUndefined(
|
||||||
|
YGResolveValue(style_.padding[YGEdgeStart], widthSize)) &&
|
||||||
|
YGResolveValue(style_.padding[YGEdgeStart], widthSize) > 0.0f) {
|
||||||
return YGResolveValue(style_.padding[YGEdgeStart], widthSize);
|
return YGResolveValue(style_.padding[YGEdgeStart], widthSize);
|
||||||
}
|
}
|
||||||
return fmaxf(
|
|
||||||
YGResolveValue(
|
float resolvedValue = YGResolveValue(
|
||||||
*YGComputedEdgeValue(style_.padding, leading[axis], &YGValueZero),
|
*YGComputedEdgeValue(style_.padding, leading[axis], &YGValueZero),
|
||||||
widthSize),
|
widthSize);
|
||||||
0.0f);
|
return YGFloatMax(resolvedValue, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float YGNode::getTrailingPadding(
|
float YGNode::getTrailingPadding(
|
||||||
|
@ -666,14 +670,17 @@ float YGNode::getTrailingPadding(
|
||||||
const float widthSize) {
|
const float widthSize) {
|
||||||
if (YGFlexDirectionIsRow(axis) &&
|
if (YGFlexDirectionIsRow(axis) &&
|
||||||
style_.padding[YGEdgeEnd].unit != YGUnitUndefined &&
|
style_.padding[YGEdgeEnd].unit != YGUnitUndefined &&
|
||||||
|
!YGFloatIsUndefined(
|
||||||
|
YGResolveValue(style_.padding[YGEdgeEnd], widthSize)) &&
|
||||||
YGResolveValue(style_.padding[YGEdgeEnd], widthSize) >= 0.0f) {
|
YGResolveValue(style_.padding[YGEdgeEnd], widthSize) >= 0.0f) {
|
||||||
return YGResolveValue(style_.padding[YGEdgeEnd], widthSize);
|
return YGResolveValue(style_.padding[YGEdgeEnd], widthSize);
|
||||||
}
|
}
|
||||||
return fmaxf(
|
|
||||||
YGResolveValue(
|
float resolvedValue = YGResolveValue(
|
||||||
*YGComputedEdgeValue(style_.padding, trailing[axis], &YGValueZero),
|
*YGComputedEdgeValue(style_.padding, trailing[axis], &YGValueZero),
|
||||||
widthSize),
|
widthSize);
|
||||||
0.0f);
|
|
||||||
|
return YGFloatMax(resolvedValue, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float YGNode::getLeadingPaddingAndBorder(
|
float YGNode::getLeadingPaddingAndBorder(
|
||||||
|
|
|
@ -70,21 +70,23 @@ bool YGStyle::operator==(const YGStyle& style) {
|
||||||
YGValueArrayEqual(minDimensions, style.minDimensions) &&
|
YGValueArrayEqual(minDimensions, style.minDimensions) &&
|
||||||
YGValueArrayEqual(maxDimensions, style.maxDimensions);
|
YGValueArrayEqual(maxDimensions, style.maxDimensions);
|
||||||
|
|
||||||
if (!(std::isnan(flex) && std::isnan(style.flex))) {
|
if (!(YGFloatIsUndefined(flex) && YGFloatIsUndefined(style.flex))) {
|
||||||
areNonFloatValuesEqual = areNonFloatValuesEqual && flex == style.flex;
|
areNonFloatValuesEqual = areNonFloatValuesEqual && flex == style.flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(std::isnan(flexGrow) && std::isnan(style.flexGrow))) {
|
if (!(YGFloatIsUndefined(flexGrow) && YGFloatIsUndefined(style.flexGrow))) {
|
||||||
areNonFloatValuesEqual =
|
areNonFloatValuesEqual =
|
||||||
areNonFloatValuesEqual && flexGrow == style.flexGrow;
|
areNonFloatValuesEqual && flexGrow == style.flexGrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(std::isnan(flexShrink) && std::isnan(style.flexShrink))) {
|
if (!(YGFloatIsUndefined(flexShrink) &&
|
||||||
|
YGFloatIsUndefined(style.flexShrink))) {
|
||||||
areNonFloatValuesEqual =
|
areNonFloatValuesEqual =
|
||||||
areNonFloatValuesEqual && flexShrink == style.flexShrink;
|
areNonFloatValuesEqual && flexShrink == style.flexShrink;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(std::isnan(aspectRatio) && std::isnan(style.aspectRatio))) {
|
if (!(YGFloatIsUndefined(aspectRatio) &&
|
||||||
|
YGFloatIsUndefined(style.aspectRatio))) {
|
||||||
areNonFloatValuesEqual =
|
areNonFloatValuesEqual =
|
||||||
areNonFloatValuesEqual && aspectRatio == style.aspectRatio;
|
areNonFloatValuesEqual && aspectRatio == style.aspectRatio;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,19 +62,20 @@ struct YGCachedMeasurement {
|
||||||
bool isEqual = widthMeasureMode == measurement.widthMeasureMode &&
|
bool isEqual = widthMeasureMode == measurement.widthMeasureMode &&
|
||||||
heightMeasureMode == measurement.heightMeasureMode;
|
heightMeasureMode == measurement.heightMeasureMode;
|
||||||
|
|
||||||
if (!std::isnan(availableWidth) ||
|
if (!YGFloatIsUndefined(availableWidth) ||
|
||||||
!std::isnan(measurement.availableWidth)) {
|
!YGFloatIsUndefined(measurement.availableWidth)) {
|
||||||
isEqual = isEqual && availableWidth == measurement.availableWidth;
|
isEqual = isEqual && availableWidth == measurement.availableWidth;
|
||||||
}
|
}
|
||||||
if (!std::isnan(availableHeight) ||
|
if (!YGFloatIsUndefined(availableHeight) ||
|
||||||
!std::isnan(measurement.availableHeight)) {
|
!YGFloatIsUndefined(measurement.availableHeight)) {
|
||||||
isEqual = isEqual && availableHeight == measurement.availableHeight;
|
isEqual = isEqual && availableHeight == measurement.availableHeight;
|
||||||
}
|
}
|
||||||
if (!std::isnan(computedWidth) || !std::isnan(measurement.computedWidth)) {
|
if (!YGFloatIsUndefined(computedWidth) ||
|
||||||
|
!YGFloatIsUndefined(measurement.computedWidth)) {
|
||||||
isEqual = isEqual && computedWidth == measurement.computedWidth;
|
isEqual = isEqual && computedWidth == measurement.computedWidth;
|
||||||
}
|
}
|
||||||
if (!std::isnan(computedHeight) ||
|
if (!YGFloatIsUndefined(computedHeight) ||
|
||||||
!std::isnan(measurement.computedHeight)) {
|
!YGFloatIsUndefined(measurement.computedHeight)) {
|
||||||
isEqual = isEqual && computedHeight == measurement.computedHeight;
|
isEqual = isEqual && computedHeight == measurement.computedHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,11 @@
|
||||||
/* define fmaxf if < VC12 */
|
/* define fmaxf if < VC12 */
|
||||||
#if _MSC_VER < 1800
|
#if _MSC_VER < 1800
|
||||||
__forceinline const float fmaxf(const float a, const float b) {
|
__forceinline const float fmaxf(const float a, const float b) {
|
||||||
|
if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) {
|
||||||
return (a > b) ? a : b;
|
return (a > b) ? a : b;
|
||||||
}
|
}
|
||||||
|
return YGFloatIsUndefined(a) ? b : a;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -118,7 +121,15 @@ static int YGDefaultLog(const YGConfigRef config,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool YGFloatIsUndefined(const float value) {
|
bool YGFloatIsUndefined(const float value) {
|
||||||
return std::isnan(value);
|
// Value of a float in the case of it being not defined is 10.1E20. Earlier
|
||||||
|
// it used to be NAN, the benefit of which was that if NAN is involved in any
|
||||||
|
// mathematical expression the result was NAN. But since we want to have
|
||||||
|
// `-ffast-math` flag being used by compiler which assumes that the floating
|
||||||
|
// point values are not NAN and Inf, we represent YGUndefined as 10.1E20. But
|
||||||
|
// now if YGUndefined is involved in any mathematical operations this
|
||||||
|
// value(10.1E20) would change. So the following check makes sure that if the
|
||||||
|
// value is outside a range (-10E8, 10E8) then it is undefined.
|
||||||
|
return value >= 10E8 || value <= -10E8;
|
||||||
}
|
}
|
||||||
|
|
||||||
const YGValue* YGComputedEdgeValue(
|
const YGValue* YGComputedEdgeValue(
|
||||||
|
@ -788,13 +799,6 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
|
||||||
const char *reason,
|
const char *reason,
|
||||||
const YGConfigRef config);
|
const YGConfigRef config);
|
||||||
|
|
||||||
bool YGFloatsEqual(const float a, const float b) {
|
|
||||||
if (YGFloatIsUndefined(a)) {
|
|
||||||
return YGFloatIsUndefined(b);
|
|
||||||
}
|
|
||||||
return fabs(a - b) < 0.0001f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void YGNodePrintInternal(const YGNodeRef node,
|
static void YGNodePrintInternal(const YGNodeRef node,
|
||||||
const YGPrintOptions options) {
|
const YGPrintOptions options) {
|
||||||
std::string str;
|
std::string str;
|
||||||
|
@ -909,12 +913,15 @@ static inline float YGNodeDimWithMargin(const YGNodeRef node,
|
||||||
static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node,
|
static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node,
|
||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
const float parentSize) {
|
const float parentSize) {
|
||||||
|
bool isUndefined =
|
||||||
|
YGFloatIsUndefined(node->getResolvedDimension(dim[axis]).value);
|
||||||
return !(
|
return !(
|
||||||
node->getResolvedDimension(dim[axis]).unit == YGUnitAuto ||
|
node->getResolvedDimension(dim[axis]).unit == YGUnitAuto ||
|
||||||
node->getResolvedDimension(dim[axis]).unit == YGUnitUndefined ||
|
node->getResolvedDimension(dim[axis]).unit == YGUnitUndefined ||
|
||||||
(node->getResolvedDimension(dim[axis]).unit == YGUnitPoint &&
|
(node->getResolvedDimension(dim[axis]).unit == YGUnitPoint &&
|
||||||
node->getResolvedDimension(dim[axis]).value < 0.0f) ||
|
!isUndefined && node->getResolvedDimension(dim[axis]).value < 0.0f) ||
|
||||||
(node->getResolvedDimension(dim[axis]).unit == YGUnitPercent &&
|
(node->getResolvedDimension(dim[axis]).unit == YGUnitPercent &&
|
||||||
|
!isUndefined &&
|
||||||
(node->getResolvedDimension(dim[axis]).value < 0.0f ||
|
(node->getResolvedDimension(dim[axis]).value < 0.0f ||
|
||||||
YGFloatIsUndefined(parentSize))));
|
YGFloatIsUndefined(parentSize))));
|
||||||
}
|
}
|
||||||
|
@ -964,7 +971,8 @@ static inline float YGNodeBoundAxis(const YGNodeRef node,
|
||||||
const float value,
|
const float value,
|
||||||
const float axisSize,
|
const float axisSize,
|
||||||
const float widthSize) {
|
const float widthSize) {
|
||||||
return fmaxf(YGNodeBoundAxisWithinMinAndMax(node, axis, value, axisSize),
|
return YGFloatMax(
|
||||||
|
YGNodeBoundAxisWithinMinAndMax(node, axis, value, axisSize),
|
||||||
YGNodePaddingAndBorderForAxis(node, axis, widthSize));
|
YGNodePaddingAndBorderForAxis(node, axis, widthSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1035,19 +1043,19 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
|
||||||
child->getConfig(), YGExperimentalFeatureWebFlexBasis) &&
|
child->getConfig(), YGExperimentalFeatureWebFlexBasis) &&
|
||||||
child->getLayout().computedFlexBasisGeneration !=
|
child->getLayout().computedFlexBasisGeneration !=
|
||||||
gCurrentGenerationCount)) {
|
gCurrentGenerationCount)) {
|
||||||
child->setLayoutComputedFlexBasis(fmaxf(
|
child->setLayoutComputedFlexBasis(YGFloatMax(
|
||||||
resolvedFlexBasis,
|
resolvedFlexBasis,
|
||||||
YGNodePaddingAndBorderForAxis(child, mainAxis, parentWidth)));
|
YGNodePaddingAndBorderForAxis(child, mainAxis, parentWidth)));
|
||||||
}
|
}
|
||||||
} else if (isMainAxisRow && isRowStyleDimDefined) {
|
} else if (isMainAxisRow && isRowStyleDimDefined) {
|
||||||
// The width is definite, so use that as the flex basis.
|
// The width is definite, so use that as the flex basis.
|
||||||
child->setLayoutComputedFlexBasis(fmaxf(
|
child->setLayoutComputedFlexBasis(YGFloatMax(
|
||||||
YGResolveValue(
|
YGResolveValue(
|
||||||
child->getResolvedDimension(YGDimensionWidth), parentWidth),
|
child->getResolvedDimension(YGDimensionWidth), parentWidth),
|
||||||
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, parentWidth)));
|
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, parentWidth)));
|
||||||
} else if (!isMainAxisRow && isColumnStyleDimDefined) {
|
} else if (!isMainAxisRow && isColumnStyleDimDefined) {
|
||||||
// The height is definite, so use that as the flex basis.
|
// The height is definite, so use that as the flex basis.
|
||||||
child->setLayoutComputedFlexBasis(fmaxf(
|
child->setLayoutComputedFlexBasis(YGFloatMax(
|
||||||
YGResolveValue(
|
YGResolveValue(
|
||||||
child->getResolvedDimension(YGDimensionHeight), parentHeight),
|
child->getResolvedDimension(YGDimensionHeight), parentHeight),
|
||||||
YGNodePaddingAndBorderForAxis(
|
YGNodePaddingAndBorderForAxis(
|
||||||
|
@ -1162,7 +1170,7 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
|
||||||
"measure",
|
"measure",
|
||||||
config);
|
config);
|
||||||
|
|
||||||
child->setLayoutComputedFlexBasis(fmaxf(
|
child->setLayoutComputedFlexBasis(YGFloatMax(
|
||||||
child->getLayout().measuredDimensions[dim[mainAxis]],
|
child->getLayout().measuredDimensions[dim[mainAxis]],
|
||||||
YGNodePaddingAndBorderForAxis(child, mainAxis, parentWidth)));
|
YGNodePaddingAndBorderForAxis(child, mainAxis, parentWidth)));
|
||||||
}
|
}
|
||||||
|
@ -1252,7 +1260,8 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
|
||||||
// If the size of the parent is defined then try to constrain the absolute child to that size
|
// If the size of the parent 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 parent.
|
// as well. This allows text within the absolute child to wrap to the size of its parent.
|
||||||
// This is the same behavior as many browsers implement.
|
// This is the same behavior as many browsers implement.
|
||||||
if (!isMainAxisRow && YGFloatIsUndefined(childWidth) && widthMode != YGMeasureModeUndefined &&
|
if (!isMainAxisRow && YGFloatIsUndefined(childWidth) &&
|
||||||
|
widthMode != YGMeasureModeUndefined && !YGFloatIsUndefined(width) &&
|
||||||
width > 0) {
|
width > 0) {
|
||||||
childWidth = width;
|
childWidth = width;
|
||||||
childWidthMeasureMode = YGMeasureModeAtMost;
|
childWidthMeasureMode = YGMeasureModeAtMost;
|
||||||
|
@ -1368,10 +1377,10 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(const YGNodeRef node,
|
||||||
// We want to make sure we don't call measure with negative size
|
// We want to make sure we don't call measure with negative size
|
||||||
const float innerWidth = YGFloatIsUndefined(availableWidth)
|
const float innerWidth = YGFloatIsUndefined(availableWidth)
|
||||||
? availableWidth
|
? availableWidth
|
||||||
: fmaxf(0, availableWidth - marginAxisRow - paddingAndBorderAxisRow);
|
: YGFloatMax(0, availableWidth - marginAxisRow - paddingAndBorderAxisRow);
|
||||||
const float innerHeight = YGFloatIsUndefined(availableHeight)
|
const float innerHeight = YGFloatIsUndefined(availableHeight)
|
||||||
? availableHeight
|
? availableHeight
|
||||||
: fmaxf(
|
: YGFloatMax(
|
||||||
0, availableHeight - marginAxisColumn - paddingAndBorderAxisColumn);
|
0, availableHeight - marginAxisColumn - paddingAndBorderAxisColumn);
|
||||||
|
|
||||||
if (widthMeasureMode == YGMeasureModeExactly &&
|
if (widthMeasureMode == YGMeasureModeExactly &&
|
||||||
|
@ -1474,9 +1483,12 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(const YGNodeRef node,
|
||||||
const YGMeasureMode heightMeasureMode,
|
const YGMeasureMode heightMeasureMode,
|
||||||
const float parentWidth,
|
const float parentWidth,
|
||||||
const float parentHeight) {
|
const float parentHeight) {
|
||||||
if ((widthMeasureMode == YGMeasureModeAtMost && availableWidth <= 0.0f) ||
|
if ((!YGFloatIsUndefined(availableWidth) &&
|
||||||
(heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) ||
|
widthMeasureMode == YGMeasureModeAtMost && availableWidth <= 0.0f) ||
|
||||||
(widthMeasureMode == YGMeasureModeExactly && heightMeasureMode == YGMeasureModeExactly)) {
|
(!YGFloatIsUndefined(availableHeight) &&
|
||||||
|
heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) ||
|
||||||
|
(widthMeasureMode == YGMeasureModeExactly &&
|
||||||
|
heightMeasureMode == YGMeasureModeExactly)) {
|
||||||
const float marginAxisColumn =
|
const float marginAxisColumn =
|
||||||
node->getMarginForAxis(YGFlexDirectionColumn, parentWidth);
|
node->getMarginForAxis(YGFlexDirectionColumn, parentWidth);
|
||||||
const float marginAxisRow =
|
const float marginAxisRow =
|
||||||
|
@ -1545,13 +1557,16 @@ static float YGNodeCalculateAvailableInnerDim(
|
||||||
// We want to make sure our available height does not violate min and max
|
// We want to make sure our available height does not violate min and max
|
||||||
// constraints
|
// constraints
|
||||||
const float minInnerDim =
|
const float minInnerDim =
|
||||||
YGResolveValue(node->getStyle().minDimensions[dimension], parentDim) -
|
YGFloatIsUndefined(YGResolveValue(
|
||||||
|
node->getStyle().minDimensions[dimension], parentDim))
|
||||||
|
? 0.0f
|
||||||
|
: YGResolveValue(node->getStyle().minDimensions[dimension], parentDim) -
|
||||||
paddingAndBorder;
|
paddingAndBorder;
|
||||||
const float maxInnerDim =
|
const float maxInnerDim =
|
||||||
YGResolveValue(node->getStyle().maxDimensions[dimension], parentDim) -
|
YGResolveValue(node->getStyle().maxDimensions[dimension], parentDim) -
|
||||||
paddingAndBorder;
|
paddingAndBorder;
|
||||||
availableInnerDim =
|
availableInnerDim =
|
||||||
fmaxf(fminf(availableInnerDim, maxInnerDim), minInnerDim);
|
YGFloatMax(YGFloatMin(availableInnerDim, maxInnerDim), minInnerDim);
|
||||||
}
|
}
|
||||||
|
|
||||||
return availableInnerDim;
|
return availableInnerDim;
|
||||||
|
@ -1752,14 +1767,17 @@ static float YGDistributeFreeSpaceSecondPass(
|
||||||
mainAxisParentSize);
|
mainAxisParentSize);
|
||||||
float updatedMainSize = childFlexBasis;
|
float updatedMainSize = childFlexBasis;
|
||||||
|
|
||||||
if (collectedFlexItemsValues.remainingFreeSpace < 0) {
|
if (!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
|
||||||
|
collectedFlexItemsValues.remainingFreeSpace < 0) {
|
||||||
flexShrinkScaledFactor =
|
flexShrinkScaledFactor =
|
||||||
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
||||||
// Is this child able to shrink?
|
// Is this child able to shrink?
|
||||||
if (flexShrinkScaledFactor != 0) {
|
if (flexShrinkScaledFactor != 0) {
|
||||||
float childSize;
|
float childSize;
|
||||||
|
|
||||||
if (collectedFlexItemsValues.totalFlexShrinkScaledFactors == 0) {
|
if (!YGFloatIsUndefined(
|
||||||
|
collectedFlexItemsValues.totalFlexShrinkScaledFactors) &&
|
||||||
|
collectedFlexItemsValues.totalFlexShrinkScaledFactors == 0) {
|
||||||
childSize = childFlexBasis + flexShrinkScaledFactor;
|
childSize = childFlexBasis + flexShrinkScaledFactor;
|
||||||
} else {
|
} else {
|
||||||
childSize = childFlexBasis +
|
childSize = childFlexBasis +
|
||||||
|
@ -1775,11 +1793,13 @@ static float YGDistributeFreeSpaceSecondPass(
|
||||||
availableInnerMainDim,
|
availableInnerMainDim,
|
||||||
availableInnerWidth);
|
availableInnerWidth);
|
||||||
}
|
}
|
||||||
} else if (collectedFlexItemsValues.remainingFreeSpace > 0) {
|
} else if (
|
||||||
|
!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
|
||||||
|
collectedFlexItemsValues.remainingFreeSpace > 0) {
|
||||||
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
||||||
|
|
||||||
// Is this child able to grow?
|
// Is this child able to grow?
|
||||||
if (flexGrowFactor != 0) {
|
if (!YGFloatIsUndefined(flexGrowFactor) && flexGrowFactor != 0) {
|
||||||
updatedMainSize = YGNodeBoundAxis(
|
updatedMainSize = YGNodeBoundAxis(
|
||||||
currentRelativeChild,
|
currentRelativeChild,
|
||||||
mainAxis,
|
mainAxis,
|
||||||
|
@ -1926,7 +1946,8 @@ static void YGDistributeFreeSpaceFirstPass(
|
||||||
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
||||||
|
|
||||||
// Is this child able to shrink?
|
// Is this child able to shrink?
|
||||||
if (flexShrinkScaledFactor != 0) {
|
if (!YGFloatIsUndefined(flexShrinkScaledFactor) &&
|
||||||
|
flexShrinkScaledFactor != 0) {
|
||||||
baseMainSize = childFlexBasis +
|
baseMainSize = childFlexBasis +
|
||||||
collectedFlexItemsValues.remainingFreeSpace /
|
collectedFlexItemsValues.remainingFreeSpace /
|
||||||
collectedFlexItemsValues.totalFlexShrinkScaledFactors *
|
collectedFlexItemsValues.totalFlexShrinkScaledFactors *
|
||||||
|
@ -1937,7 +1958,9 @@ static void YGDistributeFreeSpaceFirstPass(
|
||||||
baseMainSize,
|
baseMainSize,
|
||||||
availableInnerMainDim,
|
availableInnerMainDim,
|
||||||
availableInnerWidth);
|
availableInnerWidth);
|
||||||
if (baseMainSize != boundMainSize) {
|
if (!YGFloatIsUndefined(baseMainSize) &&
|
||||||
|
!YGFloatIsUndefined(boundMainSize) &&
|
||||||
|
baseMainSize != boundMainSize) {
|
||||||
// By excluding this item's size and flex factor from remaining,
|
// By excluding this item's size and flex factor from remaining,
|
||||||
// this item's
|
// this item's
|
||||||
// min/max constraints should also trigger in the second pass
|
// min/max constraints should also trigger in the second pass
|
||||||
|
@ -1949,11 +1972,13 @@ static void YGDistributeFreeSpaceFirstPass(
|
||||||
flexShrinkScaledFactor;
|
flexShrinkScaledFactor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (collectedFlexItemsValues.remainingFreeSpace > 0) {
|
} else if (
|
||||||
|
!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
|
||||||
|
collectedFlexItemsValues.remainingFreeSpace > 0) {
|
||||||
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
||||||
|
|
||||||
// Is this child able to grow?
|
// Is this child able to grow?
|
||||||
if (flexGrowFactor != 0) {
|
if (!YGFloatIsUndefined(flexGrowFactor) && flexGrowFactor != 0) {
|
||||||
baseMainSize = childFlexBasis +
|
baseMainSize = childFlexBasis +
|
||||||
collectedFlexItemsValues.remainingFreeSpace /
|
collectedFlexItemsValues.remainingFreeSpace /
|
||||||
collectedFlexItemsValues.totalFlexGrowFactors * flexGrowFactor;
|
collectedFlexItemsValues.totalFlexGrowFactors * flexGrowFactor;
|
||||||
|
@ -1964,7 +1989,9 @@ static void YGDistributeFreeSpaceFirstPass(
|
||||||
availableInnerMainDim,
|
availableInnerMainDim,
|
||||||
availableInnerWidth);
|
availableInnerWidth);
|
||||||
|
|
||||||
if (baseMainSize != boundMainSize) {
|
if (!YGFloatIsUndefined(baseMainSize) &&
|
||||||
|
!YGFloatIsUndefined(boundMainSize) &&
|
||||||
|
baseMainSize != boundMainSize) {
|
||||||
// By excluding this item's size and flex factor from remaining,
|
// By excluding this item's size and flex factor from remaining,
|
||||||
// this item's
|
// this item's
|
||||||
// min/max constraints should also trigger in the second pass
|
// min/max constraints should also trigger in the second pass
|
||||||
|
@ -2069,9 +2096,9 @@ static void YGJustifyMainAxis(
|
||||||
if (measureModeMainDim == YGMeasureModeAtMost &&
|
if (measureModeMainDim == YGMeasureModeAtMost &&
|
||||||
collectedFlexItemsValues.remainingFreeSpace > 0) {
|
collectedFlexItemsValues.remainingFreeSpace > 0) {
|
||||||
if (style.minDimensions[dim[mainAxis]].unit != YGUnitUndefined &&
|
if (style.minDimensions[dim[mainAxis]].unit != YGUnitUndefined &&
|
||||||
YGResolveValue(
|
!YGFloatIsUndefined(YGResolveValue(
|
||||||
style.minDimensions[dim[mainAxis]], mainAxisParentSize) >= 0) {
|
style.minDimensions[dim[mainAxis]], mainAxisParentSize))) {
|
||||||
collectedFlexItemsValues.remainingFreeSpace = fmaxf(
|
collectedFlexItemsValues.remainingFreeSpace = YGFloatMax(
|
||||||
0,
|
0,
|
||||||
YGResolveValue(
|
YGResolveValue(
|
||||||
style.minDimensions[dim[mainAxis]], mainAxisParentSize) -
|
style.minDimensions[dim[mainAxis]], mainAxisParentSize) -
|
||||||
|
@ -2115,7 +2142,7 @@ static void YGJustifyMainAxis(
|
||||||
case YGJustifySpaceBetween:
|
case YGJustifySpaceBetween:
|
||||||
if (collectedFlexItemsValues.itemsOnLine > 1) {
|
if (collectedFlexItemsValues.itemsOnLine > 1) {
|
||||||
betweenMainDim =
|
betweenMainDim =
|
||||||
fmaxf(collectedFlexItemsValues.remainingFreeSpace, 0) /
|
YGFloatMax(collectedFlexItemsValues.remainingFreeSpace, 0) /
|
||||||
(collectedFlexItemsValues.itemsOnLine - 1);
|
(collectedFlexItemsValues.itemsOnLine - 1);
|
||||||
} else {
|
} else {
|
||||||
betweenMainDim = 0;
|
betweenMainDim = 0;
|
||||||
|
@ -2207,7 +2234,7 @@ static void YGJustifyMainAxis(
|
||||||
|
|
||||||
// The cross dimension is the max of the elements dimension since
|
// The cross dimension is the max of the elements dimension since
|
||||||
// there can only be one element in that cross dimension.
|
// there can only be one element in that cross dimension.
|
||||||
collectedFlexItemsValues.crossDim = fmaxf(
|
collectedFlexItemsValues.crossDim = YGFloatMax(
|
||||||
collectedFlexItemsValues.crossDim,
|
collectedFlexItemsValues.crossDim,
|
||||||
YGNodeDimWithMargin(child, crossAxis, availableInnerWidth));
|
YGNodeDimWithMargin(child, crossAxis, availableInnerWidth));
|
||||||
}
|
}
|
||||||
|
@ -2537,8 +2564,11 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||||
availableInnerMainDim = maxInnerMainDim;
|
availableInnerMainDim = maxInnerMainDim;
|
||||||
} else {
|
} else {
|
||||||
if (!node->getConfig()->useLegacyStretchBehaviour &&
|
if (!node->getConfig()->useLegacyStretchBehaviour &&
|
||||||
(collectedFlexItemsValues.totalFlexGrowFactors == 0 ||
|
((YGFloatIsUndefined(
|
||||||
node->resolveFlexGrow() == 0)) {
|
collectedFlexItemsValues.totalFlexGrowFactors) &&
|
||||||
|
collectedFlexItemsValues.totalFlexGrowFactors == 0) ||
|
||||||
|
(YGFloatIsUndefined(node->resolveFlexGrow()) &&
|
||||||
|
node->resolveFlexGrow() == 0))) {
|
||||||
// If we don't have any children to flex or we can't flex the node
|
// If we don't have any children to flex or we can't flex the node
|
||||||
// itself, space we've used is all space we need. Root node also
|
// itself, space we've used is all space we need. Root node also
|
||||||
// should be shrunk to minimum
|
// should be shrunk to minimum
|
||||||
|
@ -2743,13 +2773,13 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||||
|
|
||||||
if (child->marginLeadingValue(crossAxis).unit == YGUnitAuto &&
|
if (child->marginLeadingValue(crossAxis).unit == YGUnitAuto &&
|
||||||
child->marginTrailingValue(crossAxis).unit == YGUnitAuto) {
|
child->marginTrailingValue(crossAxis).unit == YGUnitAuto) {
|
||||||
leadingCrossDim += fmaxf(0.0f, remainingCrossDim / 2);
|
leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim / 2);
|
||||||
} else if (
|
} else if (
|
||||||
child->marginTrailingValue(crossAxis).unit == YGUnitAuto) {
|
child->marginTrailingValue(crossAxis).unit == YGUnitAuto) {
|
||||||
// No-Op
|
// No-Op
|
||||||
} else if (
|
} else if (
|
||||||
child->marginLeadingValue(crossAxis).unit == YGUnitAuto) {
|
child->marginLeadingValue(crossAxis).unit == YGUnitAuto) {
|
||||||
leadingCrossDim += fmaxf(0.0f, remainingCrossDim);
|
leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim);
|
||||||
} else if (alignItem == YGAlignFlexStart) {
|
} else if (alignItem == YGAlignFlexStart) {
|
||||||
// No-Op
|
// No-Op
|
||||||
} else if (alignItem == YGAlignCenter) {
|
} else if (alignItem == YGAlignCenter) {
|
||||||
|
@ -2768,7 +2798,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||||
}
|
}
|
||||||
|
|
||||||
totalLineCrossDim += collectedFlexItemsValues.crossDim;
|
totalLineCrossDim += collectedFlexItemsValues.crossDim;
|
||||||
maxLineMainDim = fmaxf(maxLineMainDim, collectedFlexItemsValues.mainDim);
|
maxLineMainDim =
|
||||||
|
YGFloatMax(maxLineMainDim, collectedFlexItemsValues.mainDim);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STEP 8: MULTI-LINE CONTENT ALIGNMENT
|
// STEP 8: MULTI-LINE CONTENT ALIGNMENT
|
||||||
|
@ -2831,7 +2862,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (YGNodeIsLayoutDimDefined(child, crossAxis)) {
|
if (YGNodeIsLayoutDimDefined(child, crossAxis)) {
|
||||||
lineHeight = fmaxf(
|
lineHeight = YGFloatMax(
|
||||||
lineHeight,
|
lineHeight,
|
||||||
child->getLayout().measuredDimensions[dim[crossAxis]] +
|
child->getLayout().measuredDimensions[dim[crossAxis]] +
|
||||||
child->getMarginForAxis(crossAxis, availableInnerWidth));
|
child->getMarginForAxis(crossAxis, availableInnerWidth));
|
||||||
|
@ -2845,9 +2876,12 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||||
child->getMarginForAxis(
|
child->getMarginForAxis(
|
||||||
YGFlexDirectionColumn, availableInnerWidth) -
|
YGFlexDirectionColumn, availableInnerWidth) -
|
||||||
ascent;
|
ascent;
|
||||||
maxAscentForCurrentLine = fmaxf(maxAscentForCurrentLine, ascent);
|
maxAscentForCurrentLine =
|
||||||
maxDescentForCurrentLine = fmaxf(maxDescentForCurrentLine, descent);
|
YGFloatMax(maxAscentForCurrentLine, ascent);
|
||||||
lineHeight = fmaxf(lineHeight, maxAscentForCurrentLine + maxDescentForCurrentLine);
|
maxDescentForCurrentLine =
|
||||||
|
YGFloatMax(maxDescentForCurrentLine, descent);
|
||||||
|
lineHeight = YGFloatMax(
|
||||||
|
lineHeight, maxAscentForCurrentLine + maxDescentForCurrentLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2990,8 +3024,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||||
measureModeMainDim == YGMeasureModeAtMost &&
|
measureModeMainDim == YGMeasureModeAtMost &&
|
||||||
node->getStyle().overflow == YGOverflowScroll) {
|
node->getStyle().overflow == YGOverflowScroll) {
|
||||||
node->setLayoutMeasuredDimension(
|
node->setLayoutMeasuredDimension(
|
||||||
fmaxf(
|
YGFloatMax(
|
||||||
fminf(
|
YGFloatMin(
|
||||||
availableInnerMainDim + paddingAndBorderAxisMain,
|
availableInnerMainDim + paddingAndBorderAxisMain,
|
||||||
YGNodeBoundAxisWithinMinAndMax(
|
YGNodeBoundAxisWithinMinAndMax(
|
||||||
node, mainAxis, maxLineMainDim, mainAxisParentSize)),
|
node, mainAxis, maxLineMainDim, mainAxisParentSize)),
|
||||||
|
@ -3018,8 +3052,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||||
measureModeCrossDim == YGMeasureModeAtMost &&
|
measureModeCrossDim == YGMeasureModeAtMost &&
|
||||||
node->getStyle().overflow == YGOverflowScroll) {
|
node->getStyle().overflow == YGOverflowScroll) {
|
||||||
node->setLayoutMeasuredDimension(
|
node->setLayoutMeasuredDimension(
|
||||||
fmaxf(
|
YGFloatMax(
|
||||||
fminf(
|
YGFloatMin(
|
||||||
availableInnerCrossDim + paddingAndBorderAxisCross,
|
availableInnerCrossDim + paddingAndBorderAxisCross,
|
||||||
YGNodeBoundAxisWithinMinAndMax(
|
YGNodeBoundAxisWithinMinAndMax(
|
||||||
node,
|
node,
|
||||||
|
@ -3134,8 +3168,11 @@ static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid(YGMeasureM
|
||||||
YGMeasureMode lastSizeMode,
|
YGMeasureMode lastSizeMode,
|
||||||
float lastSize,
|
float lastSize,
|
||||||
float lastComputedSize) {
|
float lastComputedSize) {
|
||||||
return lastSizeMode == YGMeasureModeAtMost && sizeMode == YGMeasureModeAtMost &&
|
return lastSizeMode == YGMeasureModeAtMost &&
|
||||||
lastSize > size && (lastComputedSize <= size || YGFloatsEqual(size, lastComputedSize));
|
sizeMode == YGMeasureModeAtMost && !YGFloatIsUndefined(lastSize) &&
|
||||||
|
!YGFloatIsUndefined(size) && !YGFloatIsUndefined(lastComputedSize) &&
|
||||||
|
lastSize > size &&
|
||||||
|
(lastComputedSize <= size || YGFloatsEqual(size, lastComputedSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
float YGRoundValueToPixelGrid(const float value,
|
float YGRoundValueToPixelGrid(const float value,
|
||||||
|
@ -3157,9 +3194,15 @@ float YGRoundValueToPixelGrid(const float value,
|
||||||
} else {
|
} else {
|
||||||
// Finally we just round the value
|
// Finally we just round the value
|
||||||
scaledValue = scaledValue - fractial +
|
scaledValue = scaledValue - fractial +
|
||||||
(fractial > 0.5f || YGFloatsEqual(fractial, 0.5f) ? 1.0f : 0.0f);
|
(!YGFloatIsUndefined(fractial) &&
|
||||||
|
(fractial > 0.5f || YGFloatsEqual(fractial, 0.5f))
|
||||||
|
? 1.0f
|
||||||
|
: 0.0f);
|
||||||
}
|
}
|
||||||
return scaledValue / pointScaleFactor;
|
return (YGFloatIsUndefined(scaledValue) ||
|
||||||
|
YGFloatIsUndefined(pointScaleFactor))
|
||||||
|
? YGUndefined
|
||||||
|
: scaledValue / pointScaleFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode,
|
bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode,
|
||||||
|
@ -3175,7 +3218,8 @@ bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode,
|
||||||
const float marginRow,
|
const float marginRow,
|
||||||
const float marginColumn,
|
const float marginColumn,
|
||||||
const YGConfigRef config) {
|
const YGConfigRef config) {
|
||||||
if (lastComputedHeight < 0 || lastComputedWidth < 0) {
|
if ((!YGFloatIsUndefined(lastComputedHeight) && lastComputedHeight < 0) ||
|
||||||
|
(!YGFloatIsUndefined(lastComputedWidth) && lastComputedWidth < 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool useRoundedComparison =
|
bool useRoundedComparison =
|
||||||
|
@ -3533,11 +3577,16 @@ static void YGRoundToPixelGrid(const YGNodeRef node,
|
||||||
|
|
||||||
const uint32_t childCount = YGNodeGetChildCount(node);
|
const uint32_t childCount = YGNodeGetChildCount(node);
|
||||||
for (uint32_t i = 0; i < childCount; i++) {
|
for (uint32_t i = 0; i < childCount; i++) {
|
||||||
YGRoundToPixelGrid(YGNodeGetChild(node, i), pointScaleFactor, absoluteNodeLeft, absoluteNodeTop);
|
YGRoundToPixelGrid(
|
||||||
|
YGNodeGetChild(node, i),
|
||||||
|
pointScaleFactor,
|
||||||
|
absoluteNodeLeft,
|
||||||
|
absoluteNodeTop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void YGNodeCalculateLayout(const YGNodeRef node,
|
void YGNodeCalculateLayout(
|
||||||
|
const YGNodeRef node,
|
||||||
const float parentWidth,
|
const float parentWidth,
|
||||||
const float parentHeight,
|
const float parentHeight,
|
||||||
const YGDirection parentDirection) {
|
const YGDirection parentDirection) {
|
||||||
|
@ -3556,16 +3605,16 @@ void YGNodeCalculateLayout(const YGNodeRef node,
|
||||||
node->getResolvedDimension(dim[YGFlexDirectionRow]), parentWidth) +
|
node->getResolvedDimension(dim[YGFlexDirectionRow]), parentWidth) +
|
||||||
node->getMarginForAxis(YGFlexDirectionRow, parentWidth);
|
node->getMarginForAxis(YGFlexDirectionRow, parentWidth);
|
||||||
widthMeasureMode = YGMeasureModeExactly;
|
widthMeasureMode = YGMeasureModeExactly;
|
||||||
} else if (
|
} else if (!YGFloatIsUndefined(YGResolveValue(
|
||||||
YGResolveValue(
|
node->getStyle().maxDimensions[YGDimensionWidth],
|
||||||
node->getStyle().maxDimensions[YGDimensionWidth], parentWidth) >=
|
parentWidth))) {
|
||||||
0.0f) {
|
|
||||||
width = YGResolveValue(
|
width = YGResolveValue(
|
||||||
node->getStyle().maxDimensions[YGDimensionWidth], parentWidth);
|
node->getStyle().maxDimensions[YGDimensionWidth], parentWidth);
|
||||||
widthMeasureMode = YGMeasureModeAtMost;
|
widthMeasureMode = YGMeasureModeAtMost;
|
||||||
} else {
|
} else {
|
||||||
width = parentWidth;
|
width = parentWidth;
|
||||||
widthMeasureMode = YGFloatIsUndefined(width) ? YGMeasureModeUndefined : YGMeasureModeExactly;
|
widthMeasureMode = YGFloatIsUndefined(width) ? YGMeasureModeUndefined
|
||||||
|
: YGMeasureModeExactly;
|
||||||
}
|
}
|
||||||
|
|
||||||
float height = YGUndefined;
|
float height = YGUndefined;
|
||||||
|
@ -3576,18 +3625,17 @@ void YGNodeCalculateLayout(const YGNodeRef node,
|
||||||
parentHeight) +
|
parentHeight) +
|
||||||
node->getMarginForAxis(YGFlexDirectionColumn, parentWidth);
|
node->getMarginForAxis(YGFlexDirectionColumn, parentWidth);
|
||||||
heightMeasureMode = YGMeasureModeExactly;
|
heightMeasureMode = YGMeasureModeExactly;
|
||||||
} else if (
|
} else if (!YGFloatIsUndefined(YGResolveValue(
|
||||||
YGResolveValue(
|
node->getStyle().maxDimensions[YGDimensionHeight],
|
||||||
node->getStyle().maxDimensions[YGDimensionHeight], parentHeight) >=
|
parentHeight))) {
|
||||||
0.0f) {
|
|
||||||
height = YGResolveValue(
|
height = YGResolveValue(
|
||||||
node->getStyle().maxDimensions[YGDimensionHeight], parentHeight);
|
node->getStyle().maxDimensions[YGDimensionHeight], parentHeight);
|
||||||
heightMeasureMode = YGMeasureModeAtMost;
|
heightMeasureMode = YGMeasureModeAtMost;
|
||||||
} else {
|
} else {
|
||||||
height = parentHeight;
|
height = parentHeight;
|
||||||
heightMeasureMode = YGFloatIsUndefined(height) ? YGMeasureModeUndefined : YGMeasureModeExactly;
|
heightMeasureMode = YGFloatIsUndefined(height) ? YGMeasureModeUndefined
|
||||||
|
: YGMeasureModeExactly;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (YGLayoutNodeInternal(
|
if (YGLayoutNodeInternal(
|
||||||
node,
|
node,
|
||||||
width,
|
width,
|
||||||
|
|
|
@ -18,13 +18,14 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Not defined in MSVC++
|
/** Large positive number signifies that the property(float) is undefined.
|
||||||
#ifndef NAN
|
*Earlier we used to have YGundefined as NAN, but the downside of this is that
|
||||||
static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
|
*we can't use -ffast-math compiler flag as it assumes all floating-point
|
||||||
#define NAN (*(const float *) __nan)
|
*calculation involve and result into finite numbers. For more information
|
||||||
#endif
|
*regarding -ffast-math compiler flag in clang, have a look at
|
||||||
|
*https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math
|
||||||
#define YGUndefined NAN
|
**/
|
||||||
|
#define YGUndefined 10E20F
|
||||||
|
|
||||||
#include "YGEnums.h"
|
#include "YGEnums.h"
|
||||||
#include "YGMacros.h"
|
#include "YGMacros.h"
|
||||||
|
|
Loading…
Reference in New Issue