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