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