1 /* 2 * Copyright (c) 2023 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 #ifndef ROSEN_MODULES_TEXGINE_SRC_CHAR_GROUPS_H 17 #define ROSEN_MODULES_TEXGINE_SRC_CHAR_GROUPS_H 18 19 #include "typeface.h" 20 21 #include <array> 22 #include <cstdint> 23 #include <memory> 24 #include <ostream> 25 #include <vector> 26 #include <unicode/uchar.h> 27 28 namespace OHOS { 29 namespace Rosen { 30 namespace TextEngine { 31 struct Glyph { 32 uint32_t codepoint; 33 double advanceX; 34 double advanceY; 35 double offsetX; 36 double offsetY; 37 }; 38 39 enum SpacesModel : uint8_t { 40 NORMAL = 0, // no handle of spaces 41 LEFT = 1, // handle the whitespace at the end of the string on the left 42 RIGHT = 2, // handle whitespace at the begin of the string on the right 43 }; 44 45 struct CharGroup { 46 std::vector<uint16_t> chars; 47 std::vector<struct Glyph> glyphs; 48 std::shared_ptr<Typeface> typeface; 49 double visibleWidth = 0; 50 double invisibleWidth = 0; 51 bool isWordEnd = false; 52 GetWidthCharGroup53 double GetWidth() const 54 { 55 return visibleWidth + invisibleWidth; 56 } 57 GetHeightCharGroup58 double GetHeight() const 59 { 60 double maxAdvanceY = 0; 61 for (const auto &glyph : glyphs) { 62 maxAdvanceY = std::max(maxAdvanceY, glyph.advanceY); 63 } 64 return maxAdvanceY; 65 } 66 CheckCodePointCharGroup67 bool CheckCodePoint() const 68 { 69 if (!glyphs.size()) { 70 return false; 71 } 72 for (const auto& glyph : glyphs) { 73 if (!glyph.codepoint) { 74 return false; 75 } 76 } 77 return true; 78 }; 79 IsHardBreakCharGroup80 bool IsHardBreak() 81 { 82 ULineBreak lineBreak = static_cast<ULineBreak>( 83 u_getIntPropertyValue(chars[0], UCHAR_LINE_BREAK)); 84 return (lineBreak == U_LB_LINE_FEED || lineBreak == U_LB_MANDATORY_BREAK); 85 } 86 IsEmojiCharGroup87 bool IsEmoji() const 88 { 89 bool isEmoji = false; 90 for (size_t i = 0; i < chars.size(); i++) { 91 isEmoji = (u_hasBinaryProperty(chars[i], UCHAR_EMOJI) || 92 u_hasBinaryProperty(chars[i], UCHAR_EMOJI_PRESENTATION) || 93 u_hasBinaryProperty(chars[i], UCHAR_EMOJI_MODIFIER) || 94 u_hasBinaryProperty(chars[i], UCHAR_EMOJI_MODIFIER_BASE)); 95 if (isEmoji) { 96 return isEmoji; 97 } 98 } 99 return isEmoji; 100 } 101 HasWhitesSpaceCharGroup102 bool HasWhitesSpace() const 103 { 104 for (const auto &ch : chars) { 105 if (u_isWhitespace(ch)) { 106 return true; 107 } 108 } 109 return false; 110 } 111 JudgeOnlyHardBreakCharGroup112 bool JudgeOnlyHardBreak() const 113 { 114 if (chars.empty()) { 115 return false; 116 } 117 bool onlyHardBreak = true; 118 for (size_t i = 0; i < chars.size(); i++) { 119 ULineBreak lineBreak = static_cast<ULineBreak>( 120 u_getIntPropertyValue(chars[i], UCHAR_LINE_BREAK)); 121 onlyHardBreak = (lineBreak == U_LB_LINE_FEED || lineBreak == U_LB_MANDATORY_BREAK); 122 if (!onlyHardBreak) { 123 break; 124 } 125 } 126 return onlyHardBreak; 127 } 128 HasHardBreakCharGroup129 bool HasHardBreak() const 130 { 131 if (chars.empty()) { 132 return false; 133 } 134 bool isHardBreak = false; 135 for (size_t i = 0; i < chars.size(); i++) { 136 ULineBreak lineBreak = static_cast<ULineBreak>( 137 u_getIntPropertyValue(chars[i], UCHAR_LINE_BREAK)); 138 isHardBreak = (lineBreak == U_LB_LINE_FEED || lineBreak == U_LB_MANDATORY_BREAK); 139 if (isHardBreak) { 140 break; 141 } 142 } 143 return isHardBreak; 144 } 145 }; 146 147 struct IndexRange { 148 int start = 0; 149 int end = 0; 150 151 bool operator==(IndexRange const &range) const 152 { 153 return range.start == start && range.end == end; 154 } 155 }; 156 157 std::ostream &operator<<(std::ostream &os, const struct IndexRange &range); 158 class CharGroups; 159 // 2 is the count of CharGroups in the return value 160 using CharGroupsPair = std::array<CharGroups, 2>; 161 class CharGroups { 162 public: 163 static CharGroups CreateEmpty(); 164 static CharGroups CreateWithInvalidRange(IndexRange range); 165 166 size_t GetNumberOfGlyph() const; 167 size_t GetNumberOfCharGroup() const; 168 const IndexRange &GetRange() const; 169 CharGroup &GetBack() const; 170 size_t GetSize() const; 171 172 bool IsValid() const; 173 bool IsSameCharGroups(const CharGroups &right) const; 174 bool IsIntersect(const CharGroups &right) const; 175 176 CharGroupsPair GetSplit(const int &index) const; 177 CharGroupsPair GetSplitAll(const int &index) const; 178 CharGroups GetSub(const int &start, const int &end) const; 179 CharGroups GetSubAll(const int &start, const int &end) const; 180 CharGroups GetSubFromU16RangeAll(const int &u16start, const int &u16end) const; 181 CharGroups GetIntersect(const CharGroups &right) const; 182 struct CharGroup &Get(const int32_t &index) const; 183 struct CharGroup &GetAll(const int32_t &index) const; 184 185 std::vector<uint16_t> ToUTF16() const; 186 std::vector<uint16_t> ToUTF16All() const; 187 188 std::vector<struct CharGroup>::iterator begin() const; 189 std::vector<struct CharGroup>::iterator end() const; 190 191 CharGroups Clone() const; 192 193 void Merge(const CharGroups &right); 194 void PushBack(const struct CharGroup &cg); 195 void ReverseAll(); 196 bool operator==(CharGroups const &cgs) const 197 { 198 return IsSameCharGroups(cgs) && range_ == cgs.range_; 199 } 200 201 bool CheckCodePoint() const; 202 std::string GetTypefaceName(); 203 double GetAllCharWidth() const; 204 double GetCharWidth(const size_t index) const; 205 std::vector<uint16_t> GetCharsToU16(size_t start, size_t end, const SpacesModel &spacesModel); 206 bool IsSingleWord() const; 207 bool JudgeOnlyHardBreak() const; 208 int FindHardBreakPos() const; 209 std::vector<uint16_t> GetSubCharsToU16(const int start, const int end); 210 private: 211 friend void ReportMemoryUsage(const std::string &member, const CharGroups &that, bool needThis); 212 213 std::shared_ptr<std::vector<struct CharGroup>> pcgs_ = nullptr; 214 struct IndexRange range_ = {0, 0}; 215 }; 216 } // namespace TextEngine 217 } // namespace Rosen 218 } // namespace OHOS 219 220 #endif // ROSEN_MODULES_TEXGINE_SRC_CHAR_GROUPS_H 221