mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-14 06:42:58 +08:00
WIP: pos_conv, bugfixes, use in lv_label
This commit is contained in:
parent
c7a7d1adca
commit
6f57de051b
@ -140,17 +140,28 @@ bool lv_bidi_letter_is_neutral(uint32_t letter)
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t lv_bidi_get_logical_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos)
|
||||
uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos)
|
||||
{
|
||||
return 0; // TODO
|
||||
uint32_t pos_conv_len = get_txt_len(str_in, len);
|
||||
void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t));
|
||||
if (bidi_txt) *bidi_txt = buf;
|
||||
uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len);
|
||||
lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len);
|
||||
return pos_conv_buf[visual_pos];
|
||||
}
|
||||
|
||||
uint16_t lv_bidi_get_visual_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos)
|
||||
uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos)
|
||||
{
|
||||
uint32_t pos_conv_len = get_txt_len(str_in, len) * sizeof(uint16_t);
|
||||
uint16_t *pos_conv_buf = lv_draw_get_buf(pos_conv_len);
|
||||
lv_bidi_process_paragraph(str_in, NULL, len, base_dir, pos_conv_buf, pos_conv_len);
|
||||
return pos_conv_buf[logical_pos];
|
||||
uint32_t pos_conv_len = get_txt_len(str_in, len);
|
||||
void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t));
|
||||
if (bidi_txt) *bidi_txt = buf;
|
||||
uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len);
|
||||
lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len);
|
||||
for (uint16_t i = 0; i < pos_conv_len; i++){
|
||||
if (pos_conv_buf[i] == logical_pos)
|
||||
return i;
|
||||
}
|
||||
return (uint16_t) -1;
|
||||
}
|
||||
|
||||
void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir, uint16_t *pos_conv_out, uint16_t pos_conv_len)
|
||||
@ -207,7 +218,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len
|
||||
} else {
|
||||
wr -= rd;
|
||||
pos_conv_wr -= pos_conv_rd;
|
||||
rtl_reverse(str_out? &str_out[wr]: NULL, str_in, rd, pos_conv_out? &pos_conv_out[pos_conv_rd]: NULL, 0, pos_conv_rd);
|
||||
rtl_reverse(str_out? &str_out[wr]: NULL, str_in, rd, pos_conv_out? &pos_conv_out[pos_conv_wr]: NULL, 0, pos_conv_rd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,7 +232,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len
|
||||
if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len);
|
||||
if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd);
|
||||
}
|
||||
else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_rd] : NULL, pos_conv_rd, pos_conv_run_len);
|
||||
else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len);
|
||||
wr += run_len;
|
||||
pos_conv_wr += pos_conv_run_len;
|
||||
} else {
|
||||
@ -231,7 +242,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len
|
||||
if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len);
|
||||
if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd);
|
||||
}
|
||||
else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_rd] : NULL, pos_conv_rd, pos_conv_run_len);
|
||||
else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len);
|
||||
}
|
||||
|
||||
rd += run_len;
|
||||
@ -411,8 +422,8 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *p
|
||||
uint32_t new_letter = letter = char_change_to_pair(letter);
|
||||
if (dest) dest[wr] = (uint8_t)new_letter;
|
||||
if (pos_conv_out) pos_conv_out[pos_conv_wr] = pos_conv_rd_base + pos_conv_letter;
|
||||
wr += 1;
|
||||
pos_conv_wr += 1;
|
||||
wr++;
|
||||
pos_conv_wr++;
|
||||
}
|
||||
/*Just store the letter*/
|
||||
else {
|
||||
|
@ -60,8 +60,8 @@ lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter);
|
||||
bool lv_bidi_letter_is_weak(uint32_t letter);
|
||||
bool lv_bidi_letter_is_rtl(uint32_t letter);
|
||||
bool lv_bidi_letter_is_neutral(uint32_t letter);
|
||||
uint16_t lv_bidi_get_logical_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos);
|
||||
uint16_t lv_bidi_get_visual_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos);
|
||||
uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos);
|
||||
uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
@ -593,6 +593,8 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t
|
||||
uint8_t letter_height = lv_font_get_line_height(font);
|
||||
lv_coord_t y = 0;
|
||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||
uint16_t visual_pos;
|
||||
char *bidi_txt;
|
||||
|
||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||
@ -626,19 +628,27 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_USE_BIDI
|
||||
/*Handle Bidi*/
|
||||
visual_pos = lv_bidi_get_visual_pos(&txt[line_start], &bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), index - line_start);
|
||||
#else
|
||||
visual_pos = index - line_start;
|
||||
bidi_txt = &txt[line_start];
|
||||
#endif
|
||||
|
||||
/*Calculate the x coordinate*/
|
||||
lv_coord_t x = lv_txt_get_width(&txt[line_start], index - line_start, font, style->text.letter_space, flag);
|
||||
lv_coord_t x = lv_txt_get_width(bidi_txt, visual_pos, font, style->text.letter_space, flag);
|
||||
|
||||
if(index != line_start) x += style->text.letter_space;
|
||||
|
||||
if(align == LV_LABEL_ALIGN_CENTER) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
||||
|
||||
} else if(align == LV_LABEL_ALIGN_RIGHT) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
|
||||
x += lv_obj_get_width(label) - line_w;
|
||||
}
|
||||
@ -668,6 +678,8 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
||||
uint8_t letter_height = lv_font_get_line_height(font);
|
||||
lv_coord_t y = 0;
|
||||
lv_txt_flag_t flag = LV_TXT_FLAG_NONE;
|
||||
uint16_t logical_pos;
|
||||
char *bidi_txt;
|
||||
|
||||
if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;
|
||||
@ -691,37 +703,44 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
||||
line_start = new_line_start;
|
||||
}
|
||||
|
||||
#if LV_USE_BIDI
|
||||
bidi_txt = lv_draw_get_buf(new_line_start - line_start + 1);
|
||||
lv_bidi_process_paragraph(txt + line_start, bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), NULL, 0);
|
||||
#else
|
||||
bidi_txt = txt + line_start;
|
||||
#endif
|
||||
|
||||
/*Calculate the x coordinate*/
|
||||
lv_coord_t x = 0;
|
||||
if(align == LV_LABEL_ALIGN_CENTER) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
x += lv_obj_get_width(label) / 2 - line_w / 2;
|
||||
}
|
||||
else if(align == LV_LABEL_ALIGN_RIGHT) {
|
||||
lv_coord_t line_w;
|
||||
line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag);
|
||||
x += lv_obj_get_width(label) - line_w;
|
||||
}
|
||||
|
||||
lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;
|
||||
|
||||
uint32_t i = line_start;
|
||||
uint32_t i = 0;
|
||||
uint32_t i_act = i;
|
||||
uint32_t letter;
|
||||
uint32_t letter_next;
|
||||
|
||||
if(new_line_start > 0) {
|
||||
while(i < new_line_start) {
|
||||
while(i + line_start < new_line_start) {
|
||||
/* Get the current letter.*/
|
||||
letter = lv_txt_encoded_next(txt, &i);
|
||||
letter = lv_txt_encoded_next(bidi_txt, &i);
|
||||
|
||||
/*Get the next letter too for kerning*/
|
||||
letter_next = lv_txt_encoded_next(&txt[i], NULL);
|
||||
letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL);
|
||||
|
||||
/*Handle the recolor command*/
|
||||
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||
if(lv_txt_is_cmd(&cmd_state, txt[i]) != false) {
|
||||
if(lv_txt_is_cmd(&cmd_state, bidi_txt[i]) != false) {
|
||||
continue; /*Skip the letter is it is part of a command*/
|
||||
}
|
||||
}
|
||||
@ -729,7 +748,7 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
||||
x += lv_font_get_glyph_width(font, letter, letter_next);
|
||||
|
||||
/*Finish if the x position or the last char of the line is reached*/
|
||||
if(pos->x < x || i == new_line_start) {
|
||||
if(pos->x < x || i + line_start == new_line_start) {
|
||||
i = i_act;
|
||||
break;
|
||||
}
|
||||
@ -738,7 +757,14 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
|
||||
}
|
||||
}
|
||||
|
||||
return lv_encoded_get_char_id(txt, i);
|
||||
#if LV_USE_BIDI
|
||||
/*Handle Bidi*/
|
||||
logical_pos = lv_bidi_get_logical_pos(&txt[line_start], NULL, new_line_start - line_start, lv_obj_get_base_dir(label), lv_encoded_get_char_id(bidi_txt, i));
|
||||
#else
|
||||
logical_pos = lv_encoded_get_char_id(bidi_txt, i);
|
||||
#endif
|
||||
|
||||
return logical_pos;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user