1 /* 2 * Copyright 2017 Google Inc. 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 SkBlurMaskFilter_DEFINED 9 #define SkBlurMaskFilter_DEFINED 10 11 #include <algorithm> 12 #include <memory> 13 14 #include "SkMask.h" 15 #include "SkTypes.h" 16 17 // Implement a single channel Gaussian blur. The specifics for implementation are taken from: 18 // https://drafts.fxtf.org/filters/#feGaussianBlurElement 19 class SkMaskBlurFilter { 20 public: 21 // Given a filter specified by sigma, generate various quantities. 22 class FilterInfo { 23 public: 24 explicit FilterInfo(double sigma); 25 26 // The final weight to divide by given a box size calculated from sigma accumulated for 27 // all three passes. For example, if the box size is 5, then the final weight for all 28 // three passes is 5^3 or 125. 29 uint64_t weight() const; 30 31 // The distance between the first value of the dst and the first value of the src. 32 uint32_t borderSize() const; 33 34 // The size of the box filter. 35 size_t diameter(uint8_t) const; 36 37 // A factor used to simulate division using multiplication and shift. 38 uint64_t scaledWeight() const; 39 40 private: 41 const uint32_t fFilterWindow; 42 const uint64_t fScaledWeight; 43 }; 44 45 // Create an object suitable for filtering an SkMask using a filter with width sigmaW and 46 // height sigmaH. 47 SkMaskBlurFilter(double sigmaW, double sigmaH); 48 49 // Given a src SkMask, generate dst SkMask returning the border width and height. 50 SkIPoint blur(const SkMask& src, SkMask* dst) const; 51 52 private: 53 size_t bufferSize(uint8_t bufferPass) const; 54 55 void blurOneScan(FilterInfo gen, 56 const uint8_t* src, size_t srcStride, const uint8_t* srcEnd, 57 uint8_t* dst, size_t dstStride, uint8_t* dstEnd) const; 58 59 60 const FilterInfo fInfoW, 61 fInfoH; 62 std::unique_ptr<uint32_t[]> fBuffer0, 63 fBuffer1, 64 fBuffer2; 65 }; 66 67 #endif // SkBlurMaskFilter_DEFINED 68