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.
7 #include "cc/output/filter_operations.h"
9 #include "base/values.h"
10 #include "cc/output/filter_operation.h"
14 FilterOperations::FilterOperations() {}
16 FilterOperations::FilterOperations(const FilterOperations
& other
)
17 : operations_(other
.operations_
) {}
19 FilterOperations::~FilterOperations() {}
21 FilterOperations
& FilterOperations::operator=(const FilterOperations
& other
) {
22 operations_
= other
.operations_
;
26 bool FilterOperations::operator==(const FilterOperations
& other
) const {
27 if (other
.size() != size())
29 for (size_t i
= 0; i
< size(); ++i
) {
30 if (other
.at(i
) != at(i
))
36 void FilterOperations::Append(const FilterOperation
& filter
) {
37 operations_
.push_back(filter
);
40 void FilterOperations::Clear() {
44 bool FilterOperations::IsEmpty() const {
45 return operations_
.empty();
48 static int SpreadForStdDeviation(float std_deviation
) {
49 // https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#feGaussianBlurElement
50 // provides this approximation for evaluating a gaussian blur by a triple box
52 float d
= floorf(std_deviation
* 3.f
* sqrt(8.f
* atan(1.f
)) / 4.f
+ 0.5f
);
53 return static_cast<int>(ceilf(d
* 3.f
/ 2.f
));
56 void FilterOperations::GetOutsets(int* top
,
60 *top
= *right
= *bottom
= *left
= 0;
61 for (size_t i
= 0; i
< operations_
.size(); ++i
) {
62 const FilterOperation op
= operations_
[i
];
63 if (op
.type() == FilterOperation::BLUR
||
64 op
.type() == FilterOperation::DROP_SHADOW
) {
65 int spread
= SpreadForStdDeviation(op
.amount());
66 if (op
.type() == FilterOperation::BLUR
) {
72 *top
+= spread
- op
.drop_shadow_offset().y();
73 *right
+= spread
+ op
.drop_shadow_offset().x();
74 *bottom
+= spread
+ op
.drop_shadow_offset().y();
75 *left
+= spread
- op
.drop_shadow_offset().x();
81 bool FilterOperations::HasFilterThatMovesPixels() const {
82 for (size_t i
= 0; i
< operations_
.size(); ++i
) {
83 const FilterOperation op
= operations_
[i
];
85 case FilterOperation::BLUR
:
86 case FilterOperation::DROP_SHADOW
:
87 case FilterOperation::ZOOM
:
89 case FilterOperation::OPACITY
:
90 case FilterOperation::COLOR_MATRIX
:
91 case FilterOperation::GRAYSCALE
:
92 case FilterOperation::SEPIA
:
93 case FilterOperation::SATURATE
:
94 case FilterOperation::HUE_ROTATE
:
95 case FilterOperation::INVERT
:
96 case FilterOperation::BRIGHTNESS
:
97 case FilterOperation::CONTRAST
:
98 case FilterOperation::SATURATING_BRIGHTNESS
:
105 bool FilterOperations::HasFilterThatAffectsOpacity() const {
106 for (size_t i
= 0; i
< operations_
.size(); ++i
) {
107 const FilterOperation op
= operations_
[i
];
109 case FilterOperation::OPACITY
:
110 case FilterOperation::BLUR
:
111 case FilterOperation::DROP_SHADOW
:
112 case FilterOperation::ZOOM
:
114 case FilterOperation::COLOR_MATRIX
: {
115 const SkScalar
* matrix
= op
.matrix();
124 case FilterOperation::GRAYSCALE
:
125 case FilterOperation::SEPIA
:
126 case FilterOperation::SATURATE
:
127 case FilterOperation::HUE_ROTATE
:
128 case FilterOperation::INVERT
:
129 case FilterOperation::BRIGHTNESS
:
130 case FilterOperation::CONTRAST
:
131 case FilterOperation::SATURATING_BRIGHTNESS
:
138 FilterOperations
FilterOperations::Blend(const FilterOperations
& from
,
139 double progress
) const {
140 FilterOperations blended_filters
;
141 if (from
.size() == 0) {
142 for (size_t i
= 0; i
< size(); i
++)
143 blended_filters
.Append(FilterOperation::Blend(NULL
, &at(i
), progress
));
144 return blended_filters
;
148 for (size_t i
= 0; i
< from
.size(); i
++) {
149 blended_filters
.Append(
150 FilterOperation::Blend(&from
.at(i
), NULL
, progress
));
152 return blended_filters
;
155 if (from
.size() != size())
158 for (size_t i
= 0; i
< size(); i
++) {
159 if (from
.at(i
).type() != at(i
).type())
163 for (size_t i
= 0; i
< size(); i
++) {
164 blended_filters
.Append(
165 FilterOperation::Blend(&from
.at(i
), &at(i
), progress
));
168 return blended_filters
;
171 scoped_ptr
<base::Value
> FilterOperations::AsValue() const {
172 scoped_ptr
<base::ListValue
> value(new ListValue
);
173 for (size_t i
= 0; i
< operations_
.size(); ++i
)
174 value
->Append(operations_
[i
].AsValue().release());
175 return value
.PassAs
<base::Value
>();