forked from enlightenment/efl
edje entry: improve selection performance
Summary: The selection performance is slow if we select large chunk of text. This is caused by many rectangles created and deleted. This patch provides a way to improve it by combine selection rectangles of line in middle into one rectangles (i.e, if we have N lines, the selection rectangle for lines 2 to N-1 will be combined into one.) @feature Reviewers: raster, cedric, tasn Subscribers: herdsman, woohyun, cedric Differential Revision: https://phab.enlightenment.org/D1508
This commit is contained in:
parent
f6a5ada4a2
commit
c30303d7e8
|
@ -620,30 +620,29 @@ _sel_clear(Edje *ed, Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o EINA_U
|
|||
static void
|
||||
_sel_update(Edje *ed, Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o, Entry *en)
|
||||
{
|
||||
Eina_List *range = NULL, *l;
|
||||
Sel *sel;
|
||||
Evas_Coord x, y, w, h;
|
||||
Evas_Coord x, y;
|
||||
Evas_Object *smart, *clip;
|
||||
|
||||
smart = evas_object_smart_parent_get(o);
|
||||
clip = evas_object_clip_get(o);
|
||||
if (en->sel_start)
|
||||
range = evas_textblock_cursor_range_geometry_get(en->sel_start, en->sel_end);
|
||||
else
|
||||
if (!en->sel_start)
|
||||
return;
|
||||
if (eina_list_count(range) != eina_list_count(en->sel))
|
||||
{
|
||||
while (en->sel)
|
||||
{
|
||||
sel = en->sel->data;
|
||||
if (sel->obj_bg) evas_object_del(sel->obj_bg);
|
||||
if (sel->obj_fg) evas_object_del(sel->obj_fg);
|
||||
free(sel);
|
||||
en->sel = eina_list_remove_list(en->sel, en->sel);
|
||||
}
|
||||
|
||||
evas_object_geometry_get(o, &x, &y, NULL, NULL);
|
||||
if (en->have_selection)
|
||||
{
|
||||
for (l = range; l; l = eina_list_next(l))
|
||||
Eina_Iterator *range = NULL;
|
||||
Eina_List *l;
|
||||
Sel *sel;
|
||||
Evas_Textblock_Rectangle *r;
|
||||
|
||||
range = evas_textblock_cursor_range_simple_geometry_get(en->sel_start,
|
||||
en->sel_end);
|
||||
|
||||
l = en->sel;
|
||||
EINA_ITERATOR_FOREACH(range, r)
|
||||
{
|
||||
if (!l)
|
||||
{
|
||||
Evas_Object *ob;
|
||||
|
||||
|
@ -669,17 +668,13 @@ _sel_update(Edje *ed, Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o, Entr
|
|||
sel->obj_fg = ob;
|
||||
_edje_subobj_register(ed, sel->obj_fg);
|
||||
}
|
||||
}
|
||||
}
|
||||
x = y = w = h = -1;
|
||||
evas_object_geometry_get(o, &x, &y, &w, &h);
|
||||
if (en->have_selection)
|
||||
else
|
||||
{
|
||||
EINA_LIST_FOREACH(en->sel, l, sel)
|
||||
{
|
||||
Evas_Textblock_Rectangle *r;
|
||||
sel = eina_list_data_get(l);
|
||||
l = l->next;
|
||||
}
|
||||
*(&(sel->rect)) = *r;
|
||||
|
||||
r = range->data;
|
||||
if (sel->obj_bg)
|
||||
{
|
||||
evas_object_move(sel->obj_bg, x + r->x, y + r->y);
|
||||
|
@ -690,17 +685,23 @@ _sel_update(Edje *ed, Evas_Textblock_Cursor *c EINA_UNUSED, Evas_Object *o, Entr
|
|||
evas_object_move(sel->obj_fg, x + r->x, y + r->y);
|
||||
evas_object_resize(sel->obj_fg, r->w, r->h);
|
||||
}
|
||||
*(&(sel->rect)) = *r;
|
||||
range = eina_list_remove_list(range, range);
|
||||
free(r);
|
||||
}
|
||||
eina_iterator_free(range);
|
||||
|
||||
/* delete redundant selection rects */
|
||||
while (l)
|
||||
{
|
||||
Eina_List *temp = l->next;
|
||||
sel = eina_list_data_get(l);
|
||||
if (sel)
|
||||
{
|
||||
if (sel->obj_bg) evas_object_del(sel->obj_bg);
|
||||
if (sel->obj_fg) evas_object_del(sel->obj_fg);
|
||||
free(sel);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (range)
|
||||
{
|
||||
free(range->data);
|
||||
range = eina_list_remove_list(range, range);
|
||||
en->sel = eina_list_remove_list(en->sel, l);
|
||||
l = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3980,6 +3980,17 @@ EAPI int evas_textblock_cursor_line_coord_s
|
|||
*/
|
||||
EAPI Eina_List *evas_textblock_cursor_range_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
/**
|
||||
* Get the simple geometry of a range.
|
||||
* The simple geometry is the geomtry in which rectangles in middle
|
||||
* lines of range are merged into one big rectangle.
|
||||
*
|
||||
* @param cur1 one side of the range.
|
||||
* @param cur2 other side of the range.
|
||||
* @return an iterator of rectangles representing the geometry of the range.
|
||||
*/
|
||||
EAPI Eina_Iterator *evas_textblock_cursor_range_simple_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
/**
|
||||
* Get the geometry of ?
|
||||
*
|
||||
|
|
|
@ -199,7 +199,12 @@ typedef struct _Evas_Object_Textblock_Format_Item Evas_Object_Textblock_Format_I
|
|||
* A textblock format.
|
||||
*/
|
||||
typedef struct _Evas_Object_Textblock_Format Evas_Object_Textblock_Format;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @typedef Evas_Textblock_Selection_Iterator
|
||||
* A textblock selection iterator.
|
||||
*/
|
||||
typedef struct _Evas_Textblock_Selection_Iterator Evas_Textblock_Selection_Iterator;
|
||||
/**
|
||||
* @internal
|
||||
* @def IS_AT_END(ti, ind)
|
||||
|
@ -513,6 +518,13 @@ struct _Evas_Object_Textblock
|
|||
Eina_Bool legacy_newline : 1;
|
||||
};
|
||||
|
||||
struct _Evas_Textblock_Selection_Iterator
|
||||
{
|
||||
Eina_Iterator iterator; /**< Eina Iterator. */
|
||||
Eina_List *list; /**< Head of list. */
|
||||
Eina_List *current; /**< Current node in loop. */
|
||||
};
|
||||
|
||||
/* private methods for textblock objects */
|
||||
static void evas_object_textblock_init(Evas_Object *eo_obj);
|
||||
static void evas_object_textblock_render(Evas_Object *eo_obj,
|
||||
|
@ -597,6 +609,85 @@ static void _evas_textblock_invalidate_all(Evas_Textblock_Data *o);
|
|||
static void _evas_textblock_cursors_update_offset(const Evas_Textblock_Cursor *cur, const Evas_Object_Textblock_Node_Text *n, size_t start, int offset);
|
||||
static void _evas_textblock_cursors_set_node(Evas_Textblock_Data *o, const Evas_Object_Textblock_Node_Text *n, Evas_Object_Textblock_Node_Text *new_node);
|
||||
|
||||
/** selection iterator */
|
||||
/**
|
||||
* @internal
|
||||
* Returns the value of the current data of list node,
|
||||
* and goes to the next list node.
|
||||
*
|
||||
* @param it the iterator.
|
||||
* @param data the data of the current list node.
|
||||
* @return EINA_FALSE if the current list node does not exists.
|
||||
* Otherwise, returns EINA_TRUE.
|
||||
*/
|
||||
static Eina_Bool
|
||||
_evas_textblock_selection_iterator_next(Evas_Textblock_Selection_Iterator *it, void **data)
|
||||
{
|
||||
if (!it->current)
|
||||
return EINA_FALSE;
|
||||
|
||||
*data = eina_list_data_get(it->current);
|
||||
it->current = eina_list_next(it->current);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Gets the iterator container (Eina_List) which created the iterator.
|
||||
* @param it the iterator.
|
||||
* @return A pointer to Eina_List.
|
||||
*/
|
||||
static Eina_List *
|
||||
_evas_textblock_selection_iterator_get_container(Evas_Textblock_Selection_Iterator *it)
|
||||
{
|
||||
return it->list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Frees the iterator container (Eina_List).
|
||||
* @param it the iterator.
|
||||
*/
|
||||
static void
|
||||
_evas_textblock_selection_iterator_free(Evas_Textblock_Selection_Iterator *it)
|
||||
{
|
||||
while (it->list)
|
||||
it->list = eina_list_remove_list(it->list, it->list);
|
||||
EINA_MAGIC_SET(&it->iterator, 0);
|
||||
free(it);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Creates newly allocated iterator associated to a list.
|
||||
* @param list The list.
|
||||
* @return If the memory cannot be allocated, NULL is returned.
|
||||
* Otherwise, a valid iterator is returned.
|
||||
*/
|
||||
Eina_Iterator *
|
||||
_evas_textblock_selection_iterator_new(Eina_List *list)
|
||||
{
|
||||
Evas_Textblock_Selection_Iterator *it;
|
||||
|
||||
it = calloc(1, sizeof(Evas_Textblock_Selection_Iterator));
|
||||
if (!it) return NULL;
|
||||
|
||||
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
||||
it->list = list;
|
||||
it->current = list;
|
||||
|
||||
it->iterator.version = EINA_ITERATOR_VERSION;
|
||||
it->iterator.next = FUNC_ITERATOR_NEXT(
|
||||
_evas_textblock_selection_iterator_next);
|
||||
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
|
||||
_evas_textblock_selection_iterator_get_container);
|
||||
it->iterator.free = FUNC_ITERATOR_FREE(
|
||||
_evas_textblock_selection_iterator_free);
|
||||
|
||||
return &it->iterator;
|
||||
}
|
||||
|
||||
/* styles */
|
||||
/**
|
||||
* @internal
|
||||
|
@ -10343,6 +10434,99 @@ _evas_textblock_cursor_range_in_line_geometry_get(
|
|||
return rects;
|
||||
}
|
||||
|
||||
EAPI Eina_Iterator *
|
||||
evas_textblock_cursor_range_simple_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2)
|
||||
{
|
||||
Evas_Object_Textblock_Line *ln1, *ln2;
|
||||
Evas_Object_Textblock_Item *it1, *it2;
|
||||
Eina_List *rects = NULL;
|
||||
Eina_Iterator *itr = NULL;
|
||||
|
||||
if (!cur1 || !cur1->node) return NULL;
|
||||
if (!cur2 || !cur2->node) return NULL;
|
||||
if (cur1->obj != cur2->obj) return NULL;
|
||||
Evas_Textblock_Data *o = eo_data_scope_get(cur1->obj, MY_CLASS);
|
||||
|
||||
_relayout_if_needed(cur1->obj, o);
|
||||
|
||||
if (evas_textblock_cursor_compare(cur1, cur2) > 0)
|
||||
{
|
||||
const Evas_Textblock_Cursor *tc;
|
||||
|
||||
tc = cur1;
|
||||
cur1 = cur2;
|
||||
cur2 = tc;
|
||||
}
|
||||
|
||||
ln1 = ln2 = NULL;
|
||||
it1 = it2 = NULL;
|
||||
_find_layout_item_match(cur1, &ln1, &it1);
|
||||
if (!ln1 || !it1) return NULL;
|
||||
_find_layout_item_match(cur2, &ln2, &it2);
|
||||
if (!ln2 || !it2) return NULL;
|
||||
|
||||
if (ln1 == ln2)
|
||||
{
|
||||
rects = _evas_textblock_cursor_range_in_line_geometry_get(ln1, cur1, cur2);
|
||||
}
|
||||
else
|
||||
{
|
||||
int lm = 0, rm = 0;
|
||||
Eina_List *rects2 = NULL;
|
||||
Evas_Coord w;
|
||||
Evas_Textblock_Cursor *tc;
|
||||
Evas_Textblock_Rectangle *tr;
|
||||
|
||||
if (ln1->items)
|
||||
{
|
||||
Evas_Object_Textblock_Format *fm = ln1->items->format;
|
||||
if (fm)
|
||||
{
|
||||
lm = fm->margin.l;
|
||||
rm = fm->margin.r;
|
||||
}
|
||||
}
|
||||
|
||||
evas_object_geometry_get(cur1->obj, NULL, NULL, &w, NULL);
|
||||
rects = _evas_textblock_cursor_range_in_line_geometry_get(ln1, cur1, NULL);
|
||||
|
||||
/* Extend selection rectangle in first line */
|
||||
tc = evas_object_textblock_cursor_new(cur1->obj);
|
||||
evas_textblock_cursor_copy(cur1, tc);
|
||||
evas_textblock_cursor_line_char_last(tc);
|
||||
tr = calloc(1, sizeof(Evas_Textblock_Rectangle));
|
||||
evas_textblock_cursor_pen_geometry_get(tc, &tr->x, &tr->y, &tr->w, &tr->h);
|
||||
if (ln1->par->direction == EVAS_BIDI_DIRECTION_RTL)
|
||||
{
|
||||
tr->w = tr->x + tr->w - rm;
|
||||
tr->x = lm;
|
||||
}
|
||||
else
|
||||
{
|
||||
tr->w = w - tr->x - rm;
|
||||
}
|
||||
rects = eina_list_append(rects, tr);
|
||||
evas_textblock_cursor_free(tc);
|
||||
|
||||
rects2 = _evas_textblock_cursor_range_in_line_geometry_get(ln2, NULL, cur2);
|
||||
|
||||
/* Add middle rect */
|
||||
if ((ln1->par->y + ln1->y + ln1->h) != (ln2->par->y + ln2->y))
|
||||
{
|
||||
tr = calloc(1, sizeof(Evas_Textblock_Rectangle));
|
||||
tr->x = lm;
|
||||
tr->y = ln1->par->y + ln1->y + ln1->h;
|
||||
tr->w = w - tr->x - rm;
|
||||
tr->h = ln2->par->y + ln2->y - tr->y;
|
||||
rects = eina_list_append(rects, tr);
|
||||
}
|
||||
rects = eina_list_merge(rects, rects2);
|
||||
}
|
||||
itr = _evas_textblock_selection_iterator_new(rects);
|
||||
|
||||
return itr;
|
||||
}
|
||||
|
||||
EAPI Eina_List *
|
||||
evas_textblock_cursor_range_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2)
|
||||
{
|
||||
|
|
|
@ -2134,6 +2134,203 @@ START_TEST(evas_textblock_geometries)
|
|||
EINA_LIST_FREE(rects, tr)
|
||||
free(tr);
|
||||
|
||||
/* Range simple geometry */
|
||||
/* Single line range */
|
||||
Eina_Iterator *it, *it2;
|
||||
Evas_Textblock_Rectangle *tr3;
|
||||
Evas_Coord w = 200;
|
||||
evas_object_textblock_text_markup_set(tb, "This <br/> is a test.<br/>Another <br/>text.");
|
||||
evas_object_resize(tb, w, w / 2);
|
||||
evas_textblock_cursor_pos_set(cur, 0);
|
||||
evas_textblock_cursor_pos_set(main_cur, 3);
|
||||
|
||||
it = evas_textblock_cursor_range_simple_geometry_get(cur, main_cur);
|
||||
fail_if(!it);
|
||||
rects = eina_iterator_container_get(it);
|
||||
fail_if(!rects);
|
||||
it2 = evas_textblock_cursor_range_simple_geometry_get(main_cur, cur);
|
||||
fail_if(!it2);
|
||||
rects2 = eina_iterator_container_get(it2);
|
||||
fail_if(!rects2);
|
||||
|
||||
fail_if(eina_list_count(rects) != 1);
|
||||
fail_if(eina_list_count(rects2) != 1);
|
||||
|
||||
tr = eina_list_data_get(rects);
|
||||
fail_if((tr->h <= 0) || (tr->w <= 0));
|
||||
tr2 = eina_list_data_get(rects2);
|
||||
fail_if((tr->h <= 0) || (tr->w <= 0));
|
||||
|
||||
fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
|
||||
(tr->h != tr2->h));
|
||||
|
||||
EINA_LIST_FREE(rects, tr)
|
||||
free(tr);
|
||||
EINA_LIST_FREE(rects2, tr2)
|
||||
free(tr2);
|
||||
eina_iterator_free(it);
|
||||
eina_iterator_free(it2);
|
||||
|
||||
/* Multiple range */
|
||||
evas_textblock_cursor_pos_set(cur, 0);
|
||||
evas_textblock_cursor_pos_set(main_cur, 16);
|
||||
|
||||
it = evas_textblock_cursor_range_simple_geometry_get(cur, main_cur);
|
||||
fail_if(!it);
|
||||
rects = eina_iterator_container_get(it);
|
||||
fail_if(!rects);
|
||||
it2 = evas_textblock_cursor_range_simple_geometry_get(main_cur, cur);
|
||||
fail_if(!it2);
|
||||
rects2 = eina_iterator_container_get(it2);
|
||||
fail_if(!rects2);
|
||||
|
||||
fail_if(eina_list_count(rects) != 3);
|
||||
fail_if(eina_list_count(rects2) != 3);
|
||||
|
||||
tr = eina_list_data_get(rects);
|
||||
fail_if((tr->h <= 0) || (tr->w <= 0));
|
||||
tr2 = eina_list_data_get(rects2);
|
||||
fail_if((tr2->h <= 0) || (tr2->w <= 0));
|
||||
|
||||
fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
|
||||
(tr->h != tr2->h));
|
||||
|
||||
tr = eina_list_nth(rects, 1);
|
||||
fail_if((tr->h <= 0) || (tr->w <= 0));
|
||||
tr2 = eina_list_data_get(eina_list_next(rects2));
|
||||
fail_if((tr2->h <= 0) || (tr2->w <= 0));
|
||||
|
||||
fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
|
||||
(tr->h != tr2->h));
|
||||
|
||||
tr = eina_list_nth(rects, 2);
|
||||
fail_if((tr->h <= 0) || (tr->w <= 0));
|
||||
tr2 = eina_list_nth(rects2, 2);
|
||||
fail_if((tr2->h <= 0) || (tr2->w <= 0));
|
||||
|
||||
fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
|
||||
(tr->h != tr2->h));
|
||||
|
||||
/* Check that the second line is positioned below the first */
|
||||
tr = eina_list_data_get(rects);
|
||||
tr2 = eina_list_nth(rects, 1);
|
||||
tr3 = eina_list_nth(rects, 2);
|
||||
fail_if((tr->y >= tr3->y) || (tr2->y >= tr3->y));
|
||||
fail_if(tr2->x + tr2->w != w);
|
||||
|
||||
/* Have middle rectangle */
|
||||
evas_textblock_cursor_pos_set(cur, 0);
|
||||
evas_textblock_cursor_pos_set(main_cur, 31);
|
||||
it = evas_textblock_cursor_range_simple_geometry_get(cur, main_cur);
|
||||
fail_if(!it);
|
||||
rects = eina_iterator_container_get(it);
|
||||
fail_if(!rects);
|
||||
it2 = evas_textblock_cursor_range_simple_geometry_get(main_cur, cur);
|
||||
fail_if(!it2);
|
||||
rects2 = eina_iterator_container_get(it2);
|
||||
fail_if(!rects2);
|
||||
|
||||
fail_if(eina_list_count(rects) != 4);
|
||||
fail_if(eina_list_count(rects) != 4);
|
||||
|
||||
tr = eina_list_data_get(rects);
|
||||
fail_if((tr->h <= 0) || (tr->w <= 0));
|
||||
tr2 = eina_list_data_get(rects2);
|
||||
fail_if((tr2->h <= 0) || (tr2->w <= 0));
|
||||
fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
|
||||
(tr->h != tr2->h));
|
||||
|
||||
tr = eina_list_nth(rects, 1);
|
||||
fail_if((tr->h <= 0) || (tr->w <= 0));
|
||||
tr2 = eina_list_nth(rects2, 1);
|
||||
fail_if((tr2->h <= 0) || (tr2->w <= 0));
|
||||
fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
|
||||
(tr->h != tr2->h));
|
||||
|
||||
tr = eina_list_nth(rects, 2);
|
||||
fail_if((tr->h <= 0) || (tr->w <= 0));
|
||||
tr2 = eina_list_nth(rects2, 2);
|
||||
fail_if((tr2->h <= 0) || (tr2->w <= 0));
|
||||
fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
|
||||
(tr->h != tr2->h));
|
||||
|
||||
tr = eina_list_nth(rects, 3);
|
||||
fail_if((tr->h <= 0) || (tr->w <= 0));
|
||||
tr2 = eina_list_nth(rects2, 3);
|
||||
fail_if((tr2->h <= 0) || (tr2->w <= 0));
|
||||
fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
|
||||
(tr->h != tr2->h));
|
||||
|
||||
/* Check that the middle rectanlge is between first and last rectangles */
|
||||
tr = eina_list_data_get(rects);
|
||||
tr2 = eina_list_nth(rects, 2);
|
||||
tr3 = eina_list_nth(rects, 3);
|
||||
fail_if((tr2->y < tr->y + tr->h) || (tr2->y + tr2->h > tr3->y));
|
||||
|
||||
/* Check that the middle rectangle has proper width */
|
||||
tr = eina_list_data_get(rects);
|
||||
tr2 = eina_list_nth(rects, 1);
|
||||
fail_if((tr->y != tr2->y) || (tr->h != tr2->h));
|
||||
tr3 = eina_list_nth(rects, 2);
|
||||
fail_if((tr2->x + tr2->w != w) || (tr2->x + tr2->w != tr3->x + tr3->w));
|
||||
tr2 = eina_list_nth(rects, 2);
|
||||
tr3 = eina_list_nth(rects, 3);
|
||||
fail_if((tr2->x != tr3->x));
|
||||
|
||||
EINA_LIST_FREE(rects, tr)
|
||||
free(tr);
|
||||
EINA_LIST_FREE(rects2, tr2)
|
||||
free(tr2);
|
||||
eina_iterator_free(it);
|
||||
eina_iterator_free(it2);
|
||||
|
||||
/* Same run different scripts */
|
||||
evas_object_textblock_text_markup_set(tb, "עבריתenglishрусскийעברית");
|
||||
|
||||
evas_textblock_cursor_pos_set(cur, 3);
|
||||
evas_textblock_cursor_pos_set(main_cur, 7);
|
||||
it = evas_textblock_cursor_range_simple_geometry_get(cur, main_cur);
|
||||
fail_if(!it);
|
||||
rects = eina_iterator_container_get(it);
|
||||
fail_if(!rects);
|
||||
|
||||
fail_if(eina_list_count(rects) != 2);
|
||||
|
||||
EINA_LIST_FREE(rects, tr)
|
||||
free(tr);
|
||||
eina_iterator_free(it);
|
||||
|
||||
/* Same run different styles */
|
||||
evas_object_textblock_text_markup_set(tb, "test<b>test2</b>test3");
|
||||
|
||||
evas_textblock_cursor_pos_set(cur, 3);
|
||||
evas_textblock_cursor_pos_set(main_cur, 11);
|
||||
it = evas_textblock_cursor_range_simple_geometry_get(cur, main_cur);
|
||||
fail_if(!it);
|
||||
rects = eina_iterator_container_get(it);
|
||||
|
||||
fail_if(eina_list_count(rects) != 3);
|
||||
|
||||
EINA_LIST_FREE(rects, tr)
|
||||
free(tr);
|
||||
eina_iterator_free(it);
|
||||
|
||||
/* Bidi text with a few back and forth from bidi. */
|
||||
evas_object_textblock_text_markup_set(tb, "נגכדגךלח eountoheunth ךלחגדךכלח");
|
||||
|
||||
evas_textblock_cursor_pos_set(cur, 0);
|
||||
evas_textblock_cursor_pos_set(main_cur, 28);
|
||||
it = evas_textblock_cursor_range_simple_geometry_get(cur, main_cur);
|
||||
fail_if(!it);
|
||||
rects = eina_iterator_container_get(it);
|
||||
fail_if(!rects);
|
||||
|
||||
ck_assert_int_eq(eina_list_count(rects), 3);
|
||||
|
||||
EINA_LIST_FREE(rects, tr)
|
||||
free(tr);
|
||||
eina_iterator_free(it);
|
||||
|
||||
END_TB_TEST();
|
||||
}
|
||||
END_TEST
|
||||
|
|
Loading…
Reference in New Issue