1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CC_OUTPUT_FILTER_OPERATION_H_ 6 #define CC_OUTPUT_FILTER_OPERATION_H_ 7 8 #include "base/logging.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "cc/base/cc_export.h" 11 #include "skia/ext/refptr.h" 12 #include "third_party/skia/include/core/SkColor.h" 13 #include "third_party/skia/include/core/SkImageFilter.h" 14 #include "third_party/skia/include/core/SkRegion.h" 15 #include "third_party/skia/include/core/SkScalar.h" 16 #include "ui/gfx/geometry/point.h" 17 18 namespace base { 19 namespace debug { 20 class TracedValue; 21 } 22 class Value; 23 } 24 25 namespace cc { 26 27 class CC_EXPORT FilterOperation { 28 public: 29 enum FilterType { 30 GRAYSCALE, 31 SEPIA, 32 SATURATE, 33 HUE_ROTATE, 34 INVERT, 35 BRIGHTNESS, 36 CONTRAST, 37 OPACITY, 38 BLUR, 39 DROP_SHADOW, 40 COLOR_MATRIX, 41 ZOOM, 42 REFERENCE, 43 SATURATING_BRIGHTNESS, // Not used in CSS/SVG. 44 ALPHA_THRESHOLD, // Not used in CSS/SVG. 45 FILTER_TYPE_LAST = ALPHA_THRESHOLD 46 }; 47 48 FilterOperation(const FilterOperation& other); 49 50 ~FilterOperation(); 51 52 FilterType type() const { return type_; } 53 54 float amount() const { 55 DCHECK_NE(type_, COLOR_MATRIX); 56 DCHECK_NE(type_, REFERENCE); 57 return amount_; 58 } 59 60 float outer_threshold() const { 61 DCHECK_EQ(type_, ALPHA_THRESHOLD); 62 return outer_threshold_; 63 } 64 65 gfx::Point drop_shadow_offset() const { 66 DCHECK_EQ(type_, DROP_SHADOW); 67 return drop_shadow_offset_; 68 } 69 70 SkColor drop_shadow_color() const { 71 DCHECK_EQ(type_, DROP_SHADOW); 72 return drop_shadow_color_; 73 } 74 75 skia::RefPtr<SkImageFilter> image_filter() const { 76 DCHECK_EQ(type_, REFERENCE); 77 return image_filter_; 78 } 79 80 const SkScalar* matrix() const { 81 DCHECK_EQ(type_, COLOR_MATRIX); 82 return matrix_; 83 } 84 85 int zoom_inset() const { 86 DCHECK_EQ(type_, ZOOM); 87 return zoom_inset_; 88 } 89 90 const SkRegion& region() const { 91 DCHECK_EQ(type_, ALPHA_THRESHOLD); 92 return region_; 93 } 94 95 static FilterOperation CreateGrayscaleFilter(float amount) { 96 return FilterOperation(GRAYSCALE, amount); 97 } 98 99 static FilterOperation CreateSepiaFilter(float amount) { 100 return FilterOperation(SEPIA, amount); 101 } 102 103 static FilterOperation CreateSaturateFilter(float amount) { 104 return FilterOperation(SATURATE, amount); 105 } 106 107 static FilterOperation CreateHueRotateFilter(float amount) { 108 return FilterOperation(HUE_ROTATE, amount); 109 } 110 111 static FilterOperation CreateInvertFilter(float amount) { 112 return FilterOperation(INVERT, amount); 113 } 114 115 static FilterOperation CreateBrightnessFilter(float amount) { 116 return FilterOperation(BRIGHTNESS, amount); 117 } 118 119 static FilterOperation CreateContrastFilter(float amount) { 120 return FilterOperation(CONTRAST, amount); 121 } 122 123 static FilterOperation CreateOpacityFilter(float amount) { 124 return FilterOperation(OPACITY, amount); 125 } 126 127 static FilterOperation CreateBlurFilter(float amount) { 128 return FilterOperation(BLUR, amount); 129 } 130 131 static FilterOperation CreateDropShadowFilter(const gfx::Point& offset, 132 float std_deviation, 133 SkColor color) { 134 return FilterOperation(DROP_SHADOW, offset, std_deviation, color); 135 } 136 137 static FilterOperation CreateColorMatrixFilter(SkScalar matrix[20]) { 138 return FilterOperation(COLOR_MATRIX, matrix); 139 } 140 141 static FilterOperation CreateZoomFilter(float amount, int inset) { 142 return FilterOperation(ZOOM, amount, inset); 143 } 144 145 static FilterOperation CreateReferenceFilter( 146 const skia::RefPtr<SkImageFilter>& image_filter) { 147 return FilterOperation(REFERENCE, image_filter); 148 } 149 150 static FilterOperation CreateSaturatingBrightnessFilter(float amount) { 151 return FilterOperation(SATURATING_BRIGHTNESS, amount); 152 } 153 154 static FilterOperation CreateAlphaThresholdFilter(const SkRegion& region, 155 float inner_threshold, 156 float outer_threshold) { 157 return FilterOperation(ALPHA_THRESHOLD, region, 158 inner_threshold, outer_threshold); 159 } 160 161 bool operator==(const FilterOperation& other) const; 162 163 bool operator!=(const FilterOperation& other) const { 164 return !(*this == other); 165 } 166 167 // Methods for restoring a FilterOperation. 168 static FilterOperation CreateEmptyFilter() { 169 return FilterOperation(GRAYSCALE, 0.f); 170 } 171 172 void set_type(FilterType type) { type_ = type; } 173 174 void set_amount(float amount) { 175 DCHECK_NE(type_, COLOR_MATRIX); 176 DCHECK_NE(type_, REFERENCE); 177 amount_ = amount; 178 } 179 180 void set_outer_threshold(float outer_threshold) { 181 DCHECK_EQ(type_, ALPHA_THRESHOLD); 182 outer_threshold_ = outer_threshold; 183 } 184 185 void set_drop_shadow_offset(const gfx::Point& offset) { 186 DCHECK_EQ(type_, DROP_SHADOW); 187 drop_shadow_offset_ = offset; 188 } 189 190 void set_drop_shadow_color(SkColor color) { 191 DCHECK_EQ(type_, DROP_SHADOW); 192 drop_shadow_color_ = color; 193 } 194 195 void set_image_filter(const skia::RefPtr<SkImageFilter>& image_filter) { 196 DCHECK_EQ(type_, REFERENCE); 197 image_filter_ = image_filter; 198 } 199 200 void set_matrix(const SkScalar matrix[20]) { 201 DCHECK_EQ(type_, COLOR_MATRIX); 202 for (unsigned i = 0; i < 20; ++i) 203 matrix_[i] = matrix[i]; 204 } 205 206 void set_zoom_inset(int inset) { 207 DCHECK_EQ(type_, ZOOM); 208 zoom_inset_ = inset; 209 } 210 211 void set_region(const SkRegion& region) { 212 DCHECK_EQ(type_, ALPHA_THRESHOLD); 213 region_ = region; 214 } 215 216 // Given two filters of the same type, returns a filter operation created by 217 // linearly interpolating a |progress| fraction from |from| to |to|. If either 218 // |from| or |to| (but not both) is null, it is treated as a no-op filter of 219 // the same type as the other given filter. If both |from| and |to| are null, 220 // or if |from| and |to| are non-null but of different types, returns a 221 // no-op filter. 222 static FilterOperation Blend(const FilterOperation* from, 223 const FilterOperation* to, 224 double progress); 225 226 void AsValueInto(base::debug::TracedValue* value) const; 227 228 private: 229 FilterOperation(FilterType type, float amount); 230 231 FilterOperation(FilterType type, 232 const gfx::Point& offset, 233 float stdDeviation, 234 SkColor color); 235 236 FilterOperation(FilterType, SkScalar matrix[20]); 237 238 FilterOperation(FilterType type, float amount, int inset); 239 240 FilterOperation(FilterType type, 241 const skia::RefPtr<SkImageFilter>& image_filter); 242 243 FilterOperation(FilterType type, 244 const SkRegion& region, 245 float inner_threshold, 246 float outer_threshold); 247 248 FilterType type_; 249 float amount_; 250 float outer_threshold_; 251 gfx::Point drop_shadow_offset_; 252 SkColor drop_shadow_color_; 253 skia::RefPtr<SkImageFilter> image_filter_; 254 SkScalar matrix_[20]; 255 int zoom_inset_; 256 SkRegion region_; 257 }; 258 259 } // namespace cc 260 261 #endif // CC_OUTPUT_FILTER_OPERATION_H_ 262