Chromium Code Reviews| Index: sky/sdk/lib/framework/rendering/paragraph.dart |
| diff --git a/sky/sdk/lib/framework/rendering/paragraph.dart b/sky/sdk/lib/framework/rendering/paragraph.dart |
| index 58ad8915d459db8709859e852a9cc37d835bd2d0..6d04c4c0d52dd0a37df884099bd95a5d3bc2f767 100644 |
| --- a/sky/sdk/lib/framework/rendering/paragraph.dart |
| +++ b/sky/sdk/lib/framework/rendering/paragraph.dart |
| @@ -12,6 +12,17 @@ class RenderInline extends RenderObject { |
| RenderInline(this.data); |
| } |
| +// Unfortunately, using full precision floating point here causes bad layouts |
| +// because floating point math isn't associative. If we add and subtract |
| +// padding, for example, we'll get different values when we estimate sizes and |
| +// when we actually compute layout because the operations will end up associated |
| +// differently. To work around this problem for now, we round fractional pixel |
| +// values up to the nearest whole pixel value. The right long-term fix is to do |
| +// layout using fixed precision arithmetic. |
| +double _applyFloatingPointHack(double layoutValue) { |
| + return layoutValue.ceilToDouble(); |
| +} |
| + |
| class RenderParagraph extends RenderBox { |
| RenderParagraph({ |
| @@ -40,39 +51,46 @@ class RenderParagraph extends RenderBox { |
| } |
| } |
| - // We don't currently support this for RenderParagraph |
| + sky.Element _layout(BoxConstraints constraints) { |
| + _layoutRoot.maxWidth = constraints.maxWidth; |
| + _layoutRoot.minWidth = constraints.minWidth; |
| + _layoutRoot.minHeight = constraints.minHeight; |
| + _layoutRoot.maxHeight = constraints.maxHeight; |
| + _layoutRoot.layout(); |
| + } |
| + |
| double getMinIntrinsicWidth(BoxConstraints constraints) { |
| - assert(false); |
| - return constraints.constrainWidth(0.0); |
| + _layout(constraints); |
|
Hixie
2015/06/08 23:00:36
Isn't this destructive?
What if someone calls get
|
| + return constraints.constrainWidth( |
| + _applyFloatingPointHack(_layoutRoot.rootElement.minContentWidth)); |
| } |
| - // We don't currently support this for RenderParagraph |
| double getMaxIntrinsicWidth(BoxConstraints constraints) { |
| - assert(false); |
| - return constraints.constrainWidth(0.0); |
| + _layout(constraints); |
| + return constraints.constrainWidth( |
| + _applyFloatingPointHack(_layoutRoot.rootElement.maxContentWidth)); |
| + } |
| + |
| + double _getIntrinsicHeight(BoxConstraints constraints) { |
| + _layout(constraints); |
| + return constraints.constrainHeight( |
| + _applyFloatingPointHack(_layoutRoot.rootElement.height.ceilToDouble)); |
| } |
| - // We don't currently support this for RenderParagraph |
| double getMinIntrinsicHeight(BoxConstraints constraints) { |
| - assert(false); |
| - return constraints.constrainHeight(0.0); |
| + return _getIntrinsicHeight(constraints); |
| } |
| - // We don't currently support this for RenderParagraph |
| double getMaxIntrinsicHeight(BoxConstraints constraints) { |
| - assert(false); |
| - return constraints.constrainHeight(0.0); |
| + return _getIntrinsicHeight(constraints); |
| } |
| void performLayout() { |
| - _layoutRoot.maxWidth = constraints.maxWidth; |
| - _layoutRoot.minWidth = constraints.minWidth; |
| - _layoutRoot.minHeight = constraints.minHeight; |
| - _layoutRoot.maxHeight = constraints.maxHeight; |
| - _layoutRoot.layout(); |
| - // rootElement.width always expands to fill, use maxContentWidth instead. |
| + _layout(constraints); |
| sky.Element root = _layoutRoot.rootElement; |
| - size = constraints.constrain(new Size(root.maxContentWidth, root.height)); |
| + // rootElement.width always expands to fill, use maxContentWidth instead. |
| + size = constraints.constrain(new Size(_applyFloatingPointHack(root.maxContentWidth), |
| + _applyFloatingPointHack(root.height.ceilToDouble))); |
| } |
| void paint(RenderObjectDisplayList canvas) { |