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 ¶ms,
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