diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 38b2427ad..c9bee1008 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -1,7 +1,7 @@ # Contributing to Littlev Graphics Library First of all thank you for reading these guide before contributing! -In this guide you can read how can you help in developing the Littlev Graphic Library. These are not strict rules rather just suggestions. If you have a constructive idea just create pull request on this document! +In this guide you can read how can you help in developing the Littlev Graphic Library. If you have a constructive idea just create pull request on this document! ### Table Of Content * [Who can contribute?](#who-can-contribute) @@ -11,19 +11,17 @@ In this guide you can read how can you help in developing the Littlev Graphic Li * [How to suggest a feature?](#how-to-suggest-a-feature) * [How to implement a feature?](#how-to-implement-a-feature) * [Styling guide](#styling-guide) - * [Git Commit Messages](#Git-commit-messages) * [File format](#file-format) * [Functions](#functions) * [Variables](#variables) * [Defines](#defines) + * [Typedefs](#typedefs) * [Comments](#comments) * [Formatting](#formatting) ## Who can contribute? -Everybody is welcome in contributing independently from skills, programming level or any personal attribute. - -There are several ways to contribute in the graphics library like: +As graphical interfaces for embedded systems has an increasing relevance today. You also might find important to work with a good graphics library. Now - independently from skills, programming level or any personal attributes - you can influence the development of the graphics library with: * Report an issue * Suggest feature * Fix an issue @@ -31,11 +29,9 @@ There are several ways to contribute in the graphics library like: Please, take a look at [CODE_OF_CONDUCT](https://github.com/littlevgl/lvgl/blob/master/docs/CODE_OF_CONDUCT.md) +Continue reading to know how you can be part of the development! We are waiting for you! + ## How to report an issue? -There are 3 permanent branches: - * `master` for stable, released versions - * `beta` for developers, all feature branches merged here first - * `bugfix` for hotfixes, not new features ### Simple issue If you find an issue which is very simple to fix, and you fixed it, please send a pull request against `beta` branch. @@ -72,21 +68,15 @@ If you have a good and useful idea you can use GitHub issues to suggest a new fe After a discussion we figure out the specification of the new feature and the technical details/implementation possibilities. With the knowledge of how to do it somebody can implement the new feature. -The new feature should be in a new branch. - Keep in mind if you wouldn't like to do the implementation there is no guarantee that it will be ready in the new future. However if you would like to force it, take a look at this page: [Feature request service](http://www.gl.littlev.hu/services#feature) ## How to implement a feature? In [docs/TODO_MINOR.md](https://github.com/littlevgl/lvgl/blob/master/docs/TODO_MINOR.md) and [docs/TODO_PATCH.md](https://github.com/littlevgl/lvgl/blob/master/docs/TODO_PATCH.md) you can see some ideas which are waiting for somebody to realize them! If want to deal with a feature from this files, please start an issue and discusse the details. -## Styling guide +The new feature should be in a new branch. -### Git Commit Messages -* Use the present tense ("Add feature" not "Added feature") -* Use the imperative mood ("Move cursor to..." not "Moves cursor to...") -* Limit the first line to 72 characters or less -* Reference issues and pull requests liberally after the first line +## Styling guide ### File format Use [misc/templ/templ.c](https://github.com/littlevgl/misc/blob/master/templ/templ.c) and [misc/templ/templ.h](https://github.com/littlevgl/misc/blob/master/templ/templ.h) @@ -114,23 +104,32 @@ Names can be used freely. ### Variables * words sparated by '_' * always lower case -* one line one declaration (BAD: char x, y;) +* one line, one declaration (BAD: char x, y;) * use `` (*uint8_t*, *int32_t* etc) * declare variables when needed (not all at function start) * use the smallest required scope * variables in a file (outside functions) are always *static* * do not use global variables (use functions to set/get static variables) -### Defines +### Defines * always upper case * starts with *LV_* * followed by the modul: *OBJ*, *BTN* etc. * closed by the subject: *ANIM_TIME*, *VALUE_MIN*, *WIDTH_DEF* +### Typedefs +- prefer `typedef struct` instead of `struct name` +- prefer `typedef enum` instead of `enum name` +- types always lowercase speperated by '_' +- first word for public typedefs is *lv_...* +- next word identifies the modul: *lv_obj_...*, *lv_btn_...* +- always add closing *..._t* +- Examples: *lv_obj_t*, *lv_cont_layout_t* + ### Comments Before every function have a comment like this: -``` +```c /** * Return with the screen of an object * @param obj pointer to an object @@ -150,7 +149,7 @@ You should write **why** have you done this: ### Formatting Here is example to show bracket placing and using of white spaces: -``` +```c /** * Set a new text for a label. Memory will be allocated to store the text by the label. * @param label pointer to a label object diff --git a/docs/README.md b/docs/README.md index 25d631ea3..8cdde5624 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,9 +2,9 @@ ![LittlevGL cover](http://www.gl.littlev.hu/home/main_cover_small.png) -LittlevGL is a graphics library to create Graphical User Interfaces (GUI) on TFT, LCD or monochrome displays using microcontroller based embedded systems. +LittlevGL is a graphics library to create Graphical User Interfaces (GUI) on TFT, LCD or monochrome displays for microcontroller based embedded systems. -Transparency, anti-aliassing and smooth animations can be used with no double buffering so typically no external memories are required. +Transparency, anti-aliassing and smooth animations can be used with no double buffering so typically no external memories are required. Layouts, scrolling, word-wrapping, layers and other features make your job easier. The graphics library is written in C and it is completely hardware independent. You can even run it in a PC simulator without any embedded hardware. @@ -17,12 +17,18 @@ Homepage: http://gl.littlev.hu * Build GUI from simple graphical objects * Buttons, Labels, Images * Charts, Lists, Bars, Sliders, Text areas etc. +* Create or delete graphical object dynamically in run time * High level graphical features without double buffering * Antialiassing (font or full screen) * Animations * Transparency * Gradient colors * Smooth dragging and scrolling +* Built-in features + * Layouts (to auto-arrange items) + * Scrolling + * Auto-size (aligned to the content) + * Word wrapping * Layers * Customizable appearance with styles * Applications for complex tasks diff --git a/docs/TODO_MAJOR.md b/docs/TODO_MAJOR.md index 0e10a5b7e..dddf6501a 100644 --- a/docs/TODO_MAJOR.md +++ b/docs/TODO_MAJOR.md @@ -5,8 +5,20 @@ Major versions released typically when API changes are required Please create an issue to suggest a new feature instead of adding pull request to this file. ## v5 +**Architectural changes** - [ ] rename repository from *lvgl* to *littlevgl* +- [ ] rename repository from *proj_pc* to *pc_simulator* +- [ ] integrate *hal* in LittlevGL as a normal folder +- [ ] integrate *misc* in LittlevGl as submodule +- [ ] create a new repository for examples +- [ ] convert Applications into simple examples + +**API changes** - [ ] define renames: e.g. *USE_LV_BTN* to *LV_BTN_USE* - [ ] Remove LV_DOWNSCALE (LV_ANTIALIAS will be used instead) - [ ] *lv_ta_get_txt* rename to *lv_ta_get_text* -- [ ] btnm_action pass text instead of text_id +- [x] lv_btnm_set_styles for *tpr*, *trel* and *ina* too +- [x] LV_LABEL_LONG_DOTS removed, use LV_LABEL_LONG_ROLL instead +- [x] *lv_list_set_element_text_roll()* removed. +- [x] *lv_ddlist_set_fix_height()* instead of *auto_size* +- [x] rename *lv_dispi_...* to *lv_indev_proc_...* (except *lv_dispi_t* -> *lv_indev_t*) diff --git a/docs/TODO_MINOR.md b/docs/TODO_MINOR.md index 560328f7e..6631ddf05 100644 --- a/docs/TODO_MINOR.md +++ b/docs/TODO_MINOR.md @@ -8,18 +8,21 @@ Please create an issue to suggest a new feature instead of adding pull request t Here are ideas which are not assigned to a minor version yet: - label: add a horzintal line (e.g. underline or line through). - label long mode: dot begin -- music player app -- files app update: show content as text - GUI remote control - automatically build GUI from file (e.g. XML, JSON or HTML) -- lv_split: new object type, a hor. or ver. line for decoration purpose -- lv_valset: new object type, a label with "+" and "-" buttons -- lv_tabview: new object type to organise content with tabs -- lv_btngrp: new object type to display more buttons to choose an option from them -- lv_switch: new object type, turn on/off by tap (a little slider) -- lv_roller: new object type, a roller to select a value (like on smartphones) -## v4.2 +## v4.3 (in progress) +- [x] UTF-8 support +- [ ] lv_split: new object type, a hor. or ver. line for decoration purpose +- [ ] lv_valset: new object type, a label with "+" and "-" buttons +- [ ] lv_tabview: new object type to organise content with tabs +- [x] lv_sw: new object type, switch, turn on/off by tap (a little slider) +- [ ] lv_roller: new object type, a roller to select a value (like on smartphones) +- [x] lv_kb: new object type, Keyboard +- [x] lv_btnm: lv_btnm_set_tgl() to toggle last button +- [x] lv_ta: cursor types + +## v4.2 (released at: 17.08.2017) - [x] Double VDB support: one for rendering, another to transfer former rendered image to frame buffer in the background (e.g. with DMA) [#15](https://github.com/littlevgl/lvgl/issues/15) - [x] lv_group: to control without touch pad. Issue [#14](https://github.com/littlevgl/lvgl/issues/14) - [x] lv_page: scrl def fit modification: hor:false, ver:true, and always set width to parent width diff --git a/docs/TODO_PATCH.md b/docs/TODO_PATCH.md index 12d0e3851..0d25d2c40 100644 --- a/docs/TODO_PATCH.md +++ b/docs/TODO_PATCH.md @@ -8,7 +8,14 @@ The bugfixes of the still not released version are in `beta` branche. ## Contributing Please create an issue to introduce a bug instead of adding pull request to this file. + ## Next release +- [x] lv_btnm: check hide code (\177) at 0. byte position too (if width is not specified) +- [ ] lv_img: define *lv_img_raw_header* in *lv_draw.h* because now lv_img can't be disabled +- [ ] lv_list: ignore image related things when *lv_img* is not enebled +- [ ] lv_ta: fix hegiht if *one_line* and *FONT_ANTIALIAS* + +## v4.2 (released at: 17.08.2017) - [x] lv_slider: don't let indicator or bar to disappear because of hpad/vpad - [x] lv_ta: memory leak if deleted in password mode - [x] lv_list: work without *lv_img* by ignore the image file name parameter of *lv_list_add()* diff --git a/lv_obj/lv_obj.c b/lv_obj/lv_obj.c index 76172205b..786cb9b79 100644 --- a/lv_obj/lv_obj.c +++ b/lv_obj/lv_obj.c @@ -809,6 +809,9 @@ void lv_obj_set_style(lv_obj_t * obj, lv_style_t * style) /*Send a signal about style change to every children with NULL style*/ lv_child_refr_style(obj); + /*Notify the object about the style change too*/ + lv_obj_refr_style(obj); + } /** @@ -1527,7 +1530,7 @@ static void lv_child_refr_style(lv_obj_t * obj) while(child != NULL) { if(child->style_p == NULL) { lv_child_refr_style(child); /*Check children too*/ - lv_obj_refr_style(obj); /*Send a style change signal to the object*/ + lv_obj_refr_style(child); /*Notify the child about the style change*/ } else if(child->style_p->glass) { /*Children with 'glass' parent might be effected if their style == NULL*/ lv_child_refr_style(child); diff --git a/lv_objx/lv_btn.c b/lv_objx/lv_btn.c index ddfb22be7..f6e1ee5ef 100644 --- a/lv_objx/lv_btn.c +++ b/lv_objx/lv_btn.c @@ -295,7 +295,7 @@ void lv_btn_set_lpr_rep_action(lv_obj_t * btn, lv_action_t lpr_rep_action) } /** - * Set styles of a button is each state + * Set styles of a button is each state. Use NULL for any style which are not be changed. * @param btn pointer to button object * @param rel pointer to a style for releases state * @param pr pointer to a style for pressed state @@ -308,14 +308,18 @@ void lv_btn_set_styles(lv_obj_t * btn, lv_style_t * rel, lv_style_t * pr, lv_style_t * ina) { lv_btn_ext_t * ext = lv_obj_get_ext(btn); - ext->styles[LV_BTN_STATE_REL] = rel; - ext->styles[LV_BTN_STATE_PR] = pr; - ext->styles[LV_BTN_STATE_TREL] = trel; - ext->styles[LV_BTN_STATE_TPR] = tpr; - ext->styles[LV_BTN_STATE_INA] = ina; + + if(rel != NULL) ext->styles[LV_BTN_STATE_REL] = rel; + + if(pr != NULL) ext->styles[LV_BTN_STATE_PR] = pr; + + if(trel) ext->styles[LV_BTN_STATE_TREL] = trel; + + if(tpr) ext->styles[LV_BTN_STATE_TPR] = tpr; + + if(ina) ext->styles[LV_BTN_STATE_INA] = ina; lv_obj_set_style(btn, ext->styles[ext->state]); - } /*===================== diff --git a/lv_objx/lv_cont.c b/lv_objx/lv_cont.c index 793fb1447..f754ba847 100644 --- a/lv_objx/lv_cont.c +++ b/lv_objx/lv_cont.c @@ -116,24 +116,18 @@ bool lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param) /* The object can be deleted so check its validity and then * make the object specific signal handling */ if(valid != false) { - switch(sign) { - case LV_SIGNAL_STYLE_CHG: /*Recalculate the padding if the style changed*/ + if(sign == LV_SIGNAL_STYLE_CHG) { /*Recalculate the padding if the style changed*/ lv_cont_refr_layout(cont); lv_cont_refr_autofit(cont); - break; - case LV_SIGNAL_CHILD_CHG: + } else if(sign == LV_SIGNAL_CHILD_CHG) { lv_cont_refr_layout(cont); lv_cont_refr_autofit(cont); - break; - case LV_SIGNAL_CORD_CHG: - if(lv_obj_get_width(cont) != area_get_width(param) || - lv_obj_get_height(cont) != area_get_height(param)) { + } else if(sign == LV_SIGNAL_CORD_CHG) { + if(lv_obj_get_width(cont) != area_get_width(param) || + lv_obj_get_height(cont) != area_get_height(param)) { lv_cont_refr_layout(cont); lv_cont_refr_autofit(cont); } - break; - default: - break; } } diff --git a/lv_objx/lv_page.c b/lv_objx/lv_page.c index fa95a22c0..bf8d2c81f 100644 --- a/lv_objx/lv_page.c +++ b/lv_objx/lv_page.c @@ -157,6 +157,8 @@ bool lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) lv_style_t * style = lv_obj_get_style(page); if(lv_cont_get_hfit(ext->scrl) == false) { lv_obj_set_width(ext->scrl, lv_obj_get_width(page) - 2 * style->hpad); + } else { + ext->scrl->signal_f(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->cords); } if(ext->sb_mode == LV_PAGE_SB_MODE_ON) { @@ -172,8 +174,8 @@ bool lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) lv_style_t * style = lv_obj_get_style(page); /*Refresh the scrollbar and notify the scrl if the size is changed*/ if(ext->scrl != NULL && - (lv_obj_get_width(page) != area_get_width(param) || - lv_obj_get_height(page) != area_get_height(param))) { + (lv_obj_get_width(page) != area_get_width(param) || + lv_obj_get_height(page) != area_get_height(param))) { if(lv_cont_get_hfit(ext->scrl) == false) { lv_obj_set_width(ext->scrl, lv_obj_get_width(page) - 2 * style->hpad); @@ -181,9 +183,9 @@ bool lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param) ext->scrl->signal_f(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->cords); - /*The scrollbars are important olny if they are visible now*/ + /*The scrollbars are important only if they are visible now*/ if(ext->sbh_draw != 0 || ext->sbv_draw != 0) - lv_page_sb_refresh(page); + lv_page_sb_refresh(page); } } else if(sign == LV_SIGNAL_PRESSED) { @@ -224,6 +226,12 @@ bool lv_page_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param) lv_page_ext_t * page_ext = lv_obj_get_ext(page); if(sign == LV_SIGNAL_CORD_CHG) { + + /*Be sure the width of the scrollable is correct*/ + if(lv_cont_get_hfit(scrl) == false) { + lv_obj_set_width(scrl, lv_obj_get_width(page) - 2 * page_style->hpad); + } + cord_t new_x; cord_t new_y; bool refr_x = false; @@ -278,10 +286,6 @@ bool lv_page_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param) } lv_page_sb_refresh(page); - } else if(sign == LV_SIGNAL_CORD_CHG) { - if(lv_cont_get_hfit(scrl) == false) { - lv_obj_set_width(scrl, lv_obj_get_width(page) - 2 * page_style->hpad); - } } else if(sign == LV_SIGNAL_DRAG_BEGIN) { if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG ) { cord_t sbh_pad = MATH_MAX(page_ext->sb_width, page_style->hpad); diff --git a/lv_objx/lv_ta.c b/lv_objx/lv_ta.c index 0fae18055..83afcb256 100644 --- a/lv_objx/lv_ta.c +++ b/lv_objx/lv_ta.c @@ -172,9 +172,16 @@ bool lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param) } else if(sign == LV_SIGNAL_STYLE_CHG) { if(ext->label) { lv_obj_t * scrl = lv_page_get_scrl(ta); + lv_style_t * style_ta = lv_obj_get_style(ta); lv_style_t * style_scrl = lv_obj_get_style(scrl); - lv_obj_set_width(ext->label, lv_obj_get_width(scrl) - 2 * style_scrl->hpad); - lv_obj_set_pos(ext->label, style_scrl->hpad, style_scrl->vpad); + if(ext->one_line) { /*In one line mode refresh the Text Area height because 'vpad' can modify it*/ + lv_style_t * style_label = lv_obj_get_style(ext->label); + cord_t font_h = font_get_height(style_label->font) >> FONT_ANTIALIAS; + lv_obj_set_height(ta, font_h + (style_ta->vpad + style_scrl->vpad) * 2); + } else { /*In not one line mode refresh the Label width because 'hpad' can modify it*/ + lv_obj_set_width(ext->label, lv_obj_get_width(scrl) - 2 * style_scrl->hpad); + lv_obj_set_pos(ext->label, style_scrl->hpad, style_scrl->vpad); /*Be sure the Label is in the correct position*/ + } lv_label_set_text(ext->label, NULL); lv_obj_refr_ext_size(lv_page_get_scrl(ta)); @@ -670,12 +677,13 @@ void lv_ta_set_one_line(lv_obj_t * ta, bool en) if(en != false) { lv_ta_ext_t * ext = lv_obj_get_ext(ta); lv_style_t * style_ta = lv_obj_get_style(ta); + lv_style_t * style_scrl = lv_obj_get_style(lv_page_get_scrl(ta)); lv_style_t * style_label = lv_obj_get_style(ext->label); cord_t font_h = font_get_height(style_label->font) >> FONT_ANTIALIAS; ext->one_line = 1; lv_cont_set_fit(lv_page_get_scrl(ta), true, true); - lv_obj_set_height(ta, font_h + style_ta->vpad * 2); + lv_obj_set_height(ta, font_h + (style_ta->vpad + style_scrl->vpad) * 2); lv_label_set_long_mode(ext->label, LV_LABEL_LONG_EXPAND); lv_label_set_no_break(ext->label, true); lv_obj_set_pos(lv_page_get_scrl(ta), style_ta->hpad, style_ta->vpad); @@ -859,6 +867,8 @@ static bool lv_ta_scrling_design(lv_obj_t * scrl, const area_t * mask, lv_design cur_style.radius = 0; cur_style.empty = 0; cur_style.opa = OPA_COVER; + cur_style.hpad = 0; + cur_style.vpad = 0; } uint16_t cur_pos = lv_ta_get_cursor_pos(ta); @@ -903,16 +913,16 @@ static bool lv_ta_scrling_design(lv_obj_t * scrl, const area_t * mask, lv_design /*Draw he cursor according to the type*/ area_t cur_area; if(ta_ext->cursor_type == LV_TA_CURSOR_LINE) { - cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1 - (cur_style.line_width >> 1) - (cur_style.line_width & 0x1); - cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1; - cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + (cur_style.line_width >> 1); - cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 + letter_h; + cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1 + cur_style.hpad - (cur_style.line_width >> 1) - (cur_style.line_width & 0x1); + cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1 + cur_style.vpad; + cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + cur_style.hpad + (cur_style.line_width >> 1); + cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 + cur_style.vpad + letter_h; lv_draw_rect(&cur_area, mask, &cur_style); } else if(ta_ext->cursor_type == LV_TA_CURSOR_BLOCK) { - cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1; - cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1; - cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + letter_w; - cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 + letter_h; + cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1 - cur_style.hpad; + cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1 - cur_style.vpad; + cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + cur_style.hpad + letter_w; + cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 + cur_style.vpad + letter_h; lv_draw_rect(&cur_area, mask, &cur_style); @@ -925,22 +935,24 @@ static bool lv_ta_scrling_design(lv_obj_t * scrl, const area_t * mask, lv_design char letter_buf[8] = {0}; memcpy(letter_buf, &txt[byte_pos], txt_utf8_size(txt[byte_pos])); #endif + cur_area.x1 += cur_style.hpad; + cur_area.y1 += cur_style.vpad; lv_draw_label(&cur_area, mask, &cur_style, letter_buf, TXT_FLAG_NONE, 0); } else if(ta_ext->cursor_type == LV_TA_CURSOR_OUTLINE) { - cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1; - cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1; - cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + letter_w; - cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 + letter_h; + cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1 - cur_style.hpad; + cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1 - cur_style.vpad; + cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + cur_style.hpad + letter_w; + cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 - cur_style.vpad+ letter_h; cur_style.empty = 1; if(cur_style.bwidth == 0) cur_style.bwidth = 1 * LV_DOWNSCALE; /*Be sure the border will be drawn*/ lv_draw_rect(&cur_area, mask, &cur_style); } else if(ta_ext->cursor_type == LV_TA_CURSOR_UNDERLINE) { - cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1; - cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1 + letter_h - (cur_style.line_width >> 1); - cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + letter_w; - cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 + letter_h + (cur_style.line_width >> 1) + (cur_style.line_width & 0x1); + cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1 + cur_style.hpad; + cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1 + cur_style.vpad + letter_h - (cur_style.line_width >> 1); + cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + cur_style.hpad + letter_w; + cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 + cur_style.vpad + letter_h + (cur_style.line_width >> 1) + (cur_style.line_width & 0x1); lv_draw_rect(&cur_area, mask, &cur_style); }