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 "core/loader/cache/DocumentResourceReference.h" 30 #include "core/platform/Length.h" 31 #include "core/platform/graphics/Color.h" 32 #include "core/platform/graphics/filters/Filter.h" 33 #include "core/platform/graphics/filters/ReferenceFilter.h" 34 #include "wtf/OwnPtr.h" 35 #include "wtf/PassOwnPtr.h" 36 #include "wtf/RefCounted.h" 37 #include "wtf/text/WTFString.h" 38 39 // Annoyingly, wingdi.h #defines this. 40 #ifdef PASSTHROUGH 41 #undef PASSTHROUGH 42 #endif 43 44 namespace WebCore { 45 46 // CSS Filters 47 48 class FilterOperation : public RefCounted<FilterOperation> { 49 public: 50 enum OperationType { 51 REFERENCE, // url(#somefilter) 52 GRAYSCALE, 53 SEPIA, 54 SATURATE, 55 HUE_ROTATE, 56 INVERT, 57 OPACITY, 58 BRIGHTNESS, 59 CONTRAST, 60 BLUR, 61 DROP_SHADOW, 62 CUSTOM, 63 VALIDATED_CUSTOM, 64 PASSTHROUGH, 65 NONE 66 }; 67 68 virtual ~FilterOperation() { } 69 70 virtual bool operator==(const FilterOperation&) const = 0; 71 bool operator!=(const FilterOperation& o) const { return !(*this == o); } 72 73 virtual PassRefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, bool /*blendToPassthrough*/ = false) 74 { 75 return 0; 76 } 77 78 virtual OperationType getOperationType() const { return m_type; } 79 virtual bool isSameType(const FilterOperation& o) const { return o.getOperationType() == m_type; } 80 81 virtual bool isDefault() const { return false; } 82 83 // True if the alpha channel of any pixel can change under this operation. 84 virtual bool affectsOpacity() const { return false; } 85 // True if the the value of one pixel can affect the value of another pixel under this operation, such as blur. 86 virtual bool movesPixels() const { return false; } 87 88 protected: 89 FilterOperation(OperationType type) 90 : m_type(type) 91 { 92 } 93 94 OperationType m_type; 95 }; 96 97 class DefaultFilterOperation : public FilterOperation { 98 public: 99 static PassRefPtr<DefaultFilterOperation> create(OperationType type) 100 { 101 return adoptRef(new DefaultFilterOperation(type)); 102 } 103 104 private: 105 106 virtual bool operator==(const FilterOperation& o) const 107 { 108 return isSameType(o); 109 } 110 111 virtual bool isDefault() const { return true; } 112 113 DefaultFilterOperation(OperationType type) 114 : FilterOperation(type) 115 { 116 } 117 }; 118 119 class PassthroughFilterOperation : public FilterOperation { 120 public: 121 static PassRefPtr<PassthroughFilterOperation> create() 122 { 123 return adoptRef(new PassthroughFilterOperation()); 124 } 125 126 private: 127 128 virtual bool operator==(const FilterOperation& o) const 129 { 130 return isSameType(o); 131 } 132 133 PassthroughFilterOperation() 134 : FilterOperation(PASSTHROUGH) 135 { 136 } 137 }; 138 139 class ReferenceFilterOperation : public FilterOperation { 140 public: 141 static PassRefPtr<ReferenceFilterOperation> create(const String& url, const String& fragment, OperationType type) 142 { 143 return adoptRef(new ReferenceFilterOperation(url, fragment, type)); 144 } 145 146 virtual bool affectsOpacity() const { return true; } 147 virtual bool movesPixels() const { return true; } 148 149 const String& url() const { return m_url; } 150 const String& fragment() const { return m_fragment; } 151 152 DocumentResourceReference* documentResourceReference() const { return m_documentResourceReference.get(); } 153 void setDocumentResourceReference(PassOwnPtr<DocumentResourceReference> documentResourceReference) { m_documentResourceReference = documentResourceReference; } 154 155 ReferenceFilter* filter() const { return m_filter.get(); } 156 void setFilter(PassRefPtr<ReferenceFilter> filter) { m_filter = filter; } 157 158 private: 159 160 virtual bool operator==(const FilterOperation& o) const 161 { 162 if (!isSameType(o)) 163 return false; 164 const ReferenceFilterOperation* other = static_cast<const ReferenceFilterOperation*>(&o); 165 return m_url == other->m_url; 166 } 167 168 ReferenceFilterOperation(const String& url, const String& fragment, OperationType type) 169 : FilterOperation(type) 170 , m_url(url) 171 , m_fragment(fragment) 172 { 173 } 174 175 String m_url; 176 String m_fragment; 177 OwnPtr<DocumentResourceReference> m_documentResourceReference; 178 RefPtr<ReferenceFilter> m_filter; 179 }; 180 181 // GRAYSCALE, SEPIA, SATURATE and HUE_ROTATE are variations on a basic color matrix effect. 182 // For HUE_ROTATE, the angle of rotation is stored in m_amount. 183 class BasicColorMatrixFilterOperation : public FilterOperation { 184 public: 185 static PassRefPtr<BasicColorMatrixFilterOperation> create(double amount, OperationType type) 186 { 187 return adoptRef(new BasicColorMatrixFilterOperation(amount, type)); 188 } 189 190 double amount() const { return m_amount; } 191 192 virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false); 193 194 private: 195 virtual bool operator==(const FilterOperation& o) const 196 { 197 if (!isSameType(o)) 198 return false; 199 const BasicColorMatrixFilterOperation* other = static_cast<const BasicColorMatrixFilterOperation*>(&o); 200 return m_amount == other->m_amount; 201 } 202 203 double passthroughAmount() const; 204 205 BasicColorMatrixFilterOperation(double amount, OperationType type) 206 : FilterOperation(type) 207 , m_amount(amount) 208 { 209 } 210 211 double m_amount; 212 }; 213 214 // INVERT, BRIGHTNESS, CONTRAST and OPACITY are variations on a basic component transfer effect. 215 class BasicComponentTransferFilterOperation : public FilterOperation { 216 public: 217 static PassRefPtr<BasicComponentTransferFilterOperation> create(double amount, OperationType type) 218 { 219 return adoptRef(new BasicComponentTransferFilterOperation(amount, type)); 220 } 221 222 double amount() const { return m_amount; } 223 224 virtual bool affectsOpacity() const { return m_type == OPACITY; } 225 226 virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false); 227 228 private: 229 virtual bool operator==(const FilterOperation& o) const 230 { 231 if (!isSameType(o)) 232 return false; 233 const BasicComponentTransferFilterOperation* other = static_cast<const BasicComponentTransferFilterOperation*>(&o); 234 return m_amount == other->m_amount; 235 } 236 237 double passthroughAmount() const; 238 239 BasicComponentTransferFilterOperation(double amount, OperationType type) 240 : FilterOperation(type) 241 , m_amount(amount) 242 { 243 } 244 245 double m_amount; 246 }; 247 248 class GammaFilterOperation : public FilterOperation { 249 public: 250 static PassRefPtr<GammaFilterOperation> create(double amplitude, double exponent, double offset, OperationType type) 251 { 252 return adoptRef(new GammaFilterOperation(amplitude, exponent, offset, type)); 253 } 254 255 double amplitude() const { return m_amplitude; } 256 double exponent() const { return m_exponent; } 257 double offset() const { return m_offset; } 258 259 virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false); 260 261 private: 262 virtual bool operator==(const FilterOperation& o) const 263 { 264 if (!isSameType(o)) 265 return false; 266 const GammaFilterOperation* other = static_cast<const GammaFilterOperation*>(&o); 267 return m_amplitude == other->m_amplitude && m_exponent == other->m_exponent && m_offset == other->m_offset; 268 } 269 270 GammaFilterOperation(double amplitude, double exponent, double offset, OperationType type) 271 : FilterOperation(type) 272 , m_amplitude(amplitude) 273 , m_exponent(exponent) 274 , m_offset(offset) 275 { 276 } 277 278 double m_amplitude; 279 double m_exponent; 280 double m_offset; 281 }; 282 283 class BlurFilterOperation : public FilterOperation { 284 public: 285 static PassRefPtr<BlurFilterOperation> create(Length stdDeviation, OperationType type) 286 { 287 return adoptRef(new BlurFilterOperation(stdDeviation, type)); 288 } 289 290 Length stdDeviation() const { return m_stdDeviation; } 291 292 virtual bool affectsOpacity() const { return true; } 293 virtual bool movesPixels() const { return true; } 294 295 virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false); 296 297 private: 298 virtual bool operator==(const FilterOperation& o) const 299 { 300 if (!isSameType(o)) 301 return false; 302 const BlurFilterOperation* other = static_cast<const BlurFilterOperation*>(&o); 303 return m_stdDeviation == other->m_stdDeviation; 304 } 305 306 BlurFilterOperation(Length stdDeviation, OperationType type) 307 : FilterOperation(type) 308 , m_stdDeviation(stdDeviation) 309 { 310 } 311 312 Length m_stdDeviation; 313 }; 314 315 class DropShadowFilterOperation : public FilterOperation { 316 public: 317 static PassRefPtr<DropShadowFilterOperation> create(const IntPoint& location, int stdDeviation, Color color, OperationType type) 318 { 319 return adoptRef(new DropShadowFilterOperation(location, stdDeviation, color, type)); 320 } 321 322 int x() const { return m_location.x(); } 323 int y() const { return m_location.y(); } 324 IntPoint location() const { return m_location; } 325 int stdDeviation() const { return m_stdDeviation; } 326 Color color() const { return m_color; } 327 328 virtual bool affectsOpacity() const { return true; } 329 virtual bool movesPixels() const { return true; } 330 331 virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false); 332 333 private: 334 335 virtual bool operator==(const FilterOperation& o) const 336 { 337 if (!isSameType(o)) 338 return false; 339 const DropShadowFilterOperation* other = static_cast<const DropShadowFilterOperation*>(&o); 340 return m_location == other->m_location && m_stdDeviation == other->m_stdDeviation && m_color == other->m_color; 341 } 342 343 DropShadowFilterOperation(const IntPoint& location, int stdDeviation, Color color, OperationType type) 344 : FilterOperation(type) 345 , m_location(location) 346 , m_stdDeviation(stdDeviation) 347 , m_color(color) 348 { 349 } 350 351 IntPoint m_location; // FIXME: should location be in Lengths? 352 int m_stdDeviation; 353 Color m_color; 354 }; 355 356 } // namespace WebCore 357 358 359 #endif // FilterOperation_h 360