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