• 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 #include "frameworks/core/components_ng/pattern/custom/custom_measure_layout_node.h"
24 
25 namespace OHOS::Ace::Framework {
26 
27 #ifdef USE_ARK_ENGINE
28 
29 namespace {
30 using OHOS::Ace::NG::LayoutConstraintF;
31 using OHOS::Ace::NG::LayoutProperty;
32 using OHOS::Ace::NG::SizeF;
GenConstraint(const std::optional<NG::LayoutConstraintF> & parentConstraint)33 JSRef<JSObject> GenConstraint(const std::optional<NG::LayoutConstraintF>& parentConstraint)
34 {
35     auto minSize = parentConstraint->minSize;
36     auto maxSize = parentConstraint->maxSize;
37     JSRef<JSObject> constraint = JSRef<JSObject>::New();
38     constraint->SetProperty<double>("minWidth", minSize.Width());
39     constraint->SetProperty<double>("minHeight", minSize.Height());
40     constraint->SetProperty<double>("maxWidth", maxSize.Width());
41     constraint->SetProperty<double>("maxHeight", maxSize.Height());
42     return constraint;
43 }
44 
GenConstraintNG(const NG::LayoutConstraintF & parentConstraint)45 JSRef<JSObject> GenConstraintNG(const NG::LayoutConstraintF& parentConstraint)
46 {
47     auto minSize = parentConstraint.minSize;
48     auto maxSize = parentConstraint.maxSize;
49     JSRef<JSObject> constraint = JSRef<JSObject>::New();
50     constraint->SetProperty<double>("minWidth", 0.0f);
51     constraint->SetProperty<double>("minHeight", 0.0f);
52     constraint->SetProperty<double>("maxWidth", 0.0f);
53     constraint->SetProperty<double>("maxHeight", 0.0f);
54     auto pipeline = PipelineBase::GetCurrentContext();
55     if (!pipeline) {
56         return constraint;
57     }
58     constraint->SetProperty<double>("minWidth", minSize.Width() / pipeline->GetDipScale());
59     constraint->SetProperty<double>("minHeight", minSize.Height() / pipeline->GetDipScale());
60     constraint->SetProperty<double>("maxWidth", maxSize.Width() / pipeline->GetDipScale());
61     constraint->SetProperty<double>("maxHeight", maxSize.Height() / pipeline->GetDipScale());
62     return constraint;
63 }
64 
GenPlaceChildrenConstraintNG(const NG::SizeF & size,RefPtr<NG::LayoutProperty> layoutProperty)65 JSRef<JSObject> GenPlaceChildrenConstraintNG(const NG::SizeF& size, RefPtr<NG::LayoutProperty> layoutProperty)
66 {
67     JSRef<JSObject> constraint = JSRef<JSObject>::New();
68     auto pipeline = PipelineBase::GetCurrentContext();
69     if (!layoutProperty || !pipeline) {
70         constraint->SetProperty<double>("minWidth", 0.0f);
71         constraint->SetProperty<double>("minHeight", 0.0f);
72         constraint->SetProperty<double>("maxWidth", 0.0f);
73         constraint->SetProperty<double>("maxHeight", 0.0f);
74         return constraint;
75     }
76     auto minSize = layoutProperty->GetLayoutConstraint().value().minSize;
77     constraint->SetProperty<double>("minWidth", minSize.Width() / pipeline->GetDipScale());
78     constraint->SetProperty<double>("minHeight", minSize.Height() / pipeline->GetDipScale());
79     auto parentNode = AceType::DynamicCast<NG::FrameNode>(layoutProperty->GetHost()->GetParent());
80     if (parentNode && parentNode->GetTag() == V2::COMMON_VIEW_ETS_TAG) {
81         layoutProperty = parentNode->GetLayoutProperty();
82     }
83     const std::unique_ptr<NG::PaddingProperty>& padding =  layoutProperty->GetPaddingProperty();
84     const std::unique_ptr<NG::BorderWidthProperty>& borderWidth =  layoutProperty->GetBorderWidthProperty();
85     auto topPadding = padding ? padding->top->GetDimension().ConvertToVp() : 0.0f;
86     auto bottomPadding = padding ? padding->bottom->GetDimension().ConvertToVp() : 0.0f;
87     auto leftPadding = padding ? padding->left->GetDimension().ConvertToVp() : 0.0f;
88     auto rightPadding = padding ? padding->right->GetDimension().ConvertToVp() : 0.0f;
89     auto topBorder = borderWidth ? borderWidth->topDimen->ConvertToVp() : 0.0f;
90     auto bottomBorder = borderWidth ? borderWidth->bottomDimen->ConvertToVp() : 0.0f;
91     auto leftBorder = borderWidth ? borderWidth->leftDimen->ConvertToVp() : 0.0f;
92     auto rightBorder = borderWidth ? borderWidth->rightDimen->ConvertToVp() : 0.0f;
93     constraint->SetProperty<double>("maxWidth", size.Width() / pipeline->GetDipScale() - leftPadding - rightPadding -
94         leftBorder - rightBorder);
95     constraint->SetProperty<double>("maxHeight", size.Height() / pipeline->GetDipScale() - topPadding - bottomPadding -
96         topBorder - bottomBorder);
97     return constraint;
98 }
99 
GenPadding(const std::unique_ptr<NG::PaddingProperty> & paddingNative)100 JSRef<JSObject> GenPadding(const std::unique_ptr<NG::PaddingProperty>& paddingNative)
101 {
102     JSRef<JSObject> padding = JSRef<JSObject>::New();
103     padding->SetProperty("top", paddingNative->top->GetDimension().ConvertToVp());
104     padding->SetProperty("right", paddingNative->right->GetDimension().ConvertToVp());
105     padding->SetProperty("bottom", paddingNative->bottom->GetDimension().ConvertToVp());
106     padding->SetProperty("left", paddingNative->left->GetDimension().ConvertToVp());
107     return padding;
108 }
109 
GenMargin(const std::unique_ptr<NG::MarginProperty> & marginNative)110 JSRef<JSObject> GenMargin(const std::unique_ptr<NG::MarginProperty>& marginNative)
111 {
112     JSRef<JSObject> margin = JSRef<JSObject>::New();
113     margin->SetProperty("top", marginNative->top->GetDimension().ConvertToVp());
114     margin->SetProperty("right", marginNative->right->GetDimension().ConvertToVp());
115     margin->SetProperty("bottom", marginNative->bottom->GetDimension().ConvertToVp());
116     margin->SetProperty("left", marginNative->left->GetDimension().ConvertToVp());
117     return margin;
118 }
119 
GenEdgeWidths(const std::unique_ptr<NG::BorderWidthProperty> & edgeWidthsNative)120 JSRef<JSObject> GenEdgeWidths(const std::unique_ptr<NG::BorderWidthProperty>& edgeWidthsNative)
121 {
122     JSRef<JSObject> edgeWidths = JSRef<JSObject>::New();
123     edgeWidths->SetProperty("top", edgeWidthsNative->topDimen->ConvertToVp());
124     edgeWidths->SetProperty("right", edgeWidthsNative->rightDimen->ConvertToVp());
125     edgeWidths->SetProperty("bottom", edgeWidthsNative->bottomDimen->ConvertToVp());
126     edgeWidths->SetProperty("left", edgeWidthsNative->leftDimen->ConvertToVp());
127     return edgeWidths;
128 }
129 
GenEdgesGlobalized(const NG::PaddingPropertyT<float> & edgeNative,TextDirection direction)130 JSRef<JSObject> GenEdgesGlobalized(const NG::PaddingPropertyT<float>& edgeNative, TextDirection direction)
131 {
132     JSRef<JSObject> edges = JSRef<JSObject>::New();
133     auto pipeline = PipelineBase::GetCurrentContext();
134     double px2vpScale = pipeline ? 1.0 / pipeline->GetDipScale() : 1.0;
135     edges->SetProperty("top", edgeNative.top.value_or(0) * px2vpScale);
136     edges->SetProperty("bottom", edgeNative.bottom.value_or(0) * px2vpScale);
137     if (direction != TextDirection::RTL) {
138         edges->SetProperty("start", edgeNative.left.value_or(0) * px2vpScale);
139         edges->SetProperty("end", edgeNative.right.value_or(0) * px2vpScale);
140     } else {
141         edges->SetProperty("start", edgeNative.right.value_or(0) * px2vpScale);
142         edges->SetProperty("end", edgeNative.left.value_or(0) * px2vpScale);
143     }
144     return edges;
145 }
146 
GenBorderWidthGlobalized(const NG::BorderWidthPropertyT<float> & edgeNative,TextDirection direction)147 JSRef<JSObject> GenBorderWidthGlobalized(const NG::BorderWidthPropertyT<float>& edgeNative, TextDirection direction)
148 {
149     JSRef<JSObject> edges = JSRef<JSObject>::New();
150     auto pipeline = PipelineBase::GetCurrentContext();
151     double px2vpScale = pipeline ? 1.0 / pipeline->GetDipScale() : 1.0;
152     edges->SetProperty("top", edgeNative.topDimen.value_or(0) * px2vpScale);
153     edges->SetProperty("bottom", edgeNative.bottomDimen.value_or(0) * px2vpScale);
154     if (direction != TextDirection::RTL) {
155         edges->SetProperty("start", edgeNative.leftDimen.value_or(0) * px2vpScale);
156         edges->SetProperty("end", edgeNative.rightDimen.value_or(0) * px2vpScale);
157     } else {
158         edges->SetProperty("start", edgeNative.rightDimen.value_or(0) * px2vpScale);
159         edges->SetProperty("end", edgeNative.leftDimen.value_or(0) * px2vpScale);
160     }
161     return edges;
162 }
163 
GenBorderInfo(const RefPtr<NG::LayoutWrapper> & layoutWrapper)164 JSRef<JSObject> GenBorderInfo(const RefPtr<NG::LayoutWrapper>& layoutWrapper)
165 {
166     JSRef<JSObject> borderInfo = JSRef<JSObject>::New();
167     auto layoutProperty = layoutWrapper->GetLayoutProperty();
168     const std::unique_ptr<NG::PaddingProperty> defaultPadding = std::make_unique<NG::PaddingProperty>();
169     const std::unique_ptr<NG::PaddingProperty> defaultMargin = std::make_unique<NG::MarginProperty>();
170     const std::unique_ptr<NG::BorderWidthProperty>& defaultEdgeWidth = std::make_unique<NG::BorderWidthProperty>();
171     if (!layoutProperty) {
172         borderInfo->SetPropertyObject("borderWidth", GenEdgeWidths(defaultEdgeWidth));
173         borderInfo->SetPropertyObject("margin", GenMargin(defaultPadding));
174         borderInfo->SetPropertyObject("padding", GenPadding(defaultPadding));
175         return borderInfo;
176     }
177 
178     borderInfo->SetPropertyObject("borderWidth",
179         GenEdgeWidths(
180             layoutProperty->GetBorderWidthProperty() ? layoutProperty->GetBorderWidthProperty() : defaultEdgeWidth));
181 
182     borderInfo->SetPropertyObject("margin",
183         GenMargin(layoutProperty->GetMarginProperty() ? layoutProperty->GetMarginProperty() : defaultMargin));
184     borderInfo->SetPropertyObject("padding",
185         GenPadding(layoutProperty->GetPaddingProperty() ? layoutProperty->GetPaddingProperty() : defaultPadding));
186 
187     return borderInfo;
188 }
189 
GenPositionInfo(const RefPtr<NG::LayoutWrapper> & layoutWrapper)190 JSRef<JSObject> GenPositionInfo(const RefPtr<NG::LayoutWrapper>& layoutWrapper)
191 {
192     auto offset = layoutWrapper->GetGeometryNode()->GetFrameOffset();
193     JSRef<JSObject> position = JSRef<JSObject>::New();
194     position->SetProperty("x", offset.GetX());
195     position->SetProperty("y", offset.GetY());
196     return position;
197 }
198 
GenSelfLayoutInfo(RefPtr<NG::LayoutProperty> layoutProperty)199 JSRef<JSObject> GenSelfLayoutInfo(RefPtr<NG::LayoutProperty> layoutProperty)
200 {
201     JSRef<JSObject> selfLayoutInfo = JSRef<JSObject>::New();
202     const std::unique_ptr<NG::PaddingProperty> defaultPadding = std::make_unique<NG::PaddingProperty>();
203     const std::unique_ptr<NG::PaddingProperty> defaultMargin = std::make_unique<NG::MarginProperty>();
204     const std::unique_ptr<NG::BorderWidthProperty>& defaultEdgeWidth = std::make_unique<NG::BorderWidthProperty>();
205     auto pipeline = PipelineBase::GetCurrentContext();
206     if (!layoutProperty || !pipeline) {
207         selfLayoutInfo->SetPropertyObject("borderWidth", GenEdgeWidths(defaultEdgeWidth));
208         selfLayoutInfo->SetPropertyObject("margin", GenMargin(defaultPadding));
209         selfLayoutInfo->SetPropertyObject("padding", GenPadding(defaultPadding));
210         selfLayoutInfo->SetProperty("width", 0.0f);
211         selfLayoutInfo->SetProperty("height", 0.0f);
212         return selfLayoutInfo;
213     }
214     auto parentNode = AceType::DynamicCast<NG::FrameNode>(layoutProperty->GetHost()->GetParent());
215     if (parentNode && parentNode->GetTag() == V2::COMMON_VIEW_ETS_TAG) {
216         layoutProperty = parentNode->GetLayoutProperty();
217     }
218     auto host = layoutProperty->GetHost();
219     NG::RectF originGeoRect;
220     if (host) {
221         originGeoRect = host->GetGeometryNode()->GetFrameRect();
222     }
223     auto width =
224         GreatNotEqual(originGeoRect.Width(), 0.0f) ? originGeoRect.Width() / pipeline->GetDipScale()
225         : layoutProperty->GetLayoutConstraint()
226             ? layoutProperty->GetLayoutConstraint()->selfIdealSize.Width().value_or(0.0) / pipeline->GetDipScale()
227             : 0.0f;
228     auto height =
229         GreatNotEqual(originGeoRect.Height(), 0.0f) ? originGeoRect.Height() / pipeline->GetDipScale()
230         : layoutProperty->GetLayoutConstraint()
231             ? layoutProperty->GetLayoutConstraint()->selfIdealSize.Height().value_or(0.0) / pipeline->GetDipScale()
232             : 0.0f;
233 
234     selfLayoutInfo->SetPropertyObject("borderWidth",
235         GenEdgeWidths(
236             layoutProperty->GetBorderWidthProperty() ? layoutProperty->GetBorderWidthProperty() : defaultEdgeWidth));
237     selfLayoutInfo->SetPropertyObject("margin",
238         GenMargin(layoutProperty->GetMarginProperty() ? layoutProperty->GetMarginProperty() : defaultPadding));
239     selfLayoutInfo->SetPropertyObject("padding",
240         GenPadding(layoutProperty->GetPaddingProperty() ? layoutProperty->GetPaddingProperty() : defaultPadding));
241     selfLayoutInfo->SetProperty(
242         "width", NearEqual(width, 0.0f)
243                      ? layoutProperty->GetLayoutConstraint()->percentReference.Width() / pipeline->GetDipScale()
244                      : width);
245     selfLayoutInfo->SetProperty(
246         "height", NearEqual(height, 0.0f)
247                       ? layoutProperty->GetLayoutConstraint()->percentReference.Height() / pipeline->GetDipScale()
248                       : height);
249     return selfLayoutInfo;
250 }
251 
FillSubComponentProperty(JSRef<JSObjTemplate> & info,const RefPtr<NG::LayoutWrapper> & layoutWrapper,const size_t & index)252 void FillSubComponentProperty(
253     JSRef<JSObjTemplate>& info, const RefPtr<NG::LayoutWrapper>& layoutWrapper, const size_t& index)
254 {
255     info->SetProperty<std::string>("name", layoutWrapper->GetHostNode()->GetTag());
256     info->SetProperty<std::string>("id", std::to_string(layoutWrapper->GetHostNode()->GetId()));
257     const auto& layoutProperty = layoutWrapper->GetLayoutProperty();
258     if (layoutProperty) {
259         info->SetPropertyObject("constraint", GenConstraint(layoutProperty->GetLayoutConstraint()));
260     }
261     info->SetPropertyObject("borderInfo", GenBorderInfo(layoutWrapper));
262     info->SetPropertyObject("position", GenPositionInfo(layoutWrapper));
263 }
264 
FillPlaceSizeProperty(JSRef<JSObjTemplate> & info,const NG::SizeF & size)265 void FillPlaceSizeProperty(JSRef<JSObjTemplate>& info, const NG::SizeF& size)
266 {
267     JSRef<JSObject> measureResult = JSRef<JSObject>::New();
268     Dimension measureWidth(size.Width(), DimensionUnit::PX);
269     Dimension measureHeight(size.Height(), DimensionUnit::PX);
270     measureResult->SetProperty("width", measureWidth.ConvertToVp());
271     measureResult->SetProperty("height", measureHeight.ConvertToVp());
272     info->SetPropertyObject("measureResult", measureResult);
273 }
274 } // namespace
275 
JSMeasureLayoutParam(NG::LayoutWrapper * layoutWrapper)276 JSMeasureLayoutParam::JSMeasureLayoutParam(NG::LayoutWrapper* layoutWrapper) : MeasureLayoutParam(layoutWrapper)
277 {
278     Init();
279 }
280 
Init()281 void JSMeasureLayoutParam::Init()
282 {
283     int32_t count = GetTotalChildCount();
284     childArray_ = JSRef<JSArray>::New(count);
285     GenChildArray(0, count);
286 }
287 
GenChildArray(int32_t start,int32_t end)288 void JSMeasureLayoutParam::GenChildArray(int32_t start, int32_t end)
289 {
290     JSRef<JSFunc> measureFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSMeasure);
291     JSRef<JSFunc> layoutFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSLayout);
292     for (int32_t index = start; index < end; index++) {
293         JSRef<JSObjTemplate> info = JSRef<JSObjTemplate>::New();
294         info->SetInternalFieldCount(1);
295         FillSubComponentProperty(info, GetOrCreateChildByIndex(index), index);
296         info->Wrap<NG::MeasureLayoutChild>(&Get(index));
297         info->SetPropertyObject("measure", measureFunc);
298         info->SetPropertyObject("layout", layoutFunc);
299         childArray_->SetValueAt(index, info);
300     }
301 }
302 
GetConstraint()303 JSRef<JSObject> JSMeasureLayoutParam::GetConstraint()
304 {
305     auto layoutWrapper = GetLayoutWrapper();
306     if (layoutWrapper && layoutWrapper->GetGeometryNode() &&
307         layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint()) {
308         auto parentConstraint = layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint();
309         return GenConstraint(parentConstraint);
310     }
311     return GenConstraint(LayoutConstraintF());
312 }
313 
Update(NG::LayoutWrapper * layoutWrapper)314 void JSMeasureLayoutParam::Update(NG::LayoutWrapper* layoutWrapper)
315 {
316     NG::MeasureLayoutChild* addr = nullptr;
317     int32_t count = GetTotalChildCount();
318     if (count > 0) {
319         addr = &Get(0);
320     }
321     MeasureLayoutParam::Update(layoutWrapper);
322     int32_t newCount = GetTotalChildCount();
323     if (count == newCount) {
324         return;
325     }
326     childArray_->SetLength(newCount);
327     if (count < newCount) {
328         GenChildArray(count, newCount);
329     }
330     if (addr != &Get(0)) {
331         for (int32_t index = 0; index < count; index++) {
332             auto info = JSRef<JSObjTemplate>::Cast(childArray_->GetValueAt(index));
333             info->Wrap<NG::MeasureLayoutChild>(&Get(index));
334         }
335     }
336 }
337 
GetInstance(NG::LayoutWrapper * layoutWrapper)338 RefPtr<JSMeasureLayoutParam> JSMeasureLayoutParam::GetInstance(NG::LayoutWrapper* layoutWrapper)
339 {
340     auto host = AceType::DynamicCast<NG::CustomMeasureLayoutNode>(layoutWrapper->GetHostNode());
341     CHECK_NULL_RETURN(host, nullptr);
342     auto jsParam = AceType::DynamicCast<JSMeasureLayoutParam>(host->GetMeasureLayoutParam());
343     if (!jsParam) {
344         jsParam = AceType::MakeRefPtr<JSMeasureLayoutParam>(layoutWrapper);
345         host->SetMeasureLayoutParam(jsParam);
346     } else {
347         jsParam->Update(layoutWrapper);
348     }
349     return jsParam;
350 }
351 
JSMeasureLayoutParamNG(NG::LayoutWrapper * layoutWrapper)352 JSMeasureLayoutParamNG::JSMeasureLayoutParamNG(NG::LayoutWrapper* layoutWrapper) : MeasureLayoutParam(layoutWrapper)
353 {
354     Init();
355 }
356 
Init()357 void JSMeasureLayoutParamNG::Init()
358 {
359     int32_t count = GetTotalChildCount();
360     childArray_ = JSRef<JSArray>::New(count);
361     GenChildArray(0, count);
362 }
363 
GenChildArray(int32_t start,int32_t end)364 void JSMeasureLayoutParamNG::GenChildArray(int32_t start, int32_t end)
365 {
366     JSRef<JSObject> size = JSRef<JSObject>::New();
367     size->SetProperty("width", 0);
368     size->SetProperty("height", 0);
369     JSRef<JSFunc> measureFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSMeasure);
370     JSRef<JSFunc> layoutFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSPlaceChildren);
371     JSRef<JSFunc> getMarginFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSGetMargin);
372     JSRef<JSFunc> getPaddingFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSGetPadding);
373     JSRef<JSFunc> getBorderWidthFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSGetBorderWidth);
374     for (int32_t index = start; index < end; index++) {
375         JSRef<JSObjTemplate> info = JSRef<JSObjTemplate>::New();
376         info->SetInternalFieldCount(1);
377         auto child = GetChildByIndex(index);
378         if (child && child->GetHostNode()) {
379             auto uniqueId = child->GetHostNode()->GetId();
380             info->SetProperty("uniqueId", uniqueId);
381         }
382         info->SetPropertyObject("measureResult", size);
383         info->Wrap<NG::MeasureLayoutChild>(&Get(index));
384         info->SetPropertyObject("measure", measureFunc);
385         info->SetPropertyObject("layout", layoutFunc);
386         info->SetPropertyObject("getMargin", getMarginFunc);
387         info->SetPropertyObject("getPadding", getPaddingFunc);
388         info->SetPropertyObject("getBorderWidth", getBorderWidthFunc);
389         childArray_->SetValueAt(index, info);
390     }
391 }
392 
GetConstraint()393 JSRef<JSObject> JSMeasureLayoutParamNG::GetConstraint()
394 {
395     auto layoutWrapper = GetLayoutWrapper();
396     if (layoutWrapper && layoutWrapper->GetLayoutProperty() &&
397         layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()) {
398         auto layoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint().value();
399         return GenConstraintNG(layoutConstraint);
400     }
401     return GenConstraintNG(LayoutConstraintF());
402 }
403 
GetPlaceChildrenConstraint()404 JSRef<JSObject> JSMeasureLayoutParamNG::GetPlaceChildrenConstraint()
405 {
406     auto layoutWrapper = GetLayoutWrapper();
407     if (layoutWrapper && layoutWrapper->GetLayoutProperty() && layoutWrapper->GetGeometryNode()) {
408         auto layoutFrameSize = layoutWrapper->GetGeometryNode()->GetFrameSize();
409         return GenPlaceChildrenConstraintNG(layoutFrameSize, layoutWrapper->GetLayoutProperty());
410     }
411     return GenPlaceChildrenConstraintNG(SizeF(), MakeRefPtr<LayoutProperty>());
412 }
413 
GetSelfLayoutInfo()414 JSRef<JSObject> JSMeasureLayoutParamNG::GetSelfLayoutInfo()
415 {
416     auto layoutWrapper = GetLayoutWrapper();
417     return GenSelfLayoutInfo(layoutWrapper && layoutWrapper->GetLayoutProperty() ? layoutWrapper->GetLayoutProperty()
418                                                                                  : MakeRefPtr<LayoutProperty>());
419 }
420 
UpdateSize(int32_t index,const NG::SizeF & size)421 void JSMeasureLayoutParamNG::UpdateSize(int32_t index, const NG::SizeF& size)
422 {
423     auto info = JSRef<JSObjTemplate>::Cast(childArray_->GetValueAt(index));
424     auto layoutWrapper = GetChildByIndex(index);
425     FillPlaceSizeProperty(info, size);
426 }
427 
Update(NG::LayoutWrapper * layoutWrapper)428 void JSMeasureLayoutParamNG::Update(NG::LayoutWrapper* layoutWrapper)
429 {
430     NG::MeasureLayoutChild* addr = nullptr;
431     int32_t count = GetTotalChildCount();
432     if (count > 0) {
433         addr = &Get(0);
434     }
435     MeasureLayoutParam::Update(layoutWrapper);
436     int32_t newCount = GetTotalChildCount();
437     if (count == newCount) {
438         return;
439     }
440     childArray_->SetLength(newCount);
441     if (count < newCount) {
442         GenChildArray(count, newCount);
443     }
444     if (addr != &Get(0)) {
445         for (int32_t index = 0; index < count; index++) {
446             auto info = JSRef<JSObjTemplate>::Cast(childArray_->GetValueAt(index));
447             info->Wrap<NG::MeasureLayoutChild>(&Get(index));
448         }
449     }
450 }
451 
GetInstance(NG::LayoutWrapper * layoutWrapper)452 RefPtr<JSMeasureLayoutParamNG> JSMeasureLayoutParamNG::GetInstance(NG::LayoutWrapper* layoutWrapper)
453 {
454     auto host = AceType::DynamicCast<NG::CustomMeasureLayoutNode>(layoutWrapper->GetHostNode());
455     CHECK_NULL_RETURN(host, nullptr);
456     auto jsParam = AceType::DynamicCast<JSMeasureLayoutParamNG>(host->GetMeasureLayoutParam());
457     if (!jsParam) {
458         jsParam = AceType::MakeRefPtr<JSMeasureLayoutParamNG>(layoutWrapper);
459         host->SetMeasureLayoutParam(jsParam);
460     } else {
461         jsParam->Update(layoutWrapper);
462     }
463     return jsParam;
464 }
465 
JSMeasure(panda::JsiRuntimeCallInfo * runtimeCallInfo)466 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSMeasure(panda::JsiRuntimeCallInfo* runtimeCallInfo)
467 {
468     ACE_SCOPED_TRACE("ViewMeasureLayout::JSMeasure");
469     EcmaVM* vm = runtimeCallInfo->GetVM();
470     Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
471     auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
472         vm, 0));
473     CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
474     auto child = ptr->GetOrCreateChild();
475     if (!child) {
476         return panda::JSValueRef::Undefined(vm);
477     }
478 
479     auto childLayoutConstraint = ptr->CreateChildConstraint();
480     auto layoutProperty = child->GetLayoutProperty();
481     auto info = runtimeCallInfo;
482     if (info->GetArgsNumber() >= 1 && info->GetCallArgRef(0)->IsObject(vm)) {
483         auto jsObject = JsiObject(info->GetCallArgRef(0)->ToObject(vm));
484         JSRef<JSObject> sizeObj = JSRef<JSObject>::Make(jsObject);
485         CalcDimension minWidth;
486         if (JSViewAbstract::ParseJsDimensionVp(sizeObj->GetProperty("minWidth"), minWidth)) {
487             if (layoutProperty) {
488                 layoutProperty->UpdateCalcMinSize(NG::CalcSize(NG::CalcLength(minWidth), std::nullopt));
489             } else {
490                 auto length = ConvertToPx(NG::CalcLength(minWidth), childLayoutConstraint.scaleProperty,
491                     childLayoutConstraint.percentReference.Width());
492                 if (length) {
493                     childLayoutConstraint.minSize.SetWidth(length.value());
494                 }
495             }
496         }
497 
498         CalcDimension maxWidth;
499         if (JSViewAbstract::ParseJsDimensionVp(sizeObj->GetProperty("maxWidth"), maxWidth)) {
500             if (layoutProperty) {
501                 layoutProperty->UpdateCalcMaxSize(NG::CalcSize(NG::CalcLength(maxWidth), std::nullopt));
502             } else {
503                 auto length = ConvertToPx(NG::CalcLength(maxWidth), childLayoutConstraint.scaleProperty,
504                     childLayoutConstraint.percentReference.Width());
505                 if (length) {
506                     childLayoutConstraint.maxSize.SetWidth(length.value());
507                 }
508             }
509         }
510 
511         CalcDimension minHeight;
512         if (JSViewAbstract::ParseJsDimensionVp(sizeObj->GetProperty("minHeight"), minHeight)) {
513             if (layoutProperty) {
514                 layoutProperty->UpdateCalcMinSize(NG::CalcSize(std::nullopt, NG::CalcLength(minHeight)));
515             } else {
516                 auto length = ConvertToPx(NG::CalcLength(minHeight), childLayoutConstraint.scaleProperty,
517                     childLayoutConstraint.percentReference.Height());
518                 if (length) {
519                     childLayoutConstraint.minSize.SetHeight(length.value());
520                 }
521             }
522         }
523 
524         CalcDimension maxHeight;
525         if (JSViewAbstract::ParseJsDimensionVp(sizeObj->GetProperty("maxHeight"), maxHeight)) {
526             if (layoutProperty) {
527                 layoutProperty->UpdateCalcMaxSize(NG::CalcSize(std::nullopt, NG::CalcLength(maxHeight)));
528             } else {
529                 auto length = ConvertToPx(NG::CalcLength(maxHeight), childLayoutConstraint.scaleProperty,
530                     childLayoutConstraint.percentReference.Height());
531                 if (length) {
532                     childLayoutConstraint.maxSize.SetHeight(length.value());
533                 }
534             }
535         }
536     }
537     child->Measure(childLayoutConstraint);
538 
539     auto size = child->GetGeometryNode()->GetFrameSize();
540     ptr->UpdateSize(size);
541     Dimension measureWidth(size.Width(), DimensionUnit::PX);
542     Dimension measureHeight(size.Height(), DimensionUnit::PX);
543     Local<ObjectRef> measureResultObject = ObjectRef::New(vm);
544     measureResultObject->Set(vm, ToJSValue("width"), ToJSValue(measureWidth.ConvertToVp()));
545     measureResultObject->Set(vm, ToJSValue("height"), ToJSValue(measureHeight.ConvertToVp()));
546     return measureResultObject;
547 }
548 
JSLayout(panda::JsiRuntimeCallInfo * runtimeCallInfo)549 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSLayout(panda::JsiRuntimeCallInfo* runtimeCallInfo)
550 {
551     ACE_SCOPED_TRACE("ViewMeasureLayout::JSLayout");
552     EcmaVM* vm = runtimeCallInfo->GetVM();
553     Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
554     auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
555         vm, 0));
556     CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
557     auto child = ptr->GetChild();
558     if (!child) {
559         return panda::JSValueRef::Undefined(vm);
560     }
561 
562     auto info = runtimeCallInfo;
563     if (info->GetArgsNumber() != 1 || !info->GetCallArgRef(0)->IsObject(vm)) {
564         LOGE("JSLayout arg is wrong");
565         child->Layout();
566         return panda::JSValueRef::Undefined(vm);
567     }
568 
569     auto jsObject = JsiObject(info->GetCallArgRef(0)->ToObject(vm));
570     JSRef<JSObject> layoutInfo = JSRef<JSObject>::Make(jsObject);
571     JSRef<JSObject> sizeObj = layoutInfo->GetProperty("position");
572     JSRef<JSVal> xVal = sizeObj->GetProperty("x");
573     JSRef<JSVal> yVal = sizeObj->GetProperty("y");
574     CalcDimension dimenX;
575     CalcDimension dimenY;
576     auto xResult = JSViewAbstract::ParseJsDimensionVp(xVal, dimenX);
577     auto yResult = JSViewAbstract::ParseJsDimensionVp(yVal, dimenY);
578     if (!(xResult || yResult)) {
579         LOGE("the position prop is illegal");
580     } else {
581         child->GetGeometryNode()->SetMarginFrameOffset({ static_cast<float>(dimenX.ConvertToPx()),
582             static_cast<float>(dimenY.ConvertToPx()) });
583     }
584     child->Layout();
585 
586     return panda::JSValueRef::Undefined(vm);
587 }
588 
JSPlaceChildren(panda::JsiRuntimeCallInfo * runtimeCallInfo)589 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSPlaceChildren(panda::JsiRuntimeCallInfo* runtimeCallInfo)
590 {
591     ACE_SCOPED_TRACE("ViewMeasureLayout::JSPlaceChildren");
592     EcmaVM* vm = runtimeCallInfo->GetVM();
593     Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
594     auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
595         vm, 0));
596     CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
597     auto child = ptr->GetChild();
598     if (!child) {
599         return panda::JSValueRef::Undefined(vm);
600     }
601 
602     auto info = runtimeCallInfo;
603     if (info->GetArgsNumber() != 1 || !info->GetCallArgRef(0)->IsObject(vm)) {
604         LOGE("JSPlaceChildren arg is wrong");
605         child->Layout();
606         return panda::JSValueRef::Undefined(vm);
607     }
608 
609     auto jsObject = JsiObject(info->GetCallArgRef(0)->ToObject(vm));
610     JSRef<JSObject> layoutInfo = JSRef<JSObject>::Make(jsObject);
611     JSRef<JSVal> xVal = layoutInfo->GetProperty("x");
612     JSRef<JSVal> yVal = layoutInfo->GetProperty("y");
613     CalcDimension dimenX;
614     CalcDimension dimenY;
615     auto xResult = JSViewAbstract::ParseJsDimensionVp(xVal, dimenX);
616     auto yResult = JSViewAbstract::ParseJsDimensionVp(yVal, dimenY);
617     if (!(xResult || yResult)) {
618         LOGE("the position prop is illegal");
619     } else {
620         child->GetGeometryNode()->SetMarginFrameOffset({ static_cast<float>(dimenX.ConvertToPx()),
621             static_cast<float>(dimenY.ConvertToPx()) });
622     }
623     child->Layout();
624     return panda::JSValueRef::Undefined(vm);
625 }
626 
JSGetMargin(panda::JsiRuntimeCallInfo * runtimeCallInfo)627 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSGetMargin(panda::JsiRuntimeCallInfo* runtimeCallInfo)
628 {
629     EcmaVM* vm = runtimeCallInfo->GetVM();
630     Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
631     auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
632         vm, 0));
633     CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
634     auto child = ptr->GetOrCreateChild();
635     if (!(child && child->GetLayoutProperty())) {
636         return GenEdgesGlobalized({}, TextDirection::LTR).Get().GetLocalHandle();
637     }
638     auto layoutProperty = child->GetLayoutProperty();
639     auto direction = layoutProperty->GetNonAutoLayoutDirection();
640     return GenEdgesGlobalized(layoutProperty->CreateMarginWithoutCache(), direction).Get().GetLocalHandle();
641 }
642 
JSGetPadding(panda::JsiRuntimeCallInfo * runtimeCallInfo)643 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSGetPadding(panda::JsiRuntimeCallInfo* runtimeCallInfo)
644 {
645     EcmaVM* vm = runtimeCallInfo->GetVM();
646     Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
647     auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
648         vm, 0));
649     CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
650     auto child = ptr->GetOrCreateChild();
651     if (!(child && child->GetLayoutProperty())) {
652         return GenEdgesGlobalized({}, TextDirection::LTR).Get().GetLocalHandle();
653     }
654     auto layoutProperty = child->GetLayoutProperty();
655     auto direction = layoutProperty->GetNonAutoLayoutDirection();
656     return GenEdgesGlobalized(layoutProperty->CreatePaddingWithoutBorder(false, false), direction)
657         .Get()
658         .GetLocalHandle();
659 }
660 
JSGetBorderWidth(panda::JsiRuntimeCallInfo * runtimeCallInfo)661 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSGetBorderWidth(panda::JsiRuntimeCallInfo* runtimeCallInfo)
662 {
663     EcmaVM* vm = runtimeCallInfo->GetVM();
664     Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
665     auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
666         vm, 0));
667     CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
668     auto child = ptr->GetOrCreateChild();
669     if (!(child && child->GetLayoutProperty())) {
670         return GenBorderWidthGlobalized({}, TextDirection::LTR).Get().GetLocalHandle();
671     }
672     auto layoutProperty = child->GetLayoutProperty();
673     auto direction = layoutProperty->GetNonAutoLayoutDirection();
674     return GenBorderWidthGlobalized(layoutProperty->CreateBorder(), direction).Get().GetLocalHandle();
675 }
676 #endif
677 
678 } // namespace OHOS::Ace::Framework