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