Add RTL indication to pos_conv

When getting visual/logical pos, also get whether this pos is RTL (was reversed)
This commit is contained in:
Amir Gonnen
2019-11-09 01:02:51 +02:00
parent a3a326c2ff
commit 0130f3e5f2
3 changed files with 23 additions and 11 deletions

View File

@@ -18,6 +18,11 @@
*********************/
#define LV_BIDI_BRACKLET_DEPTH 4
// Highest bit of the 16-bit pos_conv value specifies whether this pos is RTL or not
#define GET_POS(x) ((x) & 0x7FFF)
#define IS_RTL_POS(x) (((x) & 0x8000) != 0)
#define SET_RTL_POS(x, is_rtl) (GET_POS(x) | ((is_rtl)? 0x8000: 0))
/**********************
* TYPEDEFS
**********************/
@@ -140,17 +145,18 @@ bool lv_bidi_letter_is_neutral(uint32_t letter)
return false;
}
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_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos, bool *is_rtl)
{
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];
if (is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[visual_pos]);
return GET_POS(pos_conv_buf[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)
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, bool *is_rtl)
{
uint32_t pos_conv_len = get_txt_len(str_in, len);
void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t));
@@ -158,8 +164,10 @@ uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t l
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)
if (GET_POS(pos_conv_buf[i]) == logical_pos){
if (is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[i]);
return i;
}
}
return (uint16_t) -1;
}
@@ -284,7 +292,7 @@ static void fill_pos_conv(uint16_t * out, uint16_t len, uint16_t index)
{
for (uint16_t i = 0; i < len; i++)
{
out[i] = index;
out[i] = SET_RTL_POS(index, false);
index++;
}
}
@@ -421,14 +429,14 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *p
if(letter_size == 1) {
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;
if (pos_conv_out) pos_conv_out[pos_conv_wr] = SET_RTL_POS(pos_conv_rd_base + pos_conv_letter, true);
wr++;
pos_conv_wr++;
}
/*Just store the letter*/
else {
if (dest) memcpy(&dest[wr], &src[i], letter_size);
if (pos_conv_out) pos_conv_out[pos_conv_wr] = pos_conv_rd_base + pos_conv_i;
if (pos_conv_out) pos_conv_out[pos_conv_wr] = SET_RTL_POS(pos_conv_rd_base + pos_conv_i, true);
wr += letter_size;
pos_conv_wr++;
}

View File

@@ -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, 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);
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, bool *is_rtl);
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, bool *is_rtl);
/**********************
* MACROS

View File

@@ -631,7 +631,9 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t char_id, lv_point_
/*Handle Bidi*/
uint16_t line_char_id = lv_txt_encoded_get_char_id(&txt[line_start], byte_id - line_start);
uint16_t visual_char_pos = lv_bidi_get_visual_pos(&txt[line_start], &bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), line_char_id);
bool is_rtl;
uint16_t visual_char_pos = lv_bidi_get_visual_pos(&txt[line_start], &bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), line_char_id, &is_rtl);
if (is_rtl) visual_char_pos++;
uint16_t visual_byte_pos = lv_txt_encoded_get_byte_id(bidi_txt, visual_char_pos);
#else
bidi_txt = &txt[line_start];
@@ -761,7 +763,9 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)
#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_txt_encoded_get_char_id(bidi_txt, i));
bool is_rtl;
logical_pos = lv_bidi_get_logical_pos(&txt[line_start], NULL, new_line_start - line_start, lv_obj_get_base_dir(label), lv_txt_encoded_get_char_id(bidi_txt, i), &is_rtl);
if (is_rtl) logical_pos++;
#else
logical_pos = lv_encoded_get_char_id(bidi_txt, i);
#endif