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_PATTERN_BUBBLE_BUBBLE_PAINT_METHOD_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_BUBBLE_BUBBLE_PAINT_METHOD_H
18 
19 #include "base/geometry/dimension.h"
20 #include "base/geometry/ng/offset_t.h"
21 #include "base/geometry/ng/size_t.h"
22 #include "core/components/common/properties/alignment.h"
23 #include "core/components/common/properties/border.h"
24 #include "core/components/common/properties/placement.h"
25 #include "core/components/common/properties/shadow.h"
26 #include "core/components/common/properties/shadow_config.h"
27 #include "core/components_ng/render/canvas_image.h"
28 #include "core/components_ng/render/drawing.h"
29 #include "core/components_ng/render/node_paint_method.h"
30 #include "core/components_ng/render/paint_wrapper.h"
31 
32 namespace OHOS::Ace::NG {
33 
34 class ACE_EXPORT BubblePaintMethod : public NodePaintMethod {
35     DECLARE_ACE_TYPE(BubblePaintMethod, NodePaintMethod)
36 public:
37     BubblePaintMethod() = default;
38     ~BubblePaintMethod() override = default;
39 
GetContentDrawFunction(PaintWrapper * paintWrapper)40     CanvasDrawFunction GetContentDrawFunction(PaintWrapper* paintWrapper) override
41     {
42         return [weak = WeakClaim(this), paintWrapper](RSCanvas& canvas) {
43             auto bubble = weak.Upgrade();
44             if (bubble) {
45                 bubble->PaintMask(canvas, paintWrapper);
46                 bubble->ClipBubble(paintWrapper);
47                 bubble->PaintBorder(canvas, paintWrapper);
48             }
49         };
50     }
51 
GetOverlayDrawFunction(PaintWrapper * paintWrapper)52     CanvasDrawFunction GetOverlayDrawFunction(PaintWrapper* paintWrapper) override
53     {
54         return [weak = WeakClaim(this), paintWrapper](RSCanvas& canvas) {
55             auto bubble = weak.Upgrade();
56             if (bubble) {
57                 bubble->PaintInnerBorder(canvas, paintWrapper);
58                 bubble->PaintOuterBorder(canvas, paintWrapper);
59             }
60         };
61     }
62 
SetShowArrow(bool flag)63     void SetShowArrow(bool flag)
64     {
65         showArrow_ = flag;
66     }
67 
SetChildOffset(const OffsetF & offset)68     void SetChildOffset(const OffsetF& offset)
69     {
70         childOffset_ = offset;
71     }
72 
SetChildSize(const SizeF & size)73     void SetChildSize(const SizeF& size)
74     {
75         childSize_ = size;
76     }
77 
SetArrowPosition(const OffsetF & offset)78     void SetArrowPosition(const OffsetF& offset)
79     {
80         arrowPosition_ = offset;
81     }
82 
SetClipPath(const std::string & clipPath)83     void SetClipPath(const std::string& clipPath)
84     {
85         clipPath_ = clipPath;
86     }
87 
SetBorder(const Border & border)88     void SetBorder(const Border& border)
89     {
90         border_ = border;
91     }
92 
SetClipFrameNode(RefPtr<FrameNode> & clipFrameNode)93     void SetClipFrameNode(RefPtr<FrameNode>& clipFrameNode)
94     {
95         clipFrameNode_ = clipFrameNode;
96     }
97 
SetArrowOffsetsFromClip(const std::vector<std::vector<float>> & arrowOffsetsFromClip)98     void SetArrowOffsetsFromClip(const std::vector<std::vector<float>>& arrowOffsetsFromClip)
99     {
100         arrowOffsetsFromClip_ = arrowOffsetsFromClip;
101     }
102 
SetArrowWidth(const float arrowWidth)103     void SetArrowWidth(const float arrowWidth)
104     {
105         arrowWidth_ = arrowWidth;
106     }
107 
SetArrowHeight(const float arrowHeight)108     void SetArrowHeight(const float arrowHeight)
109     {
110         arrowHeight_ = arrowHeight;
111     }
112 
113     void PaintBubble(RSCanvas& canvas, PaintWrapper* paintWrapper);
114     void PaintMask(RSCanvas& canvas, PaintWrapper* paintWrapper);
115     void PaintBorder(RSCanvas& canvas, PaintWrapper* paintWrapper);
116     void ClipBubble(PaintWrapper* paintWrapper);
117     void PaintDoubleBorder(RSCanvas& canvas, PaintWrapper* paintWrapper);
118     void PaintOuterBorder(RSCanvas& canvas, PaintWrapper* paintWrapper);
119     void PaintInnerBorder(RSCanvas& canvas, PaintWrapper* paintWrapper);
120     bool IsPaintDoubleBorder(PaintWrapper* paintWrapper);
121     void DrawDashedBorder(RSCanvas& canvas, RSPen& paint);
122 
123 private:
124     void PaintBubbleWithArrow(RSCanvas& canvas, PaintWrapper* paintWrapper);
125     void PaintDoubleBorderWithArrow(RSCanvas& canvas, PaintWrapper* paintWrapper);
126     void PaintNonCustomPopup(RSCanvas& canvas, PaintWrapper* wrapper);
127 
128     void PaintTopBubble(RSCanvas& canvas);
129     void PaintBottomBubble(RSCanvas& canvas);
130     void PaintDefaultBubble(RSCanvas& canvas);
131 
132     void UpdateArrowOffset(const std::optional<Dimension>& offset, const Placement& placement);
133 
134     RSRoundRect MakeRRect();
135     float GetArrowOffset(const Placement& placement);
136     void InitEdgeSize(Edge& edge);
137 
138     void BuildCompletePath(RSPath& path);
139     void BuildCornerPath(RSPath& path, const Placement& placement, float radius);
140     void BuildTopLinePath(RSPath& path, float arrowOffset, float radius);
141     void BuildRightLinePath(RSPath& path, float arrowOffset, float radius);
142     void BuildBottomLinePath(RSPath& path, float arrowOffset, float radius);
143     void BuildLeftLinePath(RSPath& path, float arrowOffset, float radius);
144     void PaintShadow(const RSPath& path, const Shadow& shadow, RSCanvas& canvas);
145     void ClipBubbleWithPath(const RefPtr<FrameNode>& frameNode);
146 
147     void BuildDoubleBorderPath(RSPath& path);
148     void BuildTopDoubleBorderPath(RSPath& path, float radius);
149     void BuildRightDoubleBorderPath(RSPath& path, float radius);
150     void BuildBottomDoubleBorderPath(RSPath& path, float radius);
151     void BuildLeftDoubleBorderPath(RSPath& path, float radius);
152 
153     float GetInnerBorderOffset();
154     float GetBorderOffset();
155     float outerBorderWidth_ = Dimension(0.8_vp).ConvertToPx();
156     float innerBorderWidth_ = Dimension(0.6_vp).ConvertToPx();
157     bool needPaintOuterBorder_ = false;
158     bool isPaintBubble_ = false;
159     std::vector<std::vector<float>> arrowOffsetsFromClip_
160         = { {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f} };
161     float arrowWidth_ = Dimension(16.0_vp).ConvertToPx();
162     float arrowHeight_ = Dimension(8.0_vp).ConvertToPx();
163 
164     // Get from RenderProp
165     bool useCustom_ = false;
166     Placement arrowPlacement_ = Placement::BOTTOM;
167     bool enableArrow_ = false;
168     Dimension arrowOffset_;
169     Color maskColor_;
170     Color backgroundColor_;
171 
172     // Get from pattern
173     OffsetF childOffset_;
174     OffsetF arrowPosition_;
175     SizeF childSize_;
176     bool showArrow_ = false;
177     std::string clipPath_;
178     RefPtr<FrameNode> clipFrameNode_;
179     // Get from theme
180     Border border_;
181     Edge padding_;
182     // top right bottom left
183     std::vector<float> arrowOffsetByClips_ = { 0.0f, 0.0f, 0.0f, 0.0f };
184 
185 #ifndef USE_ROSEN_DRAWING
186     RSPath path_;
187 #else
188     RSRecordingPath path_;
189 #endif
190 
191     ACE_DISALLOW_COPY_AND_MOVE(BubblePaintMethod);
192 };
193 } // namespace OHOS::Ace::NG
194 
195 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_BUBBLE_BUBBLE_PAINT_METHOD_H