Enable CSS_FILTERS in Chromium.
[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 "Length.h"
33 #include <wtf/OwnPtr.h>
34 #include <wtf/PassOwnPtr.h>
35 #include <wtf/RefCounted.h>
36 #include <wtf/text/AtomicString.h>
37
38 // Annoyingly, wingdi.h #defines this.
39 #ifdef PASSTHROUGH
40 #undef PASSTHROUGH
41 #endif
42
43 namespace WebCore {
44
45 // CSS Filters
46
47 class FilterOperation : public RefCounted<FilterOperation> {
48 public:
49     enum OperationType {
50         REFERENCE, // url(#somefilter)
51         GRAYSCALE,
52         SEPIA,
53         SATURATE,
54         HUE_ROTATE,
55         INVERT,
56         OPACITY,
57         GAMMA,
58         BLUR,
59         SHARPEN,
60         DROP_SHADOW,
61 #if ENABLE(CSS_SHADERS)
62         CUSTOM,
63 #endif
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) { return 0; }
74
75     virtual OperationType getOperationType() const { return m_type; }
76     virtual bool isSameType(const FilterOperation& o) const { return o.getOperationType() == m_type; }
77
78 protected:
79     FilterOperation(OperationType type)
80         : m_type(type)
81     {
82     }
83
84     OperationType m_type;
85 };
86
87 class PassthroughFilterOperation : public FilterOperation {
88 public:
89     static PassRefPtr<PassthroughFilterOperation> create()
90     {
91         return adoptRef(new PassthroughFilterOperation());
92     }
93
94 private:
95
96     virtual bool operator==(const FilterOperation& o) const
97     {
98         return isSameType(o);
99     }
100
101     PassthroughFilterOperation()
102         : FilterOperation(PASSTHROUGH)
103     {
104     }
105 };
106
107 class ReferenceFilterOperation : public FilterOperation {
108 public:
109     static PassRefPtr<ReferenceFilterOperation> create(const AtomicString& reference, OperationType type)
110     {
111         return adoptRef(new ReferenceFilterOperation(reference, type));
112     }
113
114     const AtomicString& reference() const { return m_reference; }
115
116 private:
117
118     virtual bool operator==(const FilterOperation& o) const
119     {
120         if (!isSameType(o))
121             return false;
122         const ReferenceFilterOperation* other = static_cast<const ReferenceFilterOperation*>(&o);
123         return m_reference == other->m_reference;
124     }
125
126     ReferenceFilterOperation(const AtomicString& reference, OperationType type)
127         : FilterOperation(type)
128         , m_reference(reference)
129     {
130     }
131
132     AtomicString m_reference;
133 };
134
135 // GRAYSCALE, SEPIA, SATURATE and HUE_ROTATE are variations on a basic color matrix effect.
136 // For HUE_ROTATE, the angle of rotation is stored in m_amount.
137 class BasicColorMatrixFilterOperation : public FilterOperation {
138 public:
139     static PassRefPtr<BasicColorMatrixFilterOperation> create(double amount, OperationType type)
140     {
141         return adoptRef(new BasicColorMatrixFilterOperation(amount, type));
142     }
143
144     double amount() const { return m_amount; }
145
146     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
147
148 private:
149     virtual bool operator==(const FilterOperation& o) const
150     {
151         if (!isSameType(o))
152             return false;
153         const BasicColorMatrixFilterOperation* other = static_cast<const BasicColorMatrixFilterOperation*>(&o);
154         return m_amount == other->m_amount;
155     }
156     
157     double passthroughAmount() const;
158     
159     BasicColorMatrixFilterOperation(double amount, OperationType type)
160         : FilterOperation(type)
161         , m_amount(amount)
162     {
163     }
164
165     double m_amount;
166 };
167
168 // INVERT and OPACITY are variations on a basic component transfer effect.
169 class BasicComponentTransferFilterOperation : public FilterOperation {
170 public:
171     static PassRefPtr<BasicComponentTransferFilterOperation> create(double amount, OperationType type)
172     {
173         return adoptRef(new BasicComponentTransferFilterOperation(amount, type));
174     }
175
176     double amount() const { return m_amount; }
177
178     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
179
180 private:
181     virtual bool operator==(const FilterOperation& o) const
182     {
183         if (!isSameType(o))
184             return false;
185         const BasicComponentTransferFilterOperation* other = static_cast<const BasicComponentTransferFilterOperation*>(&o);
186         return m_amount == other->m_amount;
187     }
188
189     double passthroughAmount() const;
190
191     BasicComponentTransferFilterOperation(double amount, OperationType type)
192         : FilterOperation(type)
193         , m_amount(amount)
194     {
195     }
196
197     double m_amount;
198 };
199
200 class GammaFilterOperation : public FilterOperation {
201 public:
202     static PassRefPtr<GammaFilterOperation> create(double amplitude, double exponent, double offset, OperationType type)
203     {
204         return adoptRef(new GammaFilterOperation(amplitude, exponent, offset, type));
205     }
206
207     double amplitude() const { return m_amplitude; }
208     double exponent() const { return m_exponent; }
209     double offset() const { return m_offset; }
210
211     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
212
213 private:
214     virtual bool operator==(const FilterOperation& o) const
215     {
216         if (!isSameType(o))
217             return false;
218         const GammaFilterOperation* other = static_cast<const GammaFilterOperation*>(&o);
219         return m_amplitude == other->m_amplitude && m_exponent == other->m_exponent && m_offset == other->m_offset;
220     }
221
222     GammaFilterOperation(double amplitude, double exponent, double offset, OperationType type)
223         : FilterOperation(type)
224         , m_amplitude(amplitude)
225         , m_exponent(exponent)
226         , m_offset(offset)
227     {
228     }
229
230     double m_amplitude;
231     double m_exponent;
232     double m_offset;
233 };
234
235 class BlurFilterOperation : public FilterOperation {
236 public:
237     static PassRefPtr<BlurFilterOperation> create(Length stdDeviationX, Length stdDeviationY, OperationType type)
238     {
239         return adoptRef(new BlurFilterOperation(stdDeviationX, stdDeviationY, type));
240     }
241
242     Length stdDeviationX() const { return m_stdDeviationX; }
243     Length stdDeviationY() const { return m_stdDeviationY; }
244
245     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
246
247 private:
248     virtual bool operator==(const FilterOperation& o) const
249     {
250         if (!isSameType(o))
251             return false;
252         const BlurFilterOperation* other = static_cast<const BlurFilterOperation*>(&o);
253         return m_stdDeviationX == other->m_stdDeviationX && m_stdDeviationY == other->m_stdDeviationY;
254     }
255
256     BlurFilterOperation(Length stdDeviationX, Length stdDeviationY, OperationType type)
257         : FilterOperation(type)
258         , m_stdDeviationX(stdDeviationX)
259         , m_stdDeviationY(stdDeviationY)
260     {
261     }
262
263     Length m_stdDeviationX;
264     Length m_stdDeviationY;
265 };
266
267 // FIXME: sharpen will be removed.
268 class SharpenFilterOperation : public FilterOperation {
269 public:
270     static PassRefPtr<SharpenFilterOperation> create(double amount, Length radius, double threshold, OperationType type)
271     {
272         return adoptRef(new SharpenFilterOperation(amount, radius, threshold, type));
273     }
274
275     double amount() const { return m_amount; }
276     Length radius() const { return m_radius; }
277     double threshold() const { return m_threshold; }
278
279 private:
280     virtual bool operator==(const FilterOperation& o) const
281     {
282         if (!isSameType(o))
283             return false;
284         const SharpenFilterOperation* other = static_cast<const SharpenFilterOperation*>(&o);
285         return m_radius == other->m_radius && m_threshold == other->m_threshold && m_amount == other->m_amount;
286     }
287
288     SharpenFilterOperation(double amount, Length radius, double threshold, OperationType type)
289         : FilterOperation(type)
290         , m_amount(amount)
291         , m_radius(radius)
292         , m_threshold(threshold)
293     {
294     }
295
296     double m_amount;
297     Length m_radius;
298     double m_threshold;
299 };
300
301 class DropShadowFilterOperation : public FilterOperation {
302 public:
303     static PassRefPtr<DropShadowFilterOperation> create(int x, int y, int stdDeviation, Color color, OperationType type)
304     {
305         return adoptRef(new DropShadowFilterOperation(x, y, stdDeviation, color, type));
306     }
307
308     int x() const { return m_x; }
309     int y() const { return m_y; }
310     int stdDeviation() const { return m_stdDeviation; }
311     Color color() const { return m_color; }
312
313     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
314
315 private:
316
317     virtual bool operator==(const FilterOperation& o) const
318     {
319         if (!isSameType(o))
320             return false;
321         const DropShadowFilterOperation* other = static_cast<const DropShadowFilterOperation*>(&o);
322         return m_x == other->m_x && m_y == other->m_y && m_stdDeviation == other->m_stdDeviation && m_color == other->m_color;
323     }
324
325     DropShadowFilterOperation(int x, int y, int stdDeviation, Color color, OperationType type)
326         : FilterOperation(type)
327         , m_x(x)
328         , m_y(y)
329         , m_stdDeviation(stdDeviation)
330         , m_color(color)
331     {
332     }
333
334     int m_x; // FIXME: x and y should be Lengths?
335     int m_y;
336     int m_stdDeviation;
337     Color m_color;
338 };
339
340 } // namespace WebCore
341
342 #endif // ENABLE(CSS_FILTERS)
343
344 #endif // FilterOperation_h