diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index 23c6603967..c2dc52ebe8 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -8,6 +8,7 @@ *********************/ #include "lv_draw_label.h" #include "../lv_misc/lv_math.h" +#include "../lv_misc/lv_bidi.h" /********************* * DEFINES @@ -162,12 +163,16 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st } /*Write all letter of a line*/ cmd_state = CMD_STATE_WAIT; - i = line_start; + i = 0; uint32_t letter; uint32_t letter_next; - while(i < line_end) { - letter = lv_txt_encoded_next(txt, &i); - letter_next = lv_txt_encoded_next(&txt[i], NULL); + while(i < line_end - line_start) { + // TODO handle bidi conditionally on ifdef + static char bidi_txt[1000]; // TODO: allocate dynamically once (gloablly?), according to max label size + lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, LV_BIDI_DIR_RTL /* lv_obj_get_base_dir(label) */ ); // TODO: pass base dir as paramter + + letter = lv_txt_encoded_next(bidi_txt, &i); + letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL); /*Handle the re-color command*/ if((flag & LV_TXT_FLAG_RECOLOR) != 0) { @@ -190,7 +195,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st /*Get the parameter*/ if(i - par_start == LABEL_RECOLOR_PAR_LENGTH + 1) { char buf[LABEL_RECOLOR_PAR_LENGTH + 1]; - memcpy(buf, &txt[par_start], LABEL_RECOLOR_PAR_LENGTH); + memcpy(buf, &bidi_txt[par_start], LABEL_RECOLOR_PAR_LENGTH); buf[LABEL_RECOLOR_PAR_LENGTH] = '\0'; int r, g, b; r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]); @@ -213,7 +218,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st letter_w = lv_font_get_glyph_width(font, letter, letter_next); if(sel_start != 0xFFFF && sel_end != 0xFFFF) { - int char_ind = lv_encoded_get_char_id(txt, i); + int char_ind = lv_encoded_get_char_id(bidi_txt, i); /*Do not draw the rectangle on the character at `sel_start`.*/ if(char_ind > sel_start && char_ind <= sel_end) { lv_area_t sel_coords; diff --git a/src/lv_misc/lv_bidi.c b/src/lv_misc/lv_bidi.c index e9929bc673..7f829354b7 100644 --- a/src/lv_misc/lv_bidi.c +++ b/src/lv_misc/lv_bidi.c @@ -23,9 +23,7 @@ /********************** * STATIC PROTOTYPES **********************/ -static void process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir); -static uint32_t get_next_paragraph(const char * txt); -static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t * len); +static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t max_len, uint32_t * len); static void rtl_reverse(char * dest, const char * src, uint32_t len); static uint32_t char_change_to_pair(uint32_t letter); @@ -55,8 +53,8 @@ void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir } while(str_in[par_start] != '\0') { - par_len = get_next_paragraph(&str_in[par_start]); - process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir); + par_len = lv_bidi_get_next_paragraph(&str_in[par_start]); + lv_bidi_process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir); par_start += par_len; while(str_in[par_start] == '\n' || str_in[par_start] == '\r') { @@ -134,7 +132,7 @@ bool lv_bidi_letter_is_neutral(uint32_t letter) * STATIC FUNCTIONS **********************/ -static void process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir) +void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir) { uint32_t run_len = 0; lv_bidi_dir_t run_dir; @@ -168,7 +166,7 @@ static void process_paragraph(const char * str_in, char * str_out, uint32_t len, /*Get and process the runs*/ while(rd < len) { - run_dir = get_next_run(&str_in[rd], base_dir, &run_len); + run_dir = get_next_run(&str_in[rd], base_dir, len - rd, &run_len); if(base_dir == LV_BIDI_DIR_LTR) { if(run_dir == LV_BIDI_DIR_LTR) memcpy(&str_out[wr], &str_in[rd], run_len); @@ -184,7 +182,7 @@ static void process_paragraph(const char * str_in, char * str_out, uint32_t len, } } -static uint32_t get_next_paragraph(const char * txt) +uint32_t lv_bidi_get_next_paragraph(const char * txt) { uint32_t i = 0; @@ -197,7 +195,7 @@ static uint32_t get_next_paragraph(const char * txt) return i; } -static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t * len) +static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t max_len, uint32_t * len) { uint32_t i = 0; uint32_t letter; @@ -209,7 +207,7 @@ static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint while(dir == LV_BIDI_DIR_NEUTRAL || dir == LV_BIDI_DIR_WEAK) { letter = lv_txt_encoded_next(txt, &i); dir = lv_bidi_get_letter_dir(letter); - if(txt[i] == '\0' || txt[i] == '\n' || txt[i] == '\r') { + if(i >= max_len || txt[i] == '\0' || txt[i] == '\n' || txt[i] == '\r') { *len = i; return base_dir; } @@ -222,7 +220,7 @@ static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint /*Find the next char which has different direction*/ lv_bidi_dir_t next_dir = base_dir; - while(txt[i] != '\0'&& txt[i] != '\n' && txt[i] != '\r') { + while(i_prev < max_len && txt[i] != '\0' && txt[i] != '\n' && txt[i] != '\r') { letter = lv_txt_encoded_next(txt, &i); next_dir = lv_bidi_get_letter_dir(letter); diff --git a/src/lv_misc/lv_bidi.h b/src/lv_misc/lv_bidi.h index 233765ca29..9ce0fffa1c 100644 --- a/src/lv_misc/lv_bidi.h +++ b/src/lv_misc/lv_bidi.h @@ -53,6 +53,8 @@ typedef uint8_t lv_bidi_dir_t; #if LV_USE_BIDI void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir); +void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir); +uint32_t lv_bidi_get_next_paragraph(const char * txt); lv_bidi_dir_t lv_bidi_detect_base_dir(const char * txt); lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter); bool lv_bidi_letter_is_weak(uint32_t letter); diff --git a/src/lv_objx/lv_btnm.c b/src/lv_objx/lv_btnm.c index c9f095ac42..729b745a2c 100644 --- a/src/lv_objx/lv_btnm.c +++ b/src/lv_objx/lv_btnm.c @@ -671,11 +671,6 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo lv_txt_flag_t txt_flag = LV_TXT_FLAG_NONE; if(ext->recolor) txt_flag = LV_TXT_FLAG_RECOLOR; -#if LV_USE_BIDI - char * bidi_buf = lv_mem_alloc(64); - lv_bidi_dir_t base_dir = lv_obj_get_base_dir(btnm); -#endif - for(btn_i = 0; btn_i < ext->btn_cnt; btn_i++, txt_i++) { /*Search the next valid text in the map*/ while(strcmp(ext->map_p[txt_i], "\n") == 0) { @@ -744,22 +739,8 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo area_tmp.x2 = area_tmp.x1 + txt_size.x; area_tmp.y2 = area_tmp.y1 + txt_size.y; -#if LV_USE_BIDI == 0 lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, -1, -1, NULL); -#else - uint32_t txt_len = strlen(ext->map_p[txt_i]) + 1; - if(txt_len > lv_mem_get_size(bidi_buf)) { - bidi_buf = lv_mem_realloc(bidi_buf, txt_len); - } - - lv_bidi_process(ext->map_p[txt_i], bidi_buf, base_dir); - lv_draw_label(&area_tmp, mask, btn_style, opa_scale, bidi_buf, txt_flag, NULL, -1, -1, NULL); -#endif } - -#if LV_USE_BIDI - lv_mem_free(bidi_buf); -#endif } return true; diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index 4ce18f42f2..4bb547ffe8 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -205,12 +205,8 @@ void lv_label_set_text(lv_obj_t * label, const char * text) LV_ASSERT_MEM(ext->text); if(ext->text == NULL) return; -#if LV_USE_BIDI == 0 strcpy(ext->text, text); -#else - lv_bidi_dir_t base_dir = lv_obj_get_base_dir(label); - lv_bidi_process(text, ext->text, base_dir); -#endif + /*Now the text is dynamically allocated*/ ext->static_txt = 0; } @@ -904,19 +900,7 @@ void lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt) pos = lv_txt_get_encoded_length(ext->text); } -#if LV_USE_BIDI - char * bidi_buf = lv_mem_alloc(ins_len) + 1; - LV_ASSERT_MEM(bidi_buf); - if(bidi_buf == NULL) return; - - lv_bidi_process(txt, bidi_buf, lv_obj_get_base_dir(label)); - lv_txt_ins(ext->text, pos, bidi_buf); - - lv_mem_free(bidi_buf); -#else lv_txt_ins(ext->text, pos, txt); -#endif - lv_label_refr_text(label); } diff --git a/src/lv_objx/lv_table.c b/src/lv_objx/lv_table.c index e1ca6a2d02..3a7ec3f569 100644 --- a/src/lv_objx/lv_table.c +++ b/src/lv_objx/lv_table.c @@ -163,12 +163,7 @@ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const } ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/ - -#if LV_USE_BIDI == 0 strcpy(ext->cell_data[cell] + 1, txt); /*+1 to skip the format byte*/ -#else - lv_bidi_process(txt, ext->cell_data[cell] + 1, base_dir); -#endif ext->cell_data[cell][0] = format.format_byte; refr_size(table);