summaryrefslogtreecommitdiffstats
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.cc101
1 files changed, 100 insertions, 1 deletions
diff --git a/chromium/cc/animation/transform_operations.cc b/chromium/cc/animation/transform_operations.cc
index f8abe441fbf..34c526b9a40 100644
--- a/chromium/cc/animation/transform_operations.cc
+++ b/chromium/cc/animation/transform_operations.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "ui/gfx/animation/tween.h"
#include "ui/gfx/box_f.h"
#include "ui/gfx/transform_util.h"
#include "ui/gfx/vector3d_f.h"
@@ -60,7 +61,11 @@ bool TransformOperations::BlendedBoundsForBox(const gfx::BoxF& box,
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) {
+
+ // Because we are squashing all of the matrices together when applying
+ // them to the animation, we must apply them in reverse order when
+ // not squashing them.
+ for (int i = num_operations - 1; i >= 0; --i) {
gfx::BoxF bounds_for_operation;
const TransformOperation* from_op =
from_identity ? NULL : &from.operations_[i];
@@ -78,6 +83,100 @@ bool TransformOperations::BlendedBoundsForBox(const gfx::BoxF& box,
return true;
}
+bool TransformOperations::AffectsScale() const {
+ for (size_t i = 0; i < operations_.size(); ++i) {
+ if (operations_[i].type == TransformOperation::TransformOperationScale)
+ return true;
+ if (operations_[i].type == TransformOperation::TransformOperationMatrix &&
+ !operations_[i].matrix.IsIdentityOrTranslation())
+ return true;
+ }
+ return false;
+}
+
+bool TransformOperations::IsTranslation() const {
+ for (size_t i = 0; i < operations_.size(); ++i) {
+ switch (operations_[i].type) {
+ case TransformOperation::TransformOperationIdentity:
+ case TransformOperation::TransformOperationTranslate:
+ continue;
+ case TransformOperation::TransformOperationMatrix:
+ if (!operations_[i].matrix.IsIdentityOrTranslation())
+ return false;
+ continue;
+ case TransformOperation::TransformOperationRotate:
+ case TransformOperation::TransformOperationScale:
+ case TransformOperation::TransformOperationSkew:
+ case TransformOperation::TransformOperationPerspective:
+ return false;
+ }
+ }
+ return true;
+}
+
+bool TransformOperations::MaximumScale(const TransformOperations& from,
+ SkMScalar min_progress,
+ SkMScalar max_progress,
+ float* max_scale) const {
+ if (!MatchesTypes(from))
+ return false;
+
+ gfx::Vector3dF from_scale;
+ gfx::Vector3dF to_scale;
+
+ if (!from.ScaleComponent(&from_scale) || !ScaleComponent(&to_scale))
+ return false;
+
+ gfx::Vector3dF scale_at_min_progress(
+ std::abs(gfx::Tween::FloatValueBetween(
+ min_progress, from_scale.x(), to_scale.x())),
+ std::abs(gfx::Tween::FloatValueBetween(
+ min_progress, from_scale.y(), to_scale.y())),
+ std::abs(gfx::Tween::FloatValueBetween(
+ min_progress, from_scale.z(), to_scale.z())));
+ gfx::Vector3dF scale_at_max_progress(
+ std::abs(gfx::Tween::FloatValueBetween(
+ max_progress, from_scale.x(), to_scale.x())),
+ std::abs(gfx::Tween::FloatValueBetween(
+ max_progress, from_scale.y(), to_scale.y())),
+ std::abs(gfx::Tween::FloatValueBetween(
+ max_progress, from_scale.z(), to_scale.z())));
+
+ gfx::Vector3dF max_scale_3d = scale_at_min_progress;
+ max_scale_3d.SetToMax(scale_at_max_progress);
+ *max_scale =
+ std::max(max_scale_3d.x(), std::max(max_scale_3d.y(), max_scale_3d.z()));
+ return true;
+}
+
+bool TransformOperations::ScaleComponent(gfx::Vector3dF* scale) const {
+ *scale = gfx::Vector3dF(1.f, 1.f, 1.f);
+ bool has_scale_component = false;
+ for (size_t i = 0; i < operations_.size(); ++i) {
+ switch (operations_[i].type) {
+ case TransformOperation::TransformOperationIdentity:
+ case TransformOperation::TransformOperationTranslate:
+ continue;
+ case TransformOperation::TransformOperationMatrix:
+ if (!operations_[i].matrix.IsIdentityOrTranslation())
+ return false;
+ continue;
+ case TransformOperation::TransformOperationRotate:
+ case TransformOperation::TransformOperationSkew:
+ case TransformOperation::TransformOperationPerspective:
+ return false;
+ case TransformOperation::TransformOperationScale:
+ if (has_scale_component)
+ return false;
+ has_scale_component = true;
+ scale->Scale(operations_[i].scale.x,
+ operations_[i].scale.y,
+ operations_[i].scale.z);
+ }
+ }
+ return true;
+}
+
bool TransformOperations::MatchesTypes(const TransformOperations& other) const {
if (IsIdentity() || other.IsIdentity())
return true;