1 /*
2  * Copyright (c) 2021-2024 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 MATRIX_H
17 #define MATRIX_H
18 
19 #include <array>
20 #include <iostream>
21 
22 #include "drawing/engine_adapter/impl_interface/matrix_impl.h"
23 #include "utils/drawing_macros.h"
24 #include "utils/matrix44.h"
25 #include "utils/scalar.h"
26 
27 namespace OHOS {
28 namespace Rosen {
29 namespace Drawing {
30 enum class ScaleToFit {
31     FILL_SCALETOFIT,
32     START_SCALETOFIT,
33     CENTER_SCALETOFIT,
34     END_SCALETOFIT,
35 };
36 
37 class DRAWING_API Matrix {
38 public:
39     // Matrix is a 3x3 float type matrix.
40     static constexpr int MATRIX_SIZE = 9;
41     static constexpr size_t ROW0 = 0;
42     static constexpr size_t ROW1 = 1;
43     static constexpr size_t ROW2 = 2;
44     static constexpr size_t ROW3 = 3;
45     static constexpr size_t COL0 = 0;
46     static constexpr size_t COL1 = 1;
47     static constexpr size_t COL2 = 2;
48     static constexpr size_t COL3 = 3;
49     using Buffer = std::array<scalar, MATRIX_SIZE>;
50 
51     enum Index {
52         SCALE_X,
53         SKEW_X,
54         TRANS_X,
55         SKEW_Y,
56         SCALE_Y,
57         TRANS_Y,
58         PERSP_0,
59         PERSP_1,
60         PERSP_2,
61     };
62 
63     Matrix();
64     Matrix(const Matrix& matrix);
65     Matrix& operator=(const Matrix& matrix);
~Matrix()66     virtual ~Matrix() {}
Skew(scalar kx,scalar ky)67     static Matrix Skew(scalar kx, scalar ky)
68     {
69         Matrix m;
70         m.SetSkew(kx, ky);
71         return m;
72     }
73 
74     void Rotate(scalar degree, scalar px, scalar py);
75     void Translate(scalar dx, scalar dy);
76     void Scale(scalar sx, scalar sy, scalar px, scalar py);
77     void SetScale(scalar sx, scalar sy);
78     void SetScaleTranslate(scalar sx, scalar sy, scalar dx, scalar dy);
79     void SetSkew(scalar kx, scalar ky);
80     void SetSkew(scalar kx, scalar ky, scalar px, scalar py);
81     /**
82      * @brief         Sets Matrix to Matrix multiplied by Matrix constructed
83      *                from rotating by degrees about pivot point(0,0).
84      * @param degree  Angle of axes relative to upright axes.
85      */
86     void PreRotate(scalar degree);
87 
88     void PostRotate(scalar degree);
89 
90     /**
91      * @brief         Sets Matrix to Matrix constructed from rotating by degrees
92      *                about pivot point(px,py), multiplied by Matrix.
93      * @param degree  Angle of axes relative to upright axes.
94      * @param px      pivot on x-axis
95      * @param px      pivot on y-axis
96      */
97     void PostRotate(scalar degree, scalar px, scalar py);
98 
99     /**
100      * @brief     Sets Matrix to Matrix constructed from translation (dx, dy) multiplied by Matrix.
101      * @param dx  X-axis translation after applying Matrix.
102      * @param dy  Y-axis translation after applying Matrix.
103      */
104     void PreTranslate(scalar dx, scalar dy);
105 
106     void PostTranslate(scalar dx, scalar dy);
107 
108     /**
109      * @brief     Sets Matrix to Matrix multiplied by Matrix constructed
110      *            from scaling by (sx, sy) about pivot point (0, 0).
111      * @param sx  Horizontal scale factor.
112      * @param sy  Vertical scale factor.
113      */
114     void PreScale(scalar sx, scalar sy);
115 
116     void PostScale(scalar sx, scalar sy);
117 
118     /**
119      * @brief         Sets Matrix to Matrix constructed from scaling by (sx, sy)
120      *                about pivot point(px,py), multiplied by Matrix.
121      * @param sx      horizontal scale factor
122      * @param sy      vertical scale factor
123      * @param px      pivot on x-axis
124      * @param px      pivot on y-axis
125      */
126     void PostScale(scalar sx, scalar sy, scalar px, scalar py);
127 
128     /**
129      * @brief     Sets Matrix to Matrix multiplied by Matrix constructed
130      *            from skewing by (kx, ky) about pivot point (0, 0).
131      * @param kx  Horizontal skew factor.
132      * @param ky  Vertical skew factor.
133      */
134     void PreSkew(scalar kx, scalar ky);
135 
136     /**
137      * @brief     Sets Matrix to Matrix constructed from skewing by (kx, ky)
138      *            about pivot point(0, 0), multiplied by Matrix.
139      * @param kx  Horizontal skew factor.
140      * @param ky  Vertical skew factor.
141      */
142     void PostSkew(scalar kx, scalar ky);
143 
144     /**
145      * @brief         Sets Matrix to Matrix multiplied by Matrix constructed
146      *                from skewing by (kx, ky) about pivot point (px, py).
147      * @param sx      horizontal skew factor
148      * @param sy      vertical skew factor
149      * @param kx      pivot on x-axis
150      * @param ky      pivot on y-axis
151      */
152     void PreSkew(scalar kx, scalar ky, scalar px, scalar py);
153 
154     /**
155      * @brief         Sets Matrix to Matrix constructed from skewing by (kx, ky)
156      *                about pivot point(px,py), multiplied by Matrix.
157      * @param sx      horizontal skew factor
158      * @param sy      vertical skew factor
159      * @param kx      pivot on x-axis
160      * @param ky      pivot on y-axis
161      */
162     void PostSkew(scalar kx, scalar ky, scalar px, scalar py);
163 
164     /**
165      * @brief         Sets Matrix to Matrix other multiplied by Matrix.
166      * @param other   Matrix on left side of multiply expression.
167      */
168     void PreConcat(const Matrix& other);
169 
170     /**
171      * @brief            Sets Matrix to Matrix other multiplied by Matrix44.
172      * @param matrix44   Matrix on left side of multiply expression.
173      */
174     void PreConcat(const Matrix44& matrix44);
175 
176     /**
177      * @brief         Sets Matrix to Matrix other multiplied by Matrix.
178      * @param other   Matrix on right side of multiply expression.
179      */
180     void PostConcat(const Matrix& other);
181 
182     /**
183      * @brief         Sets Matrix to Matrix other multiplied by Matrix44.
184      * @param other   Matrix on right side of multiply expression.
185      */
186     void PostConcat(const Matrix44& matrix44);
187 
188     /**
189      * @brief           Sets inverse to the inverse of Matrix.
190      * @param inverse   To store to inverse Matrix, may be nullptr.
191      * @return          Return true if Matrix can be inverted, otherwise return false.
192      */
193     bool Invert(Matrix& inverse) const;
194     Matrix operator*(const Matrix& other);
195 
196     /**
197      * @brief         Compares Matrix and other.
198      * @param other   To compare Matrix.
199      * @return        True if Matrix and other are numerically equal.
200      */
201     bool operator==(const Matrix& other) const;
202     void SetMatrix(scalar scaleX, scalar skewX, scalar transX, scalar skewY, scalar scaleY, scalar transY,
203         scalar persp0, scalar persp1, scalar persp2);
204 
205     /**
206      * @brief Sets matrix to scale and translate src rect to dst rect.
207      *
208      * @param src Rect to map from
209      * @param dst Rect to map to
210      * @param stf Describes how matrix is constructed to map one rect to another
211      * @return Returns true if dst is empty, and sets matrix to:
212                | 0 0 0 |
213                | 0 0 0 |
214                | 0 0 1 |.
215      */
216     bool SetRectToRect(const Rect& src, const Rect& dst, ScaleToFit stf);
217 
218     void MapPoints(std::vector<Point>& dst, const std::vector<Point>& src, uint32_t count) const;
219 
220     /**
221      * @brief       Sets dst to bounds of src corners mapped by Matrix.
222      * @param dst   Storage for bounds of map.
223      * @param src   To map.
224      * @return      True if dst is equivalent to mapped src.
225      */
226     bool MapRect(Rect& dst, const Rect& src) const;
227 
228     /**
229      * @brief       Sets Matrix to map src to dst. count must be zero or greater, and four or less.
230      * @param src   Point to map from
231      * @param dst   Point to map to
232      * @param count Number of Point in src and dst
233      * @return      True if Matrix was constructed successfully
234      */
235     bool SetPolyToPoly(const Point src[], const Point dst[], uint32_t count);
236 
237     /**
238      * @brief         Sets Matrix value.
239      * @param index   One of Index.
240      * @param value   Scalar to store in Matrix.
241      */
242     void Set(Index index, scalar value);
243     scalar Get(int index) const;
244 
245     /**
246      * @brief         Copies nine scalar values contained by Matrix into buffer.
247      * @param buffer  Storage for nine scalar values
248      */
249     void GetAll(Buffer& buffer) const;
250 
251     /**
252      * @brief         Copies nine scalar values contained by Matrix from buffer.
253      * @param buffer  Storage for nine scalar values
254      */
255     void SetAll(Buffer& buffer);
256 
257     template<typename T>
GetImpl()258     T* GetImpl() const
259     {
260         return matrixImplPtr->DowncastingTo<T>();
261     }
262 
263     /**
264      * @brief Returns true if matrix is Identity. Identity matrix is:
265      *    | 1 0 0 |
266      *    | 0 1 0 |
267      *    | 0 0 1 |
268      * @return true if is identity
269      */
270     bool IsIdentity() const;
271 
272     void PreRotate(scalar degree, scalar px, scalar py);
273     void PreScale(scalar sx, scalar sy, scalar px, scalar py);
274     void Reset();
275 
276     bool GetMinMaxScales(scalar scaleFactors[2]);
277     bool HasPerspective() const;
278 
279     void Swap(Matrix& target);
280 
281 private:
282     std::shared_ptr<MatrixImpl> matrixImplPtr;
283 };
284 } // namespace Drawing
285 } // namespace Rosen
286 } // namespace OHOS
287 #endif
288