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#ifndef SPANNABLE_STRING_H 16a3e0fd82Sopenharmony_ci#define SPANNABLE_STRING_H 17a3e0fd82Sopenharmony_ci#include "font/ui_font_header.h" 18a3e0fd82Sopenharmony_ci#include "gfx_utils/color.h" 19a3e0fd82Sopenharmony_ci#include "gfx_utils/list.h" 20a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_types.h" 21a3e0fd82Sopenharmony_cinamespace OHOS { 22a3e0fd82Sopenharmony_cistruct FontSizeSpan : HeapBase { 23a3e0fd82Sopenharmony_ci uint16_t start; 24a3e0fd82Sopenharmony_ci uint16_t end; 25a3e0fd82Sopenharmony_ci uint8_t fontSize; 26a3e0fd82Sopenharmony_ci}; 27a3e0fd82Sopenharmony_ci 28a3e0fd82Sopenharmony_ci/** 29a3e0fd82Sopenharmony_ci * @brief Stores the attribute information about letter height for full text. 30a3e0fd82Sopenharmony_ci */ 31a3e0fd82Sopenharmony_cistruct LetterHeightSpan : HeapBase { 32a3e0fd82Sopenharmony_ci uint16_t start; 33a3e0fd82Sopenharmony_ci uint16_t end; 34a3e0fd82Sopenharmony_ci int16_t height; 35a3e0fd82Sopenharmony_ci}; 36a3e0fd82Sopenharmony_ci 37a3e0fd82Sopenharmony_cistruct FontIdSpan : HeapBase { 38a3e0fd82Sopenharmony_ci uint16_t start; 39a3e0fd82Sopenharmony_ci uint16_t end; 40a3e0fd82Sopenharmony_ci uint16_t fontId; 41a3e0fd82Sopenharmony_ci}; 42a3e0fd82Sopenharmony_ci 43a3e0fd82Sopenharmony_cistruct BackgroundColorSpan : public HeapBase { 44a3e0fd82Sopenharmony_ci int16_t start; 45a3e0fd82Sopenharmony_ci int16_t end; 46a3e0fd82Sopenharmony_ci ColorType backgroundColor; 47a3e0fd82Sopenharmony_ci}; 48a3e0fd82Sopenharmony_ci 49a3e0fd82Sopenharmony_cistruct ForegroundColorSpan : public HeapBase { 50a3e0fd82Sopenharmony_ci int16_t start; 51a3e0fd82Sopenharmony_ci int16_t end; 52a3e0fd82Sopenharmony_ci ColorType fontColor; 53a3e0fd82Sopenharmony_ci}; 54a3e0fd82Sopenharmony_ci 55a3e0fd82Sopenharmony_cistruct LineBackgroundColorSpan : public HeapBase { 56a3e0fd82Sopenharmony_ci int16_t start; 57a3e0fd82Sopenharmony_ci int16_t end; 58a3e0fd82Sopenharmony_ci ColorType linebackgroundColor; 59a3e0fd82Sopenharmony_ci}; 60a3e0fd82Sopenharmony_ci 61a3e0fd82Sopenharmony_ciclass StyleSpan : public HeapBase { 62a3e0fd82Sopenharmony_cipublic: 63a3e0fd82Sopenharmony_ci StyleSpan() {}; 64a3e0fd82Sopenharmony_ci ~StyleSpan() {}; 65a3e0fd82Sopenharmony_ci TextStyle textStyle_; 66a3e0fd82Sopenharmony_ci uint16_t start_; 67a3e0fd82Sopenharmony_ci uint16_t end_; 68a3e0fd82Sopenharmony_ci StyleSpan(TextStyle textStyle, uint16_t start, uint16_t end) 69a3e0fd82Sopenharmony_ci { 70a3e0fd82Sopenharmony_ci textStyle_ = textStyle; 71a3e0fd82Sopenharmony_ci start_ = start; 72a3e0fd82Sopenharmony_ci end_ = end; 73a3e0fd82Sopenharmony_ci }; 74a3e0fd82Sopenharmony_ci}; 75a3e0fd82Sopenharmony_ciclass SpannableString : public HeapBase { 76a3e0fd82Sopenharmony_cipublic: 77a3e0fd82Sopenharmony_ci SpannableString(); 78a3e0fd82Sopenharmony_ci ~SpannableString(); 79a3e0fd82Sopenharmony_ci 80a3e0fd82Sopenharmony_ci bool GetSpannable(uint16_t index); 81a3e0fd82Sopenharmony_ci void SetTextStyle(TextStyle textStyle, uint16_t startIndex, uint16_t endIndex); 82a3e0fd82Sopenharmony_ci bool GetTextStyle(uint16_t index, TextStyle& textStyle); 83a3e0fd82Sopenharmony_ci void SetFontSize(uint8_t inputFontSize, uint16_t startIndex, uint16_t endIndex); 84a3e0fd82Sopenharmony_ci bool GetFontSize(uint16_t index, uint8_t& outputSize); 85a3e0fd82Sopenharmony_ci void SetFontId(uint16_t inputFontId, uint16_t startIndex, uint16_t endIndex); 86a3e0fd82Sopenharmony_ci bool GetFontId(uint16_t index, uint16_t& outputFontId); 87a3e0fd82Sopenharmony_ci bool GetFontHeight(uint16_t index, int16_t& outputHeight, uint16_t& defaultFontId, uint8_t defaultFontSize); 88a3e0fd82Sopenharmony_ci 89a3e0fd82Sopenharmony_ci void SetBackgroundColor(ColorType inputBackgroundColor, uint16_t startIndex, uint16_t endIndex); 90a3e0fd82Sopenharmony_ci bool GetBackgroundColor(uint16_t index, ColorType& outputBackgroundColor); 91a3e0fd82Sopenharmony_ci void SetForegroundColor(ColorType inputForegroundColor, uint16_t startIndex, uint16_t endIndex); 92a3e0fd82Sopenharmony_ci bool GetForegroundColor(uint16_t index, ColorType& outputForegroundColor); 93a3e0fd82Sopenharmony_ci void SetLineBackgroundColor(ColorType inputLineBackgroundColor, uint16_t startIndex, uint16_t endIndex); 94a3e0fd82Sopenharmony_ci bool GetLineBackgroundColor(uint16_t index, ColorType& outputLineBackgroundColor); 95a3e0fd82Sopenharmony_ci 96a3e0fd82Sopenharmony_ci void Reset(); 97a3e0fd82Sopenharmony_ci void SetSpannableString(const SpannableString* input); 98a3e0fd82Sopenharmony_ci 99a3e0fd82Sopenharmony_ciprivate: 100a3e0fd82Sopenharmony_ci uint16_t isSpannableLen_; 101a3e0fd82Sopenharmony_ci 102a3e0fd82Sopenharmony_ci /* Record each letter having full text setting or not. */ 103a3e0fd82Sopenharmony_ci bool* isSpannable_; 104a3e0fd82Sopenharmony_ci List<StyleSpan*> styleList_; 105a3e0fd82Sopenharmony_ci List<FontSizeSpan> sizeList_; 106a3e0fd82Sopenharmony_ci List<FontIdSpan> fontIdList_; 107a3e0fd82Sopenharmony_ci List<LetterHeightSpan> heightList_; 108a3e0fd82Sopenharmony_ci 109a3e0fd82Sopenharmony_ci List<BackgroundColorSpan> backgroundColorList_; 110a3e0fd82Sopenharmony_ci List<ForegroundColorSpan> foregroundColorList_; 111a3e0fd82Sopenharmony_ci List<LineBackgroundColorSpan> lineBackgroundColorList_; 112a3e0fd82Sopenharmony_ci 113a3e0fd82Sopenharmony_ci /* If endIndex larger than isSpannableLen_, the array isSpannable_ will re-malloc endIndex length memory. */ 114a3e0fd82Sopenharmony_ci bool SetSpannable(bool value, uint16_t startIndex, uint16_t endIndex); 115a3e0fd82Sopenharmony_ci void SetFontHeight(int16_t inputHeight, uint16_t startIndex, uint16_t endIndex); 116a3e0fd82Sopenharmony_ci bool ExpandSpannableLen(uint16_t index); 117a3e0fd82Sopenharmony_ci 118a3e0fd82Sopenharmony_ci /* merge same value. */ 119a3e0fd82Sopenharmony_ci template <typename SpanType> 120a3e0fd82Sopenharmony_ci bool EqualInsert(uint16_t& startIndex, 121a3e0fd82Sopenharmony_ci uint16_t& endIndex, 122a3e0fd82Sopenharmony_ci uint16_t tempStart, 123a3e0fd82Sopenharmony_ci uint16_t tempEnd, 124a3e0fd82Sopenharmony_ci ListNode<SpanType>** tempSpan, 125a3e0fd82Sopenharmony_ci List<SpanType>& tempList) 126a3e0fd82Sopenharmony_ci { 127a3e0fd82Sopenharmony_ci if ((startIndex == tempStart) && endIndex == tempEnd) { 128a3e0fd82Sopenharmony_ci return false; 129a3e0fd82Sopenharmony_ci } 130a3e0fd82Sopenharmony_ci bool needAddNode = true; 131a3e0fd82Sopenharmony_ci if (startIndex <= tempStart) { 132a3e0fd82Sopenharmony_ci if (*tempSpan == nullptr) { 133a3e0fd82Sopenharmony_ci return false; 134a3e0fd82Sopenharmony_ci } 135a3e0fd82Sopenharmony_ci if (endIndex < tempStart) { 136a3e0fd82Sopenharmony_ci // not overlap 137a3e0fd82Sopenharmony_ci } else if (endIndex <= tempEnd) { 138a3e0fd82Sopenharmony_ci endIndex = tempEnd; 139a3e0fd82Sopenharmony_ci *tempSpan = tempList.Remove(*tempSpan)->prev_; 140a3e0fd82Sopenharmony_ci } else { 141a3e0fd82Sopenharmony_ci *tempSpan = tempList.Remove(*tempSpan)->prev_; 142a3e0fd82Sopenharmony_ci } 143a3e0fd82Sopenharmony_ci } else { 144a3e0fd82Sopenharmony_ci if (*tempSpan == nullptr) { 145a3e0fd82Sopenharmony_ci return false; 146a3e0fd82Sopenharmony_ci } 147a3e0fd82Sopenharmony_ci if (startIndex > tempEnd) { 148a3e0fd82Sopenharmony_ci // not overlap 149a3e0fd82Sopenharmony_ci } else if (endIndex <= tempEnd) { 150a3e0fd82Sopenharmony_ci needAddNode = false; 151a3e0fd82Sopenharmony_ci } else { 152a3e0fd82Sopenharmony_ci startIndex = tempStart; 153a3e0fd82Sopenharmony_ci *tempSpan = tempList.Remove(*tempSpan)->prev_; 154a3e0fd82Sopenharmony_ci } 155a3e0fd82Sopenharmony_ci } 156a3e0fd82Sopenharmony_ci return needAddNode; 157a3e0fd82Sopenharmony_ci } 158a3e0fd82Sopenharmony_ci 159a3e0fd82Sopenharmony_ci /* merge different value. */ 160a3e0fd82Sopenharmony_ci template <typename SpanType> 161a3e0fd82Sopenharmony_ci bool UnequalInsert(uint16_t& startIndex, 162a3e0fd82Sopenharmony_ci uint16_t& endIndex, 163a3e0fd82Sopenharmony_ci uint16_t tempStart, 164a3e0fd82Sopenharmony_ci uint16_t tempEnd, 165a3e0fd82Sopenharmony_ci ListNode<SpanType>** tempSpan, 166a3e0fd82Sopenharmony_ci List<SpanType>& tempList, 167a3e0fd82Sopenharmony_ci SpanType tempLeft, 168a3e0fd82Sopenharmony_ci SpanType tempRight) 169a3e0fd82Sopenharmony_ci { 170a3e0fd82Sopenharmony_ci bool needAddNode = true; 171a3e0fd82Sopenharmony_ci if (*tempSpan == nullptr) { 172a3e0fd82Sopenharmony_ci return false; 173a3e0fd82Sopenharmony_ci } 174a3e0fd82Sopenharmony_ci if (startIndex > tempEnd) { 175a3e0fd82Sopenharmony_ci // case A, no change 176a3e0fd82Sopenharmony_ci } else if (startIndex > tempStart && endIndex >= tempEnd) { 177a3e0fd82Sopenharmony_ci // case B 178a3e0fd82Sopenharmony_ci (*tempSpan)->data_.end = startIndex; 179a3e0fd82Sopenharmony_ci } else if (startIndex <= tempStart && endIndex >= tempEnd) { 180a3e0fd82Sopenharmony_ci // case C 181a3e0fd82Sopenharmony_ci *tempSpan = tempList.Remove(*tempSpan)->prev_; 182a3e0fd82Sopenharmony_ci } else if (startIndex <= tempStart && endIndex < tempEnd) { 183a3e0fd82Sopenharmony_ci // case D 184a3e0fd82Sopenharmony_ci (*tempSpan)->data_.start = endIndex; 185a3e0fd82Sopenharmony_ci } else if (endIndex < tempStart) { 186a3e0fd82Sopenharmony_ci // case E, no change 187a3e0fd82Sopenharmony_ci } else if (startIndex > tempStart && endIndex < tempEnd) { 188a3e0fd82Sopenharmony_ci // case F 189a3e0fd82Sopenharmony_ci tempList.Insert(*tempSpan, tempLeft); 190a3e0fd82Sopenharmony_ci tempList.Insert(*tempSpan, tempRight); 191a3e0fd82Sopenharmony_ci *tempSpan = tempList.Remove(*tempSpan)->prev_; 192a3e0fd82Sopenharmony_ci } else { 193a3e0fd82Sopenharmony_ci /* it shall not go here */ 194a3e0fd82Sopenharmony_ci } 195a3e0fd82Sopenharmony_ci return needAddNode; 196a3e0fd82Sopenharmony_ci } 197a3e0fd82Sopenharmony_ci}; 198a3e0fd82Sopenharmony_ci} // namespace OHOS 199a3e0fd82Sopenharmony_ci#endif 200