1 /*
2  * Copyright (c) 2022-2023 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_TEXT_DRAG_TEXT_DRAG_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_DRAG_TEXT_DRAG_PATTERN_H
18 
19 #include "base/memory/referenced.h"
20 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
21 #include "core/components_ng/pattern/text_drag/text_drag_overlay_modifier.h"
22 #include "core/components_ng/pattern/text_drag/text_drag_paint_method.h"
23 #include "core/components_ng/render/drawing.h"
24 #include "core/components_ng/render/paragraph.h"
25 
26 namespace OHOS::Ace::NG {
27 constexpr Dimension TEXT_DRAG_RADIUS = 18.0_vp;
28 constexpr Dimension TEXT_DRAG_OFFSET = 8.0_vp;
29 constexpr Dimension TEXT_DRAG_MIN_WIDTH = 64.0_vp;
30 constexpr uint32_t TEXT_DRAG_COLOR_BG = 0xf2ffffff;
31 
32 struct SelectPositionInfo {
SelectPositionInfoSelectPositionInfo33     SelectPositionInfo() {}
SelectPositionInfoSelectPositionInfo34     SelectPositionInfo(float startX, float startY, float endX, float endY)
35         : startX_(startX), startY_(startY), endX_(endX), endY_(endY)
36     {}
37 
InitGlobalInfoSelectPositionInfo38     void InitGlobalInfo(float globalX, float globalY)
39     {
40         globalX_ = globalX;
41         globalY_ = globalY;
42     }
43 
44     float startX_ = 0;
45     float startY_ = 0;
46     float endX_ = 0;
47     float endY_ = 0;
48     float globalX_ = 0;
49     float globalY_ = 0;
50 };
51 
52 struct TextDragData {
TextDragDataTextDragData53     TextDragData() {}
TextDragDataTextDragData54     TextDragData(RectF textRect, float frameWidth, float frameHeight, float lineHeight, float lastLineHeight)
55         : textRect_(textRect), frameWidth_(frameWidth), frameHeight_(frameHeight), lineHeight_(lineHeight),
56           lastLineHeight_(lastLineHeight)
57     {}
58 
59     RectF textRect_;
60     float frameWidth_ = 0;
61     float frameHeight_ = 0;
62     float lineHeight_ = 0;
63     float lastLineHeight_ = 0;
64     SelectPositionInfo selectPosition_;
65     bool oneLineSelected_ = false;
initSelecitonInfoTextDragData66     void initSelecitonInfo(SelectPositionInfo selectionInfo, bool oneLineSelected)
67     {
68         selectPosition_ = selectionInfo;
69         oneLineSelected_ = oneLineSelected;
70     }
71 };
72 
73 struct TextPoint {
TextPointTextPoint74     TextPoint() {}
TextPointTextPoint75     TextPoint(float x, float y) : x(x), y(y) {}
76 
77     float x = 0;
78     float y = 0;
79 };
80 
81 class TextDragPattern : public Pattern {
82     DECLARE_ACE_TYPE(TextDragPattern, Pattern);
83 
84 public:
85     TextDragPattern() = default;
86     ~TextDragPattern() override = default;
87 
88     static RefPtr<FrameNode> CreateDragNode(const RefPtr<FrameNode>& hostNode);
89 
Initialize(const RefPtr<Paragraph> & paragraph,const TextDragData & data)90     void Initialize(const RefPtr<Paragraph>& paragraph, const TextDragData& data)
91     {
92         paragraph_ = paragraph;
93         textDragData_ = data;
94     }
95 
UpdateParagraph(const RefPtr<Paragraph> & paragraph)96     void UpdateParagraph(const RefPtr<Paragraph>& paragraph)
97     {
98         paragraph_ = paragraph;
99     }
100 
CreateNodePaintMethod()101     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
102     {
103         if (!overlayModifier_) {
104             overlayModifier_ = AceType::MakeRefPtr<TextDragOverlayModifier>(WeakClaim(this));
105         }
106         return MakeRefPtr<TextDragPaintMethod>(WeakClaim(this), overlayModifier_);
107     }
108 
GetParagraph()109     const WeakPtr<Paragraph>& GetParagraph() const
110     {
111         return paragraph_;
112     }
113 
GetOverlayModifier()114     virtual const RefPtr<TextDragOverlayModifier>& GetOverlayModifier() const
115     {
116         return overlayModifier_;
117     }
118 
GetTextRect()119     const RectF& GetTextRect() const
120     {
121         return textDragData_.textRect_;
122     }
123 
GetFrameWidth()124     float GetFrameWidth() const
125     {
126         return textDragData_.frameWidth_;
127     }
128 
GetFrameHeight()129     float GetFrameHeight() const
130     {
131         return textDragData_.frameHeight_;
132     }
133 
GetLineHeight()134     float GetLineHeight() const
135     {
136         return textDragData_.lineHeight_;
137     }
138 
GetSelectPosition()139     const SelectPositionInfo& GetSelectPosition() const
140     {
141         return textDragData_.selectPosition_;
142     }
143 
OneLineSelected()144     bool OneLineSelected() const
145     {
146         return textDragData_.oneLineSelected_;
147     }
148 
GetClipPath()149     const std::shared_ptr<RSPath>& GetClipPath()
150     {
151         if (!clipPath_) {
152             clipPath_ = GenerateClipPath();
153         }
154         return clipPath_;
155     }
156 
GetBackgroundPath()157     const std::shared_ptr<RSPath>& GetBackgroundPath()
158     {
159         if (!backGroundPath_) {
160             backGroundPath_ = GenerateBackgroundPath(TEXT_DRAG_OFFSET.ConvertToPx());
161         }
162         return backGroundPath_;
163     }
164 
GetSelBackgroundPath()165     const std::shared_ptr<RSPath>& GetSelBackgroundPath()
166     {
167         if (!selBackGroundPath_) {
168             selBackGroundPath_ = GenerateSelBackgroundPath(0.0);
169         }
170         return selBackGroundPath_;
171     }
172 
173     std::shared_ptr<RSPath> GenerateBackgroundPath(float offset, float radiusRatio = 1.0f);
174 
175     std::shared_ptr<RSPath> GenerateSelBackgroundPath(float offset);
176 
SetImageChildren(const std::list<RefPtr<FrameNode>> & imageChildren)177     void SetImageChildren(const std::list<RefPtr<FrameNode>>& imageChildren)
178     {
179         imageChildren_ = imageChildren;
180     }
181 
GetImageChildren()182     const std::list<RefPtr<FrameNode>>& GetImageChildren()
183     {
184         return imageChildren_;
185     }
186 
InitSpanImageLayout(const std::list<RefPtr<FrameNode>> & imageChildren,const std::vector<RectF> & rectsForPlaceholders)187     void InitSpanImageLayout(
188         const std::list<RefPtr<FrameNode>>& imageChildren, const std::vector<RectF>& rectsForPlaceholders)
189     {
190         imageChildren_ = imageChildren;
191         rectsForPlaceholders_ = rectsForPlaceholders;
192     }
193 
GetContentOffset()194     OffsetF GetContentOffset()
195     {
196         return contentOffset_;
197     }
198 
SetContentOffset(OffsetF contentOffset)199     void SetContentOffset(OffsetF contentOffset)
200     {
201         contentOffset_ = contentOffset;
202     }
203 
GetRectsForPlaceholders()204     const std::vector<RectF>& GetRectsForPlaceholders()
205     {
206         return rectsForPlaceholders_;
207     }
208 
GetDragCornerRadius()209     virtual Dimension GetDragCornerRadius()
210     {
211         return TEXT_DRAG_RADIUS;
212     }
213 
214     Color GetDragBackgroundColor();
215 protected:
216     static TextDragData CalculateTextDragData(RefPtr<TextDragBase>& pattern, RefPtr<FrameNode>& dragNode);
217     static RectF GetHandler(const bool isLeftHandler, const std::vector<RectF> boxes, const RectF contentRect,
218         const OffsetF globalOffset, const OffsetF textStartOffset);
219     static void AdjustHandlers(const RectF contentRect, RectF& leftHandler, RectF& rightHandler);
220     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
221     std::shared_ptr<RSPath> GenerateClipPath();
222     void GenerateBackgroundPoints(std::vector<TextPoint>& points, float offset, bool needAdjust = true);
223     void CalculateLineAndArc(std::vector<TextPoint>& points, std::shared_ptr<RSPath>& path, float radiusRatio);
224     void CalculateLine(std::vector<TextPoint>& points, std::shared_ptr<RSPath>& path);
225 
SetLastLineHeight(float lineHeight)226     void SetLastLineHeight(float lineHeight)
227     {
228         lastLineHeight_ = lineHeight;
229     }
230 
231 protected:
232     RefPtr<TextDragOverlayModifier> overlayModifier_;
233 
234     TextDragData textDragData_;
235 private:
236     float lastLineHeight_ = 0.0f;
237     OffsetF contentOffset_;
238     WeakPtr<Paragraph> paragraph_;
239     std::shared_ptr<RSPath> clipPath_;
240     std::shared_ptr<RSPath> backGroundPath_;
241     std::shared_ptr<RSPath> selBackGroundPath_;
242     std::list<RefPtr<FrameNode>> imageChildren_;
243     std::vector<RectF> rectsForPlaceholders_;
244 
245     ACE_DISALLOW_COPY_AND_MOVE(TextDragPattern);
246 };
247 } // namespace OHOS::Ace::NG
248 
249 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_DRAG_TEXT_DRAG_PATTERN_H
250