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 "components/ui_label.h"
17a3e0fd82Sopenharmony_ci#include "font/ui_font.h"
18a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h"
19a3e0fd82Sopenharmony_ci#include "themes/theme_manager.h"
20a3e0fd82Sopenharmony_ci
21a3e0fd82Sopenharmony_cinamespace OHOS {
22a3e0fd82Sopenharmony_ciclass LabelAnimator : public Animator, public AnimatorCallback {
23a3e0fd82Sopenharmony_cipublic:
24a3e0fd82Sopenharmony_ci    LabelAnimator(uint16_t textX, uint16_t labelX, int16_t startPos, UIView* view)
25a3e0fd82Sopenharmony_ci        : Animator(this, view, 0, true),
26a3e0fd82Sopenharmony_ci          startPos_(startPos),
27a3e0fd82Sopenharmony_ci          textX_(textX),
28a3e0fd82Sopenharmony_ci          labelX_(labelX),
29a3e0fd82Sopenharmony_ci          offsetX_(startPos),
30a3e0fd82Sopenharmony_ci          waitCount_(ANIM_WAIT_COUNT),
31a3e0fd82Sopenharmony_ci          speed_(0),
32a3e0fd82Sopenharmony_ci          preRunTime_(0),
33a3e0fd82Sopenharmony_ci          decimal_(0)
34a3e0fd82Sopenharmony_ci    {
35a3e0fd82Sopenharmony_ci    }
36a3e0fd82Sopenharmony_ci
37a3e0fd82Sopenharmony_ci    virtual ~LabelAnimator() {}
38a3e0fd82Sopenharmony_ci
39a3e0fd82Sopenharmony_ci    int16_t GetStartPos() const
40a3e0fd82Sopenharmony_ci    {
41a3e0fd82Sopenharmony_ci        return startPos_;
42a3e0fd82Sopenharmony_ci    }
43a3e0fd82Sopenharmony_ci
44a3e0fd82Sopenharmony_ci    void SetStartPos(int16_t pos)
45a3e0fd82Sopenharmony_ci    {
46a3e0fd82Sopenharmony_ci        startPos_ = pos;
47a3e0fd82Sopenharmony_ci    }
48a3e0fd82Sopenharmony_ci
49a3e0fd82Sopenharmony_ci    void UpdateWidth(uint16_t textWidth, uint16_t labelWidth)
50a3e0fd82Sopenharmony_ci    {
51a3e0fd82Sopenharmony_ci        textX_ = textWidth;
52a3e0fd82Sopenharmony_ci        labelX_ = labelWidth;
53a3e0fd82Sopenharmony_ci        waitCount_ = ANIM_WAIT_COUNT;
54a3e0fd82Sopenharmony_ci        preRunTime_ = 0;
55a3e0fd82Sopenharmony_ci        decimal_ = 0;
56a3e0fd82Sopenharmony_ci        offsetX_ = startPos_;
57a3e0fd82Sopenharmony_ci        static_cast<UILabel*>(view_)->offsetX_ = offsetX_;
58a3e0fd82Sopenharmony_ci        view_->Invalidate();
59a3e0fd82Sopenharmony_ci    }
60a3e0fd82Sopenharmony_ci
61a3e0fd82Sopenharmony_ci    void Callback(UIView* view) override
62a3e0fd82Sopenharmony_ci    {
63a3e0fd82Sopenharmony_ci        if (view == nullptr) {
64a3e0fd82Sopenharmony_ci            return;
65a3e0fd82Sopenharmony_ci        }
66a3e0fd82Sopenharmony_ci
67a3e0fd82Sopenharmony_ci        uint32_t curTime = GetRunTime();
68a3e0fd82Sopenharmony_ci        if (waitCount_ > 0) {
69a3e0fd82Sopenharmony_ci            waitCount_--;
70a3e0fd82Sopenharmony_ci            preRunTime_ = curTime;
71a3e0fd82Sopenharmony_ci            return;
72a3e0fd82Sopenharmony_ci        }
73a3e0fd82Sopenharmony_ci        if (curTime == preRunTime_) {
74a3e0fd82Sopenharmony_ci            return;
75a3e0fd82Sopenharmony_ci        }
76a3e0fd82Sopenharmony_ci        uint32_t time = (curTime > preRunTime_) ? (curTime - preRunTime_) : (UINT32_MAX - preRunTime_ + curTime);
77a3e0fd82Sopenharmony_ci        // 1000: 1000 milliseconds is 1 second
78a3e0fd82Sopenharmony_ci        float floatStep = (static_cast<float>(time * speed_) / 1000) + decimal_;
79a3e0fd82Sopenharmony_ci        uint16_t integerStep = static_cast<uint16_t>(floatStep);
80a3e0fd82Sopenharmony_ci        decimal_ = floatStep - integerStep;
81a3e0fd82Sopenharmony_ci        preRunTime_ = curTime;
82a3e0fd82Sopenharmony_ci
83a3e0fd82Sopenharmony_ci        if (integerStep != 0) {
84a3e0fd82Sopenharmony_ci            offsetX_ -= integerStep;
85a3e0fd82Sopenharmony_ci        } else {
86a3e0fd82Sopenharmony_ci            return;
87a3e0fd82Sopenharmony_ci        }
88a3e0fd82Sopenharmony_ci        offsetX_ = ((offsetX_ - labelX_) % (textX_ + labelX_)) + labelX_;
89a3e0fd82Sopenharmony_ci        static_cast<UILabel*>(view)->offsetX_ = offsetX_;
90a3e0fd82Sopenharmony_ci        view->Invalidate();
91a3e0fd82Sopenharmony_ci    }
92a3e0fd82Sopenharmony_ci
93a3e0fd82Sopenharmony_ci    void SetAnimatorSpeed(uint16_t animSpeed)
94a3e0fd82Sopenharmony_ci    {
95a3e0fd82Sopenharmony_ci        speed_ = animSpeed;
96a3e0fd82Sopenharmony_ci        decimal_ = 0;
97a3e0fd82Sopenharmony_ci    }
98a3e0fd82Sopenharmony_ci
99a3e0fd82Sopenharmony_ci    int16_t GetAnimatorSpeed() const
100a3e0fd82Sopenharmony_ci    {
101a3e0fd82Sopenharmony_ci        return speed_;
102a3e0fd82Sopenharmony_ci    }
103a3e0fd82Sopenharmony_ci
104a3e0fd82Sopenharmony_ciprivate:
105a3e0fd82Sopenharmony_ci    static constexpr uint8_t ANIM_WAIT_COUNT = 50;
106a3e0fd82Sopenharmony_ci    int16_t startPos_;
107a3e0fd82Sopenharmony_ci    uint16_t textX_;
108a3e0fd82Sopenharmony_ci    uint16_t labelX_;
109a3e0fd82Sopenharmony_ci    int16_t offsetX_;
110a3e0fd82Sopenharmony_ci    uint16_t waitCount_;
111a3e0fd82Sopenharmony_ci    uint16_t speed_;
112a3e0fd82Sopenharmony_ci    uint32_t preRunTime_;
113a3e0fd82Sopenharmony_ci    float decimal_;
114a3e0fd82Sopenharmony_ci};
115a3e0fd82Sopenharmony_ci
116a3e0fd82Sopenharmony_ciUILabel::UILabel()
117a3e0fd82Sopenharmony_ci    : labelText_(nullptr),
118a3e0fd82Sopenharmony_ci      needRefresh_(false),
119a3e0fd82Sopenharmony_ci      useTextColor_(false),
120a3e0fd82Sopenharmony_ci      hasAnimator_(false),
121a3e0fd82Sopenharmony_ci      lineBreakMode_(LINE_BREAK_ELLIPSIS),
122a3e0fd82Sopenharmony_ci      ellipsisIndex_(Text::TEXT_ELLIPSIS_END_INV),
123a3e0fd82Sopenharmony_ci      offsetX_(0),
124a3e0fd82Sopenharmony_ci      textColor_(Color::White()),
125a3e0fd82Sopenharmony_ci      animator_{nullptr}
126a3e0fd82Sopenharmony_ci{
127a3e0fd82Sopenharmony_ci    Theme* theme = ThemeManager::GetInstance().GetCurrent();
128a3e0fd82Sopenharmony_ci    Style& style = (theme != nullptr) ? (theme->GetLabelStyle()) : (StyleDefault::GetLabelStyle());
129a3e0fd82Sopenharmony_ci    UIView::SetStyle(style);
130a3e0fd82Sopenharmony_ci    animator_.speed = DEFAULT_ANIMATOR_SPEED;
131a3e0fd82Sopenharmony_ci}
132a3e0fd82Sopenharmony_ci
133a3e0fd82Sopenharmony_ciUILabel::~UILabel()
134a3e0fd82Sopenharmony_ci{
135a3e0fd82Sopenharmony_ci    if (hasAnimator_) {
136a3e0fd82Sopenharmony_ci        delete animator_.animator;
137a3e0fd82Sopenharmony_ci        animator_.animator = nullptr;
138a3e0fd82Sopenharmony_ci        hasAnimator_ = false;
139a3e0fd82Sopenharmony_ci    }
140a3e0fd82Sopenharmony_ci    if (labelText_ != nullptr) {
141a3e0fd82Sopenharmony_ci        delete labelText_;
142a3e0fd82Sopenharmony_ci        labelText_ = nullptr;
143a3e0fd82Sopenharmony_ci    }
144a3e0fd82Sopenharmony_ci}
145a3e0fd82Sopenharmony_ci
146a3e0fd82Sopenharmony_civoid UILabel::InitLabelText()
147a3e0fd82Sopenharmony_ci{
148a3e0fd82Sopenharmony_ci    if (labelText_ == nullptr) {
149a3e0fd82Sopenharmony_ci        labelText_ = new Text();
150a3e0fd82Sopenharmony_ci    }
151a3e0fd82Sopenharmony_ci}
152a3e0fd82Sopenharmony_ci
153a3e0fd82Sopenharmony_ciint16_t UILabel::GetWidth()
154a3e0fd82Sopenharmony_ci{
155a3e0fd82Sopenharmony_ci    InitLabelText();
156a3e0fd82Sopenharmony_ci    if (needRefresh_ && labelText_->IsExpandWidth()) {
157a3e0fd82Sopenharmony_ci        ReMeasure();
158a3e0fd82Sopenharmony_ci    }
159a3e0fd82Sopenharmony_ci    return UIView::GetWidth();
160a3e0fd82Sopenharmony_ci}
161a3e0fd82Sopenharmony_ci
162a3e0fd82Sopenharmony_ciint16_t UILabel::GetHeight()
163a3e0fd82Sopenharmony_ci{
164a3e0fd82Sopenharmony_ci    InitLabelText();
165a3e0fd82Sopenharmony_ci    if (needRefresh_ && labelText_->IsExpandHeight()) {
166a3e0fd82Sopenharmony_ci        ReMeasure();
167a3e0fd82Sopenharmony_ci    }
168a3e0fd82Sopenharmony_ci    return UIView::GetHeight();
169a3e0fd82Sopenharmony_ci}
170a3e0fd82Sopenharmony_ci
171a3e0fd82Sopenharmony_civoid UILabel::SetStyle(uint8_t key, int64_t value)
172a3e0fd82Sopenharmony_ci{
173a3e0fd82Sopenharmony_ci    UIView::SetStyle(key, value);
174a3e0fd82Sopenharmony_ci    RefreshLabel();
175a3e0fd82Sopenharmony_ci}
176a3e0fd82Sopenharmony_ci
177a3e0fd82Sopenharmony_civoid UILabel::SetText(const char* text)
178a3e0fd82Sopenharmony_ci{
179a3e0fd82Sopenharmony_ci    InitLabelText();
180a3e0fd82Sopenharmony_ci    labelText_->SetText(text);
181a3e0fd82Sopenharmony_ci    if (labelText_->IsNeedRefresh()) {
182a3e0fd82Sopenharmony_ci        RefreshLabel();
183a3e0fd82Sopenharmony_ci    }
184a3e0fd82Sopenharmony_ci}
185a3e0fd82Sopenharmony_ci
186a3e0fd82Sopenharmony_ci
187a3e0fd82Sopenharmony_civoid UILabel::SetText(const SpannableString* text)
188a3e0fd82Sopenharmony_ci{
189a3e0fd82Sopenharmony_ci    InitLabelText();
190a3e0fd82Sopenharmony_ci    labelText_->SetSpannableString(text);
191a3e0fd82Sopenharmony_ci    if (labelText_->IsNeedRefresh()) {
192a3e0fd82Sopenharmony_ci        RefreshLabel();
193a3e0fd82Sopenharmony_ci    }
194a3e0fd82Sopenharmony_ci}
195a3e0fd82Sopenharmony_ci
196a3e0fd82Sopenharmony_ci
197a3e0fd82Sopenharmony_civoid UILabel::SetAbsoluteSizeSpan(uint16_t start, uint16_t end, uint8_t size)
198a3e0fd82Sopenharmony_ci{
199a3e0fd82Sopenharmony_ci    if (labelText_ == nullptr) {
200a3e0fd82Sopenharmony_ci        return;
201a3e0fd82Sopenharmony_ci    }
202a3e0fd82Sopenharmony_ci    labelText_->SetAbsoluteSizeSpan(start, end, size);
203a3e0fd82Sopenharmony_ci    if (labelText_->IsNeedRefresh()) {
204a3e0fd82Sopenharmony_ci        RefreshLabel();
205a3e0fd82Sopenharmony_ci    }
206a3e0fd82Sopenharmony_ci}
207a3e0fd82Sopenharmony_ci
208a3e0fd82Sopenharmony_civoid UILabel::SetRelativeSizeSpan(uint16_t start, uint16_t end, float size)
209a3e0fd82Sopenharmony_ci{
210a3e0fd82Sopenharmony_ci    if (labelText_ == nullptr) {
211a3e0fd82Sopenharmony_ci        return;
212a3e0fd82Sopenharmony_ci    }
213a3e0fd82Sopenharmony_ci    labelText_->SetRelativeSizeSpan(start, end, size);
214a3e0fd82Sopenharmony_ci    if (labelText_->IsNeedRefresh()) {
215a3e0fd82Sopenharmony_ci        RefreshLabel();
216a3e0fd82Sopenharmony_ci    }
217a3e0fd82Sopenharmony_ci}
218a3e0fd82Sopenharmony_ci
219a3e0fd82Sopenharmony_ciuint8_t UILabel::GetFontSize()
220a3e0fd82Sopenharmony_ci{
221a3e0fd82Sopenharmony_ci    InitLabelText();
222a3e0fd82Sopenharmony_ci    return labelText_->GetFontSize();
223a3e0fd82Sopenharmony_ci}
224a3e0fd82Sopenharmony_ci
225a3e0fd82Sopenharmony_civoid UILabel::SetLineBreakMode(const uint8_t lineBreakMode)
226a3e0fd82Sopenharmony_ci{
227a3e0fd82Sopenharmony_ci    InitLabelText();
228a3e0fd82Sopenharmony_ci    if ((lineBreakMode >= LINE_BREAK_MAX) || (lineBreakMode_ == lineBreakMode)) {
229a3e0fd82Sopenharmony_ci        return;
230a3e0fd82Sopenharmony_ci    }
231a3e0fd82Sopenharmony_ci    lineBreakMode_ = lineBreakMode;
232a3e0fd82Sopenharmony_ci    if ((lineBreakMode_ == LINE_BREAK_ADAPT) || (lineBreakMode_ == LINE_BREAK_STRETCH) ||
233a3e0fd82Sopenharmony_ci        (lineBreakMode_ == LINE_BREAK_MARQUEE)) {
234a3e0fd82Sopenharmony_ci        labelText_->SetExpandWidth(true);
235a3e0fd82Sopenharmony_ci    } else {
236a3e0fd82Sopenharmony_ci        labelText_->SetExpandWidth(false);
237a3e0fd82Sopenharmony_ci    }
238a3e0fd82Sopenharmony_ci    if ((lineBreakMode_ == LINE_BREAK_ADAPT) || (lineBreakMode_ == LINE_BREAK_WRAP)) {
239a3e0fd82Sopenharmony_ci        labelText_->SetExpandHeight(true);
240a3e0fd82Sopenharmony_ci    } else {
241a3e0fd82Sopenharmony_ci        labelText_->SetExpandHeight(false);
242a3e0fd82Sopenharmony_ci    }
243a3e0fd82Sopenharmony_ci    if (lineBreakMode_ != LINE_BREAK_MARQUEE) {
244a3e0fd82Sopenharmony_ci        offsetX_ = 0;
245a3e0fd82Sopenharmony_ci        if (hasAnimator_) {
246a3e0fd82Sopenharmony_ci            animator_.animator->Stop();
247a3e0fd82Sopenharmony_ci        }
248a3e0fd82Sopenharmony_ci    }
249a3e0fd82Sopenharmony_ci    RefreshLabel();
250a3e0fd82Sopenharmony_ci}
251a3e0fd82Sopenharmony_ci
252a3e0fd82Sopenharmony_civoid UILabel::SetAlign(UITextLanguageAlignment horizontalAlign, UITextLanguageAlignment verticalAlign)
253a3e0fd82Sopenharmony_ci{
254a3e0fd82Sopenharmony_ci    InitLabelText();
255a3e0fd82Sopenharmony_ci    labelText_->SetAlign(horizontalAlign, verticalAlign);
256a3e0fd82Sopenharmony_ci    if (labelText_->IsNeedRefresh()) {
257a3e0fd82Sopenharmony_ci        RefreshLabel();
258a3e0fd82Sopenharmony_ci    }
259a3e0fd82Sopenharmony_ci}
260a3e0fd82Sopenharmony_ci
261a3e0fd82Sopenharmony_civoid UILabel::SetFontId(uint16_t fontId)
262a3e0fd82Sopenharmony_ci{
263a3e0fd82Sopenharmony_ci    InitLabelText();
264a3e0fd82Sopenharmony_ci    labelText_->SetFontId(fontId);
265a3e0fd82Sopenharmony_ci    if (labelText_->IsNeedRefresh()) {
266a3e0fd82Sopenharmony_ci        RefreshLabel();
267a3e0fd82Sopenharmony_ci    }
268a3e0fd82Sopenharmony_ci}
269a3e0fd82Sopenharmony_ci
270a3e0fd82Sopenharmony_civoid UILabel::SetFont(const char* name, uint8_t size)
271a3e0fd82Sopenharmony_ci{
272a3e0fd82Sopenharmony_ci    InitLabelText();
273a3e0fd82Sopenharmony_ci    labelText_->SetFont(name, size);
274a3e0fd82Sopenharmony_ci    if (labelText_->IsNeedRefresh()) {
275a3e0fd82Sopenharmony_ci        RefreshLabel();
276a3e0fd82Sopenharmony_ci    }
277a3e0fd82Sopenharmony_ci}
278a3e0fd82Sopenharmony_ci
279a3e0fd82Sopenharmony_ciuint16_t UILabel::GetTextWidth()
280a3e0fd82Sopenharmony_ci{
281a3e0fd82Sopenharmony_ci    InitLabelText();
282a3e0fd82Sopenharmony_ci    if (labelText_->IsNeedRefresh()) {
283a3e0fd82Sopenharmony_ci        ReMeasure();
284a3e0fd82Sopenharmony_ci    }
285a3e0fd82Sopenharmony_ci    return labelText_->GetTextSize().x;
286a3e0fd82Sopenharmony_ci}
287a3e0fd82Sopenharmony_ci
288a3e0fd82Sopenharmony_ciuint16_t UILabel::GetTextHeight()
289a3e0fd82Sopenharmony_ci{
290a3e0fd82Sopenharmony_ci    InitLabelText();
291a3e0fd82Sopenharmony_ci    if (labelText_->IsNeedRefresh()) {
292a3e0fd82Sopenharmony_ci        ReMeasure();
293a3e0fd82Sopenharmony_ci    }
294a3e0fd82Sopenharmony_ci    return labelText_->GetTextSize().y;
295a3e0fd82Sopenharmony_ci}
296a3e0fd82Sopenharmony_ci
297a3e0fd82Sopenharmony_civoid UILabel::SetWidth(int16_t width)
298a3e0fd82Sopenharmony_ci{
299a3e0fd82Sopenharmony_ci    if (GetWidth() != width) {
300a3e0fd82Sopenharmony_ci        UIView::SetWidth(width);
301a3e0fd82Sopenharmony_ci        RefreshLabel();
302a3e0fd82Sopenharmony_ci    }
303a3e0fd82Sopenharmony_ci}
304a3e0fd82Sopenharmony_ci
305a3e0fd82Sopenharmony_civoid UILabel::SetHeight(int16_t height)
306a3e0fd82Sopenharmony_ci{
307a3e0fd82Sopenharmony_ci    if (GetHeight() != height) {
308a3e0fd82Sopenharmony_ci        UIView::SetHeight(height);
309a3e0fd82Sopenharmony_ci        RefreshLabel();
310a3e0fd82Sopenharmony_ci    }
311a3e0fd82Sopenharmony_ci}
312a3e0fd82Sopenharmony_ci
313a3e0fd82Sopenharmony_civoid UILabel::RefreshLabel()
314a3e0fd82Sopenharmony_ci{
315a3e0fd82Sopenharmony_ci    Invalidate();
316a3e0fd82Sopenharmony_ci    ellipsisIndex_ = Text::TEXT_ELLIPSIS_END_INV;
317a3e0fd82Sopenharmony_ci    if (!needRefresh_) {
318a3e0fd82Sopenharmony_ci        needRefresh_ = true;
319a3e0fd82Sopenharmony_ci    }
320a3e0fd82Sopenharmony_ci}
321a3e0fd82Sopenharmony_ci
322a3e0fd82Sopenharmony_civoid UILabel::ReMeasure()
323a3e0fd82Sopenharmony_ci{
324a3e0fd82Sopenharmony_ci    if (!needRefresh_) {
325a3e0fd82Sopenharmony_ci        return;
326a3e0fd82Sopenharmony_ci    }
327a3e0fd82Sopenharmony_ci    needRefresh_ = false;
328a3e0fd82Sopenharmony_ci    InitLabelText();
329a3e0fd82Sopenharmony_ci    Style style = GetStyleConst();
330a3e0fd82Sopenharmony_ci    style.textColor_ = GetTextColor();
331a3e0fd82Sopenharmony_ci    bool flag = false;
332a3e0fd82Sopenharmony_ci    if ((transMap_ != nullptr) && !transMap_->IsInvalid()) {
333a3e0fd82Sopenharmony_ci        transMap_->SetInvalid(true);
334a3e0fd82Sopenharmony_ci        flag = true;
335a3e0fd82Sopenharmony_ci    }
336a3e0fd82Sopenharmony_ci    labelText_->ReMeasureTextSize(GetContentRect(), style);
337a3e0fd82Sopenharmony_ci    Point textSize = labelText_->GetTextSize();
338a3e0fd82Sopenharmony_ci    switch (lineBreakMode_) {
339a3e0fd82Sopenharmony_ci        case LINE_BREAK_ADAPT:
340a3e0fd82Sopenharmony_ci            Resize(textSize.x, textSize.y);
341a3e0fd82Sopenharmony_ci            break;
342a3e0fd82Sopenharmony_ci        case LINE_BREAK_STRETCH:
343a3e0fd82Sopenharmony_ci            SetWidth(textSize.x);
344a3e0fd82Sopenharmony_ci            break;
345a3e0fd82Sopenharmony_ci        case LINE_BREAK_WRAP:
346a3e0fd82Sopenharmony_ci            SetHeight(textSize.y);
347a3e0fd82Sopenharmony_ci            break;
348a3e0fd82Sopenharmony_ci        case LINE_BREAK_ELLIPSIS:
349a3e0fd82Sopenharmony_ci            ellipsisIndex_ = labelText_->GetEllipsisIndex(GetContentRect(), style);
350a3e0fd82Sopenharmony_ci            labelText_->ReMeasureTextWidthInEllipsisMode(GetContentRect(), style, ellipsisIndex_);
351a3e0fd82Sopenharmony_ci            break;
352a3e0fd82Sopenharmony_ci        case LINE_BREAK_MARQUEE:
353a3e0fd82Sopenharmony_ci            RemeasureForMarquee(textSize.x);
354a3e0fd82Sopenharmony_ci            break;
355a3e0fd82Sopenharmony_ci        default:
356a3e0fd82Sopenharmony_ci            break;
357a3e0fd82Sopenharmony_ci    }
358a3e0fd82Sopenharmony_ci    if ((transMap_ != nullptr) && flag) {
359a3e0fd82Sopenharmony_ci        transMap_->SetInvalid(false);
360a3e0fd82Sopenharmony_ci    }
361a3e0fd82Sopenharmony_ci}
362a3e0fd82Sopenharmony_ci
363a3e0fd82Sopenharmony_civoid UILabel::RemeasureForMarquee(int16_t textWidth)
364a3e0fd82Sopenharmony_ci{
365a3e0fd82Sopenharmony_ci    int16_t rectWidth = GetWidth();
366a3e0fd82Sopenharmony_ci    if (textWidth > rectWidth) {
367a3e0fd82Sopenharmony_ci        offsetX_ = GetRollStartPos();
368a3e0fd82Sopenharmony_ci        if (labelText_->GetDirect() == TEXT_DIRECT_RTL) {
369a3e0fd82Sopenharmony_ci            labelText_->SetAlign(TEXT_ALIGNMENT_RIGHT, GetVerAlign());
370a3e0fd82Sopenharmony_ci        } else {
371a3e0fd82Sopenharmony_ci            labelText_->SetAlign(TEXT_ALIGNMENT_LEFT, GetVerAlign());
372a3e0fd82Sopenharmony_ci        }
373a3e0fd82Sopenharmony_ci        if (hasAnimator_) {
374a3e0fd82Sopenharmony_ci            static_cast<LabelAnimator*>(animator_.animator)->UpdateWidth(textWidth, rectWidth);
375a3e0fd82Sopenharmony_ci        } else {
376a3e0fd82Sopenharmony_ci            LabelAnimator* animator = new LabelAnimator(textWidth, rectWidth, offsetX_, this);
377a3e0fd82Sopenharmony_ci            if (animator == nullptr) {
378a3e0fd82Sopenharmony_ci                GRAPHIC_LOGE("new LabelAnimator fail");
379a3e0fd82Sopenharmony_ci                return;
380a3e0fd82Sopenharmony_ci            }
381a3e0fd82Sopenharmony_ci            animator->SetAnimatorSpeed(animator_.speed);
382a3e0fd82Sopenharmony_ci            animator_.animator = animator;
383a3e0fd82Sopenharmony_ci            hasAnimator_ = true;
384a3e0fd82Sopenharmony_ci        }
385a3e0fd82Sopenharmony_ci        animator_.animator->Start();
386a3e0fd82Sopenharmony_ci    } else {
387a3e0fd82Sopenharmony_ci        offsetX_ = 0;
388a3e0fd82Sopenharmony_ci        if (hasAnimator_) {
389a3e0fd82Sopenharmony_ci            animator_.animator->Stop();
390a3e0fd82Sopenharmony_ci        }
391a3e0fd82Sopenharmony_ci    }
392a3e0fd82Sopenharmony_ci}
393a3e0fd82Sopenharmony_ci
394a3e0fd82Sopenharmony_civoid UILabel::SetRollStartPos(int16_t pos)
395a3e0fd82Sopenharmony_ci{
396a3e0fd82Sopenharmony_ci    if (hasAnimator_) {
397a3e0fd82Sopenharmony_ci        static_cast<LabelAnimator*>(animator_.animator)->SetStartPos(pos);
398a3e0fd82Sopenharmony_ci    } else {
399a3e0fd82Sopenharmony_ci        animator_.pos = pos;
400a3e0fd82Sopenharmony_ci    }
401a3e0fd82Sopenharmony_ci}
402a3e0fd82Sopenharmony_ci
403a3e0fd82Sopenharmony_ciint16_t UILabel::GetRollStartPos() const
404a3e0fd82Sopenharmony_ci{
405a3e0fd82Sopenharmony_ci    return hasAnimator_ ? static_cast<LabelAnimator*>(animator_.animator)->GetStartPos() : animator_.pos;
406a3e0fd82Sopenharmony_ci}
407a3e0fd82Sopenharmony_ci
408a3e0fd82Sopenharmony_civoid UILabel::SetRollSpeed(uint16_t speed)
409a3e0fd82Sopenharmony_ci{
410a3e0fd82Sopenharmony_ci    if (hasAnimator_) {
411a3e0fd82Sopenharmony_ci        static_cast<LabelAnimator*>(animator_.animator)->SetAnimatorSpeed(speed);
412a3e0fd82Sopenharmony_ci    } else {
413a3e0fd82Sopenharmony_ci        animator_.speed = speed;
414a3e0fd82Sopenharmony_ci    }
415a3e0fd82Sopenharmony_ci}
416a3e0fd82Sopenharmony_ci
417a3e0fd82Sopenharmony_ciuint16_t UILabel::GetRollSpeed() const
418a3e0fd82Sopenharmony_ci{
419a3e0fd82Sopenharmony_ci    return hasAnimator_ ? static_cast<LabelAnimator*>(animator_.animator)->GetAnimatorSpeed() : animator_.speed;
420a3e0fd82Sopenharmony_ci}
421a3e0fd82Sopenharmony_ci
422a3e0fd82Sopenharmony_civoid UILabel::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
423a3e0fd82Sopenharmony_ci{
424a3e0fd82Sopenharmony_ci    InitLabelText();
425a3e0fd82Sopenharmony_ci    UIView::OnDraw(gfxDstBuffer, invalidatedArea);
426a3e0fd82Sopenharmony_ci    Style style = GetStyleConst();
427a3e0fd82Sopenharmony_ci    style.textColor_ = GetTextColor();
428a3e0fd82Sopenharmony_ci    OpacityType opa = GetMixOpaScale();
429a3e0fd82Sopenharmony_ci    labelText_->OnDraw(gfxDstBuffer, invalidatedArea, GetOrigRect(),
430a3e0fd82Sopenharmony_ci                       GetContentRect(), offsetX_, style, ellipsisIndex_, opa);
431a3e0fd82Sopenharmony_ci}
432a3e0fd82Sopenharmony_ci} // namespace OHOS
433