fix(label): fix rtl txt long dots not show all (#4962)

Signed-off-by: yushuailong1 <yushuailong1@xiaomi.com>
Co-authored-by: yushuailong1 <yushuailong1@xiaomi.com>
This commit is contained in:
yushuailong
2023-12-13 23:13:24 +08:00
committed by GitHub
parent f9135d5498
commit 636aba8c34
6 changed files with 67 additions and 32 deletions
+31 -21
View File
@@ -354,8 +354,9 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t
#endif
}
uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in)
uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool bidi)
{
LV_UNUSED(bidi);
LV_ASSERT_OBJ(obj, MY_CLASS);
LV_ASSERT_NULL(pos_in);
lv_label_t * label = (lv_label_t *)obj;
@@ -400,13 +401,18 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in)
char * bidi_txt;
#if LV_USE_BIDI
bidi_txt = lv_malloc(new_line_start - line_start + 1);
uint32_t txt_len = new_line_start - line_start;
if(new_line_start > 0 && txt[new_line_start - 1] == '\0' && txt_len > 0) txt_len--;
_lv_bidi_process_paragraph(txt + line_start, bidi_txt, txt_len, lv_obj_get_style_base_dir(obj, LV_PART_MAIN), NULL, 0);
#else
bidi_txt = (char *)txt + line_start;
uint32_t txt_len;
if(bidi) {
bidi_txt = lv_malloc(new_line_start - line_start + 1);
txt_len = new_line_start - line_start;
if(new_line_start > 0 && txt[new_line_start - 1] == '\0' && txt_len > 0) txt_len--;
_lv_bidi_process_paragraph(txt + line_start, bidi_txt, txt_len, lv_obj_get_style_base_dir(obj, LV_PART_MAIN), NULL, 0);
}
else
#endif
{
bidi_txt = (char *)txt + line_start;
}
/*Calculate the x coordinate*/
int32_t x = 0;
@@ -440,21 +446,25 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in)
uint32_t logical_pos;
#if LV_USE_BIDI
/*Handle Bidi*/
uint32_t cid = _lv_text_encoded_get_char_id(bidi_txt, i);
if(txt[line_start + i] == '\0') {
logical_pos = i;
if(bidi) {
/*Handle Bidi*/
uint32_t cid = _lv_text_encoded_get_char_id(bidi_txt, i);
if(txt[line_start + i] == '\0') {
logical_pos = i;
}
else {
bool is_rtl;
logical_pos = _lv_bidi_get_logical_pos(&txt[line_start], NULL,
txt_len, lv_obj_get_style_base_dir(obj, LV_PART_MAIN), cid, &is_rtl);
if(is_rtl) logical_pos++;
}
lv_free(bidi_txt);
}
else {
bool is_rtl;
logical_pos = _lv_bidi_get_logical_pos(&txt[line_start], NULL,
txt_len, lv_obj_get_style_base_dir(obj, LV_PART_MAIN), cid, &is_rtl);
if(is_rtl) logical_pos++;
}
lv_free(bidi_txt);
#else
logical_pos = _lv_text_encoded_get_char_id(bidi_txt, i);
else
#endif
{
logical_pos = _lv_text_encoded_get_char_id(bidi_txt, i);
}
return logical_pos + _lv_text_encoded_get_char_id(txt, line_start);
}
@@ -1076,7 +1086,7 @@ static void lv_label_refr_text(lv_obj_t * obj)
p.y -= line_space;
}
uint32_t letter_id = lv_label_get_letter_on(obj, &p);
uint32_t letter_id = lv_label_get_letter_on(obj, &p, false);
/*Be sure there is space for the dots*/
size_t txt_len = lv_strlen(label->text);
+4 -3
View File
@@ -169,7 +169,7 @@ lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * obj);
/**
* Get the relative x and y coordinates of a letter
* @param obj pointer to a label object
* @param char_id index of the character [0 ... text length - 1].
* @param char_id index of the character [0 ... text length - 1].
* Expressed in character index, not byte index (different in UTF-8)
* @param pos store the result here (E.g. index = 0 gives 0;0 coordinates if the text if aligned to the left)
*/
@@ -178,11 +178,12 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t
/**
* Get the index of letter on a relative point of a label.
* @param obj pointer to label object
* @param pos_in pointer to point with coordinates on a the label
* @param pos_in pointer to point with coordinates on a the label
* @param bidi whether to use bidi processed
* @return The index of the letter on the 'pos_p' point (E.g. on 0;0 is the 0. letter if aligned to the left)
* Expressed in character index and not byte index (different in UTF-8)
*/
uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in);
uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool bidi);
/**
* Check if a character is drawn under a point.
+1 -1
View File
@@ -698,7 +698,7 @@ static lv_result_t release_handler(lv_obj_t * obj)
p.y -= label->coords.y1;
p.x -= label->coords.x1;
uint32_t letter_i;
letter_i = lv_label_get_letter_on(label, &p);
letter_i = lv_label_get_letter_on(label, &p, true);
const char * txt = lv_label_get_text(label);
uint32_t i = 0;
+4 -4
View File
@@ -776,7 +776,7 @@ void lv_textarea_cursor_down(lv_obj_t * obj)
/*Do not go below the last line*/
if(pos.y < lv_obj_get_height(ta->label)) {
/*Get the letter index on the new cursor position and set it*/
uint32_t new_cur_pos = lv_label_get_letter_on(ta->label, &pos);
uint32_t new_cur_pos = lv_label_get_letter_on(ta->label, &pos, true);
int32_t cur_valid_x_tmp = ta->cursor.valid_x; /*Cursor position set overwrites the valid position*/
lv_textarea_set_cursor_pos(obj, new_cur_pos);
@@ -802,7 +802,7 @@ void lv_textarea_cursor_up(lv_obj_t * obj)
pos.x = ta->cursor.valid_x;
/*Get the letter index on the new cursor position and set it*/
uint32_t new_cur_pos = lv_label_get_letter_on(ta->label, &pos);
uint32_t new_cur_pos = lv_label_get_letter_on(ta->label, &pos, true);
int32_t cur_valid_x_tmp = ta->cursor.valid_x; /*Cursor position set overwrites the valid position*/
lv_textarea_set_cursor_pos(obj, new_cur_pos);
ta->cursor.valid_x = cur_valid_x_tmp;
@@ -1184,7 +1184,7 @@ static void update_cursor_position_on_click(lv_event_t * e)
click_outside_label = true;
}
else {
char_id_at_click = lv_label_get_letter_on(ta->label, &rel_pos);
char_id_at_click = lv_label_get_letter_on(ta->label, &rel_pos, true);
click_outside_label = !lv_label_is_char_under_pos(ta->label, &rel_pos);
}
@@ -1248,7 +1248,7 @@ static void update_cursor_position_on_click(lv_event_t * e)
char_id_at_click = LV_TEXTAREA_CURSOR_LAST;
}
else {
char_id_at_click = lv_label_get_letter_on(ta->label, &rel_pos);
char_id_at_click = lv_label_get_letter_on(ta->label, &rel_pos, true);
}
if(code == LV_EVENT_PRESSED) lv_textarea_set_cursor_pos(obj, char_id_at_click);
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

+27 -3
View File
@@ -522,7 +522,7 @@ void test_label_get_letter_on_left(void)
const uint32_t last_letter_idx = strlen(lv_label_get_text(label)) - 1;
lv_label_get_letter_pos(label, last_letter_idx, &last_letter_point);
uint32_t letter_idx_result = lv_label_get_letter_on(label, &last_letter_point);
uint32_t letter_idx_result = lv_label_get_letter_on(label, &last_letter_point, true);
TEST_ASSERT_EQUAL(last_letter_idx, letter_idx_result);
}
@@ -535,7 +535,7 @@ void test_label_get_letter_on_center(void)
const uint32_t last_letter_idx = strlen(lv_label_get_text(label)) - 1;
lv_label_get_letter_pos(label, last_letter_idx, &last_letter_point);
uint32_t letter_idx_result = lv_label_get_letter_on(label, &last_letter_point);
uint32_t letter_idx_result = lv_label_get_letter_on(label, &last_letter_point, true);
TEST_ASSERT_EQUAL(last_letter_idx, letter_idx_result);
}
@@ -548,7 +548,7 @@ void test_label_get_letter_on_right(void)
const uint32_t last_letter_idx = strlen(lv_label_get_text(label)) - 1;
lv_label_get_letter_pos(label, last_letter_idx, &last_letter_point);
uint32_t letter_idx_result = lv_label_get_letter_on(label, &last_letter_point);
uint32_t letter_idx_result = lv_label_get_letter_on(label, &last_letter_point, true);
TEST_ASSERT_EQUAL(last_letter_idx, letter_idx_result);
}
@@ -568,4 +568,28 @@ void test_label_text_selection(void)
TEST_ASSERT_EQUAL(selection_end, end);
}
void test_label_rtl_dot_long_mode(void)
{
const char * message =
"מעבד, או בשמו המלא יחידת עיבוד מרכזית (באנגלית: CPU - Central Processing Unit).";
lv_obj_t * screen = lv_obj_create(lv_scr_act());
lv_obj_remove_style_all(screen);
lv_obj_set_size(screen, 800, 480);
lv_obj_center(screen);
lv_obj_set_style_bg_color(screen, lv_color_white(), 0);
lv_obj_set_style_bg_opa(screen, LV_OPA_100, 0);
lv_obj_set_style_pad_all(screen, 0, 0);
lv_obj_t * test_label = lv_label_create(screen);
lv_obj_set_style_text_font(test_label, &lv_font_dejavu_16_persian_hebrew, 0);
lv_label_set_long_mode(test_label, LV_LABEL_LONG_DOT);
lv_obj_set_style_base_dir(test_label, LV_BASE_DIR_RTL, 0);
lv_obj_set_size(test_label, 300, lv_font_dejavu_16_persian_hebrew.line_height);
lv_label_set_text(test_label, message);
lv_obj_center(test_label);
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/label_rtl_dot_long_mode.png");
}
#endif