• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef MMI_TRANSFORM_H
17 #define MMI_TRANSFORM_H
18 
19 #include "window_info.h"
20 
21 namespace OHOS {
22 namespace MMI {
23 
24 template <typename T> struct Vector2D {
25     T x;
26     T y;
27 };
28 
29 template <typename T> class SimpleTransform {
30 public:
31     enum class Type {
32         Translate,
33         Rotate,
34     };
35     const Type type;
36     const T a00;
37     const T a01;
38     const T x0;
39     const T a10;
40     const T a11;
41     const T y0;
42     static SimpleTransform<T> Translate(const Vector2D<T> &v);
43     static SimpleTransform<T> RotateDirection(Direction direction);
44     Vector2D<T> Apply(const Vector2D<T> &v) const;
45     Vector2D<T> Reset(const Vector2D<T> &v) const;
46 };
47 
Translate(const Vector2D<T> & v)48 template <typename T> SimpleTransform<T> SimpleTransform<T>::Translate(const Vector2D<T> &v)
49 {
50     return SimpleTransform<T>{
51         .type = Type::Translate,
52         .a00 = 1,
53         .a01 = 0,
54         .x0 = v.x,
55         .a10 = 0,
56         .a11 = 1,
57         .y0 = v.y,
58     };
59 }
60 
RotateDirection(Direction direction)61 template <typename T> SimpleTransform<T> SimpleTransform<T>::RotateDirection(Direction direction)
62 {
63     // direction 0 1 2 3
64     // cos 1 0 -1 0
65     // sin 0 1 0 -1
66     T cosine = 1;
67     T sine = 0;
68     switch (direction) {
69         case DIRECTION90:
70             cosine = 0;
71             sine = 1;
72             break;
73         case DIRECTION180:
74             cosine = -1;
75             sine = 0;
76             break;
77         case DIRECTION270:
78             cosine = 0;
79             sine = -1;
80             break;
81         case DIRECTION0:
82         default:
83             break;
84     }
85     return SimpleTransform<T>{
86         .type = Type::Rotate,
87         .a00 = cosine,
88         .a01 = -sine,
89         .x0 = 0,
90         .a10 = sine,
91         .a11 = cosine,
92         .y0 = 0,
93     };
94 }
95 
Apply(const Vector2D<T> & v)96 template <typename T> Vector2D<T> SimpleTransform<T>::Apply(const Vector2D<T> &v) const
97 {
98     return {
99         .x = a00 * v.x + a01 * v.y + x0,
100         .y = a10 * v.x + a11 * v.y + y0,
101     };
102 }
103 
Reset(const Vector2D<T> & v)104 template <typename T> Vector2D<T> SimpleTransform<T>::Reset(const Vector2D<T> &v) const
105 {
106     // Since only translate and rotation are supported,
107     // we can assert the inverse of transform matrix is in the following form:
108     return {
109         .x = a00 * v.x + a10 * v.y - x0,
110         .y = a01 * v.x + a11 * v.y - y0,
111     };
112 }
113 
114 template <typename T>
ApplyTransformSteps(const std::vector<SimpleTransform<T>> & steps,const Vector2D<T> & v)115 inline Vector2D<T> ApplyTransformSteps(const std::vector<SimpleTransform<T>> &steps, const Vector2D<T> &v)
116 {
117     Vector2D<T> result = v;
118     for (const auto &step : steps) {
119         result = step.Apply(result);
120     }
121     return result;
122 }
123 
124 template <typename T>
ResetTransformSteps(const std::vector<SimpleTransform<T>> & steps,const Vector2D<T> & v)125 inline Vector2D<T> ResetTransformSteps(const std::vector<SimpleTransform<T>> &steps, const Vector2D<T> &v)
126 {
127     Vector2D<T> result = v;
128     for (auto iter = steps.rbegin(); iter != steps.rend(); ++iter) {
129         result = iter->Reset(result);
130     }
131     return result;
132 }
133 
RotateAndFitScreen(Direction direction,const Vector2D<T> & size)134 template <typename T> std::vector<SimpleTransform<T>> RotateAndFitScreen(Direction direction, const Vector2D<T> &size)
135 {
136     std::vector<SimpleTransform<T>> result;
137     if (direction == DIRECTION0) {
138         return result;
139     }
140     result.emplace_back(SimpleTransform<T>::RotateDirection(direction));
141     switch (direction) {
142         case DIRECTION90:
143             result.emplace_back(SimpleTransform<T>::Translate({ size.y, 0 }));
144             break;
145         case DIRECTION180:
146             result.emplace_back(SimpleTransform<T>::Translate(size));
147             break;
148         case DIRECTION270:
149             result.emplace_back(SimpleTransform<T>::Translate({ 0, size.x }));
150             break;
151         case DIRECTION0:
152         default:
153             break;
154     }
155 
156     return result;
157 }
158 
RotateRect(Direction direction,const Vector2D<T> & size)159 template <typename T> inline Vector2D<T> RotateRect(Direction direction, const Vector2D<T> &size)
160 {
161     switch (direction) {
162         case DIRECTION90:
163         case DIRECTION270:
164             return { size.y, size.x };
165         case DIRECTION0:
166         case DIRECTION180:
167         default:
168             return size;
169     }
170 }
171 
172 } // namespace MMI
173 } // namespace OHOS
174 
175 #endif /* MMI_TRANSFORM_H */
176