Unverified Commit b2c67e88 authored by Todd Volkert's avatar Todd Volkert Committed by GitHub

Make Layer.toImage() accept bounds rather than size (#17129)

It allows callers to account for things like shadows that paint
outside the bounds of the widget.

https://github.com/flutter/flutter/issues/16859
parent 5972fdb7
...@@ -519,8 +519,9 @@ class OffsetLayer extends ContainerLayer { ...@@ -519,8 +519,9 @@ class OffsetLayer extends ContainerLayer {
/// Capture an image of the current state of this layer and its children. /// Capture an image of the current state of this layer and its children.
/// ///
/// The returned [ui.Image] has uncompressed raw RGBA bytes, in the /// The returned [ui.Image] has uncompressed raw RGBA bytes, will be offset
/// dimensions [logicalSize] multiplied by the [pixelRatio]. /// by the top-left corner of [bounds], and have dimensions equal to the size
/// of [bounds] multiplied by [pixelRatio].
/// ///
/// The [pixelRatio] describes the scale between the logical pixels and the /// The [pixelRatio] describes the scale between the logical pixels and the
/// size of the output image. It is independent of the /// size of the output image. It is independent of the
...@@ -532,11 +533,12 @@ class OffsetLayer extends ContainerLayer { ...@@ -532,11 +533,12 @@ class OffsetLayer extends ContainerLayer {
/// ///
/// * [RenderRepaintBoundary.toImage] for a similar API at the render object level. /// * [RenderRepaintBoundary.toImage] for a similar API at the render object level.
/// * [dart:ui.Scene.toImage] for more information about the image returned. /// * [dart:ui.Scene.toImage] for more information about the image returned.
Future<ui.Image> toImage(Size logicalSize, {double pixelRatio: 1.0}) async { Future<ui.Image> toImage(Rect bounds, {double pixelRatio: 1.0}) async {
assert(bounds != null);
assert(pixelRatio != null); assert(pixelRatio != null);
final ui.SceneBuilder builder = new ui.SceneBuilder(); final ui.SceneBuilder builder = new ui.SceneBuilder();
final Matrix4 transform = new Matrix4.diagonal3Values(pixelRatio, pixelRatio, 1.0); final Matrix4 transform = new Matrix4.translationValues(bounds.left - offset.dx, bounds.top - offset.dy, 0.0);
transform.translate(-offset.dx, -offset.dy, 0.0); transform.scale(pixelRatio, pixelRatio);
builder.pushTransform(transform.storage); builder.pushTransform(transform.storage);
addToScene(builder, Offset.zero); addToScene(builder, Offset.zero);
final ui.Scene scene = builder.build(); final ui.Scene scene = builder.build();
...@@ -544,8 +546,8 @@ class OffsetLayer extends ContainerLayer { ...@@ -544,8 +546,8 @@ class OffsetLayer extends ContainerLayer {
// Size is rounded up to the next pixel to make sure we don't clip off // Size is rounded up to the next pixel to make sure we don't clip off
// anything. // anything.
return await scene.toImage( return await scene.toImage(
(pixelRatio * logicalSize.width).ceil(), (pixelRatio * bounds.width).ceil(),
(pixelRatio * logicalSize.height).ceil(), (pixelRatio * bounds.height).ceil(),
); );
} finally { } finally {
scene.dispose(); scene.dispose();
......
...@@ -2515,7 +2515,7 @@ class RenderRepaintBoundary extends RenderProxyBox { ...@@ -2515,7 +2515,7 @@ class RenderRepaintBoundary extends RenderProxyBox {
/// * [dart:ui.Scene.toImage] for more information about the image returned. /// * [dart:ui.Scene.toImage] for more information about the image returned.
Future<ui.Image> toImage({double pixelRatio: 1.0}) { Future<ui.Image> toImage({double pixelRatio: 1.0}) {
assert(!debugNeedsPaint); assert(!debugNeedsPaint);
return layer.toImage(size, pixelRatio: pixelRatio); return layer.toImage(Offset.zero & size, pixelRatio: pixelRatio);
} }
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'rendering_tester.dart';
void main() {
group('RenderView', () {
test('accounts for device pixel ratio in paintBounds', () {
layout(new RenderAspectRatio(aspectRatio: 1.0));
pumpFrame();
final Size logicalSize = renderer.renderView.configuration.size;
final double devicePixelRatio = renderer.renderView.configuration.devicePixelRatio;
final Size physicalSize = logicalSize * devicePixelRatio;
expect(renderer.renderView.paintBounds, Offset.zero & physicalSize);
});
});
}
...@@ -1235,7 +1235,7 @@ class _MatchesGoldenFile extends AsyncMatcher { ...@@ -1235,7 +1235,7 @@ class _MatchesGoldenFile extends AsyncMatcher {
} }
assert(!renderObject.debugNeedsPaint); assert(!renderObject.debugNeedsPaint);
final OffsetLayer layer = renderObject.layer; final OffsetLayer layer = renderObject.layer;
final Future<ui.Image> imageFuture = layer.toImage(element.size); final Future<ui.Image> imageFuture = layer.toImage(renderObject.paintBounds);
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized(); final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
return binding.runAsync<String>(() async { return binding.runAsync<String>(() async {
......
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