• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/text_layout_property.h"
20 #include "core/components_ng/pattern/text_field/auto_fill_controller.h"
21 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
22 
23 namespace OHOS::Ace::NG {
24 
MeasureContent(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)25 std::optional<SizeF> TextInputLayoutAlgorithm::MeasureContent(
26     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
27 {
28     auto frameNode = layoutWrapper->GetHostNode();
29     CHECK_NULL_RETURN(frameNode, std::nullopt);
30     auto textFieldLayoutProperty = DynamicCast<TextFieldLayoutProperty>(layoutWrapper->GetLayoutProperty());
31     auto pattern = frameNode->GetPattern<TextFieldPattern>();
32     CHECK_NULL_RETURN(pattern, std::nullopt);
33 
34     // Construct text style.
35     TextStyle textStyle;
36     ConstructTextStyles(frameNode, textStyle, textContent_, showPlaceHolder_);
37     std::replace(textContent_.begin(), textContent_.end(), u'\n', u' ');
38 
39     auto isInlineStyle = pattern->IsNormalInlineState();
40     isInlineFocus_ = isInlineStyle && pattern->HasFocus();
41 
42     direction_ = textFieldLayoutProperty->GetLayoutDirection();
43 
44     // Create paragraph.
45     pattern->SetAdaptFontSize(std::nullopt);
46     auto disableTextAlign = !pattern->IsTextArea() && !showPlaceHolder_ && !isInlineStyle;
47     textFieldContentConstraint_ = CalculateContentMaxSizeWithCalculateConstraint(contentConstraint, layoutWrapper);
48     auto contentConstraintWithoutResponseArea =
49         BuildLayoutConstraintWithoutResponseArea(textFieldContentConstraint_, layoutWrapper);
50     if (IsNeedAdaptFontSize(textStyle, textFieldLayoutProperty, textFieldContentConstraint_)) {
51         if (!AddAdaptFontSizeAndAnimations(
52             textStyle, textFieldLayoutProperty, contentConstraintWithoutResponseArea, layoutWrapper)) {
53             return std::nullopt;
54         }
55         pattern->SetAdaptFontSize(textStyle.GetFontSize());
56     } else {
57         CreateParagraphEx(textStyle, textContent_, contentConstraint, layoutWrapper);
58     }
59 
60     autoWidth_ = textFieldLayoutProperty->GetWidthAutoValue(false);
61     isFontSizeNonPositive_ = IsFontSizeNonPositive(textStyle);
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 = textStyle.GetFontSize().ConvertToPxDistribute(
71             textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
72         auto paragraphData = CreateParagraphData { disableTextAlign, fontSize };
73         CreateInlineParagraph(textStyle, textContent_, false, pattern->GetNakedCharPosition(), paragraphData);
74         return InlineMeasureContent(contentConstraintWithoutResponseArea, layoutWrapper);
75     } else if (showPlaceHolder_) {
76         return PlaceHolderMeasureContent(contentConstraintWithoutResponseArea, layoutWrapper, 0);
77     } else {
78         return TextInputMeasureContent(contentConstraintWithoutResponseArea, layoutWrapper, 0);
79     }
80 }
81 
IsFontSizeNonPositive(const TextStyle & textStyle) const82 bool TextInputLayoutAlgorithm::IsFontSizeNonPositive(const TextStyle& textStyle) const
83 {
84     return textStyle.GetFontSize().IsNonPositive();
85 }
86 
Measure(LayoutWrapper * layoutWrapper)87 void TextInputLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
88 {
89     const auto& layoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint();
90     OptionalSizeF frameSize;
91     const auto& content = layoutWrapper->GetGeometryNode()->GetContent();
92     auto frameNode = layoutWrapper->GetHostNode();
93     CHECK_NULL_VOID(frameNode);
94     auto pattern = frameNode->GetPattern<TextFieldPattern>();
95     CHECK_NULL_VOID(pattern);
96     float contentWidth = 0.0f;
97     float contentHeight = 0.0f;
98     if (content) {
99         auto contentSize = content->GetRect().GetSize();
100         contentWidth = contentSize.Width();
101         contentHeight = contentSize.Height();
102     }
103     auto pipeline = frameNode->GetContext();
104     CHECK_NULL_VOID(pipeline);
105     auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>();
106     CHECK_NULL_VOID(textFieldTheme);
107     auto defaultHeight = GetDefaultHeightByType(layoutWrapper);
108 
109     auto responseAreaWidth = 0.0f;
110     if (pattern->GetCleanNodeResponseArea()) {
111         responseAreaWidth += pattern->GetCleanNodeResponseArea()->GetFrameSize().Width();
112     }
113     if (pattern->GetResponseArea()) {
114         responseAreaWidth += pattern->GetResponseArea()->GetFrameSize().Width();
115     }
116     frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingAndBorderSum() + responseAreaWidth);
117 
118     if (textFieldContentConstraint_.selfIdealSize.Height().has_value()) {
119         if (LessOrEqual(contentWidth, 0)) {
120             frameSize.SetHeight(textFieldContentConstraint_.maxSize.Height());
121         } else {
122             frameSize.SetHeight(
123                 textFieldContentConstraint_.maxSize.Height() + pattern->GetVerticalPaddingAndBorderSum());
124         }
125     } else {
126         auto height = LessNotEqual(contentHeight, defaultHeight)
127                           ? defaultHeight + pattern->GetVerticalPaddingAndBorderSum()
128                           : contentHeight + pattern->GetVerticalPaddingAndBorderSum();
129         frameSize.SetHeight(height);
130     }
131     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
132         frameSize.Constrain(layoutConstraint->minSize, layoutConstraint->maxSize);
133     } else if (!layoutWrapper->GetLayoutProperty()->GetLayoutRect()) {
134         auto frameSizeConstraint = CalculateFrameSizeConstraint(textFieldContentConstraint_, layoutWrapper);
135         auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(frameSize,
136             layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(),
137             layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference);
138         frameSize.SetHeight(finalSize.Height());
139         frameSize.Constrain(frameSizeConstraint.minSize, frameSizeConstraint.maxSize);
140     }
141     layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize.ConvertToSizeT());
142     MeasureAutoFillIcon(layoutWrapper);
143     MeasureCounterWithPolicy(layoutWrapper, responseAreaWidth + pattern->GetHorizontalPaddingAndBorderSum());
144 }
145 
Layout(LayoutWrapper * layoutWrapper)146 void TextInputLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
147 {
148     auto frameNode = layoutWrapper->GetHostNode();
149     CHECK_NULL_VOID(frameNode);
150     auto pattern = frameNode->GetPattern<TextFieldPattern>();
151     CHECK_NULL_VOID(pattern);
152     auto geometryNode = layoutWrapper->GetGeometryNode();
153     CHECK_NULL_VOID(geometryNode);
154     auto size = geometryNode->GetFrameSize() -
155                 SizeF(pattern->GetHorizontalPaddingAndBorderSum(), pattern->GetVerticalPaddingAndBorderSum());
156     const auto& content = geometryNode->GetContent();
157     CHECK_NULL_VOID(content);
158     SizeT<float> contentSize = content->GetRect().GetSize();
159     auto layoutProperty = DynamicCast<TextFieldLayoutProperty>(layoutWrapper->GetLayoutProperty());
160     CHECK_NULL_VOID(layoutProperty);
161     PipelineContext* context = frameNode->GetContext();
162     CHECK_NULL_VOID(context);
163     parentGlobalOffset_ = frameNode->GetPaintRectOffset(false, true) - context->GetRootRect().GetOffset();
164     Alignment align = Alignment::CENTER;
165     auto isRTL = layoutProperty->GetNonAutoLayoutDirection() == TextDirection::RTL;
166     if (layoutProperty->GetPositionProperty()) {
167         align = layoutProperty->GetPositionProperty()->GetAlignment().value_or(align);
168     }
169     auto border = pattern->GetBorderWidthProperty();
170     OffsetF offsetBase = OffsetF(pattern->GetPaddingLeft() + pattern->GetBorderLeft(border),
171         pattern->GetPaddingTop() + pattern->GetBorderTop(border));
172 
173     auto responseArea = pattern->GetResponseArea();
174     auto cleanNodeResponseArea = pattern->GetCleanNodeResponseArea();
175     auto unitNodeWidth = 0.0f;
176     if (responseArea) {
177         int32_t childIndex = frameNode->GetChildIndex(responseArea->GetFrameNode());
178         responseArea->Layout(layoutWrapper, childIndex, unitNodeWidth);
179     }
180     if (cleanNodeResponseArea) {
181         int32_t childIndex = frameNode->GetChildIndex(cleanNodeResponseArea->GetFrameNode());
182         cleanNodeResponseArea->Layout(layoutWrapper, childIndex, unitNodeWidth);
183     }
184 
185     UpdateContentPositionParams params = {
186         .isRTL = isRTL,
187         .offsetBase = offsetBase,
188         .size = size,
189         .contentSize = contentSize,
190         .align = align,
191         .responseArea = responseArea,
192         .cleanResponseArea = cleanNodeResponseArea
193     };
194     UpdateContentPosition(params, content);
195 
196     auto paintProperty = pattern->GetPaintProperty<TextFieldPaintProperty>();
197     CHECK_NULL_VOID(paintProperty);
198     UpdateTextRectParams updateTextRectParams = {
199         .layoutProperty = layoutProperty,
200         .pattern = pattern,
201         .contentSize = contentSize,
202         .isRTL = isRTL,
203         .responseArea = responseArea,
204         .cleanResponseArea = cleanNodeResponseArea,
205         .contentOffset = content->GetRect().GetOffset()
206     };
207     UpdateTextRect(updateTextRectParams);
208 
209     bool isInlineStyle = pattern->IsNormalInlineState();
210     if (layoutProperty->GetShowCounterValue(false) && layoutProperty->HasMaxLength() && !isInlineStyle) {
211         TextFieldLayoutAlgorithm::CounterLayout(layoutWrapper);
212     }
213     if (pattern->IsShowError()) {
214         TextFieldLayoutAlgorithm::ErrorLayout(layoutWrapper);
215     }
216     LayoutAutoFillIcon(layoutWrapper);
217 }
218 
UpdateContentPosition(const UpdateContentPositionParams & params,const std::unique_ptr<GeometryProperty> & content)219 void TextInputLayoutAlgorithm::UpdateContentPosition(const UpdateContentPositionParams &params,
220     const std::unique_ptr<GeometryProperty> &content)
221 {
222     OffsetF contentOffset =
223         params.offsetBase + Alignment::GetAlignPosition(params.size, params.contentSize, params.align);
224     auto offsetBaseX = params.offsetBase.GetX();
225     if (params.isRTL) {
226         if (params.responseArea) {
227             offsetBaseX += params.responseArea->GetAreaRect().Width();
228         }
229         if (params.cleanResponseArea) {
230             offsetBaseX += params.cleanResponseArea->GetAreaRect().Width();
231         }
232     }
233     content->SetOffset(OffsetF(offsetBaseX, contentOffset.GetY()));
234 }
235 
UpdateTextRect(const UpdateTextRectParams & params)236 void TextInputLayoutAlgorithm::UpdateTextRect(const UpdateTextRectParams& params)
237 {
238     if (LessOrEqual(textRect_.Width(), params.contentSize.Width())) {
239         float textRectOffsetX = 0.0f;
240         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
241             textRectOffsetX = params.pattern->GetPaddingLeft();
242         } else {
243             auto border = params.pattern->GetBorderWidthProperty();
244             textRectOffsetX = params.pattern->GetPaddingLeft() + params.pattern->GetBorderLeft(border);
245         }
246         bool isEmptyTextEditValue = params.pattern->GetTextUtf16Value().empty();
247         bool isInlineStyle = params.pattern->IsNormalInlineState();
248         if (!isEmptyTextEditValue && !isInlineStyle) {
249             TextAlign textAlign = params.layoutProperty->GetTextAlignValue(TextAlign::START);
250             params.pattern->CheckTextAlignByDirection(textAlign, direction_);
251         }
252         if (params.isRTL) {
253             if (params.responseArea) {
254                 RectF responseAreaRect = params.responseArea->GetAreaRect();
255                 textRectOffsetX += responseAreaRect.Width();
256             }
257             if (params.cleanResponseArea) {
258                 RectF cleanResponseAreaRect = params.cleanResponseArea->GetAreaRect();
259                 textRectOffsetX += cleanResponseAreaRect.Width();
260             }
261             textRect_.SetOffset(OffsetF(textRectOffsetX, params.contentOffset.GetY()));
262         } else {
263             textRect_.SetOffset(OffsetF(textRectOffsetX, params.contentOffset.GetY()));
264         }
265     } else {
266         textRect_.SetOffset({ params.pattern->GetTextRect().GetOffset().GetX(), params.contentOffset.GetY() });
267     }
268 }
269 
GetDefaultHeightByType(LayoutWrapper * layoutWrapper)270 float TextInputLayoutAlgorithm::GetDefaultHeightByType(LayoutWrapper* layoutWrapper)
271 {
272     auto frameNode = layoutWrapper->GetHostNode();
273     CHECK_NULL_RETURN(frameNode, 0.0f);
274     auto pipeline = frameNode->GetContext();
275     CHECK_NULL_RETURN(pipeline, 0.0f);
276     auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>();
277     CHECK_NULL_RETURN(textFieldTheme, 0.0f);
278     return static_cast<float>(textFieldTheme->GetContentHeight().ConvertToPx());
279 }
280 
CreateParagraphEx(const TextStyle & textStyle,const std::u16string & content,const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)281 bool TextInputLayoutAlgorithm::CreateParagraphEx(const TextStyle& textStyle, const std::u16string& content,
282     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
283 {
284     // update child position.
285     auto frameNode = layoutWrapper->GetHostNode();
286     CHECK_NULL_RETURN(frameNode, false);
287     auto pattern = frameNode->GetPattern<TextFieldPattern>();
288     CHECK_NULL_RETURN(pattern, false);
289     auto isInlineStyle = pattern->IsNormalInlineState();
290     auto isPasswordType = pattern->IsInPasswordMode();
291     auto disableTextAlign = false;
292     auto fontSize =
293         textStyle.GetFontSize().ConvertToPxDistribute(textStyle.GetMinFontScale(), textStyle.GetMaxFontScale());
294     auto paragraphData = CreateParagraphData { disableTextAlign, fontSize };
295     auto autofillController = pattern->GetOrCreateAutoFillController();
296     CHECK_NULL_RETURN(autofillController, false);
297     auto autoFillAnimationStatus = autofillController->GetAutoFillAnimationStatus();
298     if (autoFillAnimationStatus != AutoFillAnimationStatus::INIT) {
299         CreateAutoFillParagraph(textStyle, content, isPasswordType && pattern->GetTextObscured(),
300             pattern->GetNakedCharPosition(), paragraphData);
301         autofillController->SetAutoFillOriginTextColor(textStyle.GetTextColor());
302     } else {
303         if (pattern->IsDragging() && !showPlaceHolder_ && !isInlineStyle) {
304             CreateParagraph(textStyle, pattern->GetDragContents(), content,
305                 isPasswordType && pattern->GetTextObscured() && !showPlaceHolder_, paragraphData);
306         } else {
307             CreateParagraph(textStyle, content, isPasswordType && pattern->GetTextObscured() && !showPlaceHolder_,
308                 pattern->GetNakedCharPosition(), paragraphData);
309         }
310     }
311     return true;
312 }
313 
BuildLayoutConstraintWithoutResponseArea(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)314 LayoutConstraintF TextInputLayoutAlgorithm::BuildLayoutConstraintWithoutResponseArea(
315     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
316 {
317     auto frameNode = layoutWrapper->GetHostNode();
318     CHECK_NULL_RETURN(frameNode, contentConstraint);
319     auto pattern = frameNode->GetPattern<TextFieldPattern>();
320     CHECK_NULL_RETURN(pattern, contentConstraint);
321 
322     auto responseArea = pattern->GetResponseArea();
323     auto cleanNodeResponseArea = pattern->GetCleanNodeResponseArea();
324     float childWidth = 0.0f;
325     if (responseArea) {
326         auto childIndex = frameNode->GetChildIndex(responseArea->GetFrameNode());
327         childWidth += responseArea->Measure(layoutWrapper, childIndex).Width();
328     }
329     if (cleanNodeResponseArea) {
330         auto childIndex = frameNode->GetChildIndex(cleanNodeResponseArea->GetFrameNode());
331         childWidth += cleanNodeResponseArea->Measure(layoutWrapper, childIndex).Width();
332     }
333 
334     auto newLayoutConstraint = contentConstraint;
335     newLayoutConstraint.maxSize.SetWidth(std::max(newLayoutConstraint.maxSize.Width() - childWidth, 0.0f));
336     newLayoutConstraint.minSize.SetWidth(std::max(newLayoutConstraint.minSize.Width() - childWidth, 0.0f));
337     if (newLayoutConstraint.selfIdealSize.Width()) {
338         newLayoutConstraint.selfIdealSize.SetWidth(newLayoutConstraint.selfIdealSize.Width().value() - childWidth);
339     }
340     return newLayoutConstraint;
341 }
342 
MeasureAutoFillIcon(LayoutWrapper * layoutWrapper)343 void TextInputLayoutAlgorithm::MeasureAutoFillIcon(LayoutWrapper* layoutWrapper)
344 {
345     CHECK_NULL_VOID(layoutWrapper);
346     auto frameNode = layoutWrapper->GetHostNode();
347     CHECK_NULL_VOID(frameNode);
348     auto textFieldPattern = frameNode->GetPattern<TextFieldPattern>();
349     CHECK_NULL_VOID(textFieldPattern);
350     auto textFieldlayoutProperty = frameNode->GetLayoutProperty();
351     CHECK_NULL_VOID(textFieldlayoutProperty);
352     auto autofillController = textFieldPattern->GetOrCreateAutoFillController();
353     CHECK_NULL_VOID(autofillController);
354     auto weakAutoFillIcon = autofillController->GetAutoFillIconNode();
355     auto autoFillIcon =  weakAutoFillIcon.Upgrade();
356     CHECK_NULL_VOID(autoFillIcon);
357     auto autoFillIconIndex = frameNode->GetChildIndex(autoFillIcon);
358     auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(autoFillIconIndex);
359     CHECK_NULL_VOID(childWrapper);
360     auto iconGeometryNode = childWrapper->GetGeometryNode();
361     CHECK_NULL_VOID(iconGeometryNode);
362     auto iconLayoutProperty = AceType::DynamicCast<TextLayoutProperty>(childWrapper->GetLayoutProperty());
363     CHECK_NULL_VOID(iconLayoutProperty);
364     auto pipeline = frameNode->GetContext();
365     CHECK_NULL_VOID(pipeline);
366     auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>();
367     CHECK_NULL_VOID(textFieldTheme);
368     auto iconSize = iconLayoutProperty->GetFontSize().value_or(textFieldTheme->GetAutoFillIconSize());
369     auto iconHeight = iconSize.ConvertToPx();
370     CalcSize iconCalcSize;
371     iconCalcSize.SetWidth(CalcLength(iconHeight));
372     iconCalcSize.SetHeight(CalcLength(iconHeight));
373     iconLayoutProperty->UpdateUserDefinedIdealSize(iconCalcSize);
374     auto childLayoutConstraint = textFieldlayoutProperty->CreateChildConstraint();
375     childWrapper->Measure(childLayoutConstraint);
376     autoFillIconSizeMeasure_ = iconGeometryNode->GetFrameSize();
377 }
378 
LayoutAutoFillIcon(LayoutWrapper * layoutWrapper)379 void TextInputLayoutAlgorithm::LayoutAutoFillIcon(LayoutWrapper* layoutWrapper)
380 {
381     CHECK_NULL_VOID(layoutWrapper);
382     auto frameNode = layoutWrapper->GetHostNode();
383     CHECK_NULL_VOID(frameNode);
384     auto textFieldPattern = frameNode->GetPattern<TextFieldPattern>();
385     CHECK_NULL_VOID(textFieldPattern);
386     auto textFieldlayoutProperty = frameNode->GetLayoutProperty();
387     CHECK_NULL_VOID(textFieldlayoutProperty);
388     auto isRTL = textFieldlayoutProperty->GetNonAutoLayoutDirection() == TextDirection::RTL;
389     auto textFieldGeometryNode = layoutWrapper->GetGeometryNode();
390     CHECK_NULL_VOID(textFieldGeometryNode);
391     auto textFieldSize = textFieldGeometryNode->GetFrameSize();
392     auto textFieldFrameWidth = textFieldSize.Width();
393     auto textFieldFrameHeight = textFieldSize.Height();
394     auto autofillController = textFieldPattern->GetOrCreateAutoFillController();
395     CHECK_NULL_VOID(autofillController);
396     auto weakAutoFillIcon = autofillController->GetAutoFillIconNode();
397     auto autoFillIcon =  weakAutoFillIcon.Upgrade();
398     CHECK_NULL_VOID(autoFillIcon);
399     auto autoFillIconIndex = frameNode->GetChildIndex(autoFillIcon);
400     auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(autoFillIconIndex);
401     CHECK_NULL_VOID(childWrapper);
402     auto iconGeometryNode = childWrapper->GetGeometryNode();
403     CHECK_NULL_VOID(iconGeometryNode);
404     auto iconFrameWidth = autoFillIconSizeMeasure_.Width();
405     auto iconFrameHeight = autoFillIconSizeMeasure_.Height();
406 
407     auto padding = textFieldlayoutProperty->CreatePaddingAndBorder();
408     auto leftOffset = padding.left.value_or(0.0f);
409     auto rightOffset = padding.right.value_or(0.0f);
410     float iconHorizontalOffset = isRTL ? textFieldFrameWidth - iconFrameWidth - rightOffset : leftOffset;
411     // Vertically center-align text
412     auto half = 2.0f;
413     float iconVerticalOffset = textRect_.Top() + textRect_.Height() / half - autoFillIconSizeMeasure_.Height() / half;
414     // Vertically center-align textinput
415     if (GreatOrEqual(iconFrameHeight, textFieldFrameHeight)) {
416         iconVerticalOffset = -(iconFrameHeight - textFieldFrameHeight) / half;
417     } else if (LessNotEqual(iconVerticalOffset, 0.0f)) {
418         iconVerticalOffset = 0.0f;
419     } else if (GreatNotEqual(iconVerticalOffset + iconFrameHeight, textFieldFrameHeight)) {
420         iconVerticalOffset = iconVerticalOffset - (iconVerticalOffset + iconFrameHeight - textFieldFrameHeight);
421     }
422 
423     OffsetF iconOffset(iconHorizontalOffset, iconVerticalOffset);
424     iconGeometryNode->SetMarginFrameOffset(iconOffset);
425     childWrapper->Layout();
426 }
427 
MeasureCounterWithPolicy(LayoutWrapper * layoutWrapper,float nonContentWidth)428 void TextInputLayoutAlgorithm::MeasureCounterWithPolicy(LayoutWrapper* layoutWrapper, float nonContentWidth)
429 {
430     CHECK_NULL_VOID(layoutWrapper);
431     auto widthLayoutPolicy = TextBase::GetLayoutCalPolicy(layoutWrapper, true);
432     if (widthLayoutPolicy != LayoutCalPolicy::NO_MATCH) {
433         auto frameSize = layoutWrapper->GetGeometryNode()->GetFrameSize();
434         auto counterWidth = frameSize.Width() - nonContentWidth;
435         CounterNodeMeasure(counterWidth, layoutWrapper);
436     }
437 }
438 } // namespace OHOS::Ace::NG
439