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