Use "= default" to denote default constructor or destructor
[WebKit-https.git] / Source / WebCore / platform / graphics / filters / FilterOperation.cpp
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 #include "config.h"
27 #include "FilterOperation.h"
28
29 #include "AnimationUtilities.h"
30 #include "CachedResourceLoader.h"
31 #include "CachedSVGDocumentReference.h"
32 #include "FilterEffect.h"
33 #include "SVGURIReference.h"
34 #include <wtf/text/TextStream.h>
35
36 namespace WebCore {
37     
38 bool DefaultFilterOperation::operator==(const FilterOperation& operation) const
39 {
40     if (!isSameType(operation))
41         return false;
42     
43     return representedType() == downcast<DefaultFilterOperation>(operation).representedType();
44 }
45
46 ReferenceFilterOperation::ReferenceFilterOperation(const String& url, const String& fragment)
47     : FilterOperation(REFERENCE)
48     , m_url(url)
49     , m_fragment(fragment)
50 {
51 }
52
53 ReferenceFilterOperation::~ReferenceFilterOperation() = default;
54     
55 bool ReferenceFilterOperation::operator==(const FilterOperation& operation) const
56 {
57     if (!isSameType(operation))
58         return false;
59     
60     return m_url == downcast<ReferenceFilterOperation>(operation).m_url;
61 }
62
63 void ReferenceFilterOperation::loadExternalDocumentIfNeeded(CachedResourceLoader& cachedResourceLoader, const ResourceLoaderOptions& options)
64 {
65     if (m_cachedSVGDocumentReference)
66         return;
67     if (!SVGURIReference::isExternalURIReference(m_url, *cachedResourceLoader.document()))
68         return;
69     m_cachedSVGDocumentReference = std::make_unique<CachedSVGDocumentReference>(m_url);
70     m_cachedSVGDocumentReference->load(cachedResourceLoader, options);
71 }
72
73 void ReferenceFilterOperation::setFilterEffect(RefPtr<FilterEffect>&& filterEffect)
74 {
75     m_filterEffect = WTFMove(filterEffect);
76 }
77
78 RefPtr<FilterOperation> BasicColorMatrixFilterOperation::blend(const FilterOperation* from, double progress, bool blendToPassthrough)
79 {
80     if (from && !from->isSameType(*this))
81         return this;
82     
83     if (blendToPassthrough)
84         return BasicColorMatrixFilterOperation::create(WebCore::blend(m_amount, passthroughAmount(), progress), m_type);
85         
86     const BasicColorMatrixFilterOperation* fromOperation = downcast<BasicColorMatrixFilterOperation>(from);
87     double fromAmount = fromOperation ? fromOperation->amount() : passthroughAmount();
88     return BasicColorMatrixFilterOperation::create(WebCore::blend(fromAmount, m_amount, progress), m_type);
89 }
90
91 inline bool BasicColorMatrixFilterOperation::operator==(const FilterOperation& operation) const
92 {
93     if (!isSameType(operation))
94         return false;
95     const BasicColorMatrixFilterOperation& other = downcast<BasicColorMatrixFilterOperation>(operation);
96     return m_amount == other.m_amount;
97 }
98
99 double BasicColorMatrixFilterOperation::passthroughAmount() const
100 {
101     switch (m_type) {
102     case GRAYSCALE:
103     case SEPIA:
104     case HUE_ROTATE:
105         return 0;
106     case SATURATE:
107         return 1;
108     default:
109         ASSERT_NOT_REACHED();
110         return 0;
111     }
112 }
113
114 RefPtr<FilterOperation> BasicComponentTransferFilterOperation::blend(const FilterOperation* from, double progress, bool blendToPassthrough)
115 {
116     if (from && !from->isSameType(*this))
117         return this;
118     
119     if (blendToPassthrough)
120         return BasicComponentTransferFilterOperation::create(WebCore::blend(m_amount, passthroughAmount(), progress), m_type);
121         
122     const BasicComponentTransferFilterOperation* fromOperation = downcast<BasicComponentTransferFilterOperation>(from);
123     double fromAmount = fromOperation ? fromOperation->amount() : passthroughAmount();
124     return BasicComponentTransferFilterOperation::create(WebCore::blend(fromAmount, m_amount, progress), m_type);
125 }
126
127 inline bool BasicComponentTransferFilterOperation::operator==(const FilterOperation& operation) const
128 {
129     if (!isSameType(operation))
130         return false;
131     const BasicComponentTransferFilterOperation& other = downcast<BasicComponentTransferFilterOperation>(operation);
132     return m_amount == other.m_amount;
133 }
134
135 double BasicComponentTransferFilterOperation::passthroughAmount() const
136 {
137     switch (m_type) {
138     case OPACITY:
139         return 1;
140     case INVERT:
141         return 0;
142     case CONTRAST:
143         return 1;
144     case BRIGHTNESS:
145         return 1;
146     default:
147         ASSERT_NOT_REACHED();
148         return 0;
149     }
150 }
151     
152 bool BlurFilterOperation::operator==(const FilterOperation& operation) const
153 {
154     if (!isSameType(operation))
155         return false;
156     
157     return m_stdDeviation == downcast<BlurFilterOperation>(operation).stdDeviation();
158 }
159     
160 RefPtr<FilterOperation> BlurFilterOperation::blend(const FilterOperation* from, double progress, bool blendToPassthrough)
161 {
162     if (from && !from->isSameType(*this))
163         return this;
164
165     LengthType lengthType = m_stdDeviation.type();
166
167     if (blendToPassthrough)
168         return BlurFilterOperation::create(WebCore::blend(m_stdDeviation, Length(lengthType), progress));
169
170     const BlurFilterOperation* fromOperation = downcast<BlurFilterOperation>(from);
171     Length fromLength = fromOperation ? fromOperation->m_stdDeviation : Length(lengthType);
172     return BlurFilterOperation::create(WebCore::blend(fromLength, m_stdDeviation, progress));
173 }
174     
175 bool DropShadowFilterOperation::operator==(const FilterOperation& operation) const
176 {
177     if (!isSameType(operation))
178         return false;
179     const DropShadowFilterOperation& other = downcast<DropShadowFilterOperation>(operation);
180     return m_location == other.m_location && m_stdDeviation == other.m_stdDeviation && m_color == other.m_color;
181 }
182     
183 RefPtr<FilterOperation> DropShadowFilterOperation::blend(const FilterOperation* from, double progress, bool blendToPassthrough)
184 {
185     if (from && !from->isSameType(*this))
186         return this;
187
188     if (blendToPassthrough)
189         return DropShadowFilterOperation::create(
190             WebCore::blend(m_location, IntPoint(), progress),
191             WebCore::blend(m_stdDeviation, 0, progress),
192             WebCore::blend(m_color, Color(Color::transparent), progress));
193
194     const DropShadowFilterOperation* fromOperation = downcast<DropShadowFilterOperation>(from);
195     IntPoint fromLocation = fromOperation ? fromOperation->location() : IntPoint();
196     int fromStdDeviation = fromOperation ? fromOperation->stdDeviation() : 0;
197     Color fromColor = fromOperation ? fromOperation->color() : Color(Color::transparent);
198     
199     return DropShadowFilterOperation::create(
200         WebCore::blend(fromLocation, m_location, progress),
201         WebCore::blend(fromStdDeviation, m_stdDeviation, progress),
202         WebCore::blend(fromColor, m_color, progress));
203 }
204
205 TextStream& operator<<(TextStream& ts, const FilterOperation& filter)
206 {
207     switch (filter.type()) {
208     case FilterOperation::REFERENCE:
209         ts << "reference";
210         break;
211     case FilterOperation::GRAYSCALE: {
212         const auto& colorMatrixFilter = downcast<BasicColorMatrixFilterOperation>(filter);
213         ts << "grayscale(" << colorMatrixFilter.amount() << ")";
214         break;
215     }
216     case FilterOperation::SEPIA: {
217         const auto& colorMatrixFilter = downcast<BasicColorMatrixFilterOperation>(filter);
218         ts << "sepia(" << colorMatrixFilter.amount() << ")";
219         break;
220     }
221     case FilterOperation::SATURATE: {
222         const auto& colorMatrixFilter = downcast<BasicColorMatrixFilterOperation>(filter);
223         ts << "saturate(" << colorMatrixFilter.amount() << ")";
224         break;
225     }
226     case FilterOperation::HUE_ROTATE: {
227         const auto& colorMatrixFilter = downcast<BasicColorMatrixFilterOperation>(filter);
228         ts << "hue-rotate(" << colorMatrixFilter.amount() << ")";
229         break;
230     }
231     case FilterOperation::INVERT: {
232         const auto& componentTransferFilter = downcast<BasicComponentTransferFilterOperation>(filter);
233         ts << "invert(" << componentTransferFilter.amount() << ")";
234         break;
235     }
236     case FilterOperation::OPACITY: {
237         const auto& componentTransferFilter = downcast<BasicComponentTransferFilterOperation>(filter);
238         ts << "opacity(" << componentTransferFilter.amount() << ")";
239         break;
240     }
241     case FilterOperation::BRIGHTNESS: {
242         const auto& componentTransferFilter = downcast<BasicComponentTransferFilterOperation>(filter);
243         ts << "brightness(" << componentTransferFilter.amount() << ")";
244         break;
245     }
246     case FilterOperation::CONTRAST: {
247         const auto& componentTransferFilter = downcast<BasicComponentTransferFilterOperation>(filter);
248         ts << "contrast(" << componentTransferFilter.amount() << ")";
249         break;
250     }
251     case FilterOperation::BLUR: {
252         const auto& blurFilter = downcast<BlurFilterOperation>(filter);
253         ts << "blur(" << blurFilter.stdDeviation().value() << ")"; // FIXME: should call floatValueForLength() but that's outisde of platform/.
254         break;
255     }
256     case FilterOperation::DROP_SHADOW: {
257         const auto& dropShadowFilter = downcast<DropShadowFilterOperation>(filter);
258         ts << "drop-shadow(" << dropShadowFilter.x() << " " << dropShadowFilter.y() << " " << dropShadowFilter.location() << " ";
259         ts << dropShadowFilter.color() << ")";
260         break;
261     }
262     case FilterOperation::PASSTHROUGH:
263         ts << "passthrough";
264         break;
265     case FilterOperation::DEFAULT: {
266         const auto& defaultFilter = downcast<DefaultFilterOperation>(filter);
267         ts << "default type=" << (int)defaultFilter.representedType();
268         break;
269     }
270     case FilterOperation::NONE:
271         ts << "none";
272         break;
273     }
274     return ts;
275 }
276
277 } // namespace WebCore