• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-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 
16 #include "common/typed_text.h"
17 #include "font/ui_font.h"
18 #include "font/ui_font_adaptor.h"
19 #include "gfx_utils/graphic_log.h"
20 #include "gfx_utils/mem_api.h"
21 #include "gfx_utils/transform.h"
22 #if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT
23 #include "font/ui_multi_font_manager.h"
24 #endif
25 
26 namespace OHOS {
27 #ifndef _FONT_TOOL
GetTextSize(const char * text,uint16_t fontId,uint8_t fontSize,int16_t letterSpace,int16_t lineHeight,int16_t maxWidth,int8_t lineSpace,SizeSpan * sizeSpans,bool eliminateTrailingSpaces)28 Point TypedText::GetTextSize(const char* text, uint16_t fontId, uint8_t fontSize, int16_t letterSpace,
29                              int16_t lineHeight, int16_t maxWidth, int8_t lineSpace, SizeSpan* sizeSpans,
30                              bool eliminateTrailingSpaces)
31 {
32     Point size{0, 0};
33 
34     if (text == nullptr) {
35         GRAPHIC_LOGE("TypedText::GetTextSize invalid parameter");
36         return size;
37     }
38 
39     uint32_t lineBegin = 0;
40     uint32_t newLineBegin = 0;
41     uint16_t letterHeight = UIFont::GetInstance()->GetHeight(fontId, fontSize);
42     bool hasLineHeight = (lineHeight != 0);
43     uint16_t curLineHeight;
44     uint16_t letterIndex = 0;
45     int16_t curLetterHeight = 0;
46     while (text[lineBegin] != '\0') {
47         int16_t lineWidth = maxWidth;
48         newLineBegin += UIFontAdaptor::GetNextLineAndWidth(&text[lineBegin], fontId, fontSize, letterSpace, lineWidth,
49                                                            curLetterHeight, letterIndex, sizeSpans, false,
50                                                            0xFFFF, eliminateTrailingSpaces);
51         if (!hasLineHeight) {
52             curLineHeight = curLetterHeight + lineSpace;
53         } else {
54             curLineHeight = lineHeight;
55         }
56 
57         if (newLineBegin == lineBegin) {
58             break;
59         }
60         size.y += curLineHeight;
61         size.x = MATH_MAX(lineWidth, size.x);
62         lineBegin = newLineBegin;
63     }
64 
65     if ((lineBegin != 0) && ((text[lineBegin - 1] == '\n') || (text[lineBegin - 1] == '\r'))) {
66         if (!hasLineHeight) {
67             size.y += letterHeight + lineSpace;
68         } else {
69             size.y += lineHeight;
70         }
71     }
72 
73     if (!hasLineHeight) {
74         if (size.y == 0) {
75             size.y = letterHeight;
76         } else {
77             size.y -= lineSpace;
78         }
79     } else {
80         if (size.y == 0) {
81             size.y = lineHeight;
82         }
83     }
84     return size;
85 }
86 
GetArcTextRect(const char * text,uint16_t fontId,uint8_t fontSize,const Point & arcCenter,int16_t letterSpace,TextOrientation orientation,const ArcTextInfo & arcTextInfo)87 Rect TypedText::GetArcTextRect(const char* text,
88                                uint16_t fontId,
89                                uint8_t fontSize,
90                                const Point& arcCenter,
91                                int16_t letterSpace,
92                                TextOrientation orientation,
93                                const ArcTextInfo& arcTextInfo)
94 {
95     if ((text == nullptr) || (arcTextInfo.lineStart == arcTextInfo.lineEnd) || (arcTextInfo.radius == 0)) {
96         GRAPHIC_LOGE("TypedText::GetArcTextRect invalid parameter\n");
97         return Rect();
98     }
99 
100     uint16_t letterHeight = UIFont::GetInstance()->GetHeight(fontId, fontSize);
101     bool xorFlag = (orientation == TextOrientation::INSIDE) ^ (arcTextInfo.direct == TEXT_DIRECT_LTR);
102     float posX = 0;
103     float posY = 0;
104     uint32_t i = arcTextInfo.lineStart;
105     float angle = arcTextInfo.startAngle;
106     Rect rect;
107     Rect rectLetter;
108     TransformMap transform;
109     while (i < arcTextInfo.lineEnd) {
110         uint32_t tmp = i;
111         uint32_t letter = GetUTF8Next(text, tmp, i);
112         if (letter == 0) {
113             continue;
114         }
115         if ((letter == '\r') || (letter == '\n')) {
116             break;
117         }
118         uint16_t letterWidth = UIFont::GetInstance()->GetWidth(letter, fontId, fontSize, 0);
119         if (tmp == arcTextInfo.lineStart) {
120             angle += xorFlag ? GetAngleForArcLen(static_cast<float>(letterWidth), letterHeight, arcTextInfo.radius,
121                                                  arcTextInfo.direct, orientation)
122                              : 0;
123             GetArcLetterPos(arcCenter, arcTextInfo.radius, angle, posX, posY);
124             rect.SetPosition(MATH_ROUND(posX), MATH_ROUND(posY));
125         }
126         rectLetter.SetPosition(MATH_ROUND(posX), MATH_ROUND(posY));
127         rectLetter.Resize(letterWidth, letterHeight);
128         transform.SetTransMapRect(rectLetter);
129 
130         uint16_t arcLen = letterWidth + letterSpace;
131         if (arcLen == 0) {
132             continue;
133         }
134         float incrementAngle = GetAngleForArcLen(static_cast<float>(arcLen), letterHeight, arcTextInfo.radius,
135                                                  arcTextInfo.direct, orientation);
136         float rotateAngle =
137             (orientation == TextOrientation::INSIDE) ? angle : (angle - SEMICIRCLE_IN_DEGREE);
138         // 2: letterWidth's half
139         float fineTuningAngle = incrementAngle * (static_cast<float>(letterWidth) / (2 * arcLen));
140         rotateAngle += (xorFlag ? -fineTuningAngle : fineTuningAngle);
141 
142         transform.Rotate(MATH_ROUND(rotateAngle), Vector2<float>(0, 0));
143         rect.Join(rect, transform.GetBoxRect());
144 
145         angle += incrementAngle;
146         GetArcLetterPos(arcCenter, arcTextInfo.radius, angle, posX, posY);
147     }
148     return rect;
149 }
150 
GetAngleForArcLen(float len,uint16_t height,uint16_t radius,UITextLanguageDirect direct,TextOrientation orientation)151 float TypedText::GetAngleForArcLen(float len,
152                                    uint16_t height,
153                                    uint16_t radius,
154                                    UITextLanguageDirect direct,
155                                    TextOrientation orientation)
156 {
157     if (radius == 0) {
158         return 0;
159     }
160     float realRadius =
161         static_cast<float>((orientation == TextOrientation::OUTSIDE) ? (radius + height) : radius);
162     float angle = static_cast<float>(len * SEMICIRCLE_IN_DEGREE) / (UI_PI * realRadius);
163     return (direct == TEXT_DIRECT_LTR) ? angle : -angle;
164 }
165 
GetAngleForArcLen(uint16_t letterWidth,int16_t letterSpace,uint16_t radius)166 float TypedText::GetAngleForArcLen(uint16_t letterWidth, int16_t letterSpace, uint16_t radius)
167 {
168     if (radius == 0) {
169         return 0.0f;
170     }
171     const int TWOX_COEFFICIENT = 2;
172     const float FLOATING_POINT_TWO = 2.0f;
173     float sinA = (letterWidth + letterSpace) / (FLOATING_POINT_TWO * radius);
174     float a = asin(sinA);
175     if (a >= -EPSINON && a <= EPSINON) {
176         return 0.0f;
177     }
178 
179     return static_cast<float>(TWOX_COEFFICIENT * a * SEMICIRCLE_IN_DEGREE / UI_PI);
180 }
181 
GetArcLetterPos(const Point & arcCenter,uint16_t radius,float angle,float & posX,float & posY)182 void TypedText::GetArcLetterPos(const Point& arcCenter, uint16_t radius, float angle, float& posX, float& posY)
183 {
184     posX = arcCenter.x + (static_cast<float>(radius) * Sin(angle));
185     posY = arcCenter.y - (static_cast<float>(radius) * Sin(angle + QUARTER_IN_DEGREE));
186 }
187 
GetNextLine(const char * text,uint16_t fontId,uint8_t fontSize,int16_t letterSpace,int16_t maxWidth)188 uint32_t TypedText::GetNextLine(const char* text, uint16_t fontId, uint8_t fontSize, int16_t letterSpace,
189                                 int16_t maxWidth)
190 {
191     uint32_t index = 0;
192     if ((text == nullptr) || (GetWrapPoint(text, index) &&
193         (TypedText::GetTextWidth(text, fontId, fontSize, index, letterSpace) <= maxWidth))) {
194         return index;
195     }
196     uint32_t lastBreakPos = 0;
197     uint32_t tmp = 0;
198     while (true) {
199         int16_t curW = TypedText::GetTextWidth(text, fontId, fontSize, index, letterSpace);
200         if (curW > maxWidth) {
201             index = lastBreakPos;
202             if (lastBreakPos == 0) {
203                 curW = 0;
204                 uint32_t i = 0;
205                 while (text[i] != '\0') {
206                     tmp = i;
207                     uint32_t letter = TypedText::GetUTF8Next(text, tmp, i);
208                     uint16_t letterWidth = UIFont::GetInstance()->GetWidth(letter, fontId, fontSize, 0);
209                     curW += letterWidth;
210                     if (letterWidth > 0) {
211                         curW += letterSpace;
212                     }
213                     if (curW > maxWidth) {
214                         index = lastBreakPos;
215                         return index;
216                     }
217                     lastBreakPos = i;
218                 }
219             }
220             break;
221         }
222         if ((index > 0) && (index < strlen(text)) && ((text[index - 1] == '\r') || (text[index - 1] == '\n'))) {
223             break;
224         }
225         lastBreakPos = index;
226         if (text[index] == '\0') {
227             break;
228         }
229         if (GetWrapPoint(text + index, tmp) &&
230             (TypedText::GetTextWidth(text, fontId, fontSize, index + tmp, letterSpace) <= maxWidth)) {
231             return index + tmp;
232         }
233         index += tmp;
234         if (lastBreakPos == index) {
235             break;
236         }
237     }
238     return index;
239 }
240 
GetWrapPoint(const char * text,uint32_t & breakPoint)241 bool TypedText::GetWrapPoint(const char* text, uint32_t& breakPoint)
242 {
243     breakPoint = 0;
244     uint32_t j = 0;
245     if (text == nullptr) {
246         return true;
247     }
248 
249     while (text[breakPoint] != '\0') {
250         uint32_t letter = GetUTF8Next(text, breakPoint, j);
251         breakPoint = j;
252         if ((letter == ' ') || (letter == '.') || (letter == ',') || (letter == '!') || (letter == '=')
253             || (letter == '?')) {
254             return false;
255         }
256         if (letter == '\n') {
257             return true;
258         }
259         if ((letter == '\r') && (GetUTF8Next(text, breakPoint, j) == '\n')) {
260             breakPoint = j;
261             return true;
262         }
263     }
264     return false;
265 }
266 
GetTextWidth(const char * text,uint16_t fontId,uint8_t fontSize,uint16_t length,int16_t letterSpace,uint16_t beginUTF8Index,uint16_t count)267 int16_t TypedText::GetTextWidth(const char* text,
268                                 uint16_t fontId,
269                                 uint8_t fontSize,
270                                 uint16_t length,
271                                 int16_t letterSpace,
272                                 uint16_t beginUTF8Index,
273                                 uint16_t count)
274 {
275     if ((text == nullptr) || (length == 0) || (length > strlen(text))) {
276         GRAPHIC_LOGE("TypedText::GetTextWidth invalid parameter\n");
277         return 0;
278     }
279 
280     uint32_t byteIndex = GetByteIndexFromUTF8Id(text, beginUTF8Index);
281     uint16_t width = 0;
282 
283     while (byteIndex < length) {
284         uint32_t letter = GetUTF8Next(text, byteIndex, byteIndex);
285         if ((letter == 0) || (letter == '\n') || (letter == '\r')) {
286             continue;
287         }
288         uint16_t charWidth = UIFont::GetInstance()->GetWidth(letter, fontId, fontSize, 0);
289         width += charWidth + letterSpace;
290         count--;
291         if (count == 0) {
292             break;
293         }
294     }
295     if (width > 0) {
296         width -= letterSpace;
297     }
298     return width;
299 }
300 #endif // _FONT_TOOL
301 
GetUTF8OneCharacterSize(const char * str)302 uint8_t TypedText::GetUTF8OneCharacterSize(const char* str)
303 {
304     if (str == nullptr) {
305         return 0;
306     }
307     if ((str[0] & 0x80) == 0) {
308         return 1;
309     } else if ((str[0] & 0xE0) == 0xC0) {
310         return 2; // 2: 2 bytes
311     } else if ((str[0] & 0xF0) == 0xE0) {
312         return 3; // 3: 3 bytes
313     } else if ((str[0] & 0xF8) == 0xF0) {
314         return 4; // 4: 4 bytes
315     }
316     return 0;
317 }
318 
GetUTF8Next(const char * text,uint32_t i,uint32_t & j)319 uint32_t TypedText::GetUTF8Next(const char* text, uint32_t i, uint32_t& j)
320 {
321     uint32_t unicode = 0;
322     if (text == nullptr) {
323         GRAPHIC_LOGE("text invalid parameter");
324         return 0;
325     }
326 
327     j = i;
328     uint8_t lettetSize = GetUTF8OneCharacterSize(text + i);
329     switch (lettetSize) {
330         case 1:
331             unicode = text[j];
332             break;
333         case 2: // 2: letter size
334             unicode = static_cast<uint32_t>(text[j] & 0x1F) << UTF8_TO_UNICODE_SHIFT1;
335             j++;
336             if ((text[j] & 0xC0) != 0x80) {
337                 return 0;
338             }
339             unicode += (text[j] & 0x3F);
340             break;
341         case 3: // 3: letter size
342             unicode = static_cast<uint32_t>(text[j] & 0x0F) << UTF8_TO_UNICODE_SHIFT2;
343             unicode += static_cast<uint32_t>(text[++j] & 0x3F) << UTF8_TO_UNICODE_SHIFT1;
344             unicode += (text[++j] & 0x3F);
345             break;
346         case 4: // 4: letter size
347             unicode = static_cast<uint32_t>(text[j] & 0x07) << UTF8_TO_UNICODE_SHIFT3;
348             unicode += static_cast<uint32_t>(text[++j] & 0x3F) << UTF8_TO_UNICODE_SHIFT2;
349             unicode += static_cast<uint32_t>(text[++j] & 0x3F) << UTF8_TO_UNICODE_SHIFT1;
350             unicode += text[++j] & 0x3F;
351             break;
352         default:
353             break;
354     }
355     j++;
356     return unicode;
357 }
358 
GetByteIndexFromUTF8Id(const char * text,uint32_t utf8Id)359 uint32_t TypedText::GetByteIndexFromUTF8Id(const char* text, uint32_t utf8Id)
360 {
361     if (text == nullptr) {
362         GRAPHIC_LOGE("TypedText::GetByteIndexFromUTF8Id text invalid parameter\n");
363         return 0;
364     }
365     uint32_t byteIndex = 0;
366     for (uint32_t i = 0; i < utf8Id; i++) {
367         byteIndex += GetUTF8OneCharacterSize(&text[byteIndex]);
368     }
369 
370     return byteIndex;
371 }
372 
GetUTF8CharacterSize(const char * text,uint32_t byteIndex)373 uint32_t TypedText::GetUTF8CharacterSize(const char* text, uint32_t byteIndex)
374 {
375     uint32_t i = 0;
376     uint32_t size = 0;
377 
378     if (text == nullptr) {
379         GRAPHIC_LOGE("TypedText::GetUTF8CharacterSize text invalid parameter\n");
380         return 0;
381     }
382     while ((i < byteIndex) && (text[i] != '\0')) {
383         GetUTF8Next(text, i, i);
384         size++;
385     }
386 
387     return size;
388 }
389 
Utf8ToUtf16(const char * utf8Str,uint16_t * utf16Str,uint32_t len)390 void TypedText::Utf8ToUtf16(const char* utf8Str, uint16_t* utf16Str, uint32_t len)
391 {
392     if ((utf8Str == nullptr) || (utf16Str == nullptr)) {
393         GRAPHIC_LOGE("utf8Str or u16Str is null");
394         return;
395     }
396 
397     uint32_t i = 0;
398     uint32_t cnt = 0;
399     while (utf8Str[i] != '\0') {
400         uint32_t unicode = GetUTF8Next(utf8Str, i, i);
401         if (cnt < len) {
402             if (unicode <= MAX_UINT16_LOW_SCOPE) {
403                 utf16Str[cnt] = (unicode & MAX_UINT16_LOW_SCOPE);
404             } else if (unicode <= MAX_UINT16_HIGH_SCOPE) {
405                 if (cnt + 1 < len) {
406                     utf16Str[cnt] = static_cast<uint16_t>(UTF16_LOW_PARAM + (unicode & UTF16_LOW_MASK)); // low
407                     cnt++;
408                     utf16Str[cnt] = static_cast<uint16_t>(UTF16_HIGH_PARAM1 + (unicode >> UTF16_HIGH_SHIFT) -
409                                                           UTF16_HIGH_PARAM2); // high
410                 }
411             } else {
412                 GRAPHIC_LOGE("Invalid unicode");
413                 return;
414             }
415             cnt++;
416         }
417     }
418 }
419 
Utf16ToUtf32Word(const uint16_t * src,uint32_t & des)420 int32_t TypedText::Utf16ToUtf32Word(const uint16_t* src, uint32_t& des)
421 {
422     if (!src) {
423         return -1; // invalid
424     }
425 
426     uint16_t w1 = src[0];
427     uint16_t flag = w1 & UTF16_MASK;
428     if (flag == UTF16_LOW_PARAM) {
429         uint16_t w2 = src[1];
430         flag = w2 & UTF16_MASK;
431         if (flag == UTF16_HIGH_PARAM1) {
432             des = (w1 & UTF16_LOW_MASK) + (((w2 & UTF16_LOW_MASK) + UTF16_HIGH_PARAM2) << UTF16_HIGH_SHIFT);
433             return 2; // 2 : used length
434         }
435         return -1;
436     } else if (flag == UTF16_HIGH_PARAM1) {
437         uint16_t w2 = src[1];
438         flag = w2 & UTF16_MASK;
439         if (flag == UTF16_LOW_PARAM) {
440             des = (w2 & UTF16_LOW_MASK) + (((w1 & UTF16_LOW_MASK) + UTF16_HIGH_PARAM2) << UTF16_HIGH_SHIFT);
441             return 2; // 2 : used length
442         }
443         return -1;
444     } else {
445         des = w1;
446         return 1;
447     }
448 }
449 
Utf16ToUtf32(const uint16_t * utf16Str,uint32_t * utf32Str,uint32_t len)450 uint16_t TypedText::Utf16ToUtf32(const uint16_t* utf16Str, uint32_t* utf32Str, uint32_t len)
451 {
452     if (!utf16Str || (!utf32Str)) {
453         return 0;
454     }
455 
456     uint16_t utf32Len = 0;
457     while (len > 0) {
458         uint32_t tmp;
459         int32_t length = Utf16ToUtf32Word(utf16Str, tmp);
460         if (length == -1) {
461             utf32Str = nullptr;
462             return 0;
463         }
464         len -= length;
465         if (utf32Str) {
466             (*utf32Str) = tmp;
467             ++utf32Str;
468             ++utf32Len;
469         }
470         utf16Str += length;
471     }
472     return utf32Len;
473 }
474 
GetUtf16Cnt(const char * utf8Str,uint32_t maxLength)475 uint32_t TypedText::GetUtf16Cnt(const char* utf8Str, uint32_t maxLength)
476 {
477     if (utf8Str == nullptr) {
478         GRAPHIC_LOGE("text invalid parameter");
479         return 0;
480     }
481     uint32_t len = 0;
482     uint32_t i = 0;
483 
484     while (utf8Str[i] != '\0' && i < maxLength) {
485         uint32_t unicode = GetUTF8Next(utf8Str, i, i);
486         if (unicode <= MAX_UINT16_LOW_SCOPE) {
487             len++;
488         } else if (unicode <= MAX_UINT16_HIGH_SCOPE) {
489             len += 2; // 2: low and high, two uint16_t numbers
490         } else {
491             GRAPHIC_LOGE("Invalid unicode");
492             return 0;
493         }
494     }
495     return len;
496 }
497 
IsEmoji(uint32_t codePoint)498 bool TypedText::IsEmoji(uint32_t codePoint)
499 {
500     // Miscellaneous symbols and symbol fonts
501     return (codePoint >= 0x2600 && codePoint <= 0x27BF) || codePoint == 0x303D || codePoint == 0x2049 ||
502             codePoint == 0x203C || (codePoint >= 0x2000 && codePoint <= 0x200F) ||
503             (codePoint >= 0x2028 && codePoint <= 0x202F) || codePoint == 0x205F ||
504             // Area occupied by punctuation, Alphabetic symbol
505             (codePoint >= 0x2065 && codePoint <= 0x206F) || (codePoint >= 0x2100 && codePoint <= 0x214F) ||
506             // Various technical symbols, Arrow A
507             (codePoint >= 0x2300 && codePoint <= 0x23FF) || (codePoint >= 0x2B00 && codePoint <= 0x2BFF) ||
508             // Arrow B,Chinese symbols
509             (codePoint >= 0x2900 && codePoint <= 0x297F) || (codePoint >= 0x3200 && codePoint <= 0x32FF) ||
510             // High and low substitution reserved area, Private reserved area
511             (codePoint >= 0xD800 && codePoint <= 0xDFFF) || (codePoint >= 0xE000 && codePoint <= 0xF8FF) ||
512             // Mutation selector, Plane above the second plane,char can't be saved, all can be transferred
513             (codePoint >= 0xFE00 && codePoint <= 0xFE0F) || codePoint >= 0x10000;
514 }
515 
IsEmojiModifier(uint32_t codePoint)516 bool TypedText::IsEmojiModifier(uint32_t codePoint)
517 {
518     return (codePoint >= 0x1F3FB && codePoint <= 0x1F3FF);
519 }
520 
521 // Based on Emoji_Modifier_Base from
IsEmojiBase(uint32_t codePoint)522 bool TypedText::IsEmojiBase(uint32_t codePoint)
523 {
524     if (codePoint >= 0x261D && codePoint <= 0x270D) {
525         return (codePoint == 0x261D || codePoint == 0x26F9 || (codePoint >= 0x270A && codePoint <= 0x270D));
526     } else if (codePoint >= 0x1F385 && codePoint <= 0x1F93E) {
527         return (codePoint == 0x1F385 || (codePoint >= 0x1F3C3 && codePoint <= 0x1F3C4) ||
528                 (codePoint >= 0x1F3CA && codePoint <= 0x1F3CB) || (codePoint >= 0x1F442 && codePoint <= 0x1F443) ||
529                 (codePoint >= 0x1F446 && codePoint <= 0x1F450) || (codePoint >= 0x1F466 && codePoint <= 0x1F469) ||
530                 codePoint == 0x1F46E || (codePoint >= 0x1F470 && codePoint <= 0x1F478) || codePoint == 0x1F47C ||
531                 (codePoint >= 0x1F481 && codePoint <= 0x1F483) || (codePoint >= 0x1F485 && codePoint <= 0x1F487) ||
532                 codePoint == 0x1F4AA || codePoint == 0x1F575 || codePoint == 0x1F57A || codePoint == 0x1F590 ||
533                 (codePoint >= 0x1F595 && codePoint <= 0x1F596) || (codePoint >= 0x1F645 && codePoint <= 0x1F647) ||
534                 (codePoint >= 0x1F64B && codePoint <= 0x1F64F) || codePoint == 0x1F6A3 ||
535                 (codePoint >= 0x1F6B4 && codePoint <= 0x1F6B6) || codePoint == 0x1F6C0 ||
536                 (codePoint >= 0x1F918 && codePoint <= 0x1F91E) || codePoint == 0x1F926 || codePoint == 0x1F930 ||
537                 (codePoint >= 0x1F933 && codePoint <= 0x1F939) || (codePoint >= 0x1F93B && codePoint <= 0x1F93E));
538     } else {
539         return false;
540     }
541 }
542 
IsColourWord(uint32_t codePoint,uint16_t fontId,uint8_t fontSize)543 bool TypedText::IsColourWord(uint32_t codePoint, uint16_t fontId, uint8_t fontSize)
544 {
545     bool hasColor = false;
546     UIFont* font = UIFont::GetInstance();
547     uint8_t weight = font->GetFontWeight(fontId);
548     if (weight >= 16) { // 16: rgb565->16 rgba8888->32 font with rgba
549         hasColor = true;
550     } else {
551 #if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT
552         uint16_t* searchLists = nullptr;
553         int8_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists);
554         if ((listSize > 0) && (searchLists != nullptr)) {
555             int8_t currentIndex = 0;
556             do {
557                 weight = font->GetFontWeight(searchLists[currentIndex]);
558                 if (weight >= 16) { // 16: rgb565->16 rgba8888->32 font with rgba
559                     hasColor = true;
560                     break;
561                 }
562                 currentIndex++;
563             } while ((currentIndex < listSize) && (searchLists != nullptr));
564         }
565 #endif
566     }
567     if (!hasColor) {
568         return false;
569     }
570     GlyphNode glyphNode;
571     int8_t ret = font->GetGlyphNode(codePoint, glyphNode, fontId, fontSize);
572     if (ret != RET_VALUE_OK) {
573         GRAPHIC_LOGE("Failed to get glyphNode for color word");
574         return false;
575     }
576 
577     weight = font->GetFontWeight(glyphNode.fontId);
578     return (weight >= 16); // 16: rgb565->16 rgba8888->32 font with rgba
579 }
580 } // namespace OHOS
581