1 /*
2 * Copyright (c) 2021-2023 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/declarative_frontend/jsview/js_matrix2d.h"
17 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
18 #include "core/components/common/properties/paint_state.h"
19 #include "frameworks/core/components_ng/render/adapter/matrix2d.h"
20
21 namespace OHOS::Ace::Framework {
22 constexpr int JS_MATRIX2D_PARAMETER_COUNTS_0 = 0;
23 constexpr int JS_MATRIX2D_PARAMETER_COUNTS_1 = 1;
24 constexpr int JS_MATRIX2D_PARAMETER_COUNTS_2 = 2;
25 constexpr int JS_MATRIX2D_PARAMETER_COUNTS_3 = 3;
26
Constructor(const JSCallbackInfo & info)27 void JSMatrix2d::Constructor(const JSCallbackInfo& info)
28 {
29 auto matrix2d = Referenced::MakeRefPtr<JSMatrix2d>();
30 matrix2d->IncRefCount();
31 info.SetReturnValue(Referenced::RawPtr(matrix2d));
32 }
33
Destructor(JSMatrix2d * matrix2d)34 void JSMatrix2d::Destructor(JSMatrix2d* matrix2d)
35 {
36 if (matrix2d != nullptr) {
37 matrix2d->DecRefCount();
38 }
39 }
40
GetTransformInfo(const JSRef<JSObject> & obj)41 TransformParam JSMatrix2d::GetTransformInfo(const JSRef<JSObject>& obj)
42 {
43 auto scaleXVal = obj->GetProperty("scaleX");
44 auto rotateXVal = obj->GetProperty("rotateX");
45 auto rotateYVal = obj->GetProperty("rotateY");
46 auto scaleYVal = obj->GetProperty("scaleY");
47 auto translateXVal = obj->GetProperty("translateX");
48 auto translateYVal = obj->GetProperty("translateY");
49
50 TransformParam param = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
51 JSViewAbstract::ParseJsDouble(scaleXVal, param.scaleX);
52 JSViewAbstract::ParseJsDouble(rotateXVal, param.skewX);
53 JSViewAbstract::ParseJsDouble(rotateYVal, param.skewY);
54 JSViewAbstract::ParseJsDouble(scaleYVal, param.scaleY);
55 JSViewAbstract::ParseJsDouble(translateXVal, param.translateX);
56 JSViewAbstract::ParseJsDouble(translateYVal, param.translateY);
57 param.translateX = PipelineBase::Vp2PxWithCurrentDensity(param.translateX);
58 param.translateY = PipelineBase::Vp2PxWithCurrentDensity(param.translateY);
59
60 return param;
61 }
62
JSBind(BindingTarget globalObj)63 void JSMatrix2d::JSBind(BindingTarget globalObj)
64 {
65 JSClass<JSMatrix2d>::Declare("Matrix2D");
66 JSClass<JSMatrix2d>::CustomProperty("scaleX", &JSMatrix2d::JsGetScaleX, &JSMatrix2d::JsSetScaleX);
67 JSClass<JSMatrix2d>::CustomProperty("rotateY", &JSMatrix2d::JsGetRotateY, &JSMatrix2d::JsSetRotateY);
68 JSClass<JSMatrix2d>::CustomProperty("rotateX", &JSMatrix2d::JsGetRotateX, &JSMatrix2d::JsSetRotateX);
69 JSClass<JSMatrix2d>::CustomProperty("scaleY", &JSMatrix2d::JsGetScaleY, &JSMatrix2d::JsSetScaleY);
70 JSClass<JSMatrix2d>::CustomProperty("translateX", &JSMatrix2d::JsGetTranslateX, &JSMatrix2d::JsSetTranslateX);
71 JSClass<JSMatrix2d>::CustomProperty("translateY", &JSMatrix2d::JsGetTranslateY, &JSMatrix2d::JsSetTranslateY);
72 JSClass<JSMatrix2d>::CustomMethod("identity", &JSMatrix2d::JsIdentity);
73 JSClass<JSMatrix2d>::CustomMethod("invert", &JSMatrix2d::JsInvert);
74 JSClass<JSMatrix2d>::CustomMethod("rotate", &JSMatrix2d::JsRotate);
75 JSClass<JSMatrix2d>::CustomMethod("translate", &JSMatrix2d::JsTranslate);
76 JSClass<JSMatrix2d>::CustomMethod("scale", &JSMatrix2d::JsScale);
77 JSClass<JSMatrix2d>::CustomMethod("multiply", &JSMatrix2d::JSMultiply);
78
79 JSClass<JSMatrix2d>::Bind(globalObj, JSMatrix2d::Constructor, JSMatrix2d::Destructor);
80 }
81
JsSetScaleX(const JSCallbackInfo & info)82 void JSMatrix2d::JsSetScaleX(const JSCallbackInfo& info)
83 {
84 if (info.Length() != JS_MATRIX2D_PARAMETER_COUNTS_1) {
85 return;
86 }
87 if (info[JS_MATRIX2D_PARAMETER_COUNTS_0]->IsNumber()) {
88 double scaleX = 0;
89 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_0], scaleX);
90 transform_.scaleX = scaleX;
91 }
92 }
93
JsSetRotateY(const JSCallbackInfo & info)94 void JSMatrix2d::JsSetRotateY(const JSCallbackInfo& info)
95 {
96 if (info.Length() != JS_MATRIX2D_PARAMETER_COUNTS_1) {
97 return;
98 }
99 if (info[JS_MATRIX2D_PARAMETER_COUNTS_0]->IsNumber()) {
100 double rotateY = 0;
101 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_0], rotateY);
102 transform_.skewY = rotateY;
103 }
104 }
105
JsSetRotateX(const JSCallbackInfo & info)106 void JSMatrix2d::JsSetRotateX(const JSCallbackInfo& info)
107 {
108 if (info.Length() != JS_MATRIX2D_PARAMETER_COUNTS_1) {
109 return;
110 }
111 if (info[JS_MATRIX2D_PARAMETER_COUNTS_0]->IsNumber()) {
112 double rotateX = 0;
113 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_0], rotateX);
114 transform_.skewX = rotateX;
115 }
116 }
117
JsSetScaleY(const JSCallbackInfo & info)118 void JSMatrix2d::JsSetScaleY(const JSCallbackInfo& info)
119 {
120 if (info.Length() != JS_MATRIX2D_PARAMETER_COUNTS_1) {
121 return;
122 }
123 if (info[JS_MATRIX2D_PARAMETER_COUNTS_0]->IsNumber()) {
124 double scaleY = 0;
125 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_0], scaleY);
126 transform_.scaleY = scaleY;
127 }
128 }
129
JsSetTranslateX(const JSCallbackInfo & info)130 void JSMatrix2d::JsSetTranslateX(const JSCallbackInfo& info)
131 {
132 if (info.Length() != JS_MATRIX2D_PARAMETER_COUNTS_1) {
133 return;
134 }
135 if (info[JS_MATRIX2D_PARAMETER_COUNTS_0]->IsNumber()) {
136 double translateX = 0;
137 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_0], translateX);
138 translateX = PipelineBase::Vp2PxWithCurrentDensity(translateX);
139 transform_.translateX = translateX;
140 }
141 }
142
JsSetTranslateY(const JSCallbackInfo & info)143 void JSMatrix2d::JsSetTranslateY(const JSCallbackInfo& info)
144 {
145 if (info.Length() != JS_MATRIX2D_PARAMETER_COUNTS_1) {
146 return;
147 }
148 if (info[JS_MATRIX2D_PARAMETER_COUNTS_0]->IsNumber()) {
149 double translateY = 0;
150 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_0], translateY);
151 translateY = PipelineBase::Vp2PxWithCurrentDensity(translateY);
152 transform_.translateY = translateY;
153 }
154 }
155
JsGetScaleX(const JSCallbackInfo & info)156 void JSMatrix2d::JsGetScaleX(const JSCallbackInfo& info)
157 {
158 auto returnValue = JSVal(ToJSValue(transform_.scaleX));
159 auto returnPtr = JSRef<JSVal>::Make(returnValue);
160 info.SetReturnValue(returnPtr);
161 }
162
JsGetRotateY(const JSCallbackInfo & info)163 void JSMatrix2d::JsGetRotateY(const JSCallbackInfo& info)
164 {
165 auto returnValue = JSVal(ToJSValue(transform_.skewY));
166 auto returnPtr = JSRef<JSVal>::Make(returnValue);
167 info.SetReturnValue(returnPtr);
168 }
169
JsGetRotateX(const JSCallbackInfo & info)170 void JSMatrix2d::JsGetRotateX(const JSCallbackInfo& info)
171 {
172 auto returnValue = JSVal(ToJSValue(transform_.skewX));
173 auto returnPtr = JSRef<JSVal>::Make(returnValue);
174 info.SetReturnValue(returnPtr);
175 }
176
JsGetScaleY(const JSCallbackInfo & info)177 void JSMatrix2d::JsGetScaleY(const JSCallbackInfo& info)
178 {
179 auto returnValue = JSVal(ToJSValue(transform_.scaleY));
180 auto returnPtr = JSRef<JSVal>::Make(returnValue);
181 info.SetReturnValue(returnPtr);
182 }
183
JsGetTranslateX(const JSCallbackInfo & info)184 void JSMatrix2d::JsGetTranslateX(const JSCallbackInfo& info)
185 {
186 double translateX = PipelineBase::Px2VpWithCurrentDensity(transform_.translateX);
187 auto returnValue = JSVal(ToJSValue(translateX));
188 auto returnPtr = JSRef<JSVal>::Make(returnValue);
189 info.SetReturnValue(returnPtr);
190 }
191
JsGetTranslateY(const JSCallbackInfo & info)192 void JSMatrix2d::JsGetTranslateY(const JSCallbackInfo& info)
193 {
194 double translateY = PipelineBase::Px2VpWithCurrentDensity(transform_.translateY);
195 auto returnValue = JSVal(ToJSValue(translateY));
196 auto returnPtr = JSRef<JSVal>::Make(returnValue);
197 info.SetReturnValue(returnPtr);
198 }
199
JsIdentity(const JSCallbackInfo & info)200 void JSMatrix2d::JsIdentity(const JSCallbackInfo& info)
201 {
202 if (info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_0) {
203 return;
204 }
205 NG::Matrix2D::Identity(transform_);
206 info.SetReturnValue(info.This());
207 }
208
JsInvert(const JSCallbackInfo & info)209 void JSMatrix2d::JsInvert(const JSCallbackInfo& info)
210 {
211 if (info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_0) {
212 return;
213 }
214 bool retValue = NG::Matrix2D::Invert(transform_);
215 if (!retValue) {
216 transform_.scaleX = NAN;
217 transform_.scaleY = NAN;
218 transform_.skewX = NAN;
219 transform_.skewY = NAN;
220 transform_.translateX = NAN;
221 transform_.translateY = NAN;
222 }
223 info.SetReturnValue(info.This());
224 }
225
JsRotate(const JSCallbackInfo & info)226 void JSMatrix2d::JsRotate(const JSCallbackInfo& info)
227 {
228 if (info.Length() < JS_MATRIX2D_PARAMETER_COUNTS_1 || info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_3) {
229 return;
230 }
231 double degree = 0;
232 double rx = 0;
233 double ry = 0;
234 if (info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_0 && info[JS_MATRIX2D_PARAMETER_COUNTS_0]->IsNumber()) {
235 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_0], degree);
236 }
237 if (info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_1 && info[JS_MATRIX2D_PARAMETER_COUNTS_1]->IsNumber()) {
238 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_1], rx);
239 rx = PipelineBase::Vp2PxWithCurrentDensity(rx);
240 }
241 if (info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_2 && info[JS_MATRIX2D_PARAMETER_COUNTS_2]->IsNumber()) {
242 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_2], ry);
243 ry = PipelineBase::Vp2PxWithCurrentDensity(ry);
244 }
245 NG::Matrix2D::Rotate(transform_, degree, rx, ry);
246 info.SetReturnValue(info.This());
247 }
248
JsTranslate(const JSCallbackInfo & info)249 void JSMatrix2d::JsTranslate(const JSCallbackInfo& info)
250 {
251 if (info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_2) {
252 return;
253 }
254 double tx = 0;
255 double ty = 0;
256 if (info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_0 && info[JS_MATRIX2D_PARAMETER_COUNTS_0]->IsNumber()) {
257 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_0], tx);
258 tx = PipelineBase::Vp2PxWithCurrentDensity(tx);
259 }
260 if (info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_1 && info[JS_MATRIX2D_PARAMETER_COUNTS_1]->IsNumber()) {
261 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_1], ty);
262 ty = PipelineBase::Vp2PxWithCurrentDensity(ty);
263 }
264 NG::Matrix2D::Translate(transform_, tx, ty);
265 info.SetReturnValue(info.This());
266 }
267
JsScale(const JSCallbackInfo & info)268 void JSMatrix2d::JsScale(const JSCallbackInfo& info)
269 {
270 if (info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_2) {
271 return;
272 }
273 double sx = 1.0f;
274 double sy = 1.0f;
275 if (info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_0 && info[JS_MATRIX2D_PARAMETER_COUNTS_0]->IsNumber()) {
276 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_0], sx);
277 }
278 if (info.Length() > JS_MATRIX2D_PARAMETER_COUNTS_1 && info[JS_MATRIX2D_PARAMETER_COUNTS_1]->IsNumber()) {
279 JSViewAbstract::ParseJsDouble(info[JS_MATRIX2D_PARAMETER_COUNTS_1], sy);
280 }
281 NG::Matrix2D::Scale(transform_, sx, sy);
282 info.SetReturnValue(info.This());
283 }
284
ToString() const285 std::string JSMatrix2d::ToString() const
286 {
287 auto jsonValue = JsonUtil::Create(true);
288 jsonValue->Put("scaleX", transform_.scaleX);
289 jsonValue->Put("scaleY", transform_.scaleY);
290 jsonValue->Put("skewX", transform_.skewX);
291 jsonValue->Put("skewY", transform_.skewY);
292 jsonValue->Put("translateX", transform_.translateX);
293 jsonValue->Put("translateY", transform_.translateY);
294 return jsonValue->ToString();
295 }
296 } // namespace OHOS::Ace::Framework
297