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