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