• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ColorSpace.h"
30 
31 #include "third_party/skia/include/core/SkImageFilter.h"
32 
33 #include "wtf/PassOwnPtr.h"
34 #include "wtf/RefCounted.h"
35 #include "wtf/RefPtr.h"
36 #include "wtf/Uint8ClampedArray.h"
37 #include "wtf/Vector.h"
38 
39 static const float kMaxFilterSize = 5000.0f;
40 
41 namespace WebCore {
42 
43 class Filter;
44 class FilterEffect;
45 class ImageBuffer;
46 class TextStream;
47 
48 class SkiaImageFilterBuilder;
49 
50 typedef Vector<RefPtr<FilterEffect> > FilterEffectVector;
51 
52 enum FilterEffectType {
53     FilterEffectTypeUnknown,
54     FilterEffectTypeImage,
55     FilterEffectTypeTile,
56     FilterEffectTypeSourceInput
57 };
58 
59 enum DetermineSubregionFlag {
60     DetermineSubregionNone = 0,
61     MapRectForward = 1,
62     ClipToFilterRegion = 1 << 1
63 };
64 
65 typedef int DetermineSubregionFlags;
66 
67 class PLATFORM_EXPORT FilterEffect : public RefCounted<FilterEffect> {
68 public:
69     virtual ~FilterEffect();
70 
71     void clearResult();
72     void clearResultsRecursive();
73 
74     ImageBuffer* asImageBuffer();
75     PassRefPtr<Uint8ClampedArray> asUnmultipliedImage(const IntRect&);
76     PassRefPtr<Uint8ClampedArray> asPremultipliedImage(const IntRect&);
77     void copyUnmultipliedImage(Uint8ClampedArray* destination, const IntRect&);
78     void copyPremultipliedImage(Uint8ClampedArray* destination, const IntRect&);
79 
inputEffects()80     FilterEffectVector& inputEffects() { return m_inputEffects; }
81     FilterEffect* inputEffect(unsigned) const;
numberOfEffectInputs()82     unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
83 
hasResult()84     inline bool hasResult() const
85     {
86         // This function needs platform specific checks, if the memory managment is not done by FilterEffect.
87         return m_imageBufferResult
88             || m_unmultipliedImageResult
89             || m_premultipliedImageResult;
90     }
91 
92     IntRect drawingRegionOfInputImage(const IntRect&) const;
93     IntRect requestedRegionOfInputImageData(const IntRect&) const;
94 
95     // Solid black image with different alpha values.
isAlphaImage()96     bool isAlphaImage() const { return m_alphaImage; }
setIsAlphaImage(bool alphaImage)97     void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; }
98 
absolutePaintRect()99     IntRect absolutePaintRect() const { return m_absolutePaintRect; }
setAbsolutePaintRect(const IntRect & absolutePaintRect)100     void setAbsolutePaintRect(const IntRect& absolutePaintRect) { m_absolutePaintRect = absolutePaintRect; }
101 
maxEffectRect()102     FloatRect maxEffectRect() const { return m_maxEffectRect; }
setMaxEffectRect(const FloatRect & maxEffectRect)103     void setMaxEffectRect(const FloatRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; }
104 
105     void apply();
106 
107     // Correct any invalid pixels, if necessary, in the result of a filter operation.
108     // This method is used to ensure valid pixel values on filter inputs and the final result.
109     // Only the arithmetic composite filter ever needs to perform correction.
correctFilterResultIfNeeded()110     virtual void correctFilterResultIfNeeded() { }
111 
112     virtual PassRefPtr<SkImageFilter> createImageFilter(SkiaImageFilterBuilder*);
113 
114     virtual void determineAbsolutePaintRect();
115 
116     // Mapping a rect forwards determines which which destination pixels a
117     // given source rect would affect. Mapping a rect backwards determines
118     // which pixels from the source rect would be required to fill a given
119     // destination rect. Note that these are not necessarily the inverse of
120     // each other. For example, for FEGaussianBlur, they are the same
121     // transformation.
122     virtual FloatRect mapRect(const FloatRect& rect, bool forward = true) { return rect; }
123     FloatRect mapRectRecursive(const FloatRect&);
124 
125     // This is a recursive version of a backwards mapRect(), which also takes
126     // into account the filter primitive subregion of each effect.
127     FloatRect getSourceRect(const FloatRect& destRect, const FloatRect& clipRect);
128 
filterEffectType()129     virtual FilterEffectType filterEffectType() const { return FilterEffectTypeUnknown; }
130 
131     virtual TextStream& externalRepresentation(TextStream&, int indention = 0) const;
132 
133     // The following functions are SVG specific and will move to RenderSVGResourceFilterPrimitive.
134     // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
hasX()135     bool hasX() const { return m_hasX; }
setHasX(bool value)136     void setHasX(bool value) { m_hasX = value; }
137 
hasY()138     bool hasY() const { return m_hasY; }
setHasY(bool value)139     void setHasY(bool value) { m_hasY = value; }
140 
hasWidth()141     bool hasWidth() const { return m_hasWidth; }
setHasWidth(bool value)142     void setHasWidth(bool value) { m_hasWidth = value; }
143 
hasHeight()144     bool hasHeight() const { return m_hasHeight; }
setHasHeight(bool value)145     void setHasHeight(bool value) { m_hasHeight = value; }
146 
filterPrimitiveSubregion()147     FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; }
setFilterPrimitiveSubregion(const FloatRect & filterPrimitiveSubregion)148     void setFilterPrimitiveSubregion(const FloatRect& filterPrimitiveSubregion) { m_filterPrimitiveSubregion = filterPrimitiveSubregion; }
149 
effectBoundaries()150     FloatRect effectBoundaries() const { return m_effectBoundaries; }
setEffectBoundaries(const FloatRect & effectBoundaries)151     void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; }
152 
filter()153     Filter* filter() { return m_filter; }
filter()154     const Filter* filter() const { return m_filter; }
155 
clipsToBounds()156     bool clipsToBounds() const { return m_clipsToBounds; }
setClipsToBounds(bool value)157     void setClipsToBounds(bool value) { m_clipsToBounds = value; }
158 
operatingColorSpace()159     ColorSpace operatingColorSpace() const { return m_operatingColorSpace; }
setOperatingColorSpace(ColorSpace colorSpace)160     virtual void setOperatingColorSpace(ColorSpace colorSpace) { m_operatingColorSpace = colorSpace; }
resultColorSpace()161     ColorSpace resultColorSpace() const { return m_resultColorSpace; }
setResultColorSpace(ColorSpace colorSpace)162     virtual void setResultColorSpace(ColorSpace colorSpace) { m_resultColorSpace = colorSpace; }
163 
transformResultColorSpace(FilterEffect * in,const int)164     virtual void transformResultColorSpace(FilterEffect* in, const int) { in->transformResultColorSpace(m_operatingColorSpace); }
165     void transformResultColorSpace(ColorSpace);
166 
167     FloatRect determineFilterPrimitiveSubregion(DetermineSubregionFlags = DetermineSubregionNone);
168 
169 protected:
170     FilterEffect(Filter*);
171 
172     ImageBuffer* createImageBufferResult();
173     Uint8ClampedArray* createUnmultipliedImageResult();
174     Uint8ClampedArray* createPremultipliedImageResult();
175 
176     // Return true if the filter will only operate correctly on valid RGBA values, with
177     // alpha in [0,255] and each color component in [0, alpha].
requiresValidPreMultipliedPixels()178     virtual bool requiresValidPreMultipliedPixels() { return true; }
179 
180     // If a pre-multiplied image, check every pixel for validity and correct if necessary.
181     void forceValidPreMultipliedPixels();
182     SkImageFilter::CropRect getCropRect(const FloatSize& cropOffset) const;
183 
184 private:
185     virtual void applySoftware() = 0;
applySkia()186     virtual bool applySkia() { return false; }
187 
188     inline void copyImageBytes(Uint8ClampedArray* source, Uint8ClampedArray* destination, const IntRect&);
189 
190     OwnPtr<ImageBuffer> m_imageBufferResult;
191     RefPtr<Uint8ClampedArray> m_unmultipliedImageResult;
192     RefPtr<Uint8ClampedArray> m_premultipliedImageResult;
193     FilterEffectVector m_inputEffects;
194 
195     bool m_alphaImage;
196 
197     IntRect m_absolutePaintRect;
198 
199     // The maximum size of a filter primitive. In SVG this is the primitive subregion in absolute coordinate space.
200     // The absolute paint rect should never be bigger than m_maxEffectRect.
201     FloatRect m_maxEffectRect;
202     Filter* m_filter;
203 
204     // The following member variables are SVG specific and will move to RenderSVGResourceFilterPrimitive.
205     // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
206 
207     // The subregion of a filter primitive according to the SVG Filter specification in local coordinates.
208     // This is SVG specific and needs to move to RenderSVGResourceFilterPrimitive.
209     FloatRect m_filterPrimitiveSubregion;
210 
211     // x, y, width and height of the actual SVGFE*Element. Is needed to determine the subregion of the
212     // filter primitive on a later step.
213     FloatRect m_effectBoundaries;
214     bool m_hasX;
215     bool m_hasY;
216     bool m_hasWidth;
217     bool m_hasHeight;
218 
219     // Should the effect clip to its primitive region, or expand to use the combined region of its inputs.
220     bool m_clipsToBounds;
221 
222     ColorSpace m_operatingColorSpace;
223     ColorSpace m_resultColorSpace;
224 };
225 
226 } // namespace WebCore
227 
228 #endif // FilterEffect_h
229