Revert 199284 "[Downloads] Clear current_path_ when deleting int..."
[chromium-blink-merge.git] / cc / animation / transform_operations.cc
blob8826d297a497c9a9eaad148201bffc58d735e3d2
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 "cc/animation/transform_operations.h"
7 #include <algorithm>
9 #include "ui/gfx/transform_util.h"
10 #include "ui/gfx/vector3d_f.h"
12 namespace cc {
14 TransformOperations::TransformOperations()
15 : decomposed_transform_dirty_(true) {
18 TransformOperations::TransformOperations(const TransformOperations& other) {
19 operations_ = other.operations_;
20 decomposed_transform_dirty_ = other.decomposed_transform_dirty_;
21 if (!decomposed_transform_dirty_) {
22 decomposed_transform_.reset(
23 new gfx::DecomposedTransform(*other.decomposed_transform_.get()));
27 TransformOperations::~TransformOperations() {
30 gfx::Transform TransformOperations::Apply() const {
31 gfx::Transform to_return;
32 for (size_t i = 0; i < operations_.size(); ++i)
33 to_return.PreconcatTransform(operations_[i].matrix);
34 return to_return;
37 gfx::Transform TransformOperations::Blend(
38 const TransformOperations& from, double progress) const {
39 gfx::Transform to_return;
40 BlendInternal(from, progress, &to_return);
41 return to_return;
44 bool TransformOperations::MatchesTypes(const TransformOperations& other) const {
45 if (IsIdentity() || other.IsIdentity())
46 return true;
48 if (operations_.size() != other.operations_.size())
49 return false;
51 for (size_t i = 0; i < operations_.size(); ++i) {
52 if (operations_[i].type != other.operations_[i].type
53 && !operations_[i].IsIdentity()
54 && !other.operations_[i].IsIdentity())
55 return false;
58 return true;
61 bool TransformOperations::CanBlendWith(
62 const TransformOperations& other) const {
63 gfx::Transform dummy;
64 return BlendInternal(other, 0.5, &dummy);
67 void TransformOperations::AppendTranslate(double x, double y, double z) {
68 TransformOperation to_add;
69 to_add.matrix.Translate3d(x, y, z);
70 to_add.type = TransformOperation::TransformOperationTranslate;
71 to_add.translate.x = x;
72 to_add.translate.y = y;
73 to_add.translate.z = z;
74 operations_.push_back(to_add);
75 decomposed_transform_dirty_ = true;
78 void TransformOperations::AppendRotate(double x, double y, double z,
79 double degrees) {
80 TransformOperation to_add;
81 to_add.matrix.RotateAbout(gfx::Vector3dF(x, y, z), degrees);
82 to_add.type = TransformOperation::TransformOperationRotate;
83 to_add.rotate.axis.x = x;
84 to_add.rotate.axis.y = y;
85 to_add.rotate.axis.z = z;
86 to_add.rotate.angle = degrees;
87 operations_.push_back(to_add);
88 decomposed_transform_dirty_ = true;
91 void TransformOperations::AppendScale(double x, double y, double z) {
92 TransformOperation to_add;
93 to_add.matrix.Scale3d(x, y, z);
94 to_add.type = TransformOperation::TransformOperationScale;
95 to_add.scale.x = x;
96 to_add.scale.y = y;
97 to_add.scale.z = z;
98 operations_.push_back(to_add);
99 decomposed_transform_dirty_ = true;
102 void TransformOperations::AppendSkew(double x, double y) {
103 TransformOperation to_add;
104 to_add.matrix.SkewX(x);
105 to_add.matrix.SkewY(y);
106 to_add.type = TransformOperation::TransformOperationSkew;
107 to_add.skew.x = x;
108 to_add.skew.y = y;
109 operations_.push_back(to_add);
110 decomposed_transform_dirty_ = true;
113 void TransformOperations::AppendPerspective(double depth) {
114 TransformOperation to_add;
115 to_add.matrix.ApplyPerspectiveDepth(depth);
116 to_add.type = TransformOperation::TransformOperationPerspective;
117 to_add.perspective_depth = depth;
118 operations_.push_back(to_add);
119 decomposed_transform_dirty_ = true;
122 void TransformOperations::AppendMatrix(const gfx::Transform& matrix) {
123 TransformOperation to_add;
124 to_add.matrix = matrix;
125 to_add.type = TransformOperation::TransformOperationMatrix;
126 operations_.push_back(to_add);
127 decomposed_transform_dirty_ = true;
130 void TransformOperations::AppendIdentity() {
131 operations_.push_back(TransformOperation());
134 bool TransformOperations::IsIdentity() const {
135 for (size_t i = 0; i < operations_.size(); ++i) {
136 if (!operations_[i].IsIdentity())
137 return false;
139 return true;
142 bool TransformOperations::BlendInternal(const TransformOperations& from,
143 double progress,
144 gfx::Transform* result) const {
145 bool from_identity = from.IsIdentity();
146 bool to_identity = IsIdentity();
147 if (from_identity && to_identity)
148 return true;
150 if (MatchesTypes(from)) {
151 size_t num_operations =
152 std::max(from_identity ? 0 : from.operations_.size(),
153 to_identity ? 0 : operations_.size());
154 for (size_t i = 0; i < num_operations; ++i) {
155 gfx::Transform blended;
156 if (!TransformOperation::BlendTransformOperations(
157 from_identity ? 0 : &from.operations_[i],
158 to_identity ? 0 : &operations_[i],
159 progress,
160 &blended))
161 return false;
162 result->PreconcatTransform(blended);
164 return true;
167 if (progress <= 0.0) {
168 *result = from.Apply();
169 return true;
172 if (progress >= 1.0) {
173 *result = Apply();
174 return true;
177 if (!ComputeDecomposedTransform() || !from.ComputeDecomposedTransform())
178 return false;
180 gfx::DecomposedTransform to_return;
181 if (!gfx::BlendDecomposedTransforms(&to_return,
182 *decomposed_transform_.get(),
183 *from.decomposed_transform_.get(),
184 progress))
185 return false;
187 *result = ComposeTransform(to_return);
188 return true;
191 bool TransformOperations::ComputeDecomposedTransform() const {
192 if (decomposed_transform_dirty_) {
193 if (!decomposed_transform_)
194 decomposed_transform_.reset(new gfx::DecomposedTransform());
195 gfx::Transform transform = Apply();
196 if (!gfx::DecomposeTransform(decomposed_transform_.get(), transform))
197 return false;
198 decomposed_transform_dirty_ = false;
200 return true;
203 } // namespace cc