blob: a9e5997114f21414291c7ee2afe8394986bc3ece [file] [log] [blame]
[email protected]3c2196b22012-03-17 03:42:251// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]36df22b2011-02-24 21:47:562// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef UI_GFX_TRANSFORM_H_
6#define UI_GFX_TRANSFORM_H_
[email protected]36df22b2011-02-24 21:47:567
[email protected]6ab42d92012-12-20 20:36:538#include <string>
9
[email protected]45127922012-11-17 12:24:4910#include "base/compiler_specific.h"
[email protected]80248e32011-07-08 15:31:1111#include "third_party/skia/include/utils/SkMatrix44.h"
[email protected]507bad52011-08-06 04:51:0712#include "ui/base/ui_export.h"
[email protected]b9b1e7a42011-05-17 15:29:5113
[email protected]36df22b2011-02-24 21:47:5614namespace gfx {
[email protected]0f0453e2012-10-14 18:15:3515
[email protected]79fbdab02012-11-14 07:28:1116class RectF;
[email protected]80248e32011-07-08 15:31:1117class Point;
[email protected]2771b1c2012-10-31 05:15:4318class Point3F;
[email protected]f7c321eb2012-11-26 20:13:0819class Vector3dF;
[email protected]36df22b2011-02-24 21:47:5620
[email protected]80248e32011-07-08 15:31:1121// 4x4 transformation matrix. Transform is cheap and explicitly allows
[email protected]b9b1e7a42011-05-17 15:29:5122// copy/assign.
[email protected]507bad52011-08-06 04:51:0723class UI_EXPORT Transform {
[email protected]36df22b2011-02-24 21:47:5624 public:
[email protected]bda41962013-01-07 18:46:1725
26 enum SkipInitialization {
27 kSkipInitialization
28 };
29
[email protected]0db13222012-12-13 21:27:5430 Transform() : matrix_(SkMatrix44::kIdentity_Constructor) {}
[email protected]bda41962013-01-07 18:46:1731
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) {}
[email protected]0db13222012-12-13 21:27:5436 Transform(const Transform& rhs) : matrix_(rhs.matrix_) {}
[email protected]d9a6f3302012-12-07 19:17:5437 // Initialize with the concatenation of lhs * rhs.
[email protected]0db13222012-12-13 21:27:5438 Transform(const Transform& lhs, const Transform& rhs)
39 : matrix_(lhs.matrix_, rhs.matrix_) {}
40 ~Transform() {}
[email protected]36df22b2011-02-24 21:47:5641
[email protected]0db13222012-12-13 21:27:5442 bool operator==(const Transform& rhs) const { return matrix_ == rhs.matrix_; }
43 bool operator!=(const Transform& rhs) const { return matrix_ != rhs.matrix_; }
[email protected]80248e32011-07-08 15:31:1144
[email protected]f7c321eb2012-11-26 20:13:0845 // Resets this transform to the identity transform.
[email protected]0db13222012-12-13 21:27:5446 void MakeIdentity() { matrix_.setIdentity(); }
[email protected]2fcafa02012-11-15 01:12:5547
[email protected]2c7cd6d2012-11-28 23:49:2648 // Applies the current transformation on a 2d rotation and assigns the result
[email protected]2fcafa02012-11-15 01:12:5549 // to |this|.
[email protected]2c7cd6d2012-11-28 23:49:2650 void Rotate(double degrees) { RotateAboutZAxis(degrees); }
[email protected]2fcafa02012-11-15 01:12:5551
52 // Applies the current transformation on an axis-angle rotation and assigns
53 // the result to |this|.
[email protected]2c7cd6d2012-11-28 23:49:2654 void RotateAboutXAxis(double degrees);
55 void RotateAboutYAxis(double degrees);
56 void RotateAboutZAxis(double degrees);
57 void RotateAbout(const Vector3dF& axis, double degrees);
[email protected]2fcafa02012-11-15 01:12:5558
59 // Applies the current transformation on a scaling and assigns the result
60 // to |this|.
[email protected]f7c321eb2012-11-26 20:13:0861 void Scale(double x, double y);
62 void Scale3d(double x, double y, double z);
[email protected]2fcafa02012-11-15 01:12:5563
64 // Applies the current transformation on a translation and assigns the result
65 // to |this|.
[email protected]f7c321eb2012-11-26 20:13:0866 void Translate(double x, double y);
67 void Translate3d(double x, double y, double z);
[email protected]2fcafa02012-11-15 01:12:5568
69 // Applies the current transformation on a skew and assigns the result
70 // to |this|.
[email protected]f7c321eb2012-11-26 20:13:0871 void SkewX(double angle_x);
72 void SkewY(double angle_y);
[email protected]2fcafa02012-11-15 01:12:5573
74 // Applies the current transformation on a perspective transform and assigns
75 // the result to |this|.
[email protected]f7c321eb2012-11-26 20:13:0876 void ApplyPerspectiveDepth(double depth);
[email protected]2fcafa02012-11-15 01:12:5577
[email protected]b9b1e7a42011-05-17 15:29:5178 // Applies a transformation on the current transformation
[email protected]80248e32011-07-08 15:31:1179 // (i.e. 'this = this * transform;').
80 void PreconcatTransform(const Transform& transform);
[email protected]36df22b2011-02-24 21:47:5681
[email protected]598080082011-04-14 19:36:3382 // Applies a transformation on the current transformation
[email protected]80248e32011-07-08 15:31:1183 // (i.e. 'this = transform * this;').
84 void ConcatTransform(const Transform& transform);
[email protected]36df22b2011-02-24 21:47:5685
[email protected]45127922012-11-17 12:24:4986 // Returns true if this is the identity matrix.
[email protected]d9a6f3302012-12-07 19:17:5487 bool IsIdentity() const { return matrix_.isIdentity(); }
[email protected]45127922012-11-17 12:24:4988
[email protected]2c7cd6d2012-11-28 23:49:2689 // Returns true if the matrix is either identity or pure translation.
[email protected]d9a6f3302012-12-07 19:17:5490 bool IsIdentityOrTranslation() const {
91 return !(matrix_.getType() & ~SkMatrix44::kTranslate_Mask);
92 }
[email protected]2c7cd6d2012-11-28 23:49:2693
[email protected]aedf4e52013-01-09 23:24:4494 // Returns true if the matrix is either a positive scale and/or a translation.
95 bool IsPositiveScaleOrTranslation() const {
96 if (!IsScaleOrTranslation())
97 return false;
98 return matrix_.getDouble(0, 0) > 0.0 &&
99 matrix_.getDouble(1, 1) > 0.0 &&
100 matrix_.getDouble(2, 2) > 0.0;
101 }
102
[email protected]d1a56f02012-12-04 12:18:30103 // Returns true if the matrix is either identity or pure, non-fractional
104 // translation.
105 bool IsIdentityOrIntegerTranslation() const;
106
[email protected]2c7cd6d2012-11-28 23:49:26107 // Returns true if the matrix is has only scaling and translation components.
[email protected]0db13222012-12-13 21:27:54108 bool IsScaleOrTranslation() const {
109 int mask = SkMatrix44::kScale_Mask | SkMatrix44::kTranslate_Mask;
110 return (matrix_.getType() & ~mask) == 0;
111 }
[email protected]2c7cd6d2012-11-28 23:49:26112
113 // Returns true if the matrix has any perspective component that would
114 // change the w-component of a homogeneous point.
[email protected]0db13222012-12-13 21:27:54115 bool HasPerspective() const {
116 return (matrix_.getType() & SkMatrix44::kPerspective_Mask) != 0;
117 }
[email protected]2c7cd6d2012-11-28 23:49:26118
[email protected]45127922012-11-17 12:24:49119 // Returns true if this transform is non-singular.
[email protected]0db13222012-12-13 21:27:54120 bool IsInvertible() const { return matrix_.invert(NULL); }
[email protected]36df22b2011-02-24 21:47:56121
[email protected]2c7cd6d2012-11-28 23:49:26122 // Returns true if a layer with a forward-facing normal of (0, 0, 1) would
123 // have its back side facing frontwards after applying the transform.
124 bool IsBackFaceVisible() const;
125
[email protected]38919392011-10-24 22:26:23126 // Inverts the transform which is passed in. Returns true if successful.
[email protected]45127922012-11-17 12:24:49127 bool GetInverse(Transform* transform) const WARN_UNUSED_RESULT;
128
129 // Transposes this transform in place.
130 void Transpose();
[email protected]38919392011-10-24 22:26:23131
[email protected]598080082011-04-14 19:36:33132 // Applies the transformation on the point. Returns true if the point is
133 // transformed successfully.
[email protected]2771b1c2012-10-31 05:15:43134 void TransformPoint(Point3F& point) const;
[email protected]36df22b2011-02-24 21:47:56135
[email protected]80248e32011-07-08 15:31:11136 // Applies the transformation on the point. Returns true if the point is
137 // transformed successfully. Rounds the result to the nearest point.
[email protected]0f0453e2012-10-14 18:15:35138 void TransformPoint(Point& point) const;
[email protected]36df22b2011-02-24 21:47:56139
[email protected]80248e32011-07-08 15:31:11140 // Applies the reverse transformation on the point. Returns true if the
141 // transformation can be inverted.
[email protected]2771b1c2012-10-31 05:15:43142 bool TransformPointReverse(Point3F& point) const;
[email protected]463eb0e2011-05-10 03:11:04143
[email protected]80248e32011-07-08 15:31:11144 // Applies the reverse transformation on the point. Returns true if the
145 // transformation can be inverted. Rounds the result to the nearest point.
[email protected]0f0453e2012-10-14 18:15:35146 bool TransformPointReverse(Point& point) const;
[email protected]80248e32011-07-08 15:31:11147
148 // Applies transformation on the rectangle. Returns true if the transformed
149 // rectangle was axis aligned. If it returns false, rect will be the
[email protected]91f4c792012-06-06 02:21:19150 // smallest axis aligned bounding box containing the transformed rect.
[email protected]79fbdab02012-11-14 07:28:11151 void TransformRect(RectF* rect) const;
[email protected]80248e32011-07-08 15:31:11152
153 // Applies the reverse transformation on the rectangle. Returns true if
154 // the transformed rectangle was axis aligned. If it returns false,
[email protected]91f4c792012-06-06 02:21:19155 // rect will be the smallest axis aligned bounding box containing the
[email protected]80248e32011-07-08 15:31:11156 // transformed rect.
[email protected]79fbdab02012-11-14 07:28:11157 bool TransformRectReverse(RectF* rect) const;
[email protected]277c7b72011-06-06 15:23:09158
[email protected]2fcafa02012-11-15 01:12:55159 // Decomposes |this| and |from|, interpolates the decomposed values, and
160 // sets |this| to the reconstituted result. Returns false if either matrix
161 // can't be decomposed. Uses routines described in this spec:
162 // http://www.w3.org/TR/css3-3d-transforms/.
163 //
164 // Note: this call is expensive since we need to decompose the transform. If
165 // you're going to be calling this rapidly (e.g., in an animation) you should
166 // decompose once using gfx::DecomposeTransforms and reuse your
167 // DecomposedTransform.
168 bool Blend(const Transform& from, double progress);
169
[email protected]f7c321eb2012-11-26 20:13:08170 // Returns |this| * |other|.
[email protected]d9a6f3302012-12-07 19:17:54171 Transform operator*(const Transform& other) const {
172 return Transform(*this, other);
173 }
[email protected]f7c321eb2012-11-26 20:13:08174
175 // Sets |this| = |this| * |other|
[email protected]0db13222012-12-13 21:27:54176 Transform& operator*=(const Transform& other) {
177 PreconcatTransform(other);
178 return *this;
179 }
[email protected]f7c321eb2012-11-26 20:13:08180
[email protected]b9b1e7a42011-05-17 15:29:51181 // Returns the underlying matrix.
[email protected]80248e32011-07-08 15:31:11182 const SkMatrix44& matrix() const { return matrix_; }
183 SkMatrix44& matrix() { return matrix_; }
[email protected]b9b1e7a42011-05-17 15:29:51184
[email protected]6ab42d92012-12-20 20:36:53185 std::string ToString() const;
186
[email protected]b9b1e7a42011-05-17 15:29:51187 private:
[email protected]80248e32011-07-08 15:31:11188 void TransformPointInternal(const SkMatrix44& xform,
[email protected]0f0453e2012-10-14 18:15:35189 Point& point) const;
[email protected]80248e32011-07-08 15:31:11190
191 void TransformPointInternal(const SkMatrix44& xform,
[email protected]2771b1c2012-10-31 05:15:43192 Point3F& point) const;
[email protected]80248e32011-07-08 15:31:11193
194 SkMatrix44 matrix_;
[email protected]b9b1e7a42011-05-17 15:29:51195
196 // copy/assign are allowed.
[email protected]36df22b2011-02-24 21:47:56197};
198
[email protected]0f0453e2012-10-14 18:15:35199} // namespace gfx
[email protected]36df22b2011-02-24 21:47:56200
201#endif // UI_GFX_TRANSFORM_H_