1 /*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <stdint.h>
20 #include <sys/types.h>
21 #include <array>
22 #include <ostream>
23 #include <string>
24
25 #include <math/mat4.h>
26 #include <math/vec2.h>
27 #include <math/vec3.h>
28 #include <ui/Point.h>
29 #include <ui/Rect.h>
30 #include <ui/Rotation.h>
31
32 namespace android {
33
34 class Region;
35
36 namespace ui {
37
38 class Transform {
39 public:
40 Transform();
41 Transform(const Transform& other);
42 explicit Transform(uint32_t orientation, int w = 0, int h = 0);
43 ~Transform();
44
45 enum RotationFlags : uint32_t {
46 ROT_0 = 0,
47 FLIP_H = 1, // HAL_TRANSFORM_FLIP_H
48 FLIP_V = 2, // HAL_TRANSFORM_FLIP_V
49 ROT_90 = 4, // HAL_TRANSFORM_ROT_90
50 ROT_180 = FLIP_H | FLIP_V,
51 ROT_270 = ROT_180 | ROT_90,
52 ROT_INVALID = 0x80
53 };
54
55 enum type_mask : uint32_t {
56 IDENTITY = 0,
57 TRANSLATE = 0x1,
58 ROTATE = 0x2,
59 SCALE = 0x4,
60 UNKNOWN = 0x8
61 };
62
63 // query the transform
64 bool preserveRects() const;
65
66 // Returns if bilinear filtering is needed after applying this transform to avoid aliasing.
67 bool needsBilinearFiltering() const;
68
69 uint32_t getType() const;
70 uint32_t getOrientation() const;
71 bool operator==(const Transform& other) const;
72
73 const vec3& operator [] (size_t i) const; // returns column i
74 float tx() const;
75 float ty() const;
76 float dsdx() const;
77 float dtdx() const;
78 float dtdy() const;
79 float dsdy() const;
80 float det() const;
81
82 float getScaleX() const;
83 float getScaleY() const;
84
85 // modify the transform
86 void reset();
87 void set(float tx, float ty);
88 void set(float a, float b, float c, float d);
89 status_t set(uint32_t flags, float w, float h);
90 void set(const std::array<float, 9>& matrix);
91
92 // transform data
93 Rect makeBounds(int w, int h) const;
94 vec2 transform(float x, float y) const;
95 Region transform(const Region& reg) const;
96 Rect transform(const Rect& bounds,
97 bool roundOutwards = false) const;
98 FloatRect transform(const FloatRect& bounds) const;
99 Transform& operator = (const Transform& other);
100 Transform operator * (const Transform& rhs) const;
101 Transform operator * (float value) const;
102 // assumes the last row is < 0 , 0 , 1 >
103 vec2 transform(const vec2& v) const;
104 vec3 transform(const vec3& v) const;
105
106 // Expands from the internal 3x3 matrix to an equivalent 4x4 matrix
107 mat4 asMatrix4() const;
108
109 Transform inverse() const;
110
111 // for debugging
112 void dump(std::string& result, const char* name, const char* prefix = "") const;
113 void dump(const char* name, const char* prefix = "") const;
114
115 static constexpr RotationFlags toRotationFlags(Rotation);
116 static constexpr Rotation toRotation(RotationFlags);
117
118 private:
119 struct mat33 {
120 vec3 v[3];
121 inline const vec3& operator [] (size_t i) const { return v[i]; }
122 inline vec3& operator [] (size_t i) { return v[i]; }
123 };
124
125 enum { UNKNOWN_TYPE = 0x80000000 };
126
127 uint32_t type() const;
128 static bool absIsOne(float f);
129 static bool isZero(float f);
130
131 mat33 mMatrix;
132 mutable uint32_t mType;
133 };
134
PrintTo(const Transform & t,::std::ostream * os)135 inline void PrintTo(const Transform& t, ::std::ostream* os) {
136 std::string out;
137 t.dump(out, "ui::Transform");
138 *os << out;
139 }
140
toRotationFlags(Rotation rotation)141 inline constexpr Transform::RotationFlags Transform::toRotationFlags(Rotation rotation) {
142 switch (rotation) {
143 case ROTATION_0:
144 return ROT_0;
145 case ROTATION_90:
146 return ROT_90;
147 case ROTATION_180:
148 return ROT_180;
149 case ROTATION_270:
150 return ROT_270;
151 default:
152 return ROT_INVALID;
153 }
154 }
155
toRotation(Transform::RotationFlags rotationFlags)156 inline constexpr Rotation Transform::toRotation(Transform::RotationFlags rotationFlags) {
157 switch (rotationFlags) {
158 case ROT_0:
159 return ROTATION_0;
160 case ROT_90:
161 return ROTATION_90;
162 case ROT_180:
163 return ROTATION_180;
164 case ROT_270:
165 return ROTATION_270;
166 default:
167 return ROTATION_0;
168 }
169 }
170
171 } // namespace ui
172 } // namespace android
173