Handle negative and zero sizes. (#11827)
This commit is contained in:
parent
4faa036736
commit
aaa9d18024
@ -125,6 +125,9 @@ class FittedSizes {
|
|||||||
/// * [DecoratedBox], [BoxDecoration], and [DecorationImage], which together
|
/// * [DecoratedBox], [BoxDecoration], and [DecorationImage], which together
|
||||||
/// provide access to [paintImage] at the widgets layer.
|
/// provide access to [paintImage] at the widgets layer.
|
||||||
FittedSizes applyBoxFit(BoxFit fit, Size inputSize, Size outputSize) {
|
FittedSizes applyBoxFit(BoxFit fit, Size inputSize, Size outputSize) {
|
||||||
|
if (inputSize.height <= 0.0 || inputSize.width <= 0.0 || outputSize.height <= 0.0 || outputSize.width <= 0.0)
|
||||||
|
return const FittedSizes(Size.zero, Size.zero);
|
||||||
|
|
||||||
Size sourceSize, destinationSize;
|
Size sourceSize, destinationSize;
|
||||||
switch (fit) {
|
switch (fit) {
|
||||||
case BoxFit.fill:
|
case BoxFit.fill:
|
||||||
|
@ -1212,7 +1212,7 @@ Iterable<Rect> _generateImageTileRects(Rect outputRect, Rect fundamentalRect, Im
|
|||||||
/// * `canvas`: The canvas onto which the image will be painted.
|
/// * `canvas`: The canvas onto which the image will be painted.
|
||||||
/// * `rect`: The region of the canvas into which the image will be painted.
|
/// * `rect`: The region of the canvas into which the image will be painted.
|
||||||
/// The image might not fill the entire rectangle (e.g., depending on the
|
/// The image might not fill the entire rectangle (e.g., depending on the
|
||||||
/// `fit`).
|
/// `fit`). If `rect` is empty, nothing is painted.
|
||||||
/// * `image`: The image to paint onto the canvas.
|
/// * `image`: The image to paint onto the canvas.
|
||||||
/// * `colorFilter`: If non-null, the color filter to apply when painting the
|
/// * `colorFilter`: If non-null, the color filter to apply when painting the
|
||||||
/// image.
|
/// image.
|
||||||
@ -1251,6 +1251,8 @@ void paintImage({
|
|||||||
}) {
|
}) {
|
||||||
assert(canvas != null);
|
assert(canvas != null);
|
||||||
assert(image != null);
|
assert(image != null);
|
||||||
|
if (rect.isEmpty)
|
||||||
|
return;
|
||||||
Size outputSize = rect.size;
|
Size outputSize = rect.size;
|
||||||
Size inputSize = new Size(image.width.toDouble(), image.height.toDouble());
|
Size inputSize = new Size(image.width.toDouble(), image.height.toDouble());
|
||||||
Offset sliceBorder;
|
Offset sliceBorder;
|
||||||
|
@ -375,6 +375,8 @@ class _FlutterLogoPainter extends BoxPainter {
|
|||||||
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
|
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
|
||||||
offset += _config.margin.topLeft;
|
offset += _config.margin.topLeft;
|
||||||
final Size canvasSize = _config.margin.deflateSize(configuration.size);
|
final Size canvasSize = _config.margin.deflateSize(configuration.size);
|
||||||
|
if (canvasSize.isEmpty)
|
||||||
|
return;
|
||||||
Size logoSize;
|
Size logoSize;
|
||||||
if (_config._position > 0.0) {
|
if (_config._position > 0.0) {
|
||||||
// horizontal style
|
// horizontal style
|
||||||
|
@ -1860,6 +1860,8 @@ class RenderFittedBox extends RenderProxyBox {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool hitTest(HitTestResult result, { Offset position }) {
|
bool hitTest(HitTestResult result, { Offset position }) {
|
||||||
|
if (size.isEmpty)
|
||||||
|
return false;
|
||||||
_updatePaintData();
|
_updatePaintData();
|
||||||
Matrix4 inverse;
|
Matrix4 inverse;
|
||||||
try {
|
try {
|
||||||
@ -1875,8 +1877,12 @@ class RenderFittedBox extends RenderProxyBox {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void applyPaintTransform(RenderBox child, Matrix4 transform) {
|
void applyPaintTransform(RenderBox child, Matrix4 transform) {
|
||||||
_updatePaintData();
|
if (size.isEmpty) {
|
||||||
transform.multiply(_transform);
|
transform.setZero();
|
||||||
|
} else {
|
||||||
|
_updatePaintData();
|
||||||
|
transform.multiply(_transform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -25,5 +25,49 @@ void main() {
|
|||||||
result = applyBoxFit(BoxFit.fitHeight, const Size(400.0, 2000.0), const Size(100.0, 1000.0));
|
result = applyBoxFit(BoxFit.fitHeight, const Size(400.0, 2000.0), const Size(100.0, 1000.0));
|
||||||
expect(result.source, equals(const Size(200.0, 2000.0)));
|
expect(result.source, equals(const Size(200.0, 2000.0)));
|
||||||
expect(result.destination, equals(const Size(100.0, 1000.0)));
|
expect(result.destination, equals(const Size(100.0, 1000.0)));
|
||||||
|
|
||||||
|
_testZeroAndNegativeSizes(BoxFit.fill);
|
||||||
|
_testZeroAndNegativeSizes(BoxFit.contain);
|
||||||
|
_testZeroAndNegativeSizes(BoxFit.cover);
|
||||||
|
_testZeroAndNegativeSizes(BoxFit.fitWidth);
|
||||||
|
_testZeroAndNegativeSizes(BoxFit.fitHeight);
|
||||||
|
_testZeroAndNegativeSizes(BoxFit.none);
|
||||||
|
_testZeroAndNegativeSizes(BoxFit.scaleDown);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _testZeroAndNegativeSizes(BoxFit fit) {
|
||||||
|
FittedSizes result;
|
||||||
|
|
||||||
|
result = applyBoxFit(fit, const Size(-400.0, 2000.0), const Size(100.0, 1000.0));
|
||||||
|
expect(result.source, equals(Size.zero));
|
||||||
|
expect(result.destination, equals(Size.zero));
|
||||||
|
|
||||||
|
result = applyBoxFit(fit, const Size(400.0, -2000.0), const Size(100.0, 1000.0));
|
||||||
|
expect(result.source, equals(Size.zero));
|
||||||
|
expect(result.destination, equals(Size.zero));
|
||||||
|
|
||||||
|
result = applyBoxFit(fit, const Size(400.0, 2000.0), const Size(-100.0, 1000.0));
|
||||||
|
expect(result.source, equals(Size.zero));
|
||||||
|
expect(result.destination, equals(Size.zero));
|
||||||
|
|
||||||
|
result = applyBoxFit(fit, const Size(400.0, 2000.0), const Size(100.0, -1000.0));
|
||||||
|
expect(result.source, equals(Size.zero));
|
||||||
|
expect(result.destination, equals(Size.zero));
|
||||||
|
|
||||||
|
result = applyBoxFit(fit, const Size(0.0, 2000.0), const Size(100.0, 1000.0));
|
||||||
|
expect(result.source, equals(Size.zero));
|
||||||
|
expect(result.destination, equals(Size.zero));
|
||||||
|
|
||||||
|
result = applyBoxFit(fit, const Size(400.0, 0.0), const Size(100.0, 1000.0));
|
||||||
|
expect(result.source, equals(Size.zero));
|
||||||
|
expect(result.destination, equals(Size.zero));
|
||||||
|
|
||||||
|
result = applyBoxFit(fit, const Size(400.0, 2000.0), const Size(0.0, 1000.0));
|
||||||
|
expect(result.source, equals(Size.zero));
|
||||||
|
expect(result.destination, equals(Size.zero));
|
||||||
|
|
||||||
|
result = applyBoxFit(fit, const Size(400.0, 2000.0), const Size(100.0, 0.0));
|
||||||
|
expect(result.source, equals(Size.zero));
|
||||||
|
expect(result.destination, equals(Size.zero));
|
||||||
|
}
|
||||||
|
@ -213,14 +213,14 @@ void main() {
|
|||||||
final BoxDecoration boxDecoration = new BoxDecoration(image: backgroundImage);
|
final BoxDecoration boxDecoration = new BoxDecoration(image: backgroundImage);
|
||||||
final BoxPainter boxPainter = boxDecoration.createBoxPainter(() { assert(false); });
|
final BoxPainter boxPainter = boxDecoration.createBoxPainter(() { assert(false); });
|
||||||
final TestCanvas canvas = new TestCanvas(<Invocation>[]);
|
final TestCanvas canvas = new TestCanvas(<Invocation>[]);
|
||||||
boxPainter.paint(canvas, Offset.zero, const ImageConfiguration(size: const Size(10.0, 10.0)));
|
boxPainter.paint(canvas, Offset.zero, const ImageConfiguration(size: const Size(100.0, 100.0)));
|
||||||
|
|
||||||
final Invocation call = canvas.invocations.singleWhere((Invocation call) => call.memberName == #drawImageNine);
|
final Invocation call = canvas.invocations.singleWhere((Invocation call) => call.memberName == #drawImageNine);
|
||||||
expect(call.isMethod, isTrue);
|
expect(call.isMethod, isTrue);
|
||||||
expect(call.positionalArguments, hasLength(4));
|
expect(call.positionalArguments, hasLength(4));
|
||||||
expect(call.positionalArguments[0], const isInstanceOf<TestImage>());
|
expect(call.positionalArguments[0], const isInstanceOf<TestImage>());
|
||||||
expect(call.positionalArguments[1], new Rect.fromLTRB(10.0, 20.0, 40.0, 60.0));
|
expect(call.positionalArguments[1], new Rect.fromLTRB(10.0, 20.0, 40.0, 60.0));
|
||||||
expect(call.positionalArguments[2], new Rect.fromLTRB(0.0, 0.0, 32.5, 10.0));
|
expect(call.positionalArguments[2], new Rect.fromLTRB(0.0, 0.0, 100.0, 100.0));
|
||||||
expect(call.positionalArguments[3], const isInstanceOf<Paint>());
|
expect(call.positionalArguments[3], const isInstanceOf<Paint>());
|
||||||
expect(call.positionalArguments[3].isAntiAlias, false);
|
expect(call.positionalArguments[3].isAntiAlias, false);
|
||||||
expect(call.positionalArguments[3].colorFilter, colorFilter);
|
expect(call.positionalArguments[3].colorFilter, colorFilter);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user