12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CC_ANIMATION_TRANSFORM_OPERATIONS_H_ 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CC_ANIMATION_TRANSFORM_OPERATIONS_H_ 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/animation/transform_operation.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/cc_export.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/transform.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gfx { 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class BoxF; 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct DecomposedTransform; 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Transform operations are a decomposed transformation matrix. It can be 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// applied to obtain a gfx::Transform at any time, and can be blended 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// intelligently with other transform operations, so long as they represent the 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// same decomposition. For example, if we have a transform that is made up of 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// a rotation followed by skew, it can be blended intelligently with another 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// transform made up of a rotation followed by a skew. Blending is possible if 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// we have two dissimilar sets of transform operations, but the effect may not 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// be what was intended. For more information, see the comments for the blend 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// function below. 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CC_EXPORT TransformOperations { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransformOperations(); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransformOperations(const TransformOperations& other); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~TransformOperations(); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns a transformation matrix representing these transform operations. 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform Apply() const; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Given another set of transform operations and a progress in the range 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // [0, 1], returns a transformation matrix representing the intermediate 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // value. If this->MatchesTypes(from), then each of the operations are 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // blended separately and then combined. Otherwise, the two sets of 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // transforms are baked to matrices (using apply), and the matrices are 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // then decomposed and interpolated. For more information, see 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // http://www.w3.org/TR/2011/WD-css3-2d-transforms-20111215/#matrix-decomposition. 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) gfx::Transform Blend(const TransformOperations& from, 4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SkMScalar progress) const; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Sets |bounds| be the bounding box for the region within which |box| will 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // exist when it is transformed by the result of calling Blend on |from| and 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // with progress in the range [min_progress, max_progress]. If this region 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // cannot be computed, returns false. 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool BlendedBoundsForBox(const gfx::BoxF& box, 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const TransformOperations& from, 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SkMScalar min_progress, 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SkMScalar max_progress, 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) gfx::BoxF* bounds) const; 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Returns true if these operations affect scale. 61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool AffectsScale() const; 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Returns true if these operations are only translations. 64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool IsTranslation() const; 65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns true if this operation and its descendants have the same types 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // as other and its descendants. 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool MatchesTypes(const TransformOperations& other) const; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns true if these operations can be blended. It will only return 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // false if we must resort to matrix interpolation, and matrix interpolation 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // fails (this can happen if either matrix cannot be decomposed). 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool CanBlendWith(const TransformOperations& other) const; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 751675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // If these operations have no more than one scale operation, and if the only 761675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // other operations are translations, sets |scale| to the scale component 771675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // of these operations. Otherwise, returns false. 781675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch bool ScaleComponent(gfx::Vector3dF* scale) const; 791675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch 8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void AppendTranslate(SkMScalar x, SkMScalar y, SkMScalar z); 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void AppendRotate(SkMScalar x, SkMScalar y, SkMScalar z, SkMScalar degrees); 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void AppendScale(SkMScalar x, SkMScalar y, SkMScalar z); 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void AppendSkew(SkMScalar x, SkMScalar y); 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void AppendPerspective(SkMScalar depth); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AppendMatrix(const gfx::Transform& matrix); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AppendIdentity(); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool IsIdentity() const; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool BlendInternal(const TransformOperations& from, 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SkMScalar progress, 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Transform* result) const; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<TransformOperation> operations_; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ComputeDecomposedTransform() const; 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For efficiency, we cache the decomposed transform. 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mutable scoped_ptr<gfx::DecomposedTransform> decomposed_transform_; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mutable bool decomposed_transform_dirty_; 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_ASSIGN(TransformOperations); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace cc 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // CC_ANIMATION_TRANSFORM_OPERATIONS_H_ 108