[go: nahoru, domu]

Skip to content

Commit

Permalink
[canvaskit] Fix color filter for dst and dstIn (#51693)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
harryterkelsen committed Mar 27, 2024
1 parent 68af8cc commit 6bb4374
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
13 changes: 6 additions & 7 deletions lib/web_ui/lib/src/engine/canvaskit/color_filter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
39 changes: 38 additions & 1 deletion lib/web_ui/test/canvaskit/color_filter_golden_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 6bb4374

Please sign in to comment.