summaryrefslogtreecommitdiff
path: root/chromium/cc/animation/transform_operations.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/cc/animation/transform_operations.cc')
-rw-r--r--chromium/cc/animation/transform_operations.cc193
1 files changed, 193 insertions, 0 deletions
diff --git a/chromium/cc/animation/transform_operations.cc b/chromium/cc/animation/transform_operations.cc
new file mode 100644
index 00000000000..d74f1a5343a
--- /dev/null
+++ b/chromium/cc/animation/transform_operations.cc
@@ -0,0 +1,193 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/animation/transform_operations.h"
+
+#include <algorithm>
+
+#include "ui/gfx/transform_util.h"
+#include "ui/gfx/vector3d_f.h"
+
+namespace cc {
+
+TransformOperations::TransformOperations()
+ : decomposed_transform_dirty_(true) {
+}
+
+TransformOperations::TransformOperations(const TransformOperations& other) {
+ operations_ = other.operations_;
+ decomposed_transform_dirty_ = other.decomposed_transform_dirty_;
+ if (!decomposed_transform_dirty_) {
+ decomposed_transform_.reset(
+ new gfx::DecomposedTransform(*other.decomposed_transform_.get()));
+ }
+}
+
+TransformOperations::~TransformOperations() {
+}
+
+gfx::Transform TransformOperations::Apply() const {
+ gfx::Transform to_return;
+ for (size_t i = 0; i < operations_.size(); ++i)
+ to_return.PreconcatTransform(operations_[i].matrix);
+ return to_return;
+}
+
+gfx::Transform TransformOperations::Blend(
+ const TransformOperations& from, double progress) const {
+ gfx::Transform to_return;
+ BlendInternal(from, progress, &to_return);
+ return to_return;
+}
+
+bool TransformOperations::MatchesTypes(const TransformOperations& other) const {
+ if (IsIdentity() || other.IsIdentity())
+ return true;
+
+ if (operations_.size() != other.operations_.size())
+ return false;
+
+ for (size_t i = 0; i < operations_.size(); ++i) {
+ if (operations_[i].type != other.operations_[i].type
+ && !operations_[i].IsIdentity()
+ && !other.operations_[i].IsIdentity())
+ return false;
+ }
+
+ return true;
+}
+
+bool TransformOperations::CanBlendWith(
+ const TransformOperations& other) const {
+ gfx::Transform dummy;
+ return BlendInternal(other, 0.5, &dummy);
+}
+
+void TransformOperations::AppendTranslate(double x, double y, double z) {
+ TransformOperation to_add;
+ to_add.matrix.Translate3d(x, y, z);
+ to_add.type = TransformOperation::TransformOperationTranslate;
+ to_add.translate.x = x;
+ to_add.translate.y = y;
+ to_add.translate.z = z;
+ operations_.push_back(to_add);
+ decomposed_transform_dirty_ = true;
+}
+
+void TransformOperations::AppendRotate(double x, double y, double z,
+ double degrees) {
+ TransformOperation to_add;
+ to_add.matrix.RotateAbout(gfx::Vector3dF(x, y, z), degrees);
+ to_add.type = TransformOperation::TransformOperationRotate;
+ to_add.rotate.axis.x = x;
+ to_add.rotate.axis.y = y;
+ to_add.rotate.axis.z = z;
+ to_add.rotate.angle = degrees;
+ operations_.push_back(to_add);
+ decomposed_transform_dirty_ = true;
+}
+
+void TransformOperations::AppendScale(double x, double y, double z) {
+ TransformOperation to_add;
+ to_add.matrix.Scale3d(x, y, z);
+ to_add.type = TransformOperation::TransformOperationScale;
+ to_add.scale.x = x;
+ to_add.scale.y = y;
+ to_add.scale.z = z;
+ operations_.push_back(to_add);
+ decomposed_transform_dirty_ = true;
+}
+
+void TransformOperations::AppendSkew(double x, double y) {
+ TransformOperation to_add;
+ to_add.matrix.SkewX(x);
+ to_add.matrix.SkewY(y);
+ to_add.type = TransformOperation::TransformOperationSkew;
+ to_add.skew.x = x;
+ to_add.skew.y = y;
+ operations_.push_back(to_add);
+ decomposed_transform_dirty_ = true;
+}
+
+void TransformOperations::AppendPerspective(double depth) {
+ TransformOperation to_add;
+ to_add.matrix.ApplyPerspectiveDepth(depth);
+ to_add.type = TransformOperation::TransformOperationPerspective;
+ to_add.perspective_depth = depth;
+ operations_.push_back(to_add);
+ decomposed_transform_dirty_ = true;
+}
+
+void TransformOperations::AppendMatrix(const gfx::Transform& matrix) {
+ TransformOperation to_add;
+ to_add.matrix = matrix;
+ to_add.type = TransformOperation::TransformOperationMatrix;
+ operations_.push_back(to_add);
+ decomposed_transform_dirty_ = true;
+}
+
+void TransformOperations::AppendIdentity() {
+ operations_.push_back(TransformOperation());
+}
+
+bool TransformOperations::IsIdentity() const {
+ for (size_t i = 0; i < operations_.size(); ++i) {
+ if (!operations_[i].IsIdentity())
+ return false;
+ }
+ return true;
+}
+
+bool TransformOperations::BlendInternal(const TransformOperations& from,
+ double progress,
+ gfx::Transform* result) const {
+ bool from_identity = from.IsIdentity();
+ bool to_identity = IsIdentity();
+ if (from_identity && to_identity)
+ return true;
+
+ if (MatchesTypes(from)) {
+ size_t num_operations =
+ std::max(from_identity ? 0 : from.operations_.size(),
+ to_identity ? 0 : operations_.size());
+ for (size_t i = 0; i < num_operations; ++i) {
+ gfx::Transform blended;
+ if (!TransformOperation::BlendTransformOperations(
+ from_identity ? 0 : &from.operations_[i],
+ to_identity ? 0 : &operations_[i],
+ progress,
+ &blended))
+ return false;
+ result->PreconcatTransform(blended);
+ }
+ return true;
+ }
+
+ if (!ComputeDecomposedTransform() || !from.ComputeDecomposedTransform())
+ return false;
+
+ gfx::DecomposedTransform to_return;
+ if (!gfx::BlendDecomposedTransforms(&to_return,
+ *decomposed_transform_.get(),
+ *from.decomposed_transform_.get(),
+ progress))
+ return false;
+
+ *result = ComposeTransform(to_return);
+ return true;
+}
+
+bool TransformOperations::ComputeDecomposedTransform() const {
+ if (decomposed_transform_dirty_) {
+ if (!decomposed_transform_)
+ decomposed_transform_.reset(new gfx::DecomposedTransform());
+ gfx::Transform transform = Apply();
+ if (!gfx::DecomposeTransform(decomposed_transform_.get(), transform))
+ return false;
+ decomposed_transform_dirty_ = false;
+ }
+ return true;
+}
+
+} // namespace cc