Add protected casting to FilterOperation classes.
[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 // Annoyingly, wingdi.h #defines this.
41 #ifdef PASSTHROUGH
42 #undef PASSTHROUGH
43 #endif
44
45 namespace WebCore {
46
47 // CSS Filters
48
49 class CachedSVGDocumentReference;
50
51 class FilterOperation : public RefCounted<FilterOperation> {
52 public:
53     enum OperationType {
54         REFERENCE, // url(#somefilter)
55         GRAYSCALE,
56         SEPIA,
57         SATURATE,
58         HUE_ROTATE,
59         INVERT,
60         OPACITY,
61         BRIGHTNESS,
62         CONTRAST,
63         BLUR,
64         DROP_SHADOW,
65         PASSTHROUGH,
66         NONE
67     };
68
69     virtual ~FilterOperation() { }
70
71     virtual bool operator==(const FilterOperation&) const = 0;
72     bool operator!=(const FilterOperation& o) const { return !(*this == o); }
73
74     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, bool /*blendToPassthrough*/ = false)
75     { 
76         ASSERT(!blendingNeedsRendererSize());
77         return 0; 
78     }
79
80     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, const LayoutSize&, bool /*blendToPassthrough*/ = false)
81     { 
82         ASSERT(blendingNeedsRendererSize());
83         return 0; 
84     }
85
86     virtual OperationType type() const { return m_type; }
87     virtual bool isSameType(const FilterOperation& o) const { return o.type() == m_type; }
88     
89     virtual bool isDefault() const { return false; }
90
91     // True if the alpha channel of any pixel can change under this operation.
92     virtual bool affectsOpacity() const { return false; }
93     // True if the the value of one pixel can affect the value of another pixel under this operation, such as blur.
94     virtual bool movesPixels() const { return false; }
95     // True if the filter needs the size of the box in order to calculate the animations.
96     virtual bool blendingNeedsRendererSize() const { return false; }
97
98 protected:
99     FilterOperation(OperationType type)
100         : m_type(type)
101     {
102     }
103
104     OperationType m_type;
105 };
106
107 class DefaultFilterOperation : public FilterOperation {
108 public:
109     static PassRefPtr<DefaultFilterOperation> create(OperationType type)
110     {
111         return adoptRef(new DefaultFilterOperation(type));
112     }
113
114 private:
115     virtual bool operator==(const FilterOperation& o) const override
116     {
117         return isSameType(o);
118     }
119
120     virtual bool isDefault() const override { return true; }
121
122     DefaultFilterOperation(OperationType type)
123         : FilterOperation(type)
124     {
125     }
126 };
127
128 class PassthroughFilterOperation : public FilterOperation {
129 public:
130     static PassRefPtr<PassthroughFilterOperation> create()
131     {
132         return adoptRef(new PassthroughFilterOperation());
133     }
134
135 private:
136     virtual bool operator==(const FilterOperation& o) const override
137     {
138         return isSameType(o);
139     }
140
141     PassthroughFilterOperation()
142         : FilterOperation(PASSTHROUGH)
143     {
144     }
145 };
146
147 class ReferenceFilterOperation : public FilterOperation {
148 public:
149     static PassRefPtr<ReferenceFilterOperation> create(const String& url, const String& fragment, OperationType type)
150     {
151         return adoptRef(new ReferenceFilterOperation(url, fragment, type));
152     }
153     virtual ~ReferenceFilterOperation();
154
155     virtual bool affectsOpacity() const override { return true; }
156     virtual bool movesPixels() const override { return true; }
157
158     const String& url() const { return m_url; }
159     const String& fragment() const { return m_fragment; }
160
161     CachedSVGDocumentReference* cachedSVGDocumentReference() const { return m_cachedSVGDocumentReference.get(); }
162     CachedSVGDocumentReference* getOrCreateCachedSVGDocumentReference();
163
164     FilterEffect* filterEffect() const { return m_filterEffect.get(); }
165     void setFilterEffect(PassRefPtr<FilterEffect> filterEffect) { m_filterEffect = filterEffect; }
166
167 private:
168     ReferenceFilterOperation(const String& url, const String& fragment, OperationType);
169
170     virtual bool operator==(const FilterOperation& o) const override
171     {
172         if (!isSameType(o))
173             return false;
174         const ReferenceFilterOperation* other = static_cast<const ReferenceFilterOperation*>(&o);
175         return m_url == other->m_url;
176     }
177
178     String m_url;
179     String m_fragment;
180     std::unique_ptr<CachedSVGDocumentReference> m_cachedSVGDocumentReference;
181     RefPtr<FilterEffect> m_filterEffect;
182 };
183
184 // GRAYSCALE, SEPIA, SATURATE and HUE_ROTATE are variations on a basic color matrix effect.
185 // For HUE_ROTATE, the angle of rotation is stored in m_amount.
186 class BasicColorMatrixFilterOperation : public FilterOperation {
187 public:
188     static PassRefPtr<BasicColorMatrixFilterOperation> create(double amount, OperationType type)
189     {
190         return adoptRef(new BasicColorMatrixFilterOperation(amount, type));
191     }
192
193     double amount() const { return m_amount; }
194
195     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
196
197 private:
198     virtual bool operator==(const FilterOperation&) const override;
199
200     double passthroughAmount() const;
201
202     BasicColorMatrixFilterOperation(double amount, OperationType type)
203         : FilterOperation(type)
204         , m_amount(amount)
205     {
206     }
207
208     double m_amount;
209 };
210
211 // INVERT, BRIGHTNESS, CONTRAST and OPACITY are variations on a basic component transfer effect.
212 class BasicComponentTransferFilterOperation : public FilterOperation {
213 public:
214     static PassRefPtr<BasicComponentTransferFilterOperation> create(double amount, OperationType type)
215     {
216         return adoptRef(new BasicComponentTransferFilterOperation(amount, type));
217     }
218
219     double amount() const { return m_amount; }
220
221     virtual bool affectsOpacity() const override { return m_type == OPACITY; }
222
223     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
224
225 private:
226     virtual bool operator==(const FilterOperation&) const override;
227
228     double passthroughAmount() const;
229
230     BasicComponentTransferFilterOperation(double amount, OperationType type)
231         : FilterOperation(type)
232         , m_amount(amount)
233     {
234     }
235
236     double m_amount;
237 };
238
239 class BlurFilterOperation : public FilterOperation {
240 public:
241     static PassRefPtr<BlurFilterOperation> create(Length stdDeviation, OperationType type)
242     {
243         return adoptRef(new BlurFilterOperation(std::move(stdDeviation), type));
244     }
245
246     const Length& stdDeviation() const { return m_stdDeviation; }
247
248     virtual bool affectsOpacity() const override { return true; }
249     virtual bool movesPixels() const override { return true; }
250
251     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
252
253 private:
254     virtual bool operator==(const FilterOperation& o) const override
255     {
256         if (!isSameType(o))
257             return false;
258         const BlurFilterOperation* other = static_cast<const BlurFilterOperation*>(&o);
259         return m_stdDeviation == other->m_stdDeviation;
260     }
261
262     BlurFilterOperation(Length stdDeviation, OperationType type)
263         : FilterOperation(type)
264         , m_stdDeviation(std::move(stdDeviation))
265     {
266     }
267
268     Length m_stdDeviation;
269 };
270
271 class DropShadowFilterOperation : public FilterOperation {
272 public:
273     static PassRefPtr<DropShadowFilterOperation> create(const IntPoint& location, int stdDeviation, Color color, OperationType type)
274     {
275         return adoptRef(new DropShadowFilterOperation(location, stdDeviation, color, type));
276     }
277
278     int x() const { return m_location.x(); }
279     int y() const { return m_location.y(); }
280     IntPoint location() const { return m_location; }
281     int stdDeviation() const { return m_stdDeviation; }
282     Color color() const { return m_color; }
283
284     virtual bool affectsOpacity() const override { return true; }
285     virtual bool movesPixels() const override { return true; }
286
287     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
288
289 private:
290     virtual bool operator==(const FilterOperation& o) const override
291     {
292         if (!isSameType(o))
293             return false;
294         const DropShadowFilterOperation* other = static_cast<const DropShadowFilterOperation*>(&o);
295         return m_location == other->m_location && m_stdDeviation == other->m_stdDeviation && m_color == other->m_color;
296     }
297
298     DropShadowFilterOperation(const IntPoint& location, int stdDeviation, Color color, OperationType type)
299         : FilterOperation(type)
300         , m_location(location)
301         , m_stdDeviation(stdDeviation)
302         , m_color(color)
303     {
304     }
305
306     IntPoint m_location; // FIXME: should location be in Lengths?
307     int m_stdDeviation;
308     Color m_color;
309 };
310
311 #define SIMPLE_FILTER_OPERATION_CASTS(ToValueTypeName, predicate) \
312     TYPE_CASTS_BASE(ToValueTypeName, FilterOperation, operation, operation->type() == FilterOperation::predicate, operation.type() == FilterOperation::predicate)
313
314 SIMPLE_FILTER_OPERATION_CASTS(ReferenceFilterOperation, REFERENCE)
315 SIMPLE_FILTER_OPERATION_CASTS(BlurFilterOperation, BLUR)
316 SIMPLE_FILTER_OPERATION_CASTS(DropShadowFilterOperation, DROP_SHADOW)
317
318 TYPE_CASTS_BASE(BasicColorMatrixFilterOperation, FilterOperation, operation, operation->type() == FilterOperation::GRAYSCALE || operation->type() == FilterOperation::SEPIA || operation->type() == FilterOperation::SATURATE || operation->type() == FilterOperation::HUE_ROTATE, operation.type() == FilterOperation::GRAYSCALE || operation.type() == FilterOperation::SEPIA || operation.type() == FilterOperation::SATURATE || operation.type() == FilterOperation::HUE_ROTATE)
319 TYPE_CASTS_BASE(BasicComponentTransferFilterOperation, FilterOperation, operation, operation->type() == FilterOperation::INVERT || operation->type() == FilterOperation::BRIGHTNESS || operation->type() == FilterOperation::CONTRAST || operation->type() == FilterOperation::OPACITY, operation.type() == FilterOperation::INVERT || operation.type() == FilterOperation::BRIGHTNESS || operation.type() == FilterOperation::CONTRAST || operation.type() == FilterOperation::OPACITY)
320
321 } // namespace WebCore
322
323 #endif // ENABLE(CSS_FILTERS)
324
325 #endif // FilterOperation_h