From 42e4e16b4739165b01d31eda94395e00d70b052b Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Sun, 18 Mar 2018 22:00:14 -0700 Subject: [PATCH] Fix clipping in FittedBox (#15418) Fixes https://github.com/flutter/flutter/issues/15410 --- .../flutter/lib/src/rendering/proxy_box.dart | 2 +- .../flutter/test/widgets/fitted_box_test.dart | 113 ++++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart index 6deff8993a8..6f04fde5aae 100644 --- a/packages/flutter/lib/src/rendering/proxy_box.dart +++ b/packages/flutter/lib/src/rendering/proxy_box.dart @@ -2187,7 +2187,7 @@ class RenderFittedBox extends RenderProxyBox { final double scaleY = sizes.destination.height / sizes.source.height; final Rect sourceRect = _resolvedAlignment.inscribe(sizes.source, Offset.zero & childSize); final Rect destinationRect = _resolvedAlignment.inscribe(sizes.destination, Offset.zero & size); - _hasVisualOverflow = sourceRect.width < childSize.width || sourceRect.height < childSize.width; + _hasVisualOverflow = sourceRect.width < childSize.width || sourceRect.height < childSize.height; _transform = new Matrix4.translationValues(destinationRect.left, destinationRect.top, 0.0) ..scale(scaleX, scaleY, 1.0) ..translate(-sourceRect.left, -sourceRect.top); diff --git a/packages/flutter/test/widgets/fitted_box_test.dart b/packages/flutter/test/widgets/fitted_box_test.dart index 23182874e3d..f53d383f6d0 100644 --- a/packages/flutter/test/widgets/fitted_box_test.dart +++ b/packages/flutter/test/widgets/fitted_box_test.dart @@ -338,4 +338,117 @@ void main() { expect(insideBottomRight, equals(outsideBottomRight)); } }); + + testWidgets('FittedBox layers - contain', (WidgetTester tester) async { + await tester.pumpWidget( + const Center( + child: const SizedBox( + width: 100.0, + height: 10.0, + child: const FittedBox( + fit: BoxFit.contain, + child: const SizedBox( + width: 50.0, + height: 50.0, + child: const RepaintBoundary( + child: const Placeholder(), + ), + ), + ), + ), + ), + ); + expect(getLayers(), [TransformLayer, TransformLayer, OffsetLayer]); + }); + + testWidgets('FittedBox layers - cover - horizontal', (WidgetTester tester) async { + await tester.pumpWidget( + const Center( + child: const SizedBox( + width: 100.0, + height: 10.0, + child: const FittedBox( + fit: BoxFit.cover, + child: const SizedBox( + width: 10.0, + height: 50.0, + child: const RepaintBoundary( + child: const Placeholder(), + ), + ), + ), + ), + ), + ); + expect(getLayers(), [TransformLayer, ClipRectLayer, TransformLayer, OffsetLayer]); + }); + + testWidgets('FittedBox layers - cover - vertical', (WidgetTester tester) async { + await tester.pumpWidget( + const Center( + child: const SizedBox( + width: 10.0, + height: 100.0, + child: const FittedBox( + fit: BoxFit.cover, + child: const SizedBox( + width: 50.0, + height: 10.0, + child: const RepaintBoundary( + child: const Placeholder(), + ), + ), + ), + ), + ), + ); + expect(getLayers(), [TransformLayer, ClipRectLayer, TransformLayer, OffsetLayer]); + }); + + testWidgets('FittedBox layers - none - clip', (WidgetTester tester) async { + final List values = [10.0, 50.0, 100.0]; + for (double a in values) { + for (double b in values) { + for (double c in values) { + for (double d in values) { + await tester.pumpWidget( + new Center( + child: new SizedBox( + width: a, + height: b, + child: new FittedBox( + fit: BoxFit.none, + child: new SizedBox( + width: c, + height: d, + child: const RepaintBoundary( + child: const Placeholder(), + ), + ), + ), + ), + ), + ); + if (a < c || b < d) { + expect(getLayers(), [TransformLayer, ClipRectLayer, OffsetLayer]); + } else { + expect(getLayers(), [TransformLayer, OffsetLayer]); + } + } + } + } + } + }); +} + +List getLayers() { + final List layers = []; + Layer layer = RendererBinding.instance.renderView.debugLayer; + while (layer is ContainerLayer) { + final ContainerLayer container = layer; + layers.add(container.runtimeType); + expect(container.firstChild, same(container.lastChild)); + layer = container.firstChild; + } + return layers; }