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:
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user