blob: 6cd10b13f3fcad93ddfac117cdd8a2340f342d38 [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]0db13222012-12-13 21:27:5425 Transform() : matrix_(SkMatrix44::kIdentity_Constructor) {}
26 Transform(const Transform& rhs) : matrix_(rhs.matrix_) {}
[email protected]d9a6f3302012-12-07 19:17:5427 // Initialize with the concatenation of lhs * rhs.
[email protected]0db13222012-12-13 21:27:5428 Transform(const Transform& lhs, const Transform& rhs)
29 : matrix_(lhs.matrix_, rhs.matrix_) {}
30 ~Transform() {}
[email protected]36df22b2011-02-24 21:47:5631
[email protected]0db13222012-12-13 21:27:5432 bool operator==(const Transform& rhs) const { return matrix_ == rhs.matrix_; }
33 bool operator!=(const Transform& rhs) const { return matrix_ != rhs.matrix_; }
[email protected]80248e32011-07-08 15:31:1134
[email protected]f7c321eb2012-11-26 20:13:0835 // Resets this transform to the identity transform.
[email protected]0db13222012-12-13 21:27:5436 void MakeIdentity() { matrix_.setIdentity(); }
[email protected]2fcafa02012-11-15 01:12:5537
[email protected]2c7cd6d2012-11-28 23:49:2638 // Applies the current transformation on a 2d rotation and assigns the result
[email protected]2fcafa02012-11-15 01:12:5539 // to |this|.
[email protected]2c7cd6d2012-11-28 23:49:2640 void Rotate(double degrees) { RotateAboutZAxis(degrees); }
[email protected]2fcafa02012-11-15 01:12:5541
42 // Applies the current transformation on an axis-angle rotation and assigns
43 // the result to |this|.
[email protected]2c7cd6d2012-11-28 23:49:2644 void RotateAboutXAxis(double degrees);
45 void RotateAboutYAxis(double degrees);
46 void RotateAboutZAxis(double degrees);
47 void RotateAbout(const Vector3dF& axis, double degrees);
[email protected]2fcafa02012-11-15 01:12:5548
49 // Applies the current transformation on a scaling and assigns the result
50 // to |this|.
[email protected]f7c321eb2012-11-26 20:13:0851 void Scale(double x, double y);
52 void Scale3d(double x, double y, double z);
[email protected]2fcafa02012-11-15 01:12:5553
54 // Applies the current transformation on a translation and assigns the result
55 // to |this|.
[email protected]f7c321eb2012-11-26 20:13:0856 void Translate(double x, double y);
57 void Translate3d(double x, double y, double z);
[email protected]2fcafa02012-11-15 01:12:5558
59 // Applies the current transformation on a skew and assigns the result
60 // to |this|.
[email protected]f7c321eb2012-11-26 20:13:0861 void SkewX(double angle_x);
62 void SkewY(double angle_y);
[email protected]2fcafa02012-11-15 01:12:5563
64 // Applies the current transformation on a perspective transform and assigns
65 // the result to |this|.
[email protected]f7c321eb2012-11-26 20:13:0866 void ApplyPerspectiveDepth(double depth);
[email protected]2fcafa02012-11-15 01:12:5567
[email protected]b9b1e7a42011-05-17 15:29:5168 // Applies a transformation on the current transformation
[email protected]80248e32011-07-08 15:31:1169 // (i.e. 'this = this * transform;').
70 void PreconcatTransform(const Transform& transform);
[email protected]36df22b2011-02-24 21:47:5671
[email protected]598080082011-04-14 19:36:3372 // Applies a transformation on the current transformation
[email protected]80248e32011-07-08 15:31:1173 // (i.e. 'this = transform * this;').
74 void ConcatTransform(const Transform& transform);
[email protected]36df22b2011-02-24 21:47:5675
[email protected]45127922012-11-17 12:24:4976 // Returns true if this is the identity matrix.
[email protected]d9a6f3302012-12-07 19:17:5477 bool IsIdentity() const { return matrix_.isIdentity(); }
[email protected]45127922012-11-17 12:24:4978
[email protected]2c7cd6d2012-11-28 23:49:2679 // Returns true if the matrix is either identity or pure translation.
[email protected]d9a6f3302012-12-07 19:17:5480 bool IsIdentityOrTranslation() const {
81 return !(matrix_.getType() & ~SkMatrix44::kTranslate_Mask);
82 }
[email protected]2c7cd6d2012-11-28 23:49:2683
[email protected]d1a56f02012-12-04 12:18:3084 // Returns true if the matrix is either identity or pure, non-fractional
85 // translation.
86 bool IsIdentityOrIntegerTranslation() const;
87
[email protected]2c7cd6d2012-11-28 23:49:2688 // Returns true if the matrix is has only scaling and translation components.
[email protected]0db13222012-12-13 21:27:5489 bool IsScaleOrTranslation() const {
90 int mask = SkMatrix44::kScale_Mask | SkMatrix44::kTranslate_Mask;
91 return (matrix_.getType() & ~mask) == 0;
92 }
[email protected]2c7cd6d2012-11-28 23:49:2693
94 // Returns true if the matrix has any perspective component that would
95 // change the w-component of a homogeneous point.
[email protected]0db13222012-12-13 21:27:5496 bool HasPerspective() const {
97 return (matrix_.getType() & SkMatrix44::kPerspective_Mask) != 0;
98 }
[email protected]2c7cd6d2012-11-28 23:49:2699
[email protected]45127922012-11-17 12:24:49100 // Returns true if this transform is non-singular.
[email protected]0db13222012-12-13 21:27:54101 bool IsInvertible() const { return matrix_.invert(NULL); }
[email protected]36df22b2011-02-24 21:47:56102
[email protected]2c7cd6d2012-11-28 23:49:26103 // Returns true if a layer with a forward-facing normal of (0, 0, 1) would
104 // have its back side facing frontwards after applying the transform.
105 bool IsBackFaceVisible() const;
106
[email protected]38919392011-10-24 22:26:23107 // Inverts the transform which is passed in. Returns true if successful.
[email protected]45127922012-11-17 12:24:49108 bool GetInverse(Transform* transform) const WARN_UNUSED_RESULT;
109
110 // Transposes this transform in place.
111 void Transpose();
[email protected]38919392011-10-24 22:26:23112
[email protected]598080082011-04-14 19:36:33113 // Applies the transformation on the point. Returns true if the point is
114 // transformed successfully.
[email protected]2771b1c2012-10-31 05:15:43115 void TransformPoint(Point3F& point) const;
[email protected]36df22b2011-02-24 21:47:56116
[email protected]80248e32011-07-08 15:31:11117 // Applies the transformation on the point. Returns true if the point is
118 // transformed successfully. Rounds the result to the nearest point.
[email protected]0f0453e2012-10-14 18:15:35119 void TransformPoint(Point& point) const;
[email protected]36df22b2011-02-24 21:47:56120
[email protected]80248e32011-07-08 15:31:11121 // Applies the reverse transformation on the point. Returns true if the
122 // transformation can be inverted.
[email protected]2771b1c2012-10-31 05:15:43123 bool TransformPointReverse(Point3F& point) const;
[email protected]463eb0e2011-05-10 03:11:04124
[email protected]80248e32011-07-08 15:31:11125 // Applies the reverse transformation on the point. Returns true if the
126 // transformation can be inverted. Rounds the result to the nearest point.
[email protected]0f0453e2012-10-14 18:15:35127 bool TransformPointReverse(Point& point) const;
[email protected]80248e32011-07-08 15:31:11128
129 // Applies transformation on the rectangle. Returns true if the transformed
130 // rectangle was axis aligned. If it returns false, rect will be the
[email protected]91f4c792012-06-06 02:21:19131 // smallest axis aligned bounding box containing the transformed rect.
[email protected]79fbdab02012-11-14 07:28:11132 void TransformRect(RectF* rect) const;
[email protected]80248e32011-07-08 15:31:11133
134 // Applies the reverse transformation on the rectangle. Returns true if
135 // the transformed rectangle was axis aligned. If it returns false,
[email protected]91f4c792012-06-06 02:21:19136 // rect will be the smallest axis aligned bounding box containing the
[email protected]80248e32011-07-08 15:31:11137 // transformed rect.
[email protected]79fbdab02012-11-14 07:28:11138 bool TransformRectReverse(RectF* rect) const;
[email protected]277c7b72011-06-06 15:23:09139
[email protected]2fcafa02012-11-15 01:12:55140 // Decomposes |this| and |from|, interpolates the decomposed values, and
141 // sets |this| to the reconstituted result. Returns false if either matrix
142 // can't be decomposed. Uses routines described in this spec:
143 // http://www.w3.org/TR/css3-3d-transforms/.
144 //
145 // Note: this call is expensive since we need to decompose the transform. If
146 // you're going to be calling this rapidly (e.g., in an animation) you should
147 // decompose once using gfx::DecomposeTransforms and reuse your
148 // DecomposedTransform.
149 bool Blend(const Transform& from, double progress);
150
[email protected]f7c321eb2012-11-26 20:13:08151 // Returns |this| * |other|.
[email protected]d9a6f3302012-12-07 19:17:54152 Transform operator*(const Transform& other) const {
153 return Transform(*this, other);
154 }
[email protected]f7c321eb2012-11-26 20:13:08155
156 // Sets |this| = |this| * |other|
[email protected]0db13222012-12-13 21:27:54157 Transform& operator*=(const Transform& other) {
158 PreconcatTransform(other);
159 return *this;
160 }
[email protected]f7c321eb2012-11-26 20:13:08161
[email protected]b9b1e7a42011-05-17 15:29:51162 // Returns the underlying matrix.
[email protected]80248e32011-07-08 15:31:11163 const SkMatrix44& matrix() const { return matrix_; }
164 SkMatrix44& matrix() { return matrix_; }
[email protected]b9b1e7a42011-05-17 15:29:51165
[email protected]6ab42d92012-12-20 20:36:53166 std::string ToString() const;
167
[email protected]b9b1e7a42011-05-17 15:29:51168 private:
[email protected]80248e32011-07-08 15:31:11169 void TransformPointInternal(const SkMatrix44& xform,
[email protected]0f0453e2012-10-14 18:15:35170 Point& point) const;
[email protected]80248e32011-07-08 15:31:11171
172 void TransformPointInternal(const SkMatrix44& xform,
[email protected]2771b1c2012-10-31 05:15:43173 Point3F& point) const;
[email protected]80248e32011-07-08 15:31:11174
175 SkMatrix44 matrix_;
[email protected]b9b1e7a42011-05-17 15:29:51176
177 // copy/assign are allowed.
[email protected]36df22b2011-02-24 21:47:56178};
179
[email protected]0f0453e2012-10-14 18:15:35180} // namespace gfx
[email protected]36df22b2011-02-24 21:47:56181
182#endif // UI_GFX_TRANSFORM_H_