• 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 #include "cj_matrix.h"
17 #include "cj_drawing_log.h"
18 #include "utils/point.h"
19 
20 static constexpr uint32_t POLY_POINT_COUNT_MAX = 4;
21 
22 namespace OHOS {
23 namespace CJDrawing {
24 using namespace Rosen::Drawing;
25 
CreateCjMatrix(int64_t id)26 int64_t CjMatrix::CreateCjMatrix(int64_t id)
27 {
28     std::shared_ptr<Matrix> matrix = nullptr;
29     if (id == 0) {
30         matrix = std::make_shared<Matrix>();
31     } else {
32         auto cjMatrix = FFIData::GetData<CjMatrix>(id);
33         if (cjMatrix == nullptr || cjMatrix->GetMatrix() == nullptr) {
34             matrix = std::make_shared<Matrix>();
35         } else {
36             matrix = std::make_shared<Matrix>(*(cjMatrix->GetMatrix()));
37         }
38     }
39     if (matrix == nullptr) {
40         ROSEN_LOGE("CjMatrix::CreateCjMatrix get matrix failed");
41         return 0;
42     }
43     auto instance = FFIData::Create<CjMatrix>(matrix);
44     if (instance == nullptr) {
45         ROSEN_LOGE("CjMatrix::CreateCjMatrix create FFIData failed");
46         return 0;
47     }
48     return instance->GetID();
49 }
50 
SetRotation(scalar degree,scalar px,scalar py)51 int32_t CjMatrix::SetRotation(scalar degree, scalar px, scalar py)
52 {
53     if (m_matrix == nullptr) {
54         ROSEN_LOGE("CjMatrix::SetRotation matrix is nullptr");
55         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
56     }
57     m_matrix->Rotate(degree, px, py);
58     return ParserErr(CjDrawingErrorCode::OK);
59 }
60 
SetScale(scalar sx,scalar sy,scalar px,scalar py)61 int32_t CjMatrix::SetScale(scalar sx, scalar sy, scalar px, scalar py)
62 {
63     if (m_matrix == nullptr) {
64         ROSEN_LOGE("CjMatrix::SetScale matrix is nullptr");
65         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
66     }
67     m_matrix->Scale(sx, sy, px, py);
68     return ParserErr(CjDrawingErrorCode::OK);
69 }
70 
SetTranslation(scalar dx,scalar dy)71 int32_t CjMatrix::SetTranslation(scalar dx, scalar dy)
72 {
73     if (m_matrix == nullptr) {
74         ROSEN_LOGE("CjMatrix::SetTranslation matrix is nullptr");
75         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
76     }
77     m_matrix->Translate(dx, dy);
78     return ParserErr(CjDrawingErrorCode::OK);
79 }
80 
SetSkew(scalar kx,scalar ky,scalar px,scalar py)81 int32_t CjMatrix::SetSkew(scalar kx, scalar ky, scalar px, scalar py)
82 {
83     if (m_matrix == nullptr) {
84         ROSEN_LOGE("CjMatrix::SetSkew matrix is nullptr");
85         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
86     }
87     m_matrix->SetSkew(kx, ky, px, py);
88     return ParserErr(CjDrawingErrorCode::OK);
89 }
90 
SetConcat(CjMatrix & matrix1,CjMatrix & matrix2)91 int32_t CjMatrix::SetConcat(CjMatrix& matrix1, CjMatrix& matrix2)
92 {
93     if (m_matrix == nullptr) {
94         ROSEN_LOGE("CjMatrix::SetConcat matrix is nullptr");
95         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
96     }
97     std::shared_ptr<Matrix> nativeMatrix1 = matrix1.GetMatrix();
98     std::shared_ptr<Matrix> nativeMatrix2 = matrix2.GetMatrix();
99     if (nativeMatrix1 == nullptr || nativeMatrix2 == nullptr) {
100         ROSEN_LOGE("CjMatrix::SetConcat param matrix is nullptr");
101         return ParserErr(CjDrawingErrorCode::OK);
102     }
103     m_matrix->SetConcat(*nativeMatrix1, *nativeMatrix2);
104     return ParserErr(CjDrawingErrorCode::OK);
105 }
106 
SetSinCos(scalar sinValue,scalar cosValue,scalar px,scalar py)107 int32_t CjMatrix::SetSinCos(scalar sinValue, scalar cosValue, scalar px, scalar py)
108 {
109     if (m_matrix == nullptr) {
110         ROSEN_LOGE("CjMatrix::SetSinCos matrix is nullptr");
111         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
112     }
113     m_matrix->SetSinCos(sinValue, cosValue, px, py);
114     return ParserErr(CjDrawingErrorCode::OK);
115 }
116 
SetMatrix(const CArrFloat & values)117 int32_t CjMatrix::SetMatrix(const CArrFloat& values)
118 {
119     if (m_matrix == nullptr) {
120         ROSEN_LOGE("CjMatrix::SetMatrix matrix is nullptr");
121         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
122     }
123     if (values.size != Matrix::MATRIX_SIZE) {
124         ROSEN_LOGE("CjMatrix::SetMatrix count of array is not nine");
125         return ParserErr(CjDrawingErrorCode::ERROR_PARAM_VERIFICATION_FAILED);
126     }
127     m_matrix->SetMatrix(values.head[ARGC_ZERO], values.head[ARGC_ONE], values.head[ARGC_TWO], values.head[ARGC_THREE],
128                         values.head[ARGC_FOUR], values.head[ARGC_FIVE], values.head[ARGC_SIX], values.head[ARGC_SEVEN],
129                         values.head[ARGC_EIGHT]);
130     return ParserErr(CjDrawingErrorCode::OK);
131 }
132 
SetMatrixByMatrix(CjMatrix & matrix)133 int32_t CjMatrix::SetMatrixByMatrix(CjMatrix& matrix)
134 {
135     if (m_matrix == nullptr) {
136         ROSEN_LOGE("CjMatrix::SetMatrixByMatrix matrix is nullptr");
137         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
138     }
139     auto nativeMatrix = matrix.GetMatrix();
140     if (nativeMatrix == nullptr) {
141         ROSEN_LOGE("CjMatrix::SetMatrixByMatrix param matrix is nullptr");
142         return ParserErr(CjDrawingErrorCode::OK);
143     }
144     *m_matrix = *nativeMatrix;
145     return ParserErr(CjDrawingErrorCode::OK);
146 }
147 
PostRotate(scalar degree,scalar px,scalar py)148 int32_t CjMatrix::PostRotate(scalar degree, scalar px, scalar py)
149 {
150     if (m_matrix == nullptr) {
151         ROSEN_LOGE("CjMatrix::PostRotate matrix is nullptr");
152         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
153     }
154     m_matrix->PostRotate(degree, px, py);
155     return ParserErr(CjDrawingErrorCode::OK);
156 }
157 
PostScale(scalar sx,scalar sy,scalar px,scalar py)158 int32_t CjMatrix::PostScale(scalar sx, scalar sy, scalar px, scalar py)
159 {
160     if (m_matrix == nullptr) {
161         ROSEN_LOGE("CjMatrix::PostScale matrix is nullptr");
162         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
163     }
164     m_matrix->PostScale(sx, sy, px, py);
165     return ParserErr(CjDrawingErrorCode::OK);
166 }
167 
PostTranslate(scalar dx,scalar dy)168 int32_t CjMatrix::PostTranslate(scalar dx, scalar dy)
169 {
170     if (m_matrix == nullptr) {
171         ROSEN_LOGE("CjMatrix::PostTranslate matrix is nullptr");
172         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
173     }
174     m_matrix->PostTranslate(dx, dy);
175     return ParserErr(CjDrawingErrorCode::OK);
176 }
177 
PostSkew(scalar kx,scalar ky,scalar px,scalar py)178 int32_t CjMatrix::PostSkew(scalar kx, scalar ky, scalar px, scalar py)
179 {
180     if (m_matrix == nullptr) {
181         ROSEN_LOGE("CjMatrix::PostSkew matrix is nullptr");
182         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
183     }
184     m_matrix->PostSkew(kx, ky, px, py);
185     return ParserErr(CjDrawingErrorCode::OK);
186 }
187 
PostConcat(CjMatrix & matrix)188 int32_t CjMatrix::PostConcat(CjMatrix& matrix)
189 {
190     if (m_matrix == nullptr) {
191         ROSEN_LOGE("CjMatrix::PostConcat matrix is nullptr");
192         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
193     }
194     if (matrix.GetMatrix() == nullptr) {
195         ROSEN_LOGE("CjMatrix::PostConcat param matrix is nullptr");
196         return ParserErr(CjDrawingErrorCode::OK);
197     }
198     m_matrix->PostConcat(*matrix.GetMatrix());
199     return ParserErr(CjDrawingErrorCode::OK);
200 }
201 
PreRotate(scalar degree,scalar px,scalar py)202 int32_t CjMatrix::PreRotate(scalar degree, scalar px, scalar py)
203 {
204     if (m_matrix == nullptr) {
205         ROSEN_LOGE("CjMatrix::PreRotate matrix is nullptr");
206         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
207     }
208     m_matrix->PreRotate(degree, px, py);
209     return ParserErr(CjDrawingErrorCode::OK);
210 }
211 
PreScale(scalar sx,scalar sy,scalar px,scalar py)212 int32_t CjMatrix::PreScale(scalar sx, scalar sy, scalar px, scalar py)
213 {
214     if (m_matrix == nullptr) {
215         ROSEN_LOGE("CjMatrix::PreScale matrix is nullptr");
216         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
217     }
218     m_matrix->PreScale(sx, sy, px, py);
219     return ParserErr(CjDrawingErrorCode::OK);
220 }
221 
PreTranslate(scalar dx,scalar dy)222 int32_t CjMatrix::PreTranslate(scalar dx, scalar dy)
223 {
224     if (m_matrix == nullptr) {
225         ROSEN_LOGE("CjMatrix::PreTranslate matrix is nullptr");
226         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
227     }
228     m_matrix->PreTranslate(dx, dy);
229     return ParserErr(CjDrawingErrorCode::OK);
230 }
231 
PreSkew(scalar kx,scalar ky,scalar px,scalar py)232 int32_t CjMatrix::PreSkew(scalar kx, scalar ky, scalar px, scalar py)
233 {
234     if (m_matrix == nullptr) {
235         ROSEN_LOGE("CjMatrix::PreSkew matrix is nullptr");
236         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
237     }
238     m_matrix->PreSkew(kx, ky, px, py);
239     return ParserErr(CjDrawingErrorCode::OK);
240 }
241 
PreConcat(CjMatrix & matrix)242 int32_t CjMatrix::PreConcat(CjMatrix& matrix)
243 {
244     if (m_matrix == nullptr) {
245         ROSEN_LOGE("CjMatrix::PreConcat matrix is nullptr");
246         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
247     }
248     if (matrix.GetMatrix() == nullptr) {
249         ROSEN_LOGE("CjMatrix::PreConcat param matrix is nullptr");
250         return ParserErr(CjDrawingErrorCode::OK);
251     }
252     m_matrix->PreConcat(*matrix.GetMatrix());
253     return ParserErr(CjDrawingErrorCode::OK);
254 }
255 
Invert(CjMatrix & matrix)256 RetDataBool CjMatrix::Invert(CjMatrix& matrix)
257 {
258     RetDataBool ret = {.code = ParserErr(CjDrawingErrorCode::OK), .data = false};
259     if (m_matrix == nullptr) {
260         ROSEN_LOGE("CjMatrix::Invert matrix is nullptr");
261         ret.code = ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
262         return ret;
263     }
264     if (matrix.GetMatrix() == nullptr) {
265         ROSEN_LOGE("CjMatrix::Invert param matrix is nullptr");
266         ret.code = ParserErr(CjDrawingErrorCode::ERROR_PARAM_VERIFICATION_FAILED);
267         return ret;
268     }
269     ret.data = m_matrix->Invert(*matrix.GetMatrix());
270     return ret;
271 }
272 
Reset()273 int32_t CjMatrix::Reset()
274 {
275     if (m_matrix == nullptr) {
276         ROSEN_LOGE("CjMatrix::Reset matrix is nullptr");
277         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
278     }
279     m_matrix->Reset();
280     return ParserErr(CjDrawingErrorCode::OK);
281 }
282 
IsEqual(CjMatrix & matrix)283 RetDataBool CjMatrix::IsEqual(CjMatrix& matrix)
284 {
285     RetDataBool ret = {.code = ParserErr(CjDrawingErrorCode::OK), .data = false};
286     if (m_matrix == nullptr) {
287         ROSEN_LOGE("CjMatrix::IsEqual matrix is nullptr");
288         ret.code = ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
289         return ret;
290     }
291     if (matrix.GetMatrix() == nullptr) {
292         ROSEN_LOGE("CjMatrix::IsEqual param matrix is nullptr");
293         return ret;
294     }
295     ret.data = ((*m_matrix) == (*matrix.GetMatrix()));
296     return ret;
297 }
298 
IsIdentity()299 RetDataBool CjMatrix::IsIdentity()
300 {
301     RetDataBool ret = {.code = ParserErr(CjDrawingErrorCode::OK), .data = false};
302     if (m_matrix == nullptr) {
303         ROSEN_LOGE("CjMatrix::IsIdentity matrix is nullptr");
304         ret.code = ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
305         return ret;
306     }
307     ret.data = m_matrix->IsIdentity();
308     return ret;
309 }
310 
IsAffine()311 RetDataBool CjMatrix::IsAffine()
312 {
313     RetDataBool ret = {.code = ParserErr(CjDrawingErrorCode::OK), .data = false};
314     if (m_matrix == nullptr) {
315         ROSEN_LOGE("CjMatrix::IsAffine matrix is nullptr");
316         ret.code = ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
317         return ret;
318     }
319     ret.data = m_matrix->IsAffine();
320     return ret;
321 }
322 
RectStaysRect()323 RetDataBool CjMatrix::RectStaysRect()
324 {
325     RetDataBool ret = {.code = ParserErr(CjDrawingErrorCode::OK), .data = false};
326     if (m_matrix == nullptr) {
327         ROSEN_LOGE("CjMatrix::RectStaysRect matrix is nullptr");
328         ret.code = ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
329         return ret;
330     }
331     ret.data = m_matrix->RectStaysRect();
332     return ret;
333 }
334 
GetValue(int64_t index)335 RetDataScalar CjMatrix::GetValue(int64_t index)
336 {
337     RetDataScalar ret = {.code = ParserErr(CjDrawingErrorCode::OK), .data = 0.0};
338     if (m_matrix == nullptr) {
339         ROSEN_LOGE("CjMatrix::GetValue matrix is nullptr");
340         ret.code = ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
341         return ret;
342     }
343     if (index < 0 || index >= Matrix::MATRIX_SIZE) {
344         ROSEN_LOGE("CjMatrix::GetValue index is out of range");
345         ret.code = ParserErr(CjDrawingErrorCode::ERROR_PARAM_VERIFICATION_FAILED);
346         return ret;
347     }
348     ret.data = m_matrix->Get(index);
349     return ret;
350 }
351 
GetAll(const CArrFloat & arr)352 int32_t CjMatrix::GetAll(const CArrFloat& arr)
353 {
354     if (m_matrix == nullptr) {
355         ROSEN_LOGE("CjMatrix::GetAll matrix is nullptr");
356         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
357     }
358     Matrix::Buffer matrData;
359     m_matrix->GetAll(matrData);
360     for (uint32_t i = 0; i < Matrix::MATRIX_SIZE; i++) {
361         arr.head[i] = matrData[i];
362     }
363     return ParserErr(CjDrawingErrorCode::OK);
364 }
365 
MapRadius(scalar radius)366 RetDataScalar CjMatrix::MapRadius(scalar radius)
367 {
368     RetDataScalar ret = {.code = ParserErr(CjDrawingErrorCode::OK), .data = 0.0};
369     if (m_matrix == nullptr) {
370         ROSEN_LOGE("CjMatrix::MapRadius matrix is nullptr");
371         ret.code = ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
372         return ret;
373     }
374     ret.data = m_matrix->MapRadius(radius);
375     return ret;
376 }
377 
MapPoints(const CArrPoint & src,const CArrPoint & dst)378 int32_t CjMatrix::MapPoints(const CArrPoint& src, const CArrPoint& dst)
379 {
380     if (m_matrix == nullptr) {
381         ROSEN_LOGE("CjMatrix::MapPoints matrix is nullptr");
382         return ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
383     }
384     std::vector<Point> dstPoints(src.size);
385     std::vector<Point> srcPoints(src.size);
386     ConvertToPointsArray(src, srcPoints.data(), src.size);
387     m_matrix->MapPoints(dstPoints, srcPoints, src.size);
388     WriteToCjPointsArray(dstPoints.data(), dst, src.size);
389     return ParserErr(CjDrawingErrorCode::OK);
390 }
391 
MapRect(CRect & dst,const CRect & src)392 RetDataBool CjMatrix::MapRect(CRect& dst, const CRect& src)
393 {
394     RetDataBool ret = {.code = ParserErr(CjDrawingErrorCode::OK), .data = false};
395     if (m_matrix == nullptr) {
396         ROSEN_LOGE("CjMatrix::MapRect matrix is nullptr");
397         ret.code = ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
398         return ret;
399     }
400     Rect dstRect;
401     Rect srcRect = Rect(src.left, src.top, src.right, src.bottom);
402     ret.data = m_matrix->MapRect(dstRect, srcRect);
403     dst.left = dstRect.GetLeft();
404     dst.top = dstRect.GetTop();
405     dst.right = dstRect.GetRight();
406     dst.bottom = dstRect.GetBottom();
407     return ret;
408 }
409 
SetRectToRect(const CRect & src,const CRect & dst,int32_t scaleToFit)410 RetDataBool CjMatrix::SetRectToRect(const CRect& src, const CRect& dst, int32_t scaleToFit)
411 {
412     RetDataBool ret = {.code = ParserErr(CjDrawingErrorCode::OK), .data = false};
413     if (m_matrix == nullptr) {
414         ROSEN_LOGE("CjMatrix::SetRectToRect matrix is nullptr");
415         ret.code = ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
416         return ret;
417     }
418     Rect srcRect = Rect(src.left, src.top, src.right, src.bottom);
419     Rect dstRect = Rect(dst.left, dst.top, dst.right, dst.bottom);
420     ret.data = m_matrix->SetRectToRect(srcRect, dstRect, static_cast<ScaleToFit>(scaleToFit));
421     return ret;
422 }
423 
SetPolyToPoly(const CArrPoint & src,const CArrPoint & dst,int64_t count)424 RetDataBool CjMatrix::SetPolyToPoly(const CArrPoint& src, const CArrPoint& dst, int64_t count)
425 {
426     RetDataBool ret = {.code = ParserErr(CjDrawingErrorCode::OK), .data = false};
427     if (m_matrix == nullptr) {
428         ROSEN_LOGE("CjMatrix::SetPolyToPoly matrix is nullptr");
429         ret.code = ParserErr(CjDrawingErrorCode::INTERNAL_ERROR);
430         return ret;
431     }
432     if (count > POLY_POINT_COUNT_MAX || count < 0) {
433         ROSEN_LOGE("CjMatrix::SetPolyToPoly invalid param");
434         ret.code = ParserErr(CjDrawingErrorCode::ERROR_PARAM_VERIFICATION_FAILED);
435         return ret;
436     }
437     Point srcPoints[POLY_POINT_COUNT_MAX];
438     Point dstPoints[POLY_POINT_COUNT_MAX];
439     ConvertToPointsArray(src, srcPoints, count);
440     ConvertToPointsArray(dst, dstPoints, count);
441     ret.data = m_matrix->SetPolyToPoly(srcPoints, dstPoints, count);
442     return ret;
443 }
444 
~CjMatrix()445 CjMatrix::~CjMatrix()
446 {
447     m_matrix = nullptr;
448 }
449 
GetMatrix()450 std::shared_ptr<Matrix> CjMatrix::GetMatrix()
451 {
452     return m_matrix;
453 }
454 }
455 }
456