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