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