Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 6bb4374

Browse files
[canvaskit] Fix color filter for dst and dstIn (#51693)
When CanvasKit returns `null` for a ColorFilter, it indicates the ColorFilter is a no-op, not that an error has occurred. This fixes the engine to correctly handle when CanvasKit returns a null ColorFilter. Fixes flutter/flutter#123537 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making or feature I am adding, or the PR is [test-exempt]. See [testing the engine] for instructions on writing and running engine tests. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I signed the [CLA]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [testing the engine]: https://github.com/flutter/flutter/wiki/Testing-the-engine [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat
1 parent 68af8cc commit 6bb4374

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

lib/web_ui/lib/src/engine/canvaskit/color_filter.dart

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,17 @@ Float32List _computeIdentityTransform() {
100100
return result;
101101
}
102102

103-
SkColorFilter createSkColorFilterFromColorAndBlendMode(ui.Color color, ui.BlendMode blendMode) {
104-
/// Return the identity matrix when the color opacity is 0. Replicates
105-
/// effect of applying no filter
106-
if (color.opacity == 0) {
107-
return canvasKit.ColorFilter.MakeMatrix(_identityTransform);
108-
}
103+
SkColorFilter createSkColorFilterFromColorAndBlendMode(
104+
ui.Color color, ui.BlendMode blendMode) {
109105
final SkColorFilter? filter = canvasKit.ColorFilter.MakeBlend(
110106
toSharedSkColor1(color),
111107
toSkBlendMode(blendMode),
112108
);
113109
if (filter == null) {
114-
throw ArgumentError('Invalid parameters for blend mode ColorFilter');
110+
// If CanvasKit returns null, then the ColorFilter with this combination of
111+
// color and blend mode is a no-op. So just return a dummy color filter that
112+
// does nothing.
113+
return canvasKit.ColorFilter.MakeMatrix(_identityTransform);
115114
}
116115
return filter;
117116
}

lib/web_ui/test/canvaskit/color_filter_golden_test.dart

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,44 @@ void testMain() {
156156

157157
builder.addPicture(ui.Offset.zero, redCircle2);
158158

159-
await matchSceneGolden('canvaskit_transparent_colorfilter.png', builder.build(), region: region);
159+
await matchSceneGolden(
160+
'canvaskit_transparent_colorfilter.png', builder.build(),
161+
region: region);
162+
});
163+
164+
test('ColorFilter with dst blend mode', () async {
165+
final LayerSceneBuilder builder = LayerSceneBuilder();
166+
builder.pushOffset(0, 0);
167+
final CkPictureRecorder recorder = CkPictureRecorder();
168+
final CkCanvas canvas = recorder.beginRecording(region);
169+
170+
canvas.drawCircle(
171+
const ui.Offset(75, 125),
172+
50,
173+
CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0),
174+
);
175+
final CkPicture redCircle1 = recorder.endRecording();
176+
builder.addPicture(ui.Offset.zero, redCircle1);
177+
178+
// Push dst color filter
179+
builder.pushColorFilter(
180+
const ui.ColorFilter.mode(ui.Color(0xffff0000), ui.BlendMode.dst));
181+
182+
// Draw another red circle and apply it to the scene.
183+
// This one should also be red with the color filter doing nothing
184+
final CkPictureRecorder recorder2 = CkPictureRecorder();
185+
final CkCanvas canvas2 = recorder2.beginRecording(region);
186+
canvas2.drawCircle(
187+
const ui.Offset(425, 125),
188+
50,
189+
CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0),
190+
);
191+
final CkPicture redCircle2 = recorder2.endRecording();
192+
193+
builder.addPicture(ui.Offset.zero, redCircle2);
194+
195+
await matchSceneGolden('canvaskit_dst_colorfilter.png', builder.build(),
196+
region: region);
160197
});
161198
// TODO(hterkelsen): https://github.com/flutter/flutter/issues/71520
162199
}, skip: isSafari || isFirefox);

0 commit comments

Comments
 (0)