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 if (font_.strokeWidth.has_value()) {
109 spanItem->fontStyle->UpdateStrokeWidth(font_.strokeWidth.value());
110 }
111
112 if (font_.strokeColor.has_value()) {
113 spanItem->fontStyle->UpdateStrokeColor(font_.strokeColor.value());
114 }
115
116 if (font_.superscript.has_value()) {
117 spanItem->fontStyle->UpdateSuperscript(font_.superscript.value());
118 }
119 }
120
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)121 void FontSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
122 {
123 spanItem->fontStyle->ResetTextColor();
124 spanItem->fontStyle->ResetFontFamily();
125 spanItem->fontStyle->ResetFontSize();
126 spanItem->fontStyle->ResetItalicFontStyle();
127 spanItem->fontStyle->ResetFontWeight();
128 spanItem->fontStyle->ResetStrokeWidth();
129 spanItem->fontStyle->ResetStrokeColor();
130 spanItem->fontStyle->ResetSuperscript();
131 }
132
GetFont() const133 Font FontSpan::GetFont() const
134 {
135 return font_;
136 }
137
GetSpanType() const138 SpanType FontSpan::GetSpanType() const
139 {
140 return SpanType::Font;
141 }
142
ToString() const143 std::string FontSpan::ToString() const
144 {
145 std::stringstream ss;
146 ss << "FontSpan [";
147 ss << GetStartIndex();
148 ss << ":";
149 ss << GetEndIndex();
150 ss << "]";
151 if (font_.fontColor.has_value()) {
152 ss << " FontColor:" << font_.fontColor.value().ColorToString();
153 }
154 if (font_.fontFamiliesNG.has_value()) {
155 ss << " FontFamily:";
156 for (auto& fontFam : font_.fontFamiliesNG.value()) {
157 ss << fontFam;
158 }
159 }
160 if (font_.fontSize.has_value()) {
161 ss << " FontSize:" << font_.fontSize.value().ToString();
162 }
163 if (font_.fontStyle.has_value()) {
164 ss << " FontStyle:" << static_cast<int32_t>(font_.fontStyle.value());
165 }
166 if (font_.fontWeight.has_value()) {
167 ss << " FontWeight:" << static_cast<int32_t>(font_.fontWeight.value());
168 }
169 if (font_.strokeWidth.has_value()) {
170 ss << " StrokeWidth:" << font_.strokeWidth.value().ToString();
171 }
172 if (font_.strokeColor.has_value()) {
173 ss << " StrokeColor:" << font_.strokeColor.value().ColorToString();
174 }
175 if (font_.superscript.has_value()) {
176 ss << " superscript:" << static_cast<int32_t>(font_.superscript.value());
177 }
178 std::string output = ss.str();
179 return output;
180 }
181
IsAttributesEqual(const RefPtr<SpanBase> & other) const182 bool FontSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
183 {
184 auto fontSpan = DynamicCast<FontSpan>(other);
185 if (!fontSpan) {
186 return false;
187 }
188 auto font = fontSpan->GetFont();
189 return font_.IsEqual(font);
190 }
191
192 // DecorationSpan
DecorationSpan(const std::vector<TextDecoration> & types,std::optional<Color> color,std::optional<TextDecorationStyle> style,std::optional<TextDecorationOptions> options)193 DecorationSpan::DecorationSpan(const std::vector<TextDecoration>& types, std::optional<Color> color,
194 std::optional<TextDecorationStyle> style, std::optional<TextDecorationOptions> options)
195 : SpanBase(0, 0), types_(types), color_(color), style_(style), options_(options)
196 {}
197
DecorationSpan(const std::vector<TextDecoration> & types,std::optional<Color> color,std::optional<TextDecorationStyle> style,std::optional<TextDecorationOptions> options,int32_t start,int32_t end)198 DecorationSpan::DecorationSpan(const std::vector<TextDecoration>& types, std::optional<Color> color,
199 std::optional<TextDecorationStyle> style, std::optional<TextDecorationOptions> options,
200 int32_t start, int32_t end)
201 : SpanBase(start, end), types_(types), color_(color), style_(style), options_(options)
202 {}
203
DecorationSpan(const std::vector<TextDecoration> & types,std::optional<Color> color,std::optional<TextDecorationStyle> style,std::optional<float> lineThicknessScale,std::optional<TextDecorationOptions> options)204 DecorationSpan::DecorationSpan(
205 const std::vector<TextDecoration>& types, std::optional<Color> color,
206 std::optional<TextDecorationStyle> style, std::optional<float> lineThicknessScale,
207 std::optional<TextDecorationOptions> options)
208 : SpanBase(0, 0), types_(types), color_(color), style_(style),
209 lineThicknessScale_(lineThicknessScale), options_(options)
210 {}
211
DecorationSpan(const std::vector<TextDecoration> & types,std::optional<Color> color,std::optional<TextDecorationStyle> style,std::optional<float> lineThicknessScale,std::optional<TextDecorationOptions> options,int32_t start,int32_t end)212 DecorationSpan::DecorationSpan(const std::vector<TextDecoration>& types, std::optional<Color> color,
213 std::optional<TextDecorationStyle> style, std::optional<float> lineThicknessScale,
214 std::optional<TextDecorationOptions> options, int32_t start, int32_t end)
215 : SpanBase(start, end), types_(types), color_(color), style_(style),
216 lineThicknessScale_(lineThicknessScale), options_(options)
217 {}
218
GetTextDecorationFirst() const219 TextDecoration DecorationSpan::GetTextDecorationFirst() const
220 {
221 return types_.size() > 0 ? types_[0] : TextDecoration::NONE;
222 }
223
GetTextDecorationTypes() const224 std::vector<TextDecoration> DecorationSpan::GetTextDecorationTypes() const
225 {
226 return types_;
227 }
228
SetTextDecorationTypes(const std::vector<TextDecoration> & types)229 void DecorationSpan::SetTextDecorationTypes(const std::vector<TextDecoration>& types)
230 {
231 types_ = types;
232 }
233
RemoveTextDecorationType(TextDecoration type)234 void DecorationSpan::RemoveTextDecorationType(TextDecoration type)
235 {
236 if (!V2::HasTextDecoration(types_, type)) {
237 return;
238 }
239 auto iter = std::find(types_.begin(), types_.end(), type);
240 if (iter != types_.end()) {
241 types_.erase(iter);
242 }
243 }
244
AddTextDecorationType(TextDecoration value)245 void DecorationSpan::AddTextDecorationType(TextDecoration value)
246 {
247 if (value == TextDecoration::NONE || V2::HasTextDecoration(types_, value)) {
248 return;
249 }
250 auto iter = std::find(types_.begin(), types_.end(), TextDecoration::NONE);
251 if (iter != types_.end()) {
252 types_.erase(iter);
253 }
254 types_.push_back(value);
255 }
256
GetColor() const257 std::optional<Color> DecorationSpan::GetColor() const
258 {
259 return color_;
260 }
261
GetTextDecorationStyle() const262 std::optional<TextDecorationStyle> DecorationSpan::GetTextDecorationStyle() const
263 {
264 return style_;
265 }
266
GetTextDecorationLineThicknessScale() const267 std::optional<float> DecorationSpan::GetTextDecorationLineThicknessScale() const
268 {
269 return lineThicknessScale_;
270 }
271
GetTextDecorationOptions() const272 std::optional<TextDecorationOptions> DecorationSpan::GetTextDecorationOptions() const
273 {
274 return options_;
275 }
276
SetTextDecorationOptions(const TextDecorationOptions & options)277 void DecorationSpan::SetTextDecorationOptions(const TextDecorationOptions& options)
278 {
279 options_ = options;
280 }
281
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const282 void DecorationSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
283 {
284 switch (operation) {
285 case SpanOperation::ADD:
286 AddDecorationStyle(spanItem);
287 break;
288 case SpanOperation::REMOVE:
289 RemoveDecorationStyle(spanItem);
290 }
291 }
292
GetLineThicknessScale() const293 std::optional<float> DecorationSpan::GetLineThicknessScale() const
294 {
295 return lineThicknessScale_;
296 }
297
GetSubSpan(int32_t start,int32_t end)298 RefPtr<SpanBase> DecorationSpan::GetSubSpan(int32_t start, int32_t end)
299 {
300 RefPtr<SpanBase> spanBase = MakeRefPtr<DecorationSpan>(
301 types_, color_, style_, lineThicknessScale_, options_, start, end);
302 return spanBase;
303 }
304
AddDecorationStyle(const RefPtr<NG::SpanItem> & spanItem) const305 void DecorationSpan::AddDecorationStyle(const RefPtr<NG::SpanItem>& spanItem) const
306 {
307 spanItem->fontStyle->UpdateTextDecoration(types_);
308 if (color_.has_value()) {
309 spanItem->fontStyle->UpdateTextDecorationColor(color_.value());
310 }
311 if (style_.has_value()) {
312 spanItem->fontStyle->UpdateTextDecorationStyle(style_.value());
313 }
314 if (lineThicknessScale_.has_value()) {
315 spanItem->fontStyle->UpdateLineThicknessScale(lineThicknessScale_.value());
316 }
317 if (options_.has_value()) {
318 spanItem->fontStyle->UpdateTextDecorationOptions(options_.value());
319 }
320 }
321
RemoveDecorationStyle(const RefPtr<NG::SpanItem> & spanItem)322 void DecorationSpan::RemoveDecorationStyle(const RefPtr<NG::SpanItem>& spanItem)
323 {
324 spanItem->fontStyle->ResetTextDecoration();
325 spanItem->fontStyle->ResetTextDecorationColor();
326 spanItem->fontStyle->ResetTextDecorationStyle();
327 spanItem->fontStyle->ResetLineThicknessScale();
328 }
329
GetSpanType() const330 SpanType DecorationSpan::GetSpanType() const
331 {
332 return SpanType::Decoration;
333 }
334
DecorationTypesToString() const335 std::string DecorationSpan::DecorationTypesToString() const
336 {
337 std::string result = "";
338 for (TextDecoration type : types_) {
339 switch (type) {
340 case TextDecoration::UNDERLINE:
341 result += "UNDERLINE,";
342 break;
343 case TextDecoration::OVERLINE:
344 result += "OVERLINE,";
345 break;
346 case TextDecoration::LINE_THROUGH:
347 result += "LINE_THROUGH,";
348 break;
349 default:
350 result += "NONE,";
351 break;
352 }
353 }
354 result.pop_back();
355 return result;
356 }
357
ToString() const358 std::string DecorationSpan::ToString() const
359 {
360 std::stringstream ss;
361 ss << "DecorationSpan [";
362 ss << GetStartIndex();
363 ss << ":";
364 ss << GetEndIndex();
365 ss << "]";
366 ss << " type:" << DecorationTypesToString() << " color:"
367 << (color_.has_value() ? color_.value().ColorToString(): "None")
368 << " style:" << (style_.has_value() ? static_cast<int32_t>(style_.value()): -1);
369 std::string output = ss.str();
370 return output;
371 }
372
IsAttributesEqual(const RefPtr<SpanBase> & other) const373 bool DecorationSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
374 {
375 auto decorationSpan = DynamicCast<DecorationSpan>(other);
376 if (!decorationSpan) {
377 return false;
378 }
379 std::optional<Color> color = decorationSpan->GetColor();
380 std::optional<TextDecorationStyle> style = decorationSpan->GetTextDecorationStyle();
381 std::optional<float> lineThicknessScale = decorationSpan->GetTextDecorationLineThicknessScale();
382 std::optional<TextDecorationOptions> options = decorationSpan->GetTextDecorationOptions();
383 return color == color_ && style == style_ && lineThicknessScale_ == lineThicknessScale &&
384 V2::IsEqualTextDecorations(types_, decorationSpan->GetTextDecorationTypes()) &&
385 options_.value_or(TextDecorationOptions()) == options.value_or(TextDecorationOptions());
386 }
387
388 // BaselineOffsetSpan
BaselineOffsetSpan(Dimension baselineOffset)389 BaselineOffsetSpan::BaselineOffsetSpan(Dimension baselineOffset) : SpanBase(0, 0), baselineOffset_(baselineOffset) {}
390
BaselineOffsetSpan(Dimension baselineOffset,int32_t start,int32_t end)391 BaselineOffsetSpan::BaselineOffsetSpan(Dimension baselineOffset, int32_t start, int32_t end)
392 : SpanBase(start, end), baselineOffset_(baselineOffset)
393 {}
394
GetBaselineOffset() const395 Dimension BaselineOffsetSpan::GetBaselineOffset() const
396 {
397 return baselineOffset_;
398 }
399
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const400 void BaselineOffsetSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
401 {
402 switch (operation) {
403 case SpanOperation::ADD:
404 AddBaselineOffsetStyle(spanItem);
405 break;
406 case SpanOperation::REMOVE:
407 RemoveBaselineOffsetStyle(spanItem);
408 }
409 }
410
GetSubSpan(int32_t start,int32_t end)411 RefPtr<SpanBase> BaselineOffsetSpan::GetSubSpan(int32_t start, int32_t end)
412 {
413 RefPtr<SpanBase> spanBase = MakeRefPtr<BaselineOffsetSpan>(baselineOffset_, start, end);
414 return spanBase;
415 }
416
AddBaselineOffsetStyle(const RefPtr<NG::SpanItem> & spanItem) const417 void BaselineOffsetSpan::AddBaselineOffsetStyle(const RefPtr<NG::SpanItem>& spanItem) const
418 {
419 CHECK_NULL_VOID(spanItem);
420 if (!spanItem->textLineStyle) {
421 spanItem->textLineStyle = std::make_unique<NG::TextLineStyle>();
422 }
423 spanItem->textLineStyle->UpdateBaselineOffset(baselineOffset_);
424 }
425
RemoveBaselineOffsetStyle(const RefPtr<NG::SpanItem> & spanItem)426 void BaselineOffsetSpan::RemoveBaselineOffsetStyle(const RefPtr<NG::SpanItem>& spanItem)
427 {
428 CHECK_NULL_VOID(spanItem);
429 if (!spanItem->textLineStyle) {
430 spanItem->textLineStyle = std::make_unique<NG::TextLineStyle>();
431 }
432 spanItem->textLineStyle->ResetBaselineOffset();
433 }
434
GetSpanType() const435 SpanType BaselineOffsetSpan::GetSpanType() const
436 {
437 return SpanType::BaselineOffset;
438 }
439
ToString() const440 std::string BaselineOffsetSpan::ToString() const
441 {
442 std::stringstream ss;
443 ss << "BaselineOffsetSpan [";
444 ss << GetStartIndex();
445 ss << ":";
446 ss << GetEndIndex();
447 ss << "]";
448 ss << " baselineOffset:" << baselineOffset_.ToString();
449 std::string output = ss.str();
450 return output;
451 }
452
IsAttributesEqual(const RefPtr<SpanBase> & other) const453 bool BaselineOffsetSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
454 {
455 auto baselineOffsetSpan = DynamicCast<BaselineOffsetSpan>(other);
456 if (!baselineOffsetSpan) {
457 return false;
458 }
459 auto baselineOffset = baselineOffsetSpan->GetBaselineOffset();
460 return baselineOffset == baselineOffset_;
461 }
462
463 // LetterSpacingSpan
LetterSpacingSpan(Dimension letterSpacing)464 LetterSpacingSpan::LetterSpacingSpan(Dimension letterSpacing) : SpanBase(0, 0), letterSpacing_(letterSpacing) {}
465
LetterSpacingSpan(Dimension letterSpacing,int32_t start,int32_t end)466 LetterSpacingSpan::LetterSpacingSpan(Dimension letterSpacing, int32_t start, int32_t end)
467 : SpanBase(start, end), letterSpacing_(letterSpacing)
468 {}
469
GetLetterSpacing() const470 Dimension LetterSpacingSpan::GetLetterSpacing() const
471 {
472 return letterSpacing_;
473 }
474
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const475 void LetterSpacingSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
476 {
477 switch (operation) {
478 case SpanOperation::ADD:
479 AddLetterSpacingStyle(spanItem);
480 break;
481 case SpanOperation::REMOVE:
482 RemoveLetterSpacingStyle(spanItem);
483 }
484 }
485
GetSubSpan(int32_t start,int32_t end)486 RefPtr<SpanBase> LetterSpacingSpan::GetSubSpan(int32_t start, int32_t end)
487 {
488 RefPtr<SpanBase> spanBase = MakeRefPtr<LetterSpacingSpan>(letterSpacing_, start, end);
489 return spanBase;
490 }
491
AddLetterSpacingStyle(const RefPtr<NG::SpanItem> & spanItem) const492 void LetterSpacingSpan::AddLetterSpacingStyle(const RefPtr<NG::SpanItem>& spanItem) const
493 {
494 spanItem->fontStyle->UpdateLetterSpacing(letterSpacing_);
495 }
496
RemoveLetterSpacingStyle(const RefPtr<NG::SpanItem> & spanItem)497 void LetterSpacingSpan::RemoveLetterSpacingStyle(const RefPtr<NG::SpanItem>& spanItem)
498 {
499 spanItem->fontStyle->ResetLetterSpacing();
500 }
501
GetSpanType() const502 SpanType LetterSpacingSpan::GetSpanType() const
503 {
504 return SpanType::LetterSpacing;
505 }
506
ToString() const507 std::string LetterSpacingSpan::ToString() const
508 {
509 std::stringstream ss;
510 ss << "LetterSpacingSpan [";
511 ss << GetStartIndex();
512 ss << ":";
513 ss << GetEndIndex();
514 ss << "]";
515 ss << " letterSpacing:" << letterSpacing_.ToString();
516 std::string output = ss.str();
517 return output;
518 }
519
IsAttributesEqual(const RefPtr<SpanBase> & other) const520 bool LetterSpacingSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
521 {
522 auto letterSpacingSpan = DynamicCast<LetterSpacingSpan>(other);
523 if (!letterSpacingSpan) {
524 return false;
525 }
526 auto letterSpacing = letterSpacingSpan->GetLetterSpacing();
527 return letterSpacing == letterSpacing_;
528 }
529
530 // GestureSpan
GestureSpan(GestureStyle gestureInfo)531 GestureSpan::GestureSpan(GestureStyle gestureInfo) : SpanBase(0, 0), gestureInfo_(std::move(gestureInfo)) {}
532
GestureSpan(GestureStyle gestureInfo,int32_t start,int32_t end)533 GestureSpan::GestureSpan(GestureStyle gestureInfo, int32_t start, int32_t end)
534 : SpanBase(start, end), gestureInfo_(std::move(gestureInfo))
535 {}
536
GetGestureStyle() const537 GestureStyle GestureSpan::GetGestureStyle() const
538 {
539 return gestureInfo_;
540 }
541
GetSubSpan(int32_t start,int32_t end)542 RefPtr<SpanBase> GestureSpan::GetSubSpan(int32_t start, int32_t end)
543 {
544 RefPtr<SpanBase> spanBase = MakeRefPtr<GestureSpan>(gestureInfo_, start, end);
545 auto gestureSpan = DynamicCast<GestureSpan>(spanBase);
546 CHECK_NULL_RETURN(gestureSpan, spanBase);
547 if (gestureSpanId_ == -1) {
548 gestureSpanId_ = gGestureSpanId.fetch_add(1) % GESTURES_SPAN_DIVIDE_SIZE;
549 }
550 gestureSpan->SetGestureSpanId(gestureSpanId_);
551 return spanBase;
552 }
553
IsAttributesEqual(const RefPtr<SpanBase> & other) const554 bool GestureSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
555 {
556 auto gestureSpan = DynamicCast<GestureSpan>(other);
557 if (!gestureSpan) {
558 return false;
559 }
560 if (gestureSpanId_ != -1 && gestureSpanId_ == gestureSpan->GetGestureSpanId()) {
561 return true;
562 }
563 auto gestureInfo = gestureSpan->GetGestureStyle();
564 return gestureInfo_.IsEqual(gestureInfo);
565 }
566
GetSpanType() const567 SpanType GestureSpan::GetSpanType() const
568 {
569 return SpanType::Gesture;
570 }
571
ToString() const572 std::string GestureSpan::ToString() const
573 {
574 std::stringstream ss;
575 ss << "GestureSpan [";
576 ss << GetStartIndex();
577 ss << ":";
578 ss << GetEndIndex();
579 ss << "]";
580 std::string output = ss.str();
581 return output;
582 }
583
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const584 void GestureSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
585 {
586 switch (operation) {
587 case SpanOperation::ADD:
588 AddSpanStyle(spanItem);
589 break;
590 case SpanOperation::REMOVE:
591 RemoveSpanStyle(spanItem);
592 }
593 }
594
AddSpanStyle(const RefPtr<NG::SpanItem> & spanItem) const595 void GestureSpan::AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const
596 {
597 spanItem->onClick = gestureInfo_.onClick.value_or(nullptr);
598 spanItem->onLongPress = gestureInfo_.onLongPress.value_or(nullptr);
599 spanItem->onTouch = gestureInfo_.onTouch.value_or(nullptr);
600 }
601
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)602 void GestureSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
603 {
604 spanItem->onClick = nullptr;
605 spanItem->onLongPress = nullptr;
606 spanItem->onTouch = nullptr;
607 }
608
609 // TextShadowSpan
TextShadowSpan(std::vector<Shadow> textShadow)610 TextShadowSpan::TextShadowSpan(std::vector<Shadow> textShadow) : SpanBase(0, 0), textShadow_(std::move(textShadow)) {}
611
TextShadowSpan(std::vector<Shadow> textShadow,int32_t start,int32_t end)612 TextShadowSpan::TextShadowSpan(std::vector<Shadow> textShadow, int32_t start, int32_t end)
613 : SpanBase(start, end), textShadow_(std::move(textShadow))
614 {}
615
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const616 void TextShadowSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
617 {
618 switch (operation) {
619 case SpanOperation::ADD:
620 AddSpanStyle(spanItem);
621 break;
622 case SpanOperation::REMOVE:
623 RemoveSpanStyle(spanItem);
624 }
625 }
626
GetSubSpan(int32_t start,int32_t end)627 RefPtr<SpanBase> TextShadowSpan::GetSubSpan(int32_t start, int32_t end)
628 {
629 RefPtr<SpanBase> spanBase = MakeRefPtr<TextShadowSpan>(GetTextShadow(), start, end);
630 return spanBase;
631 }
632
AddSpanStyle(const RefPtr<NG::SpanItem> & spanItem) const633 void TextShadowSpan::AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const
634 {
635 if (textShadow_.has_value()) {
636 spanItem->fontStyle->UpdateTextShadow(textShadow_.value());
637 }
638 }
639
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)640 void TextShadowSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
641 {
642 spanItem->fontStyle->ResetTextShadow();
643 }
644
GetTextShadow() const645 std::vector<Shadow> TextShadowSpan::GetTextShadow() const
646 {
647 return textShadow_.value_or(std::vector<Shadow>());
648 }
649
GetSpanType() const650 SpanType TextShadowSpan::GetSpanType() const
651 {
652 return SpanType::TextShadow;
653 }
654
ToString() const655 std::string TextShadowSpan::ToString() const
656 {
657 std::stringstream ss;
658 ss << "TextShadowSpan [";
659 ss << GetStartIndex();
660 ss << ":";
661 ss << GetEndIndex();
662 ss << "]";
663 std::string output = ss.str();
664 return output;
665 }
666
IsAttributesEqual(const RefPtr<SpanBase> & other) const667 bool TextShadowSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
668 {
669 auto textShadowSpan = DynamicCast<TextShadowSpan>(other);
670 if (!textShadowSpan) {
671 return false;
672 }
673 auto textShadow = textShadowSpan->GetTextShadow();
674 auto selfTextShadow = GetTextShadow();
675 if (textShadow.size() != selfTextShadow.size()) {
676 return false;
677 }
678 for (size_t i = 0; i < selfTextShadow.size(); ++i) {
679 if (selfTextShadow[i] != textShadow[i]) {
680 return false;
681 }
682 }
683 return true;
684 }
685
686 // ImageSpan
ImageSpan(const ImageSpanOptions & options)687 ImageSpan::ImageSpan(const ImageSpanOptions& options) : SpanBase(0, 1), imageOptions_(options) {}
688
ImageSpan(const ImageSpanOptions & options,int32_t position)689 ImageSpan::ImageSpan(const ImageSpanOptions& options, int32_t position)
690 : SpanBase(position, position + 1), imageOptions_(options)
691 {}
692
IsAttributesEqual(const RefPtr<SpanBase> & other) const693 bool ImageSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
694 {
695 auto imageSpan = DynamicCast<ImageSpan>(other);
696 if (!imageSpan) {
697 return false;
698 }
699 if (imageOptions_.imageAttribute.has_value() && imageSpan->GetImageAttribute().has_value()) {
700 return imageOptions_.imageAttribute.value() == imageSpan->GetImageAttribute().value();
701 }
702 return false;
703 }
704
GetSubSpan(int32_t start,int32_t end)705 RefPtr<SpanBase> ImageSpan::GetSubSpan(int32_t start, int32_t end)
706 {
707 if (end - start > 1) {
708 return nullptr;
709 }
710 auto spanBase = MakeRefPtr<ImageSpan>(imageOptions_);
711 spanBase->UpdateStartIndex(start);
712 spanBase->UpdateEndIndex(end);
713 return spanBase;
714 }
715
GetSpanType() const716 SpanType ImageSpan::GetSpanType() const
717 {
718 return SpanType::Image;
719 }
720
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const721 void ImageSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
722 {
723 auto imageItem = DynamicCast<NG::ImageSpanItem>(spanItem);
724 if (!imageItem) {
725 return;
726 }
727
728 switch (operation) {
729 case SpanOperation::ADD:
730 imageItem->SetImageSpanOptions(imageOptions_);
731 break;
732 case SpanOperation::REMOVE:
733 imageItem->ResetImageSpanOptions();
734 }
735 }
736
ToString() const737 std::string ImageSpan::ToString() const
738 {
739 std::stringstream ss;
740 ss << "ImageSpan [";
741 ss << GetStartIndex();
742 ss << ":";
743 ss << GetEndIndex();
744 ss << "]";
745 std::string output = ss.str();
746 return output;
747 }
748
GetImageSpanOptions()749 const ImageSpanOptions& ImageSpan::GetImageSpanOptions()
750 {
751 return imageOptions_;
752 }
753
GetImageAttribute() const754 const std::optional<ImageSpanAttribute>& ImageSpan::GetImageAttribute() const
755 {
756 return imageOptions_.imageAttribute;
757 }
758
759 // CustomSpan
CustomSpan()760 CustomSpan::CustomSpan() : SpanBase(0, 1) {}
761
CustomSpan(std::optional<std::function<CustomSpanMetrics (CustomSpanMeasureInfo)>> onMeasure,std::optional<std::function<void (NG::DrawingContext &,CustomSpanOptions)>> onDraw)762 CustomSpan::CustomSpan(std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
763 std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw)
764 : SpanBase(0, 1), onMeasure_(std::move(onMeasure)), onDraw_(std::move(onDraw))
765 {}
766
CustomSpan(std::optional<std::function<CustomSpanMetrics (CustomSpanMeasureInfo)>> onMeasure,std::optional<std::function<void (NG::DrawingContext &,CustomSpanOptions)>> onDraw,int32_t start,int32_t end)767 CustomSpan::CustomSpan(std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
768 std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw, int32_t start, int32_t end)
769 : SpanBase(start, end), onMeasure_(std::move(onMeasure)), onDraw_(std::move(onDraw))
770 {}
771
SetOnMeasure(std::function<CustomSpanMetrics (CustomSpanMeasureInfo)> onMeasure)772 void CustomSpan::SetOnMeasure(std::function<CustomSpanMetrics(CustomSpanMeasureInfo)> onMeasure)
773 {
774 onMeasure_ = onMeasure;
775 }
776
SetOnDraw(std::function<void (NG::DrawingContext &,CustomSpanOptions)> onDraw)777 void CustomSpan::SetOnDraw(std::function<void(NG::DrawingContext&, CustomSpanOptions)> onDraw)
778 {
779 onDraw_ = onDraw;
780 }
781
GetOnMeasure()782 std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> CustomSpan::GetOnMeasure()
783 {
784 return onMeasure_;
785 }
786
GetOnDraw()787 std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> CustomSpan::GetOnDraw()
788 {
789 return onDraw_;
790 }
791
GetSubSpan(int32_t start,int32_t end)792 RefPtr<SpanBase> CustomSpan::GetSubSpan(int32_t start, int32_t end)
793 {
794 if (end - start > 1) {
795 return nullptr;
796 }
797 RefPtr<SpanBase> spanBase = MakeRefPtr<CustomSpan>(onMeasure_, onDraw_, start, end);
798 return spanBase;
799 }
800
GetSpanType() const801 SpanType CustomSpan::GetSpanType() const
802 {
803 return SpanType::CustomSpan;
804 }
805
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const806 void CustomSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
807 {
808 auto imageItem = DynamicCast<NG::CustomSpanItem>(spanItem);
809 if (!imageItem) {
810 return;
811 }
812
813 switch (operation) {
814 case SpanOperation::ADD:
815 imageItem->onMeasure = onMeasure_;
816 imageItem->onDraw = onDraw_;
817 break;
818 case SpanOperation::REMOVE:
819 imageItem->onMeasure = std::nullopt;
820 imageItem->onDraw = std::nullopt;
821 }
822 }
823
ToString() const824 std::string CustomSpan::ToString() const
825 {
826 std::stringstream ss;
827 ss << "CustomSpan [";
828 ss << GetStartIndex();
829 ss << ":";
830 ss << GetEndIndex();
831 ss << "]";
832 std::string output = ss.str();
833 return output;
834 }
835
IsAttributesEqual(const RefPtr<SpanBase> & other) const836 bool CustomSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
837 {
838 return false;
839 }
840
841 // ParagraphStyleSpan
ParagraphStyleSpan(SpanParagraphStyle paragraphStyle)842 ParagraphStyleSpan::ParagraphStyleSpan(SpanParagraphStyle paragraphStyle)
843 : SpanBase(0, 0), paragraphStyle_(std::move(paragraphStyle))
844 {}
845
ParagraphStyleSpan(SpanParagraphStyle paragraphStyle,int32_t start,int32_t end)846 ParagraphStyleSpan::ParagraphStyleSpan(SpanParagraphStyle paragraphStyle, int32_t start, int32_t end)
847 : SpanBase(start, end), paragraphStyle_(std::move(paragraphStyle))
848 {}
849
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const850 void ParagraphStyleSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
851 {
852 switch (operation) {
853 case SpanOperation::ADD:
854 AddParagraphStyle(spanItem);
855 break;
856 case SpanOperation::REMOVE:
857 RemoveParagraphStyle(spanItem);
858 }
859 }
860
AddParagraphStyle(const RefPtr<NG::SpanItem> & spanItem) const861 void ParagraphStyleSpan::AddParagraphStyle(const RefPtr<NG::SpanItem>& spanItem) const
862 {
863 if (paragraphStyle_.align.has_value()) {
864 spanItem->textLineStyle->UpdateTextAlign(paragraphStyle_.align.value());
865 }
866
867 if (paragraphStyle_.textVerticalAlign.has_value()) {
868 spanItem->textLineStyle->UpdateTextVerticalAlign(paragraphStyle_.textVerticalAlign.value());
869 }
870
871 if (paragraphStyle_.maxLines.has_value()) {
872 spanItem->textLineStyle->UpdateMaxLines(static_cast<uint32_t>(paragraphStyle_.maxLines.value()));
873 }
874
875 if (paragraphStyle_.textOverflow.has_value()) {
876 spanItem->textLineStyle->UpdateTextOverflow(paragraphStyle_.textOverflow.value());
877 }
878
879 if (paragraphStyle_.leadingMargin.has_value()) {
880 spanItem->textLineStyle->UpdateLeadingMargin(paragraphStyle_.leadingMargin.value());
881 }
882
883 if (paragraphStyle_.wordBreak.has_value()) {
884 spanItem->textLineStyle->UpdateWordBreak(paragraphStyle_.wordBreak.value());
885 }
886
887 if (paragraphStyle_.textIndent.has_value()) {
888 spanItem->textLineStyle->UpdateTextIndent(paragraphStyle_.textIndent.value());
889 }
890
891 if (paragraphStyle_.paragraphSpacing.has_value()) {
892 spanItem->textLineStyle->UpdateParagraphSpacing(paragraphStyle_.paragraphSpacing.value());
893 }
894 }
895
RemoveParagraphStyle(const RefPtr<NG::SpanItem> & spanItem) const896 void ParagraphStyleSpan::RemoveParagraphStyle(const RefPtr<NG::SpanItem>& spanItem) const
897 {
898 spanItem->textLineStyle->ResetTextAlign();
899 spanItem->textLineStyle->ResetTextVerticalAlign();
900 spanItem->textLineStyle->ResetMaxLines();
901 spanItem->textLineStyle->ResetTextOverflow();
902 spanItem->textLineStyle->ResetLeadingMargin();
903 spanItem->textLineStyle->ResetWordBreak();
904 spanItem->textLineStyle->ResetTextIndent();
905 spanItem->textLineStyle->ResetParagraphSpacing();
906 }
907
IsAttributesEqual(const RefPtr<SpanBase> & other) const908 bool ParagraphStyleSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
909 {
910 auto paragraphSpan = DynamicCast<ParagraphStyleSpan>(other);
911 if (!paragraphSpan) {
912 return false;
913 }
914 auto paragraphStyle = paragraphSpan->GetParagraphStyle();
915 return paragraphStyle_.Equal(paragraphStyle);
916 }
917
GetParagraphStyle() const918 SpanParagraphStyle ParagraphStyleSpan::GetParagraphStyle() const
919 {
920 return paragraphStyle_;
921 }
922
GetSpanType() const923 SpanType ParagraphStyleSpan::GetSpanType() const
924 {
925 return SpanType::ParagraphStyle;
926 }
927
ToString() const928 std::string ParagraphStyleSpan::ToString() const
929 {
930 std::stringstream ss;
931 ss << "ParagraphStyleSpan [";
932 ss << GetStartIndex();
933 ss << ":";
934 ss << GetEndIndex();
935 ss << "]";
936 std::string output = ss.str();
937 return output;
938 }
939
GetSubSpan(int32_t start,int32_t end)940 RefPtr<SpanBase> ParagraphStyleSpan::GetSubSpan(int32_t start, int32_t end)
941 {
942 RefPtr<SpanBase> spanBase = MakeRefPtr<ParagraphStyleSpan>(paragraphStyle_, start, end);
943 return spanBase;
944 }
945
946 // LineHeightSpan
LineHeightSpan(Dimension lineHeight)947 LineHeightSpan::LineHeightSpan(Dimension lineHeight) : SpanBase(0, 0), lineHeight_(lineHeight) {}
948
LineHeightSpan(Dimension lineHeight,int32_t start,int32_t end)949 LineHeightSpan::LineHeightSpan(Dimension lineHeight, int32_t start, int32_t end)
950 : SpanBase(start, end), lineHeight_(lineHeight)
951 {}
952
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const953 void LineHeightSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
954 {
955 switch (operation) {
956 case SpanOperation::ADD:
957 AddLineHeightStyle(spanItem);
958 break;
959 case SpanOperation::REMOVE:
960 RemoveLineHeightStyle(spanItem);
961 }
962 }
963
GetSubSpan(int32_t start,int32_t end)964 RefPtr<SpanBase> LineHeightSpan::GetSubSpan(int32_t start, int32_t end)
965 {
966 RefPtr<SpanBase> spanBase = MakeRefPtr<LineHeightSpan>(GetLineHeight(), start, end);
967 return spanBase;
968 }
969
AddLineHeightStyle(const RefPtr<NG::SpanItem> & spanItem) const970 void LineHeightSpan::AddLineHeightStyle(const RefPtr<NG::SpanItem>& spanItem) const
971 {
972 spanItem->textLineStyle->UpdateLineHeight(lineHeight_);
973 }
974
RemoveLineHeightStyle(const RefPtr<NG::SpanItem> & spanItem) const975 void LineHeightSpan::RemoveLineHeightStyle(const RefPtr<NG::SpanItem>& spanItem) const
976 {
977 spanItem->textLineStyle->ResetLineHeight();
978 }
979
GetLineHeight() const980 Dimension LineHeightSpan::GetLineHeight() const
981 {
982 return lineHeight_;
983 }
984
GetSpanType() const985 SpanType LineHeightSpan::GetSpanType() const
986 {
987 return SpanType::LineHeight;
988 }
989
ToString() const990 std::string LineHeightSpan::ToString() const
991 {
992 std::stringstream ss;
993 ss << "LineHeightSpan [";
994 ss << GetStartIndex();
995 ss << ":";
996 ss << GetEndIndex();
997 ss << "]";
998 ss << " baselineOffset:" << lineHeight_.ToString();
999 std::string output = ss.str();
1000 return output;
1001 }
1002
IsAttributesEqual(const RefPtr<SpanBase> & other) const1003 bool LineHeightSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1004 {
1005 auto lineHeightSpan = DynamicCast<LineHeightSpan>(other);
1006 if (!lineHeightSpan) {
1007 return false;
1008 }
1009 auto lineHeight = lineHeightSpan->GetLineHeight();
1010 return lineHeight_ == lineHeight;
1011 }
1012
1013 // HalfLeadingSpan
HalfLeadingSpan(bool halfLeading)1014 HalfLeadingSpan::HalfLeadingSpan(bool halfLeading) : SpanBase(0, 0), halfLeading_(halfLeading) {}
1015
HalfLeadingSpan(bool halfLeading,int32_t start,int32_t end)1016 HalfLeadingSpan::HalfLeadingSpan(bool halfLeading, int32_t start, int32_t end)
1017 : SpanBase(start, end), halfLeading_(halfLeading)
1018 {}
1019
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const1020 void HalfLeadingSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
1021 {
1022 switch (operation) {
1023 case SpanOperation::ADD:
1024 AddHalfLeadingStyle(spanItem);
1025 break;
1026 case SpanOperation::REMOVE:
1027 RemoveHalfLeadingStyle(spanItem);
1028 }
1029 }
1030
GetSubSpan(int32_t start,int32_t end)1031 RefPtr<SpanBase> HalfLeadingSpan::GetSubSpan(int32_t start, int32_t end)
1032 {
1033 return MakeRefPtr<HalfLeadingSpan>(halfLeading_, start, end);
1034 }
1035
AddHalfLeadingStyle(const RefPtr<NG::SpanItem> & spanItem) const1036 void HalfLeadingSpan::AddHalfLeadingStyle(const RefPtr<NG::SpanItem>& spanItem) const
1037 {
1038 spanItem->textLineStyle->UpdateHalfLeading(halfLeading_);
1039 }
1040
RemoveHalfLeadingStyle(const RefPtr<NG::SpanItem> & spanItem) const1041 void HalfLeadingSpan::RemoveHalfLeadingStyle(const RefPtr<NG::SpanItem>& spanItem) const
1042 {
1043 spanItem->textLineStyle->ResetHalfLeading();
1044 }
1045
GetHalfLeading() const1046 bool HalfLeadingSpan::GetHalfLeading() const
1047 {
1048 return halfLeading_;
1049 }
1050
GetSpanType() const1051 SpanType HalfLeadingSpan::GetSpanType() const
1052 {
1053 return SpanType::HalfLeading;
1054 }
1055
ToString() const1056 std::string HalfLeadingSpan::ToString() const
1057 {
1058 std::stringstream str;
1059 str << "HalfLeadingSpan ( start:";
1060 str << GetStartIndex();
1061 str << " end:";
1062 str << GetEndIndex();
1063 str << "]";
1064 return str.str();
1065 }
1066
IsAttributesEqual(const RefPtr<SpanBase> & other) const1067 bool HalfLeadingSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1068 {
1069 auto halfLeadingSpan = DynamicCast<HalfLeadingSpan>(other);
1070 CHECK_NULL_RETURN(halfLeadingSpan, false);
1071 return halfLeading_ == halfLeadingSpan->GetHalfLeading();
1072 }
1073
1074 // ExtSpan
ExtSpan(int32_t start,int32_t end)1075 ExtSpan::ExtSpan(int32_t start, int32_t end) : SpanBase(start, end) {}
1076
GetSubSpan(int32_t start,int32_t end)1077 RefPtr<SpanBase> ExtSpan::GetSubSpan(int32_t start, int32_t end)
1078 {
1079 RefPtr<SpanBase> spanBase = MakeRefPtr<ExtSpan>(start, end);
1080 return spanBase;
1081 }
1082
GetSpanType() const1083 SpanType ExtSpan::GetSpanType() const
1084 {
1085 return SpanType::ExtSpan;
1086 }
1087
ToString() const1088 std::string ExtSpan::ToString() const
1089 {
1090 std::stringstream ss;
1091 ss << "ExtSpan [";
1092 ss << GetStartIndex();
1093 ss << ":";
1094 ss << GetEndIndex();
1095 ss << "]";
1096 std::string output = ss.str();
1097 return output;
1098 }
1099
IsAttributesEqual(const RefPtr<SpanBase> & other) const1100 bool ExtSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1101 {
1102 return false;
1103 }
1104
BackgroundColorSpan(std::optional<TextBackgroundStyle> textBackgroundStyle,int32_t start,int32_t end)1105 BackgroundColorSpan::BackgroundColorSpan(
1106 std::optional<TextBackgroundStyle> textBackgroundStyle, int32_t start, int32_t end)
1107 : SpanBase(start, end), textBackgroundStyle_(std::move(textBackgroundStyle))
1108 {}
1109
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const1110 void BackgroundColorSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
1111 {
1112 switch (operation) {
1113 case SpanOperation::ADD:
1114 AddSpanStyle(spanItem);
1115 break;
1116 case SpanOperation::REMOVE:
1117 RemoveSpanStyle(spanItem);
1118 break;
1119 }
1120 }
1121
BackgroundColorSpan(std::optional<TextBackgroundStyle> textBackgroundStyle)1122 BackgroundColorSpan::BackgroundColorSpan(std::optional<TextBackgroundStyle> textBackgroundStyle)
1123 : textBackgroundStyle_(textBackgroundStyle) {}
1124
GetSubSpan(int32_t start,int32_t end)1125 RefPtr<SpanBase> BackgroundColorSpan::GetSubSpan(int32_t start, int32_t end)
1126 {
1127 RefPtr<SpanBase> spanBase = MakeRefPtr<BackgroundColorSpan>(GetBackgroundColor(), start, end);
1128 return spanBase;
1129 }
AddSpanStyle(const RefPtr<NG::SpanItem> & spanItem) const1130 void BackgroundColorSpan::AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const
1131 {
1132 if (textBackgroundStyle_.has_value()) {
1133 TextBackgroundStyle tempVal = GetBackgroundColor();
1134 spanItem->backgroundStyle = tempVal;
1135 }
1136 }
1137
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)1138 void BackgroundColorSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
1139 {
1140 if (spanItem->backgroundStyle.has_value()) {
1141 spanItem->backgroundStyle.reset();
1142 }
1143 }
1144
GetBackgroundColor() const1145 TextBackgroundStyle BackgroundColorSpan::GetBackgroundColor() const
1146 {
1147 return textBackgroundStyle_.value_or(TextBackgroundStyle());
1148 }
1149
SetBackgroundColorGroupId(int32_t groupId)1150 void BackgroundColorSpan::SetBackgroundColorGroupId(int32_t groupId)
1151 {
1152 textBackgroundStyle_->groupId = groupId;
1153 }
1154
GetSpanType() const1155 SpanType BackgroundColorSpan::GetSpanType() const
1156 {
1157 return SpanType::BackgroundColor;
1158 }
1159
ToString() const1160 std::string BackgroundColorSpan::ToString() const
1161 {
1162 std::stringstream ss;
1163 ss << "BackgroundColorSpan [";
1164 ss << GetStartIndex();
1165 ss << ":";
1166 ss << GetEndIndex();
1167 ss << "]";
1168 std::string output = ss.str();
1169 return output;
1170 }
1171
IsAttributesEqual(const RefPtr<SpanBase> & other) const1172 bool BackgroundColorSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1173 {
1174 auto backgroundColorSpan = DynamicCast<BackgroundColorSpan>(other);
1175 if (!backgroundColorSpan) {
1176 return false;
1177 }
1178 auto backgroundColor = backgroundColorSpan->GetBackgroundColor();
1179 return backgroundColor == textBackgroundStyle_;
1180 }
1181
1182 // UrlSpan
UrlSpan(const std::string & urlAddress)1183 UrlSpan::UrlSpan(const std::string& urlAddress) : SpanBase(0, 0), urlAddress_(urlAddress) {}
1184
UrlSpan(const std::string & urlAddress,int32_t start,int32_t end)1185 UrlSpan::UrlSpan(const std::string& urlAddress, int32_t start, int32_t end)
1186 : SpanBase(start, end), urlAddress_(urlAddress)
1187 {}
1188
GetUrlSpanAddress() const1189 std::string UrlSpan::GetUrlSpanAddress() const
1190 {
1191 return urlAddress_;
1192 }
1193
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const1194 void UrlSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
1195 {
1196 switch (operation) {
1197 case SpanOperation::ADD:
1198 AddUrlStyle(spanItem);
1199 break;
1200 case SpanOperation::REMOVE:
1201 RemoveUrlStyle(spanItem);
1202 break;
1203 }
1204 }
1205
GetSubSpan(int32_t start,int32_t end)1206 RefPtr<SpanBase> UrlSpan::GetSubSpan(int32_t start, int32_t end)
1207 {
1208 RefPtr<SpanBase> spanBase = MakeRefPtr<UrlSpan>(urlAddress_, start, end);
1209 return spanBase;
1210 }
1211
AddUrlStyle(const RefPtr<NG::SpanItem> & spanItem) const1212 void UrlSpan::AddUrlStyle(const RefPtr<NG::SpanItem>& spanItem) const
1213 {
1214 auto address = urlAddress_;
1215 spanItem->urlAddress = UtfUtils::Str8DebugToStr16(address);
1216 auto urlOnRelease = [address]() {
1217 auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
1218 CHECK_NULL_VOID(pipelineContext);
1219 pipelineContext->HyperlinkStartAbility(address);
1220 };
1221 spanItem->SetUrlOnReleaseEvent(std::move(urlOnRelease));
1222 spanItem->urlAddress = std::u16string(address.begin(), address.end());
1223 }
1224
RemoveUrlStyle(const RefPtr<NG::SpanItem> & spanItem)1225 void UrlSpan::RemoveUrlStyle(const RefPtr<NG::SpanItem>& spanItem)
1226 {
1227 spanItem->urlAddress = std::nullopt;
1228 spanItem->urlOnRelease = nullptr;
1229 }
1230
GetSpanType() const1231 SpanType UrlSpan::GetSpanType() const
1232 {
1233 return SpanType::Url;
1234 }
1235
ToString() const1236 std::string UrlSpan::ToString() const
1237 {
1238 std::stringstream ss;
1239 ss << "UrlSpan [";
1240 ss << GetStartIndex();
1241 ss << ":";
1242 ss << GetEndIndex();
1243 ss << "]";
1244 std::string output = ss.str();
1245 return output;
1246 }
1247
IsAttributesEqual(const RefPtr<SpanBase> & other) const1248 bool UrlSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1249 {
1250 auto urlSpan = DynamicCast<UrlSpan>(other);
1251 if (!urlSpan) {
1252 return false;
1253 }
1254 auto urlAddress = urlSpan->GetUrlSpanAddress();
1255 return urlAddress == urlAddress_;
1256 }
1257 } // namespace OHOS::Ace