OLD | NEW |
| (Empty) |
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 #include "platform/Length.h" | |
30 #include "platform/PlatformExport.h" | |
31 #include "platform/graphics/BoxReflection.h" | |
32 #include "platform/graphics/Color.h" | |
33 #include "platform/graphics/filters/Filter.h" | |
34 #include "platform/heap/Handle.h" | |
35 #include "wtf/Noncopyable.h" | |
36 #include "wtf/text/WTFString.h" | |
37 | |
38 namespace blink { | |
39 | |
40 // CSS Filters | |
41 | |
42 class PLATFORM_EXPORT FilterOperation : public GarbageCollectedFinalized<FilterO
peration> { | |
43 WTF_MAKE_NONCOPYABLE(FilterOperation); | |
44 public: | |
45 enum OperationType { | |
46 REFERENCE, // url(#somefilter) | |
47 GRAYSCALE, | |
48 SEPIA, | |
49 SATURATE, | |
50 HUE_ROTATE, | |
51 INVERT, | |
52 OPACITY, | |
53 BRIGHTNESS, | |
54 CONTRAST, | |
55 BLUR, | |
56 DROP_SHADOW, | |
57 BOX_REFLECT, | |
58 NONE | |
59 }; | |
60 | |
61 static bool canInterpolate(FilterOperation::OperationType type) | |
62 { | |
63 switch (type) { | |
64 case GRAYSCALE: | |
65 case SEPIA: | |
66 case SATURATE: | |
67 case HUE_ROTATE: | |
68 case INVERT: | |
69 case OPACITY: | |
70 case BRIGHTNESS: | |
71 case CONTRAST: | |
72 case BLUR: | |
73 case DROP_SHADOW: | |
74 return true; | |
75 case REFERENCE: | |
76 case BOX_REFLECT: | |
77 return false; | |
78 case NONE: | |
79 break; | |
80 } | |
81 ASSERT_NOT_REACHED(); | |
82 return false; | |
83 } | |
84 | |
85 virtual ~FilterOperation() { } | |
86 DEFINE_INLINE_VIRTUAL_TRACE() { } | |
87 | |
88 static FilterOperation* blend(const FilterOperation* from, const FilterOpera
tion* to, double progress); | |
89 virtual bool operator==(const FilterOperation&) const = 0; | |
90 bool operator!=(const FilterOperation& o) const { return !(*this == o); } | |
91 | |
92 OperationType type() const { return m_type; } | |
93 virtual bool isSameType(const FilterOperation& o) const { return o.type() ==
m_type; } | |
94 | |
95 // True if the alpha channel of any pixel can change under this operation. | |
96 virtual bool affectsOpacity() const { return false; } | |
97 // True if the the value of one pixel can affect the value of another pixel
under this operation, such as blur. | |
98 virtual bool movesPixels() const { return false; } | |
99 | |
100 // Maps "forward" to determine which pixels in a destination rect are | |
101 // affected by pixels in the source rect. | |
102 // See also FilterEffect::mapRect. | |
103 virtual FloatRect mapRect(const FloatRect& rect) const { return rect; } | |
104 | |
105 protected: | |
106 FilterOperation(OperationType type) | |
107 : m_type(type) | |
108 { | |
109 } | |
110 | |
111 OperationType m_type; | |
112 | |
113 private: | |
114 virtual FilterOperation* blend(const FilterOperation* from, double progress)
const = 0; | |
115 }; | |
116 | |
117 #define DEFINE_FILTER_OPERATION_TYPE_CASTS(thisType, operationType) \ | |
118 DEFINE_TYPE_CASTS(thisType, FilterOperation, op, op->type() == FilterOperati
on::operationType, op.type() == FilterOperation::operationType); | |
119 | |
120 class PLATFORM_EXPORT ReferenceFilterOperation : public FilterOperation { | |
121 public: | |
122 static ReferenceFilterOperation* create(const String& url, const AtomicStrin
g& fragment) | |
123 { | |
124 return new ReferenceFilterOperation(url, fragment); | |
125 } | |
126 | |
127 bool affectsOpacity() const override { return true; } | |
128 bool movesPixels() const override { return true; } | |
129 FloatRect mapRect(const FloatRect&) const override; | |
130 | |
131 const String& url() const { return m_url; } | |
132 const AtomicString& fragment() const { return m_fragment; } | |
133 | |
134 Filter* getFilter() const { return m_filter.get(); } | |
135 void setFilter(Filter* filter) { m_filter = filter; } | |
136 | |
137 DECLARE_VIRTUAL_TRACE(); | |
138 | |
139 private: | |
140 FilterOperation* blend(const FilterOperation* from, double progress) const o
verride | |
141 { | |
142 ASSERT_NOT_REACHED(); | |
143 return nullptr; | |
144 } | |
145 | |
146 bool operator==(const FilterOperation& o) const override | |
147 { | |
148 if (!isSameType(o)) | |
149 return false; | |
150 const ReferenceFilterOperation* other = static_cast<const ReferenceFilte
rOperation*>(&o); | |
151 return m_url == other->m_url; | |
152 } | |
153 | |
154 ReferenceFilterOperation(const String& url, const AtomicString& fragment) | |
155 : FilterOperation(REFERENCE) | |
156 , m_url(url) | |
157 , m_fragment(fragment) | |
158 { | |
159 } | |
160 | |
161 String m_url; | |
162 AtomicString m_fragment; | |
163 Member<Filter> m_filter; | |
164 }; | |
165 | |
166 DEFINE_FILTER_OPERATION_TYPE_CASTS(ReferenceFilterOperation, REFERENCE); | |
167 | |
168 // GRAYSCALE, SEPIA, SATURATE and HUE_ROTATE are variations on a basic color mat
rix effect. | |
169 // For HUE_ROTATE, the angle of rotation is stored in m_amount. | |
170 class PLATFORM_EXPORT BasicColorMatrixFilterOperation : public FilterOperation { | |
171 public: | |
172 static BasicColorMatrixFilterOperation* create(double amount, OperationType
type) | |
173 { | |
174 return new BasicColorMatrixFilterOperation(amount, type); | |
175 } | |
176 | |
177 double amount() const { return m_amount; } | |
178 | |
179 | |
180 private: | |
181 FilterOperation* blend(const FilterOperation* from, double progress) const o
verride; | |
182 bool operator==(const FilterOperation& o) const override | |
183 { | |
184 if (!isSameType(o)) | |
185 return false; | |
186 const BasicColorMatrixFilterOperation* other = static_cast<const BasicCo
lorMatrixFilterOperation*>(&o); | |
187 return m_amount == other->m_amount; | |
188 } | |
189 | |
190 BasicColorMatrixFilterOperation(double amount, OperationType type) | |
191 : FilterOperation(type) | |
192 , m_amount(amount) | |
193 { | |
194 } | |
195 | |
196 double m_amount; | |
197 }; | |
198 | |
199 inline bool isBasicColorMatrixFilterOperation(const FilterOperation& operation) | |
200 { | |
201 FilterOperation::OperationType type = operation.type(); | |
202 return type == FilterOperation::GRAYSCALE || type == FilterOperation::SEPIA
|| type == FilterOperation::SATURATE || type == FilterOperation::HUE_ROTATE; | |
203 } | |
204 | |
205 DEFINE_TYPE_CASTS(BasicColorMatrixFilterOperation, FilterOperation, op, isBasicC
olorMatrixFilterOperation(*op), isBasicColorMatrixFilterOperation(op)); | |
206 | |
207 // INVERT, BRIGHTNESS, CONTRAST and OPACITY are variations on a basic component
transfer effect. | |
208 class PLATFORM_EXPORT BasicComponentTransferFilterOperation : public FilterOpera
tion { | |
209 public: | |
210 static BasicComponentTransferFilterOperation* create(double amount, Operatio
nType type) | |
211 { | |
212 return new BasicComponentTransferFilterOperation(amount, type); | |
213 } | |
214 | |
215 double amount() const { return m_amount; } | |
216 | |
217 bool affectsOpacity() const override { return m_type == OPACITY; } | |
218 | |
219 | |
220 private: | |
221 FilterOperation* blend(const FilterOperation* from, double progress) const o
verride; | |
222 bool operator==(const FilterOperation& o) const override | |
223 { | |
224 if (!isSameType(o)) | |
225 return false; | |
226 const BasicComponentTransferFilterOperation* other = static_cast<const B
asicComponentTransferFilterOperation*>(&o); | |
227 return m_amount == other->m_amount; | |
228 } | |
229 | |
230 BasicComponentTransferFilterOperation(double amount, OperationType type) | |
231 : FilterOperation(type) | |
232 , m_amount(amount) | |
233 { | |
234 } | |
235 | |
236 double m_amount; | |
237 }; | |
238 | |
239 inline bool isBasicComponentTransferFilterOperation(const FilterOperation& opera
tion) | |
240 { | |
241 FilterOperation::OperationType type = operation.type(); | |
242 return type == FilterOperation::INVERT || type == FilterOperation::OPACITY |
| type == FilterOperation::BRIGHTNESS || type == FilterOperation::CONTRAST; | |
243 } | |
244 | |
245 DEFINE_TYPE_CASTS(BasicComponentTransferFilterOperation, FilterOperation, op, is
BasicComponentTransferFilterOperation(*op), isBasicComponentTransferFilterOperat
ion(op)); | |
246 | |
247 class PLATFORM_EXPORT BlurFilterOperation : public FilterOperation { | |
248 public: | |
249 static BlurFilterOperation* create(const Length& stdDeviation) | |
250 { | |
251 return new BlurFilterOperation(stdDeviation); | |
252 } | |
253 | |
254 const Length& stdDeviation() const { return m_stdDeviation; } | |
255 | |
256 bool affectsOpacity() const override { return true; } | |
257 bool movesPixels() const override { return true; } | |
258 FloatRect mapRect(const FloatRect&) const override; | |
259 | |
260 private: | |
261 FilterOperation* blend(const FilterOperation* from, double progress) const o
verride; | |
262 bool operator==(const FilterOperation& o) const override | |
263 { | |
264 if (!isSameType(o)) | |
265 return false; | |
266 const BlurFilterOperation* other = static_cast<const BlurFilterOperation
*>(&o); | |
267 return m_stdDeviation == other->m_stdDeviation; | |
268 } | |
269 | |
270 BlurFilterOperation(const Length& stdDeviation) | |
271 : FilterOperation(BLUR) | |
272 , m_stdDeviation(stdDeviation) | |
273 { | |
274 } | |
275 | |
276 Length m_stdDeviation; | |
277 }; | |
278 | |
279 DEFINE_FILTER_OPERATION_TYPE_CASTS(BlurFilterOperation, BLUR); | |
280 | |
281 class PLATFORM_EXPORT DropShadowFilterOperation : public FilterOperation { | |
282 public: | |
283 static DropShadowFilterOperation* create(const IntPoint& location, int stdDe
viation, Color color) | |
284 { | |
285 return new DropShadowFilterOperation(location, stdDeviation, color); | |
286 } | |
287 | |
288 int x() const { return m_location.x(); } | |
289 int y() const { return m_location.y(); } | |
290 IntPoint location() const { return m_location; } | |
291 int stdDeviation() const { return m_stdDeviation; } | |
292 Color getColor() const { return m_color; } | |
293 | |
294 bool affectsOpacity() const override { return true; } | |
295 bool movesPixels() const override { return true; } | |
296 FloatRect mapRect(const FloatRect&) const override; | |
297 | |
298 private: | |
299 FilterOperation* blend(const FilterOperation* from, double progress) const o
verride; | |
300 bool operator==(const FilterOperation& o) const override | |
301 { | |
302 if (!isSameType(o)) | |
303 return false; | |
304 const DropShadowFilterOperation* other = static_cast<const DropShadowFil
terOperation*>(&o); | |
305 return m_location == other->m_location && m_stdDeviation == other->m_std
Deviation && m_color == other->m_color; | |
306 } | |
307 | |
308 DropShadowFilterOperation(const IntPoint& location, int stdDeviation, Color
color) | |
309 : FilterOperation(DROP_SHADOW) | |
310 , m_location(location) | |
311 , m_stdDeviation(stdDeviation) | |
312 , m_color(color) | |
313 { | |
314 } | |
315 | |
316 IntPoint m_location; // FIXME: should location be in Lengths? | |
317 int m_stdDeviation; | |
318 Color m_color; | |
319 }; | |
320 | |
321 DEFINE_FILTER_OPERATION_TYPE_CASTS(DropShadowFilterOperation, DROP_SHADOW); | |
322 | |
323 class PLATFORM_EXPORT BoxReflectFilterOperation : public FilterOperation { | |
324 public: | |
325 static BoxReflectFilterOperation* create(const BoxReflection& reflection) | |
326 { | |
327 return new BoxReflectFilterOperation(reflection); | |
328 } | |
329 | |
330 const BoxReflection& reflection() const { return m_reflection; } | |
331 | |
332 bool affectsOpacity() const override { return true; } | |
333 bool movesPixels() const override { return true; } | |
334 FloatRect mapRect(const FloatRect&) const override; | |
335 | |
336 private: | |
337 FilterOperation* blend(const FilterOperation* from, double progress) const o
verride; | |
338 bool operator==(const FilterOperation&) const override; | |
339 | |
340 BoxReflectFilterOperation(const BoxReflection& reflection) | |
341 : FilterOperation(BOX_REFLECT) | |
342 , m_reflection(reflection) | |
343 { | |
344 } | |
345 | |
346 BoxReflection m_reflection; | |
347 }; | |
348 DEFINE_FILTER_OPERATION_TYPE_CASTS(BoxReflectFilterOperation, BOX_REFLECT); | |
349 | |
350 } // namespace blink | |
351 | |
352 #endif // FilterOperation_h | |
OLD | NEW |