1 /*
2  * Copyright (c) 2023 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 "core/components_ng/pattern/text_input/text_input_layout_algorithm.h"
17 
18 #include "base/utils/utils.h"
19 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
20 
21 namespace OHOS::Ace::NG {
22 namespace {
23     constexpr Dimension ERROR_TEXT_UNDERLINE_MARGIN = 8.0_vp;
24     constexpr Dimension ERROR_TEXT_CAPSULE_MARGIN = 8.0_vp;
25 } // namespace
26 
MeasureContent(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)27 std::optional<SizeF> TextInputLayoutAlgorithm::MeasureContent(
28     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
29 {
30     auto frameNode = layoutWrapper->GetHostNode();
31     CHECK_NULL_RETURN(frameNode, std::nullopt);
32     auto textFieldLayoutProperty = DynamicCast<TextFieldLayoutProperty>(layoutWrapper->GetLayoutProperty());
33     auto pattern = frameNode->GetPattern<TextFieldPattern>();
34     CHECK_NULL_RETURN(pattern, std::nullopt);
35 
36     // Construct text style.
37     TextStyle textStyle;
38     ConstructTextStyles(frameNode, textStyle, textContent_, showPlaceHolder_);
39     std::replace(textContent_.begin(), textContent_.end(), '\n', ' ');
40 
41     auto isInlineStyle = pattern->IsNormalInlineState();
42 
43     direction_ = textFieldLayoutProperty->GetLayoutDirection();
44 
45     // Create paragraph.
46     pattern->SetAdaptFontSize(std::nullopt);
47     auto disableTextAlign = !pattern->IsTextArea() && !showPlaceHolder_ && !isInlineStyle;
48     textFieldContentConstraint_ = CalculateContentMaxSizeWithCalculateConstraint(contentConstraint, layoutWrapper);
49     auto contentConstraintWithoutResponseArea =
50         BuildLayoutConstraintWithoutResponseArea(textFieldContentConstraint_, layoutWrapper);
51     if (IsNeedAdaptFontSize(textStyle, textFieldLayoutProperty, textFieldContentConstraint_)) {
52         if (!AddAdaptFontSizeAndAnimations(
53             textStyle, textFieldLayoutProperty, contentConstraintWithoutResponseArea, layoutWrapper)) {
54             return std::nullopt;
55         }
56         pattern->SetAdaptFontSize(textStyle.GetFontSize());
57     } else {
58         CreateParagraphEx(textStyle, textContent_, contentConstraint, layoutWrapper);
59     }
60 
61     autoWidth_ = textFieldLayoutProperty->GetWidthAutoValue(false);
62 
63     if (textContent_.empty()) {
64         // Used for empty text.
65         preferredHeight_ = pattern->PreferredLineHeight(true);
66     }
67 
68     // Paragraph layout.
69     if (isInlineStyle) {
70         auto fontSize = pattern->FontSizeConvertToPx(textStyle.GetFontSize());
71         auto paragraphData = CreateParagraphData { disableTextAlign, fontSize };
72         CreateInlineParagraph(textStyle, textContent_, false, pattern->GetNakedCharPosition(), paragraphData);
73         return InlineMeasureContent(contentConstraintWithoutResponseArea, layoutWrapper);
74     } else if (showPlaceHolder_) {
75         return PlaceHolderMeasureContent(contentConstraintWithoutResponseArea, layoutWrapper, 0);
76     } else {
77         return TextInputMeasureContent(contentConstraintWithoutResponseArea, layoutWrapper, 0);
78     }
79 }
80 
Measure(LayoutWrapper * layoutWrapper)81 void TextInputLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
82 {
83     const auto& layoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint();
84     OptionalSizeF frameSize;
85     const auto& content = layoutWrapper->GetGeometryNode()->GetContent();
86     auto frameNode = layoutWrapper->GetHostNode();
87     CHECK_NULL_VOID(frameNode);
88     auto pattern = frameNode->GetPattern<TextFieldPattern>();
89     CHECK_NULL_VOID(pattern);
90     float contentWidth = 0.0f;
91     float contentHeight = 0.0f;
92     if (content) {
93         auto contentSize = content->GetRect().GetSize();
94         contentWidth = contentSize.Width();
95         contentHeight = contentSize.Height();
96     }
97     auto pipeline = frameNode->GetContext();
98     CHECK_NULL_VOID(pipeline);
99     auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>();
100     CHECK_NULL_VOID(textFieldTheme);
101     auto defaultHeight = GetDefaultHeightByType(layoutWrapper);
102 
103     auto responseAreaWidth = 0.0f;
104     if (pattern->GetCleanNodeResponseArea()) {
105         responseAreaWidth += pattern->GetCleanNodeResponseArea()->GetFrameSize().Width();
106     }
107     if (pattern->GetResponseArea()) {
108         responseAreaWidth += pattern->GetResponseArea()->GetFrameSize().Width();
109     }
110     frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingAndBorderSum() + responseAreaWidth);
111 
112     if (textFieldContentConstraint_.selfIdealSize.Height().has_value()) {
113         if (LessOrEqual(contentWidth, 0)) {
114             frameSize.SetHeight(textFieldContentConstraint_.maxSize.Height());
115         } else {
116             frameSize.SetHeight(
117                 textFieldContentConstraint_.maxSize.Height() + pattern->GetVerticalPaddingAndBorderSum());
118         }
119     } else {
120         auto height = LessNotEqual(contentHeight, defaultHeight)
121                           ? defaultHeight + pattern->GetVerticalPaddingAndBorderSum()
122                           : contentHeight + pattern->GetVerticalPaddingAndBorderSum();
123         frameSize.SetHeight(height);
124     }
125     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
126         frameSize.Constrain(layoutConstraint->minSize, layoutConstraint->maxSize);
127     } else if (!layoutWrapper->GetLayoutProperty()->GetLayoutRect()) {
128         auto frameSizeConstraint = CalculateFrameSizeConstraint(textFieldContentConstraint_, layoutWrapper);
129         auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(frameSize,
130             layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(),
131             layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference);
132         frameSize.SetHeight(finalSize.Height());
133         frameSize.Constrain(frameSizeConstraint.minSize, frameSizeConstraint.maxSize);
134     }
135     layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize.ConvertToSizeT());
136 }
137 
PrepareErrorTextNode(LayoutWrapper * layoutWrapper)138 void PrepareErrorTextNode(LayoutWrapper* layoutWrapper)
139 {
140     auto host = layoutWrapper->GetHostNode();
141     CHECK_NULL_VOID(host);
142     auto pattern = host->GetPattern<TextFieldPattern>();
143     CHECK_NULL_VOID(pattern);
144     auto textNode = pattern->GetErrorNode().Upgrade();
145     CHECK_NULL_VOID(textNode);
146     auto theme = pattern->GetTheme();
147     CHECK_NULL_VOID(theme);
148     auto textNodeLayoutProperty = AceType::DynamicCast<TextLayoutProperty>(textNode->GetLayoutProperty());
149     CHECK_NULL_VOID(textNodeLayoutProperty);
150 
151     TextStyle errorTextStyle = theme->GetErrorTextStyle(); // update content
152     auto errorText = pattern->GetErrorTextString();
153     StringUtils::TransformStrCase(errorText, static_cast<int32_t>(errorTextStyle.GetTextCase()));
154     textNodeLayoutProperty->UpdateContent(errorText);
155 }
156 
157 // calculate width constraint according to width of Counter and TextInput
BeforeErrorLayout(LayoutWrapper * layoutWrapper)158 void BeforeErrorLayout(LayoutWrapper* layoutWrapper)
159 {
160     PrepareErrorTextNode(layoutWrapper);
161     auto host = layoutWrapper->GetHostNode();
162     CHECK_NULL_VOID(host);
163     auto pattern = host->GetPattern<TextFieldPattern>();
164     CHECK_NULL_VOID(pattern);
165     auto geometryNode = host->GetGeometryNode();
166     CHECK_NULL_VOID(geometryNode);
167     auto textNode = pattern->GetErrorNode().Upgrade();
168     CHECK_NULL_VOID(textNode);
169     RectF textFieldFrameRect = geometryNode->GetFrameRect(); // calculate layoutWidth
170     auto errorValue = pattern->GetErrorTextString();
171     if (pattern->IsShowError() && !pattern->IsDisabled() && !errorValue.empty()) {
172         float padding = 0.0f;
173         auto textFieldLayoutProperty = pattern->GetLayoutProperty<TextFieldLayoutProperty>();
174         if (textFieldLayoutProperty && textFieldLayoutProperty->GetPaddingProperty()) {
175             const auto& paddingProperty = textFieldLayoutProperty->GetPaddingProperty();
176             padding = paddingProperty->left.value_or(CalcLength(0.0f)).GetDimension().ConvertToPx() +
177                 paddingProperty->right.value_or(CalcLength(0.0f)).GetDimension().ConvertToPx();
178         }
179         float layoutWidth = textFieldFrameRect.Width() - padding; // subtract border width
180         auto localBorder = pattern->GetBorderWidthProperty();
181         float borderWidth = pattern->GetBorderLeft(localBorder) + pattern->GetBorderRight(localBorder);
182         borderWidth = std::max(borderWidth, 0.0f);
183         layoutWidth -= borderWidth;
184         auto counterDecoratorWrapper = pattern->GetCounterNode().Upgrade();
185         if (pattern->IsShowCount() && counterDecoratorWrapper) {
186             auto counterDecorator = counterDecoratorWrapper->GetHostNode();
187             if (counterDecorator) { // subtract counter length
188                 float counterWidth = pattern->CalcDecoratorWidth(counterDecorator);
189                 layoutWidth -= counterWidth;
190             }
191         }
192         LayoutConstraintF invisibleConstraint;
193         invisibleConstraint.UpdateMaxSizeWithCheck({0.0f, 0.0f});
194         if (LessOrEqual(layoutWidth, 0.0f)) {
195             textNode->Measure(invisibleConstraint);
196             return;
197         }
198         LayoutConstraintF textContentConstraint;
199         textContentConstraint.UpdateMaxSizeWithCheck({layoutWidth, Infinity<float>()});
200         auto textNodeLayoutWrapper = host->GetOrCreateChildByIndex(host->GetChildIndex(textNode));
201         if (textNodeLayoutWrapper) {
202             textNode->Measure(textContentConstraint);
203             if (GreatNotEqual(pattern->CalcDecoratorWidth(textNode), layoutWidth)) {
204                 textNode->Measure(invisibleConstraint);
205             }
206         }
207     }
208 }
209 
ErrorLayout(LayoutWrapper * layoutWrapper)210 void ErrorLayout(LayoutWrapper* layoutWrapper)
211 {
212     BeforeErrorLayout(layoutWrapper);
213     auto decoratedNode = layoutWrapper->GetHostNode();
214     CHECK_NULL_VOID(decoratedNode);
215     RefPtr<TextFieldPattern> textFieldPattern = decoratedNode->GetPattern<TextFieldPattern>();
216     CHECK_NULL_VOID(textFieldPattern);
217     auto textFieldLayoutProperty = decoratedNode->GetLayoutProperty<TextFieldLayoutProperty>();
218     CHECK_NULL_VOID(textFieldLayoutProperty);
219     auto textFieldGeometryNode = decoratedNode->GetGeometryNode();
220     CHECK_NULL_VOID(textFieldGeometryNode);
221     auto textNode = textFieldPattern->GetErrorNode().Upgrade();
222     CHECK_NULL_VOID(textNode);
223     auto textGeometryNode = textNode->GetGeometryNode();
224     CHECK_NULL_VOID(textGeometryNode);
225 
226     float errorMargin = 0.0f;
227     if (textFieldLayoutProperty->GetShowUnderlineValue(false) && textFieldPattern->IsShowError()) {
228         errorMargin = ERROR_TEXT_UNDERLINE_MARGIN.ConvertToPx();
229     } else if (textFieldPattern->NeedShowPasswordIcon() && textFieldPattern->IsShowError()) {
230         errorMargin = ERROR_TEXT_CAPSULE_MARGIN.ConvertToPx();
231     } else if (textFieldPattern->IsShowError()) {
232         errorMargin = ERROR_TEXT_CAPSULE_MARGIN.ConvertToPx();
233     } else {
234         errorMargin = 0;
235     }
236 
237     auto textFrameRect = textFieldGeometryNode->GetFrameRect();
238     auto offset = textFieldGeometryNode->GetContentOffset();
239     auto isRTL = textFieldLayoutProperty->GetNonAutoLayoutDirection() == TextDirection::RTL;
240     auto offSetX = offset.GetX();
241     if (isRTL) {
242         auto textFieldContentRect = textFieldGeometryNode->GetContentRect();
243         offSetX += textFieldContentRect.Width() - textGeometryNode->GetFrameRect().Width();
244     }
245 
246     textGeometryNode->SetFrameOffset(OffsetF(offSetX, textFrameRect.Bottom() - textFrameRect.Top() + errorMargin));
247     textNode->Layout();
248 }
249 
Layout(LayoutWrapper * layoutWrapper)250 void TextInputLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
251 {
252     auto frameNode = layoutWrapper->GetHostNode();
253     CHECK_NULL_VOID(frameNode);
254     auto pattern = frameNode->GetPattern<TextFieldPattern>();
255     CHECK_NULL_VOID(pattern);
256     auto size = layoutWrapper->GetGeometryNode()->GetFrameSize() -
257                 SizeF(pattern->GetHorizontalPaddingAndBorderSum(), pattern->GetVerticalPaddingAndBorderSum());
258     const auto& content = layoutWrapper->GetGeometryNode()->GetContent();
259     CHECK_NULL_VOID(content);
260     SizeT<float> contentSize = content->GetRect().GetSize();
261     auto layoutProperty = DynamicCast<TextFieldLayoutProperty>(layoutWrapper->GetLayoutProperty());
262     CHECK_NULL_VOID(layoutProperty);
263     PipelineContext* context = layoutWrapper->GetHostNode()->GetContext();
264     CHECK_NULL_VOID(context);
265     parentGlobalOffset_ = layoutWrapper->GetHostNode()->GetPaintRectOffset() - context->GetRootRect().GetOffset();
266     Alignment align = Alignment::CENTER;
267     auto isRTL = layoutProperty->GetNonAutoLayoutDirection() == TextDirection::RTL;
268     auto hasAlign = false;
269     if (layoutProperty->GetPositionProperty()) {
270         align = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().value_or(align);
271         hasAlign = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().has_value();
272     }
273     auto border = pattern->GetBorderWidthProperty();
274     OffsetF offsetBase = OffsetF(pattern->GetPaddingLeft() + pattern->GetBorderLeft(border),
275         pattern->GetPaddingTop() + pattern->GetBorderTop(border));
276 
277     auto responseArea = pattern->GetResponseArea();
278     auto cleanNodeResponseArea = pattern->GetCleanNodeResponseArea();
279     auto unitNodeWidth = 0.0f;
280     if (responseArea) {
281         int32_t childIndex = frameNode->GetChildIndex(responseArea->GetFrameNode());
282         responseArea->Layout(layoutWrapper, childIndex, unitNodeWidth);
283     }
284     if (cleanNodeResponseArea) {
285         int32_t childIndex = frameNode->GetChildIndex(cleanNodeResponseArea->GetFrameNode());
286         cleanNodeResponseArea->Layout(layoutWrapper, childIndex, unitNodeWidth);
287     }
288 
289     UpdateContentPositionParams params = {
290         .isRTL = isRTL,
291         .offsetBase = offsetBase,
292         .size = size,
293         .contentSize = contentSize,
294         .align = align,
295         .responseArea = responseArea,
296         .cleanResponseArea = cleanNodeResponseArea
297     };
298     UpdateContentPosition(params, content);
299 
300     auto paintProperty = pattern->GetPaintProperty<TextFieldPaintProperty>();
301     CHECK_NULL_VOID(paintProperty);
302     UpdateTextRectParams updateTextRectParams = {
303         .layoutProperty = layoutProperty,
304         .pattern = pattern,
305         .contentSize = contentSize,
306         .isRTL = isRTL,
307         .responseArea = responseArea,
308         .cleanResponseArea = cleanNodeResponseArea,
309         .contentOffset = content->GetRect().GetOffset()
310     };
311     UpdateTextRect(updateTextRectParams);
312 
313     bool isInlineStyle = pattern->IsNormalInlineState();
314     if (layoutProperty->GetShowCounterValue(false) && layoutProperty->HasMaxLength() && !isInlineStyle) {
315         TextFieldLayoutAlgorithm::CounterLayout(layoutWrapper);
316     }
317     if (pattern->IsShowError()) {
318         ErrorLayout(layoutWrapper);
319     }
320 }
321 
UpdateContentPosition(const UpdateContentPositionParams & params,const std::unique_ptr<GeometryProperty> & content)322 void TextInputLayoutAlgorithm::UpdateContentPosition(const UpdateContentPositionParams &params,
323     const std::unique_ptr<GeometryProperty> &content)
324 {
325     OffsetF contentOffset =
326         params.offsetBase + Alignment::GetAlignPosition(params.size, params.contentSize, params.align);
327     auto offsetBaseX = params.offsetBase.GetX();
328     if (params.isRTL) {
329         if (params.responseArea) {
330             offsetBaseX += params.responseArea->GetAreaRect().Width();
331         }
332         if (params.cleanResponseArea) {
333             offsetBaseX += params.cleanResponseArea->GetAreaRect().Width();
334         }
335     }
336     content->SetOffset(OffsetF(offsetBaseX, contentOffset.GetY()));
337 }
338 
UpdateTextRect(const UpdateTextRectParams & params)339 void TextInputLayoutAlgorithm::UpdateTextRect(const UpdateTextRectParams& params)
340 {
341     if (LessOrEqual(textRect_.Width(), params.contentSize.Width())) {
342         float textRectOffsetX = 0.0f;
343         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
344             textRectOffsetX = params.pattern->GetPaddingLeft();
345         } else {
346             auto border = params.pattern->GetBorderWidthProperty();
347             textRectOffsetX = params.pattern->GetPaddingLeft() + params.pattern->GetBorderLeft(border);
348         }
349         bool isEmptyTextEditValue = params.pattern->GetTextValue().empty();
350         bool isInlineStyle = params.pattern->IsNormalInlineState();
351         if (!isEmptyTextEditValue && !isInlineStyle) {
352             TextAlign textAlign = params.layoutProperty->GetTextAlignValue(TextAlign::START);
353             params.pattern->CheckTextAlignByDirection(textAlign, direction_);
354         }
355         if (params.isRTL) {
356             if (params.responseArea) {
357                 RectF responseAreaRect = params.responseArea->GetAreaRect();
358                 textRectOffsetX += responseAreaRect.Width();
359             }
360             if (params.cleanResponseArea) {
361                 RectF cleanResponseAreaRect = params.cleanResponseArea->GetAreaRect();
362                 textRectOffsetX += cleanResponseAreaRect.Width();
363             }
364             textRect_.SetOffset(OffsetF(textRectOffsetX, params.contentOffset.GetY()));
365         } else {
366             textRect_.SetOffset(OffsetF(textRectOffsetX, params.contentOffset.GetY()));
367         }
368     } else {
369         textRect_.SetOffset({ params.pattern->GetTextRect().GetOffset().GetX(), params.contentOffset.GetY() });
370     }
371 }
372 
GetDefaultHeightByType(LayoutWrapper * layoutWrapper)373 float TextInputLayoutAlgorithm::GetDefaultHeightByType(LayoutWrapper* layoutWrapper)
374 {
375     auto frameNode = layoutWrapper->GetHostNode();
376     CHECK_NULL_RETURN(frameNode, 0.0f);
377     auto pipeline = frameNode->GetContext();
378     CHECK_NULL_RETURN(pipeline, 0.0f);
379     auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>();
380     CHECK_NULL_RETURN(textFieldTheme, 0.0f);
381     return static_cast<float>(textFieldTheme->GetContentHeight().ConvertToPx());
382 }
383 
CreateParagraphEx(const TextStyle & textStyle,const std::string & content,const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)384 bool TextInputLayoutAlgorithm::CreateParagraphEx(const TextStyle& textStyle, const std::string& content,
385     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
386 {
387     // update child position.
388     auto frameNode = layoutWrapper->GetHostNode();
389     CHECK_NULL_RETURN(frameNode, false);
390     auto pattern = frameNode->GetPattern<TextFieldPattern>();
391     CHECK_NULL_RETURN(pattern, false);
392     auto isInlineStyle = pattern->IsNormalInlineState();
393     auto isPasswordType = pattern->IsInPasswordMode();
394     auto disableTextAlign = false;
395     auto fontSize = pattern->FontSizeConvertToPx(textStyle.GetFontSize());
396     auto paragraphData = CreateParagraphData { disableTextAlign, fontSize };
397 
398     if (pattern->IsDragging() && !showPlaceHolder_ && !isInlineStyle) {
399         CreateParagraph(textStyle, pattern->GetDragContents(), content,
400             isPasswordType && pattern->GetTextObscured() && !showPlaceHolder_, paragraphData);
401     } else {
402         CreateParagraph(textStyle, content, isPasswordType && pattern->GetTextObscured() && !showPlaceHolder_,
403             pattern->GetNakedCharPosition(), paragraphData);
404     }
405     return true;
406 }
407 
BuildLayoutConstraintWithoutResponseArea(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)408 LayoutConstraintF TextInputLayoutAlgorithm::BuildLayoutConstraintWithoutResponseArea(
409     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
410 {
411     auto frameNode = layoutWrapper->GetHostNode();
412     CHECK_NULL_RETURN(frameNode, contentConstraint);
413     auto pattern = frameNode->GetPattern<TextFieldPattern>();
414     CHECK_NULL_RETURN(pattern, contentConstraint);
415 
416     auto responseArea = pattern->GetResponseArea();
417     auto cleanNodeResponseArea = pattern->GetCleanNodeResponseArea();
418     float childWidth = 0.0f;
419     if (responseArea) {
420         auto childIndex = frameNode->GetChildIndex(responseArea->GetFrameNode());
421         childWidth += responseArea->Measure(layoutWrapper, childIndex).Width();
422     }
423     if (cleanNodeResponseArea) {
424         auto childIndex = frameNode->GetChildIndex(cleanNodeResponseArea->GetFrameNode());
425         childWidth += cleanNodeResponseArea->Measure(layoutWrapper, childIndex).Width();
426     }
427 
428     auto newLayoutConstraint = contentConstraint;
429     newLayoutConstraint.maxSize.SetWidth(std::max(newLayoutConstraint.maxSize.Width() - childWidth, 0.0f));
430     newLayoutConstraint.minSize.SetWidth(std::max(newLayoutConstraint.minSize.Width() - childWidth, 0.0f));
431     if (newLayoutConstraint.selfIdealSize.Width()) {
432         newLayoutConstraint.selfIdealSize.SetWidth(newLayoutConstraint.selfIdealSize.Width().value() - childWidth);
433     }
434     return newLayoutConstraint;
435 }
436 } // namespace OHOS::Ace::NG
437