mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[canvaskit] Fix incorrect clipping with Opacity scene layer (flutter/engine#55751)
Fixes opacity layer incorrectly clipping its children when there are complex transforms applied to them. Since the opacity saveLayer only applies to children which actually draw, it doesn't need to have tight bounds anyways. Pre-requisite for re-enabling tests here: https://github.com/flutter/flutter/issues/110785 BEFORE:  AFTER:  BEFORE:  AFTER:  [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
parent
173af3d95f
commit
0ed39374df
@ -329,9 +329,7 @@ class MeasureVisitor extends LayerVisitor {
|
||||
measuringCanvas.save();
|
||||
measuringCanvas.translate(opacity.offset.dx, opacity.offset.dy);
|
||||
|
||||
final ui.Rect saveLayerBounds = opacity.paintBounds.shift(-opacity.offset);
|
||||
|
||||
measuringCanvas.saveLayer(saveLayerBounds, paint);
|
||||
measuringCanvas.saveLayer(ui.Rect.largest, paint);
|
||||
measureChildren(opacity);
|
||||
// Restore twice: once for the translate and once for the saveLayer.
|
||||
measuringCanvas.restore();
|
||||
@ -567,9 +565,7 @@ class PaintVisitor extends LayerVisitor {
|
||||
nWayCanvas.save();
|
||||
nWayCanvas.translate(opacity.offset.dx, opacity.offset.dy);
|
||||
|
||||
final ui.Rect saveLayerBounds = opacity.paintBounds.shift(-opacity.offset);
|
||||
|
||||
nWayCanvas.saveLayer(saveLayerBounds, paint);
|
||||
nWayCanvas.saveLayer(ui.Rect.largest, paint);
|
||||
paintChildren(opacity);
|
||||
// Restore twice: once for the translate and once for the saveLayer.
|
||||
nWayCanvas.restore();
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:math' as math;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:test/bootstrap/browser.dart';
|
||||
import 'package:test/test.dart';
|
||||
@ -403,6 +404,69 @@ Future<void> testMain() async {
|
||||
},
|
||||
skip: isFirefox &&
|
||||
isHtml); // https://github.com/flutter/flutter/issues/86623
|
||||
|
||||
test('opacity layer with transformed children', () async {
|
||||
final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
|
||||
sceneBuilder.pushOffset(0, 0);
|
||||
sceneBuilder.pushOpacity(128);
|
||||
// Push some complex transforms
|
||||
final Float64List transform1 = Float64List.fromList([
|
||||
1.00,
|
||||
0.00,
|
||||
0.00,
|
||||
0.00,
|
||||
0.06,
|
||||
1.00,
|
||||
-0.88,
|
||||
0.00,
|
||||
-0.03,
|
||||
0.60,
|
||||
0.47,
|
||||
-0.00,
|
||||
-4.58,
|
||||
257.03,
|
||||
63.11,
|
||||
0.81,
|
||||
]);
|
||||
final Float64List transform2 = Float64List.fromList([
|
||||
1.00,
|
||||
0.00,
|
||||
0.00,
|
||||
0.00,
|
||||
0.07,
|
||||
0.90,
|
||||
-0.94,
|
||||
0.00,
|
||||
-0.02,
|
||||
0.75,
|
||||
0.33,
|
||||
-0.00,
|
||||
-3.28,
|
||||
309.29,
|
||||
45.20,
|
||||
0.86,
|
||||
]);
|
||||
sceneBuilder
|
||||
.pushTransform(Matrix4.identity().scaled(0.3, 0.3).toFloat64());
|
||||
sceneBuilder.pushTransform(transform1);
|
||||
sceneBuilder.pushTransform(transform2);
|
||||
|
||||
sceneBuilder.addPicture(const ui.Offset(20, 20),
|
||||
drawPicture((ui.Canvas canvas) {
|
||||
canvas.drawCircle(const ui.Offset(25, 75), 25,
|
||||
ui.Paint()..color = const ui.Color(0xFFFF0000));
|
||||
}));
|
||||
sceneBuilder.pop();
|
||||
sceneBuilder.pop();
|
||||
sceneBuilder.pop();
|
||||
sceneBuilder.pop();
|
||||
sceneBuilder.pop();
|
||||
await renderScene(sceneBuilder.build());
|
||||
|
||||
await matchGoldenFile(
|
||||
'scene_builder_opacity_layer_with_transformed_children.png',
|
||||
region: region);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user