• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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_field/text_field_layout_algorithm.h"
17 
18 #include "base/geometry/axis.h"
19 #include "base/geometry/dimension.h"
20 #include "base/geometry/ng/rect_t.h"
21 #include "base/geometry/ng/size_t.h"
22 #include "base/i18n/localization.h"
23 #include "base/log/log_wrapper.h"
24 #include "base/memory/referenced.h"
25 #include "base/utils/utils.h"
26 #include "bridge/common/utils/utils.h"
27 #include "core/common/font_manager.h"
28 #include "core/components_ng/pattern/text/text_layout_adapter.h"
29 #include "core/components_ng/pattern/text/text_styles.h"
30 #include "core/components_ng/pattern/text_field/text_field_content_modifier.h"
31 #include "core/components_ng/pattern/text_field/text_field_layout_property.h"
32 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
33 #include "core/components_ng/pattern/text_field/text_selector.h"
34 #include "core/components_ng/property/measure_utils.h"
35 #include "core/pipeline_ng/pipeline_context.h"
36 
37 namespace OHOS::Ace::NG {
38 namespace {
39 constexpr float PARAGRAPH_SAVE_BOUNDARY = 1.0f;
40 constexpr uint32_t INLINE_DEFAULT_VIEW_MAXLINE = 3;
41 constexpr double TEXT_DECORATION_DISABLED_COLOR_ALPHA = 0.2;
42 constexpr Dimension INLINE_MIN_WITH = 16.0_vp;
43 
IsNeedUpdateCounterWidth(const LayoutConstraintF & contentConstraint,float maxParagraphWidth,float contentWidth)44 bool IsNeedUpdateCounterWidth(const LayoutConstraintF& contentConstraint,
45     float maxParagraphWidth, float contentWidth)
46 {
47     auto maxContentWidth = contentConstraint.maxSize.Width();
48     auto minContentWidth = contentConstraint.minSize.Width();
49     if (GreatNotEqual(minContentWidth, 0.0) && GreatNotEqual(maxContentWidth, minContentWidth) &&
50         GreatNotEqual(maxParagraphWidth, 0.0) && GreatNotEqual(contentWidth, maxParagraphWidth)) {
51         return true;
52     } else {
53         return false;
54     }
55 }
56 } // namespace
ConstructTextStyles(const RefPtr<FrameNode> & frameNode,TextStyle & textStyle,std::u16string & textContent,bool & showPlaceHolder)57 void TextFieldLayoutAlgorithm::ConstructTextStyles(
58     const RefPtr<FrameNode>& frameNode, TextStyle& textStyle, std::u16string& textContent, bool& showPlaceHolder)
59 {
60     CHECK_NULL_VOID(frameNode);
61     auto pipeline = frameNode->GetContext();
62     CHECK_NULL_VOID(pipeline);
63     auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>(frameNode->GetThemeScopeId());
64     CHECK_NULL_VOID(textFieldTheme);
65     auto pattern = frameNode->GetPattern<TextFieldPattern>();
66     CHECK_NULL_VOID(pattern);
67     auto textFieldLayoutProperty = pattern->GetLayoutProperty<TextFieldLayoutProperty>();
68     CHECK_NULL_VOID(textFieldLayoutProperty);
69     auto textFieldPaintProperty = pattern->GetPaintProperty<TextFieldPaintProperty>();
70     CHECK_NULL_VOID(textFieldPaintProperty);
71     auto isInlineStyle = pattern->IsNormalInlineState();
72     auto isTextArea = pattern->IsTextArea();
73     UpdateTextStyleFontScale(textFieldLayoutProperty, textStyle, pattern);
74     if (!pattern->GetTextUtf16Value().empty()) {
75         UpdateTextStyle(frameNode, textFieldLayoutProperty, textFieldTheme, textStyle, pattern->IsDisabled(),
76             textFieldPaintProperty->HasTextColorFlagByUser());
77         textContent = pattern->GetTextUtf16Value();
78         UpdateTextStyleTextOverflowAndWordBreak(textStyle, isTextArea, isInlineStyle, textFieldLayoutProperty,
79             textFieldTheme->TextFadeoutEnabled());
80     } else {
81         UpdatePlaceholderTextStyle(
82             frameNode, textFieldLayoutProperty, textFieldTheme, textStyle, pattern->IsDisabled(),
83             textFieldPaintProperty->GetPlaceholderColorFlagByUserValue(false));
84         textContent = textFieldLayoutProperty->GetPlaceholderValue(u"");
85         showPlaceHolder = true;
86     }
87 
88     textIndent_ = textStyle.GetTextIndent();
89     auto fontManager = pipeline->GetFontManager();
90     if (fontManager && !(fontManager->GetAppCustomFont().empty()) &&
91         !(textFieldLayoutProperty->GetFontFamily().has_value())) {
92         textStyle.SetFontFamilies(Framework::ConvertStrToFontFamilies(fontManager->GetAppCustomFont()));
93     }
94     // use for modifier.
95     auto contentModifier = pattern->GetContentModifier();
96     CHECK_NULL_VOID(contentModifier);
97     SetPropertyToModifier(textStyle, contentModifier);
98     contentModifier->ModifyTextStyle(textStyle);
99     contentModifier->SetFontReady(false);
100 }
101 
UpdateTextStyleTextOverflowAndWordBreak(TextStyle & textStyle,bool isTextArea,bool isInlineStyle,const RefPtr<TextFieldLayoutProperty> & textFieldLayoutProperty,bool isTextFadeout)102 void TextFieldLayoutAlgorithm::UpdateTextStyleTextOverflowAndWordBreak(TextStyle& textStyle, bool isTextArea,
103     bool isInlineStyle, const RefPtr<TextFieldLayoutProperty>& textFieldLayoutProperty, bool isTextFadeout)
104 {
105     CHECK_NULL_VOID(textFieldLayoutProperty);
106     if (textFieldLayoutProperty->HasTextOverflow() &&
107         textFieldLayoutProperty->GetTextOverflow() != TextOverflow::DEFAULT) {
108         textStyle.SetTextOverflow(textFieldLayoutProperty->GetTextOverflow().value());
109     } else {
110         auto overflowStyle =
111             (!isTextArea && isInlineStyle && !isTextFadeout) ? TextOverflow::ELLIPSIS : TextOverflow::CLIP;
112         textStyle.SetTextOverflow(overflowStyle);
113     }
114 
115     if (isTextArea || isInlineStyle) {
116         textStyle.SetWordBreak(textFieldLayoutProperty->GetWordBreak().value_or(WordBreak::BREAK_WORD));
117     }
118     // Not Support TextOverflow::MARQUEE Now
119     if (textStyle.GetTextOverflow() == TextOverflow::MARQUEE) {
120         if (!isTextArea && isInlineStyle) {
121             textStyle.SetTextOverflow(TextOverflow::ELLIPSIS);
122         } else {
123             textStyle.SetTextOverflow(TextOverflow::CLIP);
124         }
125     }
126     if (textFieldLayoutProperty->HasEllipsisMode() && textStyle.GetTextOverflow() == TextOverflow::ELLIPSIS) {
127         textStyle.SetEllipsisMode(textFieldLayoutProperty->GetEllipsisModeValue(EllipsisMode::TAIL));
128     }
129 }
130 
InlineFocusMeasure(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper,double & safeBoundary,float & contentWidth)131 void TextFieldLayoutAlgorithm::InlineFocusMeasure(const LayoutConstraintF& contentConstraint,
132     LayoutWrapper* layoutWrapper, double& safeBoundary, float& contentWidth)
133 {
134     ApplyIndent(layoutWrapper, contentConstraint.maxSize.Width());
135     paragraph_->Layout(
136         contentConstraint.maxSize.Width() - static_cast<float>(safeBoundary) - PARAGRAPH_SAVE_BOUNDARY);
137     auto longestLine = std::ceil(paragraph_->GetLongestLineWithIndent());
138     paragraph_->Layout(std::min(static_cast<float>(longestLine), paragraph_->GetMaxWidth()));
139     contentWidth = ConstraintWithMinWidth(
140         contentConstraint, layoutWrapper, paragraph_, static_cast<float>(safeBoundary) + PARAGRAPH_SAVE_BOUNDARY);
141 }
142 
InlineMeasureContent(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)143 std::optional<SizeF> TextFieldLayoutAlgorithm::InlineMeasureContent(const LayoutConstraintF& contentConstraint,
144     LayoutWrapper* layoutWrapper)
145 {
146     auto frameNode = layoutWrapper->GetHostNode();
147     CHECK_NULL_RETURN(frameNode, std::nullopt);
148     auto textFieldLayoutProperty = DynamicCast<TextFieldLayoutProperty>(layoutWrapper->GetLayoutProperty());
149     CHECK_NULL_RETURN(textFieldLayoutProperty, std::nullopt);
150     auto pattern = frameNode->GetPattern<TextFieldPattern>();
151     CHECK_NULL_RETURN(pattern, std::nullopt);
152     auto textFieldTheme = pattern->GetTheme();
153     CHECK_NULL_RETURN(textFieldTheme, std::nullopt);
154 
155     float contentWidth = 0.0f;
156     auto safeBoundary = textFieldTheme->GetInlineBorderWidth().ConvertToPx() * 2;
157     if (pattern->HasFocus()) {
158         InlineFocusMeasure(contentConstraint, layoutWrapper, safeBoundary, contentWidth);
159     } else {
160         ApplyIndent(layoutWrapper, contentConstraint.maxSize.Width());
161         paragraph_->Layout(contentConstraint.maxSize.Width());
162         if (autoWidth_) {
163             auto paragraphLongestLine = std::ceil(paragraph_->GetLongestLineWithIndent());
164             paragraph_->Layout(std::min(static_cast<float>(paragraphLongestLine), paragraph_->GetMaxWidth()));
165         }
166         contentWidth = ConstraintWithMinWidth(contentConstraint, layoutWrapper, paragraph_);
167         // calc inline status in advance
168         auto widthOffSet = contentConstraint.selfIdealSize.Width().has_value()?
169             pattern->GetPaddingLeft() + pattern->GetPaddingRight() - safeBoundary : 0.0f - safeBoundary;
170         inlineParagraph_->Layout(contentConstraint.maxSize.Width() + widthOffSet
171             - safeBoundary - PARAGRAPH_SAVE_BOUNDARY);
172         auto longestLine = std::ceil(inlineParagraph_->GetLongestLineWithIndent());
173         inlineParagraph_->Layout(std::min(static_cast<float>(longestLine), inlineParagraph_->GetMaxWidth()));
174         auto inlineContentWidth = ConstraintWithMinWidth(contentConstraint, layoutWrapper, inlineParagraph_,
175             static_cast<float>(safeBoundary) + PARAGRAPH_SAVE_BOUNDARY);
176         inlineMeasureItem_.inlineScrollRectOffsetX = contentWidth
177             + pattern->GetHorizontalPaddingAndBorderSum() - inlineContentWidth - safeBoundary - PARAGRAPH_SAVE_BOUNDARY;
178     }
179 
180     textRect_.SetSize(SizeF(GetVisualTextWidth(), paragraph_->GetHeight()));
181 
182     auto inlineIdealHeight = contentConstraint.maxSize.Height();
183     GetInlineMeasureItem(contentConstraint, layoutWrapper, inlineIdealHeight);
184     auto contentHeight = GreatNotEqual(paragraph_->GetLongestLine(), 0.0)
185         ? paragraph_->GetHeight() : std::max(preferredHeight_, paragraph_->GetHeight());
186     auto minWidth = INLINE_MIN_WITH.ConvertToPx();
187     contentWidth = GreatNotEqual(contentWidth, minWidth) ? contentWidth : minWidth;
188     return SizeF(contentWidth, std::min(inlineIdealHeight, contentHeight));
189 }
190 
GetInlineMeasureItem(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper,float & inlineIdealHeight)191 void TextFieldLayoutAlgorithm::GetInlineMeasureItem(
192     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, float& inlineIdealHeight)
193 {
194     auto frameNode = layoutWrapper->GetHostNode();
195     CHECK_NULL_VOID(frameNode);
196     auto textFieldLayoutProperty = DynamicCast<TextFieldLayoutProperty>(layoutWrapper->GetLayoutProperty());
197     CHECK_NULL_VOID(textFieldLayoutProperty);
198     auto pattern = frameNode->GetPattern<TextFieldPattern>();
199     CHECK_NULL_VOID(pattern);
200 
201     if (pattern->HasFocus() && paragraph_->GetLineCount() != 0) {
202         pattern->SetSingleLineHeight(paragraph_->GetHeight() / paragraph_->GetLineCount());
203         // The maximum height of the inline mode defaults to a maximum of three rows.
204         inlineIdealHeight =
205             pattern->GetSingleLineHeight() * textFieldLayoutProperty->GetMaxViewLinesValue(INLINE_DEFAULT_VIEW_MAXLINE);
206         inlineMeasureItem_.inlineSizeHeight = pattern->GetSingleLineHeight() * std::min(
207             static_cast<uint32_t>(paragraph_->GetLineCount()),
208                 textFieldLayoutProperty->GetMaxViewLinesValue(INLINE_DEFAULT_VIEW_MAXLINE));
209     } else {
210         // calc inline status in advance
211         CalcInlineMeasureItem(layoutWrapper);
212     }
213 }
214 
ApplyIndent(LayoutWrapper * layoutWrapper,double width)215 void TextFieldLayoutAlgorithm::ApplyIndent(LayoutWrapper* layoutWrapper, double width)
216 {
217     if (LessOrEqual(textIndent_.Value(), 0.0)) {
218         return;
219     }
220     // first line indent
221     CHECK_NULL_VOID(paragraph_);
222     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
223     CHECK_NULL_VOID(pipeline);
224     auto frameNode = layoutWrapper->GetHostNode();
225     CHECK_NULL_VOID(frameNode);
226     auto textFieldLayoutProperty = DynamicCast<TextFieldLayoutProperty>(layoutWrapper->GetLayoutProperty());
227     CHECK_NULL_VOID(textFieldLayoutProperty);
228     auto pattern = frameNode->GetPattern<TextFieldPattern>();
229     CHECK_NULL_VOID(pattern);
230 
231     double indentValue = 0.0;
232     if (textIndent_.Unit() != DimensionUnit::PERCENT) {
233         float minFontScale = textFieldLayoutProperty->GetMinFontScale().value_or(0.0f);
234         float maxFontScale = textFieldLayoutProperty->GetMaxFontScale().value_or(
235             pipeline->GetMaxAppFontScale());
236         float fontScale = std::min(pipeline->GetFontScale(), maxFontScale);
237         indentValue = Dimension(indentValue).ConvertToPxDistribute(minFontScale, maxFontScale);
238         if (!textIndent_.NormalizeToPx(pipeline->GetDipScale(),
239             fontScale, pipeline->GetLogicScale(), width, indentValue)) {
240             return;
241         }
242     } else {
243         indentValue = width * textIndent_.Value();
244     }
245     indent_ = static_cast<float>(indentValue);
246     std::vector<float> indents;
247     // only indent first line
248     indents.emplace_back(indent_);
249     indents.emplace_back(0.0);
250     paragraph_->SetIndents(indents);
251 }
252 
CalcInlineMeasureItem(LayoutWrapper * layoutWrapper)253 void TextFieldLayoutAlgorithm::CalcInlineMeasureItem(LayoutWrapper* layoutWrapper)
254 {
255     auto textFieldLayoutProperty = DynamicCast<TextFieldLayoutProperty>(layoutWrapper->GetLayoutProperty());
256     CHECK_NULL_VOID(textFieldLayoutProperty);
257     auto lineCount = inlineParagraph_->GetLineCount() != 0 ? inlineParagraph_->GetLineCount() : 1;
258     inlineMeasureItem_.inlineSizeHeight = inlineParagraph_->GetHeight() / lineCount
259         * std::min(static_cast<uint32_t>(lineCount),
260             textFieldLayoutProperty->GetMaxViewLinesValue(INLINE_DEFAULT_VIEW_MAXLINE));
261     inlineMeasureItem_.inlineContentRectHeight = GreatNotEqual(inlineParagraph_->GetLongestLine(), 0.0)
262         ? inlineParagraph_->GetHeight() : std::max(preferredHeight_, inlineParagraph_->GetHeight());
263     inlineMeasureItem_.inlineLastOffsetY =
264         std::max(inlineMeasureItem_.inlineSizeHeight, inlineMeasureItem_.inlineContentRectHeight)
265         - std::min(inlineMeasureItem_.inlineSizeHeight, inlineMeasureItem_.inlineContentRectHeight);
266 }
267 
ConstraintWithMinWidth(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper,RefPtr<Paragraph> & paragraph,float removeValue)268 float TextFieldLayoutAlgorithm::ConstraintWithMinWidth(
269     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper,
270     RefPtr<Paragraph>& paragraph, float removeValue)
271 {
272     CHECK_NULL_RETURN(paragraph, 0.0f);
273     CHECK_NULL_RETURN(layoutWrapper, 0.0f);
274     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN) &&
275         !layoutWrapper->GetLayoutProperty()->GetLayoutRect()) {
276         const auto& calcLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint();
277         if (calcLayoutConstraint && calcLayoutConstraint->minSize.has_value() &&
278             calcLayoutConstraint->minSize->Width().has_value() &&
279             !contentConstraint.selfIdealSize.Width().has_value()) {
280             auto width = std::max(contentConstraint.minSize.Width() - removeValue, paragraph->GetLongestLine());
281             if (width != paragraph->GetLongestLine()) {
282                 paragraph->Layout(width);
283             } else {
284                 if (LessNotEqual(paragraph->GetLongestLine(), paragraph->GetMaxWidth())) {
285                     paragraph->Layout(std::ceil(paragraph->GetLongestLine()));
286                 }
287                 return contentConstraint.selfIdealSize.Width().has_value() ? paragraph->GetMaxWidth()
288                                                                            : GetVisualTextWidth();
289             }
290         }
291     }
292     return std::max(paragraph->GetMaxWidth(), 0.0f);
293 }
294 
PlaceHolderMeasureContent(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper,float imageWidth)295 SizeF TextFieldLayoutAlgorithm::PlaceHolderMeasureContent(const LayoutConstraintF& contentConstraint,
296     LayoutWrapper* layoutWrapper, float imageWidth)
297 {
298     paragraph_->Layout(contentConstraint.maxSize.Width() - imageWidth);
299 
300     // Adapts to auto width.
301     if (autoWidth_) {
302         auto minWidth = static_cast<float>(INLINE_MIN_WITH.ConvertToPx());
303         paragraph_->Layout(std::max(minWidth, std::ceil(paragraph_->GetLongestLine())));
304     }
305 
306     auto contentWidth = ConstraintWithMinWidth(contentConstraint, layoutWrapper, paragraph_, imageWidth);
307 
308     auto frameNode = layoutWrapper->GetHostNode();
309     CHECK_NULL_RETURN(frameNode, SizeF());
310     auto pattern = frameNode->GetPattern<TextFieldPattern>();
311     CHECK_NULL_RETURN(pattern, SizeF());
312     if (pattern->GetTextInputFlag()) {
313         // TextInput's counter is outside the input area
314         auto reviseContentWidth = contentWidth + imageWidth;
315         CounterNodeMeasure(reviseContentWidth, layoutWrapper);
316     } else {
317         // TextArea's counter is inside the input area
318         CounterNodeMeasure(contentWidth, layoutWrapper);
319     }
320 
321     float height = 0.0f;
322     if (isFontSizeNonPositive_) {
323         height = paragraph_->GetHeight();
324     } else {
325         height = GreatNotEqual(paragraph_->GetLongestLine(), 0.0) ? paragraph_->GetHeight()
326                                                                   : std::max(preferredHeight_, paragraph_->GetHeight());
327     }
328 
329     auto contentHeight = std::min(contentConstraint.maxSize.Height(), height);
330 
331     textRect_.SetSize(SizeF(GetVisualTextWidth(), paragraph_->GetHeight()));
332 
333     return SizeF(contentWidth, contentHeight);
334 }
335 
TextAreaMeasureContent(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)336 SizeF TextFieldLayoutAlgorithm::TextAreaMeasureContent(const LayoutConstraintF& contentConstraint,
337     LayoutWrapper* layoutWrapper)
338 {
339     ACE_LAYOUT_SCOPED_TRACE("TextAreaMeasureContent");
340     ApplyIndent(layoutWrapper, contentConstraint.maxSize.Width());
341     paragraph_->Layout(contentConstraint.maxSize.Width());
342 
343     auto contentWidth = ConstraintWithMinWidth(contentConstraint, layoutWrapper, paragraph_);
344 
345     if (autoWidth_) {
346         contentWidth = std::min(contentWidth, paragraph_->GetLongestLineWithIndent());
347         auto minWidth = INLINE_MIN_WITH.ConvertToPx();
348         contentWidth = GreatNotEqual(contentWidth, minWidth) ? contentWidth : minWidth;
349         paragraph_->Layout(std::ceil(contentWidth));
350     }
351 
352     auto counterNodeHeight = CounterNodeMeasure(contentWidth, layoutWrapper);
353 
354     auto height = GreatNotEqual(paragraph_->GetLongestLine(), 0.0)
355                       ? paragraph_->GetHeight()
356                       : std::max(preferredHeight_, paragraph_->GetHeight());
357 
358     auto contentHeight = std::min(contentConstraint.maxSize.Height() - counterNodeHeight, height);
359 
360     textRect_.SetSize(SizeF(GetVisualTextWidth(), paragraph_->GetHeight()));
361     return SizeF(contentWidth, contentHeight);
362 }
363 
TextInputMeasureContent(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper,float imageWidth)364 SizeF TextFieldLayoutAlgorithm::TextInputMeasureContent(const LayoutConstraintF& contentConstraint,
365     LayoutWrapper* layoutWrapper, float imageWidth)
366 {
367     ACE_LAYOUT_SCOPED_TRACE("TextInputMeasureContent");
368     ApplyIndent(layoutWrapper, contentConstraint.maxSize.Width());
369     paragraph_->Layout(std::numeric_limits<double>::infinity());
370     float contentWidth = CalculateContentWidth(contentConstraint, layoutWrapper, imageWidth);
371     float contentHeight = CalculateContentHeight(contentConstraint);
372     textRect_.SetSize(SizeF(std::max(0.0f, paragraph_->GetLongestLine()) + indent_, paragraph_->GetHeight()));
373     return SizeF(contentWidth, contentHeight);
374 }
375 
CalculateContentWidth(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper,float imageWidth)376 float TextFieldLayoutAlgorithm::CalculateContentWidth(const LayoutConstraintF& contentConstraint,
377     LayoutWrapper* layoutWrapper, float imageWidth)
378 {
379     auto contentWidth = contentConstraint.maxSize.Width() - imageWidth;
380     auto textFieldWidth = contentWidth;
381 
382     std::optional<SizeF> minSize;
383     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN) &&
384         !layoutWrapper->GetLayoutProperty()->GetLayoutRect()) {
385         const auto &calcLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint();
386         if (calcLayoutConstraint && calcLayoutConstraint->minSize.has_value() &&
387             calcLayoutConstraint->minSize->Width().has_value() &&
388             !contentConstraint.selfIdealSize.Width().has_value()) {
389             minSize = contentConstraint.minSize;
390         }
391     }
392     if (minSize.has_value()) {
393         auto minWidth = minSize.value().Width();
394         paragraph_->Layout(std::max(std::ceil(paragraph_->GetLongestLineWithIndent()), minWidth));
395     } else if (autoWidth_) {
396         paragraph_->Layout(std::ceil(paragraph_->GetLongestLineWithIndent()));
397     } else {
398         paragraph_->Layout(std::max(std::ceil(paragraph_->GetLongestLineWithIndent()), textFieldWidth));
399     }
400     auto counterWidth = contentWidth;
401     auto maxParagraphWidth = paragraph_->GetMaxWidth();
402     if (autoWidth_ || IsNeedUpdateCounterWidth(contentConstraint, maxParagraphWidth, contentWidth)) {
403         counterWidth = maxParagraphWidth;
404     }
405     CounterNodeMeasure(counterWidth, layoutWrapper);
406     if (autoWidth_) {
407         double minWidth = INLINE_MIN_WITH.ConvertToPx();
408         contentWidth = GreatNotEqual(contentWidth, minWidth) ? contentWidth : minWidth;
409         contentWidth = std::min(contentWidth, std::ceil(paragraph_->GetLongestLineWithIndent()));
410     }
411 
412     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN) &&
413         !layoutWrapper->GetLayoutProperty()->GetLayoutRect()) {
414         const auto &calcLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint();
415         if (calcLayoutConstraint && calcLayoutConstraint->minSize.has_value() &&
416             calcLayoutConstraint->minSize->Width().has_value() &&
417             !contentConstraint.selfIdealSize.Width().has_value()) {
418             contentWidth = std::min(contentConstraint.maxSize.Width() - imageWidth,
419                 std::max(std::ceil(paragraph_->GetLongestLineWithIndent()),
420                 contentConstraint.minSize.Width() - imageWidth));
421         }
422     }
423     return contentWidth;
424 }
425 
CalculateContentHeight(const LayoutConstraintF & contentConstraint)426 float TextFieldLayoutAlgorithm::CalculateContentHeight(const LayoutConstraintF& contentConstraint)
427 {
428     auto height = GreatNotEqual(paragraph_->GetLongestLine(), 0.0)
429                       ? paragraph_->GetHeight()
430                       : std::max(preferredHeight_, paragraph_->GetHeight());
431 
432     return std::min(contentConstraint.maxSize.Height(), height);
433 }
434 
CounterLayout(LayoutWrapper * layoutWrapper)435 void TextFieldLayoutAlgorithm::CounterLayout(LayoutWrapper* layoutWrapper)
436 {
437     CHECK_NULL_VOID(layoutWrapper);
438     auto frameNode = layoutWrapper->GetHostNode();
439     CHECK_NULL_VOID(frameNode);
440     auto pattern = frameNode->GetPattern<TextFieldPattern>();
441     CHECK_NULL_VOID(pattern);
442     auto counterDecorator = pattern->GetCounterDecorator();
443     CHECK_NULL_VOID(counterDecorator);
444     counterDecorator->LayoutDecorator();
445 }
446 
ErrorLayout(LayoutWrapper * layoutWrapper)447 void TextFieldLayoutAlgorithm::ErrorLayout(LayoutWrapper* layoutWrapper)
448 {
449     auto frameNode = layoutWrapper->GetHostNode();
450     CHECK_NULL_VOID(frameNode);
451     auto pattern = frameNode->GetPattern<TextFieldPattern>();
452     CHECK_NULL_VOID(pattern);
453     auto errorDecorator = pattern->GetErrorDecorator();
454     CHECK_NULL_VOID(errorDecorator);
455     errorDecorator->LayoutDecorator();
456 }
457 
CounterNodeMeasure(float contentWidth,LayoutWrapper * layoutWrapper)458 float TextFieldLayoutAlgorithm::CounterNodeMeasure(float contentWidth, LayoutWrapper* layoutWrapper)
459 {
460     CHECK_NULL_RETURN(layoutWrapper, 0.0f);
461     auto frameNode = layoutWrapper->GetHostNode();
462     CHECK_NULL_RETURN(frameNode, 0.0f);
463     auto pattern = frameNode->GetPattern<TextFieldPattern>();
464     CHECK_NULL_RETURN(pattern, 0.0f);
465     auto counterDecorator = pattern->GetCounterDecorator();
466     CHECK_NULL_RETURN(counterDecorator, 0.0f);
467     return counterDecorator->MeasureDecorator(contentWidth, textContent_, showPlaceHolder_);
468 }
469 
GetVisualTextWidth() const470 float TextFieldLayoutAlgorithm::GetVisualTextWidth() const
471 {
472     return std::min(paragraph_->GetMaxWidth(), std::max(0.0f, paragraph_->GetLongestLine()));
473 }
474 
UpdateTextStyleFontScale(const RefPtr<TextFieldLayoutProperty> & textFieldLayoutProperty,TextStyle & textStyle,const RefPtr<TextFieldPattern> & pattern)475 void TextFieldLayoutAlgorithm::UpdateTextStyleFontScale(const RefPtr<TextFieldLayoutProperty>& textFieldLayoutProperty,
476     TextStyle& textStyle, const RefPtr<TextFieldPattern>& pattern)
477 {
478     if (textFieldLayoutProperty->HasMaxFontScale()) {
479         textStyle.SetMaxFontScale(textFieldLayoutProperty->GetMaxFontScale().value());
480     }
481     if (textFieldLayoutProperty->HasMinFontScale()) {
482         textStyle.SetMinFontScale(textFieldLayoutProperty->GetMinFontScale().value());
483     }
484 }
485 
UpdateTextStyleSetTextColor(const RefPtr<FrameNode> & frameNode,const RefPtr<TextFieldLayoutProperty> & layoutProperty,const RefPtr<TextFieldTheme> & theme,TextStyle & textStyle,bool isDisabled,bool isTextColorByUser)486 void TextFieldLayoutAlgorithm::UpdateTextStyleSetTextColor(const RefPtr<FrameNode>& frameNode,
487     const RefPtr<TextFieldLayoutProperty>& layoutProperty, const RefPtr<TextFieldTheme>& theme,
488     TextStyle& textStyle, bool isDisabled, bool isTextColorByUser)
489 {
490     CHECK_NULL_VOID(frameNode);
491     CHECK_NULL_VOID(layoutProperty);
492     CHECK_NULL_VOID(theme);
493     auto renderContext = frameNode->GetRenderContext();
494     CHECK_NULL_VOID(renderContext);
495     if (renderContext->HasForegroundColor()) {
496         auto textColor = renderContext->GetForegroundColor().value();
497         if (isDisabled) {
498             textColor = textColor.BlendOpacity(theme->GetDisableOpacityRatio());
499         }
500         textStyle.SetTextColor(textColor);
501     } else if (renderContext->HasForegroundColorStrategy()) {
502         if (isDisabled) {
503             textStyle.SetTextColor(theme->GetDisableTextColor());
504         } else {
505             textStyle.SetTextColor(Color::BLACK);
506         }
507     } else {
508         if (isDisabled) {
509             textStyle.SetTextColor(theme->GetDisableTextColor());
510         } else {
511             if (!isTextColorByUser) {
512                 layoutProperty->UpdateTextColor(theme ? theme->GetTextColor() : textStyle.GetTextColor());
513             }
514             textStyle.SetTextColor(
515                 layoutProperty->GetTextColorValue(theme ? theme->GetTextColor() : textStyle.GetTextColor()));
516         }
517     }
518 }
519 
UpdateTextStyle(const RefPtr<FrameNode> & frameNode,const RefPtr<TextFieldLayoutProperty> & layoutProperty,const RefPtr<TextFieldTheme> & theme,TextStyle & textStyle,bool isDisabled,bool isTextColorByUser)520 void TextFieldLayoutAlgorithm::UpdateTextStyle(const RefPtr<FrameNode>& frameNode,
521     const RefPtr<TextFieldLayoutProperty>& layoutProperty, const RefPtr<TextFieldTheme>& theme,
522     TextStyle& textStyle, bool isDisabled, bool isTextColorByUser)
523 {
524     CHECK_NULL_VOID(layoutProperty);
525     CHECK_NULL_VOID(theme);
526     const std::vector<std::string> defaultFontFamily = { "sans-serif" };
527     textStyle.SetFontFamilies(layoutProperty->GetFontFamilyValue(defaultFontFamily));
528     FontRegisterCallback(frameNode, textStyle.GetFontFamilies());
529 
530     Dimension fontSize = theme->GetFontSize();
531     if (layoutProperty->HasFontSize() && layoutProperty->GetFontSize().value_or(Dimension()).IsNonNegative()) {
532         fontSize = Dimension(layoutProperty->GetFontSizeValue(Dimension()).ConvertToPxDistribute(
533             textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale()));
534     }
535     textStyle.SetFontSize(fontSize);
536     textStyle.SetTextAlign(layoutProperty->GetTextAlignValue(TextAlign::START));
537     textStyle.SetLineBreakStrategy(layoutProperty->GetLineBreakStrategyValue(LineBreakStrategy::GREEDY));
538     textStyle.SetFontWeight(layoutProperty->GetFontWeightValue(theme->GetFontWeight()));
539     UpdateTextStyleSetTextColor(frameNode, layoutProperty, theme, textStyle, isDisabled, isTextColorByUser);
540     if (layoutProperty->GetMaxLines()) {
541         textStyle.SetMaxLines(layoutProperty->GetMaxLines().value());
542     }
543     if (layoutProperty->HasItalicFontStyle()) {
544         textStyle.SetFontStyle(layoutProperty->GetItalicFontStyle().value());
545     }
546     if (layoutProperty->HasTextAlign()) {
547         textStyle.SetTextAlign(layoutProperty->GetTextAlign().value());
548     }
549     UpdateTextStyleMore(frameNode, layoutProperty, textStyle, isDisabled);
550 }
551 
UpdatePlaceholderTextStyleSetTextColor(const RefPtr<TextFieldLayoutProperty> & layoutProperty,const RefPtr<TextFieldTheme> & theme,TextStyle & textStyle,bool isDisabled,bool isTextColorByUser)552 void TextFieldLayoutAlgorithm::UpdatePlaceholderTextStyleSetTextColor(
553     const RefPtr<TextFieldLayoutProperty>& layoutProperty, const RefPtr<TextFieldTheme>& theme, TextStyle& textStyle,
554     bool isDisabled, bool isTextColorByUser)
555 {
556     CHECK_NULL_VOID(layoutProperty);
557     CHECK_NULL_VOID(theme);
558     if (isTextColorByUser) {
559         auto textColor = layoutProperty->GetPlaceholderTextColorValue(theme->GetPlaceholderColor());
560         if (isDisabled) {
561             textColor = textColor.BlendOpacity(theme->GetDisableOpacityRatio());
562         }
563         textStyle.SetTextColor(textColor);
564     } else {
565         if (isDisabled) {
566             textStyle.SetTextColor(theme->GetDisableTextColor());
567         } else {
568             auto placeholderTextColor = theme ? theme->GetPlaceholderColor() : textStyle.GetTextColor();
569             layoutProperty->UpdatePlaceholderTextColor(placeholderTextColor);
570             textStyle.SetTextColor(layoutProperty->GetPlaceholderTextColorValue(placeholderTextColor));
571         }
572     }
573 }
574 
UpdatePlaceholderTextStyle(const RefPtr<FrameNode> & frameNode,const RefPtr<TextFieldLayoutProperty> & layoutProperty,const RefPtr<TextFieldTheme> & theme,TextStyle & textStyle,bool isDisabled,bool isTextColorByUser)575 void TextFieldLayoutAlgorithm::UpdatePlaceholderTextStyle(const RefPtr<FrameNode>& frameNode,
576     const RefPtr<TextFieldLayoutProperty>& layoutProperty, const RefPtr<TextFieldTheme>& theme, TextStyle& textStyle,
577     bool isDisabled, bool isTextColorByUser)
578 {
579     CHECK_NULL_VOID(frameNode);
580     CHECK_NULL_VOID(layoutProperty);
581     CHECK_NULL_VOID(theme);
582     const std::vector<std::string> defaultFontFamily = { "sans-serif" };
583     textStyle.SetFontFamilies(layoutProperty->GetPlaceholderFontFamilyValue(defaultFontFamily));
584     FontRegisterCallback(frameNode, textStyle.GetFontFamilies());
585 
586     Dimension fontSize;
587     if (layoutProperty->GetPlaceholderValue(u"").empty()) {
588         if (layoutProperty->HasFontSize() && layoutProperty->GetFontSize().value_or(Dimension()).IsNonNegative()) {
589             fontSize = layoutProperty->GetFontSizeValue(Dimension());
590         } else {
591             fontSize = theme->GetFontSize();
592         }
593     } else {
594         if (layoutProperty->HasPlaceholderFontSize() &&
595             layoutProperty->GetPlaceholderFontSize().value_or(Dimension()).IsNonNegative()) {
596             fontSize = layoutProperty->GetPlaceholderFontSizeValue(Dimension());
597         } else {
598             fontSize = theme->GetFontSize();
599         }
600     }
601 
602     textStyle.SetFontSize(fontSize);
603     textStyle.SetFontWeight(layoutProperty->GetPlaceholderFontWeightValue(theme->GetFontWeight()));
604     UpdatePlaceholderTextStyleSetTextColor(layoutProperty, theme, textStyle, isDisabled, isTextColorByUser);
605     if (layoutProperty->HasPlaceholderMaxLines()) {
606         textStyle.SetMaxLines(layoutProperty->GetPlaceholderMaxLines().value());
607     }
608     if (layoutProperty->HasPlaceholderItalicFontStyle()) {
609         textStyle.SetFontStyle(layoutProperty->GetPlaceholderItalicFontStyle().value());
610     }
611     if (layoutProperty->HasPlaceholderTextAlign()) {
612         textStyle.SetTextAlign(layoutProperty->GetPlaceholderTextAlign().value());
613     }
614     textStyle.SetTextOverflow(TextOverflow::ELLIPSIS);
615     textStyle.SetTextAlign(layoutProperty->GetTextAlignValue(TextAlign::START));
616     UpdatePlaceholderTextStyleMore(frameNode, layoutProperty, theme, textStyle, isDisabled);
617 }
618 
CalculateContentMaxSizeWithCalculateConstraint(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)619 LayoutConstraintF TextFieldLayoutAlgorithm::CalculateContentMaxSizeWithCalculateConstraint(
620     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
621 {
622     auto textFieldContentConstraint = contentConstraint;
623     CHECK_NULL_RETURN(layoutWrapper, textFieldContentConstraint);
624     auto frameNode = layoutWrapper->GetHostNode();
625     CHECK_NULL_RETURN(frameNode, textFieldContentConstraint);
626     auto pattern = frameNode->GetPattern<TextFieldPattern>();
627     CHECK_NULL_RETURN(pattern, textFieldContentConstraint);
628     auto idealWidth = contentConstraint.selfIdealSize.Width().value_or(contentConstraint.maxSize.Width());
629     auto idealHeight = contentConstraint.selfIdealSize.Height().value_or(contentConstraint.maxSize.Height());
630     auto maxIdealSize = SizeF { idealWidth, idealHeight };
631     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) &&
632         !layoutWrapper->GetLayoutProperty()->GetLayoutRect()) {
633         auto frameIdealSize = maxIdealSize + SizeF(pattern->GetHorizontalPaddingAndBorderSum(),
634                                                  pattern->GetVerticalPaddingAndBorderSum());
635         auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(static_cast<OptionalSize<float>>(frameIdealSize),
636             layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(),
637             layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference);
638         finalSize.SetWidth(
639             finalSize.Width().value_or(frameIdealSize.Width()) - pattern->GetHorizontalPaddingAndBorderSum());
640         finalSize.SetHeight(
641             finalSize.Height().value_or(frameIdealSize.Height()) - pattern->GetVerticalPaddingAndBorderSum());
642         maxIdealSize.UpdateSizeWhenSmaller(finalSize.ConvertToSizeT());
643         maxIdealSize.UpdateSizeWhenLarger(textFieldContentConstraint.minSize);
644     }
645     textFieldContentConstraint.maxSize = maxIdealSize;
646     return textFieldContentConstraint;
647 }
648 
CalculateFrameSizeConstraint(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)649 LayoutConstraintF TextFieldLayoutAlgorithm::CalculateFrameSizeConstraint(
650     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
651 {
652     LayoutConstraintF frameSizeConstraintF = contentConstraint;
653     auto frameNode = layoutWrapper->GetHostNode();
654     CHECK_NULL_RETURN(frameNode, frameSizeConstraintF);
655     auto pattern = frameNode->GetPattern<TextFieldPattern>();
656     CHECK_NULL_RETURN(pattern, frameSizeConstraintF);
657     auto border = pattern->GetBorderWidthProperty();
658     auto left = pattern->GetBorderLeft(border) + pattern->GetPaddingLeft();
659     auto right = pattern->GetBorderRight(border) + pattern->GetPaddingRight();
660     auto top = pattern->GetBorderTop(border) + pattern->GetPaddingTop();
661     auto bottom = pattern->GetBorderBottom(border) + pattern->GetPaddingBottom();
662     frameSizeConstraintF.maxSize.AddPadding(left, right, top, bottom);
663     frameSizeConstraintF.minSize.AddPadding(left, right, top, bottom);
664     return frameSizeConstraintF;
665 }
666 
FontRegisterCallback(const RefPtr<FrameNode> & frameNode,const std::vector<std::string> & fontFamilies)667 void TextFieldLayoutAlgorithm::FontRegisterCallback(
668     const RefPtr<FrameNode>& frameNode, const std::vector<std::string>& fontFamilies)
669 {
670     auto callback = [weakNode = WeakPtr<FrameNode>(frameNode)] {
671         auto frameNode = weakNode.Upgrade();
672         CHECK_NULL_VOID(frameNode);
673         frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
674         auto pattern = frameNode->GetPattern<TextFieldPattern>();
675         CHECK_NULL_VOID(pattern);
676         auto modifier = DynamicCast<TextFieldContentModifier>(pattern->GetContentModifier());
677         CHECK_NULL_VOID(modifier);
678         modifier->SetFontReady(true);
679     };
680     auto pipeline = frameNode->GetContext();
681     CHECK_NULL_VOID(pipeline);
682     auto fontManager = pipeline->GetFontManager();
683     CHECK_NULL_VOID(fontManager);
684     bool isCustomFont = false;
685     for (const auto& familyName : fontFamilies) {
686         bool customFont = fontManager->RegisterCallbackNG(frameNode, familyName, callback);
687         if (customFont) {
688             isCustomFont = true;
689         }
690     }
691     if (isCustomFont || fontManager->IsDefaultFontChanged()) {
692         auto pattern = frameNode->GetPattern<TextFieldPattern>();
693         CHECK_NULL_VOID(pattern);
694         pattern->SetIsCustomFont(true);
695         auto modifier = DynamicCast<TextFieldContentModifier>(pattern->GetContentModifier());
696         CHECK_NULL_VOID(modifier);
697         modifier->SetIsCustomFont(true);
698     }
699 }
700 
GetParagraphStyle(const TextStyle & textStyle,const std::u16string & content,const float fontSize) const701 ParagraphStyle TextFieldLayoutAlgorithm::GetParagraphStyle(
702     const TextStyle& textStyle, const std::u16string& content, const float fontSize) const
703 {
704     return {
705         .direction = GetTextDirection(content, direction_),
706         .maxLines = textStyle.GetMaxLines(),
707         .fontLocale = Localization::GetInstance()->GetFontLocale(),
708         .wordBreak = textStyle.GetWordBreak(),
709         .ellipsisMode = textStyle.GetEllipsisMode(),
710         .lineBreakStrategy = textStyle.GetLineBreakStrategy(),
711         .textOverflow = textStyle.GetTextOverflow(),
712         .fontSize = fontSize
713     };
714 }
715 
CreateParagraph(const TextStyle & textStyle,std::u16string content,bool needObscureText,int32_t nakedCharPosition,CreateParagraphData paragraphData)716 void TextFieldLayoutAlgorithm::CreateParagraph(const TextStyle& textStyle, std::u16string content, bool needObscureText,
717     int32_t nakedCharPosition, CreateParagraphData paragraphData)
718 {
719     auto paraStyle = GetParagraphStyle(textStyle, content, paragraphData.fontSize);
720     if (!paragraphData.disableTextAlign) {
721         paraStyle.align = textStyle.GetTextAlign();
722     }
723     paragraph_ = Paragraph::Create(paraStyle, FontCollection::Current());
724     CHECK_NULL_VOID(paragraph_);
725     paragraph_->PushStyle(textStyle);
726     StringUtils::TransformStrCase(content, static_cast<int32_t>(textStyle.GetTextCase()));
727     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
728     CHECK_NULL_VOID(pipeline);
729     auto theme = pipeline->GetTheme<TextFieldTheme>();
730     CHECK_NULL_VOID(theme);
731     auto displayText = TextFieldPattern::CreateDisplayText(content, nakedCharPosition,
732         needObscureText, theme->IsShowPasswordDirectly());
733     UtfUtils::HandleInvalidUTF16(reinterpret_cast<uint16_t*>(displayText.data()), displayText.length(), 0);
734     paragraph_->AddText(displayText);
735     paragraph_->Build();
736 }
737 
CreateParagraph(const TextStyle & textStyle,const std::vector<std::u16string> & contents,const std::u16string & content,bool needObscureText,CreateParagraphData paragraphData)738 void TextFieldLayoutAlgorithm::CreateParagraph(const TextStyle& textStyle, const std::vector<std::u16string>& contents,
739     const std::u16string& content, bool needObscureText, CreateParagraphData paragraphData)
740 {
741     TextStyle dragTextStyle = textStyle;
742     Color color = textStyle.GetTextColor().ChangeAlpha(DRAGGED_TEXT_TRANSPARENCY);
743     dragTextStyle.SetTextColor(color);
744     std::vector<TextStyle> textStyles { textStyle, dragTextStyle, textStyle };
745 
746     auto style = textStyles.begin();
747     ParagraphStyle paraStyle { .direction = GetTextDirection(content, direction_),
748         .maxLines = style->GetMaxLines(),
749         .fontLocale = Localization::GetInstance()->GetFontLocale(),
750         .wordBreak = style->GetWordBreak(),
751         .ellipsisMode = textStyle.GetEllipsisMode(),
752         .lineBreakStrategy = textStyle.GetLineBreakStrategy(),
753         .textOverflow = style->GetTextOverflow(),
754         .fontSize = paragraphData.fontSize };
755     if (!paragraphData.disableTextAlign) {
756         paraStyle.align = style->GetTextAlign();
757     }
758     paragraph_ = Paragraph::Create(paraStyle, FontCollection::Current());
759     CHECK_NULL_VOID(paragraph_);
760     for (size_t i = 0; i < contents.size(); i++) {
761         std::u16string splitStr = contents[i];
762         if (splitStr.empty()) {
763             continue;
764         }
765         if (style->GetMaxLines() == 1) {
766             std::replace(splitStr.begin(), splitStr.end(), u'\n', u' ');
767         }
768         auto& style = textStyles[i];
769         paragraph_->PushStyle(style);
770         StringUtils::TransformStrCase(splitStr, static_cast<int32_t>(style.GetTextCase()));
771         if (needObscureText) {
772             paragraph_->AddText(
773                 TextFieldPattern::CreateObscuredText(static_cast<int32_t>(splitStr.length())));
774         } else {
775             UtfUtils::HandleInvalidUTF16(reinterpret_cast<uint16_t*>(splitStr.data()), splitStr.length(), 0);
776             paragraph_->AddText(splitStr);
777         }
778         paragraph_->PopStyle();
779     }
780     paragraph_->Build();
781 }
782 
CreateInlineParagraph(const TextStyle & textStyle,std::u16string content,bool needObscureText,int32_t nakedCharPosition,CreateParagraphData paragraphData)783 void TextFieldLayoutAlgorithm::CreateInlineParagraph(const TextStyle& textStyle, std::u16string content,
784     bool needObscureText, int32_t nakedCharPosition, CreateParagraphData paragraphData)
785 {
786     auto paraStyle = GetParagraphStyle(textStyle, content, paragraphData.fontSize);
787     if (!paragraphData.disableTextAlign) {
788         paraStyle.align = textStyle.GetTextAlign();
789     }
790     paraStyle.maxLines = -1;
791     inlineParagraph_ = Paragraph::Create(paraStyle, FontCollection::Current());
792     CHECK_NULL_VOID(paragraph_);
793     inlineParagraph_->PushStyle(textStyle);
794     StringUtils::TransformStrCase(content, static_cast<int32_t>(textStyle.GetTextCase()));
795     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
796     CHECK_NULL_VOID(pipeline);
797     auto theme = pipeline->GetTheme<TextFieldTheme>();
798     CHECK_NULL_VOID(theme);
799     auto displayText = TextFieldPattern::CreateDisplayText(content, nakedCharPosition,
800         needObscureText, theme->IsShowPasswordDirectly());
801     UtfUtils::HandleInvalidUTF16(reinterpret_cast<uint16_t*>(displayText.data()), displayText.length(), 0);
802     inlineParagraph_->AddText(displayText);
803     inlineParagraph_->Build();
804 }
805 
GetTextDirection(const std::u16string & content,TextDirection direction)806 TextDirection TextFieldLayoutAlgorithm::GetTextDirection(const std::u16string& content, TextDirection direction)
807 {
808     if (direction == TextDirection::LTR || direction == TextDirection::RTL) {
809         return direction;
810     }
811 
812     bool isRTL = AceApplicationInfo::GetInstance().IsRightToLeft();
813     auto textDirection = isRTL ? TextDirection::RTL : TextDirection::LTR;
814     for (const auto& charOfShowingText : content) {
815         if (TextLayoutadapter::IsLeftToRight(charOfShowingText)) {
816             return TextDirection::LTR;
817         }
818         if (TextLayoutadapter::IsRightToLeft(charOfShowingText) ||
819             TextLayoutadapter::IsRightTOLeftArabic(charOfShowingText)) {
820             return TextDirection::RTL;
821         }
822     }
823     return textDirection;
824 }
825 
GetParagraph() const826 RefPtr<Paragraph> TextFieldLayoutAlgorithm::GetParagraph() const
827 {
828     return paragraph_;
829 }
830 
GetSuitableSize(SizeF & maxSize,LayoutWrapper * layoutWrapper)831 void TextFieldLayoutAlgorithm::GetSuitableSize(SizeF& maxSize, LayoutWrapper* layoutWrapper)
832 {
833     auto frameNode = layoutWrapper->GetHostNode();
834     CHECK_NULL_VOID(frameNode);
835     auto pattern = frameNode->GetPattern<TextFieldPattern>();
836     CHECK_NULL_VOID(pattern);
837     auto textFieldTheme = pattern->GetTheme();
838     CHECK_NULL_VOID(textFieldTheme);
839     auto safeBoundary = textFieldTheme->GetInlineBorderWidth().ConvertToPx() * 2;
840     if (pattern->HasFocus() && pattern->IsInlineMode()) {
841         maxSize.SetWidth(maxSize.Width() - static_cast<float>(safeBoundary) - PARAGRAPH_SAVE_BOUNDARY);
842     }
843 }
844 
GetTextFieldDefaultHeight()845 float TextFieldLayoutAlgorithm::GetTextFieldDefaultHeight()
846 {
847     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
848     CHECK_NULL_RETURN(pipeline, 0.0f);
849     auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>();
850     CHECK_NULL_RETURN(textFieldTheme, 0.0f);
851     auto height = textFieldTheme->GetHeight();
852     return static_cast<float>(height.ConvertToPx());
853 }
854 
SetPropertyToModifier(const TextStyle & textStyle,RefPtr<TextFieldContentModifier> modifier)855 void TextFieldLayoutAlgorithm::SetPropertyToModifier(
856     const TextStyle& textStyle, RefPtr<TextFieldContentModifier> modifier)
857 {
858     CHECK_NULL_VOID(modifier);
859     modifier->SetFontFamilies(textStyle.GetFontFamilies());
860     modifier->SetFontSize(textStyle.GetFontSize(), textStyle);
861     if (textStyle.GetAdaptTextSize()) {
862         modifier->SetAdaptMinFontSize(textStyle.GetAdaptMinFontSize(), textStyle);
863         modifier->SetAdaptMaxFontSize(textStyle.GetAdaptMaxFontSize(), textStyle);
864     }
865     modifier->SetFontWeight(textStyle.GetFontWeight());
866     modifier->SetTextColor(textStyle.GetTextColor());
867     modifier->SetFontStyle(textStyle.GetFontStyle());
868     modifier->SetTextOverflow(textStyle.GetTextOverflow());
869     modifier->SetTextDecoration(textStyle.GetTextDecoration(), textStyle.GetTextDecorationColor(),
870         textStyle.GetTextDecorationStyle());
871 }
872 
AddAdaptFontSizeAndAnimations(TextStyle & textStyle,const RefPtr<TextFieldLayoutProperty> & layoutProperty,const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)873 bool TextFieldLayoutAlgorithm::AddAdaptFontSizeAndAnimations(TextStyle& textStyle,
874     const RefPtr<TextFieldLayoutProperty>& layoutProperty, const LayoutConstraintF& contentConstraint,
875     LayoutWrapper* layoutWrapper)
876 {
877     auto frameNode = layoutWrapper->GetHostNode();
878     CHECK_NULL_RETURN(frameNode, false);
879     auto pattern = frameNode->GetPattern<TextFieldPattern>();
880     CHECK_NULL_RETURN(pattern, false);
881     bool hasHeightOverride = textStyle.HasHeightOverride();
882     auto lineHeight = textStyle.GetLineHeight();
883     SetAdaptFontSizeLineHeight(lineHeight, textStyle);
884     textStyle.SetLineHeight(Dimension(), false);
885     bool result = false;
886     const std::u16string& text = textContent_.empty() ? u"a" : textContent_;
887     switch (layoutProperty->GetHeightAdaptivePolicyValue(TextHeightAdaptivePolicy::MAX_LINES_FIRST)) {
888         case TextHeightAdaptivePolicy::MAX_LINES_FIRST:
889             if (pattern->IsInlineMode()) {
890                 result = AdaptInlineFocusMinFontSize(textStyle, text, 1.0_fp, contentConstraint, layoutWrapper);
891             } else {
892                 result = AdaptMinFontSize(textStyle, text, 1.0_fp, contentConstraint, layoutWrapper);
893             }
894             break;
895         case TextHeightAdaptivePolicy::LAYOUT_CONSTRAINT_FIRST:
896             if (pattern->IsInlineMode()) {
897                 result = AdaptInlineFocusFontSize(textStyle, text, 1.0_fp, contentConstraint, layoutWrapper);
898             } else {
899                 result = AdaptMinFontSize(textStyle, text, 1.0_fp, contentConstraint, layoutWrapper);
900             }
901             break;
902         case TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST:
903             if (pattern->IsInlineMode()) {
904                 result = AdaptInlineFocusFontSize(textStyle, text, 1.0_fp, contentConstraint, layoutWrapper);
905             } else {
906                 result = AdaptMaxFontSize(textStyle, text, 1.0_fp, contentConstraint, layoutWrapper);
907             }
908             break;
909         default:
910             break;
911     }
912     textStyle.SetLineHeight(lineHeight, hasHeightOverride);
913     if (result && (hasHeightOverride || textContent_.empty())) {
914         return CreateParagraphAndLayout(textStyle, textContent_, contentConstraint, layoutWrapper, false);
915     }
916     return result;
917 }
918 
IsNeedAdaptFontSize(const TextStyle & textStyle,const RefPtr<TextFieldLayoutProperty> & layoutProperty,const LayoutConstraintF & contentConstraint)919 bool TextFieldLayoutAlgorithm::IsNeedAdaptFontSize(const TextStyle& textStyle,
920     const RefPtr<TextFieldLayoutProperty>& layoutProperty, const LayoutConstraintF& contentConstraint)
921 {
922     if (!textStyle.GetAdaptTextSize()) {
923         return false;
924     }
925     auto adaptivePolicy = layoutProperty->GetHeightAdaptivePolicyValue(TextHeightAdaptivePolicy::MAX_LINES_FIRST);
926     if ((adaptivePolicy != TextHeightAdaptivePolicy::MAX_LINES_FIRST) &&
927         (adaptivePolicy != TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST) &&
928         (adaptivePolicy != TextHeightAdaptivePolicy::LAYOUT_CONSTRAINT_FIRST)) {
929         return false;
930     }
931     return TextAdaptFontSizer::IsNeedAdaptFontSize(textStyle, contentConstraint);
932 }
933 
AdaptInlineFocusFontSize(TextStyle & textStyle,const std::u16string & content,const Dimension & stepUnit,const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)934 bool TextFieldLayoutAlgorithm::AdaptInlineFocusFontSize(TextStyle& textStyle, const std::u16string& content,
935     const Dimension& stepUnit, const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
936 {
937     double maxFontSize = 0.0;
938     double minFontSize = 0.0;
939     GetAdaptMaxMinFontSize(textStyle, maxFontSize, minFontSize, contentConstraint);
940     if (LessNotEqual(maxFontSize, minFontSize) || LessOrEqual(minFontSize, 0.0)) {
941         return CreateParagraphAndLayout(textStyle, content, contentConstraint, layoutWrapper, false);
942     }
943     double stepSize = 0.0;
944     GetAdaptFontSizeStep(textStyle, stepSize, stepUnit, contentConstraint);
945     auto tag = static_cast<int32_t>((maxFontSize - minFontSize) / stepSize);
946     auto length = tag + 1 + (GreatNotEqual(maxFontSize, minFontSize + stepSize * tag) ? 1 : 0);
947     int32_t left = 0;
948     int32_t right = length - 1;
949     float fontSize = 0.0f;
950     auto newContentConstraint = BuildInfinityLayoutConstraint(contentConstraint);
951     auto maxSize = GetMaxMeasureSize(contentConstraint);
952     GetSuitableSize(maxSize, layoutWrapper);
953     while (left <= right) {
954         int32_t mid = left + (right - left) / 2;
955         fontSize = static_cast<float>((mid == length - 1) ? (maxFontSize) : (minFontSize + stepSize * mid));
956         textStyle.SetFontSize(Dimension(fontSize));
957         if (!CreateParagraphAndLayout(textStyle, content, newContentConstraint, layoutWrapper)) {
958             return false;
959         }
960         if (!IsInlineFocusAdaptExceedLimit(maxSize)) {
961             left = mid + 1;
962         } else {
963             right = mid - 1;
964         }
965     }
966     fontSize = static_cast<float>((left - 1 == length - 1) ? (maxFontSize) : (minFontSize + stepSize * (left - 1)));
967     fontSize = LessNotEqual(fontSize, minFontSize) ? minFontSize : fontSize;
968     fontSize = GreatNotEqual(fontSize, maxFontSize) ? maxFontSize : fontSize;
969     textStyle.SetFontSize(Dimension(fontSize));
970     return CreateParagraphAndLayout(textStyle, content, contentConstraint, layoutWrapper);
971 }
972 
BuildInfinityLayoutConstraint(const LayoutConstraintF & contentConstraint)973 LayoutConstraintF TextFieldLayoutAlgorithm::BuildInfinityLayoutConstraint(const LayoutConstraintF& contentConstraint)
974 {
975     auto newContentConstraint = contentConstraint;
976     newContentConstraint.maxSize = { std::numeric_limits<double>::infinity(),
977         std::numeric_limits<double>::infinity() };
978     if (newContentConstraint.selfIdealSize.Width()) {
979         newContentConstraint.selfIdealSize.SetWidth(std::numeric_limits<double>::infinity());
980     }
981     if (newContentConstraint.selfIdealSize.Height()) {
982         newContentConstraint.selfIdealSize.SetHeight(std::numeric_limits<double>::infinity());
983     }
984     return newContentConstraint;
985 }
986 
IsInlineFocusAdaptExceedLimit(const SizeF & maxSize)987 bool TextFieldLayoutAlgorithm::IsInlineFocusAdaptExceedLimit(const SizeF& maxSize)
988 {
989     auto paragraph = GetParagraph();
990     CHECK_NULL_RETURN(paragraph, false);
991     bool didExceedMaxLines = false;
992     didExceedMaxLines |= GreatNotEqual(paragraph->GetHeight() / paragraph->GetLineCount(),
993         maxSize.Height());
994     didExceedMaxLines |= GreatNotEqual(paragraph->GetLongestLine(), maxSize.Width());
995     didExceedMaxLines |= IsAdaptFontSizeExceedLineHeight(paragraph);
996     return didExceedMaxLines;
997 }
998 
AdaptInlineFocusMinFontSize(TextStyle & textStyle,const std::u16string & content,const Dimension & stepUnit,const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)999 bool TextFieldLayoutAlgorithm::AdaptInlineFocusMinFontSize(TextStyle& textStyle, const std::u16string& content,
1000     const Dimension& stepUnit, const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
1001 {
1002     double maxFontSize = 0.0;
1003     double minFontSize = 0.0;
1004     GetAdaptMaxMinFontSize(textStyle, maxFontSize, minFontSize, contentConstraint);
1005     if (LessNotEqual(maxFontSize, minFontSize) || LessOrEqual(minFontSize, 0.0)) {
1006         return CreateParagraphAndLayout(textStyle, content, contentConstraint, layoutWrapper, false);
1007     }
1008     double stepSize = 0.0;
1009     GetAdaptFontSizeStep(textStyle, stepSize, stepUnit, contentConstraint);
1010     auto textFieldLayoutProperty = DynamicCast<TextFieldLayoutProperty>(layoutWrapper->GetLayoutProperty());
1011     CHECK_NULL_RETURN(textFieldLayoutProperty, false);
1012     auto maxViewLines = textFieldLayoutProperty->GetMaxViewLinesValue(INLINE_DEFAULT_VIEW_MAXLINE);
1013     auto newContentConstraint = BuildInlineFocusLayoutConstraint(contentConstraint, layoutWrapper);
1014     auto maxSize = GetMaxMeasureSize(contentConstraint);
1015     GetSuitableSize(maxSize, layoutWrapper);
1016     while (GreatOrEqual(maxFontSize, minFontSize)) {
1017         textStyle.SetFontSize(Dimension(maxFontSize));
1018         if (!CreateParagraphAndLayout(textStyle, content, newContentConstraint, layoutWrapper)) {
1019             return false;
1020         }
1021         if (!IsInlineFocusAdaptMinExceedLimit(maxSize, maxViewLines)) {
1022             break;
1023         }
1024         maxFontSize -= stepSize;
1025     }
1026     return true;
1027 }
1028 
BuildInlineFocusLayoutConstraint(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)1029 LayoutConstraintF TextFieldLayoutAlgorithm::BuildInlineFocusLayoutConstraint(
1030     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
1031 {
1032     auto frameNode = layoutWrapper->GetHostNode();
1033     CHECK_NULL_RETURN(frameNode, contentConstraint);
1034     auto pattern = frameNode->GetPattern<TextFieldPattern>();
1035     CHECK_NULL_RETURN(pattern, contentConstraint);
1036     auto textFieldTheme = pattern->GetTheme();
1037     CHECK_NULL_RETURN(textFieldTheme, contentConstraint);
1038     auto safeBoundary = textFieldTheme->GetInlineBorderWidth().ConvertToPx() * 2;
1039     auto inlineBoundary = static_cast<float>(safeBoundary) + PARAGRAPH_SAVE_BOUNDARY;
1040     auto newContentConstraint = contentConstraint;
1041     newContentConstraint.maxSize.SetWidth(newContentConstraint.maxSize.Width() - inlineBoundary);
1042     if (newContentConstraint.selfIdealSize.Width()) {
1043         newContentConstraint.selfIdealSize.SetWidth(newContentConstraint.selfIdealSize.Width().value() -
1044             inlineBoundary);
1045     }
1046     return newContentConstraint;
1047 }
1048 
IsInlineFocusAdaptMinExceedLimit(const SizeF & maxSize,uint32_t maxViewLines)1049 bool TextFieldLayoutAlgorithm::IsInlineFocusAdaptMinExceedLimit(const SizeF& maxSize, uint32_t maxViewLines)
1050 {
1051     auto paragraph = GetParagraph();
1052     CHECK_NULL_RETURN(paragraph, false);
1053     bool didExceedMaxLines = paragraph->DidExceedMaxLines();
1054     didExceedMaxLines = didExceedMaxLines || ((maxViewLines > 0) && (paragraph->GetLineCount() > maxViewLines));
1055     didExceedMaxLines = didExceedMaxLines || GreatNotEqual(paragraph->GetHeight() / paragraph->GetLineCount(),
1056         maxSize.Height());
1057     didExceedMaxLines = didExceedMaxLines || GreatNotEqual(paragraph->GetLongestLine(), maxSize.Width());
1058     didExceedMaxLines = didExceedMaxLines || IsAdaptFontSizeExceedLineHeight(paragraph);
1059     return didExceedMaxLines;
1060 }
1061 
CreateParagraphAndLayout(const TextStyle & textStyle,const std::u16string & content,const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper,bool needLayout)1062 bool TextFieldLayoutAlgorithm::CreateParagraphAndLayout(const TextStyle& textStyle, const std::u16string& content,
1063     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, bool needLayout)
1064 {
1065     if (!CreateParagraphEx(textStyle, content, contentConstraint, layoutWrapper)) {
1066         return false;
1067     }
1068     ACE_LAYOUT_SCOPED_TRACE("CreateParagraphAndLayout[needLayout:%d]", needLayout);
1069     if (needLayout) {
1070         CHECK_NULL_RETURN(paragraph_, false);
1071         auto maxSize = GetMaxMeasureSize(contentConstraint);
1072         ApplyIndent(layoutWrapper, maxSize.Width());
1073         paragraph_->Layout(std::max(0.0f, maxSize.Width()));
1074     }
1075     return true;
1076 }
1077 
UpdateTextStyleLineHeight(const RefPtr<FrameNode> & frameNode,const RefPtr<TextFieldLayoutProperty> & layoutProperty,TextStyle & textStyle)1078 void TextFieldLayoutAlgorithm::UpdateTextStyleLineHeight(const RefPtr<FrameNode>& frameNode,
1079     const RefPtr<TextFieldLayoutProperty>& layoutProperty, TextStyle& textStyle)
1080 {
1081     auto pattern = frameNode->GetPattern<TextFieldPattern>();
1082     CHECK_NULL_VOID(pattern);
1083     auto pipeline = frameNode->GetContext();
1084     CHECK_NULL_VOID(pipeline);
1085     if (layoutProperty->HasLineHeight()) {
1086         auto heightValue = layoutProperty->GetLineHeightValue(Dimension());
1087         if (heightValue.Unit() == DimensionUnit::PERCENT) {
1088             textStyle.SetLineHeight(heightValue);
1089         } else {
1090             textStyle.SetLineHeight(
1091                 Dimension(heightValue.ConvertToPxDistribute(textStyle.GetMinFontScale(), textStyle.GetMaxFontScale())));
1092         }
1093         textStyle.SetHalfLeading(layoutProperty->GetHalfLeading().value_or(pipeline->GetHalfLeading()));
1094     }
1095 }
1096 
UpdateTextStyleMore(const RefPtr<FrameNode> & frameNode,const RefPtr<TextFieldLayoutProperty> & layoutProperty,TextStyle & textStyle,bool isDisabled)1097 void TextFieldLayoutAlgorithm::UpdateTextStyleMore(const RefPtr<FrameNode>& frameNode,
1098     const RefPtr<TextFieldLayoutProperty>& layoutProperty, TextStyle& textStyle, bool isDisabled)
1099 {
1100     if (layoutProperty->HasTextIndent()) {
1101         textStyle.SetTextIndent(layoutProperty->GetTextIndent().value());
1102     }
1103     if (layoutProperty->HasAdaptMinFontSize()) {
1104         textStyle.SetAdaptMinFontSize(layoutProperty->GetAdaptMinFontSize().value());
1105     }
1106     if (layoutProperty->HasAdaptMaxFontSize()) {
1107         textStyle.SetAdaptMaxFontSize(layoutProperty->GetAdaptMaxFontSize().value());
1108     }
1109     auto pattern = frameNode->GetPattern<TextFieldPattern>();
1110     CHECK_NULL_VOID(pattern);
1111     auto pipeline = frameNode->GetContext();
1112     CHECK_NULL_VOID(pipeline);
1113     if (pattern->IsInPasswordMode()) {
1114         return;
1115     }
1116     if (layoutProperty->HasTextDecoration()) {
1117         textStyle.SetTextDecoration(layoutProperty->GetTextDecoration().value());
1118     }
1119     if (layoutProperty->HasTextDecorationColor()) {
1120         if (isDisabled) {
1121             textStyle.SetTextDecorationColor(layoutProperty->GetTextDecorationColor().value()
1122                 .BlendOpacity(TEXT_DECORATION_DISABLED_COLOR_ALPHA));
1123         } else {
1124             textStyle.SetTextDecorationColor(layoutProperty->GetTextDecorationColor().value());
1125         }
1126     }
1127     if (layoutProperty->HasTextDecorationStyle()) {
1128         textStyle.SetTextDecorationStyle(layoutProperty->GetTextDecorationStyle().value());
1129     }
1130     if (layoutProperty->HasLetterSpacing()) {
1131         textStyle.SetLetterSpacing(layoutProperty->GetLetterSpacing().value());
1132     }
1133     UpdateTextStyleLineHeight(frameNode, layoutProperty, textStyle);
1134     if (layoutProperty->HasFontFeature()) {
1135         textStyle.SetFontFeatures(layoutProperty->GetFontFeature().value());
1136     }
1137     if (layoutProperty->HasLineSpacing()) {
1138         textStyle.SetLineSpacing(layoutProperty->GetLineSpacing().value());
1139     }
1140 }
1141 
UpdatePlaceholderTextStyleMore(const RefPtr<FrameNode> & frameNode,const RefPtr<TextFieldLayoutProperty> & layoutProperty,const RefPtr<TextFieldTheme> & theme,TextStyle & placeholderTextStyle,bool isDisabled)1142 void TextFieldLayoutAlgorithm::UpdatePlaceholderTextStyleMore(const RefPtr<FrameNode>& frameNode,
1143     const RefPtr<TextFieldLayoutProperty>& layoutProperty, const RefPtr<TextFieldTheme>& theme,
1144     TextStyle& placeholderTextStyle, bool isDisabled)
1145 {
1146     if (layoutProperty->GetPlaceholderValue(u"").empty()) {
1147         if (layoutProperty->HasAdaptMinFontSize()) {
1148             placeholderTextStyle.SetAdaptMinFontSize(layoutProperty->GetAdaptMinFontSize().value());
1149         }
1150         if (layoutProperty->HasAdaptMaxFontSize()) {
1151             placeholderTextStyle.SetAdaptMaxFontSize(layoutProperty->GetAdaptMaxFontSize().value());
1152         }
1153     }
1154     auto pattern = frameNode->GetPattern<TextFieldPattern>();
1155     CHECK_NULL_VOID(pattern);
1156     auto pipeline = frameNode->GetContext();
1157     CHECK_NULL_VOID(pipeline);
1158     if (pattern->IsInPasswordMode()) {
1159         return;
1160     }
1161     if (layoutProperty->HasLineHeight()) {
1162         auto heightValue = layoutProperty->GetLineHeightValue(Dimension());
1163         if (heightValue.Unit() == DimensionUnit::PERCENT) {
1164             placeholderTextStyle.SetLineHeight(heightValue);
1165         } else {
1166             placeholderTextStyle.SetLineHeight(
1167                 Dimension(heightValue.ConvertToPxDistribute(placeholderTextStyle.GetMinFontScale(),
1168                     placeholderTextStyle.GetMaxFontScale())));
1169         }
1170         placeholderTextStyle.SetHalfLeading(layoutProperty->GetHalfLeading().value_or(pipeline->GetHalfLeading()));
1171     }
1172     if (layoutProperty->HasMaxFontScale()) {
1173         placeholderTextStyle.SetMaxFontScale(layoutProperty->GetMaxFontScale().value());
1174     }
1175     if (layoutProperty->HasMinFontScale()) {
1176         placeholderTextStyle.SetMinFontScale(layoutProperty->GetMinFontScale().value());
1177     }
1178     placeholderTextStyle.SetLineSpacing(theme->GetPlaceholderLineSpacing());
1179 }
1180 
DidExceedMaxLines(const SizeF & maxSize)1181 bool TextFieldLayoutAlgorithm::DidExceedMaxLines(const SizeF& maxSize)
1182 {
1183     auto paragraph = GetParagraph();
1184     CHECK_NULL_RETURN(paragraph, false);
1185     return paragraph->DidExceedMaxLines() ||
1186         GreatNotEqual(paragraph->GetHeight(), maxSize.Height()) ||
1187         GreatNotEqual(paragraph->GetLongestLine(), maxSize.Width()) ||
1188         IsAdaptFontSizeExceedLineHeight(paragraph);
1189 }
1190 
IsAdaptExceedLimit(const SizeF & maxSize)1191 bool TextFieldLayoutAlgorithm::IsAdaptExceedLimit(const SizeF& maxSize)
1192 {
1193     auto paragraph = GetParagraph();
1194     CHECK_NULL_RETURN(paragraph, false);
1195     return (paragraph->GetLineCount() > 1) || paragraph->DidExceedMaxLines() ||
1196         GreatNotEqual(paragraph->GetLongestLine(), maxSize.Width()) ||
1197         IsAdaptFontSizeExceedLineHeight(paragraph) ||
1198            GreatNotEqual(paragraph->GetHeight(), maxSize.Height());
1199 }
1200 } // namespace OHOS::Ace::NG
1201