-
Notifications
You must be signed in to change notification settings - Fork 6k
Create DlLocalMatrixImageFilter #34878
Changes from all commits
d48807e
e19c17b
8c91fb3
de99e7d
c323d42
9f48c9c
abd475b
97864c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,19 +34,27 @@ enum class DlImageFilterType { | |
| kMatrix, | ||
| kComposeFilter, | ||
| kColorFilter, | ||
| kLocalMatrixFilter, | ||
| kUnknown | ||
| }; | ||
|
|
||
| class DlBlurImageFilter; | ||
| class DlDilateImageFilter; | ||
| class DlErodeImageFilter; | ||
| class DlMatrixImageFilter; | ||
| class DlLocalMatrixImageFilter; | ||
| class DlComposeImageFilter; | ||
| class DlColorFilterImageFilter; | ||
|
|
||
| class DlImageFilter | ||
| : public DlAttribute<DlImageFilter, SkImageFilter, DlImageFilterType> { | ||
| public: | ||
| enum class MatrixCapability { | ||
| kTranslate, | ||
| kScaleTranslate, | ||
| kComplex, | ||
| }; | ||
|
|
||
| // Return a shared_ptr holding a DlImageFilter representing the indicated | ||
| // Skia SkImageFilter pointer. | ||
| // | ||
|
|
@@ -82,6 +90,13 @@ class DlImageFilter | |
| // type of ImageFilter, otherwise return nullptr. | ||
| virtual const DlMatrixImageFilter* asMatrix() const { return nullptr; } | ||
|
|
||
| virtual const DlLocalMatrixImageFilter* asLocalMatrix() const { | ||
| return nullptr; | ||
| } | ||
|
|
||
| virtual std::shared_ptr<DlImageFilter> makeWithLocalMatrix( | ||
| const SkMatrix& matrix); | ||
|
|
||
| // Return a DlComposeImageFilter pointer to this object iff it is a Compose | ||
| // type of ImageFilter, otherwise return nullptr. | ||
| virtual const DlComposeImageFilter* asCompose() const { return nullptr; } | ||
|
|
@@ -137,6 +152,10 @@ class DlImageFilter | |
| const SkMatrix& ctm, | ||
| SkIRect& input_bounds) const = 0; | ||
|
|
||
| virtual MatrixCapability matrix_capability() const { | ||
| return MatrixCapability::kScaleTranslate; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where did you get information about the compatibility here?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In Skia, the ImageFilter has a method |
||
| } | ||
|
|
||
| protected: | ||
| static SkVector map_vectors_affine(const SkMatrix& ctm, | ||
| SkScalar x, | ||
|
|
@@ -534,6 +553,10 @@ class DlComposeImageFilter final : public DlImageFilter { | |
| inner_->skia_object()); | ||
| } | ||
|
|
||
| MatrixCapability matrix_capability() const override { | ||
| return std::min(outer_->matrix_capability(), inner_->matrix_capability()); | ||
| } | ||
|
|
||
| protected: | ||
| bool equals_(const DlImageFilter& other) const override { | ||
| FML_DCHECK(other.type() == DlImageFilterType::kComposeFilter); | ||
|
|
@@ -606,6 +629,15 @@ class DlColorFilterImageFilter final : public DlImageFilter { | |
| return SkImageFilters::ColorFilter(color_filter_->skia_object(), nullptr); | ||
| } | ||
|
|
||
| MatrixCapability matrix_capability() const override { | ||
flar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return MatrixCapability::kComplex; | ||
| } | ||
|
|
||
| std::shared_ptr<DlImageFilter> makeWithLocalMatrix( | ||
| const SkMatrix& matrix) override { | ||
| return shared(); | ||
| } | ||
|
|
||
| protected: | ||
| bool equals_(const DlImageFilter& other) const override { | ||
| FML_DCHECK(other.type() == DlImageFilterType::kColorFilter); | ||
|
|
@@ -617,6 +649,85 @@ class DlColorFilterImageFilter final : public DlImageFilter { | |
| std::shared_ptr<DlColorFilter> color_filter_; | ||
| }; | ||
|
|
||
| class DlLocalMatrixImageFilter final : public DlImageFilter { | ||
| public: | ||
| explicit DlLocalMatrixImageFilter(const SkMatrix& matrix, | ||
| std::shared_ptr<DlImageFilter> filter) | ||
| : matrix_(matrix), image_filter_(filter) {} | ||
| explicit DlLocalMatrixImageFilter(const DlLocalMatrixImageFilter* filter) | ||
| : DlLocalMatrixImageFilter(filter->matrix_, filter->image_filter_) {} | ||
| DlLocalMatrixImageFilter(const DlLocalMatrixImageFilter& filter) | ||
| : DlLocalMatrixImageFilter(&filter) {} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no protection against a null filter in the constructors so everywhere |
||
| std::shared_ptr<DlImageFilter> shared() const override { | ||
| return std::make_shared<DlLocalMatrixImageFilter>(this); | ||
| } | ||
|
|
||
| DlImageFilterType type() const override { | ||
| return DlImageFilterType::kLocalMatrixFilter; | ||
| } | ||
| size_t size() const override { return sizeof(*this); } | ||
|
|
||
| const SkMatrix& matrix() const { return matrix_; } | ||
|
|
||
| const DlLocalMatrixImageFilter* asLocalMatrix() const override { | ||
| return this; | ||
| } | ||
|
|
||
| bool modifies_transparent_black() const override { | ||
| if (!image_filter_) { | ||
| return false; | ||
| } | ||
| return image_filter_->modifies_transparent_black(); | ||
| } | ||
|
|
||
| SkRect* map_local_bounds(const SkRect& input_bounds, | ||
| SkRect& output_bounds) const override { | ||
| if (!image_filter_) { | ||
| return nullptr; | ||
| } | ||
| return image_filter_->map_local_bounds(input_bounds, output_bounds); | ||
| } | ||
|
|
||
| SkIRect* map_device_bounds(const SkIRect& input_bounds, | ||
| const SkMatrix& ctm, | ||
| SkIRect& output_bounds) const override { | ||
| if (!image_filter_) { | ||
| return nullptr; | ||
| } | ||
| return image_filter_->map_device_bounds( | ||
| input_bounds, SkMatrix::Concat(ctm, matrix_), output_bounds); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The input bounds are relative to
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I'm wondering what Skia does with this. Have you run tests to see how the bounds methods behave with a local matrix?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a test case: auto blur_filter = SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat, nullptr);
auto local_filter = blur_filter->makeWithLocalMatrix(SkMatrix::Scale(2, 2));
auto inputBounds = SkIRect::MakeLTRB(20, 20, 80, 80);
auto rect = local_filter->filterBounds(inputBounds, SkMatrix::I(), SkImageFilter::MapDirection::kForward_MapDirection);
auto dl_color_filter = std::make_shared<DlBlurImageFilter>(5.0, 6.0, DlTileMode::kRepeat);
auto local_matrix_filter = DlLocalMatrixImageFilter(SkMatrix::Scale(2, 2), dl_color_filter);
SkIRect out_bounds;
local_matrix_filter.map_device_bounds(inputBounds, SkMatrix::I(),out_bounds);
ASSERT_EQ(out_bounds, rect);the out_bouns is equal the rect when we use
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a very basic test of some of the cases that have the fewest quirks in them. Try something like: Transform types should be:
|
||
| } | ||
|
|
||
| SkIRect* get_input_device_bounds(const SkIRect& output_bounds, | ||
| const SkMatrix& ctm, | ||
| SkIRect& input_bounds) const override { | ||
| if (!image_filter_) { | ||
| return nullptr; | ||
| } | ||
| return image_filter_->get_input_device_bounds( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as |
||
| output_bounds, SkMatrix::Concat(ctm, matrix_), input_bounds); | ||
| } | ||
|
|
||
| sk_sp<SkImageFilter> skia_object() const override { | ||
| if (!image_filter_) { | ||
| return nullptr; | ||
| } | ||
| return image_filter_->skia_object()->makeWithLocalMatrix(matrix_); | ||
| } | ||
|
|
||
| protected: | ||
| bool equals_(const DlImageFilter& other) const override { | ||
| FML_DCHECK(other.type() == DlImageFilterType::kMatrix); | ||
| auto that = static_cast<const DlLocalMatrixImageFilter*>(&other); | ||
| return (matrix_ == that->matrix_ && | ||
| Equals(image_filter_, that->image_filter_)); | ||
| } | ||
|
|
||
| private: | ||
| SkMatrix matrix_; | ||
| std::shared_ptr<DlImageFilter> image_filter_; | ||
| }; | ||
|
|
||
| // A wrapper class for a Skia ImageFilter of unknown type. The above 4 types | ||
| // are the only types that can be constructed by Flutter using the | ||
| // ui.ImageFilter class so this class should be rarely used. The main use | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.