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_PATTERNS_SHAPE_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SHAPE_PATTERN_H
18 
19 #include <cstddef>
20 #include <optional>
21 
22 #include "base/geometry/ng/rect_t.h"
23 #include "base/log/log_wrapper.h"
24 #include "base/memory/referenced.h"
25 #include "base/utils/noncopyable.h"
26 #include "core/components_ng/pattern/pattern.h"
27 #include "core/components_ng/pattern/shape/shape_container_pattern.h"
28 #include "core/components_ng/pattern/shape/shape_layout_algorithm.h"
29 #include "core/components_ng/pattern/shape/shape_overlay_modifier.h"
30 #include "core/components_ng/pattern/shape/shape_paint_property.h"
31 #include "core/components_ng/pattern/shape/shape_view_box.h"
32 
33 namespace OHOS::Ace::NG {
34 class ShapePattern : public Pattern {
35     DECLARE_ACE_TYPE(ShapePattern, Pattern);
36 
37 public:
38     ShapePattern() = default;
39     ~ShapePattern() override = default;
40 
CreateLayoutAlgorithm()41     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
42     {
43         return MakeRefPtr<ShapeLayoutAlgorithm>();
44     }
45 
CreatePaintProperty()46     RefPtr<PaintProperty> CreatePaintProperty() override
47     {
48         return MakeRefPtr<ShapePaintProperty>();
49     }
50 
OnModifyDone()51     void OnModifyDone() override
52     {
53         Pattern::OnModifyDone();
54         auto host = GetHost();
55         CHECK_NULL_VOID(host);
56         auto paintProperty = host->GetPaintProperty<ShapePaintProperty>();
57         CHECK_NULL_VOID(paintProperty);
58         if (paintProperty->HasStrokeMiterLimit()) {
59             auto miterLimit = paintProperty->GetStrokeMiterLimitValue();
60             if (Negative(miterLimit)) {
61                 paintProperty->UpdateStrokeMiterLimit(ShapePaintProperty::STROKE_MITERLIMIT_DEFAULT);
62             } else if (NonNegative(miterLimit) &&
63                 LessNotEqual(miterLimit, ShapePaintProperty::STROKE_MITERLIMIT_MIN)) {
64                 paintProperty->UpdateStrokeMiterLimit(ShapePaintProperty::STROKE_MITERLIMIT_MIN);
65             }
66         }
67     }
68 
69 protected:
GetAncestorPaintProperty()70     RefPtr<ShapePaintProperty> GetAncestorPaintProperty()
71     {
72         auto curFrameNode = GetHost();
73         CHECK_NULL_RETURN(curFrameNode, nullptr);
74         auto childNode = curFrameNode;
75         ShapePaintProperty propertiesFromAncestor;
76         auto parentFrameNode = AceType::DynamicCast<FrameNode>(curFrameNode->GetAncestorNodeOfFrame());
77         while (parentFrameNode) {
78             auto parentPaintProperty = parentFrameNode->GetPaintProperty<ShapePaintProperty>();
79             if (parentPaintProperty) {
80                 propertiesFromAncestor.UpdateShapeProperty(parentPaintProperty);
81                 UpdateForeground(parentFrameNode, childNode);
82                 auto pattern = AceType::DynamicCast<ShapeContainerPattern>(parentFrameNode->GetPattern());
83                 if (pattern) {
84                     pattern->AddChildShapeNode(WeakPtr<FrameNode>(childNode));
85                 }
86             }
87             curFrameNode = parentFrameNode;
88             parentFrameNode = AceType::DynamicCast<FrameNode>(curFrameNode->GetAncestorNodeOfFrame());
89         }
90         return DynamicCast<ShapePaintProperty>(propertiesFromAncestor.Clone());
91     }
92 
UpdateForeground(RefPtr<FrameNode> parentFrameNode,RefPtr<FrameNode> childFrameNode)93     void UpdateForeground(RefPtr<FrameNode> parentFrameNode, RefPtr<FrameNode> childFrameNode)
94     {
95         auto renderContext = parentFrameNode->GetRenderContext();
96         CHECK_NULL_VOID(renderContext);
97         auto childRenderContext = childFrameNode->GetRenderContext();
98         CHECK_NULL_VOID(childRenderContext);
99         if (!childRenderContext->HasForegroundColor() && !childRenderContext->HasForegroundColorStrategy()) {
100             if (renderContext->HasForegroundColor()) {
101                 childRenderContext->UpdateForegroundColor(renderContext->GetForegroundColorValue());
102                 childRenderContext->ResetForegroundColorStrategy();
103                 childRenderContext->UpdateForegroundColorFlag(false);
104             } else if (renderContext->HasForegroundColorStrategy()) {
105                 childRenderContext->UpdateForegroundColorStrategy(renderContext->GetForegroundColorStrategyValue());
106                 childRenderContext->ResetForegroundColor();
107                 childRenderContext->UpdateForegroundColorFlag(false);
108             }
109         } else {
110             if (!childRenderContext->GetForegroundColorFlag().value_or(false)) {
111                 if (renderContext->HasForegroundColor()) {
112                     childRenderContext->UpdateForegroundColor(renderContext->GetForegroundColorValue());
113                     childRenderContext->ResetForegroundColorStrategy();
114                     childRenderContext->UpdateForegroundColorFlag(false);
115                 } else if (renderContext->HasForegroundColorStrategy()) {
116                     childRenderContext->UpdateForegroundColorStrategy(renderContext->GetForegroundColorStrategyValue());
117                     childRenderContext->ResetForegroundColor();
118                     childRenderContext->UpdateForegroundColorFlag(false);
119                 }
120             }
121         }
122     }
123 
124     RefPtr<ShapeOverlayModifier> shapeOverlayModifier_;
125 
126 private:
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,bool skipMeasure,bool skipLayout)127     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, bool skipMeasure, bool skipLayout) override
128     {
129         return !(skipMeasure || dirty->SkipMeasureContent());
130     }
131     ACE_DISALLOW_COPY_AND_MOVE(ShapePattern);
132 };
133 } // namespace OHOS::Ace::NG
134 
135 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SHAPE_PATTERN_H
136