• 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 <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     [[deprecated]] std::list<RefPtr<SpanItem>> children;
209     std::map<int32_t, AISpan> aiSpanMap;
210     int32_t placeholderIndex = -1;
211     // when paragraph ends with a \n, it causes the paragraph height to gain an extra line
212     // to have normal spacing between paragraphs, remove \n from every paragraph except the last one.
213     bool needRemoveNewLine = false;
214     bool useThemeFontColor = true;
215     bool useThemeDecorationColor = true;
216     std::optional<LeadingMargin> leadingMargin;
217     int32_t selectedStart = -1;
218     int32_t selectedEnd = -1;
219     RefPtr<AccessibilityProperty> accessibilityProperty = MakeRefPtr<AccessibilityProperty>();
220     void UpdateSymbolSpanParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder);
221     virtual int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
222         bool isSpanStringMode = false, PlaceholderStyle placeholderStyle = PlaceholderStyle(), bool isMarquee = false);
223     virtual void UpdateSymbolSpanColor(const RefPtr<FrameNode>& frameNode, TextStyle& symbolSpanStyle);
224     virtual void UpdateTextStyleForAISpan(const std::string& content, const RefPtr<Paragraph>& builder,
225         const TextStyle& textStyle, const TextStyle& aiSpanStyle);
226     virtual void UpdateTextStyle(const std::string& content, const RefPtr<Paragraph>& builder,
227         const TextStyle& textStyle, const int32_t selStart, const int32_t selEnd);
228     virtual void UpdateContentTextStyle(
229         const std::string& content, const RefPtr<Paragraph>& builder, const TextStyle& textStyle);
230     virtual void GetIndex(int32_t& start, int32_t& end) const;
231     virtual void FontRegisterCallback(const RefPtr<FrameNode>& frameNode, const TextStyle& textStyle);
232     virtual void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const;
233     std::string GetFont() const;
234     virtual void StartDrag(int32_t start, int32_t end);
235     virtual void EndDrag();
236     virtual bool IsDragging();
237     virtual ResultObject GetSpanResultObject(int32_t start, int32_t end);
238     TextStyle InheritParentProperties(const RefPtr<FrameNode>& frameNode, bool isSpanStringMode = false);
239     virtual RefPtr<SpanItem> GetSameStyleSpanItem() const;
240     std::optional<std::pair<int32_t, int32_t>> GetIntersectionInterval(std::pair<int32_t, int32_t> interval) const;
ContainsSpanItem241     bool Contains(int32_t index)
242     {
243         return rangeStart < index && index < position;
244     }
GetTextStyleSpanItem245     std::optional<TextStyle> GetTextStyle() const
246     {
247         return textStyle_;
248     }
SetTextStyleSpanItem249     void SetTextStyle(const std::optional<TextStyle>& textStyle)
250     {
251         textStyle_ = textStyle;
252     }
GetResourceObjectSpanItem253     RefPtr<ResourceObject> GetResourceObject()
254     {
255         return resourceObject_;
256     }
SetResourceObjectSpanItem257     void SetResourceObject(RefPtr<ResourceObject> resourceObject)
258     {
259         resourceObject_ = resourceObject;
260     }
SetNeedRemoveNewLineSpanItem261     void SetNeedRemoveNewLine(bool value)
262     {
263         needRemoveNewLine = value;
264     }
SetOnClickEventSpanItem265     void SetOnClickEvent(GestureEventFunc&& onClick_)
266     {
267         onClick = std::move(onClick_);
268     }
SetLongPressEventSpanItem269     void SetLongPressEvent(GestureEventFunc&& onLongPress_)
270     {
271         onLongPress = std::move(onLongPress_);
272     }
SetIsParentTextSpanItem273     void SetIsParentText(bool isText)
274     {
275         isParentText = isText;
276     }
GetIsParentTextSpanItem277     bool GetIsParentText()
278     {
279         return isParentText;
280     }
GetHasUserFontWeightSpanItem281     bool GetHasUserFontWeight()
282     {
283         return hasUserFontWeight_;
284     }
SetHasUserFontWeightSpanItem285     void SetHasUserFontWeight(bool hasUserFontWeight)
286     {
287         hasUserFontWeight_ = hasUserFontWeight;
288     }
289     std::string GetSpanContent(const std::string& rawContent, bool isMarquee = false);
290     std::string GetSpanContent();
291     uint32_t GetSymbolUnicode();
292     std::string SymbolColorToString();
293 
294     virtual bool EncodeTlv(std::vector<uint8_t>& buff);
295     static RefPtr<SpanItem> DecodeTlv(std::vector<uint8_t>& buff, int32_t& cursor);
296 
SetTextPatternSpanItem297     void SetTextPattern(const RefPtr<Pattern>& pattern)
298     {
299         pattern_ = pattern;
300     }
301 
302     bool UpdateSpanTextColor(Color color);
SetSymbolIdSpanItem303     void SetSymbolId(uint32_t symbolId)
304     {
305         symbolId_ = symbolId;
306     }
307 
GetSymbolIdSpanItem308     uint32_t GetSymbolId()
309     {
310         return symbolId_;
311     }
312 private:
313     std::optional<TextStyle> textStyle_;
314     bool isParentText = false;
315     bool hasUserFontWeight_ = false;
316     RefPtr<ResourceObject> resourceObject_;
317     WeakPtr<Pattern> pattern_;
318     uint32_t symbolId_ = 0;
319 };
320 
321 enum class PropertyInfo {
322     FONTSIZE = 0,
323     FONTCOLOR,
324     FONTSTYLE,
325     FONTWEIGHT,
326     FONTFAMILY,
327     TEXTDECORATION,
328     TEXTCASE,
329     LETTERSPACE,
330     LINEHEIGHT,
331     TEXT_ALIGN,
332     LEADING_MARGIN,
333     NONE,
334     TEXTSHADOW,
335     SYMBOL_COLOR,
336     SYMBOL_RENDERING_STRATEGY,
337     SYMBOL_EFFECT_STRATEGY,
338     WORD_BREAK,
339     LINE_BREAK_STRATEGY,
340     FONTFEATURE,
341     BASELINE_OFFSET,
342     MIN_FONT_SCALE,
343     MAX_FONT_SCALE,
344     LINESPACING,
345     SYMBOL_EFFECT_OPTIONS,
346     HALFLEADING,
347     VARIABLE_FONT_WEIGHT,
348     ENABLE_VARIABLE_FONT_WEIGHT,
349 };
350 
351 class ACE_EXPORT BaseSpan : public virtual AceType {
352     DECLARE_ACE_TYPE(BaseSpan, AceType);
353 
354 public:
BaseSpan(int32_t id)355     explicit BaseSpan(int32_t id) : groupId_(id) {}
356     virtual void MarkTextDirty() = 0;
357     virtual void SetTextBackgroundStyle(const TextBackgroundStyle& style);
UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle> & style)358     virtual void UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle>& style)
359     {
360         textBackgroundStyle_ = style;
361     }
362 
GetTextBackgroundStyle()363     const std::optional<TextBackgroundStyle> GetTextBackgroundStyle() const
364     {
365         return textBackgroundStyle_;
366     }
367 
SetHasTextBackgroundStyle(bool hasStyle)368     void SetHasTextBackgroundStyle(bool hasStyle)
369     {
370         hasTextBackgroundStyle_ = hasStyle;
371     }
372 
HasTextBackgroundStyle()373     bool HasTextBackgroundStyle()
374     {
375         return hasTextBackgroundStyle_;
376     }
377 
378 private:
379     std::optional<TextBackgroundStyle> textBackgroundStyle_;
380     int32_t groupId_ = 0;
381     bool hasTextBackgroundStyle_ = false;
382 };
383 
384 class ACE_EXPORT SpanNode : public UINode, public BaseSpan {
385     DECLARE_ACE_TYPE(SpanNode, UINode, BaseSpan);
386 
387 public:
388     static RefPtr<SpanNode> GetOrCreateSpanNode(int32_t nodeId);
389     static RefPtr<SpanNode> GetOrCreateSpanNode(const std::string& tag, int32_t nodeId);
390     static RefPtr<SpanNode> CreateSpanNode(int32_t nodeId);
391 
SpanNode(int32_t nodeId)392     explicit SpanNode(int32_t nodeId) : UINode(V2::SPAN_ETS_TAG, nodeId), BaseSpan(nodeId) {}
SpanNode(const std::string & tag,int32_t nodeId)393     explicit SpanNode(const std::string& tag, int32_t nodeId) : UINode(tag, nodeId), BaseSpan(nodeId) {}
394     ~SpanNode() override = default;
395 
396     void SetTextBackgroundStyle(const TextBackgroundStyle& style) override;
397     void UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle>& style) override;
398 
IsAtomicNode()399     bool IsAtomicNode() const override
400     {
401         return true;
402     }
403 
GetSpanItem()404     const RefPtr<SpanItem>& GetSpanItem() const
405     {
406         return spanItem_;
407     }
408 
UpdateContent(const uint32_t & unicode)409     void UpdateContent(const uint32_t& unicode)
410     {
411         if (spanItem_->unicode == unicode) {
412             return;
413         }
414         spanItem_->unicode = unicode;
415         RequestTextFlushDirty();
416     }
417 
UpdateContent(const std::string & content)418     void UpdateContent(const std::string& content)
419     {
420         if (spanItem_->content == content) {
421             return;
422         }
423         spanItem_->content = content;
424         RequestTextFlushDirty();
425     }
426 
UpdateOnClickEvent(GestureEventFunc && onClick)427     void UpdateOnClickEvent(GestureEventFunc&& onClick)
428     {
429         spanItem_->onClick = std::move(onClick);
430     }
431 
OnInspectorIdUpdate(const std::string & inspectorId)432     void OnInspectorIdUpdate(const std::string& inspectorId) override
433     {
434         spanItem_->inspectId = inspectorId;
435     }
436 
OnAutoEventParamUpdate(const std::string & desc)437     void OnAutoEventParamUpdate(const std::string& desc) override
438     {
439         spanItem_->description = desc;
440     }
441 
UpdateColorByResourceId()442     void UpdateColorByResourceId()
443     {
444         spanItem_->fontStyle->UpdateColorByResourceId();
445     }
446 
GetHasUserFontWeight()447     bool GetHasUserFontWeight()
448     {
449         return hasUserFontWeight_;
450     }
451 
UpdateUserFontWeight(bool hasUserFontWeight)452     void UpdateUserFontWeight(bool hasUserFontWeight)
453     {
454         hasUserFontWeight_ = hasUserFontWeight;
455         spanItem_->SetHasUserFontWeight(hasUserFontWeight);
456     }
457 
458     DEFINE_SPAN_FONT_STYLE_ITEM(FontSize, Dimension);
459     DEFINE_SPAN_FONT_STYLE_ITEM(TextColor, Color);
460     DEFINE_SPAN_FONT_STYLE_ITEM(ItalicFontStyle, Ace::FontStyle);
461     DEFINE_SPAN_FONT_STYLE_ITEM(FontWeight, FontWeight);
462     DEFINE_SPAN_FONT_STYLE_ITEM(FontFamily, std::vector<std::string>);
463     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecoration, TextDecoration);
464     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecorationStyle, TextDecorationStyle);
465     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecorationColor, Color);
466     DEFINE_SPAN_FONT_STYLE_ITEM(FontFeature, FONT_FEATURES_LIST);
467     DEFINE_SPAN_FONT_STYLE_ITEM(TextCase, TextCase);
468     DEFINE_SPAN_FONT_STYLE_ITEM(TextShadow, std::vector<Shadow>);
469     DEFINE_SPAN_FONT_STYLE_ITEM(LetterSpacing, Dimension);
470     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolColorList, std::vector<Color>);
471     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolRenderingStrategy, uint32_t);
472     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolEffectStrategy, uint32_t);
473     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolEffectOptions, SymbolEffectOptions);
474     DEFINE_SPAN_FONT_STYLE_ITEM(MinFontScale, float);
475     DEFINE_SPAN_FONT_STYLE_ITEM(MaxFontScale, float);
476     DEFINE_SPAN_FONT_STYLE_ITEM(VariableFontWeight, int32_t);
477     DEFINE_SPAN_FONT_STYLE_ITEM(EnableVariableFontWeight, bool);
478     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineHeight, Dimension);
479     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(BaselineOffset, Dimension);
480     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(TextAlign, TextAlign);
481     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(WordBreak, WordBreak);
482     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LeadingMargin, LeadingMargin);
483     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineBreakStrategy, LineBreakStrategy);
484     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineSpacing, Dimension);
485     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(HalfLeading, bool);
486 
487     // Mount to the previous Span node or Text node.
488     void MountToParagraph();
489 
AddChildSpanItem(const RefPtr<SpanNode> & child)490     void AddChildSpanItem(const RefPtr<SpanNode>& child)
491     {
492         spanItem_->children.emplace_back(child->GetSpanItem());
493     }
494 
CleanSpanItemChildren()495     void CleanSpanItemChildren()
496     {
497         spanItem_->children.clear();
498     }
499 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)500     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override
501     {
502         spanItem_->ToJsonValue(json, filter);
503     }
504 
505     void RequestTextFlushDirty();
506     static void RequestTextFlushDirty(const RefPtr<UINode>& node);
507     // The function is only used for fast preview.
FastPreviewUpdateChildDone()508     void FastPreviewUpdateChildDone() override
509     {
510         RequestTextFlushDirty();
511     }
512 
AddPropertyInfo(PropertyInfo value)513     void AddPropertyInfo(PropertyInfo value)
514     {
515         propertyInfo_.insert(value);
516     }
517 
ResetPropertyInfo(PropertyInfo value)518     void ResetPropertyInfo(PropertyInfo value)
519     {
520         propertyInfo_.erase(value);
521     }
522 
CleanPropertyInfo()523     void CleanPropertyInfo()
524     {
525         propertyInfo_.clear();
526     }
527 
MarkTextDirty()528     void MarkTextDirty() override
529     {
530         RequestTextFlushDirty();
531     }
532 
533     std::set<PropertyInfo> CalculateInheritPropertyInfo();
534 
535 
UpdateSpanTextColor(Color color)536     void UpdateSpanTextColor(Color color)
537     {
538         if (!spanItem_->fontStyle) {
539             spanItem_->fontStyle = std::make_unique<FontStyle>();
540         }
541         if (spanItem_->fontStyle->CheckTextColor(color)) {
542             return;
543         }
544         spanItem_->fontStyle->UpdateTextColor(color);
545         auto parent = GetParent();
546         CHECK_NULL_VOID(parent);
547         if (!spanItem_->UpdateSpanTextColor(color)) {
548             RequestTextFlushDirty();
549         }
550     }
551 
552 protected:
553     void DumpInfo() override;
554 
555 private:
556     std::list<RefPtr<SpanNode>> spanChildren_;
557     std::set<PropertyInfo> propertyInfo_;
558     bool hasUserFontWeight_ = false;
559     RefPtr<SpanItem> spanItem_ = MakeRefPtr<SpanItem>();
560 
561     ACE_DISALLOW_COPY_AND_MOVE(SpanNode);
562 };
563 
564 struct PlaceholderSpanItem : public SpanItem {
565     DECLARE_ACE_TYPE(PlaceholderSpanItem, SpanItem);
566 
567 public:
568     int32_t placeholderSpanNodeId = -1;
569     TextStyle textStyle;
570     PlaceholderRun run_;
571     PlaceholderSpanItem() = default;
572     ~PlaceholderSpanItem() override = default;
ToJsonValuePlaceholderSpanItem573     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override {};
574     int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
575         bool isSpanStringMode = false, PlaceholderStyle placeholderStyle = PlaceholderStyle(),
576         bool isMarquee = false) override;
577 
DumpInfoPlaceholderSpanItem578     void DumpInfo() const
579     {
580         auto& dumpLog = DumpLog::GetInstance();
581         dumpLog.AddDesc("--------------- print run info ---------------");
582         dumpLog.AddDesc(std::string("Width: ").append(std::to_string(run_.width)));
583         dumpLog.AddDesc(std::string("Height: ").append(std::to_string(run_.height)));
584         dumpLog.AddDesc(std::string("Alignment: ").append(StringUtils::ToString(run_.alignment)));
585         dumpLog.AddDesc(std::string("Baseline: ").append(StringUtils::ToString(run_.baseline)));
586         dumpLog.AddDesc(std::string("BaselineOffset: ").append(std::to_string(run_.baseline_offset)));
587         dumpLog.AddDesc("--------------- print text style ---------------");
588         dumpLog.AddDesc(std::string("FontSize: ").append(textStyle.GetFontSize().ToString()));
589         dumpLog.AddDesc(std::string("LineHeight: ").append(textStyle.GetLineHeight().ToString()));
590         dumpLog.AddDesc(std::string("LineSpacing: ").append(textStyle.GetLineSpacing().ToString()));
591         dumpLog.AddDesc(std::string("VerticalAlign: ").append(StringUtils::ToString(textStyle.GetTextVerticalAlign())));
592         dumpLog.AddDesc(std::string("HalfLeading: ").append(std::to_string(textStyle.GetHalfLeading())));
593         dumpLog.AddDesc(std::string("TextBaseline: ").append(StringUtils::ToString(textStyle.GetTextBaseline())));
594     }
595     ACE_DISALLOW_COPY_AND_MOVE(PlaceholderSpanItem);
596 
SetCustomNodePlaceholderSpanItem597     void SetCustomNode(const RefPtr<UINode>& customNode)
598     {
599         customNode_ = customNode;
600     }
601 
GetCustomNodePlaceholderSpanItem602     const RefPtr<UINode> GetCustomNode() const
603     {
604         return customNode_;
605     }
606 private:
607     RefPtr<UINode> customNode_;
608 };
609 
610 class PlaceholderSpanPattern : public Pattern {
611     DECLARE_ACE_TYPE(PlaceholderSpanPattern, Pattern);
612 
613 public:
614     PlaceholderSpanPattern() = default;
615     ~PlaceholderSpanPattern() override = default;
616 
IsAtomicNode()617     bool IsAtomicNode() const override
618     {
619         return false;
620     }
621 };
622 
623 class ACE_EXPORT PlaceholderSpanNode : public FrameNode {
624     DECLARE_ACE_TYPE(PlaceholderSpanNode, FrameNode);
625 
626 public:
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)627     static RefPtr<PlaceholderSpanNode> GetOrCreateSpanNode(
628         const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
629     {
630         auto frameNode = GetFrameNode(tag, nodeId);
631         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<PlaceholderSpanNode>(frameNode));
632         auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
633         auto placeholderSpanNode = AceType::MakeRefPtr<PlaceholderSpanNode>(tag, nodeId, pattern);
634         placeholderSpanNode->InitializePatternAndContext();
635         ElementRegister::GetInstance()->AddUINode(placeholderSpanNode);
636         return placeholderSpanNode;
637     }
638 
PlaceholderSpanNode(const std::string & tag,int32_t nodeId)639     PlaceholderSpanNode(const std::string& tag, int32_t nodeId) : FrameNode(tag, nodeId, AceType::MakeRefPtr<Pattern>())
640     {}
PlaceholderSpanNode(const std::string & tag,int32_t nodeId,const RefPtr<Pattern> & pattern)641     PlaceholderSpanNode(const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern)
642         : FrameNode(tag, nodeId, pattern)
643     {}
644     ~PlaceholderSpanNode() override = default;
645 
GetSpanItem()646     const RefPtr<PlaceholderSpanItem>& GetSpanItem() const
647     {
648         return placeholderSpanItem_;
649     }
650 
IsAtomicNode()651     bool IsAtomicNode() const override
652     {
653         return false;
654     }
655 
DumpInfo()656     void DumpInfo() override
657     {
658         FrameNode::DumpInfo();
659         CHECK_NULL_VOID(placeholderSpanItem_);
660         placeholderSpanItem_->DumpInfo();
661     }
662 
663 private:
664     RefPtr<PlaceholderSpanItem> placeholderSpanItem_ = MakeRefPtr<PlaceholderSpanItem>();
665 
666     ACE_DISALLOW_COPY_AND_MOVE(PlaceholderSpanNode);
667 };
668 
669 struct CustomSpanItem : public PlaceholderSpanItem {
670     DECLARE_ACE_TYPE(CustomSpanItem, PlaceholderSpanItem);
671 
672 public:
CustomSpanItemCustomSpanItem673     CustomSpanItem() : PlaceholderSpanItem()
674     {
675         this->spanItemType = SpanItemType::CustomSpan;
676     }
677     ~CustomSpanItem() override = default;
678     RefPtr<SpanItem> GetSameStyleSpanItem() const override;
679     ResultObject GetSpanResultObject(int32_t start, int32_t end) override;
ToJsonValueCustomSpanItem680     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override {};
681     ACE_DISALLOW_COPY_AND_MOVE(CustomSpanItem);
682     std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure;
683     std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw;
684 };
685 
686 class ACE_EXPORT CustomSpanNode : public FrameNode {
687     DECLARE_ACE_TYPE(CustomSpanNode, FrameNode);
688 
689 public:
CreateFrameNode(int32_t nodeId)690     static RefPtr<CustomSpanNode> CreateFrameNode(int32_t nodeId)
691     {
692         auto customSpanNode = AceType::MakeRefPtr<CustomSpanNode>(
693             V2::CUSTOM_SPAN_NODE_ETS_TAG, nodeId);
694         customSpanNode->InitializePatternAndContext();
695         ElementRegister::GetInstance()->AddUINode(customSpanNode);
696         return customSpanNode;
697     }
698 
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId)699     static RefPtr<CustomSpanNode> GetOrCreateSpanNode(
700         const std::string& tag, int32_t nodeId)
701     {
702         auto frameNode = GetFrameNode(tag, nodeId);
703         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<CustomSpanNode>(frameNode));
704         auto customSpanNode = AceType::MakeRefPtr<CustomSpanNode>(tag, nodeId);
705         customSpanNode->InitializePatternAndContext();
706         ElementRegister::GetInstance()->AddUINode(customSpanNode);
707         return customSpanNode;
708     }
709 
CustomSpanNode(const std::string & tag,int32_t nodeId)710     CustomSpanNode(const std::string& tag, int32_t nodeId) :
711         FrameNode(tag, nodeId, AceType::MakeRefPtr<Pattern>()) {}
712     ~CustomSpanNode() override = default;
713 
GetSpanItem()714     const RefPtr<CustomSpanItem>& GetSpanItem() const
715     {
716         return customSpanItem_;
717     }
718 
IsAtomicNode()719     bool IsAtomicNode() const override
720     {
721         return false;
722     }
723 
DumpInfo()724     void DumpInfo() override
725     {
726         FrameNode::DumpInfo();
727         CHECK_NULL_VOID(customSpanItem_);
728         customSpanItem_->DumpInfo();
729     }
730 
731 private:
732     RefPtr<CustomSpanItem> customSpanItem_ = MakeRefPtr<CustomSpanItem>();
733 
734     ACE_DISALLOW_COPY_AND_MOVE(CustomSpanNode);
735 };
736 
737 struct ImageSpanItem : public PlaceholderSpanItem {
738     DECLARE_ACE_TYPE(ImageSpanItem, PlaceholderSpanItem);
739 
740 public:
ImageSpanItemImageSpanItem741     ImageSpanItem() : PlaceholderSpanItem()
742     {
743         this->spanItemType = SpanItemType::IMAGE;
744     }
745     ~ImageSpanItem() override = default;
746     int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
747         bool isSpanStringMode = false, PlaceholderStyle placeholderStyle = PlaceholderStyle(),
748         bool isMarquee = false) override;
ToJsonValueImageSpanItem749     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override {};
750     void UpdatePlaceholderBackgroundStyle(const RefPtr<FrameNode>& imageNode);
751     void SetImageSpanOptions(const ImageSpanOptions& options);
752     void ResetImageSpanOptions();
753     ResultObject GetSpanResultObject(int32_t start, int32_t end) override;
754     RefPtr<SpanItem> GetSameStyleSpanItem() const override;
755     ACE_DISALLOW_COPY_AND_MOVE(ImageSpanItem);
756 
757     bool EncodeTlv(std::vector<uint8_t>& buff) override;
758     static RefPtr<ImageSpanItem> DecodeTlv(std::vector<uint8_t>& buff, int32_t& cursor);
759 
760     ImageSpanOptions options;
761 };
762 
763 class ACE_EXPORT ImageSpanNode : public FrameNode {
764     DECLARE_ACE_TYPE(ImageSpanNode, FrameNode);
765 
766 public:
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)767     static RefPtr<ImageSpanNode> GetOrCreateSpanNode(
768         const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
769     {
770         auto frameNode = GetFrameNode(tag, nodeId);
771         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<ImageSpanNode>(frameNode));
772         auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
773         auto imageSpanNode = AceType::MakeRefPtr<ImageSpanNode>(tag, nodeId, pattern);
774         imageSpanNode->InitializePatternAndContext();
775         ElementRegister::GetInstance()->AddUINode(imageSpanNode);
776         return imageSpanNode;
777     }
778 
ImageSpanNode(const std::string & tag,int32_t nodeId)779     ImageSpanNode(const std::string& tag, int32_t nodeId) : FrameNode(tag, nodeId, AceType::MakeRefPtr<ImagePattern>())
780     {}
ImageSpanNode(const std::string & tag,int32_t nodeId,const RefPtr<Pattern> & pattern)781     ImageSpanNode(const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern)
782         : FrameNode(tag, nodeId, pattern)
783     {}
784     ~ImageSpanNode() override = default;
785 
GetSpanItem()786     const RefPtr<ImageSpanItem>& GetSpanItem() const
787     {
788         return imageSpanItem_;
789     }
790 
DumpInfo()791     void DumpInfo() override
792     {
793         FrameNode::DumpInfo();
794         CHECK_NULL_VOID(imageSpanItem_);
795         imageSpanItem_->DumpInfo();
796     }
797 
SetImageItem(const RefPtr<ImageSpanItem> & imageSpan)798     void SetImageItem(const RefPtr<ImageSpanItem>& imageSpan)
799     {
800         imageSpanItem_ = imageSpan;
801     }
802 
803 private:
804     RefPtr<ImageSpanItem> imageSpanItem_ = MakeRefPtr<ImageSpanItem>();
805 
806     ACE_DISALLOW_COPY_AND_MOVE(ImageSpanNode);
807 };
808 
809 class ACE_EXPORT ContainerSpanNode : public UINode, public BaseSpan {
810     DECLARE_ACE_TYPE(ContainerSpanNode, UINode, BaseSpan);
811 
812 public:
GetOrCreateSpanNode(int32_t nodeId)813     static RefPtr<ContainerSpanNode> GetOrCreateSpanNode(int32_t nodeId)
814     {
815         auto spanNode = ElementRegister::GetInstance()->GetSpecificItemById<ContainerSpanNode>(nodeId);
816         if (spanNode) {
817             spanNode->SetHasTextBackgroundStyle(false);
818             return spanNode;
819         }
820         spanNode = MakeRefPtr<ContainerSpanNode>(nodeId);
821         ElementRegister::GetInstance()->AddUINode(spanNode);
822         return spanNode;
823     }
824 
ContainerSpanNode(int32_t nodeId)825     explicit ContainerSpanNode(int32_t nodeId) : UINode(V2::CONTAINER_SPAN_ETS_TAG, nodeId), BaseSpan(nodeId) {}
826     ~ContainerSpanNode() override = default;
827 
828     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override;
829 
IsAtomicNode()830     bool IsAtomicNode() const override
831     {
832         return false;
833     }
834 
MarkTextDirty()835     void MarkTextDirty() override
836     {
837         SpanNode::RequestTextFlushDirty(Claim(this));
838     }
839 
840 private:
841     ACE_DISALLOW_COPY_AND_MOVE(ContainerSpanNode);
842 };
843 } // namespace OHOS::Ace::NG
844 
845 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_FOR_EACH_NODE_H
846