• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_view_measure_layout.h"
17 
18 #include "jsnapi.h"
19 
20 #include "base/geometry/dimension.h"
21 #include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
22 #include "frameworks/core/components_ng/base/frame_node.h"
23 
24 namespace OHOS::Ace::Framework {
25 
26 #ifdef USE_ARK_ENGINE
27 
28 thread_local std::list<RefPtr<NG::LayoutWrapper>> ViewMeasureLayout::measureChildren_;
29 thread_local std::list<RefPtr<NG::LayoutWrapper>>::iterator ViewMeasureLayout::iterMeasureChildren_;
30 thread_local std::list<RefPtr<NG::LayoutWrapper>> ViewMeasureLayout::layoutChildren_;
31 thread_local std::list<RefPtr<NG::LayoutWrapper>>::iterator ViewMeasureLayout::iterLayoutChildren_;
32 thread_local NG::LayoutConstraintF ViewMeasureLayout::measureDefaultConstraint_;
33 
JSMeasure(panda::JsiRuntimeCallInfo * runtimeCallInfo)34 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSMeasure(panda::JsiRuntimeCallInfo* runtimeCallInfo)
35 {
36     ACE_SCOPED_TRACE("ViewMeasureLayout::JSMeasure");
37     EcmaVM* vm = runtimeCallInfo->GetVM();
38 
39     if (iterMeasureChildren_ == measureChildren_.end()) {
40         LOGE("Call measure exceed limit");
41         return panda::JSValueRef::Undefined(vm);
42     }
43 
44     auto info = runtimeCallInfo;
45     if (info->GetArgsNumber() != 1 || !info->GetCallArgRef(0)->IsObject()) {
46         LOGE("JSMeasure arg is wrong");
47         (*iterMeasureChildren_)->Measure(measureDefaultConstraint_);
48         iterMeasureChildren_++;
49         return panda::JSValueRef::Undefined(vm);
50     }
51 
52     auto jsObject = JsiObject(info->GetCallArgRef(0)->ToObject(vm));
53     JSRef<JSObject> sizeObj = JSRef<JSObject>::Make(jsObject);
54     JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
55     CalcDimension minWidth;
56     JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
57     CalcDimension maxWidth;
58     JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
59     CalcDimension minHeight;
60     JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
61     CalcDimension maxHeight;
62 
63     if (JSViewAbstract::ParseJsDimensionVp(minWidthValue, minWidth)) {
64         (*iterMeasureChildren_)
65             ->GetLayoutProperty()
66             ->UpdateCalcMinSize(NG::CalcSize(NG::CalcLength(minWidth), std::nullopt));
67     }
68     if (JSViewAbstract::ParseJsDimensionVp(maxWidthValue, maxWidth)) {
69         (*iterMeasureChildren_)
70             ->GetLayoutProperty()
71             ->UpdateCalcMaxSize(NG::CalcSize(NG::CalcLength(maxWidth), std::nullopt));
72     }
73     if (JSViewAbstract::ParseJsDimensionVp(minHeightValue, minHeight)) {
74         (*iterMeasureChildren_)
75             ->GetLayoutProperty()
76             ->UpdateCalcMinSize(NG::CalcSize(std::nullopt, NG::CalcLength(minHeight)));
77     }
78     if (JSViewAbstract::ParseJsDimensionVp(maxHeightValue, maxHeight)) {
79         (*iterMeasureChildren_)
80             ->GetLayoutProperty()
81             ->UpdateCalcMaxSize(NG::CalcSize(std::nullopt, NG::CalcLength(maxHeight)));
82     }
83     (*iterMeasureChildren_)->Measure(measureDefaultConstraint_);
84 
85     Dimension measureWidth((*iterMeasureChildren_)->GetGeometryNode()->GetFrameRect().Width(), DimensionUnit::PX);
86     Dimension measureHeight((*iterMeasureChildren_)->GetGeometryNode()->GetFrameRect().Height(), DimensionUnit::PX);
87     Local<ObjectRef> measureResultObject = ObjectRef::New(vm);
88     measureResultObject->Set(vm, ToJSValue("width"), ToJSValue(measureWidth.ConvertToVp()));
89     measureResultObject->Set(vm, ToJSValue("height"), ToJSValue(measureHeight.ConvertToVp()));
90 
91     iterMeasureChildren_++;
92     return measureResultObject;
93 }
94 
JSLayout(panda::JsiRuntimeCallInfo * runtimeCallInfo)95 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSLayout(panda::JsiRuntimeCallInfo* runtimeCallInfo)
96 {
97     ACE_SCOPED_TRACE("ViewMeasureLayout::JSLayout");
98     EcmaVM* vm = runtimeCallInfo->GetVM();
99 
100     if (iterLayoutChildren_ == layoutChildren_.end()) {
101         LOGE("Call layout exceed limit");
102         return panda::JSValueRef::Undefined(vm);
103     }
104 
105     auto info = runtimeCallInfo;
106     if (info->GetArgsNumber() != 1 || !info->GetCallArgRef(0)->IsObject()) {
107         LOGE("JSLayout arg is wrong");
108         (*iterLayoutChildren_)->Layout();
109         iterLayoutChildren_++;
110         return panda::JSValueRef::Undefined(vm);
111     }
112 
113     auto jsObject = JsiObject(info->GetCallArgRef(0)->ToObject(vm));
114     JSRef<JSObject> layoutInfo = JSRef<JSObject>::Make(jsObject);
115     JSRef<JSObject> sizeObj = layoutInfo->GetProperty("position");
116     JSRef<JSVal> xVal = sizeObj->GetProperty("x");
117     JSRef<JSVal> yVal = sizeObj->GetProperty("y");
118     CalcDimension dimenX;
119     CalcDimension dimenY;
120     auto xResult = JSViewAbstract::ParseJsDimensionVp(xVal, dimenX);
121     auto yResult = JSViewAbstract::ParseJsDimensionVp(yVal, dimenY);
122     if (!(xResult || yResult)) {
123         LOGE("the position prop is illegal");
124     } else {
125         (*iterLayoutChildren_)->GetGeometryNode()->SetFrameOffset({ dimenX.ConvertToPx(), dimenY.ConvertToPx() });
126     }
127     (*iterLayoutChildren_)->Layout();
128     iterLayoutChildren_++;
129 
130     return panda::JSValueRef::Undefined(vm);
131 }
132 
JSPlaceChildren(panda::JsiRuntimeCallInfo * runtimeCallInfo)133 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSPlaceChildren(panda::JsiRuntimeCallInfo* runtimeCallInfo)
134 {
135     ACE_SCOPED_TRACE("ViewMeasureLayout::JSPlaceChildren");
136     EcmaVM* vm = runtimeCallInfo->GetVM();
137 
138     if (iterLayoutChildren_ == layoutChildren_.end()) {
139         LOGE("Call layout exceed limit");
140         return panda::JSValueRef::Undefined(vm);
141     }
142 
143     auto info = runtimeCallInfo;
144     if (info->GetArgsNumber() != 1 || !info->GetCallArgRef(0)->IsObject()) {
145         LOGE("JSPlaceChildren arg is wrong");
146         (*iterLayoutChildren_)->Layout();
147         iterLayoutChildren_++;
148         return panda::JSValueRef::Undefined(vm);
149     }
150 
151     auto jsObject = JsiObject(info->GetCallArgRef(0)->ToObject(vm));
152     JSRef<JSObject> layoutInfo = JSRef<JSObject>::Make(jsObject);
153     JSRef<JSVal> xVal = layoutInfo->GetProperty("x");
154     JSRef<JSVal> yVal = layoutInfo->GetProperty("y");
155     CalcDimension dimenX;
156     CalcDimension dimenY;
157     auto xResult = JSViewAbstract::ParseJsDimensionVp(xVal, dimenX);
158     auto yResult = JSViewAbstract::ParseJsDimensionVp(yVal, dimenY);
159     if (!(xResult || yResult)) {
160         LOGE("the position prop is illegal");
161     } else {
162         (*iterLayoutChildren_)->GetGeometryNode()->SetFrameOffset({ dimenX.ConvertToPx(), dimenY.ConvertToPx() });
163     }
164     (*iterLayoutChildren_)->Layout();
165     iterLayoutChildren_++;
166     return panda::JSValueRef::Undefined(vm);
167 }
168 
169 #endif
170 
171 } // namespace OHOS::Ace::Framework
172