From a116bf679a8d595f4731131e46487310da6b501b Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Tue, 26 Mar 2024 16:31:27 -0700 Subject: [PATCH] Fix color filter for dst and dstIn --- .../src/engine/canvaskit/color_filter.dart | 13 +++---- .../canvaskit/color_filter_golden_test.dart | 39 ++++++++++++++++++- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/color_filter.dart b/lib/web_ui/lib/src/engine/canvaskit/color_filter.dart index 8114aa3cedc01..569a48edb9552 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/color_filter.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/color_filter.dart @@ -100,18 +100,17 @@ Float32List _computeIdentityTransform() { return result; } -SkColorFilter createSkColorFilterFromColorAndBlendMode(ui.Color color, ui.BlendMode blendMode) { - /// Return the identity matrix when the color opacity is 0. Replicates - /// effect of applying no filter - if (color.opacity == 0) { - return canvasKit.ColorFilter.MakeMatrix(_identityTransform); - } +SkColorFilter createSkColorFilterFromColorAndBlendMode( + ui.Color color, ui.BlendMode blendMode) { final SkColorFilter? filter = canvasKit.ColorFilter.MakeBlend( toSharedSkColor1(color), toSkBlendMode(blendMode), ); if (filter == null) { - throw ArgumentError('Invalid parameters for blend mode ColorFilter'); + // If CanvasKit returns null, then the ColorFilter with this combination of + // color and blend mode is a no-op. So just return a dummy color filter that + // does nothing. + return canvasKit.ColorFilter.MakeMatrix(_identityTransform); } return filter; } diff --git a/lib/web_ui/test/canvaskit/color_filter_golden_test.dart b/lib/web_ui/test/canvaskit/color_filter_golden_test.dart index 48045ad942652..cf5ba125bbe18 100644 --- a/lib/web_ui/test/canvaskit/color_filter_golden_test.dart +++ b/lib/web_ui/test/canvaskit/color_filter_golden_test.dart @@ -156,7 +156,44 @@ void testMain() { builder.addPicture(ui.Offset.zero, redCircle2); - await matchSceneGolden('canvaskit_transparent_colorfilter.png', builder.build(), region: region); + await matchSceneGolden( + 'canvaskit_transparent_colorfilter.png', builder.build(), + region: region); + }); + + test('ColorFilter with dst blend mode', () async { + final LayerSceneBuilder builder = LayerSceneBuilder(); + builder.pushOffset(0, 0); + final CkPictureRecorder recorder = CkPictureRecorder(); + final CkCanvas canvas = recorder.beginRecording(region); + + canvas.drawCircle( + const ui.Offset(75, 125), + 50, + CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0), + ); + final CkPicture redCircle1 = recorder.endRecording(); + builder.addPicture(ui.Offset.zero, redCircle1); + + // Push dst color filter + builder.pushColorFilter( + const ui.ColorFilter.mode(ui.Color(0xffff0000), ui.BlendMode.dst)); + + // Draw another red circle and apply it to the scene. + // This one should also be red with the color filter doing nothing + final CkPictureRecorder recorder2 = CkPictureRecorder(); + final CkCanvas canvas2 = recorder2.beginRecording(region); + canvas2.drawCircle( + const ui.Offset(425, 125), + 50, + CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0), + ); + final CkPicture redCircle2 = recorder2.endRecording(); + + builder.addPicture(ui.Offset.zero, redCircle2); + + await matchSceneGolden('canvaskit_dst_colorfilter.png', builder.build(), + region: region); }); // TODO(hterkelsen): https://github.com/flutter/flutter/issues/71520 }, skip: isSafari || isFirefox);