710dbc913039f32fa77b053a88c9964a2c1fc8c4
[WebKit-https.git] / Source / WebCore / platform / graphics / filters / FilterOperation.h
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 #if ENABLE(CSS_FILTERS)
30
31 #include "Color.h"
32 #include "LayoutTypes.h"
33 #include "Length.h"
34 #include <wtf/OwnPtr.h>
35 #include <wtf/PassOwnPtr.h>
36 #include <wtf/RefCounted.h>
37 #include <wtf/text/WTFString.h>
38
39 #if PLATFORM(BLACKBERRY)
40 #include <wtf/ThreadSafeRefCounted.h>
41 #endif
42
43 // Annoyingly, wingdi.h #defines this.
44 #ifdef PASSTHROUGH
45 #undef PASSTHROUGH
46 #endif
47
48 namespace WebCore {
49
50 // CSS Filters
51
52 #if PLATFORM(BLACKBERRY)
53 class FilterOperation : public ThreadSafeRefCounted<FilterOperation> {
54 #else
55 class FilterOperation : public RefCounted<FilterOperation> {
56 #endif
57 public:
58     enum OperationType {
59         REFERENCE, // url(#somefilter)
60         GRAYSCALE,
61         SEPIA,
62         SATURATE,
63         HUE_ROTATE,
64         INVERT,
65         OPACITY,
66         BRIGHTNESS,
67         CONTRAST,
68         BLUR,
69         DROP_SHADOW,
70 #if ENABLE(CSS_SHADERS)
71         CUSTOM,
72         VALIDATED_CUSTOM,
73 #endif
74         PASSTHROUGH,
75         NONE
76     };
77
78     virtual ~FilterOperation() { }
79
80     virtual bool operator==(const FilterOperation&) const = 0;
81     bool operator!=(const FilterOperation& o) const { return !(*this == o); }
82
83     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, bool /*blendToPassthrough*/ = false)
84     { 
85         ASSERT(!blendingNeedsRendererSize());
86         return 0; 
87     }
88
89     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, const LayoutSize&, bool /*blendToPassthrough*/ = false)
90     { 
91         ASSERT(blendingNeedsRendererSize());
92         return 0; 
93     }
94
95     virtual OperationType getOperationType() const { return m_type; }
96     virtual bool isSameType(const FilterOperation& o) const { return o.getOperationType() == m_type; }
97     
98     virtual bool isDefault() const { return false; }
99
100     // True if the alpha channel of any pixel can change under this operation.
101     virtual bool affectsOpacity() const { return false; }
102     // True if the the value of one pixel can affect the value of another pixel under this operation, such as blur.
103     virtual bool movesPixels() const { return false; }
104     // True if the filter needs the size of the box in order to calculate the animations.
105     virtual bool blendingNeedsRendererSize() const { return false; }
106
107 protected:
108     FilterOperation(OperationType type)
109         : m_type(type)
110     {
111     }
112
113     OperationType m_type;
114 };
115
116 class DefaultFilterOperation : public FilterOperation {
117 public:
118     static PassRefPtr<DefaultFilterOperation> create(OperationType type)
119     {
120         return adoptRef(new DefaultFilterOperation(type));
121     }
122
123 private:
124
125     virtual bool operator==(const FilterOperation& o) const
126     {
127         return isSameType(o);
128     }
129
130     virtual bool isDefault() const { return true; }
131
132     DefaultFilterOperation(OperationType type)
133         : FilterOperation(type)
134     {
135     }
136 };
137
138 class PassthroughFilterOperation : public FilterOperation {
139 public:
140     static PassRefPtr<PassthroughFilterOperation> create()
141     {
142         return adoptRef(new PassthroughFilterOperation());
143     }
144
145 private:
146
147     virtual bool operator==(const FilterOperation& o) const
148     {
149         return isSameType(o);
150     }
151
152     PassthroughFilterOperation()
153         : FilterOperation(PASSTHROUGH)
154     {
155     }
156 };
157
158 class ReferenceFilterOperation : public FilterOperation {
159 public:
160     static PassRefPtr<ReferenceFilterOperation> create(const String& url, const String& fragment, OperationType type)
161     {
162         return adoptRef(new ReferenceFilterOperation(url, fragment, type));
163     }
164
165     class Data {
166     public:
167         virtual ~Data() { }
168     };
169
170     virtual bool affectsOpacity() const { return true; }
171     virtual bool movesPixels() const { return true; }
172
173     const String& url() const { return m_url; }
174     const String& fragment() const { return m_fragment; }
175
176     Data* data() const { return m_data.get(); }
177     void setData(PassOwnPtr<Data> data) { m_data = data; }
178
179 private:
180
181     virtual bool operator==(const FilterOperation& o) const
182     {
183         if (!isSameType(o))
184             return false;
185         const ReferenceFilterOperation* other = static_cast<const ReferenceFilterOperation*>(&o);
186         return m_url == other->m_url;
187     }
188
189     ReferenceFilterOperation(const String& url, const String& fragment, OperationType type)
190         : FilterOperation(type)
191         , m_url(url)
192         , m_fragment(fragment)
193     {
194     }
195
196     String m_url;
197     String m_fragment;
198     OwnPtr<Data> m_data;
199 };
200
201 // GRAYSCALE, SEPIA, SATURATE and HUE_ROTATE are variations on a basic color matrix effect.
202 // For HUE_ROTATE, the angle of rotation is stored in m_amount.
203 class BasicColorMatrixFilterOperation : public FilterOperation {
204 public:
205     static PassRefPtr<BasicColorMatrixFilterOperation> create(double amount, OperationType type)
206     {
207         return adoptRef(new BasicColorMatrixFilterOperation(amount, type));
208     }
209
210     double amount() const { return m_amount; }
211
212     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
213
214 private:
215     virtual bool operator==(const FilterOperation& o) const
216     {
217         if (!isSameType(o))
218             return false;
219         const BasicColorMatrixFilterOperation* other = static_cast<const BasicColorMatrixFilterOperation*>(&o);
220         return m_amount == other->m_amount;
221     }
222     
223     double passthroughAmount() const;
224     
225     BasicColorMatrixFilterOperation(double amount, OperationType type)
226         : FilterOperation(type)
227         , m_amount(amount)
228     {
229     }
230
231     double m_amount;
232 };
233
234 // INVERT, BRIGHTNESS, CONTRAST and OPACITY are variations on a basic component transfer effect.
235 class BasicComponentTransferFilterOperation : public FilterOperation {
236 public:
237     static PassRefPtr<BasicComponentTransferFilterOperation> create(double amount, OperationType type)
238     {
239         return adoptRef(new BasicComponentTransferFilterOperation(amount, type));
240     }
241
242     double amount() const { return m_amount; }
243
244     virtual bool affectsOpacity() const { return m_type == OPACITY; }
245
246     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
247
248 private:
249     virtual bool operator==(const FilterOperation& o) const
250     {
251         if (!isSameType(o))
252             return false;
253         const BasicComponentTransferFilterOperation* other = static_cast<const BasicComponentTransferFilterOperation*>(&o);
254         return m_amount == other->m_amount;
255     }
256
257     double passthroughAmount() const;
258
259     BasicComponentTransferFilterOperation(double amount, OperationType type)
260         : FilterOperation(type)
261         , m_amount(amount)
262     {
263     }
264
265     double m_amount;
266 };
267
268 class GammaFilterOperation : public FilterOperation {
269 public:
270     static PassRefPtr<GammaFilterOperation> create(double amplitude, double exponent, double offset, OperationType type)
271     {
272         return adoptRef(new GammaFilterOperation(amplitude, exponent, offset, type));
273     }
274
275     double amplitude() const { return m_amplitude; }
276     double exponent() const { return m_exponent; }
277     double offset() const { return m_offset; }
278
279     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
280
281 private:
282     virtual bool operator==(const FilterOperation& o) const
283     {
284         if (!isSameType(o))
285             return false;
286         const GammaFilterOperation* other = static_cast<const GammaFilterOperation*>(&o);
287         return m_amplitude == other->m_amplitude && m_exponent == other->m_exponent && m_offset == other->m_offset;
288     }
289
290     GammaFilterOperation(double amplitude, double exponent, double offset, OperationType type)
291         : FilterOperation(type)
292         , m_amplitude(amplitude)
293         , m_exponent(exponent)
294         , m_offset(offset)
295     {
296     }
297
298     double m_amplitude;
299     double m_exponent;
300     double m_offset;
301 };
302
303 class BlurFilterOperation : public FilterOperation {
304 public:
305     static PassRefPtr<BlurFilterOperation> create(Length stdDeviation, OperationType type)
306     {
307         return adoptRef(new BlurFilterOperation(stdDeviation, type));
308     }
309
310     Length stdDeviation() const { return m_stdDeviation; }
311
312     virtual bool affectsOpacity() const { return true; }
313     virtual bool movesPixels() const { return true; }
314
315     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
316
317 private:
318     virtual bool operator==(const FilterOperation& o) const
319     {
320         if (!isSameType(o))
321             return false;
322         const BlurFilterOperation* other = static_cast<const BlurFilterOperation*>(&o);
323         return m_stdDeviation == other->m_stdDeviation;
324     }
325
326     BlurFilterOperation(Length stdDeviation, OperationType type)
327         : FilterOperation(type)
328         , m_stdDeviation(stdDeviation)
329     {
330     }
331
332     Length m_stdDeviation;
333 };
334
335 class DropShadowFilterOperation : public FilterOperation {
336 public:
337     static PassRefPtr<DropShadowFilterOperation> create(const IntPoint& location, int stdDeviation, Color color, OperationType type)
338     {
339         return adoptRef(new DropShadowFilterOperation(location, stdDeviation, color, type));
340     }
341
342     int x() const { return m_location.x(); }
343     int y() const { return m_location.y(); }
344     IntPoint location() const { return m_location; }
345     int stdDeviation() const { return m_stdDeviation; }
346     Color color() const { return m_color; }
347
348     virtual bool affectsOpacity() const { return true; }
349     virtual bool movesPixels() const { return true; }
350
351     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
352
353 private:
354
355     virtual bool operator==(const FilterOperation& o) const
356     {
357         if (!isSameType(o))
358             return false;
359         const DropShadowFilterOperation* other = static_cast<const DropShadowFilterOperation*>(&o);
360         return m_location == other->m_location && m_stdDeviation == other->m_stdDeviation && m_color == other->m_color;
361     }
362
363     DropShadowFilterOperation(const IntPoint& location, int stdDeviation, Color color, OperationType type)
364         : FilterOperation(type)
365         , m_location(location)
366         , m_stdDeviation(stdDeviation)
367         , m_color(color)
368     {
369     }
370
371     IntPoint m_location; // FIXME: should location be in Lengths?
372     int m_stdDeviation;
373     Color m_color;
374 };
375
376 } // namespace WebCore
377
378 #endif // ENABLE(CSS_FILTERS)
379
380 #endif // FilterOperation_h