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