Commit 5245d388 authored by Ian Hickson's avatar Ian Hickson

Clean up the way RenderIntrinsicWidth works (#4340)

The old code had gotten crufty with all the refactors. This simplifies
it down to what it really means.

Also, add a bunch of tests.
parent d8283d1c
...@@ -530,20 +530,12 @@ class RenderIntrinsicWidth extends RenderProxyBox { ...@@ -530,20 +530,12 @@ class RenderIntrinsicWidth extends RenderProxyBox {
} }
static double _applyStep(double input, double step) { static double _applyStep(double input, double step) {
assert(input.isFinite);
if (step == null) if (step == null)
return input; return input;
return (input / step).ceil() * step; return (input / step).ceil() * step;
} }
BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
assert(child != null);
if (constraints.hasTightWidth)
return constraints;
final double width = child.getMaxIntrinsicWidth(constraints.maxHeight);
assert(width == constraints.constrainWidth(width));
return constraints.tighten(width: _applyStep(width, _stepWidth));
}
@override @override
double getMinIntrinsicWidth(double height) { double getMinIntrinsicWidth(double height) {
return getMaxIntrinsicWidth(height); return getMaxIntrinsicWidth(height);
...@@ -553,36 +545,46 @@ class RenderIntrinsicWidth extends RenderProxyBox { ...@@ -553,36 +545,46 @@ class RenderIntrinsicWidth extends RenderProxyBox {
double getMaxIntrinsicWidth(double height) { double getMaxIntrinsicWidth(double height) {
if (child == null) if (child == null)
return 0.0; return 0.0;
double childResult = child.getMaxIntrinsicWidth(height); final double width = child.getMaxIntrinsicWidth(height);
assert(childResult.isFinite); return _applyStep(width, _stepWidth);
return _applyStep(childResult, _stepWidth);
} }
@override @override
double getMinIntrinsicHeight(double width) { double getMinIntrinsicHeight(double width) {
if (child == null) if (child == null)
return 0.0; return 0.0;
double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(new BoxConstraints.tightForFinite(width: width)).maxWidth); if (!width.isFinite)
assert(childResult.isFinite); width = getMaxIntrinsicWidth(double.INFINITY);
return _applyStep(childResult, _stepHeight); assert(width.isFinite);
final double height = child.getMinIntrinsicHeight(width);
return _applyStep(height, _stepHeight);
} }
@override @override
double getMaxIntrinsicHeight(double width) { double getMaxIntrinsicHeight(double width) {
if (child == null) if (child == null)
return 0.0; return 0.0;
double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(new BoxConstraints.tightForFinite(width: width)).maxWidth); if (!width.isFinite)
assert(childResult.isFinite); width = getMaxIntrinsicWidth(double.INFINITY);
return _applyStep(childResult, _stepHeight); assert(width.isFinite);
final double height = child.getMaxIntrinsicHeight(width);
return _applyStep(height, _stepHeight);
} }
@override @override
void performLayout() { void performLayout() {
if (child != null) { if (child != null) {
BoxConstraints childConstraints = _getInnerConstraints(constraints); BoxConstraints childConstraints = constraints;
assert(childConstraints.hasTightWidth); if (!childConstraints.hasTightWidth) {
if (_stepHeight != null) final double width = child.getMaxIntrinsicWidth(childConstraints.maxHeight);
childConstraints.tighten(height: getMaxIntrinsicHeight(childConstraints.maxWidth)); assert(width.isFinite);
childConstraints = childConstraints.tighten(width: _applyStep(width, _stepWidth));
}
if (_stepHeight != null) {
final double height = child.getMaxIntrinsicHeight(childConstraints.maxWidth);
assert(height.isFinite);
childConstraints = childConstraints.tighten(height: _applyStep(height, _stepHeight));
}
child.layout(childConstraints, parentUsesSize: true); child.layout(childConstraints, parentUsesSize: true);
size = child.size; size = child.size;
} else { } else {
...@@ -611,27 +613,24 @@ class RenderIntrinsicHeight extends RenderProxyBox { ...@@ -611,27 +613,24 @@ class RenderIntrinsicHeight extends RenderProxyBox {
RenderBox child RenderBox child
}) : super(child); }) : super(child);
BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
assert(child != null);
if (constraints.hasTightHeight)
return constraints;
final double height = child.getMaxIntrinsicHeight(constraints.maxWidth);
assert(height == constraints.constrainHeight(height));
return constraints.tighten(height: height);
}
@override @override
double getMinIntrinsicWidth(double height) { double getMinIntrinsicWidth(double height) {
if (child == null) if (child == null)
return 0.0; return 0.0;
return child.getMinIntrinsicWidth(_getInnerConstraints(new BoxConstraints.tightForFinite(height: height)).maxHeight); if (!height.isFinite)
height = child.getMaxIntrinsicHeight(double.INFINITY);
assert(height.isFinite);
return child.getMinIntrinsicWidth(height);
} }
@override @override
double getMaxIntrinsicWidth(double height) { double getMaxIntrinsicWidth(double height) {
if (child == null) if (child == null)
return 0.0; return 0.0;
return child.getMaxIntrinsicWidth(_getInnerConstraints(new BoxConstraints.tightForFinite(height: height)).maxHeight); if (!height.isFinite)
height = child.getMaxIntrinsicHeight(double.INFINITY);
assert(height.isFinite);
return child.getMaxIntrinsicWidth(height);
} }
@override @override
...@@ -642,7 +641,13 @@ class RenderIntrinsicHeight extends RenderProxyBox { ...@@ -642,7 +641,13 @@ class RenderIntrinsicHeight extends RenderProxyBox {
@override @override
void performLayout() { void performLayout() {
if (child != null) { if (child != null) {
child.layout(_getInnerConstraints(constraints), parentUsesSize: true); BoxConstraints childConstraints = constraints;
if (!childConstraints.hasTightHeight) {
final double height = child.getMaxIntrinsicHeight(childConstraints.maxWidth);
assert(height.isFinite);
childConstraints = childConstraints.tighten(height: height);
}
child.layout(childConstraints, parentUsesSize: true);
size = child.size; size = child.size;
} else { } else {
performResize(); performResize();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment