• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "core/components_ng/pattern/text/span/span_object.h"
16 
17 #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 
IsAttributesEqual(const RefPtr<SpanBase> & other) const529 bool ImageSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
530 {
531     auto imageSpan = DynamicCast<ImageSpan>(other);
532     if (!imageSpan) {
533         return false;
534     }
535     if (imageOptions_.imageAttribute.has_value() && imageSpan->GetImageAttribute().has_value()) {
536         return imageOptions_.imageAttribute.value() == imageSpan->GetImageAttribute().value();
537     }
538     return false;
539 }
540 
GetSubSpan(int32_t start,int32_t end)541 RefPtr<SpanBase> ImageSpan::GetSubSpan(int32_t start, int32_t end)
542 {
543     if (end - start > 1) {
544         return nullptr;
545     }
546     auto spanBase = MakeRefPtr<ImageSpan>(imageOptions_);
547     spanBase->UpdateStartIndex(start);
548     spanBase->UpdateEndIndex(end);
549     return spanBase;
550 }
551 
GetSpanType() const552 SpanType ImageSpan::GetSpanType() const
553 {
554     return SpanType::Image;
555 }
556 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const557 void ImageSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
558 {
559     auto imageItem = DynamicCast<NG::ImageSpanItem>(spanItem);
560     if (!imageItem) {
561         return;
562     }
563 
564     switch (operation) {
565         case SpanOperation::ADD:
566             imageItem->SetImageSpanOptions(imageOptions_);
567             break;
568         case SpanOperation::REMOVE:
569             imageItem->ResetImageSpanOptions();
570     }
571 }
572 
ToString() const573 std::string ImageSpan::ToString() const
574 {
575     return "";
576 }
577 
GetImageSpanOptions()578 const ImageSpanOptions& ImageSpan::GetImageSpanOptions()
579 {
580     return imageOptions_;
581 }
582 
GetImageAttribute() const583 const std::optional<ImageSpanAttribute>& ImageSpan::GetImageAttribute() const
584 {
585     return imageOptions_.imageAttribute;
586 }
587 
588 // CustomSpan
CustomSpan()589 CustomSpan::CustomSpan() : SpanBase(0, 1) {}
590 
CustomSpan(std::optional<std::function<CustomSpanMetrics (CustomSpanMeasureInfo)>> onMeasure,std::optional<std::function<void (NG::DrawingContext &,CustomSpanOptions)>> onDraw)591 CustomSpan::CustomSpan(std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
592     std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw)
593     : SpanBase(0, 1), onMeasure_(std::move(onMeasure)), onDraw_(std::move(onDraw))
594 {}
595 
CustomSpan(std::optional<std::function<CustomSpanMetrics (CustomSpanMeasureInfo)>> onMeasure,std::optional<std::function<void (NG::DrawingContext &,CustomSpanOptions)>> onDraw,int32_t start,int32_t end)596 CustomSpan::CustomSpan(std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
597     std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw, int32_t start, int32_t end)
598     : SpanBase(start, end), onMeasure_(std::move(onMeasure)), onDraw_(std::move(onDraw))
599 {}
600 
SetOnMeasure(std::function<CustomSpanMetrics (CustomSpanMeasureInfo)> onMeasure)601 void CustomSpan::SetOnMeasure(std::function<CustomSpanMetrics(CustomSpanMeasureInfo)> onMeasure)
602 {
603     onMeasure_ = onMeasure;
604 }
605 
SetOnDraw(std::function<void (NG::DrawingContext &,CustomSpanOptions)> onDraw)606 void CustomSpan::SetOnDraw(std::function<void(NG::DrawingContext&, CustomSpanOptions)> onDraw)
607 {
608     onDraw_ = onDraw;
609 }
610 
GetOnMeasure()611 std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> CustomSpan::GetOnMeasure()
612 {
613     return onMeasure_;
614 }
615 
GetOnDraw()616 std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> CustomSpan::GetOnDraw()
617 {
618     return onDraw_;
619 }
620 
GetSubSpan(int32_t start,int32_t end)621 RefPtr<SpanBase> CustomSpan::GetSubSpan(int32_t start, int32_t end)
622 {
623     if (end - start > 1) {
624         return nullptr;
625     }
626     RefPtr<SpanBase> spanBase = MakeRefPtr<CustomSpan>(onMeasure_, onDraw_, start, end);
627     return spanBase;
628 }
629 
GetSpanType() const630 SpanType CustomSpan::GetSpanType() const
631 {
632     return SpanType::CustomSpan;
633 }
634 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const635 void CustomSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
636 {
637     auto imageItem = DynamicCast<NG::CustomSpanItem>(spanItem);
638     if (!imageItem) {
639         return;
640     }
641 
642     switch (operation) {
643         case SpanOperation::ADD:
644             imageItem->onMeasure = onMeasure_;
645             imageItem->onDraw = onDraw_;
646             break;
647         case SpanOperation::REMOVE:
648             imageItem->onMeasure = std::nullopt;
649             imageItem->onDraw = std::nullopt;
650     }
651 }
652 
ToString() const653 std::string CustomSpan::ToString() const
654 {
655     std::stringstream str;
656     str << "CustomSpan ( start:";
657     str << GetStartIndex();
658     str << " end:";
659     str << GetEndIndex();
660     str << "]";
661     std::string output = str.str();
662     return output;
663 }
664 
IsAttributesEqual(const RefPtr<SpanBase> & other) const665 bool CustomSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
666 {
667     return false;
668 }
669 
670 // ParagraphStyleSpan
ParagraphStyleSpan(SpanParagraphStyle paragraphStyle)671 ParagraphStyleSpan::ParagraphStyleSpan(SpanParagraphStyle paragraphStyle)
672     : SpanBase(0, 0), paragraphStyle_(std::move(paragraphStyle))
673 {}
674 
ParagraphStyleSpan(SpanParagraphStyle paragraphStyle,int32_t start,int32_t end)675 ParagraphStyleSpan::ParagraphStyleSpan(SpanParagraphStyle paragraphStyle, int32_t start, int32_t end)
676     : SpanBase(start, end), paragraphStyle_(std::move(paragraphStyle))
677 {}
678 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const679 void ParagraphStyleSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
680 {
681     switch (operation) {
682         case SpanOperation::ADD:
683             AddParagraphStyle(spanItem);
684             break;
685         case SpanOperation::REMOVE:
686             RemoveParagraphStyle(spanItem);
687     }
688 }
689 
AddParagraphStyle(const RefPtr<NG::SpanItem> & spanItem) const690 void ParagraphStyleSpan::AddParagraphStyle(const RefPtr<NG::SpanItem>& spanItem) const
691 {
692     if (paragraphStyle_.align.has_value()) {
693         spanItem->textLineStyle->UpdateTextAlign(paragraphStyle_.align.value());
694     }
695 
696     if (paragraphStyle_.maxLines.has_value()) {
697         spanItem->textLineStyle->UpdateMaxLines(static_cast<uint32_t>(paragraphStyle_.maxLines.value()));
698     }
699 
700     if (paragraphStyle_.textOverflow.has_value()) {
701         spanItem->textLineStyle->UpdateTextOverflow(paragraphStyle_.textOverflow.value());
702     }
703 
704     if (paragraphStyle_.leadingMargin.has_value()) {
705         spanItem->textLineStyle->UpdateLeadingMargin(paragraphStyle_.leadingMargin.value());
706     }
707 
708     if (paragraphStyle_.wordBreak.has_value()) {
709         spanItem->textLineStyle->UpdateWordBreak(paragraphStyle_.wordBreak.value());
710     }
711 
712     if (paragraphStyle_.textIndent.has_value()) {
713         spanItem->textLineStyle->UpdateTextIndent(paragraphStyle_.textIndent.value());
714     }
715 }
716 
RemoveParagraphStyle(const RefPtr<NG::SpanItem> & spanItem) const717 void ParagraphStyleSpan::RemoveParagraphStyle(const RefPtr<NG::SpanItem>& spanItem) const
718 {
719     spanItem->textLineStyle->ResetTextAlign();
720     spanItem->textLineStyle->ResetMaxLines();
721     spanItem->textLineStyle->ResetTextOverflow();
722     spanItem->textLineStyle->ResetLeadingMargin();
723     spanItem->textLineStyle->ResetWordBreak();
724     spanItem->textLineStyle->ResetTextIndent();
725 }
726 
IsAttributesEqual(const RefPtr<SpanBase> & other) const727 bool ParagraphStyleSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
728 {
729     auto paragraphSpan = DynamicCast<ParagraphStyleSpan>(other);
730     if (!paragraphSpan) {
731         return false;
732     }
733     auto paragraphStyle = paragraphSpan->GetParagraphStyle();
734     return paragraphStyle_.Equal(paragraphStyle);
735 }
736 
GetParagraphStyle() const737 SpanParagraphStyle ParagraphStyleSpan::GetParagraphStyle() const
738 {
739     return paragraphStyle_;
740 }
741 
GetSpanType() const742 SpanType ParagraphStyleSpan::GetSpanType() const
743 {
744     return SpanType::ParagraphStyle;
745 }
746 
ToString() const747 std::string ParagraphStyleSpan::ToString() const
748 {
749     return "";
750 }
751 
GetSubSpan(int32_t start,int32_t end)752 RefPtr<SpanBase> ParagraphStyleSpan::GetSubSpan(int32_t start, int32_t end)
753 {
754     RefPtr<SpanBase> spanBase = MakeRefPtr<ParagraphStyleSpan>(paragraphStyle_, start, end);
755     return spanBase;
756 }
757 
758 // LineHeightSpan
LineHeightSpan(Dimension lineHeight)759 LineHeightSpan::LineHeightSpan(Dimension lineHeight) : SpanBase(0, 0), lineHeight_(lineHeight) {}
760 
LineHeightSpan(Dimension lineHeight,int32_t start,int32_t end)761 LineHeightSpan::LineHeightSpan(Dimension lineHeight, int32_t start, int32_t end)
762     : SpanBase(start, end), lineHeight_(lineHeight)
763 {}
764 
ApplyToSpanItem(const RefPtr<NG::SpanItem> & spanItem,SpanOperation operation) const765 void LineHeightSpan::ApplyToSpanItem(const RefPtr<NG::SpanItem>& spanItem, SpanOperation operation) const
766 {
767     switch (operation) {
768         case SpanOperation::ADD:
769             AddLineHeightStyle(spanItem);
770             break;
771         case SpanOperation::REMOVE:
772             RemoveLineHeightStyle(spanItem);
773     }
774 }
775 
GetSubSpan(int32_t start,int32_t end)776 RefPtr<SpanBase> LineHeightSpan::GetSubSpan(int32_t start, int32_t end)
777 {
778     RefPtr<SpanBase> spanBase = MakeRefPtr<LineHeightSpan>(GetLineHeight(), start, end);
779     return spanBase;
780 }
781 
AddLineHeightStyle(const RefPtr<NG::SpanItem> & spanItem) const782 void LineHeightSpan::AddLineHeightStyle(const RefPtr<NG::SpanItem>& spanItem) const
783 {
784     spanItem->textLineStyle->UpdateLineHeight(lineHeight_);
785 }
786 
RemoveLineHeightStyle(const RefPtr<NG::SpanItem> & spanItem) const787 void LineHeightSpan::RemoveLineHeightStyle(const RefPtr<NG::SpanItem>& spanItem) const
788 {
789     spanItem->textLineStyle->ResetLineHeight();
790 }
791 
GetLineHeight() const792 Dimension LineHeightSpan::GetLineHeight() const
793 {
794     return lineHeight_;
795 }
796 
GetSpanType() const797 SpanType LineHeightSpan::GetSpanType() const
798 {
799     return SpanType::LineHeight;
800 }
801 
ToString() const802 std::string LineHeightSpan::ToString() const
803 {
804     std::stringstream str;
805     str << "LineHeightSpan ( start:";
806     str << GetStartIndex();
807     str << " end:";
808     str << GetEndIndex();
809     str << "]";
810     std::string output = str.str();
811     return output;
812 }
813 
IsAttributesEqual(const RefPtr<SpanBase> & other) const814 bool LineHeightSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
815 {
816     auto lineHeightSpan = DynamicCast<LineHeightSpan>(other);
817     if (!lineHeightSpan) {
818         return false;
819     }
820     auto lineHeight = lineHeightSpan->GetLineHeight();
821     return lineHeight_ == lineHeight;
822 }
823 
824 // ExtSpan
ExtSpan(int32_t start,int32_t end)825 ExtSpan::ExtSpan(int32_t start, int32_t end) : SpanBase(start, end) {}
826 
GetSubSpan(int32_t start,int32_t end)827 RefPtr<SpanBase> ExtSpan::GetSubSpan(int32_t start, int32_t end)
828 {
829     RefPtr<SpanBase> spanBase = MakeRefPtr<ExtSpan>(start, end);
830     return spanBase;
831 }
832 
GetSpanType() const833 SpanType ExtSpan::GetSpanType() const
834 {
835     return SpanType::ExtSpan;
836 }
837 
ToString() const838 std::string ExtSpan::ToString() const
839 {
840     std::stringstream str;
841     str << "ExtSpan ( start:";
842     str << GetStartIndex();
843     str << " end:";
844     str << GetEndIndex();
845     str << "]";
846     std::string output = str.str();
847     return output;
848 }
849 
IsAttributesEqual(const RefPtr<SpanBase> & other) const850 bool ExtSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
851 {
852     return false;
853 }
854 } // namespace OHOS::Ace