Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / graphics / filters / FilterEffect.h
1 /*
2  * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
3  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
4  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
5  * Copyright (C) 2013 Google Inc. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #ifndef FilterEffect_h
24 #define FilterEffect_h
25
26 #include "platform/PlatformExport.h"
27 #include "platform/geometry/FloatRect.h"
28 #include "platform/geometry/IntRect.h"
29 #include "platform/graphics/Color.h"
30 #include "platform/graphics/ColorSpace.h"
31
32 #include "third_party/skia/include/core/SkImageFilter.h"
33
34 #include "wtf/PassOwnPtr.h"
35 #include "wtf/RefCounted.h"
36 #include "wtf/RefPtr.h"
37 #include "wtf/Uint8ClampedArray.h"
38 #include "wtf/Vector.h"
39
40 namespace WebCore {
41
42 class Filter;
43 class FilterEffect;
44 class ImageBuffer;
45 class TextStream;
46
47 class SkiaImageFilterBuilder;
48
49 typedef Vector<RefPtr<FilterEffect> > FilterEffectVector;
50
51 enum FilterEffectType {
52     FilterEffectTypeUnknown,
53     FilterEffectTypeImage,
54     FilterEffectTypeTile,
55     FilterEffectTypeSourceInput
56 };
57
58 enum DetermineSubregionFlag {
59     DetermineSubregionNone = 0,
60     MapRectForward = 1,
61     ClipToFilterRegion = 1 << 1
62 };
63
64 typedef int DetermineSubregionFlags;
65
66 class PLATFORM_EXPORT FilterEffect : public RefCounted<FilterEffect> {
67 public:
68     virtual ~FilterEffect();
69
70     static bool isFilterSizeValid(const FloatRect&);
71     static float maxFilterArea();
72
73     void clearResult();
74     void clearResultsRecursive();
75
76     ImageBuffer* asImageBuffer();
77     PassRefPtr<Uint8ClampedArray> asUnmultipliedImage(const IntRect&);
78     PassRefPtr<Uint8ClampedArray> asPremultipliedImage(const IntRect&);
79     void copyUnmultipliedImage(Uint8ClampedArray* destination, const IntRect&);
80     void copyPremultipliedImage(Uint8ClampedArray* destination, const IntRect&);
81
82     FilterEffectVector& inputEffects() { return m_inputEffects; }
83     FilterEffect* inputEffect(unsigned) const;
84     unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
85
86     inline bool hasResult() const
87     {
88         // This function needs platform specific checks, if the memory managment is not done by FilterEffect.
89         return m_imageBufferResult
90             || m_unmultipliedImageResult
91             || m_premultipliedImageResult;
92     }
93     inline bool hasImageFilter() const
94     {
95         return m_imageFilters[0] || m_imageFilters[1] || m_imageFilters[2] || m_imageFilters[3];
96     }
97
98     IntRect drawingRegionOfInputImage(const IntRect&) const;
99     IntRect requestedRegionOfInputImageData(const IntRect&) const;
100
101     // Solid black image with different alpha values.
102     bool isAlphaImage() const { return m_alphaImage; }
103     void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; }
104
105     IntRect absolutePaintRect() const { return m_absolutePaintRect; }
106
107     FloatRect maxEffectRect() const { return m_maxEffectRect; }
108     void setMaxEffectRect(const FloatRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; }
109
110     void apply();
111
112     // Correct any invalid pixels, if necessary, in the result of a filter operation.
113     // This method is used to ensure valid pixel values on filter inputs and the final result.
114     // Only the arithmetic composite filter ever needs to perform correction.
115     virtual void correctFilterResultIfNeeded() { }
116
117     virtual PassRefPtr<SkImageFilter> createImageFilter(SkiaImageFilterBuilder*);
118     virtual PassRefPtr<SkImageFilter> createImageFilterWithoutValidation(SkiaImageFilterBuilder*);
119
120     // Mapping a rect forwards determines which which destination pixels a
121     // given source rect would affect. Mapping a rect backwards determines
122     // which pixels from the source rect would be required to fill a given
123     // destination rect. Note that these are not necessarily the inverse of
124     // each other. For example, for FEGaussianBlur, they are the same
125     // transformation.
126     virtual FloatRect mapRect(const FloatRect& rect, bool forward = true) { return rect; }
127     // A version of the above that is used for calculating paint rects. We can't
128     // use mapRect above for that, because that is also used for calculating effect
129     // regions for CSS filters and has undesirable effects for tile and
130     // displacement map.
131     virtual FloatRect mapPaintRect(const FloatRect& rect, bool forward)
132     {
133         return mapRect(rect, forward);
134     }
135     FloatRect mapRectRecursive(const FloatRect&);
136
137     // This is a recursive version of a backwards mapRect(), which also takes
138     // into account the filter primitive subregion of each effect.
139     // Note: This works in absolute coordinates!
140     FloatRect getSourceRect(const FloatRect& destRect, const FloatRect& clipRect);
141
142     virtual FilterEffectType filterEffectType() const { return FilterEffectTypeUnknown; }
143
144     virtual TextStream& externalRepresentation(TextStream&, int indention = 0) const;
145
146     // The following functions are SVG specific and will move to RenderSVGResourceFilterPrimitive.
147     // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
148     bool hasX() const { return m_hasX; }
149     void setHasX(bool value) { m_hasX = value; }
150
151     bool hasY() const { return m_hasY; }
152     void setHasY(bool value) { m_hasY = value; }
153
154     bool hasWidth() const { return m_hasWidth; }
155     void setHasWidth(bool value) { m_hasWidth = value; }
156
157     bool hasHeight() const { return m_hasHeight; }
158     void setHasHeight(bool value) { m_hasHeight = value; }
159
160     FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; }
161     void setFilterPrimitiveSubregion(const FloatRect& filterPrimitiveSubregion) { m_filterPrimitiveSubregion = filterPrimitiveSubregion; }
162
163     FloatRect effectBoundaries() const { return m_effectBoundaries; }
164     void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; }
165
166     Filter* filter() { return m_filter; }
167     const Filter* filter() const { return m_filter; }
168
169     bool clipsToBounds() const { return m_clipsToBounds; }
170     void setClipsToBounds(bool value) { m_clipsToBounds = value; }
171
172     ColorSpace operatingColorSpace() const { return m_operatingColorSpace; }
173     virtual void setOperatingColorSpace(ColorSpace colorSpace) { m_operatingColorSpace = colorSpace; }
174     ColorSpace resultColorSpace() const { return m_resultColorSpace; }
175     virtual void setResultColorSpace(ColorSpace colorSpace) { m_resultColorSpace = colorSpace; }
176
177     virtual void transformResultColorSpace(FilterEffect* in, const int) { in->transformResultColorSpace(m_operatingColorSpace); }
178     void transformResultColorSpace(ColorSpace);
179
180     FloatRect determineFilterPrimitiveSubregion(DetermineSubregionFlags = DetermineSubregionNone);
181     void determineAllAbsolutePaintRects();
182
183     virtual FloatRect determineAbsolutePaintRect(const FloatRect& requestedAbsoluteRect);
184     virtual bool affectsTransparentPixels() { return false; }
185
186     // Return false if the filter will only operate correctly on valid RGBA values, with
187     // alpha in [0,255] and each color component in [0, alpha].
188     virtual bool mayProduceInvalidPreMultipliedPixels() { return false; }
189
190     SkImageFilter* getImageFilter(ColorSpace, bool requiresPMColorValidation) const;
191     void setImageFilter(ColorSpace, bool requiresPMColorValidation, PassRefPtr<SkImageFilter>);
192
193 protected:
194     FilterEffect(Filter*);
195     ImageBuffer* createImageBufferResult();
196     Uint8ClampedArray* createUnmultipliedImageResult();
197     Uint8ClampedArray* createPremultipliedImageResult();
198
199     Color adaptColorToOperatingColorSpace(const Color& deviceColor);
200
201     // If a pre-multiplied image, check every pixel for validity and correct if necessary.
202     void forceValidPreMultipliedPixels();
203     SkImageFilter::CropRect getCropRect(const FloatSize& cropOffset) const;
204
205     void addAbsolutePaintRect(const FloatRect& absolutePaintRect);
206
207 private:
208     void applyRecursive();
209     virtual void applySoftware() = 0;
210
211     inline void copyImageBytes(Uint8ClampedArray* source, Uint8ClampedArray* destination, const IntRect&);
212
213     OwnPtr<ImageBuffer> m_imageBufferResult;
214     RefPtr<Uint8ClampedArray> m_unmultipliedImageResult;
215     RefPtr<Uint8ClampedArray> m_premultipliedImageResult;
216     FilterEffectVector m_inputEffects;
217
218     bool m_alphaImage;
219
220     IntRect m_absolutePaintRect;
221
222     // The maximum size of a filter primitive. In SVG this is the primitive subregion in absolute coordinate space.
223     // The absolute paint rect should never be bigger than m_maxEffectRect.
224     FloatRect m_maxEffectRect;
225     Filter* m_filter;
226
227     // The following member variables are SVG specific and will move to RenderSVGResourceFilterPrimitive.
228     // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
229
230     // The subregion of a filter primitive according to the SVG Filter specification in local coordinates.
231     // This is SVG specific and needs to move to RenderSVGResourceFilterPrimitive.
232     FloatRect m_filterPrimitiveSubregion;
233
234     // x, y, width and height of the actual SVGFE*Element. Is needed to determine the subregion of the
235     // filter primitive on a later step.
236     FloatRect m_effectBoundaries;
237     bool m_hasX;
238     bool m_hasY;
239     bool m_hasWidth;
240     bool m_hasHeight;
241
242     // Should the effect clip to its primitive region, or expand to use the combined region of its inputs.
243     bool m_clipsToBounds;
244
245     ColorSpace m_operatingColorSpace;
246     ColorSpace m_resultColorSpace;
247
248     RefPtr<SkImageFilter> m_imageFilters[4];
249 };
250
251 } // namespace WebCore
252
253 #endif // FilterEffect_h