diff --git a/CSSLayout/CSSEnums.h b/CSSLayout/CSSEnums.h
index 8f9979f5b9..dbcb58e27b 100644
--- a/CSSLayout/CSSEnums.h
+++ b/CSSLayout/CSSEnums.h
@@ -67,6 +67,7 @@ typedef enum CSSDirection {
} CSSDirection;
typedef enum CSSExperimentalFeature {
+ CSSExperimentalFeatureRounding,
CSSExperimentalFeatureCount,
} CSSExperimentalFeature;
diff --git a/CSSLayout/CSSLayout.c b/CSSLayout/CSSLayout.c
index 8c07333701..eeb99195f7 100644
--- a/CSSLayout/CSSLayout.c
+++ b/CSSLayout/CSSLayout.c
@@ -2534,6 +2534,25 @@ bool layoutNodeInternal(const CSSNodeRef node,
return (needToVisitNode || cachedResults == NULL);
}
+static void roundToPixelGrid(const CSSNodeRef node) {
+ const float fractialLeft =
+ node->layout.position[CSSEdgeLeft] - floorf(node->layout.position[CSSEdgeLeft]);
+ const float fractialTop =
+ node->layout.position[CSSEdgeTop] - floorf(node->layout.position[CSSEdgeTop]);
+ node->layout.dimensions[CSSDimensionWidth] =
+ roundf(fractialLeft + node->layout.dimensions[CSSDimensionWidth]) - roundf(fractialLeft);
+ node->layout.dimensions[CSSDimensionHeight] =
+ roundf(fractialTop + node->layout.dimensions[CSSDimensionHeight]) - roundf(fractialTop);
+
+ node->layout.position[CSSEdgeLeft] = roundf(node->layout.position[CSSEdgeLeft]);
+ node->layout.position[CSSEdgeTop] = roundf(node->layout.position[CSSEdgeTop]);
+
+ const uint32_t childCount = CSSNodeListCount(node->children);
+ for (uint32_t i = 0; i < childCount; i++) {
+ roundToPixelGrid(CSSNodeGetChild(node, i));
+ }
+}
+
void CSSNodeCalculateLayout(const CSSNodeRef node,
const float availableWidth,
const float availableHeight,
@@ -2583,6 +2602,10 @@ void CSSNodeCalculateLayout(const CSSNodeRef node,
"l")) {
setPosition(node, node->layout.direction);
+ if (CSSLayoutIsExperimentalFeatureEnabled(CSSExperimentalFeatureRounding)) {
+ roundToPixelGrid(node);
+ }
+
if (gPrintTree) {
CSSNodePrint(node, CSSPrintOptionsLayout | CSSPrintOptionsChildren | CSSPrintOptionsStyle);
}
@@ -2606,7 +2629,7 @@ void CSSLayoutSetExperimentalFeatureEnabled(CSSExperimentalFeature feature, bool
experimentalFeatures[feature] = enabled;
}
-bool CSSLayoutIsExperimentalFeatureEnabled(CSSExperimentalFeature feature) {
+inline bool CSSLayoutIsExperimentalFeatureEnabled(CSSExperimentalFeature feature) {
return experimentalFeatures[feature];
}
diff --git a/CSSLayout/CSSLayout.h b/CSSLayout/CSSLayout.h
index 7bcc244e9a..e2dca0a727 100644
--- a/CSSLayout/CSSLayout.h
+++ b/CSSLayout/CSSLayout.h
@@ -152,9 +152,12 @@ CSS_NODE_STYLE_PROPERTY(float, MaxHeight, maxHeight);
// Yoga specific properties, not compatible with flexbox specification
// Aspect ratio control the size of the undefined dimension of a node.
// - On a node with a set width/height aspect ratio control the size of the unset dimension
-// - On a node with a set flex basis aspect ratio controls the size of the node in the cross axis if unset
-// - On a node with a measure function aspect ratio works as though the measure function measures the flex basis
-// - On a node with flex grow/shrink aspect ratio controls the size of the node in the cross axis if unset
+// - On a node with a set flex basis aspect ratio controls the size of the node in the cross axis if
+// unset
+// - On a node with a measure function aspect ratio works as though the measure function measures
+// the flex basis
+// - On a node with flex grow/shrink aspect ratio controls the size of the node in the cross axis if
+// unset
// - Aspect ratio takes min/max dimensions into account
CSS_NODE_STYLE_PROPERTY(float, AspectRatio, aspectRatio);
diff --git a/csharp/Facebook.CSSLayout/CSSExperimentalFeature.cs b/csharp/Facebook.CSSLayout/CSSExperimentalFeature.cs
index bd0809320c..9eb743091d 100644
--- a/csharp/Facebook.CSSLayout/CSSExperimentalFeature.cs
+++ b/csharp/Facebook.CSSLayout/CSSExperimentalFeature.cs
@@ -11,5 +11,6 @@ namespace Facebook.CSSLayout
{
public enum CSSExperimentalFeature
{
+ Rounding,
}
}
diff --git a/enums.py b/enums.py
index 40f36d5a81..76261b7fa3 100644
--- a/enums.py
+++ b/enums.py
@@ -77,7 +77,9 @@
'Debug',
'Verbose',
],
- 'CSSExperimentalFeature': [],
+ 'CSSExperimentalFeature': [
+ 'Rounding',
+ ],
'CSSPrintOptions': [
('Layout', 1),
('Style', 2),
diff --git a/java/com/facebook/csslayout/CSSExperimentalFeature.java b/java/com/facebook/csslayout/CSSExperimentalFeature.java
index e0b269f9af..c2b8b7af22 100644
--- a/java/com/facebook/csslayout/CSSExperimentalFeature.java
+++ b/java/com/facebook/csslayout/CSSExperimentalFeature.java
@@ -10,7 +10,8 @@
package com.facebook.csslayout;
public enum CSSExperimentalFeature {
-__EMPTY(-1);
+ ROUNDING(0);
+
private int mIntValue;
CSSExperimentalFeature(int intValue) {
@@ -23,6 +24,7 @@ public int intValue() {
public static CSSExperimentalFeature fromInt(int value) {
switch (value) {
+ case 0: return ROUNDING;
default: throw new IllegalArgumentException("Unkown enum value: " + value);
}
}
diff --git a/tests/CSSLayoutPixelRoundingTest.cpp b/tests/CSSLayoutPixelRoundingTest.cpp
new file mode 100644
index 0000000000..8fb3c73a58
--- /dev/null
+++ b/tests/CSSLayoutPixelRoundingTest.cpp
@@ -0,0 +1,852 @@
+/**
+ * Copyright (c) 2014-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+/*
+*
+
+
+
+
+
+
+
+
+
+
+
+ *
+ */
+
+#include
+#include
+
+class CSSLayoutFeatureRoundingTest : public ::testing::Test {
+
+protected:
+ virtual void SetUp() {
+ CSSLayoutSetExperimentalFeatureEnabled(CSSExperimentalFeatureRounding, true);
+ }
+
+ virtual void TearDown() {
+ CSSLayoutSetExperimentalFeatureEnabled(CSSExperimentalFeatureRounding, false);
+ }
+};
+
+TEST_F(CSSLayoutFeatureRoundingTest, pixel_rounding_flex_basis_flex_grow_row_width_of_100) {
+ const CSSNodeRef root = CSSNodeNew();
+ CSSNodeStyleSetFlexDirection(root, CSSFlexDirectionRow);
+ CSSNodeStyleSetWidth(root, 100);
+ CSSNodeStyleSetHeight(root, 100);
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0, 1);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ const CSSNodeRef root_child1 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child1, 1);
+ CSSNodeInsertChild(root, root_child1, 1);
+
+ const CSSNodeRef root_child2 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child2, 1);
+ CSSNodeInsertChild(root, root_child2, 2);
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(33, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(33, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(34, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(67, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(33, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(67, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(33, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(33, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(34, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(33, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeFreeRecursive(root);
+}
+
+TEST_F(CSSLayoutFeatureRoundingTest, pixel_rounding_flex_basis_flex_grow_row_prime_number_width) {
+ const CSSNodeRef root = CSSNodeNew();
+ CSSNodeStyleSetFlexDirection(root, CSSFlexDirectionRow);
+ CSSNodeStyleSetWidth(root, 113);
+ CSSNodeStyleSetHeight(root, 100);
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0, 1);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ const CSSNodeRef root_child1 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child1, 1);
+ CSSNodeInsertChild(root, root_child1, 1);
+
+ const CSSNodeRef root_child2 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child2, 1);
+ CSSNodeInsertChild(root, root_child2, 2);
+
+ const CSSNodeRef root_child3 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child3, 1);
+ CSSNodeInsertChild(root, root_child3, 3);
+
+ const CSSNodeRef root_child4 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child4, 1);
+ CSSNodeInsertChild(root, root_child4, 4);
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(113, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(23, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(23, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(22, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(45, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(23, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child2));
+
+ ASSERT_FLOAT_EQ(68, CSSNodeLayoutGetLeft(root_child3));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child3));
+ ASSERT_FLOAT_EQ(22, CSSNodeLayoutGetWidth(root_child3));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child3));
+
+ ASSERT_FLOAT_EQ(90, CSSNodeLayoutGetLeft(root_child4));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child4));
+ ASSERT_FLOAT_EQ(23, CSSNodeLayoutGetWidth(root_child4));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child4));
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(113, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(90, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(23, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(68, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(22, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(45, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(23, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child2));
+
+ ASSERT_FLOAT_EQ(23, CSSNodeLayoutGetLeft(root_child3));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child3));
+ ASSERT_FLOAT_EQ(22, CSSNodeLayoutGetWidth(root_child3));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child3));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child4));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child4));
+ ASSERT_FLOAT_EQ(23, CSSNodeLayoutGetWidth(root_child4));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child4));
+
+ CSSNodeFreeRecursive(root);
+}
+
+TEST_F(CSSLayoutFeatureRoundingTest, pixel_rounding_flex_basis_flex_shrink_row) {
+ const CSSNodeRef root = CSSNodeNew();
+ CSSNodeStyleSetFlexDirection(root, CSSFlexDirectionRow);
+ CSSNodeStyleSetWidth(root, 101);
+ CSSNodeStyleSetHeight(root, 100);
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexShrink(root_child0, 1);
+ CSSNodeStyleSetFlexBasis(root_child0, 100);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ const CSSNodeRef root_child1 = CSSNodeNew();
+ CSSNodeStyleSetFlexBasis(root_child1, 25);
+ CSSNodeInsertChild(root, root_child1, 1);
+
+ const CSSNodeRef root_child2 = CSSNodeNew();
+ CSSNodeStyleSetFlexBasis(root_child2, 25);
+ CSSNodeInsertChild(root, root_child2, 2);
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(101, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(51, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(51, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(76, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(101, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(50, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(51, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeFreeRecursive(root);
+}
+
+
+TEST_F(CSSLayoutFeatureRoundingTest, pixel_roundingflex_basis_overrides_main_size) {
+ const CSSNodeRef root = CSSNodeNew();
+ CSSNodeStyleSetWidth(root, 100);
+ CSSNodeStyleSetHeight(root, 113);
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0, 1);
+ CSSNodeStyleSetFlexBasis(root_child0, 50);
+ CSSNodeStyleSetHeight(root_child0, 20);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ const CSSNodeRef root_child1 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child1, 1);
+ CSSNodeStyleSetHeight(root_child1, 10);
+ CSSNodeInsertChild(root, root_child1, 1);
+
+ const CSSNodeRef root_child2 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child2, 1);
+ CSSNodeStyleSetHeight(root_child2, 10);
+ CSSNodeInsertChild(root, root_child2, 2);
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_EQ(113, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(64, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_EQ(64, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_EQ(25, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_EQ(113, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(64, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_EQ(64, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_EQ(25, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeFreeRecursive(root);
+}
+
+TEST_F(CSSLayoutFeatureRoundingTest, flex_basis_overrides_main_size_1) {
+ const CSSNodeRef root = CSSNodeNew();
+ CSSNodeStyleSetWidth(root, 100);
+ CSSNodeStyleSetHeight(root, 113.4f);
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0, 1);
+ CSSNodeStyleSetFlexBasis(root_child0, 50);
+ CSSNodeStyleSetHeight(root_child0, 20);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ const CSSNodeRef root_child1 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child1, 1);
+ CSSNodeStyleSetHeight(root_child1, 10);
+ CSSNodeInsertChild(root, root_child1, 1);
+
+ const CSSNodeRef root_child2 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child2, 1);
+ CSSNodeStyleSetHeight(root_child2, 10);
+ CSSNodeInsertChild(root, root_child2, 2);
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(113, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(113, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeFreeRecursive(root);
+}
+
+TEST_F(CSSLayoutFeatureRoundingTest, flex_basis_overrides_main_size_2) {
+ const CSSNodeRef root = CSSNodeNew();
+ CSSNodeStyleSetWidth(root, 100);
+ CSSNodeStyleSetHeight(root, 113.6f);
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0, 1);
+ CSSNodeStyleSetFlexBasis(root_child0, 50);
+ CSSNodeStyleSetHeight(root_child0, 20);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ const CSSNodeRef root_child1 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child1, 1);
+ CSSNodeStyleSetHeight(root_child1, 10);
+ CSSNodeInsertChild(root, root_child1, 1);
+
+ const CSSNodeRef root_child2 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child2, 1);
+ CSSNodeStyleSetHeight(root_child2, 10);
+ CSSNodeInsertChild(root, root_child2, 2);
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(114, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(65, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(65, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(114, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(65, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(65, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeFreeRecursive(root);
+}
+
+TEST_F(CSSLayoutFeatureRoundingTest, flex_basis_overrides_main_size_3) {
+ const CSSNodeRef root = CSSNodeNew();
+ CSSNodeStyleSetPosition(root, CSSEdgeTop, 0.3f);
+ CSSNodeStyleSetWidth(root, 100);
+ CSSNodeStyleSetHeight(root, 113.4f);
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0, 1);
+ CSSNodeStyleSetFlexBasis(root_child0, 50);
+ CSSNodeStyleSetHeight(root_child0, 20);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ const CSSNodeRef root_child1 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child1, 1);
+ CSSNodeStyleSetHeight(root_child1, 10);
+ CSSNodeInsertChild(root, root_child1, 1);
+
+ const CSSNodeRef root_child2 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child2, 1);
+ CSSNodeStyleSetHeight(root_child2, 10);
+ CSSNodeInsertChild(root, root_child2, 2);
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(114, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(114, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeFreeRecursive(root);
+}
+
+TEST_F(CSSLayoutFeatureRoundingTest, flex_basis_overrides_main_size_4) {
+ const CSSNodeRef root = CSSNodeNew();
+ CSSNodeStyleSetPosition(root, CSSEdgeTop, 0.7f);
+ CSSNodeStyleSetWidth(root, 100);
+ CSSNodeStyleSetHeight(root, 113.4f);
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0, 1);
+ CSSNodeStyleSetFlexBasis(root_child0, 50);
+ CSSNodeStyleSetHeight(root_child0, 20);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ const CSSNodeRef root_child1 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child1, 1);
+ CSSNodeStyleSetHeight(root_child1, 10);
+ CSSNodeInsertChild(root, root_child1, 1);
+
+ const CSSNodeRef root_child2 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child2, 1);
+ CSSNodeStyleSetHeight(root_child2, 10);
+ CSSNodeInsertChild(root, root_child2, 2);
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(1, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(113, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(1, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(113, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(64, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(25, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeFreeRecursive(root);
+}
+
+TEST_F(CSSLayoutFeatureRoundingTest, rounding_feature_total_fractial) {
+ const CSSNodeRef root = CSSNodeNew();
+ CSSNodeStyleSetWidth(root, 87.4f);
+ CSSNodeStyleSetHeight(root, 113.4f);
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0, 0.7f);
+ CSSNodeStyleSetFlexBasis(root_child0, 50.3f);
+ CSSNodeStyleSetHeight(root_child0, 20.3f);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ const CSSNodeRef root_child1 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child1, 1.6f);
+ CSSNodeStyleSetHeight(root_child1, 10);
+ CSSNodeInsertChild(root, root_child1, 1);
+
+ const CSSNodeRef root_child2 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child2, 1.1f);
+ CSSNodeStyleSetHeight(root_child2, 10.7f);
+ CSSNodeInsertChild(root, root_child2, 2);
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(113, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(59, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(59, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(30, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(113, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(59, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(59, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(30, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeFreeRecursive(root);
+}
+
+
+TEST_F(CSSLayoutFeatureRoundingTest, rounding_feature_total_fractial_nested) {
+ const CSSNodeRef root = CSSNodeNew();
+ CSSNodeStyleSetWidth(root, 87.4f);
+ CSSNodeStyleSetHeight(root, 113.4f);
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0, 0.7f);
+ CSSNodeStyleSetFlexBasis(root_child0, 50.3f);
+ CSSNodeStyleSetHeight(root_child0, 20.3f);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ const CSSNodeRef root_child0_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0_child0, 1.2f);
+ CSSNodeStyleSetFlexBasis(root_child0_child0, 0.3f);
+ CSSNodeStyleSetPosition(root_child0_child0, CSSEdgeBottom, 13.3f);
+ CSSNodeStyleSetHeight(root_child0_child0, 9.9f);
+ CSSNodeInsertChild(root_child0, root_child0_child0, 0);
+
+ const CSSNodeRef root_child0_child1 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0_child1, 4.2f);
+ CSSNodeStyleSetFlexBasis(root_child0_child1, 0.3f);
+ CSSNodeStyleSetPosition(root_child0_child1, CSSEdgeTop, 13.3f);
+ CSSNodeStyleSetHeight(root_child0_child1, 1.1f);
+ CSSNodeInsertChild(root_child0, root_child0_child1, 1);
+
+ const CSSNodeRef root_child1 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child1, 1.6f);
+ CSSNodeStyleSetHeight(root_child1, 10);
+ CSSNodeInsertChild(root, root_child1, 1);
+
+ const CSSNodeRef root_child2 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child2, 1.1f);
+ CSSNodeStyleSetHeight(root_child2, 10.7f);
+ CSSNodeInsertChild(root, root_child2, 2);
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(113, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(59, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0));
+ ASSERT_FLOAT_EQ(-13, CSSNodeLayoutGetTop(root_child0_child0));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child0_child0));
+ ASSERT_FLOAT_EQ(13, CSSNodeLayoutGetHeight(root_child0_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child1));
+ ASSERT_FLOAT_EQ(27, CSSNodeLayoutGetTop(root_child0_child1));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child0_child1));
+ ASSERT_FLOAT_EQ(45, CSSNodeLayoutGetHeight(root_child0_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(59, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(30, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(113, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(59, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0));
+ ASSERT_FLOAT_EQ(-13, CSSNodeLayoutGetTop(root_child0_child0));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child0_child0));
+ ASSERT_FLOAT_EQ(13, CSSNodeLayoutGetHeight(root_child0_child0));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child1));
+ ASSERT_FLOAT_EQ(27, CSSNodeLayoutGetTop(root_child0_child1));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child0_child1));
+ ASSERT_FLOAT_EQ(45, CSSNodeLayoutGetHeight(root_child0_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(59, CSSNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(30, CSSNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(89, CSSNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(87, CSSNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(24, CSSNodeLayoutGetHeight(root_child2));
+
+ CSSNodeFreeRecursive(root);
+}
+
+
+static CSSSize _measureFloor(CSSNodeRef node,
+ float width,
+ CSSMeasureMode widthMode,
+ float height,
+ CSSMeasureMode heightMode) {
+
+ return CSSSize{
+ width = 10.2,
+ height = 10.2,
+ };
+}
+
+static CSSSize _measureCeil(CSSNodeRef node,
+ float width,
+ CSSMeasureMode widthMode,
+ float height,
+ CSSMeasureMode heightMode) {
+
+ return CSSSize{
+ width = 10.5,
+ height = 10.5,
+ };
+}
+
+
+TEST_F(CSSLayoutFeatureRoundingTest, rounding_feature_with_custom_measure_func_floor) {
+ const CSSNodeRef root = CSSNodeNew();
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeSetMeasureFunc(root_child0, _measureFloor);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_FLOAT_EQ(10, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(10, CSSNodeLayoutGetHeight(root_child0));
+
+ CSSNodeFreeRecursive(root);
+}
+
+TEST_F(CSSLayoutFeatureRoundingTest, rounding_feature_with_custom_measure_func_ceil) {
+ const CSSNodeRef root = CSSNodeNew();
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeSetMeasureFunc(root_child0, _measureCeil);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_FLOAT_EQ(11, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(11, CSSNodeLayoutGetHeight(root_child0));
+
+ CSSNodeFreeRecursive(root);
+}