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/property/measure_utils.h"
17 
18 #include <memory>
19 #include <optional>
20 
21 #include "base/geometry/ng/size_t.h"
22 #include "base/geometry/size.h"
23 #include "base/log/log.h"
24 #include "base/utils/utils.h"
25 #include "core/components_ng/property/measure_property.h"
26 #include "core/pipeline/pipeline_base.h"
27 
28 namespace OHOS::Ace::NG {
29 namespace {
30 const static int32_t PLATFORM_VERSION_TEN = 10;
31 }
32 
ConvertToSize(const CalcSize & size,const ScaleProperty & scaleProperty,const SizeF & percentReference)33 SizeF ConvertToSize(const CalcSize& size, const ScaleProperty& scaleProperty, const SizeF& percentReference)
34 {
35     auto width = ConvertToPx(size.Width(), scaleProperty, percentReference.Width());
36     auto height = ConvertToPx(size.Height(), scaleProperty, percentReference.Height());
37     return { width.value_or(-1.0f), height.value_or(-1.0f) };
38 }
39 
ConvertToOptionalSize(const CalcSize & size,const ScaleProperty & scaleProperty,const SizeF & percentReference)40 OptionalSizeF ConvertToOptionalSize(
41     const CalcSize& size, const ScaleProperty& scaleProperty, const SizeF& percentReference)
42 {
43     auto width = ConvertToPx(size.Width(), scaleProperty, percentReference.Width());
44     auto height = ConvertToPx(size.Height(), scaleProperty, percentReference.Height());
45     return { width, height };
46 }
47 
ConvertToPx(const CalcLength & value,const ScaleProperty & scaleProperty,float percentReference)48 std::optional<float> ConvertToPx(const CalcLength& value, const ScaleProperty& scaleProperty, float percentReference)
49 {
50     double result = -1.0;
51     if (!value.NormalizeToPx(
52             scaleProperty.vpScale, scaleProperty.fpScale, scaleProperty.lpxScale, percentReference, result)) {
53         return std::nullopt;
54     }
55     return static_cast<float>(result);
56 }
57 
ConvertToPx(const std::optional<CalcLength> & value,const ScaleProperty & scaleProperty,float percentReference)58 std::optional<float> ConvertToPx(
59     const std::optional<CalcLength>& value, const ScaleProperty& scaleProperty, float percentReference)
60 {
61     if (!value) {
62         return std::nullopt;
63     }
64     double result = -1.0;
65     if (!value.value().NormalizeToPx(
66             scaleProperty.vpScale, scaleProperty.fpScale, scaleProperty.lpxScale, percentReference, result)) {
67         return std::nullopt;
68     }
69     return static_cast<float>(result);
70 }
71 
ConvertToPx(const Dimension & dimension,const ScaleProperty & scaleProperty,float percentReference)72 std::optional<float> ConvertToPx(const Dimension& dimension, const ScaleProperty& scaleProperty, float percentReference)
73 {
74     double result = -1.0;
75     if (!dimension.NormalizeToPx(
76             scaleProperty.vpScale, scaleProperty.fpScale, scaleProperty.lpxScale, percentReference, result)) {
77         return std::nullopt;
78     }
79     return static_cast<float>(result);
80 }
81 
ConvertToPx(const std::optional<Dimension> & dimension,const ScaleProperty & scaleProperty,float percentReference)82 std::optional<float> ConvertToPx(
83     const std::optional<Dimension>& dimension, const ScaleProperty& scaleProperty, float percentReference)
84 {
85     if (!dimension) {
86         return std::nullopt;
87     }
88     double result = -1.0;
89     if (!dimension.value().NormalizeToPx(
90             scaleProperty.vpScale, scaleProperty.fpScale, scaleProperty.lpxScale, percentReference, result)) {
91         return std::nullopt;
92     }
93     return static_cast<float>(result);
94 }
95 
ConstrainSize(const SizeF & size,const SizeF & minSize,const SizeF & maxSize)96 SizeF ConstrainSize(const SizeF& size, const SizeF& minSize, const SizeF& maxSize)
97 {
98     float height = std::max(minSize.Height(), size.Height());
99     if (maxSize.Height() > 0) {
100         height = std::min(maxSize.Height(), height);
101     }
102     float width = std::max(minSize.Width(), size.Width());
103     if (maxSize.Width() > 0) {
104         width = std::min(maxSize.Width(), width);
105     }
106     return { width, height };
107 }
108 
ConvertToPaddingPropertyF(const std::unique_ptr<PaddingProperty> & padding,const ScaleProperty & scaleProperty,float percentReference,bool roundPixel,bool nonNegative)109 PaddingPropertyF ConvertToPaddingPropertyF(const std::unique_ptr<PaddingProperty>& padding,
110     const ScaleProperty& scaleProperty, float percentReference, bool roundPixel, bool nonNegative)
111 {
112     if (!padding) {
113         return {};
114     }
115     return ConvertToPaddingPropertyF(*padding, scaleProperty, percentReference, roundPixel, nonNegative);
116 }
117 
ConvertToPaddingPropertyF(const PaddingProperty & padding,const ScaleProperty & scaleProperty,float percentReference,bool roundPixel,bool nonNegative)118 PaddingPropertyF ConvertToPaddingPropertyF(const PaddingProperty& padding, const ScaleProperty& scaleProperty,
119     float percentReference, bool roundPixel, bool nonNegative)
120 {
121     auto left = ConvertToPx(padding.left, scaleProperty, percentReference);
122     auto right = ConvertToPx(padding.right, scaleProperty, percentReference);
123     auto top = ConvertToPx(padding.top, scaleProperty, percentReference);
124     auto bottom = ConvertToPx(padding.bottom, scaleProperty, percentReference);
125     bool versionSatisfy =
126         AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE);
127     if (roundPixel && versionSatisfy) {
128         if (left.has_value()) {
129             left = floor(left.value());
130         }
131         if (right.has_value()) {
132             right = floor(right.value());
133         }
134         if (top.has_value()) {
135             top = floor(top.value());
136         }
137         if (bottom.has_value()) {
138             bottom = floor(bottom.value());
139         }
140     }
141     if (nonNegative && versionSatisfy) {
142         if (left.has_value()) {
143             left = std::max(left.value(), 0.0f);
144         }
145         if (right.has_value()) {
146             right = std::max(right.value(), 0.0f);
147         }
148         if (top.has_value()) {
149             top = std::max(top.value(), 0.0f);
150         }
151         if (bottom.has_value()) {
152             bottom = std::max(bottom.value(), 0.0f);
153         }
154     }
155     return PaddingPropertyF { left, right, top, bottom };
156 }
157 
ConvertToMarginPropertyF(const std::unique_ptr<MarginProperty> & margin,const ScaleProperty & scaleProperty,float percentReference,bool roundPixel)158 MarginPropertyF ConvertToMarginPropertyF(const std::unique_ptr<MarginProperty>& margin,
159     const ScaleProperty& scaleProperty, float percentReference, bool roundPixel)
160 {
161     return ConvertToPaddingPropertyF(margin, scaleProperty, percentReference, roundPixel);
162 }
163 
ConvertToMarginPropertyF(const MarginProperty & margin,const ScaleProperty & scaleProperty,float percentReference,bool roundPixel)164 MarginPropertyF ConvertToMarginPropertyF(
165     const MarginProperty& margin, const ScaleProperty& scaleProperty, float percentReference, bool roundPixel)
166 {
167     return ConvertToPaddingPropertyF(margin, scaleProperty, percentReference, roundPixel);
168 }
169 
ConvertToBorderWidthPropertyF(const std::unique_ptr<BorderWidthProperty> & borderWidth,const ScaleProperty & scaleProperty,float percentReference,bool roundPixel)170 BorderWidthPropertyF ConvertToBorderWidthPropertyF(const std::unique_ptr<BorderWidthProperty>& borderWidth,
171     const ScaleProperty& scaleProperty, float percentReference, bool roundPixel)
172 {
173     if (!borderWidth) {
174         return {};
175     }
176     return ConvertToBorderWidthPropertyF(*borderWidth, scaleProperty, percentReference, roundPixel);
177 }
178 
ConvertToBorderWidthPropertyF(const BorderWidthProperty & borderWidth,const ScaleProperty & scaleProperty,float percentReference,bool roundPixel)179 BorderWidthPropertyF ConvertToBorderWidthPropertyF(
180     const BorderWidthProperty& borderWidth, const ScaleProperty& scaleProperty, float percentReference, bool roundPixel)
181 {
182     auto left = ConvertToPx(borderWidth.leftDimen, scaleProperty, percentReference);
183     auto right = ConvertToPx(borderWidth.rightDimen, scaleProperty, percentReference);
184     auto top = ConvertToPx(borderWidth.topDimen, scaleProperty, percentReference);
185     auto bottom = ConvertToPx(borderWidth.bottomDimen, scaleProperty, percentReference);
186     if (roundPixel && AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
187         if (left.has_value()) {
188             left = (GreatOrEqual(left.value(), 1.0f) || NearEqual(left.value(), 0.0f)) ? floor(left.value()) : 1.0f;
189         }
190         if (right.has_value()) {
191             right = (GreatOrEqual(right.value(), 1.0f) || NearEqual(right.value(), 0.0f)) ? floor(right.value()) : 1.0f;
192         }
193         if (top.has_value()) {
194             top = (GreatOrEqual(top.value(), 1.0f) || NearEqual(top.value(), 0.0f)) ? floor(top.value()) : 1.0f;
195         }
196         if (bottom.has_value()) {
197             bottom =
198                 (GreatOrEqual(bottom.value(), 1.0f) || NearEqual(bottom.value(), 0.0f)) ? floor(bottom.value()) : 1.0f;
199         }
200     }
201     return BorderWidthPropertyF { left, top, right, bottom };
202 }
203 
UpdatePaddingPropertyF(const PaddingProperty & padding,const ScaleProperty & scaleProperty,const SizeF & selfSize,PaddingPropertyF & paddingValue)204 void UpdatePaddingPropertyF(const PaddingProperty& padding, const ScaleProperty& scaleProperty, const SizeF& selfSize,
205     PaddingPropertyF& paddingValue)
206 {
207     auto left = ConvertToPx(padding.left, scaleProperty, selfSize.Width());
208     auto right = ConvertToPx(padding.right, scaleProperty, selfSize.Width());
209     auto top = ConvertToPx(padding.top, scaleProperty, selfSize.Height());
210     auto bottom = ConvertToPx(padding.bottom, scaleProperty, selfSize.Height());
211     if (left.has_value()) {
212         paddingValue.left = left;
213     }
214     if (right.has_value()) {
215         paddingValue.right = right;
216     }
217     if (top.has_value()) {
218         paddingValue.top = top;
219     }
220     if (bottom.has_value()) {
221         paddingValue.bottom = bottom;
222     }
223 }
224 
AddPaddingToSize(const PaddingPropertyF & padding,SizeF & size)225 void AddPaddingToSize(const PaddingPropertyF& padding, SizeF& size)
226 {
227     size.AddPadding(padding.left, padding.right, padding.top, padding.bottom);
228 }
229 
MinusPaddingToSize(const PaddingPropertyF & padding,SizeF & size)230 void MinusPaddingToSize(const PaddingPropertyF& padding, SizeF& size)
231 {
232     size.MinusPadding(padding.left, padding.right, padding.top, padding.bottom);
233 }
234 
MinusPaddingToNonNegativeSize(const PaddingPropertyF & padding,SizeF & size)235 void MinusPaddingToNonNegativeSize(const PaddingPropertyF& padding, SizeF& size)
236 {
237     size.MinusPaddingToNonNegative(padding.left, padding.right, padding.top, padding.bottom);
238 }
239 
AddPaddingToSize(const PaddingPropertyF & padding,OptionalSizeF & size)240 void AddPaddingToSize(const PaddingPropertyF& padding, OptionalSizeF& size)
241 {
242     size.AddPadding(padding.left, padding.right, padding.top, padding.bottom);
243 }
244 
MinusPaddingToSize(const PaddingPropertyF & padding,OptionalSizeF & size)245 void MinusPaddingToSize(const PaddingPropertyF& padding, OptionalSizeF& size)
246 {
247     size.MinusPadding(padding.left, padding.right, padding.top, padding.bottom);
248 }
249 
GetMainAxisOffset(const OffsetF & offset,Axis axis)250 float GetMainAxisOffset(const OffsetF& offset, Axis axis)
251 {
252     return axis == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
253 }
254 
GetMainAxisSize(const SizeF & size,Axis axis)255 float GetMainAxisSize(const SizeF& size, Axis axis)
256 {
257     return axis == Axis::HORIZONTAL ? size.Width() : size.Height();
258 }
259 
GetCrossAxisSize(const SizeF & size,Axis axis)260 float GetCrossAxisSize(const SizeF& size, Axis axis)
261 {
262     return axis == Axis::HORIZONTAL ? size.Height() : size.Width();
263 }
264 
SetCrossAxisSize(float value,Axis axis,SizeF & size)265 void SetCrossAxisSize(float value, Axis axis, SizeF& size)
266 {
267     if (axis == Axis::VERTICAL) {
268         size.SetWidth(value);
269         return;
270     }
271     size.SetHeight(value);
272 }
273 
GetMainAxisSize(const OptionalSizeF & size,Axis axis)274 std::optional<float> GetMainAxisSize(const OptionalSizeF& size, Axis axis)
275 {
276     return axis == Axis::HORIZONTAL ? size.Width() : size.Height();
277 }
278 
GetCrossAxisSize(const OptionalSizeF & size,Axis axis)279 std::optional<float> GetCrossAxisSize(const OptionalSizeF& size, Axis axis)
280 {
281     return axis == Axis::HORIZONTAL ? size.Height() : size.Width();
282 }
283 
SetCrossAxisSize(float value,Axis axis,OptionalSizeF & size)284 void SetCrossAxisSize(float value, Axis axis, OptionalSizeF& size)
285 {
286     if (axis == Axis::VERTICAL) {
287         size.SetWidth(value);
288         return;
289     }
290     size.SetHeight(value);
291 }
292 
SetMainAxisSize(float value,Axis axis,OptionalSizeF & size)293 void SetMainAxisSize(float value, Axis axis, OptionalSizeF& size)
294 {
295     if (axis == Axis::VERTICAL) {
296         size.SetHeight(value);
297         return;
298     }
299     size.SetWidth(value);
300 }
301 
CreateIdealSize(const LayoutConstraintF & layoutConstraint,Axis axis,MeasureType measureType,bool usingMaxSize)302 SizeF CreateIdealSize(const LayoutConstraintF& layoutConstraint, Axis axis, MeasureType measureType, bool usingMaxSize)
303 {
304     auto optional = CreateIdealSize(layoutConstraint, axis, measureType);
305     if (usingMaxSize) {
306         optional.UpdateIllegalSizeWithCheck(layoutConstraint.maxSize);
307     } else {
308         optional.UpdateIllegalSizeWithCheck(layoutConstraint.minSize);
309     }
310     return optional.ConvertToSizeT();
311 }
312 
CreateIdealSize(const LayoutConstraintF & layoutConstraint,Axis axis,MeasureType measureType)313 OptionalSizeF CreateIdealSize(const LayoutConstraintF& layoutConstraint, Axis axis, MeasureType measureType)
314 {
315     OptionalSizeF idealSize;
316     do {
317         // Use idea size first if it is valid.
318         idealSize.UpdateSizeWithCheck(layoutConstraint.selfIdealSize);
319         if (idealSize.IsValid()) {
320             break;
321         }
322 
323         if (measureType == MeasureType::MATCH_PARENT) {
324             idealSize.UpdateIllegalSizeWithCheck(layoutConstraint.parentIdealSize);
325             idealSize.UpdateIllegalSizeWithCheck(layoutConstraint.maxSize);
326             break;
327         }
328 
329         if (measureType == MeasureType::MATCH_PARENT_CROSS_AXIS) {
330             auto selfSize = GetCrossAxisSize(idealSize, axis);
331             if (!selfSize) {
332                 auto parentCrossSize = GetCrossAxisSize(layoutConstraint.parentIdealSize, axis);
333                 if (parentCrossSize) {
334                     SetCrossAxisSize(parentCrossSize.value(), axis, idealSize);
335                 } else {
336                     parentCrossSize = GetCrossAxisSize(layoutConstraint.maxSize, axis);
337                     SetCrossAxisSize(parentCrossSize.value(), axis, idealSize);
338                 }
339             }
340             break;
341         }
342 
343         if (measureType == MeasureType::MATCH_PARENT_MAIN_AXIS) {
344             auto selfSize = GetMainAxisSize(idealSize, axis);
345             auto parentMainSize = GetMainAxisSize(layoutConstraint.parentIdealSize, axis);
346             if (!selfSize) {
347                 if (parentMainSize) {
348                     SetMainAxisSize(parentMainSize.value(), axis, idealSize);
349                 } else {
350                     parentMainSize = GetMainAxisSize(layoutConstraint.maxSize, axis);
351                     SetMainAxisSize(parentMainSize.value(), axis, idealSize);
352                 }
353             }
354             break;
355         }
356     } while (false);
357     return idealSize;
358 }
359 
UpdateOptionSizeByCalcLayoutConstraint(const OptionalSize<float> & frameSize,const std::unique_ptr<MeasureProperty> & calcLayoutConstraint,const SizeT<float> percentReference)360 OptionalSizeF UpdateOptionSizeByCalcLayoutConstraint(const OptionalSize<float>& frameSize,
361     const std::unique_ptr<MeasureProperty>& calcLayoutConstraint, const SizeT<float> percentReference)
362 {
363     OptionalSizeF finalSize(frameSize.Width(), frameSize.Height());
364     if (!calcLayoutConstraint) {
365         return finalSize;
366     } else {
367         UpdateOptionSizeByMaxOrMinCalcLayoutConstraint(
368             finalSize, calcLayoutConstraint->maxSize, percentReference, true);
369         UpdateOptionSizeByMaxOrMinCalcLayoutConstraint(
370             finalSize, calcLayoutConstraint->minSize, percentReference, false);
371     }
372     return finalSize;
373 }
374 
UpdateOptionSizeByMaxOrMinCalcLayoutConstraint(OptionalSizeF & frameSize,const std::optional<CalcSize> & calcLayoutConstraintMaxMinSize,const SizeT<float> percentReference,bool IsMaxSize)375 void UpdateOptionSizeByMaxOrMinCalcLayoutConstraint(OptionalSizeF& frameSize,
376     const std::optional<CalcSize>& calcLayoutConstraintMaxMinSize, const SizeT<float> percentReference, bool IsMaxSize)
377 {
378     auto scaleProperty = ScaleProperty::CreateScaleProperty();
379     if (!calcLayoutConstraintMaxMinSize.has_value()) {
380         return;
381     }
382     if (calcLayoutConstraintMaxMinSize->Width().has_value()) {
383         auto maxWidthPx = ConvertToPx(calcLayoutConstraintMaxMinSize->Width(), scaleProperty, percentReference.Width());
384         if (maxWidthPx.has_value()) {
385             if (IsMaxSize) {
386                 frameSize.SetWidth(std::min(maxWidthPx.value(), frameSize.Width().value_or(maxWidthPx.value())));
387             } else {
388                 frameSize.SetWidth(std::max(maxWidthPx.value(), frameSize.Width().value_or(maxWidthPx.value())));
389             }
390         }
391     }
392     if (calcLayoutConstraintMaxMinSize->Height().has_value()) {
393         auto maxHeightPx =
394             ConvertToPx(calcLayoutConstraintMaxMinSize->Height(), scaleProperty, percentReference.Height());
395         if (maxHeightPx.has_value()) {
396             if (IsMaxSize) {
397                 frameSize.SetHeight(std::min(maxHeightPx.value(), frameSize.Height().value_or(maxHeightPx.value())));
398             } else {
399                 frameSize.SetHeight(std::max(maxHeightPx.value(), frameSize.Height().value_or(maxHeightPx.value())));
400             }
401         }
402     }
403 }
404 
UpdateConstraintByRawConstraint(SizeF & validMinSize,SizeF & validMaxSize,const std::unique_ptr<MeasureProperty> & rawConstraint)405 void UpdateConstraintByRawConstraint(SizeF& validMinSize, SizeF& validMaxSize,
406     const std::unique_ptr<MeasureProperty>& rawConstraint)
407 {
408     if (rawConstraint->minSize) {
409         if (!rawConstraint->minSize.value().Width()) {
410             validMinSize.SetWidth(-1.0f);
411         }
412         if (!rawConstraint->minSize.value().Height()) {
413             validMinSize.SetHeight(-1.0f);
414         }
415     } else {
416         validMinSize = SizeF(-1.0f, -1.0f);
417     }
418     if (rawConstraint->maxSize) {
419         if (!rawConstraint->maxSize.value().Width()) {
420             validMaxSize.SetWidth(-1.0f);
421         }
422         if (!rawConstraint->maxSize.value().Height()) {
423             validMaxSize.SetHeight(-1.0f);
424         }
425     } else {
426         validMaxSize = SizeF(-1.0f, -1.0f);
427     }
428 }
429 
ApplyConstraint(OptionalSizeF & idealSize,const LayoutConstraintF & layoutConstraint,const std::unique_ptr<MeasureProperty> & rawConstraint)430 void ApplyConstraint(OptionalSizeF& idealSize, const LayoutConstraintF& layoutConstraint,
431     const std::unique_ptr<MeasureProperty>& rawConstraint)
432 {
433     auto validMinSize = layoutConstraint.minSize;
434     auto validMaxSize = layoutConstraint.maxSize;
435     if (rawConstraint) {
436         UpdateConstraintByRawConstraint(validMinSize, validMaxSize, rawConstraint);
437     }
438     idealSize.Constrain(validMinSize, validMaxSize,
439         PipelineBase::GetCurrentContext() &&
440             PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN,
441         rawConstraint != nullptr);
442 }
443 
CreateIdealSizeByPercentRef(const LayoutConstraintF & layoutConstraint,Axis axis,MeasureType measureType,bool needToConstrain,const std::unique_ptr<MeasureProperty> & rawConstraint)444 OptionalSizeF CreateIdealSizeByPercentRef(
445     const LayoutConstraintF& layoutConstraint, Axis axis, MeasureType measureType, bool needToConstrain,
446     const std::unique_ptr<MeasureProperty>& rawConstraint)
447 {
448     OptionalSizeF idealSize;
449     do {
450         // Use idea size first if it is valid.
451         idealSize.UpdateSizeWithCheck(layoutConstraint.selfIdealSize);
452         if (idealSize.IsValid()) {
453             break;
454         }
455 
456         if (measureType == MeasureType::MATCH_PARENT) {
457             idealSize.UpdateIllegalSizeWithCheck(layoutConstraint.parentIdealSize);
458             idealSize.UpdateIllegalSizeWithCheck(layoutConstraint.percentReference);
459             break;
460         }
461 
462         if (measureType == MeasureType::MATCH_PARENT_CROSS_AXIS) {
463             auto selfSize = GetCrossAxisSize(idealSize, axis);
464             if (!selfSize) {
465                 auto parentCrossSize = GetCrossAxisSize(layoutConstraint.parentIdealSize, axis);
466                 if (parentCrossSize) {
467                     SetCrossAxisSize(parentCrossSize.value(), axis, idealSize);
468                 } else {
469                     parentCrossSize = GetCrossAxisSize(layoutConstraint.percentReference, axis);
470                     SetCrossAxisSize(parentCrossSize.value(), axis, idealSize);
471                 }
472             }
473             break;
474         }
475 
476         if (measureType == MeasureType::MATCH_PARENT_MAIN_AXIS) {
477             auto selfSize = GetMainAxisSize(idealSize, axis);
478             auto parentMainSize = GetMainAxisSize(layoutConstraint.parentIdealSize, axis);
479             if (!selfSize) {
480                 if (parentMainSize) {
481                     SetMainAxisSize(parentMainSize.value(), axis, idealSize);
482                 } else {
483                     parentMainSize = GetMainAxisSize(layoutConstraint.percentReference, axis);
484                     SetMainAxisSize(parentMainSize.value(), axis, idealSize);
485                 }
486             }
487             break;
488         }
489     } while (false);
490     if (needToConstrain) {
491         ApplyConstraint(idealSize, layoutConstraint, rawConstraint);
492     }
493     return idealSize;
494 }
495 
CreateChildrenConstraint(SizeF & size,const PaddingPropertyF & padding)496 void CreateChildrenConstraint(SizeF& size, const PaddingPropertyF& padding)
497 {
498     float width = 0;
499     float height = 0;
500 
501     float paddingLeft = padding.left.has_value() ? padding.left.value() : 0;
502     float paddingRight = padding.right.has_value() ? padding.right.value() : 0;
503     float paddingTop = padding.top.has_value() ? padding.top.value() : 0;
504     float paddingBottom = padding.bottom.has_value() ? padding.bottom.value() : 0;
505     width += (paddingLeft + paddingRight);
506     height += (paddingTop + paddingBottom);
507 
508     size.SetHeight(size.Height() - height);
509     size.SetWidth(size.Width() - width);
510 }
511 
ConvertToCalcPaddingProperty(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & left,const std::optional<CalcDimension> & right)512 PaddingProperty ConvertToCalcPaddingProperty(const std::optional<CalcDimension>& top,
513     const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& left,
514     const std::optional<CalcDimension>& right)
515 {
516     PaddingProperty paddings;
517     if (top.has_value()) {
518         if (top.value().Unit() == DimensionUnit::CALC) {
519             paddings.top =
520                 NG::CalcLength(top.value().IsNonNegative() ? top.value().CalcValue() : CalcDimension().CalcValue());
521         } else {
522             paddings.top = NG::CalcLength(top.value().IsNonNegative() ? top.value() : CalcDimension());
523         }
524     }
525     if (bottom.has_value()) {
526         if (bottom.value().Unit() == DimensionUnit::CALC) {
527             paddings.bottom = NG::CalcLength(
528                 bottom.value().IsNonNegative() ? bottom.value().CalcValue() : CalcDimension().CalcValue());
529         } else {
530             paddings.bottom = NG::CalcLength(bottom.value().IsNonNegative() ? bottom.value() : CalcDimension());
531         }
532     }
533     if (left.has_value()) {
534         if (left.value().Unit() == DimensionUnit::CALC) {
535             paddings.left =
536                 NG::CalcLength(left.value().IsNonNegative() ? left.value().CalcValue() : CalcDimension().CalcValue());
537         } else {
538             paddings.left = NG::CalcLength(left.value().IsNonNegative() ? left.value() : CalcDimension());
539         }
540     }
541     if (right.has_value()) {
542         if (right.value().Unit() == DimensionUnit::CALC) {
543             paddings.right =
544                 NG::CalcLength(right.value().IsNonNegative() ? right.value().CalcValue() : CalcDimension().CalcValue());
545         } else {
546             paddings.right = NG::CalcLength(right.value().IsNonNegative() ? right.value() : CalcDimension());
547         }
548     }
549     return paddings;
550 }
551 } // namespace OHOS::Ace::NG
552