diff options
Diffstat (limited to 'src/effects/SkXfermodeImageFilter.cpp')
-rw-r--r-- | src/effects/SkXfermodeImageFilter.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp index f7ce0a3027..ddc5d99b5e 100644 --- a/src/effects/SkXfermodeImageFilter.cpp +++ b/src/effects/SkXfermodeImageFilter.cpp @@ -40,6 +40,8 @@ protected: SkIPoint* offset) const override; sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override; + SkIRect onFilterBounds(const SkIRect&, const SkMatrix&, MapDirection) const override; + #if SK_SUPPORT_GPU sk_sp<SkSpecialImage> filterImageGPU(SkSpecialImage* source, sk_sp<SkSpecialImage> background, @@ -173,6 +175,49 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage* return surf->makeImageSnapshot(); } +SkIRect SkXfermodeImageFilter_Base::onFilterBounds(const SkIRect& src, + const SkMatrix& ctm, + MapDirection direction) const { + if (kReverse_MapDirection == direction) { + return SkImageFilter::onFilterBounds(src, ctm, direction); + } + + SkASSERT(2 == this->countInputs()); + auto getBackground = [&]() { + return this->getInput(0) ? this->getInput(0)->filterBounds(src, ctm, direction) : src; + }; + auto getForeground = [&]() { + return this->getInput(1) ? this->getInput(1)->filterBounds(src, ctm, direction) : src; + }; + switch (fMode) { + case SkBlendMode::kClear: + return SkIRect::MakeEmpty(); + + case SkBlendMode::kSrc: + case SkBlendMode::kDstATop: + return getForeground(); + + case SkBlendMode::kDst: + case SkBlendMode::kSrcATop: + return getBackground(); + + case SkBlendMode::kSrcIn: + case SkBlendMode::kDstIn: { + auto result = getBackground(); + if (!result.intersect(getForeground())) { + return SkIRect::MakeEmpty(); + } + return result; + } + + default: { + auto result = getBackground(); + result.join(getForeground()); + return result; + } + } +} + sk_sp<SkImageFilter> SkXfermodeImageFilter_Base::onMakeColorSpace(SkColorSpaceXformer* xformer) const { SkASSERT(2 == this->countInputs()); |