• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "text_label.h"
16 #include <cstdio>
17 #include <iostream>
18 #include <linux/input.h>
19 #include <string>
20 #include "log/log.h"
21 #include "png.h"
22 #include "securec.h"
23 #include "updater_ui_const.h"
24 
25 namespace updater {
TextLabel(int mStartX,int mStartY,int w,int h,Frame * mparent)26 TextLabel::TextLabel(int mStartX, int mStartY, int w, int h, Frame *mparent)
27 {
28     startX_ = mStartX;
29     startY_ = mStartY;
30     this->CreateBuffer(w, h, View::PixelFormat::BGRA888);
31     parent_ = mparent;
32     parent_->ViewRegister(this);
33 
34     SetFocusAble(true);
35     outlineColor_.r = 0x00;
36     outlineColor_.g = 0x00;
37     outlineColor_.b = 0x00;
38     outlineColor_.a = 0x00;
39     boldTopLine_ = false;
40     boldTopLine_ = false;
41 
42     const char midAlpha = 0xAA;
43     actionBgColor_.r = 0x00;
44     actionBgColor_.g = 0x00;
45     actionBgColor_.b = 0x00;
46     actionBgColor_.a = midAlpha;
47 
48     const char maxAlpha = 0xff;
49     normalBgColor_.r = 0x00;
50     normalBgColor_.g = 0x00;
51     normalBgColor_.b = 0x00;
52     normalBgColor_.a = maxAlpha;
53 
54     const char maxLevel = 0xff;
55     textColor_.r = maxLevel;
56     textColor_.g = maxLevel;
57     textColor_.b = maxLevel;
58     textColor_.a = maxLevel;
59 
60     if (memset_s(textBuf_, MAX_TEXT_SIZE + 1, 0, MAX_TEXT_SIZE) != 0) {
61         LOG(WARNING) << "clear buffer failed";
62     }
63     InitFont();
64 }
65 
SetFont(FontType fType)66 void TextLabel::SetFont(FontType fType)
67 {
68     fontType_ = fType;
69     InitFont();
70     OnDraw();
71 }
72 
PngInitSet(png_structp fontPngPtr,FILE * fp,int size,png_infop fontInfoPtr)73 static void PngInitSet(png_structp fontPngPtr, FILE *fp, int size, png_infop fontInfoPtr)
74 {
75     png_init_io(fontPngPtr, fp);
76     png_set_sig_bytes(fontPngPtr, size);
77     png_read_info(fontPngPtr, fontInfoPtr);
78     return;
79 }
80 
CheckInitFont(png_structp fontPngPtr,FILE * fp,png_infop fontInfoPtr)81 static void CheckInitFont(png_structp fontPngPtr, FILE *fp, png_infop fontInfoPtr)
82 {
83     png_destroy_read_struct(&fontPngPtr, &fontInfoPtr, 0);
84     if (fp != nullptr) {
85         fclose(fp);
86         fp = nullptr;
87     }
88 }
89 
PNGReadRow(png_uint_32 fontWidth,png_uint_32 fontHeight,png_structp fontPngPtr,char * fontBuf)90 static void PNGReadRow(png_uint_32 fontWidth, png_uint_32 fontHeight, png_structp fontPngPtr, char *fontBuf)
91 {
92     if ((fontWidth > MAX_FONT_BUFFER_SIZE_HW) || (fontHeight > MAX_FONT_BUFFER_SIZE_HW)) {
93         LOG(ERROR) << "font file size is too big!";
94         return;
95     }
96     for (unsigned int y = 0; y < fontHeight; y++) {
97         uint8_t* pRow = reinterpret_cast<uint8_t *>((fontBuf) + y * MAX_FONT_BUFFER_SIZE_HW);
98         png_read_row(fontPngPtr, pRow, nullptr);
99     }
100     return;
101 }
102 
InitFont()103 void TextLabel::InitFont()
104 {
105     char resPath[MAX_TEXT_SIZE + 1];
106     png_infop fontInfoPtr = nullptr;
107     png_uint_32 fontWidth = 0;
108     png_uint_32 fontHeight = 0;
109     png_structp fontPngPtr = nullptr;
110     int fontBitDepth = 0;
111     int fontColorType = 0;
112     UPDATER_CHECK_ONLY_RETURN(!memset_s(resPath, MAX_TEXT_SIZE + offset_, 0, MAX_TEXT_SIZE + 1), return);
113     switch (fontType_) {
114         case DEFAULT_FONT:
115             UPDATER_CHECK_ONLY_RETURN(snprintf_s(resPath, sizeof(resPath), sizeof(resPath) -1, "/resources/%s.png",
116                 DEFAULT_FONT_NAME.c_str()) != -1, return);
117             break;
118         default:
119             UPDATER_CHECK_ONLY_RETURN(snprintf_s(resPath, sizeof(resPath), sizeof(resPath)-1, "/resources/%s.png",
120                 DEFAULT_FONT_NAME.c_str()) != -1, return);
121             break;
122     }
123     FILE* fp = fopen(resPath, "rb");
124     UPDATER_ERROR_CHECK(fp, "open font failed!", return);
125     uint8_t header[headerNumber_];
126     size_t bytesRead = fread(header, 1, sizeof(header), fp);
127     UPDATER_ERROR_CHECK(bytesRead == sizeof(header), "read header failed!", fclose(fp); return);
128     if (png_sig_cmp(header, 0, sizeof(header))) {
129         LOG(ERROR) << "cmp header failed!";
130         fclose(fp);
131         return;
132     }
133     fontPngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
134     UPDATER_ERROR_CHECK(fontPngPtr, "creat font ptr_ failed!", fclose(fp); return);
135     fontInfoPtr = png_create_info_struct(fontPngPtr);
136     if (fontInfoPtr == nullptr) {
137         png_destroy_read_struct(&fontPngPtr, nullptr, nullptr);
138         fclose(fp);
139         return;
140     }
141     PngInitSet(fontPngPtr, fp, sizeof(header), fontInfoPtr);
142     png_get_IHDR(fontPngPtr, fontInfoPtr, &fontWidth, &fontHeight, &fontBitDepth, &fontColorType,
143         nullptr, nullptr, nullptr);
144     png_byte fontChannels = png_get_channels(fontPngPtr, fontInfoPtr);
145     if (fontBitDepth <= defaultFontBitDepth_ && fontChannels == 1 && fontColorType == PNG_COLOR_TYPE_GRAY) {
146         png_set_expand_gray_1_2_4_to_8(fontPngPtr);
147     }
148     fontWidth_ = fontWidth / defaultFontWidth_;
149     fontHeight_ = fontHeight >> 1;
150     PNGReadRow(fontWidth_, fontHeight_, fontPngPtr, fontBuf_);
151     CheckInitFont(fontPngPtr, fp, fontInfoPtr);
152 }
153 
SetText(const char * str)154 void TextLabel::SetText(const char *str)
155 {
156     UPDATER_CHECK_ONLY_RETURN(!memset_s(textBuf_, MAX_TEXT_SIZE + 1, 0, MAX_TEXT_SIZE), return);
157     OnDraw();
158     UPDATER_CHECK_ONLY_RETURN(!memcpy_s(textBuf_, MAX_TEXT_SIZE + 1, str, strlen(const_cast<char*>(str))), return);
159     OnDraw();
160 }
161 
OnDraw()162 void TextLabel::OnDraw()
163 {
164     std::unique_lock<std::mutex> locker(mutex_);
165     SyncBuffer();
166     if (IsSelected()) {
167         DrawFocus();
168     }
169     DrawOutline();
170     DrawText();
171     if (parent_ != nullptr) {
172         parent_->OnDraw();
173     }
174 }
175 
SetOutLineBold(bool topBold,bool bottomBold)176 void TextLabel::SetOutLineBold(bool topBold, bool bottomBold)
177 {
178     boldTopLine_ = topBold;
179     boldBottomLine_ = bottomBold;
180     OnDraw();
181 }
182 
DrawOutline()183 void TextLabel::DrawOutline()
184 {
185     void *tmpBuf = GetBuffer();
186     auto *pixelBuf = static_cast<BRGA888Pixel*>(tmpBuf);
187     for (int i = 0; i < viewWidth_; i++) {
188         if (boldTopLine_) {
189             pixelBuf[i].r = outlineColor_.r;
190             pixelBuf[i].g = outlineColor_.g;
191             pixelBuf[i].b = outlineColor_.b;
192             pixelBuf[i].a = outlineColor_.a;
193 
194             pixelBuf[viewWidth_ + i].r = outlineColor_.r;
195             pixelBuf[viewWidth_ + i].g = outlineColor_.g;
196             pixelBuf[viewWidth_ + i].b = outlineColor_.b;
197             pixelBuf[viewWidth_ + i].a = outlineColor_.a;
198         }
199 
200         const int lines = 2;
201         if (boldBottomLine_) {
202             pixelBuf[(viewHeight_ - lines) * viewWidth_ + i].r = outlineColor_.r;
203             pixelBuf[(viewHeight_ - lines) * viewWidth_ + i].g = outlineColor_.g;
204             pixelBuf[(viewHeight_ - lines) * viewWidth_ + i].b = outlineColor_.b;
205             pixelBuf[(viewHeight_ - lines) * viewWidth_ + i].a = outlineColor_.a;
206             pixelBuf[(viewHeight_ - 1) * viewWidth_ + i].r = outlineColor_.r;
207             pixelBuf[(viewHeight_ - 1) * viewWidth_ + i].g = outlineColor_.g;
208             pixelBuf[(viewHeight_ - 1) * viewWidth_ + i].b = outlineColor_.b;
209             pixelBuf[(viewHeight_ - 1) * viewWidth_ + i].a = outlineColor_.a;
210         }
211     }
212 }
213 
SetTextColor(BRGA888Pixel color)214 void TextLabel::SetTextColor(BRGA888Pixel color)
215 {
216     textColor_.r = color.r;
217     textColor_.g = color.g;
218     textColor_.b = color.b;
219     textColor_.a = color.a;
220 }
221 
SetTextAlignmentMethod(AlignmentMethod methodH,AlignmentMethod methodV)222 void TextLabel::SetTextAlignmentMethod(AlignmentMethod methodH, AlignmentMethod methodV)
223 {
224     fontAligMethodLevel_ = methodH;
225     fontAligMethodUpright_ = methodV;
226 }
227 
SetOnClickCallback(ClickCallback cb)228 void TextLabel::SetOnClickCallback(ClickCallback cb)
229 {
230     callBack_ = cb;
231 }
232 
DrawText()233 void TextLabel::DrawText()
234 {
235     void *tmpBuf = GetBuffer();
236     int textSx = 0;
237     int textSy = 0;
238     switch (fontAligMethodUpright_) {
239         case ALIGN_CENTER:
240             textSy = (viewHeight_ - fontHeight_) / MEDIAN_NUMBER;
241             break;
242         case ALIGN_TO_TOP:
243             textSy = 0;
244             break;
245         default:
246             break;
247     }
248 
249     const int minPosition = 10;
250     const int average = 2;
251     switch (fontAligMethodLevel_) {
252         case ALIGN_CENTER:
253             textSx = (viewWidth_ - (strlen(textBuf_) * fontWidth_)) / average;
254             UPDATER_CHECK_ONLY_RETURN(textSx >= minPosition, textSx = minPosition);
255             break;
256         case ALIGN_TO_LEFT:
257             textSx = minPosition;
258             break;
259         default:
260             break;
261     }
262     unsigned char ch;
263     char* s = textBuf_;
264     while ((ch = *s++)) {
265         UPDATER_CHECK_ONLY_RETURN(!(ch < ' ' || ch > '~'), ch = '?');
266         auto *srcP = reinterpret_cast<uint8_t*>(static_cast<char*>(fontBuf_) + ((ch - ' ') * fontWidth_));
267         auto *dstP = reinterpret_cast<BRGA888Pixel*>(static_cast<char*>(tmpBuf) + (textSy * viewWidth_ + textSx) *
268             sizeof(BRGA888Pixel));
269         for (unsigned int j = 0; j < fontHeight_; j++) {
270             for (unsigned int i = 0; i < fontWidth_; i++) {
271                 uint8_t a = srcP[i];
272                 if (a > 0) {
273                     dstP[i].r = textColor_.r;
274                     dstP[i].g = textColor_.g;
275                     dstP[i].b = textColor_.b;
276                     dstP[i].a = textColor_.a;
277                 }
278             }
279             srcP += MAX_FONT_BUFFER_SIZE_HW;
280             dstP = dstP + viewWidth_;
281         }
282         textSx += fontWidth_;
283     }
284 }
285 
DrawFocus()286 void TextLabel::DrawFocus()
287 {
288     BRGA888Pixel pixBuf[viewWidth_];
289     for (int a = 0; a < viewWidth_; a++) {
290         pixBuf[a].r = actionBgColor_.r;
291         pixBuf[a].g = actionBgColor_.g;
292         pixBuf[a].b = actionBgColor_.b;
293         pixBuf[a].a = actionBgColor_.a;
294     }
295     void *viewBgBuf = GetBuffer();
296     for (int i = 0; i < viewHeight_; i++) {
297         UPDATER_CHECK_ONLY_RETURN(!memcpy_s(static_cast<char*>(static_cast<char*>(viewBgBuf) + i * viewWidth_ *
298             sizeof(BRGA888Pixel)), viewWidth_ * sizeof(BRGA888Pixel) + 1, reinterpret_cast<char*>(pixBuf),
299             viewWidth_ * sizeof(BRGA888Pixel)), return);
300     }
301 }
302 
OnKeyEvent(int key)303 void TextLabel::OnKeyEvent(int key)
304 {
305     LOG(INFO) << "OnKeyEvent !";
306     switch (key) {
307         case KEY_POWER:
308             if (callBack_ != nullptr) {
309                 callBack_(GetViewId());
310             }
311             break;
312         default:
313             break;
314     }
315 }
316 } // namespace updater
317