Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / include / core / SkImageFilter.h
1 /*
2  * Copyright 2011 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 SkImageFilter_DEFINED
9 #define SkImageFilter_DEFINED
10
11 #include "SkFlattenable.h"
12 #include "SkRect.h"
13
14 class SkBitmap;
15 class SkColorFilter;
16 class SkBaseDevice;
17 class SkMatrix;
18 struct SkIPoint;
19 class SkShader;
20 class GrEffectRef;
21 class GrTexture;
22
23 /**
24  *  Base class for image filters. If one is installed in the paint, then
25  *  all drawing occurs as usual, but it is as if the drawing happened into an
26  *  offscreen (before the xfermode is applied). This offscreen bitmap will
27  *  then be handed to the imagefilter, who in turn creates a new bitmap which
28  *  is what will finally be drawn to the device (using the original xfermode).
29  */
30 class SK_API SkImageFilter : public SkFlattenable {
31 public:
32     SK_DECLARE_INST_COUNT(SkImageFilter)
33
34     class CropRect {
35     public:
36         enum CropEdge {
37             kHasLeft_CropEdge   = 0x01,
38             kHasTop_CropEdge    = 0x02,
39             kHasRight_CropEdge  = 0x04,
40             kHasBottom_CropEdge = 0x08,
41             kHasAll_CropEdge    = 0x0F,
42         };
43         CropRect() {}
44         explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge) : fRect(rect), fFlags(flags) {}
45         uint32_t flags() const { return fFlags; }
46         const SkRect& rect() const { return fRect; }
47     private:
48         SkRect fRect;
49         uint32_t fFlags;
50     };
51
52     class Proxy {
53     public:
54         virtual ~Proxy() {};
55
56         virtual SkBaseDevice* createDevice(int width, int height) = 0;
57         // returns true if the proxy can handle this filter natively
58         virtual bool canHandleImageFilter(const SkImageFilter*) = 0;
59         // returns true if the proxy handled the filter itself. if this returns
60         // false then the filter's code will be called.
61         virtual bool filterImage(const SkImageFilter*, const SkBitmap& src,
62                                  const SkMatrix& ctm,
63                                  SkBitmap* result, SkIPoint* offset) = 0;
64     };
65
66     /**
67      *  Request a new (result) image to be created from the src image.
68      *  If the src has no pixels (isNull()) then the request just wants to
69      *  receive the config and width/height of the result.
70      *
71      *  The matrix is the current matrix on the canvas.
72      *
73      *  Offset is the amount to translate the resulting image relative to the
74      *  src when it is drawn. This is an out-param.
75      *
76      *  If the result image cannot be created, return false, in which case both
77      *  the result and offset parameters will be ignored by the caller.
78      */
79     bool filterImage(Proxy*, const SkBitmap& src, const SkMatrix& ctm,
80                      SkBitmap* result, SkIPoint* offset) const;
81
82     /**
83      *  Given the src bounds of an image, this returns the bounds of the result
84      *  image after the filter has been applied.
85      */
86     bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const;
87
88     /**
89      *  Returns true if the filter can be processed on the GPU.  This is most
90      *  often used for multi-pass effects, where intermediate results must be
91      *  rendered to textures.  For single-pass effects, use asNewEffect().
92      *  The default implementation returns asNewEffect(NULL, NULL, SkMatrix::I(),
93      *  SkIRect()).
94      */
95     virtual bool canFilterImageGPU() const;
96
97     /**
98      *  Process this image filter on the GPU.  This is most often used for
99      *  multi-pass effects, where intermediate results must be rendered to
100      *  textures.  For single-pass effects, use asNewEffect().  src is the
101      *  source image for processing, as a texture-backed bitmap.  result is
102      *  the destination bitmap, which should contain a texture-backed pixelref
103      *  on success.  offset is the amount to translate the resulting image
104      *  relative to the src when it is drawn. The default implementation does
105      *  single-pass processing using asNewEffect().
106      */
107     virtual bool filterImageGPU(Proxy*, const SkBitmap& src, const SkMatrix& ctm,
108                                 SkBitmap* result, SkIPoint* offset) const;
109
110     /**
111      *  Returns whether this image filter is a color filter and puts the color filter into the
112      *  "filterPtr" parameter if it can. Does nothing otherwise.
113      *  If this returns false, then the filterPtr is unchanged.
114      *  If this returns true, then if filterPtr is not null, it must be set to a ref'd colorfitler
115      *  (i.e. it may not be set to NULL).
116      */
117     virtual bool asColorFilter(SkColorFilter** filterPtr) const;
118
119     /**
120      *  Returns the number of inputs this filter will accept (some inputs can
121      *  be NULL).
122      */
123     int countInputs() const { return fInputCount; }
124
125     /**
126      *  Returns the input filter at a given index, or NULL if no input is
127      *  connected.  The indices used are filter-specific.
128      */
129     SkImageFilter* getInput(int i) const {
130         SkASSERT(i < fInputCount);
131         return fInputs[i];
132     }
133
134     /**
135      *  Returns whether any edges of the crop rect have been set. The crop
136      *  rect is set at construction time, and determines which pixels from the
137      *  input image will be processed. The size of the crop rect should be
138      *  used as the size of the destination image. The origin of this rect
139      *  should be used to offset access to the input images, and should also
140      *  be added to the "offset" parameter in onFilterImage and
141      *  filterImageGPU(). (The latter ensures that the resulting buffer is
142      *  drawn in the correct location.)
143      */
144     bool cropRectIsSet() const { return fCropRect.flags() != 0x0; }
145
146     // Default impl returns union of all input bounds.
147     virtual void computeFastBounds(const SkRect&, SkRect*) const;
148
149     SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
150
151 protected:
152     SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL);
153
154     // Convenience constructor for 1-input filters.
155     explicit SkImageFilter(SkImageFilter* input, const CropRect* cropRect = NULL);
156
157     // Convenience constructor for 2-input filters.
158     SkImageFilter(SkImageFilter* input1, SkImageFilter* input2, const CropRect* cropRect = NULL);
159
160     virtual ~SkImageFilter();
161
162     /**
163      *  Constructs a new SkImageFilter read from an SkReadBuffer object.
164      *
165      *  @param inputCount    The exact number of inputs expected for this SkImageFilter object.
166      *                       -1 can be used if the filter accepts any number of inputs.
167      *  @param rb            SkReadBuffer object from which the SkImageFilter is read.
168      */
169     explicit SkImageFilter(int inputCount, SkReadBuffer& rb);
170
171     virtual void flatten(SkWriteBuffer& wb) const SK_OVERRIDE;
172
173     /**
174      *  This is the virtual which should be overridden by the derived class
175      *  to perform image filtering.
176      *
177      *  src is the original primitive bitmap. If the filter has a connected
178      *  input, it should recurse on that input and use that in place of src.
179      *
180      *  The matrix is the current matrix on the canvas.
181      *
182      *  Offset is the amount to translate the resulting image relative to the
183      *  src when it is drawn. This is an out-param.
184      *
185      *  If the result image cannot be created, this should false, in which
186      *  case both the result and offset parameters will be ignored by the
187      *  caller.
188      */
189     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
190                                SkBitmap* result, SkIPoint* offset) const;
191     // Given the bounds of the destination rect to be filled in device
192     // coordinates (first parameter), and the CTM, compute (conservatively)
193     // which rect of the source image would be required (third parameter).
194     // Used for clipping and temp-buffer allocations, so the result need not
195     // be exact, but should never be smaller than the real answer. The default
196     // implementation recursively unions all input bounds, or returns false if
197     // no inputs.
198     virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const;
199
200     // Applies "matrix" to the crop rect, and sets "rect" to the intersection of
201     // "rect" and the transformed crop rect. If there is no overlap, returns
202     // false and leaves "rect" unchanged.
203     bool applyCropRect(SkIRect* rect, const SkMatrix& matrix) const;
204
205     /**
206      *  Returns true if the filter can be expressed a single-pass
207      *  GrEffect, used to process this filter on the GPU, or false if
208      *  not.
209      *
210      *  If effect is non-NULL, a new GrEffect instance is stored
211      *  in it.  The caller assumes ownership of the stage, and it is up to the
212      *  caller to unref it.
213      *
214      *  The effect can assume its vertexCoords space maps 1-to-1 with texels
215      *  in the texture.  "matrix" is a transformation to apply to filter
216      *  parameters before they are used in the effect. Note that this function
217      *  will be called with (NULL, NULL, SkMatrix::I()) to query for support,
218      *  so returning "true" indicates support for all possible matrices.
219      */
220     virtual bool asNewEffect(GrEffectRef** effect,
221                              GrTexture*,
222                              const SkMatrix& matrix,
223                              const SkIRect& bounds) const;
224
225 private:
226     typedef SkFlattenable INHERITED;
227     int fInputCount;
228     SkImageFilter** fInputs;
229     CropRect fCropRect;
230 };
231
232 #endif