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