1 /* 2 * Copyright 2015 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkLocalMatrixImageFilter_DEFINED 9 #define SkLocalMatrixImageFilter_DEFINED 10 11 #include "include/core/SkFlattenable.h" 12 #include "include/core/SkMatrix.h" 13 #include "include/core/SkRect.h" 14 #include "include/core/SkRefCnt.h" 15 #include "src/core/SkImageFilterTypes.h" 16 #include "src/core/SkImageFilter_Base.h" 17 18 #include <optional> 19 20 class SkImageFilter; 21 class SkReadBuffer; 22 class SkWriteBuffer; 23 24 /** 25 * Wraps another imagefilter + matrix, such that using this filter will give the same result 26 * as using the wrapped filter with the matrix applied to its context. 27 */ 28 class SkLocalMatrixImageFilter : public SkImageFilter_Base { 29 public: 30 static sk_sp<SkImageFilter> Make(const SkMatrix& localMatrix, sk_sp<SkImageFilter> input); 31 32 SkRect computeFastBounds(const SkRect&) const override; 33 34 protected: 35 void flatten(SkWriteBuffer&) const override; 36 37 private: SK_FLATTENABLE_HOOKS(SkLocalMatrixImageFilter)38 SK_FLATTENABLE_HOOKS(SkLocalMatrixImageFilter) 39 40 SkLocalMatrixImageFilter(const SkMatrix& localMatrix, 41 const SkMatrix& invLocalMatrix, 42 sk_sp<SkImageFilter> const* input) 43 : SkImageFilter_Base(input, 1) 44 , fLocalMatrix{localMatrix} 45 , fInvLocalMatrix{invLocalMatrix} {} 46 onGetCTMCapability()47 MatrixCapability onGetCTMCapability() const override { return MatrixCapability::kComplex; } 48 49 skif::FilterResult onFilterImage(const skif::Context& ctx) const override; 50 51 skif::LayerSpace<SkIRect> onGetInputLayerBounds( 52 const skif::Mapping&, 53 const skif::LayerSpace<SkIRect>& desiredOutput, 54 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const override; 55 56 std::optional<skif::LayerSpace<SkIRect>> onGetOutputLayerBounds( 57 const skif::Mapping&, 58 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const override; 59 60 skif::Mapping localMapping(const skif::Mapping&) const; 61 62 // NOTE: This is not a ParameterSpace<SkMatrix> like that of SkMatrixTransformImageFilter. 63 // It's a bit pedantic, but does impact the math. A parameter-space transform has to be modified 64 // to represent a layer-space transform: (L*P*L^-1); while this local matrix changes L directly 65 // to L*P for its child filter. 66 SkMatrix fLocalMatrix; 67 SkMatrix fInvLocalMatrix; 68 }; 69 70 #endif 71