evas/edje: Add evas_textblock_cursor_cluster_* internal APIs. 07/58207/3
authorYoungbok Shin <youngb.shin@samsung.com>
Tue, 27 Jan 2015 08:16:26 +0000 (17:16 +0900)
committerYoungbok Shin <youngb.shin@samsung.com>
Fri, 29 Jan 2016 04:49:05 +0000 (20:49 -0800)
This is TIZEN_ONLY feature.

Change-Id: Ib99ec407b294ea2daf212e9968edcd76cff14ef2

src/lib/edje/edje_entry.c
src/lib/evas/Evas_Common.h
src/lib/evas/canvas/evas_object_textblock.c
src/lib/evas/common/evas_text_utils.h

index b6cbf84..2ecf30d 100644 (file)
@@ -500,7 +500,9 @@ _curs_jump_line(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en, int ln)
 
    if (!evas_object_textblock_line_number_geometry_get(o, ln, &lx, &ly, &lw, &lh))
      return EINA_FALSE;
-   if (evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
+   // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+   //if (evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
+   if (evas_textblock_cursor_cluster_coord_set(c, cx, ly + (lh / 2)))
      return EINA_TRUE;
    evas_textblock_cursor_line_set(c, ln);
    if (cx < (lx + (lw / 2)))
@@ -1543,7 +1545,9 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
                     }
                }
           }
-        if (evas_textblock_cursor_char_prev(en->cursor))
+        // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+        //if (evas_textblock_cursor_char_prev(en->cursor))
+        if (evas_textblock_cursor_cluster_prev(en->cursor))
           ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
         /* If control is pressed, go to the start of the word */
         if (control) evas_textblock_cursor_word_start(en->cursor);
@@ -1583,7 +1587,9 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
           }
         /* If control is pressed, go to the end of the word */
         if (control) evas_textblock_cursor_word_end(en->cursor);
-        if (evas_textblock_cursor_char_next(en->cursor))
+        // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+        //if (evas_textblock_cursor_char_next(en->cursor))
+        if (evas_textblock_cursor_cluster_next(en->cursor))
           ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
         if (en->select_allow)
           {
@@ -1601,7 +1607,10 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
              // del to start of previous word
              _sel_start(en->cursor, rp->object, en);
 
-             evas_textblock_cursor_char_prev(en->cursor);
+             // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+             //evas_textblock_cursor_char_prev(en->cursor);
+             evas_textblock_cursor_cluster_prev(en->cursor);
+             //
              evas_textblock_cursor_word_start(en->cursor);
 
              _sel_preextend(ed, en->cursor, rp->object, en);
@@ -1641,7 +1650,10 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
              _sel_start(en->cursor, rp->object, en);
 
              evas_textblock_cursor_word_end(en->cursor);
-             evas_textblock_cursor_char_next(en->cursor);
+             // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+             //evas_textblock_cursor_char_next(en->cursor);
+             evas_textblock_cursor_cluster_next(en->cursor);
+             //
 
              _sel_extend(ed, en->cursor, rp->object, en);
 
@@ -2131,7 +2143,10 @@ _edje_part_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_
                   else
                     {
                        evas_textblock_cursor_word_end(en->cursor);
-                       evas_textblock_cursor_char_next(en->cursor);
+                       // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+                       //evas_textblock_cursor_char_next(en->cursor);
+                       evas_textblock_cursor_cluster_next(en->cursor);
+                       //
                     }
                   _sel_extend(en->ed, en->cursor, rp->object, en);
                }
@@ -2145,7 +2160,10 @@ _edje_part_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_
                   evas_textblock_cursor_word_start(en->cursor);
                   _sel_start(en->cursor, rp->object, en);
                   evas_textblock_cursor_word_end(en->cursor);
-                  evas_textblock_cursor_char_next(en->cursor);
+                  // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+                  //evas_textblock_cursor_char_next(en->cursor);
+                  evas_textblock_cursor_cluster_next(en->cursor);
+                  //
                   _sel_extend(en->ed, en->cursor, rp->object, en);
                }
              goto end;
@@ -2313,7 +2331,9 @@ _edje_part_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UN
    evas_object_geometry_get(rp->object, &x, &y, &w, &h);
    cx = ev->canvas.x - x;
    cy = ev->canvas.y - y;
-   if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
+   // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs. //
+   //if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
+   if (!evas_textblock_cursor_cluster_coord_set(en->cursor, cx, cy))
      {
         Evas_Coord lx, ly, lw, lh;
         int line;
@@ -2327,7 +2347,9 @@ _edje_part_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UN
                {
                   evas_textblock_cursor_paragraph_first(en->cursor);
                   evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
-                  if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
+                  // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+                  //if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
+                  if (!evas_textblock_cursor_cluster_coord_set(en->cursor, cx, ly + (lh / 2)))
                     _curs_end(en->cursor, rp->object, en);
                }
           }
@@ -2425,7 +2447,9 @@ _edje_part_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_
         evas_object_geometry_get(rp->object, &x, &y, &w, &h);
         cx = ev->cur.canvas.x - x;
         cy = ev->cur.canvas.y - y;
-        if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
+        // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+        //if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
+        if (!evas_textblock_cursor_cluster_coord_set(en->cursor, cx, cy))
           {
              Evas_Coord lx, ly, lw, lh;
 
@@ -2437,7 +2461,9 @@ _edje_part_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_
                     {
                        evas_textblock_cursor_paragraph_first(en->cursor);
                        evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
-                       if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
+                       // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+                       //if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
+                       if (!evas_textblock_cursor_cluster_coord_set(en->cursor, cx, ly + (lh / 2)))
                          _curs_end(en->cursor, rp->object, en);
                     }
                }
@@ -3620,7 +3646,9 @@ _edje_entry_cursor_next(Edje_Real_Part *rp, Edje_Cursor cur)
 
    _edje_entry_imf_context_reset(rp);
 
-   if (!evas_textblock_cursor_char_next(c))
+   // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+   //if (!evas_textblock_cursor_char_next(c))
+   if (!evas_textblock_cursor_cluster_next(c))
      {
         return EINA_FALSE;
      }
@@ -3646,7 +3674,9 @@ _edje_entry_cursor_prev(Edje_Real_Part *rp, Edje_Cursor cur)
 
    _edje_entry_imf_context_reset(rp);
 
-   if (!evas_textblock_cursor_char_prev(c))
+   // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+   //if (!evas_textblock_cursor_char_prev(c))
+   if (!evas_textblock_cursor_cluster_prev(c))
      {
         if (evas_textblock_cursor_paragraph_prev(c)) goto ok;
         else return EINA_FALSE;
@@ -3684,7 +3714,9 @@ _edje_entry_cursor_up(Edje_Real_Part *rp, Edje_Cursor cur)
                                                        &lx, &ly, &lw, &lh))
      return EINA_FALSE;
    evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
-   if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
+   // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+   //if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
+   if (!evas_textblock_cursor_cluster_coord_set(c, cx, ly + (lh / 2)))
      evas_textblock_cursor_line_char_last(c);
    _sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
 
@@ -3717,9 +3749,10 @@ _edje_entry_cursor_down(Edje_Real_Part *rp, Edje_Cursor cur)
                                                        &lx, &ly, &lw, &lh))
      return EINA_FALSE;
    evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
-   if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
+   // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+   //if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
+   if (!evas_textblock_cursor_cluster_coord_set(c, cx, ly + (lh / 2)))
      evas_textblock_cursor_line_char_last(c);
-
    _sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
 
    _edje_entry_imf_cursor_info_set(en);
@@ -3852,7 +3885,10 @@ _edje_entry_cursor_coord_set(Edje_Real_Part *rp, Edje_Cursor cur,
         if (en->have_selection)
           _edje_emit(en->ed, "selection,changed", rp->part->name);
      }
-   return evas_textblock_cursor_char_coord_set(c, x, y);
+   // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+   //return evas_textblock_cursor_char_coord_set(c, x, y);
+   return evas_textblock_cursor_cluster_coord_set(c, x, y);
+   //
 }
 
 Eina_Bool
index af8f5ca..a5b84e9 100755 (executable)
@@ -3496,6 +3496,28 @@ EAPI Eina_Bool                                evas_textblock_cursor_char_next(Ev
 EAPI Eina_Bool                                evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
+ * @internal
+ * TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+ * Advances 1 cluster forward.
+ * Cluster is an text ligature. 
+ *
+ * @param cur the cursor to advance.
+ * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool                                evas_textblock_cursor_cluster_next(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+
+/**
+ * @internal
+ * TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+ * Advances 1 cluster backward.
+ * Cluster is an text ligature. 
+ *
+ * @param cur the cursor to advance.
+ * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool                                evas_textblock_cursor_cluster_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+
+/**
  * Moves the cursor to the start of the word under the cursor.
  *
  * @param cur the cursor to move.
@@ -3825,6 +3847,18 @@ EAPI int                                      evas_textblock_cursor_line_geometr
 EAPI Eina_Bool                                evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
 
 /**
+ * @internal
+ * TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+ * Set the position of the cursor according to the X and Y coordinates and text ligature.
+ *
+ * @param cur the cursor to set.
+ * @param x coord to set by.
+ * @param y coord to set by.
+ * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ */
+EAPI Eina_Bool                                evas_textblock_cursor_cluster_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
+
+/**
  * Set the cursor position according to the y coord.
  *
  * @param cur the cur to be set.
index d3d8eaf..df3efbf 100644 (file)
@@ -8238,8 +8238,11 @@ evas_textblock_cursor_word_end(Evas_Textblock_Cursor *cur)
    return EINA_TRUE;
 }
 
-EAPI Eina_Bool
-evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
+/////////////////////////////////////////////////////////////////////
+// TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs. //
+/////////////////////////////////////////////////////////////////////
+static Eina_Bool
+_evas_textblock_cursor_next(Evas_Textblock_Cursor *cur, Eina_Bool per_cluster)
 {
    int ind;
    const Eina_Unicode *text;
@@ -8251,7 +8254,70 @@ evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
 
    ind = cur->pos;
    text = eina_ustrbuf_string_get(cur->node->unicode);
-   if (text[ind]) ind++;
+
+   if (text[ind])
+     {
+        if (per_cluster)
+          {
+             Evas_Object_Textblock_Paragraph *par = cur->node->par;
+
+             if (par)
+               {
+                  Eina_List *l;
+                  Evas_Object_Textblock_Item *it, *last_it = NULL;
+                  EINA_LIST_FOREACH(par->logical_items, l, it)
+                    {
+                       if (it->text_pos > cur->pos)
+                         {
+                            if (!last_it) last_it = it;
+                            break;
+                         }
+                       last_it = it;
+                    }
+
+                  if (last_it)
+                    {
+                       if ((last_it->type == EVAS_TEXTBLOCK_ITEM_TEXT) &&
+                           (CHECK_LANGUAGE_CLUSTER_AVAILABLE(_ITEM_TEXT(last_it)->text_props.script)))
+                         {
+                            size_t cluster_pos = 0;
+                            int i;
+
+                            cluster_pos = last_it->text_pos + (size_t)evas_common_text_props_cluster_next(
+                               &_ITEM_TEXT(last_it)->text_props, cur->pos - last_it->text_pos);
+
+                            if (cluster_pos == cur->pos)
+                              {
+                                 if (it)
+                                   {
+                                      cluster_pos = it->text_pos;
+                                   }
+                                 else
+                                   {
+                                      cluster_pos = eina_ustrbuf_length_get(cur->node->unicode);
+                                   }
+                              }
+
+                            /* Check cluster exception characters */
+                            for (i = cur->pos + 1; i < (int)cluster_pos; i++)
+                              {
+                                 if (text[i] && CHECK_CLUSTER_EXCEPTION_CHAR(text[i]))
+                                   {
+                                      cluster_pos = i;
+                                      break;
+                                   }
+                              }
+
+                            ind = cluster_pos;
+                         }
+                    }
+               }
+          }
+
+        if (ind <= (int)cur->pos)
+          ind = cur->pos + 1;
+     }
+
    /* Only allow pointing a null if it's the last paragraph.
     * because we don't have a PS there. */
    if (text[ind])
@@ -8278,9 +8344,137 @@ evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
      }
 }
 
+static Eina_Bool
+_evas_textblock_cursor_prev(Evas_Textblock_Cursor *cur, Eina_Bool per_cluster)
+{
+   const Eina_Unicode *text;
+
+   if (!cur) return EINA_FALSE;
+   TB_NULL_CHECK(cur->node, EINA_FALSE);
+
+   text = eina_ustrbuf_string_get(cur->node->unicode);
+
+   if (cur->pos != 0)
+     {
+        if (per_cluster)
+          {
+             Evas_Object_Textblock_Paragraph *par = cur->node->par;
+
+             if (par)
+               {
+                  Eina_List *l;
+                  Evas_Object_Textblock_Item *it, *last_it = NULL;
+                  EINA_LIST_FOREACH(par->logical_items, l, it)
+                    {
+                       if (it->text_pos >= cur->pos)
+                         {
+                            if (!last_it) last_it = it;
+                            break;
+                         }
+                       last_it = it;
+                    }
+
+                  if (last_it)
+                    {
+                       if ((last_it->type == EVAS_TEXTBLOCK_ITEM_TEXT) &&
+                           (CHECK_LANGUAGE_CLUSTER_AVAILABLE(_ITEM_TEXT(last_it)->text_props.script)))
+                         {
+                            size_t cluster_temp = 0;
+                            size_t cluster_pos;
+                            int i = 0;
+
+                            cluster_pos = last_it->text_pos + (size_t)evas_common_text_props_cluster_prev(
+                               &_ITEM_TEXT(last_it)->text_props, cur->pos - last_it->text_pos);
+                            cluster_temp = cluster_pos;
+
+                            while ((cur->pos - i > last_it->text_pos) &&
+                                   (cluster_temp == cur->pos - i))
+                              {
+                                 cluster_pos--;
+                                 i++;
+                                 cluster_temp = last_it->text_pos + evas_common_text_props_cluster_prev(
+                                    &_ITEM_TEXT(last_it)->text_props, cur->pos - last_it->text_pos - i);
+                              }
+
+                            /* Check cluster exception characters */
+                            for (i = cur->pos - 1; i > (int)cluster_pos; i--)
+                              {
+                                 if (text[i] && CHECK_CLUSTER_EXCEPTION_CHAR(text[i]))
+                                   {
+                                      cluster_pos = i;
+                                      break;
+                                   }
+                              }
+
+                            cur->pos = cluster_pos;
+                            return EINA_TRUE;
+                         }
+                    }
+               }
+          }
+
+        cur->pos--;
+        return EINA_TRUE;
+     }
+   return evas_textblock_cursor_paragraph_prev(cur);
+}
+
+EAPI Eina_Bool
+evas_textblock_cursor_cluster_next(Evas_Textblock_Cursor *cur)
+{
+   return _evas_textblock_cursor_next(cur, EINA_TRUE);
+}
+
+EAPI Eina_Bool
+evas_textblock_cursor_cluster_prev(Evas_Textblock_Cursor *cur)
+{
+   return _evas_textblock_cursor_prev(cur, EINA_TRUE);
+}
+
+EAPI Eina_Bool
+evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
+{
+   // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+   /*
+   int ind;
+   const Eina_Unicode *text;
+
+   if (!cur) return EINA_FALSE;
+   TB_NULL_CHECK(cur->node, EINA_FALSE);
+
+   ind = cur->pos;
+   text = eina_ustrbuf_string_get(cur->node->unicode);
+   if (text[ind]) ind++;
+   if (text[ind])
+     {
+        cur->pos = ind;
+        return EINA_TRUE;
+     }
+   else
+     {
+        if (!evas_textblock_cursor_paragraph_next(cur))
+          {
+             if (cur->pos == (size_t) ind)
+               return EINA_FALSE;
+
+             cur->pos = ind;
+             return EINA_TRUE;
+          }
+        else
+          {
+             return EINA_TRUE;
+          }
+     }
+   */
+   return _evas_textblock_cursor_next(cur, EINA_FALSE);
+   //
+}
+
 EAPI Eina_Bool
 evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur)
 {
+   // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs.
+   /*
    if (!cur) return EINA_FALSE;
    Evas_Object_Protected_Data *obj = eo_data_scope_get(cur->obj, EVAS_OBJECT_CLASS);
    evas_object_async_block(obj);
@@ -8292,7 +8486,11 @@ evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur)
         return EINA_TRUE;
      }
    return evas_textblock_cursor_paragraph_prev(cur);
+   */
+   return _evas_textblock_cursor_prev(cur, EINA_FALSE);
+   //
 }
+///////////////////////////////////////////////////////////////////
 
 EAPI void
 evas_textblock_cursor_paragraph_char_first(Evas_Textblock_Cursor *cur)
@@ -10675,8 +10873,11 @@ evas_textblock_cursor_visible_range_get(Evas_Textblock_Cursor *start, Evas_Textb
    return EINA_TRUE;
 }
 
-EAPI Eina_Bool
-evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y)
+/////////////////////////////////////////////////////////////////////
+// TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs. //
+/////////////////////////////////////////////////////////////////////
+static Eina_Bool
+_evas_textblock_cursor_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y, Eina_Bool per_cluster)
 {
    Evas_Object_Textblock_Paragraph *found_par;
    Evas_Object_Textblock_Line *ln;
@@ -10751,8 +10952,14 @@ evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, E
                                          &ti->text_props,
                                          x - it->x - ln->x, 0,
                                          &cx, &cy, &cw, &ch);
+
                                  if (pos < 0)
                                    return EINA_FALSE;
+
+                                 while (per_cluster && (evas_common_text_props_index_find(&ti->text_props, pos) == -1) &&
+                                        CHECK_LANGUAGE_CLUSTER_AVAILABLE(ti->text_props.script))
+                                   pos--;
+
                                  cur->pos = pos + it->text_pos;
                                  cur->node = it->text_node;
                                  return EINA_TRUE;
@@ -10791,6 +10998,127 @@ evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, E
    return EINA_FALSE;
 }
 
+EAPI Eina_Bool
+evas_textblock_cursor_cluster_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y)
+{
+   return _evas_textblock_cursor_coord_set(cur, x, y, EINA_TRUE);
+}
+
+EAPI Eina_Bool
+evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y)
+{
+   /*
+   Evas_Object_Textblock_Paragraph *found_par;
+   Evas_Object_Textblock_Line *ln;
+   Evas_Object_Textblock_Item *it = NULL;
+
+   if (!cur) return EINA_FALSE;
+   Evas_Textblock_Data *o = eo_data_scope_get(cur->obj, MY_CLASS);
+
+   _relayout_if_needed(cur->obj, o);
+
+   x += o->style_pad.l;
+   y += o->style_pad.t;
+
+   found_par = _layout_find_paragraph_by_y(o, y);
+   if (found_par)
+     {
+        _layout_paragraph_render(o, found_par);
+        EINA_INLIST_FOREACH(found_par->lines, ln)
+          {
+             if (ln->par->y + ln->y > y) break;
+             if ((ln->par->y + ln->y <= y) && ((ln->par->y + ln->y + ln->h) > y))
+               {
+                  if (x < ln->x)
+                    {
+                       cur->pos = ln->items->text_pos;
+                       cur->node = found_par->text_node;
+                       if (found_par->direction == EVAS_BIDI_DIRECTION_RTL)
+                         {
+                            evas_textblock_cursor_line_char_last(cur);
+                         }
+                       else
+                         {
+                            evas_textblock_cursor_line_char_first(cur);
+                         }
+                       return EINA_TRUE;
+                    }
+                  else if (x >= ln->x + ln->w)
+                    {
+                       cur->pos = ln->items->text_pos;
+                       cur->node = found_par->text_node;
+                       if (found_par->direction == EVAS_BIDI_DIRECTION_RTL)
+                         {
+                            evas_textblock_cursor_line_char_first(cur);
+                         }
+                       else
+                         {
+                            evas_textblock_cursor_line_char_last(cur);
+                         }
+                       return EINA_TRUE;
+                    }
+
+                  Evas_Object_Protected_Data *obj = eo_data_scope_get(cur->obj, EVAS_OBJECT_CLASS);
+                  EINA_INLIST_FOREACH(ln->items, it)
+                    {
+                       if (((it->x + ln->x) <= x) && (((it->x + ln->x) + it->adv) > x))
+                         {
+                            if (it->type == EVAS_TEXTBLOCK_ITEM_TEXT)
+                              {
+                                 int pos;
+                                 int cx, cy, cw, ch;
+                                 Evas_Object_Textblock_Text_Item *ti;
+                                 ti = _ITEM_TEXT(it);
+
+                                 pos = -1;
+                                 if (ti->parent.format->font.font)
+                                   pos = ENFN->font_char_at_coords_get(
+                                         ENDT,
+                                         ti->parent.format->font.font,
+                                         &ti->text_props,
+                                         x - it->x - ln->x, 0,
+                                         &cx, &cy, &cw, &ch);
+                                 if (pos < 0)
+                                   return EINA_FALSE;
+                                 cur->pos = pos + it->text_pos;
+                                 cur->node = it->text_node;
+                                 return EINA_TRUE;
+                              }
+                            else
+                              {
+                                 Evas_Object_Textblock_Format_Item *fi;
+                                 fi = _ITEM_FORMAT(it);
+                                 cur->pos = fi->parent.text_pos;
+                                 cur->node = found_par->text_node;
+                                 return EINA_TRUE;
+                              }
+                         }
+                    }
+               }
+          }
+     }
+
+   if (o->paragraphs)
+     {
+        Evas_Object_Textblock_Line *first_line = o->paragraphs->lines;
+        if (y >= o->paragraphs->y + o->formatted.h)
+          {
+             evas_textblock_cursor_paragraph_last(cur);
+             return EINA_TRUE;
+          }
+        else if (o->paragraphs && (y < (o->paragraphs->y + first_line->y)))
+          {
+             evas_textblock_cursor_paragraph_first(cur);
+             return EINA_TRUE;
+          }
+     }
+
+   return EINA_FALSE;
+   */
+   return _evas_textblock_cursor_coord_set(cur, x, y, EINA_FALSE);
+}
+////////////////////////////////////////////////////////////////////
+
 EAPI int
 evas_textblock_cursor_line_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord y)
 {
index e54046d..8b9dd97 100644 (file)
@@ -23,6 +23,28 @@ typedef enum
 /* Used for showing "malformed" or missing chars */
 #define REPLACEMENT_CHAR 0xFFFD
 
+/////////////////////////////////////////////////////////////////////
+// TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs. //
+/////////////////////////////////////////////////////////////////////
+#define CHECK_LANGUAGE_CLUSTER_AVAILABLE(script) \
+   (((script == EVAS_SCRIPT_THAI) || \
+     (script == EVAS_SCRIPT_DEVANAGARI) || \
+     (script == EVAS_SCRIPT_BENGALI) || \
+     (script == EVAS_SCRIPT_GUJARATI) || \
+     (script == EVAS_SCRIPT_TELUGU) || \
+     (script == EVAS_SCRIPT_KHMER) || \
+     (script == EVAS_SCRIPT_SINHALA) || \
+     (script == EVAS_SCRIPT_KANNADA) || \
+     (script == EVAS_SCRIPT_MALAYALAM) || \
+     (script == EVAS_SCRIPT_GURMUKHI) || \
+     (script == EVAS_SCRIPT_ORIYA) || \
+     (script == EVAS_SCRIPT_TAMIL)) ? \
+    EINA_TRUE : EINA_FALSE)
+
+#define CHECK_CLUSTER_EXCEPTION_CHAR(x) \
+   (0x0E33 == (x))
+//
+
 typedef struct _Evas_Glyph Evas_Glyph;
 typedef struct _Evas_Glyph_Array Evas_Glyph_Array;