Home | History | Annotate | Download | only in filters
      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