From 3fc758b9824859b223f48af01b4efc9c54f9be88 Mon Sep 17 00:00:00 2001 From: Daniel Hirt Date: Mon, 7 Dec 2015 17:23:24 +0200 Subject: [PATCH] Evas textblock: fix evas_textblock_cursor_line_set The line_set function should set the cursor to the first logical position in the line. We can't use the first text position of the first item in the line, due to BiDi considerations (the line may be reordered). I've split evas_textblock_cursor_line_char_first to avoid code duplication, as it already handles these cases. @fix Change-Id: I8f493bc62b53b57e170829d01ad8cf43dc716642 --- src/lib/evas/canvas/evas_object_textblock.c | 62 +++++++++++++++-------------- src/tests/evas/evas_test_textblock.c | 19 +++++++++ 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index 402604b..a78389d 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -8624,6 +8624,33 @@ evas_textblock_cursor_paragraph_char_last(Evas_Textblock_Cursor *cur) } +static void +_cursor_line_first_char_get(Evas_Object_Textblock_Line *ln, + Evas_Textblock_Cursor *cur, + Evas_Textblock_Data *o) +{ + if (ln->items) + { + Evas_Object_Textblock_Item *it; + size_t pos; + pos = ln->items->text_pos; + EINA_INLIST_FOREACH(EINA_INLIST_GET(ln->items)->next, it) + { + if (it->text_pos < pos) + { + pos = it->text_pos; + } + } + cur->pos = pos; + cur->node = ln->items->text_node; + } + else + { + cur->pos = 0; + cur->node = o->text_nodes; + } +} + EAPI void evas_textblock_cursor_line_char_first(Evas_Textblock_Cursor *cur) { @@ -8638,26 +8665,12 @@ evas_textblock_cursor_line_char_first(Evas_Textblock_Cursor *cur) _relayout_if_needed(cur->obj, o); + /* We don't actually need 'it', but it needs to be non NULL */ _find_layout_item_match(cur, &ln, &it); if (!ln) return; - if (ln->items) - { - Evas_Object_Textblock_Item *i; - it = ln->items; - EINA_INLIST_FOREACH(ln->items, i) - { - if (it->text_pos > i->text_pos) - { - it = i; - } - } - } - if (it) - { - cur->pos = it->text_pos; - cur->node = it->text_node; - } + + _cursor_line_first_char_get(ln, cur, o); } EAPI void @@ -9204,7 +9217,6 @@ EAPI Eina_Bool evas_textblock_cursor_line_set(Evas_Textblock_Cursor *cur, int line) { Evas_Object_Textblock_Line *ln; - Evas_Object_Textblock_Item *it; if (!cur) return EINA_FALSE; Evas_Object_Protected_Data *obj = eo_data_scope_get(cur->obj, EVAS_OBJECT_CLASS); @@ -9216,17 +9228,9 @@ evas_textblock_cursor_line_set(Evas_Textblock_Cursor *cur, int line) ln = _find_layout_line_num(cur->obj, line); if (!ln) return EINA_FALSE; - it = (Evas_Object_Textblock_Item *)ln->items; - if (it) - { - cur->pos = it->text_pos; - cur->node = it->text_node; - } - else - { - cur->pos = 0; - cur->node = o->text_nodes; - } + + _cursor_line_first_char_get(ln, cur, o); + return EINA_TRUE; } diff --git a/src/tests/evas/evas_test_textblock.c b/src/tests/evas/evas_test_textblock.c index bf151c6..acd76cf 100644 --- a/src/tests/evas/evas_test_textblock.c +++ b/src/tests/evas/evas_test_textblock.c @@ -924,6 +924,25 @@ START_TEST(evas_textblock_cursor) #endif } + /* Line set with BiDi text */ + { + size_t pos; + + evas_object_textblock_text_markup_set(tb, + "שלום עולם hello world" + "שלום עולם hello world" + "hello world שלום עולם"); + evas_textblock_cursor_line_set(cur, 0); + pos = evas_textblock_cursor_pos_get(cur); + ck_assert_int_eq(pos, 0); + evas_textblock_cursor_line_set(cur, 1); + pos = evas_textblock_cursor_pos_get(cur); + ck_assert_int_eq(pos, 22); + evas_textblock_cursor_line_set(cur, 2); + pos = evas_textblock_cursor_pos_get(cur); + ck_assert_int_eq(pos, 44); + } + END_TB_TEST(); } END_TEST -- 2.7.4