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 these operations affect scale. 61 bool AffectsScale() const; 62 63 // Returns true if these operations are only translations. 64 bool IsTranslation() const; 65 66 // Returns true if this operation and its descendants have the same types 67 // as other and its descendants. 68 bool MatchesTypes(const TransformOperations& other) const; 69 70 // Returns true if these operations can be blended. It will only return 71 // false if we must resort to matrix interpolation, and matrix interpolation 72 // fails (this can happen if either matrix cannot be decomposed). 73 bool CanBlendWith(const TransformOperations& other) const; 74 75 // If these operations have no more than one scale operation, and if the only 76 // other operations are translations, sets |scale| to the scale component 77 // of these operations. Otherwise, returns false. 78 bool ScaleComponent(gfx::Vector3dF* scale) const; 79 80 void AppendTranslate(SkMScalar x, SkMScalar y, SkMScalar z); 81 void AppendRotate(SkMScalar x, SkMScalar y, SkMScalar z, SkMScalar degrees); 82 void AppendScale(SkMScalar x, SkMScalar y, SkMScalar z); 83 void AppendSkew(SkMScalar x, SkMScalar y); 84 void AppendPerspective(SkMScalar depth); 85 void AppendMatrix(const gfx::Transform& matrix); 86 void AppendIdentity(); 87 bool IsIdentity() const; 88 89 private: 90 bool BlendInternal(const TransformOperations& from, 91 SkMScalar progress, 92 gfx::Transform* result) const; 93 94 std::vector<TransformOperation> operations_; 95 96 bool ComputeDecomposedTransform() const; 97 98 // For efficiency, we cache the decomposed transform. 99 mutable scoped_ptr<gfx::DecomposedTransform> decomposed_transform_; 100 mutable bool decomposed_transform_dirty_; 101 102 DISALLOW_ASSIGN(TransformOperations); 103 }; 104 105 } // namespace cc 106 107 #endif // CC_ANIMATION_TRANSFORM_OPERATIONS_H_ 108