1 /*
2 * Copyright (c) 2021 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 "frameworks/bridge/declarative_frontend/jsview/js_shape_abstract.h"
17
18 #include "base/utils/utils.h"
19 #include "bridge/declarative_frontend/jsview/models/shape_abstract_model_impl.h"
20 #include "core/common/container.h"
21 #include "core/common/resource/resource_parse_utils.h"
22 #include "core/components_ng/pattern/shape/shape_abstract_model.h"
23 #include "core/components_ng/pattern/shape/shape_abstract_model_ng.h"
24 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
25
26 namespace OHOS::Ace {
27
GetInstance()28 ShapeAbstractModel* ShapeAbstractModel::GetInstance()
29 {
30 #ifdef NG_BUILD
31 static NG::ShapeAbstractModelNG instance;
32 return &instance;
33 #else
34 if (Container::IsCurrentUseNewPipeline()) {
35 static NG::ShapeAbstractModelNG instance;
36 return &instance;
37 } else {
38 static Framework::ShapeAbstractModelImpl instance;
39 return &instance;
40 }
41 #endif
42 }
43 } // namespace OHOS::Ace
44
45 namespace OHOS::Ace::Framework {
46 namespace {
47 constexpr double DEFAULT_OPACITY = 1.0;
48 constexpr double MIN_OPACITY = 0.0;
49 constexpr double STROKE_MITERLIMIT_DEFAULT = 4.0f;
50 } // namespace
51
SetStrokeDashArray(const JSCallbackInfo & info)52 void JSShapeAbstract::SetStrokeDashArray(const JSCallbackInfo& info)
53 {
54 std::vector<Dimension> dashArray;
55 std::vector<RefPtr<ResourceObject>> resObjArray;
56 bool hasResObj = false;
57 UnRegisterResource("ShapeAbstractStrokeDashArray");
58 if (info.Length() < 1 || !info[0]->IsArray()) {
59 ShapeAbstractModel::GetInstance()->SetStrokeDashArray(dashArray);
60 return;
61 }
62 JSRef<JSArray> array = JSRef<JSArray>::Cast(info[0]);
63 auto length = static_cast<int32_t>(array->Length());
64 for (int32_t i = 0; i < length; i++) {
65 JSRef<JSVal> value = array->GetValueAt(i);
66 CalcDimension dim;
67 RefPtr<ResourceObject> resObj;
68 bool paramIsValid = false;
69 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
70 paramIsValid = ParseJsDimensionVp(value, dim, resObj);
71 } else {
72 paramIsValid = ParseJsDimensionVpNG(value, dim, resObj);
73 }
74 if (resObj) {
75 hasResObj = true;
76 }
77 if (paramIsValid) {
78 dashArray.emplace_back(dim);
79 resObjArray.emplace_back(resObj);
80 } else {
81 dashArray.clear();
82 resObjArray.clear();
83 break;
84 }
85 }
86 // if odd,add twice
87 if (static_cast<uint32_t>(length) == dashArray.size() && (static_cast<uint32_t>(length) & 1)) {
88 for (int32_t i = 0; i < length; i++) {
89 dashArray.emplace_back(dashArray[i]);
90 resObjArray.emplace_back(resObjArray[i]);
91 }
92 }
93 if (SystemProperties::ConfigChangePerform() && hasResObj) {
94 ShapeAbstractModel::GetInstance()->SetStrokeDashArray(dashArray, resObjArray);
95 }
96 ShapeAbstractModel::GetInstance()->SetStrokeDashArray(dashArray);
97 }
98
SetStroke(const JSCallbackInfo & info)99 void JSShapeAbstract::SetStroke(const JSCallbackInfo& info)
100 {
101 if (info.Length() < 1) {
102 return;
103 }
104 Color strokeColor;
105 RefPtr<ResourceObject> strokeResObj;
106 UnRegisterResource("ShapeAbstractStroke");
107 if (!ParseJsColor(info[0], strokeColor, strokeResObj)) {
108 ShapeAbstractModel::GetInstance()->SetStroke(Color::TRANSPARENT);
109 return;
110 }
111 if (SystemProperties::ConfigChangePerform() && strokeResObj) {
112 RegisterResource<Color>("ShapeAbstractStroke", strokeResObj, strokeColor);
113 }
114 ShapeAbstractModel::GetInstance()->SetStroke(strokeColor);
115 }
116
SetFill(const JSCallbackInfo & info)117 void JSShapeAbstract::SetFill(const JSCallbackInfo& info)
118 {
119 if (info.Length() < 1) {
120 return;
121 }
122 UnRegisterResource("ShapeAbstractFill");
123 if (info[0]->IsString() && info[0]->ToString() == "none") {
124 ShapeAbstractModel::GetInstance()->SetFill(Color::TRANSPARENT);
125 } else {
126 Color fillColor = Color::BLACK;
127 RefPtr<ResourceObject> fillResObj;
128 static const char shapeComponentName[] = "";
129 static const char attrsShapeAbstractFill[] = "fill";
130 CheckColor(info[0], fillColor, shapeComponentName, attrsShapeAbstractFill, fillResObj);
131 if (SystemProperties::ConfigChangePerform() && fillResObj) {
132 RegisterResource<Color>("ShapeAbstractFill", fillResObj, fillColor);
133 }
134 ShapeAbstractModel::GetInstance()->SetFill(fillColor);
135 }
136 }
137
SetStrokeDashOffset(const JSCallbackInfo & info)138 void JSShapeAbstract::SetStrokeDashOffset(const JSCallbackInfo& info)
139 {
140 if (info.Length() < 1) {
141 return;
142 }
143 CalcDimension offset(0.0f);
144 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
145 if (!ParseJsDimensionVp(info[0], offset)) {
146 return;
147 }
148 } else {
149 if (!ParseJsDimensionVpNG(info[0], offset)) {
150 // set to default value(0.0f)
151 offset.SetValue(0.0f);
152 }
153 }
154 ShapeAbstractModel::GetInstance()->SetStrokeDashOffset(offset);
155 }
156
SetStrokeLineCap(int lineCap)157 void JSShapeAbstract::SetStrokeLineCap(int lineCap)
158 {
159 ShapeAbstractModel::GetInstance()->SetStrokeLineCap(lineCap);
160 }
161
SetStrokeLineJoin(int lineJoin)162 void JSShapeAbstract::SetStrokeLineJoin(int lineJoin)
163 {
164 ShapeAbstractModel::GetInstance()->SetStrokeLineJoin(lineJoin);
165 }
166
SetStrokeMiterLimit(const JSCallbackInfo & info)167 void JSShapeAbstract::SetStrokeMiterLimit(const JSCallbackInfo& info)
168 {
169 if (info.Length() < 1) {
170 return;
171 }
172 double miterLimit = STROKE_MITERLIMIT_DEFAULT;
173 ParseJsDouble(info[0], miterLimit);
174 ShapeAbstractModel::GetInstance()->SetStrokeMiterLimit(miterLimit);
175 }
176
SetStrokeOpacity(const JSCallbackInfo & info)177 void JSShapeAbstract::SetStrokeOpacity(const JSCallbackInfo& info)
178 {
179 if (info.Length() < 1) {
180 return;
181 }
182 double strokeOpacity = DEFAULT_OPACITY;
183 RefPtr<ResourceObject> strokeOpacityResObj;
184 ParseJsDouble(info[0], strokeOpacity, strokeOpacityResObj);
185 UnRegisterResource("ShapeAbstractStrokeOpacity");
186 if (SystemProperties::ConfigChangePerform() && strokeOpacityResObj) {
187 RegisterResource<double>("ShapeAbstractStrokeOpacity", strokeOpacityResObj, strokeOpacity);
188 }
189 if (GreatOrEqual(strokeOpacity, 1.0)) {
190 strokeOpacity = DEFAULT_OPACITY;
191 }
192 if (LessOrEqual(strokeOpacity, 0.0)) {
193 strokeOpacity = MIN_OPACITY;
194 }
195 ShapeAbstractModel::GetInstance()->SetStrokeOpacity(strokeOpacity);
196 }
197
198 // https://svgwg.org/svg2-draft/painting.html#FillOpacity
SetFillOpacity(const JSCallbackInfo & info)199 void JSShapeAbstract::SetFillOpacity(const JSCallbackInfo& info)
200 {
201 if (info.Length() < 1) {
202 return;
203 }
204 double fillOpacity = DEFAULT_OPACITY;
205 RefPtr<ResourceObject> fillOpacityResObj;
206 ParseJsDouble(info[0], fillOpacity, fillOpacityResObj);
207 UnRegisterResource("ShapeAbstractFillOpacity");
208 if (SystemProperties::ConfigChangePerform() && fillOpacityResObj) {
209 RegisterResource<double>("ShapeAbstractFillOpacity", fillOpacityResObj, fillOpacity);
210 }
211 if (GreatOrEqual(fillOpacity, DEFAULT_OPACITY)) {
212 fillOpacity = DEFAULT_OPACITY;
213 }
214 if (LessOrEqual(fillOpacity, MIN_OPACITY)) {
215 fillOpacity = MIN_OPACITY;
216 }
217 ShapeAbstractModel::GetInstance()->SetFillOpacity(fillOpacity);
218 }
219
SetStrokeWidth(const JSCallbackInfo & info)220 void JSShapeAbstract::SetStrokeWidth(const JSCallbackInfo& info)
221 {
222 if (info.Length() < 1) {
223 return;
224 }
225 // the default value is 1.0_vp
226 CalcDimension lineWidth = 1.0_vp;
227 RefPtr<ResourceObject> strokeWidthResObj;
228 UnRegisterResource("ShapeAbstractStrokeWidth");
229 if (info[0]->IsString()) {
230 const std::string& value = info[0]->ToString();
231 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
232 lineWidth = StringUtils::StringToDimensionWithUnit(value, DimensionUnit::VP, 1.0);
233 } else {
234 if (!StringUtils::StringToDimensionWithUnitNG(value, lineWidth, DimensionUnit::VP, 1.0)) {
235 // unit is invalid, use default value(1.0vp) instead.
236 lineWidth = 1.0_vp;
237 }
238 }
239 } else {
240 ParseJsDimensionVp(info[0], lineWidth, strokeWidthResObj);
241 if (SystemProperties::ConfigChangePerform() && strokeWidthResObj) {
242 RegisterResource<CalcDimension>("ShapeAbstractStrokeWidth", strokeWidthResObj, lineWidth);
243 }
244 }
245 if (lineWidth.IsNegative()) {
246 lineWidth = 1.0_vp;
247 }
248 ShapeAbstractModel::GetInstance()->SetStrokeWidth(lineWidth);
249 }
250
SetAntiAlias(bool antiAlias)251 void JSShapeAbstract::SetAntiAlias(bool antiAlias)
252 {
253 ShapeAbstractModel::GetInstance()->SetAntiAlias(antiAlias);
254 }
255
JsWidth(const JSCallbackInfo & info)256 void JSShapeAbstract::JsWidth(const JSCallbackInfo& info)
257 {
258 if (info.Length() < 1) {
259 return;
260 }
261
262 SetWidth(info[0]);
263 }
264
SetWidth(const JSRef<JSVal> & jsValue)265 void JSShapeAbstract::SetWidth(const JSRef<JSVal>& jsValue)
266 {
267 CalcDimension value;
268 RefPtr<ResourceObject> widthResObj;
269 UnRegisterResource("ShapeAbstractWidth");
270 if (jsValue->IsUndefined()) {
271 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, true);
272 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
273 return;
274 }
275 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
276 if (!ParseJsDimensionVp(jsValue, value, widthResObj)) {
277 return;
278 }
279 } else {
280 if (!ParseJsDimensionVpNG(jsValue, value, widthResObj)) {
281 // JsWidth return, check if set LayoutPolicy before return.
282 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
283 if (jsValue->IsObject()) {
284 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsValue);
285 JSRef<JSVal> layoutPolicy = object->GetProperty("id_");
286 if (layoutPolicy->IsString()) {
287 auto policy = ParseLayoutPolicy(layoutPolicy->ToString());
288 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(policy, true);
289 return;
290 }
291 }
292 return;
293 }
294 }
295 if (SystemProperties::ConfigChangePerform() && widthResObj) {
296 RegisterResource<CalcDimension>("ShapeAbstractWidth", widthResObj, value);
297 }
298 if (LessNotEqual(value.Value(), 0.0)) {
299 value.SetValue(0.0);
300 }
301 ShapeAbstractModel::GetInstance()->SetWidth(value);
302 }
303
JsHeight(const JSCallbackInfo & info)304 void JSShapeAbstract::JsHeight(const JSCallbackInfo& info)
305 {
306 if (info.Length() < 1) {
307 return;
308 }
309
310 SetHeight(info[0]);
311 }
312
SetHeight(const JSRef<JSVal> & jsValue)313 void JSShapeAbstract::SetHeight(const JSRef<JSVal>& jsValue)
314 {
315 CalcDimension value;
316 RefPtr<ResourceObject> heightResObj;
317 UnRegisterResource("ShapeAbstractHeight");
318 if (jsValue->IsUndefined()) {
319 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, false);
320 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
321 return;
322 }
323 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
324 if (!ParseJsDimensionVp(jsValue, value, heightResObj)) {
325 return;
326 }
327 } else {
328 if (!ParseJsDimensionVpNG(jsValue, value, heightResObj)) {
329 // JsHeight return, check if set LayoutPolicy before return.
330 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
331 if (jsValue->IsObject()) {
332 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsValue);
333 JSRef<JSVal> layoutPolicy = object->GetProperty("id_");
334 if (layoutPolicy->IsString()) {
335 auto policy = ParseLayoutPolicy(layoutPolicy->ToString());
336 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(policy, false);
337 return;
338 }
339 }
340 return;
341 }
342 }
343 if (SystemProperties::ConfigChangePerform() && heightResObj) {
344 RegisterResource<CalcDimension>("ShapeAbstractHeight", heightResObj, value);
345 }
346
347 if (LessNotEqual(value.Value(), 0.0)) {
348 value.SetValue(0.0);
349 }
350 ShapeAbstractModel::GetInstance()->SetHeight(value);
351 }
352
JsSize(const JSCallbackInfo & info)353 void JSShapeAbstract::JsSize(const JSCallbackInfo& info)
354 {
355 if (info.Length() < 1) {
356 return;
357 }
358
359 if (!info[0]->IsObject()) {
360 return;
361 }
362
363 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
364 SetWidth(sizeObj->GetProperty("width"));
365 SetHeight(sizeObj->GetProperty("height"));
366 }
367
ObjectWidth(const JSCallbackInfo & info)368 void JSShapeAbstract::ObjectWidth(const JSCallbackInfo& info)
369 {
370 info.ReturnSelf();
371 if (info.Length() < 1) {
372 return;
373 }
374
375 ObjectWidth(info[0]);
376 }
377
ObjectWidth(const JSRef<JSVal> & jsValue)378 void JSShapeAbstract::ObjectWidth(const JSRef<JSVal>& jsValue)
379 {
380 CalcDimension value;
381 RefPtr<ResourceObject> widthResObj;
382 if (!ParseJsDimensionVp(jsValue, value, widthResObj)) {
383 return;
384 }
385 if (SystemProperties::ConfigChangePerform() && widthResObj) {
386 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, BasicShape& basicShape) {
387 CalcDimension shapeValue;
388 ResourceParseUtils::ParseResDimensionVp(resObj, shapeValue);
389 if (LessNotEqual(shapeValue.Value(), 0.0)) {
390 return;
391 }
392 basicShape.SetWidth(shapeValue);
393 };
394 basicShape_->AddResource("shapeAbstract.width", widthResObj, std::move(updateFunc));
395 }
396 if (LessNotEqual(value.Value(), 0.0)) {
397 return;
398 }
399 if (basicShape_) {
400 basicShape_->SetWidth(value);
401 }
402 }
403
ObjectHeight(const JSCallbackInfo & info)404 void JSShapeAbstract::ObjectHeight(const JSCallbackInfo& info)
405 {
406 info.ReturnSelf();
407 if (info.Length() < 1) {
408 return;
409 }
410
411 ObjectHeight(info[0]);
412 }
413
ObjectHeightUpdate(const RefPtr<ResourceObject> & heightResObj)414 void JSShapeAbstract::ObjectHeightUpdate(const RefPtr<ResourceObject>& heightResObj)
415 {
416 if (heightResObj) {
417 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, BasicShape& basicShape) {
418 CalcDimension shapeValue;
419 ResourceParseUtils::ParseResDimensionVp(resObj, shapeValue);
420 if (LessNotEqual(shapeValue.Value(), 0.0)) {
421 return;
422 }
423 basicShape.SetHeight(shapeValue);
424 };
425 basicShape_->AddResource("shapeAbstract.height", heightResObj, std::move(updateFunc));
426 }
427 }
428
ObjectHeight(const JSRef<JSVal> & jsValue)429 void JSShapeAbstract::ObjectHeight(const JSRef<JSVal>& jsValue)
430 {
431 CalcDimension value;
432 if (!SystemProperties::ConfigChangePerform()) {
433 if (!ParseJsDimensionVp(jsValue, value)) {
434 return;
435 }
436 } else {
437 RefPtr<ResourceObject> heightResObj;
438 if (!ParseJsDimensionVp(jsValue, value, heightResObj)) {
439 LOGE("fail to parse the Dimension!");
440 return;
441 }
442 ObjectHeightUpdate(heightResObj);
443 }
444 if (LessNotEqual(value.Value(), 0.0)) {
445 return;
446 }
447 if (basicShape_) {
448 basicShape_->SetHeight(value);
449 }
450 }
451
ObjectSize(const JSCallbackInfo & info)452 void JSShapeAbstract::ObjectSize(const JSCallbackInfo& info)
453 {
454 info.ReturnSelf();
455 if (info.Length() < 1) {
456 return;
457 }
458
459 if (!info[0]->IsObject()) {
460 return;
461 }
462
463 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
464 ObjectWidth(sizeObj->GetProperty("width"));
465 ObjectHeight(sizeObj->GetProperty("height"));
466 }
467
ObjectOffsetUpdate(const RefPtr<ResourceObject> & xResObj,RefPtr<ResourceObject> yResObj)468 void JSShapeAbstract::ObjectOffsetUpdate(const RefPtr<ResourceObject>& xResObj, RefPtr<ResourceObject> yResObj)
469 {
470 if (xResObj) {
471 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, BasicShape& basicShape) {
472 CalcDimension shapeValueX;
473 ResourceParseUtils::ParseResDimensionVp(resObj, shapeValueX);
474 CalcDimension shapeValueY = basicShape.GetOffset().GetY();
475 basicShape.SetOffset(DimensionOffset(shapeValueX, shapeValueY));
476 };
477 basicShape_->AddResource("shapeAbstract.ObjectOffset.X", xResObj, std::move(updateFunc));
478 }
479 if (yResObj) {
480 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, BasicShape& basicShape) {
481 CalcDimension shapeValueY;
482 ResourceParseUtils::ParseResDimensionVp(resObj, shapeValueY);
483 CalcDimension shapeValueX = basicShape.GetOffset().GetX();
484 basicShape.SetOffset(DimensionOffset(shapeValueX, shapeValueY));
485 };
486 basicShape_->AddResource("shapeAbstract.ObjectOffset.Y", yResObj, std::move(updateFunc));
487 }
488 }
489
ObjectOffset(const JSCallbackInfo & info)490 void JSShapeAbstract::ObjectOffset(const JSCallbackInfo& info)
491 {
492 info.ReturnSelf();
493 if (info.Length() > 0 && info[0]->IsObject()) {
494 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
495 JSRef<JSVal> xVal = sizeObj->GetProperty("x");
496 JSRef<JSVal> yVal = sizeObj->GetProperty("y");
497 CalcDimension x;
498 CalcDimension y;
499 if (!SystemProperties::ConfigChangePerform()) {
500 if (basicShape_ && ParseJsDimensionVp(xVal, x) && ParseJsDimensionVp(yVal, y)) {
501 basicShape_->SetOffset(DimensionOffset(x, y));
502 }
503 } else {
504 RefPtr<ResourceObject> xResObj;
505 RefPtr<ResourceObject> yResObj;
506 if (basicShape_ && ParseJsDimensionVp(xVal, x, xResObj) && ParseJsDimensionVp(yVal, y, yResObj)) {
507 ObjectOffsetUpdate(xResObj, yResObj);
508 basicShape_->SetOffset(DimensionOffset(x, y));
509 }
510 }
511 }
512 }
513
ObjectFillUpdate(const RefPtr<ResourceObject> & fillResObj)514 void JSShapeAbstract::ObjectFillUpdate(const RefPtr<ResourceObject>& fillResObj)
515 {
516 if (fillResObj) {
517 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, BasicShape& basicShape) {
518 Color shapeValue;
519 ResourceParseUtils::ParseResColor(resObj, shapeValue);
520 basicShape.SetColor(shapeValue);
521 };
522 basicShape_->AddResource("shapeAbstract.fill", fillResObj, std::move(updateFunc));
523 }
524 }
525
ObjectFill(const JSCallbackInfo & info)526 void JSShapeAbstract::ObjectFill(const JSCallbackInfo& info)
527 {
528 info.ReturnSelf();
529 if (info.Length() < 1) {
530 return;
531 }
532
533 Color color;
534 if (!SystemProperties::ConfigChangePerform()) {
535 if (ParseJsColor(info[0], color) && basicShape_) {
536 basicShape_->SetColor(color);
537 }
538 } else {
539 RefPtr<ResourceObject> fillResObj;
540 if (ParseJsColor(info[0], color, fillResObj) && basicShape_) {
541 ObjectFillUpdate(fillResObj);
542 basicShape_->SetColor(color);
543 }
544 }
545 }
546
JSBind(BindingTarget globalObj)547 void JSShapeAbstract::JSBind(BindingTarget globalObj)
548 {
549 JSClass<JSShapeAbstract>::Declare("JSShapeAbstract");
550 MethodOptions opt = MethodOptions::NONE;
551 JSClass<JSShapeAbstract>::StaticMethod("stroke", &JSShapeAbstract::SetStroke, opt);
552 JSClass<JSShapeAbstract>::StaticMethod("fill", &JSShapeAbstract::SetFill, opt);
553 JSClass<JSShapeAbstract>::StaticMethod("foregroundColor", &JSShapeAbstract::SetForegroundColor, opt);
554 JSClass<JSShapeAbstract>::StaticMethod("strokeDashOffset", &JSShapeAbstract::SetStrokeDashOffset, opt);
555 JSClass<JSShapeAbstract>::StaticMethod("strokeDashArray", &JSShapeAbstract::SetStrokeDashArray);
556 JSClass<JSShapeAbstract>::StaticMethod("strokeLineCap", &JSShapeAbstract::SetStrokeLineCap, opt);
557 JSClass<JSShapeAbstract>::StaticMethod("strokeLineJoin", &JSShapeAbstract::SetStrokeLineJoin, opt);
558 JSClass<JSShapeAbstract>::StaticMethod("strokeMiterLimit", &JSShapeAbstract::SetStrokeMiterLimit, opt);
559 JSClass<JSShapeAbstract>::StaticMethod("strokeOpacity", &JSShapeAbstract::SetStrokeOpacity, opt);
560 JSClass<JSShapeAbstract>::StaticMethod("fillOpacity", &JSShapeAbstract::SetFillOpacity, opt);
561 JSClass<JSShapeAbstract>::StaticMethod("strokeWidth", &JSShapeAbstract::SetStrokeWidth, opt);
562 JSClass<JSShapeAbstract>::StaticMethod("antiAlias", &JSShapeAbstract::SetAntiAlias, opt);
563 JSClass<JSShapeAbstract>::StaticMethod("width", &JSShapeAbstract::JsWidth, opt);
564 JSClass<JSShapeAbstract>::StaticMethod("height", &JSShapeAbstract::JsHeight, opt);
565 JSClass<JSShapeAbstract>::StaticMethod("size", &JSShapeAbstract::JsSize, opt);
566 JSClass<JSShapeAbstract>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
567 JSClass<JSShapeAbstract>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
568 JSClass<JSShapeAbstract>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
569 JSClass<JSShapeAbstract>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
570 JSClass<JSShapeAbstract>::InheritAndBind<JSViewAbstract>(globalObj);
571 }
572
SetSize(const JSCallbackInfo & info)573 void JSShapeAbstract::SetSize(const JSCallbackInfo& info)
574 {
575 if (info.Length() > 0 && info[0]->IsObject()) {
576 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
577 JSRef<JSVal> width = obj->GetProperty("width");
578 JSRef<JSVal> height = obj->GetProperty("height");
579 SetWidth(width);
580 SetHeight(height);
581 }
582 }
583
ObjectPositionUpdate(DimensionOffset & position,RefPtr<ResourceObject> & xResObj,RefPtr<ResourceObject> & yResObj)584 void JSShapeAbstract::ObjectPositionUpdate(DimensionOffset& position, RefPtr<ResourceObject>& xResObj,
585 RefPtr<ResourceObject>& yResObj)
586 {
587 if (SystemProperties::ConfigChangePerform() && xResObj) {
588 auto&& updateFunc = [position](const RefPtr<ResourceObject>& resObj, BasicShape& basicShape) {
589 DimensionOffset& value = const_cast<DimensionOffset&>(position);
590 CalcDimension x;
591 CalcDimension y;
592 if (!ResourceParseUtils::ParseResDimensionVp(resObj, x)) {
593 x = basicShape.GetPosition().GetX();
594 }
595 y = basicShape.GetPosition().GetY();
596 value.SetX(x);
597 value.SetY(y);
598 basicShape.SetPosition(value);
599 };
600 basicShape_->AddResource("shapeAbstract.position.xResObj", xResObj, std::move(updateFunc));
601 }
602 if (SystemProperties::ConfigChangePerform() && yResObj) {
603 auto&& updateFunc = [position](const RefPtr<ResourceObject>& resObj, BasicShape& basicShape) {
604 DimensionOffset& value = const_cast<DimensionOffset&>(position);
605 CalcDimension x;
606 CalcDimension y;
607 x = basicShape.GetPosition().GetX();
608 if (!ResourceParseUtils::ParseResDimensionVp(resObj, y)) {
609 y = basicShape.GetPosition().GetY();
610 }
611 value.SetX(x);
612 value.SetY(y);
613 basicShape.SetPosition(value);
614 };
615 basicShape_->AddResource("shapeAbstract.position.yResObj", yResObj, std::move(updateFunc));
616 }
617 }
618
ObjectPosition(const JSCallbackInfo & info)619 void JSShapeAbstract::ObjectPosition(const JSCallbackInfo& info)
620 {
621 info.ReturnSelf();
622 if (!(info.Length() > 0 && info[0]->IsObject())) {
623 LOGE("Info is invalid!");
624 return;
625 }
626 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
627 JSRef<JSVal> xVal = sizeObj->GetProperty("x");
628 JSRef<JSVal> yVal = sizeObj->GetProperty("y");
629 CalcDimension x;
630 CalcDimension y;
631 DimensionOffset position(x, y);
632 CHECK_NULL_VOID(basicShape_);
633 RefPtr<ResourceObject> xResObj;
634 RefPtr<ResourceObject> yResObj;
635 if (ParseJsDimensionVp(xVal, x, xResObj)) {
636 position.SetX(x);
637 }
638 if (ParseJsDimensionVp(yVal, y, yResObj)) {
639 position.SetY(y);
640 }
641 ObjectPositionUpdate(position, xResObj, yResObj);
642 basicShape_->SetPosition(position);
643 }
644
SetForegroundColor(const JSCallbackInfo & info)645 void JSShapeAbstract::SetForegroundColor(const JSCallbackInfo& info)
646 {
647 if (info.Length() < 1) {
648 return;
649 }
650 Color foregroundColor;
651 RefPtr<ResourceObject> foregroundColorResObj;
652 ForegroundColorStrategy strategy;
653 UnRegisterResource("ShapeAbstractForegroundColor");
654 if (ParseJsColorStrategy(info[0], strategy)) {
655 ShapeAbstractModel::GetInstance()->SetFill(Color::FOREGROUND);
656 ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
657 return;
658 }
659 if (!ParseJsColor(info[0], foregroundColor, foregroundColorResObj)) {
660 ShapeAbstractModel::GetInstance()->SetFill(Color::BLACK);
661 ViewAbstractModel::GetInstance()->SetForegroundColor(Color::BLACK);
662 return;
663 }
664 if (SystemProperties::ConfigChangePerform() && foregroundColorResObj) {
665 RegisterResource<Color>("ShapeAbstractForegroundColor", foregroundColorResObj, foregroundColor);
666 }
667 ShapeAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
668 ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
669 }
670 } // namespace OHOS::Ace::Framework
671