Baseline support #317
@@ -281,5 +281,83 @@ namespace Facebook.Yoga
|
||||
Assert.AreEqual(20f, root_child1.LayoutHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_align_baseline_child_margin()
|
||||
{
|
||||
YogaNode root = new YogaNode();
|
||||
root.FlexDirection = YogaFlexDirection.Row;
|
||||
root.AlignItems = YogaAlign.Baseline;
|
||||
root.Width = 100;
|
||||
root.Height = 100;
|
||||
|
||||
YogaNode root_child0 = new YogaNode();
|
||||
root_child0.SetMargin(YogaEdge.Left, 5);
|
||||
root_child0.SetMargin(YogaEdge.Top, 5);
|
||||
root_child0.SetMargin(YogaEdge.Right, 5);
|
||||
root_child0.SetMargin(YogaEdge.Bottom, 5);
|
||||
root_child0.Width = 50;
|
||||
root_child0.Height = 50;
|
||||
root.Insert(0, root_child0);
|
||||
|
||||
YogaNode root_child1 = new YogaNode();
|
||||
root_child1.Width = 50;
|
||||
root_child1.Height = 20;
|
||||
root.Insert(1, root_child1);
|
||||
|
||||
YogaNode root_child1_child0 = new YogaNode();
|
||||
root_child1_child0.SetMargin(YogaEdge.Left, 1);
|
||||
root_child1_child0.SetMargin(YogaEdge.Top, 1);
|
||||
root_child1_child0.SetMargin(YogaEdge.Right, 1);
|
||||
root_child1_child0.SetMargin(YogaEdge.Bottom, 1);
|
||||
root_child1_child0.Width = 50;
|
||||
root_child1_child0.Height = 10;
|
||||
root_child1.Insert(0, root_child1_child0);
|
||||
root.StyleDirection = YogaDirection.LTR;
|
||||
root.CalculateLayout();
|
||||
|
||||
Assert.AreEqual(0f, root.LayoutX);
|
||||
Assert.AreEqual(0f, root.LayoutY);
|
||||
Assert.AreEqual(100f, root.LayoutWidth);
|
||||
Assert.AreEqual(100f, root.LayoutHeight);
|
||||
|
||||
Assert.AreEqual(5f, root_child0.LayoutX);
|
||||
Assert.AreEqual(5f, root_child0.LayoutY);
|
||||
Assert.AreEqual(50f, root_child0.LayoutWidth);
|
||||
Assert.AreEqual(50f, root_child0.LayoutHeight);
|
||||
|
||||
Assert.AreEqual(60f, root_child1.LayoutX);
|
||||
Assert.AreEqual(44f, root_child1.LayoutY);
|
||||
Assert.AreEqual(50f, root_child1.LayoutWidth);
|
||||
Assert.AreEqual(20f, root_child1.LayoutHeight);
|
||||
|
||||
Assert.AreEqual(1f, root_child1_child0.LayoutX);
|
||||
Assert.AreEqual(1f, root_child1_child0.LayoutY);
|
||||
Assert.AreEqual(50f, root_child1_child0.LayoutWidth);
|
||||
Assert.AreEqual(10f, root_child1_child0.LayoutHeight);
|
||||
|
||||
root.StyleDirection = YogaDirection.RTL;
|
||||
root.CalculateLayout();
|
||||
|
||||
Assert.AreEqual(0f, root.LayoutX);
|
||||
Assert.AreEqual(0f, root.LayoutY);
|
||||
Assert.AreEqual(100f, root.LayoutWidth);
|
||||
Assert.AreEqual(100f, root.LayoutHeight);
|
||||
|
||||
Assert.AreEqual(45f, root_child0.LayoutX);
|
||||
Assert.AreEqual(5f, root_child0.LayoutY);
|
||||
Assert.AreEqual(50f, root_child0.LayoutWidth);
|
||||
Assert.AreEqual(50f, root_child0.LayoutHeight);
|
||||
|
||||
Assert.AreEqual(-10f, root_child1.LayoutX);
|
||||
Assert.AreEqual(44f, root_child1.LayoutY);
|
||||
Assert.AreEqual(50f, root_child1.LayoutWidth);
|
||||
Assert.AreEqual(20f, root_child1.LayoutHeight);
|
||||
|
||||
Assert.AreEqual(-1f, root_child1_child0.LayoutX);
|
||||
Assert.AreEqual(1f, root_child1_child0.LayoutY);
|
||||
Assert.AreEqual(50f, root_child1_child0.LayoutWidth);
|
||||
Assert.AreEqual(10f, root_child1_child0.LayoutHeight);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -24,3 +24,10 @@
|
||||
<div style="width: 50px; height: 50px;"></div>
|
||||
<div style="width: 50px; height: 20px;"></div>
|
||||
</div>
|
||||
|
||||
<div id="align_baseline_child_margin" style="width: 100px; height: 100px; flex-direction:row; align-items: baseline;">
|
||||
<div style="width: 50px; height: 50px;margin: 5px;"></div>
|
||||
<div style="width: 50px; height: 20px;">
|
||||
<div style="width: 50px; height: 10px;margin: 1px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -276,4 +276,81 @@ public class YGAlignBaseline {
|
||||
assertEquals(20f, root_child1.getLayoutHeight(), 0.0f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_align_baseline_child_margin() {
|
||||
final YogaNode root = new YogaNode();
|
||||
root.setFlexDirection(YogaFlexDirection.ROW);
|
||||
root.setAlignItems(YogaAlign.BASELINE);
|
||||
root.setWidth(100f);
|
||||
root.setHeight(100f);
|
||||
|
||||
final YogaNode root_child0 = new YogaNode();
|
||||
root_child0.setMargin(YogaEdge.LEFT, 5f);
|
||||
root_child0.setMargin(YogaEdge.TOP, 5f);
|
||||
root_child0.setMargin(YogaEdge.RIGHT, 5f);
|
||||
root_child0.setMargin(YogaEdge.BOTTOM, 5f);
|
||||
root_child0.setWidth(50f);
|
||||
root_child0.setHeight(50f);
|
||||
root.addChildAt(root_child0, 0);
|
||||
|
||||
final YogaNode root_child1 = new YogaNode();
|
||||
root_child1.setWidth(50f);
|
||||
root_child1.setHeight(20f);
|
||||
root.addChildAt(root_child1, 1);
|
||||
|
||||
final YogaNode root_child1_child0 = new YogaNode();
|
||||
root_child1_child0.setMargin(YogaEdge.LEFT, 1f);
|
||||
root_child1_child0.setMargin(YogaEdge.TOP, 1f);
|
||||
root_child1_child0.setMargin(YogaEdge.RIGHT, 1f);
|
||||
root_child1_child0.setMargin(YogaEdge.BOTTOM, 1f);
|
||||
root_child1_child0.setWidth(50f);
|
||||
root_child1_child0.setHeight(10f);
|
||||
root_child1.addChildAt(root_child1_child0, 0);
|
||||
root.setDirection(YogaDirection.LTR);
|
||||
root.calculateLayout();
|
||||
|
||||
assertEquals(0f, root.getLayoutX(), 0.0f);
|
||||
assertEquals(0f, root.getLayoutY(), 0.0f);
|
||||
assertEquals(100f, root.getLayoutWidth(), 0.0f);
|
||||
assertEquals(100f, root.getLayoutHeight(), 0.0f);
|
||||
|
||||
assertEquals(5f, root_child0.getLayoutX(), 0.0f);
|
||||
assertEquals(5f, root_child0.getLayoutY(), 0.0f);
|
||||
assertEquals(50f, root_child0.getLayoutWidth(), 0.0f);
|
||||
assertEquals(50f, root_child0.getLayoutHeight(), 0.0f);
|
||||
|
||||
assertEquals(60f, root_child1.getLayoutX(), 0.0f);
|
||||
assertEquals(44f, root_child1.getLayoutY(), 0.0f);
|
||||
assertEquals(50f, root_child1.getLayoutWidth(), 0.0f);
|
||||
assertEquals(20f, root_child1.getLayoutHeight(), 0.0f);
|
||||
|
||||
assertEquals(1f, root_child1_child0.getLayoutX(), 0.0f);
|
||||
assertEquals(1f, root_child1_child0.getLayoutY(), 0.0f);
|
||||
assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f);
|
||||
assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f);
|
||||
|
||||
root.setDirection(YogaDirection.RTL);
|
||||
root.calculateLayout();
|
||||
|
||||
assertEquals(0f, root.getLayoutX(), 0.0f);
|
||||
assertEquals(0f, root.getLayoutY(), 0.0f);
|
||||
assertEquals(100f, root.getLayoutWidth(), 0.0f);
|
||||
assertEquals(100f, root.getLayoutHeight(), 0.0f);
|
||||
|
||||
assertEquals(45f, root_child0.getLayoutX(), 0.0f);
|
||||
assertEquals(5f, root_child0.getLayoutY(), 0.0f);
|
||||
assertEquals(50f, root_child0.getLayoutWidth(), 0.0f);
|
||||
assertEquals(50f, root_child0.getLayoutHeight(), 0.0f);
|
||||
|
||||
assertEquals(-10f, root_child1.getLayoutX(), 0.0f);
|
||||
assertEquals(44f, root_child1.getLayoutY(), 0.0f);
|
||||
assertEquals(50f, root_child1.getLayoutWidth(), 0.0f);
|
||||
assertEquals(20f, root_child1.getLayoutHeight(), 0.0f);
|
||||
|
||||
assertEquals(-1f, root_child1_child0.getLayoutX(), 0.0f);
|
||||
assertEquals(1f, root_child1_child0.getLayoutY(), 0.0f);
|
||||
assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f);
|
||||
assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -267,3 +267,79 @@ TEST(YogaTest, align_baseline_column) {
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
|
||||
TEST(YogaTest, align_baseline_child_margin) {
|
||||
const YGNodeRef root = YGNodeNew();
|
||||
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
|
||||
YGNodeStyleSetAlignItems(root, YGAlignBaseline);
|
||||
YGNodeStyleSetWidth(root, 100);
|
||||
YGNodeStyleSetHeight(root, 100);
|
||||
|
||||
const YGNodeRef root_child0 = YGNodeNew();
|
||||
YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 5);
|
||||
YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5);
|
||||
YGNodeStyleSetMargin(root_child0, YGEdgeRight, 5);
|
||||
YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 5);
|
||||
YGNodeStyleSetWidth(root_child0, 50);
|
||||
YGNodeStyleSetHeight(root_child0, 50);
|
||||
YGNodeInsertChild(root, root_child0, 0);
|
||||
|
||||
const YGNodeRef root_child1 = YGNodeNew();
|
||||
YGNodeStyleSetWidth(root_child1, 50);
|
||||
YGNodeStyleSetHeight(root_child1, 20);
|
||||
YGNodeInsertChild(root, root_child1, 1);
|
||||
|
||||
const YGNodeRef root_child1_child0 = YGNodeNew();
|
||||
YGNodeStyleSetMargin(root_child1_child0, YGEdgeLeft, 1);
|
||||
YGNodeStyleSetMargin(root_child1_child0, YGEdgeTop, 1);
|
||||
YGNodeStyleSetMargin(root_child1_child0, YGEdgeRight, 1);
|
||||
YGNodeStyleSetMargin(root_child1_child0, YGEdgeBottom, 1);
|
||||
YGNodeStyleSetWidth(root_child1_child0, 50);
|
||||
YGNodeStyleSetHeight(root_child1_child0, 10);
|
||||
YGNodeInsertChild(root_child1, root_child1_child0, 0);
|
||||
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
|
||||
|
||||
ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child0));
|
||||
ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0));
|
||||
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1));
|
||||
ASSERT_FLOAT_EQ(44, YGNodeLayoutGetTop(root_child1));
|
||||
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1));
|
||||
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1));
|
||||
|
||||
ASSERT_FLOAT_EQ(1, YGNodeLayoutGetLeft(root_child1_child0));
|
||||
ASSERT_FLOAT_EQ(1, YGNodeLayoutGetTop(root_child1_child0));
|
||||
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0));
|
||||
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0));
|
||||
|
||||
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
|
||||
|
||||
ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0));
|
||||
ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0));
|
||||
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child1));
|
||||
ASSERT_FLOAT_EQ(44, YGNodeLayoutGetTop(root_child1));
|
||||
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1));
|
||||
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1));
|
||||
|
||||
ASSERT_FLOAT_EQ(-1, YGNodeLayoutGetLeft(root_child1_child0));
|
||||
ASSERT_FLOAT_EQ(1, YGNodeLayoutGetTop(root_child1_child0));
|
||||
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0));
|
||||
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0));
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
|
13
yoga/Yoga.c
13
yoga/Yoga.c
@@ -1000,14 +1000,14 @@ static float YGBaselineOfFirstLine(const YGNodeRef node, const YGFlexDirection m
|
||||
return baseline + baselineChild->layout.position[YGEdgeTop];
|
||||
}
|
||||
|
||||
static float YGBaselineWithMargin(const YGNodeRef node, const YGFlexDirection mainAxis, const float parentWidth)
|
||||
static inline float YGBaselineForNode(const YGNodeRef node, const YGFlexDirection crossAxis, const float parentWidth)
|
||||
{
|
||||
float baseline = YGBaselineOfFirstLine(node, mainAxis, parentWidth);
|
||||
float baseline = YGBaselineOfFirstLine(node, crossAxis, parentWidth);
|
||||
|
||||
if(YGFloatIsUndefined(baseline))
|
||||
{
|
||||
baseline = node->layout.measuredDimensions[dim[mainAxis]];
|
||||
return node->layout.measuredDimensions[dim[crossAxis]];
|
||||
}
|
||||
return baseline + YGNodeLeadingMargin(node, mainAxis, parentWidth);
|
||||
return baseline;
|
||||
}
|
||||
|
||||
|
||||
@@ -2535,7 +2535,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||
if (performLayout && YGNodeAlignItem(node, child) == YGAlignBaseline)
|
||||
{
|
||||
maxAscentForCurrentLine = fmaxf(maxAscentForCurrentLine,
|
||||
YGBaselineWithMargin(child, crossAxis, availableInnerWidth));
|
||||
YGBaselineForNode(child, crossAxis, availableInnerWidth))
|
||||
+ YGNodeLeadingMargin(child, crossAxis, availableInnerWidth);
|
||||
}
|
||||
|
||||
if (YGNodeIsLayoutDimDefined(child, crossAxis)) {
|
||||
@@ -2582,7 +2583,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||
case YGAlignBaseline: {
|
||||
child->layout.position[pos[crossAxis]] =
|
||||
currentLead + maxAscentForCurrentLine -
|
||||
YGBaselineWithMargin(child, crossAxis, availableInnerWidth);;
|
||||
YGBaselineForNode(child, crossAxis, availableInnerWidth);
|
||||
break;
|
||||
}
|
||||
case YGAlignAuto:
|
||||
|
Reference in New Issue
Block a user
not quite sure why we break if a child has more than one line. That would mean if the first child of this node has two lines then the baseline would default to the height of the node. I'm not sure why that would be correct.
we break as only childs on the first line which have align baseline are taken into account. I already added a testcase for this.
oh, I see the confusion,
child->lineIndex
does not mean that it has more than one line. It means it is itself on the seconds (or later) line.@woehrl01 yeah that was my confusion, i'm not super familiar with the multi line code and read it too quickly 🐱