• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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