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. 4 5 #ifndef CC_ANIMATION_TRANSFORM_OPERATIONS_H_ 6 #define CC_ANIMATION_TRANSFORM_OPERATIONS_H_ 7 8 #include <vector> 9 10 #include "base/memory/scoped_ptr.h" 11 #include "cc/animation/transform_operation.h" 12 #include "cc/base/cc_export.h" 13 #include "ui/gfx/transform.h" 14 15 namespace gfx { 16 class BoxF; 17 struct DecomposedTransform; 18 } 19 20 namespace cc { 21 22 // Transform operations are a decomposed transformation matrix. It can be 23 // applied to obtain a gfx::Transform at any time, and can be blended 24 // intelligently with other transform operations, so long as they represent the 25 // same decomposition. For example, if we have a transform that is made up of 26 // a rotation followed by skew, it can be blended intelligently with another 27 // transform made up of a rotation followed by a skew. Blending is possible if 28 // we have two dissimilar sets of transform operations, but the effect may not 29 // be what was intended. For more information, see the comments for the blend 30 // function below. 31 class CC_EXPORT TransformOperations { 32 public: 33 TransformOperations(); 34 TransformOperations(const TransformOperations& other); 35 ~TransformOperations(); 36 37 // Returns a transformation matrix representing these transform operations. 38 gfx::Transform Apply() const; 39 40 // Given another set of transform operations and a progress in the range 41 // [0, 1], returns a transformation matrix representing the intermediate 42 // value. If this->MatchesTypes(from), then each of the operations are 43 // blended separately and then combined. Otherwise, the two sets of 44 // transforms are baked to matrices (using apply), and the matrices are 45 // then decomposed and interpolated. For more information, see 46 // http://www.w3.org/TR/2011/WD-css3-2d-transforms-20111215/#matrix-decomposition. 47 gfx::Transform Blend(const TransformOperations& from, 48 SkMScalar progress) const; 49 50 // Sets |bounds| be the bounding box for the region within which |box| will 51 // exist when it is transformed by the result of calling Blend on |from| and 52 // with progress in the range [min_progress, max_progress]. If this region 53 // cannot be computed, returns false. 54 bool BlendedBoundsForBox(const gfx::BoxF& box, 55 const TransformOperations& from, 56 SkMScalar min_progress, 57 SkMScalar max_progress, 58 gfx::BoxF* bounds) const; 59 60 // Returns true if this operation and its descendants have the same types 61 // as other and its descendants. 62 bool MatchesTypes(const TransformOperations& other) const; 63 64 // Returns true if these operations can be blended. It will only return 65 // false if we must resort to matrix interpolation, and matrix interpolation 66 // fails (this can happen if either matrix cannot be decomposed). 67 bool CanBlendWith(const TransformOperations& other) const; 68 69 void AppendTranslate(SkMScalar x, SkMScalar y, SkMScalar z); 70 void AppendRotate(SkMScalar x, SkMScalar y, SkMScalar z, SkMScalar degrees); 71 void AppendScale(SkMScalar x, SkMScalar y, SkMScalar z); 72 void AppendSkew(SkMScalar x, SkMScalar y); 73 void AppendPerspective(SkMScalar depth); 74 void AppendMatrix(const gfx::Transform& matrix); 75 void AppendIdentity(); 76 bool IsIdentity() const; 77 78 private: 79 bool BlendInternal(const TransformOperations& from, 80 SkMScalar progress, 81 gfx::Transform* result) const; 82 83 std::vector<TransformOperation> operations_; 84 85 bool ComputeDecomposedTransform() const; 86 87 // For efficiency, we cache the decomposed transform. 88 mutable scoped_ptr<gfx::DecomposedTransform> decomposed_transform_; 89 mutable bool decomposed_transform_dirty_; 90 91 DISALLOW_ASSIGN(TransformOperations); 92 }; 93 94 } // namespace cc 95 96 #endif // CC_ANIMATION_TRANSFORM_OPERATIONS_H_ 97