Don't crash when SimpleCache index is corrupt.
[chromium-blink-merge.git] / ui / gfx / transform.h
blob10885bd3aaff9d3c345fe948a6744bb6ee93ebb4
1 // Copyright (c) 2012 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.
5 #ifndef UI_GFX_TRANSFORM_H_
6 #define UI_GFX_TRANSFORM_H_
8 #include <string>
10 #include "base/compiler_specific.h"
11 #include "third_party/skia/include/utils/SkMatrix44.h"
12 #include "ui/base/ui_export.h"
14 namespace gfx {
16 class RectF;
17 class Point;
18 class Point3F;
19 class Vector3dF;
21 // 4x4 transformation matrix. Transform is cheap and explicitly allows
22 // copy/assign.
23 class UI_EXPORT Transform {
24 public:
26 enum SkipInitialization {
27 kSkipInitialization
30 Transform() : matrix_(SkMatrix44::kIdentity_Constructor) {}
32 // Skips initializing this matrix to avoid overhead, when we know it will be
33 // initialized before use.
34 Transform(SkipInitialization)
35 : matrix_(SkMatrix44::kUninitialized_Constructor) {}
36 Transform(const Transform& rhs) : matrix_(rhs.matrix_) {}
37 // Initialize with the concatenation of lhs * rhs.
38 Transform(const Transform& lhs, const Transform& rhs)
39 : matrix_(lhs.matrix_, rhs.matrix_) {}
40 // Constructs a transform from explicit 16 matrix elements. Elements
41 // should be given in row-major order.
42 Transform(double col1row1, double col2row1, double col3row1, double col4row1,
43 double col1row2, double col2row2, double col3row2, double col4row2,
44 double col1row3, double col2row3, double col3row3, double col4row3,
45 double col1row4, double col2row4, double col3row4, double col4row4);
46 // Constructs a transform from explicit 2d elements. All other matrix
47 // elements remain the same as the corresponding elements of an identity
48 // matrix.
49 Transform(double col1row1, double col2row1,
50 double col1row2, double col2row2,
51 double x_translation, double y_translation);
52 ~Transform() {}
54 bool operator==(const Transform& rhs) const { return matrix_ == rhs.matrix_; }
55 bool operator!=(const Transform& rhs) const { return matrix_ != rhs.matrix_; }
57 // Resets this transform to the identity transform.
58 void MakeIdentity() { matrix_.setIdentity(); }
60 // Applies the current transformation on a 2d rotation and assigns the result
61 // to |this|.
62 void Rotate(double degrees) { RotateAboutZAxis(degrees); }
64 // Applies the current transformation on an axis-angle rotation and assigns
65 // the result to |this|.
66 void RotateAboutXAxis(double degrees);
67 void RotateAboutYAxis(double degrees);
68 void RotateAboutZAxis(double degrees);
69 void RotateAbout(const Vector3dF& axis, double degrees);
71 // Applies the current transformation on a scaling and assigns the result
72 // to |this|.
73 void Scale(double x, double y);
74 void Scale3d(double x, double y, double z);
76 // Applies the current transformation on a translation and assigns the result
77 // to |this|.
78 void Translate(double x, double y);
79 void Translate3d(double x, double y, double z);
81 // Applies the current transformation on a skew and assigns the result
82 // to |this|.
83 void SkewX(double angle_x);
84 void SkewY(double angle_y);
86 // Applies the current transformation on a perspective transform and assigns
87 // the result to |this|.
88 void ApplyPerspectiveDepth(double depth);
90 // Applies a transformation on the current transformation
91 // (i.e. 'this = this * transform;').
92 void PreconcatTransform(const Transform& transform);
94 // Applies a transformation on the current transformation
95 // (i.e. 'this = transform * this;').
96 void ConcatTransform(const Transform& transform);
98 // Returns true if this is the identity matrix.
99 bool IsIdentity() const { return matrix_.isIdentity(); }
101 // Returns true if the matrix is either identity or pure translation.
102 bool IsIdentityOrTranslation() const {
103 return !(matrix_.getType() & ~SkMatrix44::kTranslate_Mask);
106 // Returns true if the matrix is either a positive scale and/or a translation.
107 bool IsPositiveScaleOrTranslation() const {
108 if (!IsScaleOrTranslation())
109 return false;
110 return matrix_.getDouble(0, 0) > 0.0 &&
111 matrix_.getDouble(1, 1) > 0.0 &&
112 matrix_.getDouble(2, 2) > 0.0;
115 // Returns true if the matrix is either identity or pure, non-fractional
116 // translation.
117 bool IsIdentityOrIntegerTranslation() const;
119 // Returns true if the matrix is has only scaling and translation components.
120 bool IsScaleOrTranslation() const {
121 int mask = SkMatrix44::kScale_Mask | SkMatrix44::kTranslate_Mask;
122 return (matrix_.getType() & ~mask) == 0;
125 // Returns true if the matrix has any perspective component that would
126 // change the w-component of a homogeneous point.
127 bool HasPerspective() const {
128 return (matrix_.getType() & SkMatrix44::kPerspective_Mask) != 0;
131 // Returns true if this transform is non-singular.
132 bool IsInvertible() const { return matrix_.invert(NULL); }
134 // Returns true if a layer with a forward-facing normal of (0, 0, 1) would
135 // have its back side facing frontwards after applying the transform.
136 bool IsBackFaceVisible() const;
138 // Inverts the transform which is passed in. Returns true if successful.
139 bool GetInverse(Transform* transform) const WARN_UNUSED_RESULT;
141 // Transposes this transform in place.
142 void Transpose();
144 // Set 3rd row and 3rd colum to (0, 0, 1, 0). Note that this flattening
145 // operation is not quite the same as an orthographic projection and is
146 // technically not a linear operation.
148 // One useful interpretation of doing this operation:
149 // - For x and y values, the new transform behaves effectively like an
150 // orthographic projection was added to the matrix sequence.
151 // - For z values, the new transform overrides any effect that the transform
152 // had on z, and instead it preserves the z value for any points that are
153 // transformed.
154 // - Because of linearity of transforms, this flattened transform also
155 // preserves the effect that any subsequent (multiplied from the right)
156 // transforms would have on z values.
158 void FlattenTo2d();
160 // Applies the transformation on the point. Returns true if the point is
161 // transformed successfully.
162 void TransformPoint(Point3F& point) const;
164 // Applies the transformation on the point. Returns true if the point is
165 // transformed successfully. Rounds the result to the nearest point.
166 void TransformPoint(Point& point) const;
168 // Applies the reverse transformation on the point. Returns true if the
169 // transformation can be inverted.
170 bool TransformPointReverse(Point3F& point) const;
172 // Applies the reverse transformation on the point. Returns true if the
173 // transformation can be inverted. Rounds the result to the nearest point.
174 bool TransformPointReverse(Point& point) const;
176 // Applies transformation on the rectangle. Returns true if the transformed
177 // rectangle was axis aligned. If it returns false, rect will be the
178 // smallest axis aligned bounding box containing the transformed rect.
179 void TransformRect(RectF* rect) const;
181 // Applies the reverse transformation on the rectangle. Returns true if
182 // the transformed rectangle was axis aligned. If it returns false,
183 // rect will be the smallest axis aligned bounding box containing the
184 // transformed rect.
185 bool TransformRectReverse(RectF* rect) const;
187 // Decomposes |this| and |from|, interpolates the decomposed values, and
188 // sets |this| to the reconstituted result. Returns false if either matrix
189 // can't be decomposed. Uses routines described in this spec:
190 // http://www.w3.org/TR/css3-3d-transforms/.
192 // Note: this call is expensive since we need to decompose the transform. If
193 // you're going to be calling this rapidly (e.g., in an animation) you should
194 // decompose once using gfx::DecomposeTransforms and reuse your
195 // DecomposedTransform.
196 bool Blend(const Transform& from, double progress);
198 // Returns |this| * |other|.
199 Transform operator*(const Transform& other) const {
200 return Transform(*this, other);
203 // Sets |this| = |this| * |other|
204 Transform& operator*=(const Transform& other) {
205 PreconcatTransform(other);
206 return *this;
209 // Returns the underlying matrix.
210 const SkMatrix44& matrix() const { return matrix_; }
211 SkMatrix44& matrix() { return matrix_; }
213 std::string ToString() const;
215 private:
216 void TransformPointInternal(const SkMatrix44& xform,
217 Point& point) const;
219 void TransformPointInternal(const SkMatrix44& xform,
220 Point3F& point) const;
222 SkMatrix44 matrix_;
224 // copy/assign are allowed.
227 } // namespace gfx
229 #endif // UI_GFX_TRANSFORM_H_