diff options
Diffstat (limited to 'chromium/cc/animation/transform_operations.cc')
-rw-r--r-- | chromium/cc/animation/transform_operations.cc | 101 |
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; |