1 /*
2 * Copyright (c) 2023-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 #include "drawing_matrix.h"
17
18 #include <vector>
19
20 #include "drawing_canvas_utils.h"
21
22 #include "utils/matrix.h"
23 #include "utils/rect.h"
24
25 static constexpr int POLY_POINT_COUNT_MAX = 4;
26 using namespace OHOS;
27 using namespace Rosen;
28 using namespace Drawing;
29
CastToMatrix(OH_Drawing_Matrix * cMatrix)30 static Matrix* CastToMatrix(OH_Drawing_Matrix* cMatrix)
31 {
32 return reinterpret_cast<Matrix*>(cMatrix);
33 }
34
CastToMatrix(const OH_Drawing_Matrix * cMatrix)35 static const Matrix* CastToMatrix(const OH_Drawing_Matrix* cMatrix)
36 {
37 return reinterpret_cast<const Matrix*>(cMatrix);
38 }
39
CastToPoint(OH_Drawing_Point2D * cPoint)40 static Point* CastToPoint(OH_Drawing_Point2D* cPoint)
41 {
42 return reinterpret_cast<Point*>(cPoint);
43 }
44
CastToPoint(const OH_Drawing_Point2D * cPoint)45 static const Point* CastToPoint(const OH_Drawing_Point2D* cPoint)
46 {
47 return reinterpret_cast<const Point*>(cPoint);
48 }
49
CastToRect(OH_Drawing_Rect & cRect)50 static Rect& CastToRect(OH_Drawing_Rect& cRect)
51 {
52 return reinterpret_cast<Rect&>(cRect);
53 }
54
CastToRect(const OH_Drawing_Rect & cRect)55 static const Rect& CastToRect(const OH_Drawing_Rect& cRect)
56 {
57 return reinterpret_cast<const Rect&>(cRect);
58 }
59
OH_Drawing_MatrixCreate()60 OH_Drawing_Matrix* OH_Drawing_MatrixCreate()
61 {
62 return (OH_Drawing_Matrix*)new Matrix();
63 }
64
OH_Drawing_MatrixCreateRotation(float deg,float x,float y)65 OH_Drawing_Matrix* OH_Drawing_MatrixCreateRotation(float deg, float x, float y)
66 {
67 Matrix* matrix = new Matrix();
68 matrix->Rotate(deg, x, y);
69 return (OH_Drawing_Matrix*)matrix;
70 }
71
OH_Drawing_MatrixCreateScale(float sx,float sy,float px,float py)72 OH_Drawing_Matrix* OH_Drawing_MatrixCreateScale(float sx, float sy, float px, float py)
73 {
74 Matrix* matrix = new Matrix();
75 matrix->Scale(sx, sy, px, py);
76 return (OH_Drawing_Matrix*)matrix;
77 }
78
OH_Drawing_MatrixCreateTranslation(float dx,float dy)79 OH_Drawing_Matrix* OH_Drawing_MatrixCreateTranslation(float dx, float dy)
80 {
81 Matrix* matrix = new Matrix();
82 matrix->Translate(dx, dy);
83 return (OH_Drawing_Matrix*)matrix;
84 }
85
OH_Drawing_MatrixSetMatrix(OH_Drawing_Matrix * cMatrix,float scaleX,float skewX,float transX,float skewY,float scaleY,float transY,float persp0,float persp1,float persp2)86 void OH_Drawing_MatrixSetMatrix(OH_Drawing_Matrix* cMatrix, float scaleX, float skewX, float transX,
87 float skewY, float scaleY, float transY, float persp0, float persp1, float persp2)
88 {
89 Matrix* matrix = CastToMatrix(cMatrix);
90 if (matrix == nullptr) {
91 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
92 return;
93 }
94 matrix->SetMatrix(scaleX, skewX, transX, skewY, scaleY, transY, persp0, persp1, persp2);
95 }
96
OH_Drawing_MatrixSetRectToRect(OH_Drawing_Matrix * cMatrix,const OH_Drawing_Rect * src,const OH_Drawing_Rect * dst,OH_Drawing_ScaleToFit stf)97 bool OH_Drawing_MatrixSetRectToRect(OH_Drawing_Matrix* cMatrix, const OH_Drawing_Rect* src,
98 const OH_Drawing_Rect* dst, OH_Drawing_ScaleToFit stf)
99 {
100 Matrix* matrix = CastToMatrix(cMatrix);
101 if (matrix == nullptr || src == nullptr || dst == nullptr) {
102 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
103 return false;
104 }
105 return matrix->SetRectToRect(CastToRect(*src), CastToRect(*dst), static_cast<ScaleToFit>(stf));
106 }
107
108
OH_Drawing_MatrixPreScale(OH_Drawing_Matrix * cMatrix,float sx,float sy,float px,float py)109 void OH_Drawing_MatrixPreScale(OH_Drawing_Matrix* cMatrix, float sx, float sy, float px, float py)
110 {
111 Matrix* matrix = CastToMatrix(cMatrix);
112 if (matrix == nullptr) {
113 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
114 return;
115 }
116 matrix->PreScale(sx, sy, px, py);
117 }
118
OH_Drawing_MatrixPreTranslate(OH_Drawing_Matrix * cMatrix,float dx,float dy)119 void OH_Drawing_MatrixPreTranslate(OH_Drawing_Matrix* cMatrix, float dx, float dy)
120 {
121 Matrix* matrix = CastToMatrix(cMatrix);
122 if (matrix == nullptr) {
123 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
124 return;
125 }
126 matrix->PreTranslate(dx, dy);
127 }
128
129
OH_Drawing_MatrixPreRotate(OH_Drawing_Matrix * cMatrix,float degree,float px,float py)130 void OH_Drawing_MatrixPreRotate(OH_Drawing_Matrix* cMatrix, float degree, float px, float py)
131 {
132 Matrix* matrix = CastToMatrix(cMatrix);
133 if (matrix == nullptr) {
134 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
135 return;
136 }
137 matrix->PreRotate(degree, px, py);
138 }
139
OH_Drawing_MatrixPostScale(OH_Drawing_Matrix * cMatrix,float sx,float sy,float px,float py)140 void OH_Drawing_MatrixPostScale(OH_Drawing_Matrix* cMatrix, float sx, float sy, float px, float py)
141 {
142 Matrix* matrix = CastToMatrix(cMatrix);
143 if (matrix == nullptr) {
144 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
145 return;
146 }
147 matrix->PostScale(sx, sy, px, py);
148 }
149
OH_Drawing_MatrixPostTranslate(OH_Drawing_Matrix * cMatrix,float dx,float dy)150 void OH_Drawing_MatrixPostTranslate(OH_Drawing_Matrix* cMatrix, float dx, float dy)
151 {
152 Matrix* matrix = CastToMatrix(cMatrix);
153 if (matrix == nullptr) {
154 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
155 return;
156 }
157 matrix->PostTranslate(dx, dy);
158 }
159
OH_Drawing_MatrixPostRotate(OH_Drawing_Matrix * cMatrix,float degree,float px,float py)160 void OH_Drawing_MatrixPostRotate(OH_Drawing_Matrix* cMatrix, float degree, float px, float py)
161 {
162 Matrix* matrix = CastToMatrix(cMatrix);
163 if (matrix == nullptr) {
164 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
165 return;
166 }
167 matrix->PostRotate(degree, px, py);
168 }
169
OH_Drawing_MatrixReset(OH_Drawing_Matrix * cMatrix)170 void OH_Drawing_MatrixReset(OH_Drawing_Matrix* cMatrix)
171 {
172 Matrix* matrix = CastToMatrix(cMatrix);
173 if (matrix == nullptr) {
174 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
175 return;
176 }
177 matrix->Reset();
178 }
179
OH_Drawing_MatrixConcat(OH_Drawing_Matrix * cTotal,const OH_Drawing_Matrix * cA,const OH_Drawing_Matrix * cB)180 void OH_Drawing_MatrixConcat(OH_Drawing_Matrix* cTotal, const OH_Drawing_Matrix* cA,
181 const OH_Drawing_Matrix* cB)
182 {
183 if (cTotal == nullptr || cA == nullptr || cB == nullptr) {
184 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
185 return;
186 }
187 Matrix* total = CastToMatrix(cTotal);
188 Matrix* a = CastToMatrix(const_cast<OH_Drawing_Matrix*>(cA));
189 Matrix* b = CastToMatrix(const_cast<OH_Drawing_Matrix*>(cB));
190 *total = *a;
191 total->PreConcat(*b);
192 }
193
OH_Drawing_MatrixGetValue(OH_Drawing_Matrix * cMatrix,int index)194 float OH_Drawing_MatrixGetValue(OH_Drawing_Matrix* cMatrix, int index)
195 {
196 if (cMatrix == nullptr) {
197 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
198 return 0;
199 }
200
201 // 3x3 matrix index is between 0-8
202 if (index < 0 || index > 8) {
203 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
204 return 0;
205 }
206 Matrix* matrix = CastToMatrix(cMatrix);
207 return matrix->Get(index);
208 }
209
OH_Drawing_MatrixRotate(OH_Drawing_Matrix * cMatrix,float degree,float px,float py)210 void OH_Drawing_MatrixRotate(OH_Drawing_Matrix* cMatrix, float degree, float px, float py)
211 {
212 Matrix* matrix = CastToMatrix(cMatrix);
213 if (matrix == nullptr) {
214 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
215 return;
216 }
217 matrix->Rotate(degree, px, py);
218 }
219
OH_Drawing_MatrixTranslate(OH_Drawing_Matrix * cMatrix,float dx,float dy)220 void OH_Drawing_MatrixTranslate(OH_Drawing_Matrix* cMatrix, float dx, float dy)
221 {
222 Matrix* matrix = CastToMatrix(cMatrix);
223 if (matrix == nullptr) {
224 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
225 return;
226 }
227 matrix->Translate(dx, dy);
228 }
229
OH_Drawing_MatrixScale(OH_Drawing_Matrix * cMatrix,float sx,float sy,float px,float py)230 void OH_Drawing_MatrixScale(OH_Drawing_Matrix* cMatrix, float sx, float sy, float px, float py)
231 {
232 Matrix* matrix = CastToMatrix(cMatrix);
233 if (matrix == nullptr) {
234 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
235 return;
236 }
237 matrix->Scale(sx, sy, px, py);
238 }
239
OH_Drawing_MatrixInvert(OH_Drawing_Matrix * cMatrix,OH_Drawing_Matrix * inverse)240 bool OH_Drawing_MatrixInvert(OH_Drawing_Matrix* cMatrix, OH_Drawing_Matrix* inverse)
241 {
242 Matrix* matrix = CastToMatrix(cMatrix);
243 if (matrix == nullptr) {
244 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
245 return false;
246 }
247 Matrix* inverseMatrix = CastToMatrix(inverse);
248 if (inverseMatrix == nullptr) {
249 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
250 return false;
251 }
252 return matrix->Invert(*inverseMatrix);
253 }
254
OH_Drawing_MatrixIsEqual(OH_Drawing_Matrix * cMatrix,OH_Drawing_Matrix * other)255 bool OH_Drawing_MatrixIsEqual(OH_Drawing_Matrix* cMatrix, OH_Drawing_Matrix* other)
256 {
257 Matrix* matrix = CastToMatrix(cMatrix);
258 if (matrix == nullptr) {
259 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
260 return false;
261 }
262 Matrix* otherMatrix = CastToMatrix(other);
263 if (otherMatrix == nullptr) {
264 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
265 return false;
266 }
267 return (*matrix == *otherMatrix);
268 }
269
OH_Drawing_MatrixSetPolyToPoly(OH_Drawing_Matrix * cMatrix,const OH_Drawing_Point2D * src,const OH_Drawing_Point2D * dst,uint32_t count)270 bool OH_Drawing_MatrixSetPolyToPoly(OH_Drawing_Matrix* cMatrix, const OH_Drawing_Point2D* src,
271 const OH_Drawing_Point2D* dst, uint32_t count)
272 {
273 Matrix* matrix = CastToMatrix(cMatrix);
274 if (matrix == nullptr) {
275 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
276 return false;
277 }
278 if (count > POLY_POINT_COUNT_MAX) {
279 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
280 return false;
281 }
282 return matrix->SetPolyToPoly(CastToPoint(src), CastToPoint(dst), count);
283 }
284
OH_Drawing_MatrixMapPoints(const OH_Drawing_Matrix * cMatrix,const OH_Drawing_Point2D * src,OH_Drawing_Point2D * dst,int count)285 void OH_Drawing_MatrixMapPoints(const OH_Drawing_Matrix* cMatrix, const OH_Drawing_Point2D* src,
286 OH_Drawing_Point2D* dst, int count)
287 {
288 if (src == nullptr || dst == nullptr || count <= 0) {
289 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
290 return;
291 }
292 const Matrix* matrix = CastToMatrix(cMatrix);
293 if (matrix == nullptr) {
294 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
295 return;
296 }
297 const Point* srcTemp = CastToPoint(src);
298 Point* dstTemp = CastToPoint(dst);
299 std::vector<Point> srcPoints(count);
300 std::vector<Point> dstPoints(count);
301 for (int idx = 0; idx < count; idx++) {
302 srcPoints[idx] = srcTemp[idx];
303 dstPoints[idx] = dstTemp[idx];
304 }
305 matrix->MapPoints(dstPoints, srcPoints, count);
306 for (int idx = 0; idx < count; idx++) {
307 dstTemp[idx] = dstPoints[idx];
308 }
309 }
310
OH_Drawing_MatrixMapRect(const OH_Drawing_Matrix * cMatrix,const OH_Drawing_Rect * src,OH_Drawing_Rect * dst)311 bool OH_Drawing_MatrixMapRect(const OH_Drawing_Matrix* cMatrix, const OH_Drawing_Rect* src, OH_Drawing_Rect* dst)
312 {
313 if (src == nullptr || dst == nullptr) {
314 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
315 return false;
316 }
317 const Matrix* matrix = CastToMatrix(cMatrix);
318 if (matrix == nullptr) {
319 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
320 return false;
321 }
322 return matrix->MapRect(CastToRect(*dst), CastToRect(*src));
323 }
324
OH_Drawing_MatrixIsIdentity(OH_Drawing_Matrix * cMatrix)325 bool OH_Drawing_MatrixIsIdentity(OH_Drawing_Matrix* cMatrix)
326 {
327 Matrix* matrix = CastToMatrix(cMatrix);
328 if (matrix == nullptr) {
329 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
330 return false;
331 }
332 return matrix->IsIdentity();
333 }
334
OH_Drawing_MatrixGetAll(OH_Drawing_Matrix * cMatrix,float value[9])335 OH_Drawing_ErrorCode OH_Drawing_MatrixGetAll(OH_Drawing_Matrix* cMatrix, float value[9])
336 {
337 Matrix* matrix = CastToMatrix(cMatrix);
338 if (matrix == nullptr || value == nullptr) {
339 return OH_DRAWING_ERROR_INVALID_PARAMETER;
340 }
341 std::array<float, 9> buffer; // 9:size of buffer
342 matrix->GetAll(buffer);
343 for (int i = 0; i < 9; ++i) { // 9:size of value
344 value[i] = buffer[i];
345 }
346 return OH_DRAWING_SUCCESS;
347 }
348
OH_Drawing_MatrixDestroy(OH_Drawing_Matrix * cMatrix)349 void OH_Drawing_MatrixDestroy(OH_Drawing_Matrix* cMatrix)
350 {
351 if (!cMatrix) {
352 return;
353 }
354 delete CastToMatrix(cMatrix);
355 }
356