User interface of Apps Developer Tool:
[chromium-blink-merge.git] / cc / output / filter_operations.cc
blob43315279090f67861daff282214b6b70dd014029
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.
5 #include <cmath>
7 #include "cc/output/filter_operation.h"
8 #include "cc/output/filter_operations.h"
10 namespace cc {
12 FilterOperations::FilterOperations() {}
14 FilterOperations::FilterOperations(const FilterOperations& other)
15 : operations_(other.operations_) {}
17 FilterOperations::~FilterOperations() {}
19 FilterOperations& FilterOperations::operator=(const FilterOperations& other) {
20 operations_ = other.operations_;
21 return *this;
24 bool FilterOperations::operator==(const FilterOperations& other) const {
25 if (other.size() != size())
26 return false;
27 for (size_t i = 0; i < size(); ++i) {
28 if (other.at(i) != at(i))
29 return false;
31 return true;
34 void FilterOperations::Append(const FilterOperation& filter) {
35 operations_.push_back(filter);
38 void FilterOperations::Clear() {
39 operations_.clear();
42 bool FilterOperations::IsEmpty() const {
43 return operations_.empty();
46 static int SpreadForStdDeviation(float std_deviation) {
47 // https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#feGaussianBlurElement
48 // provides this approximation for evaluating a gaussian blur by a triple box
49 // filter.
50 float d = floorf(std_deviation * 3.f * sqrt(8.f * atan(1.f)) / 4.f + 0.5f);
51 return static_cast<int>(ceilf(d * 3.f / 2.f));
54 void FilterOperations::GetOutsets(int* top,
55 int* right,
56 int* bottom,
57 int* left) const {
58 *top = *right = *bottom = *left = 0;
59 for (size_t i = 0; i < operations_.size(); ++i) {
60 const FilterOperation op = operations_[i];
61 if (op.type() == FilterOperation::BLUR ||
62 op.type() == FilterOperation::DROP_SHADOW) {
63 int spread = SpreadForStdDeviation(op.amount());
64 if (op.type() == FilterOperation::BLUR) {
65 *top += spread;
66 *right += spread;
67 *bottom += spread;
68 *left += spread;
69 } else {
70 *top += spread - op.drop_shadow_offset().y();
71 *right += spread + op.drop_shadow_offset().x();
72 *bottom += spread + op.drop_shadow_offset().y();
73 *left += spread - op.drop_shadow_offset().x();
79 bool FilterOperations::HasFilterThatMovesPixels() const {
80 for (size_t i = 0; i < operations_.size(); ++i) {
81 const FilterOperation op = operations_[i];
82 switch (op.type()) {
83 case FilterOperation::BLUR:
84 case FilterOperation::DROP_SHADOW:
85 case FilterOperation::ZOOM:
86 return true;
87 default:
88 break;
91 return false;
94 bool FilterOperations::HasFilterThatAffectsOpacity() const {
95 for (size_t i = 0; i < operations_.size(); ++i) {
96 const FilterOperation op = operations_[i];
97 switch (op.type()) {
98 case FilterOperation::OPACITY:
99 case FilterOperation::BLUR:
100 case FilterOperation::DROP_SHADOW:
101 case FilterOperation::ZOOM:
102 return true;
103 case FilterOperation::COLOR_MATRIX: {
104 const SkScalar* matrix = op.matrix();
105 return matrix[15] || matrix[16] || matrix[17] || matrix[18] != 1 ||
106 matrix[19];
108 default:
109 break;
112 return false;
115 FilterOperations FilterOperations::Blend(const FilterOperations& from,
116 double progress) const {
117 FilterOperations blended_filters;
118 if (from.size() == 0) {
119 for (size_t i = 0; i < size(); i++)
120 blended_filters.Append(FilterOperation::Blend(NULL, &at(i), progress));
121 return blended_filters;
124 if (size() == 0) {
125 for (size_t i = 0; i < from.size(); i++) {
126 blended_filters.Append(
127 FilterOperation::Blend(&from.at(i), NULL, progress));
129 return blended_filters;
132 if (from.size() != size())
133 return *this;
135 for (size_t i = 0; i < size(); i++) {
136 if (from.at(i).type() != at(i).type())
137 return *this;
140 for (size_t i = 0; i < size(); i++) {
141 blended_filters.Append(
142 FilterOperation::Blend(&from.at(i), &at(i), progress));
145 return blended_filters;
148 } // namespace cc