1 /*
2  * Copyright (c) 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 "bridge/cj_frontend/interfaces/cj_ffi/matrix4/cj_matrix4_ffi.h"
17 
18 #include "base/utils/utils.h"
19 #include "bridge/common/utils/engine_helper.h"
20 
21 namespace OHOS::Matrix4 {
22 
NativeMatrix()23 NativeMatrix::NativeMatrix() : FFIData()
24 {
25     LOGI("Native NativeMatrix constructed");
26 }
27 } // namespace OHOS::Matrix4
28 
29 using namespace OHOS::Ace;
30 using namespace OHOS::FFI;
31 using namespace OHOS::Matrix4;
32 using namespace OHOS::Ace::Framework;
33 
34 extern "C" {
FfiOHOSMatrix4Init(VectorFloat32Ptr array)35 int64_t FfiOHOSMatrix4Init(VectorFloat32Ptr array)
36 {
37     auto nativeMatrix = FFIData::Create<NativeMatrix>();
38     if (nativeMatrix == nullptr) {
39         return FFI_ERROR_CODE;
40     }
41     Matrix4 matrix = Matrix4::CreateIdentity();
42 
43     const auto& vector = *reinterpret_cast<std::vector<float>*>(array);
44     if (vector.size() != Matrix4::DIMENSION * Matrix4::DIMENSION) {
45         LOGE("FfiOHOSMatrix4Init: invalid size of matrix4 array");
46         nativeMatrix->SetMatrix4(std::move(matrix));
47         return nativeMatrix->GetID();
48     }
49     for (int32_t i = 0; i < Matrix4::DIMENSION; i++) {
50         for (int32_t j = 0; j < Matrix4::DIMENSION; j++) {
51             auto index = i * Matrix4::DIMENSION + j;
52             if (index < vector.size()) {
53                 matrix.Set(j, i, vector[index]);
54             }
55         }
56     }
57 
58     nativeMatrix->SetMatrix4(std::move(matrix));
59     return nativeMatrix->GetID();
60 }
61 
FfiOHOSMatrix4Identity()62 int64_t FfiOHOSMatrix4Identity()
63 {
64     auto nativeMatrix = FFIData::Create<NativeMatrix>();
65     if (nativeMatrix == nullptr) {
66         return FFI_ERROR_CODE;
67     }
68     nativeMatrix->SetMatrix4(Matrix4::CreateIdentity());
69     return nativeMatrix->GetID();
70 }
71 
FfiOHOSMatrix4Copy(int64_t id)72 int64_t FfiOHOSMatrix4Copy(int64_t id)
73 {
74     auto nativeMatrix = FFIData::GetData<NativeMatrix>(id);
75     if (nativeMatrix == nullptr) {
76         return FFI_ERROR_CODE;
77     }
78     if (nativeMatrix != nullptr) {
79         auto copyMatrix = nativeMatrix->GetMatrix4();
80         auto result = FFIData::Create<NativeMatrix>();
81         result->SetMatrix4(std::move(copyMatrix));
82         return result->GetID();
83     } else {
84         LOGE("FfiOHOSMatrix4Copy: invalid id of Matrix");
85         return ERR_INVALID_INSTANCE_CODE;
86     }
87 }
88 
FfiOHOSMatrix4Invert(int64_t id)89 void FfiOHOSMatrix4Invert(int64_t id)
90 {
91     auto nativeMatrix = FFIData::GetData<NativeMatrix>(id);
92     if (nativeMatrix == nullptr) {
93         return;
94     }
95     if (nativeMatrix != nullptr) {
96         auto invertMatrix = Matrix4::Invert(nativeMatrix->GetMatrix4());
97         nativeMatrix->SetMatrix4(std::move(invertMatrix));
98     } else {
99         LOGE("FfiOHOSMatrix4Invert: invalid id of Matrix");
100     }
101 }
102 
FfiOHOSMatrix4Combine(int64_t origin,int64_t target)103 void FfiOHOSMatrix4Combine(int64_t origin, int64_t target)
104 {
105     auto nativeMatrixOrigin = FFIData::GetData<NativeMatrix>(origin);
106     auto nativeMatrixTarget = FFIData::GetData<NativeMatrix>(target);
107     if (nativeMatrixOrigin == nullptr) {
108         LOGE("FfiOHOSMatrix4Combine: invalid id of MatrixResult");
109         return;
110     }
111     if (nativeMatrixTarget == nullptr) {
112         LOGE("FfiOHOSMatrix4Combine: invalid id of MatrixTarge");
113         return;
114     }
115     Matrix4 originMatrix4 = nativeMatrixOrigin->GetMatrix4();
116     auto result = originMatrix4 * nativeMatrixTarget->GetMatrix4();
117     nativeMatrixOrigin->SetMatrix4(std::move(result));
118 }
119 
FfiOHOSMatrix4Translate(int64_t id,float x,float y,float z)120 void FfiOHOSMatrix4Translate(int64_t id, float x, float y, float z)
121 {
122     auto nativeMatrix = FFIData::GetData<NativeMatrix>(id);
123     if (nativeMatrix != nullptr) {
124         auto result = Matrix4::CreateTranslate(x, y, z) * nativeMatrix->GetMatrix4();
125         nativeMatrix->SetMatrix4(std::move(result));
126     } else {
127         LOGE("FfiOHOSMatrix4Translate: invalid id of Matrix4");
128     }
129 }
130 
FfiOHOSMatrix4Scale(int64_t id,FfiScaleParams params)131 void FfiOHOSMatrix4Scale(int64_t id, FfiScaleParams params)
132 {
133     auto nativeMatrix = FFIData::GetData<NativeMatrix>(id);
134     if (nativeMatrix != nullptr) {
135         auto scaleMatrix = Matrix4::CreateScale(params.x, params.y, params.z);
136         if (!NearZero(params.centerX) || !NearZero(params.centerY)) {
137             auto translate1 = Matrix4::CreateTranslate(params.centerX, params.centerY, 0.0);
138             auto translate2 = Matrix4::CreateTranslate(-params.centerX, -params.centerY, 0.0);
139             scaleMatrix = scaleMatrix * translate2;
140             scaleMatrix = translate1 * scaleMatrix;
141         }
142         auto result = scaleMatrix * nativeMatrix->GetMatrix4();
143         nativeMatrix->SetMatrix4(std::move(result));
144     } else {
145         LOGE("FfiOHOSMatrix4Scale: invalid id of Matrix4");
146     }
147 }
148 
FfiOHOSMatrix4Rotate(int64_t id,FfiRotateParams params)149 void FfiOHOSMatrix4Rotate(int64_t id, FfiRotateParams params)
150 {
151     auto nativeMatrix = FFIData::GetData<NativeMatrix>(id);
152     if (nativeMatrix != nullptr) {
153         auto rotateMatrix = Matrix4::CreateRotate(params.angle, params.x, params.y, params.z);
154         if (!NearZero(params.centerX) || !NearZero(params.centerY)) {
155             auto translate1 = Matrix4::CreateTranslate(params.centerX, params.centerY, 0.0);
156             auto translate2 = Matrix4::CreateTranslate(-params.centerX, -params.centerY, 0.0);
157             rotateMatrix = rotateMatrix * translate2;
158             rotateMatrix = translate1 * rotateMatrix;
159         }
160         auto result = rotateMatrix * nativeMatrix->GetMatrix4();
161         nativeMatrix->SetMatrix4(std::move(result));
162     } else {
163         LOGE("FfiOHOSMatrix4Scale: invalid id of Matrix4");
164     }
165 }
166 
FfiOHOSMatrix4TransformPoint(int64_t id,FfiPoint ffiPoint)167 FfiPoint FfiOHOSMatrix4TransformPoint(int64_t id, FfiPoint ffiPoint)
168 {
169     FfiPoint result = { 0.0, 0.0 };
170     auto nativeMatrix = FFIData::GetData<NativeMatrix>(id);
171     if (nativeMatrix != nullptr) {
172         auto matrix = nativeMatrix->GetMatrix4();
173         Point point { ffiPoint.x, ffiPoint.y };
174         Point target = matrix * point;
175         result.x = target.GetX();
176         result.y = target.GetY();
177         return result;
178     } else {
179         LOGE("FfiOHOSMatrix4TransformPoint: invalid id of Matrix4");
180         return result;
181     }
182 }
183 }
184