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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_GEOMETRY_NODE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_GEOMETRY_NODE_H 18 19 #include <list> 20 #include <memory> 21 22 #include "base/geometry/ng/offset_t.h" 23 #include "base/geometry/ng/rect_t.h" 24 #include "base/geometry/ng/size_t.h" 25 #include "base/memory/ace_type.h" 26 #include "base/memory/referenced.h" 27 #include "base/utils/macros.h" 28 #include "base/utils/utils.h" 29 #include "core/components_ng/layout/box_layout_algorithm.h" 30 #include "core/components_ng/property/geometry_property.h" 31 #include "core/components_ng/property/layout_constraint.h" 32 #include "core/components_ng/property/magic_layout_property.h" 33 #include "core/components_ng/property/measure_property.h" 34 #include "core/components_ng/property/measure_utils.h" 35 #include "core/components_ng/property/position_property.h" 36 37 namespace OHOS::Ace::NG { 38 class InspectorFilter; 39 using ExpandEdges = PaddingPropertyF; 40 // GeometryNode acts as a physical property of the size and position of the component 41 class ACE_EXPORT GeometryNode : public AceType { 42 DECLARE_ACE_TYPE(GeometryNode, AceType) 43 public: 44 GeometryNode() = default; 45 ~GeometryNode() override = default; 46 47 void Reset(); 48 CheckUnchanged(const GeometryNode & geometryNode)49 bool CheckUnchanged(const GeometryNode& geometryNode) 50 { 51 return (frame_ == geometryNode.frame_) && (margin_ == geometryNode.margin_) && 52 (content_ == geometryNode.content_) && (parentGlobalOffset_ == geometryNode.parentGlobalOffset_) && 53 (parentLayoutConstraint_ == geometryNode.parentLayoutConstraint_); 54 } 55 56 RefPtr<GeometryNode> Clone() const; 57 58 SizeF GetMarginFrameSize(bool withSafeArea = false) const 59 { 60 auto size = frame_.rect_.GetSize(); 61 if (withSafeArea) { 62 size += selfAdjust_.GetSize(); 63 } 64 if (margin_) { 65 AddPaddingToSize(*margin_, size); 66 } 67 return size; 68 } 69 70 OffsetF GetMarginFrameOffset(bool withSafeArea = false) const 71 { 72 auto offset = frame_.rect_.GetOffset(); 73 if (withSafeArea) { 74 offset += selfAdjust_.GetOffset(); 75 } 76 if (margin_) { 77 offset -= OffsetF(margin_->left.value_or(0), margin_->top.value_or(0)); 78 } 79 return offset; 80 } 81 82 RectF GetMarginFrameRect(bool withSafeArea = false) const 83 { 84 auto offset = frame_.rect_.GetOffset(); 85 auto size = frame_.rect_.GetSize(); 86 if (withSafeArea) { 87 offset += selfAdjust_.GetOffset(); 88 size += selfAdjust_.GetSize(); 89 } 90 if (margin_) { 91 offset -= OffsetF(margin_->left.value_or(0), margin_->top.value_or(0)); 92 AddPaddingToSize(*margin_, size); 93 } 94 return RectF(offset, size); 95 } 96 SetMarginFrameOffset(const OffsetF & translate)97 void SetMarginFrameOffset(const OffsetF& translate) 98 { 99 OffsetF offset; 100 if (margin_) { 101 offset += OffsetF(margin_->left.value_or(0), margin_->top.value_or(0)); 102 } 103 frame_.rect_.SetOffset(translate + offset); 104 } 105 106 RectF GetFrameRect(bool withSafeArea = false) const 107 { 108 auto result = frame_.rect_; 109 if (withSafeArea) { 110 result += selfAdjust_; 111 } 112 return result; 113 } 114 115 SizeF GetFrameSize(bool withSafeArea = false) const 116 { 117 auto result = frame_.rect_.GetSize(); 118 if (withSafeArea) { 119 result += selfAdjust_.GetSize(); 120 } 121 return result; 122 } 123 124 OffsetF GetFrameOffset(bool withSafeArea = false) const 125 { 126 auto result = frame_.rect_.GetOffset(); 127 if (withSafeArea) { 128 result += selfAdjust_.GetOffset(); 129 } 130 return result; 131 } 132 SetFrameOffset(const OffsetF & offset)133 void SetFrameOffset(const OffsetF& offset) 134 { 135 frame_.rect_.SetOffset(offset); 136 } 137 SetFrameSize(const SizeF & size)138 void SetFrameSize(const SizeF& size) 139 { 140 frame_.rect_.SetSize(size); 141 } 142 SetFrameHeight(const float height)143 void SetFrameHeight(const float height) 144 { 145 frame_.rect_.SetHeight(height); 146 } 147 SetFrameWidth(const float width)148 void SetFrameWidth(const float width) 149 { 150 frame_.rect_.SetWidth(width); 151 } 152 SetMarginFrameOffsetX(int32_t offsetX)153 void SetMarginFrameOffsetX(int32_t offsetX) 154 { 155 float offset = offsetX; 156 if (margin_) { 157 offset += margin_->left.value_or(0); 158 } 159 frame_.rect_.SetLeft(offset); 160 } 161 SetMarginFrameOffsetY(int32_t offsetY)162 void SetMarginFrameOffsetY(int32_t offsetY) 163 { 164 float offset = offsetY; 165 if (margin_) { 166 offset += margin_->top.value_or(0); 167 } 168 frame_.rect_.SetTop(offset); 169 } 170 171 SizeF GetPaddingSize(bool withSafeArea = false) const 172 { 173 auto size = frame_.rect_.GetSize(); 174 if (withSafeArea) { 175 size += selfAdjust_.GetSize(); 176 } 177 if (padding_) { 178 MinusPaddingToSize(*padding_, size); 179 } 180 return size; 181 } 182 183 OffsetF GetPaddingOffset(bool withSafeArea = false) const 184 { 185 auto offset = frame_.rect_.GetOffset(); 186 if (withSafeArea) { 187 offset += selfAdjust_.GetOffset(); 188 } 189 if (padding_) { 190 offset += OffsetF(padding_->left.value_or(0), padding_->top.value_or(0)); 191 } 192 return offset; 193 } 194 195 RectF GetPaddingRect(bool withSafeArea = false) const 196 { 197 auto rect = frame_.rect_; 198 if (withSafeArea) { 199 rect += selfAdjust_; 200 } 201 if (padding_) { 202 auto size = rect.GetSize(); 203 MinusPaddingToSize(*padding_, size); 204 rect.SetSize(size); 205 auto offset = rect.GetOffset(); 206 offset += OffsetF(padding_->left.value_or(0), padding_->top.value_or(0)); 207 rect.SetOffset(offset); 208 } 209 return rect; 210 } 211 SetContentSize(const SizeF & size)212 void SetContentSize(const SizeF& size) 213 { 214 if (!content_) { 215 content_ = std::make_unique<GeometryProperty>(); 216 } 217 content_->rect_.SetSize(size); 218 } 219 SetContentOffset(const OffsetF & translate)220 void SetContentOffset(const OffsetF& translate) 221 { 222 if (!content_) { 223 content_ = std::make_unique<GeometryProperty>(); 224 } 225 content_->rect_.SetOffset(translate); 226 } 227 GetContentRect()228 RectF GetContentRect() const 229 { 230 return content_ ? content_->rect_ : RectF(); 231 } 232 GetContentSize()233 SizeF GetContentSize() const 234 { 235 return content_ ? content_->rect_.GetSize() : SizeF(); 236 } 237 GetContentOffset()238 OffsetF GetContentOffset() const 239 { 240 return content_ ? content_->rect_.GetOffset() : OffsetF(); 241 } 242 GetPixelRoundContentSize()243 SizeF GetPixelRoundContentSize() const 244 { 245 auto deltaSize = GetPixelGridRoundSize() - GetFrameSize(); 246 return content_ ? (content_->rect_.GetSize() + deltaSize) : SizeF(); 247 } 248 GetPixelRoundContentOffset()249 OffsetF GetPixelRoundContentOffset() const 250 { 251 return content_ ? content_->rect_.GetOffset() : OffsetF(); 252 } 253 GetContent()254 const std::unique_ptr<GeometryProperty>& GetContent() const 255 { 256 return content_; 257 } 258 GetMargin()259 const std::unique_ptr<MarginPropertyF>& GetMargin() const 260 { 261 return margin_; 262 } 263 GetPadding()264 const std::unique_ptr<PaddingPropertyF>& GetPadding() const 265 { 266 return padding_; 267 } 268 UpdateMargin(const MarginPropertyF & margin)269 void UpdateMargin(const MarginPropertyF& margin) 270 { 271 if (!margin_) { 272 margin_ = std::make_unique<MarginPropertyF>(margin); 273 return; 274 } 275 margin_->Reset(); 276 if (margin.left) { 277 margin_->left = margin.left; 278 } 279 if (margin.right) { 280 margin_->right = margin.right; 281 } 282 if (margin.top) { 283 margin_->top = margin.top; 284 } 285 if (margin.bottom) { 286 margin_->bottom = margin.bottom; 287 } 288 } 289 UpdatePaddingWithBorder(const PaddingPropertyF & padding)290 void UpdatePaddingWithBorder(const PaddingPropertyF& padding) 291 { 292 if (!padding_) { 293 padding_ = std::make_unique<PaddingPropertyF>(padding); 294 return; 295 } 296 padding_->Reset(); 297 if (padding.left) { 298 padding_->left = padding.left; 299 } 300 if (padding.right) { 301 padding_->right = padding.right; 302 } 303 if (padding.top) { 304 padding_->top = padding.top; 305 } 306 if (padding.bottom) { 307 padding_->bottom = padding.bottom; 308 } 309 } 310 GetParentGlobalOffset()311 const OffsetF& GetParentGlobalOffset() const 312 { 313 return parentGlobalOffset_; 314 } 315 SetParentGlobalOffset(const OffsetF & parentGlobalOffset)316 void SetParentGlobalOffset(const OffsetF& parentGlobalOffset) 317 { 318 parentGlobalOffset_ = parentGlobalOffset; 319 } 320 GetPixelGridRoundOffset()321 const OffsetF& GetPixelGridRoundOffset() const 322 { 323 return pixelGridRoundOffset_; 324 } 325 SetPixelGridRoundOffset(const OffsetF & pixelGridRoundOffset)326 void SetPixelGridRoundOffset(const OffsetF& pixelGridRoundOffset) 327 { 328 pixelGridRoundOffset_ = pixelGridRoundOffset; 329 } 330 GetPixelGridRoundSize()331 const SizeF& GetPixelGridRoundSize() const 332 { 333 return pixelGridRoundSize_; 334 } 335 GetPixelGridRoundRect()336 RectF GetPixelGridRoundRect() const 337 { 338 return RectF(pixelGridRoundOffset_, pixelGridRoundSize_); 339 } 340 SetPixelGridRoundSize(const SizeF & pixelGridRoundSize)341 void SetPixelGridRoundSize(const SizeF& pixelGridRoundSize) 342 { 343 pixelGridRoundSize_ = pixelGridRoundSize; 344 } 345 GetParentAbsoluteOffset()346 const OffsetF& GetParentAbsoluteOffset() const 347 { 348 return parentAbsoluteOffset_; 349 } 350 SetParentAbsoluteOffset(const OffsetF & parentAbsoluteOffset)351 void SetParentAbsoluteOffset(const OffsetF& parentAbsoluteOffset) 352 { 353 parentAbsoluteOffset_ = parentAbsoluteOffset; 354 } 355 ResetParentLayoutConstraint()356 void ResetParentLayoutConstraint() 357 { 358 parentLayoutConstraint_ = std::nullopt; 359 } 360 SetParentLayoutConstraint(const LayoutConstraintF & layoutConstraint)361 void SetParentLayoutConstraint(const LayoutConstraintF& layoutConstraint) 362 { 363 parentLayoutConstraint_ = layoutConstraint; 364 } 365 GetParentLayoutConstraint()366 const std::optional<LayoutConstraintF>& GetParentLayoutConstraint() const 367 { 368 return parentLayoutConstraint_; 369 } 370 SetBaselineDistance(float baselineDistance)371 void SetBaselineDistance(float baselineDistance) 372 { 373 baselineDistance_ = baselineDistance; 374 } 375 GetBaselineDistance()376 float GetBaselineDistance() 377 { 378 return baselineDistance_.value_or(frame_.rect_.GetY()); 379 } 380 381 void SetAccumulatedSafeAreaEdges(const ExpandEdges& safeAreaPadding); 382 const std::unique_ptr<ExpandEdges>& GetAccumulatedSafeAreaExpand() const; 383 std::optional<RectF> ConvertExpandCacheToAdjustRect() const; 384 void ResetAccumulatedSafeAreaPadding(); 385 // once get resolved, value shou not be changed before reset 386 void SetResolvedSingleSafeAreaPadding(const PaddingPropertyF& safeAreaPadding); 387 const std::unique_ptr<PaddingPropertyF>& GetResolvedSingleSafeAreaPadding() const; 388 void ResetResolvedSelfSafeAreaPadding(); 389 390 RectF GetParentAdjust() const; 391 void SetParentAdjust(RectF parentAdjust); 392 RectF GetSelfAdjust() const; 393 void SetSelfAdjust(RectF selfAdjust); 394 395 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 396 397 private: 398 // the layoutConstraint of prev measure task. 399 std::optional<LayoutConstraintF> parentLayoutConstraint_; 400 401 std::optional<float> baselineDistance_; 402 403 // the frame size in parent local coordinate. 404 GeometryProperty frame_; 405 // the size of margin property. 406 std::unique_ptr<MarginPropertyF> margin_; 407 // the size of padding property. 408 std::unique_ptr<MarginPropertyF> padding_; 409 // the size of content rect in current node local coordinate. 410 std::unique_ptr<GeometryProperty> content_; 411 // all parent safeArea paddings that can be concatenated to expand 412 std::unique_ptr<ExpandEdges> accumulatedSafeAreaExpand_; 413 // value converted from dimension to float to avoid duplicate calculation 414 std::unique_ptr<PaddingPropertyF> resolvedSingleSafeAreaPadding_; 415 416 RectF parentAdjust_; 417 RectF selfAdjust_; 418 419 OffsetF parentGlobalOffset_; 420 OffsetF parentAbsoluteOffset_; 421 OffsetF pixelGridRoundOffset_; 422 SizeF pixelGridRoundSize_; 423 }; 424 } // namespace OHOS::Ace::NG 425 426 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_GEOMETRY_NODE_H 427