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