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 <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         RequestTextFlushDirty();                                             \
76     }                                                                        \
77     void Reset##name()                                                       \
78     {                                                                        \
79         if (spanItem_->fontStyle) {                                          \
80             return spanItem_->fontStyle->Reset##name();                      \
81         }                                                                    \
82     }                                                                        \
83     void Update##name##WithoutFlushDirty(const type& value)                  \
84     {                                                                        \
85         if (!spanItem_->fontStyle) {                                         \
86             spanItem_->fontStyle = std::make_unique<FontStyle>();            \
87         }                                                                    \
88         if (spanItem_->fontStyle->Check##name(value)) {                      \
89             return;                                                          \
90         }                                                                    \
91         spanItem_->fontStyle->Update##name(value);                           \
92     }
93 
94 #define DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(name, type)                             \
95 public:                                                                          \
96     std::optional<type> Get##name() const                                        \
97     {                                                                            \
98         if (spanItem_->textLineStyle) {                                          \
99             return spanItem_->textLineStyle->Get##name();                        \
100         }                                                                        \
101         return std::nullopt;                                                     \
102     }                                                                            \
103     bool Has##name() const                                                       \
104     {                                                                            \
105         if (spanItem_->textLineStyle) {                                          \
106             return spanItem_->textLineStyle->Has##name();                        \
107         }                                                                        \
108         return false;                                                            \
109     }                                                                            \
110     type Get##name##Value(const type& defaultValue) const                        \
111     {                                                                            \
112         if (spanItem_->textLineStyle) {                                          \
113             return spanItem_->textLineStyle->Get##name().value_or(defaultValue); \
114         }                                                                        \
115         return defaultValue;                                                     \
116     }                                                                            \
117     void Update##name(const type& value)                                         \
118     {                                                                            \
119         if (!spanItem_->textLineStyle) {                                         \
120             spanItem_->textLineStyle = std::make_unique<TextLineStyle>();        \
121         }                                                                        \
122         if (spanItem_->textLineStyle->Check##name(value)) {                      \
123             return;                                                              \
124         }                                                                        \
125         spanItem_->textLineStyle->Update##name(value);                           \
126         RequestTextFlushDirty();                                                 \
127     }                                                                            \
128     void Reset##name()                                                           \
129     {                                                                            \
130         if (spanItem_->textLineStyle) {                                          \
131             return spanItem_->textLineStyle->Reset##name();                      \
132         }                                                                        \
133     }                                                                            \
134     void Update##name##WithoutFlushDirty(const type& value)                      \
135     {                                                                            \
136         if (!spanItem_->textLineStyle) {                                         \
137             spanItem_->textLineStyle = std::make_unique<TextLineStyle>();        \
138         }                                                                        \
139         if (spanItem_->textLineStyle->Check##name(value)) {                      \
140             return;                                                              \
141         }                                                                        \
142         spanItem_->textLineStyle->Update##name(value);                           \
143     }
144 
145 namespace OHOS::Ace::NG {
146 namespace {
147 constexpr double DEFAULT_FONT_SIZE_VALUE = 16.0;
148 }
149 using FONT_FEATURES_LIST = std::list<std::pair<std::string, int32_t>>;
150 class InspectorFilter;
151 class Paragraph;
152 
153 enum class SpanItemType { NORMAL = 0, IMAGE = 1, CustomSpan = 2, SYMBOL = 3 };
154 
155 struct PlaceholderStyle {
156     double width = 0.0f;
157     double height = 0.0f;
158     double baselineOffset = 0.0f;
159     VerticalAlign verticalAlign = VerticalAlign::BOTTOM;
160     TextBaseline baseline = TextBaseline::ALPHABETIC;
161     Dimension paragraphFontSize = Dimension(DEFAULT_FONT_SIZE_VALUE, DimensionUnit::FP);
162     Color paragraphTextColor = { Color::BLACK };
163 };
164 
165 struct CustomSpanPlaceholderInfo {
166     int32_t customSpanIndex = -1;
167     int32_t paragraphIndex = -1;
168     std::function<void(NG::DrawingContext&, CustomSpanOptions)> onDraw;
169 
ToStringCustomSpanPlaceholderInfo170     std::string ToString()
171     {
172         std::string result = "CustomPlaceholderInfo: [";
173         result += "customSpanIndex: " + std::to_string(customSpanIndex);
174         result += ", paragraphIndex: " + std::to_string(paragraphIndex);
175         result += ", onDraw: ";
176         result += !onDraw ? "nullptr" : "true";
177         result += "]";
178         return result;
179     }
180 };
181 
182 struct SpanItem : public AceType {
183     DECLARE_ACE_TYPE(SpanItem, AceType);
184 public:
185     SpanItem() = default;
~SpanItemSpanItem186     virtual ~SpanItem()
187     {
188         children.clear();
189     }
190     // position of last char + 1
191     int32_t rangeStart = -1;
192     int32_t position = -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::string 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;
220     int32_t selectedEnd = -1;
221     RefPtr<AccessibilityProperty> accessibilityProperty = MakeRefPtr<AccessibilityProperty>();
222     void UpdateSymbolSpanParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder);
223     virtual int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
224         bool isSpanStringMode = false, PlaceholderStyle placeholderStyle = PlaceholderStyle(), bool isMarquee = false);
225     virtual void UpdateSymbolSpanColor(const RefPtr<FrameNode>& frameNode, TextStyle& symbolSpanStyle);
226     virtual void UpdateTextStyleForAISpan(const std::string& content, const RefPtr<Paragraph>& builder,
227         const TextStyle& textStyle, const TextStyle& aiSpanStyle);
228     virtual void UpdateTextStyle(const std::string& content, const RefPtr<Paragraph>& builder,
229         const TextStyle& textStyle, const int32_t selStart, const int32_t selEnd);
230     virtual void UpdateContentTextStyle(
231         const std::string& content, const RefPtr<Paragraph>& builder, const TextStyle& textStyle);
232     virtual void GetIndex(int32_t& start, int32_t& end) const;
233     virtual void FontRegisterCallback(const RefPtr<FrameNode>& frameNode, const TextStyle& textStyle);
234     virtual void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const;
235     std::string GetFont() const;
236     virtual void StartDrag(int32_t start, int32_t end);
237     virtual void EndDrag();
238     virtual bool IsDragging();
239     virtual ResultObject GetSpanResultObject(int32_t start, int32_t end);
240     TextStyle InheritParentProperties(const RefPtr<FrameNode>& frameNode, bool isSpanStringMode = false);
241     virtual RefPtr<SpanItem> GetSameStyleSpanItem() const;
242     std::optional<std::pair<int32_t, int32_t>> GetIntersectionInterval(std::pair<int32_t, int32_t> interval) const;
243     std::function<void()> urlOnRelease;
SetUrlOnReleaseEventSpanItem244     void SetUrlOnReleaseEvent(std::function<void()>&& onRelease)
245     {
246         urlOnRelease = std::move(onRelease);
247     }
ContainsSpanItem248     bool Contains(int32_t index)
249     {
250         return rangeStart < index && index < position;
251     }
GetTextStyleSpanItem252     std::optional<TextStyle> GetTextStyle() const
253     {
254         return textStyle_;
255     }
SetTextStyleSpanItem256     void SetTextStyle(const std::optional<TextStyle>& textStyle)
257     {
258         textStyle_ = textStyle;
259     }
GetResourceObjectSpanItem260     RefPtr<ResourceObject> GetResourceObject()
261     {
262         return resourceObject_;
263     }
SetResourceObjectSpanItem264     void SetResourceObject(RefPtr<ResourceObject> resourceObject)
265     {
266         resourceObject_ = resourceObject;
267     }
SetNeedRemoveNewLineSpanItem268     void SetNeedRemoveNewLine(bool value)
269     {
270         needRemoveNewLine = value;
271     }
SetOnClickEventSpanItem272     void SetOnClickEvent(GestureEventFunc&& onClick_)
273     {
274         onClick = std::move(onClick_);
275     }
SetLongPressEventSpanItem276     void SetLongPressEvent(GestureEventFunc&& onLongPress_)
277     {
278         onLongPress = std::move(onLongPress_);
279     }
280 
SetDoubleClickEventSpanItem281     void SetDoubleClickEvent(GestureEventFunc&& onDoubleClick_)
282     {
283         onDoubleClick = std::move(onDoubleClick_);
284     }
285 
SetHoverEventSpanItem286     void SetHoverEvent(OnHoverFunc&& onHover_)
287     {
288         onHover = std::move(onHover_);
289     }
290 
SetIsParentTextSpanItem291     void SetIsParentText(bool isText)
292     {
293         isParentText = isText;
294     }
GetIsParentTextSpanItem295     bool GetIsParentText()
296     {
297         return isParentText;
298     }
GetHasUserFontWeightSpanItem299     bool GetHasUserFontWeight()
300     {
301         return hasUserFontWeight_;
302     }
SetHasUserFontWeightSpanItem303     void SetHasUserFontWeight(bool hasUserFontWeight)
304     {
305         hasUserFontWeight_ = hasUserFontWeight;
306     }
307     std::string GetSpanContent(const std::string& rawContent, bool isMarquee = false);
308     std::string GetSpanContent();
309     uint32_t GetSymbolUnicode();
310     std::string SymbolColorToString();
311 
312     virtual bool EncodeTlv(std::vector<uint8_t>& buff);
313     static RefPtr<SpanItem> DecodeTlv(std::vector<uint8_t>& buff, int32_t& cursor);
314 
SetTextPatternSpanItem315     void SetTextPattern(const RefPtr<Pattern>& pattern)
316     {
317         pattern_ = pattern;
318     }
319 
320     bool UpdateSpanTextColor(Color color);
SetSymbolIdSpanItem321     void SetSymbolId(uint32_t symbolId)
322     {
323         symbolId_ = symbolId;
324     }
325 
GetSymbolIdSpanItem326     uint32_t GetSymbolId()
327     {
328         return symbolId_;
329     }
330 private:
331     std::optional<TextStyle> textStyle_;
332     bool isParentText = false;
333     bool hasUserFontWeight_ = false;
334     RefPtr<ResourceObject> resourceObject_;
335     WeakPtr<Pattern> pattern_;
336     uint32_t symbolId_ = 0;
337 };
338 
339 enum class PropertyInfo {
340     FONTSIZE = 0,
341     FONTCOLOR,
342     FONTSTYLE,
343     FONTWEIGHT,
344     FONTFAMILY,
345     TEXTDECORATION,
346     TEXTCASE,
347     LETTERSPACE,
348     LINEHEIGHT,
349     TEXT_ALIGN,
350     LEADING_MARGIN,
351     NONE,
352     TEXTSHADOW,
353     SYMBOL_COLOR,
354     SYMBOL_RENDERING_STRATEGY,
355     SYMBOL_EFFECT_STRATEGY,
356     WORD_BREAK,
357     LINE_BREAK_STRATEGY,
358     FONTFEATURE,
359     BASELINE_OFFSET,
360     MIN_FONT_SCALE,
361     MAX_FONT_SCALE,
362     LINESPACING,
363     SYMBOL_EFFECT_OPTIONS,
364     HALFLEADING,
365     VARIABLE_FONT_WEIGHT,
366     ENABLE_VARIABLE_FONT_WEIGHT,
367     BACKGROUNDCOLOR,
368 };
369 
370 class ACE_EXPORT BaseSpan : public virtual AceType {
371     DECLARE_ACE_TYPE(BaseSpan, AceType);
372 
373 public:
BaseSpan(int32_t id)374     explicit BaseSpan(int32_t id) : groupId_(id) {}
375     virtual void MarkTextDirty() = 0;
376     virtual void SetTextBackgroundStyle(const TextBackgroundStyle& style);
UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle> & style)377     virtual void UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle>& style)
378     {
379         textBackgroundStyle_ = style;
380     }
381 
GetTextBackgroundStyle()382     const std::optional<TextBackgroundStyle> GetTextBackgroundStyle() const
383     {
384         return textBackgroundStyle_;
385     }
386 
SetHasTextBackgroundStyle(bool hasStyle)387     void SetHasTextBackgroundStyle(bool hasStyle)
388     {
389         hasTextBackgroundStyle_ = hasStyle;
390     }
391 
HasTextBackgroundStyle()392     bool HasTextBackgroundStyle()
393     {
394         return hasTextBackgroundStyle_;
395     }
396 
397 private:
398     std::optional<TextBackgroundStyle> textBackgroundStyle_;
399     int32_t groupId_ = 0;
400     bool hasTextBackgroundStyle_ = false;
401 };
402 
403 class ACE_EXPORT SpanNode : public UINode, public BaseSpan {
404     DECLARE_ACE_TYPE(SpanNode, UINode, BaseSpan);
405 
406 public:
407     static RefPtr<SpanNode> GetOrCreateSpanNode(int32_t nodeId);
408     static RefPtr<SpanNode> GetOrCreateSpanNode(const std::string& tag, int32_t nodeId);
409     static RefPtr<SpanNode> CreateSpanNode(int32_t nodeId);
410 
SpanNode(int32_t nodeId)411     explicit SpanNode(int32_t nodeId) : UINode(V2::SPAN_ETS_TAG, nodeId), BaseSpan(nodeId) {}
SpanNode(const std::string & tag,int32_t nodeId)412     explicit SpanNode(const std::string& tag, int32_t nodeId) : UINode(tag, nodeId), BaseSpan(nodeId) {}
413     ~SpanNode() override = default;
414 
415     void SetTextBackgroundStyle(const TextBackgroundStyle& style) override;
416     void UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle>& style) override;
417 
IsAtomicNode()418     bool IsAtomicNode() const override
419     {
420         return true;
421     }
422 
GetSpanItem()423     const RefPtr<SpanItem>& GetSpanItem() const
424     {
425         return spanItem_;
426     }
427 
UpdateContent(const uint32_t & unicode)428     void UpdateContent(const uint32_t& unicode)
429     {
430         if (spanItem_->unicode == unicode) {
431             return;
432         }
433         spanItem_->unicode = unicode;
434         RequestTextFlushDirty();
435     }
436 
UpdateContent(const std::string & content)437     void UpdateContent(const std::string& content)
438     {
439         if (spanItem_->content == content) {
440             return;
441         }
442         spanItem_->content = content;
443         RequestTextFlushDirty();
444     }
445 
UpdateOnClickEvent(GestureEventFunc && onClick)446     void UpdateOnClickEvent(GestureEventFunc&& onClick)
447     {
448         spanItem_->onClick = std::move(onClick);
449     }
450 
OnInspectorIdUpdate(const std::string & inspectorId)451     void OnInspectorIdUpdate(const std::string& inspectorId) override
452     {
453         spanItem_->inspectId = inspectorId;
454     }
455 
OnAutoEventParamUpdate(const std::string & desc)456     void OnAutoEventParamUpdate(const std::string& desc) override
457     {
458         spanItem_->description = desc;
459     }
460 
UpdateColorByResourceId()461     void UpdateColorByResourceId()
462     {
463         spanItem_->fontStyle->UpdateColorByResourceId();
464     }
465 
GetHasUserFontWeight()466     bool GetHasUserFontWeight()
467     {
468         return hasUserFontWeight_;
469     }
470 
UpdateUserFontWeight(bool hasUserFontWeight)471     void UpdateUserFontWeight(bool hasUserFontWeight)
472     {
473         hasUserFontWeight_ = hasUserFontWeight;
474         spanItem_->SetHasUserFontWeight(hasUserFontWeight);
475     }
476 
477     DEFINE_SPAN_FONT_STYLE_ITEM(FontSize, Dimension);
478     DEFINE_SPAN_FONT_STYLE_ITEM(TextColor, Color);
479     DEFINE_SPAN_FONT_STYLE_ITEM(ItalicFontStyle, Ace::FontStyle);
480     DEFINE_SPAN_FONT_STYLE_ITEM(FontWeight, FontWeight);
481     DEFINE_SPAN_FONT_STYLE_ITEM(FontFamily, std::vector<std::string>);
482     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecoration, TextDecoration);
483     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecorationStyle, TextDecorationStyle);
484     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecorationColor, Color);
485     DEFINE_SPAN_FONT_STYLE_ITEM(FontFeature, FONT_FEATURES_LIST);
486     DEFINE_SPAN_FONT_STYLE_ITEM(TextCase, TextCase);
487     DEFINE_SPAN_FONT_STYLE_ITEM(TextShadow, std::vector<Shadow>);
488     DEFINE_SPAN_FONT_STYLE_ITEM(LetterSpacing, Dimension);
489     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolColorList, std::vector<Color>);
490     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolRenderingStrategy, uint32_t);
491     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolEffectStrategy, uint32_t);
492     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolEffectOptions, SymbolEffectOptions);
493     DEFINE_SPAN_FONT_STYLE_ITEM(MinFontScale, float);
494     DEFINE_SPAN_FONT_STYLE_ITEM(MaxFontScale, float);
495     DEFINE_SPAN_FONT_STYLE_ITEM(VariableFontWeight, int32_t);
496     DEFINE_SPAN_FONT_STYLE_ITEM(EnableVariableFontWeight, bool);
497     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineHeight, Dimension);
498     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(BaselineOffset, Dimension);
499     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(TextAlign, TextAlign);
500     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(WordBreak, WordBreak);
501     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LeadingMargin, LeadingMargin);
502     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineBreakStrategy, LineBreakStrategy);
503     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineSpacing, Dimension);
504     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(HalfLeading, bool);
505 
506     // Mount to the previous Span node or Text node.
507     void MountToParagraph();
508 
AddChildSpanItem(const RefPtr<SpanNode> & child)509     void AddChildSpanItem(const RefPtr<SpanNode>& child)
510     {
511         spanItem_->children.emplace_back(child->GetSpanItem());
512     }
513 
CleanSpanItemChildren()514     void CleanSpanItemChildren()
515     {
516         spanItem_->children.clear();
517     }
518 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)519     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override
520     {
521         spanItem_->ToJsonValue(json, filter);
522     }
523 
524     void RequestTextFlushDirty();
525     static void RequestTextFlushDirty(const RefPtr<UINode>& node);
526     // The function is only used for fast preview.
FastPreviewUpdateChildDone()527     void FastPreviewUpdateChildDone() override
528     {
529         RequestTextFlushDirty();
530     }
531 
AddPropertyInfo(PropertyInfo value)532     void AddPropertyInfo(PropertyInfo value)
533     {
534         propertyInfo_.insert(value);
535     }
536 
ResetPropertyInfo(PropertyInfo value)537     void ResetPropertyInfo(PropertyInfo value)
538     {
539         propertyInfo_.erase(value);
540     }
541 
CleanPropertyInfo()542     void CleanPropertyInfo()
543     {
544         propertyInfo_.clear();
545     }
546 
MarkTextDirty()547     void MarkTextDirty() override
548     {
549         RequestTextFlushDirty();
550     }
551 
552     std::set<PropertyInfo> CalculateInheritPropertyInfo();
553 
554 
UpdateSpanTextColor(Color color)555     void UpdateSpanTextColor(Color color)
556     {
557         if (!spanItem_->fontStyle) {
558             spanItem_->fontStyle = std::make_unique<FontStyle>();
559         }
560         if (spanItem_->fontStyle->CheckTextColor(color)) {
561             return;
562         }
563         spanItem_->fontStyle->UpdateTextColor(color);
564         auto parent = GetParent();
565         CHECK_NULL_VOID(parent);
566         if (!spanItem_->UpdateSpanTextColor(color)) {
567             RequestTextFlushDirty();
568         }
569     }
570 
571 protected:
572     void DumpInfo() override;
573 
574 private:
575     std::list<RefPtr<SpanNode>> spanChildren_;
576     std::set<PropertyInfo> propertyInfo_;
577     bool hasUserFontWeight_ = false;
578     RefPtr<SpanItem> spanItem_ = MakeRefPtr<SpanItem>();
579 
580     ACE_DISALLOW_COPY_AND_MOVE(SpanNode);
581 };
582 
583 struct PlaceholderSpanItem : public SpanItem {
584     DECLARE_ACE_TYPE(PlaceholderSpanItem, SpanItem);
585 
586 public:
587     int32_t placeholderSpanNodeId = -1;
588     TextStyle textStyle;
589     PlaceholderRun run_;
590     PlaceholderSpanItem() = default;
591     ~PlaceholderSpanItem() override = default;
ToJsonValuePlaceholderSpanItem592     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override {};
593     int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
594         bool isSpanStringMode = false, PlaceholderStyle placeholderStyle = PlaceholderStyle(),
595         bool isMarquee = false) override;
596 
DumpInfoPlaceholderSpanItem597     void DumpInfo() const
598     {
599         auto& dumpLog = DumpLog::GetInstance();
600         dumpLog.AddDesc("--------------- print run info ---------------");
601         dumpLog.AddDesc(std::string("Width: ").append(std::to_string(run_.width)));
602         dumpLog.AddDesc(std::string("Height: ").append(std::to_string(run_.height)));
603         dumpLog.AddDesc(std::string("Alignment: ").append(StringUtils::ToString(run_.alignment)));
604         dumpLog.AddDesc(std::string("Baseline: ").append(StringUtils::ToString(run_.baseline)));
605         dumpLog.AddDesc(std::string("BaselineOffset: ").append(std::to_string(run_.baseline_offset)));
606         dumpLog.AddDesc("--------------- print text style ---------------");
607         dumpLog.AddDesc(std::string("FontSize: ").append(textStyle.GetFontSize().ToString()));
608         dumpLog.AddDesc(std::string("LineHeight: ").append(textStyle.GetLineHeight().ToString()));
609         dumpLog.AddDesc(std::string("LineSpacing: ").append(textStyle.GetLineSpacing().ToString()));
610         dumpLog.AddDesc(std::string("VerticalAlign: ").append(StringUtils::ToString(textStyle.GetTextVerticalAlign())));
611         dumpLog.AddDesc(std::string("HalfLeading: ").append(std::to_string(textStyle.GetHalfLeading())));
612         dumpLog.AddDesc(std::string("TextBaseline: ").append(StringUtils::ToString(textStyle.GetTextBaseline())));
613     }
614     ACE_DISALLOW_COPY_AND_MOVE(PlaceholderSpanItem);
615 
SetCustomNodePlaceholderSpanItem616     void SetCustomNode(const RefPtr<UINode>& customNode)
617     {
618         customNode_ = customNode;
619     }
620 
GetCustomNodePlaceholderSpanItem621     const RefPtr<UINode> GetCustomNode() const
622     {
623         return customNode_;
624     }
625 private:
626     RefPtr<UINode> customNode_;
627 };
628 
629 class PlaceholderSpanPattern : public Pattern {
630     DECLARE_ACE_TYPE(PlaceholderSpanPattern, Pattern);
631 
632 public:
633     PlaceholderSpanPattern() = default;
634     ~PlaceholderSpanPattern() override = default;
635 
IsAtomicNode()636     bool IsAtomicNode() const override
637     {
638         return false;
639     }
640 };
641 
642 class ACE_EXPORT PlaceholderSpanNode : public FrameNode {
643     DECLARE_ACE_TYPE(PlaceholderSpanNode, FrameNode);
644 
645 public:
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)646     static RefPtr<PlaceholderSpanNode> GetOrCreateSpanNode(
647         const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
648     {
649         auto frameNode = GetFrameNode(tag, nodeId);
650         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<PlaceholderSpanNode>(frameNode));
651         auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
652         auto placeholderSpanNode = AceType::MakeRefPtr<PlaceholderSpanNode>(tag, nodeId, pattern);
653         placeholderSpanNode->InitializePatternAndContext();
654         ElementRegister::GetInstance()->AddUINode(placeholderSpanNode);
655         return placeholderSpanNode;
656     }
657 
PlaceholderSpanNode(const std::string & tag,int32_t nodeId)658     PlaceholderSpanNode(const std::string& tag, int32_t nodeId) : FrameNode(tag, nodeId, AceType::MakeRefPtr<Pattern>())
659     {}
PlaceholderSpanNode(const std::string & tag,int32_t nodeId,const RefPtr<Pattern> & pattern)660     PlaceholderSpanNode(const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern)
661         : FrameNode(tag, nodeId, pattern)
662     {}
663     ~PlaceholderSpanNode() override = default;
664 
GetSpanItem()665     const RefPtr<PlaceholderSpanItem>& GetSpanItem() const
666     {
667         return placeholderSpanItem_;
668     }
669 
IsAtomicNode()670     bool IsAtomicNode() const override
671     {
672         return false;
673     }
674 
DumpInfo()675     void DumpInfo() override
676     {
677         FrameNode::DumpInfo();
678         CHECK_NULL_VOID(placeholderSpanItem_);
679         placeholderSpanItem_->DumpInfo();
680     }
681 
682 private:
683     RefPtr<PlaceholderSpanItem> placeholderSpanItem_ = MakeRefPtr<PlaceholderSpanItem>();
684 
685     ACE_DISALLOW_COPY_AND_MOVE(PlaceholderSpanNode);
686 };
687 
688 struct CustomSpanItem : public PlaceholderSpanItem {
689     DECLARE_ACE_TYPE(CustomSpanItem, PlaceholderSpanItem);
690 
691 public:
CustomSpanItemCustomSpanItem692     CustomSpanItem() : PlaceholderSpanItem()
693     {
694         this->spanItemType = SpanItemType::CustomSpan;
695     }
696     ~CustomSpanItem() override = default;
697     RefPtr<SpanItem> GetSameStyleSpanItem() const override;
698     ResultObject GetSpanResultObject(int32_t start, int32_t end) override;
ToJsonValueCustomSpanItem699     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override {};
700     ACE_DISALLOW_COPY_AND_MOVE(CustomSpanItem);
701     std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure;
702     std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw;
703     bool isFrameNode = false;
704 };
705 
706 class ACE_EXPORT CustomSpanNode : public FrameNode {
707     DECLARE_ACE_TYPE(CustomSpanNode, FrameNode);
708 
709 public:
CreateFrameNode(int32_t nodeId)710     static RefPtr<CustomSpanNode> CreateFrameNode(int32_t nodeId)
711     {
712         auto customSpanNode = AceType::MakeRefPtr<CustomSpanNode>(
713             V2::CUSTOM_SPAN_NODE_ETS_TAG, nodeId);
714         customSpanNode->InitializePatternAndContext();
715         ElementRegister::GetInstance()->AddUINode(customSpanNode);
716         customSpanNode->customSpanItem_->isFrameNode = true;
717         return customSpanNode;
718     }
719 
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId)720     static RefPtr<CustomSpanNode> GetOrCreateSpanNode(
721         const std::string& tag, int32_t nodeId)
722     {
723         auto frameNode = GetFrameNode(tag, nodeId);
724         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<CustomSpanNode>(frameNode));
725         auto customSpanNode = AceType::MakeRefPtr<CustomSpanNode>(tag, nodeId);
726         customSpanNode->InitializePatternAndContext();
727         ElementRegister::GetInstance()->AddUINode(customSpanNode);
728         customSpanNode->customSpanItem_->isFrameNode = true;
729         return customSpanNode;
730     }
731 
CustomSpanNode(const std::string & tag,int32_t nodeId)732     CustomSpanNode(const std::string& tag, int32_t nodeId) :
733         FrameNode(tag, nodeId, AceType::MakeRefPtr<Pattern>()) {}
734     ~CustomSpanNode() override = default;
735 
GetSpanItem()736     const RefPtr<CustomSpanItem>& GetSpanItem() const
737     {
738         return customSpanItem_;
739     }
740 
IsAtomicNode()741     bool IsAtomicNode() const override
742     {
743         return false;
744     }
745 
DumpInfo()746     void DumpInfo() override
747     {
748         FrameNode::DumpInfo();
749         CHECK_NULL_VOID(customSpanItem_);
750         customSpanItem_->DumpInfo();
751     }
752 
753 private:
754     RefPtr<CustomSpanItem> customSpanItem_ = MakeRefPtr<CustomSpanItem>();
755 
756     ACE_DISALLOW_COPY_AND_MOVE(CustomSpanNode);
757 };
758 
759 struct ImageSpanItem : public PlaceholderSpanItem {
760     DECLARE_ACE_TYPE(ImageSpanItem, PlaceholderSpanItem);
761 
762 public:
ImageSpanItemImageSpanItem763     ImageSpanItem() : PlaceholderSpanItem()
764     {
765         this->spanItemType = SpanItemType::IMAGE;
766     }
767     ~ImageSpanItem() override = default;
768     int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
769         bool isSpanStringMode = false, PlaceholderStyle placeholderStyle = PlaceholderStyle(),
770         bool isMarquee = false) override;
ToJsonValueImageSpanItem771     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override {};
772     void UpdatePlaceholderBackgroundStyle(const RefPtr<FrameNode>& imageNode);
773     void SetImageSpanOptions(const ImageSpanOptions& options);
774     void ResetImageSpanOptions();
775     ResultObject GetSpanResultObject(int32_t start, int32_t end) override;
776     RefPtr<SpanItem> GetSameStyleSpanItem() const override;
777     ACE_DISALLOW_COPY_AND_MOVE(ImageSpanItem);
778 
779     bool EncodeTlv(std::vector<uint8_t>& buff) override;
780     static RefPtr<ImageSpanItem> DecodeTlv(std::vector<uint8_t>& buff, int32_t& cursor);
781 
782     ImageSpanOptions options;
783 };
784 
785 class ACE_EXPORT ImageSpanNode : public FrameNode {
786     DECLARE_ACE_TYPE(ImageSpanNode, FrameNode);
787 
788 public:
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)789     static RefPtr<ImageSpanNode> GetOrCreateSpanNode(
790         const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
791     {
792         auto frameNode = GetFrameNode(tag, nodeId);
793         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<ImageSpanNode>(frameNode));
794         auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
795         auto imageSpanNode = AceType::MakeRefPtr<ImageSpanNode>(tag, nodeId, pattern);
796         imageSpanNode->InitializePatternAndContext();
797         ElementRegister::GetInstance()->AddUINode(imageSpanNode);
798         return imageSpanNode;
799     }
800 
ImageSpanNode(const std::string & tag,int32_t nodeId)801     ImageSpanNode(const std::string& tag, int32_t nodeId) : FrameNode(tag, nodeId, AceType::MakeRefPtr<ImagePattern>())
802     {}
ImageSpanNode(const std::string & tag,int32_t nodeId,const RefPtr<Pattern> & pattern)803     ImageSpanNode(const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern)
804         : FrameNode(tag, nodeId, pattern)
805     {}
806     ~ImageSpanNode() override = default;
807 
GetSpanItem()808     const RefPtr<ImageSpanItem>& GetSpanItem() const
809     {
810         return imageSpanItem_;
811     }
812 
DumpInfo()813     void DumpInfo() override
814     {
815         FrameNode::DumpInfo();
816         CHECK_NULL_VOID(imageSpanItem_);
817         imageSpanItem_->DumpInfo();
818     }
819 
SetImageItem(const RefPtr<ImageSpanItem> & imageSpan)820     void SetImageItem(const RefPtr<ImageSpanItem>& imageSpan)
821     {
822         imageSpanItem_ = imageSpan;
823     }
824 
825 private:
826     RefPtr<ImageSpanItem> imageSpanItem_ = MakeRefPtr<ImageSpanItem>();
827 
828     ACE_DISALLOW_COPY_AND_MOVE(ImageSpanNode);
829 };
830 
831 class ACE_EXPORT ContainerSpanNode : public UINode, public BaseSpan {
832     DECLARE_ACE_TYPE(ContainerSpanNode, UINode, BaseSpan);
833 
834 public:
GetOrCreateSpanNode(int32_t nodeId)835     static RefPtr<ContainerSpanNode> GetOrCreateSpanNode(int32_t nodeId)
836     {
837         auto spanNode = ElementRegister::GetInstance()->GetSpecificItemById<ContainerSpanNode>(nodeId);
838         if (spanNode) {
839             spanNode->SetHasTextBackgroundStyle(false);
840             return spanNode;
841         }
842         spanNode = MakeRefPtr<ContainerSpanNode>(nodeId);
843         ElementRegister::GetInstance()->AddUINode(spanNode);
844         return spanNode;
845     }
846 
ContainerSpanNode(int32_t nodeId)847     explicit ContainerSpanNode(int32_t nodeId) : UINode(V2::CONTAINER_SPAN_ETS_TAG, nodeId), BaseSpan(nodeId) {}
848     ~ContainerSpanNode() override = default;
849 
850     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override;
851 
IsAtomicNode()852     bool IsAtomicNode() const override
853     {
854         return false;
855     }
856 
MarkTextDirty()857     void MarkTextDirty() override
858     {
859         SpanNode::RequestTextFlushDirty(Claim(this));
860     }
861 
862 private:
863     ACE_DISALLOW_COPY_AND_MOVE(ContainerSpanNode);
864 };
865 } // namespace OHOS::Ace::NG
866 
867 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_FOR_EACH_NODE_H
868