1a3e0fd82Sopenharmony_ci/*
2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2021 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/text_adapter.h"
17a3e0fd82Sopenharmony_ci#include <cstdio>
18a3e0fd82Sopenharmony_ci#include "securec.h"
19a3e0fd82Sopenharmony_ci
20a3e0fd82Sopenharmony_cinamespace OHOS {
21a3e0fd82Sopenharmony_cibool TextFormatter::Format(int16_t value, char* outText, uint16_t textLen)
22a3e0fd82Sopenharmony_ci{
23a3e0fd82Sopenharmony_ci    if (sprintf_s(outText, textLen, "%d", value) < 0) {
24a3e0fd82Sopenharmony_ci        return false;
25a3e0fd82Sopenharmony_ci    }
26a3e0fd82Sopenharmony_ci    return true;
27a3e0fd82Sopenharmony_ci}
28a3e0fd82Sopenharmony_ci
29a3e0fd82Sopenharmony_ciTextAdapter::TextAdapter()
30a3e0fd82Sopenharmony_ci    : dataMode_(DYNAMIC_TEXT_MODE),
31a3e0fd82Sopenharmony_ci      fontName_(nullptr),
32a3e0fd82Sopenharmony_ci      fontSize_(0),
33a3e0fd82Sopenharmony_ci      width_(0),
34a3e0fd82Sopenharmony_ci      height_(0),
35a3e0fd82Sopenharmony_ci      direct_(UITextLanguageDirect::TEXT_DIRECT_LTR),
36a3e0fd82Sopenharmony_ci      lineBreakMode_(UILabel::LINE_BREAK_ADAPT),
37a3e0fd82Sopenharmony_ci      integerTextStart_(0),
38a3e0fd82Sopenharmony_ci      integerTextEnd_(0),
39a3e0fd82Sopenharmony_ci      clickListener_(nullptr),
40a3e0fd82Sopenharmony_ci      formatter_(nullptr)
41a3e0fd82Sopenharmony_ci{
42a3e0fd82Sopenharmony_ci    style_ = StyleDefault::GetBackgroundTransparentStyle();
43a3e0fd82Sopenharmony_ci    fontId_ = style_.font_;
44a3e0fd82Sopenharmony_ci}
45a3e0fd82Sopenharmony_ci
46a3e0fd82Sopenharmony_ciTextAdapter::~TextAdapter()
47a3e0fd82Sopenharmony_ci{
48a3e0fd82Sopenharmony_ci    ClearDynamicText();
49a3e0fd82Sopenharmony_ci    if (fontName_ != nullptr) {
50a3e0fd82Sopenharmony_ci        UIFree(fontName_);
51a3e0fd82Sopenharmony_ci        fontName_ = nullptr;
52a3e0fd82Sopenharmony_ci    }
53a3e0fd82Sopenharmony_ci}
54a3e0fd82Sopenharmony_ci
55a3e0fd82Sopenharmony_civoid TextAdapter::SetFont(const char* name, uint8_t size)
56a3e0fd82Sopenharmony_ci{
57a3e0fd82Sopenharmony_ci    Text::SetFont(name, size, fontName_, fontSize_);
58a3e0fd82Sopenharmony_ci}
59a3e0fd82Sopenharmony_ci
60a3e0fd82Sopenharmony_ciUIView* TextAdapter::GetView(UIView* inView, int16_t index)
61a3e0fd82Sopenharmony_ci{
62a3e0fd82Sopenharmony_ci    UILabel* newView = GetTextView(inView, index);
63a3e0fd82Sopenharmony_ci    if (newView == nullptr) {
64a3e0fd82Sopenharmony_ci        return nullptr;
65a3e0fd82Sopenharmony_ci    }
66a3e0fd82Sopenharmony_ci    newView->SetLineBreakMode(lineBreakMode_);
67a3e0fd82Sopenharmony_ci    newView->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
68a3e0fd82Sopenharmony_ci    if (width_) {
69a3e0fd82Sopenharmony_ci        newView->SetWidth(width_);
70a3e0fd82Sopenharmony_ci    }
71a3e0fd82Sopenharmony_ci    if (height_) {
72a3e0fd82Sopenharmony_ci        newView->SetHeight(height_);
73a3e0fd82Sopenharmony_ci    }
74a3e0fd82Sopenharmony_ci    newView->SetViewIndex(index);
75a3e0fd82Sopenharmony_ci    newView->UIView::SetStyle(style_);
76a3e0fd82Sopenharmony_ci    newView->GetHeight();
77a3e0fd82Sopenharmony_ci    if (clickListener_) {
78a3e0fd82Sopenharmony_ci        newView->SetOnClickListener(clickListener_);
79a3e0fd82Sopenharmony_ci        newView->SetTouchable(true);
80a3e0fd82Sopenharmony_ci    }
81a3e0fd82Sopenharmony_ci    return newView;
82a3e0fd82Sopenharmony_ci}
83a3e0fd82Sopenharmony_ci
84a3e0fd82Sopenharmony_ciUILabel* TextAdapter::GetTextView(UIView* inView, int16_t index)
85a3e0fd82Sopenharmony_ci{
86a3e0fd82Sopenharmony_ci    switch (dataMode_) {
87a3e0fd82Sopenharmony_ci        case DYNAMIC_TEXT_MODE:
88a3e0fd82Sopenharmony_ci            return GetDynamicText(inView, index);
89a3e0fd82Sopenharmony_ci        case CONTINUOUS_INTEGER_MODE:
90a3e0fd82Sopenharmony_ci            return GetIntegerText(inView, index);
91a3e0fd82Sopenharmony_ci        default:
92a3e0fd82Sopenharmony_ci            return nullptr;
93a3e0fd82Sopenharmony_ci    }
94a3e0fd82Sopenharmony_ci}
95a3e0fd82Sopenharmony_ci
96a3e0fd82Sopenharmony_ciUILabel* TextAdapter::GetDynamicText(UIView* inView, int16_t index)
97a3e0fd82Sopenharmony_ci{
98a3e0fd82Sopenharmony_ci    if (dynamicText_.IsEmpty() || (index > dynamicText_.Size() - 1) || (index < 0)) {
99a3e0fd82Sopenharmony_ci        return nullptr;
100a3e0fd82Sopenharmony_ci    }
101a3e0fd82Sopenharmony_ci
102a3e0fd82Sopenharmony_ci    ListNode<const char*>* node = dynamicText_.Begin();
103a3e0fd82Sopenharmony_ci    for (int16_t i = 0; i < index; i++) {
104a3e0fd82Sopenharmony_ci        node = node->next_;
105a3e0fd82Sopenharmony_ci    }
106a3e0fd82Sopenharmony_ci    UILabel* newView = CreateUILabel(inView);
107a3e0fd82Sopenharmony_ci    if (newView != nullptr) {
108a3e0fd82Sopenharmony_ci        newView->SetText(node->data_);
109a3e0fd82Sopenharmony_ci        if (fontName_ == nullptr) {
110a3e0fd82Sopenharmony_ci            newView->SetFontId(fontId_);
111a3e0fd82Sopenharmony_ci        } else {
112a3e0fd82Sopenharmony_ci            newView->SetFont(fontName_, fontSize_);
113a3e0fd82Sopenharmony_ci        }
114a3e0fd82Sopenharmony_ci        newView->SetDirect(direct_);
115a3e0fd82Sopenharmony_ci    }
116a3e0fd82Sopenharmony_ci    return newView;
117a3e0fd82Sopenharmony_ci}
118a3e0fd82Sopenharmony_ci
119a3e0fd82Sopenharmony_ciUILabel* TextAdapter::GetIntegerText(UIView* inView, int16_t index)
120a3e0fd82Sopenharmony_ci{
121a3e0fd82Sopenharmony_ci    if ((index < 0) || ((integerTextEnd_ - integerTextStart_) < index)) {
122a3e0fd82Sopenharmony_ci        return nullptr;
123a3e0fd82Sopenharmony_ci    }
124a3e0fd82Sopenharmony_ci    UILabel* newView = CreateUILabel(inView);
125a3e0fd82Sopenharmony_ci    if (newView != nullptr) {
126a3e0fd82Sopenharmony_ci        char buf[BUF_LEN] = {0};
127a3e0fd82Sopenharmony_ci        if (formatter_ != nullptr) {
128a3e0fd82Sopenharmony_ci            if (!formatter_->Format(integerTextStart_ + index, buf, BUF_LEN)) {
129a3e0fd82Sopenharmony_ci                if (inView == nullptr) {
130a3e0fd82Sopenharmony_ci                    delete newView;
131a3e0fd82Sopenharmony_ci                    newView = nullptr;
132a3e0fd82Sopenharmony_ci                }
133a3e0fd82Sopenharmony_ci                return nullptr;
134a3e0fd82Sopenharmony_ci            }
135a3e0fd82Sopenharmony_ci        } else {
136a3e0fd82Sopenharmony_ci            if (sprintf_s(buf, sizeof(buf), "%02d", integerTextStart_ + index) < 0) {
137a3e0fd82Sopenharmony_ci                if (inView == nullptr) {
138a3e0fd82Sopenharmony_ci                    delete newView;
139a3e0fd82Sopenharmony_ci                    newView = nullptr;
140a3e0fd82Sopenharmony_ci                }
141a3e0fd82Sopenharmony_ci                return nullptr;
142a3e0fd82Sopenharmony_ci            }
143a3e0fd82Sopenharmony_ci        }
144a3e0fd82Sopenharmony_ci
145a3e0fd82Sopenharmony_ci        buf[BUF_LEN - 1] = '\0';
146a3e0fd82Sopenharmony_ci        newView->SetText(buf);
147a3e0fd82Sopenharmony_ci        if (fontName_ == nullptr) {
148a3e0fd82Sopenharmony_ci            newView->SetFontId(fontId_);
149a3e0fd82Sopenharmony_ci        } else {
150a3e0fd82Sopenharmony_ci            newView->SetFont(fontName_, fontSize_);
151a3e0fd82Sopenharmony_ci        }
152a3e0fd82Sopenharmony_ci        newView->SetDirect(direct_);
153a3e0fd82Sopenharmony_ci    }
154a3e0fd82Sopenharmony_ci    return newView;
155a3e0fd82Sopenharmony_ci}
156a3e0fd82Sopenharmony_ci
157a3e0fd82Sopenharmony_ciUILabel* TextAdapter::CreateUILabel(UIView* inView)
158a3e0fd82Sopenharmony_ci{
159a3e0fd82Sopenharmony_ci    if (inView == nullptr) {
160a3e0fd82Sopenharmony_ci        return new UILabel();
161a3e0fd82Sopenharmony_ci    }
162a3e0fd82Sopenharmony_ci    return static_cast<UILabel*>(inView);
163a3e0fd82Sopenharmony_ci}
164a3e0fd82Sopenharmony_ci
165a3e0fd82Sopenharmony_civoid TextAdapter::ClearDynamicText()
166a3e0fd82Sopenharmony_ci{
167a3e0fd82Sopenharmony_ci    ListNode<const char*>* node = dynamicText_.Begin();
168a3e0fd82Sopenharmony_ci    while (node != dynamicText_.End()) {
169a3e0fd82Sopenharmony_ci        if (node->data_) {
170a3e0fd82Sopenharmony_ci            UIFree(reinterpret_cast<void*>(const_cast<char*>(node->data_)));
171a3e0fd82Sopenharmony_ci            node->data_ = nullptr;
172a3e0fd82Sopenharmony_ci        }
173a3e0fd82Sopenharmony_ci        node = node->next_;
174a3e0fd82Sopenharmony_ci    }
175a3e0fd82Sopenharmony_ci    dynamicText_.Clear();
176a3e0fd82Sopenharmony_ci}
177a3e0fd82Sopenharmony_ci
178a3e0fd82Sopenharmony_civoid TextAdapter::SetData(List<const char*>* data)
179a3e0fd82Sopenharmony_ci{
180a3e0fd82Sopenharmony_ci    if (data == nullptr) {
181a3e0fd82Sopenharmony_ci        return;
182a3e0fd82Sopenharmony_ci    }
183a3e0fd82Sopenharmony_ci    if (!dynamicText_.IsEmpty()) {
184a3e0fd82Sopenharmony_ci        ClearDynamicText();
185a3e0fd82Sopenharmony_ci    }
186a3e0fd82Sopenharmony_ci    ListNode<const char*>* node = data->Begin();
187a3e0fd82Sopenharmony_ci    while (node != data->End()) {
188a3e0fd82Sopenharmony_ci        uint32_t len = strlen(node->data_);
189a3e0fd82Sopenharmony_ci        char* stringData = static_cast<char*>(UIMalloc(len + 1));
190a3e0fd82Sopenharmony_ci        if (stringData == nullptr) {
191a3e0fd82Sopenharmony_ci            return;
192a3e0fd82Sopenharmony_ci        }
193a3e0fd82Sopenharmony_ci        if (memcpy_s(stringData, len + 1, node->data_, len) != EOK) {
194a3e0fd82Sopenharmony_ci            UIFree(reinterpret_cast<void*>(stringData));
195a3e0fd82Sopenharmony_ci            stringData = nullptr;
196a3e0fd82Sopenharmony_ci            return;
197a3e0fd82Sopenharmony_ci        }
198a3e0fd82Sopenharmony_ci        stringData[len] = '\0';
199a3e0fd82Sopenharmony_ci        dynamicText_.PushBack(stringData);
200a3e0fd82Sopenharmony_ci        node = node->next_;
201a3e0fd82Sopenharmony_ci    }
202a3e0fd82Sopenharmony_ci    dataMode_ = DYNAMIC_TEXT_MODE;
203a3e0fd82Sopenharmony_ci}
204a3e0fd82Sopenharmony_ci
205a3e0fd82Sopenharmony_civoid TextAdapter::SetData(int16_t start, int16_t end)
206a3e0fd82Sopenharmony_ci{
207a3e0fd82Sopenharmony_ci    if (start <= end) {
208a3e0fd82Sopenharmony_ci        integerTextStart_ = start;
209a3e0fd82Sopenharmony_ci        integerTextEnd_ = end;
210a3e0fd82Sopenharmony_ci        dataMode_ = CONTINUOUS_INTEGER_MODE;
211a3e0fd82Sopenharmony_ci    }
212a3e0fd82Sopenharmony_ci}
213a3e0fd82Sopenharmony_ci
214a3e0fd82Sopenharmony_ciuint16_t TextAdapter::GetCount()
215a3e0fd82Sopenharmony_ci{
216a3e0fd82Sopenharmony_ci    switch (dataMode_) {
217a3e0fd82Sopenharmony_ci        case DYNAMIC_TEXT_MODE:
218a3e0fd82Sopenharmony_ci            return dynamicText_.Size();
219a3e0fd82Sopenharmony_ci        case CONTINUOUS_INTEGER_MODE:
220a3e0fd82Sopenharmony_ci            return (integerTextStart_ <= integerTextEnd_) ? (integerTextEnd_ - integerTextStart_ + 1) : 0;
221a3e0fd82Sopenharmony_ci        default:
222a3e0fd82Sopenharmony_ci            return 0;
223a3e0fd82Sopenharmony_ci    }
224a3e0fd82Sopenharmony_ci}
225a3e0fd82Sopenharmony_ci} // namespace OHOS
226