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