From 32d742cf520678572c1328db9d29fb981f231dc0 Mon Sep 17 00:00:00 2001 From: guoweilkd <35251456+guoweilkd@users.noreply.github.com> Date: Wed, 19 May 2021 19:27:09 +0800 Subject: [PATCH] fix encoded letter bug (#2252) Co-authored-by: guowei15 --- src/draw/lv_draw_label.c | 6 +++--- src/misc/lv_txt.c | 12 ++++++++++-- src/misc/lv_txt.h | 11 +++++++++++ src/widgets/lv_label.c | 19 ++++++++----------- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/draw/lv_draw_label.c b/src/draw/lv_draw_label.c index 23fab20f1..bc99cd577 100644 --- a/src/draw/lv_draw_label.c +++ b/src/draw/lv_draw_label.c @@ -261,9 +261,9 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area #endif } - uint32_t letter = _lv_txt_encoded_next(bidi_txt, &i); - uint32_t letter_next = _lv_txt_encoded_next(&bidi_txt[i], NULL); - + uint32_t letter; + uint32_t letter_next; + _lv_txt_encoded_letter_next_2(bidi_txt, &letter, &letter_next, &i); /*Handle the re-color command*/ if((dsc->flag & LV_TEXT_FLAG_RECOLOR) != 0) { if(letter == (uint32_t)LV_TXT_COLOR_CMD[0]) { diff --git a/src/misc/lv_txt.c b/src/misc/lv_txt.c index 9c400ce06..fa2bf0be9 100644 --- a/src/misc/lv_txt.c +++ b/src/misc/lv_txt.c @@ -366,8 +366,10 @@ lv_coord_t lv_txt_get_width(const char * txt, uint32_t length, const lv_font_t * if(length != 0) { while(i < length) { - uint32_t letter = _lv_txt_encoded_next(txt, &i); - uint32_t letter_next = _lv_txt_encoded_next(&txt[i], NULL); + uint32_t letter; + uint32_t letter_next; + _lv_txt_encoded_letter_next_2(txt, &letter, &letter_next, &i); + if((flag & LV_TEXT_FLAG_RECOLOR) != 0) { if(_lv_txt_is_cmd(&cmd_state, letter) != false) { continue; @@ -525,6 +527,12 @@ char * _lv_txt_set_text_vfmt(const char * fmt, va_list ap) return text; } +void _lv_txt_encoded_letter_next_2(const char * txt, uint32_t * letter, uint32_t * letter_next, uint32_t *ofs) +{ + *letter = _lv_txt_encoded_next(txt, ofs); + *letter_next = *letter != '\0' ? _lv_txt_encoded_next(&txt[*ofs], NULL) : 0; +} + #if LV_TXT_ENC == LV_TXT_ENC_UTF8 /******************************* * UTF-8 ENCODER/DECODER diff --git a/src/misc/lv_txt.h b/src/misc/lv_txt.h index 38c7e8a0e..c12bd1769 100644 --- a/src/misc/lv_txt.h +++ b/src/misc/lv_txt.h @@ -143,6 +143,17 @@ void _lv_txt_cut(char * txt, uint32_t pos, uint32_t len); */ char * _lv_txt_set_text_vfmt(const char * fmt, va_list ap); +/** + * Decode two encoded character from a string. + * @param txt pointer to '\0' terminated string + * @param letter the first decoded Unicode character or 0 on invalid data code + * @param letter_next the second decoded Unicode character or 0 on invalid data code + * @param ofs start index in 'txt' where to start. + * After the call it will point to the next encoded char in 'txt'. + * NULL to use txt[0] as index + */ +void _lv_txt_encoded_letter_next_2(const char * txt, uint32_t * letter, uint32_t * letter_next, uint32_t *ofs); + /*************************************************************** * GLOBAL FUNCTION POINTERS FOR CHARACTER ENCODING INTERFACE ***************************************************************/ diff --git a/src/widgets/lv_label.c b/src/widgets/lv_label.c index 4ff3e4578..d93817ec3 100644 --- a/src/widgets/lv_label.c +++ b/src/widgets/lv_label.c @@ -472,11 +472,11 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in) if(new_line_start > 0) { while(i + line_start < new_line_start) { - /*Get the current letter.*/ - uint32_t letter = _lv_txt_encoded_next(bidi_txt, &i); - - /*Get the next letter too for kerning*/ - uint32_t letter_next = _lv_txt_encoded_next(&bidi_txt[i], NULL); + /*Get the current letter and the next letter for kerning*/ + /*Be careful 'i' already points to the next character*/ + uint32_t letter; + uint32_t letter_next; + _lv_txt_encoded_letter_next_2(bidi_txt, &letter, &letter_next, &i); /*Handle the recolor command*/ if((flag & LV_TEXT_FLAG_RECOLOR) != 0) { @@ -575,12 +575,9 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) if(new_line_start > 0) { while(i <= new_line_start - 1) { - /*Get the current letter - *Be careful 'i' already points to the next character*/ - letter = _lv_txt_encoded_next(txt, &i); - - /*Get the next letter for kerning*/ - letter_next = _lv_txt_encoded_next(&txt[i], NULL); + /*Get the current letter and the next letter for kerning*/ + /*Be careful 'i' already points to the next character*/ + _lv_txt_encoded_letter_next_2(txt, &letter, &letter_next, &i); /*Handle the recolor command*/ if((flag & LV_TEXT_FLAG_RECOLOR) != 0) {