bidi: txt_sel fixes

This commit is contained in:
Gabor Kiss-Vamosi
2019-11-11 11:10:01 +01:00
parent 6eaf8dd6d3
commit c4f8d8cd5b

View File

@@ -56,8 +56,8 @@ static uint8_t hex_char_to_num(char hex);
* @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none) * @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
*/ */
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale, void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end, const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end,
lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir) lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir)
{ {
const lv_font_t * font = style->text.font; const lv_font_t * font = style->text.font;
lv_coord_t w; lv_coord_t w;
@@ -75,7 +75,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
/*If EXAPND is enabled then not limit the text's width to the object's width*/ /*If EXAPND is enabled then not limit the text's width to the object's width*/
lv_point_t p; lv_point_t p;
lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX,
flag); flag);
w = p.x; w = p.x;
} }
@@ -113,23 +113,6 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
pos.y += hint->y; pos.y += hint->y;
} }
if(sel_start != 0xFFFF) {
sel_start = lv_bidi_get_visual_pos(txt, NULL, strlen(txt), bidi_dir, sel_start, NULL);
sel_start = lv_txt_encoded_get_byte_id(txt, sel_start);
}
if(sel_end != 0xFFFF) {
sel_end = lv_bidi_get_visual_pos(txt, NULL, strlen(txt), bidi_dir, sel_end, NULL);
sel_end = lv_txt_encoded_get_byte_id(txt, sel_end);
}
if(sel_start > sel_end) {
uint16_t tmp = sel_start;
sel_start = sel_end;
sel_end = tmp;
}
uint32_t line_end = line_start + lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag); uint32_t line_end = line_start + lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag);
@@ -165,6 +148,12 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->text.opa : (uint16_t)((uint16_t)style->text.opa * opa_scale) >> 8; lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->text.opa : (uint16_t)((uint16_t)style->text.opa * opa_scale) >> 8;
if(sel_start > sel_end) {
uint16_t tmp = sel_start;
sel_start = sel_end;
sel_end = tmp;
}
cmd_state_t cmd_state = CMD_STATE_WAIT; cmd_state_t cmd_state = CMD_STATE_WAIT;
uint32_t i; uint32_t i;
uint16_t par_start = 0; uint16_t par_start = 0;
@@ -185,16 +174,24 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
uint32_t letter; uint32_t letter;
uint32_t letter_next; uint32_t letter_next;
#if LV_USE_BIDI #if LV_USE_BIDI
char *bidi_txt = lv_draw_get_buf(line_end - line_start + 1); char *bidi_txt = lv_draw_get_buf(line_end - line_start + 1);
lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir, NULL, 0); lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir, NULL, 0);
#else #else
const char *bidi_txt = txt + line_start; const char *bidi_txt = txt + line_start;
#endif #endif
while(i < line_end - line_start) { while(i < line_end - line_start) {
uint16_t logical_char_pos = 0;
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start);
uint16_t t = lv_txt_encoded_get_char_id(bidi_txt, i);
logical_char_pos += lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, bidi_dir, t, NULL);
}
letter = lv_txt_encoded_next(bidi_txt, &i); letter = lv_txt_encoded_next(bidi_txt, &i);
letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL); letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL);
/*Handle the re-color command*/ /*Handle the re-color command*/
if((flag & LV_TXT_FLAG_RECOLOR) != 0) { if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
if(letter == (uint32_t)LV_TXT_COLOR_CMD[0]) { if(letter == (uint32_t)LV_TXT_COLOR_CMD[0]) {
@@ -240,7 +237,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
if(sel_start != 0xFFFF && sel_end != 0xFFFF) { if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
/*Do not draw the rectangle on the character at `sel_start`.*/ /*Do not draw the rectangle on the character at `sel_start`.*/
if(i + line_start > sel_start && i + line_start <= sel_end) { if(logical_char_pos > sel_start && logical_char_pos <= sel_end) {
lv_area_t sel_coords; lv_area_t sel_coords;
sel_coords.x1 = pos.x; sel_coords.x1 = pos.x;
sel_coords.y1 = pos.y; sel_coords.y1 = pos.y;
@@ -263,7 +260,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
/*Align to middle*/ /*Align to middle*/
if(flag & LV_TXT_FLAG_CENTER) { if(flag & LV_TXT_FLAG_CENTER) {
line_width = line_width =
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag); lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
pos.x += (lv_area_get_width(coords) - line_width) / 2; pos.x += (lv_area_get_width(coords) - line_width) / 2;
@@ -271,7 +268,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
/*Align to the right*/ /*Align to the right*/
else if(flag & LV_TXT_FLAG_RIGHT) { else if(flag & LV_TXT_FLAG_RIGHT) {
line_width = line_width =
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag); lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
pos.x += lv_area_get_width(coords) - line_width; pos.x += lv_area_get_width(coords) - line_width;
} }
@@ -301,13 +298,13 @@ static uint8_t hex_char_to_num(char hex)
if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/ if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/
switch(hex) { switch(hex) {
case 'A': result = 10; break; case 'A': result = 10; break;
case 'B': result = 11; break; case 'B': result = 11; break;
case 'C': result = 12; break; case 'C': result = 12; break;
case 'D': result = 13; break; case 'D': result = 13; break;
case 'E': result = 14; break; case 'E': result = 14; break;
case 'F': result = 15; break; case 'F': result = 15; break;
default: result = 0; break; default: result = 0; break;
} }
} }