• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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/button/button_layout_algorithm.h"
17 
18 #include "core/components/toggle/toggle_theme.h"
19 #include "core/components_ng/pattern/button/button_pattern.h"
20 
21 namespace OHOS::Ace::NG {
22 namespace {
checkNegativeBorderRadius(std::optional<Dimension> & radius,const float defaultBorderRadius)23 void checkNegativeBorderRadius(std::optional<Dimension>& radius, const float defaultBorderRadius)
24 {
25     // Change the borderRadius size of a negative number to the default.
26     if (!radius.has_value() || LessNotEqual(radius.value().ConvertToPx(), 0.0)) {
27         radius = Dimension(defaultBorderRadius);
28     }
29 }
30 }
Measure(LayoutWrapper * layoutWrapper)31 void ButtonLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
32 {
33     auto host = layoutWrapper->GetHostNode();
34     CHECK_NULL_VOID(host);
35     auto pattern = host->GetPattern<ButtonPattern>();
36     CHECK_NULL_VOID(pattern);
37     auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
38     CHECK_NULL_VOID(buttonLayoutProperty);
39     if (buttonLayoutProperty->HasType() && buttonLayoutProperty->GetType() == ButtonType::CIRCLE &&
40         !pattern->GetHasCustomPadding()) {
41         NG::PaddingProperty paddings;
42         paddings.top = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
43         paddings.bottom = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
44         paddings.left = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
45         paddings.right = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
46         buttonLayoutProperty->UpdatePadding(paddings);
47     }
48     if (pattern->UseContentModifier()) {
49         const auto& childList = layoutWrapper->GetAllChildrenWithBuild();
50         std::list<RefPtr<LayoutWrapper>> builderChildList;
51         for (const auto& child : childList) {
52             if (child->GetHostNode()->GetId() != pattern->GetBuilderId()) {
53                 child->GetGeometryNode()->Reset();
54                 child->GetGeometryNode()->SetContentSize(SizeF());
55             } else {
56                 auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
57                 child->Measure(layoutConstraint);
58                 builderChildList.push_back(child);
59             }
60         }
61         BoxLayoutAlgorithm::PerformMeasureSelfWithChildList(layoutWrapper, builderChildList);
62         return;
63     }
64     auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
65     HandleChildLayoutConstraint(layoutWrapper, layoutConstraint);
66     if (buttonLayoutProperty->HasLabel()) {
67         // If the button has label, according to whether the font size is set to do the corresponding expansion button,
68         // font reduction, truncation and other operations.
69         HandleAdaptiveText(layoutWrapper, layoutConstraint);
70     } else {
71         // If the button has not label, measure the child directly.
72         for (auto&& child : layoutWrapper->GetAllChildrenWithBuild()) {
73             child->Measure(layoutConstraint);
74         }
75     }
76     PerformMeasureSelf(layoutWrapper);
77 }
78 
HandleChildLayoutConstraint(LayoutWrapper * layoutWrapper,LayoutConstraintF & layoutConstraint)79 void ButtonLayoutAlgorithm::HandleChildLayoutConstraint(
80     LayoutWrapper* layoutWrapper, LayoutConstraintF& layoutConstraint)
81 {
82     auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
83     CHECK_NULL_VOID(buttonLayoutProperty);
84     if (!buttonLayoutProperty->HasLabel()) {
85         return;
86     }
87     auto buttonType = buttonLayoutProperty->GetType().value_or(ButtonType::CAPSULE);
88     if (buttonType == ButtonType::CIRCLE) {
89         layoutConstraint.maxSize = HandleLabelCircleButtonConstraint(layoutWrapper).value_or(SizeF());
90         return;
91     }
92     const auto& selfLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint();
93     // If height is not set, apply the default height.
94     if (selfLayoutConstraint && !selfLayoutConstraint->selfIdealSize.Height().has_value()) {
95         auto maxHeight = selfLayoutConstraint->maxSize.Height();
96         if (IsAging(layoutWrapper)) {
97             layoutConstraint.maxSize.SetHeight(maxHeight);
98             return;
99         }
100         auto defaultHeight = GetDefaultHeight(layoutWrapper);
101         layoutConstraint.maxSize.SetHeight(maxHeight > defaultHeight ? defaultHeight : maxHeight);
102     }
103 }
104 
105 // If the ButtonType is CIRCLE, then omit text by the smaller edge.
HandleLabelCircleButtonConstraint(LayoutWrapper * layoutWrapper)106 std::optional<SizeF> ButtonLayoutAlgorithm::HandleLabelCircleButtonConstraint(LayoutWrapper* layoutWrapper)
107 {
108     SizeF constraintSize;
109     auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
110     CHECK_NULL_RETURN(buttonLayoutProperty, constraintSize);
111     const auto& selfLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint();
112     CHECK_NULL_RETURN(selfLayoutConstraint, constraintSize);
113     auto host = layoutWrapper->GetHostNode();
114     CHECK_NULL_RETURN(host, constraintSize);
115     auto* context = host->GetContextWithCheck();
116     CHECK_NULL_RETURN(context, constraintSize);
117     auto buttonTheme = context->GetTheme<ButtonTheme>();
118     CHECK_NULL_RETURN(buttonTheme, constraintSize);
119     const auto& padding = buttonLayoutProperty->CreatePaddingAndBorder();
120     auto defaultHeight = GetDefaultHeight(layoutWrapper);
121     float minLength = 0.0f;
122     if (selfLayoutConstraint->selfIdealSize.IsNull()) {
123         // Width and height are not set.
124         minLength = defaultHeight;
125     } else if (selfLayoutConstraint->selfIdealSize.Width().has_value() &&
126                !selfLayoutConstraint->selfIdealSize.Height().has_value()) {
127         // Only width is set.
128         minLength = selfLayoutConstraint->selfIdealSize.Width().value();
129     } else if (selfLayoutConstraint->selfIdealSize.Height().has_value() &&
130                !selfLayoutConstraint->selfIdealSize.Width().has_value()) {
131         // Only height is set.
132         minLength = selfLayoutConstraint->selfIdealSize.Height().value();
133     } else {
134         // Both width and height are set.
135         auto buttonWidth = selfLayoutConstraint->selfIdealSize.Width().value();
136         auto buttonHeight = selfLayoutConstraint->selfIdealSize.Height().value();
137         minLength = std::min(buttonWidth, buttonHeight);
138     }
139     if (buttonLayoutProperty->HasBorderRadius() && selfLayoutConstraint->selfIdealSize.IsNull()) {
140         auto radius =
141             static_cast<float>(GetFirstValidRadius(buttonLayoutProperty->GetBorderRadius().value()).ConvertToPx());
142         minLength = 2 * radius;
143     }
144     constraintSize.SetSizeT(SizeF(minLength, minLength));
145     MinusPaddingToSize(padding, constraintSize);
146     return ConstrainSize(constraintSize, selfLayoutConstraint->minSize, selfLayoutConstraint->maxSize);
147 }
148 
HandleAdaptiveText(LayoutWrapper * layoutWrapper,LayoutConstraintF & layoutConstraint)149 void ButtonLayoutAlgorithm::HandleAdaptiveText(LayoutWrapper* layoutWrapper, LayoutConstraintF& layoutConstraint)
150 {
151     auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
152     CHECK_NULL_VOID(buttonLayoutProperty);
153     auto host = layoutWrapper->GetHostNode();
154     CHECK_NULL_VOID(host);
155     auto* context = host->GetContextWithCheck();
156     CHECK_NULL_VOID(context);
157     auto buttonTheme = context->GetTheme<ButtonTheme>();
158     CHECK_NULL_VOID(buttonTheme);
159     auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0);
160     CHECK_NULL_VOID(childWrapper);
161     if (buttonLayoutProperty->HasFontSize() || buttonLayoutProperty->HasControlSize()) {
162         auto childConstraint = layoutWrapper->GetLayoutProperty()->GetContentLayoutConstraint();
163         childWrapper->Measure(childConstraint);
164         auto textSize = childWrapper->GetGeometryNode()->GetContentSize();
165         // Fonsize is set. When the font height is larger than the button height, make the button fit the font
166         // height.
167         if (GreatOrEqual(textSize.Height(), layoutConstraint.maxSize.Height())) {
168             layoutConstraint.maxSize.SetHeight(textSize.Height());
169         }
170     } else {
171         // Fonsize is not set. When the font width is greater than the button width, dynamically change the font
172         // size to no less than 9sp.
173         auto textLayoutProperty = DynamicCast<TextLayoutProperty>(childWrapper->GetLayoutProperty());
174         CHECK_NULL_VOID(textLayoutProperty);
175         if (buttonTheme->GetIsApplyTextFontSize() && !buttonLayoutProperty->GetMaxFontSize().has_value() &&
176             !buttonLayoutProperty->GetMinFontSize().has_value()) {
177             textLayoutProperty->ResetAdaptMaxFontSize();
178             textLayoutProperty->ResetAdaptMinFontSize();
179         } else {
180             textLayoutProperty->UpdateAdaptMaxFontSize(
181                 buttonLayoutProperty->GetMaxFontSize().value_or(buttonTheme->GetMaxFontSize()));
182             textLayoutProperty->UpdateAdaptMinFontSize(
183                 buttonLayoutProperty->GetMinFontSize().value_or(buttonTheme->GetMinFontSize()));
184         }
185     }
186     childWrapper->Measure(layoutConstraint);
187     childSize_ = childWrapper->GetGeometryNode()->GetContentSize();
188 }
189 
HandleBorderRadius(LayoutWrapper * layoutWrapper)190 void ButtonLayoutAlgorithm::HandleBorderRadius(LayoutWrapper* layoutWrapper)
191 {
192     auto host = layoutWrapper->GetHostNode();
193     CHECK_NULL_VOID(host);
194     auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
195     CHECK_NULL_VOID(buttonLayoutProperty);
196     auto frameSize = layoutWrapper->GetGeometryNode()->GetFrameSize();
197     auto renderContext = host->GetRenderContext();
198     CHECK_NULL_VOID(renderContext);
199     auto buttonType = buttonLayoutProperty->GetType().value_or(ButtonType::CAPSULE);
200     if (buttonType == ButtonType::CIRCLE) {
201         auto minSize = std::min(frameSize.Height(), frameSize.Width());
202         auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
203         if (buttonLayoutProperty->HasBorderRadius() && layoutConstraint.parentIdealSize.IsNull()) {
204             auto borderRadius = buttonLayoutProperty->GetBorderRadius().value_or(NG::BorderRadiusProperty());
205             minSize = static_cast<float>(GetFirstValidRadius(borderRadius).ConvertToPx() * 2);
206         }
207         renderContext->UpdateBorderRadius(BorderRadiusProperty(Dimension(minSize / 2)));
208         MeasureCircleButton(layoutWrapper);
209     } else if (buttonType == ButtonType::CAPSULE) {
210         renderContext->UpdateBorderRadius(BorderRadiusProperty(Dimension(frameSize.Height() / 2)));
211     } else if (buttonType == ButtonType::NORMAL) {
212         auto normalRadius = buttonLayoutProperty->GetBorderRadiusValue(BorderRadiusProperty(Dimension()));
213         renderContext->UpdateBorderRadius(normalRadius);
214     } else if (buttonType == ButtonType::ROUNDED_RECTANGLE) {
215         auto defaultBorderRadius = GetDefaultBorderRadius(layoutWrapper);
216         auto roundedRectRadius =
217             buttonLayoutProperty->GetBorderRadiusValue(BorderRadiusProperty(Dimension(defaultBorderRadius)));
218         checkNegativeBorderRadius(roundedRectRadius.radiusTopLeft, defaultBorderRadius);
219         checkNegativeBorderRadius(roundedRectRadius.radiusTopRight, defaultBorderRadius);
220         checkNegativeBorderRadius(roundedRectRadius.radiusBottomLeft, defaultBorderRadius);
221         checkNegativeBorderRadius(roundedRectRadius.radiusBottomRight, defaultBorderRadius);
222         renderContext->UpdateBorderRadius(roundedRectRadius);
223     }
224 }
225 
226 // Called to perform measure current render node.
PerformMeasureSelf(LayoutWrapper * layoutWrapper)227 void ButtonLayoutAlgorithm::PerformMeasureSelf(LayoutWrapper* layoutWrapper)
228 {
229     auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
230     CHECK_NULL_VOID(buttonLayoutProperty);
231     BoxLayoutAlgorithm::PerformMeasureSelf(layoutWrapper);
232     if (NeedAgingMeasure(layoutWrapper)) {
233         return;
234     }
235     if (buttonLayoutProperty->HasLabel()) {
236         auto frameSize = layoutWrapper->GetGeometryNode()->GetFrameSize();
237         auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
238         const auto& selfLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint();
239         auto padding = buttonLayoutProperty->CreatePaddingAndBorder();
240         auto topPadding = padding.top.value_or(0.0);
241         auto bottomPadding = padding.bottom.value_or(0.0);
242         auto host = layoutWrapper->GetHostNode();
243         CHECK_NULL_VOID(host);
244         auto* context = host->GetContextWithCheck();
245         CHECK_NULL_VOID(context);
246         auto buttonTheme = context->GetTheme<ButtonTheme>();
247         CHECK_NULL_VOID(buttonTheme);
248 
249         auto defaultHeight = GetDefaultHeight(layoutWrapper);
250         auto buttonType = buttonLayoutProperty->GetType().value_or(ButtonType::CAPSULE);
251         if (buttonType == ButtonType::CIRCLE) {
252             HandleLabelCircleButtonFrameSize(layoutConstraint, frameSize, defaultHeight);
253         } else {
254             if (selfLayoutConstraint && !selfLayoutConstraint->selfIdealSize.Height().has_value()) {
255                 auto layoutContraint = buttonLayoutProperty->GetLayoutConstraint();
256                 CHECK_NULL_VOID(layoutContraint);
257                 auto maxHeight = layoutContraint->maxSize.Height();
258                 auto minHeight = layoutContraint->minSize.Height();
259                 auto actualHeight = static_cast<float>(childSize_.Height() + topPadding + bottomPadding);
260                 actualHeight = std::min(actualHeight, maxHeight);
261                 actualHeight = std::max(actualHeight, minHeight);
262                 frameSize.SetHeight(maxHeight > defaultHeight ? std::max(defaultHeight, actualHeight) : maxHeight);
263             }
264         }
265         // Determine if the button needs to fit the font size.
266         if (buttonLayoutProperty->HasFontSize()) {
267             if (GreatOrEqual(childSize_.Height() + topPadding + bottomPadding, frameSize.Height())) {
268                 frameSize = SizeF(frameSize.Width(), childSize_.Height() + topPadding + bottomPadding);
269             }
270         }
271         layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize);
272     }
273     HandleBorderRadius(layoutWrapper);
274 }
275 
HandleLabelCircleButtonFrameSize(const LayoutConstraintF & layoutConstraint,SizeF & frameSize,const float & defaultHeight)276 void ButtonLayoutAlgorithm::HandleLabelCircleButtonFrameSize(
277     const LayoutConstraintF& layoutConstraint, SizeF& frameSize, const float& defaultHeight)
278 {
279     float minLength = 0.0f;
280     if (layoutConstraint.parentIdealSize.IsNull()) {
281         minLength = static_cast<float>(defaultHeight);
282     } else if (layoutConstraint.parentIdealSize.Width().has_value() &&
283                !layoutConstraint.parentIdealSize.Height().has_value()) {
284         minLength = frameSize.Width();
285     } else if (layoutConstraint.parentIdealSize.Height().has_value() &&
286                !layoutConstraint.parentIdealSize.Width().has_value()) {
287         minLength = frameSize.Height();
288     } else {
289         minLength = std::min(frameSize.Width(), frameSize.Height());
290     }
291     frameSize.SetWidth(minLength);
292     frameSize.SetHeight(minLength);
293 }
294 
MeasureCircleButton(LayoutWrapper * layoutWrapper)295 void ButtonLayoutAlgorithm::MeasureCircleButton(LayoutWrapper* layoutWrapper)
296 {
297     auto frameNode = layoutWrapper->GetHostNode();
298     CHECK_NULL_VOID(frameNode);
299     auto context = frameNode->GetRenderContext();
300     CHECK_NULL_VOID(context);
301     const auto& radius = context->GetBorderRadius();
302     SizeF frameSize = { -1, -1 };
303     if (radius.has_value()) {
304         auto radiusTopMax = std::max(radius->radiusTopLeft, radius->radiusTopRight);
305         auto radiusBottomMax = std::max(radius->radiusBottomLeft, radius->radiusBottomRight);
306         auto radiusMax = std::max(radiusTopMax, radiusBottomMax);
307         auto rrectRadius = radiusMax.value_or(0.0_vp).ConvertToPx();
308         frameSize.SetSizeT(SizeF { static_cast<float>(rrectRadius * 2), static_cast<float>(rrectRadius * 2) });
309     }
310     frameSize.UpdateIllegalSizeWithCheck(SizeF { 0.0f, 0.0f });
311     layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize);
312 }
313 
GetFirstValidRadius(const BorderRadiusProperty & borderRadius)314 Dimension ButtonLayoutAlgorithm::GetFirstValidRadius(const BorderRadiusProperty& borderRadius)
315 {
316     if (borderRadius.radiusTopLeft.has_value()) {
317         return borderRadius.radiusTopLeft.value();
318     }
319     if (borderRadius.radiusTopRight.has_value()) {
320         return borderRadius.radiusTopRight.value();
321     }
322     if (borderRadius.radiusBottomLeft.has_value()) {
323         return borderRadius.radiusBottomLeft.value();
324     }
325     if (borderRadius.radiusBottomRight.has_value()) {
326         return borderRadius.radiusBottomRight.value();
327     }
328     return 0.0_vp;
329 }
330 
GetDefaultHeight(LayoutWrapper * layoutWrapper)331 float ButtonLayoutAlgorithm::GetDefaultHeight(LayoutWrapper* layoutWrapper)
332 {
333     auto layoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
334     CHECK_NULL_RETURN(layoutProperty, 0.0);
335     auto frameNode = layoutWrapper->GetHostNode();
336     CHECK_NULL_RETURN(frameNode, 0.0);
337     auto* context = frameNode->GetContext();
338     CHECK_NULL_RETURN(context, 0.0);
339     auto buttonTheme = context->GetTheme<ButtonTheme>();
340     CHECK_NULL_RETURN(buttonTheme, 0.0);
341     if (frameNode->GetTag() == V2::TOGGLE_ETS_TAG) {
342         auto toggleTheme = context->GetTheme<ToggleTheme>();
343         CHECK_NULL_RETURN(toggleTheme, 0.0);
344         return static_cast<float>(toggleTheme->GetButtonHeight().ConvertToPx());
345     }
346     ControlSize controlSize = layoutProperty->GetControlSize().value_or(ControlSize::NORMAL);
347     return static_cast<float>(buttonTheme->GetHeight(controlSize).ConvertToPx());
348 }
349 
GetDefaultBorderRadius(LayoutWrapper * layoutWrapper)350 float ButtonLayoutAlgorithm::GetDefaultBorderRadius(LayoutWrapper* layoutWrapper)
351 {
352     auto layoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
353     CHECK_NULL_RETURN(layoutProperty, 0.0f);
354     auto frameNode = layoutWrapper->GetHostNode();
355     CHECK_NULL_RETURN(frameNode, 0.0f);
356     auto* context = frameNode->GetContext();
357     CHECK_NULL_RETURN(context, 0.0f);
358     auto buttonTheme = context->GetTheme<ButtonTheme>();
359     CHECK_NULL_RETURN(buttonTheme, 0.0f);
360     ControlSize controlSize = layoutProperty->GetControlSize().value_or(ControlSize::NORMAL);
361     return static_cast<float>(buttonTheme->GetBorderRadius(controlSize).ConvertToPx());
362 }
363 
NeedAgingMeasure(LayoutWrapper * layoutWrapper)364 bool ButtonLayoutAlgorithm::NeedAgingMeasure(LayoutWrapper* layoutWrapper)
365 {
366     if (!IsAging(layoutWrapper)) {
367         return false;
368     }
369     auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
370     CHECK_NULL_RETURN(buttonLayoutProperty, false);
371     auto pipeline = NG::PipelineContext::GetCurrentContextSafely();
372     CHECK_NULL_RETURN(pipeline, false);
373     auto buttonTheme = pipeline->GetTheme<ButtonTheme>();
374     float agingPadding = buttonTheme->GetAgingNormalPadding().ConvertToPx() * 2.0f;
375     if (buttonLayoutProperty->HasControlSize() && buttonLayoutProperty->GetControlSize() == ControlSize::SMALL) {
376         agingPadding = buttonTheme->GetAgingSmallPadding().ConvertToPx() * 2.0f;
377     }
378     auto host = layoutWrapper->GetHostNode();
379     CHECK_NULL_RETURN(host, false);
380     auto pattern = host->GetPattern<ButtonPattern>();
381     CHECK_NULL_RETURN(pattern, false);
382     if (!pattern->GetHasCustomPadding()) {
383         auto geometryNode = layoutWrapper->GetGeometryNode();
384         CHECK_NULL_RETURN(geometryNode, false);
385         auto frameSize = geometryNode->GetFrameSize();
386         if (buttonLayoutProperty->HasLabel()) {
387             auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0);
388             CHECK_NULL_RETURN(childWrapper, false);
389             auto childGeometryNode = childWrapper->GetGeometryNode();
390             CHECK_NULL_RETURN(childGeometryNode, false);
391             auto childFrameSize = childGeometryNode->GetContentSize();
392             frameSize.SetHeight(childFrameSize.Height() + agingPadding);
393         } else {
394             frameSize.SetHeight(frameSize.Height() + agingPadding);
395         }
396         auto layoutContraint = buttonLayoutProperty->GetLayoutConstraint();
397         CHECK_NULL_RETURN(layoutContraint, false);
398         auto maxHeight = layoutContraint->maxSize.Height();
399         auto minHeight = layoutContraint->minSize.Height();
400         auto actualHeight = frameSize.Height();
401         actualHeight = std::min(actualHeight, maxHeight);
402         actualHeight = std::max(actualHeight, minHeight);
403         frameSize.SetHeight(actualHeight);
404         geometryNode->SetFrameSize(frameSize);
405     }
406     HandleBorderRadius(layoutWrapper);
407     return true;
408 }
409 
IsAging(LayoutWrapper * layoutWrapper)410 bool ButtonLayoutAlgorithm::IsAging(LayoutWrapper* layoutWrapper)
411 {
412     auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
413     CHECK_NULL_RETURN(buttonLayoutProperty, false);
414 
415     if (buttonLayoutProperty->HasType() && buttonLayoutProperty->GetType() == ButtonType::CIRCLE) {
416         return false;
417     }
418 
419     if (buttonLayoutProperty->HasLabel() && buttonLayoutProperty->GetLabel()->empty()) {
420         return false;
421     }
422 
423     if (buttonLayoutProperty->HasFontSize() && buttonLayoutProperty->GetFontSize()->Unit() != DimensionUnit::FP) {
424         return false;
425     }
426     const auto& calcConstraint = buttonLayoutProperty->GetCalcLayoutConstraint();
427     if (calcConstraint && calcConstraint->selfIdealSize->Height().has_value() &&
428         calcConstraint->selfIdealSize->Width().has_value()) {
429         return false;
430     }
431     auto pipeline = NG::PipelineContext::GetCurrentContextSafely();
432     CHECK_NULL_RETURN(pipeline, false);
433     auto buttonTheme = pipeline->GetTheme<ButtonTheme>();
434     CHECK_NULL_RETURN(buttonTheme, false);
435     auto fontScale = pipeline->GetFontScale();
436     if (!(NearEqual(fontScale, buttonTheme->GetBigFontSizeScale()) ||
437             NearEqual(fontScale, buttonTheme->GetLargeFontSizeScale()) ||
438             NearEqual(fontScale, buttonTheme->GetMaxFontSizeScale()))) {
439         return false;
440     }
441     return true;
442 }
443 } // namespace OHOS::Ace::NG
444