未验证 提交 c31dc589 编写于 作者: Y Yegor 提交者: GitHub

[canvaskit] fix TransformLayer.preroll (#22890)

上级 9af38d36
......@@ -71,6 +71,11 @@ class PaintContext {
abstract class ContainerLayer extends Layer {
final List<Layer> _layers = <Layer>[];
/// The list of child layers.
///
/// Useful in tests.
List<Layer> get debugLayers => _layers;
/// Register [child] as a child of this layer.
void add(Layer child) {
child.parent = this;
......@@ -294,46 +299,10 @@ class TransformLayer extends ContainerLayer
final Matrix4 childMatrix = matrix * _transform;
context.mutatorsStack.pushTransform(_transform);
final ui.Rect childPaintBounds = prerollChildren(context, childMatrix);
paintBounds = _transformRect(_transform, childPaintBounds);
paintBounds = transformRect(_transform, childPaintBounds);
context.mutatorsStack.pop();
}
/// Applies the given matrix as a perspective transform to the given point.
///
/// This function assumes the given point has a z-coordinate of 0.0. The
/// z-coordinate of the result is ignored.
static ui.Offset _transformPoint(Matrix4 transform, ui.Offset point) {
final Vector3 position3 = Vector3(point.dx, point.dy, 0.0);
final Vector3 transformed3 = transform.perspectiveTransform(position3);
return ui.Offset(transformed3.x, transformed3.y);
}
/// Returns a rect that bounds the result of applying the given matrix as a
/// perspective transform to the given rect.
///
/// This function assumes the given rect is in the plane with z equals 0.0.
/// The transformed rect is then projected back into the plane with z equals
/// 0.0 before computing its bounding rect.
static ui.Rect _transformRect(Matrix4 transform, ui.Rect rect) {
final ui.Offset point1 = _transformPoint(transform, rect.topLeft);
final ui.Offset point2 = _transformPoint(transform, rect.topRight);
final ui.Offset point3 = _transformPoint(transform, rect.bottomLeft);
final ui.Offset point4 = _transformPoint(transform, rect.bottomRight);
return ui.Rect.fromLTRB(
_min4(point1.dx, point2.dx, point3.dx, point4.dx),
_min4(point1.dy, point2.dy, point3.dy, point4.dy),
_max4(point1.dx, point2.dx, point3.dx, point4.dx),
_max4(point1.dy, point2.dy, point3.dy, point4.dy));
}
static double _min4(double a, double b, double c, double d) {
return math.min(a, math.min(b, math.min(c, d)));
}
static double _max4(double a, double b, double c, double d) {
return math.max(a, math.max(b, math.max(c, d)));
}
@override
void paint(PaintContext paintContext) {
assert(needsPainting);
......
......@@ -45,6 +45,16 @@ void setUpCanvasKitTest() {
});
}
/// Utility function for CanvasKit tests to draw pictures without
/// the [CkPictureRecorder] boilerplate.
CkPicture paintPicture(
ui.Rect cullRect, void Function(CkCanvas canvas) painter) {
final CkPictureRecorder recorder = CkPictureRecorder();
final CkCanvas canvas = recorder.beginRecording(cullRect);
painter(canvas);
return recorder.endRecording();
}
class _TestFinalizerRegistration {
_TestFinalizerRegistration(this.wrapper, this.deletable, this.stackTrace);
......
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.12
import 'dart:typed_data';
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;
import 'common.dart';
void main() {
internalBootstrapBrowserTest(() => testMain);
}
void testMain() {
group('CanvasKit', () {
setUpCanvasKitTest();
// Regression test for https://github.com/flutter/flutter/issues/63715
test('TransformLayer prerolls correctly', () async {
final EnginePlatformDispatcher dispatcher =
ui.window.platformDispatcher as EnginePlatformDispatcher;
final CkPicture picture =
paintPicture(ui.Rect.fromLTRB(0, 0, 30, 30), (CkCanvas canvas) {
canvas.drawRect(ui.Rect.fromLTRB(0, 0, 30, 30),
CkPaint()..style = ui.PaintingStyle.fill);
});
final LayerSceneBuilder sb = LayerSceneBuilder();
sb.pushClipRect(ui.Rect.fromLTRB(15, 15, 30, 30));
// Intentionally use a perspective transform, which triggered the
// https://github.com/flutter/flutter/issues/63715 bug.
sb.pushTransform(
Float64List.fromList(Matrix4.identity().storage
..[15] = 2,
));
sb.addPicture(ui.Offset.zero, picture);
final LayerTree layerTree = sb.build().layerTree;
dispatcher.rasterizer!.draw(layerTree);
final ClipRectLayer clipRect = layerTree.rootLayer as ClipRectLayer;
expect(clipRect.paintBounds, ui.Rect.fromLTRB(15, 15, 30, 30));
final TransformLayer transform = clipRect.debugLayers.single as TransformLayer;
expect(transform.paintBounds, ui.Rect.fromLTRB(0, 0, 30, 30));
});
// TODO: https://github.com/flutter/flutter/issues/60040
}, skip: isIosSafari);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册