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