• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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 <optional>
22 #include <string>
23 
24 #include "base/memory/referenced.h"
25 #include "base/log/dump_log.h"
26 #include "core/common/ai/data_detector_adapter.h"
27 #include "core/common/resource/resource_object.h"
28 #include "core/components/common/layout/constants.h"
29 #include "core/components/common/properties/color.h"
30 #include "core/components/common/properties/text_style.h"
31 #include "core/components_ng/base/ui_node.h"
32 #include "core/components_ng/pattern/image/image_pattern.h"
33 #include "core/components_ng/pattern/pattern.h"
34 #include "core/components_ng/pattern/rich_editor/selection_info.h"
35 #include "core/components_ng/pattern/text/text_styles.h"
36 #include "core/components_ng/pattern/text/span/tlv_util.h"
37 #include "core/components_ng/render/paragraph.h"
38 #include "core/components_v2/inspector/inspector_constants.h"
39 #include "core/components_v2/inspector/utils.h"
40 #include "core/components_ng/pattern/symbol/symbol_effect_options.h"
41 #include "core/components_ng/property/accessibility_property.h"
42 
43 #define DEFINE_SPAN_FONT_STYLE_ITEM(name, type)                              \
44 public:                                                                      \
45     std::optional<type> Get##name() const                                    \
46     {                                                                        \
47         if (spanItem_->fontStyle) {                                          \
48             return spanItem_->fontStyle->Get##name();                        \
49         }                                                                    \
50         return std::nullopt;                                                 \
51     }                                                                        \
52     bool Has##name() const                                                   \
53     {                                                                        \
54         if (spanItem_->fontStyle) {                                          \
55             return spanItem_->fontStyle->Has##name();                        \
56         }                                                                    \
57         return false;                                                        \
58     }                                                                        \
59     type Get##name##Value(const type& defaultValue) const                    \
60     {                                                                        \
61         if (spanItem_->fontStyle) {                                          \
62             return spanItem_->fontStyle->Get##name().value_or(defaultValue); \
63         }                                                                    \
64         return defaultValue;                                                 \
65     }                                                                        \
66     void Update##name(const type& value)                                     \
67     {                                                                        \
68         if (!spanItem_->fontStyle) {                                         \
69             spanItem_->fontStyle = std::make_unique<FontStyle>();            \
70         }                                                                    \
71         if (spanItem_->fontStyle->Check##name(value)) {                      \
72             return;                                                          \
73         }                                                                    \
74         spanItem_->fontStyle->Update##name(value);                           \
75         spanItem_->MarkDirty();                                              \
76         RequestTextFlushDirty();                                             \
77     }                                                                        \
78     void Reset##name()                                                       \
79     {                                                                        \
80         if (spanItem_->fontStyle) {                                          \
81             return spanItem_->fontStyle->Reset##name();                      \
82         }                                                                    \
83     }                                                                        \
84     void Update##name##WithoutFlushDirty(const type& value)                  \
85     {                                                                        \
86         if (!spanItem_->fontStyle) {                                         \
87             spanItem_->fontStyle = std::make_unique<FontStyle>();            \
88         }                                                                    \
89         if (spanItem_->fontStyle->Check##name(value)) {                      \
90             return;                                                          \
91         }                                                                    \
92         spanItem_->fontStyle->Update##name(value);                           \
93     }
94 
95 #define DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(name, type)                             \
96 public:                                                                          \
97     std::optional<type> Get##name() const                                        \
98     {                                                                            \
99         if (spanItem_->textLineStyle) {                                          \
100             return spanItem_->textLineStyle->Get##name();                        \
101         }                                                                        \
102         return std::nullopt;                                                     \
103     }                                                                            \
104     bool Has##name() const                                                       \
105     {                                                                            \
106         if (spanItem_->textLineStyle) {                                          \
107             return spanItem_->textLineStyle->Has##name();                        \
108         }                                                                        \
109         return false;                                                            \
110     }                                                                            \
111     type Get##name##Value(const type& defaultValue) const                        \
112     {                                                                            \
113         if (spanItem_->textLineStyle) {                                          \
114             return spanItem_->textLineStyle->Get##name().value_or(defaultValue); \
115         }                                                                        \
116         return defaultValue;                                                     \
117     }                                                                            \
118     void Update##name(const type& value)                                         \
119     {                                                                            \
120         if (!spanItem_->textLineStyle) {                                         \
121             spanItem_->textLineStyle = std::make_unique<TextLineStyle>();        \
122         }                                                                        \
123         if (spanItem_->textLineStyle->Check##name(value)) {                      \
124             return;                                                              \
125         }                                                                        \
126         spanItem_->textLineStyle->Update##name(value);                           \
127         spanItem_->MarkDirty();                                                  \
128         RequestTextFlushDirty();                                                 \
129     }                                                                            \
130     void Reset##name()                                                           \
131     {                                                                            \
132         if (spanItem_->textLineStyle) {                                          \
133             return spanItem_->textLineStyle->Reset##name();                      \
134         }                                                                        \
135     }                                                                            \
136     void Update##name##WithoutFlushDirty(const type& value)                      \
137     {                                                                            \
138         if (!spanItem_->textLineStyle) {                                         \
139             spanItem_->textLineStyle = std::make_unique<TextLineStyle>();        \
140         }                                                                        \
141         if (spanItem_->textLineStyle->Check##name(value)) {                      \
142             return;                                                              \
143         }                                                                        \
144         spanItem_->textLineStyle->Update##name(value);                           \
145     }
146 
147 namespace OHOS::Ace::NG {
148 namespace {
149 constexpr double DEFAULT_FONT_SIZE_VALUE = 16.0;
150 }
151 using FONT_FEATURES_LIST = std::list<std::pair<std::string, int32_t>>;
152 class InspectorFilter;
153 class Paragraph;
154 
155 enum class SpanItemType { NORMAL = 0, IMAGE = 1, CustomSpan = 2, SYMBOL = 3, PLACEHOLDER = 4 };
156 
157 struct PlaceholderStyle {
158     double width = 0.0f;
159     double height = 0.0f;
160     double baselineOffset = 0.0f;
161     VerticalAlign verticalAlign = VerticalAlign::BOTTOM;
162     TextBaseline baseline = TextBaseline::ALPHABETIC;
163     Dimension paragraphFontSize = Dimension(DEFAULT_FONT_SIZE_VALUE, DimensionUnit::FP);
164 };
165 
166 struct CustomSpanPlaceholderInfo {
167     int32_t customSpanIndex = -1;
168     int32_t paragraphIndex = -1;
169     std::function<void(NG::DrawingContext&, CustomSpanOptions)> onDraw;
170 
ToStringCustomSpanPlaceholderInfo171     std::string ToString()
172     {
173         std::string result = "CustomPlaceholderInfo: [";
174         result += "customSpanIndex: " + std::to_string(customSpanIndex);
175         result += ", paragraphIndex: " + std::to_string(paragraphIndex);
176         result += ", onDraw: ";
177         result += !onDraw ? "nullptr" : "true";
178         result += "]";
179         return result;
180     }
181 };
182 struct SpanItem : public AceType {
183     DECLARE_ACE_TYPE(SpanItem, AceType);
184 
185 public:
186     SpanItem() = default;
~SpanItemSpanItem187     virtual ~SpanItem()
188     {
189         children.clear();
190     }
191     int32_t rangeStart = -1;
192     int32_t position = -1; // position of last char + 1
193     int32_t imageNodeId = -1;
194     int32_t paragraphIndex = -1;
195     uint32_t length = 0;
196     std::string inspectId;
197     std::string description;
198     std::u16string content;
199     uint32_t unicode = 0;
200     SpanItemType spanItemType = SpanItemType::NORMAL;
201     std::pair<int32_t, int32_t> interval;
202     std::unique_ptr<FontStyle> fontStyle = std::make_unique<FontStyle>();
203     std::unique_ptr<TextLineStyle> textLineStyle = std::make_unique<TextLineStyle>();
204     // for text background style
205     std::optional<TextBackgroundStyle> backgroundStyle;
206     GestureEventFunc onClick;
207     GestureEventFunc onLongPress;
208     GestureEventFunc onDoubleClick;
209     OnHoverFunc onHover;
210     [[deprecated]] std::list<RefPtr<SpanItem>> children;
211     std::map<int32_t, AISpan> aiSpanMap;
212     int32_t placeholderIndex = -1;
213     // when paragraph ends with a \n, it causes the paragraph height to gain an extra line
214     // to have normal spacing between paragraphs, remove \n from every paragraph except the last one.
215     bool needRemoveNewLine = false;
216     bool useThemeFontColor = true;
217     bool useThemeDecorationColor = true;
218     std::optional<LeadingMargin> leadingMargin;
219     int32_t selectedStart = -1; // relative offset from span, [selectedStart, selectedEnd)
220     int32_t selectedEnd = -1;
221     bool needReLayout = false;
222     RefPtr<AccessibilityProperty> accessibilityProperty = MakeRefPtr<AccessibilityProperty>();
223     bool UpdateSymbolSpanFontFamily(TextStyle& symbolSpanStyle);
224     void UpdateSymbolSpanParagraph(
225         const RefPtr<FrameNode>& frameNode, const TextStyle& textStyle, const RefPtr<Paragraph>& builder,
226         bool isDragging = false);
227     virtual int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
228         const TextStyle& textStyle, PlaceholderStyle placeholderStyle = PlaceholderStyle(), bool isMarquee = false);
229     virtual void UpdateSymbolSpanColor(const RefPtr<FrameNode>& frameNode, TextStyle& symbolSpanStyle);
230     virtual void UpdateTextStyleForAISpan(const std::u16string& content, const RefPtr<Paragraph>& builder,
231         const TextStyle& textStyle, const TextStyle& aiSpanStyle);
232     virtual void UpdateTextStyle(const std::u16string& content, const RefPtr<Paragraph>& builder,
233         const TextStyle& textStyle, const int32_t selStart, const int32_t selEnd);
234     virtual void UpdateContentTextStyle(
235         const std::u16string& content, const RefPtr<Paragraph>& builder, const TextStyle& textStyle);
236     virtual void GetIndex(int32_t& start, int32_t& end) const;
237     virtual void FontRegisterCallback(const RefPtr<FrameNode>& frameNode, const TextStyle& textStyle);
238     virtual void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const;
239     void ToTreeJson(std::unique_ptr<JsonValue>& json, const InspectorConfig& config) const;
240     std::string GetFont() const;
241     virtual void StartDrag(int32_t start, int32_t end);
242     virtual void EndDrag();
243     virtual bool IsDragging();
244     virtual ResultObject GetSpanResultObject(int32_t start, int32_t end);
245     virtual RefPtr<SpanItem> GetSameStyleSpanItem(bool isEncodeTlvS = false) const;
246     std::optional<std::pair<int32_t, int32_t>> GetIntersectionInterval(std::pair<int32_t, int32_t> interval) const;
247     std::u16string urlAddress;
248     std::function<void()> urlOnRelease;
SetUrlOnReleaseEventSpanItem249     void SetUrlOnReleaseEvent(std::function<void()>&& onRelease)
250     {
251         urlOnRelease = std::move(onRelease);
252     }
ContainsSpanItem253     bool Contains(int32_t index)
254     {
255         return rangeStart < index && index < position;
256     }
GetTextStyleSpanItem257     std::optional<TextStyle> GetTextStyle() const
258     {
259         return textStyle_;
260     }
SetTextStyleSpanItem261     void SetTextStyle(const std::optional<TextStyle>& textStyle)
262     {
263         textStyle_ = textStyle;
264     }
GetResourceObjectSpanItem265     RefPtr<ResourceObject> GetResourceObject()
266     {
267         return resourceObject_;
268     }
SetResourceObjectSpanItem269     void SetResourceObject(RefPtr<ResourceObject> resourceObject)
270     {
271         resourceObject_ = resourceObject;
272     }
SetNeedRemoveNewLineSpanItem273     void SetNeedRemoveNewLine(bool value)
274     {
275         needRemoveNewLine = value;
276     }
SetOnClickEventSpanItem277     void SetOnClickEvent(GestureEventFunc&& onClick_)
278     {
279         onClick = std::move(onClick_);
280     }
SetLongPressEventSpanItem281     void SetLongPressEvent(GestureEventFunc&& onLongPress_)
282     {
283         onLongPress = std::move(onLongPress_);
284     }
285 
SetDoubleClickEventSpanItem286     void SetDoubleClickEvent(GestureEventFunc&& onDoubleClick_)
287     {
288         onDoubleClick = std::move(onDoubleClick_);
289     }
290 
SetHoverEventSpanItem291     void SetHoverEvent(OnHoverFunc&& onHover_)
292     {
293         onHover = std::move(onHover_);
294     }
295 
SetIsParentTextSpanItem296     void SetIsParentText(bool isText)
297     {
298         isParentText = isText;
299     }
GetIsParentTextSpanItem300     bool GetIsParentText()
301     {
302         return isParentText;
303     }
304     std::u16string GetSpanContent(const std::u16string& rawContent, bool isMarquee = false);
305     std::u16string GetSpanContent();
306     uint32_t GetSymbolUnicode();
307     std::string SymbolColorToString();
308 
309     virtual bool EncodeTlv(std::vector<uint8_t>& buff);
310     static RefPtr<SpanItem> DecodeTlv(std::vector<uint8_t>& buff, int32_t& cursor);
311 
SetTextPatternSpanItem312     void SetTextPattern(const RefPtr<Pattern>& pattern)
313     {
314         pattern_ = pattern;
315     }
316 
317     bool UpdateSpanTextColor(Color color);
318 
GetSymbolEffectSwitchSpanItem319     bool GetSymbolEffectSwitch() const
320     {
321         return symbolEffectSwitch_;
322     }
323 
SetSymbolEffectSwitchSpanItem324     void SetSymbolEffectSwitch(bool symbolEffectSwitch)
325     {
326         symbolEffectSwitch_ = symbolEffectSwitch;
327     }
328 
SetSymbolIdSpanItem329     void SetSymbolId(uint32_t symbolId)
330     {
331         symbolId_ = symbolId;
332     }
333 
GetSymbolIdSpanItem334     uint32_t GetSymbolId()
335     {
336         return symbolId_;
337     }
338 
339     virtual void SpanDumpInfo();
340     void SpanDumpInfoAdvance();
MarkDirtySpanItem341     void MarkDirty()
342     {
343         needReLayout = true;
344     }
UpdateContentSpanItem345     void UpdateContent(const std::u16string& newContent)
346     {
347         content = newContent;
348         MarkDirty();
349     }
350 
UpdateTextColorWithoutCheckSpanItem351     void UpdateTextColorWithoutCheck(Color color)
352     {
353         fontStyle->propTextColor = color;
354         MarkDirty();
355     }
356 
UpdateTextDecorationColorWithoutCheckSpanItem357     void UpdateTextDecorationColorWithoutCheck(Color color)
358     {
359         fontStyle->propTextDecorationColor = color;
360         MarkDirty();
361     }
362 
363 private:
364     void EncodeFontStyleTlv(std::vector<uint8_t>& buff) const;
365     void EncodeTextLineStyleTlv(std::vector<uint8_t>& buff) const;
366     std::optional<TextStyle> textStyle_;
367     bool isParentText = false;
368     RefPtr<ResourceObject> resourceObject_;
369     WeakPtr<Pattern> pattern_;
370     bool symbolEffectSwitch_ = true;
371     uint32_t symbolId_ = 0;
372 };
373 
374 class ACE_EXPORT BaseSpan : public virtual AceType {
375     DECLARE_ACE_TYPE(BaseSpan, AceType);
376 
377 public:
BaseSpan(int32_t id)378     explicit BaseSpan(int32_t id) : groupId_(id) {}
379     virtual void MarkTextDirty() = 0;
380     virtual void SetTextBackgroundStyle(const TextBackgroundStyle& style);
UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle> & style)381     virtual void UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle>& style)
382     {
383         textBackgroundStyle_ = style;
384     }
385 
GetTextBackgroundStyle()386     const std::optional<TextBackgroundStyle> GetTextBackgroundStyle() const
387     {
388         return textBackgroundStyle_;
389     }
390 
SetHasTextBackgroundStyle(bool hasStyle)391     void SetHasTextBackgroundStyle(bool hasStyle)
392     {
393         hasTextBackgroundStyle_ = hasStyle;
394     }
395 
HasTextBackgroundStyle()396     bool HasTextBackgroundStyle()
397     {
398         return hasTextBackgroundStyle_;
399     }
400 
401 private:
402     std::optional<TextBackgroundStyle> textBackgroundStyle_;
403     int32_t groupId_ = 0;
404     bool hasTextBackgroundStyle_ = false;
405 };
406 
407 class ACE_EXPORT SpanNode : public UINode, public BaseSpan {
408     DECLARE_ACE_TYPE(SpanNode, UINode, BaseSpan);
409 
410 public:
411     static RefPtr<SpanNode> GetOrCreateSpanNode(int32_t nodeId);
412     static RefPtr<SpanNode> GetOrCreateSpanNode(const std::string& tag, int32_t nodeId);
413     static RefPtr<SpanNode> CreateSpanNode(int32_t nodeId);
414 
SpanNode(int32_t nodeId)415     explicit SpanNode(int32_t nodeId) : UINode(V2::SPAN_ETS_TAG, nodeId), BaseSpan(nodeId) {}
SpanNode(const std::string & tag,int32_t nodeId)416     explicit SpanNode(const std::string& tag, int32_t nodeId) : UINode(tag, nodeId), BaseSpan(nodeId) {}
417     ~SpanNode() override = default;
418 
419     void SetTextBackgroundStyle(const TextBackgroundStyle& style) override;
420     void UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle>& style) override;
421 
IsAtomicNode()422     bool IsAtomicNode() const override
423     {
424         return true;
425     }
426 
IsSyntaxNode()427     bool IsSyntaxNode() const override
428     {
429         return true;
430     }
431 
GetSpanItem()432     const RefPtr<SpanItem>& GetSpanItem() const
433     {
434         return spanItem_;
435     }
436 
UpdateContent(const uint32_t & unicode)437     void UpdateContent(const uint32_t& unicode)
438     {
439         spanItem_->spanItemType = SpanItemType::SYMBOL;
440         if (spanItem_->unicode == unicode) {
441             return;
442         }
443         spanItem_->unicode = unicode;
444         spanItem_->MarkDirty();
445         RequestTextFlushDirty(true);
446     }
447 
UpdateContent(const std::u16string & content)448     void UpdateContent(const std::u16string& content)
449     {
450         if (spanItem_->content == content) {
451             return;
452         }
453         spanItem_->content = content;
454         spanItem_->MarkDirty();
455         RequestTextFlushDirty(true);
456     }
457 
UpdateOnClickEvent(GestureEventFunc && onClick)458     void UpdateOnClickEvent(GestureEventFunc&& onClick)
459     {
460         spanItem_->onClick = std::move(onClick);
461     }
462 
OnInspectorIdUpdate(const std::string & inspectorId)463     void OnInspectorIdUpdate(const std::string& inspectorId) override
464     {
465         spanItem_->inspectId = inspectorId;
466     }
467 
OnAutoEventParamUpdate(const std::string & desc)468     void OnAutoEventParamUpdate(const std::string& desc) override
469     {
470         spanItem_->description = desc;
471     }
472 
UpdateColorByResourceId()473     void UpdateColorByResourceId()
474     {
475         spanItem_->fontStyle->UpdateColorByResourceId();
476         if (spanItem_->backgroundStyle) {
477             spanItem_->backgroundStyle->UpdateColorByResourceId();
478         }
479     }
480 
UpdateTextColorWithoutCheck(Color color)481     void UpdateTextColorWithoutCheck(Color color)
482     {
483         spanItem_->UpdateTextColorWithoutCheck(color);
484     }
485 
UpdateTextDecorationColorWithoutCheck(Color color)486     void UpdateTextDecorationColorWithoutCheck(Color color)
487     {
488         spanItem_->UpdateTextDecorationColorWithoutCheck(color);
489     }
490 
491     DEFINE_SPAN_FONT_STYLE_ITEM(FontSize, Dimension);
492     DEFINE_SPAN_FONT_STYLE_ITEM(TextColor, Color);
493     DEFINE_SPAN_FONT_STYLE_ITEM(ItalicFontStyle, Ace::FontStyle);
494     DEFINE_SPAN_FONT_STYLE_ITEM(FontWeight, FontWeight);
495     DEFINE_SPAN_FONT_STYLE_ITEM(FontFamily, std::vector<std::string>);
496     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecoration, TextDecoration);
497     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecorationStyle, TextDecorationStyle);
498     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecorationColor, Color);
499     DEFINE_SPAN_FONT_STYLE_ITEM(FontFeature, FONT_FEATURES_LIST);
500     DEFINE_SPAN_FONT_STYLE_ITEM(TextCase, TextCase);
501     DEFINE_SPAN_FONT_STYLE_ITEM(TextShadow, std::vector<Shadow>);
502     DEFINE_SPAN_FONT_STYLE_ITEM(LetterSpacing, Dimension);
503     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolColorList, std::vector<Color>);
504     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolRenderingStrategy, uint32_t);
505     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolEffectStrategy, uint32_t);
506     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolEffectOptions, SymbolEffectOptions);
507     DEFINE_SPAN_FONT_STYLE_ITEM(MinFontScale, float);
508     DEFINE_SPAN_FONT_STYLE_ITEM(MaxFontScale, float);
509     DEFINE_SPAN_FONT_STYLE_ITEM(VariableFontWeight, int32_t);
510     DEFINE_SPAN_FONT_STYLE_ITEM(EnableVariableFontWeight, bool);
511     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolType, SymbolType);
512     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineHeight, Dimension);
513     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(BaselineOffset, Dimension);
514     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(TextAlign, TextAlign);
515     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(WordBreak, WordBreak);
516     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LeadingMargin, LeadingMargin);
517     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineBreakStrategy, LineBreakStrategy);
518     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineSpacing, Dimension);
519     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(HalfLeading, bool);
520     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(ParagraphSpacing, Dimension);
521 
522     // Mount to the previous Span node or Text node.
523     void MountToParagraph();
524 
AddChildSpanItem(const RefPtr<SpanNode> & child)525     void AddChildSpanItem(const RefPtr<SpanNode>& child)
526     {
527         spanItem_->children.emplace_back(child->GetSpanItem());
528     }
529 
CleanSpanItemChildren()530     void CleanSpanItemChildren()
531     {
532         spanItem_->children.clear();
533     }
534 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)535     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override
536     {
537         spanItem_->ToJsonValue(json, filter);
538     }
539 
ToTreeJson(std::unique_ptr<JsonValue> & json,const InspectorConfig & config)540     void ToTreeJson(std::unique_ptr<JsonValue>& json, const InspectorConfig& config) const override
541     {
542         spanItem_->ToTreeJson(json, config);
543     }
544 
545     void RequestTextFlushDirty(bool markModifyDone = false);
546     static void RequestTextFlushDirty(const RefPtr<UINode>& node, bool markModifyDone = true);
547     // The function is only used for fast preview.
FastPreviewUpdateChildDone()548     void FastPreviewUpdateChildDone() override
549     {
550         RequestTextFlushDirty(true);
551     }
552 
553     void SetPropertyInfoContainer();
554 
MarkTextDirty()555     void MarkTextDirty() override
556     {
557         RequestTextFlushDirty();
558     }
559 
UpdateSpanTextColor(Color color)560     void UpdateSpanTextColor(Color color)
561     {
562         if (!spanItem_->fontStyle) {
563             spanItem_->fontStyle = std::make_unique<FontStyle>();
564         }
565         if (spanItem_->fontStyle->CheckTextColor(color)) {
566             return;
567         }
568         spanItem_->fontStyle->UpdateTextColor(color);
569         auto parent = GetParent();
570         CHECK_NULL_VOID(parent);
571         if (!spanItem_->UpdateSpanTextColor(color)) {
572             RequestTextFlushDirty();
573         }
574     }
575 
576 protected:
577     void DumpInfo() override;
578     void DumpInfo(std::unique_ptr<JsonValue>& json) override;
DumpSimplifyInfo(std::unique_ptr<JsonValue> & json)579     void DumpSimplifyInfo(std::unique_ptr<JsonValue>& json) override {}
580 
581 private:
582     std::list<RefPtr<SpanNode>> spanChildren_;
583     RefPtr<SpanItem> spanItem_ = MakeRefPtr<SpanItem>();
584 
585     ACE_DISALLOW_COPY_AND_MOVE(SpanNode);
586 };
587 
588 struct PlaceholderSpanItem : public SpanItem {
589     DECLARE_ACE_TYPE(PlaceholderSpanItem, SpanItem);
590 
591 public:
592     int32_t placeholderSpanNodeId = -1;
593     TextStyle textStyle;
594     PlaceholderRun run_;
595     std::optional<Color> dragBackgroundColor_;
596     bool isDragShadowNeeded_ = true;
PlaceholderSpanItemPlaceholderSpanItem597     PlaceholderSpanItem()
598     {
599         this->spanItemType = SpanItemType::PLACEHOLDER;
600     }
601     ~PlaceholderSpanItem() override = default;
ToJsonValuePlaceholderSpanItem602     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override {};
603     int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
604         const TextStyle& textStyle, PlaceholderStyle placeholderStyle = PlaceholderStyle(),
605         bool isMarquee = false) override;
606 
607     void DumpInfo() const;
608     ACE_DISALLOW_COPY_AND_MOVE(PlaceholderSpanItem);
609 
SetCustomNodePlaceholderSpanItem610     void SetCustomNode(const RefPtr<UINode>& customNode)
611     {
612         customNode_ = customNode;
613     }
614 
GetCustomNodePlaceholderSpanItem615     const RefPtr<UINode> GetCustomNode() const
616     {
617         return customNode_;
618     }
619 
UpdateColorByResourceIdPlaceholderSpanItem620     void UpdateColorByResourceId()
621     {
622         CHECK_NULL_VOID(dragBackgroundColor_.has_value());
623         dragBackgroundColor_.value().UpdateColorByResourceId();
624     }
625 
626 private:
627     RefPtr<UINode> customNode_;
628 };
629 
630 class PlaceholderSpanPattern : public Pattern {
631     DECLARE_ACE_TYPE(PlaceholderSpanPattern, Pattern);
632 
633 public:
634     PlaceholderSpanPattern() = default;
635     ~PlaceholderSpanPattern() override = default;
636 
IsAtomicNode()637     bool IsAtomicNode() const override
638     {
639         return false;
640     }
641 };
642 
643 class ACE_EXPORT PlaceholderSpanNode : public FrameNode {
644     DECLARE_ACE_TYPE(PlaceholderSpanNode, FrameNode);
645 
646 public:
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)647     static RefPtr<PlaceholderSpanNode> GetOrCreateSpanNode(
648         const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
649     {
650         auto frameNode = GetFrameNode(tag, nodeId);
651         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<PlaceholderSpanNode>(frameNode));
652         auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
653         auto placeholderSpanNode = AceType::MakeRefPtr<PlaceholderSpanNode>(tag, nodeId, pattern);
654         placeholderSpanNode->InitializePatternAndContext();
655         ElementRegister::GetInstance()->AddUINode(placeholderSpanNode);
656         return placeholderSpanNode;
657     }
658 
PlaceholderSpanNode(const std::string & tag,int32_t nodeId)659     PlaceholderSpanNode(const std::string& tag, int32_t nodeId) : FrameNode(tag, nodeId, AceType::MakeRefPtr<Pattern>())
660     {}
PlaceholderSpanNode(const std::string & tag,int32_t nodeId,const RefPtr<Pattern> & pattern)661     PlaceholderSpanNode(const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern)
662         : FrameNode(tag, nodeId, pattern)
663     {}
664     ~PlaceholderSpanNode() override = default;
665 
GetSpanItem()666     const RefPtr<PlaceholderSpanItem>& GetSpanItem() const
667     {
668         return placeholderSpanItem_;
669     }
670 
IsAtomicNode()671     bool IsAtomicNode() const override
672     {
673         return false;
674     }
675 
MarkModifyDone()676     void MarkModifyDone() override
677     {
678         FrameNode::MarkModifyDone();
679         placeholderSpanItem_->MarkDirty();
680     }
681 
682     void MarkDirtyNode(PropertyChangeFlag extraFlag = PROPERTY_UPDATE_NORMAL) override
683     {
684         FrameNode::MarkDirtyNode(extraFlag);
685         placeholderSpanItem_->MarkDirty();
686     }
687 
DumpInfo()688     void DumpInfo() override
689     {
690         FrameNode::DumpInfo();
691         CHECK_NULL_VOID(placeholderSpanItem_);
692         placeholderSpanItem_->DumpInfo();
693     }
694 
695 private:
696     RefPtr<PlaceholderSpanItem> placeholderSpanItem_ = MakeRefPtr<PlaceholderSpanItem>();
697 
698     ACE_DISALLOW_COPY_AND_MOVE(PlaceholderSpanNode);
699 };
700 
701 struct CustomSpanItem : public PlaceholderSpanItem {
702     DECLARE_ACE_TYPE(CustomSpanItem, PlaceholderSpanItem);
703 
704 public:
CustomSpanItemCustomSpanItem705     CustomSpanItem() : PlaceholderSpanItem()
706     {
707         this->spanItemType = SpanItemType::CustomSpan;
708     }
709     ~CustomSpanItem() override = default;
710     RefPtr<SpanItem> GetSameStyleSpanItem(bool isEncodeTlvS = false) const override;
711     ResultObject GetSpanResultObject(int32_t start, int32_t end) override;
ToJsonValueCustomSpanItem712     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override {};
713     ACE_DISALLOW_COPY_AND_MOVE(CustomSpanItem);
714     std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure;
715     std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw;
SpanDumpInfoCustomSpanItem716     void SpanDumpInfo() override
717     {
718         PlaceholderSpanItem::DumpInfo();
719     }
720     bool isFrameNode = false;
721 };
722 
723 class ACE_EXPORT CustomSpanNode : public FrameNode {
724     DECLARE_ACE_TYPE(CustomSpanNode, FrameNode);
725 
726 public:
CreateFrameNode(int32_t nodeId)727     static RefPtr<CustomSpanNode> CreateFrameNode(int32_t nodeId)
728     {
729         auto customSpanNode = AceType::MakeRefPtr<CustomSpanNode>(V2::CUSTOM_SPAN_NODE_ETS_TAG, nodeId);
730         customSpanNode->InitializePatternAndContext();
731         ElementRegister::GetInstance()->AddUINode(customSpanNode);
732         customSpanNode->customSpanItem_->isFrameNode = true;
733         return customSpanNode;
734     }
735 
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId)736     static RefPtr<CustomSpanNode> GetOrCreateSpanNode(const std::string& tag, int32_t nodeId)
737     {
738         auto frameNode = GetFrameNode(tag, nodeId);
739         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<CustomSpanNode>(frameNode));
740         auto customSpanNode = AceType::MakeRefPtr<CustomSpanNode>(tag, nodeId);
741         customSpanNode->InitializePatternAndContext();
742         ElementRegister::GetInstance()->AddUINode(customSpanNode);
743         customSpanNode->customSpanItem_->isFrameNode = true;
744         return customSpanNode;
745     }
746 
CustomSpanNode(const std::string & tag,int32_t nodeId)747     CustomSpanNode(const std::string& tag, int32_t nodeId) : FrameNode(tag, nodeId, AceType::MakeRefPtr<Pattern>()) {}
748     ~CustomSpanNode() override = default;
749 
GetSpanItem()750     const RefPtr<CustomSpanItem>& GetSpanItem() const
751     {
752         return customSpanItem_;
753     }
754 
IsAtomicNode()755     bool IsAtomicNode() const override
756     {
757         return false;
758     }
759 
DumpInfo()760     void DumpInfo() override
761     {
762         FrameNode::DumpInfo();
763         CHECK_NULL_VOID(customSpanItem_);
764         customSpanItem_->DumpInfo();
765     }
766 
767 private:
768     RefPtr<CustomSpanItem> customSpanItem_ = MakeRefPtr<CustomSpanItem>();
769 
770     ACE_DISALLOW_COPY_AND_MOVE(CustomSpanNode);
771 };
772 
773 struct ImageSpanItem : public PlaceholderSpanItem {
774     DECLARE_ACE_TYPE(ImageSpanItem, PlaceholderSpanItem);
775 
776 public:
ImageSpanItemImageSpanItem777     ImageSpanItem() : PlaceholderSpanItem()
778     {
779         this->spanItemType = SpanItemType::IMAGE;
780     }
781     ~ImageSpanItem() override = default;
782     int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
783         const TextStyle& textStyle, PlaceholderStyle placeholderStyle = PlaceholderStyle(),
784         bool isMarquee = false) override;
ToJsonValueImageSpanItem785     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override {};
786     void UpdatePlaceholderBackgroundStyle(const RefPtr<FrameNode>& imageNode);
787     void SetImageSpanOptions(const ImageSpanOptions& options);
788     void ResetImageSpanOptions();
789     ResultObject GetSpanResultObject(int32_t start, int32_t end) override;
790     RefPtr<SpanItem> GetSameStyleSpanItem(bool isEncodeTlvS = false) const override;
791     ACE_DISALLOW_COPY_AND_MOVE(ImageSpanItem);
792 
793     bool EncodeTlv(std::vector<uint8_t>& buff) override;
794     static RefPtr<ImageSpanItem> DecodeTlv(std::vector<uint8_t>& buff, int32_t& cursor);
795 
796     ImageSpanOptions options;
797     OnHoverFunc onHover_;
798 private:
799     ImageSpanOptions GetImageSpanOptionsFromImageNode() const;
800     ImageSpanAttribute CreateImageSpanAttribute(const  RefPtr<ImageLayoutProperty>& layoutProperty) const;
801 };
802 
803 class ACE_EXPORT ImageSpanNode : public FrameNode {
804     DECLARE_ACE_TYPE(ImageSpanNode, FrameNode);
805 
806 public:
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)807     static RefPtr<ImageSpanNode> GetOrCreateSpanNode(
808         const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
809     {
810         auto frameNode = GetFrameNode(tag, nodeId);
811         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<ImageSpanNode>(frameNode));
812         auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
813         auto imageSpanNode = AceType::MakeRefPtr<ImageSpanNode>(tag, nodeId, pattern);
814         imageSpanNode->InitializePatternAndContext();
815         ElementRegister::GetInstance()->AddUINode(imageSpanNode);
816         return imageSpanNode;
817     }
818 
ImageSpanNode(const std::string & tag,int32_t nodeId)819     ImageSpanNode(const std::string& tag, int32_t nodeId) : FrameNode(tag, nodeId, AceType::MakeRefPtr<ImagePattern>())
820     {}
ImageSpanNode(const std::string & tag,int32_t nodeId,const RefPtr<Pattern> & pattern)821     ImageSpanNode(const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern)
822         : FrameNode(tag, nodeId, pattern)
823     {}
824     ~ImageSpanNode() override = default;
825 
GetSpanItem()826     const RefPtr<ImageSpanItem>& GetSpanItem() const
827     {
828         return imageSpanItem_;
829     }
830 
DumpInfo()831     void DumpInfo() override
832     {
833         FrameNode::DumpInfo();
834         CHECK_NULL_VOID(imageSpanItem_);
835         imageSpanItem_->DumpInfo();
836     }
837 
SetImageItem(const RefPtr<ImageSpanItem> & imageSpan)838     void SetImageItem(const RefPtr<ImageSpanItem>& imageSpan)
839     {
840         imageSpanItem_ = imageSpan;
841     }
842 
843 private:
844     RefPtr<ImageSpanItem> imageSpanItem_ = MakeRefPtr<ImageSpanItem>();
845 
846     ACE_DISALLOW_COPY_AND_MOVE(ImageSpanNode);
847 };
848 
849 class ACE_EXPORT ContainerSpanNode : public UINode, public BaseSpan {
850     DECLARE_ACE_TYPE(ContainerSpanNode, UINode, BaseSpan);
851 
852 public:
GetOrCreateSpanNode(int32_t nodeId)853     static RefPtr<ContainerSpanNode> GetOrCreateSpanNode(int32_t nodeId)
854     {
855         auto spanNode = ElementRegister::GetInstance()->GetSpecificItemById<ContainerSpanNode>(nodeId);
856         if (spanNode) {
857             spanNode->SetHasTextBackgroundStyle(false);
858             return spanNode;
859         }
860         spanNode = MakeRefPtr<ContainerSpanNode>(nodeId);
861         ElementRegister::GetInstance()->AddUINode(spanNode);
862         return spanNode;
863     }
864 
ContainerSpanNode(int32_t nodeId)865     explicit ContainerSpanNode(int32_t nodeId) : UINode(V2::CONTAINER_SPAN_ETS_TAG, nodeId), BaseSpan(nodeId) {}
866     ~ContainerSpanNode() override = default;
867 
868     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override;
869 
IsAtomicNode()870     bool IsAtomicNode() const override
871     {
872         return false;
873     }
874 
MarkTextDirty()875     void MarkTextDirty() override
876     {
877         SpanNode::RequestTextFlushDirty(Claim(this));
878     }
879 
880 private:
881     ACE_DISALLOW_COPY_AND_MOVE(ContainerSpanNode);
882 };
883 } // namespace OHOS::Ace::NG
884 
885 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_FOR_EACH_NODE_H
886