epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 1 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 2 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 3 | * Copyright 2006 The Android Open Source Project |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 4 | * |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 5 | * Use of this source code is governed by a BSD-style license that can be |
| 6 | * found in the LICENSE file. |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 7 | */ |
| 8 | |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 9 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 10 | #ifndef SkMaskFilter_DEFINED |
| 11 | #define SkMaskFilter_DEFINED |
| 12 | |
| 13 | #include "SkFlattenable.h" |
| 14 | #include "SkMask.h" |
junov@chromium.org | 2ac4ef5 | 2012-04-04 15:16:51 +0000 | [diff] [blame] | 15 | #include "SkPaint.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 16 | |
| 17 | class SkBlitter; |
| 18 | class SkBounder; |
| 19 | class SkMatrix; |
| 20 | class SkPath; |
reed@google.com | 045e62d | 2011-10-24 12:19:46 +0000 | [diff] [blame] | 21 | class SkRasterClip; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 22 | |
| 23 | /** \class SkMaskFilter |
| 24 | |
| 25 | SkMaskFilter is the base class for object that perform transformations on |
| 26 | an alpha-channel mask before drawing it. A subclass of SkMaskFilter may be |
| 27 | installed into a SkPaint. Once there, each time a primitive is drawn, it |
| 28 | is first scan converted into a SkMask::kA8_Format mask, and handed to the |
| 29 | filter, calling its filterMask() method. If this returns true, then the |
| 30 | new mask is used to render into the device. |
| 31 | |
| 32 | Blur and emboss are implemented as subclasses of SkMaskFilter. |
| 33 | */ |
bungeman@google.com | 4200dfe | 2012-10-13 17:13:18 +0000 | [diff] [blame] | 34 | class SK_API SkMaskFilter : public SkFlattenable { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 35 | public: |
robertphillips@google.com | 0456e0b | 2012-06-27 14:03:26 +0000 | [diff] [blame] | 36 | SK_DECLARE_INST_COUNT(SkMaskFilter) |
| 37 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 38 | SkMaskFilter() {} |
| 39 | |
| 40 | /** Returns the format of the resulting mask that this subclass will return |
| 41 | when its filterMask() method is called. |
| 42 | */ |
reed@google.com | 30711b7 | 2012-12-18 19:18:39 +0000 | [diff] [blame] | 43 | virtual SkMask::Format getFormat() const = 0; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 44 | |
| 45 | /** Create a new mask by filter the src mask. |
| 46 | If src.fImage == null, then do not allocate or create the dst image |
| 47 | but do fill out the other fields in dstMask. |
| 48 | If you do allocate a dst image, use SkMask::AllocImage() |
| 49 | If this returns false, dst mask is ignored. |
| 50 | @param dst the result of the filter. If src.fImage == null, dst should not allocate its image |
| 51 | @param src the original image to be filtered. |
| 52 | @param matrix the CTM |
| 53 | @param margin if not null, return the buffer dx/dy need when calculating the effect. Used when |
| 54 | drawing a clipped object to know how much larger to allocate the src before |
| 55 | applying the filter. If returning false, ignore this parameter. |
| 56 | @return true if the dst mask was correctly created. |
| 57 | */ |
mike@reedtribe.org | 4135f28 | 2011-04-20 11:04:30 +0000 | [diff] [blame] | 58 | virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, |
reed@google.com | 30711b7 | 2012-12-18 19:18:39 +0000 | [diff] [blame] | 59 | SkIPoint* margin) const; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 60 | |
reed@google.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 61 | enum BlurType { |
| 62 | kNone_BlurType, //!< this maskfilter is not a blur |
| 63 | kNormal_BlurType, //!< fuzzy inside and outside |
| 64 | kSolid_BlurType, //!< solid inside, fuzzy outside |
| 65 | kOuter_BlurType, //!< nothing inside, fuzzy outside |
tomhudson@google.com | 1f90287 | 2012-06-01 13:15:47 +0000 | [diff] [blame] | 66 | kInner_BlurType //!< fuzzy inside, nothing outside |
reed@google.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 67 | }; |
| 68 | |
| 69 | struct BlurInfo { |
| 70 | SkScalar fRadius; |
| 71 | bool fIgnoreTransform; |
| 72 | bool fHighQuality; |
| 73 | }; |
| 74 | |
| 75 | /** |
| 76 | * Optional method for maskfilters that can be described as a blur. If so, |
| 77 | * they return the corresponding BlurType and set the fields in BlurInfo |
| 78 | * (if not null). If they cannot be described as a blur, they return |
| 79 | * kNone_BlurType and ignore the info parameter. |
| 80 | */ |
bungeman@google.com | 18ac1ba | 2011-10-04 15:11:38 +0000 | [diff] [blame] | 81 | virtual BlurType asABlur(BlurInfo*) const; |
reed@google.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 82 | |
reed@google.com | 9efd9a0 | 2012-01-30 15:41:43 +0000 | [diff] [blame] | 83 | /** |
| 84 | * The fast bounds function is used to enable the paint to be culled early |
| 85 | * in the drawing pipeline. This function accepts the current bounds of the |
| 86 | * paint as its src param and the filter adjust those bounds using its |
| 87 | * current mask and returns the result using the dest param. Callers are |
| 88 | * allowed to provide the same struct for both src and dest so each |
| 89 | * implementation must accomodate that behavior. |
| 90 | * |
| 91 | * The default impl calls filterMask with the src mask having no image, |
| 92 | * but subclasses may override this if they can compute the rect faster. |
| 93 | */ |
reed@google.com | 30711b7 | 2012-12-18 19:18:39 +0000 | [diff] [blame] | 94 | virtual void computeFastBounds(const SkRect& src, SkRect* dest) const; |
reed@google.com | 9efd9a0 | 2012-01-30 15:41:43 +0000 | [diff] [blame] | 95 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 96 | protected: |
| 97 | // empty for now, but lets get our subclass to remember to init us for the future |
djsollen@google.com | 5492424 | 2012-03-29 15:18:04 +0000 | [diff] [blame] | 98 | SkMaskFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} |
reed@google.com | 045e62d | 2011-10-24 12:19:46 +0000 | [diff] [blame] | 99 | |
reed@google.com | d729b3e | 2012-11-09 14:30:48 +0000 | [diff] [blame] | 100 | enum FilterReturn { |
| 101 | kFalse_FilterReturn, |
| 102 | kTrue_FilterReturn, |
| 103 | kUnimplemented_FilterReturn |
| 104 | }; |
| 105 | |
reed@google.com | dab9b4f | 2012-11-19 16:45:14 +0000 | [diff] [blame] | 106 | struct NinePatch { |
| 107 | SkMask fMask; // fBounds must have [0,0] in its top-left |
| 108 | SkIRect fOuterRect; // width/height must be >= fMask.fBounds' |
| 109 | SkIPoint fCenter; // identifies center row/col for stretching |
| 110 | }; |
| 111 | |
reed@google.com | d729b3e | 2012-11-09 14:30:48 +0000 | [diff] [blame] | 112 | /** |
| 113 | * Override if your subclass can filter a rect, and return the answer as |
| 114 | * a ninepatch mask to be stretched over the returned outerRect. On success |
| 115 | * return kTrue_FilterReturn. On failure (e.g. out of memory) return |
| 116 | * kFalse_FilterReturn. If the normal filterMask() entry-point should be |
| 117 | * called (the default) return kUnimplemented_FilterReturn. |
| 118 | * |
| 119 | * By convention, the caller will take the center rol/col from the returned |
| 120 | * mask as the slice it can replicate horizontally and vertically as we |
| 121 | * stretch the mask to fit inside outerRect. It is an error for outerRect |
| 122 | * to be smaller than the mask's bounds. This would imply that the width |
| 123 | * and height of the mask should be odd. This is not required, just that |
| 124 | * the caller will call mask.fBounds.centerX() and centerY() to find the |
| 125 | * strips that will be replicated. |
| 126 | */ |
reed@google.com | dab9b4f | 2012-11-19 16:45:14 +0000 | [diff] [blame] | 127 | virtual FilterReturn filterRectsToNine(const SkRect[], int count, |
| 128 | const SkMatrix&, |
| 129 | const SkIRect& clipBounds, |
reed@google.com | 30711b7 | 2012-12-18 19:18:39 +0000 | [diff] [blame] | 130 | NinePatch*) const; |
reed@google.com | d729b3e | 2012-11-09 14:30:48 +0000 | [diff] [blame] | 131 | |
reed@google.com | 045e62d | 2011-10-24 12:19:46 +0000 | [diff] [blame] | 132 | private: |
| 133 | friend class SkDraw; |
| 134 | |
| 135 | /** Helper method that, given a path in device space, will rasterize it into a kA8_Format mask |
| 136 | and then call filterMask(). If this returns true, the specified blitter will be called |
| 137 | to render that mask. Returns false if filterMask() returned false. |
| 138 | This method is not exported to java. |
| 139 | */ |
| 140 | bool filterPath(const SkPath& devPath, const SkMatrix& devMatrix, |
junov@chromium.org | 2ac4ef5 | 2012-04-04 15:16:51 +0000 | [diff] [blame] | 141 | const SkRasterClip&, SkBounder*, SkBlitter* blitter, |
reed@google.com | 30711b7 | 2012-12-18 19:18:39 +0000 | [diff] [blame] | 142 | SkPaint::Style style) const; |
djsollen@google.com | 5492424 | 2012-03-29 15:18:04 +0000 | [diff] [blame] | 143 | |
| 144 | typedef SkFlattenable INHERITED; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 145 | }; |
| 146 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 147 | #endif |
| 148 | |