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