From 136664648d069ffb3354d4b900abcafcf18ac015 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Thu, 5 Sep 2024 14:28:17 -0700 Subject: [PATCH 1/2] [canvaskit] Fix incorrect calculation of ImageFilter paint bounds --- .../lib/src/engine/canvaskit/layer.dart | 30 +-- lib/web_ui/test/ui/scene_builder_test.dart | 207 ++++++++++-------- 2 files changed, 127 insertions(+), 110 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/layer.dart b/lib/web_ui/lib/src/engine/canvaskit/layer.dart index b4d419a926548..010fc012786d3 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/layer.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/layer.dart @@ -415,32 +415,34 @@ class ImageFilterEngineLayer extends ContainerLayer } else { convertible = _filter as CkManagedSkImageFilterConvertible; } - final ui.Rect childPaintBounds = + ui.Rect childPaintBounds = prerollChildren(prerollContext, childMatrix); - if (_filter is ui.ColorFilter) { - // If the filter is a ColorFilter, the extended paint bounds will be the - // entire screen, which is not what we want. - paintBounds = childPaintBounds; - } else { - convertible.withSkImageFilter((skFilter) { - paintBounds = rectFromSkIRect( - skFilter.getOutputBounds(toSkRect(childPaintBounds)), - ); - }); - } + childPaintBounds = childPaintBounds.translate(_offset.dx, _offset.dy); + if (_filter is ui.ColorFilter) { + // If the filter is a ColorFilter, the extended paint bounds will be the + // entire screen, which is not what we want. + paintBounds = childPaintBounds; + } else { + convertible.withSkImageFilter((skFilter) { + paintBounds = rectFromSkIRect( + skFilter.getOutputBounds(toSkRect(childPaintBounds)), + ); + }); + } prerollContext.mutatorsStack.pop(); } @override void paint(PaintContext paintContext) { assert(needsPainting); + final ui.Rect offsetPaintBounds = paintBounds.shift(-_offset); paintContext.internalNodesCanvas.save(); paintContext.internalNodesCanvas.translate(_offset.dx, _offset.dy); paintContext.internalNodesCanvas - .clipRect(paintBounds, ui.ClipOp.intersect, false); + .clipRect(offsetPaintBounds, ui.ClipOp.intersect, false); final CkPaint paint = CkPaint(); paint.imageFilter = _filter; - paintContext.internalNodesCanvas.saveLayer(paintBounds, paint); + paintContext.internalNodesCanvas.saveLayer(offsetPaintBounds, paint); paintChildren(paintContext); paintContext.internalNodesCanvas.restore(); paintContext.internalNodesCanvas.restore(); diff --git a/lib/web_ui/test/ui/scene_builder_test.dart b/lib/web_ui/test/ui/scene_builder_test.dart index fc77fd98c2d39..f03b0db2a0922 100644 --- a/lib/web_ui/test/ui/scene_builder_test.dart +++ b/lib/web_ui/test/ui/scene_builder_test.dart @@ -32,14 +32,12 @@ Future testMain() async { sceneBuilder.pushOffset(150, 150); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { canvas.drawCircle( - ui.Offset.zero, - 50, - ui.Paint()..color = const ui.Color(0xFF00FF00) - ); + ui.Offset.zero, 50, ui.Paint()..color = const ui.Color(0xFF00FF00)); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_centered_circle.png', region: region); + await matchGoldenFile('scene_builder_centered_circle.png', + region: region); }); test('Test transform layer', () async { @@ -54,93 +52,83 @@ Future testMain() async { sceneBuilder.pushTransform(transform.toFloat64()); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { canvas.drawRRect( - ui.RRect.fromRectAndRadius( - ui.Rect.fromCircle(center: ui.Offset.zero, radius: 50), - const ui.Radius.circular(10) - ), - ui.Paint()..color = const ui.Color(0xFF0000FF) - ); + ui.RRect.fromRectAndRadius( + ui.Rect.fromCircle(center: ui.Offset.zero, radius: 50), + const ui.Radius.circular(10)), + ui.Paint()..color = const ui.Color(0xFF0000FF)); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_rotated_rounded_square.png', region: region); + await matchGoldenFile('scene_builder_rotated_rounded_square.png', + region: region); }); test('Test clipRect layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); sceneBuilder.pushClipRect(const ui.Rect.fromLTRB(0, 0, 150, 150)); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { - canvas.drawCircle( - const ui.Offset(150, 150), - 50, - ui.Paint()..color = const ui.Color(0xFFFF0000) - ); + canvas.drawCircle(const ui.Offset(150, 150), 50, + ui.Paint()..color = const ui.Color(0xFFFF0000)); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_circle_clip_rect.png', region: region); + await matchGoldenFile('scene_builder_circle_clip_rect.png', + region: region); }); test('Test clipRRect layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); - sceneBuilder.pushClipRRect(ui.RRect.fromRectAndRadius( - const ui.Rect.fromLTRB(0, 0, 150, 150), - const ui.Radius.circular(25), - ), clipBehavior: ui.Clip.antiAlias); + sceneBuilder.pushClipRRect( + ui.RRect.fromRectAndRadius( + const ui.Rect.fromLTRB(0, 0, 150, 150), + const ui.Radius.circular(25), + ), + clipBehavior: ui.Clip.antiAlias); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { - canvas.drawCircle( - const ui.Offset(150, 150), - 50, - ui.Paint()..color = const ui.Color(0xFFFF00FF) - ); + canvas.drawCircle(const ui.Offset(150, 150), 50, + ui.Paint()..color = const ui.Color(0xFFFF00FF)); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_circle_clip_rrect.png', region: region); + await matchGoldenFile('scene_builder_circle_clip_rrect.png', + region: region); }); test('Test clipPath layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); final ui.Path path = ui.Path(); - path.addOval(ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 60)); + path.addOval( + ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 60)); sceneBuilder.pushClipPath(path); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { canvas.drawRect( - ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), - ui.Paint()..color = const ui.Color(0xFF00FFFF) - ); + ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), + ui.Paint()..color = const ui.Color(0xFF00FFFF)); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_rectangle_clip_circular_path.png', region: region); + await matchGoldenFile('scene_builder_rectangle_clip_circular_path.png', + region: region); }); test('Test opacity layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { canvas.drawRect( - ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), - ui.Paint()..color = const ui.Color(0xFF00FF00) - ); + ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), + ui.Paint()..color = const ui.Color(0xFF00FF00)); })); sceneBuilder.pushOpacity(0x7F, offset: const ui.Offset(150, 150)); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { final ui.Paint paint = ui.Paint()..color = const ui.Color(0xFFFF0000); - canvas.drawCircle( - const ui.Offset(-25, 0), - 50, - paint - ); - canvas.drawCircle( - const ui.Offset(25, 0), - 50, - paint - ); + canvas.drawCircle(const ui.Offset(-25, 0), 50, paint); + canvas.drawCircle(const ui.Offset(25, 0), 50, paint); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_opacity_circles_on_square.png', region: region); + await matchGoldenFile('scene_builder_opacity_circles_on_square.png', + region: region); }); test('shader mask layer', () async { @@ -148,48 +136,39 @@ Future testMain() async { sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { final ui.Paint paint = ui.Paint()..color = const ui.Color(0xFFFF0000); - canvas.drawCircle( - const ui.Offset(125, 150), - 50, - paint - ); - canvas.drawCircle( - const ui.Offset(175, 150), - 50, - paint - ); + canvas.drawCircle(const ui.Offset(125, 150), 50, paint); + canvas.drawCircle(const ui.Offset(175, 150), 50, paint); })); final ui.Shader shader = ui.Gradient.linear( - ui.Offset.zero, - const ui.Offset(50, 50), [ - const ui.Color(0xFFFFFFFF), - const ui.Color(0x00000000), - ]); - sceneBuilder.pushShaderMask( - shader, - const ui.Rect.fromLTRB(125, 125, 175, 175), - ui.BlendMode.srcATop - ); + ui.Offset.zero, const ui.Offset(50, 50), [ + const ui.Color(0xFFFFFFFF), + const ui.Color(0x00000000), + ]); + sceneBuilder.pushShaderMask(shader, + const ui.Rect.fromLTRB(125, 125, 175, 175), ui.BlendMode.srcATop); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { canvas.drawRect( - ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), - ui.Paint()..color = const ui.Color(0xFF00FF00) - ); + ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), + ui.Paint()..color = const ui.Color(0xFF00FF00)); })); await renderScene(sceneBuilder.build()); await matchGoldenFile('scene_builder_shader_mask.png', region: region); - }, skip: isFirefox && isHtml); // https://github.com/flutter/flutter/issues/86623 + }, + skip: isFirefox && + isHtml); // https://github.com/flutter/flutter/issues/86623 test('backdrop filter layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { // Create a red and blue checkerboard pattern - final ui.Paint redPaint = ui.Paint()..color = const ui.Color(0xFFFF0000); - final ui.Paint bluePaint = ui.Paint()..color = const ui.Color(0xFF0000FF); + final ui.Paint redPaint = ui.Paint() + ..color = const ui.Color(0xFFFF0000); + final ui.Paint bluePaint = ui.Paint() + ..color = const ui.Color(0xFF0000FF); for (double y = 0; y < 300; y += 10) { for (double x = 0; x < 300; x += 10) { final ui.Paint paint = ((x + y) % 20 == 0) ? redPaint : bluePaint; @@ -204,15 +183,13 @@ Future testMain() async { )); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { - canvas.drawCircle( - const ui.Offset(150, 150), - 50, - ui.Paint()..color = const ui.Color(0xFF00FF00) - ); + canvas.drawCircle(const ui.Offset(150, 150), 50, + ui.Paint()..color = const ui.Color(0xFF00FF00)); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_backdrop_filter.png', region: region); + await matchGoldenFile('scene_builder_backdrop_filter.png', + region: region); }); test('empty backdrop filter layer with clip', () async { @@ -223,8 +200,10 @@ Future testMain() async { sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { // Create a red and blue checkerboard pattern - final ui.Paint redPaint = ui.Paint()..color = const ui.Color(0xFFFF0000); - final ui.Paint bluePaint = ui.Paint()..color = const ui.Color(0xFF0000FF); + final ui.Paint redPaint = ui.Paint() + ..color = const ui.Color(0xFFFF0000); + final ui.Paint bluePaint = ui.Paint() + ..color = const ui.Color(0xFF0000FF); for (double y = 0; y < 300; y += 10) { for (double x = 0; x < 300; x += 10) { final ui.Paint paint = ((x + y) % 20 == 0) ? redPaint : bluePaint; @@ -240,7 +219,8 @@ Future testMain() async { sigmaY: 3.0, )); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_empty_backdrop_filter_with_clip.png', region: region); + await matchGoldenFile('scene_builder_empty_backdrop_filter_with_clip.png', + region: region); }); test('image filter layer', () async { @@ -251,33 +231,68 @@ Future testMain() async { )); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { - canvas.drawCircle( - const ui.Offset(150, 150), - 50, - ui.Paint()..color = const ui.Color(0xFF00FF00) - ); + canvas.drawCircle(const ui.Offset(150, 150), 50, + ui.Paint()..color = const ui.Color(0xFF00FF00)); })); await renderScene(sceneBuilder.build()); await matchGoldenFile('scene_builder_image_filter.png', region: region); }); + // Regression test for https://github.com/flutter/flutter/issues/154303 + test('image filter layer with offset', () async { + final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); + + sceneBuilder.pushClipRect(const ui.Rect.fromLTWH(100, 100, 100, 100)); + sceneBuilder.pushImageFilter( + ui.ImageFilter.blur( + sigmaX: 5.0, + sigmaY: 5.0, + ), + offset: const ui.Offset(100, 100), + ); + + sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { + canvas.drawCircle(const ui.Offset(50, 50), 25, + ui.Paint()..color = const ui.Color(0xFF00FF00)); + })); + + await renderScene(sceneBuilder.build()); + await matchGoldenFile( + 'scene_builder_image_filter_with_offset.png', + region: region, + ); + }); + test('color filter layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); const ui.ColorFilter sepia = ui.ColorFilter.matrix([ - 0.393, 0.769, 0.189, 0, 0, - 0.349, 0.686, 0.168, 0, 0, - 0.272, 0.534, 0.131, 0, 0, - 0, 0, 0, 1, 0, + 0.393, + 0.769, + 0.189, + 0, + 0, + 0.349, + 0.686, + 0.168, + 0, + 0, + 0.272, + 0.534, + 0.131, + 0, + 0, + 0, + 0, + 0, + 1, + 0, ]); sceneBuilder.pushColorFilter(sepia); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { - canvas.drawCircle( - const ui.Offset(150, 150), - 50, - ui.Paint()..color = const ui.Color(0xFF00FF00) - ); + canvas.drawCircle(const ui.Offset(150, 150), 50, + ui.Paint()..color = const ui.Color(0xFF00FF00)); })); await renderScene(sceneBuilder.build()); From 9a4748effc45da33ac3c90db01fe0630225f3db0 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Thu, 5 Sep 2024 14:31:49 -0700 Subject: [PATCH 2/2] undo formatting --- lib/web_ui/test/ui/scene_builder_test.dart | 182 +++++++++++---------- 1 file changed, 96 insertions(+), 86 deletions(-) diff --git a/lib/web_ui/test/ui/scene_builder_test.dart b/lib/web_ui/test/ui/scene_builder_test.dart index f03b0db2a0922..aeaef07ad0c5a 100644 --- a/lib/web_ui/test/ui/scene_builder_test.dart +++ b/lib/web_ui/test/ui/scene_builder_test.dart @@ -32,12 +32,14 @@ Future testMain() async { sceneBuilder.pushOffset(150, 150); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { canvas.drawCircle( - ui.Offset.zero, 50, ui.Paint()..color = const ui.Color(0xFF00FF00)); + ui.Offset.zero, + 50, + ui.Paint()..color = const ui.Color(0xFF00FF00) + ); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_centered_circle.png', - region: region); + await matchGoldenFile('scene_builder_centered_circle.png', region: region); }); test('Test transform layer', () async { @@ -52,83 +54,93 @@ Future testMain() async { sceneBuilder.pushTransform(transform.toFloat64()); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { canvas.drawRRect( - ui.RRect.fromRectAndRadius( - ui.Rect.fromCircle(center: ui.Offset.zero, radius: 50), - const ui.Radius.circular(10)), - ui.Paint()..color = const ui.Color(0xFF0000FF)); + ui.RRect.fromRectAndRadius( + ui.Rect.fromCircle(center: ui.Offset.zero, radius: 50), + const ui.Radius.circular(10) + ), + ui.Paint()..color = const ui.Color(0xFF0000FF) + ); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_rotated_rounded_square.png', - region: region); + await matchGoldenFile('scene_builder_rotated_rounded_square.png', region: region); }); test('Test clipRect layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); sceneBuilder.pushClipRect(const ui.Rect.fromLTRB(0, 0, 150, 150)); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { - canvas.drawCircle(const ui.Offset(150, 150), 50, - ui.Paint()..color = const ui.Color(0xFFFF0000)); + canvas.drawCircle( + const ui.Offset(150, 150), + 50, + ui.Paint()..color = const ui.Color(0xFFFF0000) + ); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_circle_clip_rect.png', - region: region); + await matchGoldenFile('scene_builder_circle_clip_rect.png', region: region); }); test('Test clipRRect layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); - sceneBuilder.pushClipRRect( - ui.RRect.fromRectAndRadius( - const ui.Rect.fromLTRB(0, 0, 150, 150), - const ui.Radius.circular(25), - ), - clipBehavior: ui.Clip.antiAlias); + sceneBuilder.pushClipRRect(ui.RRect.fromRectAndRadius( + const ui.Rect.fromLTRB(0, 0, 150, 150), + const ui.Radius.circular(25), + ), clipBehavior: ui.Clip.antiAlias); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { - canvas.drawCircle(const ui.Offset(150, 150), 50, - ui.Paint()..color = const ui.Color(0xFFFF00FF)); + canvas.drawCircle( + const ui.Offset(150, 150), + 50, + ui.Paint()..color = const ui.Color(0xFFFF00FF) + ); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_circle_clip_rrect.png', - region: region); + await matchGoldenFile('scene_builder_circle_clip_rrect.png', region: region); }); test('Test clipPath layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); final ui.Path path = ui.Path(); - path.addOval( - ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 60)); + path.addOval(ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 60)); sceneBuilder.pushClipPath(path); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { canvas.drawRect( - ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), - ui.Paint()..color = const ui.Color(0xFF00FFFF)); + ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), + ui.Paint()..color = const ui.Color(0xFF00FFFF) + ); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_rectangle_clip_circular_path.png', - region: region); + await matchGoldenFile('scene_builder_rectangle_clip_circular_path.png', region: region); }); test('Test opacity layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { canvas.drawRect( - ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), - ui.Paint()..color = const ui.Color(0xFF00FF00)); + ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), + ui.Paint()..color = const ui.Color(0xFF00FF00) + ); })); sceneBuilder.pushOpacity(0x7F, offset: const ui.Offset(150, 150)); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { final ui.Paint paint = ui.Paint()..color = const ui.Color(0xFFFF0000); - canvas.drawCircle(const ui.Offset(-25, 0), 50, paint); - canvas.drawCircle(const ui.Offset(25, 0), 50, paint); + canvas.drawCircle( + const ui.Offset(-25, 0), + 50, + paint + ); + canvas.drawCircle( + const ui.Offset(25, 0), + 50, + paint + ); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_opacity_circles_on_square.png', - region: region); + await matchGoldenFile('scene_builder_opacity_circles_on_square.png', region: region); }); test('shader mask layer', () async { @@ -136,39 +148,48 @@ Future testMain() async { sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { final ui.Paint paint = ui.Paint()..color = const ui.Color(0xFFFF0000); - canvas.drawCircle(const ui.Offset(125, 150), 50, paint); - canvas.drawCircle(const ui.Offset(175, 150), 50, paint); + canvas.drawCircle( + const ui.Offset(125, 150), + 50, + paint + ); + canvas.drawCircle( + const ui.Offset(175, 150), + 50, + paint + ); })); final ui.Shader shader = ui.Gradient.linear( - ui.Offset.zero, const ui.Offset(50, 50), [ - const ui.Color(0xFFFFFFFF), - const ui.Color(0x00000000), - ]); - sceneBuilder.pushShaderMask(shader, - const ui.Rect.fromLTRB(125, 125, 175, 175), ui.BlendMode.srcATop); + ui.Offset.zero, + const ui.Offset(50, 50), [ + const ui.Color(0xFFFFFFFF), + const ui.Color(0x00000000), + ]); + sceneBuilder.pushShaderMask( + shader, + const ui.Rect.fromLTRB(125, 125, 175, 175), + ui.BlendMode.srcATop + ); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { canvas.drawRect( - ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), - ui.Paint()..color = const ui.Color(0xFF00FF00)); + ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50), + ui.Paint()..color = const ui.Color(0xFF00FF00) + ); })); await renderScene(sceneBuilder.build()); await matchGoldenFile('scene_builder_shader_mask.png', region: region); - }, - skip: isFirefox && - isHtml); // https://github.com/flutter/flutter/issues/86623 + }, skip: isFirefox && isHtml); // https://github.com/flutter/flutter/issues/86623 test('backdrop filter layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { // Create a red and blue checkerboard pattern - final ui.Paint redPaint = ui.Paint() - ..color = const ui.Color(0xFFFF0000); - final ui.Paint bluePaint = ui.Paint() - ..color = const ui.Color(0xFF0000FF); + final ui.Paint redPaint = ui.Paint()..color = const ui.Color(0xFFFF0000); + final ui.Paint bluePaint = ui.Paint()..color = const ui.Color(0xFF0000FF); for (double y = 0; y < 300; y += 10) { for (double x = 0; x < 300; x += 10) { final ui.Paint paint = ((x + y) % 20 == 0) ? redPaint : bluePaint; @@ -183,13 +204,15 @@ Future testMain() async { )); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { - canvas.drawCircle(const ui.Offset(150, 150), 50, - ui.Paint()..color = const ui.Color(0xFF00FF00)); + canvas.drawCircle( + const ui.Offset(150, 150), + 50, + ui.Paint()..color = const ui.Color(0xFF00FF00) + ); })); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_backdrop_filter.png', - region: region); + await matchGoldenFile('scene_builder_backdrop_filter.png', region: region); }); test('empty backdrop filter layer with clip', () async { @@ -200,10 +223,8 @@ Future testMain() async { sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { // Create a red and blue checkerboard pattern - final ui.Paint redPaint = ui.Paint() - ..color = const ui.Color(0xFFFF0000); - final ui.Paint bluePaint = ui.Paint() - ..color = const ui.Color(0xFF0000FF); + final ui.Paint redPaint = ui.Paint()..color = const ui.Color(0xFFFF0000); + final ui.Paint bluePaint = ui.Paint()..color = const ui.Color(0xFF0000FF); for (double y = 0; y < 300; y += 10) { for (double x = 0; x < 300; x += 10) { final ui.Paint paint = ((x + y) % 20 == 0) ? redPaint : bluePaint; @@ -219,8 +240,7 @@ Future testMain() async { sigmaY: 3.0, )); await renderScene(sceneBuilder.build()); - await matchGoldenFile('scene_builder_empty_backdrop_filter_with_clip.png', - region: region); + await matchGoldenFile('scene_builder_empty_backdrop_filter_with_clip.png', region: region); }); test('image filter layer', () async { @@ -231,8 +251,11 @@ Future testMain() async { )); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { - canvas.drawCircle(const ui.Offset(150, 150), 50, - ui.Paint()..color = const ui.Color(0xFF00FF00)); + canvas.drawCircle( + const ui.Offset(150, 150), + 50, + ui.Paint()..color = const ui.Color(0xFF00FF00) + ); })); await renderScene(sceneBuilder.build()); @@ -267,32 +290,19 @@ Future testMain() async { test('color filter layer', () async { final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); const ui.ColorFilter sepia = ui.ColorFilter.matrix([ - 0.393, - 0.769, - 0.189, - 0, - 0, - 0.349, - 0.686, - 0.168, - 0, - 0, - 0.272, - 0.534, - 0.131, - 0, - 0, - 0, - 0, - 0, - 1, - 0, + 0.393, 0.769, 0.189, 0, 0, + 0.349, 0.686, 0.168, 0, 0, + 0.272, 0.534, 0.131, 0, 0, + 0, 0, 0, 1, 0, ]); sceneBuilder.pushColorFilter(sepia); sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) { - canvas.drawCircle(const ui.Offset(150, 150), 50, - ui.Paint()..color = const ui.Color(0xFF00FF00)); + canvas.drawCircle( + const ui.Offset(150, 150), + 50, + ui.Paint()..color = const ui.Color(0xFF00FF00) + ); })); await renderScene(sceneBuilder.build());