• 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/text.h"
17 #include "common/typed_text.h"
18 #include "draw/draw_label.h"
19 #include "font/ui_font.h"
20 #include "font/ui_font_adaptor.h"
21 #include "font/ui_font_builder.h"
22 #include "gfx_utils/graphic_log.h"
23 #include "securec.h"
24 
25 namespace OHOS {
26 Text::TextLine Text::textLine_[MAX_LINE_COUNT] = {{0}};
27 
Text()28 Text::Text()
29     : text_(nullptr),
30       fontId_(0),
31       fontSize_(0),
32       textSize_({0, 0}),
33       needRefresh_(false),
34       expandWidth_(false),
35       expandHeight_(false),
36       baseLine_(true),
37       direct_(TEXT_DIRECT_LTR),
38       sizeSpans_(nullptr),
39       characterSize_(0),
40       horizontalAlign_(TEXT_ALIGNMENT_LEFT),
41       verticalAlign_(TEXT_ALIGNMENT_TOP)
42 {
43 #if defined(ENABLE_SPANNABLE_STRING) && ENABLE_SPANNABLE_STRING
44     textStyles_ = nullptr;
45 #endif
46     SetFont(DEFAULT_VECTOR_FONT_FILENAME, DEFAULT_VECTOR_FONT_SIZE);
47 }
48 
~Text()49 Text::~Text()
50 {
51     if (text_ != nullptr) {
52         UIFree(text_);
53         text_ = nullptr;
54     }
55 #if defined(ENABLE_SPANNABLE_STRING) && ENABLE_SPANNABLE_STRING
56     if (textStyles_ != nullptr) {
57         UIFree(textStyles_);
58         textStyles_ = nullptr;
59     }
60 #endif
61     if (backgroundColor_.Size() > 0) {
62         backgroundColor_.Clear();
63     }
64     if (linebackgroundColor_.Size() > 0) {
65         linebackgroundColor_.Clear();
66     }
67     if (foregroundColor_.Size() > 0) {
68         foregroundColor_.Clear();
69     }
70     if (sizeSpans_ != nullptr) {
71         UIFree(sizeSpans_);
72         sizeSpans_ = nullptr;
73     }
74 }
75 
76 #if defined(ENABLE_SPANNABLE_STRING) && ENABLE_SPANNABLE_STRING
SetSpannableString(const SpannableString * spannableString)77 void Text::SetSpannableString(const SpannableString* spannableString)
78 {
79     SetText(spannableString->text_);
80     if (textStyles_ != nullptr) {
81         UIFree(textStyles_);
82         textStyles_ = nullptr;
83     }
84     if (spannableString->spanList_.IsEmpty()) {
85         return;
86     }
87     uint32_t textLen = TypedText::GetUTF8CharacterSize(text_, GetTextStrLen());
88     if (textLen == 0 || textLen > MAX_TEXT_LENGTH) {
89         return;
90     }
91     textStyles_ = static_cast<TextStyle*>(UIMalloc(textLen));
92     if (textStyles_ == nullptr) {
93         GRAPHIC_LOGE("Text::SetSpannableString invalid parameter");
94         return;
95     }
96     ListNode<StyleSpan*>* node = spannableString->spanList_.Begin();
97     while (node != spannableString->spanList_.End()) {
98         for (uint32_t i = node->data_->start_; i < node->data_->end_; i++) {
99             if (textLen > i) {
100                 textStyles_[i] = node->data_->textStyle_;
101             }
102         }
103         node = node->next_;
104     }
105     needRefresh_ = true;
106 }
107 #endif
SetText(const char * text)108 void Text::SetText(const char* text)
109 {
110     if (text == nullptr) {
111         return;
112     }
113     uint32_t textLen = static_cast<uint32_t>(strlen(text));
114     if (textLen > MAX_TEXT_LENGTH) {
115         textLen = MAX_TEXT_LENGTH;
116     }
117     if (text_ != nullptr) {
118         if (strcmp(text, text_) == 0) {
119             return;
120         }
121         UIFree(text_);
122         text_ = nullptr;
123     }
124     text_ = static_cast<char*>(UIMalloc(textLen + 1));
125     if (text_ == nullptr) {
126         return;
127     }
128     if (strncpy_s(text_, textLen + 1, text, textLen) != EOK) {
129         UIFree(text_);
130         text_ = nullptr;
131         return;
132     }
133 #if defined(ENABLE_SPANNABLE_STRING) && ENABLE_SPANNABLE_STRING
134     if (textStyles_ != nullptr) {
135         UIFree(textStyles_);
136         textStyles_ = nullptr;
137     }
138 #endif
139     needRefresh_ = true;
140     if (sizeSpans_ != nullptr) {
141         UIFree(sizeSpans_);
142         sizeSpans_ = nullptr;
143     }
144 }
145 
SetFont(const char * name,uint8_t size)146 void Text::SetFont(const char* name, uint8_t size)
147 {
148     if (name == nullptr) {
149         return;
150     }
151     if (UIFont::GetInstance()->IsVectorFont()) {
152         uint16_t fontId = UIFont::GetInstance()->GetFontId(name);
153         if ((fontId != UIFontBuilder::GetInstance()->GetTotalFontId()) &&
154             ((fontId_ != fontId) || (fontSize_ != size))) {
155             fontId_ = fontId;
156             fontSize_ = size;
157             needRefresh_ = true;
158         }
159     } else {
160         uint16_t fontId = UIFont::GetInstance()->GetFontId(name, size);
161         SetFontId(fontId);
162     }
163 }
164 
SetFont(const char * name,uint8_t size,char * & destName,uint8_t & destSize)165 void Text::SetFont(const char* name, uint8_t size, char*& destName, uint8_t& destSize)
166 {
167     if (name == nullptr) {
168         return;
169     }
170     uint32_t nameLen = static_cast<uint32_t>(strlen(name));
171     if (nameLen > MAX_TEXT_LENGTH) {
172         return;
173     }
174     if (destName != nullptr) {
175         if (strcmp(destName, name) == 0) {
176             destSize = size;
177             return;
178         }
179         UIFree(destName);
180         destName = nullptr;
181     }
182     if (nameLen != 0) {
183         /* one more to store '\0' */
184         destName = static_cast<char*>(UIMalloc(++nameLen));
185         if (destName == nullptr) {
186             return;
187         }
188         if (memcpy_s(destName, nameLen, name, nameLen) != EOK) {
189             UIFree(destName);
190             destName = nullptr;
191             return;
192         }
193         destSize = size;
194     }
195 }
196 
SetFontId(uint16_t fontId)197 void Text::SetFontId(uint16_t fontId)
198 {
199     if (fontId >= UIFontBuilder::GetInstance()->GetTotalFontId()) {
200         GRAPHIC_LOGE("Text::SetFontId invalid fontId(%hhd)", fontId);
201         return;
202     }
203 
204     if ((fontId_ == fontId) && (fontSize_ != 0) && !UIFont::GetInstance()->IsVectorFont()) {
205         GRAPHIC_LOGD("Text::SetFontId same font has already set");
206         return;
207     }
208 
209     UITextLanguageFontParam* fontParam = UIFontBuilder::GetInstance()->GetTextLangFontsTable(fontId);
210     if (fontParam == nullptr) {
211         return;
212     }
213     if (UIFont::GetInstance()->IsVectorFont()) {
214         uint16_t fontId = UIFont::GetInstance()->GetFontId(fontParam->ttfName);
215         if ((fontId != UIFontBuilder::GetInstance()->GetTotalFontId()) && ((fontId_ != fontId) ||
216             (fontSize_ != fontParam->size))) {
217             fontId_ = fontId;
218             fontSize_ = fontParam->size;
219             needRefresh_ = true;
220         }
221     } else {
222         fontId_ = fontId;
223         fontSize_ = fontParam->size;
224         needRefresh_ = true;
225     }
226 }
227 
ReMeasureTextSize(const Rect & textRect,const Style & style)228 void Text::ReMeasureTextSize(const Rect& textRect, const Style& style)
229 {
230     if (fontSize_ == 0) {
231         return;
232     }
233     int16_t maxWidth = (expandWidth_ ? COORD_MAX : textRect.GetWidth());
234     if (maxWidth > 0) {
235         textSize_ = TypedText::GetTextSize(text_, fontId_, fontSize_, style.letterSpace_, style.lineHeight_, maxWidth,
236                                            style.lineSpace_, sizeSpans_);
237         if (baseLine_) {
238             FontHeader head;
239             if (UIFont::GetInstance()->GetFontHeader(head, fontId_, fontSize_) != 0) {
240                 return;
241             }
242             textSize_.y += fontSize_ - head.ascender;
243         }
244     }
245 }
246 
ReMeasureTextWidthInEllipsisMode(const Rect & textRect,const Style & style,uint16_t ellipsisIndex)247 void Text::ReMeasureTextWidthInEllipsisMode(const Rect& textRect, const Style& style, uint16_t ellipsisIndex)
248 {
249     if (ellipsisIndex != TEXT_ELLIPSIS_END_INV) {
250         int16_t lineMaxWidth  = expandWidth_ ? textSize_.x : textRect.GetWidth();
251         uint32_t maxLineBytes = 0;
252         uint16_t lineCount = GetLine(lineMaxWidth, style.letterSpace_, ellipsisIndex, maxLineBytes);
253         if ((lineCount > 0) && (textSize_.x < textLine_[lineCount - 1].linePixelWidth)) {
254             textSize_.x = textLine_[lineCount - 1].linePixelWidth;
255         }
256     }
257 }
258 
DrawEllipsis(BufferInfo & gfxDstBuffer,LabelLineInfo & labelLine,uint16_t & letterIndex)259 void Text::DrawEllipsis(BufferInfo& gfxDstBuffer, LabelLineInfo& labelLine, uint16_t& letterIndex)
260 {
261     labelLine.offset.x = 0;
262     labelLine.text = TEXT_ELLIPSIS;
263     labelLine.lineLength = 1;
264     labelLine.length = 1;
265     DrawLabel::DrawTextOneLine(gfxDstBuffer, labelLine, letterIndex);
266 }
267 
OnDraw(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea,const Rect & viewOrigRect,const Rect & textRect,int16_t offsetX,const Style & style,uint16_t ellipsisIndex,OpacityType opaScale)268 void Text::OnDraw(BufferInfo& gfxDstBuffer,
269                   const Rect& invalidatedArea,
270                   const Rect& viewOrigRect,
271                   const Rect& textRect,
272                   int16_t offsetX,
273                   const Style& style,
274                   uint16_t ellipsisIndex,
275                   OpacityType opaScale)
276 {
277     if ((text_ == nullptr) || (strlen(text_) == 0) || (fontSize_ == 0)) {
278         return;
279     }
280     Rect mask = invalidatedArea;
281 
282     if (mask.Intersect(mask, textRect)) {
283         Draw(gfxDstBuffer, mask, textRect, style, offsetX, ellipsisIndex, opaScale);
284     }
285 }
286 
Draw(BufferInfo & gfxDstBuffer,const Rect & mask,const Rect & coords,const Style & style,int16_t offsetX,uint16_t ellipsisIndex,OpacityType opaScale)287 void Text::Draw(BufferInfo& gfxDstBuffer,
288                 const Rect& mask,
289                 const Rect& coords,
290                 const Style& style,
291                 int16_t offsetX,
292                 uint16_t ellipsisIndex,
293                 OpacityType opaScale)
294 {
295     Point offset = {offsetX, 0};
296     int16_t lineMaxWidth = expandWidth_ ? textSize_.x : coords.GetWidth();
297     uint16_t lineBegin = 0;
298     uint32_t maxLineBytes = 0;
299     uint16_t lineCount = GetLine(lineMaxWidth, style.letterSpace_, ellipsisIndex, maxLineBytes);
300     int16_t lineHeight = style.lineHeight_;
301     int16_t curLineHeight;
302     if (lineHeight == 0) {
303         lineHeight = UIFont::GetInstance()->GetHeight(fontId_, fontSize_);
304         lineHeight += style.lineSpace_;
305     }
306     if ((style.lineSpace_ == 0) && (sizeSpans_ != nullptr)) {
307         uint16_t letterIndex = 0;
308         curLineHeight = UIFont::GetInstance()->GetLineMaxHeight(text_, textLine_[0].lineBytes, fontId_, fontSize_,
309                                                                 letterIndex, sizeSpans_);
310         curLineHeight += style.lineSpace_;
311     } else {
312         curLineHeight = lineHeight;
313     }
314     Point pos;
315     if (lineHeight == style.lineHeight_) {
316         pos.y = TextPositionY(coords, (lineCount * lineHeight));
317     } else {
318         pos.y = TextPositionY(coords, (lineCount * lineHeight - style.lineSpace_));
319     }
320     OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.textOpa_);
321     uint16_t letterIndex = 0;
322     for (uint16_t i = 0; i < lineCount; i++) {
323         if (pos.y > mask.GetBottom()) {
324             return;
325         }
326         int16_t nextLine = pos.y + curLineHeight;
327         if (lineHeight != style.lineHeight_) {
328             nextLine -= style.lineSpace_;
329         }
330         int16_t tempLetterIndex = letterIndex;
331         if (nextLine >= mask.GetTop()) {
332             pos.x = LineStartPos(coords, textLine_[i].linePixelWidth);
333             LabelLineInfo labelLine{pos, offset, mask, curLineHeight, textLine_[i].lineBytes,
334                                     0, opa, style, &text_[lineBegin], textLine_[i].lineBytes,
335                                     lineBegin, fontId_, fontSize_, 0, static_cast<UITextLanguageDirect>(direct_),
336                                     nullptr, baseLine_,
337 #if defined(ENABLE_SPANNABLE_STRING) && ENABLE_SPANNABLE_STRING
338                                     textStyles_,
339 #endif
340                                     &backgroundColor_, &foregroundColor_, &linebackgroundColor_, sizeSpans_, 0};
341 
342             uint16_t ellipsisOssetY = DrawLabel::DrawTextOneLine(gfxDstBuffer, labelLine, letterIndex);
343             if ((i == (lineCount - 1)) && (ellipsisIndex != TEXT_ELLIPSIS_END_INV)) {
344                 labelLine.ellipsisOssetY = ellipsisOssetY;
345                 DrawEllipsis(gfxDstBuffer, labelLine, letterIndex);
346             }
347         } else {
348             letterIndex = TypedText::GetUTF8CharacterSize(text_, lineBegin + textLine_[i].lineBytes);
349         }
350         if ((style.lineSpace_ == 0) && (sizeSpans_ != nullptr)) {
351             curLineHeight = UIFont::GetInstance()->GetLineMaxHeight(&text_[lineBegin], textLine_[i].lineBytes, fontId_,
352                                                                     fontSize_, tempLetterIndex, sizeSpans_);
353             curLineHeight += style.lineSpace_;
354         } else {
355             curLineHeight = lineHeight;
356         }
357         lineBegin += textLine_[i].lineBytes;
358         pos.y += curLineHeight;
359     }
360 }
361 
TextPositionY(const Rect & textRect,int16_t textHeight)362 int16_t Text::TextPositionY(const Rect& textRect, int16_t textHeight)
363 {
364     int16_t yOffset = 0;
365     if (!expandHeight_ && (verticalAlign_ != TEXT_ALIGNMENT_TOP) && (textRect.GetHeight() > textHeight)) {
366         if (verticalAlign_ == TEXT_ALIGNMENT_CENTER) {
367             yOffset = (textRect.GetHeight() - textHeight) >> 1;
368         } else if (verticalAlign_ == TEXT_ALIGNMENT_BOTTOM) {
369             yOffset = textRect.GetHeight() - textHeight;
370         }
371     }
372     return textRect.GetY() + yOffset + EXTRA_HEIGHT / 2;   // 2:half extra height for first line
373 }
374 
LineStartPos(const Rect & textRect,uint16_t lineWidth)375 int16_t Text::LineStartPos(const Rect& textRect, uint16_t lineWidth)
376 {
377     int16_t xOffset = 0;
378     int16_t rectWidth = textRect.GetWidth();
379     if (horizontalAlign_ == TEXT_ALIGNMENT_CENTER) {
380         xOffset = (direct_ == TEXT_DIRECT_RTL) ? ((rectWidth + lineWidth + 1) >> 1) : ((rectWidth - lineWidth) >> 1);
381     } else if (horizontalAlign_ == TEXT_ALIGNMENT_RIGHT) {
382         xOffset = (direct_ == TEXT_DIRECT_RTL) ? rectWidth : (rectWidth - lineWidth);
383     } else {
384         xOffset = (direct_ == TEXT_DIRECT_RTL) ? lineWidth : 0;
385     }
386     return textRect.GetX() + xOffset;
387 }
388 
GetLine(int16_t width,uint8_t letterSpace,uint16_t ellipsisIndex,uint32_t & maxLineBytes)389 uint16_t Text::GetLine(int16_t width, uint8_t letterSpace, uint16_t ellipsisIndex, uint32_t& maxLineBytes)
390 {
391     if (text_ == nullptr) {
392         return 0;
393     }
394     uint16_t lineNum = 0;
395     uint32_t textLen = GetTextStrLen();
396     if ((ellipsisIndex != TEXT_ELLIPSIS_END_INV) && (ellipsisIndex < textLen)) {
397         textLen = ellipsisIndex;
398     }
399     uint32_t begin = 0;
400     uint16_t letterIndex = 0;
401     while ((begin < textLen) && (text_[begin] != '\0') && (lineNum < MAX_LINE_COUNT)) {
402         begin += GetTextLine(begin, textLen, width, lineNum, letterSpace, letterIndex, sizeSpans_);
403         if (maxLineBytes < textLine_[lineNum].lineBytes) {
404             maxLineBytes = textLine_[lineNum].lineBytes;
405         }
406         lineNum++;
407     }
408     if ((lineNum != 0) && (ellipsisIndex != TEXT_ELLIPSIS_END_INV)) {
409         uint16_t ellipsisWidth =
410             UIFont::GetInstance()->GetWidth(TEXT_ELLIPSIS_UNICODE, fontId_, fontSize_, 0) + letterSpace;
411         textLine_[lineNum - 1].linePixelWidth += ellipsisWidth;
412         if (textLine_[lineNum - 1].linePixelWidth > width) {
413             int16_t newWidth = width - ellipsisWidth;
414             maxLineBytes = CalculateLineWithEllipsis(begin, textLen, newWidth, letterSpace, lineNum, letterIndex,
415                                                      sizeSpans_);
416             textLine_[lineNum - 1].linePixelWidth += ellipsisWidth;
417         }
418     }
419     return lineNum;
420 }
421 
CalculateLineWithEllipsis(uint32_t begin,uint32_t textLen,int16_t width,uint8_t letterSpace,uint16_t & lineNum,uint16_t & letterIndex,SizeSpan * sizeSpans)422 uint32_t Text::CalculateLineWithEllipsis(uint32_t begin, uint32_t textLen, int16_t width,
423                                          uint8_t letterSpace, uint16_t& lineNum,
424                                          uint16_t& letterIndex,
425                                          SizeSpan* sizeSpans)
426 {
427     begin -= textLine_[lineNum - 1].lineBytes;
428     lineNum--;
429     while ((begin < textLen) && (text_[begin] != '\0') && (lineNum < MAX_LINE_COUNT)) {
430         begin += GetTextLine(begin, textLen, width, lineNum, letterSpace, letterIndex, sizeSpans);
431         lineNum++;
432     }
433     uint32_t maxLineBytes = 0;
434     for (uint16_t i = 0; i < lineNum; i++) {
435         if (maxLineBytes < textLine_[i].lineBytes) {
436             maxLineBytes = textLine_[i].lineBytes;
437         }
438     }
439     return maxLineBytes;
440 }
441 
GetTextStrLen()442 uint32_t Text::GetTextStrLen()
443 {
444     return (text_ != nullptr) ? (strlen(text_)) : 0;
445 }
446 
GetTextLine(uint32_t begin,uint32_t textLen,int16_t width,uint16_t lineNum,uint8_t letterSpace,uint16_t & letterIndex,SizeSpan * sizeSpans)447 uint32_t Text::GetTextLine(uint32_t begin, uint32_t textLen, int16_t width, uint16_t lineNum, uint8_t letterSpace,
448                            uint16_t& letterIndex, SizeSpan* sizeSpans)
449 {
450     int16_t lineWidth = width;
451     int16_t lineHeight = 0;
452     uint16_t nextLineBytes = UIFontAdaptor::GetNextLineAndWidth(&text_[begin], fontId_, fontSize_, letterSpace,
453                                                                 lineWidth, lineHeight, letterIndex, sizeSpans, false,
454                                                                 textLen - begin);
455     if (nextLineBytes + begin > textLen) {
456         nextLineBytes = textLen - begin;
457     }
458     textLine_[lineNum].lineBytes = nextLineBytes;
459     textLine_[lineNum].linePixelWidth = lineWidth;
460     return nextLineBytes;
461 }
462 
GetEllipsisIndex(const Rect & textRect,const Style & style)463 uint16_t Text::GetEllipsisIndex(const Rect& textRect, const Style& style)
464 {
465     if (textSize_.y <= textRect.GetHeight()) {
466         return TEXT_ELLIPSIS_END_INV;
467     }
468     UIFont* fontEngine = UIFont::GetInstance();
469     int16_t letterWidth = fontEngine->GetWidth(TEXT_ELLIPSIS_UNICODE, fontId_, fontSize_, 0) + style.letterSpace_;
470     Point p;
471     p.x = textRect.GetWidth() - letterWidth;
472     p.y = textRect.GetHeight();
473     int16_t height = style.lineHeight_;
474     if (height == 0) {
475         height = fontEngine->GetHeight(fontId_, fontSize_) + style.lineSpace_;
476     }
477     if (height) {
478         p.y -= p.y % height;
479     }
480     if (height != style.lineHeight_) {
481         p.y -= style.lineSpace_;
482     }
483     return GetLetterIndexByPosition(textRect, style, p);
484 }
485 
GetLetterIndexByPosition(const Rect & textRect,const Style & style,const Point & pos)486 uint16_t Text::GetLetterIndexByPosition(const Rect& textRect, const Style& style, const Point& pos)
487 {
488     if (text_ == nullptr) {
489         return 0;
490     }
491     uint32_t lineStart = 0;
492     uint32_t nextLineStart = 0;
493     int16_t lineHeight = style.lineHeight_;
494     uint16_t letterHeight = UIFont::GetInstance()->GetHeight(fontId_, fontSize_);
495     if (lineHeight == 0) {
496         lineHeight = letterHeight + style.lineSpace_;
497     }
498     uint16_t height = 0;
499     if (lineHeight != style.lineHeight_) {
500         height = letterHeight;
501     } else {
502         height = lineHeight;
503     }
504     int16_t y = 0;
505     uint32_t textLen = static_cast<uint32_t>(strlen(text_));
506     int16_t width = 0;
507     uint16_t letterIndex = 0;
508     while ((lineStart < textLen) && (text_[lineStart] != '\0')) {
509         width = textRect.GetWidth();
510         nextLineStart += UIFontAdaptor::GetNextLineAndWidth(&text_[lineStart], fontId_, fontSize_, style.letterSpace_,
511                                                             width, lineHeight, letterIndex, sizeSpans_);
512         if (nextLineStart == 0) {
513             break;
514         }
515         if (pos.y <= y + height) {
516             break;
517         }
518         y += lineHeight;
519         lineStart = nextLineStart;
520     }
521     if (nextLineStart == textLen) {
522         return TEXT_ELLIPSIS_END_INV;
523     }
524     /* Calculate the x coordinate */
525     width = pos.x;
526     lineStart +=
527         UIFontAdaptor::GetNextLineAndWidth(&text_[lineStart], fontId_, fontSize_, style.letterSpace_, width, lineHeight,
528                                            letterIndex, sizeSpans_, true);
529     return (lineStart < textLen) ? lineStart : TEXT_ELLIPSIS_END_INV;
530 }
531 
SetAbsoluteSizeSpan(uint16_t start,uint16_t end,uint8_t size)532 void Text::SetAbsoluteSizeSpan(uint16_t start, uint16_t end, uint8_t size)
533 {
534 #if defined(ENABLE_VECTOR_FONT) && ENABLE_VECTOR_FONT
535     if (fontId_ == FONT_ID_MAX) {
536         return;
537     }
538 #else
539     if (fontId_ == UIFontBuilder::GetInstance()->GetBitmapFontIdMax()) {
540         return;
541     }
542 #endif
543     uint16_t fontId = GetSpanFontIdBySize(size);
544 #if defined(ENABLE_VECTOR_FONT) && !ENABLE_VECTOR_FONT
545     if (fontId == fontId_) {
546         return;
547     }
548 #endif
549     if (text_ != nullptr && sizeSpans_ == nullptr) {
550         characterSize_ = TypedText::GetUTF8CharacterSize(text_, GetTextStrLen());
551         sizeSpans_ = static_cast<SizeSpan*>(UIMalloc(characterSize_ * sizeof(SizeSpan)));
552         if (sizeSpans_ == nullptr) {
553             GRAPHIC_LOGE("Text::SetAbsoluteSizeSpan invalid parameter");
554             return;
555         }
556         InitSizeSpans();
557     }
558 
559     if (sizeSpans_ != nullptr && start <= characterSize_) {
560         for (uint16_t i = start; i < end && i < characterSize_; i++) {
561             sizeSpans_[i].fontId = fontId;
562             sizeSpans_[i].size = size;
563             sizeSpans_[i].isSizeSpan = true;
564         }
565     }
566 }
567 
SetRelativeSizeSpan(uint16_t start,uint16_t end,float size)568 void Text::SetRelativeSizeSpan(uint16_t start, uint16_t end, float size)
569 {
570     uint8_t absoluteSize = 0;
571 #if defined(ENABLE_VECTOR_FONT) && ENABLE_VECTOR_FONT
572     absoluteSize = static_cast<uint8_t>(size * fontSize_);
573 #else
574     UITextLanguageFontParam* fontParam = UIFontBuilder::GetInstance()->GetTextLangFontsTable(fontId_);
575     if (fontParam == nullptr) {
576         GRAPHIC_LOGE("Text::SetRelativeSizeSpan invalid parameter");
577         return;
578     }
579     absoluteSize = static_cast<uint8_t>(size * fontParam->size);
580 #endif
581     SetAbsoluteSizeSpan(start, end, absoluteSize);
582 }
583 
GetSpanFontIdBySize(uint8_t size)584 uint16_t Text::GetSpanFontIdBySize(uint8_t size)
585 {
586 #if defined(ENABLE_VECTOR_FONT) && ENABLE_VECTOR_FONT
587     return fontId_;
588 #else
589     UITextLanguageFontParam* fontParam = UIFontBuilder::GetInstance()->GetTextLangFontsTable(fontId_);
590     if (fontParam == nullptr) {
591         return fontId_;
592     }
593 
594     uint8_t ttfId = fontParam->ttfId;
595     for (uint16_t fontId = 0; fontId < UIFontBuilder::GetInstance()->GetTotalFontId(); fontId++) {
596         UITextLanguageFontParam* tempFontParam = UIFontBuilder::GetInstance()->GetTextLangFontsTable(fontId);
597         if (tempFontParam == nullptr) {
598             continue;
599         }
600         if (ttfId == tempFontParam->ttfId && size == tempFontParam->size) {
601             return fontId;
602         }
603     }
604     return fontId_;
605 #endif
606 }
607 
InitSizeSpans()608 void Text::InitSizeSpans()
609 {
610     if (sizeSpans_ != nullptr) {
611         for (uint32_t i = 0 ; i < TypedText::GetUTF8CharacterSize(text_, GetTextStrLen()); i++) {
612             sizeSpans_[i].isSizeSpan = false;
613             sizeSpans_[i].height = 0;
614         }
615     }
616 }
617 } // namespace OHOS
618