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 #include <optional>
18 #include <utility>
19
20 #include "base/memory/referenced.h"
21 #include "core/components/common/layout/constants.h"
22 #include "core/components/common/properties/color.h"
23 #include "core/components_ng/pattern/text_field/text_field_model.h"
24 #include "core/components_ng/render/paragraph.h"
25
26 namespace OHOS::Ace {
27 // SpanBase
GetIntersectionInterval(std::pair<int32_t,int32_t> interval) const28 std::optional<std::pair<int32_t, int32_t>> SpanBase::GetIntersectionInterval(std::pair<int32_t, int32_t> interval) const
29 {
30 // 检查相交情况
31 if (end_ <= interval.first || interval.second <= start_) {
32 return std::nullopt;
33 }
34
35 // 计算相交区间
36 int start = std::max(start_, interval.first);
37 int end = std::min(end_, interval.second);
38 return std::make_optional<std::pair<int32_t, int32_t>>(std::make_pair(start, end));
39 }
40
GetStartIndex() const41 int32_t SpanBase::GetStartIndex() const
42 {
43 return start_;
44 }
45
GetEndIndex() const46 int32_t SpanBase::GetEndIndex() const
47 {
48 return end_;
49 }
UpdateStartIndex(int32_t startIndex)50 void SpanBase::UpdateStartIndex(int32_t startIndex)
51 {
52 start_ = startIndex;
53 }
54
UpdateEndIndex(int32_t endIndex)55 void SpanBase::UpdateEndIndex(int32_t endIndex)
56 {
57 end_ = endIndex;
58 }
59
GetLength() const60 int32_t SpanBase::GetLength() const
61 {
62 return end_ - start_;
63 }
64
65 // FontSpan
FontSpan(Font font)66 FontSpan::FontSpan(Font font) : SpanBase(0, 0), font_(std::move(font)) {}
67
FontSpan(Font font,int32_t start,int32_t end)68 FontSpan::FontSpan(Font font, int32_t start, int32_t end) : SpanBase(start, end), font_(std::move(font)) {}
69
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const70 void FontSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
71 {
72 switch (operation) {
73 case SpanOperation::ADD:
74 AddSpanStyle(spanItem);
75 break;
76 case SpanOperation::REMOVE:
77 RemoveSpanStyle(spanItem);
78 }
79 }
80
GetSubSpan(int32_t start,int32_t end)81 RefPtr<SpanBase> FontSpan::GetSubSpan(int32_t start, int32_t end)
82 {
83 RefPtr<SpanBase> spanBase = MakeRefPtr<FontSpan>(font_, start, end);
84 return spanBase;
85 }
86
AddSpanStyle(const RefPtr<NG::SpanItem> & spanItem) const87 void FontSpan::AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const
88 {
89 if (font_.fontColor.has_value()) {
90 spanItem->fontStyle->UpdateTextColor(font_.fontColor.value());
91 }
92
93 if (font_.fontFamiliesNG.has_value()) {
94 spanItem->fontStyle->UpdateFontFamily(font_.fontFamiliesNG.value());
95 }
96
97 if (font_.fontSize.has_value()) {
98 spanItem->fontStyle->UpdateFontSize(font_.fontSize.value());
99 }
100
101 if (font_.fontStyle.has_value()) {
102 spanItem->fontStyle->UpdateItalicFontStyle(font_.fontStyle.value());
103 }
104
105 if (font_.fontWeight.has_value()) {
106 spanItem->fontStyle->UpdateFontWeight(font_.fontWeight.value());
107 }
108 }
109
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)110 void FontSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
111 {
112 spanItem->fontStyle->ResetTextColor();
113 spanItem->fontStyle->ResetFontFamily();
114 spanItem->fontStyle->ResetFontSize();
115 spanItem->fontStyle->ResetItalicFontStyle();
116 spanItem->fontStyle->ResetFontWeight();
117 }
118
GetFont() const119 Font FontSpan::GetFont() const
120 {
121 return font_;
122 }
123
GetSpanType() const124 SpanType FontSpan::GetSpanType() const
125 {
126 return SpanType::Font;
127 }
128
ToString() const129 std::string FontSpan::ToString() const
130 {
131 std::stringstream str;
132 str << "FontSpan ( start:";
133 str << GetStartIndex();
134 str << " end:";
135 str << GetEndIndex();
136 str << "]";
137 std::string output = str.str();
138 return output;
139 }
140
IsAttributesEqual(const RefPtr<SpanBase> & other) const141 bool FontSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
142 {
143 auto fontSpan = DynamicCast<FontSpan>(other);
144 if (!fontSpan) {
145 return false;
146 }
147 auto font = fontSpan->GetFont();
148 return font_.IsEqual(font);
149 }
150
151 // DecorationSpan
DecorationSpan(TextDecoration type,std::optional<Color> color,std::optional<TextDecorationStyle> style)152 DecorationSpan::DecorationSpan(
153 TextDecoration type, std::optional<Color> color, std::optional<TextDecorationStyle> style)
154 : SpanBase(0, 0), type_(type), color_(color), style_(style)
155 {}
156
DecorationSpan(TextDecoration type,std::optional<Color> color,std::optional<TextDecorationStyle> style,int32_t start,int32_t end)157 DecorationSpan::DecorationSpan(TextDecoration type, std::optional<Color> color,
158 std::optional<TextDecorationStyle> style, int32_t start, int32_t end)
159 : SpanBase(start, end), type_(type), color_(color), style_(style)
160 {}
161
GetTextDecorationType() const162 TextDecoration DecorationSpan::GetTextDecorationType() const
163 {
164 return type_;
165 }
166
GetColor() const167 std::optional<Color> DecorationSpan::GetColor() const
168 {
169 return color_;
170 }
171
GetTextDecorationStyle() const172 std::optional<TextDecorationStyle> DecorationSpan::GetTextDecorationStyle() const
173 {
174 return style_;
175 }
176
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const177 void DecorationSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
178 {
179 switch (operation) {
180 case SpanOperation::ADD:
181 AddDecorationStyle(spanItem);
182 break;
183 case SpanOperation::REMOVE:
184 RemoveDecorationStyle(spanItem);
185 }
186 }
187
GetSubSpan(int32_t start,int32_t end)188 RefPtr<SpanBase> DecorationSpan::GetSubSpan(int32_t start, int32_t end)
189 {
190 RefPtr<SpanBase> spanBase = MakeRefPtr<DecorationSpan>(type_, color_, style_, start, end);
191 return spanBase;
192 }
193
AddDecorationStyle(const RefPtr<NG::SpanItem> & spanItem) const194 void DecorationSpan::AddDecorationStyle(const RefPtr<NG::SpanItem>& spanItem) const
195 {
196 spanItem->fontStyle->UpdateTextDecoration(type_);
197 if (color_.has_value()) {
198 spanItem->fontStyle->UpdateTextDecorationColor(color_.value());
199 }
200 if (style_.has_value()) {
201 spanItem->fontStyle->UpdateTextDecorationStyle(style_.value());
202 }
203 }
204
RemoveDecorationStyle(const RefPtr<NG::SpanItem> & spanItem)205 void DecorationSpan::RemoveDecorationStyle(const RefPtr<NG::SpanItem>& spanItem)
206 {
207 spanItem->fontStyle->ResetTextDecoration();
208 spanItem->fontStyle->ResetTextDecorationColor();
209 spanItem->fontStyle->ResetTextDecorationStyle();
210 }
211
GetSpanType() const212 SpanType DecorationSpan::GetSpanType() const
213 {
214 return SpanType::Decoration;
215 }
216
ToString() const217 std::string DecorationSpan::ToString() const
218 {
219 std::stringstream str;
220 str << "DecorationSpan ( start:";
221 str << GetStartIndex();
222 str << " end:";
223 str << GetEndIndex();
224 str << "]";
225 std::string output = str.str();
226 return output;
227 }
228
IsAttributesEqual(const RefPtr<SpanBase> & other) const229 bool DecorationSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
230 {
231 auto decorationSpan = DynamicCast<DecorationSpan>(other);
232 if (!decorationSpan) {
233 return false;
234 }
235 std::optional<Color> color = decorationSpan->GetColor();
236 std::optional<TextDecorationStyle> style = decorationSpan->GetTextDecorationStyle();
237 TextDecoration type = decorationSpan->GetTextDecorationType();
238 return color == color_ && style == style_ && type == type_;
239 }
240
241 // BaselineOffsetSpan
BaselineOffsetSpan(Dimension baselineOffset)242 BaselineOffsetSpan::BaselineOffsetSpan(Dimension baselineOffset) : SpanBase(0, 0), baselineOffset_(baselineOffset) {}
243
BaselineOffsetSpan(Dimension baselineOffset,int32_t start,int32_t end)244 BaselineOffsetSpan::BaselineOffsetSpan(Dimension baselineOffset, int32_t start, int32_t end)
245 : SpanBase(start, end), baselineOffset_(baselineOffset)
246 {}
247
GetBaselineOffset() const248 Dimension BaselineOffsetSpan::GetBaselineOffset() const
249 {
250 return baselineOffset_;
251 }
252
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const253 void BaselineOffsetSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
254 {
255 switch (operation) {
256 case SpanOperation::ADD:
257 AddBaselineOffsetStyle(spanItem);
258 break;
259 case SpanOperation::REMOVE:
260 RemoveBaselineOffsetStyle(spanItem);
261 }
262 }
263
GetSubSpan(int32_t start,int32_t end)264 RefPtr<SpanBase> BaselineOffsetSpan::GetSubSpan(int32_t start, int32_t end)
265 {
266 RefPtr<SpanBase> spanBase = MakeRefPtr<BaselineOffsetSpan>(baselineOffset_, start, end);
267 return spanBase;
268 }
269
AddBaselineOffsetStyle(const RefPtr<NG::SpanItem> & spanItem) const270 void BaselineOffsetSpan::AddBaselineOffsetStyle(const RefPtr<NG::SpanItem>& spanItem) const
271 {
272 spanItem->textLineStyle->UpdateBaselineOffset(baselineOffset_);
273 }
274
RemoveBaselineOffsetStyle(const RefPtr<NG::SpanItem> & spanItem)275 void BaselineOffsetSpan::RemoveBaselineOffsetStyle(const RefPtr<NG::SpanItem>& spanItem)
276 {
277 spanItem->textLineStyle->ResetBaselineOffset();
278 }
279
GetSpanType() const280 SpanType BaselineOffsetSpan::GetSpanType() const
281 {
282 return SpanType::BaselineOffset;
283 }
284
ToString() const285 std::string BaselineOffsetSpan::ToString() const
286 {
287 std::stringstream str;
288 str << "BaselineOffsetSpan ( start:";
289 str << GetStartIndex();
290 str << " end:";
291 str << GetEndIndex();
292 str << "]";
293 std::string output = str.str();
294 return output;
295 }
296
IsAttributesEqual(const RefPtr<SpanBase> & other) const297 bool BaselineOffsetSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
298 {
299 auto baselineOffsetSpan = DynamicCast<BaselineOffsetSpan>(other);
300 if (!baselineOffsetSpan) {
301 return false;
302 }
303 auto baselineOffset = baselineOffsetSpan->GetBaselineOffset();
304 return baselineOffset == baselineOffset_;
305 }
306
307 // LetterSpacingSpan
LetterSpacingSpan(Dimension letterSpacing)308 LetterSpacingSpan::LetterSpacingSpan(Dimension letterSpacing) : SpanBase(0, 0), letterSpacing_(letterSpacing) {}
309
LetterSpacingSpan(Dimension letterSpacing,int32_t start,int32_t end)310 LetterSpacingSpan::LetterSpacingSpan(Dimension letterSpacing, int32_t start, int32_t end)
311 : SpanBase(start, end), letterSpacing_(letterSpacing)
312 {}
313
GetLetterSpacing() const314 Dimension LetterSpacingSpan::GetLetterSpacing() const
315 {
316 return letterSpacing_;
317 }
318
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const319 void LetterSpacingSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
320 {
321 switch (operation) {
322 case SpanOperation::ADD:
323 AddLetterSpacingStyle(spanItem);
324 break;
325 case SpanOperation::REMOVE:
326 RemoveLetterSpacingStyle(spanItem);
327 }
328 }
329
GetSubSpan(int32_t start,int32_t end)330 RefPtr<SpanBase> LetterSpacingSpan::GetSubSpan(int32_t start, int32_t end)
331 {
332 RefPtr<SpanBase> spanBase = MakeRefPtr<LetterSpacingSpan>(letterSpacing_, start, end);
333 return spanBase;
334 }
335
AddLetterSpacingStyle(const RefPtr<NG::SpanItem> & spanItem) const336 void LetterSpacingSpan::AddLetterSpacingStyle(const RefPtr<NG::SpanItem>& spanItem) const
337 {
338 spanItem->fontStyle->UpdateLetterSpacing(letterSpacing_);
339 }
340
RemoveLetterSpacingStyle(const RefPtr<NG::SpanItem> & spanItem)341 void LetterSpacingSpan::RemoveLetterSpacingStyle(const RefPtr<NG::SpanItem>& spanItem)
342 {
343 spanItem->fontStyle->ResetLetterSpacing();
344 }
345
GetSpanType() const346 SpanType LetterSpacingSpan::GetSpanType() const
347 {
348 return SpanType::LetterSpacing;
349 }
350
ToString() const351 std::string LetterSpacingSpan::ToString() const
352 {
353 std::stringstream str;
354 str << "LetterSpacingSpan ( start:";
355 str << GetStartIndex();
356 str << " end:";
357 str << GetEndIndex();
358 str << "]";
359 std::string output = str.str();
360 return output;
361 }
362
IsAttributesEqual(const RefPtr<SpanBase> & other) const363 bool LetterSpacingSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
364 {
365 auto letterSpacingSpan = DynamicCast<LetterSpacingSpan>(other);
366 if (!letterSpacingSpan) {
367 return false;
368 }
369 auto letterSpacing = letterSpacingSpan->GetLetterSpacing();
370 return letterSpacing == letterSpacing_;
371 }
372
373 // GestureSpan
GestureSpan(GestureStyle gestureInfo)374 GestureSpan::GestureSpan(GestureStyle gestureInfo) : SpanBase(0, 0), gestureInfo_(std::move(gestureInfo)) {}
375
GestureSpan(GestureStyle gestureInfo,int32_t start,int32_t end)376 GestureSpan::GestureSpan(GestureStyle gestureInfo, int32_t start, int32_t end)
377 : SpanBase(start, end), gestureInfo_(std::move(gestureInfo))
378 {}
379
GetGestureStyle() const380 GestureStyle GestureSpan::GetGestureStyle() const
381 {
382 return gestureInfo_;
383 }
384
GetSubSpan(int32_t start,int32_t end)385 RefPtr<SpanBase> GestureSpan::GetSubSpan(int32_t start, int32_t end)
386 {
387 RefPtr<SpanBase> spanBase = MakeRefPtr<GestureSpan>(gestureInfo_, start, end);
388 return spanBase;
389 }
390
IsAttributesEqual(const RefPtr<SpanBase> & other) const391 bool GestureSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
392 {
393 auto gestureSpan = DynamicCast<GestureSpan>(other);
394 if (!gestureSpan) {
395 return false;
396 }
397 auto gestureInfo = gestureSpan->GetGestureStyle();
398 return gestureInfo_.IsEqual(gestureInfo);
399 }
400
GetSpanType() const401 SpanType GestureSpan::GetSpanType() const
402 {
403 return SpanType::Gesture;
404 }
405
ToString() const406 std::string GestureSpan::ToString() const
407 {
408 std::stringstream str;
409 str << "GestureSpan [ start:";
410 str << GetStartIndex();
411 str << " end:";
412 str << GetEndIndex();
413 str << "]";
414 std::string output = str.str();
415 return output;
416 }
417
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const418 void GestureSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
419 {
420 switch (operation) {
421 case SpanOperation::ADD:
422 AddSpanStyle(spanItem);
423 break;
424 case SpanOperation::REMOVE:
425 RemoveSpanStyle(spanItem);
426 }
427 }
428
AddSpanStyle(const RefPtr<NG::SpanItem> & spanItem) const429 void GestureSpan::AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const
430 {
431 if (gestureInfo_.onClick.has_value()) {
432 spanItem->onClick = gestureInfo_.onClick.value();
433 } else {
434 spanItem->onClick = nullptr;
435 }
436
437 if (gestureInfo_.onLongPress.has_value()) {
438 spanItem->onLongPress = gestureInfo_.onLongPress.value();
439 } else {
440 spanItem->onLongPress = nullptr;
441 }
442 }
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)443 void GestureSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
444 {
445 spanItem->onClick = nullptr;
446 spanItem->onLongPress = nullptr;
447 }
448
449 // TextShadowSpan
TextShadowSpan(std::vector<Shadow> textShadow)450 TextShadowSpan::TextShadowSpan(std::vector<Shadow> textShadow) : SpanBase(0, 0), textShadow_(std::move(textShadow)) {}
451
TextShadowSpan(std::vector<Shadow> textShadow,int32_t start,int32_t end)452 TextShadowSpan::TextShadowSpan(std::vector<Shadow> textShadow, int32_t start, int32_t end)
453 : SpanBase(start, end), textShadow_(std::move(textShadow))
454 {}
455
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const456 void TextShadowSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
457 {
458 switch (operation) {
459 case SpanOperation::ADD:
460 AddSpanStyle(spanItem);
461 break;
462 case SpanOperation::REMOVE:
463 RemoveSpanStyle(spanItem);
464 }
465 }
466
GetSubSpan(int32_t start,int32_t end)467 RefPtr<SpanBase> TextShadowSpan::GetSubSpan(int32_t start, int32_t end)
468 {
469 RefPtr<SpanBase> spanBase = MakeRefPtr<TextShadowSpan>(GetTextShadow(), start, end);
470 return spanBase;
471 }
472
AddSpanStyle(const RefPtr<NG::SpanItem> & spanItem) const473 void TextShadowSpan::AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const
474 {
475 if (textShadow_.has_value()) {
476 spanItem->fontStyle->UpdateTextShadow(textShadow_.value());
477 }
478 }
479
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)480 void TextShadowSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
481 {
482 spanItem->fontStyle->ResetTextShadow();
483 }
484
GetTextShadow() const485 std::vector<Shadow> TextShadowSpan::GetTextShadow() const
486 {
487 return textShadow_.value_or(std::vector<Shadow>());
488 }
489
GetSpanType() const490 SpanType TextShadowSpan::GetSpanType() const
491 {
492 return SpanType::TextShadow;
493 }
494
ToString() const495 std::string TextShadowSpan::ToString() const
496 {
497 std::stringstream str;
498 str << "TextShadowSpan ( start:";
499 str << GetStartIndex();
500 str << " end:";
501 str << GetEndIndex();
502 str << "]";
503 std::string output = str.str();
504 return output;
505 }
506
IsAttributesEqual(const RefPtr<SpanBase> & other) const507 bool TextShadowSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
508 {
509 auto textShadowSpan = DynamicCast<TextShadowSpan>(other);
510 if (!textShadowSpan) {
511 return false;
512 }
513 auto textShadow = textShadowSpan->GetTextShadow();
514 auto selfTextShadow = GetTextShadow();
515 if (textShadow.size() != selfTextShadow.size()) {
516 return false;
517 }
518 for (size_t i = 0; i < selfTextShadow.size(); ++i) {
519 if (selfTextShadow[i] != textShadow[i]) {
520 return false;
521 }
522 }
523 return true;
524 }
525
526 // ImageSpan
ImageSpan(const ImageSpanOptions & options)527 ImageSpan::ImageSpan(const ImageSpanOptions& options) : SpanBase(0, 1), imageOptions_(options) {}
528
ImageSpan(const ImageSpanOptions & options,int32_t position)529 ImageSpan::ImageSpan(const ImageSpanOptions& options, int32_t position)
530 : SpanBase(position, position + 1), imageOptions_(options)
531 {}
532
IsAttributesEqual(const RefPtr<SpanBase> & other) const533 bool ImageSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
534 {
535 auto imageSpan = DynamicCast<ImageSpan>(other);
536 if (!imageSpan) {
537 return false;
538 }
539 if (imageOptions_.imageAttribute.has_value() && imageSpan->GetImageAttribute().has_value()) {
540 return imageOptions_.imageAttribute.value() == imageSpan->GetImageAttribute().value();
541 }
542 return false;
543 }
544
GetSubSpan(int32_t start,int32_t end)545 RefPtr<SpanBase> ImageSpan::GetSubSpan(int32_t start, int32_t end)
546 {
547 if (end - start > 1) {
548 return nullptr;
549 }
550 auto spanBase = MakeRefPtr<ImageSpan>(imageOptions_);
551 spanBase->UpdateStartIndex(start);
552 spanBase->UpdateEndIndex(end);
553 return spanBase;
554 }
555
GetSpanType() const556 SpanType ImageSpan::GetSpanType() const
557 {
558 return SpanType::Image;
559 }
560
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const561 void ImageSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
562 {
563 auto imageItem = DynamicCast<NG::ImageSpanItem>(spanItem);
564 if (!imageItem) {
565 return;
566 }
567
568 switch (operation) {
569 case SpanOperation::ADD:
570 imageItem->SetImageSpanOptions(imageOptions_);
571 break;
572 case SpanOperation::REMOVE:
573 imageItem->ResetImageSpanOptions();
574 }
575 }
576
ToString() const577 std::string ImageSpan::ToString() const
578 {
579 return "";
580 }
581
GetImageSpanOptions()582 const ImageSpanOptions& ImageSpan::GetImageSpanOptions()
583 {
584 return imageOptions_;
585 }
586
GetImageAttribute() const587 const std::optional<ImageSpanAttribute>& ImageSpan::GetImageAttribute() const
588 {
589 return imageOptions_.imageAttribute;
590 }
591
592 // CustomSpan
CustomSpan()593 CustomSpan::CustomSpan() : SpanBase(0, 1) {}
594
CustomSpan(std::optional<std::function<CustomSpanMetrics (CustomSpanMeasureInfo)>> onMeasure,std::optional<std::function<void (NG::DrawingContext &,CustomSpanOptions)>> onDraw)595 CustomSpan::CustomSpan(std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
596 std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw)
597 : SpanBase(0, 1), onMeasure_(std::move(onMeasure)), onDraw_(std::move(onDraw))
598 {}
599
CustomSpan(std::optional<std::function<CustomSpanMetrics (CustomSpanMeasureInfo)>> onMeasure,std::optional<std::function<void (NG::DrawingContext &,CustomSpanOptions)>> onDraw,int32_t start,int32_t end)600 CustomSpan::CustomSpan(std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
601 std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw, int32_t start, int32_t end)
602 : SpanBase(start, end), onMeasure_(std::move(onMeasure)), onDraw_(std::move(onDraw))
603 {}
604
SetOnMeasure(std::function<CustomSpanMetrics (CustomSpanMeasureInfo)> onMeasure)605 void CustomSpan::SetOnMeasure(std::function<CustomSpanMetrics(CustomSpanMeasureInfo)> onMeasure)
606 {
607 onMeasure_ = onMeasure;
608 }
609
SetOnDraw(std::function<void (NG::DrawingContext &,CustomSpanOptions)> onDraw)610 void CustomSpan::SetOnDraw(std::function<void(NG::DrawingContext&, CustomSpanOptions)> onDraw)
611 {
612 onDraw_ = onDraw;
613 }
614
GetOnMeasure()615 std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> CustomSpan::GetOnMeasure()
616 {
617 return onMeasure_;
618 }
619
GetOnDraw()620 std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> CustomSpan::GetOnDraw()
621 {
622 return onDraw_;
623 }
624
GetSubSpan(int32_t start,int32_t end)625 RefPtr<SpanBase> CustomSpan::GetSubSpan(int32_t start, int32_t end)
626 {
627 if (end - start > 1) {
628 return nullptr;
629 }
630 RefPtr<SpanBase> spanBase = MakeRefPtr<CustomSpan>(onMeasure_, onDraw_, start, end);
631 return spanBase;
632 }
633
GetSpanType() const634 SpanType CustomSpan::GetSpanType() const
635 {
636 return SpanType::CustomSpan;
637 }
638
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const639 void CustomSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
640 {
641 auto imageItem = DynamicCast<NG::CustomSpanItem>(spanItem);
642 if (!imageItem) {
643 return;
644 }
645
646 switch (operation) {
647 case SpanOperation::ADD:
648 imageItem->onMeasure = onMeasure_;
649 imageItem->onDraw = onDraw_;
650 break;
651 case SpanOperation::REMOVE:
652 imageItem->onMeasure = std::nullopt;
653 imageItem->onDraw = std::nullopt;
654 }
655 }
656
ToString() const657 std::string CustomSpan::ToString() const
658 {
659 std::stringstream str;
660 str << "CustomSpan ( start:";
661 str << GetStartIndex();
662 str << " end:";
663 str << GetEndIndex();
664 str << "]";
665 std::string output = str.str();
666 return output;
667 }
668
IsAttributesEqual(const RefPtr<SpanBase> & other) const669 bool CustomSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
670 {
671 return false;
672 }
673
674 // ParagraphStyleSpan
ParagraphStyleSpan(SpanParagraphStyle paragraphStyle)675 ParagraphStyleSpan::ParagraphStyleSpan(SpanParagraphStyle paragraphStyle)
676 : SpanBase(0, 0), paragraphStyle_(std::move(paragraphStyle))
677 {}
678
ParagraphStyleSpan(SpanParagraphStyle paragraphStyle,int32_t start,int32_t end)679 ParagraphStyleSpan::ParagraphStyleSpan(SpanParagraphStyle paragraphStyle, int32_t start, int32_t end)
680 : SpanBase(start, end), paragraphStyle_(std::move(paragraphStyle))
681 {}
682
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const683 void ParagraphStyleSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
684 {
685 switch (operation) {
686 case SpanOperation::ADD:
687 AddParagraphStyle(spanItem);
688 break;
689 case SpanOperation::REMOVE:
690 RemoveParagraphStyle(spanItem);
691 }
692 }
693
AddParagraphStyle(const RefPtr<NG::SpanItem> & spanItem) const694 void ParagraphStyleSpan::AddParagraphStyle(const RefPtr<NG::SpanItem>& spanItem) const
695 {
696 if (paragraphStyle_.align.has_value()) {
697 spanItem->textLineStyle->UpdateTextAlign(paragraphStyle_.align.value());
698 }
699
700 if (paragraphStyle_.maxLines.has_value()) {
701 spanItem->textLineStyle->UpdateMaxLines(static_cast<uint32_t>(paragraphStyle_.maxLines.value()));
702 }
703
704 if (paragraphStyle_.textOverflow.has_value()) {
705 spanItem->textLineStyle->UpdateTextOverflow(paragraphStyle_.textOverflow.value());
706 }
707
708 if (paragraphStyle_.leadingMargin.has_value()) {
709 spanItem->textLineStyle->UpdateLeadingMargin(paragraphStyle_.leadingMargin.value());
710 }
711
712 if (paragraphStyle_.wordBreak.has_value()) {
713 spanItem->textLineStyle->UpdateWordBreak(paragraphStyle_.wordBreak.value());
714 }
715
716 if (paragraphStyle_.textIndent.has_value()) {
717 spanItem->textLineStyle->UpdateTextIndent(paragraphStyle_.textIndent.value());
718 }
719 }
720
RemoveParagraphStyle(const RefPtr<NG::SpanItem> & spanItem) const721 void ParagraphStyleSpan::RemoveParagraphStyle(const RefPtr<NG::SpanItem>& spanItem) const
722 {
723 spanItem->textLineStyle->ResetTextAlign();
724 spanItem->textLineStyle->ResetMaxLines();
725 spanItem->textLineStyle->ResetTextOverflow();
726 spanItem->textLineStyle->ResetLeadingMargin();
727 spanItem->textLineStyle->ResetWordBreak();
728 spanItem->textLineStyle->ResetTextIndent();
729 }
730
IsAttributesEqual(const RefPtr<SpanBase> & other) const731 bool ParagraphStyleSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
732 {
733 auto paragraphSpan = DynamicCast<ParagraphStyleSpan>(other);
734 if (!paragraphSpan) {
735 return false;
736 }
737 auto paragraphStyle = paragraphSpan->GetParagraphStyle();
738 return paragraphStyle_.Equal(paragraphStyle);
739 }
740
GetParagraphStyle() const741 SpanParagraphStyle ParagraphStyleSpan::GetParagraphStyle() const
742 {
743 return paragraphStyle_;
744 }
745
GetSpanType() const746 SpanType ParagraphStyleSpan::GetSpanType() const
747 {
748 return SpanType::ParagraphStyle;
749 }
750
ToString() const751 std::string ParagraphStyleSpan::ToString() const
752 {
753 return "";
754 }
755
GetSubSpan(int32_t start,int32_t end)756 RefPtr<SpanBase> ParagraphStyleSpan::GetSubSpan(int32_t start, int32_t end)
757 {
758 RefPtr<SpanBase> spanBase = MakeRefPtr<ParagraphStyleSpan>(paragraphStyle_, start, end);
759 return spanBase;
760 }
761
762 // LineHeightSpan
LineHeightSpan(Dimension lineHeight)763 LineHeightSpan::LineHeightSpan(Dimension lineHeight) : SpanBase(0, 0), lineHeight_(lineHeight) {}
764
LineHeightSpan(Dimension lineHeight,int32_t start,int32_t end)765 LineHeightSpan::LineHeightSpan(Dimension lineHeight, int32_t start, int32_t end)
766 : SpanBase(start, end), lineHeight_(lineHeight)
767 {}
768
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const769 void LineHeightSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
770 {
771 switch (operation) {
772 case SpanOperation::ADD:
773 AddLineHeightStyle(spanItem);
774 break;
775 case SpanOperation::REMOVE:
776 RemoveLineHeightStyle(spanItem);
777 }
778 }
779
GetSubSpan(int32_t start,int32_t end)780 RefPtr<SpanBase> LineHeightSpan::GetSubSpan(int32_t start, int32_t end)
781 {
782 RefPtr<SpanBase> spanBase = MakeRefPtr<LineHeightSpan>(GetLineHeight(), start, end);
783 return spanBase;
784 }
785
AddLineHeightStyle(const RefPtr<NG::SpanItem> & spanItem) const786 void LineHeightSpan::AddLineHeightStyle(const RefPtr<NG::SpanItem>& spanItem) const
787 {
788 spanItem->textLineStyle->UpdateLineHeight(lineHeight_);
789 }
790
RemoveLineHeightStyle(const RefPtr<NG::SpanItem> & spanItem) const791 void LineHeightSpan::RemoveLineHeightStyle(const RefPtr<NG::SpanItem>& spanItem) const
792 {
793 spanItem->textLineStyle->ResetLineHeight();
794 }
795
GetLineHeight() const796 Dimension LineHeightSpan::GetLineHeight() const
797 {
798 return lineHeight_;
799 }
800
GetSpanType() const801 SpanType LineHeightSpan::GetSpanType() const
802 {
803 return SpanType::LineHeight;
804 }
805
ToString() const806 std::string LineHeightSpan::ToString() const
807 {
808 std::stringstream str;
809 str << "LineHeightSpan ( start:";
810 str << GetStartIndex();
811 str << " end:";
812 str << GetEndIndex();
813 str << "]";
814 std::string output = str.str();
815 return output;
816 }
817
IsAttributesEqual(const RefPtr<SpanBase> & other) const818 bool LineHeightSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
819 {
820 auto lineHeightSpan = DynamicCast<LineHeightSpan>(other);
821 if (!lineHeightSpan) {
822 return false;
823 }
824 auto lineHeight = lineHeightSpan->GetLineHeight();
825 return lineHeight_ == lineHeight;
826 }
827
828 // ExtSpan
ExtSpan(int32_t start,int32_t end)829 ExtSpan::ExtSpan(int32_t start, int32_t end) : SpanBase(start, end) {}
830
GetSubSpan(int32_t start,int32_t end)831 RefPtr<SpanBase> ExtSpan::GetSubSpan(int32_t start, int32_t end)
832 {
833 RefPtr<SpanBase> spanBase = MakeRefPtr<ExtSpan>(start, end);
834 return spanBase;
835 }
836
GetSpanType() const837 SpanType ExtSpan::GetSpanType() const
838 {
839 return SpanType::ExtSpan;
840 }
841
ToString() const842 std::string ExtSpan::ToString() const
843 {
844 std::stringstream str;
845 str << "ExtSpan ( start:";
846 str << GetStartIndex();
847 str << " end:";
848 str << GetEndIndex();
849 str << "]";
850 std::string output = str.str();
851 return output;
852 }
853
IsAttributesEqual(const RefPtr<SpanBase> & other) const854 bool ExtSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
855 {
856 return false;
857 }
858
BackgroundColorSpan(std::optional<TextBackgroundStyle> textBackgroundStyle,int32_t start,int32_t end)859 BackgroundColorSpan::BackgroundColorSpan(
860 std::optional<TextBackgroundStyle> textBackgroundStyle, int32_t start, int32_t end)
861 : SpanBase(start, end), textBackgroundStyle_(std::move(textBackgroundStyle))
862 {}
863
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const864 void BackgroundColorSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
865 {
866 switch (operation) {
867 case SpanOperation::ADD:
868 AddSpanStyle(spanItem);
869 break;
870 case SpanOperation::REMOVE:
871 RemoveSpanStyle(spanItem);
872 break;
873 }
874 }
875
BackgroundColorSpan(std::optional<TextBackgroundStyle> textBackgroundStyle)876 BackgroundColorSpan::BackgroundColorSpan(std::optional<TextBackgroundStyle> textBackgroundStyle)
877 : textBackgroundStyle_(textBackgroundStyle) {}
878
GetSubSpan(int32_t start,int32_t end)879 RefPtr<SpanBase> BackgroundColorSpan::GetSubSpan(int32_t start, int32_t end)
880 {
881 RefPtr<SpanBase> spanBase = MakeRefPtr<BackgroundColorSpan>(GetBackgroundColor(), start, end);
882 return spanBase;
883 }
AddSpanStyle(const RefPtr<NG::SpanItem> & spanItem) const884 void BackgroundColorSpan::AddSpanStyle(const RefPtr<NG::SpanItem>& spanItem) const
885 {
886 if (textBackgroundStyle_.has_value()) {
887 TextBackgroundStyle tempVal = GetBackgroundColor();
888 spanItem->backgroundStyle = tempVal;
889 }
890 }
891
RemoveSpanStyle(const RefPtr<NG::SpanItem> & spanItem)892 void BackgroundColorSpan::RemoveSpanStyle(const RefPtr<NG::SpanItem>& spanItem)
893 {
894 if (spanItem->backgroundStyle.has_value()) {
895 spanItem->backgroundStyle.reset();
896 }
897 }
898
GetBackgroundColor() const899 TextBackgroundStyle BackgroundColorSpan::GetBackgroundColor() const
900 {
901 return textBackgroundStyle_.value();
902 }
903
SetBackgroundColorGroupId(int32_t groupId)904 void BackgroundColorSpan::SetBackgroundColorGroupId(int32_t groupId)
905 {
906 textBackgroundStyle_->groupId = groupId;
907 }
908
GetSpanType() const909 SpanType BackgroundColorSpan::GetSpanType() const
910 {
911 return SpanType::BackgroundColor;
912 }
913
ToString() const914 std::string BackgroundColorSpan::ToString() const
915 {
916 std::stringstream str;
917 str << "BackgroundColorSpan ( start:";
918 str << GetStartIndex();
919 str << " end:";
920 str << GetEndIndex();
921 str << "]";
922 std::string output = str.str();
923 return output;
924 }
925
IsAttributesEqual(const RefPtr<SpanBase> & other) const926 bool BackgroundColorSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
927 {
928 auto backgroundColorSpan = DynamicCast<BackgroundColorSpan>(other);
929 if (!backgroundColorSpan) {
930 return false;
931 }
932 auto backgroundColor = backgroundColorSpan->GetBackgroundColor();
933 return backgroundColor == textBackgroundStyle_;
934 }
935
936 // UrlSpan
UrlSpan(const std::string & urlAddress)937 UrlSpan::UrlSpan(const std::string& urlAddress) : SpanBase(0, 0), urlAddress_(urlAddress) {}
938
UrlSpan(const std::string & urlAddress,int32_t start,int32_t end)939 UrlSpan::UrlSpan(const std::string& urlAddress, int32_t start, int32_t end)
940 : SpanBase(start, end), urlAddress_(urlAddress)
941 {}
942
GetUrlSpanAddress() const943 std::string UrlSpan::GetUrlSpanAddress() const
944 {
945 return urlAddress_;
946 }
947
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const948 void UrlSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
949 {
950 switch (operation) {
951 case SpanOperation::ADD:
952 AddUrlStyle(spanItem);
953 break;
954 case SpanOperation::REMOVE:
955 RemoveUrlStyle(spanItem);
956 break;
957 }
958 }
959
GetSubSpan(int32_t start,int32_t end)960 RefPtr<SpanBase> UrlSpan::GetSubSpan(int32_t start, int32_t end)
961 {
962 RefPtr<SpanBase> spanBase = MakeRefPtr<UrlSpan>(urlAddress_, start, end);
963 return spanBase;
964 }
965
AddUrlStyle(const RefPtr<NG::SpanItem> & spanItem) const966 void UrlSpan::AddUrlStyle(const RefPtr<NG::SpanItem>& spanItem) const
967 {
968 auto address = urlAddress_;
969 auto urlOnRelease = [address]() {
970 auto pipelineContext = PipelineContext::GetCurrentContextSafely();
971 CHECK_NULL_VOID(pipelineContext);
972 pipelineContext->HyperlinkStartAbility(address);
973 };
974 spanItem->SetUrlOnReleaseEvent(std::move(urlOnRelease));
975 }
976
RemoveUrlStyle(const RefPtr<NG::SpanItem> & spanItem)977 void UrlSpan::RemoveUrlStyle(const RefPtr<NG::SpanItem>& spanItem)
978 {
979 spanItem->urlOnRelease = nullptr;
980 }
981
GetSpanType() const982 SpanType UrlSpan::GetSpanType() const
983 {
984 return SpanType::Url;
985 }
986
ToString() const987 std::string UrlSpan::ToString() const
988 {
989 std::stringstream str;
990 str << "UrlSpan ( start:";
991 str << GetStartIndex();
992 str << " end:";
993 str << GetEndIndex();
994 str << "]";
995 std::string output = str.str();
996 return output;
997 }
998
IsAttributesEqual(const RefPtr<SpanBase> & other) const999 bool UrlSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1000 {
1001 auto urlSpan = DynamicCast<UrlSpan>(other);
1002 if (!urlSpan) {
1003 return false;
1004 }
1005 auto urlAddress = urlSpan->GetUrlSpanAddress();
1006 return urlAddress == urlAddress_;
1007 }
1008 } // namespace OHOS::Ace