@@ -28,13 +28,17 @@ namespace flutter {
2828// provided as a fallback.
2929enum class DlImageFilterType {
3030 kBlur ,
31+ kDilate ,
32+ kErode ,
3133 kMatrix ,
3234 kComposeFilter ,
3335 kColorFilter ,
3436 kUnknown
3537};
3638
3739class DlBlurImageFilter ;
40+ class DlDilateImageFilter ;
41+ class DlErodeImageFilter ;
3842class DlMatrixImageFilter ;
3943class DlComposeImageFilter ;
4044class DlColorFilterImageFilter ;
@@ -64,6 +68,14 @@ class DlImageFilter
6468 // type of ImageFilter, otherwise return nullptr.
6569 virtual const DlBlurImageFilter* asBlur () const { return nullptr ; }
6670
71+ // Return a DlDilateImageFilter pointer to this object iff it is a Dilate
72+ // type of ImageFilter, otherwise return nullptr.
73+ virtual const DlDilateImageFilter* asDilate () const { return nullptr ; }
74+
75+ // Return a DlErodeImageFilter pointer to this object iff it is an Erode
76+ // type of ImageFilter, otherwise return nullptr.
77+ virtual const DlErodeImageFilter* asErode () const { return nullptr ; }
78+
6779 // Return a DlMatrixImageFilter pointer to this object iff it is a Matrix
6880 // type of ImageFilter, otherwise return nullptr.
6981 virtual const DlMatrixImageFilter* asMatrix () const { return nullptr ; }
@@ -140,7 +152,7 @@ class DlBlurImageFilter final : public DlImageFilter {
140152 SkIRect* map_device_bounds (const SkIRect& input_bounds,
141153 const SkMatrix& ctm,
142154 SkIRect& output_bounds) const override {
143- SkVector device_sigma = ctm.mapVector (sigma_x_, sigma_y_);
155+ SkVector device_sigma = ctm.mapVector (sigma_x_ * 3 , sigma_y_ * 3 );
144156 if (!SkScalarIsFinite (device_sigma.fX )) {
145157 device_sigma.fX = 0 ;
146158 }
@@ -174,6 +186,126 @@ class DlBlurImageFilter final : public DlImageFilter {
174186 DlTileMode tile_mode_;
175187};
176188
189+ class DlDilateImageFilter final : public DlImageFilter {
190+ public:
191+ DlDilateImageFilter (SkScalar radius_x, SkScalar radius_y)
192+ : radius_x_(radius_x), radius_y_(radius_y) {}
193+ explicit DlDilateImageFilter (const DlDilateImageFilter* filter)
194+ : DlDilateImageFilter(filter->radius_x_, filter->radius_y_) {}
195+ explicit DlDilateImageFilter (const DlDilateImageFilter& filter)
196+ : DlDilateImageFilter(&filter) {}
197+
198+ std::shared_ptr<DlImageFilter> shared () const override {
199+ return std::make_shared<DlDilateImageFilter>(this );
200+ }
201+
202+ DlImageFilterType type () const override { return DlImageFilterType::kDilate ; }
203+ size_t size () const override { return sizeof (*this ); }
204+
205+ const DlDilateImageFilter* asDilate () const override { return this ; }
206+
207+ bool modifies_transparent_black () const override { return false ; }
208+
209+ SkRect* map_local_bounds (const SkRect& input_bounds,
210+ SkRect& output_bounds) const override {
211+ output_bounds = input_bounds.makeOutset (radius_x_, radius_y_);
212+ return &output_bounds;
213+ }
214+
215+ SkIRect* map_device_bounds (const SkIRect& input_bounds,
216+ const SkMatrix& ctm,
217+ SkIRect& output_bounds) const override {
218+ SkVector device_radius = ctm.mapVector (radius_x_, radius_y_);
219+ if (!SkScalarIsFinite (device_radius.fX )) {
220+ device_radius.fX = 0 ;
221+ }
222+ if (!SkScalarIsFinite (device_radius.fY )) {
223+ device_radius.fY = 0 ;
224+ }
225+ output_bounds = input_bounds.makeOutset (ceil (abs (device_radius.fX )),
226+ ceil (abs (device_radius.fY )));
227+ return &output_bounds;
228+ }
229+
230+ SkScalar radius_x () const { return radius_x_; }
231+ SkScalar radius_y () const { return radius_y_; }
232+
233+ sk_sp<SkImageFilter> skia_object () const override {
234+ return SkImageFilters::Dilate (radius_x_, radius_y_, nullptr );
235+ }
236+
237+ protected:
238+ bool equals_ (const DlImageFilter& other) const override {
239+ FML_DCHECK (other.type () == DlImageFilterType::kDilate );
240+ auto that = static_cast <const DlDilateImageFilter*>(&other);
241+ return (radius_x_ == that->radius_x_ && radius_y_ == that->radius_y_ );
242+ }
243+
244+ private:
245+ SkScalar radius_x_;
246+ SkScalar radius_y_;
247+ };
248+
249+ class DlErodeImageFilter final : public DlImageFilter {
250+ public:
251+ DlErodeImageFilter (SkScalar radius_x, SkScalar radius_y)
252+ : radius_x_(radius_x), radius_y_(radius_y) {}
253+ explicit DlErodeImageFilter (const DlErodeImageFilter* filter)
254+ : DlErodeImageFilter(filter->radius_x_, filter->radius_y_) {}
255+ explicit DlErodeImageFilter (const DlErodeImageFilter& filter)
256+ : DlErodeImageFilter(&filter) {}
257+
258+ std::shared_ptr<DlImageFilter> shared () const override {
259+ return std::make_shared<DlErodeImageFilter>(this );
260+ }
261+
262+ DlImageFilterType type () const override { return DlImageFilterType::kErode ; }
263+ size_t size () const override { return sizeof (*this ); }
264+
265+ const DlErodeImageFilter* asErode () const override { return this ; }
266+
267+ bool modifies_transparent_black () const override { return false ; }
268+
269+ SkRect* map_local_bounds (const SkRect& input_bounds,
270+ SkRect& output_bounds) const override {
271+ output_bounds = input_bounds.makeOutset (radius_x_, radius_y_);
272+ return &output_bounds;
273+ }
274+
275+ SkIRect* map_device_bounds (const SkIRect& input_bounds,
276+ const SkMatrix& ctm,
277+ SkIRect& output_bounds) const override {
278+ SkVector device_radius = ctm.mapVector (radius_x_, radius_y_);
279+ if (!SkScalarIsFinite (device_radius.fX )) {
280+ device_radius.fX = 0 ;
281+ }
282+ if (!SkScalarIsFinite (device_radius.fY )) {
283+ device_radius.fY = 0 ;
284+ }
285+ output_bounds = input_bounds.makeOutset (ceil (abs (device_radius.fX )),
286+ ceil (abs (device_radius.fY )));
287+ return &output_bounds;
288+ }
289+
290+ SkScalar radius_x () const { return radius_x_; }
291+ SkScalar radius_y () const { return radius_y_; }
292+
293+ sk_sp<SkImageFilter> skia_object () const override {
294+ return SkImageFilters::Erode (radius_x_, radius_y_, nullptr );
295+ }
296+
297+ protected:
298+ bool equals_ (const DlImageFilter& other) const override {
299+ FML_DCHECK (other.type () == DlImageFilterType::kErode );
300+ auto that = static_cast <const DlErodeImageFilter*>(&other);
301+ return (radius_x_ == that->radius_x_ && radius_y_ == that->radius_y_ );
302+ }
303+
304+ private:
305+ SkScalar radius_x_;
306+ SkScalar radius_y_;
307+ };
308+
177309class DlMatrixImageFilter final : public DlImageFilter {
178310 public:
179311 DlMatrixImageFilter (const SkMatrix& matrix, const SkSamplingOptions& sampling)
0 commit comments