herdsman pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=20ef85e307818c7c92927688ee6fd5d9dec1ee8f

commit 20ef85e307818c7c92927688ee6fd5d9dec1ee8f
Author: Youngbok Shin <youngb.s...@samsung.com>
Date:   Wed Dec 9 09:50:33 2015 +0200

    Evas text: Fix Evas Text truncated text case.
    
    Summary:
    Evas Text only concerns about a advance of each text item.
    When a width of last character is bigger than its advance, the last 
character can be truncated.
    And the different line size calculation caused different aligning between 
Evas Text and Evas Textblock.
    So, the width of last character will be considered in Evas Text just like 
Evas Textblock.
    @fix
    
    Test Plan:
    The following text shows how the size calculation is different between Evas 
Textblock and Text.
    Get native size from Evas Textblock and get width(geometry) of Evas Text.
    You can see the width of Evas Text is bigger than native size of Evas 
Textblock.
    (adv > width)
    こんにちは。
    
    The following text will be truncated without this patch.
    (adv < width)
    ନୂଁ
    
    Reviewers: woohyun, tasn, herdsman
    
    Subscribers: jpeg, cedric
    
    Differential Revision: https://phab.enlightenment.org/D3004
---
 src/lib/evas/canvas/evas_object_text.c | 33 ++++++++++-------
 src/tests/evas/evas_test_text.c        | 65 ++++++++++++++++++++++++++--------
 2 files changed, 71 insertions(+), 27 deletions(-)

diff --git a/src/lib/evas/canvas/evas_object_text.c 
b/src/lib/evas/canvas/evas_object_text.c
index ff3e761..46b2039 100644
--- a/src/lib/evas/canvas/evas_object_text.c
+++ b/src/lib/evas/canvas/evas_object_text.c
@@ -54,7 +54,7 @@ struct _Evas_Text_Data
       Evas_Object_Text_Item    *ellipsis_end;
       Evas_Coord                w, h;
       int                       advance;
-      int                       advance_without_ellipsis;
+      int                       width_without_ellipsis;
       Eina_Bool                 ellipsis;
    } last_computed;
 
@@ -348,9 +348,9 @@ _evas_object_text_char_at_coords(const Evas_Object *eo_obj,
 }
 
 static Evas_Coord
-_evas_object_text_horiz_advance_without_ellipsis_get(const Evas_Text_Data *o)
+_evas_object_text_horiz_width_without_ellipsis_get(const Evas_Text_Data *o)
 {
-   return o->last_computed.advance_without_ellipsis;
+   return o->last_computed.width_without_ellipsis;
 }
 
 static Evas_Coord
@@ -685,7 +685,7 @@ _evas_object_text_layout(Evas_Object *eo_obj, 
Evas_Text_Data *o, Eina_Unicode *t
 {
    Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, 
EVAS_OBJECT_CLASS);
    EvasBiDiStrIndex *v_to_l = NULL;
-   Evas_Coord advance = 0;
+   Evas_Coord advance = 0, width = 0;
    size_t pos, visual_pos;
    int len = eina_unicode_strlen(text);
    int l = 0, r = 0;
@@ -754,6 +754,8 @@ _evas_object_text_layout(Evas_Object *eo_obj, 
Evas_Text_Data *o, Eina_Unicode *t
 
    if (text)
      {
+        const Evas_Object_Text_Item *last_it = NULL;
+
         while (len > 0)
           {
              Evas_Font_Instance *script_fi = NULL;
@@ -791,15 +793,22 @@ _evas_object_text_layout(Evas_Object *eo_obj, 
Evas_Text_Data *o, Eina_Unicode *t
                   pos += run_len;
                   script_len -= run_len;
                   len -= run_len;
+
+                  if (it->w > 0)
+                    last_it = it;
                }
           }
+
+        width = advance;
+        if (last_it)
+          width += last_it->w - last_it->adv;
      }
-   o->last_computed.advance_without_ellipsis = advance;
+   o->last_computed.width_without_ellipsis = width;
 
    _evas_object_text_pad_get(eo_obj, o, &l, &r, NULL, NULL);
 
    /* Handle ellipsis */
-   if (pos && (o->cur.ellipsis >= 0.0) && (advance + l + r > 
obj->cur->geometry.w) && (obj->cur->geometry.w > 0))
+   if (pos && (o->cur.ellipsis >= 0.0) && (width + l + r > 
obj->cur->geometry.w) && (obj->cur->geometry.w > 0))
      {
         Evas_Coord ellip_frame = obj->cur->geometry.w;
         Evas_Object_Text_Item *start_ellip_it = NULL, *end_ellip_it = NULL;
@@ -821,7 +830,7 @@ _evas_object_text_layout(Evas_Object *eo_obj, 
Evas_Text_Data *o, Eina_Unicode *t
                   start_ellip_it = _layout_ellipsis_item_new(obj, o);
                }
              o->last_computed.ellipsis_start = start_ellip_it;
-             ellip_frame -= start_ellip_it->adv;
+             ellip_frame -= start_ellip_it->w;
           }
         if (o->cur.ellipsis != 1)
           {
@@ -837,18 +846,18 @@ _evas_object_text_layout(Evas_Object *eo_obj, 
Evas_Text_Data *o, Eina_Unicode *t
                   end_ellip_it = _layout_ellipsis_item_new(obj, o);
                }
              o->last_computed.ellipsis_end = end_ellip_it;
-             ellip_frame -= end_ellip_it->adv;
+             ellip_frame -= end_ellip_it->w;
           }
 
         /* The point where we should start from, going for the full
          * ellip frame. */
-        Evas_Coord ellipsis_coord = o->cur.ellipsis * (advance - ellip_frame);
+        Evas_Coord ellipsis_coord = o->cur.ellipsis * (width - ellip_frame);
         if (start_ellip_it)
           {
              Evas_Object_Text_Item *itr = o->items;
              advance = 0;
 
-             while (itr && (advance + l + r + itr->adv < ellipsis_coord))
+             while (itr && (advance + l + r + itr->w < ellipsis_coord))
                {
                   Eina_Inlist *itrn = EINA_INLIST_GET(itr)->next;
                   if ((itr != start_ellip_it) && (itr != end_ellip_it))
@@ -890,7 +899,7 @@ _evas_object_text_layout(Evas_Object *eo_obj, 
Evas_Text_Data *o, Eina_Unicode *t
                {
                   if (itr != end_ellip_it) /* was start_ellip_it */
                     {
-                       if (advance + l + r + itr->adv >= ellip_frame)
+                       if (advance + l + r + itr->w >= ellip_frame)
                          {
                             break;
                          }
@@ -2243,7 +2252,7 @@ _evas_object_text_recalc(Evas_Object *eo_obj, 
Eina_Unicode *text)
         int w, h;
         int l = 0, r = 0, t = 0, b = 0;
 
-        w = _evas_object_text_horiz_advance_without_ellipsis_get(o);
+        w = _evas_object_text_horiz_width_without_ellipsis_get(o);
         h = _evas_object_text_vert_advance_get(eo_obj, o);
         _evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
 
diff --git a/src/tests/evas/evas_test_text.c b/src/tests/evas/evas_test_text.c
index 128e8ac..fe5644a 100644
--- a/src/tests/evas/evas_test_text.c
+++ b/src/tests/evas/evas_test_text.c
@@ -141,6 +141,20 @@ START_TEST(evas_text_geometries)
    pos = evas_object_text_last_up_to_pos(to, -50, 0);
    ck_assert_int_eq(pos, -1);
 
+   /* Obviously, adv > width case */
+   evas_object_text_text_set(to, "こんにちは。");
+   adv = evas_object_text_horiz_advance_get(to);
+   evas_object_geometry_get(to, NULL, NULL, &w, NULL);
+   ck_assert_int_lt(w, adv);
+
+#ifdef HAVE_HARFBUZZ
+   /* Obviously, adv < width case */
+   evas_object_text_text_set(to, "ନୂଁ");
+   adv = evas_object_text_horiz_advance_get(to);
+   evas_object_geometry_get(to, NULL, NULL, &w, NULL);
+   ck_assert_int_lt(adv, w);
+#endif
+
    END_TEXT_TEST();
 }
 END_TEST
@@ -172,27 +186,36 @@ END_TEST
 static void
 _test_ellipsis(Evas_Object *to, const char *buf, const char *font, 
Evas_Font_Size size, double ellipsis)
 {
+   Evas_Coord text_width;
+   Evas_Coord w, h;
+
    evas_object_text_ellipsis_set(to, ellipsis);
    evas_object_move(to, 0, 0);
-   evas_object_resize(to, 500, 500);
    evas_object_text_font_set(to, font, size);
    evas_object_text_text_set(to, buf);
+   /* Besure to give a enough width for text. */
+   evas_object_resize(to, 500, 500);
+   /* Because of the way text object behaves, this will actually force
+    * a resize. */
+   evas_object_geometry_get(to, NULL, NULL, &w, NULL);
+
+   text_width = w;
+   /* Force a resize. */
+   evas_object_resize(to, text_width - 1, 500);
+   evas_object_geometry_get(to, NULL, NULL, &w, NULL);
+   ck_assert_int_ne(text_width, w);
 
    /* Make it smaller to force ellipsis and check the resulting size. */
-     {
-        Evas_Coord w, h;
-        evas_object_geometry_get(to, NULL, NULL, NULL, &h);
-        evas_object_resize(to, 140, h);
-
-        /* Because of the way text object behaves, this will actually force
-         * a resize. */
-        evas_object_geometry_get(to, NULL, NULL, &w, NULL);
-        /* If it's gotten way too small, it means we have an issue. */
-        fail_if(w < 100);
-
-        w = evas_object_text_horiz_advance_get(to);
-        fail_if(w < 100);
-     }
+   evas_object_geometry_get(to, NULL, NULL, NULL, &h);
+   evas_object_resize(to, 140, h);
+
+   /* Force a resize. */
+   evas_object_geometry_get(to, NULL, NULL, &w, NULL);
+   /* If it's gotten way too small, it means we have an issue. */
+   fail_if(w < 100);
+
+   w = evas_object_text_horiz_advance_get(to);
+   fail_if(w < 100);
 }
 
 START_TEST(evas_text_ellipsis)
@@ -225,6 +248,18 @@ START_TEST(evas_text_ellipsis)
    buf = "Fffffffffffffffffffffffffffffffffff";
    _test_ellipsis(to, buf, font, size, 0.0);
 
+   /* Obviously, adv > width case */
+   buf = "This is a test for adv > width case. こんにちは。";
+   _test_ellipsis(to, buf, font, size, 0.0);
+   _test_ellipsis(to, buf, font, size, 0.5);
+   _test_ellipsis(to, buf, font, size, 1.0);
+
+   /* Obviously, adv < width case */
+   buf = "This is a test for adv < width case. ନୂଁ";
+   _test_ellipsis(to, buf, font, size, 0.0);
+   _test_ellipsis(to, buf, font, size, 0.5);
+   _test_ellipsis(to, buf, font, size, 1.0);
+
    /* Check ellipsis value with NULL */
    fail_if(evas_object_text_ellipsis_get(NULL) != -1.0);
 

-- 


Reply via email to