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 {
/// Capture an image of the current state of this layer and its children.
///
/// The returned [ui.Image] has uncompressed raw RGBA bytes, in the
/// dimensions [logicalSize] multiplied by the [pixelRatio].
/// The returned [ui.Image] has uncompressed raw RGBA bytes, will be offset
/// 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
/// size of the output image. It is independent of the
......@@ -532,11 +533,12 @@ class OffsetLayer extends ContainerLayer {
///
/// * [RenderRepaintBoundary.toImage] for a similar API at the render object level.
/// * [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);
final ui.SceneBuilder builder = new ui.SceneBuilder();
final Matrix4 transform = new Matrix4.diagonal3Values(pixelRatio, pixelRatio, 1.0);
transform.translate(-offset.dx, -offset.dy, 0.0);
final Matrix4 transform = new Matrix4.translationValues(bounds.left - offset.dx, bounds.top - offset.dy, 0.0);
transform.scale(pixelRatio, pixelRatio);
builder.pushTransform(transform.storage);
addToScene(builder, Offset.zero);
final ui.Scene scene = builder.build();
......@@ -544,8 +546,8 @@ class OffsetLayer extends ContainerLayer {
// Size is rounded up to the next pixel to make sure we don't clip off
// anything.
return await scene.toImage(
(pixelRatio * logicalSize.width).ceil(),
(pixelRatio * logicalSize.height).ceil(),
(pixelRatio * bounds.width).ceil(),
(pixelRatio * bounds.height).ceil(),
);
} finally {
scene.dispose();
......
......@@ -2515,7 +2515,7 @@ class RenderRepaintBoundary extends RenderProxyBox {
/// * [dart:ui.Scene.toImage] for more information about the image returned.
Future<ui.Image> toImage({double pixelRatio: 1.0}) {
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 {
}
assert(!renderObject.debugNeedsPaint);
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();
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