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