Stop using PassRefPtr in platform/graphics
[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 "LayoutSize.h"
31 #include "Length.h"
32 #include <wtf/RefCounted.h>
33 #include <wtf/TypeCasts.h>
34 #include <wtf/text/WTFString.h>
35
36 // Annoyingly, wingdi.h #defines this.
37 #ifdef PASSTHROUGH
38 #undef PASSTHROUGH
39 #endif
40
41 namespace WebCore {
42
43 // CSS Filters
44
45 class CachedResourceLoader;
46 class CachedSVGDocumentReference;
47 class FilterEffect;
48 struct ResourceLoaderOptions;
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 Ref<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 RefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, bool /*blendToPassthrough*/ = false)
77     {
78         ASSERT(!blendingNeedsRendererSize());
79         return nullptr;
80     }
81
82     virtual RefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, const LayoutSize&, bool /*blendToPassthrough*/ = false)
83     {
84         ASSERT(blendingNeedsRendererSize());
85         return nullptr;
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 should not be allowed to work on content that is not available from this security origin.
107     virtual bool shouldBeRestrictedBySecurityOrigin() const { return false; }
108     // True if the filter needs the size of the box in order to calculate the animations.
109     virtual bool blendingNeedsRendererSize() const { return false; }
110
111 protected:
112     FilterOperation(OperationType type)
113         : m_type(type)
114     {
115     }
116
117     OperationType m_type;
118 };
119
120 class WEBCORE_EXPORT DefaultFilterOperation : public FilterOperation {
121 public:
122     static Ref<DefaultFilterOperation> create(OperationType representedType)
123     {
124         return adoptRef(*new DefaultFilterOperation(representedType));
125     }
126
127     Ref<FilterOperation> clone() const override
128     {
129         return adoptRef(*new DefaultFilterOperation(representedType()));
130     }
131
132     OperationType representedType() const { return m_representedType; }
133
134 private:
135     bool operator==(const FilterOperation&) const override;
136
137     DefaultFilterOperation(OperationType representedType)
138         : FilterOperation(DEFAULT)
139         , m_representedType(representedType)
140     {
141     }
142
143     OperationType m_representedType;
144 };
145
146 class PassthroughFilterOperation : public FilterOperation {
147 public:
148     static Ref<PassthroughFilterOperation> create()
149     {
150         return adoptRef(*new PassthroughFilterOperation());
151     }
152
153     Ref<FilterOperation> clone() const override
154     {
155         return adoptRef(*new PassthroughFilterOperation());
156     }
157
158 private:
159     bool operator==(const FilterOperation& o) const override
160     {
161         return isSameType(o);
162     }
163
164     PassthroughFilterOperation()
165         : FilterOperation(PASSTHROUGH)
166     {
167     }
168 };
169
170 class ReferenceFilterOperation : public FilterOperation {
171 public:
172     static Ref<ReferenceFilterOperation> create(const String& url, const String& fragment)
173     {
174         return adoptRef(*new ReferenceFilterOperation(url, fragment));
175     }
176     virtual ~ReferenceFilterOperation();
177
178     Ref<FilterOperation> clone() const override
179     {
180         // Reference filters cannot be cloned.
181         RELEASE_ASSERT_NOT_REACHED();
182         return *static_cast<FilterOperation*>(nullptr);
183     }
184
185     bool affectsOpacity() const override { return true; }
186     bool movesPixels() const override { return true; }
187     // FIXME: This only needs to return true for graphs that include ConvolveMatrix, DisplacementMap, Morphology and possibly Lighting.
188     // https://bugs.webkit.org/show_bug.cgi?id=171753
189     bool shouldBeRestrictedBySecurityOrigin() const override { return true; }
190
191     const String& url() const { return m_url; }
192     const String& fragment() const { return m_fragment; }
193
194     void loadExternalDocumentIfNeeded(CachedResourceLoader&, const ResourceLoaderOptions&);
195
196     CachedSVGDocumentReference* cachedSVGDocumentReference() const { return m_cachedSVGDocumentReference.get(); }
197
198     FilterEffect* filterEffect() const { return m_filterEffect.get(); }
199     void setFilterEffect(RefPtr<FilterEffect>&&);
200
201 private:
202     ReferenceFilterOperation(const String& url, const String& fragment);
203
204     bool operator==(const FilterOperation&) const override;
205
206     String m_url;
207     String m_fragment;
208     std::unique_ptr<CachedSVGDocumentReference> m_cachedSVGDocumentReference;
209     RefPtr<FilterEffect> m_filterEffect;
210 };
211
212 // GRAYSCALE, SEPIA, SATURATE and HUE_ROTATE are variations on a basic color matrix effect.
213 // For HUE_ROTATE, the angle of rotation is stored in m_amount.
214 class WEBCORE_EXPORT BasicColorMatrixFilterOperation : public FilterOperation {
215 public:
216     static Ref<BasicColorMatrixFilterOperation> create(double amount, OperationType type)
217     {
218         return adoptRef(*new BasicColorMatrixFilterOperation(amount, type));
219     }
220
221     Ref<FilterOperation> clone() const override
222     {
223         return adoptRef(*new BasicColorMatrixFilterOperation(amount(), type()));
224     }
225
226     double amount() const { return m_amount; }
227
228     RefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
229
230 private:
231     bool operator==(const FilterOperation&) const override;
232
233     double passthroughAmount() const;
234
235     BasicColorMatrixFilterOperation(double amount, OperationType type)
236         : FilterOperation(type)
237         , m_amount(amount)
238     {
239     }
240
241     double m_amount;
242 };
243
244 // INVERT, BRIGHTNESS, CONTRAST and OPACITY are variations on a basic component transfer effect.
245 class WEBCORE_EXPORT BasicComponentTransferFilterOperation : public FilterOperation {
246 public:
247     static Ref<BasicComponentTransferFilterOperation> create(double amount, OperationType type)
248     {
249         return adoptRef(*new BasicComponentTransferFilterOperation(amount, type));
250     }
251
252     Ref<FilterOperation> clone() const override
253     {
254         return adoptRef(*new BasicComponentTransferFilterOperation(amount(), type()));
255     }
256
257     double amount() const { return m_amount; }
258
259     bool affectsOpacity() const override { return m_type == OPACITY; }
260
261     RefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
262
263 private:
264     bool operator==(const FilterOperation&) const override;
265
266     double passthroughAmount() const;
267
268     BasicComponentTransferFilterOperation(double amount, OperationType type)
269         : FilterOperation(type)
270         , m_amount(amount)
271     {
272     }
273
274     double m_amount;
275 };
276
277 class WEBCORE_EXPORT BlurFilterOperation : public FilterOperation {
278 public:
279     static Ref<BlurFilterOperation> create(Length stdDeviation)
280     {
281         return adoptRef(*new BlurFilterOperation(WTFMove(stdDeviation)));
282     }
283
284     Ref<FilterOperation> clone() const override
285     {
286         return adoptRef(*new BlurFilterOperation(stdDeviation()));
287     }
288
289     const Length& stdDeviation() const { return m_stdDeviation; }
290
291     bool affectsOpacity() const override { return true; }
292     bool movesPixels() const override { return true; }
293
294     RefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
295
296 private:
297     bool operator==(const FilterOperation&) const override;
298
299     BlurFilterOperation(Length stdDeviation)
300         : FilterOperation(BLUR)
301         , m_stdDeviation(WTFMove(stdDeviation))
302     {
303     }
304
305     Length m_stdDeviation;
306 };
307
308 class WEBCORE_EXPORT DropShadowFilterOperation : public FilterOperation {
309 public:
310     static Ref<DropShadowFilterOperation> create(const IntPoint& location, int stdDeviation, const Color& color)
311     {
312         return adoptRef(*new DropShadowFilterOperation(location, stdDeviation, color));
313     }
314
315     Ref<FilterOperation> clone() const override
316     {
317         return adoptRef(*new DropShadowFilterOperation(location(), stdDeviation(), color()));
318     }
319
320     int x() const { return m_location.x(); }
321     int y() const { return m_location.y(); }
322     IntPoint location() const { return m_location; }
323     int stdDeviation() const { return m_stdDeviation; }
324     const Color& color() const { return m_color; }
325
326     bool affectsOpacity() const override { return true; }
327     bool movesPixels() const override { return true; }
328
329     RefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false) override;
330
331 private:
332     bool operator==(const FilterOperation&) const override;
333
334     DropShadowFilterOperation(const IntPoint& location, int stdDeviation, const Color& color)
335         : FilterOperation(DROP_SHADOW)
336         , m_location(location)
337         , m_stdDeviation(stdDeviation)
338         , m_color(color)
339     {
340     }
341
342     IntPoint m_location; // FIXME: should location be in Lengths?
343     int m_stdDeviation;
344     Color m_color;
345 };
346
347 WEBCORE_EXPORT TextStream& operator<<(TextStream&, const FilterOperation&);
348
349 } // namespace WebCore
350
351 #define SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(ToValueTypeName, predicate) \
352 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
353     static bool isType(const WebCore::FilterOperation& operation) { return operation.predicate; } \
354 SPECIALIZE_TYPE_TRAITS_END()
355
356 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(DefaultFilterOperation, type() == WebCore::FilterOperation::DEFAULT)
357 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(PassthroughFilterOperation, type() == WebCore::FilterOperation::PASSTHROUGH)
358 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(ReferenceFilterOperation, type() == WebCore::FilterOperation::REFERENCE)
359 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(BasicColorMatrixFilterOperation, isBasicColorMatrixFilterOperation())
360 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(BasicComponentTransferFilterOperation, isBasicComponentTransferFilterOperation())
361 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(BlurFilterOperation, type() == WebCore::FilterOperation::BLUR)
362 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(DropShadowFilterOperation, type() == WebCore::FilterOperation::DROP_SHADOW)
363
364 #endif // FilterOperation_h