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 
81     float getScaleX() const;
82     float getScaleY() const;
83 
84     // modify the transform
85     void        reset();
86     void        set(float tx, float ty);
87     void        set(float a, float b, float c, float d);
88     status_t    set(uint32_t flags, float w, float h);
89     void        set(const std::array<float, 9>& matrix);
90 
91     // transform data
92     Rect    makeBounds(int w, int h) const;
93     vec2    transform(float x, float y) const;
94     Region  transform(const Region& reg) const;
95     Rect    transform(const Rect& bounds,
96                       bool roundOutwards = false) const;
97     FloatRect transform(const FloatRect& bounds) const;
98     Transform& operator = (const Transform& other);
99     Transform operator * (const Transform& rhs) const;
100     Transform operator * (float value) const;
101     // assumes the last row is < 0 , 0 , 1 >
102     vec2 transform(const vec2& v) const;
103     vec3 transform(const vec3& v) const;
104 
105     // Expands from the internal 3x3 matrix to an equivalent 4x4 matrix
106     mat4 asMatrix4() const;
107 
108     Transform inverse() const;
109 
110     // for debugging
111     void dump(std::string& result, const char* name, const char* prefix = "") const;
112     void dump(const char* name, const char* prefix = "") const;
113 
114     static constexpr RotationFlags toRotationFlags(Rotation);
115     static constexpr Rotation toRotation(RotationFlags);
116 
117 private:
118     struct mat33 {
119         vec3 v[3];
120         inline const vec3& operator [] (size_t i) const { return v[i]; }
121         inline vec3& operator [] (size_t i) { return v[i]; }
122     };
123 
124     enum { UNKNOWN_TYPE = 0x80000000 };
125 
126     uint32_t type() const;
127     static bool absIsOne(float f);
128     static bool isZero(float f);
129 
130     mat33               mMatrix;
131     mutable uint32_t    mType;
132 };
133 
PrintTo(const Transform & t,::std::ostream * os)134 inline void PrintTo(const Transform& t, ::std::ostream* os) {
135     std::string out;
136     t.dump(out, "ui::Transform");
137     *os << out;
138 }
139 
toRotationFlags(Rotation rotation)140 inline constexpr Transform::RotationFlags Transform::toRotationFlags(Rotation rotation) {
141     switch (rotation) {
142         case ROTATION_0:
143             return ROT_0;
144         case ROTATION_90:
145             return ROT_90;
146         case ROTATION_180:
147             return ROT_180;
148         case ROTATION_270:
149             return ROT_270;
150         default:
151             return ROT_INVALID;
152     }
153 }
154 
toRotation(Transform::RotationFlags rotationFlags)155 inline constexpr Rotation Transform::toRotation(Transform::RotationFlags rotationFlags) {
156     switch (rotationFlags) {
157         case ROT_0:
158             return ROTATION_0;
159         case ROT_90:
160             return ROTATION_90;
161         case ROT_180:
162             return ROTATION_180;
163         case ROT_270:
164             return ROTATION_270;
165         default:
166             return ROTATION_0;
167     }
168 }
169 
170 }  // namespace ui
171 }  // namespace android
172