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