Home | History | Annotate | Download | only in filters
      1 /*
      2  * Copyright (C) 2011 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef FilterOperation_h
     27 #define FilterOperation_h
     28 
     29 #include "core/loader/cache/DocumentResourceReference.h"
     30 #include "core/platform/Length.h"
     31 #include "core/platform/graphics/Color.h"
     32 #include "core/platform/graphics/filters/Filter.h"
     33 #include "core/platform/graphics/filters/ReferenceFilter.h"
     34 #include "wtf/OwnPtr.h"
     35 #include "wtf/PassOwnPtr.h"
     36 #include "wtf/RefCounted.h"
     37 #include "wtf/text/WTFString.h"
     38 
     39 // Annoyingly, wingdi.h #defines this.
     40 #ifdef PASSTHROUGH
     41 #undef PASSTHROUGH
     42 #endif
     43 
     44 namespace WebCore {
     45 
     46 // CSS Filters
     47 
     48 class FilterOperation : public RefCounted<FilterOperation> {
     49 public:
     50     enum OperationType {
     51         REFERENCE, // url(#somefilter)
     52         GRAYSCALE,
     53         SEPIA,
     54         SATURATE,
     55         HUE_ROTATE,
     56         INVERT,
     57         OPACITY,
     58         BRIGHTNESS,
     59         CONTRAST,
     60         BLUR,
     61         DROP_SHADOW,
     62         CUSTOM,
     63         VALIDATED_CUSTOM,
     64         PASSTHROUGH,
     65         NONE
     66     };
     67 
     68     virtual ~FilterOperation() { }
     69 
     70     virtual bool operator==(const FilterOperation&) const = 0;
     71     bool operator!=(const FilterOperation& o) const { return !(*this == o); }
     72 
     73     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, bool /*blendToPassthrough*/ = false)
     74     {
     75         return 0;
     76     }
     77 
     78     virtual OperationType getOperationType() const { return m_type; }
     79     virtual bool isSameType(const FilterOperation& o) const { return o.getOperationType() == m_type; }
     80 
     81     virtual bool isDefault() const { return false; }
     82 
     83     // True if the alpha channel of any pixel can change under this operation.
     84     virtual bool affectsOpacity() const { return false; }
     85     // True if the the value of one pixel can affect the value of another pixel under this operation, such as blur.
     86     virtual bool movesPixels() const { return false; }
     87 
     88 protected:
     89     FilterOperation(OperationType type)
     90         : m_type(type)
     91     {
     92     }
     93 
     94     OperationType m_type;
     95 };
     96 
     97 class DefaultFilterOperation : public FilterOperation {
     98 public:
     99     static PassRefPtr<DefaultFilterOperation> create(OperationType type)
    100     {
    101         return adoptRef(new DefaultFilterOperation(type));
    102     }
    103 
    104 private:
    105 
    106     virtual bool operator==(const FilterOperation& o) const
    107     {
    108         return isSameType(o);
    109     }
    110 
    111     virtual bool isDefault() const { return true; }
    112 
    113     DefaultFilterOperation(OperationType type)
    114         : FilterOperation(type)
    115     {
    116     }
    117 };
    118 
    119 class PassthroughFilterOperation : public FilterOperation {
    120 public:
    121     static PassRefPtr<PassthroughFilterOperation> create()
    122     {
    123         return adoptRef(new PassthroughFilterOperation());
    124     }
    125 
    126 private:
    127 
    128     virtual bool operator==(const FilterOperation& o) const
    129     {
    130         return isSameType(o);
    131     }
    132 
    133     PassthroughFilterOperation()
    134         : FilterOperation(PASSTHROUGH)
    135     {
    136     }
    137 };
    138 
    139 class ReferenceFilterOperation : public FilterOperation {
    140 public:
    141     static PassRefPtr<ReferenceFilterOperation> create(const String& url, const String& fragment, OperationType type)
    142     {
    143         return adoptRef(new ReferenceFilterOperation(url, fragment, type));
    144     }
    145 
    146     virtual bool affectsOpacity() const { return true; }
    147     virtual bool movesPixels() const { return true; }
    148 
    149     const String& url() const { return m_url; }
    150     const String& fragment() const { return m_fragment; }
    151 
    152     DocumentResourceReference* documentResourceReference() const { return m_documentResourceReference.get(); }
    153     void setDocumentResourceReference(PassOwnPtr<DocumentResourceReference> documentResourceReference) { m_documentResourceReference = documentResourceReference; }
    154 
    155     ReferenceFilter* filter() const { return m_filter.get(); }
    156     void setFilter(PassRefPtr<ReferenceFilter> filter) { m_filter = filter; }
    157 
    158 private:
    159 
    160     virtual bool operator==(const FilterOperation& o) const
    161     {
    162         if (!isSameType(o))
    163             return false;
    164         const ReferenceFilterOperation* other = static_cast<const ReferenceFilterOperation*>(&o);
    165         return m_url == other->m_url;
    166     }
    167 
    168     ReferenceFilterOperation(const String& url, const String& fragment, OperationType type)
    169         : FilterOperation(type)
    170         , m_url(url)
    171         , m_fragment(fragment)
    172     {
    173     }
    174 
    175     String m_url;
    176     String m_fragment;
    177     OwnPtr<DocumentResourceReference> m_documentResourceReference;
    178     RefPtr<ReferenceFilter> m_filter;
    179 };
    180 
    181 // GRAYSCALE, SEPIA, SATURATE and HUE_ROTATE are variations on a basic color matrix effect.
    182 // For HUE_ROTATE, the angle of rotation is stored in m_amount.
    183 class BasicColorMatrixFilterOperation : public FilterOperation {
    184 public:
    185     static PassRefPtr<BasicColorMatrixFilterOperation> create(double amount, OperationType type)
    186     {
    187         return adoptRef(new BasicColorMatrixFilterOperation(amount, type));
    188     }
    189 
    190     double amount() const { return m_amount; }
    191 
    192     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
    193 
    194 private:
    195     virtual bool operator==(const FilterOperation& o) const
    196     {
    197         if (!isSameType(o))
    198             return false;
    199         const BasicColorMatrixFilterOperation* other = static_cast<const BasicColorMatrixFilterOperation*>(&o);
    200         return m_amount == other->m_amount;
    201     }
    202 
    203     double passthroughAmount() const;
    204 
    205     BasicColorMatrixFilterOperation(double amount, OperationType type)
    206         : FilterOperation(type)
    207         , m_amount(amount)
    208     {
    209     }
    210 
    211     double m_amount;
    212 };
    213 
    214 // INVERT, BRIGHTNESS, CONTRAST and OPACITY are variations on a basic component transfer effect.
    215 class BasicComponentTransferFilterOperation : public FilterOperation {
    216 public:
    217     static PassRefPtr<BasicComponentTransferFilterOperation> create(double amount, OperationType type)
    218     {
    219         return adoptRef(new BasicComponentTransferFilterOperation(amount, type));
    220     }
    221 
    222     double amount() const { return m_amount; }
    223 
    224     virtual bool affectsOpacity() const { return m_type == OPACITY; }
    225 
    226     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
    227 
    228 private:
    229     virtual bool operator==(const FilterOperation& o) const
    230     {
    231         if (!isSameType(o))
    232             return false;
    233         const BasicComponentTransferFilterOperation* other = static_cast<const BasicComponentTransferFilterOperation*>(&o);
    234         return m_amount == other->m_amount;
    235     }
    236 
    237     double passthroughAmount() const;
    238 
    239     BasicComponentTransferFilterOperation(double amount, OperationType type)
    240         : FilterOperation(type)
    241         , m_amount(amount)
    242     {
    243     }
    244 
    245     double m_amount;
    246 };
    247 
    248 class GammaFilterOperation : public FilterOperation {
    249 public:
    250     static PassRefPtr<GammaFilterOperation> create(double amplitude, double exponent, double offset, OperationType type)
    251     {
    252         return adoptRef(new GammaFilterOperation(amplitude, exponent, offset, type));
    253     }
    254 
    255     double amplitude() const { return m_amplitude; }
    256     double exponent() const { return m_exponent; }
    257     double offset() const { return m_offset; }
    258 
    259     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
    260 
    261 private:
    262     virtual bool operator==(const FilterOperation& o) const
    263     {
    264         if (!isSameType(o))
    265             return false;
    266         const GammaFilterOperation* other = static_cast<const GammaFilterOperation*>(&o);
    267         return m_amplitude == other->m_amplitude && m_exponent == other->m_exponent && m_offset == other->m_offset;
    268     }
    269 
    270     GammaFilterOperation(double amplitude, double exponent, double offset, OperationType type)
    271         : FilterOperation(type)
    272         , m_amplitude(amplitude)
    273         , m_exponent(exponent)
    274         , m_offset(offset)
    275     {
    276     }
    277 
    278     double m_amplitude;
    279     double m_exponent;
    280     double m_offset;
    281 };
    282 
    283 class BlurFilterOperation : public FilterOperation {
    284 public:
    285     static PassRefPtr<BlurFilterOperation> create(Length stdDeviation, OperationType type)
    286     {
    287         return adoptRef(new BlurFilterOperation(stdDeviation, type));
    288     }
    289 
    290     Length stdDeviation() const { return m_stdDeviation; }
    291 
    292     virtual bool affectsOpacity() const { return true; }
    293     virtual bool movesPixels() const { return true; }
    294 
    295     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
    296 
    297 private:
    298     virtual bool operator==(const FilterOperation& o) const
    299     {
    300         if (!isSameType(o))
    301             return false;
    302         const BlurFilterOperation* other = static_cast<const BlurFilterOperation*>(&o);
    303         return m_stdDeviation == other->m_stdDeviation;
    304     }
    305 
    306     BlurFilterOperation(Length stdDeviation, OperationType type)
    307         : FilterOperation(type)
    308         , m_stdDeviation(stdDeviation)
    309     {
    310     }
    311 
    312     Length m_stdDeviation;
    313 };
    314 
    315 class DropShadowFilterOperation : public FilterOperation {
    316 public:
    317     static PassRefPtr<DropShadowFilterOperation> create(const IntPoint& location, int stdDeviation, Color color, OperationType type)
    318     {
    319         return adoptRef(new DropShadowFilterOperation(location, stdDeviation, color, type));
    320     }
    321 
    322     int x() const { return m_location.x(); }
    323     int y() const { return m_location.y(); }
    324     IntPoint location() const { return m_location; }
    325     int stdDeviation() const { return m_stdDeviation; }
    326     Color color() const { return m_color; }
    327 
    328     virtual bool affectsOpacity() const { return true; }
    329     virtual bool movesPixels() const { return true; }
    330 
    331     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
    332 
    333 private:
    334 
    335     virtual bool operator==(const FilterOperation& o) const
    336     {
    337         if (!isSameType(o))
    338             return false;
    339         const DropShadowFilterOperation* other = static_cast<const DropShadowFilterOperation*>(&o);
    340         return m_location == other->m_location && m_stdDeviation == other->m_stdDeviation && m_color == other->m_color;
    341     }
    342 
    343     DropShadowFilterOperation(const IntPoint& location, int stdDeviation, Color color, OperationType type)
    344         : FilterOperation(type)
    345         , m_location(location)
    346         , m_stdDeviation(stdDeviation)
    347         , m_color(color)
    348     {
    349     }
    350 
    351     IntPoint m_location; // FIXME: should location be in Lengths?
    352     int m_stdDeviation;
    353     Color m_color;
    354 };
    355 
    356 } // namespace WebCore
    357 
    358 
    359 #endif // FilterOperation_h
    360