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 for (uint16_t i = 0; i < isSpannableLen_; i++) {
172 isSpannable_[i] = false;
173 }
174 }
175 bool isSuccess = ExpandSpannableLen(endIndex);
176 if (isSuccess && (isSpannable_ != nullptr)) {
177 for (uint16_t i = startIndex; ((i < endIndex) && (i < isSpannableLen_)); i++) {
178 isSpannable_[i] = value;
179 }
180 isSuccess = true;
181 }
182 return isSuccess;
183 }
184
GetSpannable(uint16_t index)185 bool SpannableString::GetSpannable(uint16_t index)
186 {
187 bool result = false;
188 if ((isSpannable_ != nullptr) && (index < isSpannableLen_)) {
189 result = isSpannable_[index];
190 }
191 return result;
192 }
193
194 /*
195 * this function merge samge value when add node
196 */
SetFontSize(uint8_t inputFontSize, uint16_t startIndex, uint16_t endIndex)197 void SpannableString::SetFontSize(uint8_t inputFontSize, uint16_t startIndex, uint16_t endIndex)
198 {
199 if (sizeList_.IsEmpty()) {
200 FontSizeSpan inputSpan;
201 inputSpan.start = startIndex;
202 inputSpan.end = endIndex;
203 inputSpan.fontSize = inputFontSize;
204 sizeList_.PushFront(inputSpan);
205 SetSpannable(true, startIndex, endIndex);
206 return;
207 } else {
208 ListNode<FontSizeSpan>* tempSpan = sizeList_.Begin();
209 for (; tempSpan != sizeList_.End(); tempSpan = tempSpan->next_) {
210 bool needAddNode = true;
211 uint16_t tempStart = tempSpan->data_.start;
212 uint16_t tempEnd = tempSpan->data_.end;
213 uint8_t tempSize = tempSpan->data_.fontSize;
214 if (inputFontSize == tempSize) {
215 needAddNode = EqualInsert<FontSizeSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan, sizeList_);
216 } else {
217 FontSizeSpan tempLeft;
218 tempLeft.start = tempStart;
219 tempLeft.end = startIndex;
220 tempLeft.fontSize = tempSize;
221 FontSizeSpan tempRight;
222 tempRight.start = endIndex;
223 tempRight.end = tempEnd;
224 tempRight.fontSize = tempSize;
225 needAddNode = UnequalInsert<FontSizeSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan,
226 sizeList_, tempLeft, tempRight);
227 }
228 if (needAddNode) {
229 FontSizeSpan inputSpan;
230 inputSpan.start = startIndex;
231 inputSpan.end = endIndex;
232 inputSpan.fontSize = inputFontSize;
233 sizeList_.PushBack(inputSpan);
234 SetSpannable(true, startIndex, endIndex);
235 }
236 }
237 }
238 }
239
GetFontSize(uint16_t index, uint8_t& outputSize)240 bool SpannableString::GetFontSize(uint16_t index, uint8_t& outputSize)
241 {
242 bool hasFind = false;
243 ListNode<FontSizeSpan>* tempSpan = sizeList_.Begin();
244 for (; tempSpan != sizeList_.End(); tempSpan = tempSpan->next_) {
245 uint16_t tempStart = tempSpan->data_.start;
246 uint16_t tempEnd = tempSpan->data_.end;
247 if ((tempStart <= index) && (index < tempEnd)) {
248 outputSize = tempSpan->data_.fontSize;
249 hasFind = true;
250 break;
251 }
252 }
253 return hasFind;
254 }
255
SetFontId(uint16_t inputFontId, uint16_t startIndex, uint16_t endIndex)256 void SpannableString::SetFontId(uint16_t inputFontId, uint16_t startIndex, uint16_t endIndex)
257 {
258 if (fontIdList_.IsEmpty()) {
259 FontIdSpan inputSpan;
260 inputSpan.start = startIndex;
261 inputSpan.end = endIndex;
262 inputSpan.fontId = inputFontId;
263 fontIdList_.PushFront(inputSpan);
264 SetSpannable(true, startIndex, endIndex);
265 return;
266 }
267 ListNode<FontIdSpan>* tempSpan = fontIdList_.Begin();
268 for (; tempSpan != fontIdList_.End(); tempSpan = tempSpan->next_) {
269 bool needAddNode = true;
270 uint16_t tempStart = tempSpan->data_.start;
271 uint16_t tempEnd = tempSpan->data_.end;
272 uint16_t tempId = tempSpan->data_.fontId;
273 if (inputFontId == tempId) {
274 needAddNode = EqualInsert<FontIdSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan, fontIdList_);
275 } else {
276 FontIdSpan tempLeft;
277 tempLeft.start = tempStart;
278 tempLeft.end = startIndex;
279 tempLeft.fontId = tempId;
280 FontIdSpan tempRight;
281 tempRight.start = endIndex;
282 tempRight.end = tempEnd;
283 tempRight.fontId = tempId;
284 needAddNode = UnequalInsert<FontIdSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan, fontIdList_,
285 tempLeft, tempRight);
286 }
287 if (needAddNode) {
288 FontIdSpan inputSpan;
289 inputSpan.start = startIndex;
290 inputSpan.end = endIndex;
291 inputSpan.fontId = inputFontId;
292 fontIdList_.PushBack(inputSpan);
293 SetSpannable(true, startIndex, endIndex);
294 }
295 }
296 }
297
GetFontId(uint16_t index, uint16_t& outputFontId)298 bool SpannableString::GetFontId(uint16_t index, uint16_t& outputFontId)
299 {
300 bool hasFind = false;
301 ListNode<FontIdSpan>* tempSpan = fontIdList_.Begin();
302 for (; tempSpan != fontIdList_.End(); tempSpan = tempSpan->next_) {
303 uint16_t tempStart = tempSpan->data_.start;
304 uint16_t tempEnd = tempSpan->data_.end;
305 if ((tempStart <= index) && (index < tempEnd)) {
306 outputFontId = tempSpan->data_.fontId;
307 hasFind = true;
308 break;
309 }
310 }
311 return hasFind;
312 }
313
SetFontHeight(int16_t inputHeight, uint16_t startIndex, uint16_t endIndex)314 void SpannableString::SetFontHeight(int16_t inputHeight, uint16_t startIndex, uint16_t endIndex)
315 {
316 if (heightList_.IsEmpty()) {
317 LetterHeightSpan inputSpan;
318 inputSpan.start = startIndex;
319 inputSpan.end = endIndex;
320 inputSpan.height = inputHeight;
321 heightList_.PushFront(inputSpan);
322 SetSpannable(true, startIndex, endIndex);
323 return;
324 }
325 ListNode<LetterHeightSpan>* tempSpan = heightList_.Begin();
326 for (; tempSpan != heightList_.End(); tempSpan = tempSpan->next_) {
327 bool needAddNode = true;
328 uint16_t tempStart = tempSpan->data_.start;
329 uint16_t tempEnd = tempSpan->data_.end;
330 int16_t tempHeight = tempSpan->data_.height;
331 if (inputHeight == tempHeight) {
332 needAddNode =
333 EqualInsert<LetterHeightSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan, heightList_);
334 } else {
335 LetterHeightSpan tempLeft;
336 tempLeft.start = tempStart;
337 tempLeft.end = startIndex;
338 tempLeft.height = tempHeight;
339 LetterHeightSpan tempRight;
340 tempRight.start = endIndex;
341 tempRight.end = tempEnd;
342 tempRight.height = tempHeight;
343 needAddNode = UnequalInsert<LetterHeightSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan,
344 heightList_, tempLeft, tempRight);
345 }
346 if (needAddNode) {
347 LetterHeightSpan inputSpan;
348 inputSpan.start = startIndex;
349 inputSpan.end = endIndex;
350 inputSpan.height = inputHeight;
351 heightList_.PushBack(inputSpan);
352 SetSpannable(true, startIndex, endIndex);
353 }
354 }
355 }
356
GetFontHeight(uint16_t index, int16_t& outputHeight, uint16_t& defaultFontId, uint8_t defaultFontSize)357 bool SpannableString::GetFontHeight(uint16_t index,
358 int16_t& outputHeight,
359 uint16_t& defaultFontId,
360 uint8_t defaultFontSize)
361 {
362 bool hasFind = false;
363 ListNode<LetterHeightSpan>* tempSpan = heightList_.Begin();
364 for (; tempSpan != heightList_.End(); tempSpan = tempSpan->next_) {
365 uint16_t tempStart = tempSpan->data_.start;
366 uint16_t tempEnd = tempSpan->data_.end;
367 if ((tempStart <= index) && (index < tempEnd)) {
368 hasFind = true;
369 outputHeight = tempSpan->data_.height;
370 break;
371 }
372 }
373 if (!hasFind) {
374 GetFontId(index, defaultFontId);
375 GetFontSize(index, defaultFontSize);
376 UIFont* uifont = UIFont::GetInstance();
377 outputHeight = uifont->GetHeight(defaultFontId, defaultFontSize);
378 SetFontHeight(outputHeight, index, index + 1);
379 }
380 return hasFind;
381 }
382
SetBackgroundColor(ColorType inputBackgroundColor, uint16_t startIndex, uint16_t endIndex)383 void SpannableString::SetBackgroundColor(ColorType inputBackgroundColor, uint16_t startIndex, uint16_t endIndex)
384 {
385 if (backgroundColorList_.IsEmpty()) {
386 BackgroundColorSpan inputSpan;
387 inputSpan.start = startIndex;
388 inputSpan.end = endIndex;
389 inputSpan.backgroundColor.full = inputBackgroundColor.full;
390 backgroundColorList_.PushFront(inputSpan);
391 SetSpannable(true, startIndex, endIndex);
392 return;
393 } else {
394 ListNode<BackgroundColorSpan>* tempSpan = backgroundColorList_.Begin();
395 for (; tempSpan != backgroundColorList_.End(); tempSpan = tempSpan->next_) {
396 bool needAddNode = true;
397 uint16_t tempStart = tempSpan->data_.start;
398 uint16_t tempEnd = tempSpan->data_.end;
399 ColorType tempSize;
400 tempSize.full = tempSpan->data_.backgroundColor.full;
401 if (inputBackgroundColor.full == tempSize.full) {
402 needAddNode = EqualInsert<BackgroundColorSpan>(
403 startIndex, endIndex, tempStart, tempEnd, &tempSpan,
404 backgroundColorList_);
405 } else {
406 BackgroundColorSpan tempLeft;
407 tempLeft.start = tempStart;
408 tempLeft.end = startIndex;
409 tempLeft.backgroundColor.full = tempSize.full;
410 BackgroundColorSpan tempRight;
411 tempRight.start = endIndex;
412 tempRight.end = tempEnd;
413 tempRight.backgroundColor.full = tempSize.full;
414 needAddNode = UnequalInsert<BackgroundColorSpan>(
415 startIndex, endIndex, tempStart, tempEnd, &tempSpan,
416 backgroundColorList_, tempLeft, tempRight);
417 }
418 if (needAddNode) {
419 BackgroundColorSpan inputSpan;
420 inputSpan.start = startIndex;
421 inputSpan.end = endIndex;
422 inputSpan.backgroundColor.full = inputBackgroundColor.full;
423 backgroundColorList_.PushBack(inputSpan);
424 SetSpannable(true, startIndex, endIndex);
425 }
426 }
427 }
428 }
429
GetBackgroundColor(uint16_t index, ColorType& outputBackgroundColor)430 bool SpannableString::GetBackgroundColor(uint16_t index, ColorType& outputBackgroundColor)
431 {
432 bool hasFind = false;
433 ListNode<BackgroundColorSpan>* tempSpan = backgroundColorList_.Begin();
434 for (; tempSpan != backgroundColorList_.End(); tempSpan = tempSpan->next_) {
435 uint16_t tempStart = tempSpan->data_.start;
436 uint16_t tempEnd = tempSpan->data_.end;
437 if ((tempStart <= index) && (index < tempEnd)) {
438 outputBackgroundColor.full = tempSpan->data_.backgroundColor.full;
439 hasFind = true;
440 break;
441 }
442 }
443 return hasFind;
444 }
445
SetForegroundColor(ColorType inputForegroundColor, uint16_t startIndex, uint16_t endIndex)446 void SpannableString::SetForegroundColor(ColorType inputForegroundColor, uint16_t startIndex, uint16_t endIndex)
447 {
448 if (foregroundColorList_.IsEmpty()) {
449 ForegroundColorSpan inputSpan;
450 inputSpan.start = startIndex;
451 inputSpan.end = endIndex;
452 inputSpan.fontColor.full = inputForegroundColor.full;
453 foregroundColorList_.PushFront(inputSpan);
454 SetSpannable(true, startIndex, endIndex);
455 return;
456 } else {
457 ListNode<ForegroundColorSpan>* tempSpan = foregroundColorList_.Begin();
458 for (; tempSpan != foregroundColorList_.End(); tempSpan = tempSpan->next_) {
459 bool needAddNode = true;
460 uint16_t tempStart = tempSpan->data_.start;
461 uint16_t tempEnd = tempSpan->data_.end;
462 ColorType tempSize;
463 tempSize.full= tempSpan->data_.fontColor.full;
464 if (inputForegroundColor.full == tempSize.full) {
465 needAddNode = EqualInsert<ForegroundColorSpan>(
466 startIndex, endIndex, tempStart, tempEnd, &tempSpan,
467 foregroundColorList_);
468 } else {
469 ForegroundColorSpan tempLeft;
470 tempLeft.start = tempStart;
471 tempLeft.end = startIndex;
472 tempLeft.fontColor.full = tempSize.full;
473 ForegroundColorSpan tempRight;
474 tempRight.start = endIndex;
475 tempRight.end = tempEnd;
476 tempRight.fontColor.full = tempSize.full;
477 needAddNode = UnequalInsert<ForegroundColorSpan>(startIndex, endIndex, tempStart, tempEnd, &tempSpan,
478 foregroundColorList_, tempLeft, tempRight);
479 }
480 if (needAddNode) {
481 ForegroundColorSpan inputSpan;
482 inputSpan.start = startIndex;
483 inputSpan.end = endIndex;
484 inputSpan.fontColor.full = inputForegroundColor.full;
485 foregroundColorList_.PushBack(inputSpan);
486 SetSpannable(true, startIndex, endIndex);
487 }
488 }
489 }
490 }
491
GetForegroundColor(uint16_t index, ColorType& outputForegroundColor)492 bool SpannableString::GetForegroundColor(uint16_t index, ColorType& outputForegroundColor)
493 {
494 bool hasFind = false;
495 ListNode<ForegroundColorSpan>* tempSpan = foregroundColorList_.Begin();
496 for (; tempSpan != foregroundColorList_.End(); tempSpan = tempSpan->next_) {
497 uint16_t tempStart = tempSpan->data_.start;
498 uint16_t tempEnd = tempSpan->data_.end;
499 if ((tempStart <= index) && (index < tempEnd)) {
500 outputForegroundColor.full = tempSpan->data_.fontColor.full;
501 hasFind = true;
502 break;
503 }
504 }
505 return hasFind;
506 }
507
SetLineBackgroundColor(ColorType inputLineBackgroundColor, uint16_t startIndex, uint16_t endIndex)508 void SpannableString::SetLineBackgroundColor(ColorType inputLineBackgroundColor, uint16_t startIndex, uint16_t endIndex)
509 {
510 if (lineBackgroundColorList_.IsEmpty()) {
511 LineBackgroundColorSpan inputSpan;
512 inputSpan.start = startIndex;
513 inputSpan.end = endIndex;
514 inputSpan.linebackgroundColor.full = inputLineBackgroundColor.full;
515 lineBackgroundColorList_.PushFront(inputSpan);
516 SetSpannable(true, startIndex, endIndex);
517 return;
518 } else {
519 ListNode<LineBackgroundColorSpan>* tempSpan = lineBackgroundColorList_.Begin();
520 for (; tempSpan != lineBackgroundColorList_.End(); tempSpan = tempSpan->next_) {
521 bool needAddNode = true;
522 uint16_t tempStart = tempSpan->data_.start;
523 uint16_t tempEnd = tempSpan->data_.end;
524 ColorType tempSize;
525 tempSize.full = tempSpan->data_.linebackgroundColor.full;
526 if (inputLineBackgroundColor.full == tempSize.full) {
527 needAddNode = EqualInsert<LineBackgroundColorSpan>(
528 startIndex, endIndex, tempStart, tempEnd, &tempSpan,
529 lineBackgroundColorList_);
530 } else {
531 LineBackgroundColorSpan tempLeft;
532 tempLeft.start = tempStart;
533 tempLeft.end = startIndex;
534 tempLeft.linebackgroundColor.full = tempSize.full;
535 LineBackgroundColorSpan tempRight;
536 tempRight.start = endIndex;
537 tempRight.end = tempEnd;
538 tempRight.linebackgroundColor.full = tempSize.full;
539 needAddNode = UnequalInsert<LineBackgroundColorSpan>(
540 startIndex, endIndex, tempStart, tempEnd, &tempSpan,
541 lineBackgroundColorList_, tempLeft, tempRight);
542 }
543 if (needAddNode) {
544 LineBackgroundColorSpan inputSpan;
545 inputSpan.start = startIndex;
546 inputSpan.end = endIndex;
547 inputSpan.linebackgroundColor.full = inputLineBackgroundColor.full;
548 lineBackgroundColorList_.PushBack(inputSpan);
549 SetSpannable(true, startIndex, endIndex);
550 }
551 }
552 }
553 }
554
GetLineBackgroundColor(uint16_t index, ColorType& outputLineBackgroundColor)555 bool SpannableString::GetLineBackgroundColor(uint16_t index, ColorType& outputLineBackgroundColor)
556 {
557 bool hasFind = false;
558 ListNode<LineBackgroundColorSpan>* tempSpan = lineBackgroundColorList_.Begin();
559 for (; tempSpan != lineBackgroundColorList_.End(); tempSpan = tempSpan->next_) {
560 uint16_t tempStart = tempSpan->data_.start;
561 uint16_t tempEnd = tempSpan->data_.end;
562 if ((tempStart <= index) && (index < tempEnd)) {
563 outputLineBackgroundColor.full = tempSpan->data_.linebackgroundColor.full;
564 hasFind = true;
565 break;
566 }
567 }
568 return hasFind;
569 }
570 } // namespace OHOS
571