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.
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.
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.
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.
23 #ifndef FilterEffect_h
24 #define FilterEffect_h
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"
32 #include "third_party/skia/include/core/SkImageFilter.h"
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"
47 class SkiaImageFilterBuilder;
49 typedef Vector<RefPtr<FilterEffect> > FilterEffectVector;
51 enum FilterEffectType {
52 FilterEffectTypeUnknown,
53 FilterEffectTypeImage,
55 FilterEffectTypeSourceInput
58 enum DetermineSubregionFlag {
59 DetermineSubregionNone = 0,
61 ClipToFilterRegion = 1 << 1
64 typedef int DetermineSubregionFlags;
66 class PLATFORM_EXPORT FilterEffect : public RefCounted<FilterEffect> {
68 virtual ~FilterEffect();
70 static bool isFilterSizeValid(const FloatRect&);
71 static float maxFilterArea();
74 void clearResultsRecursive();
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&);
82 FilterEffectVector& inputEffects() { return m_inputEffects; }
83 FilterEffect* inputEffect(unsigned) const;
84 unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
86 inline bool hasResult() const
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;
93 inline bool hasImageFilter() const
95 return m_imageFilters[0] || m_imageFilters[1] || m_imageFilters[2] || m_imageFilters[3];
98 IntRect drawingRegionOfInputImage(const IntRect&) const;
99 IntRect requestedRegionOfInputImageData(const IntRect&) const;
101 // Solid black image with different alpha values.
102 bool isAlphaImage() const { return m_alphaImage; }
103 void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; }
105 IntRect absolutePaintRect() const { return m_absolutePaintRect; }
107 FloatRect maxEffectRect() const { return m_maxEffectRect; }
108 void setMaxEffectRect(const FloatRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; }
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() { }
117 virtual PassRefPtr<SkImageFilter> createImageFilter(SkiaImageFilterBuilder*);
118 virtual PassRefPtr<SkImageFilter> createImageFilterWithoutValidation(SkiaImageFilterBuilder*);
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
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
131 virtual FloatRect mapPaintRect(const FloatRect& rect, bool forward)
133 return mapRect(rect, forward);
135 FloatRect mapRectRecursive(const FloatRect&);
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);
142 virtual FilterEffectType filterEffectType() const { return FilterEffectTypeUnknown; }
144 virtual TextStream& externalRepresentation(TextStream&, int indention = 0) const;
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; }
151 bool hasY() const { return m_hasY; }
152 void setHasY(bool value) { m_hasY = value; }
154 bool hasWidth() const { return m_hasWidth; }
155 void setHasWidth(bool value) { m_hasWidth = value; }
157 bool hasHeight() const { return m_hasHeight; }
158 void setHasHeight(bool value) { m_hasHeight = value; }
160 FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; }
161 void setFilterPrimitiveSubregion(const FloatRect& filterPrimitiveSubregion) { m_filterPrimitiveSubregion = filterPrimitiveSubregion; }
163 FloatRect effectBoundaries() const { return m_effectBoundaries; }
164 void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; }
166 Filter* filter() { return m_filter; }
167 const Filter* filter() const { return m_filter; }
169 bool clipsToBounds() const { return m_clipsToBounds; }
170 void setClipsToBounds(bool value) { m_clipsToBounds = value; }
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; }
177 virtual void transformResultColorSpace(FilterEffect* in, const int) { in->transformResultColorSpace(m_operatingColorSpace); }
178 void transformResultColorSpace(ColorSpace);
180 FloatRect determineFilterPrimitiveSubregion(DetermineSubregionFlags = DetermineSubregionNone);
181 void determineAllAbsolutePaintRects();
183 virtual FloatRect determineAbsolutePaintRect(const FloatRect& requestedAbsoluteRect);
184 virtual bool affectsTransparentPixels() { return false; }
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; }
190 SkImageFilter* getImageFilter(ColorSpace, bool requiresPMColorValidation) const;
191 void setImageFilter(ColorSpace, bool requiresPMColorValidation, PassRefPtr<SkImageFilter>);
194 FilterEffect(Filter*);
195 ImageBuffer* createImageBufferResult();
196 Uint8ClampedArray* createUnmultipliedImageResult();
197 Uint8ClampedArray* createPremultipliedImageResult();
199 Color adaptColorToOperatingColorSpace(const Color& deviceColor);
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;
205 void addAbsolutePaintRect(const FloatRect& absolutePaintRect);
208 void applyRecursive();
209 virtual void applySoftware() = 0;
211 inline void copyImageBytes(Uint8ClampedArray* source, Uint8ClampedArray* destination, const IntRect&);
213 OwnPtr<ImageBuffer> m_imageBufferResult;
214 RefPtr<Uint8ClampedArray> m_unmultipliedImageResult;
215 RefPtr<Uint8ClampedArray> m_premultipliedImageResult;
216 FilterEffectVector m_inputEffects;
220 IntRect m_absolutePaintRect;
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;
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.
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;
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;
242 // Should the effect clip to its primitive region, or expand to use the combined region of its inputs.
243 bool m_clipsToBounds;
245 ColorSpace m_operatingColorSpace;
246 ColorSpace m_resultColorSpace;
248 RefPtr<SkImageFilter> m_imageFilters[4];
251 } // namespace WebCore
253 #endif // FilterEffect_h