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