b8796e802918bcb6aa3570d193cccbdf3d1c9e63
[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/WTFString.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         BRIGHTNESS,
58         CONTRAST,
59         BLUR,
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     virtual bool isDefault() const { return false; }
79
80     // True if the alpha channel of any pixel can change under this operation.
81     virtual bool affectsOpacity() const { return false; }
82     // True if the the value of one pixel can affect the value of another pixel under this operation, such as blur.
83     virtual bool movesPixels() const { return false; }
84
85     virtual PassRefPtr<FilterOperation> clone() const = 0;
86
87 protected:
88     FilterOperation(OperationType type)
89         : m_type(type)
90     {
91     }
92
93     OperationType m_type;
94 };
95
96 class DefaultFilterOperation : public FilterOperation {
97 public:
98     static PassRefPtr<DefaultFilterOperation> create(OperationType type)
99     {
100         return adoptRef(new DefaultFilterOperation(type));
101     }
102
103     virtual PassRefPtr<FilterOperation> clone() const
104     {
105         return adoptRef(new DefaultFilterOperation(m_type));
106     }
107
108 private:
109
110     virtual bool operator==(const FilterOperation& o) const
111     {
112         return isSameType(o);
113     }
114
115     virtual bool isDefault() const { return true; }
116
117     DefaultFilterOperation(OperationType type)
118         : FilterOperation(type)
119     {
120     }
121 };
122
123 class PassthroughFilterOperation : public FilterOperation {
124 public:
125     static PassRefPtr<PassthroughFilterOperation> create()
126     {
127         return adoptRef(new PassthroughFilterOperation());
128     }
129
130     virtual PassRefPtr<FilterOperation> clone() const
131     {
132         return adoptRef(new PassthroughFilterOperation());
133     }
134
135 private:
136
137     virtual bool operator==(const FilterOperation& o) const
138     {
139         return isSameType(o);
140     }
141
142     PassthroughFilterOperation()
143         : FilterOperation(PASSTHROUGH)
144     {
145     }
146 };
147
148 class ReferenceFilterOperation : public FilterOperation {
149 public:
150     static PassRefPtr<ReferenceFilterOperation> create(const String& url, const String& fragment, OperationType type)
151     {
152         return adoptRef(new ReferenceFilterOperation(url, fragment, type));
153     }
154
155     virtual PassRefPtr<FilterOperation> clone() const
156     {
157         // Unimplemented
158         return 0;
159     }
160
161     virtual bool affectsOpacity() const { return true; }
162     virtual bool movesPixels() const { return true; }
163
164     const String& url() const { return m_url; }
165     const String& fragment() const { return m_fragment; }
166
167     void* data() const { return m_data; }
168     void setData(void* data) { m_data = data; }
169
170 private:
171
172     virtual bool operator==(const FilterOperation& o) const
173     {
174         if (!isSameType(o))
175             return false;
176         const ReferenceFilterOperation* other = static_cast<const ReferenceFilterOperation*>(&o);
177         return m_url == other->m_url;
178     }
179
180     ReferenceFilterOperation(const String& url, const String& fragment, OperationType type)
181         : FilterOperation(type)
182         , m_url(url)
183         , m_fragment(fragment)
184         , m_data(0)
185     {
186     }
187
188     String m_url;
189     String m_fragment;
190     void* m_data;
191 };
192
193 // GRAYSCALE, SEPIA, SATURATE and HUE_ROTATE are variations on a basic color matrix effect.
194 // For HUE_ROTATE, the angle of rotation is stored in m_amount.
195 class BasicColorMatrixFilterOperation : public FilterOperation {
196 public:
197     static PassRefPtr<BasicColorMatrixFilterOperation> create(double amount, OperationType type)
198     {
199         return adoptRef(new BasicColorMatrixFilterOperation(amount, type));
200     }
201
202     virtual PassRefPtr<FilterOperation> clone() const
203     {
204         return adoptRef(new BasicColorMatrixFilterOperation(m_amount, m_type));
205     }
206
207     double amount() const { return m_amount; }
208
209     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
210
211 private:
212     virtual bool operator==(const FilterOperation& o) const
213     {
214         if (!isSameType(o))
215             return false;
216         const BasicColorMatrixFilterOperation* other = static_cast<const BasicColorMatrixFilterOperation*>(&o);
217         return m_amount == other->m_amount;
218     }
219     
220     double passthroughAmount() const;
221     
222     BasicColorMatrixFilterOperation(double amount, OperationType type)
223         : FilterOperation(type)
224         , m_amount(amount)
225     {
226     }
227
228     double m_amount;
229 };
230
231 // INVERT, BRIGHTNESS, CONTRAST and OPACITY are variations on a basic component transfer effect.
232 class BasicComponentTransferFilterOperation : public FilterOperation {
233 public:
234     static PassRefPtr<BasicComponentTransferFilterOperation> create(double amount, OperationType type)
235     {
236         return adoptRef(new BasicComponentTransferFilterOperation(amount, type));
237     }
238
239     virtual PassRefPtr<FilterOperation> clone() const
240     {
241         return adoptRef(new BasicComponentTransferFilterOperation(m_amount, m_type));
242     }
243
244     double amount() const { return m_amount; }
245
246     virtual bool affectsOpacity() const { return m_type == OPACITY; }
247
248     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
249
250 private:
251     virtual bool operator==(const FilterOperation& o) const
252     {
253         if (!isSameType(o))
254             return false;
255         const BasicComponentTransferFilterOperation* other = static_cast<const BasicComponentTransferFilterOperation*>(&o);
256         return m_amount == other->m_amount;
257     }
258
259     double passthroughAmount() const;
260
261     BasicComponentTransferFilterOperation(double amount, OperationType type)
262         : FilterOperation(type)
263         , m_amount(amount)
264     {
265     }
266
267     double m_amount;
268 };
269
270 class GammaFilterOperation : public FilterOperation {
271 public:
272     static PassRefPtr<GammaFilterOperation> create(double amplitude, double exponent, double offset, OperationType type)
273     {
274         return adoptRef(new GammaFilterOperation(amplitude, exponent, offset, type));
275     }
276
277     virtual PassRefPtr<FilterOperation> clone() const
278     {
279         return adoptRef(new GammaFilterOperation(m_amplitude, m_exponent, m_offset, m_type));
280     }
281
282     double amplitude() const { return m_amplitude; }
283     double exponent() const { return m_exponent; }
284     double offset() const { return m_offset; }
285
286     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
287
288 private:
289     virtual bool operator==(const FilterOperation& o) const
290     {
291         if (!isSameType(o))
292             return false;
293         const GammaFilterOperation* other = static_cast<const GammaFilterOperation*>(&o);
294         return m_amplitude == other->m_amplitude && m_exponent == other->m_exponent && m_offset == other->m_offset;
295     }
296
297     GammaFilterOperation(double amplitude, double exponent, double offset, OperationType type)
298         : FilterOperation(type)
299         , m_amplitude(amplitude)
300         , m_exponent(exponent)
301         , m_offset(offset)
302     {
303     }
304
305     double m_amplitude;
306     double m_exponent;
307     double m_offset;
308 };
309
310 class BlurFilterOperation : public FilterOperation {
311 public:
312     static PassRefPtr<BlurFilterOperation> create(Length stdDeviation, OperationType type)
313     {
314         return adoptRef(new BlurFilterOperation(stdDeviation, type));
315     }
316
317     virtual PassRefPtr<FilterOperation> clone() const
318     {
319         return adoptRef(new BlurFilterOperation(m_stdDeviation, m_type));
320     }
321
322     Length stdDeviation() const { return m_stdDeviation; }
323
324     virtual bool affectsOpacity() const { return true; }
325     virtual bool movesPixels() const { return true; }
326
327     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
328
329 private:
330     virtual bool operator==(const FilterOperation& o) const
331     {
332         if (!isSameType(o))
333             return false;
334         const BlurFilterOperation* other = static_cast<const BlurFilterOperation*>(&o);
335         return m_stdDeviation == other->m_stdDeviation;
336     }
337
338     BlurFilterOperation(Length stdDeviation, OperationType type)
339         : FilterOperation(type)
340         , m_stdDeviation(stdDeviation)
341     {
342     }
343
344     Length m_stdDeviation;
345 };
346
347 class DropShadowFilterOperation : public FilterOperation {
348 public:
349     static PassRefPtr<DropShadowFilterOperation> create(const IntPoint& location, int stdDeviation, Color color, OperationType type)
350     {
351         return adoptRef(new DropShadowFilterOperation(location, stdDeviation, color, type));
352     }
353
354     virtual PassRefPtr<FilterOperation> clone() const
355     {
356         return adoptRef(new DropShadowFilterOperation(m_location, m_stdDeviation, m_color, m_type));
357     }
358
359     int x() const { return m_location.x(); }
360     int y() const { return m_location.y(); }
361     IntPoint location() const { return m_location; }
362     int stdDeviation() const { return m_stdDeviation; }
363     Color color() const { return m_color; }
364
365     virtual bool affectsOpacity() const { return true; }
366     virtual bool movesPixels() const { return true; }
367
368     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
369
370 private:
371
372     virtual bool operator==(const FilterOperation& o) const
373     {
374         if (!isSameType(o))
375             return false;
376         const DropShadowFilterOperation* other = static_cast<const DropShadowFilterOperation*>(&o);
377         return m_location == other->m_location && m_stdDeviation == other->m_stdDeviation && m_color == other->m_color;
378     }
379
380     DropShadowFilterOperation(const IntPoint& location, int stdDeviation, Color color, OperationType type)
381         : FilterOperation(type)
382         , m_location(location)
383         , m_stdDeviation(stdDeviation)
384         , m_color(color)
385     {
386     }
387
388     IntPoint m_location; // FIXME: should location be in Lengths?
389     int m_stdDeviation;
390     Color m_color;
391 };
392
393 } // namespace WebCore
394
395 #endif // ENABLE(CSS_FILTERS)
396
397 #endif // FilterOperation_h