blob: 245de29b8e5554cab135d7bf5c30f14fa8e6c621 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#ifndef SkMaskFilter_DEFINED
11#define SkMaskFilter_DEFINED
12
13#include "SkFlattenable.h"
14#include "SkMask.h"
junov@chromium.org2ac4ef52012-04-04 15:16:51 +000015#include "SkPaint.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000016
17class SkBlitter;
18class SkBounder;
19class SkMatrix;
20class SkPath;
reed@google.com045e62d2011-10-24 12:19:46 +000021class SkRasterClip;
reed@android.com8a1c16f2008-12-17 15:59:43 +000022
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.com4200dfe2012-10-13 17:13:18 +000034class SK_API SkMaskFilter : public SkFlattenable {
reed@android.com8a1c16f2008-12-17 15:59:43 +000035public:
robertphillips@google.com0456e0b2012-06-27 14:03:26 +000036 SK_DECLARE_INST_COUNT(SkMaskFilter)
37
reed@android.com8a1c16f2008-12-17 15:59:43 +000038 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.com30711b72012-12-18 19:18:39 +000043 virtual SkMask::Format getFormat() const = 0;
reed@android.com8a1c16f2008-12-17 15:59:43 +000044
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.org4135f282011-04-20 11:04:30 +000058 virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
reed@google.com30711b72012-12-18 19:18:39 +000059 SkIPoint* margin) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +000060
reed@google.com2b75f422011-07-07 13:43:38 +000061 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.com1f902872012-06-01 13:15:47 +000066 kInner_BlurType //!< fuzzy inside, nothing outside
reed@google.com2b75f422011-07-07 13:43:38 +000067 };
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.com18ac1ba2011-10-04 15:11:38 +000081 virtual BlurType asABlur(BlurInfo*) const;
reed@google.com2b75f422011-07-07 13:43:38 +000082
reed@google.com9efd9a02012-01-30 15:41:43 +000083 /**
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.com30711b72012-12-18 19:18:39 +000094 virtual void computeFastBounds(const SkRect& src, SkRect* dest) const;
reed@google.com9efd9a02012-01-30 15:41:43 +000095
reed@android.com8a1c16f2008-12-17 15:59:43 +000096protected:
97 // empty for now, but lets get our subclass to remember to init us for the future
djsollen@google.com54924242012-03-29 15:18:04 +000098 SkMaskFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
reed@google.com045e62d2011-10-24 12:19:46 +000099
reed@google.comd729b3e2012-11-09 14:30:48 +0000100 enum FilterReturn {
101 kFalse_FilterReturn,
102 kTrue_FilterReturn,
103 kUnimplemented_FilterReturn
104 };
105
reed@google.comdab9b4f2012-11-19 16:45:14 +0000106 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.comd729b3e2012-11-09 14:30:48 +0000112 /**
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.comdab9b4f2012-11-19 16:45:14 +0000127 virtual FilterReturn filterRectsToNine(const SkRect[], int count,
128 const SkMatrix&,
129 const SkIRect& clipBounds,
reed@google.com30711b72012-12-18 19:18:39 +0000130 NinePatch*) const;
reed@google.comd729b3e2012-11-09 14:30:48 +0000131
reed@google.com045e62d2011-10-24 12:19:46 +0000132private:
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.org2ac4ef52012-04-04 15:16:51 +0000141 const SkRasterClip&, SkBounder*, SkBlitter* blitter,
reed@google.com30711b72012-12-18 19:18:39 +0000142 SkPaint::Style style) const;
djsollen@google.com54924242012-03-29 15:18:04 +0000143
144 typedef SkFlattenable INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000145};
146
reed@android.com8a1c16f2008-12-17 15:59:43 +0000147#endif
148