Efl textblock/entry: additions to split BiDi cursor

- handling multiple runs, multiple lines, last char of line/par
   - tests added

Signed-off-by: Yakov Goldberg <yakov.g@samsung.com>
This commit is contained in:
Yakov Goldberg 2013-04-10 14:54:37 +03:00
parent a70abbb381
commit 7016872619
6 changed files with 518 additions and 58 deletions

View File

@ -1,3 +1,6 @@
2013-04-10 Tom Hacohen (Tasn) Yakov Goldberg
* Evas textblock : Added split cursor for BiDi text
2013-04-10 WooHyun Jung
* Edje: When cursor is located to each edge, entry now doesn't grab events for cursor movement.

1
NEWS
View File

@ -144,6 +144,7 @@ Improvements:
* Use the right macro to disable fcntl.
* Edje: use Eina_Cow to reduce memory usage.
* Embryo: use eina_file_mkstemp().
* Evas textblock : Added split cursor for BiDi text
Fixes:
* Fix a memory leak in ecore_con_dns when using ecore_con_server_connect

View File

@ -2409,14 +2409,14 @@ _edje_entry_real_part_init(Edje *ed, Edje_Real_Part *rp)
/* A proxy to the main cursor. */
if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE)
{
en->cursor_fg2 = evas_object_image_add(rp->edje->base->evas);
en->cursor_fg2 = evas_object_image_add(ed->base->evas);
evas_object_image_source_set(en->cursor_fg2, en->cursor_fg);
evas_object_image_fill_set(en->cursor_fg2, 0, 0, 1, 1);
evas_object_smart_member_add(en->cursor_fg2, rp->edje->obj);
evas_object_smart_member_add(en->cursor_fg2, ed->obj);
evas_object_stack_above(en->cursor_fg2, rp->object);
evas_object_clip_set(en->cursor_fg2, evas_object_clip_get(rp->object));
evas_object_pass_events_set(en->cursor_fg2, EINA_TRUE);
_edje_subobj_register(en->rp->edje, en->cursor_fg2);
_edje_subobj_register(en->ed, en->cursor_fg2);
}
evas_object_textblock_legacy_newline_set(rp->object, EINA_TRUE);

View File

@ -11628,8 +11628,30 @@ EAPI char *evas_textblock_cursor_range_text_g
*/
EAPI char *evas_textblock_cursor_content_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
/** FIXME: doc.
* The cw2 and etc are not valid if false is returned. */
/**
* Returns the geometry of two cursors ("split cursor"), if logical cursor is
* between LTR/RTL text, also considering paragraph direction.
* Upper cursor is shown for the text of the same direction as paragraph,
* lower cursor - for opposite.
*
* Split cursor geometry is valid only in '|' cursor mode.
* In this case @c EINA_TRUE is returned and cx2, cy2, cw2, ch2 are set,
* otherwise it behaves like cursor_geometry_get.
*
* @param[in] cur the cursor.
* @param[out] cx the x of the cursor (or upper cursor)
* @param[out] cy the y of the cursor (or upper cursor)
* @param[out] cw the width of the cursor (or upper cursor)
* @param[out] ch the height of the cursor (or upper cursor)
* @param[out] cx2 the x of the lower cursor
* @param[out] cy2 the y of the lower cursor
* @param[out] cw2 the width of the lower cursor
* @param[out] ch2 the height of the lower cursor
* @param[in] dir the direction of the cursor, can be NULL.
* @param[in] ctype the type of the cursor.
* @return @c EINA_TRUE for split cursor, @c EINA_FALSE otherwise
* @since 1.8
*/
EAPI Eina_Bool
evas_textblock_cursor_geometry_bidi_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_Coord *cx2, Evas_Coord *cy2, Evas_Coord *cw2, Evas_Coord *ch2, Evas_Textblock_Cursor_Type ctype);

View File

@ -8950,21 +8950,43 @@ evas_textblock_cursor_format_is_visible_get(const Evas_Textblock_Cursor *cur)
return EVAS_TEXTBLOCK_IS_VISIBLE_FORMAT_CHAR(text[cur->pos]);
}
#ifdef BIDI_SUPPORT
static Evas_Object_Textblock_Line*
_find_layout_line_by_item(Evas_Object_Textblock_Paragraph *par, Evas_Object_Textblock_Item *_it)
{
Evas_Object_Textblock_Line *ln;
EINA_INLIST_FOREACH(par->lines, ln)
{
Evas_Object_Textblock_Item *it;
EINA_INLIST_FOREACH(ln->items, it)
{
if (_it == it)
return ln;
}
}
return NULL;
}
#endif
EAPI Eina_Bool
evas_textblock_cursor_geometry_bidi_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_Coord *cx2, Evas_Coord *cy2, Evas_Coord *cw2, Evas_Coord *ch2, Evas_Textblock_Cursor_Type ctype)
{
const Evas_Textblock_Cursor *dir_cur;
Evas_Textblock_Cursor cur2;
if (!cur) return EINA_FALSE;
Evas_Object_Textblock *o = eo_data_get(cur->obj, MY_CLASS);
if (!o->formatted.valid) _relayout(cur->obj);
dir_cur = cur;
if (ctype == EVAS_TEXTBLOCK_CURSOR_UNDER)
{
evas_textblock_cursor_pen_geometry_get(cur, cx, cy, cw, ch);
return EINA_FALSE;
}
#ifdef BIDI_SUPPORT
#define IS_RTL(par) ((par) % 2)
#define IS_DIFFERENT_DIR(l1, l2) ((IS_RTL(l1) && (!IS_RTL(l2))) || \
((!IS_RTL(l1)) && IS_RTL(l2)))
else
{
Evas_Object_Textblock_Line *ln = NULL;
@ -8972,74 +8994,159 @@ evas_textblock_cursor_geometry_bidi_get(const Evas_Textblock_Cursor *cur, Evas_C
_find_layout_item_match(cur, &ln, &it);
if (ln && it)
{
if (cw) *cw = 0;
if (cw2) *cw2 = 0;
/* If we are at the start or the end of the item there's a chance
* we'll want a split cursor.
* FIXME: Handle the last char of the last paragraph.
* FIXME: Handle multiple items of the same direction.
* FIXME: Handle items across different lines.. */
if (cur->pos == it->text_pos)
if (ln->par->is_bidi)
{
Evas_BiDi_Direction itdir = (it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ?
_ITEM_TEXT(it)->text_props.bidi_dir : _ITEM_FORMAT(it)->bidi_dir;
if (cw) *cw = 0;
if (cw2) *cw2 = 0;
/* If we are at the start or the end of the item there's a chance
* we'll want a split cursor. */
Evas_Object_Textblock_Item *previt = NULL;
Evas_BiDi_Direction previtdir = EVAS_BIDI_DIRECTION_NEUTRAL;
/* Get the logically previous item. */
Evas_Object_Textblock_Item *it1 = NULL, *it2 = NULL;
Evas_Coord adv1 = 0, adv2 = 0;
if (cur->pos == it->text_pos)
{
Eina_List *itr;
Evas_Object_Textblock_Item *ititr;
EINA_LIST_FOREACH(ln->par->logical_items, itr, ititr)
EvasBiDiLevel par_level, it_level, previt_level;
_layout_update_bidi_props(o, ln->par);
par_level = *(ln->par->bidi_props->embedding_levels);
it_level = ln->par->bidi_props->embedding_levels[it->text_pos];
/* Get the logically previous item. */
{
if (ititr == it)
break;
previt = ititr;
Eina_List *itr;
Evas_Object_Textblock_Item *ititr;
EINA_LIST_FOREACH(ln->par->logical_items, itr, ititr)
{
if (ititr == it)
break;
previt = ititr;
}
if (previt)
{
previt_level = ln->par->bidi_props->embedding_levels[previt->text_pos];
}
}
if (previt)
if (previt && (it_level != previt_level))
{
previtdir = (previt->type == EVAS_TEXTBLOCK_ITEM_TEXT) ?
_ITEM_TEXT(previt)->text_props.bidi_dir : _ITEM_FORMAT(previt)->bidi_dir;
Evas_Object_Textblock_Item *curit = NULL, *curit_opp = NULL;
EvasBiDiLevel cur_level;
if (it_level > previt_level)
{
curit = it;
curit_opp = previt;
cur_level = it_level;
}
else
{
curit = previt;
curit_opp = it;
cur_level = previt_level;
}
if (((curit == it) && (!IS_RTL(par_level))) ||
((curit == previt) && (IS_RTL(par_level))))
{
adv1 = (IS_DIFFERENT_DIR(cur_level, par_level)) ?
curit_opp->adv : 0;
adv2 = curit->adv;
}
else if (((curit == previt) && (!IS_RTL(par_level))) ||
((curit == it) && (IS_RTL(par_level))))
{
adv1 = (IS_DIFFERENT_DIR(cur_level, par_level)) ?
0 : curit->adv;
adv2 = 0;
}
if (!IS_DIFFERENT_DIR(cur_level, par_level))
curit_opp = curit;
it1 = curit_opp;
it2 = curit;
}
/* Clear the bidi props because we don't need them anymore. */
evas_bidi_paragraph_props_unref(ln->par->bidi_props);
ln->par->bidi_props = NULL;
}
/* Handling last char in line (or in paragraph).
* T.e. prev condition didn't work, so we are not standing in the beginning of item,
* but in the end of line or paragraph. */
else if (evas_textblock_cursor_eol_get(cur))
{
EvasBiDiLevel par_level, it_level;
_layout_update_bidi_props(o, ln->par);
par_level = *(ln->par->bidi_props->embedding_levels);
it_level = ln->par->bidi_props->embedding_levels[it->text_pos];
if (it_level > par_level)
{
Evas_Object_Textblock_Item *lastit = it;
if (IS_RTL(par_level)) /* RTL par*/
{
/* We know, that all the items before current are of the same or bigger embedding level.
* So search backwards for the first one. */
while (EINA_INLIST_GET(lastit)->prev)
{
lastit = _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(lastit)->prev);
}
adv1 = 0;
adv2 = it->adv;
}
else /* LTR par */
{
/* We know, that all the items after current are of bigger or same embedding level.
* So search forward for the last one. */
while (EINA_INLIST_GET(lastit)->next)
{
lastit = _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(lastit)->next);
}
adv1 = lastit->adv;
adv2 = 0;
}
it1 = lastit;
it2 = it;
}
/* Clear the bidi props because we don't need them anymore. */
evas_bidi_paragraph_props_unref(ln->par->bidi_props);
ln->par->bidi_props = NULL;
}
if (previt && (itdir != previtdir))
if (it1 && it2)
{
Evas_Object_Textblock_Item *curit = NULL;
/* If the current dir is different than the paragraph dir
* this is our item. */
if (itdir != ln->par->direction)
{
curit = it;
}
else
{
curit = previt;
}
Evas_Object_Textblock_Line *ln1 = NULL, *ln2 = NULL;
ln1 = _find_layout_line_by_item(ln->par, it1);
if (cx) *cx = ln1->x + it1->x + adv1;
if (cy) *cy = ln1->par->y + ln1->y;
if (ch) *ch = ln1->h;
if (((curit == it) && (ln->par->direction == EVAS_BIDI_DIRECTION_LTR)) ||
((curit == previt) && (ln->par->direction == EVAS_BIDI_DIRECTION_RTL)))
{
if (cx) *cx = ln->x + curit->x;
if (cx2) *cx2 = ln->x + curit->x + curit->w;
}
else
{
if (cx) *cx = ln->x + curit->x + curit->w;
if (cx2) *cx2 = ln->x + curit->x;
}
ln2 = _find_layout_line_by_item(ln->par, it2);
if (cx2) *cx2 = ln2->x + it2->x + adv2;
if (cy2) *cy2 = ln2->par->y + ln2->y;
if (ch2) *ch2 = ln2->h;
if (cy) *cy = ln->par->y + ln->y;
if (ch) *ch = curit->h;
if (cy2) *cy2 = ln->par->y + ln->y;
if (ch2) *ch2 = curit->h;
return EINA_TRUE;
}
}
}
}
#undef IS_DIFFERENT_DIR
#undef IS_RTL
#else
(void) cx2;
(void) cy2;
(void) cw2;
(void) ch2;
#endif
evas_textblock_cursor_geometry_get(cur, cx, cy, cw, ch, NULL, ctype);
return EINA_FALSE;
}

View File

@ -648,6 +648,332 @@ START_TEST(evas_textblock_cursor)
}
END_TEST
START_TEST(evas_textblock_split_cursor)
{
#ifdef HAVE_FRIBIDI
START_TB_TEST();
Evas_Coord x, w, x2, w2;
Evas_Coord nw, nh;
Evas_Coord cx, cy, cx2, cy2;
/* Split cursor in LTR paragraph. */
/*0123456789 10 123 14 5678901234 */
evas_object_textblock_text_markup_set(tb, "test נסיון\u202babc\u202cנסיון bang");
evas_object_textblock_size_native_get(tb, &nw, &nh);
evas_object_resize(tb, nw, nh);
/* Logical cursor after "test " */
evas_textblock_cursor_pos_set(cur, 5);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, &cx2, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 4);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
evas_textblock_cursor_pos_set(cur, 5);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
fail_if(cx != (x + w));
fail_if(cx2 != (x2 + w2));
/* Logical cursor before " bang" */
evas_textblock_cursor_pos_set(cur, 20);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, &cx2, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 19);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
fail_if(cx != x);
fail_if(cx2 != x2);
/* Logical cursor before "a" */
evas_textblock_cursor_pos_set(cur, 11);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, &cx2, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 9);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
fail_if(cx != x);
fail_if(cx2 != x2);
/* Logical cursor after "c" */
evas_textblock_cursor_pos_set(cur, 15);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, &cx2, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 13);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
fail_if(cx != (x + w));
fail_if(cx2 != (x2 + w2));
/* Logical cursor in the beginning */
evas_textblock_cursor_line_char_first(cur);
fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
fail_if(cx != x);
/* Logical cursor in the end */
evas_textblock_cursor_line_char_last(cur);
fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 24);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
fail_if(cx != (x + w));
/* Logical cursor on the first pos */
evas_textblock_cursor_pos_set(cur, 1);
fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
fail_if(cx != x);
/* Split cursor in RTL paragraph. */
/* 1 2
0123456789 0 12345 6 7890123456 */
evas_object_textblock_text_markup_set(tb, "שלום test \u202aעברית\u202c efl נסיון");
evas_object_textblock_size_native_get(tb, &nw, &nh);
evas_object_resize(tb, nw, nh);
/* Logical cursor before "test" */
evas_textblock_cursor_pos_set(cur, 4);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
evas_textblock_cursor_pos_set(cur, 5);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, &cx2, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 5);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
fail_if(cx != x);
fail_if(cx2 != x2);
/* Logical cursor after " efl" */
evas_textblock_cursor_pos_set(cur, 21);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, &cx2, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 20);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
fail_if(cx != (x + w));
fail_if(cx2 != (x2 + w2));
/* Logical cursor before " efl" */
evas_textblock_cursor_pos_set(cur, 17);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, &cx2, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 15);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
fail_if(cx != x2);
fail_if(cx2 != x);
/* Logical cursor after "test " */
evas_textblock_cursor_pos_set(cur, 11);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, &cx2, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 9);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
fail_if(cx != (x + w));
fail_if(cx2 != (x2 + w2));
/* Logical cursor in the beginning */
evas_textblock_cursor_line_char_first(cur);
fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
fail_if(cx != (x + w));
/* Logical cursor in the end */
evas_textblock_cursor_line_char_last(cur);
fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 26);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
fail_if(cx != x);
/* Corner cases for split cursor. */
/* End of line in LTR paragraph */
/* 1
01234567890123 4 567 */
evas_object_textblock_text_markup_set(tb, "test נסיוןشسيب\u202babc");
evas_textblock_cursor_line_char_last(cur);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
evas_object_textblock_size_native_get(tb, &nw, &nh);
evas_object_resize(tb, nw, nh);
evas_textblock_cursor_line_char_last(cur);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, &cx2, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 4);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
evas_textblock_cursor_pos_set(cur, 5);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
fail_if(cx != (x + w));
fail_if(cx2 != (x2 + w2));
/* End of line in RTL paragraph */
/* 1 2
0123456789012345678 9 0123 */
evas_object_textblock_text_markup_set(tb, "נסיוןشسي testпривет\u202aשלום");
evas_object_textblock_size_native_get(tb, &nw, &nh);
evas_object_resize(tb, nw, nh);
evas_textblock_cursor_line_char_last(cur);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, &cx2, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 8);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
evas_textblock_cursor_pos_set(cur, 9);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
fail_if(cx != x);
fail_if(cx2 != x2);
/* Cursor is between items of the same direction */
evas_textblock_cursor_pos_set(cur, 13);
fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
fail_if(cx != x);
/* Cursor type is UNDER */
evas_textblock_cursor_pos_set(cur, 0);
fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_UNDER));
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
fail_if(cx != x);
/* Multiline */
Evas_Coord ly;
int i;
/* 012345678901234 */
evas_object_textblock_text_markup_set(tb, "<wrap=char>testשלוםشسيبefl");
evas_object_textblock_size_native_get(tb, &nw, &nh);
nh = nh * 15;
evas_object_resize(tb, nw, nh);
for (i = 0; i < nw; i++)
{
evas_object_resize(tb, i, nh);
evas_textblock_cursor_pos_set(cur, 12);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
NULL, &cx2, &cy2, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
fail_if(cy != ly);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
fail_if(cx != x);
evas_textblock_cursor_pos_set(cur, 11);
evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
fail_if(cy2 != ly);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
fail_if(cx2 != x2);
}
/* 01234567890123456789 */
evas_object_textblock_text_markup_set(tb, "<wrap=char>נסיוןhelloприветשלום");
evas_object_textblock_size_native_get(tb, &nw, &nh);
nh = nh * 20;
evas_object_resize(tb, nw, nh);
for (i = 0; i < nw; i++)
{
evas_object_resize(tb, i, nh);
evas_textblock_cursor_pos_set(cur, 16);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
NULL, &cx2, &cy2, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
fail_if(cy != ly);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
fail_if(cx != (x + w));
evas_textblock_cursor_pos_set(cur, 15);
evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
fail_if(cy2 != ly);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
fail_if(cx2 != (x2 + w2));
}
/* Testing multiline, when only RTL item is in the line. */
/* 012345678901234567890123 */
evas_object_textblock_text_markup_set(tb, "<wrap=char>testtesttestтестשלוםشسيب");
evas_object_textblock_size_native_get(tb, &nw, &nh);
nh = nh * 23;
evas_object_resize(tb, nw, nh);
evas_textblock_cursor_pos_set(cur, 15);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
/* Resizing textblock, so RTL item will be on the next line.*/
evas_object_resize(tb, x + w, nh);
evas_textblock_cursor_pos_set(cur, 24);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
NULL, &cx2, &cy2, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 16);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
fail_if(cx != (x + w));
evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
fail_if(cy != ly);
evas_textblock_cursor_pos_set(cur, 23);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
fail_if(cx2 != x2);
evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
fail_if(cy2 != ly);
/* Testing multiline, when only LTR item is in the line. */
/* 012345678901234567890123 */
evas_object_textblock_text_markup_set(tb, "<wrap=char>שלוםשלוםשלוםشسيبtestтест");
evas_object_textblock_size_native_get(tb, &nw, &nh);
nh = nh * 23;
evas_object_resize(tb, nw, nh);
evas_textblock_cursor_pos_set(cur, 15);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
/* Resizing textblock, so LTR item will be on the next line.*/
evas_object_resize(tb, nw - x, nh);
evas_textblock_cursor_pos_set(cur, 24);
fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
NULL, &cx2, &cy2, NULL, NULL,
EVAS_TEXTBLOCK_CURSOR_BEFORE));
evas_textblock_cursor_pos_set(cur, 16);
evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
fail_if(cx != x);
evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
fail_if(cy != ly);
evas_textblock_cursor_pos_set(cur, 23);
evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
fail_if(cx2 != (x2 + w2));
evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
fail_if(cy2 != ly);
END_TB_TEST();
#endif
}
END_TEST
START_TEST(evas_textblock_format_removal)
{
START_TB_TEST();
@ -2318,6 +2644,7 @@ void evas_test_textblock(TCase *tc)
{
tcase_add_test(tc, evas_textblock_simple);
tcase_add_test(tc, evas_textblock_cursor);
tcase_add_test(tc, evas_textblock_split_cursor);
tcase_add_test(tc, evas_textblock_size);
tcase_add_test(tc, evas_textblock_editing);
tcase_add_test(tc, evas_textblock_style);