Index: sky/sdk/lib/rendering/box.dart |
diff --git a/sky/sdk/lib/rendering/box.dart b/sky/sdk/lib/rendering/box.dart |
index 36d700aee1fdbfdd35f625c4cb84e58403955d24..0d0b624c4e88f8fb9830994ff4d19c44638b0e7f 100644 |
--- a/sky/sdk/lib/rendering/box.dart |
+++ b/sky/sdk/lib/rendering/box.dart |
@@ -225,6 +225,8 @@ class BoxParentData extends ParentData { |
String toString() => 'position=$position'; |
} |
+enum TextBaseline { alphabetic, ideographic } |
+ |
abstract class RenderBox extends RenderObject { |
void setParentData(RenderObject child) { |
@@ -259,6 +261,31 @@ abstract class RenderBox extends RenderObject { |
return constraints.constrainHeight(0.0); |
} |
+ // getDistanceToBaseline() should return the distance from the |
+ // y-coordinate of the position of the box to the y-coordinate of |
+ // the first given baseline in the box's contents. This is used by |
+ // certain layout models to align adjacent boxes on a common |
+ // baseline, regardless of padding, font size differences, etc. If |
+ // there is no baseline, then it should return the distance from the |
+ // y-coordinate of the position of the box to the y-coordinate of |
+ // the bottom of the box, i.e., the height of the box. |
+ // Only call this after layout has been performed. |
+ double getDistanceToBaseline(TextBaseline baseline) { |
+ assert(!needsLayout); |
+ double result = getDistanceToActualBaseline(baseline); |
+ if (result == null) |
+ return size.height; |
+ return result; |
+ } |
+ // getDistanceToActualBaseline() should return the distance from the |
+ // y-coordinate of the position of the box to the y-coordinate of |
+ // the first given baseline in the box's contents, if any, or null |
+ // otherwise. |
+ double getDistanceToActualBaseline(TextBaseline baseline) { |
+ assert(!needsLayout); |
+ return null; |
+ } |
+ |
// This whole block should only be here in debug builds |
bool _debugDoingThisLayout = false; |
bool _debugCanParentUseSize; |
@@ -348,6 +375,12 @@ class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox |
return super.getMaxIntrinsicHeight(constraints); |
} |
+ double getDistanceToActualBaseline(TextBaseline baseline) { |
+ if (child != null) |
+ return child.getDistanceToActualBaseline(baseline); |
+ return super.getDistanceToActualBaseline(baseline); |
+ } |
+ |
void performLayout() { |
if (child != null) { |
child.layout(constraints, parentUsesSize: true); |
@@ -585,6 +618,20 @@ abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi |
canvas.paintChild(child, child.parentData.position); |
} |
+ double getDistanceToActualBaseline(TextBaseline baseline) { |
+ double result; |
+ if (child != null) { |
+ assert(!needsLayout); |
+ result = child.getDistanceToActualBaseline(baseline); |
+ assert(child.parentData is BoxParentData); |
+ if (result != null) |
+ result += child.parentData.position.y; |
+ } else { |
+ result = super.getDistanceToActualBaseline(baseline); |
+ } |
+ return result; |
+ } |
+ |
void hitTestChildren(HitTestResult result, { Point position }) { |
if (child != null) { |
assert(child.parentData is BoxParentData); |
@@ -1089,6 +1136,38 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox> |
// DEFAULT BEHAVIORS FOR RENDERBOX CONTAINERS |
abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, ParentDataType extends ContainerParentDataMixin<ChildType>> implements ContainerRenderObjectMixin<ChildType, ParentDataType> { |
+ double defaultGetDistanceToFirstActualBaseline(TextBaseline baseline) { |
+ assert(!needsLayout); |
+ RenderBox child = firstChild; |
+ while (child != null) { |
+ assert(child.parentData is ParentDataType); |
+ double result = child.getDistanceToActualBaseline(baseline); |
+ if (result != null) |
+ return result + child.parentData.position.y; |
+ child = child.parentData.nextSibling; |
+ } |
+ return null; |
+ } |
+ |
+ double defaultGetDistanceToHighestActualBaseline(TextBaseline baseline) { |
+ assert(!needsLayout); |
+ double result; |
+ RenderBox child = firstChild; |
+ while (child != null) { |
+ assert(child.parentData is ParentDataType); |
+ double candidate = child.getDistanceToActualBaseline(baseline); |
+ if (candidate != null) { |
+ candidate += child.parentData.position.x; |
+ if (result != null) |
+ result = math.min(result, candidate); |
+ else |
+ result = candidate; |
+ } |
+ child = child.parentData.nextSibling; |
+ } |
+ return result; |
+ } |
+ |
void defaultHitTestChildren(HitTestResult result, { Point position }) { |
// the x, y parameters have the top left of the node's box as the origin |
ChildType child = lastChild; |