Evas textblock+font engine: Implemented evas_textblock_cursor_geometry_get.
authortasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 2 Sep 2010 11:49:00 +0000 (11:49 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 2 Sep 2010 11:49:00 +0000 (11:49 +0000)
Fixed evas_common_font_char_coords to work correctly with the NULL character in RTL text.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@51834 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/Evas.h
src/lib/canvas/evas_object_textblock.c
src/lib/engines/common/evas_font_query.c

index e0434df..eb144f3 100644 (file)
@@ -1337,6 +1337,12 @@ typedef void (*Evas_Object_Image_Pixels_Get_Cb) (void *data, Evas_Object *o);
        EVAS_TEXTBLOCK_TEXT_MARKUP
      } Evas_Textblock_Text_Type;
 
+   typedef enum _Evas_Textblock_Cursor_Type
+     {
+       EVAS_TEXTBLOCK_CURSOR_UNDER,
+       EVAS_TEXTBLOCK_CURSOR_BEFORE
+     } Evas_Textblock_Cursor_Type;
+
    EAPI Evas_Object                 *evas_object_textblock_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
    EAPI const char                  *evas_textblock_escape_string_get(const char *escape) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE;
@@ -1403,6 +1409,7 @@ typedef void (*Evas_Object_Image_Pixels_Get_Cb) (void *data, Evas_Object *o);
    EAPI int                          evas_textblock_cursor_paragraph_text_length_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE;
    EAPI char                        *evas_textblock_cursor_range_text_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2, Evas_Textblock_Text_Type format) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2) EINA_PURE;
 
+   EAPI int                          evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_Textblock_Cursor_Type ctype) EINA_ARG_NONNULL(1);
    EAPI int                          evas_textblock_cursor_char_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
    EAPI int                          evas_textblock_cursor_line_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
    EAPI Eina_Bool                    evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
index fd56002..c9b7e9d 100644 (file)
@@ -6421,6 +6421,68 @@ evas_textblock_cursor_format_is_visible_get(const Evas_Textblock_Cursor *cur)
               EINA_TRUE : EINA_FALSE;
 }
 
+/**
+ * Returns the geometry of the cursor. Depends on the type of cursor requested.
+ * This should be used instead of char_geometry_get because there are weird
+ * special cases with BiDi text.
+ * in '_' cursor mode (i.e a line below the char) it's the same as char_geometry
+ * get, except for the case of the last char of a line which depends on the
+ * paragraph direction.
+ *
+ * in '|' cursor mode (i.e a line between two chars) it is very varyable.
+ * For example consider the following visual string:
+ * "abcCBA" (ABC are rtl chars), a cursor pointing on A should actually draw
+ * a '|' between the c and the C.
+ *
+ * @param cur the cursor.
+ * @param cx the x of the cursor
+ * @param cy the y of the cursor
+ * @param cw the w of the cursor
+ * @param ch the h of the cursor
+ * @return line number of the char on success, -1 on error.
+ */
+EAPI int
+evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_Textblock_Cursor_Type ctype)
+{
+   if (ctype == EVAS_TEXTBLOCK_CURSOR_UNDER)
+     {
+        return evas_textblock_cursor_char_geometry_get(cur, cx, cy, cw, ch);
+     }
+   else if (ctype == EVAS_TEXTBLOCK_CURSOR_BEFORE)
+     {
+        /*FIXME: Rough sketch, not yet implemented - VERY buggy. */
+        /* In the case of a "before cursor", we should get the coordinates
+         * of just after the previous char (which in bidi text may not be
+         * just before the current char). */
+        Evas_Coord x, y, h, w;
+        int ret;
+
+        if (cur->pos > 0)
+          {
+             Evas_Textblock_Cursor cur2;
+             cur2.obj = cur->obj;
+             evas_textblock_cursor_copy(cur, &cur2);
+             cur2.pos--;
+             ret = evas_textblock_cursor_char_geometry_get(&cur2, &x, &y, &w, &h);
+          }
+        else
+          {
+             ret = evas_textblock_cursor_char_geometry_get(cur, &x, &y, &w, &h);
+             w = 0;
+          }
+        if (ret > 0)
+          {
+             if (cx) *cx = x + w;
+             if (cy) *cy = y + h;
+             if (cw) *cw = 0;
+             if (ch) *ch = 0;
+          }
+        return ret;
+     }
+
+   return -1;
+}
+
 
 /**
  * Returns the geometry of the char at cur.
@@ -6498,27 +6560,18 @@ evas_textblock_cursor_char_geometry_get(const Evas_Textblock_Cursor *cur, Evas_C
         ret = -1;
 
         if (pos < 0) pos = 0;
-        if (it->format->font.font) 
+        if (it->format->font.font)
           {
              ret = cur->ENFN->font_char_coords_get(cur->ENDT, it->format->font.font,
                    it->text, &it->bidi_props,
                    pos,
                    &x, &y, &w, &h);
           }
-        if (ret <= 0)
-          {
-             if (it->format->font.font)
-               cur->ENFN->font_string_size_get(cur->ENDT, it->format->font.font,
-                     it->text, &it->bidi_props, &w, &h);
-             x = w;
-             y = 0;
-             w = 0;
-         }
-       x = ln->x + it->x - it->inset + x;
+       x += ln->x + it->x - it->inset;
        if (x < ln->x)
          {
-            x = ln->x;
             w -= (ln->x - x);
+            x = ln->x;
          }
        y = ln->y;
        h = ln->h;
index 19f7001..c5a2fd7 100644 (file)
@@ -374,6 +374,26 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
 #else
    position = pos;
 #endif
+   /* If it's the null, choose location according to the direction. */
+   if (!text[position])
+     {
+        /* if it's rtl then the location is the left of the string,
+         * otherwise, the right. */
+        if (intl_props &&
+              EVAS_BIDI_PARAGRAPH_DIRECTION_IS_RTL(intl_props->props))
+          {
+             if (cx) *cx = 0;
+             if (ch) *ch = asc + desc;
+          }
+        else
+          {
+             evas_common_font_query_size(fn, text, intl_props, cx, ch);
+          }
+        if (cy) *cy = 0;
+        if (cw) *cw = 0;
+        ret_val = 1;
+        goto end;
+     }
 
    last_adv = 0;
    for (char_index = 0; *text ; text++, char_index++)