Flutter Engine
The Flutter Engine
dl_image_filter.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FLUTTER_DISPLAY_LIST_EFFECTS_DL_IMAGE_FILTER_H_
6#define FLUTTER_DISPLAY_LIST_EFFECTS_DL_IMAGE_FILTER_H_
7
8#include <utility>
9
10#include "flutter/display_list/dl_attributes.h"
11#include "flutter/display_list/dl_sampling_options.h"
12#include "flutter/display_list/dl_tile_mode.h"
13#include "flutter/display_list/effects/dl_color_filter.h"
14#include "flutter/display_list/utils/dl_comparable.h"
15#include "flutter/fml/logging.h"
16
18
19namespace flutter {
20
21// The DisplayList ImageFilter class. This class implements all of the
22// facilities and adheres to the design goals of the |DlAttribute| base
23// class.
24//
25// The objects here define operations that can take a location and one or
26// more input pixels and produce a color for that output pixel
27
28// An enumerated type for the supported ImageFilter operations.
30 kBlur,
31 kDilate,
32 kErode,
33 kMatrix,
37};
38
39class DlBlurImageFilter;
40class DlDilateImageFilter;
41class DlErodeImageFilter;
42class DlMatrixImageFilter;
43class DlLocalMatrixImageFilter;
44class DlComposeImageFilter;
45class DlColorFilterImageFilter;
46
47class DlImageFilter : public DlAttribute<DlImageFilter, DlImageFilterType> {
48 public:
49 enum class MatrixCapability {
50 kTranslate,
52 kComplex,
53 };
54
55 // Return a DlBlurImageFilter pointer to this object iff it is a Blur
56 // type of ImageFilter, otherwise return nullptr.
57 virtual const DlBlurImageFilter* asBlur() const { return nullptr; }
58
59 // Return a DlDilateImageFilter pointer to this object iff it is a Dilate
60 // type of ImageFilter, otherwise return nullptr.
61 virtual const DlDilateImageFilter* asDilate() const { return nullptr; }
62
63 // Return a DlErodeImageFilter pointer to this object iff it is an Erode
64 // type of ImageFilter, otherwise return nullptr.
65 virtual const DlErodeImageFilter* asErode() const { return nullptr; }
66
67 // Return a DlMatrixImageFilter pointer to this object iff it is a Matrix
68 // type of ImageFilter, otherwise return nullptr.
69 virtual const DlMatrixImageFilter* asMatrix() const { return nullptr; }
70
71 virtual const DlLocalMatrixImageFilter* asLocalMatrix() const {
72 return nullptr;
73 }
74
75 virtual std::shared_ptr<DlImageFilter> makeWithLocalMatrix(
76 const SkMatrix& matrix) const;
77
78 // Return a DlComposeImageFilter pointer to this object iff it is a Compose
79 // type of ImageFilter, otherwise return nullptr.
80 virtual const DlComposeImageFilter* asCompose() const { return nullptr; }
81
82 // Return a DlColorFilterImageFilter pointer to this object iff it is a
83 // ColorFilter type of ImageFilter, otherwise return nullptr.
84 virtual const DlColorFilterImageFilter* asColorFilter() const {
85 return nullptr;
86 }
87
88 // Return a boolean indicating whether the image filtering operation will
89 // modify transparent black. This is typically used to determine if applying
90 // the ImageFilter to a temporary saveLayer buffer will turn the surrounding
91 // pixels non-transparent and therefore expand the bounds.
92 virtual bool modifies_transparent_black() const = 0;
93
94 // Return the bounds of the output for this image filtering operation
95 // based on the supplied input bounds where both are measured in the local
96 // (untransformed) coordinate space.
97 //
98 // The method will return a pointer to the output_bounds parameter if it
99 // can successfully compute the output bounds of the filter, otherwise the
100 // method will return a nullptr and the output_bounds will be filled with
101 // a best guess for the answer, even if just a copy of the input_bounds.
102 virtual SkRect* map_local_bounds(const SkRect& input_bounds,
103 SkRect& output_bounds) const = 0;
104
105 // Return the device bounds of the output for this image filtering operation
106 // based on the supplied input device bounds where both are measured in the
107 // pixel coordinate space and relative to the given rendering ctm. The
108 // transform matrix is used to adjust the filter parameters for when it
109 // is used in a rendering operation (for example, the blur radius of a
110 // Blur filter will expand based on the ctm).
111 //
112 // The method will return a pointer to the output_bounds parameter if it
113 // can successfully compute the output bounds of the filter, otherwise the
114 // method will return a nullptr and the output_bounds will be filled with
115 // a best guess for the answer, even if just a copy of the input_bounds.
116 virtual SkIRect* map_device_bounds(const SkIRect& input_bounds,
117 const SkMatrix& ctm,
118 SkIRect& output_bounds) const = 0;
119
120 // Return the input bounds that will be needed in order for the filter to
121 // properly fill the indicated output_bounds under the specified
122 // transformation matrix. Both output_bounds and input_bounds are taken to
123 // be relative to the transformed coordinate space of the provided |ctm|.
124 //
125 // The method will return a pointer to the input_bounds parameter if it
126 // can successfully compute the required input bounds, otherwise the
127 // method will return a nullptr and the input_bounds will be filled with
128 // a best guess for the answer, even if just a copy of the output_bounds.
129 virtual SkIRect* get_input_device_bounds(const SkIRect& output_bounds,
130 const SkMatrix& ctm,
131 SkIRect& input_bounds) const = 0;
132
135 }
136
137 protected:
139 SkScalar x,
140 SkScalar y) {
141 FML_DCHECK(std::isfinite(x) && x >= 0);
142 FML_DCHECK(std::isfinite(y) && y >= 0);
143 FML_DCHECK(ctm.isFinite() && !ctm.hasPerspective());
144
145 // The x and y scalars would have been used to expand a local space
146 // rectangle which is then transformed by ctm. In order to do the
147 // expansion correctly, we should look at the relevant math. The
148 // 4 corners will be moved outward by the following vectors:
149 // (UL,UR,LR,LL) = ((-x, -y), (+x, -y), (+x, +y), (-x, +y))
150 // After applying the transform, each of these vectors could be
151 // pointing in any direction so we need to examine each transformed
152 // delta vector and how it affected the bounds.
153 // Looking at just the affine 2x3 entries of the CTM we can delta
154 // transform these corner offsets and get the following:
155 // UL = dCTM(-x, -y) = (- x*m00 - y*m01, - x*m10 - y*m11)
156 // UR = dCTM(+x, -y) = ( x*m00 - y*m01, x*m10 - y*m11)
157 // LR = dCTM(+x, +y) = ( x*m00 + y*m01, x*m10 + y*m11)
158 // LL = dCTM(-x, +y) = (- x*m00 + y*m01, - x*m10 + y*m11)
159 // The X vectors are all some variation of adding or subtracting
160 // the sum of x*m00 and y*m01 or their difference. Similarly the Y
161 // vectors are +/- the associated sum/difference of x*m10 and y*m11.
162 // The largest displacements, both left/right or up/down, will
163 // happen when the signs of the m00/m01/m10/m11 matrix entries
164 // coincide with the signs of the scalars, i.e. are all positive.
165 return {x * abs(ctm[0]) + y * abs(ctm[1]),
166 x * abs(ctm[3]) + y * abs(ctm[4])};
167 }
168
169 static SkIRect* inset_device_bounds(const SkIRect& input_bounds,
170 SkScalar radius_x,
171 SkScalar radius_y,
172 const SkMatrix& ctm,
173 SkIRect& output_bounds) {
174 if (ctm.isFinite()) {
175 if (ctm.hasPerspective()) {
176 SkMatrix inverse;
177 if (ctm.invert(&inverse)) {
178 SkRect local_bounds = inverse.mapRect(SkRect::Make(input_bounds));
179 local_bounds.inset(radius_x, radius_y);
180 output_bounds = ctm.mapRect(local_bounds).roundOut();
181 return &output_bounds;
182 }
183 } else {
184 SkVector device_radius = map_vectors_affine(ctm, radius_x, radius_y);
185 output_bounds = input_bounds.makeInset(floor(device_radius.fX), //
186 floor(device_radius.fY));
187 return &output_bounds;
188 }
189 }
190 output_bounds = input_bounds;
191 return nullptr;
192 }
193
194 static SkIRect* outset_device_bounds(const SkIRect& input_bounds,
195 SkScalar radius_x,
196 SkScalar radius_y,
197 const SkMatrix& ctm,
198 SkIRect& output_bounds) {
199 if (ctm.isFinite()) {
200 if (ctm.hasPerspective()) {
201 SkMatrix inverse;
202 if (ctm.invert(&inverse)) {
203 SkRect local_bounds = inverse.mapRect(SkRect::Make(input_bounds));
204 local_bounds.outset(radius_x, radius_y);
205 output_bounds = ctm.mapRect(local_bounds).roundOut();
206 return &output_bounds;
207 }
208 } else {
209 SkVector device_radius = map_vectors_affine(ctm, radius_x, radius_y);
210 output_bounds = input_bounds.makeOutset(ceil(device_radius.fX), //
211 ceil(device_radius.fY));
212 return &output_bounds;
213 }
214 }
215 output_bounds = input_bounds;
216 return nullptr;
217 }
218};
219
220class DlBlurImageFilter final : public DlImageFilter {
221 public:
223 : sigma_x_(sigma_x), sigma_y_(sigma_y), tile_mode_(tile_mode) {}
224 explicit DlBlurImageFilter(const DlBlurImageFilter* filter)
225 : DlBlurImageFilter(filter->sigma_x_,
226 filter->sigma_y_,
227 filter->tile_mode_) {}
229 : DlBlurImageFilter(&filter) {}
230
231 static std::shared_ptr<DlImageFilter> Make(SkScalar sigma_x,
235 return nullptr;
236 }
238 return nullptr;
239 }
242 return std::make_shared<DlBlurImageFilter>(sigma_x, sigma_y, tile_mode);
243 }
244
245 std::shared_ptr<DlImageFilter> shared() const override {
246 return std::make_shared<DlBlurImageFilter>(this);
247 }
248
250 size_t size() const override { return sizeof(*this); }
251
252 const DlBlurImageFilter* asBlur() const override { return this; }
253
254 bool modifies_transparent_black() const override { return false; }
255
256 SkRect* map_local_bounds(const SkRect& input_bounds,
257 SkRect& output_bounds) const override {
258 output_bounds = input_bounds.makeOutset(sigma_x_ * 3.0f, sigma_y_ * 3.0f);
259 return &output_bounds;
260 }
261
262 SkIRect* map_device_bounds(const SkIRect& input_bounds,
263 const SkMatrix& ctm,
264 SkIRect& output_bounds) const override {
265 return outset_device_bounds(input_bounds, sigma_x_ * 3.0f, sigma_y_ * 3.0f,
266 ctm, output_bounds);
267 }
268
270 const SkMatrix& ctm,
271 SkIRect& input_bounds) const override {
272 // Blurs are symmetric in terms of output-for-input and input-for-output
273 return map_device_bounds(output_bounds, ctm, input_bounds);
274 }
275
276 SkScalar sigma_x() const { return sigma_x_; }
277 SkScalar sigma_y() const { return sigma_y_; }
278 DlTileMode tile_mode() const { return tile_mode_; }
279
280 protected:
281 bool equals_(const DlImageFilter& other) const override {
283 auto that = static_cast<const DlBlurImageFilter*>(&other);
284 return (sigma_x_ == that->sigma_x_ && sigma_y_ == that->sigma_y_ &&
285 tile_mode_ == that->tile_mode_);
286 }
287
288 private:
289 SkScalar sigma_x_;
290 SkScalar sigma_y_;
291 DlTileMode tile_mode_;
292};
293
294class DlDilateImageFilter final : public DlImageFilter {
295 public:
297 : radius_x_(radius_x), radius_y_(radius_y) {}
299 : DlDilateImageFilter(filter->radius_x_, filter->radius_y_) {}
301 : DlDilateImageFilter(&filter) {}
302
303 static std::shared_ptr<DlImageFilter> Make(SkScalar radius_x,
307 return std::make_shared<DlDilateImageFilter>(radius_x, radius_y);
308 }
309 return nullptr;
310 }
311
312 std::shared_ptr<DlImageFilter> shared() const override {
313 return std::make_shared<DlDilateImageFilter>(this);
314 }
315
317 size_t size() const override { return sizeof(*this); }
318
319 const DlDilateImageFilter* asDilate() const override { return this; }
320
321 bool modifies_transparent_black() const override { return false; }
322
323 SkRect* map_local_bounds(const SkRect& input_bounds,
324 SkRect& output_bounds) const override {
325 output_bounds = input_bounds.makeOutset(radius_x_, radius_y_);
326 return &output_bounds;
327 }
328
329 SkIRect* map_device_bounds(const SkIRect& input_bounds,
330 const SkMatrix& ctm,
331 SkIRect& output_bounds) const override {
332 return outset_device_bounds(input_bounds, radius_x_, radius_y_, ctm,
333 output_bounds);
334 }
335
337 const SkMatrix& ctm,
338 SkIRect& input_bounds) const override {
339 return inset_device_bounds(output_bounds, radius_x_, radius_y_, ctm,
340 input_bounds);
341 }
342
343 SkScalar radius_x() const { return radius_x_; }
344 SkScalar radius_y() const { return radius_y_; }
345
346 protected:
347 bool equals_(const DlImageFilter& other) const override {
349 auto that = static_cast<const DlDilateImageFilter*>(&other);
350 return (radius_x_ == that->radius_x_ && radius_y_ == that->radius_y_);
351 }
352
353 private:
354 SkScalar radius_x_;
355 SkScalar radius_y_;
356};
357
358class DlErodeImageFilter final : public DlImageFilter {
359 public:
361 : radius_x_(radius_x), radius_y_(radius_y) {}
363 : DlErodeImageFilter(filter->radius_x_, filter->radius_y_) {}
365 : DlErodeImageFilter(&filter) {}
366
367 static std::shared_ptr<DlImageFilter> Make(SkScalar radius_x,
371 return std::make_shared<DlErodeImageFilter>(radius_x, radius_y);
372 }
373 return nullptr;
374 }
375
376 std::shared_ptr<DlImageFilter> shared() const override {
377 return std::make_shared<DlErodeImageFilter>(this);
378 }
379
381 size_t size() const override { return sizeof(*this); }
382
383 const DlErodeImageFilter* asErode() const override { return this; }
384
385 bool modifies_transparent_black() const override { return false; }
386
387 SkRect* map_local_bounds(const SkRect& input_bounds,
388 SkRect& output_bounds) const override {
389 output_bounds = input_bounds.makeInset(radius_x_, radius_y_);
390 return &output_bounds;
391 }
392
393 SkIRect* map_device_bounds(const SkIRect& input_bounds,
394 const SkMatrix& ctm,
395 SkIRect& output_bounds) const override {
396 return inset_device_bounds(input_bounds, radius_x_, radius_y_, ctm,
397 output_bounds);
398 }
399
401 const SkMatrix& ctm,
402 SkIRect& input_bounds) const override {
403 return outset_device_bounds(output_bounds, radius_x_, radius_y_, ctm,
404 input_bounds);
405 }
406
407 SkScalar radius_x() const { return radius_x_; }
408 SkScalar radius_y() const { return radius_y_; }
409
410 protected:
411 bool equals_(const DlImageFilter& other) const override {
413 auto that = static_cast<const DlErodeImageFilter*>(&other);
414 return (radius_x_ == that->radius_x_ && radius_y_ == that->radius_y_);
415 }
416
417 private:
418 SkScalar radius_x_;
419 SkScalar radius_y_;
420};
421
422class DlMatrixImageFilter final : public DlImageFilter {
423 public:
425 : matrix_(matrix), sampling_(sampling) {}
427 : DlMatrixImageFilter(filter->matrix_, filter->sampling_) {}
429 : DlMatrixImageFilter(&filter) {}
430
431 static std::shared_ptr<DlImageFilter> Make(const SkMatrix& matrix,
433 if (matrix.isFinite() && !matrix.isIdentity()) {
434 return std::make_shared<DlMatrixImageFilter>(matrix, sampling);
435 }
436 return nullptr;
437 }
438
439 std::shared_ptr<DlImageFilter> shared() const override {
440 return std::make_shared<DlMatrixImageFilter>(this);
441 }
442
444 size_t size() const override { return sizeof(*this); }
445
446 const SkMatrix& matrix() const { return matrix_; }
447 DlImageSampling sampling() const { return sampling_; }
448
449 const DlMatrixImageFilter* asMatrix() const override { return this; }
450
451 bool modifies_transparent_black() const override { return false; }
452
453 SkRect* map_local_bounds(const SkRect& input_bounds,
454 SkRect& output_bounds) const override {
455 output_bounds = matrix_.mapRect(input_bounds);
456 return &output_bounds;
457 }
458
459 SkIRect* map_device_bounds(const SkIRect& input_bounds,
460 const SkMatrix& ctm,
461 SkIRect& output_bounds) const override {
463 if (!ctm.invert(&matrix)) {
464 output_bounds = input_bounds;
465 return nullptr;
466 }
467 matrix.postConcat(matrix_);
468 matrix.postConcat(ctm);
469 SkRect device_rect;
470 matrix.mapRect(&device_rect, SkRect::Make(input_bounds));
471 output_bounds = device_rect.roundOut();
472 return &output_bounds;
473 }
474
476 const SkMatrix& ctm,
477 SkIRect& input_bounds) const override {
478 SkMatrix matrix = SkMatrix::Concat(ctm, matrix_);
479 SkMatrix inverse;
480 if (!matrix.invert(&inverse)) {
481 input_bounds = output_bounds;
482 return nullptr;
483 }
484 inverse.postConcat(ctm);
486 bounds.set(output_bounds);
487 inverse.mapRect(&bounds);
488 input_bounds = bounds.roundOut();
489 return &input_bounds;
490 }
491
492 protected:
493 bool equals_(const DlImageFilter& other) const override {
495 auto that = static_cast<const DlMatrixImageFilter*>(&other);
496 return (matrix_ == that->matrix_ && sampling_ == that->sampling_);
497 }
498
499 private:
500 SkMatrix matrix_;
501 DlImageSampling sampling_;
502};
503
505 public:
506 DlComposeImageFilter(std::shared_ptr<const DlImageFilter> outer,
507 std::shared_ptr<const DlImageFilter> inner)
508 : outer_(std::move(outer)), inner_(std::move(inner)) {}
510 : outer_(outer->shared()), inner_(inner->shared()) {}
514 : DlComposeImageFilter(filter->outer_, filter->inner_) {}
516 : DlComposeImageFilter(&filter) {}
517
518 static std::shared_ptr<const DlImageFilter> Make(
519 std::shared_ptr<const DlImageFilter> outer,
520 std::shared_ptr<const DlImageFilter> inner) {
521 if (!outer) {
522 return inner;
523 }
524 if (!inner) {
525 return outer;
526 }
527 return std::make_shared<DlComposeImageFilter>(outer, inner);
528 }
529
530 std::shared_ptr<DlImageFilter> shared() const override {
531 return std::make_shared<DlComposeImageFilter>(this);
532 }
533
534 DlImageFilterType type() const override {
536 }
537 size_t size() const override { return sizeof(*this); }
538
539 std::shared_ptr<const DlImageFilter> outer() const { return outer_; }
540 std::shared_ptr<const DlImageFilter> inner() const { return inner_; }
541
542 const DlComposeImageFilter* asCompose() const override { return this; }
543
544 bool modifies_transparent_black() const override {
545 if (inner_ && inner_->modifies_transparent_black()) {
546 return true;
547 }
548 if (outer_ && outer_->modifies_transparent_black()) {
549 return true;
550 }
551 return false;
552 }
553
554 SkRect* map_local_bounds(const SkRect& input_bounds,
555 SkRect& output_bounds) const override;
556
557 SkIRect* map_device_bounds(const SkIRect& input_bounds,
558 const SkMatrix& ctm,
559 SkIRect& output_bounds) const override;
560
561 SkIRect* get_input_device_bounds(const SkIRect& output_bounds,
562 const SkMatrix& ctm,
563 SkIRect& input_bounds) const override;
564
566 return std::min(outer_->matrix_capability(), inner_->matrix_capability());
567 }
568
569 protected:
570 bool equals_(const DlImageFilter& other) const override {
572 auto that = static_cast<const DlComposeImageFilter*>(&other);
573 return (Equals(outer_, that->outer_) && Equals(inner_, that->inner_));
574 }
575
576 private:
577 std::shared_ptr<const DlImageFilter> outer_;
578 std::shared_ptr<const DlImageFilter> inner_;
579};
580
582 public:
583 explicit DlColorFilterImageFilter(std::shared_ptr<const DlColorFilter> filter)
584 : color_filter_(std::move(filter)) {}
586 : color_filter_(filter->shared()) {}
588 : color_filter_(filter.shared()) {}
590 : DlColorFilterImageFilter(filter->color_filter_) {}
592 : DlColorFilterImageFilter(&filter) {}
593
594 static std::shared_ptr<DlImageFilter> Make(
595 const std::shared_ptr<const DlColorFilter>& filter) {
596 if (filter) {
597 return std::make_shared<DlColorFilterImageFilter>(filter);
598 }
599 return nullptr;
600 }
601
602 std::shared_ptr<DlImageFilter> shared() const override {
603 return std::make_shared<DlColorFilterImageFilter>(color_filter_);
604 }
605
606 DlImageFilterType type() const override {
608 }
609 size_t size() const override { return sizeof(*this); }
610
611 const std::shared_ptr<const DlColorFilter> color_filter() const {
612 return color_filter_;
613 }
614
615 const DlColorFilterImageFilter* asColorFilter() const override {
616 return this;
617 }
618
619 bool modifies_transparent_black() const override {
620 if (color_filter_) {
621 return color_filter_->modifies_transparent_black();
622 }
623 return false;
624 }
625
626 SkRect* map_local_bounds(const SkRect& input_bounds,
627 SkRect& output_bounds) const override {
628 output_bounds = input_bounds;
629 return modifies_transparent_black() ? nullptr : &output_bounds;
630 }
631
632 SkIRect* map_device_bounds(const SkIRect& input_bounds,
633 const SkMatrix& ctm,
634 SkIRect& output_bounds) const override {
635 output_bounds = input_bounds;
636 return modifies_transparent_black() ? nullptr : &output_bounds;
637 }
638
640 const SkMatrix& ctm,
641 SkIRect& input_bounds) const override {
642 return map_device_bounds(output_bounds, ctm, input_bounds);
643 }
644
647 }
648
649 std::shared_ptr<DlImageFilter> makeWithLocalMatrix(
650 const SkMatrix& matrix) const override {
651 return shared();
652 }
653
654 protected:
655 bool equals_(const DlImageFilter& other) const override {
657 auto that = static_cast<const DlColorFilterImageFilter*>(&other);
658 return Equals(color_filter_, that->color_filter_);
659 }
660
661 private:
662 std::shared_ptr<const DlColorFilter> color_filter_;
663};
664
666 public:
668 std::shared_ptr<DlImageFilter> filter)
669 : matrix_(matrix), image_filter_(std::move(filter)) {}
671 : DlLocalMatrixImageFilter(filter->matrix_, filter->image_filter_) {}
673 : DlLocalMatrixImageFilter(&filter) {}
674 std::shared_ptr<DlImageFilter> shared() const override {
675 return std::make_shared<DlLocalMatrixImageFilter>(this);
676 }
677
678 DlImageFilterType type() const override {
680 }
681 size_t size() const override { return sizeof(*this); }
682
683 const SkMatrix& matrix() const { return matrix_; }
684
685 const std::shared_ptr<DlImageFilter> image_filter() const {
686 return image_filter_;
687 }
688
689 const DlLocalMatrixImageFilter* asLocalMatrix() const override {
690 return this;
691 }
692
693 bool modifies_transparent_black() const override {
694 if (!image_filter_) {
695 return false;
696 }
697 return image_filter_->modifies_transparent_black();
698 }
699
700 SkRect* map_local_bounds(const SkRect& input_bounds,
701 SkRect& output_bounds) const override {
702 if (!image_filter_) {
703 output_bounds = input_bounds;
704 return &output_bounds;
705 }
706 return image_filter_->map_local_bounds(input_bounds, output_bounds);
707 }
708
709 SkIRect* map_device_bounds(const SkIRect& input_bounds,
710 const SkMatrix& ctm,
711 SkIRect& output_bounds) const override {
712 if (!image_filter_) {
713 output_bounds = input_bounds;
714 return &output_bounds;
715 }
716 return image_filter_->map_device_bounds(
717 input_bounds, SkMatrix::Concat(ctm, matrix_), output_bounds);
718 }
719
721 const SkMatrix& ctm,
722 SkIRect& input_bounds) const override {
723 if (!image_filter_) {
724 input_bounds = output_bounds;
725 return &input_bounds;
726 }
727 return image_filter_->get_input_device_bounds(
728 output_bounds, SkMatrix::Concat(ctm, matrix_), input_bounds);
729 }
730
731 protected:
732 bool equals_(const DlImageFilter& other) const override {
734 auto that = static_cast<const DlLocalMatrixImageFilter*>(&other);
735 return (matrix_ == that->matrix_ &&
736 Equals(image_filter_, that->image_filter_));
737 }
738
739 private:
740 SkMatrix matrix_;
741 std::shared_ptr<DlImageFilter> image_filter_;
742};
743
744} // namespace flutter
745
746#endif // FLUTTER_DISPLAY_LIST_EFFECTS_DL_IMAGE_FILTER_H_
#define SK_ScalarNearlyZero
Definition: SkScalar.h:99
SkMatrix & postConcat(const SkMatrix &other)
Definition: SkMatrix.cpp:683
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
Definition: SkMatrix.h:1775
bool invert(SkMatrix *inverse) const
Definition: SkMatrix.h:1206
bool hasPerspective() const
Definition: SkMatrix.h:312
bool isFinite() const
Definition: SkMatrix.h:1834
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition: SkMatrix.cpp:1141
bool isIdentity() const
Definition: SkMatrix.h:223
virtual T type() const =0
bool modifies_transparent_black() const override
DlImageFilterType type() const override
std::shared_ptr< DlImageFilter > shared() const override
DlBlurImageFilter(SkScalar sigma_x, SkScalar sigma_y, DlTileMode tile_mode)
SkIRect * map_device_bounds(const SkIRect &input_bounds, const SkMatrix &ctm, SkIRect &output_bounds) const override
static std::shared_ptr< DlImageFilter > Make(SkScalar sigma_x, SkScalar sigma_y, DlTileMode tile_mode)
SkIRect * get_input_device_bounds(const SkIRect &output_bounds, const SkMatrix &ctm, SkIRect &input_bounds) const override
SkRect * map_local_bounds(const SkRect &input_bounds, SkRect &output_bounds) const override
bool equals_(const DlImageFilter &other) const override
const DlBlurImageFilter * asBlur() const override
size_t size() const override
DlBlurImageFilter(const DlBlurImageFilter *filter)
DlTileMode tile_mode() const
DlBlurImageFilter(const DlBlurImageFilter &filter)
DlColorFilterImageFilter(const DlColorFilterImageFilter *filter)
MatrixCapability matrix_capability() const override
static std::shared_ptr< DlImageFilter > Make(const std::shared_ptr< const DlColorFilter > &filter)
const std::shared_ptr< const DlColorFilter > color_filter() const
bool modifies_transparent_black() const override
DlColorFilterImageFilter(const DlColorFilterImageFilter &filter)
SkRect * map_local_bounds(const SkRect &input_bounds, SkRect &output_bounds) const override
SkIRect * get_input_device_bounds(const SkIRect &output_bounds, const SkMatrix &ctm, SkIRect &input_bounds) const override
DlColorFilterImageFilter(std::shared_ptr< const DlColorFilter > filter)
SkIRect * map_device_bounds(const SkIRect &input_bounds, const SkMatrix &ctm, SkIRect &output_bounds) const override
DlImageFilterType type() const override
size_t size() const override
std::shared_ptr< DlImageFilter > makeWithLocalMatrix(const SkMatrix &matrix) const override
const DlColorFilterImageFilter * asColorFilter() const override
DlColorFilterImageFilter(const DlColorFilter &filter)
bool equals_(const DlImageFilter &other) const override
DlColorFilterImageFilter(const DlColorFilter *filter)
std::shared_ptr< DlImageFilter > shared() const override
DlComposeImageFilter(const DlComposeImageFilter *filter)
DlComposeImageFilter(const DlComposeImageFilter &filter)
DlComposeImageFilter(const DlImageFilter *outer, const DlImageFilter *inner)
std::shared_ptr< DlImageFilter > shared() const override
DlComposeImageFilter(const DlImageFilter &outer, const DlImageFilter &inner)
MatrixCapability matrix_capability() const override
const DlComposeImageFilter * asCompose() const override
SkIRect * get_input_device_bounds(const SkIRect &output_bounds, const SkMatrix &ctm, SkIRect &input_bounds) const override
DlComposeImageFilter(std::shared_ptr< const DlImageFilter > outer, std::shared_ptr< const DlImageFilter > inner)
std::shared_ptr< const DlImageFilter > outer() const
SkRect * map_local_bounds(const SkRect &input_bounds, SkRect &output_bounds) const override
SkIRect * map_device_bounds(const SkIRect &input_bounds, const SkMatrix &ctm, SkIRect &output_bounds) const override
std::shared_ptr< const DlImageFilter > inner() const
bool modifies_transparent_black() const override
bool equals_(const DlImageFilter &other) const override
static std::shared_ptr< const DlImageFilter > Make(std::shared_ptr< const DlImageFilter > outer, std::shared_ptr< const DlImageFilter > inner)
size_t size() const override
DlImageFilterType type() const override
SkRect * map_local_bounds(const SkRect &input_bounds, SkRect &output_bounds) const override
DlDilateImageFilter(SkScalar radius_x, SkScalar radius_y)
bool modifies_transparent_black() const override
SkIRect * map_device_bounds(const SkIRect &input_bounds, const SkMatrix &ctm, SkIRect &output_bounds) const override
const DlDilateImageFilter * asDilate() const override
SkIRect * get_input_device_bounds(const SkIRect &output_bounds, const SkMatrix &ctm, SkIRect &input_bounds) const override
std::shared_ptr< DlImageFilter > shared() const override
DlImageFilterType type() const override
static std::shared_ptr< DlImageFilter > Make(SkScalar radius_x, SkScalar radius_y)
bool equals_(const DlImageFilter &other) const override
size_t size() const override
DlDilateImageFilter(const DlDilateImageFilter &filter)
DlDilateImageFilter(const DlDilateImageFilter *filter)
bool equals_(const DlImageFilter &other) const override
SkIRect * get_input_device_bounds(const SkIRect &output_bounds, const SkMatrix &ctm, SkIRect &input_bounds) const override
const DlErodeImageFilter * asErode() const override
static std::shared_ptr< DlImageFilter > Make(SkScalar radius_x, SkScalar radius_y)
std::shared_ptr< DlImageFilter > shared() const override
size_t size() const override
DlImageFilterType type() const override
DlErodeImageFilter(SkScalar radius_x, SkScalar radius_y)
SkRect * map_local_bounds(const SkRect &input_bounds, SkRect &output_bounds) const override
bool modifies_transparent_black() const override
SkIRect * map_device_bounds(const SkIRect &input_bounds, const SkMatrix &ctm, SkIRect &output_bounds) const override
DlErodeImageFilter(const DlErodeImageFilter &filter)
DlErodeImageFilter(const DlErodeImageFilter *filter)
virtual const DlLocalMatrixImageFilter * asLocalMatrix() const
virtual const DlColorFilterImageFilter * asColorFilter() const
virtual SkIRect * map_device_bounds(const SkIRect &input_bounds, const SkMatrix &ctm, SkIRect &output_bounds) const =0
static SkIRect * outset_device_bounds(const SkIRect &input_bounds, SkScalar radius_x, SkScalar radius_y, const SkMatrix &ctm, SkIRect &output_bounds)
virtual const DlMatrixImageFilter * asMatrix() const
virtual bool modifies_transparent_black() const =0
static SkIRect * inset_device_bounds(const SkIRect &input_bounds, SkScalar radius_x, SkScalar radius_y, const SkMatrix &ctm, SkIRect &output_bounds)
virtual const DlComposeImageFilter * asCompose() const
virtual SkRect * map_local_bounds(const SkRect &input_bounds, SkRect &output_bounds) const =0
virtual SkIRect * get_input_device_bounds(const SkIRect &output_bounds, const SkMatrix &ctm, SkIRect &input_bounds) const =0
virtual MatrixCapability matrix_capability() const
virtual const DlBlurImageFilter * asBlur() const
static SkVector map_vectors_affine(const SkMatrix &ctm, SkScalar x, SkScalar y)
virtual const DlDilateImageFilter * asDilate() const
virtual const DlErodeImageFilter * asErode() const
virtual std::shared_ptr< DlImageFilter > makeWithLocalMatrix(const SkMatrix &matrix) const
size_t size() const override
const SkMatrix & matrix() const
DlLocalMatrixImageFilter(const DlLocalMatrixImageFilter &filter)
SkIRect * map_device_bounds(const SkIRect &input_bounds, const SkMatrix &ctm, SkIRect &output_bounds) const override
const DlLocalMatrixImageFilter * asLocalMatrix() const override
bool equals_(const DlImageFilter &other) const override
bool modifies_transparent_black() const override
DlLocalMatrixImageFilter(const DlLocalMatrixImageFilter *filter)
DlImageFilterType type() const override
DlLocalMatrixImageFilter(const SkMatrix &matrix, std::shared_ptr< DlImageFilter > filter)
SkRect * map_local_bounds(const SkRect &input_bounds, SkRect &output_bounds) const override
const std::shared_ptr< DlImageFilter > image_filter() const
std::shared_ptr< DlImageFilter > shared() const override
SkIRect * get_input_device_bounds(const SkIRect &output_bounds, const SkMatrix &ctm, SkIRect &input_bounds) const override
DlMatrixImageFilter(const DlMatrixImageFilter *filter)
const DlMatrixImageFilter * asMatrix() const override
DlMatrixImageFilter(const DlMatrixImageFilter &filter)
DlImageFilterType type() const override
SkIRect * map_device_bounds(const SkIRect &input_bounds, const SkMatrix &ctm, SkIRect &output_bounds) const override
std::shared_ptr< DlImageFilter > shared() const override
bool modifies_transparent_black() const override
SkIRect * get_input_device_bounds(const SkIRect &output_bounds, const SkMatrix &ctm, SkIRect &input_bounds) const override
const SkMatrix & matrix() const
static std::shared_ptr< DlImageFilter > Make(const SkMatrix &matrix, DlImageSampling sampling)
size_t size() const override
DlImageSampling sampling() const
DlMatrixImageFilter(const SkMatrix &matrix, DlImageSampling sampling)
bool equals_(const DlImageFilter &other) const override
SkRect * map_local_bounds(const SkRect &input_bounds, SkRect &output_bounds) const override
float SkScalar
Definition: extension.cpp:12
#define FML_DCHECK(condition)
Definition: logging.h:103
static float min(float r, float g, float b)
Definition: hsl.cpp:48
double y
double x
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
Optional< SkRect > bounds
Definition: SkRecords.h:189
bool Equals(const T *a, const T *b)
Definition: dl_comparable.h:19
@ kBlur
Definition: paint.cc:59
SINT bool isfinite(const Vec< N, T > &v)
Definition: SkVx.h:1003
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition: SkVx.h:707
SIN Vec< N, float > floor(const Vec< N, float > &x)
Definition: SkVx.h:703
SIN Vec< N, float > ceil(const Vec< N, float > &x)
Definition: SkVx.h:702
Definition: ref_ptr.h:256
Definition: SkRect.h:32
SkIRect makeOutset(int32_t dx, int32_t dy) const
Definition: SkRect.h:350
SkIRect makeInset(int32_t dx, int32_t dy) const
Definition: SkRect.h:332
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
void inset(float dx, float dy)
Definition: SkRect.h:1060
void outset(float dx, float dy)
Definition: SkRect.h:1077
SkRect makeOutset(float dx, float dy) const
Definition: SkRect.h:1002
SkRect makeInset(float dx, float dy) const
Definition: SkRect.h:987
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241