1 /*
2 * Copyright (c) 2022 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
16 #include "common/spannable_string.h"
17 #include "font/ui_font.h"
18 #include "gfx_utils/graphic_log.h"
19 #include "securec.h"
20 namespace OHOS {
21 namespace {
22 constexpr uint16_t DEFAULT_IS_SPANNABLE_LEN = 10;
23 constexpr uint16_t DEFAULT_EXPAND_EDGE = 1024;
24 constexpr uint16_t DEFAULT_EXPAND_TIMES = 2;
25 constexpr uint16_t DEFAULT_EXPAND_OFFSET = 1;
26 } // namespace
27
SpannableString()28 SpannableString::SpannableString() : isSpannableLen_(0), isSpannable_(nullptr) {}
29
~SpannableString()30 SpannableString::~SpannableString()
31 {
32 Reset();
33 }
34
SetTextStyle(TextStyle inputTextStyle,uint16_t startIndex,uint16_t endIndex)35 void SpannableString::SetTextStyle(TextStyle inputTextStyle, uint16_t startIndex, uint16_t endIndex)
36 {
37 StyleSpan* style = new StyleSpan(inputTextStyle, startIndex, endIndex);
38 styleList_.PushBack(style);
39 SetSpannable(true, startIndex, endIndex);
40 }
GetTextStyle(uint16_t index,TextStyle & textStyle)41 bool SpannableString::GetTextStyle(uint16_t index, TextStyle& textStyle)
42 {
43 bool hasFind = false;
44 ListNode<StyleSpan*>* tempSpan = styleList_.Begin();
45 for (; tempSpan != styleList_.End(); tempSpan = tempSpan->next_) {
46 uint16_t tempStart = tempSpan->data_->start_;
47 uint16_t tempEnd = tempSpan->data_->end_;
48 if ((tempStart <= index) && (index < tempEnd)) {
49 textStyle = tempSpan->data_->textStyle_;
50 hasFind = true;
51 break;
52 }
53 }
54 return hasFind;
55 }
56
Reset()57 void SpannableString::Reset()
58 {
59 if (isSpannable_ != nullptr) {
60 UIFree(isSpannable_);
61 }
62 isSpannable_ = nullptr;
63 isSpannableLen_ = 0;
64 if (styleList_.Size() > 0) {
65 for (auto iter = styleList_.Begin(); iter != styleList_.End(); iter = iter->next_) {
66 delete iter->data_;
67 iter->data_ = nullptr;
68 }
69 styleList_.Clear();
70 }
71 if (sizeList_.Size() > 0) {
72 sizeList_.Clear();
73 }
74 if (fontIdList_.Size() > 0) {
75 fontIdList_.Clear();
76 }
77 if (heightList_.Size() > 0) {
78 heightList_.Clear();
79 }
80 if (backgroundColorList_.Size() > 0) {
81 backgroundColorList_.Clear();
82 }
83 if (foregroundColorList_.Size() > 0) {
84 foregroundColorList_.Clear();
85 }
86 if (lineBackgroundColorList_.Size() > 0) {
87 lineBackgroundColorList_.Clear();
88 }
89 }
90
SetSpannableString(const SpannableString * input)91 void SpannableString::SetSpannableString(const SpannableString* input)
92 {
93 Reset();
94 SetSpannable(true, 0, DEFAULT_IS_SPANNABLE_LEN);
95
96 ListNode<FontSizeSpan>* node = input->sizeList_.Begin();
97 while (node != input->sizeList_.End()) {
98 SetFontSize(node->data_.fontSize, node->data_.start, node->data_.end);
99 node = node->next_;
100 }
101 ListNode<FontIdSpan>* node_id = input->fontIdList_.Begin();
102 while (node_id != input->fontIdList_.End()) {
103 SetFontId(node_id->data_.fontId, node_id->data_.start, node_id->data_.end);
104 node_id = node_id->next_;
105 }
106 ListNode<LetterHeightSpan>* node_height = input->heightList_.Begin();
107 while (node_height != input->heightList_.End()) {
108 SetFontHeight(node_height->data_.height, node_height->data_.start, node_height->data_.end);
109 node_height = node_height->next_;
110 }
111 ListNode<StyleSpan*>* node_span = input->styleList_.Begin();
112 while (node_span != input->styleList_.End()) {
113 SetTextStyle(node_span->data_->textStyle_, node_span->data_->start_, node_span->data_->end_);
114 node_span = node_span->next_;
115 }
116 ListNode<BackgroundColorSpan>* node_backColor = input->backgroundColorList_.Begin();
117 while (node_backColor != input->backgroundColorList_.End()) {
118 SetBackgroundColor(node_backColor->data_.backgroundColor,
119 node_backColor->data_.start,
120 node_backColor->data_.end);
121 node_backColor = node_backColor->next_;
122 }
123 ListNode<ForegroundColorSpan>* node_foreColor = input->foregroundColorList_.Begin();
124 while (node_foreColor != input->foregroundColorList_.End()) {
125 SetForegroundColor(node_foreColor->data_.fontColor, node_foreColor->data_.start, node_foreColor->data_.end);
126 node_foreColor = node_foreColor->next_;
127 }
128 ListNode<LineBackgroundColorSpan>* node_lineBackColor = input->lineBackgroundColorList_.Begin();
129 while (node_lineBackColor != input->lineBackgroundColorList_.End()) {
130 SetLineBackgroundColor(node_lineBackColor->data_.linebackgroundColor,
131 node_lineBackColor->data_.start,
132 node_lineBackColor->data_.end);
133 node_lineBackColor = node_lineBackColor->next_;
134 }
135 }
136
ExpandSpannableLen(uint16_t index)137 bool SpannableString::ExpandSpannableLen(uint16_t index)
138 {
139 if (isSpannableLen_ < index) {
140 uint16_t preLens = isSpannableLen_;
141 while (isSpannableLen_ < index && isSpannableLen_ != 0 && isSpannableLen_ < DEFAULT_EXPAND_EDGE) {
142 isSpannableLen_ = isSpannableLen_ * DEFAULT_EXPAND_TIMES + DEFAULT_EXPAND_OFFSET;
143 }
144 bool* tempIsSpannable_ = static_cast<bool*>(UIMalloc(isSpannableLen_ * sizeof(bool)));
145 if (tempIsSpannable_ == nullptr) {
146 GRAPHIC_LOGE("SpannableString::InitSpannable() isSpannable_ == nullptr");
147 return false;
148 }
149 if (isSpannable_ != nullptr) {
150 if (memcpy_s(tempIsSpannable_, isSpannableLen_, isSpannable_, isSpannableLen_) != EOK) {
151 UIFree(tempIsSpannable_);
152 tempIsSpannable_ = nullptr;
153 return false;
154 }
155 UIFree(isSpannable_);
156 isSpannable_ = nullptr;
157 }
158 for (uint16_t i = preLens; i < isSpannableLen_; i++) {
159 tempIsSpannable_[i] = false;
160 }
161 isSpannable_ = tempIsSpannable_;
162 }
163 return true;
164 }
165
SetSpannable(bool value,uint16_t startIndex,uint16_t endIndex)166 bool SpannableString::SetSpannable(bool value, uint16_t startIndex, uint16_t endIndex)
167 {
168 if (isSpannable_ == nullptr) {
169 isSpannableLen_ = DEFAULT_IS_SPANNABLE_LEN;
170 isSpannable_ = static_cast<bool*>(UIMalloc(isSpannableLen_ * sizeof(bool)));
171 if (isSpannable_ == nullptr) {
172 GRAPHIC_LOGE("SpannableString::SetSpannable() isSpannable_ == nullptr");
173 return false;
174 }
175 for (uint16_t i = 0; i < isSpannableLen_; i++) {
176 isSpannable_[i] = false;
177 }
178 }
179 bool isSuccess = ExpandSpannableLen(endIndex);
180 if (isSuccess && (isSpannable_ != nullptr)) {
181 for (uint16_t i = startIndex; ((i < endIndex) && (i < isSpannableLen_)); i++) {
182 isSpannable_[i] = value;
183 }
184 isSuccess = true;
185 }
186 return isSuccess;
187 }
188
GetSpannable(uint16_t index)189 bool SpannableString::GetSpannable(uint16_t index)
190 {
191 bool result = false;
192 if ((isSpannable_ != nullptr) && (index < isSpannableLen_)) {
193 result = isSpannable_[index];
194 }
195 return result;
196 }
197
198 /*
199 * this function merge samge value when add node
200 */
SetFontSize(uint8_t inputFontSize,uint16_t startIndex,uint16_t endIndex)201 void SpannableString::SetFontSize(uint8_t inputFontSize, uint16_t startIndex, uint16_t endIndex)
202 {
203 if (sizeList_.IsEmpty()) {
204 FontSizeSpan inputSpan;
205 inputSpan.start = startIndex;
206 inputSpan.end = endIndex;
207 inputSpan.fontSize = inputFontSize;
208 sizeList_.PushFront(inputSpan);
209 SetSpannable(true, startIndex, endIndex);
210 return;
211 } else {
212 ListNode<FontSizeSpan>* tempSpan = sizeList_.Begin();
213 for (; tempSpan != sizeList_.End(); tempSpan = tempSpan->next_) {
214 bool needAddNode = true;
215 uint16_t tempStart = tempSpan->data_.start;
216 uint16_t tempEnd = tempSpan->data_.end;
217 uint8_t tempSize = tempSpan->data_.fontSize;
218 if (inputFontSize == tempSize) {
219 needAddNode = EqualInsert<FontSizeSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan, sizeList_);
220 } else {
221 FontSizeSpan tempLeft;
222 tempLeft.start = tempStart;
223 tempLeft.end = startIndex;
224 tempLeft.fontSize = tempSize;
225 FontSizeSpan tempRight;
226 tempRight.start = endIndex;
227 tempRight.end = tempEnd;
228 tempRight.fontSize = tempSize;
229 needAddNode = UnequalInsert<FontSizeSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan,
230 sizeList_, tempLeft, tempRight);
231 }
232 if (needAddNode) {
233 FontSizeSpan inputSpan;
234 inputSpan.start = startIndex;
235 inputSpan.end = endIndex;
236 inputSpan.fontSize = inputFontSize;
237 sizeList_.PushBack(inputSpan);
238 SetSpannable(true, startIndex, endIndex);
239 }
240 }
241 }
242 }
243
GetFontSize(uint16_t index,uint8_t & outputSize)244 bool SpannableString::GetFontSize(uint16_t index, uint8_t& outputSize)
245 {
246 bool hasFind = false;
247 ListNode<FontSizeSpan>* tempSpan = sizeList_.Begin();
248 for (; tempSpan != sizeList_.End(); tempSpan = tempSpan->next_) {
249 uint16_t tempStart = tempSpan->data_.start;
250 uint16_t tempEnd = tempSpan->data_.end;
251 if ((tempStart <= index) && (index < tempEnd)) {
252 outputSize = tempSpan->data_.fontSize;
253 hasFind = true;
254 break;
255 }
256 }
257 return hasFind;
258 }
259
SetFontId(uint16_t inputFontId,uint16_t startIndex,uint16_t endIndex)260 void SpannableString::SetFontId(uint16_t inputFontId, uint16_t startIndex, uint16_t endIndex)
261 {
262 if (fontIdList_.IsEmpty()) {
263 FontIdSpan inputSpan;
264 inputSpan.start = startIndex;
265 inputSpan.end = endIndex;
266 inputSpan.fontId = inputFontId;
267 fontIdList_.PushFront(inputSpan);
268 SetSpannable(true, startIndex, endIndex);
269 return;
270 }
271 ListNode<FontIdSpan>* tempSpan = fontIdList_.Begin();
272 for (; tempSpan != fontIdList_.End(); tempSpan = tempSpan->next_) {
273 bool needAddNode = true;
274 uint16_t tempStart = tempSpan->data_.start;
275 uint16_t tempEnd = tempSpan->data_.end;
276 uint16_t tempId = tempSpan->data_.fontId;
277 if (inputFontId == tempId) {
278 needAddNode = EqualInsert<FontIdSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan, fontIdList_);
279 } else {
280 FontIdSpan tempLeft;
281 tempLeft.start = tempStart;
282 tempLeft.end = startIndex;
283 tempLeft.fontId = tempId;
284 FontIdSpan tempRight;
285 tempRight.start = endIndex;
286 tempRight.end = tempEnd;
287 tempRight.fontId = tempId;
288 needAddNode = UnequalInsert<FontIdSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan, fontIdList_,
289 tempLeft, tempRight);
290 }
291 if (needAddNode) {
292 FontIdSpan inputSpan;
293 inputSpan.start = startIndex;
294 inputSpan.end = endIndex;
295 inputSpan.fontId = inputFontId;
296 fontIdList_.PushBack(inputSpan);
297 SetSpannable(true, startIndex, endIndex);
298 }
299 }
300 }
301
GetFontId(uint16_t index,uint16_t & outputFontId)302 bool SpannableString::GetFontId(uint16_t index, uint16_t& outputFontId)
303 {
304 bool hasFind = false;
305 ListNode<FontIdSpan>* tempSpan = fontIdList_.Begin();
306 for (; tempSpan != fontIdList_.End(); tempSpan = tempSpan->next_) {
307 uint16_t tempStart = tempSpan->data_.start;
308 uint16_t tempEnd = tempSpan->data_.end;
309 if ((tempStart <= index) && (index < tempEnd)) {
310 outputFontId = tempSpan->data_.fontId;
311 hasFind = true;
312 break;
313 }
314 }
315 return hasFind;
316 }
317
SetFontHeight(int16_t inputHeight,uint16_t startIndex,uint16_t endIndex)318 void SpannableString::SetFontHeight(int16_t inputHeight, uint16_t startIndex, uint16_t endIndex)
319 {
320 if (heightList_.IsEmpty()) {
321 LetterHeightSpan inputSpan;
322 inputSpan.start = startIndex;
323 inputSpan.end = endIndex;
324 inputSpan.height = inputHeight;
325 heightList_.PushFront(inputSpan);
326 SetSpannable(true, startIndex, endIndex);
327 return;
328 }
329 ListNode<LetterHeightSpan>* tempSpan = heightList_.Begin();
330 for (; tempSpan != heightList_.End(); tempSpan = tempSpan->next_) {
331 bool needAddNode = true;
332 uint16_t tempStart = tempSpan->data_.start;
333 uint16_t tempEnd = tempSpan->data_.end;
334 int16_t tempHeight = tempSpan->data_.height;
335 if (inputHeight == tempHeight) {
336 needAddNode =
337 EqualInsert<LetterHeightSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan, heightList_);
338 } else {
339 LetterHeightSpan tempLeft;
340 tempLeft.start = tempStart;
341 tempLeft.end = startIndex;
342 tempLeft.height = tempHeight;
343 LetterHeightSpan tempRight;
344 tempRight.start = endIndex;
345 tempRight.end = tempEnd;
346 tempRight.height = tempHeight;
347 needAddNode = UnequalInsert<LetterHeightSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan,
348 heightList_, tempLeft, tempRight);
349 }
350 if (needAddNode) {
351 LetterHeightSpan inputSpan;
352 inputSpan.start = startIndex;
353 inputSpan.end = endIndex;
354 inputSpan.height = inputHeight;
355 heightList_.PushBack(inputSpan);
356 SetSpannable(true, startIndex, endIndex);
357 }
358 }
359 }
360
GetFontHeight(uint16_t index,int16_t & outputHeight,uint16_t & defaultFontId,uint8_t defaultFontSize)361 bool SpannableString::GetFontHeight(uint16_t index,
362 int16_t& outputHeight,
363 uint16_t& defaultFontId,
364 uint8_t defaultFontSize)
365 {
366 bool hasFind = false;
367 ListNode<LetterHeightSpan>* tempSpan = heightList_.Begin();
368 for (; tempSpan != heightList_.End(); tempSpan = tempSpan->next_) {
369 uint16_t tempStart = tempSpan->data_.start;
370 uint16_t tempEnd = tempSpan->data_.end;
371 if ((tempStart <= index) && (index < tempEnd)) {
372 hasFind = true;
373 outputHeight = tempSpan->data_.height;
374 break;
375 }
376 }
377 if (!hasFind) {
378 GetFontId(index, defaultFontId);
379 GetFontSize(index, defaultFontSize);
380 UIFont* uifont = UIFont::GetInstance();
381 outputHeight = uifont->GetHeight(defaultFontId, defaultFontSize);
382 SetFontHeight(outputHeight, index, index + 1);
383 }
384 return hasFind;
385 }
386
SetBackgroundColor(ColorType inputBackgroundColor,uint16_t startIndex,uint16_t endIndex)387 void SpannableString::SetBackgroundColor(ColorType inputBackgroundColor, uint16_t startIndex, uint16_t endIndex)
388 {
389 if (backgroundColorList_.IsEmpty()) {
390 BackgroundColorSpan inputSpan;
391 inputSpan.start = startIndex;
392 inputSpan.end = endIndex;
393 inputSpan.backgroundColor.full = inputBackgroundColor.full;
394 backgroundColorList_.PushFront(inputSpan);
395 SetSpannable(true, startIndex, endIndex);
396 return;
397 } else {
398 ListNode<BackgroundColorSpan>* tempSpan = backgroundColorList_.Begin();
399 for (; tempSpan != backgroundColorList_.End(); tempSpan = tempSpan->next_) {
400 bool needAddNode = true;
401 uint16_t tempStart = tempSpan->data_.start;
402 uint16_t tempEnd = tempSpan->data_.end;
403 ColorType tempSize;
404 tempSize.full = tempSpan->data_.backgroundColor.full;
405 if (inputBackgroundColor.full == tempSize.full) {
406 needAddNode = EqualInsert<BackgroundColorSpan>(
407 startIndex, endIndex, tempStart, tempEnd, &tempSpan,
408 backgroundColorList_);
409 } else {
410 BackgroundColorSpan tempLeft;
411 tempLeft.start = tempStart;
412 tempLeft.end = startIndex;
413 tempLeft.backgroundColor.full = tempSize.full;
414 BackgroundColorSpan tempRight;
415 tempRight.start = endIndex;
416 tempRight.end = tempEnd;
417 tempRight.backgroundColor.full = tempSize.full;
418 needAddNode = UnequalInsert<BackgroundColorSpan>(
419 startIndex, endIndex, tempStart, tempEnd, &tempSpan,
420 backgroundColorList_, tempLeft, tempRight);
421 }
422 if (needAddNode) {
423 BackgroundColorSpan inputSpan;
424 inputSpan.start = startIndex;
425 inputSpan.end = endIndex;
426 inputSpan.backgroundColor.full = inputBackgroundColor.full;
427 backgroundColorList_.PushBack(inputSpan);
428 SetSpannable(true, startIndex, endIndex);
429 }
430 }
431 }
432 }
433
GetBackgroundColor(uint16_t index,ColorType & outputBackgroundColor)434 bool SpannableString::GetBackgroundColor(uint16_t index, ColorType& outputBackgroundColor)
435 {
436 bool hasFind = false;
437 ListNode<BackgroundColorSpan>* tempSpan = backgroundColorList_.Begin();
438 for (; tempSpan != backgroundColorList_.End(); tempSpan = tempSpan->next_) {
439 uint16_t tempStart = tempSpan->data_.start;
440 uint16_t tempEnd = tempSpan->data_.end;
441 if ((tempStart <= index) && (index < tempEnd)) {
442 outputBackgroundColor.full = tempSpan->data_.backgroundColor.full;
443 hasFind = true;
444 break;
445 }
446 }
447 return hasFind;
448 }
449
SetForegroundColor(ColorType inputForegroundColor,uint16_t startIndex,uint16_t endIndex)450 void SpannableString::SetForegroundColor(ColorType inputForegroundColor, uint16_t startIndex, uint16_t endIndex)
451 {
452 if (foregroundColorList_.IsEmpty()) {
453 ForegroundColorSpan inputSpan;
454 inputSpan.start = startIndex;
455 inputSpan.end = endIndex;
456 inputSpan.fontColor.full = inputForegroundColor.full;
457 foregroundColorList_.PushFront(inputSpan);
458 SetSpannable(true, startIndex, endIndex);
459 return;
460 } else {
461 ListNode<ForegroundColorSpan>* tempSpan = foregroundColorList_.Begin();
462 for (; tempSpan != foregroundColorList_.End(); tempSpan = tempSpan->next_) {
463 bool needAddNode = true;
464 uint16_t tempStart = tempSpan->data_.start;
465 uint16_t tempEnd = tempSpan->data_.end;
466 ColorType tempSize;
467 tempSize.full= tempSpan->data_.fontColor.full;
468 if (inputForegroundColor.full == tempSize.full) {
469 needAddNode = EqualInsert<ForegroundColorSpan>(
470 startIndex, endIndex, tempStart, tempEnd, &tempSpan,
471 foregroundColorList_);
472 } else {
473 ForegroundColorSpan tempLeft;
474 tempLeft.start = tempStart;
475 tempLeft.end = startIndex;
476 tempLeft.fontColor.full = tempSize.full;
477 ForegroundColorSpan tempRight;
478 tempRight.start = endIndex;
479 tempRight.end = tempEnd;
480 tempRight.fontColor.full = tempSize.full;
481 needAddNode = UnequalInsert<ForegroundColorSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan,
482 foregroundColorList_, tempLeft, tempRight);
483 }
484 if (needAddNode) {
485 ForegroundColorSpan inputSpan;
486 inputSpan.start = startIndex;
487 inputSpan.end = endIndex;
488 inputSpan.fontColor.full = inputForegroundColor.full;
489 foregroundColorList_.PushBack(inputSpan);
490 SetSpannable(true, startIndex, endIndex);
491 }
492 }
493 }
494 }
495
GetForegroundColor(uint16_t index,ColorType & outputForegroundColor)496 bool SpannableString::GetForegroundColor(uint16_t index, ColorType& outputForegroundColor)
497 {
498 bool hasFind = false;
499 ListNode<ForegroundColorSpan>* tempSpan = foregroundColorList_.Begin();
500 for (; tempSpan != foregroundColorList_.End(); tempSpan = tempSpan->next_) {
501 uint16_t tempStart = tempSpan->data_.start;
502 uint16_t tempEnd = tempSpan->data_.end;
503 if ((tempStart <= index) && (index < tempEnd)) {
504 outputForegroundColor.full = tempSpan->data_.fontColor.full;
505 hasFind = true;
506 break;
507 }
508 }
509 return hasFind;
510 }
511
SetLineBackgroundColor(ColorType inputLineBackgroundColor,uint16_t startIndex,uint16_t endIndex)512 void SpannableString::SetLineBackgroundColor(ColorType inputLineBackgroundColor, uint16_t startIndex, uint16_t endIndex)
513 {
514 if (lineBackgroundColorList_.IsEmpty()) {
515 LineBackgroundColorSpan inputSpan;
516 inputSpan.start = startIndex;
517 inputSpan.end = endIndex;
518 inputSpan.linebackgroundColor.full = inputLineBackgroundColor.full;
519 lineBackgroundColorList_.PushFront(inputSpan);
520 SetSpannable(true, startIndex, endIndex);
521 return;
522 } else {
523 ListNode<LineBackgroundColorSpan>* tempSpan = lineBackgroundColorList_.Begin();
524 for (; tempSpan != lineBackgroundColorList_.End(); tempSpan = tempSpan->next_) {
525 bool needAddNode = true;
526 uint16_t tempStart = tempSpan->data_.start;
527 uint16_t tempEnd = tempSpan->data_.end;
528 ColorType tempSize;
529 tempSize.full = tempSpan->data_.linebackgroundColor.full;
530 if (inputLineBackgroundColor.full == tempSize.full) {
531 needAddNode = EqualInsert<LineBackgroundColorSpan>(
532 startIndex, endIndex, tempStart, tempEnd, &tempSpan,
533 lineBackgroundColorList_);
534 } else {
535 LineBackgroundColorSpan tempLeft;
536 tempLeft.start = tempStart;
537 tempLeft.end = startIndex;
538 tempLeft.linebackgroundColor.full = tempSize.full;
539 LineBackgroundColorSpan tempRight;
540 tempRight.start = endIndex;
541 tempRight.end = tempEnd;
542 tempRight.linebackgroundColor.full = tempSize.full;
543 needAddNode = UnequalInsert<LineBackgroundColorSpan>(
544 startIndex, endIndex, tempStart, tempEnd, &tempSpan,
545 lineBackgroundColorList_, tempLeft, tempRight);
546 }
547 if (needAddNode) {
548 LineBackgroundColorSpan inputSpan;
549 inputSpan.start = startIndex;
550 inputSpan.end = endIndex;
551 inputSpan.linebackgroundColor.full = inputLineBackgroundColor.full;
552 lineBackgroundColorList_.PushBack(inputSpan);
553 SetSpannable(true, startIndex, endIndex);
554 }
555 }
556 }
557 }
558
GetLineBackgroundColor(uint16_t index,ColorType & outputLineBackgroundColor)559 bool SpannableString::GetLineBackgroundColor(uint16_t index, ColorType& outputLineBackgroundColor)
560 {
561 bool hasFind = false;
562 ListNode<LineBackgroundColorSpan>* tempSpan = lineBackgroundColorList_.Begin();
563 for (; tempSpan != lineBackgroundColorList_.End(); tempSpan = tempSpan->next_) {
564 uint16_t tempStart = tempSpan->data_.start;
565 uint16_t tempEnd = tempSpan->data_.end;
566 if ((tempStart <= index) && (index < tempEnd)) {
567 outputLineBackgroundColor.full = tempSpan->data_.linebackgroundColor.full;
568 hasFind = true;
569 break;
570 }
571 }
572 return hasFind;
573 }
574 } // namespace OHOS
575