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.
This commit is contained in:
parent
39ca4fa1ce
commit
b7421fcbf1
@ -1395,50 +1395,54 @@ 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;
|
//
|
||||||
|
// - 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.
|
||||||
|
|
||||||
|
double width = _image == null ? 0.0 : _image.width.toDouble();
|
||||||
|
double height = _image == null ? 0.0 : _image.height.toDouble();
|
||||||
|
double aspectRatio = width / height;
|
||||||
|
|
||||||
|
if (width > constraints.maxWidth) {
|
||||||
|
width = constraints.maxWidth;
|
||||||
|
height = width / aspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height > constraints.maxHeight) {
|
||||||
|
height = constraints.maxHeight;
|
||||||
|
width = height * aspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width < constraints.minWidth) {
|
||||||
|
width = constraints.minWidth;
|
||||||
|
height = width / aspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height < constraints.minHeight) {
|
||||||
|
height = constraints.minHeight;
|
||||||
|
width = height * aspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(width != null && height != null);
|
||||||
return constraints.constrain(new Size(width, height));
|
return constraints.constrain(new Size(width, height));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If neither height nor width are specified, use inherent image
|
|
||||||
// dimensions. If only one dimension is specified, adjust the
|
|
||||||
// other dimension to maintain the aspect ratio. In both cases,
|
|
||||||
// constrain dimensions first, otherwise we end up losing the
|
|
||||||
// ratio after constraining.
|
|
||||||
if (_width == null) {
|
|
||||||
if (_height == null) {
|
|
||||||
// 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine width from height
|
|
||||||
double width = _height * _image.width / _image.height;
|
|
||||||
return constraints.constrain(new Size(width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_height == null) {
|
|
||||||
// Determine height from width
|
|
||||||
double height = _width * _image.height / _image.width;
|
|
||||||
return constraints.constrain(new Size(width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(_width != null && _height != null);
|
|
||||||
return constraints.constrain(new Size(_width, _height));
|
|
||||||
}
|
|
||||||
|
|
||||||
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||||
if (_width == null && _height == null)
|
if (_width == null && _height == null)
|
||||||
return constraints.constrainWidth(0.0);
|
return constraints.constrainWidth(0.0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user