mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-21 22:52:46 +08:00
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:
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 |
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user