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