• 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/log/dump_log.h"
25 #include "base/memory/referenced.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/symbol/symbol_effect_options.h"
36 #include "core/components_ng/pattern/text/span/tlv_util.h"
37 #include "core/components_ng/pattern/text/text_styles.h"
38 #include "core/components_ng/property/accessibility_property.h"
39 #include "core/components_ng/render/paragraph.h"
40 #include "core/components_v2/inspector/inspector_constants.h"
41 #include "core/components_v2/inspector/utils.h"
42 
43 #define DEFINE_SPAN_FONT_STYLE_ITEM_GET(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 
67 #define DEFINE_SPAN_FONT_STYLE_ITEM(name, type, changeflag)       \
68     DEFINE_SPAN_FONT_STYLE_ITEM_GET(name, type)                   \
69 public:                                                           \
70     void Update##name(const type& value)                          \
71     {                                                             \
72         if (!spanItem_->fontStyle) {                              \
73             spanItem_->fontStyle = std::make_unique<FontStyle>(); \
74         }                                                         \
75         if (spanItem_->fontStyle->Check##name(value)) {           \
76             return;                                               \
77         }                                                         \
78         spanItem_->fontStyle->Update##name(value);                \
79         if (changeflag == ChangeFlag::RE_CREATE) {                \
80             spanItem_->MarkDirty();                               \
81         } else {                                                  \
82             spanItem_->MarkReLayoutParagraph();                   \
83         }                                                         \
84         RequestTextFlushDirty();                                  \
85     }                                                             \
86     void Update##name(const std::optional<type>& value)           \
87     {                                                             \
88         if (value.has_value()) {                                  \
89             Update##name(value.value());                          \
90         }                                                         \
91     }                                                             \
92     void Reset##name()                                            \
93     {                                                             \
94         if (spanItem_->fontStyle) {                               \
95             return spanItem_->fontStyle->Reset##name();           \
96         }                                                         \
97     }                                                             \
98     void Update##name##WithoutFlushDirty(const type& value)       \
99     {                                                             \
100         if (!spanItem_->fontStyle) {                              \
101             spanItem_->fontStyle = std::make_unique<FontStyle>(); \
102         }                                                         \
103         if (spanItem_->fontStyle->Check##name(value)) {           \
104             return;                                               \
105         }                                                         \
106         spanItem_->fontStyle->Update##name(value);                \
107     }
108 
109 #define DEFINE_SPAN_FONT_STYLE_ITEM_RECREATE(name, type, changeflag) \
110     DEFINE_SPAN_FONT_STYLE_ITEM_GET(name, type)                   \
111 public:                                                           \
112     void Update##name(const type& value)                          \
113     {                                                             \
114         if (!spanItem_->fontStyle) {                              \
115             spanItem_->fontStyle = std::make_unique<FontStyle>(); \
116         }                                                         \
117         if (spanItem_->fontStyle->Check##name(value)) {           \
118             return;                                               \
119         }                                                         \
120         spanItem_->fontStyle->Update##name(value);                \
121         if (changeflag == ChangeFlag::RE_CREATE) {                \
122             spanItem_->MarkDirty();                               \
123         } else {                                                  \
124             spanItem_->MarkReLayoutParagraph();                   \
125         }                                                         \
126         RequestTextFlushDirty();                                  \
127         spanItem_->MarkReCreateParagraph();                       \
128     }                                                             \
129     void Update##name(const std::optional<type>& value)           \
130     {                                                             \
131         if (value.has_value()) {                                  \
132             Update##name(value.value());                          \
133         }                                                         \
134     }                                                             \
135     void Reset##name()                                            \
136     {                                                             \
137         if (spanItem_->fontStyle) {                               \
138             spanItem_->fontStyle->Reset##name();                  \
139         }                                                         \
140         if (changeflag == ChangeFlag::RE_CREATE) {                \
141             spanItem_->MarkDirty();                               \
142         } else {                                                  \
143             spanItem_->MarkReLayoutParagraph();                   \
144         }                                                         \
145         spanItem_->MarkReCreateParagraph();                       \
146     }                                                             \
147     void Update##name##WithoutFlushDirty(const type& value)       \
148     {                                                             \
149         if (!spanItem_->fontStyle) {                              \
150             spanItem_->fontStyle = std::make_unique<FontStyle>(); \
151         }                                                         \
152         if (spanItem_->fontStyle->Check##name(value)) {           \
153             return;                                               \
154         }                                                         \
155         spanItem_->fontStyle->Update##name(value);                \
156         spanItem_->MarkReCreateParagraph();                       \
157     }
158 
159 #define DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(name, type, changeflag)                 \
160 public:                                                                          \
161     std::optional<type> Get##name() const                                        \
162     {                                                                            \
163         if (spanItem_->textLineStyle) {                                          \
164             return spanItem_->textLineStyle->Get##name();                        \
165         }                                                                        \
166         return std::nullopt;                                                     \
167     }                                                                            \
168     bool Has##name() const                                                       \
169     {                                                                            \
170         if (spanItem_->textLineStyle) {                                          \
171             return spanItem_->textLineStyle->Has##name();                        \
172         }                                                                        \
173         return false;                                                            \
174     }                                                                            \
175     type Get##name##Value(const type& defaultValue) const                        \
176     {                                                                            \
177         if (spanItem_->textLineStyle) {                                          \
178             return spanItem_->textLineStyle->Get##name().value_or(defaultValue); \
179         }                                                                        \
180         return defaultValue;                                                     \
181     }                                                                            \
182     void Update##name(const type& value)                                         \
183     {                                                                            \
184         if (!spanItem_->textLineStyle) {                                         \
185             spanItem_->textLineStyle = std::make_unique<TextLineStyle>();        \
186         }                                                                        \
187         if (spanItem_->textLineStyle->Check##name(value)) {                      \
188             return;                                                              \
189         }                                                                        \
190         spanItem_->textLineStyle->Update##name(value);                           \
191         if (changeflag == ChangeFlag::RE_CREATE) {                               \
192             spanItem_->MarkDirty();                                              \
193         } else {                                                                 \
194             spanItem_->MarkReLayoutParagraph();                                  \
195         }                                                                        \
196         RequestTextFlushDirty();                                                 \
197     }                                                                            \
198     void Update##name(const std::optional<type>& value)                          \
199     {                                                                            \
200         if (value.has_value()) {                                                 \
201             Update##name(value.value());                                         \
202         }                                                                        \
203     }                                                                            \
204     void Reset##name()                                                           \
205     {                                                                            \
206         if (spanItem_->textLineStyle) {                                          \
207             spanItem_->textLineStyle->Reset##name();                             \
208         }                                                                        \
209         if (changeflag == ChangeFlag::RE_CREATE) {                               \
210             spanItem_->MarkDirty();                                              \
211         } else {                                                                 \
212             spanItem_->MarkReLayoutParagraph();                                  \
213         }                                                                        \
214     }                                                                            \
215     void Update##name##WithoutFlushDirty(const type& value)                      \
216     {                                                                            \
217         if (!spanItem_->textLineStyle) {                                         \
218             spanItem_->textLineStyle = std::make_unique<TextLineStyle>();        \
219         }                                                                        \
220         if (spanItem_->textLineStyle->Check##name(value)) {                      \
221             return;                                                              \
222         }                                                                        \
223         spanItem_->textLineStyle->Update##name(value);                           \
224     }
225 
226 namespace OHOS::Ace::NG {
227 using FONT_FEATURES_LIST = std::list<std::pair<std::string, int32_t>>;
228 class InspectorFilter;
229 class Paragraph;
230 
231 struct PlaceholderStyle {
232     double width = 0.0f;
233     double height = 0.0f;
234     double baselineOffset = 0.0f;
235     VerticalAlign verticalAlign = VerticalAlign::BOTTOM;
236     TextBaseline baseline = TextBaseline::ALPHABETIC;
237 };
238 
239 struct CustomSpanPlaceholderInfo {
240     int32_t customSpanIndex = -1;
241     int32_t paragraphIndex = -1;
242     std::function<void(NG::DrawingContext&, CustomSpanOptions)> onDraw;
243 
ToStringCustomSpanPlaceholderInfo244     std::string ToString()
245     {
246         std::string result = "CustomPlaceholderInfo: [";
247         result += "customSpanIndex: " + std::to_string(customSpanIndex);
248         result += ", paragraphIndex: " + std::to_string(paragraphIndex);
249         result += ", onDraw: ";
250         result += !onDraw ? "nullptr" : "true";
251         result += "]";
252         return result;
253     }
254 };
255 
256 enum class ChangeFlag {
257     RE_CREATE = 0,
258     RE_LAYOUT = 1,
259 };
260 
261 struct SpanItem : public AceType {
262     DECLARE_ACE_TYPE(SpanItem, AceType);
263 
264 public:
SpanItemSpanItem265     SpanItem() : nodeId_(ElementRegister::GetInstance()->MakeUniqueId()) {}
~SpanItemSpanItem266     virtual ~SpanItem()
267     {
268         children.clear();
269     }
270     int32_t rangeStart = -1;
271     int32_t position = -1;  // position of last char + 1
272     int32_t nodeId_ = -1;
273     int32_t paragraphIndex = -1;
274     int32_t itemIndex_ = -1;
275     uint32_t length = 0;
276     std::string inspectId;
277     std::string description;
278     std::u16string content;
279     uint32_t unicode = 0;
280     SpanItemType spanItemType = SpanItemType::NORMAL;
281     std::pair<int32_t, int32_t> interval;
282     std::unique_ptr<FontStyle> fontStyle = std::make_unique<FontStyle>();
283     std::unique_ptr<TextLineStyle> textLineStyle = std::make_unique<TextLineStyle>();
284     // for text background style
285     std::optional<TextBackgroundStyle> backgroundStyle;
286     GestureEventFunc onClick;
287     GestureEventFunc onLongPress;
288     GestureEventFunc onDoubleClick;
289     OnHoverFunc onHover;
290     bool isOnHover = false;
291     std::function<void(TouchEventInfo&)> onTouch;
292     [[deprecated]] std::list<RefPtr<SpanItem>> children;
293     std::map<int32_t, AISpan> aiSpanMap;
294     int32_t placeholderIndex = -1;
295     // when paragraph ends with a \n, it causes the paragraph height to gain an extra line
296     // to have normal spacing between paragraphs, remove \n from every paragraph except the last one.
297     bool needRemoveNewLine = false;
298     bool useThemeFontColor = true;
299     bool useThemeDecorationColor = true;
300     std::optional<LeadingMargin> leadingMargin;
301     int32_t selectedStart = -1;  // relative offset from span, [selectedStart, selectedEnd)
302     int32_t selectedEnd = -1;
303     bool needReLayoutParagraph = false;
304     bool needReLayout = false;
305     int32_t aiSpanResultCount = 0;
306     // used for Span uiNode
307     bool needReCreateParagraph_ = true;
308     RefPtr<AccessibilityProperty> accessibilityProperty = MakeRefPtr<AccessibilityProperty>();
309     bool UpdateSymbolSpanFontFamily(TextStyle& symbolSpanStyle);
310     void UpdateSymbolSpanParagraph(const RefPtr<FrameNode>& frameNode, const TextStyle& textStyle,
311         const RefPtr<Paragraph>& builder, bool isDragging = false);
312     virtual int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
313         const TextStyle& textStyle, bool isMarquee = false);
314     virtual bool UpdateSpanTextStyle(const TextStyle& textStyle, const RefPtr<FrameNode>& frameNode);
315     bool CheckSpanNeedReCreate(int32_t index);
316     void UpdateReLayoutTextStyle(
317         TextStyle& spanTextStyle, const TextStyle& textStyle, bool isSymbol);
318     void UpdateReLayoutGradient(TextStyle& spanTextStyle, const TextStyle& textStyle);
319     virtual void UpdateSymbolSpanColor(const RefPtr<FrameNode>& frameNode, TextStyle& symbolSpanStyle);
320     virtual void UpdateTextStyleForAISpan(const std::u16string& content, const RefPtr<Paragraph>& builder,
321         const TextStyle& textStyle, const TextStyle& aiSpanStyle);
322     virtual void UpdateTextStyle(const std::u16string& content, const RefPtr<Paragraph>& builder,
323         const TextStyle& textStyle, const int32_t selStart, const int32_t selEnd);
324     virtual void UpdateContentTextStyle(
325         const std::u16string& content, const RefPtr<Paragraph>& builder, const TextStyle& textStyle);
326     virtual void GetIndex(int32_t& start, int32_t& end) const;
327     virtual void FontRegisterCallback(const RefPtr<FrameNode>& frameNode, const TextStyle& textStyle);
328     virtual void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const;
329     void ToTreeJson(std::unique_ptr<JsonValue>& json, const InspectorConfig& config) const;
330     std::string GetFont() const;
331     virtual void StartDrag(int32_t start, int32_t end);
332     virtual void EndDrag();
333     virtual bool IsDragging();
334     virtual ResultObject GetSpanResultObject(int32_t start, int32_t end);
335     virtual RefPtr<SpanItem> GetSameStyleSpanItem(bool isEncodeTlvS = false) const;
336     void GetFontStyleSpanItem(RefPtr<SpanItem>& sameSpan) const;
337     std::optional<std::pair<int32_t, int32_t>> GetIntersectionInterval(std::pair<int32_t, int32_t> interval) const;
338     std::optional<std::u16string> urlAddress;
339     std::function<void()> urlOnRelease;
SetUrlOnReleaseEventSpanItem340     void SetUrlOnReleaseEvent(std::function<void()>&& onRelease)
341     {
342         urlOnRelease = std::move(onRelease);
343     }
GetUrlAddressSpanItem344     const std::u16string GetUrlAddress()
345     {
346         return urlAddress.value_or(u"");
347     }
ContainsSpanItem348     bool Contains(int32_t index)
349     {
350         return rangeStart < index && index < position;
351     }
GetTextStyleSpanItem352     std::optional<TextStyle> GetTextStyle() const
353     {
354         return textStyle_;
355     }
SetTextStyleSpanItem356     void SetTextStyle(const std::optional<TextStyle>& textStyle)
357     {
358         textStyle_ = textStyle;
359     }
GetResourceObjectSpanItem360     RefPtr<ResourceObject> GetResourceObject()
361     {
362         return resourceObject_;
363     }
SetResourceObjectSpanItem364     void SetResourceObject(RefPtr<ResourceObject> resourceObject)
365     {
366         resourceObject_ = resourceObject;
367     }
SetNeedRemoveNewLineSpanItem368     void SetNeedRemoveNewLine(bool value)
369     {
370         needRemoveNewLine = value;
371     }
SetOnClickEventSpanItem372     void SetOnClickEvent(GestureEventFunc&& onClick_)
373     {
374         onClick = std::move(onClick_);
375     }
SetLongPressEventSpanItem376     void SetLongPressEvent(GestureEventFunc&& onLongPress_)
377     {
378         onLongPress = std::move(onLongPress_);
379     }
380 
SetDoubleClickEventSpanItem381     void SetDoubleClickEvent(GestureEventFunc&& onDoubleClick_)
382     {
383         onDoubleClick = std::move(onDoubleClick_);
384     }
385 
SetHoverEventSpanItem386     void SetHoverEvent(OnHoverFunc&& onHover_)
387     {
388         onHover = std::move(onHover_);
389     }
390 
ResetHoverEventSpanItem391     void ResetHoverEvent()
392     {
393         onHover = OnHoverFunc();
394     }
395 
SetTouchEventSpanItem396     void SetTouchEvent(std::function<void(TouchEventInfo&)>&& onTouch_)
397     {
398         onTouch = std::move(onTouch_);
399     }
400 
SetIsParentTextSpanItem401     void SetIsParentText(bool isText)
402     {
403         isParentText = isText;
404     }
GetIsParentTextSpanItem405     bool GetIsParentText()
406     {
407         return isParentText;
408     }
409     std::u16string GetSpanContent(const std::u16string& rawContent, bool isMarquee = false);
410     std::u16string GetSpanContent();
411     uint32_t GetSymbolUnicode();
412     std::string SymbolColorToString();
413 
414     virtual bool EncodeTlv(std::vector<uint8_t>& buff);
415     static RefPtr<SpanItem> DecodeTlv(std::vector<uint8_t>& buff, int32_t& cursor);
416 
SetTextPatternSpanItem417     void SetTextPattern(const RefPtr<Pattern>& pattern)
418     {
419         pattern_ = pattern;
420     }
421 
GetTextPatternSpanItem422     WeakPtr<Pattern> GetTextPattern()
423     {
424         return pattern_;
425     }
426 
427     bool UpdateSpanTextColor(Color color);
428 
GetSymbolEffectSwitchSpanItem429     bool GetSymbolEffectSwitch() const
430     {
431         return symbolEffectSwitch_;
432     }
433 
SetSymbolEffectSwitchSpanItem434     void SetSymbolEffectSwitch(bool symbolEffectSwitch)
435     {
436         symbolEffectSwitch_ = symbolEffectSwitch;
437     }
438 
SetSymbolIdSpanItem439     void SetSymbolId(uint32_t symbolId)
440     {
441         symbolId_ = symbolId;
442     }
443 
GetSymbolIdSpanItem444     uint32_t GetSymbolId()
445     {
446         return symbolId_;
447     }
448 
449     virtual void SpanDumpInfo();
450     void SpanDumpInfoAdvance();
MarkDirtySpanItem451     void MarkDirty()
452     {
453         needReLayout = true;
454     }
455 
MarkReCreateParagraphSpanItem456     void MarkReCreateParagraph()
457     {
458         needReCreateParagraph_ = true;
459     }
460 
ResetNeedReCreateParagraphSpanItem461     void ResetNeedReCreateParagraph()
462     {
463         needReCreateParagraph_ = false;
464     }
465 
MarkReLayoutParagraphSpanItem466     void MarkReLayoutParagraph()
467     {
468         needReLayoutParagraph = true;
469     }
470 
ResetReLayoutSpanItem471     void ResetReLayout()
472     {
473         needReLayout = false;
474         needReLayoutParagraph = false;
475     }
476 
UpdateContentSpanItem477     void UpdateContent(const std::u16string& newContent)
478     {
479         if (content != newContent) {
480             MarkReCreateParagraph();
481         }
482         content = newContent;
483         MarkDirty();
484     }
485 
UpdateTextColorWithoutCheckSpanItem486     void UpdateTextColorWithoutCheck(Color color)
487     {
488         fontStyle->propTextColor = color;
489         MarkReLayoutParagraph();
490     }
491 
UpdateTextDecorationColorWithoutCheckSpanItem492     void UpdateTextDecorationColorWithoutCheck(Color color)
493     {
494         fontStyle->propTextDecorationColor = color;
495         MarkReLayoutParagraph();
496     }
497 
ResetReCreateAndReLayoutSpanItem498     void ResetReCreateAndReLayout()
499     {
500         needReCreateParagraph_ = false;
501         CHECK_NULL_VOID(textStyle_.has_value());
502         textStyle_.value().ResetReCreateAndReLayoutBitmap();
503     }
504 
505     std::optional<TextStyle> textStyle_;
506 
507 private:
508     void EncodeFontStyleTlv(std::vector<uint8_t>& buff) const;
509     void EncodeTextLineStyleTlv(std::vector<uint8_t>& buff) const;
510     bool isParentText = false;
511     RefPtr<ResourceObject> resourceObject_;
512     WeakPtr<Pattern> pattern_;
513     bool symbolEffectSwitch_ = true;
514     uint32_t symbolId_ = 0;
515 };
516 
517 class ACE_EXPORT BaseSpan : public virtual AceType {
518     DECLARE_ACE_TYPE(BaseSpan, AceType);
519 
520 public:
BaseSpan(int32_t id)521     explicit BaseSpan(int32_t id) : groupId_(id)
522     {}
523     virtual void MarkTextDirty() = 0;
524     virtual void SetTextBackgroundStyle(const TextBackgroundStyle& style);
UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle> & style)525     virtual void UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle>& style)
526     {
527         textBackgroundStyle_ = style;
528     }
529 
GetTextBackgroundStyle()530     const std::optional<TextBackgroundStyle> GetTextBackgroundStyle() const
531     {
532         return textBackgroundStyle_;
533     }
534 
SetHasTextBackgroundStyle(bool hasStyle)535     void SetHasTextBackgroundStyle(bool hasStyle)
536     {
537         hasTextBackgroundStyle_ = hasStyle;
538     }
539 
HasTextBackgroundStyle()540     bool HasTextBackgroundStyle()
541     {
542         return hasTextBackgroundStyle_;
543     }
544 
GetResourceManager()545     RefPtr<PatternResourceManager> GetResourceManager()
546     {
547         return resourceMgr_;
548     }
549 
550     void ParseResToObject(const RefPtr<ResourceObject>& resObj, RefPtr<PropertyValueBase> value);
551 
UnregisterResource(const std::string & key)552     virtual void UnregisterResource(const std::string& key)
553     {
554         RemoveResObj(key);
555     }
556 
AddResObj(const std::string & key,const RefPtr<ResourceObject> & resObj,std::function<void (const RefPtr<ResourceObject> &)> && updateFunc)557     void AddResObj(
558         const std::string& key,
559         const RefPtr<ResourceObject>& resObj,
560         std::function<void(const RefPtr<ResourceObject>&)>&& updateFunc)
561     {
562         if (resourceMgr_ == nullptr) {
563             resourceMgr_ = MakeRefPtr<PatternResourceManager>();
564         }
565         resourceMgr_->AddResource(key, resObj, std::move(updateFunc));
566     }
567 
AddResCache(const std::string & key,const std::string & value)568     void AddResCache(const std::string& key, const std::string& value)
569     {
570         if (resourceMgr_ == nullptr) {
571             resourceMgr_ = MakeRefPtr<PatternResourceManager>();
572         }
573         resourceMgr_->AddResCache(key, value);
574     }
575 
GetResCacheMapByKey(const std::string & key)576     std::string GetResCacheMapByKey(const std::string& key)
577     {
578         if (resourceMgr_ == nullptr) {
579             return "";
580         }
581         return resourceMgr_->GetResCacheMapByKey(key);
582     }
583 
RemoveResObj(const std::string & key)584     void RemoveResObj(const std::string& key)
585     {
586         if (resourceMgr_) {
587             resourceMgr_->RemoveResource(key);
588             if (resourceMgr_->Empty()) {
589                 resourceMgr_ = nullptr;
590             }
591         }
592     }
593 
594 private:
595     std::optional<TextBackgroundStyle> textBackgroundStyle_;
596     RefPtr<PatternResourceManager> resourceMgr_;
597     int32_t groupId_ = 0;
598     bool hasTextBackgroundStyle_ = false;
599 };
600 
601 class ACE_EXPORT SpanNode : public UINode, public BaseSpan {
602     DECLARE_ACE_TYPE(SpanNode, UINode, BaseSpan);
603 
604 public:
605     static RefPtr<SpanNode> GetOrCreateSpanNode(int32_t nodeId);
606     static RefPtr<SpanNode> GetOrCreateSpanNode(const std::string& tag, int32_t nodeId);
607     static RefPtr<SpanNode> CreateSpanNode(int32_t nodeId);
608 
SpanNode(int32_t nodeId)609     explicit SpanNode(int32_t nodeId) : UINode(V2::SPAN_ETS_TAG, nodeId), BaseSpan(nodeId)
610     {
611         if (spanItem_) {
612             spanItem_->nodeId_ = nodeId;
613         }
614     }
SpanNode(const std::string & tag,int32_t nodeId)615     explicit SpanNode(const std::string& tag, int32_t nodeId) : UINode(tag, nodeId), BaseSpan(nodeId)
616     {
617         if (spanItem_) {
618             spanItem_->nodeId_ = nodeId;
619         }
620     }
621     ~SpanNode() override = default;
622 
623     void SetTextBackgroundStyle(const TextBackgroundStyle& style) override;
624     void UpdateTextBackgroundFromParent(const std::optional<TextBackgroundStyle>& style) override;
625 
IsAtomicNode()626     bool IsAtomicNode() const override
627     {
628         return true;
629     }
630 
IsSyntaxNode()631     bool IsSyntaxNode() const override
632     {
633         return true;
634     }
635 
SetSpanItem(const RefPtr<SpanItem> & spanItem)636     void SetSpanItem(const RefPtr<SpanItem>& spanItem)
637     {
638         spanItem_ = spanItem;
639     }
640 
GetSpanItem()641     const RefPtr<SpanItem>& GetSpanItem() const
642     {
643         return spanItem_;
644     }
645 
NotifyColorModeChange(uint32_t colorMode)646     void NotifyColorModeChange(uint32_t colorMode) override
647     {
648         UINode::NotifyColorModeChange(colorMode);
649         auto resourceMgr = GetResourceManager();
650         if (resourceMgr) {
651             resourceMgr->ReloadResources();
652         }
653     }
654 
655     void UnregisterResource(const std::string& key) override;
656     void RegisterSymbolFontColorResource(const std::string& key, std::vector<Color>& symbolColor,
657         const std::vector<std::pair<int32_t, RefPtr<ResourceObject>>>& resObjArr);
658     template<typename T>
659     void RegisterResource(const std::string& key, const RefPtr<ResourceObject>& resObj, T value);
660     template<typename T>
661     void UpdateSpanResource(const std::string& key, const RefPtr<ResourceObject>& resObj);
662     template<typename T>
663     void UpdateProperty(std::string key, const RefPtr<ResourceObject>& resObj);
664     void UpdatePropertyImpl(const std::string& key, RefPtr<PropertyValueBase> value);
665 
UpdateContent(const uint32_t & unicode)666     void UpdateContent(const uint32_t& unicode)
667     {
668         spanItem_->spanItemType = SpanItemType::SYMBOL;
669         if (spanItem_->unicode == unicode) {
670             return;
671         }
672         spanItem_->unicode = unicode;
673         spanItem_->MarkDirty();
674         spanItem_->MarkReCreateParagraph();
675         RequestTextFlushDirty(true);
676     }
677 
UpdateContent(const std::u16string & content)678     void UpdateContent(const std::u16string& content)
679     {
680         if (spanItem_->content == content) {
681             return;
682         }
683         spanItem_->content = content;
684         spanItem_->MarkDirty();
685         spanItem_->MarkReCreateParagraph();
686         RequestTextFlushDirty(true);
687     }
688 
UpdateOnClickEvent(GestureEventFunc && onClick)689     void UpdateOnClickEvent(GestureEventFunc&& onClick)
690     {
691         spanItem_->onClick = std::move(onClick);
692     }
693 
UpdateOnLongPressEvent(GestureEventFunc && onLongPress)694     void UpdateOnLongPressEvent(GestureEventFunc&& onLongPress)
695     {
696         spanItem_->onLongPress = std::move(onLongPress);
697     }
698 
OnInspectorIdUpdate(const std::string & inspectorId)699     void OnInspectorIdUpdate(const std::string& inspectorId) override
700     {
701         spanItem_->inspectId = inspectorId;
702     }
703 
OnAutoEventParamUpdate(const std::string & desc)704     void OnAutoEventParamUpdate(const std::string& desc) override
705     {
706         spanItem_->description = desc;
707     }
708 
UpdateColorByResourceId()709     void UpdateColorByResourceId()
710     {
711         spanItem_->fontStyle->UpdateColorByResourceId();
712         if (spanItem_->backgroundStyle) {
713             spanItem_->backgroundStyle->UpdateColorByResourceId();
714         }
715     }
716 
UpdateTextColorWithoutCheck(Color color)717     void UpdateTextColorWithoutCheck(Color color)
718     {
719         spanItem_->UpdateTextColorWithoutCheck(color);
720     }
721 
UpdateTextDecorationColorWithoutCheck(Color color)722     void UpdateTextDecorationColorWithoutCheck(Color color)
723     {
724         spanItem_->UpdateTextDecorationColorWithoutCheck(color);
725     }
726 
727     // ChangeFlag only for rich editor
728     DEFINE_SPAN_FONT_STYLE_ITEM(FontSize, Dimension, ChangeFlag::RE_LAYOUT);
729     DEFINE_SPAN_FONT_STYLE_ITEM(TextColor, Color, ChangeFlag::RE_LAYOUT);
730     DEFINE_SPAN_FONT_STYLE_ITEM(ItalicFontStyle, Ace::FontStyle, ChangeFlag::RE_LAYOUT);
731     DEFINE_SPAN_FONT_STYLE_ITEM(FontWeight, FontWeight, ChangeFlag::RE_LAYOUT);
732     DEFINE_SPAN_FONT_STYLE_ITEM(FontFamily, std::vector<std::string>, ChangeFlag::RE_LAYOUT);
733     DEFINE_SPAN_FONT_STYLE_ITEM(StrokeWidth, Dimension, ChangeFlag::RE_LAYOUT);
734     DEFINE_SPAN_FONT_STYLE_ITEM(StrokeColor, Color, ChangeFlag::RE_LAYOUT);
735     DEFINE_SPAN_FONT_STYLE_ITEM(Superscript, SuperscriptStyle, ChangeFlag::RE_CREATE);
736     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecoration, std::vector<TextDecoration>, ChangeFlag::RE_LAYOUT);
737     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecorationStyle, TextDecorationStyle, ChangeFlag::RE_LAYOUT);
738     DEFINE_SPAN_FONT_STYLE_ITEM(TextDecorationColor, Color, ChangeFlag::RE_LAYOUT);
739     DEFINE_SPAN_FONT_STYLE_ITEM(FontFeature, FONT_FEATURES_LIST, ChangeFlag::RE_LAYOUT);
740     DEFINE_SPAN_FONT_STYLE_ITEM_RECREATE(TextCase, TextCase, ChangeFlag::RE_CREATE);
741     DEFINE_SPAN_FONT_STYLE_ITEM(TextShadow, std::vector<Shadow>, ChangeFlag::RE_LAYOUT);
742     DEFINE_SPAN_FONT_STYLE_ITEM(LetterSpacing, Dimension, ChangeFlag::RE_LAYOUT);
743     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolColorList, std::vector<Color>, ChangeFlag::RE_CREATE);
744     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolRenderingStrategy, uint32_t, ChangeFlag::RE_CREATE);
745     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolEffectStrategy, uint32_t, ChangeFlag::RE_CREATE);
746     DEFINE_SPAN_FONT_STYLE_ITEM(SymbolEffectOptions, SymbolEffectOptions, ChangeFlag::RE_CREATE);
747     DEFINE_SPAN_FONT_STYLE_ITEM(MinFontScale, float, ChangeFlag::RE_CREATE);
748     DEFINE_SPAN_FONT_STYLE_ITEM(MaxFontScale, float, ChangeFlag::RE_CREATE);
749     DEFINE_SPAN_FONT_STYLE_ITEM(VariableFontWeight, int32_t, ChangeFlag::RE_LAYOUT);
750     DEFINE_SPAN_FONT_STYLE_ITEM(EnableVariableFontWeight, bool, ChangeFlag::RE_LAYOUT);
751     DEFINE_SPAN_FONT_STYLE_ITEM_RECREATE(SymbolType, SymbolType, ChangeFlag::RE_CREATE);
752     DEFINE_SPAN_FONT_STYLE_ITEM(LineThicknessScale, float, ChangeFlag::RE_LAYOUT);
753     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineHeight, Dimension, ChangeFlag::RE_LAYOUT);
754     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(BaselineOffset, Dimension, ChangeFlag::RE_LAYOUT);
755     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(TextAlign, TextAlign, ChangeFlag::RE_LAYOUT);
756     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(TextVerticalAlign, TextVerticalAlign, ChangeFlag::RE_CREATE);
757     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(WordBreak, WordBreak, ChangeFlag::RE_LAYOUT);
758     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LeadingMargin, LeadingMargin, ChangeFlag::RE_CREATE);
759     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineBreakStrategy, LineBreakStrategy, ChangeFlag::RE_LAYOUT);
760     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(LineSpacing, Dimension, ChangeFlag::RE_LAYOUT);
761     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(OptimizeTrailingSpace, bool, ChangeFlag::RE_LAYOUT);
762     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(HalfLeading, bool, ChangeFlag::RE_LAYOUT);
763     DEFINE_SPAN_TEXT_LINE_STYLE_ITEM(ParagraphSpacing, Dimension, ChangeFlag::RE_CREATE);
764 
GetTextDecorationFirst()765     TextDecoration GetTextDecorationFirst() const
766     {
767         auto decorations = GetTextDecoration();
768         if (!decorations.has_value()) {
769             return TextDecoration::NONE;
770         }
771         return decorations.value().size() > 0 ?
772             decorations.value()[0] : TextDecoration::NONE;
773     }
774 
775     // Mount to the previous Span node or Text node.
776     void MountToParagraph();
777 
AddChildSpanItem(const RefPtr<SpanNode> & child)778     void AddChildSpanItem(const RefPtr<SpanNode>& child)
779     {
780         spanItem_->children.emplace_back(child->GetSpanItem());
781     }
782 
CleanSpanItemChildren()783     void CleanSpanItemChildren()
784     {
785         spanItem_->children.clear();
786     }
787 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)788     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override
789     {
790         spanItem_->ToJsonValue(json, filter);
791     }
792 
ToTreeJson(std::unique_ptr<JsonValue> & json,const InspectorConfig & config)793     void ToTreeJson(std::unique_ptr<JsonValue>& json, const InspectorConfig& config) const override
794     {
795         spanItem_->ToTreeJson(json, config);
796     }
797 
798     void RequestTextFlushDirty(bool markModifyDone = false);
799     static void RequestTextFlushDirty(const RefPtr<UINode>& node, bool markModifyDone = true);
800     // The function is only used for fast preview.
FastPreviewUpdateChildDone()801     void FastPreviewUpdateChildDone() override
802     {
803         RequestTextFlushDirty(true);
804     }
805 
MarkTextDirty()806     void MarkTextDirty() override
807     {
808         RequestTextFlushDirty();
809     }
810 
UpdateSpanTextColor(Color color)811     void UpdateSpanTextColor(Color color)
812     {
813         if (!spanItem_->fontStyle) {
814             spanItem_->fontStyle = std::make_unique<FontStyle>();
815         }
816         if (spanItem_->fontStyle->CheckTextColor(color)) {
817             return;
818         }
819         spanItem_->fontStyle->UpdateTextColor(color);
820         auto parent = GetParent();
821         CHECK_NULL_VOID(parent);
822         if (!spanItem_->UpdateSpanTextColor(color)) {
823             RequestTextFlushDirty();
824         }
825     }
826 
827 protected:
828     void DumpInfo() override;
DumpSimplifyInfo(std::shared_ptr<JsonValue> & json)829     void DumpSimplifyInfo(std::shared_ptr<JsonValue>& json) override {}
830     void DumpInfo(std::unique_ptr<JsonValue>& json) override;
831 
832 private:
833     std::list<RefPtr<SpanNode>> spanChildren_;
834     RefPtr<SpanItem> spanItem_ = MakeRefPtr<SpanItem>();
835     std::vector<int32_t> symbolFontColorResObjIndexArr;
836 
837     ACE_DISALLOW_COPY_AND_MOVE(SpanNode);
838 };
839 
840 struct PlaceholderSpanItem : public SpanItem {
841     DECLARE_ACE_TYPE(PlaceholderSpanItem, SpanItem);
842 
843 public:
844     int32_t placeholderSpanNodeId = -1;
845     PlaceholderRun run_;
846     std::optional<Color> dragBackgroundColor_;
847     bool isDragShadowNeeded_ = true;
PlaceholderSpanItemPlaceholderSpanItem848     PlaceholderSpanItem()
849     {
850         this->spanItemType = SpanItemType::PLACEHOLDER;
851     }
852     ~PlaceholderSpanItem() override = default;
ToJsonValuePlaceholderSpanItem853     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override{};
854     int32_t UpdateParagraph(const RefPtr<FrameNode>& frameNode, const RefPtr<Paragraph>& builder,
855         const TextStyle& textStyle, bool isMarquee = false) override;
856     bool UpdateSpanTextStyle(const TextStyle& textStyle, const RefPtr<FrameNode>& frameNode) override;
857     virtual bool UpdatePlaceholderRun(PlaceholderStyle placeholderStyle);
858 
859     void DumpInfo() const;
860     ACE_DISALLOW_COPY_AND_MOVE(PlaceholderSpanItem);
861 
SetCustomNodePlaceholderSpanItem862     void SetCustomNode(const RefPtr<UINode>& customNode)
863     {
864         customNode_ = customNode;
865     }
866 
GetCustomNodePlaceholderSpanItem867     const RefPtr<UINode> GetCustomNode() const
868     {
869         return customNode_;
870     }
871 
UpdateColorByResourceIdPlaceholderSpanItem872     void UpdateColorByResourceId()
873     {
874         CHECK_NULL_VOID(dragBackgroundColor_.has_value());
875         dragBackgroundColor_.value().UpdateColorByResourceId();
876     }
877 
878 private:
879     RefPtr<UINode> customNode_;
880 };
881 
882 class ACE_EXPORT PlaceholderSpanNode : public FrameNode {
883     DECLARE_ACE_TYPE(PlaceholderSpanNode, FrameNode);
884 
885 public:
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)886     static RefPtr<PlaceholderSpanNode> GetOrCreateSpanNode(
887         const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
888     {
889         auto frameNode = GetFrameNode(tag, nodeId);
890         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<PlaceholderSpanNode>(frameNode));
891         auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
892         auto placeholderSpanNode = AceType::MakeRefPtr<PlaceholderSpanNode>(tag, nodeId, pattern);
893         placeholderSpanNode->InitializePatternAndContext();
894         ElementRegister::GetInstance()->AddUINode(placeholderSpanNode);
895         return placeholderSpanNode;
896     }
897 
PlaceholderSpanNode(const std::string & tag,int32_t nodeId)898     PlaceholderSpanNode(const std::string& tag, int32_t nodeId) : FrameNode(tag, nodeId, AceType::MakeRefPtr<Pattern>())
899     {
900         if (placeholderSpanItem_) {
901             placeholderSpanItem_->nodeId_ = nodeId;
902         }
903     }
PlaceholderSpanNode(const std::string & tag,int32_t nodeId,const RefPtr<Pattern> & pattern)904     PlaceholderSpanNode(const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern)
905         : FrameNode(tag, nodeId, pattern)
906     {
907         if (placeholderSpanItem_) {
908             placeholderSpanItem_->nodeId_ = nodeId;
909         }
910     }
911     ~PlaceholderSpanNode() override = default;
912 
GetSpanItem()913     const RefPtr<PlaceholderSpanItem>& GetSpanItem() const
914     {
915         return placeholderSpanItem_;
916     }
917 
IsAtomicNode()918     bool IsAtomicNode() const override
919     {
920         return false;
921     }
922 
MarkModifyDone()923     void MarkModifyDone() override
924     {
925         FrameNode::MarkModifyDone();
926         placeholderSpanItem_->MarkDirty();
927     }
928 
929     void MarkDirtyNode(PropertyChangeFlag extraFlag = PROPERTY_UPDATE_NORMAL) override
930     {
931         FrameNode::MarkDirtyNode(extraFlag);
932         placeholderSpanItem_->MarkDirty();
933     }
934 
DumpInfo()935     void DumpInfo() override
936     {
937         FrameNode::DumpInfo();
938         CHECK_NULL_VOID(placeholderSpanItem_);
939         placeholderSpanItem_->DumpInfo();
940     }
941 
942 private:
943     RefPtr<PlaceholderSpanItem> placeholderSpanItem_ = MakeRefPtr<PlaceholderSpanItem>();
944 
945     ACE_DISALLOW_COPY_AND_MOVE(PlaceholderSpanNode);
946 };
947 
948 class PlaceholderSpanPattern : public Pattern {
949     DECLARE_ACE_TYPE(PlaceholderSpanPattern, Pattern);
950 
951 public:
952     PlaceholderSpanPattern() = default;
953     ~PlaceholderSpanPattern() override = default;
954 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)955     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override
956     {
957         Pattern::OnDirtyLayoutWrapperSwap(dirty, config);
958         CHECK_NULL_RETURN(config.frameSizeChange, true);
959         auto spanNode = DynamicCast<PlaceholderSpanNode>(GetHost());
960         CHECK_NULL_RETURN(spanNode, true);
961         const auto& spanItem = spanNode->GetSpanItem();
962         CHECK_NULL_RETURN(spanItem, true);
963         spanItem->MarkDirty();
964         return true;
965     }
966 
IsAtomicNode()967     bool IsAtomicNode() const override
968     {
969         return false;
970     }
971 };
972 
973 struct CustomSpanItem : public PlaceholderSpanItem {
974     DECLARE_ACE_TYPE(CustomSpanItem, PlaceholderSpanItem);
975 
976 public:
CustomSpanItemCustomSpanItem977     CustomSpanItem() : PlaceholderSpanItem()
978     {
979         this->spanItemType = SpanItemType::CustomSpan;
980     }
981     ~CustomSpanItem() override = default;
982     RefPtr<SpanItem> GetSameStyleSpanItem(bool isEncodeTlvS = false) const override;
983     ResultObject GetSpanResultObject(int32_t start, int32_t end) override;
ToJsonValueCustomSpanItem984     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override{};
985     ACE_DISALLOW_COPY_AND_MOVE(CustomSpanItem);
986     std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure;
987     std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw;
SpanDumpInfoCustomSpanItem988     void SpanDumpInfo() override
989     {
990         PlaceholderSpanItem::DumpInfo();
991     }
992     bool isFrameNode = false;
993 };
994 
995 class ACE_EXPORT CustomSpanNode : public FrameNode {
996     DECLARE_ACE_TYPE(CustomSpanNode, FrameNode);
997 
998 public:
CreateFrameNode(int32_t nodeId)999     static RefPtr<CustomSpanNode> CreateFrameNode(int32_t nodeId)
1000     {
1001         auto customSpanNode = AceType::MakeRefPtr<CustomSpanNode>(V2::CUSTOM_SPAN_NODE_ETS_TAG, nodeId);
1002         customSpanNode->InitializePatternAndContext();
1003         ElementRegister::GetInstance()->AddUINode(customSpanNode);
1004         customSpanNode->customSpanItem_->isFrameNode = true;
1005         return customSpanNode;
1006     }
1007 
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId)1008     static RefPtr<CustomSpanNode> GetOrCreateSpanNode(const std::string& tag, int32_t nodeId)
1009     {
1010         auto frameNode = GetFrameNode(tag, nodeId);
1011         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<CustomSpanNode>(frameNode));
1012         auto customSpanNode = AceType::MakeRefPtr<CustomSpanNode>(tag, nodeId);
1013         customSpanNode->InitializePatternAndContext();
1014         ElementRegister::GetInstance()->AddUINode(customSpanNode);
1015         customSpanNode->customSpanItem_->isFrameNode = true;
1016         return customSpanNode;
1017     }
1018 
CustomSpanNode(const std::string & tag,int32_t nodeId)1019     CustomSpanNode(const std::string& tag, int32_t nodeId) : FrameNode(tag, nodeId, AceType::MakeRefPtr<Pattern>())
1020     {
1021         if (customSpanItem_) {
1022             customSpanItem_->nodeId_ = nodeId;
1023         }
1024     }
1025     ~CustomSpanNode() override = default;
1026 
GetSpanItem()1027     const RefPtr<CustomSpanItem>& GetSpanItem() const
1028     {
1029         return customSpanItem_;
1030     }
1031 
IsAtomicNode()1032     bool IsAtomicNode() const override
1033     {
1034         return false;
1035     }
1036 
DumpInfo()1037     void DumpInfo() override
1038     {
1039         FrameNode::DumpInfo();
1040         CHECK_NULL_VOID(customSpanItem_);
1041         customSpanItem_->DumpInfo();
1042     }
1043 
1044 private:
1045     RefPtr<CustomSpanItem> customSpanItem_ = MakeRefPtr<CustomSpanItem>();
1046 
1047     ACE_DISALLOW_COPY_AND_MOVE(CustomSpanNode);
1048 };
1049 
1050 struct ImageSpanItem : public PlaceholderSpanItem {
1051     DECLARE_ACE_TYPE(ImageSpanItem, PlaceholderSpanItem);
1052 
1053 public:
ImageSpanItemImageSpanItem1054     ImageSpanItem() : PlaceholderSpanItem()
1055     {
1056         this->spanItemType = SpanItemType::IMAGE;
1057     }
1058     ~ImageSpanItem() override = default;
1059     bool UpdatePlaceholderRun(PlaceholderStyle placeholderStyle) override;
ToJsonValueImageSpanItem1060     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override{};
1061     void UpdatePlaceholderBackgroundStyle(const RefPtr<FrameNode>& imageNode);
1062     void SetImageSpanOptions(const ImageSpanOptions& options);
1063     void ResetImageSpanOptions();
1064     ResultObject GetSpanResultObject(int32_t start, int32_t end) override;
1065     RefPtr<SpanItem> GetSameStyleSpanItem(bool isEncodeTlvS = false) const override;
1066     ACE_DISALLOW_COPY_AND_MOVE(ImageSpanItem);
1067 
1068     bool EncodeTlv(std::vector<uint8_t>& buff) override;
1069     static RefPtr<ImageSpanItem> DecodeTlv(std::vector<uint8_t>& buff, int32_t& cursor);
1070 
1071     ImageSpanOptions options;
1072     OnHoverFunc onHover_;
1073 private:
1074     ImageSpanOptions GetImageSpanOptionsFromImageNode() const;
1075     ImageSpanAttribute CreateImageSpanAttribute(const RefPtr<ImageLayoutProperty>& layoutProperty) const;
1076 };
1077 
1078 class ACE_EXPORT ImageSpanNode : public FrameNode {
1079     DECLARE_ACE_TYPE(ImageSpanNode, FrameNode);
1080 
1081 public:
GetOrCreateSpanNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)1082     static RefPtr<ImageSpanNode> GetOrCreateSpanNode(
1083         const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
1084     {
1085         auto frameNode = GetFrameNode(tag, nodeId);
1086         CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<ImageSpanNode>(frameNode));
1087         auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
1088         auto imageSpanNode = AceType::MakeRefPtr<ImageSpanNode>(tag, nodeId, pattern);
1089         imageSpanNode->InitializePatternAndContext();
1090         ElementRegister::GetInstance()->AddUINode(imageSpanNode);
1091         return imageSpanNode;
1092     }
1093 
ImageSpanNode(const std::string & tag,int32_t nodeId)1094     ImageSpanNode(const std::string& tag, int32_t nodeId) : FrameNode(tag, nodeId, AceType::MakeRefPtr<ImagePattern>())
1095     {
1096         if (imageSpanItem_) {
1097             imageSpanItem_->nodeId_ = nodeId;
1098         }
1099     }
ImageSpanNode(const std::string & tag,int32_t nodeId,const RefPtr<Pattern> & pattern)1100     ImageSpanNode(const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern)
1101         : FrameNode(tag, nodeId, pattern)
1102     {
1103         if (imageSpanItem_) {
1104             imageSpanItem_->nodeId_ = nodeId;
1105         }
1106     }
1107     ~ImageSpanNode() override = default;
1108 
GetSpanItem()1109     const RefPtr<ImageSpanItem>& GetSpanItem() const
1110     {
1111         return imageSpanItem_;
1112     }
1113 
DumpInfo()1114     void DumpInfo() override
1115     {
1116         FrameNode::DumpInfo();
1117         CHECK_NULL_VOID(imageSpanItem_);
1118         imageSpanItem_->DumpInfo();
1119     }
1120 
SetImageItem(const RefPtr<ImageSpanItem> & imageSpan)1121     void SetImageItem(const RefPtr<ImageSpanItem>& imageSpan)
1122     {
1123         imageSpanItem_ = imageSpan;
1124     }
1125 
1126 private:
1127     RefPtr<ImageSpanItem> imageSpanItem_ = MakeRefPtr<ImageSpanItem>();
1128 
1129     ACE_DISALLOW_COPY_AND_MOVE(ImageSpanNode);
1130 };
1131 
1132 class ACE_EXPORT ContainerSpanNode : public UINode, public BaseSpan {
1133     DECLARE_ACE_TYPE(ContainerSpanNode, UINode, BaseSpan);
1134 
1135 public:
GetOrCreateSpanNode(int32_t nodeId)1136     static RefPtr<ContainerSpanNode> GetOrCreateSpanNode(int32_t nodeId)
1137     {
1138         auto spanNode = ElementRegister::GetInstance()->GetSpecificItemById<ContainerSpanNode>(nodeId);
1139         if (spanNode) {
1140             spanNode->SetHasTextBackgroundStyle(false);
1141             return spanNode;
1142         }
1143         spanNode = MakeRefPtr<ContainerSpanNode>(nodeId);
1144         ElementRegister::GetInstance()->AddUINode(spanNode);
1145         return spanNode;
1146     }
1147 
ContainerSpanNode(int32_t nodeId)1148     explicit ContainerSpanNode(int32_t nodeId) : UINode(V2::CONTAINER_SPAN_ETS_TAG, nodeId), BaseSpan(nodeId) {}
1149     ~ContainerSpanNode() override = default;
1150 
1151     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override;
1152 
IsAtomicNode()1153     bool IsAtomicNode() const override
1154     {
1155         return false;
1156     }
1157 
MarkTextDirty()1158     void MarkTextDirty() override
1159     {
1160         SpanNode::RequestTextFlushDirty(Claim(this));
1161     }
1162 
NotifyColorModeChange(uint32_t colorMode)1163     void NotifyColorModeChange(uint32_t colorMode) override
1164     {
1165         UINode::NotifyColorModeChange(colorMode);
1166         auto resourceMgr = GetResourceManager();
1167         if (resourceMgr) {
1168             resourceMgr->ReloadResources();
1169         }
1170     }
1171 
1172     template<typename T>
1173     void RegisterResource(const std::string& key, const RefPtr<ResourceObject>& resObj, T value);
1174     template<typename T>
1175     void UpdateSpanResource(const std::string& key, const RefPtr<ResourceObject>& resObj);
1176     template<typename T>
1177     void UpdateProperty(std::string key, const RefPtr<ResourceObject>& resObj);
1178     void UpdatePropertyImpl(const std::string& key, RefPtr<PropertyValueBase> value);
1179 
1180 private:
1181     ACE_DISALLOW_COPY_AND_MOVE(ContainerSpanNode);
1182 };
1183 } // namespace OHOS::Ace::NG
1184 
1185 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_FOR_EACH_NODE_H
1186