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