From 03c7cbc5063b0c2665277610f870c1a8fa42f2ba Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Thu, 30 Nov 2023 16:25:44 -0800 Subject: [PATCH 1/2] Add dilate and erode imagefilters --- .../src/engine/canvaskit/canvaskit_api.dart | 12 +++ .../src/engine/canvaskit/image_filter.dart | 85 +++++++++++++++++++ .../lib/src/engine/canvaskit/renderer.dart | 14 ++- lib/web_ui/test/canvaskit/filter_test.dart | 2 + lib/web_ui/test/ui/filters_test.dart | 4 +- 5 files changed, 107 insertions(+), 10 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart index fea055f16bbec..226bc43e015d4 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart @@ -1490,6 +1490,18 @@ extension SkImageFilterNamespaceExtension on SkImageFilterNamespace { SkImageFilter outer, SkImageFilter inner, ); + + external SkImageFilter MakeDilate( + double radiusX, + double radiusY, + void input, // we don't use this yet + ); + + external SkImageFilter MakeErode( + double radiusX, + double radiusY, + void input, // we don't use this yet + ); } @JS() diff --git a/lib/web_ui/lib/src/engine/canvaskit/image_filter.dart b/lib/web_ui/lib/src/engine/canvaskit/image_filter.dart index 2032ccdd88670..2f4dba311f783 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/image_filter.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/image_filter.dart @@ -40,6 +40,11 @@ abstract class CkImageFilter implements CkManagedSkImageFilterConvertible { factory CkImageFilter.matrix( {required Float64List matrix, required ui.FilterQuality filterQuality}) = _CkMatrixImageFilter; + factory CkImageFilter.dilate( + {required double radiusX, + required double radiusY}) = _CkDilateImageFilter; + factory CkImageFilter.erode( + {required double radiusX, required double radiusY}) = _CkErodeImageFilter; CkImageFilter._(); @@ -194,3 +199,83 @@ class _CkMatrixImageFilter extends CkImageFilter { @override Matrix4 get transform => _transform; } + +class _CkDilateImageFilter extends CkImageFilter { + _CkDilateImageFilter({required this.radiusX, required this.radiusY}) + : super._() { + final SkImageFilter skImageFilter = canvasKit.ImageFilter.MakeDilate( + radiusX, + radiusY, + null, + ); + _ref = UniqueRef(this, skImageFilter, 'ImageFilter.dilate'); + } + + final double radiusX; + final double radiusY; + + late final UniqueRef _ref; + + @override + void imageFilter(SkImageFilterBorrow borrow) { + borrow(_ref.nativeObject); + } + + @override + bool operator ==(Object other) { + if (runtimeType != other.runtimeType) { + return false; + } + return other is _CkDilateImageFilter && + other.radiusX == radiusX && + other.radiusY == radiusY; + } + + @override + int get hashCode => Object.hash(radiusX, radiusY); + + @override + String toString() { + return 'ImageFilter.dilate($radiusX, $radiusY)'; + } +} + +class _CkErodeImageFilter extends CkImageFilter { + _CkErodeImageFilter({required this.radiusX, required this.radiusY}) + : super._() { + final SkImageFilter skImageFilter = canvasKit.ImageFilter.MakeErode( + radiusX, + radiusY, + null, + ); + _ref = UniqueRef(this, skImageFilter, 'ImageFilter.erode'); + } + + final double radiusX; + final double radiusY; + + late final UniqueRef _ref; + + @override + void imageFilter(SkImageFilterBorrow borrow) { + borrow(_ref.nativeObject); + } + + @override + bool operator ==(Object other) { + if (runtimeType != other.runtimeType) { + return false; + } + return other is _CkErodeImageFilter && + other.radiusX == radiusX && + other.radiusY == radiusY; + } + + @override + int get hashCode => Object.hash(radiusX, radiusY); + + @override + String toString() { + return 'ImageFilter.erode($radiusX, $radiusY)'; + } +} diff --git a/lib/web_ui/lib/src/engine/canvaskit/renderer.dart b/lib/web_ui/lib/src/engine/canvaskit/renderer.dart index a948b5b55f08c..f33e7ae021d26 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/renderer.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/renderer.dart @@ -174,16 +174,14 @@ class CanvasKitRenderer implements Renderer { }) => CkImageFilter.blur(sigmaX: sigmaX, sigmaY: sigmaY, tileMode: tileMode); @override - ui.ImageFilter createDilateImageFilter({double radiusX = 0.0, double radiusY = 0.0}) { - // TODO(fzyzcjy): implement dilate. https://github.com/flutter/flutter/issues/101085 - throw UnimplementedError('ImageFilter.dilate not implemented for CanvasKit.'); - } + ui.ImageFilter createDilateImageFilter( + {double radiusX = 0.0, double radiusY = 0.0}) => + CkImageFilter.dilate(radiusX: radiusX, radiusY: radiusY); @override - ui.ImageFilter createErodeImageFilter({double radiusX = 0.0, double radiusY = 0.0}) { - // TODO(fzyzcjy): implement erode. https://github.com/flutter/flutter/issues/101085 - throw UnimplementedError('ImageFilter.erode not implemented for CanvasKit.'); - } + ui.ImageFilter createErodeImageFilter( + {double radiusX = 0.0, double radiusY = 0.0}) => + CkImageFilter.erode(radiusX: radiusX, radiusY: radiusY); @override ui.ImageFilter createMatrixImageFilter( diff --git a/lib/web_ui/test/canvaskit/filter_test.dart b/lib/web_ui/test/canvaskit/filter_test.dart index 5ca14f831a03c..93a947640d952 100644 --- a/lib/web_ui/test/canvaskit/filter_test.dart +++ b/lib/web_ui/test/canvaskit/filter_test.dart @@ -42,6 +42,8 @@ void testMain() { CkImageFilter.blur(sigmaX: 5, sigmaY: 6, tileMode: ui.TileMode.clamp), CkImageFilter.blur(sigmaX: 6, sigmaY: 5, tileMode: ui.TileMode.clamp), CkImageFilter.blur(sigmaX: 6, sigmaY: 5, tileMode: ui.TileMode.decal), + CkImageFilter.dilate(radiusX: 5, radiusY: 6), + CkImageFilter.erode(radiusX: 7, radiusY: 8), for (final CkColorFilter colorFilter in createColorFilters()) CkImageFilter.color(colorFilter: colorFilter), ]; } diff --git a/lib/web_ui/test/ui/filters_test.dart b/lib/web_ui/test/ui/filters_test.dart index a2151002c8e92..29b9d026d579e 100644 --- a/lib/web_ui/test/ui/filters_test.dart +++ b/lib/web_ui/test/ui/filters_test.dart @@ -60,7 +60,7 @@ Future testMain() async { radiusY: 5.0, )); await matchGoldenFile('ui_filter_dilate_imagefilter.png', region: region); - }, skip: !isSkwasm); // Only skwasm supports dilate filter right now + }, skip: isHtml); // HTML renderer does not support the dilate filter test('erode filter', () async { await drawTestImageWithPaint(ui.Paint()..imageFilter = ui.ImageFilter.erode( @@ -68,7 +68,7 @@ Future testMain() async { radiusY: 5.0, )); await matchGoldenFile('ui_filter_erode_imagefilter.png', region: region); - }, skip: !isSkwasm); // Only skwasm supports erode filter + }, skip: isHtml); // HTML renderer does not support the erode filter test('matrix filter', () async { await drawTestImageWithPaint(ui.Paint()..imageFilter = ui.ImageFilter.matrix( From 4bbf2ec8b0dc5086a97281a276a67dbd024a6f80 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Thu, 30 Nov 2023 16:36:23 -0800 Subject: [PATCH 2/2] Add canvaskit_api tests --- lib/web_ui/test/canvaskit/canvaskit_api_test.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart index 514ad95ded270..fbf39bd5c4477 100644 --- a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart +++ b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart @@ -529,6 +529,20 @@ void _imageFilterTests() { isNotNull, ); }); + + test('MakeDilate', () { + expect( + canvasKit.ImageFilter.MakeDilate(1, 2, null), + isNotNull, + ); + }); + + test('MakeErode', () { + expect( + canvasKit.ImageFilter.MakeErode(1, 2, null), + isNotNull, + ); + }); } void _mallocTests() {