Commit b7421fcb authored by Adam Barth's avatar Adam Barth

Improve RenderImage constraint solving

We now fold the width and height properties into the constraints and try to
find a size for the image that perserves the image's intrinsict aspect ratio
while fitting within the given constraints.
parent 39ca4fa1
...@@ -1395,48 +1395,52 @@ class RenderImage extends RenderBox { ...@@ -1395,48 +1395,52 @@ class RenderImage extends RenderBox {
} }
Size _sizeForConstraints(BoxConstraints constraints) { Size _sizeForConstraints(BoxConstraints constraints) {
// Folds the given |width| and |height| into |cosntraints| so they can all
// be treated uniformly.
constraints = new BoxConstraints.tightFor(
width: _width,
height: _height
).apply(constraints);
if (constraints.isTight) if (constraints.isTight)
return constraints.constrain(Size.zero); return constraints.smallest;
// If there's no image, we can't size ourselves automatically // This algorithm attempts to find a size for the RenderImage that fits in
if (_image == null) { // the given constraints and preserves the image's intrinisc aspect ratio.
double width = _width == null ? 0.0 : _width; // Its goals as follow:
double height = _height == null ? 0.0 : _height; //
return constraints.constrain(new Size(width, height)); // - The dimensions of the RenderImage fit within the constraints.
} // - The aspect ratio of the RenderImage matches the instrinsic aspect
// ratio of the image.
// - The RenderImage's dimension are maximal subject to being smaller than
// the intrinsic size of the image.
// If neither height nor width are specified, use inherent image double width = _image == null ? 0.0 : _image.width.toDouble();
// dimensions. If only one dimension is specified, adjust the double height = _image == null ? 0.0 : _image.height.toDouble();
// other dimension to maintain the aspect ratio. In both cases, double aspectRatio = width / height;
// constrain dimensions first, otherwise we end up losing the
// ratio after constraining. if (width > constraints.maxWidth) {
if (_width == null) { width = constraints.maxWidth;
if (_height == null) { height = width / aspectRatio;
// autosize
double width = constraints.constrainWidth(_image.width.toDouble());
double maxHeight = constraints.constrainHeight(_image.height.toDouble());
double ratio = _image.height / _image.width;
double height = width * ratio;
if (height > maxHeight) {
height = maxHeight;
width = maxHeight / ratio;
} }
return constraints.constrain(new Size(width, height));
if (height > constraints.maxHeight) {
height = constraints.maxHeight;
width = height * aspectRatio;
} }
// Determine width from height if (width < constraints.minWidth) {
double width = _height * _image.width / _image.height; width = constraints.minWidth;
return constraints.constrain(new Size(width, height)); height = width / aspectRatio;
} }
if (_height == null) { if (height < constraints.minHeight) {
// Determine height from width height = constraints.minHeight;
double height = _width * _image.height / _image.width; width = height * aspectRatio;
return constraints.constrain(new Size(width, height));
} }
assert(_width != null && _height != null); assert(width != null && height != null);
return constraints.constrain(new Size(_width, _height)); return constraints.constrain(new Size(width, height));
} }
double getMinIntrinsicWidth(BoxConstraints constraints) { double getMinIntrinsicWidth(BoxConstraints constraints) {
......
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