1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "components/text_adapter.h"
17 #include <cstdio>
18 #include "securec.h"
19 
20 namespace OHOS {
Format(int16_t value,char * outText,uint16_t textLen)21 bool TextFormatter::Format(int16_t value, char* outText, uint16_t textLen)
22 {
23     if (sprintf_s(outText, textLen, "%d", value) < 0) {
24         return false;
25     }
26     return true;
27 }
28 
TextAdapter()29 TextAdapter::TextAdapter()
30     : dataMode_(DYNAMIC_TEXT_MODE),
31       fontName_(nullptr),
32       fontSize_(0),
33       width_(0),
34       height_(0),
35       direct_(UITextLanguageDirect::TEXT_DIRECT_LTR),
36       lineBreakMode_(UILabel::LINE_BREAK_ADAPT),
37       integerTextStart_(0),
38       integerTextEnd_(0),
39       clickListener_(nullptr),
40       formatter_(nullptr)
41 {
42     style_ = StyleDefault::GetBackgroundTransparentStyle();
43     fontId_ = style_.font_;
44 }
45 
~TextAdapter()46 TextAdapter::~TextAdapter()
47 {
48     ClearDynamicText();
49     if (fontName_ != nullptr) {
50         UIFree(fontName_);
51         fontName_ = nullptr;
52     }
53 }
54 
SetFont(const char * name,uint8_t size)55 void TextAdapter::SetFont(const char* name, uint8_t size)
56 {
57     Text::SetFont(name, size, fontName_, fontSize_);
58 }
59 
GetView(UIView * inView,int16_t index)60 UIView* TextAdapter::GetView(UIView* inView, int16_t index)
61 {
62     UILabel* newView = GetTextView(inView, index);
63     if (newView == nullptr) {
64         return nullptr;
65     }
66     newView->SetLineBreakMode(lineBreakMode_);
67     newView->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
68     if (width_) {
69         newView->SetWidth(width_);
70     }
71     if (height_) {
72         newView->SetHeight(height_);
73     }
74     newView->SetViewIndex(index);
75     newView->UIView::SetStyle(style_);
76     newView->GetHeight();
77     if (clickListener_) {
78         newView->SetOnClickListener(clickListener_);
79         newView->SetTouchable(true);
80     }
81     return newView;
82 }
83 
GetTextView(UIView * inView,int16_t index)84 UILabel* TextAdapter::GetTextView(UIView* inView, int16_t index)
85 {
86     switch (dataMode_) {
87         case DYNAMIC_TEXT_MODE:
88             return GetDynamicText(inView, index);
89         case CONTINUOUS_INTEGER_MODE:
90             return GetIntegerText(inView, index);
91         default:
92             return nullptr;
93     }
94 }
95 
GetDynamicText(UIView * inView,int16_t index)96 UILabel* TextAdapter::GetDynamicText(UIView* inView, int16_t index)
97 {
98     if (dynamicText_.IsEmpty() || (index > dynamicText_.Size() - 1) || (index < 0)) {
99         return nullptr;
100     }
101 
102     ListNode<const char*>* node = dynamicText_.Begin();
103     for (int16_t i = 0; i < index; i++) {
104         node = node->next_;
105     }
106     UILabel* newView = CreateUILabel(inView);
107     if (newView != nullptr) {
108         newView->SetText(node->data_);
109         if (fontName_ == nullptr) {
110             newView->SetFontId(fontId_);
111         } else {
112             newView->SetFont(fontName_, fontSize_);
113         }
114         newView->SetDirect(direct_);
115     }
116     return newView;
117 }
118 
GetIntegerText(UIView * inView,int16_t index)119 UILabel* TextAdapter::GetIntegerText(UIView* inView, int16_t index)
120 {
121     if ((index < 0) || ((integerTextEnd_ - integerTextStart_) < index)) {
122         return nullptr;
123     }
124     UILabel* newView = CreateUILabel(inView);
125     if (newView != nullptr) {
126         char buf[BUF_LEN] = {0};
127         if (formatter_ != nullptr) {
128             if (!formatter_->Format(integerTextStart_ + index, buf, BUF_LEN)) {
129                 if (inView == nullptr) {
130                     delete newView;
131                     newView = nullptr;
132                 }
133                 return nullptr;
134             }
135         } else {
136             if (sprintf_s(buf, sizeof(buf), "%02d", integerTextStart_ + index) < 0) {
137                 if (inView == nullptr) {
138                     delete newView;
139                     newView = nullptr;
140                 }
141                 return nullptr;
142             }
143         }
144 
145         buf[BUF_LEN - 1] = '\0';
146         newView->SetText(buf);
147         if (fontName_ == nullptr) {
148             newView->SetFontId(fontId_);
149         } else {
150             newView->SetFont(fontName_, fontSize_);
151         }
152         newView->SetDirect(direct_);
153     }
154     return newView;
155 }
156 
CreateUILabel(UIView * inView)157 UILabel* TextAdapter::CreateUILabel(UIView* inView)
158 {
159     if (inView == nullptr) {
160         return new UILabel();
161     }
162     return static_cast<UILabel*>(inView);
163 }
164 
ClearDynamicText()165 void TextAdapter::ClearDynamicText()
166 {
167     ListNode<const char*>* node = dynamicText_.Begin();
168     while (node != dynamicText_.End()) {
169         if (node->data_) {
170             UIFree(reinterpret_cast<void*>(const_cast<char*>(node->data_)));
171             node->data_ = nullptr;
172         }
173         node = node->next_;
174     }
175     dynamicText_.Clear();
176 }
177 
SetData(List<const char * > * data)178 void TextAdapter::SetData(List<const char*>* data)
179 {
180     if (data == nullptr) {
181         return;
182     }
183     if (!dynamicText_.IsEmpty()) {
184         ClearDynamicText();
185     }
186     ListNode<const char*>* node = data->Begin();
187     while (node != data->End()) {
188         uint32_t len = strlen(node->data_);
189         char* stringData = static_cast<char*>(UIMalloc(len + 1));
190         if (stringData == nullptr) {
191             return;
192         }
193         if (memcpy_s(stringData, len + 1, node->data_, len) != EOK) {
194             UIFree(reinterpret_cast<void*>(stringData));
195             stringData = nullptr;
196             return;
197         }
198         stringData[len] = '\0';
199         dynamicText_.PushBack(stringData);
200         node = node->next_;
201     }
202     dataMode_ = DYNAMIC_TEXT_MODE;
203 }
204 
SetData(int16_t start,int16_t end)205 void TextAdapter::SetData(int16_t start, int16_t end)
206 {
207     if (start <= end) {
208         integerTextStart_ = start;
209         integerTextEnd_ = end;
210         dataMode_ = CONTINUOUS_INTEGER_MODE;
211     }
212 }
213 
GetCount()214 uint16_t TextAdapter::GetCount()
215 {
216     switch (dataMode_) {
217         case DYNAMIC_TEXT_MODE:
218             return dynamicText_.Size();
219         case CONTINUOUS_INTEGER_MODE:
220             return (integerTextStart_ <= integerTextEnd_) ? (integerTextEnd_ - integerTextStart_ + 1) : 0;
221         default:
222             return 0;
223     }
224 }
225 } // namespace OHOS
226