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 "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 80 FilterEffectVector& inputEffects() { return m_inputEffects; } 81 FilterEffect* inputEffect(unsigned) const; 82 unsigned numberOfEffectInputs() const { return m_inputEffects.size(); } 83 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. 96 bool isAlphaImage() const { return m_alphaImage; } 97 void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; } 98 99 IntRect absolutePaintRect() const { return m_absolutePaintRect; } 100 void setAbsolutePaintRect(const IntRect& absolutePaintRect) { m_absolutePaintRect = absolutePaintRect; } 101 102 FloatRect maxEffectRect() const { return m_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. 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 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. 135 bool hasX() const { return m_hasX; } 136 void setHasX(bool value) { m_hasX = value; } 137 138 bool hasY() const { return m_hasY; } 139 void setHasY(bool value) { m_hasY = value; } 140 141 bool hasWidth() const { return m_hasWidth; } 142 void setHasWidth(bool value) { m_hasWidth = value; } 143 144 bool hasHeight() const { return m_hasHeight; } 145 void setHasHeight(bool value) { m_hasHeight = value; } 146 147 FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; } 148 void setFilterPrimitiveSubregion(const FloatRect& filterPrimitiveSubregion) { m_filterPrimitiveSubregion = filterPrimitiveSubregion; } 149 150 FloatRect effectBoundaries() const { return m_effectBoundaries; } 151 void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; } 152 153 Filter* filter() { return m_filter; } 154 const Filter* filter() const { return m_filter; } 155 156 bool clipsToBounds() const { return m_clipsToBounds; } 157 void setClipsToBounds(bool value) { m_clipsToBounds = value; } 158 159 ColorSpace operatingColorSpace() const { return m_operatingColorSpace; } 160 virtual void setOperatingColorSpace(ColorSpace colorSpace) { m_operatingColorSpace = colorSpace; } 161 ColorSpace resultColorSpace() const { return m_resultColorSpace; } 162 virtual void setResultColorSpace(ColorSpace colorSpace) { m_resultColorSpace = colorSpace; } 163 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]. 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; 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