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