From d25650f5612ad3cb451e4f9bb2e8b3b2b18ce657 Mon Sep 17 00:00:00 2001 From: Brian Pugh Date: Thu, 20 Jun 2019 08:20:45 -0700 Subject: [PATCH 1/8] long text wordwrapping refactor --- src/lv_misc/lv_txt.c | 201 +++++++++++++++++++++++++++++++------------ 1 file changed, 148 insertions(+), 53 deletions(-) diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index 0fdbf22bc..f50c21641 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -8,6 +8,7 @@ *********************/ #include "lv_txt.h" #include "lv_math.h" +#include /********************* * DEFINES @@ -130,6 +131,133 @@ void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t * size_res->y -= line_space; } +/** + * Get the next word of text. A word is delimited by break characters. + * + * If the word cannot fit in the max_width space, obey LV_TXT_LINE_BREAK_LONG_* rules. + * + * If the next word cannot fit anything, return 0. + * + * If the first character is a break character, returns the next index. + * + * @param txt a '\0' terminated string + * @param font pointer to a font + * @param letter_space letter space + * @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid line breaks + * @param flags settings for the text from 'txt_flag_type' enum + * @param[out] word_w_ptr width (in pixels) of the parsed word. May be NULL. + * @return the index of the first char of the next word (in byte index not letter index. With UTF-8 they are different) + */ +static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, + lv_coord_t letter_space, lv_coord_t max_width, + lv_txt_flag_t flag, uint32_t *word_w_ptr) +{ + if(txt == NULL) return 0; + if(font == NULL) return 0; + + if(flag & LV_TXT_FLAG_EXPAND) max_width = LV_COORD_MAX; + + uint32_t i = 0; /* Iterating index into txt */ + uint32_t i_next = 0; /* */ + lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT; + uint32_t letter_w; + uint32_t letter = 0; /* Letter at i */ + uint32_t letter_next = 0; /* Letter at i_next */ + uint32_t word_len = 0; /* Number of characters in the transversed word */ + uint32_t break_index = NO_BREAK_FOUND; // only used for "long" words + uint32_t break_letter_count = 0; + lv_coord_t cur_w = 0; /* Pixel Width of transversed string */ + + letter_next = lv_txt_encoded_next(txt, &i_next); + printf("max width: %d\n", max_width); + + while(txt[i] != '\0') { + letter = letter_next; + i = i_next; + letter_next = lv_txt_encoded_next(txt, &i_next); + word_len++; + + /*Handle the recolor command*/ + if((flag & LV_TXT_FLAG_RECOLOR) != 0) { + if(lv_txt_is_cmd(&cmd_state, letter) != false) { + continue; /*Skip the letter is it is part of a command*/ + } + } + + /*Check the transversed string pixel width*/ + letter_w = lv_font_get_glyph_width(font, letter, letter_next); + cur_w += letter_w; + + /* Test if this character fits within max_width */ + if( break_index == NO_BREAK_FOUND && cur_w > max_width) { + printf("cur_w %d exceeds max_width %d\n", cur_w, max_width); + // break_index is now pointing at the character that doesn't fit + break_index = i; + lv_txt_encoded_prev(txt, &break_index); + break_letter_count = word_len - 1; + } + + /* Update the output width */ + if( word_w_ptr != NULL && break_index == NO_BREAK_FOUND ) { + *word_w_ptr = cur_w; + } + + /*Check for new line chars and breakchars*/ + if(letter == '\n' || letter == '\r' || is_break_char(letter)) { + // i is now pointing at the character after the word + printf("break found at %d\n", i); + word_len--; + break; + } + + if(letter_w > 0) { + cur_w += letter_space; + } + } + + /* Entire Word fits in the provided space */ + if( break_index == NO_BREAK_FOUND ) { + printf("nobreak\n"); + if(letter == '\r' && letter_next == '\n') return i_next; + return i; + } + + /* Word doesn't fit in provided space, but isn't "long" */ + if(word_len < LV_TXT_LINE_BREAK_LONG_LEN) { + printf("doesn't fit in space\n"); + if(word_w_ptr != NULL) *word_w_ptr = 0; + return 0; + } + + /* Word is "long," but insufficient amounts can fit in provided space */ + if(break_letter_count < LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN) { + printf("long, doesn't fit in space\n"); + if(word_w_ptr != NULL) *word_w_ptr = 0; + return 0; + } + + i = break_index; + + /* Word is a "long", but letters may need to be better distributed */ +#if 0 + { +#if 1 + printf("redistributing\n"); + while(i!=break_index){ + lv_txt_encoded_prev(txt, &i); + } +#else + int32_t n_move = LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN - (word_len - break_letter_count); + for(;n_move>0; n_move--){ + lv_txt_encoded_prev(txt, &i); + // todo: it would be appropriate to update the returned word width here + } +#endif + } +#endif + + return i; +} /** * Get the next line of text. Check line length and break chars too. @@ -148,67 +276,34 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, if(flag & LV_TXT_FLAG_EXPAND) max_width = LV_COORD_MAX; - uint32_t i = 0; - uint32_t i_next = 0; - lv_coord_t cur_w = 0; - uint32_t last_break = NO_BREAK_FOUND; - lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT; - uint32_t letter_w; - uint32_t letter = 0; - uint32_t letter_next = 0; + uint32_t i = 0; /* Iterating index into txt */ + uint32_t i_next = 0; /* */ + uint32_t letter = 0; /* Letter at i */ + uint32_t letter_next = 0; /* Letter at i_next */ letter_next = lv_txt_encoded_next(txt, &i_next); + printf("\n\n\n"); + while(txt[i] != '\0') { - letter = letter_next; - i = i_next; - letter_next = lv_txt_encoded_next(txt, &i_next); + //letter = letter_next; + //i = i_next; + //letter_next = lv_txt_encoded_next(txt, &i_next); - /*Handle the recolor command*/ - if((flag & LV_TXT_FLAG_RECOLOR) != 0) { - if(lv_txt_is_cmd(&cmd_state, letter) != false) { - continue; /*Skip the letter is it is part of a command*/ - } + uint32_t word_w = 0; + uint32_t advance = lv_txt_get_next_word(&txt[i], font, letter_space, + max_width, flag, &word_w); + printf("word_w: %d\n", word_w); + max_width -= word_w; + + if( advance == 0 ){ + if(i == 0) lv_txt_encoded_next(txt, &i); // prevent inf loops + break; } - /*Check for new line chars*/ - if(letter == '\n' || letter == '\r') { - /*Return with the first letter of the next line*/ - if(letter == '\r' && letter_next == '\n') return i_next; - else return i; - } else { /*Check the actual length*/ - letter_w = lv_font_get_glyph_width(font, letter, letter_next); - cur_w += letter_w; - - /*If the txt is too long then finish, this is the line end*/ - if(cur_w > max_width) { - /*If a break character was already found break there*/ - if(last_break != NO_BREAK_FOUND) { - i = last_break; - } else { - /* Now this character is out of the area so it will be first character of the next line*/ - /* But 'i' already points to the next character (because of lv_txt_utf8_next) step beck one*/ - lv_txt_encoded_prev(txt, &i); - } - - /* Do not let to return without doing nothing. - * Find at least one character (Avoid infinite loop )*/ - if(i == 0) lv_txt_encoded_next(txt, &i); - - return i; - } - /*If this char still can fit to this line then check if - * txt can be broken here later */ - else if(is_break_char(letter)) { - last_break = i; /*Save the first char index after break*/ - } - } - - if(letter_w > 0) { - cur_w += letter_space; - } + printf("Getting next word\n"); + i += advance; } - return i; } From 44b21977214b36a0576d14df1e0274cf368297c4 Mon Sep 17 00:00:00 2001 From: Brian Pugh Date: Sun, 23 Jun 2019 12:25:17 -0700 Subject: [PATCH 2/8] Mostly working long text; need to fix dangling newline and remove debugging code --- src/lv_core/lv_obj.c | 1 + src/lv_misc/lv_txt.c | 70 +++++++++++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 84e27aa30..afca08f83 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -13,6 +13,7 @@ #include "lv_disp.h" #include "../lv_themes/lv_theme.h" #include "../lv_draw/lv_draw.h" +#include "../lv_draw/lv_img_cache.h" #include "../lv_misc/lv_anim.h" #include "../lv_misc/lv_task.h" #include "../lv_misc/lv_fs.h" diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index f50c21641..ffccea6f8 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -8,7 +8,10 @@ *********************/ #include "lv_txt.h" #include "lv_math.h" + +// TODO: remove #include +#include /********************* * DEFINES @@ -152,13 +155,14 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, lv_coord_t letter_space, lv_coord_t max_width, lv_txt_flag_t flag, uint32_t *word_w_ptr) { - if(txt == NULL) return 0; + if(txt == NULL || txt[0] == '\0') return 0; if(font == NULL) return 0; if(flag & LV_TXT_FLAG_EXPAND) max_width = LV_COORD_MAX; uint32_t i = 0; /* Iterating index into txt */ uint32_t i_next = 0; /* */ + uint32_t i_next_next = 0; /* */ lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT; uint32_t letter_w; uint32_t letter = 0; /* Letter at i */ @@ -168,13 +172,19 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, uint32_t break_letter_count = 0; lv_coord_t cur_w = 0; /* Pixel Width of transversed string */ - letter_next = lv_txt_encoded_next(txt, &i_next); - printf("max width: %d\n", max_width); + letter = lv_txt_encoded_next(txt, &i_next); + i_next_next = i_next; + + if(letter == '\n' || letter == '\r' || is_break_char(letter)) { + //printf("pre_while_loop: %d\n", i_next); + return i_next; + } while(txt[i] != '\0') { - letter = letter_next; - i = i_next; - letter_next = lv_txt_encoded_next(txt, &i_next); + //printf("top of while %d\n", i); + letter_next = lv_txt_encoded_next(txt, &i_next_next); + //printf("i: %d i_next: %d i_next_next: %d txt[i]:\"%c\" letter:\"%c\"\n", i, i_next, i_next_next, txt[i], letter); + //assert(txt[i]==letter); word_len++; /*Handle the recolor command*/ @@ -187,13 +197,15 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, /*Check the transversed string pixel width*/ letter_w = lv_font_get_glyph_width(font, letter, letter_next); cur_w += letter_w; + //printf("%d BLOOP\n", __LINE__); /* Test if this character fits within max_width */ if( break_index == NO_BREAK_FOUND && cur_w > max_width) { - printf("cur_w %d exceeds max_width %d\n", cur_w, max_width); // break_index is now pointing at the character that doesn't fit break_index = i; - lv_txt_encoded_prev(txt, &break_index); + if(break_index > 0) { // zero is possible if first character doesn't fit in width + lv_txt_encoded_prev(txt, &break_index); + } break_letter_count = word_len - 1; } @@ -204,34 +216,35 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, /*Check for new line chars and breakchars*/ if(letter == '\n' || letter == '\r' || is_break_char(letter)) { - // i is now pointing at the character after the word - printf("break found at %d\n", i); word_len--; + //printf("meow %d %d\n", i, i_next); break; } if(letter_w > 0) { cur_w += letter_space; } + i = i_next; + i_next = i_next_next; + letter = letter_next; } /* Entire Word fits in the provided space */ if( break_index == NO_BREAK_FOUND ) { - printf("nobreak\n"); + //if( word_w_ptr != NULL && (letter == '\r' || letter == '\n')) *word_w_ptr = 0; if(letter == '\r' && letter_next == '\n') return i_next; + //printf("(%d): txt[i] \"%c\"\n", __LINE__, txt[i]); return i; } /* Word doesn't fit in provided space, but isn't "long" */ if(word_len < LV_TXT_LINE_BREAK_LONG_LEN) { - printf("doesn't fit in space\n"); if(word_w_ptr != NULL) *word_w_ptr = 0; return 0; } /* Word is "long," but insufficient amounts can fit in provided space */ if(break_letter_count < LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN) { - printf("long, doesn't fit in space\n"); if(word_w_ptr != NULL) *word_w_ptr = 0; return 0; } @@ -277,32 +290,35 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, if(flag & LV_TXT_FLAG_EXPAND) max_width = LV_COORD_MAX; uint32_t i = 0; /* Iterating index into txt */ - uint32_t i_next = 0; /* */ - uint32_t letter = 0; /* Letter at i */ - uint32_t letter_next = 0; /* Letter at i_next */ - letter_next = lv_txt_encoded_next(txt, &i_next); - - printf("\n\n\n"); - - while(txt[i] != '\0') { - //letter = letter_next; - //i = i_next; - //letter_next = lv_txt_encoded_next(txt, &i_next); + //printf("\n\n(%d): FULL_TEXT (len %d) \"%s\"\n", __LINE__, strlen(txt), txt); + while(txt[i] != '\0' && max_width > 0) { + //printf("(%d): MAX_WIDTH: %d\n", __LINE__, max_width); uint32_t word_w = 0; uint32_t advance = lv_txt_get_next_word(&txt[i], font, letter_space, max_width, flag, &word_w); - printf("word_w: %d\n", word_w); max_width -= word_w; + { //debug + printf("Word is %d long: \"", advance); + for(uint32_t j = 0; j < advance; j++){ + printf("%c", txt[i+j]); + } + printf("\"\n"); + } + if( advance == 0 ){ - if(i == 0) lv_txt_encoded_next(txt, &i); // prevent inf loops + if(i == 0) { + lv_txt_encoded_next(txt, &i); // prevent inf loops + printf("inf loop prevented\n"); + } break; } - printf("Getting next word\n"); i += advance; + + if(txt[i] == '\n') { printf("nl_break\n");break;} } return i; } From 2f5ec6befef6b44b8a38a72dc44f5cea7d198531 Mon Sep 17 00:00:00 2001 From: Brian Pugh Date: Sun, 23 Jun 2019 16:04:17 -0700 Subject: [PATCH 3/8] long text wrapping cleanup --- src/lv_misc/lv_txt.c | 62 ++++++++++++++------------------------------ 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index ffccea6f8..768e62908 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -175,16 +175,8 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, letter = lv_txt_encoded_next(txt, &i_next); i_next_next = i_next; - if(letter == '\n' || letter == '\r' || is_break_char(letter)) { - //printf("pre_while_loop: %d\n", i_next); - return i_next; - } - while(txt[i] != '\0') { - //printf("top of while %d\n", i); letter_next = lv_txt_encoded_next(txt, &i_next_next); - //printf("i: %d i_next: %d i_next_next: %d txt[i]:\"%c\" letter:\"%c\"\n", i, i_next, i_next_next, txt[i], letter); - //assert(txt[i]==letter); word_len++; /*Handle the recolor command*/ @@ -197,13 +189,12 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, /*Check the transversed string pixel width*/ letter_w = lv_font_get_glyph_width(font, letter, letter_next); cur_w += letter_w; - //printf("%d BLOOP\n", __LINE__); /* Test if this character fits within max_width */ if( break_index == NO_BREAK_FOUND && cur_w > max_width) { - // break_index is now pointing at the character that doesn't fit + /* break_index is now pointing at the character that doesn't fit */ break_index = i; - if(break_index > 0) { // zero is possible if first character doesn't fit in width + if(break_index > 0) { /* zero is possible if first character doesn't fit in width */ lv_txt_encoded_prev(txt, &break_index); } break_letter_count = word_len - 1; @@ -217,13 +208,13 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, /*Check for new line chars and breakchars*/ if(letter == '\n' || letter == '\r' || is_break_char(letter)) { word_len--; - //printf("meow %d %d\n", i, i_next); break; } if(letter_w > 0) { cur_w += letter_space; } + i = i_next; i_next = i_next_next; letter = letter_next; @@ -231,9 +222,7 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, /* Entire Word fits in the provided space */ if( break_index == NO_BREAK_FOUND ) { - //if( word_w_ptr != NULL && (letter == '\r' || letter == '\n')) *word_w_ptr = 0; - if(letter == '\r' && letter_next == '\n') return i_next; - //printf("(%d): txt[i] \"%c\"\n", __LINE__, txt[i]); + if( word_len == 0 || (letter == '\r' && letter_next == '\n') ) i = i_next; return i; } @@ -249,25 +238,16 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, return 0; } - i = break_index; - /* Word is a "long", but letters may need to be better distributed */ -#if 0 { -#if 1 - printf("redistributing\n"); - while(i!=break_index){ - lv_txt_encoded_prev(txt, &i); - } -#else + i = break_index; int32_t n_move = LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN - (word_len - break_letter_count); + /* Move pointer "i" backwards */ for(;n_move>0; n_move--){ lv_txt_encoded_prev(txt, &i); // todo: it would be appropriate to update the returned word width here } -#endif } -#endif return i; } @@ -291,35 +271,33 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, uint32_t i = 0; /* Iterating index into txt */ - //printf("\n\n(%d): FULL_TEXT (len %d) \"%s\"\n", __LINE__, strlen(txt), txt); - while(txt[i] != '\0' && max_width > 0) { - //printf("(%d): MAX_WIDTH: %d\n", __LINE__, max_width); uint32_t word_w = 0; uint32_t advance = lv_txt_get_next_word(&txt[i], font, letter_space, max_width, flag, &word_w); max_width -= word_w; - { //debug - printf("Word is %d long: \"", advance); - for(uint32_t j = 0; j < advance; j++){ - printf("%c", txt[i+j]); - } - printf("\"\n"); - } - if( advance == 0 ){ - if(i == 0) { - lv_txt_encoded_next(txt, &i); // prevent inf loops - printf("inf loop prevented\n"); - } + if(i == 0) lv_txt_encoded_next(txt, &i); // prevent inf loops break; } i += advance; - if(txt[i] == '\n') { printf("nl_break\n");break;} + if(txt[i] == '\n') break; } + + /* If this is the last of the string, make sure pointer is at NULL-terminator. + * This catches the case, for example of a string ending in "\n" */ + if(txt[i] != '\0'){ + uint32_t i_next = i; + int tmp; + uint32_t letter_next = lv_txt_encoded_next(txt, &i_next); //Gets current letter + tmp = i_next; + letter_next = lv_txt_encoded_next(txt, &i_next); // Gets subsequent + if(letter_next == '\0') return tmp; + } + return i; } From 2f95d4a0ca8c79fbad5f9af231e220cb45fa4b95 Mon Sep 17 00:00:00 2001 From: Brian Pugh Date: Sun, 23 Jun 2019 16:15:14 -0700 Subject: [PATCH 4/8] long text comment update --- src/lv_misc/lv_txt.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index 768e62908..5b82c7ee2 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -143,6 +143,16 @@ void lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t * * * If the first character is a break character, returns the next index. * + * Example calls from lv_txt_get_next_line() assuming sufficent max_width and + * txt = "Test text\n" + * 0123456789 + * + * Calls would be as follows: + * 1. Return i=4, pointing at breakchar ' ', for the string "Test" + * 2. Return i=5, since i=4 was a breakchar. + * 3. Return i=9, pointing at breakchar '\n' + * 4. Parenting lv_txt_get_next_line() would detect subsequent '\0' + * * @param txt a '\0' terminated string * @param font pointer to a font * @param letter_space letter space @@ -160,17 +170,15 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, if(flag & LV_TXT_FLAG_EXPAND) max_width = LV_COORD_MAX; - uint32_t i = 0; /* Iterating index into txt */ - uint32_t i_next = 0; /* */ - uint32_t i_next_next = 0; /* */ + uint32_t i = 0, i_next = 0, i_next_next = 0; /* Iterating index into txt */ lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT; - uint32_t letter_w; - uint32_t letter = 0; /* Letter at i */ + uint32_t letter = 0; /* Letter at i */ uint32_t letter_next = 0; /* Letter at i_next */ + lv_coord_t letter_w; + lv_coord_t cur_w = 0; /* Pixel Width of transversed string */ uint32_t word_len = 0; /* Number of characters in the transversed word */ - uint32_t break_index = NO_BREAK_FOUND; // only used for "long" words - uint32_t break_letter_count = 0; - lv_coord_t cur_w = 0; /* Pixel Width of transversed string */ + uint32_t break_index = NO_BREAK_FOUND; /* only used for "long" words */ + uint32_t break_letter_count = 0; /* Number of characters up to the long word break point */ letter = lv_txt_encoded_next(txt, &i_next); i_next_next = i_next; @@ -246,6 +254,7 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, for(;n_move>0; n_move--){ lv_txt_encoded_prev(txt, &i); // todo: it would be appropriate to update the returned word width here + // However, in current usage, this doesn't impact anything. } } @@ -273,8 +282,7 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, while(txt[i] != '\0' && max_width > 0) { uint32_t word_w = 0; - uint32_t advance = lv_txt_get_next_word(&txt[i], font, letter_space, - max_width, flag, &word_w); + uint32_t advance = lv_txt_get_next_word(&txt[i], font, letter_space, max_width, flag, &word_w); max_width -= word_w; if( advance == 0 ){ @@ -292,9 +300,9 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, if(txt[i] != '\0'){ uint32_t i_next = i; int tmp; - uint32_t letter_next = lv_txt_encoded_next(txt, &i_next); //Gets current letter + uint32_t letter_next = lv_txt_encoded_next(txt, &i_next); /*Gets current character*/ tmp = i_next; - letter_next = lv_txt_encoded_next(txt, &i_next); // Gets subsequent + letter_next = lv_txt_encoded_next(txt, &i_next); /*Gets subsequent character*/ if(letter_next == '\0') return tmp; } From a88cacb71e8810a196541c490d38f2463f29e1b8 Mon Sep 17 00:00:00 2001 From: Brian Pugh Date: Sun, 23 Jun 2019 16:21:03 -0700 Subject: [PATCH 5/8] Restore LV_TXT_LINE_BREAK_LONG_* defines in lv_conf_template.h and checker --- lv_conf_template.h | 10 ++++++++++ src/lv_conf_checker.h | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/lv_conf_template.h b/lv_conf_template.h index 2560a586f..935a65962 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -290,6 +290,16 @@ typedef void * lv_font_user_data_t; /*Can break (wrap) texts on these chars*/ #define LV_TXT_BREAK_CHARS " ,.;:-_" +/* If a character is at least this long, will break wherever "prettiest" */ +#define LV_TXT_LINE_BREAK_LONG_LEN 12 + +/* Minimum number of characters of a word to put on a line before a break */ +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 + +/* Minimum number of characters of a word to put on a line after a break */ +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 + + /*=================== * LV_OBJ SETTINGS *==================*/ diff --git a/src/lv_conf_checker.h b/src/lv_conf_checker.h index d8274e258..afa9dab50 100644 --- a/src/lv_conf_checker.h +++ b/src/lv_conf_checker.h @@ -405,6 +405,21 @@ #define LV_TXT_BREAK_CHARS " ,.;:-_" #endif +/* If a character is at least this long, will break wherever "prettiest" */ +#ifndef LV_TXT_LINE_BREAK_LONG_LEN +#define LV_TXT_LINE_BREAK_LONG_LEN 12 +#endif + +/* Minimum number of characters of a word to put on a line before a break */ +#ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 +#endif + +/* Minimum number of characters of a word to put on a line after a break */ +#ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 +#endif + /*=================== * LV_OBJ SETTINGS *==================*/ From d85efb99268934f0508bffdadafd12cbe21b2cd2 Mon Sep 17 00:00:00 2001 From: Brian Pugh Date: Sun, 23 Jun 2019 16:22:51 -0700 Subject: [PATCH 6/8] remove debugging lines --- src/lv_misc/lv_txt.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index 5b82c7ee2..386fa7581 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -9,10 +9,6 @@ #include "lv_txt.h" #include "lv_math.h" -// TODO: remove -#include -#include - /********************* * DEFINES *********************/ From ab4c2bcd93e12a58ec20f80f3e76f9c54bbddb92 Mon Sep 17 00:00:00 2001 From: Brian Pugh Date: Mon, 24 Jun 2019 09:27:19 -0700 Subject: [PATCH 7/8] long_txt fixed incorrect width calculation of break characters. --- src/lv_misc/lv_txt.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index 386fa7581..07850f210 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -190,31 +190,32 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, } } - /*Check the transversed string pixel width*/ letter_w = lv_font_get_glyph_width(font, letter, letter_next); cur_w += letter_w; + /* Always update the output width on the first character.. + * Must do this here incase first letter is a break character. */ + if( i == 0 && word_w_ptr != NULL) *word_w_ptr = cur_w; + /* Test if this character fits within max_width */ if( break_index == NO_BREAK_FOUND && cur_w > max_width) { - /* break_index is now pointing at the character that doesn't fit */ break_index = i; if(break_index > 0) { /* zero is possible if first character doesn't fit in width */ lv_txt_encoded_prev(txt, &break_index); } + /* break_index is now pointing at the character that doesn't fit */ break_letter_count = word_len - 1; } - /* Update the output width */ - if( word_w_ptr != NULL && break_index == NO_BREAK_FOUND ) { - *word_w_ptr = cur_w; - } - /*Check for new line chars and breakchars*/ if(letter == '\n' || letter == '\r' || is_break_char(letter)) { word_len--; break; } + /* Update the output width */ + if( word_w_ptr != NULL && break_index == NO_BREAK_FOUND ) *word_w_ptr = cur_w; + if(letter_w > 0) { cur_w += letter_space; } @@ -299,7 +300,7 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, uint32_t letter_next = lv_txt_encoded_next(txt, &i_next); /*Gets current character*/ tmp = i_next; letter_next = lv_txt_encoded_next(txt, &i_next); /*Gets subsequent character*/ - if(letter_next == '\0') return tmp; + if(letter_next == '\0') i = tmp; } return i; From f56cd37f65959c38352992508fe0d60495b97616 Mon Sep 17 00:00:00 2001 From: Brian Pugh Date: Mon, 24 Jun 2019 09:36:38 -0700 Subject: [PATCH 8/8] long_txt: moved first letter width update to more intuitive location --- src/lv_misc/lv_txt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index 07850f210..249c11d87 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -193,9 +193,6 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, letter_w = lv_font_get_glyph_width(font, letter, letter_next); cur_w += letter_w; - /* Always update the output width on the first character.. - * Must do this here incase first letter is a break character. */ - if( i == 0 && word_w_ptr != NULL) *word_w_ptr = cur_w; /* Test if this character fits within max_width */ if( break_index == NO_BREAK_FOUND && cur_w > max_width) { @@ -209,6 +206,9 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, /*Check for new line chars and breakchars*/ if(letter == '\n' || letter == '\r' || is_break_char(letter)) { + /* Update the output width on the first character if it fits. + * Must do this here incase first letter is a break character. */ + if(i == 0 && break_index == NO_BREAK_FOUND && word_w_ptr != NULL) *word_w_ptr = cur_w; word_len--; break; }