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