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