• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "char_groups.h"
17 
18 #include <algorithm>
19 #include <cassert>
20 
21 #include "texgine_exception.h"
22 
23 namespace OHOS {
24 namespace Rosen {
25 namespace TextEngine {
operator <<(std::ostream & os,const struct IndexRange & range)26 std::ostream &operator<<(std::ostream &os, const struct IndexRange &range)
27 {
28     os << "[" << range.start << ", " << range.end << ")";
29     return os;
30 }
31 
CreateEmpty()32 CharGroups CharGroups::CreateEmpty()
33 {
34     CharGroups cgs;
35     cgs.pcgs_ = std::make_shared<std::vector<struct CharGroup>>();
36     cgs.range_ = {0, 0};
37     return cgs;
38 }
39 
CreateWithInvalidRange(IndexRange range)40 CharGroups CharGroups::CreateWithInvalidRange(IndexRange range)
41 {
42     CharGroups cgs = CreateEmpty();
43     cgs.range_ = range;
44     return cgs;
45 }
46 
GetNumberOfGlyph() const47 size_t CharGroups::GetNumberOfGlyph() const
48 {
49     if (!IsValid()) {
50         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
51     }
52 
53     size_t sum = 0;
54     for (auto i = range_.start; i < range_.end; i++) {
55         sum += pcgs_->at(i).glyphs.size();
56     }
57     return sum;
58 }
59 
GetNumberOfCharGroup() const60 size_t CharGroups::GetNumberOfCharGroup() const
61 {
62     if (!IsValid()) {
63         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
64     }
65 
66     return range_.end - range_.start;
67 }
68 
GetRange() const69 const IndexRange &CharGroups::GetRange() const
70 {
71     return range_;
72 }
73 
GetBack() const74 CharGroup &CharGroups::GetBack() const
75 {
76     if (!IsValid()) {
77         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
78     }
79 
80     if (GetSize() == 0) {
81         throw TEXGINE_EXCEPTION(OUT_OF_RANGE);
82     }
83 
84     return *(pcgs_->begin() + range_.end - 1);
85 }
86 
GetSize() const87 size_t CharGroups::GetSize() const
88 {
89     if (!IsValid()) {
90         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
91     }
92 
93     return pcgs_->size();
94 }
95 
IsValid() const96 bool CharGroups::IsValid() const
97 {
98     if (pcgs_ == nullptr) {
99         return false;
100     }
101 
102     if (range_.start > range_.end || range_.start < 0 ||  range_.end < 0 ||
103         range_.end > static_cast<int>(pcgs_->size()) || range_.start > static_cast<int>(pcgs_->size())) {
104         throw TEXGINE_EXCEPTION(ERROR_STATUS);
105     }
106 
107     return true;
108 }
109 
IsSameCharGroups(const CharGroups & right) const110 bool CharGroups::IsSameCharGroups(const CharGroups &right) const
111 {
112     return pcgs_ == right.pcgs_;
113 }
114 
IsIntersect(const CharGroups & right) const115 bool CharGroups::IsIntersect(const CharGroups &right) const
116 {
117     if (!IsValid()) {
118         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
119     }
120 
121     try {
122         if (!right.IsValid()) {
123             throw TEXGINE_EXCEPTION(INVALID_ARGUMENT);
124         }
125     } catch(const struct TexgineException &err) {
126         throw TEXGINE_EXCEPTION(INVALID_ARGUMENT);
127     }
128 
129     if (pcgs_ != right.pcgs_) {
130         return false;
131     }
132 
133     return range_.start < right.range_.end && right.range_.start < range_.end;
134 }
135 
GetSplit(const int & index) const136 CharGroupsPair CharGroups::GetSplit(const int &index) const
137 {
138     if (index < 0) {
139         throw TEXGINE_EXCEPTION(INVALID_ARGUMENT);
140     }
141 
142     return GetSplitAll(index + range_.start);
143 }
144 
GetSplitAll(const int & index) const145 CharGroupsPair CharGroups::GetSplitAll(const int &index) const
146 {
147     if (!IsValid()) {
148         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
149     }
150 
151     if (index <= range_.start || index >= range_.end) {
152         throw TEXGINE_EXCEPTION(OUT_OF_RANGE);
153     }
154     CharGroupsPair retval;
155     retval[0] = *this;
156     retval[0].range_.end = index;
157     retval[1] = *this;
158     retval[1].range_.start = index;
159     return retval;
160 }
161 
GetSub(const int & start,const int & end) const162 CharGroups CharGroups::GetSub(const int &start, const int &end) const
163 {
164     if (!(0 <= start && start <= end)) {
165         throw TEXGINE_EXCEPTION(INVALID_ARGUMENT);
166     }
167 
168     return GetSubAll(start + range_.start, end + range_.start);
169 }
170 
GetSubAll(const int & start,const int & end) const171 CharGroups CharGroups::GetSubAll(const int &start, const int &end) const
172 {
173     if (!IsValid()) {
174         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
175     }
176 
177     if (!(0 <= start && start <= end && end <= static_cast<int>(GetSize()))) {
178         throw TEXGINE_EXCEPTION(INVALID_ARGUMENT);
179     }
180 
181     CharGroups cgs = *this;
182     cgs.range_ = {start, end};
183     return cgs;
184 }
185 
GetSubFromU16RangeAll(const int & u16start,const int & u16end) const186 CharGroups CharGroups::GetSubFromU16RangeAll(const int &u16start, const int &u16end) const
187 {
188     if (!IsValid()) {
189         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
190     }
191 
192     if (!(0 <= u16start && u16start <= u16end)) {
193         throw TEXGINE_EXCEPTION(INVALID_ARGUMENT);
194     }
195 
196     size_t sum = 0;
197     int startIndex = 0;
198     int endIndex = 1e9;
199     for (int i = -1; i <= static_cast<int>(pcgs_->size()); i++) {
200         if (static_cast<int>(sum) <= u16start) {
201             startIndex = std::max(startIndex, i);
202         }
203 
204         if (0 <= i && i < static_cast<int>(pcgs_->size())) {
205             sum += pcgs_->at(i).chars.size();
206         }
207 
208         if (static_cast<int>(sum) >= u16end) {
209             endIndex = std::min(endIndex, i);
210         }
211     }
212 
213     return GetSubAll(startIndex, endIndex + 1);
214 }
215 
GetIntersect(const CharGroups & right) const216 CharGroups CharGroups::GetIntersect(const CharGroups &right) const
217 {
218     if (!IsValid()) {
219         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
220     }
221 
222     try {
223         if (!right.IsValid()) {
224             throw TEXGINE_EXCEPTION(INVALID_ARGUMENT);
225         }
226     } catch(const TexgineException &err) {
227         throw TEXGINE_EXCEPTION(INVALID_ARGUMENT);
228     }
229 
230     if (!IsIntersect(right)) {
231         throw CustomException("these two cgs is not intersect");
232     }
233 
234     CharGroups retval = *this;
235     retval.range_.start = std::max(range_.start, right.range_.start);
236     retval.range_.end = std::min(range_.end, right.range_.end);
237     return retval;
238 }
239 
Get(const int32_t & index) const240 struct CharGroup &CharGroups::Get(const int32_t &index) const
241 {
242     if (index < 0) {
243         throw TEXGINE_EXCEPTION(INVALID_ARGUMENT);
244     }
245 
246     return GetAll(index + range_.start);
247 }
248 
GetAll(const int32_t & index) const249 struct CharGroup &CharGroups::GetAll(const int32_t &index) const
250 {
251     if (!IsValid()) {
252         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
253     }
254 
255     if (!(0 <= index && index < static_cast<int>(GetSize()))) {
256         throw TEXGINE_EXCEPTION(OUT_OF_RANGE);
257     }
258 
259     return pcgs_->at(index);
260 }
261 
ToUTF16() const262 std::vector<uint16_t> CharGroups::ToUTF16() const
263 {
264     if (!IsValid()) {
265         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
266     }
267 
268     std::vector<uint16_t> u16;
269     for (auto i = range_.start; i < range_.end; i++) {
270         u16.insert(u16.end(), pcgs_->at(i).chars.begin(), pcgs_->at(i).chars.end());
271     }
272 
273     return u16;
274 }
275 
ToUTF16All() const276 std::vector<uint16_t> CharGroups::ToUTF16All() const
277 {
278     if (!IsValid()) {
279         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
280     }
281 
282     std::vector<uint16_t> u16;
283     for (const auto &cg : *pcgs_) {
284         u16.insert(u16.end(), cg.chars.begin(), cg.chars.end());
285     }
286 
287     return u16;
288 }
289 
begin() const290 std::vector<struct CharGroup>::iterator CharGroups::begin() const
291 {
292     if (!IsValid()) {
293         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
294     }
295 
296     return pcgs_->begin() + range_.start;
297 }
298 
end() const299 std::vector<struct CharGroup>::iterator CharGroups::end() const
300 {
301     if (!IsValid()) {
302         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
303     }
304 
305     return pcgs_->begin() + range_.end;
306 }
307 
Clone() const308 CharGroups CharGroups::Clone() const
309 {
310     if (!IsValid()) {
311         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
312     }
313 
314     auto ret = CharGroups::CreateEmpty();
315     *ret.pcgs_ = *pcgs_;
316     ret.range_ = range_;
317     return ret;
318 }
319 
Merge(const CharGroups & right)320 void CharGroups::Merge(const CharGroups &right)
321 {
322     if (!IsValid()) {
323         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
324     }
325 
326     try {
327         if (!right.IsValid()) {
328             throw TEXGINE_EXCEPTION(INVALID_ARGUMENT);
329         }
330     } catch(const struct TexgineException &err) {
331         throw TEXGINE_EXCEPTION(INVALID_ARGUMENT);
332     }
333 
334     if (range_.end != right.range_.start) {
335         throw CustomException("the right start not equal this end");
336     }
337 
338     range_.end += right.range_.end - right.range_.start;
339 }
340 
PushBack(const struct CharGroup & cg)341 void CharGroups::PushBack(const struct CharGroup &cg)
342 {
343     if (!IsValid()) {
344         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
345     }
346 
347     if (!(range_.start == 0 && range_.end == static_cast<int>(pcgs_->size()))) {
348         throw CustomException("incomplete CharGroups cannot revert");
349     }
350 
351     pcgs_->push_back(cg);
352     range_.end++;
353 }
354 
ReverseAll()355 void CharGroups::ReverseAll()
356 {
357     if (!IsValid()) {
358         throw TEXGINE_EXCEPTION(INVALID_CHAR_GROUPS);
359     }
360 
361     if (!(range_.start == 0 && range_.end == static_cast<int>(pcgs_->size()))) {
362         throw CustomException("incomplete CharGroups cannot revert");
363     }
364 
365     std::reverse(pcgs_->begin(), pcgs_->end());
366 }
367 
CheckCodePoint()368 bool CharGroups::CheckCodePoint()
369 {
370     if (!GetSize()) {
371         return false;
372     }
373     for (auto &charGroup : *pcgs_) {
374         if (!charGroup.CheckCodePoint()) {
375             return false;
376         }
377     }
378     return true;
379 };
380 } // namespace TextEngine
381 } // namespace Rosen
382 } // namespace OHOS
383