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 "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