Baseline support #317
@@ -16,5 +16,6 @@ namespace Facebook.Yoga
|
|||||||
Center,
|
Center,
|
||||||
FlexEnd,
|
FlexEnd,
|
||||||
Stretch,
|
Stretch,
|
||||||
|
Baseline,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -174,5 +174,76 @@ namespace Facebook.Yoga
|
|||||||
Assert.AreEqual(10f, root_child0.LayoutHeight);
|
Assert.AreEqual(10f, root_child0.LayoutHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test_align_self_baseline()
|
||||||
|
{
|
||||||
|
YogaNode root = new YogaNode();
|
||||||
|
root.FlexDirection = YogaFlexDirection.Row;
|
||||||
|
root.Width = 100;
|
||||||
|
root.Height = 100;
|
||||||
|
|
||||||
|
YogaNode root_child0 = new YogaNode();
|
||||||
|
root_child0.AlignSelf = YogaAlign.Baseline;
|
||||||
|
root_child0.Width = 50;
|
||||||
|
root_child0.Height = 50;
|
||||||
|
root.Insert(0, root_child0);
|
||||||
|
|
||||||
|
YogaNode root_child1 = new YogaNode();
|
||||||
|
root_child1.AlignSelf = YogaAlign.Baseline;
|
||||||
|
root_child1.Width = 50;
|
||||||
|
root_child1.Height = 20;
|
||||||
|
root.Insert(1, root_child1);
|
||||||
|
|
||||||
|
YogaNode root_child1_child0 = new YogaNode();
|
||||||
|
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(0f, root_child0.LayoutX);
|
||||||
|
Assert.AreEqual(0f, root_child0.LayoutY);
|
||||||
|
Assert.AreEqual(50f, root_child0.LayoutWidth);
|
||||||
|
Assert.AreEqual(50f, root_child0.LayoutHeight);
|
||||||
|
|
||||||
|
Assert.AreEqual(50f, root_child1.LayoutX);
|
||||||
|
Assert.AreEqual(40f, root_child1.LayoutY);
|
||||||
|
Assert.AreEqual(50f, root_child1.LayoutWidth);
|
||||||
|
Assert.AreEqual(20f, root_child1.LayoutHeight);
|
||||||
|
|
||||||
|
Assert.AreEqual(0f, root_child1_child0.LayoutX);
|
||||||
|
Assert.AreEqual(0f, 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(50f, root_child0.LayoutX);
|
||||||
|
Assert.AreEqual(0f, root_child0.LayoutY);
|
||||||
|
Assert.AreEqual(50f, root_child0.LayoutWidth);
|
||||||
|
Assert.AreEqual(50f, root_child0.LayoutHeight);
|
||||||
|
|
||||||
|
Assert.AreEqual(0f, root_child1.LayoutX);
|
||||||
|
Assert.AreEqual(40f, root_child1.LayoutY);
|
||||||
|
Assert.AreEqual(50f, root_child1.LayoutWidth);
|
||||||
|
Assert.AreEqual(20f, root_child1.LayoutHeight);
|
||||||
|
|
||||||
|
Assert.AreEqual(0f, root_child1_child0.LayoutX);
|
||||||
|
Assert.AreEqual(0f, root_child1_child0.LayoutY);
|
||||||
|
Assert.AreEqual(50f, root_child1_child0.LayoutWidth);
|
||||||
|
Assert.AreEqual(10f, root_child1_child0.LayoutHeight);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
enums.py
@@ -46,6 +46,7 @@ ENUMS = {
|
|||||||
'Center',
|
'Center',
|
||||||
'FlexEnd',
|
'FlexEnd',
|
||||||
'Stretch',
|
'Stretch',
|
||||||
|
'Baseline',
|
||||||
],
|
],
|
||||||
'PositionType': [
|
'PositionType': [
|
||||||
'Relative',
|
'Relative',
|
||||||
|
@@ -13,3 +13,135 @@
|
|||||||
<div id="align_items_flex_end" style="width: 100px; height: 100px; align-items: flex-end;">
|
<div id="align_items_flex_end" style="width: 100px; height: 100px; align-items: flex-end;">
|
||||||
<div style="height: 10px; width: 10px;"></div>
|
<div style="height: 10px; width: 10px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="align_baseline" style="width: 100px; height: 100px; flex-direction:row; align-items: baseline;">
|
||||||
|
<div style="width: 50px; height: 50px;"></div>
|
||||||
|
<div style="width: 50px; height: 20px;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="align_baseline_child" style="width: 100px; height: 100px; flex-direction:row; align-items: baseline;">
|
||||||
|
<div style="width: 50px; height: 50px;"></div>
|
||||||
|
<div style="width: 50px; height: 20px;">
|
||||||
|
<div style="width: 50px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="align_baseline_child_multiline" style="width: 100px; height: 100px; flex-direction:row; align-items: baseline;">
|
||||||
|
<div style="width: 50px; height: 60px;"></div>
|
||||||
|
<div style="width: 50px; height: 25px;flex-wrap:wrap;flex-direction:row;">
|
||||||
|
<div style="width: 25px; height: 20px;"></div>
|
||||||
|
<div style="width: 25px; height: 10px;"></div>
|
||||||
|
<div style="width: 25px; height: 20px;"></div>
|
||||||
|
<div style="width: 25px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="align_baseline_child_multiline_override" style="width: 100px; height: 100px; flex-direction:row; align-items: baseline;">
|
||||||
|
<div style="width: 50px; height: 60px;"></div>
|
||||||
|
<div style="width: 50px; height: 25px;flex-wrap:wrap;flex-direction:row;">
|
||||||
|
<div style="width: 25px; height: 20px;"></div>
|
||||||
|
<div style="width: 25px; height: 10px;align-self:baseline;"></div>
|
||||||
|
<div style="width: 25px; height: 20px;"></div>
|
||||||
|
<div style="width: 25px; height: 10px;align-self:baseline;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="align_baseline_child_multiline_no_override_on_secondline" style="width: 100px; height: 100px; flex-direction:row; align-items: baseline;">
|
||||||
|
<div style="width: 50px; height: 60px;"></div>
|
||||||
|
<div style="width: 50px; height: 25px;flex-wrap:wrap;flex-direction:row;">
|
||||||
|
<div style="width: 25px; height: 20px;"></div>
|
||||||
|
<div style="width: 25px; height: 10px;"></div>
|
||||||
|
<div style="width: 25px; height: 20px;"></div>
|
||||||
|
<div style="width: 25px; height: 10px;align-self:baseline;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="align_baseline_child_top" style="width: 100px; height: 100px; flex-direction:row; align-items: baseline;">
|
||||||
|
<div style="width: 50px; height: 50px;top:10px;"></div>
|
||||||
|
<div style="width: 50px; height: 20px;">
|
||||||
|
<div style="width: 50px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="align_baseline_child_top2" style="width: 100px; height: 100px; flex-direction:row; align-items: baseline;">
|
||||||
|
<div style="width: 50px; height: 50px;"></div>
|
||||||
|
<div style="width: 50px; height: 20px;top:5px">
|
||||||
|
<div style="width: 50px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="align_baseline_double_nested_child" style="width: 100px; height: 100px; flex-direction:row; align-items: baseline;">
|
||||||
|
<div style="width: 50px; height: 50px;">
|
||||||
|
<div style="width: 50px; height: 20px;"></div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 50px; height: 20px;">
|
||||||
|
<div style="width: 50px; height: 15px;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="align_baseline_column" style="width: 100px; height: 100px; flex-direction:column; align-items: baseline;">
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<div id="align_baseline_child_padding" style="width: 100px; height: 100px; padding:5px; flex-direction:row; align-items: baseline;">
|
||||||
|
<div style="width: 50px; height: 50px;"></div>
|
||||||
|
<div style="width: 50px; height: 20px;padding:5px;">
|
||||||
|
<div style="width: 50px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="align_baseline_multiline" style="width: 100px; height: 100px; flex-direction:row; align-items: baseline;flex-wrap:wrap;">
|
||||||
|
<div style="width: 50px; height: 50px;"></div>
|
||||||
|
<div style="width: 50px; height: 20px;">
|
||||||
|
<div style="width: 50px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 50px; height: 20px;">
|
||||||
|
<div style="width: 50px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 50px; height: 50px;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="align_baseline_multiline_column" style="width: 100px; height: 100px; flex-direction:column; align-items: baseline;flex-wrap:wrap;">
|
||||||
|
<div style="width: 50px; height: 50px;"></div>
|
||||||
|
<div style="width: 30px; height: 50px;">
|
||||||
|
<div style="width: 20px; height: 20px;"></div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 40px; height: 70px;">
|
||||||
|
<div style="width: 10px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 50px; height: 20px;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="align_baseline_multiline_column2" style="width: 100px; height: 100px; flex-direction:column; align-items: baseline;flex-wrap:wrap;">
|
||||||
|
<div style="width: 50px; height: 50px;flex-direction:column;"></div>
|
||||||
|
<div style="width: 30px; height: 50px;flex-direction:column;">
|
||||||
|
<div style="width: 20px; height: 20px;flex-direction:column;"></div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 40px; height: 70px;flex-direction:column;">
|
||||||
|
<div style="width: 10px; height: 10px;flex-direction:column;"></div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 50px; height: 20px;flex-direction:column;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="align_baseline_multiline_row_and_column" style="width: 100px; height: 100px; flex-direction:row; align-items: baseline;flex-wrap:wrap;">
|
||||||
|
<div style="width: 50px; height: 50px;"></div>
|
||||||
|
<div style="width: 50px; height: 50px;flex-direction:column;">
|
||||||
|
<div style="width: 50px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 50px; height: 20px;flex-direction:column;">
|
||||||
|
<div style="width: 50px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 50px; height: 20px;"></div>
|
||||||
|
</div>
|
@@ -13,3 +13,11 @@
|
|||||||
<div id="align_self_flex_end_override_flex_start" style="width:100px; height: 100px; align-items: flex-start;">
|
<div id="align_self_flex_end_override_flex_start" style="width:100px; height: 100px; align-items: flex-start;">
|
||||||
<div style="height: 10px; width: 10px; align-self: flex-end;"></div>
|
<div style="height: 10px; width: 10px; align-self: flex-end;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="align_self_baseline" style="width: 100px; height: 100px; flex-direction:row;">
|
||||||
|
<div style="width: 50px; height: 50px;align-self: baseline;"></div>
|
||||||
|
<div style="width: 50px; height: 20px;align-self: baseline;">
|
||||||
|
<div style="width: 50px; height: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@@ -83,6 +83,8 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, {
|
|||||||
YGAlignFlexStart:{value:'YGAlignFlexStart'},
|
YGAlignFlexStart:{value:'YGAlignFlexStart'},
|
||||||
YGAlignStretch:{value:'YGAlignStretch'},
|
YGAlignStretch:{value:'YGAlignStretch'},
|
||||||
|
|
||||||
|
YGAlignBaseline:{value:'YGAlignBaseline'},
|
||||||
|
|
||||||
YGDirectionInherit:{value:'YGDirectionInherit'},
|
YGDirectionInherit:{value:'YGDirectionInherit'},
|
||||||
YGDirectionLTR:{value:'YGDirectionLTR'},
|
YGDirectionLTR:{value:'YGDirectionLTR'},
|
||||||
YGDirectionRTL:{value:'YGDirectionRTL'},
|
YGDirectionRTL:{value:'YGDirectionRTL'},
|
||||||
|
@@ -96,6 +96,7 @@ CSEmitter.prototype = Object.create(Emitter.prototype, {
|
|||||||
YGAlignFlexEnd:{value:'YogaAlign.FlexEnd'},
|
YGAlignFlexEnd:{value:'YogaAlign.FlexEnd'},
|
||||||
YGAlignFlexStart:{value:'YogaAlign.FlexStart'},
|
YGAlignFlexStart:{value:'YogaAlign.FlexStart'},
|
||||||
YGAlignStretch:{value:'YogaAlign.Stretch'},
|
YGAlignStretch:{value:'YogaAlign.Stretch'},
|
||||||
|
YGAlignBaseline:{value:'YogaAlign.Baseline'},
|
||||||
|
|
||||||
YGDirectionInherit:{value:'YogaDirection.Inherit'},
|
YGDirectionInherit:{value:'YogaDirection.Inherit'},
|
||||||
YGDirectionLTR:{value:'YogaDirection.LTR'},
|
YGDirectionLTR:{value:'YogaDirection.LTR'},
|
||||||
|
@@ -100,6 +100,7 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, {
|
|||||||
YGAlignFlexEnd:{value:'YogaAlign.FLEX_END'},
|
YGAlignFlexEnd:{value:'YogaAlign.FLEX_END'},
|
||||||
YGAlignFlexStart:{value:'YogaAlign.FLEX_START'},
|
YGAlignFlexStart:{value:'YogaAlign.FLEX_START'},
|
||||||
YGAlignStretch:{value:'YogaAlign.STRETCH'},
|
YGAlignStretch:{value:'YogaAlign.STRETCH'},
|
||||||
|
YGAlignBaseline:{value:'YogaAlign.BASELINE'},
|
||||||
|
|
||||||
YGDirectionInherit:{value:'YogaDirection.INHERIT'},
|
YGDirectionInherit:{value:'YogaDirection.INHERIT'},
|
||||||
YGDirectionLTR:{value:'YogaDirection.LTR'},
|
YGDirectionLTR:{value:'YogaDirection.LTR'},
|
||||||
|
@@ -84,6 +84,7 @@ JavascriptEmitter.prototype = Object.create(Emitter.prototype, {
|
|||||||
YGAlignFlexEnd:{value:'Yoga.ALIGN_FLEX_END'},
|
YGAlignFlexEnd:{value:'Yoga.ALIGN_FLEX_END'},
|
||||||
YGAlignFlexStart:{value:'Yoga.ALIGN_FLEX_START'},
|
YGAlignFlexStart:{value:'Yoga.ALIGN_FLEX_START'},
|
||||||
YGAlignStretch:{value:'Yoga.ALIGN_STRETCH'},
|
YGAlignStretch:{value:'Yoga.ALIGN_STRETCH'},
|
||||||
|
YGAlignBaseline:{value:'Yoga.ALIGN_BASELINE'},
|
||||||
|
|
||||||
YGDirectionInherit:{value:'Yoga.DIRECTION_INHERIT'},
|
YGDirectionInherit:{value:'Yoga.DIRECTION_INHERIT'},
|
||||||
YGDirectionLTR:{value:'Yoga.DIRECTION_LTR'},
|
YGDirectionLTR:{value:'Yoga.DIRECTION_LTR'},
|
||||||
|
@@ -377,6 +377,7 @@ function alignValue(e, value) {
|
|||||||
case 'stretch': return e.YGAlignStretch;
|
case 'stretch': return e.YGAlignStretch;
|
||||||
case 'flex-start': return e.YGAlignFlexStart;
|
case 'flex-start': return e.YGAlignFlexStart;
|
||||||
case 'flex-end': return e.YGAlignFlexEnd;
|
case 'flex-end': return e.YGAlignFlexEnd;
|
||||||
|
case 'baseline': return e.YGAlignBaseline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,7 +17,8 @@ public enum YogaAlign {
|
|||||||
FLEX_START(1),
|
FLEX_START(1),
|
||||||
CENTER(2),
|
CENTER(2),
|
||||||
FLEX_END(3),
|
FLEX_END(3),
|
||||||
STRETCH(4);
|
STRETCH(4),
|
||||||
|
BASELINE(5);
|
||||||
|
|
||||||
private int mIntValue;
|
private int mIntValue;
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ public enum YogaAlign {
|
|||||||
case 2: return CENTER;
|
case 2: return CENTER;
|
||||||
case 3: return FLEX_END;
|
case 3: return FLEX_END;
|
||||||
case 4: return STRETCH;
|
case 4: return STRETCH;
|
||||||
|
case 5: return BASELINE;
|
||||||
default: throw new IllegalArgumentException("Unkown enum value: " + value);
|
default: throw new IllegalArgumentException("Unkown enum value: " + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -169,4 +169,74 @@ public class YGAlignSelfTest {
|
|||||||
assertEquals(10f, root_child0.getLayoutHeight(), 0.0f);
|
assertEquals(10f, root_child0.getLayoutHeight(), 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_align_self_baseline() {
|
||||||
|
final YogaNode root = new YogaNode();
|
||||||
|
root.setFlexDirection(YogaFlexDirection.ROW);
|
||||||
|
root.setWidth(100f);
|
||||||
|
root.setHeight(100f);
|
||||||
|
|
||||||
|
final YogaNode root_child0 = new YogaNode();
|
||||||
|
root_child0.setAlignSelf(YogaAlign.BASELINE);
|
||||||
|
root_child0.setWidth(50f);
|
||||||
|
root_child0.setHeight(50f);
|
||||||
|
root.addChildAt(root_child0, 0);
|
||||||
|
|
||||||
|
final YogaNode root_child1 = new YogaNode();
|
||||||
|
root_child1.setAlignSelf(YogaAlign.BASELINE);
|
||||||
|
root_child1.setWidth(50f);
|
||||||
|
root_child1.setHeight(20f);
|
||||||
|
root.addChildAt(root_child1, 1);
|
||||||
|
|
||||||
|
final YogaNode root_child1_child0 = new YogaNode();
|
||||||
|
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(0f, root_child0.getLayoutX(), 0.0f);
|
||||||
|
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
|
||||||
|
assertEquals(50f, root_child0.getLayoutWidth(), 0.0f);
|
||||||
|
assertEquals(50f, root_child0.getLayoutHeight(), 0.0f);
|
||||||
|
|
||||||
|
assertEquals(50f, root_child1.getLayoutX(), 0.0f);
|
||||||
|
assertEquals(40f, root_child1.getLayoutY(), 0.0f);
|
||||||
|
assertEquals(50f, root_child1.getLayoutWidth(), 0.0f);
|
||||||
|
assertEquals(20f, root_child1.getLayoutHeight(), 0.0f);
|
||||||
|
|
||||||
|
assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f);
|
||||||
|
assertEquals(0f, 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(50f, root_child0.getLayoutX(), 0.0f);
|
||||||
|
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
|
||||||
|
assertEquals(50f, root_child0.getLayoutWidth(), 0.0f);
|
||||||
|
assertEquals(50f, root_child0.getLayoutHeight(), 0.0f);
|
||||||
|
|
||||||
|
assertEquals(0f, root_child1.getLayoutX(), 0.0f);
|
||||||
|
assertEquals(40f, root_child1.getLayoutY(), 0.0f);
|
||||||
|
assertEquals(50f, root_child1.getLayoutWidth(), 0.0f);
|
||||||
|
assertEquals(20f, root_child1.getLayoutHeight(), 0.0f);
|
||||||
|
|
||||||
|
assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f);
|
||||||
|
assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f);
|
||||||
|
assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f);
|
||||||
|
assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -160,3 +160,72 @@ TEST(YogaTest, align_self_flex_end_override_flex_start) {
|
|||||||
|
|
||||||
YGNodeFreeRecursive(root);
|
YGNodeFreeRecursive(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(YogaTest, align_self_baseline) {
|
||||||
|
const YGNodeRef root = YGNodeNew();
|
||||||
|
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
|
||||||
|
YGNodeStyleSetWidth(root, 100);
|
||||||
|
YGNodeStyleSetHeight(root, 100);
|
||||||
|
|
||||||
|
const YGNodeRef root_child0 = YGNodeNew();
|
||||||
|
YGNodeStyleSetAlignSelf(root_child0, YGAlignBaseline);
|
||||||
|
YGNodeStyleSetWidth(root_child0, 50);
|
||||||
|
YGNodeStyleSetHeight(root_child0, 50);
|
||||||
|
YGNodeInsertChild(root, root_child0, 0);
|
||||||
|
|
||||||
|
const YGNodeRef root_child1 = YGNodeNew();
|
||||||
|
YGNodeStyleSetAlignSelf(root_child1, YGAlignBaseline);
|
||||||
|
YGNodeStyleSetWidth(root_child1, 50);
|
||||||
|
YGNodeStyleSetHeight(root_child1, 20);
|
||||||
|
YGNodeInsertChild(root, root_child1, 1);
|
||||||
|
|
||||||
|
const YGNodeRef root_child1_child0 = YGNodeNew();
|
||||||
|
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(0, YGNodeLayoutGetLeft(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
|
||||||
|
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1));
|
||||||
|
ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1));
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1));
|
||||||
|
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1));
|
||||||
|
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, 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(50, YGNodeLayoutGetLeft(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
|
||||||
|
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
|
||||||
|
ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1));
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1));
|
||||||
|
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1));
|
||||||
|
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0));
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0));
|
||||||
|
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0));
|
||||||
|
|
||||||
|
YGNodeFreeRecursive(root);
|
||||||
|
}
|
||||||
|
63
tests/YGBaselineFuncTest.cpp
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* 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 <gtest/gtest.h>
|
||||||
|
#include <yoga/Yoga.h>
|
||||||
|
|
||||||
|
static float _baseline(YGNodeRef node) {
|
||||||
|
float *baseline = (float *) YGNodeGetContext(node);
|
||||||
|
return *baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(YogaTest, align_baseline_customer_func) {
|
||||||
|
const YGNodeRef root = YGNodeNew();
|
||||||
|
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
|
||||||
|
YGNodeStyleSetAlignItems(root, YGAlignBaseline);
|
||||||
|
YGNodeStyleSetWidth(root, 100);
|
||||||
|
YGNodeStyleSetHeight(root, 100);
|
||||||
|
|
||||||
|
const YGNodeRef root_child0 = YGNodeNew();
|
||||||
|
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);
|
||||||
|
|
||||||
|
float baselineValue = 10;
|
||||||
|
const YGNodeRef root_child1_child0 = YGNodeNew();
|
||||||
|
YGNodeSetContext(root_child1_child0, &baselineValue);
|
||||||
|
YGNodeStyleSetWidth(root_child1_child0, 50);
|
||||||
|
YGNodeSetBaselineFunc(root_child1_child0, _baseline);
|
||||||
|
YGNodeStyleSetHeight(root_child1_child0, 20);
|
||||||
|
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(0, YGNodeLayoutGetLeft(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
|
||||||
|
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1));
|
||||||
|
ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1));
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1));
|
||||||
|
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1));
|
||||||
|
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0));
|
||||||
|
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0));
|
||||||
|
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0));
|
||||||
|
}
|
@@ -104,13 +104,14 @@ typedef enum YGExperimentalFeature {
|
|||||||
YGExperimentalFeatureWebFlexBasis,
|
YGExperimentalFeatureWebFlexBasis,
|
||||||
} YGExperimentalFeature;
|
} YGExperimentalFeature;
|
||||||
|
|
||||||
#define YGAlignCount 5
|
#define YGAlignCount 6
|
||||||
typedef enum YGAlign {
|
typedef enum YGAlign {
|
||||||
YGAlignAuto,
|
YGAlignAuto,
|
||||||
YGAlignFlexStart,
|
YGAlignFlexStart,
|
||||||
YGAlignCenter,
|
YGAlignCenter,
|
||||||
YGAlignFlexEnd,
|
YGAlignFlexEnd,
|
||||||
YGAlignStretch,
|
YGAlignStretch,
|
||||||
|
YGAlignBaseline,
|
||||||
} YGAlign;
|
} YGAlign;
|
||||||
|
|
||||||
#define YGUnitCount 3
|
#define YGUnitCount 3
|
||||||
|
93
yoga/Yoga.c
@@ -102,6 +102,7 @@ typedef struct YGNode {
|
|||||||
struct YGNode *nextChild;
|
struct YGNode *nextChild;
|
||||||
|
|
||||||
YGMeasureFunc measure;
|
YGMeasureFunc measure;
|
||||||
|
YGBaselineFunc baseline;
|
||||||
YGPrintFunc print;
|
YGPrintFunc print;
|
||||||
void *context;
|
void *context;
|
||||||
} YGNode;
|
} YGNode;
|
||||||
@@ -334,6 +335,14 @@ YGMeasureFunc YGNodeGetMeasureFunc(const YGNodeRef node) {
|
|||||||
return node->measure;
|
return node->measure;
|
||||||
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
void YGNodeSetBaselineFunc(const YGNodeRef node, YGBaselineFunc baselineFunc) {
|
||||||
|
node->baseline = baselineFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
YGBaselineFunc YGNodeGetBaselineFunc(const YGNodeRef node) {
|
||||||
|
return node->baseline;
|
||||||
|
}
|
||||||
|
|
||||||
void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32_t index) {
|
void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32_t index) {
|
||||||
YG_ASSERT(child->parent == NULL, "Child already has a parent, it must be removed first.");
|
YG_ASSERT(child->parent == NULL, "Child already has a parent, it must be removed first.");
|
||||||
YG_ASSERT(node->measure == NULL,
|
YG_ASSERT(node->measure == NULL,
|
||||||
@@ -929,7 +938,12 @@ static inline float YGNodePaddingAndBorderForAxis(const YGNodeRef node,
|
|||||||
}
|
}
|
||||||
![]() const const
|
|||||||
|
|
||||||
static inline YGAlign YGNodeAlignItem(const YGNodeRef node, const YGNodeRef child) {
|
static inline YGAlign YGNodeAlignItem(const YGNodeRef node, const YGNodeRef child) {
|
||||||
return child->style.alignSelf == YGAlignAuto ? node->style.alignItems : child->style.alignSelf;
|
const YGAlign align =
|
||||||
|
child->style.alignSelf == YGAlignAuto ? node->style.alignItems : child->style.alignSelf;
|
||||||
|
if (align == YGAlignBaseline && YGFlexDirectionIsColumn(node->style.flexDirection)) {
|
||||||
|
return YGAlignFlexStart;
|
||||||
|
}
|
||||||
|
return align;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
|
static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
|
||||||
@@ -941,6 +955,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node,
|
|||||||
}
|
}
|
||||||
![]() This will always be height as baseline is undefined for column flex direction. right? in that case I think it is better to be clear and use This will always be height as baseline is undefined for column flex direction. right? in that case I think it is better to be clear and use `YGDimensionHeight` instead of `dim[crossAxis]`
![]() Is there a good reason to allow undefined return value for baseline? I would prefer asserting and crashing as it would probably indicate a bug. What do you think? Is there a good reason to allow undefined return value for baseline? I would prefer asserting and crashing as it would probably indicate a bug. What do you think?
![]() Why Why `child->lineIndex > 0`? I understand that it skips multiline children but i'm not sure why.
![]() same as above regarding same as above regarding `dim[crossAxis]`
![]() The baseline of a container is defined by its first baseline aligned child, but when there is no baseline aligned child then the container's baseline is defined by it's last child. This seems odd. Are you sure we have test cases covering edge cases here to make sure this is how it works on the web? The baseline of a container is defined by its first baseline aligned child, but when there is no baseline aligned child then the container's baseline is defined by it's last child. This seems odd. Are you sure we have test cases covering edge cases here to make sure this is how it works on the web?
![]() same as above regarding same as above regarding `pos[crossAxis]`
![]() I'm not sure my self about this. I thought this could be a kind of "feature", so if you return undefined, you simply use the nodes height. But crashing would be fine too for me. What I'm not sure about is if we explicitly add the padding-top here or if the implementation of the custom function needs to consider this. I'm not sure my self about this. I thought this could be a kind of "feature", so if you return undefined, you simply use the nodes height. But crashing would be fine too for me. What I'm not sure about is if we explicitly add the padding-top here or if the implementation of the custom function needs to consider this.
![]() we use only the first line of the children for base layout alignment. At least this is how chrome handles it. we use only the first line of the children for base layout alignment. At least this is how chrome handles it.
![]() no it's defined by its first child on the first line or the first baseline aligned child if there is one (one the first line). I'll add a test for this. no it's defined by its first child on the first line or the first baseline aligned child if there is one (one the first line). I'll add a test for this.
![]() The custom function should not take padding into account. We don't expect this for the measure function so I would like to preserve that here if possible. Let's crash for now. If we find a valid reason to have this feature we can implement it later. The custom function should not take padding into account. We don't expect this for the measure function so I would like to preserve that here if possible.
Let's crash for now. If we find a valid reason to have this feature we can implement it later.
![]() yes, but this looks like we are skipping over children with multiple lines instead of just looking at their first line? yes, but this looks like we are skipping over children with multiple lines instead of just looking at their first line?
![]() So the current code is wrong i think. Right? As it will pick the last child in the case no child is baseline aligned? So the current code is wrong i think. Right? As it will pick the last child in the case no child is baseline aligned?
![]() oh, yep. We should break instead of continue here! oh, yep. We should break instead of continue here!
![]() no as we only use the child if no as we only use the child if ```baselineChild``` is still ```NULL```. Which is false as seen as we find the first one. We still need to iterate to take any baseline aligned child into account.
|
|||||||
}
|
}
|
||||||
![]() uint32_t uint32_t
![]() i++ i++
|
|||||||
|
|
||||||
|
static float YGBaseline(const YGNodeRef node) {
|
||||||
|
if (node->baseline != NULL) {
|
||||||
|
const float baseline = node->baseline(node);
|
||||||
|
YG_ASSERT(!YGFloatIsUndefined(baseline), "Expect custom baseline function to not return NaN")
|
||||||
|
return baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
YGNodeRef baselineChild = NULL;
|
||||||
|
for (uint32_t i = 0; i < YGNodeGetChildCount(node); i++) {
|
||||||
|
const YGNodeRef child = YGNodeGetChild(node, i);
|
||||||
|
if (child->lineIndex > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (child->style.positionType == YGPositionTypeAbsolute) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (YGNodeAlignItem(node, child) == YGAlignBaseline) {
|
||||||
|
baselineChild = child;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baselineChild == NULL) {
|
||||||
|
baselineChild = child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baselineChild == NULL) {
|
||||||
|
return node->layout.measuredDimensions[YGDimensionHeight];
|
||||||
|
}
|
||||||
|
|
||||||
|
const float baseline = YGBaseline(baselineChild);
|
||||||
|
return baseline + baselineChild->layout.position[YGEdgeTop];
|
||||||
|
}
|
||||||
|
|
||||||
static inline YGFlexDirection YGFlexDirectionResolve(const YGFlexDirection flexDirection,
|
static inline YGFlexDirection YGFlexDirectionResolve(const YGFlexDirection flexDirection,
|
||||||
const YGDirection direction) {
|
const YGDirection direction) {
|
||||||
if (direction == YGDirectionRTL) {
|
if (direction == YGDirectionRTL) {
|
||||||
@@ -966,6 +1014,24 @@ static inline bool YGNodeIsFlex(const YGNodeRef node) {
|
|||||||
(YGNodeStyleGetFlexGrow(node) != 0 || YGNodeStyleGetFlexShrink(node) != 0));
|
(YGNodeStyleGetFlexGrow(node) != 0 || YGNodeStyleGetFlexShrink(node) != 0));
|
||||||
}
|
}
|
||||||
![]() nit: empty line above nit: empty line above
![]() Please add this 👍 Please add this 👍
![]() not sure what you mean, should I add a empty line above not sure what you mean, should I add a empty line above ```return false```?
|
|||||||
|
|
||||||
|
static bool YGIsBaselineLayout(const YGNodeRef node) {
|
||||||
|
if (YGFlexDirectionIsColumn(node->style.flexDirection)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->style.alignItems == YGAlignBaseline) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < YGNodeGetChildCount(node); i++) {
|
||||||
|
const YGNodeRef child = YGNodeGetChild(node, i);
|
||||||
|
if (child->style.positionType == YGPositionTypeRelative &&
|
||||||
|
child->style.alignSelf == YGAlignBaseline) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static inline float YGNodeDimWithMargin(const YGNodeRef node,
|
static inline float YGNodeDimWithMargin(const YGNodeRef node,
|
||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
const float widthSize) {
|
const float widthSize) {
|
||||||
@@ -1558,8 +1624,6 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(const YGNodeRef node,
|
|||||||
// * Margins cannot be specified as 'auto'. They must be specified in terms of
|
// * Margins cannot be specified as 'auto'. They must be specified in terms of
|
||||||
// pixel
|
// pixel
|
||||||
// values, and the default value is 0.
|
// values, and the default value is 0.
|
||||||
// * The 'baseline' value is not supported for alignItems and alignSelf
|
|
||||||
// properties.
|
|
||||||
// * Values of width, maxWidth, minWidth, height, maxHeight and minHeight must
|
// * Values of width, maxWidth, minWidth, height, maxHeight and minHeight must
|
||||||
// be
|
// be
|
||||||
// specified as pixel values, not as percentages.
|
// specified as pixel values, not as percentages.
|
||||||
@@ -2422,7 +2486,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// STEP 8: MULTI-LINE CONTENT ALIGNMENT
|
// STEP 8: MULTI-LINE CONTENT ALIGNMENT
|
||||||
if (lineCount > 1 && performLayout && !YGFloatIsUndefined(availableInnerCrossDim)) {
|
if (performLayout && (lineCount > 1 || YGIsBaselineLayout(node)) &&
|
||||||
|
!YGFloatIsUndefined(availableInnerCrossDim)) {
|
||||||
const float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim;
|
const float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim;
|
||||||
|
|
||||||
float crossDimLead = 0;
|
float crossDimLead = 0;
|
||||||
@@ -2442,6 +2507,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
break;
|
break;
|
||||||
case YGAlignAuto:
|
case YGAlignAuto:
|
||||||
case YGAlignFlexStart:
|
case YGAlignFlexStart:
|
||||||
|
case YGAlignBaseline:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2452,6 +2518,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
|
|
||||||
// compute the line's height and find the endIndex
|
// compute the line's height and find the endIndex
|
||||||
float lineHeight = 0;
|
float lineHeight = 0;
|
||||||
|
float maxAscentForCurrentLine = 0;
|
||||||
|
float maxDescentForCurrentLine = 0;
|
||||||
for (ii = startIndex; ii < childCount; ii++) {
|
for (ii = startIndex; ii < childCount; ii++) {
|
||||||
const YGNodeRef child = YGNodeListGet(node->children, ii);
|
const YGNodeRef child = YGNodeListGet(node->children, ii);
|
||||||
|
|
||||||
@@ -2459,12 +2527,21 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
if (child->lineIndex != i) {
|
if (child->lineIndex != i) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (YGNodeIsLayoutDimDefined(child, crossAxis)) {
|
if (YGNodeIsLayoutDimDefined(child, crossAxis)) {
|
||||||
lineHeight = fmaxf(lineHeight,
|
lineHeight = fmaxf(lineHeight,
|
||||||
child->layout.measuredDimensions[dim[crossAxis]] +
|
child->layout.measuredDimensions[dim[crossAxis]] +
|
||||||
YGNodeMarginForAxis(child, crossAxis, availableInnerWidth));
|
YGNodeMarginForAxis(child, crossAxis, availableInnerWidth));
|
||||||
}
|
}
|
||||||
|
if (YGNodeAlignItem(node, child) == YGAlignBaseline) {
|
||||||
|
const float ascent =
|
||||||
|
YGBaseline(child) + YGNodeLeadingMargin(child, YGFlexDirectionColumn, availableInnerWidth);
|
||||||
|
const float descent = child->layout.measuredDimensions[YGDimensionHeight] +
|
||||||
|
YGNodeMarginForAxis(child, YGFlexDirectionColumn, availableInnerWidth) -
|
||||||
|
ascent;
|
||||||
|
maxAscentForCurrentLine = fmaxf(maxAscentForCurrentLine, ascent);
|
||||||
|
maxDescentForCurrentLine = fmaxf(maxDescentForCurrentLine, descent);
|
||||||
|
lineHeight = fmaxf(lineHeight, maxAscentForCurrentLine + maxDescentForCurrentLine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
endIndex = ii;
|
endIndex = ii;
|
||||||
@@ -2501,6 +2578,12 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
// (auto) crossAxis dimension.
|
// (auto) crossAxis dimension.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case YGAlignBaseline: {
|
||||||
|
child->layout.position[YGEdgeTop] =
|
||||||
|
currentLead + maxAscentForCurrentLine - YGBaseline(child) +
|
||||||
|
YGNodeLeadingPosition(child, YGFlexDirectionColumn, availableInnerCrossDim);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case YGAlignAuto:
|
case YGAlignAuto:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -49,6 +49,7 @@ typedef YGSize (*YGMeasureFunc)(YGNodeRef node,
|
|||||||
YGMeasureMode widthMode,
|
YGMeasureMode widthMode,
|
||||||
![]() nit: remove added empty lines nit: remove added empty lines
![]() nit: remove added empty line nit: remove added empty line
|
|||||||
float height,
|
float height,
|
||||||
YGMeasureMode heightMode);
|
YGMeasureMode heightMode);
|
||||||
|
typedef float (*YGBaselineFunc)(YGNodeRef node);
|
||||||
typedef void (*YGPrintFunc)(YGNodeRef node);
|
typedef void (*YGPrintFunc)(YGNodeRef node);
|
||||||
typedef int (*YGLogger)(YGLogLevel level, const char *format, va_list args);
|
typedef int (*YGLogger)(YGLogLevel level, const char *format, va_list args);
|
||||||
|
|
||||||
@@ -138,6 +139,7 @@ WIN_EXPORT void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode
|
|||||||
|
|
||||||
YG_NODE_PROPERTY(void *, Context, context);
|
YG_NODE_PROPERTY(void *, Context, context);
|
||||||
YG_NODE_PROPERTY(YGMeasureFunc, MeasureFunc, measureFunc);
|
YG_NODE_PROPERTY(YGMeasureFunc, MeasureFunc, measureFunc);
|
||||||
|
YG_NODE_PROPERTY(YGBaselineFunc, BaselineFunc, baselineFunc)
|
||||||
YG_NODE_PROPERTY(YGPrintFunc, PrintFunc, printFunc);
|
YG_NODE_PROPERTY(YGPrintFunc, PrintFunc, printFunc);
|
||||||
YG_NODE_PROPERTY(bool, HasNewLayout, hasNewLayout);
|
YG_NODE_PROPERTY(bool, HasNewLayout, hasNewLayout);
|
||||||
|
|
||||||
|
node->baseline = baselineFunc;
is enough