summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYakov Goldberg <yakov.g@samsung.com>2013-04-10 14:54:37 +0300
committerYakov Goldberg <yakov.g@samsung.com>2013-04-10 14:59:48 +0300
commit7016872619b7b84e46688de29b133997c43f95ed (patch)
treedcaa050daa1a4f6701680cd14bc3d9bc1f37ba1f /src
parenta70abbb3811bd9426bc3e30bd70fb3b027cc29e6 (diff)
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>
Diffstat (limited to 'src')
-rw-r--r--src/lib/edje/edje_entry.c6
-rw-r--r--src/lib/evas/Evas.h26
-rw-r--r--src/lib/evas/canvas/evas_object_textblock.c209
-rw-r--r--src/tests/evas/evas_test_textblock.c327
4 files changed, 512 insertions, 56 deletions
diff --git a/src/lib/edje/edje_entry.c b/src/lib/edje/edje_entry.c
index d7b0f771c6..b324d97b9f 100644
--- a/src/lib/edje/edje_entry.c
+++ b/src/lib/edje/edje_entry.c
@@ -2409,14 +2409,14 @@ _edje_entry_real_part_init(Edje *ed, Edje_Real_Part *rp)
2409 /* A proxy to the main cursor. */ 2409 /* A proxy to the main cursor. */
2410 if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE) 2410 if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE)
2411 { 2411 {
2412 en->cursor_fg2 = evas_object_image_add(rp->edje->base->evas); 2412 en->cursor_fg2 = evas_object_image_add(ed->base->evas);
2413 evas_object_image_source_set(en->cursor_fg2, en->cursor_fg); 2413 evas_object_image_source_set(en->cursor_fg2, en->cursor_fg);
2414 evas_object_image_fill_set(en->cursor_fg2, 0, 0, 1, 1); 2414 evas_object_image_fill_set(en->cursor_fg2, 0, 0, 1, 1);
2415 evas_object_smart_member_add(en->cursor_fg2, rp->edje->obj); 2415 evas_object_smart_member_add(en->cursor_fg2, ed->obj);
2416 evas_object_stack_above(en->cursor_fg2, rp->object); 2416 evas_object_stack_above(en->cursor_fg2, rp->object);
2417 evas_object_clip_set(en->cursor_fg2, evas_object_clip_get(rp->object)); 2417 evas_object_clip_set(en->cursor_fg2, evas_object_clip_get(rp->object));
2418 evas_object_pass_events_set(en->cursor_fg2, EINA_TRUE); 2418 evas_object_pass_events_set(en->cursor_fg2, EINA_TRUE);
2419 _edje_subobj_register(en->rp->edje, en->cursor_fg2); 2419 _edje_subobj_register(en->ed, en->cursor_fg2);
2420 } 2420 }
2421 2421
2422 evas_object_textblock_legacy_newline_set(rp->object, EINA_TRUE); 2422 evas_object_textblock_legacy_newline_set(rp->object, EINA_TRUE);
diff --git a/src/lib/evas/Evas.h b/src/lib/evas/Evas.h
index 9d3603b06b..86d0beb8c5 100644
--- a/src/lib/evas/Evas.h
+++ b/src/lib/evas/Evas.h
@@ -11628,8 +11628,30 @@ EAPI char *evas_textblock_cursor_range_text_g
11628 */ 11628 */
11629EAPI char *evas_textblock_cursor_content_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC; 11629EAPI char *evas_textblock_cursor_content_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
11630 11630
11631/** FIXME: doc. 11631/**
11632 * The cw2 and etc are not valid if false is returned. */ 11632 * Returns the geometry of two cursors ("split cursor"), if logical cursor is
11633 * between LTR/RTL text, also considering paragraph direction.
11634 * Upper cursor is shown for the text of the same direction as paragraph,
11635 * lower cursor - for opposite.
11636 *
11637 * Split cursor geometry is valid only in '|' cursor mode.
11638 * In this case @c EINA_TRUE is returned and cx2, cy2, cw2, ch2 are set,
11639 * otherwise it behaves like cursor_geometry_get.
11640 *
11641 * @param[in] cur the cursor.
11642 * @param[out] cx the x of the cursor (or upper cursor)
11643 * @param[out] cy the y of the cursor (or upper cursor)
11644 * @param[out] cw the width of the cursor (or upper cursor)
11645 * @param[out] ch the height of the cursor (or upper cursor)
11646 * @param[out] cx2 the x of the lower cursor
11647 * @param[out] cy2 the y of the lower cursor
11648 * @param[out] cw2 the width of the lower cursor
11649 * @param[out] ch2 the height of the lower cursor
11650 * @param[in] dir the direction of the cursor, can be NULL.
11651 * @param[in] ctype the type of the cursor.
11652 * @return @c EINA_TRUE for split cursor, @c EINA_FALSE otherwise
11653 * @since 1.8
11654 */
11633EAPI Eina_Bool 11655EAPI Eina_Bool
11634evas_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); 11656evas_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);
11635 11657
diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c
index 994b258a65..a274319446 100644
--- a/src/lib/evas/canvas/evas_object_textblock.c
+++ b/src/lib/evas/canvas/evas_object_textblock.c
@@ -8950,21 +8950,43 @@ evas_textblock_cursor_format_is_visible_get(const Evas_Textblock_Cursor *cur)
8950 return EVAS_TEXTBLOCK_IS_VISIBLE_FORMAT_CHAR(text[cur->pos]); 8950 return EVAS_TEXTBLOCK_IS_VISIBLE_FORMAT_CHAR(text[cur->pos]);
8951} 8951}
8952 8952
8953#ifdef BIDI_SUPPORT
8954static Evas_Object_Textblock_Line*
8955_find_layout_line_by_item(Evas_Object_Textblock_Paragraph *par, Evas_Object_Textblock_Item *_it)
8956{
8957 Evas_Object_Textblock_Line *ln;
8958
8959 EINA_INLIST_FOREACH(par->lines, ln)
8960 {
8961 Evas_Object_Textblock_Item *it;
8962
8963 EINA_INLIST_FOREACH(ln->items, it)
8964 {
8965 if (_it == it)
8966 return ln;
8967 }
8968 }
8969 return NULL;
8970}
8971#endif
8972
8953EAPI Eina_Bool 8973EAPI Eina_Bool
8954evas_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) 8974evas_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)
8955{ 8975{
8956 const Evas_Textblock_Cursor *dir_cur;
8957 Evas_Textblock_Cursor cur2;
8958 if (!cur) return EINA_FALSE; 8976 if (!cur) return EINA_FALSE;
8959 Evas_Object_Textblock *o = eo_data_get(cur->obj, MY_CLASS); 8977 Evas_Object_Textblock *o = eo_data_get(cur->obj, MY_CLASS);
8960 if (!o->formatted.valid) _relayout(cur->obj); 8978 if (!o->formatted.valid) _relayout(cur->obj);
8961 8979
8962 dir_cur = cur;
8963 if (ctype == EVAS_TEXTBLOCK_CURSOR_UNDER) 8980 if (ctype == EVAS_TEXTBLOCK_CURSOR_UNDER)
8964 { 8981 {
8965 evas_textblock_cursor_pen_geometry_get(cur, cx, cy, cw, ch); 8982 evas_textblock_cursor_pen_geometry_get(cur, cx, cy, cw, ch);
8966 return EINA_FALSE; 8983 return EINA_FALSE;
8967 } 8984 }
8985
8986#ifdef BIDI_SUPPORT
8987#define IS_RTL(par) ((par) % 2)
8988#define IS_DIFFERENT_DIR(l1, l2) ((IS_RTL(l1) && (!IS_RTL(l2))) || \
8989 ((!IS_RTL(l1)) && IS_RTL(l2)))
8968 else 8990 else
8969 { 8991 {
8970 Evas_Object_Textblock_Line *ln = NULL; 8992 Evas_Object_Textblock_Line *ln = NULL;
@@ -8972,74 +8994,159 @@ evas_textblock_cursor_geometry_bidi_get(const Evas_Textblock_Cursor *cur, Evas_C
8972 _find_layout_item_match(cur, &ln, &it); 8994 _find_layout_item_match(cur, &ln, &it);
8973 if (ln && it) 8995 if (ln && it)
8974 { 8996 {
8975 if (cw) *cw = 0; 8997 if (ln->par->is_bidi)
8976 if (cw2) *cw2 = 0;
8977 /* If we are at the start or the end of the item there's a chance
8978 * we'll want a split cursor.
8979 * FIXME: Handle the last char of the last paragraph.
8980 * FIXME: Handle multiple items of the same direction.
8981 * FIXME: Handle items across different lines.. */
8982 if (cur->pos == it->text_pos)
8983 { 8998 {
8984 Evas_BiDi_Direction itdir = (it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ? 8999 if (cw) *cw = 0;
8985 _ITEM_TEXT(it)->text_props.bidi_dir : _ITEM_FORMAT(it)->bidi_dir; 9000 if (cw2) *cw2 = 0;
9001
9002 /* If we are at the start or the end of the item there's a chance
9003 * we'll want a split cursor. */
8986 Evas_Object_Textblock_Item *previt = NULL; 9004 Evas_Object_Textblock_Item *previt = NULL;
8987 Evas_BiDi_Direction previtdir = EVAS_BIDI_DIRECTION_NEUTRAL; 9005 Evas_Object_Textblock_Item *it1 = NULL, *it2 = NULL;
8988 /* Get the logically previous item. */ 9006 Evas_Coord adv1 = 0, adv2 = 0;
9007
9008 if (cur->pos == it->text_pos)
8989 { 9009 {
8990 Eina_List *itr; 9010 EvasBiDiLevel par_level, it_level, previt_level;
8991 Evas_Object_Textblock_Item *ititr; 9011
8992 EINA_LIST_FOREACH(ln->par->logical_items, itr, ititr) 9012 _layout_update_bidi_props(o, ln->par);
9013 par_level = *(ln->par->bidi_props->embedding_levels);
9014 it_level = ln->par->bidi_props->embedding_levels[it->text_pos];
9015 /* Get the logically previous item. */
8993 { 9016 {
8994 if (ititr == it) 9017 Eina_List *itr;
8995 break; 9018 Evas_Object_Textblock_Item *ititr;
8996 previt = ititr; 9019
9020 EINA_LIST_FOREACH(ln->par->logical_items, itr, ititr)
9021 {
9022 if (ititr == it)
9023 break;
9024 previt = ititr;
9025 }
9026
9027 if (previt)
9028 {
9029 previt_level = ln->par->bidi_props->embedding_levels[previt->text_pos];
9030 }
8997 } 9031 }
8998 9032
8999 if (previt) 9033 if (previt && (it_level != previt_level))
9000 { 9034 {
9001 previtdir = (previt->type == EVAS_TEXTBLOCK_ITEM_TEXT) ? 9035 Evas_Object_Textblock_Item *curit = NULL, *curit_opp = NULL;
9002 _ITEM_TEXT(previt)->text_props.bidi_dir : _ITEM_FORMAT(previt)->bidi_dir; 9036 EvasBiDiLevel cur_level;
9037
9038 if (it_level > previt_level)
9039 {
9040 curit = it;
9041 curit_opp = previt;
9042 cur_level = it_level;
9043 }
9044 else
9045 {
9046 curit = previt;
9047 curit_opp = it;
9048 cur_level = previt_level;
9049 }
9050
9051 if (((curit == it) && (!IS_RTL(par_level))) ||
9052 ((curit == previt) && (IS_RTL(par_level))))
9053 {
9054 adv1 = (IS_DIFFERENT_DIR(cur_level, par_level)) ?
9055 curit_opp->adv : 0;
9056 adv2 = curit->adv;
9057 }
9058 else if (((curit == previt) && (!IS_RTL(par_level))) ||
9059 ((curit == it) && (IS_RTL(par_level))))
9060 {
9061 adv1 = (IS_DIFFERENT_DIR(cur_level, par_level)) ?
9062 0 : curit->adv;
9063 adv2 = 0;
9064 }
9065
9066 if (!IS_DIFFERENT_DIR(cur_level, par_level))
9067 curit_opp = curit;
9068
9069 it1 = curit_opp;
9070 it2 = curit;
9003 } 9071 }
9072 /* Clear the bidi props because we don't need them anymore. */
9073 evas_bidi_paragraph_props_unref(ln->par->bidi_props);
9074 ln->par->bidi_props = NULL;
9004 } 9075 }
9005 9076 /* Handling last char in line (or in paragraph).
9006 if (previt && (itdir != previtdir)) 9077 * T.e. prev condition didn't work, so we are not standing in the beginning of item,
9078 * but in the end of line or paragraph. */
9079 else if (evas_textblock_cursor_eol_get(cur))
9007 { 9080 {
9008 Evas_Object_Textblock_Item *curit = NULL; 9081 EvasBiDiLevel par_level, it_level;
9009 /* If the current dir is different than the paragraph dir
9010 * this is our item. */
9011 if (itdir != ln->par->direction)
9012 {
9013 curit = it;
9014 }
9015 else
9016 {
9017 curit = previt;
9018 }
9019 9082
9020 if (((curit == it) && (ln->par->direction == EVAS_BIDI_DIRECTION_LTR)) || 9083 _layout_update_bidi_props(o, ln->par);
9021 ((curit == previt) && (ln->par->direction == EVAS_BIDI_DIRECTION_RTL))) 9084 par_level = *(ln->par->bidi_props->embedding_levels);
9022 { 9085 it_level = ln->par->bidi_props->embedding_levels[it->text_pos];
9023 if (cx) *cx = ln->x + curit->x; 9086
9024 if (cx2) *cx2 = ln->x + curit->x + curit->w; 9087 if (it_level > par_level)
9025 }
9026 else
9027 { 9088 {
9028 if (cx) *cx = ln->x + curit->x + curit->w; 9089 Evas_Object_Textblock_Item *lastit = it;
9029 if (cx2) *cx2 = ln->x + curit->x; 9090
9091 if (IS_RTL(par_level)) /* RTL par*/
9092 {
9093 /* We know, that all the items before current are of the same or bigger embedding level.
9094 * So search backwards for the first one. */
9095 while (EINA_INLIST_GET(lastit)->prev)
9096 {
9097 lastit = _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(lastit)->prev);
9098 }
9099
9100 adv1 = 0;
9101 adv2 = it->adv;
9102 }
9103 else /* LTR par */
9104 {
9105 /* We know, that all the items after current are of bigger or same embedding level.
9106 * So search forward for the last one. */
9107 while (EINA_INLIST_GET(lastit)->next)
9108 {
9109 lastit = _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(lastit)->next);
9110 }
9111
9112 adv1 = lastit->adv;
9113 adv2 = 0;
9114 }
9115
9116 it1 = lastit;
9117 it2 = it;
9030 } 9118 }
9119 /* Clear the bidi props because we don't need them anymore. */
9120 evas_bidi_paragraph_props_unref(ln->par->bidi_props);
9121 ln->par->bidi_props = NULL;
9122 }
9123
9124 if (it1 && it2)
9125 {
9126 Evas_Object_Textblock_Line *ln1 = NULL, *ln2 = NULL;
9127 ln1 = _find_layout_line_by_item(ln->par, it1);
9128 if (cx) *cx = ln1->x + it1->x + adv1;
9129 if (cy) *cy = ln1->par->y + ln1->y;
9130 if (ch) *ch = ln1->h;
9031 9131
9032 if (cy) *cy = ln->par->y + ln->y; 9132 ln2 = _find_layout_line_by_item(ln->par, it2);
9033 if (ch) *ch = curit->h; 9133 if (cx2) *cx2 = ln2->x + it2->x + adv2;
9134 if (cy2) *cy2 = ln2->par->y + ln2->y;
9135 if (ch2) *ch2 = ln2->h;
9034 9136
9035 if (cy2) *cy2 = ln->par->y + ln->y;
9036 if (ch2) *ch2 = curit->h;
9037 return EINA_TRUE; 9137 return EINA_TRUE;
9038 } 9138 }
9039 } 9139 }
9040 } 9140 }
9041 } 9141 }
9042 9142#undef IS_DIFFERENT_DIR
9143#undef IS_RTL
9144#else
9145 (void) cx2;
9146 (void) cy2;
9147 (void) cw2;
9148 (void) ch2;
9149#endif
9043 evas_textblock_cursor_geometry_get(cur, cx, cy, cw, ch, NULL, ctype); 9150 evas_textblock_cursor_geometry_get(cur, cx, cy, cw, ch, NULL, ctype);
9044 return EINA_FALSE; 9151 return EINA_FALSE;
9045} 9152}
diff --git a/src/tests/evas/evas_test_textblock.c b/src/tests/evas/evas_test_textblock.c
index ed16077e16..b1dcacc029 100644
--- a/src/tests/evas/evas_test_textblock.c
+++ b/src/tests/evas/evas_test_textblock.c
@@ -648,6 +648,332 @@ START_TEST(evas_textblock_cursor)
648} 648}
649END_TEST 649END_TEST
650 650
651START_TEST(evas_textblock_split_cursor)
652{
653#ifdef HAVE_FRIBIDI
654 START_TB_TEST();
655 Evas_Coord x, w, x2, w2;
656 Evas_Coord nw, nh;
657 Evas_Coord cx, cy, cx2, cy2;
658
659 /* Split cursor in LTR paragraph. */
660 /*0123456789 10 123 14 5678901234 */
661 evas_object_textblock_text_markup_set(tb, "test נסיון\u202babc\u202cנסיון bang");
662 evas_object_textblock_size_native_get(tb, &nw, &nh);
663 evas_object_resize(tb, nw, nh);
664
665 /* Logical cursor after "test " */
666 evas_textblock_cursor_pos_set(cur, 5);
667 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
668 NULL, &cx2, NULL, NULL, NULL,
669 EVAS_TEXTBLOCK_CURSOR_BEFORE));
670 evas_textblock_cursor_pos_set(cur, 4);
671 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
672 evas_textblock_cursor_pos_set(cur, 5);
673 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
674 fail_if(cx != (x + w));
675 fail_if(cx2 != (x2 + w2));
676
677 /* Logical cursor before " bang" */
678 evas_textblock_cursor_pos_set(cur, 20);
679 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
680 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
681 NULL, &cx2, NULL, NULL, NULL,
682 EVAS_TEXTBLOCK_CURSOR_BEFORE));
683 evas_textblock_cursor_pos_set(cur, 19);
684 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
685 fail_if(cx != x);
686 fail_if(cx2 != x2);
687
688 /* Logical cursor before "a" */
689 evas_textblock_cursor_pos_set(cur, 11);
690 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
691 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
692 NULL, &cx2, NULL, NULL, NULL,
693 EVAS_TEXTBLOCK_CURSOR_BEFORE));
694 evas_textblock_cursor_pos_set(cur, 9);
695 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
696 fail_if(cx != x);
697 fail_if(cx2 != x2);
698
699 /* Logical cursor after "c" */
700 evas_textblock_cursor_pos_set(cur, 15);
701 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
702 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
703 NULL, &cx2, NULL, NULL, NULL,
704 EVAS_TEXTBLOCK_CURSOR_BEFORE));
705 evas_textblock_cursor_pos_set(cur, 13);
706 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
707 fail_if(cx != (x + w));
708 fail_if(cx2 != (x2 + w2));
709
710 /* Logical cursor in the beginning */
711 evas_textblock_cursor_line_char_first(cur);
712 fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
713 NULL, NULL, NULL, NULL, NULL,
714 EVAS_TEXTBLOCK_CURSOR_BEFORE));
715 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
716 fail_if(cx != x);
717
718 /* Logical cursor in the end */
719 evas_textblock_cursor_line_char_last(cur);
720 fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
721 NULL, NULL, NULL, NULL, NULL,
722 EVAS_TEXTBLOCK_CURSOR_BEFORE));
723 evas_textblock_cursor_pos_set(cur, 24);
724 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
725 fail_if(cx != (x + w));
726
727 /* Logical cursor on the first pos */
728 evas_textblock_cursor_pos_set(cur, 1);
729 fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
730 NULL, NULL, NULL, NULL, NULL,
731 EVAS_TEXTBLOCK_CURSOR_BEFORE));
732 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
733 fail_if(cx != x);
734
735 /* Split cursor in RTL paragraph. */
736 /* 1 2
737 0123456789 0 12345 6 7890123456 */
738 evas_object_textblock_text_markup_set(tb, "שלום test \u202aעברית\u202c efl נסיון");
739 evas_object_textblock_size_native_get(tb, &nw, &nh);
740 evas_object_resize(tb, nw, nh);
741
742 /* Logical cursor before "test" */
743 evas_textblock_cursor_pos_set(cur, 4);
744 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
745 evas_textblock_cursor_pos_set(cur, 5);
746
747 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
748 NULL, &cx2, NULL, NULL, NULL,
749 EVAS_TEXTBLOCK_CURSOR_BEFORE));
750 evas_textblock_cursor_pos_set(cur, 5);
751 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
752 fail_if(cx != x);
753 fail_if(cx2 != x2);
754
755 /* Logical cursor after " efl" */
756 evas_textblock_cursor_pos_set(cur, 21);
757 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
758
759 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
760 NULL, &cx2, NULL, NULL, NULL,
761 EVAS_TEXTBLOCK_CURSOR_BEFORE));
762 evas_textblock_cursor_pos_set(cur, 20);
763 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
764 fail_if(cx != (x + w));
765 fail_if(cx2 != (x2 + w2));
766
767 /* Logical cursor before " efl" */
768 evas_textblock_cursor_pos_set(cur, 17);
769 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
770
771 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
772 NULL, &cx2, NULL, NULL, NULL,
773 EVAS_TEXTBLOCK_CURSOR_BEFORE));
774 evas_textblock_cursor_pos_set(cur, 15);
775 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
776 fail_if(cx != x2);
777 fail_if(cx2 != x);
778
779 /* Logical cursor after "test " */
780 evas_textblock_cursor_pos_set(cur, 11);
781 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
782
783 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
784 NULL, &cx2, NULL, NULL, NULL,
785 EVAS_TEXTBLOCK_CURSOR_BEFORE));
786 evas_textblock_cursor_pos_set(cur, 9);
787 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
788 fail_if(cx != (x + w));
789 fail_if(cx2 != (x2 + w2));
790
791 /* Logical cursor in the beginning */
792 evas_textblock_cursor_line_char_first(cur);
793 fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
794 NULL, NULL, NULL, NULL, NULL,
795 EVAS_TEXTBLOCK_CURSOR_BEFORE));
796 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
797 fail_if(cx != (x + w));
798
799 /* Logical cursor in the end */
800 evas_textblock_cursor_line_char_last(cur);
801 fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
802 NULL, NULL, NULL, NULL, NULL,
803 EVAS_TEXTBLOCK_CURSOR_BEFORE));
804 evas_textblock_cursor_pos_set(cur, 26);
805 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
806 fail_if(cx != x);
807
808 /* Corner cases for split cursor. */
809
810 /* End of line in LTR paragraph */
811 /* 1
812 01234567890123 4 567 */
813 evas_object_textblock_text_markup_set(tb, "test נסיוןشسيب\u202babc");
814 evas_textblock_cursor_line_char_last(cur);
815 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
816 evas_object_textblock_size_native_get(tb, &nw, &nh);
817 evas_object_resize(tb, nw, nh);
818
819 evas_textblock_cursor_line_char_last(cur);
820 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
821 NULL, &cx2, NULL, NULL, NULL,
822 EVAS_TEXTBLOCK_CURSOR_BEFORE));
823 evas_textblock_cursor_pos_set(cur, 4);
824 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
825 evas_textblock_cursor_pos_set(cur, 5);
826 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
827 fail_if(cx != (x + w));
828 fail_if(cx2 != (x2 + w2));
829
830 /* End of line in RTL paragraph */
831 /* 1 2
832 0123456789012345678 9 0123 */
833 evas_object_textblock_text_markup_set(tb, "נסיוןشسي testпривет\u202aשלום");
834 evas_object_textblock_size_native_get(tb, &nw, &nh);
835 evas_object_resize(tb, nw, nh);
836
837 evas_textblock_cursor_line_char_last(cur);
838 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
839 NULL, &cx2, NULL, NULL, NULL,
840 EVAS_TEXTBLOCK_CURSOR_BEFORE));
841 evas_textblock_cursor_pos_set(cur, 8);
842 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
843 evas_textblock_cursor_pos_set(cur, 9);
844 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
845 fail_if(cx != x);
846 fail_if(cx2 != x2);
847
848 /* Cursor is between items of the same direction */
849 evas_textblock_cursor_pos_set(cur, 13);
850 fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
851 NULL, NULL, NULL, NULL, NULL,
852 EVAS_TEXTBLOCK_CURSOR_BEFORE));
853 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
854 fail_if(cx != x);
855
856 /* Cursor type is UNDER */
857 evas_textblock_cursor_pos_set(cur, 0);
858 fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
859 NULL, NULL, NULL, NULL, NULL,
860 EVAS_TEXTBLOCK_CURSOR_UNDER));
861 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
862 fail_if(cx != x);
863
864 /* Multiline */
865 Evas_Coord ly;
866 int i;
867 /* 012345678901234 */
868 evas_object_textblock_text_markup_set(tb, "<wrap=char>testשלוםشسيبefl");
869 evas_object_textblock_size_native_get(tb, &nw, &nh);
870 nh = nh * 15;
871 evas_object_resize(tb, nw, nh);
872
873 for (i = 0; i < nw; i++)
874 {
875 evas_object_resize(tb, i, nh);
876
877 evas_textblock_cursor_pos_set(cur, 12);
878 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
879 NULL, &cx2, &cy2, NULL, NULL,
880 EVAS_TEXTBLOCK_CURSOR_BEFORE));
881 evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
882 fail_if(cy != ly);
883 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
884 fail_if(cx != x);
885 evas_textblock_cursor_pos_set(cur, 11);
886 evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
887 fail_if(cy2 != ly);
888 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
889 fail_if(cx2 != x2);
890 }
891 /* 01234567890123456789 */
892 evas_object_textblock_text_markup_set(tb, "<wrap=char>נסיוןhelloприветשלום");
893 evas_object_textblock_size_native_get(tb, &nw, &nh);
894 nh = nh * 20;
895 evas_object_resize(tb, nw, nh);
896
897 for (i = 0; i < nw; i++)
898 {
899 evas_object_resize(tb, i, nh);
900
901 evas_textblock_cursor_pos_set(cur, 16);
902 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
903 NULL, &cx2, &cy2, NULL, NULL,
904 EVAS_TEXTBLOCK_CURSOR_BEFORE));
905 evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
906 fail_if(cy != ly);
907 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
908 fail_if(cx != (x + w));
909 evas_textblock_cursor_pos_set(cur, 15);
910 evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
911 fail_if(cy2 != ly);
912 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
913 fail_if(cx2 != (x2 + w2));
914 }
915
916 /* Testing multiline, when only RTL item is in the line. */
917 /* 012345678901234567890123 */
918 evas_object_textblock_text_markup_set(tb, "<wrap=char>testtesttestтестשלוםشسيب");
919 evas_object_textblock_size_native_get(tb, &nw, &nh);
920 nh = nh * 23;
921 evas_object_resize(tb, nw, nh);
922
923 evas_textblock_cursor_pos_set(cur, 15);
924 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
925 /* Resizing textblock, so RTL item will be on the next line.*/
926 evas_object_resize(tb, x + w, nh);
927
928 evas_textblock_cursor_pos_set(cur, 24);
929 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
930 NULL, &cx2, &cy2, NULL, NULL,
931 EVAS_TEXTBLOCK_CURSOR_BEFORE));
932 evas_textblock_cursor_pos_set(cur, 16);
933 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
934 fail_if(cx != (x + w));
935 evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
936 fail_if(cy != ly);
937
938 evas_textblock_cursor_pos_set(cur, 23);
939 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
940 fail_if(cx2 != x2);
941 evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
942 fail_if(cy2 != ly);
943
944 /* Testing multiline, when only LTR item is in the line. */
945 /* 012345678901234567890123 */
946 evas_object_textblock_text_markup_set(tb, "<wrap=char>שלוםשלוםשלוםشسيبtestтест");
947 evas_object_textblock_size_native_get(tb, &nw, &nh);
948 nh = nh * 23;
949 evas_object_resize(tb, nw, nh);
950
951 evas_textblock_cursor_pos_set(cur, 15);
952 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
953 /* Resizing textblock, so LTR item will be on the next line.*/
954 evas_object_resize(tb, nw - x, nh);
955
956 evas_textblock_cursor_pos_set(cur, 24);
957 fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
958 NULL, &cx2, &cy2, NULL, NULL,
959 EVAS_TEXTBLOCK_CURSOR_BEFORE));
960 evas_textblock_cursor_pos_set(cur, 16);
961 evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
962 fail_if(cx != x);
963 evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
964 fail_if(cy != ly);
965
966 evas_textblock_cursor_pos_set(cur, 23);
967 evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
968 fail_if(cx2 != (x2 + w2));
969 evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
970 fail_if(cy2 != ly);
971
972 END_TB_TEST();
973#endif
974}
975END_TEST
976
651START_TEST(evas_textblock_format_removal) 977START_TEST(evas_textblock_format_removal)
652{ 978{
653 START_TB_TEST(); 979 START_TB_TEST();
@@ -2318,6 +2644,7 @@ void evas_test_textblock(TCase *tc)
2318{ 2644{
2319 tcase_add_test(tc, evas_textblock_simple); 2645 tcase_add_test(tc, evas_textblock_simple);
2320 tcase_add_test(tc, evas_textblock_cursor); 2646 tcase_add_test(tc, evas_textblock_cursor);
2647 tcase_add_test(tc, evas_textblock_split_cursor);
2321 tcase_add_test(tc, evas_textblock_size); 2648 tcase_add_test(tc, evas_textblock_size);
2322 tcase_add_test(tc, evas_textblock_editing); 2649 tcase_add_test(tc, evas_textblock_editing);
2323 tcase_add_test(tc, evas_textblock_style); 2650 tcase_add_test(tc, evas_textblock_style);