• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "core/components_ng/pattern/text/span/span_object.h"
16 
17 namespace OHOS::Ace {
18 namespace {
19 static std::atomic<int32_t> gGestureSpanId = 0;
20 constexpr int32_t GESTURES_SPAN_DIVIDE_SIZE = 10000000;
21 }
22 
23 // SpanBase
GetIntersectionInterval(std::pair<int32_t,int32_t> interval) const24 std::optional<std::pair<int32_t, int32_t>> SpanBase::GetIntersectionInterval(std::pair<int32_t, int32_t> interval) const
25 {
26     // 检查相交情况
27     if (end_ <= interval.first || interval.second <= start_) {
28         return std::nullopt;
29     }
30 
31     // 计算相交区间
32     int start = std::max(start_, interval.first);
33     int end = std::min(end_, interval.second);
34     return std::make_optional<std::pair<int32_t, int32_t>>(std::make_pair(start, end));
35 }
36 
GetStartIndex() const37 int32_t SpanBase::GetStartIndex() const
38 {
39     return start_;
40 }
41 
GetEndIndex() const42 int32_t SpanBase::GetEndIndex() const
43 {
44     return end_;
45 }
UpdateStartIndex(int32_t startIndex)46 void SpanBase::UpdateStartIndex(int32_t startIndex)
47 {
48     start_ = startIndex;
49 }
50 
UpdateEndIndex(int32_t endIndex)51 void SpanBase::UpdateEndIndex(int32_t endIndex)
52 {
53     end_ = endIndex;
54 }
55 
GetLength() const56 int32_t SpanBase::GetLength() const
57 {
58     return end_ - start_;
59 }
60 
61 // FontSpan
FontSpan(Font font)62 FontSpan::FontSpan(Font font) : SpanBase(0, 0), font_(std::move(font)) {}
63 
FontSpan(Font font,int32_t start,int32_t end)64 FontSpan::FontSpan(Font font, int32_t start, int32_t end) : SpanBase(start, end), font_(std::move(font)) {}
65 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const66 void FontSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
67 {
68     switch (operation) {
69         case SpanOperation::ADD:
70             AddSpanStyle(spanItem);
71             break;
72         case SpanOperation::REMOVE:
73             RemoveSpanStyle(spanItem);
74     }
75 }
76 
GetSubSpan(int32_t start,int32_t end)77 RefPtr<SpanBase> FontSpan::GetSubSpan(int32_t start, int32_t end)
78 {
79     RefPtr<SpanBase> spanBase = MakeRefPtr<FontSpan>(font_, start, end);
80     return spanBase;
81 }
82 
AddSpanStyle(const RefPtr<NG::SpanItem> & spanItem) const83 void FontSpan::AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const
84 {
85     if (!spanItem || !spanItem->fontStyle) {
86         return;
87     }
88     if (font_.fontColor.has_value()) {
89         spanItem->fontStyle->UpdateTextColor(font_.fontColor.value());
90     }
91 
92     if (font_.fontFamiliesNG.has_value()) {
93         spanItem->fontStyle->UpdateFontFamily(font_.fontFamiliesNG.value());
94     }
95 
96     if (font_.fontSize.has_value()) {
97         spanItem->fontStyle->UpdateFontSize(font_.fontSize.value());
98     }
99 
100     if (font_.fontStyle.has_value()) {
101         spanItem->fontStyle->UpdateItalicFontStyle(font_.fontStyle.value());
102     }
103 
104     if (font_.fontWeight.has_value()) {
105         spanItem->fontStyle->UpdateFontWeight(font_.fontWeight.value());
106     }
107 }
108 
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)109 void FontSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
110 {
111     spanItem->fontStyle->ResetTextColor();
112     spanItem->fontStyle->ResetFontFamily();
113     spanItem->fontStyle->ResetFontSize();
114     spanItem->fontStyle->ResetItalicFontStyle();
115     spanItem->fontStyle->ResetFontWeight();
116 }
117 
GetFont() const118 Font FontSpan::GetFont() const
119 {
120     return font_;
121 }
122 
GetSpanType() const123 SpanType FontSpan::GetSpanType() const
124 {
125     return SpanType::Font;
126 }
127 
ToString() const128 std::string FontSpan::ToString() const
129 {
130     std::stringstream ss;
131     ss << "FontSpan [";
132     ss << GetStartIndex();
133     ss << ":";
134     ss << GetEndIndex();
135     ss << "]";
136     if (font_.fontColor.has_value()) {
137         ss << " FontColor:" << font_.fontColor.value().ColorToString();
138     }
139     if (font_.fontFamiliesNG.has_value()) {
140         ss << " FontFamily:";
141         for (auto& fontFam : font_.fontFamiliesNG.value()) {
142             ss << fontFam;
143         }
144     }
145     if (font_.fontSize.has_value()) {
146         ss << " FontSize:" << font_.fontSize.value().ToString();
147     }
148     if (font_.fontStyle.has_value()) {
149         ss << " FontStyle:" << static_cast<int32_t>(font_.fontStyle.value());
150     }
151     if (font_.fontWeight.has_value()) {
152         ss << " FontWeight:" << static_cast<int32_t>(font_.fontWeight.value());
153     }
154     std::string output = ss.str();
155     return output;
156 }
157 
IsAttributesEqual(const RefPtr<SpanBase> & other) const158 bool FontSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
159 {
160     auto fontSpan = DynamicCast<FontSpan>(other);
161     if (!fontSpan) {
162         return false;
163     }
164     auto font = fontSpan->GetFont();
165     return font_.IsEqual(font);
166 }
167 
168 // DecorationSpan
DecorationSpan(TextDecoration type,std::optional<Color> color,std::optional<TextDecorationStyle> style)169 DecorationSpan::DecorationSpan(
170     TextDecoration type, std::optional<Color> color, std::optional<TextDecorationStyle> style)
171     : SpanBase(0, 0), type_(type), color_(color), style_(style)
172 {}
173 
DecorationSpan(TextDecoration type,std::optional<Color> color,std::optional<TextDecorationStyle> style,int32_t start,int32_t end)174 DecorationSpan::DecorationSpan(TextDecoration type, std::optional<Color> color,
175     std::optional<TextDecorationStyle> style, int32_t start, int32_t end)
176     : SpanBase(start, end), type_(type), color_(color), style_(style)
177 {}
178 
GetTextDecorationType() const179 TextDecoration DecorationSpan::GetTextDecorationType() const
180 {
181     return type_;
182 }
183 
GetColor() const184 std::optional<Color> DecorationSpan::GetColor() const
185 {
186     return color_;
187 }
188 
GetTextDecorationStyle() const189 std::optional<TextDecorationStyle> DecorationSpan::GetTextDecorationStyle() const
190 {
191     return style_;
192 }
193 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const194 void DecorationSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
195 {
196     switch (operation) {
197         case SpanOperation::ADD:
198             AddDecorationStyle(spanItem);
199             break;
200         case SpanOperation::REMOVE:
201             RemoveDecorationStyle(spanItem);
202     }
203 }
204 
GetSubSpan(int32_t start,int32_t end)205 RefPtr<SpanBase> DecorationSpan::GetSubSpan(int32_t start, int32_t end)
206 {
207     RefPtr<SpanBase> spanBase = MakeRefPtr<DecorationSpan>(type_, color_, style_, start, end);
208     return spanBase;
209 }
210 
AddDecorationStyle(const RefPtr<NG::SpanItem> & spanItem) const211 void DecorationSpan::AddDecorationStyle(const RefPtr<NG::SpanItem>& spanItem) const
212 {
213     spanItem->fontStyle->UpdateTextDecoration(type_);
214     if (color_.has_value()) {
215         spanItem->fontStyle->UpdateTextDecorationColor(color_.value());
216     }
217     if (style_.has_value()) {
218         spanItem->fontStyle->UpdateTextDecorationStyle(style_.value());
219     }
220 }
221 
RemoveDecorationStyle(const RefPtr<NG::SpanItem> & spanItem)222 void DecorationSpan::RemoveDecorationStyle(const RefPtr<NG::SpanItem>& spanItem)
223 {
224     spanItem->fontStyle->ResetTextDecoration();
225     spanItem->fontStyle->ResetTextDecorationColor();
226     spanItem->fontStyle->ResetTextDecorationStyle();
227 }
228 
GetSpanType() const229 SpanType DecorationSpan::GetSpanType() const
230 {
231     return SpanType::Decoration;
232 }
233 
ToString() const234 std::string DecorationSpan::ToString() const
235 {
236     std::stringstream ss;
237     ss << "DecorationSpan [";
238     ss << GetStartIndex();
239     ss << ":";
240     ss << GetEndIndex();
241     ss << "]";
242     ss << " type:" << static_cast<int32_t>(type_) << " color:"
243         << (color_.has_value() ? color_.value().ColorToString(): "None")
244         << " style:" << (style_.has_value() ? static_cast<int32_t>(style_.value()): -1);
245     std::string output = ss.str();
246     return output;
247 }
248 
IsAttributesEqual(const RefPtr<SpanBase> & other) const249 bool DecorationSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
250 {
251     auto decorationSpan = DynamicCast<DecorationSpan>(other);
252     if (!decorationSpan) {
253         return false;
254     }
255     std::optional<Color> color = decorationSpan->GetColor();
256     std::optional<TextDecorationStyle> style = decorationSpan->GetTextDecorationStyle();
257     TextDecoration type = decorationSpan->GetTextDecorationType();
258     return color == color_ && style == style_ && type == type_;
259 }
260 
261 // BaselineOffsetSpan
BaselineOffsetSpan(Dimension baselineOffset)262 BaselineOffsetSpan::BaselineOffsetSpan(Dimension baselineOffset) : SpanBase(0, 0), baselineOffset_(baselineOffset) {}
263 
BaselineOffsetSpan(Dimension baselineOffset,int32_t start,int32_t end)264 BaselineOffsetSpan::BaselineOffsetSpan(Dimension baselineOffset, int32_t start, int32_t end)
265     : SpanBase(start, end), baselineOffset_(baselineOffset)
266 {}
267 
GetBaselineOffset() const268 Dimension BaselineOffsetSpan::GetBaselineOffset() const
269 {
270     return baselineOffset_;
271 }
272 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const273 void BaselineOffsetSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
274 {
275     switch (operation) {
276         case SpanOperation::ADD:
277             AddBaselineOffsetStyle(spanItem);
278             break;
279         case SpanOperation::REMOVE:
280             RemoveBaselineOffsetStyle(spanItem);
281     }
282 }
283 
GetSubSpan(int32_t start,int32_t end)284 RefPtr<SpanBase> BaselineOffsetSpan::GetSubSpan(int32_t start, int32_t end)
285 {
286     RefPtr<SpanBase> spanBase = MakeRefPtr<BaselineOffsetSpan>(baselineOffset_, start, end);
287     return spanBase;
288 }
289 
AddBaselineOffsetStyle(const RefPtr<NG::SpanItem> & spanItem) const290 void BaselineOffsetSpan::AddBaselineOffsetStyle(const RefPtr<NG::SpanItem>& spanItem) const
291 {
292     CHECK_NULL_VOID(spanItem);
293     if (!spanItem->textLineStyle) {
294         spanItem->textLineStyle = std::make_unique<NG::TextLineStyle>();
295     }
296     spanItem->textLineStyle->UpdateBaselineOffset(baselineOffset_);
297 }
298 
RemoveBaselineOffsetStyle(const RefPtr<NG::SpanItem> & spanItem)299 void BaselineOffsetSpan::RemoveBaselineOffsetStyle(const RefPtr<NG::SpanItem>& spanItem)
300 {
301     CHECK_NULL_VOID(spanItem);
302     if (!spanItem->textLineStyle) {
303         spanItem->textLineStyle = std::make_unique<NG::TextLineStyle>();
304     }
305     spanItem->textLineStyle->ResetBaselineOffset();
306 }
307 
GetSpanType() const308 SpanType BaselineOffsetSpan::GetSpanType() const
309 {
310     return SpanType::BaselineOffset;
311 }
312 
ToString() const313 std::string BaselineOffsetSpan::ToString() const
314 {
315     std::stringstream ss;
316     ss << "BaselineOffsetSpan [";
317     ss << GetStartIndex();
318     ss << ":";
319     ss << GetEndIndex();
320     ss << "]";
321     ss << " baselineOffset:" << baselineOffset_.ToString();
322     std::string output = ss.str();
323     return output;
324 }
325 
IsAttributesEqual(const RefPtr<SpanBase> & other) const326 bool BaselineOffsetSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
327 {
328     auto baselineOffsetSpan = DynamicCast<BaselineOffsetSpan>(other);
329     if (!baselineOffsetSpan) {
330         return false;
331     }
332     auto baselineOffset = baselineOffsetSpan->GetBaselineOffset();
333     return baselineOffset == baselineOffset_;
334 }
335 
336 // LetterSpacingSpan
LetterSpacingSpan(Dimension letterSpacing)337 LetterSpacingSpan::LetterSpacingSpan(Dimension letterSpacing) : SpanBase(0, 0), letterSpacing_(letterSpacing) {}
338 
LetterSpacingSpan(Dimension letterSpacing,int32_t start,int32_t end)339 LetterSpacingSpan::LetterSpacingSpan(Dimension letterSpacing, int32_t start, int32_t end)
340     : SpanBase(start, end), letterSpacing_(letterSpacing)
341 {}
342 
GetLetterSpacing() const343 Dimension LetterSpacingSpan::GetLetterSpacing() const
344 {
345     return letterSpacing_;
346 }
347 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const348 void LetterSpacingSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
349 {
350     switch (operation) {
351         case SpanOperation::ADD:
352             AddLetterSpacingStyle(spanItem);
353             break;
354         case SpanOperation::REMOVE:
355             RemoveLetterSpacingStyle(spanItem);
356     }
357 }
358 
GetSubSpan(int32_t start,int32_t end)359 RefPtr<SpanBase> LetterSpacingSpan::GetSubSpan(int32_t start, int32_t end)
360 {
361     RefPtr<SpanBase> spanBase = MakeRefPtr<LetterSpacingSpan>(letterSpacing_, start, end);
362     return spanBase;
363 }
364 
AddLetterSpacingStyle(const RefPtr<NG::SpanItem> & spanItem) const365 void LetterSpacingSpan::AddLetterSpacingStyle(const RefPtr<NG::SpanItem>& spanItem) const
366 {
367     spanItem->fontStyle->UpdateLetterSpacing(letterSpacing_);
368 }
369 
RemoveLetterSpacingStyle(const RefPtr<NG::SpanItem> & spanItem)370 void LetterSpacingSpan::RemoveLetterSpacingStyle(const RefPtr<NG::SpanItem>& spanItem)
371 {
372     spanItem->fontStyle->ResetLetterSpacing();
373 }
374 
GetSpanType() const375 SpanType LetterSpacingSpan::GetSpanType() const
376 {
377     return SpanType::LetterSpacing;
378 }
379 
ToString() const380 std::string LetterSpacingSpan::ToString() const
381 {
382     std::stringstream ss;
383     ss << "LetterSpacingSpan [";
384     ss << GetStartIndex();
385     ss << ":";
386     ss << GetEndIndex();
387     ss << "]";
388     ss << " letterSpacing:" << letterSpacing_.ToString();
389     std::string output = ss.str();
390     return output;
391 }
392 
IsAttributesEqual(const RefPtr<SpanBase> & other) const393 bool LetterSpacingSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
394 {
395     auto letterSpacingSpan = DynamicCast<LetterSpacingSpan>(other);
396     if (!letterSpacingSpan) {
397         return false;
398     }
399     auto letterSpacing = letterSpacingSpan->GetLetterSpacing();
400     return letterSpacing == letterSpacing_;
401 }
402 
403 // GestureSpan
GestureSpan(GestureStyle gestureInfo)404 GestureSpan::GestureSpan(GestureStyle gestureInfo) : SpanBase(0, 0), gestureInfo_(std::move(gestureInfo)) {}
405 
GestureSpan(GestureStyle gestureInfo,int32_t start,int32_t end)406 GestureSpan::GestureSpan(GestureStyle gestureInfo, int32_t start, int32_t end)
407     : SpanBase(start, end), gestureInfo_(std::move(gestureInfo))
408 {}
409 
GetGestureStyle() const410 GestureStyle GestureSpan::GetGestureStyle() const
411 {
412     return gestureInfo_;
413 }
414 
GetSubSpan(int32_t start,int32_t end)415 RefPtr<SpanBase> GestureSpan::GetSubSpan(int32_t start, int32_t end)
416 {
417     RefPtr<SpanBase> spanBase = MakeRefPtr<GestureSpan>(gestureInfo_, start, end);
418     auto gestureSpan = DynamicCast<GestureSpan>(spanBase);
419     CHECK_NULL_RETURN(gestureSpan, spanBase);
420     if (gestureSpanId_ == -1) {
421         gestureSpanId_ = gGestureSpanId.fetch_add(1) % GESTURES_SPAN_DIVIDE_SIZE;
422     }
423     gestureSpan->SetGestureSpanId(gestureSpanId_);
424     return spanBase;
425 }
426 
IsAttributesEqual(const RefPtr<SpanBase> & other) const427 bool GestureSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
428 {
429     auto gestureSpan = DynamicCast<GestureSpan>(other);
430     if (!gestureSpan) {
431         return false;
432     }
433     if (gestureSpanId_ != -1 && gestureSpanId_ == gestureSpan->GetGestureSpanId()) {
434         return true;
435     }
436     auto gestureInfo = gestureSpan->GetGestureStyle();
437     return gestureInfo_.IsEqual(gestureInfo);
438 }
439 
GetSpanType() const440 SpanType GestureSpan::GetSpanType() const
441 {
442     return SpanType::Gesture;
443 }
444 
ToString() const445 std::string GestureSpan::ToString() const
446 {
447     std::stringstream ss;
448     ss << "GestureSpan [";
449     ss << GetStartIndex();
450     ss << ":";
451     ss << GetEndIndex();
452     ss << "]";
453     std::string output = ss.str();
454     return output;
455 }
456 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const457 void GestureSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
458 {
459     switch (operation) {
460         case SpanOperation::ADD:
461             AddSpanStyle(spanItem);
462             break;
463         case SpanOperation::REMOVE:
464             RemoveSpanStyle(spanItem);
465     }
466 }
467 
AddSpanStyle(const RefPtr<NG::SpanItem> & spanItem) const468 void GestureSpan::AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const
469 {
470     if (gestureInfo_.onClick.has_value()) {
471         spanItem->onClick = gestureInfo_.onClick.value();
472     } else {
473         spanItem->onClick = nullptr;
474     }
475 
476     if (gestureInfo_.onLongPress.has_value()) {
477         spanItem->onLongPress = gestureInfo_.onLongPress.value();
478     } else {
479         spanItem->onLongPress = nullptr;
480     }
481 }
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)482 void GestureSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
483 {
484     spanItem->onClick = nullptr;
485     spanItem->onLongPress = nullptr;
486 }
487 
488 // TextShadowSpan
TextShadowSpan(std::vector<Shadow> textShadow)489 TextShadowSpan::TextShadowSpan(std::vector<Shadow> textShadow) : SpanBase(0, 0), textShadow_(std::move(textShadow)) {}
490 
TextShadowSpan(std::vector<Shadow> textShadow,int32_t start,int32_t end)491 TextShadowSpan::TextShadowSpan(std::vector<Shadow> textShadow, int32_t start, int32_t end)
492     : SpanBase(start, end), textShadow_(std::move(textShadow))
493 {}
494 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const495 void TextShadowSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
496 {
497     switch (operation) {
498         case SpanOperation::ADD:
499             AddSpanStyle(spanItem);
500             break;
501         case SpanOperation::REMOVE:
502             RemoveSpanStyle(spanItem);
503     }
504 }
505 
GetSubSpan(int32_t start,int32_t end)506 RefPtr<SpanBase> TextShadowSpan::GetSubSpan(int32_t start, int32_t end)
507 {
508     RefPtr<SpanBase> spanBase = MakeRefPtr<TextShadowSpan>(GetTextShadow(), start, end);
509     return spanBase;
510 }
511 
AddSpanStyle(const RefPtr<NG::SpanItem> & spanItem) const512 void TextShadowSpan::AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const
513 {
514     if (textShadow_.has_value()) {
515         spanItem->fontStyle->UpdateTextShadow(textShadow_.value());
516     }
517 }
518 
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)519 void TextShadowSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
520 {
521     spanItem->fontStyle->ResetTextShadow();
522 }
523 
GetTextShadow() const524 std::vector<Shadow> TextShadowSpan::GetTextShadow() const
525 {
526     return textShadow_.value_or(std::vector<Shadow>());
527 }
528 
GetSpanType() const529 SpanType TextShadowSpan::GetSpanType() const
530 {
531     return SpanType::TextShadow;
532 }
533 
ToString() const534 std::string TextShadowSpan::ToString() const
535 {
536     std::stringstream ss;
537     ss << "TextShadowSpan [";
538     ss << GetStartIndex();
539     ss << ":";
540     ss << GetEndIndex();
541     ss << "]";
542     std::string output = ss.str();
543     return output;
544 }
545 
IsAttributesEqual(const RefPtr<SpanBase> & other) const546 bool TextShadowSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
547 {
548     auto textShadowSpan = DynamicCast<TextShadowSpan>(other);
549     if (!textShadowSpan) {
550         return false;
551     }
552     auto textShadow = textShadowSpan->GetTextShadow();
553     auto selfTextShadow = GetTextShadow();
554     if (textShadow.size() != selfTextShadow.size()) {
555         return false;
556     }
557     for (size_t i = 0; i < selfTextShadow.size(); ++i) {
558         if (selfTextShadow[i] != textShadow[i]) {
559             return false;
560         }
561     }
562     return true;
563 }
564 
565 // ImageSpan
ImageSpan(const ImageSpanOptions & options)566 ImageSpan::ImageSpan(const ImageSpanOptions& options) : SpanBase(0, 1), imageOptions_(options) {}
567 
ImageSpan(const ImageSpanOptions & options,int32_t position)568 ImageSpan::ImageSpan(const ImageSpanOptions& options, int32_t position)
569     : SpanBase(position, position + 1), imageOptions_(options)
570 {}
571 
IsAttributesEqual(const RefPtr<SpanBase> & other) const572 bool ImageSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
573 {
574     auto imageSpan = DynamicCast<ImageSpan>(other);
575     if (!imageSpan) {
576         return false;
577     }
578     if (imageOptions_.imageAttribute.has_value() && imageSpan->GetImageAttribute().has_value()) {
579         return imageOptions_.imageAttribute.value() == imageSpan->GetImageAttribute().value();
580     }
581     return false;
582 }
583 
GetSubSpan(int32_t start,int32_t end)584 RefPtr<SpanBase> ImageSpan::GetSubSpan(int32_t start, int32_t end)
585 {
586     if (end - start > 1) {
587         return nullptr;
588     }
589     auto spanBase = MakeRefPtr<ImageSpan>(imageOptions_);
590     spanBase->UpdateStartIndex(start);
591     spanBase->UpdateEndIndex(end);
592     return spanBase;
593 }
594 
GetSpanType() const595 SpanType ImageSpan::GetSpanType() const
596 {
597     return SpanType::Image;
598 }
599 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const600 void ImageSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
601 {
602     auto imageItem = DynamicCast<NG::ImageSpanItem>(spanItem);
603     if (!imageItem) {
604         return;
605     }
606 
607     switch (operation) {
608         case SpanOperation::ADD:
609             imageItem->SetImageSpanOptions(imageOptions_);
610             break;
611         case SpanOperation::REMOVE:
612             imageItem->ResetImageSpanOptions();
613     }
614 }
615 
ToString() const616 std::string ImageSpan::ToString() const
617 {
618     std::stringstream ss;
619     ss << "ImageSpan [";
620     ss << GetStartIndex();
621     ss << ":";
622     ss << GetEndIndex();
623     ss << "]";
624     std::string output = ss.str();
625     return output;
626 }
627 
GetImageSpanOptions()628 const ImageSpanOptions& ImageSpan::GetImageSpanOptions()
629 {
630     return imageOptions_;
631 }
632 
GetImageAttribute() const633 const std::optional<ImageSpanAttribute>& ImageSpan::GetImageAttribute() const
634 {
635     return imageOptions_.imageAttribute;
636 }
637 
638 // CustomSpan
CustomSpan()639 CustomSpan::CustomSpan() : SpanBase(0, 1) {}
640 
CustomSpan(std::optional<std::function<CustomSpanMetrics (CustomSpanMeasureInfo)>> onMeasure,std::optional<std::function<void (NG::DrawingContext &,CustomSpanOptions)>> onDraw)641 CustomSpan::CustomSpan(std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
642     std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw)
643     : SpanBase(0, 1), onMeasure_(std::move(onMeasure)), onDraw_(std::move(onDraw))
644 {}
645 
CustomSpan(std::optional<std::function<CustomSpanMetrics (CustomSpanMeasureInfo)>> onMeasure,std::optional<std::function<void (NG::DrawingContext &,CustomSpanOptions)>> onDraw,int32_t start,int32_t end)646 CustomSpan::CustomSpan(std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
647     std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw, int32_t start, int32_t end)
648     : SpanBase(start, end), onMeasure_(std::move(onMeasure)), onDraw_(std::move(onDraw))
649 {}
650 
SetOnMeasure(std::function<CustomSpanMetrics (CustomSpanMeasureInfo)> onMeasure)651 void CustomSpan::SetOnMeasure(std::function<CustomSpanMetrics(CustomSpanMeasureInfo)> onMeasure)
652 {
653     onMeasure_ = onMeasure;
654 }
655 
SetOnDraw(std::function<void (NG::DrawingContext &,CustomSpanOptions)> onDraw)656 void CustomSpan::SetOnDraw(std::function<void(NG::DrawingContext&, CustomSpanOptions)> onDraw)
657 {
658     onDraw_ = onDraw;
659 }
660 
GetOnMeasure()661 std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> CustomSpan::GetOnMeasure()
662 {
663     return onMeasure_;
664 }
665 
GetOnDraw()666 std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> CustomSpan::GetOnDraw()
667 {
668     return onDraw_;
669 }
670 
GetSubSpan(int32_t start,int32_t end)671 RefPtr<SpanBase> CustomSpan::GetSubSpan(int32_t start, int32_t end)
672 {
673     if (end - start > 1) {
674         return nullptr;
675     }
676     RefPtr<SpanBase> spanBase = MakeRefPtr<CustomSpan>(onMeasure_, onDraw_, start, end);
677     return spanBase;
678 }
679 
GetSpanType() const680 SpanType CustomSpan::GetSpanType() const
681 {
682     return SpanType::CustomSpan;
683 }
684 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const685 void CustomSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
686 {
687     auto imageItem = DynamicCast<NG::CustomSpanItem>(spanItem);
688     if (!imageItem) {
689         return;
690     }
691 
692     switch (operation) {
693         case SpanOperation::ADD:
694             imageItem->onMeasure = onMeasure_;
695             imageItem->onDraw = onDraw_;
696             break;
697         case SpanOperation::REMOVE:
698             imageItem->onMeasure = std::nullopt;
699             imageItem->onDraw = std::nullopt;
700     }
701 }
702 
ToString() const703 std::string CustomSpan::ToString() const
704 {
705     std::stringstream ss;
706     ss << "CustomSpan [";
707     ss << GetStartIndex();
708     ss << ":";
709     ss << GetEndIndex();
710     ss << "]";
711     std::string output = ss.str();
712     return output;
713 }
714 
IsAttributesEqual(const RefPtr<SpanBase> & other) const715 bool CustomSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
716 {
717     return false;
718 }
719 
720 // ParagraphStyleSpan
ParagraphStyleSpan(SpanParagraphStyle paragraphStyle)721 ParagraphStyleSpan::ParagraphStyleSpan(SpanParagraphStyle paragraphStyle)
722     : SpanBase(0, 0), paragraphStyle_(std::move(paragraphStyle))
723 {}
724 
ParagraphStyleSpan(SpanParagraphStyle paragraphStyle,int32_t start,int32_t end)725 ParagraphStyleSpan::ParagraphStyleSpan(SpanParagraphStyle paragraphStyle, int32_t start, int32_t end)
726     : SpanBase(start, end), paragraphStyle_(std::move(paragraphStyle))
727 {}
728 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const729 void ParagraphStyleSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
730 {
731     switch (operation) {
732         case SpanOperation::ADD:
733             AddParagraphStyle(spanItem);
734             break;
735         case SpanOperation::REMOVE:
736             RemoveParagraphStyle(spanItem);
737     }
738 }
739 
AddParagraphStyle(const RefPtr<NG::SpanItem> & spanItem) const740 void ParagraphStyleSpan::AddParagraphStyle(const RefPtr<NG::SpanItem>& spanItem) const
741 {
742     if (paragraphStyle_.align.has_value()) {
743         spanItem->textLineStyle->UpdateTextAlign(paragraphStyle_.align.value());
744     }
745 
746     if (paragraphStyle_.maxLines.has_value()) {
747         spanItem->textLineStyle->UpdateMaxLines(static_cast<uint32_t>(paragraphStyle_.maxLines.value()));
748     }
749 
750     if (paragraphStyle_.textOverflow.has_value()) {
751         spanItem->textLineStyle->UpdateTextOverflow(paragraphStyle_.textOverflow.value());
752     }
753 
754     if (paragraphStyle_.leadingMargin.has_value()) {
755         spanItem->textLineStyle->UpdateLeadingMargin(paragraphStyle_.leadingMargin.value());
756     }
757 
758     if (paragraphStyle_.wordBreak.has_value()) {
759         spanItem->textLineStyle->UpdateWordBreak(paragraphStyle_.wordBreak.value());
760     }
761 
762     if (paragraphStyle_.textIndent.has_value()) {
763         spanItem->textLineStyle->UpdateTextIndent(paragraphStyle_.textIndent.value());
764     }
765 
766     if (paragraphStyle_.paragraphSpacing.has_value()) {
767         spanItem->textLineStyle->UpdateParagraphSpacing(paragraphStyle_.paragraphSpacing.value());
768     }
769 }
770 
RemoveParagraphStyle(const RefPtr<NG::SpanItem> & spanItem) const771 void ParagraphStyleSpan::RemoveParagraphStyle(const RefPtr<NG::SpanItem>& spanItem) const
772 {
773     spanItem->textLineStyle->ResetTextAlign();
774     spanItem->textLineStyle->ResetMaxLines();
775     spanItem->textLineStyle->ResetTextOverflow();
776     spanItem->textLineStyle->ResetLeadingMargin();
777     spanItem->textLineStyle->ResetWordBreak();
778     spanItem->textLineStyle->ResetTextIndent();
779     spanItem->textLineStyle->ResetParagraphSpacing();
780 }
781 
IsAttributesEqual(const RefPtr<SpanBase> & other) const782 bool ParagraphStyleSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
783 {
784     auto paragraphSpan = DynamicCast<ParagraphStyleSpan>(other);
785     if (!paragraphSpan) {
786         return false;
787     }
788     auto paragraphStyle = paragraphSpan->GetParagraphStyle();
789     return paragraphStyle_.Equal(paragraphStyle);
790 }
791 
GetParagraphStyle() const792 SpanParagraphStyle ParagraphStyleSpan::GetParagraphStyle() const
793 {
794     return paragraphStyle_;
795 }
796 
GetSpanType() const797 SpanType ParagraphStyleSpan::GetSpanType() const
798 {
799     return SpanType::ParagraphStyle;
800 }
801 
ToString() const802 std::string ParagraphStyleSpan::ToString() const
803 {
804     std::stringstream ss;
805     ss << "ParagraphStyleSpan [";
806     ss << GetStartIndex();
807     ss << ":";
808     ss << GetEndIndex();
809     ss << "]";
810     std::string output = ss.str();
811     return output;
812 }
813 
GetSubSpan(int32_t start,int32_t end)814 RefPtr<SpanBase> ParagraphStyleSpan::GetSubSpan(int32_t start, int32_t end)
815 {
816     RefPtr<SpanBase> spanBase = MakeRefPtr<ParagraphStyleSpan>(paragraphStyle_, start, end);
817     return spanBase;
818 }
819 
820 // LineHeightSpan
LineHeightSpan(Dimension lineHeight)821 LineHeightSpan::LineHeightSpan(Dimension lineHeight) : SpanBase(0, 0), lineHeight_(lineHeight) {}
822 
LineHeightSpan(Dimension lineHeight,int32_t start,int32_t end)823 LineHeightSpan::LineHeightSpan(Dimension lineHeight, int32_t start, int32_t end)
824     : SpanBase(start, end), lineHeight_(lineHeight)
825 {}
826 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const827 void LineHeightSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
828 {
829     switch (operation) {
830         case SpanOperation::ADD:
831             AddLineHeightStyle(spanItem);
832             break;
833         case SpanOperation::REMOVE:
834             RemoveLineHeightStyle(spanItem);
835     }
836 }
837 
GetSubSpan(int32_t start,int32_t end)838 RefPtr<SpanBase> LineHeightSpan::GetSubSpan(int32_t start, int32_t end)
839 {
840     RefPtr<SpanBase> spanBase = MakeRefPtr<LineHeightSpan>(GetLineHeight(), start, end);
841     return spanBase;
842 }
843 
AddLineHeightStyle(const RefPtr<NG::SpanItem> & spanItem) const844 void LineHeightSpan::AddLineHeightStyle(const RefPtr<NG::SpanItem>& spanItem) const
845 {
846     spanItem->textLineStyle->UpdateLineHeight(lineHeight_);
847 }
848 
RemoveLineHeightStyle(const RefPtr<NG::SpanItem> & spanItem) const849 void LineHeightSpan::RemoveLineHeightStyle(const RefPtr<NG::SpanItem>& spanItem) const
850 {
851     spanItem->textLineStyle->ResetLineHeight();
852 }
853 
GetLineHeight() const854 Dimension LineHeightSpan::GetLineHeight() const
855 {
856     return lineHeight_;
857 }
858 
GetSpanType() const859 SpanType LineHeightSpan::GetSpanType() const
860 {
861     return SpanType::LineHeight;
862 }
863 
ToString() const864 std::string LineHeightSpan::ToString() const
865 {
866     std::stringstream ss;
867     ss << "LineHeightSpan [";
868     ss << GetStartIndex();
869     ss << ":";
870     ss << GetEndIndex();
871     ss << "]";
872     ss << " baselineOffset:" << lineHeight_.ToString();
873     std::string output = ss.str();
874     return output;
875 }
876 
IsAttributesEqual(const RefPtr<SpanBase> & other) const877 bool LineHeightSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
878 {
879     auto lineHeightSpan = DynamicCast<LineHeightSpan>(other);
880     if (!lineHeightSpan) {
881         return false;
882     }
883     auto lineHeight = lineHeightSpan->GetLineHeight();
884     return lineHeight_ == lineHeight;
885 }
886 
887 // HalfLeadingSpan
HalfLeadingSpan(bool halfLeading)888 HalfLeadingSpan::HalfLeadingSpan(bool halfLeading) : SpanBase(0, 0), halfLeading_(halfLeading) {}
889 
HalfLeadingSpan(bool halfLeading,int32_t start,int32_t end)890 HalfLeadingSpan::HalfLeadingSpan(bool halfLeading, int32_t start, int32_t end)
891     : SpanBase(start, end), halfLeading_(halfLeading)
892 {}
893 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const894 void HalfLeadingSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
895 {
896     switch (operation) {
897         case SpanOperation::ADD:
898             AddHalfLeadingStyle(spanItem);
899             break;
900         case SpanOperation::REMOVE:
901             RemoveHalfLeadingStyle(spanItem);
902     }
903 }
904 
GetSubSpan(int32_t start,int32_t end)905 RefPtr<SpanBase> HalfLeadingSpan::GetSubSpan(int32_t start, int32_t end)
906 {
907     return MakeRefPtr<HalfLeadingSpan>(halfLeading_, start, end);
908 }
909 
AddHalfLeadingStyle(const RefPtr<NG::SpanItem> & spanItem) const910 void HalfLeadingSpan::AddHalfLeadingStyle(const RefPtr<NG::SpanItem>& spanItem) const
911 {
912     spanItem->textLineStyle->UpdateHalfLeading(halfLeading_);
913 }
914 
RemoveHalfLeadingStyle(const RefPtr<NG::SpanItem> & spanItem) const915 void HalfLeadingSpan::RemoveHalfLeadingStyle(const RefPtr<NG::SpanItem>& spanItem) const
916 {
917     spanItem->textLineStyle->ResetHalfLeading();
918 }
919 
GetHalfLeading() const920 bool HalfLeadingSpan::GetHalfLeading() const
921 {
922     return halfLeading_;
923 }
924 
GetSpanType() const925 SpanType HalfLeadingSpan::GetSpanType() const
926 {
927     return SpanType::HalfLeading;
928 }
929 
ToString() const930 std::string HalfLeadingSpan::ToString() const
931 {
932     std::stringstream str;
933     str << "HalfLeadingSpan ( start:";
934     str << GetStartIndex();
935     str << " end:";
936     str << GetEndIndex();
937     str << "]";
938     return str.str();
939 }
940 
IsAttributesEqual(const RefPtr<SpanBase> & other) const941 bool HalfLeadingSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
942 {
943     auto halfLeadingSpan = DynamicCast<HalfLeadingSpan>(other);
944     CHECK_NULL_RETURN(halfLeadingSpan, false);
945     return halfLeading_ == halfLeadingSpan->GetHalfLeading();
946 }
947 
948 // ExtSpan
ExtSpan(int32_t start,int32_t end)949 ExtSpan::ExtSpan(int32_t start, int32_t end) : SpanBase(start, end) {}
950 
GetSubSpan(int32_t start,int32_t end)951 RefPtr<SpanBase> ExtSpan::GetSubSpan(int32_t start, int32_t end)
952 {
953     RefPtr<SpanBase> spanBase = MakeRefPtr<ExtSpan>(start, end);
954     return spanBase;
955 }
956 
GetSpanType() const957 SpanType ExtSpan::GetSpanType() const
958 {
959     return SpanType::ExtSpan;
960 }
961 
ToString() const962 std::string ExtSpan::ToString() const
963 {
964     std::stringstream ss;
965     ss << "ExtSpan [";
966     ss << GetStartIndex();
967     ss << ":";
968     ss << GetEndIndex();
969     ss << "]";
970     std::string output = ss.str();
971     return output;
972 }
973 
IsAttributesEqual(const RefPtr<SpanBase> & other) const974 bool ExtSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
975 {
976     return false;
977 }
978 
BackgroundColorSpan(std::optional<TextBackgroundStyle> textBackgroundStyle,int32_t start,int32_t end)979 BackgroundColorSpan::BackgroundColorSpan(
980     std::optional<TextBackgroundStyle> textBackgroundStyle, int32_t start, int32_t end)
981     : SpanBase(start, end), textBackgroundStyle_(std::move(textBackgroundStyle))
982 {}
983 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const984 void BackgroundColorSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
985 {
986     switch (operation) {
987         case SpanOperation::ADD:
988             AddSpanStyle(spanItem);
989             break;
990         case SpanOperation::REMOVE:
991             RemoveSpanStyle(spanItem);
992             break;
993     }
994 }
995 
BackgroundColorSpan(std::optional<TextBackgroundStyle> textBackgroundStyle)996 BackgroundColorSpan::BackgroundColorSpan(std::optional<TextBackgroundStyle> textBackgroundStyle)
997     : textBackgroundStyle_(textBackgroundStyle) {}
998 
GetSubSpan(int32_t start,int32_t end)999 RefPtr<SpanBase> BackgroundColorSpan::GetSubSpan(int32_t start, int32_t end)
1000 {
1001     RefPtr<SpanBase> spanBase = MakeRefPtr<BackgroundColorSpan>(GetBackgroundColor(), start, end);
1002     return spanBase;
1003 }
AddSpanStyle(const RefPtr<NG::SpanItem> & spanItem) const1004 void BackgroundColorSpan::AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const
1005 {
1006     if (textBackgroundStyle_.has_value()) {
1007         TextBackgroundStyle tempVal = GetBackgroundColor();
1008         spanItem->backgroundStyle = tempVal;
1009     }
1010 }
1011 
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)1012 void BackgroundColorSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
1013 {
1014     if (spanItem->backgroundStyle.has_value()) {
1015         spanItem->backgroundStyle.reset();
1016     }
1017 }
1018 
GetBackgroundColor() const1019 TextBackgroundStyle BackgroundColorSpan::GetBackgroundColor() const
1020 {
1021     return textBackgroundStyle_.value_or(TextBackgroundStyle());
1022 }
1023 
SetBackgroundColorGroupId(int32_t groupId)1024 void BackgroundColorSpan::SetBackgroundColorGroupId(int32_t groupId)
1025 {
1026     textBackgroundStyle_->groupId = groupId;
1027 }
1028 
GetSpanType() const1029 SpanType BackgroundColorSpan::GetSpanType() const
1030 {
1031     return SpanType::BackgroundColor;
1032 }
1033 
ToString() const1034 std::string BackgroundColorSpan::ToString() const
1035 {
1036     std::stringstream ss;
1037     ss << "BackgroundColorSpan [";
1038     ss << GetStartIndex();
1039     ss << ":";
1040     ss << GetEndIndex();
1041     ss << "]";
1042     std::string output = ss.str();
1043     return output;
1044 }
1045 
IsAttributesEqual(const RefPtr<SpanBase> & other) const1046 bool BackgroundColorSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1047 {
1048     auto backgroundColorSpan = DynamicCast<BackgroundColorSpan>(other);
1049         if (!backgroundColorSpan) {
1050             return false;
1051         }
1052     auto backgroundColor = backgroundColorSpan->GetBackgroundColor();
1053     return backgroundColor == textBackgroundStyle_;
1054 }
1055 
1056 // UrlSpan
UrlSpan(const std::string & urlAddress)1057 UrlSpan::UrlSpan(const std::string& urlAddress) : SpanBase(0, 0), urlAddress_(urlAddress) {}
1058 
UrlSpan(const std::string & urlAddress,int32_t start,int32_t end)1059 UrlSpan::UrlSpan(const std::string& urlAddress, int32_t start, int32_t end)
1060     : SpanBase(start, end), urlAddress_(urlAddress)
1061 {}
1062 
GetUrlSpanAddress() const1063 std::string UrlSpan::GetUrlSpanAddress() const
1064 {
1065     return urlAddress_;
1066 }
1067 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const1068 void UrlSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
1069 {
1070     switch (operation) {
1071         case SpanOperation::ADD:
1072             AddUrlStyle(spanItem);
1073             break;
1074         case SpanOperation::REMOVE:
1075             RemoveUrlStyle(spanItem);
1076             break;
1077     }
1078 }
1079 
GetSubSpan(int32_t start,int32_t end)1080 RefPtr<SpanBase> UrlSpan::GetSubSpan(int32_t start, int32_t end)
1081 {
1082     RefPtr<SpanBase> spanBase = MakeRefPtr<UrlSpan>(urlAddress_, start, end);
1083     return spanBase;
1084 }
1085 
AddUrlStyle(const RefPtr<NG::SpanItem> & spanItem) const1086 void UrlSpan::AddUrlStyle(const RefPtr<NG::SpanItem>& spanItem) const
1087 {
1088     auto address = urlAddress_;
1089     auto urlOnRelease = [address]() {
1090         auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
1091         CHECK_NULL_VOID(pipelineContext);
1092         pipelineContext->HyperlinkStartAbility(address);
1093     };
1094     spanItem->SetUrlOnReleaseEvent(std::move(urlOnRelease));
1095 }
1096 
RemoveUrlStyle(const RefPtr<NG::SpanItem> & spanItem)1097 void UrlSpan::RemoveUrlStyle(const RefPtr<NG::SpanItem>& spanItem)
1098 {
1099     spanItem->urlOnRelease = nullptr;
1100 }
1101 
GetSpanType() const1102 SpanType UrlSpan::GetSpanType() const
1103 {
1104     return SpanType::Url;
1105 }
1106 
ToString() const1107 std::string UrlSpan::ToString() const
1108 {
1109     std::stringstream ss;
1110     ss << "UrlSpan [";
1111     ss << GetStartIndex();
1112     ss << ":";
1113     ss << GetEndIndex();
1114     ss << "]";
1115     std::string output = ss.str();
1116     return output;
1117 }
1118 
IsAttributesEqual(const RefPtr<SpanBase> & other) const1119 bool UrlSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1120 {
1121     auto urlSpan = DynamicCast<UrlSpan>(other);
1122     if (!urlSpan) {
1123         return false;
1124     }
1125     auto urlAddress = urlSpan->GetUrlSpanAddress();
1126     return urlAddress == urlAddress_;
1127 }
1128 } // namespace OHOS::Ace