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