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 /** 17 * @addtogroup UI_Common 18 * @{ 19 * 20 * @brief Defines common UI capabilities, such as image and text processing. 21 * 22 * @since 1.0 23 * @version 1.0 24 */ 25 26 /** 27 * @file text.h 28 * 29 * @brief Declares the <b>Text</b> class that provides functions to set basic text attributes, such as the text 30 * direction and alignment mode. 31 * 32 * @since 1.0 33 * @version 1.0 34 */ 35 36 #ifndef GRAPHIC_LITE_TEXT_H 37 #define GRAPHIC_LITE_TEXT_H 38 39 #include <cstring> 40 #include "common/spannable_string.h" 41 #include "engines/gfx/gfx_engine_manager.h" 42 #include "font/ui_font_header.h" 43 44 #include "gfx_utils/geometry2d.h" 45 #include "gfx_utils/graphic_types.h" 46 #include "gfx_utils/list.h" 47 #include "gfx_utils/style.h" 48 #include "gfx_utils/vector.h" 49 50 namespace OHOS { 51 namespace { 52 const std::string PASSWORD_DOT = "*"; // dot for password type 53 constexpr uint16_t DEFAULT_TEXT_OFFSET = 5; 54 constexpr uint16_t BOTH_SIDE_TEXT_OFFSET = DEFAULT_TEXT_OFFSET * 2; // 2: left and right space 55 constexpr uint16_t DEFAULT_CURSOR_OFFSET = 1; 56 constexpr uint16_t DEFAULT_CURSOR_WIDTH = 2; 57 } // namespace name 58 59 /** 60 * @brief Enumerates text alignment modes. 61 */ 62 enum UITextLanguageAlignment : uint8_t { 63 /** Left-aligned */ 64 TEXT_ALIGNMENT_LEFT = 0, 65 /** Right-aligned */ 66 TEXT_ALIGNMENT_RIGHT, 67 /** Centered */ 68 TEXT_ALIGNMENT_CENTER, 69 /** Top-aligned */ 70 TEXT_ALIGNMENT_TOP, 71 /** Bottom-aligned */ 72 TEXT_ALIGNMENT_BOTTOM, 73 }; 74 75 /** 76 * @brief Enumerates text directions. 77 */ 78 enum UITextLanguageDirect : uint8_t { 79 /** Left-to-right */ 80 TEXT_DIRECT_LTR = 0, 81 /** Right-to-left */ 82 TEXT_DIRECT_RTL, 83 TEXT_DIRECT_MIXED, 84 }; 85 86 /** 87 * @brief Stores the attribute information about this arc text to draw. 88 */ 89 struct ArcTextInfo { 90 uint16_t radius; 91 float startAngle; 92 float endAngle; 93 Point arcCenter; 94 uint32_t lineStart; 95 uint32_t lineEnd; 96 UITextLanguageDirect direct; 97 bool hasAnimator; 98 uint32_t* codePoints; 99 uint16_t codePointsNum; 100 uint8_t shapingFontId; 101 }; 102 103 /** 104 * @brief Stores attribute information for this arc text to be drawn. 105 */ 106 struct ArcLetterInfo { InitDataArcLetterInfo107 void InitData(uint16_t inFontId, uint8_t inFontSize, uint32_t inLetter, Point inPos, 108 int16_t inRotateAngle, ColorType inColor, OpacityType inOpaScale, 109 float inStartAngle, float inEndAngle, float inCurrentAngle, uint16_t inRadius, 110 bool inCompatibilityMode, bool inDirectFlag, bool inOrientationFlag, bool inHasAnimator) 111 { 112 fontId = inFontId; 113 fontSize = inFontSize; 114 letter = inLetter; 115 pos = inPos; 116 rotateAngle = inRotateAngle; 117 color = inColor; 118 opaScale = inOpaScale; 119 startAngle = inStartAngle; 120 endAngle = inEndAngle; 121 currentAngle = inCurrentAngle; 122 radius = inRadius; 123 compatibilityMode = inCompatibilityMode; 124 directFlag = inDirectFlag; 125 orientationFlag = inOrientationFlag; 126 hasAnimator = inHasAnimator; 127 } 128 uint16_t fontId; 129 uint8_t fontSize; 130 uint32_t letter; 131 Point pos; 132 int16_t rotateAngle; 133 ColorType color; 134 OpacityType opaScale; 135 float startAngle; 136 float endAngle; 137 float currentAngle; 138 uint16_t radius; 139 bool compatibilityMode; 140 bool directFlag; 141 bool orientationFlag; 142 bool hasAnimator; 143 }; 144 145 /** 146 * @brief Enumerates text orientations. 147 */ 148 enum TextInRange { 149 IN_RANGE, 150 OUT_RANGE, 151 NEED_CLIP 152 }; 153 154 /** 155 * @brief Enumerates text orientations. 156 */ 157 enum class TextOrientation : uint8_t { 158 /** Inside */ 159 INSIDE, 160 /** Outside */ 161 OUTSIDE, 162 }; 163 164 struct BackgroundColor : public HeapBase { 165 int16_t start; 166 int16_t end; 167 ColorType backgroundColor; 168 }; 169 170 struct ForegroundColor : public HeapBase { 171 int16_t start; 172 int16_t end; 173 ColorType fontColor; 174 }; 175 176 struct LineBackgroundColor : public HeapBase { 177 int16_t start; 178 int16_t end; 179 ColorType linebackgroundColor; 180 }; 181 182 struct LabelLineInfo; 183 184 /** 185 * @brief Represents the base class of <b>Text</b>, providing the text attribute setting and text drawing 186 * capabilities for components that require font display. 187 * 188 * @since 1.0 189 * @version 1.0 190 */ 191 class Text : public HeapBase { 192 public: 193 /** Invalid value for the ellipsis position */ 194 static constexpr uint16_t TEXT_ELLIPSIS_END_INV = 0xFFFF; 195 static constexpr uint16_t TEXT_ELLIPSIS_UNICODE = 0x2026; 196 197 /** 198 * @brief A constructor used to create a <b>Text</b> instance. 199 * 200 * @since 1.0 201 * @version 1.0 202 */ 203 Text(); 204 205 /** 206 * @brief A destructor used to delete the <b>Text</b> instance. 207 * 208 * @since 1.0 209 * @version 1.0 210 */ 211 virtual ~Text(); 212 213 /** 214 * @brief Sets the content for this text. 215 * 216 * @param text Indicates the pointer to the text content. 217 * @since 1.0 218 * @version 1.0 219 */ 220 virtual void SetText(const char* text); 221 222 /** 223 * @brief Sets the SpannableString for this text. 224 * 225 * @param text Indicates the pointer to the text content. 226 * @since 1.0 227 * @version 1.0 228 */ 229 void SetSpannableString(const SpannableString* spannableString); 230 231 /** 232 * @brief Obtains the content of this text. 233 * 234 * @return Returns the text content. 235 * @since 1.0 236 * @version 1.0 237 */ GetText()238 const char* GetText() const 239 { 240 return text_; 241 } 242 243 /** 244 * @brief Sets the font name and size. 245 * 246 * @param name Indicates the pointer to the font name. 247 * @param size Indicates the font size to set. 248 * @since 1.0 249 * @version 1.0 250 */ 251 void SetFont(const char* name, uint8_t size); 252 253 static void SetFont(const char* name, uint8_t size, char*& destName, uint8_t& destSize); 254 255 /** 256 * @brief Sets the font ID. 257 * 258 * @param fontId Indicates the font ID to set. 259 * @since 1.0 260 * @version 1.0 261 */ 262 void SetFontId(uint16_t fontId); 263 264 /** 265 * @brief Obtains the font ID. 266 * 267 * @return Returns the front ID. 268 * @since 1.0 269 * @version 1.0 270 */ GetFontId()271 uint16_t GetFontId() const 272 { 273 return fontId_; 274 } 275 276 /** 277 * @brief Obtains the font size. 278 * 279 * @return Returns the front size. 280 * @since 1.0 281 * @version 1.0 282 */ GetFontSize()283 uint8_t GetFontSize() const 284 { 285 return fontSize_; 286 } 287 288 /** 289 * @brief Sets the direction for this text. 290 * 291 * @param direct Indicates the text direction, as defined in {@link UITextLanguageDirect}. 292 * @since 1.0 293 * @version 1.0 294 */ SetDirect(UITextLanguageDirect direct)295 void SetDirect(UITextLanguageDirect direct) 296 { 297 direct_ = direct; 298 } 299 300 /** 301 * @brief Obtains the direction of this text. 302 * 303 * @return Returns the text direction, as defined in {@link UITextLanguageDirect}. 304 * @since 1.0 305 * @version 1.0 306 */ GetDirect()307 UITextLanguageDirect GetDirect() const 308 { 309 return static_cast<UITextLanguageDirect>(direct_); 310 } 311 312 /** 313 * @brief Sets the alignment mode for this text. 314 * 315 * @param horizontalAlign Indicates the horizontal alignment mode to set, 316 * which can be {@link TEXT_ALIGNMENT_LEFT}, 317 * {@link TEXT_ALIGNMENT_CENTER}, or {@link TEXT_ALIGNMENT_RIGHT}. 318 * @param verticalAlign Indicates the vertical alignment mode to set, which can be 319 * {@link TEXT_ALIGNMENT_TOP} (default mode), {@link TEXT_ALIGNMENT_CENTER}, 320 * or {@link TEXT_ALIGNMENT_BOTTOM}. 321 * @since 1.0 322 * @version 1.0 323 */ 324 void SetAlign(UITextLanguageAlignment horizontalAlign, UITextLanguageAlignment verticalAlign = TEXT_ALIGNMENT_TOP) 325 { 326 if ((horizontalAlign_ != horizontalAlign) || (verticalAlign_ != verticalAlign)) { 327 needRefresh_ = true; 328 horizontalAlign_ = horizontalAlign; 329 verticalAlign_ = verticalAlign; 330 } 331 } 332 333 /** 334 * @brief Obtains the horizontal alignment mode. 335 * 336 * @return Returns the horizontal alignment mode. 337 * @since 1.0 338 * @version 1.0 339 */ GetHorAlign()340 UITextLanguageAlignment GetHorAlign() const 341 { 342 return static_cast<UITextLanguageAlignment>(horizontalAlign_); 343 } 344 345 /** 346 * @brief Obtains the vertical alignment mode. 347 * 348 * @return Returns the vertical alignment mode. 349 * @since 1.0 350 * @version 1.0 351 */ GetVerAlign()352 UITextLanguageAlignment GetVerAlign() const 353 { 354 return static_cast<UITextLanguageAlignment>(verticalAlign_); 355 } 356 357 /** 358 * @brief Obtains the size of this text. 359 * 360 * @return Returns the text size. 361 * @since 1.0 362 * @version 1.0 363 */ GetTextSize()364 Point GetTextSize() const 365 { 366 return textSize_; 367 } 368 369 virtual void ReMeasureTextSize(const Rect& textRect, const Style& style); 370 371 void ReMeasureTextWidthInEllipsisMode(const Rect& textRect, const Style& style, uint16_t ellipsisIndex); 372 373 void OnDraw(BufferInfo& gfxDstBuffer, 374 const Rect& invalidatedArea, 375 const Rect& viewOrigRect, 376 const Rect& textRect, 377 int16_t offsetX, 378 const Style& style, 379 uint16_t ellipsisIndex, 380 OpacityType opaScale); 381 382 /** 383 * @brief Sets whether to adapt the component width to this text. 384 * 385 * @param expand Specifies whether to adapt the component width to this text. The value <b>true</b> indicates 386 * that the component width will adapt to this text, and <b>false</b> indicates not. 387 * @since 1.0 388 * @version 1.0 389 */ SetExpandWidth(bool expand)390 void SetExpandWidth(bool expand) 391 { 392 expandWidth_ = expand; 393 } 394 395 /** 396 * @brief Checks whether the component width adapts to this text. 397 * 398 * @return Returns <b>true</b> if the component width adapts to this text; returns <b>false</b> otherwise. 399 * @since 1.0 400 * @version 1.0 401 */ IsExpandWidth()402 bool IsExpandWidth() const 403 { 404 return expandWidth_; 405 } 406 407 /** 408 * @brief Sets whether to adapt the component height to this text. 409 * 410 * @param expand Specifies whether to adapt the component height to this text. The value <b>true</b> indicates 411 * that the component height will adapt to this text, and <b>false</b> indicates not. 412 * @since 1.0 413 * @version 1.0 414 */ SetExpandHeight(bool expand)415 void SetExpandHeight(bool expand) 416 { 417 expandHeight_ = expand; 418 } 419 420 /** 421 * @brief Checks whether the component height adapts to this text. 422 * 423 * @return Returns <b>true</b> if the component height adapts to this text; returns <b>false</b> otherwise. 424 * @since 1.0 425 * @version 1.0 426 */ IsExpandHeight()427 bool IsExpandHeight() const 428 { 429 return expandHeight_; 430 } 431 IsNeedRefresh()432 bool IsNeedRefresh() const 433 { 434 return needRefresh_; 435 } 436 437 /** 438 * @brief Obtains the index of the character from where text will be replaced by ellipses based on 439 * the text rectangle and style. 440 * 441 * @param textRect Indicates the text rectangle. 442 * @param style Indicates the text style. 443 * @since 1.0 444 * @version 1.0 445 */ 446 uint16_t GetEllipsisIndex(const Rect& textRect, const Style& style); 447 448 /** 449 * @brief Get the GetShapingFontId of text 450 * 451 * @return Return ShapingFontId 452 */ GetShapingFontId()453 virtual uint8_t GetShapingFontId() const 454 { 455 return 0; 456 } 457 458 /** 459 * @brief Get the GetCodePointNum of text 460 * 461 * @return Return num of CodePoints 462 */ GetCodePointNum()463 virtual uint16_t GetCodePointNum() const 464 { 465 return 0; 466 } 467 468 /** 469 * @brief Get the GetCodePoints of text 470 * 471 * @return Return CodePoints of text 472 */ GetCodePoints()473 virtual uint32_t* GetCodePoints() const 474 { 475 return nullptr; 476 } 477 SetSupportBaseLine(bool baseLine)478 void SetSupportBaseLine(bool baseLine) 479 { 480 baseLine_ = baseLine; 481 } 482 SetBackgroundColorSpan(ColorType backgroundColor,int16_t start,int16_t end)483 void SetBackgroundColorSpan(ColorType backgroundColor, int16_t start, int16_t end) 484 { 485 if (spannableString_ == nullptr) { 486 spannableString_ = new SpannableString(); 487 } 488 spannableString_->SetBackgroundColor(backgroundColor, (uint16_t)start, (uint16_t)end); 489 } 490 GetBackgroundColorSpan()491 List<BackgroundColor> GetBackgroundColorSpan() 492 { 493 return backgroundColor_; 494 } 495 SetForegroundColorSpan(ColorType fontColor,int16_t start,int16_t end)496 void SetForegroundColorSpan(ColorType fontColor, int16_t start, int16_t end) 497 { 498 if (spannableString_ == nullptr) { 499 spannableString_ = new SpannableString(); 500 } 501 spannableString_->SetForegroundColor(fontColor, (uint16_t)start, (uint16_t)end); 502 } 503 GetForegroundColorSpan()504 List<ForegroundColor> GetForegroundColorSpan() 505 { 506 return foregroundColor_; 507 } 508 SetLineBackgroundSpan(ColorType linebackgroundColor,int16_t start,int16_t end)509 void SetLineBackgroundSpan(ColorType linebackgroundColor, int16_t start, int16_t end) 510 { 511 if (spannableString_ == nullptr) { 512 spannableString_ = new SpannableString(); 513 } 514 spannableString_->SetLineBackgroundColor(linebackgroundColor, (uint16_t)start, (uint16_t)end); 515 } 516 GetLineBackgroundSpan()517 List<LineBackgroundColor> GetLineBackgroundSpan() 518 { 519 return linebackgroundColor_; 520 } 521 522 void SetAbsoluteSizeSpan(uint16_t start, uint16_t end, uint8_t size); 523 void SetRelativeSizeSpan(uint16_t start, uint16_t end, float size); 524 virtual uint16_t GetLetterIndexByLinePosition(const Style& style, int16_t contentWidth, 525 const int16_t& posX, int16_t offsetX); 526 virtual uint16_t GetPosXByLetterIndex(const Rect& textRect, const Style& style, 527 uint16_t beginIndex, uint16_t count); 528 SetEliminateTrailingSpaces(bool eliminateTrailingSpaces)529 void SetEliminateTrailingSpaces(bool eliminateTrailingSpaces) 530 { 531 eliminateTrailingSpaces_ = eliminateTrailingSpaces; 532 } 533 IsEliminateTrailingSpaces()534 bool IsEliminateTrailingSpaces() 535 { 536 return eliminateTrailingSpaces_; 537 } GetSizeSpan()538 uint16_t GetSizeSpan() 539 { 540 return characterSize_; 541 } 542 543 /** 544 * @brief Get next character full dispaly offset. 545 * 546 * @param textRect Indicates size of input box. 547 * @param style Indicates the style of text. 548 * @param beginIndex Indicates index at the beginning of the text. 549 * @param num Indicates num of text. 550 * 551 * @return Return text offset. 552 * 553 */ 554 virtual uint16_t GetNextCharacterFullDispalyOffset(const Rect& textRect, 555 const Style& style, uint16_t beginIndex, uint16_t num); 556 557 /** 558 * @brief Obtains the width of the meta text. 559 * 560 * @param style Indicates the style of text. 561 * 562 * @return Return meta text width. 563 */ 564 virtual int16_t GetMetaTextWidth(const Style& style); 565 566 protected: 567 struct TextLine { 568 uint16_t lineBytes; 569 uint16_t linePixelWidth; 570 }; 571 572 /** Maximum number of lines */ 573 static constexpr uint16_t MAX_LINE_COUNT = 50; 574 static TextLine textLine_[MAX_LINE_COUNT]; 575 576 static constexpr const char* TEXT_ELLIPSIS = "…"; 577 578 virtual uint32_t GetTextStrLen(); 579 580 virtual uint32_t 581 GetTextLine(uint32_t begin, uint32_t textLen, int16_t width, uint16_t lineNum, uint8_t letterSpace, 582 uint16_t& letterIndex, SpannableString* spannableString, TextLine& textLine); 583 584 virtual uint16_t GetLetterIndexByPosition(const Rect& textRect, const Style& style, const Point& pos); 585 586 virtual void Draw(BufferInfo& gfxDstBuffer, 587 const Rect& mask, 588 const Rect& coords, 589 const Style& style, 590 int16_t offsetX, 591 uint16_t ellipsisIndex, 592 OpacityType opaScale); 593 594 uint16_t GetLine(int16_t width, uint8_t letterSpace, uint16_t ellipsisIndex, uint32_t& maxLineBytes); 595 int16_t TextPositionY(const Rect& textRect, int16_t textHeight); 596 int16_t LineStartPos(const Rect& textRect, uint16_t lineWidth); 597 void DrawEllipsis(BufferInfo& gfxDstBuffer, LabelLineInfo& labelLine, uint16_t& letterIndex); 598 uint32_t CalculateLineWithEllipsis(uint32_t begin, uint32_t textLen, int16_t width, 599 uint8_t letterSpace, uint16_t& lineNum, 600 uint16_t& letterIndex, 601 SpannableString* spannableString); 602 uint16_t GetSpanFontIdBySize(uint8_t size); 603 SpannableString* CreateSpannableString(); 604 #if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE 605 TextStyle* textStyles_; 606 #endif 607 char* text_; 608 uint16_t fontId_; 609 uint8_t fontSize_; // Only the vector font library has a valid value. 610 Point textSize_; 611 bool needRefresh_ : 1; 612 bool expandWidth_ : 1; 613 bool expandHeight_ : 1; 614 bool baseLine_ : 1; 615 uint8_t direct_ : 4; // UITextLanguageDirect 616 List<BackgroundColor> backgroundColor_; 617 List<ForegroundColor> foregroundColor_; 618 List<LineBackgroundColor> linebackgroundColor_; 619 uint32_t characterSize_; 620 SpannableString* spannableString_; 621 TextLine preIndexLine_; 622 623 private: 624 uint8_t horizontalAlign_ : 4; // UITextLanguageAlignment 625 uint8_t verticalAlign_ : 4; // UITextLanguageAlignment 626 bool eliminateTrailingSpaces_; 627 static constexpr uint8_t FONT_ID_MAX = 0xFF; 628 #if defined(ENABLE_ICU) && ENABLE_ICU 629 void SetLineBytes(uint16_t& lineBytes, uint16_t lineBegin); 630 #endif 631 void CalculatedCurLineHeight(int16_t& lineHeight, int16_t& curLineHeight, 632 uint16_t fontHeight, const Style& style, uint16_t lineMaxHeight); 633 void SetNextLineBegin(const Style& style, uint16_t lineMaxHeight, int16_t& curLineHeight, Point& pos, 634 int16_t& tempLetterIndex, int16_t& lineHeight, uint16_t& lineBegin, uint16_t letterIndex); 635 Point GetPos(int16_t& lineHeight, const Style& style, uint16_t& lineCount, const Rect& coords); 636 }; 637 } // namespace OHOS 638 #endif // GRAPHIC_LITE_TEXT_H 639