| 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 |