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