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