• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SPAN_NODE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_SPAN_NODE_H
18 
19 #include <list>
20 #include <memory>
21 #include <string>
22 
23 #include "base/memory/referenced.h"
24 #include "core/components_ng/base/ui_node.h"
25 #include "core/components_ng/pattern/text/text_styles.h"
26 #include "core/components_v2/inspector/inspector_constants.h"
27 #include "core/components_v2/inspector/utils.h"
28 #include "core/gestures/gesture_info.h"
29 
30 #define DEFINE_SPAN_FONT_STYLE_ITEM(name, type)                              \
31 public:                                                                      \
32     std::optional<type> Get##name() const                                    \
33     {                                                                        \
34         if (spanItem_->fontStyle) {                                          \
35             return spanItem_->fontStyle->Get##name();                        \
36         }                                                                    \
37         return std::nullopt;                                                 \
38     }                                                                        \
39     bool Has##name() const                                                   \
40     {                                                                        \
41         if (spanItem_->fontStyle) {                                          \
42             return spanItem_->fontStyle->Has##name();                        \
43         }                                                                    \
44         return false;                                                        \
45     }                                                                        \
46     type Get##name##Value(const type& defaultValue) const                    \
47     {                                                                        \
48         if (spanItem_->fontStyle) {                                          \
49             return spanItem_->fontStyle->Get##name().value_or(defaultValue); \
50         }                                                                    \
51         return defaultValue;                                                 \
52     }                                                                        \
53     void Update##name(const type& value)                                     \
54     {                                                                        \
55         if (!spanItem_->fontStyle) {                                         \
56             spanItem_->fontStyle = std::make_unique<FontStyle>();            \
57         }                                                                    \
58         if (spanItem_->fontStyle->Check##name(value)) {                      \
59             LOGD("the %{public}s is same, just ignore", #name);              \
60             return;                                                          \
61         }                                                                    \
62         spanItem_->fontStyle->Update##name(value);                           \
63         RequestTextFlushDirty();                                             \
64     }                                                                        \
65     void Reset##name()                                                       \
66     {                                                                        \
67         if (spanItem_->fontStyle) {                                          \
68             return spanItem_->fontStyle->Reset##name();                      \
69         }                                                                    \
70     }                                                                        \
71     void Update##name##WithoutFlushDirty(const type& value)                  \
72     {                                                                        \
73         if (!spanItem_->fontStyle) {                                         \
74             spanItem_->fontStyle = std::make_unique<FontStyle>();            \
75         }                                                                    \
76         if (spanItem_->fontStyle->Check##name(value)) {                      \
77             LOGD("the %{public}s is same, just ignore", #name);              \
78             return;                                                          \
79         }                                                                    \
80         spanItem_->fontStyle->Update##name(value);                           \
81     }                                                                        \
82 
83 
84 #define DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(name, type)                             \
85 public:                                                                          \
86     std::optional<type> Get##name() const                                        \
87     {                                                                            \
88         if (spanItem_->textLineStyle) {                                          \
89             return spanItem_->textLineStyle->Get##name();                        \
90         }                                                                        \
91         return std::nullopt;                                                     \
92     }                                                                            \
93     bool Has##name() const                                                       \
94     {                                                                            \
95         if (spanItem_->textLineStyle) {                                          \
96             return spanItem_->textLineStyle->Has##name();                        \
97         }                                                                        \
98         return false;                                                            \
99     }                                                                            \
100     type Get##name##Value(const type& defaultValue) const                        \
101     {                                                                            \
102         if (spanItem_->textLineStyle) {                                          \
103             return spanItem_->textLineStyle->Get##name().value_or(defaultValue); \
104         }                                                                        \
105         return defaultValue;                                                     \
106     }                                                                            \
107     void Update##name(const type& value)                                         \
108     {                                                                            \
109         if (!spanItem_->textLineStyle) {                                         \
110             spanItem_->textLineStyle = std::make_unique<TextLineStyle>();        \
111         }                                                                        \
112         if (spanItem_->textLineStyle->Check##name(value)) {                      \
113             LOGD("the %{public}s is same, just ignore", #name);                  \
114             return;                                                              \
115         }                                                                        \
116         spanItem_->textLineStyle->Update##name(value);                           \
117         RequestTextFlushDirty();                                                 \
118     }                                                                            \
119     void Reset##name()                                                           \
120     {                                                                            \
121         if (spanItem_->textLineStyle) {                                          \
122             return spanItem_->textLineStyle->Reset##name();                      \
123         }                                                                        \
124     }                                                                            \
125     void Update##name##WithoutFlushDirty(const type& value)                      \
126     {                                                                            \
127         if (!spanItem_->textLineStyle) {                                         \
128             spanItem_->textLineStyle = std::make_unique<TextLineStyle>();        \
129         }                                                                        \
130         if (spanItem_->textLineStyle->Check##name(value)) {                      \
131             LOGD("the %{public}s is same, just ignore", #name);                  \
132             return;                                                              \
133         }                                                                        \
134         spanItem_->textLineStyle->Update##name(value);                           \
135     }
136 
137 namespace OHOS::Ace::NG {
138 
139 class Paragraph;
140 
141 struct SpanItem : public AceType {
142     DECLARE_ACE_TYPE(SpanItem, AceType);
143 
144 public:
145     SpanItem() = default;
~SpanItemSpanItem146     virtual ~SpanItem()
147     {
148         children.clear();
149     }
150     int32_t position = -1;
151     std::string content;
152     std::unique_ptr<FontStyle> fontStyle;
153     std::unique_ptr<TextLineStyle> textLineStyle;
154     GestureEventFunc onClick;
155     std::list<RefPtr<SpanItem>> children;
156     int32_t placeHolderIndex = -1;
157 #ifdef ENABLE_DRAG_FRAMEWORK
158     int32_t selectedStart = -1;
159     int32_t selectedEnd = -1;
160 #endif // ENABLE_DRAG_FRAMEWORK
161     virtual int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
162         double width = 0.0f, double height = 0.0f, VerticalAlign verticalAlign = VerticalAlign::BASELINE);
163     virtual void UpdateTextStyle(const RefPtr<Paragraph>& builder, const std::optional<TextStyle>& textStyle);
164     virtual void FontRegisterCallback(const RefPtr<FrameNode>& frameNode, const TextStyle& textStyle);
165     virtual void ToJsonValue(std::unique_ptr<JsonValue>& json) const;
166     std::string GetFont() const;
167 #ifdef ENABLE_DRAG_FRAMEWORK
168     virtual void StartDrag(int32_t start, int32_t end);
169     virtual void EndDrag();
170     virtual bool IsDragging();
171 #endif // ENABLE_DRAG_FRAMEWORK
GetTextStyleSpanItem172     std::optional<TextStyle> GetTextStyle() const
173     {
174         return textStyle_;
175     }
SetTextStyleSpanItem176     void SetTextStyle(const std::optional<TextStyle>& textStyle)
177     {
178         textStyle_ = textStyle;
179     }
180 private:
181     std::optional<TextStyle> textStyle_;
182 };
183 
184 struct ImageSpanItem : public SpanItem {
185     DECLARE_ACE_TYPE(ImageSpanItem, SpanItem);
186 
187 public:
188     ImageSpanItem() = default;
189     ~ImageSpanItem() override = default;
190     int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode,
191         const RefPtr<Paragraph>& builder, double width, double height, VerticalAlign verticalAlign) override;
ToJsonValueImageSpanItem192     void ToJsonValue(std::unique_ptr<JsonValue>& json) const override {};
193 
194     TextStyle textStyle;
195 
196     ACE_DISALLOW_COPY_AND_MOVE(ImageSpanItem);
197 };
198 
199 enum class PropertyInfo {
200     FONTSIZE = 0,
201     FONTCOLOR,
202     FONTSTYLE,
203     FONTWEIGHT,
204     FONTFAMILY,
205     TEXTDECORATION,
206     TEXTCASE,
207     LETTERSPACE,
208     LINEHEIGHT,
209     NONE,
210 };
211 
212 class ACE_EXPORT SpanNode : public UINode {
213     DECLARE_ACE_TYPE(SpanNode, UINode);
214 
215 public:
216     static RefPtr<SpanNode> GetOrCreateSpanNode(int32_t nodeId);
217 
SpanNode(int32_t nodeId)218     explicit SpanNode(int32_t nodeId) : UINode(V2::SPAN_ETS_TAG, nodeId) {}
219     ~SpanNode() override = default;
220 
IsAtomicNode()221     bool IsAtomicNode() const override
222     {
223         return true;
224     }
225 
GetSpanItem()226     const RefPtr<SpanItem>& GetSpanItem() const
227     {
228         return spanItem_;
229     }
230 
UpdateContent(const std::string & content)231     void UpdateContent(const std::string& content)
232     {
233         if (spanItem_->content == content) {
234             LOGD("the content is same, just ignore");
235             return;
236         }
237         spanItem_->content = content;
238         RequestTextFlushDirty();
239     }
240 
UpdateOnClickEvent(GestureEventFunc && onClick)241     void UpdateOnClickEvent(GestureEventFunc&& onClick)
242     {
243         spanItem_->onClick = std::move(onClick);
244     }
245 
246     DEFINE_SPAN_FONT_STYLE_ITEM(FontSize, Dimension);
247     DEFINE_SPAN_FONT_STYLE_ITEM(TextColor, Color);
248     DEFINE_SPAN_FONT_STYLE_ITEM(ItalicFontStyle, Ace::FontStyle);
249     DEFINE_SPAN_FONT_STYLE_ITEM(FontWeight, FontWeight);
250     DEFINE_SPAN_FONT_STYLE_ITEM(FontFamily, std::vector<std::string>);
251     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecoration, TextDecoration);
252     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecorationColor, Color);
253     DEFINE_SPAN_FONT_STYLE_ITEM(TextCase, TextCase);
254     DEFINE_SPAN_FONT_STYLE_ITEM(LetterSpacing, Dimension);
255     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineHeight, Dimension);
256 
257     // Mount to the previous Span node or Text node.
258     void MountToParagraph();
259 
AddChildSpanItem(const RefPtr<SpanNode> & child)260     void AddChildSpanItem(const RefPtr<SpanNode>& child)
261     {
262         spanItem_->children.emplace_back(child->GetSpanItem());
263     }
264 
CleanSpanItemChildren()265     void CleanSpanItemChildren()
266     {
267         spanItem_->children.clear();
268     }
269 
ToJsonValue(std::unique_ptr<JsonValue> & json)270     void ToJsonValue(std::unique_ptr<JsonValue>& json) const override
271     {
272         spanItem_->ToJsonValue(json);
273     }
274 
275     void RequestTextFlushDirty();
276     // The function is only used for fast preview.
FastPreviewUpdateChildDone()277     void FastPreviewUpdateChildDone() override
278     {
279         RequestTextFlushDirty();
280     }
281 
AddPropertyInfo(PropertyInfo value)282     void AddPropertyInfo(PropertyInfo value)
283     {
284         propertyInfo_.insert(value);
285     }
286 
CleanPropertyInfo()287     void CleanPropertyInfo()
288     {
289         propertyInfo_.clear();
290     }
291 
CaculateInheritPropertyInfo()292     std::set<PropertyInfo> CaculateInheritPropertyInfo()
293     {
294         std::set<PropertyInfo> inheritPropertyInfo;
295         const std::set<PropertyInfo> propertyInfoContainer = { PropertyInfo::FONTSIZE,
296                                                                PropertyInfo::FONTCOLOR,
297                                                                PropertyInfo::FONTSTYLE,
298                                                                PropertyInfo::FONTWEIGHT,
299                                                                PropertyInfo::FONTFAMILY,
300                                                                PropertyInfo::TEXTDECORATION,
301                                                                PropertyInfo::TEXTCASE,
302                                                                PropertyInfo::LETTERSPACE,
303                                                                PropertyInfo::LINEHEIGHT };
304         set_difference(propertyInfoContainer.begin(), propertyInfoContainer.end(),
305                        propertyInfo_.begin(), propertyInfo_.end(),
306                        inserter(inheritPropertyInfo, inheritPropertyInfo.begin()));
307         return inheritPropertyInfo;
308     }
309 
310 private:
311     std::list<RefPtr<SpanNode>> spanChildren_;
312     std::set<PropertyInfo> propertyInfo_;
313 
314     RefPtr<SpanItem> spanItem_ = MakeRefPtr<SpanItem>();
315 
316     ACE_DISALLOW_COPY_AND_MOVE(SpanNode);
317 };
318 
319 } // namespace OHOS::Ace::NG
320 
321 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_FOR_EACH_NODE_H
322