Use is<>() / downcast<>() for Filter / FilterOperation subclasses
[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 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 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 #include "Color.h"
30 #include "FilterEffect.h"
31 #include "LayoutSize.h"
32 #include "Length.h"
33 #include <wtf/OwnPtr.h>
34 #include <wtf/PassOwnPtr.h>
35 #include <wtf/RefCounted.h>
36 #include <wtf/TypeCasts.h>
37 #include <wtf/text/WTFString.h>
38
39 // Annoyingly, wingdi.h #defines this.
40 #ifdef PASSTHROUGH
41 #undef PASSTHROUGH
42 #endif
43
44 namespace WebCore {
45
46 // CSS Filters
47
48 class CachedSVGDocumentReference;
49
50 class FilterOperation : public RefCounted<FilterOperation> {
51 public:
52     enum OperationType {
53         REFERENCE, // url(#somefilter)
54         GRAYSCALE,
55         SEPIA,
56         SATURATE,
57         HUE_ROTATE,
58         INVERT,
59         OPACITY,
60         BRIGHTNESS,
61         CONTRAST,
62         BLUR,
63         DROP_SHADOW,
64         PASSTHROUGH,
65         DEFAULT,
66         NONE
67     };
68
69     virtual ~FilterOperation() { }
70
71     virtual PassRefPtr<FilterOperation> clone() const = 0;
72
73     virtual bool operator==(const FilterOperation&) const = 0;
74     bool operator!=(const FilterOperation& o) const { return !(*this == o); }
75
76     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, bool /*blendToPassthrough*/ = false)
77     {
78         ASSERT(!blendingNeedsRendererSize());
79         return 0;
80     }
81
82     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, const LayoutSize&, bool /*blendToPassthrough*/ = false)
83     {
84         ASSERT(blendingNeedsRendererSize());
85         return 0;
86     }
87
88     OperationType type() const { return m_type; }
89
90     bool isBasicColorMatrixFilterOperation() const
91     {
92         return m_type == GRAYSCALE || m_type == SEPIA || m_type == SATURATE || m_type == HUE_ROTATE;
93     }
94
95     bool isBasicComponentTransferFilterOperation() const
96     {
97         return m_type == INVERT || m_type == BRIGHTNESS || m_type == CONTRAST || m_type == OPACITY;
98     }
99
100     bool isSameType(const FilterOperation& o) const { return o.type() == m_type; }
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 WEBCORE_EXPORT DefaultFilterOperation : public FilterOperation {
119 public:
120     static PassRefPtr<DefaultFilterOperation> create(OperationType representedType)
121     {
122         return adoptRef(new DefaultFilterOperation(representedType));
123     }
124
125     virtual PassRefPtr<FilterOperation> clone() const override
126     {
127         return adoptRef(new DefaultFilterOperation(representedType()));
128     }
129
130     OperationType representedType() const { return m_representedType; }
131
132 private:
133     virtual bool operator==(const FilterOperation&) const override;
134
135     DefaultFilterOperation(OperationType representedType)
136         : FilterOperation(DEFAULT)
137         , m_representedType(representedType)
138     {
139     }
140
141     OperationType m_representedType;
142 };
143
144 class PassthroughFilterOperation : public FilterOperation {
145 public:
146     static PassRefPtr<PassthroughFilterOperation> create()
147     {
148         return adoptRef(new PassthroughFilterOperation());
149     }
150
151     virtual PassRefPtr<FilterOperation> clone() const override
152     {
153         return adoptRef(new PassthroughFilterOperation());
154     }
155
156 private:
157     virtual bool operator==(const FilterOperation& o) const override
158     {
159         return isSameType(o);
160     }
161
162     PassthroughFilterOperation()
163         : FilterOperation(PASSTHROUGH)
164     {
165     }
166 };
167
168 class ReferenceFilterOperation : public FilterOperation {
169 public:
170     static PassRefPtr<ReferenceFilterOperation> create(const String& url, const String& fragment)
171     {
172         return adoptRef(new ReferenceFilterOperation(url, fragment));
173     }
174     virtual ~ReferenceFilterOperation();
175
176     virtual PassRefPtr<FilterOperation> clone() const override
177     {
178         // Reference filters cannot be cloned.
179         ASSERT_NOT_REACHED();
180         return nullptr;
181     }
182
183     virtual bool affectsOpacity() const override { return true; }
184     virtual bool movesPixels() const override { return true; }
185
186     const String& url() const { return m_url; }
187     const String& fragment() const { return m_fragment; }
188
189     CachedSVGDocumentReference* cachedSVGDocumentReference() const { return m_cachedSVGDocumentReference.get(); }
190     CachedSVGDocumentReference* getOrCreateCachedSVGDocumentReference();
191
192     FilterEffect* filterEffect() const { return m_filterEffect.get(); }
193     void setFilterEffect(PassRefPtr<FilterEffect> filterEffect) { m_filterEffect = filterEffect; }
194
195 private:
196     ReferenceFilterOperation(const String& url, const String& fragment);
197
198     virtual bool operator==(const FilterOperation&) const override;
199
200     String m_url;
201     String m_fragment;
202     std::unique_ptr<CachedSVGDocumentReference> m_cachedSVGDocumentReference;
203     RefPtr<FilterEffect> m_filterEffect;
204 };
205
206 // GRAYSCALE, SEPIA, SATURATE and HUE_ROTATE are variations on a basic color matrix effect.
207 // For HUE_ROTATE, the angle of rotation is stored in m_amount.
208 class WEBCORE_EXPORT BasicColorMatrixFilterOperation : public FilterOperation {
209 public:
210     static PassRefPtr<BasicColorMatrixFilterOperation> create(double amount, OperationType type)
211     {
212         return adoptRef(new BasicColorMatrixFilterOperation(amount, type));
213     }
214
215     virtual PassRefPtr<FilterOperation> clone() const override
216     {
217         return adoptRef(new BasicColorMatrixFilterOperation(amount(), type()));
218     }
219
220     double amount() const { return m_amount; }
221
222     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
223
224 private:
225     virtual bool operator==(const FilterOperation&) const override;
226
227     double passthroughAmount() const;
228
229     BasicColorMatrixFilterOperation(double amount, OperationType type)
230         : FilterOperation(type)
231         , m_amount(amount)
232     {
233     }
234
235     double m_amount;
236 };
237
238 // INVERT, BRIGHTNESS, CONTRAST and OPACITY are variations on a basic component transfer effect.
239 class WEBCORE_EXPORT BasicComponentTransferFilterOperation : public FilterOperation {
240 public:
241     static PassRefPtr<BasicComponentTransferFilterOperation> create(double amount, OperationType type)
242     {
243         return adoptRef(new BasicComponentTransferFilterOperation(amount, type));
244     }
245
246     virtual PassRefPtr<FilterOperation> clone() const override
247     {
248         return adoptRef(new BasicComponentTransferFilterOperation(amount(), type()));
249     }
250
251     double amount() const { return m_amount; }
252
253     virtual bool affectsOpacity() const override { return m_type == OPACITY; }
254
255     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
256
257 private:
258     virtual bool operator==(const FilterOperation&) const override;
259
260     double passthroughAmount() const;
261
262     BasicComponentTransferFilterOperation(double amount, OperationType type)
263         : FilterOperation(type)
264         , m_amount(amount)
265     {
266     }
267
268     double m_amount;
269 };
270
271 class WEBCORE_EXPORT BlurFilterOperation : public FilterOperation {
272 public:
273     static PassRefPtr<BlurFilterOperation> create(Length stdDeviation)
274     {
275         return adoptRef(new BlurFilterOperation(WTF::move(stdDeviation)));
276     }
277
278     virtual PassRefPtr<FilterOperation> clone() const override
279     {
280         return adoptRef(new BlurFilterOperation(stdDeviation()));
281     }
282
283     const Length& stdDeviation() const { return m_stdDeviation; }
284
285     virtual bool affectsOpacity() const override { return true; }
286     virtual bool movesPixels() const override { return true; }
287
288     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
289
290 private:
291     virtual bool operator==(const FilterOperation&) const override;
292
293     BlurFilterOperation(Length stdDeviation)
294         : FilterOperation(BLUR)
295         , m_stdDeviation(WTF::move(stdDeviation))
296     {
297     }
298
299     Length m_stdDeviation;
300 };
301
302 class WEBCORE_EXPORT DropShadowFilterOperation : public FilterOperation {
303 public:
304     static PassRefPtr<DropShadowFilterOperation> create(const IntPoint& location, int stdDeviation, Color color)
305     {
306         return adoptRef(new DropShadowFilterOperation(location, stdDeviation, color));
307     }
308
309     virtual PassRefPtr<FilterOperation> clone() const override
310     {
311         return adoptRef(new DropShadowFilterOperation(location(), stdDeviation(), color()));
312     }
313
314     int x() const { return m_location.x(); }
315     int y() const { return m_location.y(); }
316     IntPoint location() const { return m_location; }
317     int stdDeviation() const { return m_stdDeviation; }
318     Color color() const { return m_color; }
319
320     virtual bool affectsOpacity() const override { return true; }
321     virtual bool movesPixels() const override { return true; }
322
323     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
324
325 private:
326     virtual bool operator==(const FilterOperation&) const override;
327
328     DropShadowFilterOperation(const IntPoint& location, int stdDeviation, Color color)
329         : FilterOperation(DROP_SHADOW)
330         , m_location(location)
331         , m_stdDeviation(stdDeviation)
332         , m_color(color)
333     {
334     }
335
336     IntPoint m_location; // FIXME: should location be in Lengths?
337     int m_stdDeviation;
338     Color m_color;
339 };
340
341 } // namespace WebCore
342
343 #define SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(ToValueTypeName, predicate) \
344 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
345     static bool isType(const WebCore::FilterOperation& operation) { return operation.predicate; } \
346 SPECIALIZE_TYPE_TRAITS_END()
347
348 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(DefaultFilterOperation, type() == WebCore::FilterOperation::DEFAULT)
349 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(PassthroughFilterOperation, type() == WebCore::FilterOperation::PASSTHROUGH)
350 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(ReferenceFilterOperation, type() == WebCore::FilterOperation::REFERENCE)
351 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(BasicColorMatrixFilterOperation, isBasicColorMatrixFilterOperation())
352 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(BasicComponentTransferFilterOperation, isBasicComponentTransferFilterOperation())
353 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(BlurFilterOperation, type() == WebCore::FilterOperation::BLUR)
354 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(DropShadowFilterOperation, type() == WebCore::FilterOperation::DROP_SHADOW)
355
356 #endif // FilterOperation_h