raster pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=1ab87367d8f1c0f416a65c4a43d96bb2f3683052

commit 1ab87367d8f1c0f416a65c4a43d96bb2f3683052
Author: Youngbok Shin <youngb.s...@samsung.com>
Date:   Mon Apr 10 12:15:19 2017 +0900

    evas: give width offset when Evas tries to find ellipsis position
    
    Summary:
    If the last item before ellipsis item has bigger width than its advance,
    evas_common_font_query_last_up_to_pos() function can find wrong ellipsis 
position.
    When Evas finds a position for non last item, Evas must care about 
additionally
    available space for glyph's width of the given x position.
    
    ex) the last item's glyph before ellipsis item has a tail to draw above the 
ellipsis item.
    
    @fix
    
    Test Plan:
    Test case will added as comment.
    (Becasue of font license problem.)
    
    Reviewers: herdsman, raster, jpeg, woohyun
    
    Subscribers: cedric, Blackmole
    
    Differential Revision: https://phab.enlightenment.org/D4727
---
 src/lib/evas/canvas/evas_object_text.c             |  8 ++++----
 src/lib/evas/canvas/evas_object_textblock.c        | 24 +++++++++++-----------
 src/lib/evas/common/evas_font.h                    |  2 +-
 src/lib/evas/common/evas_font_query.c              | 12 +++++++++--
 src/lib/evas/include/evas_private.h                |  2 +-
 .../evas/engines/software_generic/evas_engine.c    |  4 ++--
 6 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/src/lib/evas/canvas/evas_object_text.c 
b/src/lib/evas/canvas/evas_object_text.c
index c91e9d2..6e6f510 100644
--- a/src/lib/evas/canvas/evas_object_text.c
+++ b/src/lib/evas/canvas/evas_object_text.c
@@ -309,7 +309,7 @@ _evas_object_text_last_up_to_pos(const Evas_Object *eo_obj,
                         o->font,
                         &it->text_props,
                         cx - x,
-                        cy);
+                        cy, 0);
                   break;
                }
              x += it->adv;
@@ -327,7 +327,7 @@ _evas_object_text_last_up_to_pos(const Evas_Object *eo_obj,
                         o->font,
                         &it->text_props,
                         cx - it->x,
-                        cy);
+                        cy, 0);
                }
           }
      }
@@ -893,7 +893,7 @@ _evas_object_text_layout(Evas_Object *eo_obj, 
Evas_Text_Data *o, Eina_Unicode *t
                         o->font,
                         &itr->text_props,
                         ellipsis_coord - (advance + l + r),
-                        0);
+                        0, start_ellip_it->w);
                   if (cut >= 0)
                     {
                        start_ellip_it->text_pos = itr->text_pos;
@@ -948,7 +948,7 @@ _evas_object_text_layout(Evas_Object *eo_obj, 
Evas_Text_Data *o, Eina_Unicode *t
                                                   o->font,
                                                   &itr->text_props,
                                                   ellip_frame - (advance + l + 
r),
-                                                  0);
+                                                  0, end_ellip_it->w);
                   if (cut >= 0)
                     {
                        end_ellip_it->text_pos = itr->text_pos + cut;
diff --git a/src/lib/evas/canvas/evas_object_textblock.c 
b/src/lib/evas/canvas/evas_object_textblock.c
index db58b62..4de5938 100644
--- a/src/lib/evas/canvas/evas_object_textblock.c
+++ b/src/lib/evas/canvas/evas_object_textblock.c
@@ -3922,7 +3922,7 @@ _layout_text_item_new(Ctxt *c EINA_UNUSED, 
Evas_Object_Textblock_Format *fmt)
  */
 static int
 _layout_text_cutoff_get(Ctxt *c, Evas_Object_Textblock_Format *fmt,
-      const Evas_Object_Textblock_Text_Item *ti)
+      const Evas_Object_Textblock_Text_Item *ti, int width_offset)
 {
    if (fmt->font.font)
      {
@@ -3933,7 +3933,7 @@ _layout_text_cutoff_get(Ctxt *c, 
Evas_Object_Textblock_Format *fmt,
           x = 0;
         Evas_Object_Protected_Data *obj = efl_data_scope_get(c->obj, 
EFL_CANVAS_OBJECT_CLASS);
         return ENFN->font_last_up_to_pos(ENDT, fmt->font.font,
-              &ti->text_props, x, 0);
+              &ti->text_props, x, 0, width_offset);
      }
    return -1;
 }
@@ -4706,7 +4706,7 @@ _layout_get_charwrap(Ctxt *c, 
Evas_Object_Textblock_Format *fmt,
         if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT)
            wrap = 0;
         else
-           wrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it));
+           wrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), 0);
 
         if (wrap < 0)
            return -1;
@@ -4767,13 +4767,13 @@ _layout_get_hyphenationwrap(Ctxt *c, 
Evas_Object_Textblock_Format *fmt,
              Evas_Coord cw;
 
              /* Get cutoff */
-             swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it));
+             swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), 0);
 
              /* Get cutoff considering an additional hyphen item */
              cw = c->w;
              c->hyphen_ti = _layout_hyphen_item_new(c, _ITEM_TEXT(it));
              c->w -= c->hyphen_ti->parent.w;
-             hyphen_swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it));
+             hyphen_swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), 
c->hyphen_ti->parent.w);
              c->w = cw;
 
              /* Stronger condition than '< 0' for hyphenations */
@@ -4924,7 +4924,7 @@ _layout_get_word_mixwrap_common(Ctxt *c, 
Evas_Object_Textblock_Format *fmt,
         if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT)
            swrap = 0;
         else
-           swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it));
+           swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), 0);
         /* Avoiding too small textblocks to even contain one char.
          * FIXME: This can cause breaking inside ligatures. */
 
@@ -5098,7 +5098,7 @@ _layout_handle_ellipsis(Ctxt *c, 
Evas_Object_Textblock_Item *it, Eina_List *i)
    // XXX: with RTL considerations in mind, we need to take max(adv, w) as the
    // line may be reordered in a way that the item placement will cause the
    // formatted width to exceed the width constraints.
-   if (ellip_ti->parent.adv > ellip_ti->parent.w)
+   if (c->par->is_bidi && ellip_ti->parent.adv > ellip_ti->parent.w)
      {
         ellip_w = ellip_ti->parent.adv;
      }
@@ -5124,7 +5124,7 @@ _layout_handle_ellipsis(Ctxt *c, 
Evas_Object_Textblock_Item *it, Eina_List *i)
           {
              ti = _ITEM_TEXT(last_it);
 
-             wrap = _layout_text_cutoff_get(c, last_it->format, ti);
+             wrap = _layout_text_cutoff_get(c, last_it->format, ti, 
ellip_ti->parent.w);
 
              if ((wrap > 0) && !IS_AT_END(ti, (size_t) wrap))
                {
@@ -5246,7 +5246,7 @@ _calc_items_width(Ctxt *c)
 }
 
 static inline int
-_item_get_cutoff(Ctxt *c, Evas_Object_Textblock_Item *it, Evas_Coord x)
+_item_get_cutoff(Ctxt *c, Evas_Object_Textblock_Item *it, Evas_Coord x, 
Evas_Coord width_offset)
 {
    int pos = -1;
    Evas_Object_Textblock_Text_Item *ti;
@@ -5256,7 +5256,7 @@ _item_get_cutoff(Ctxt *c, Evas_Object_Textblock_Item *it, 
Evas_Coord x)
    if (ti && ti->parent.format->font.font)
      {
         pos = ENFN->font_last_up_to_pos(ENDT, ti->parent.format->font.font,
-              &ti->text_props, x, 0);
+              &ti->text_props, x, 0, width_offset);
      }
    return pos;
 }
@@ -5319,7 +5319,7 @@ _layout_par_ellipsis_items(Ctxt *c, double ellip)
 
 
    pos = (it && it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ?
-      (_item_get_cutoff(c, it, l - off)) : -1;
+      (_item_get_cutoff(c, it, l - off, ellip_ti->parent.w)) : -1;
    if (pos >= 0)
      {
         _layout_item_text_split_strip_white(c, _ITEM_TEXT(it), i, pos);
@@ -5340,7 +5340,7 @@ _layout_par_ellipsis_items(Ctxt *c, double ellip)
      }
 
    pos = (it && it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ?
-      (_item_get_cutoff(c, it, h - off)) : -1;
+      (_item_get_cutoff(c, it, h - off, 0)) : -1;
    if (pos >= 0)
       _layout_item_text_split_strip_white(c, _ITEM_TEXT(it), j, pos + 1);
    if (it)
diff --git a/src/lib/evas/common/evas_font.h b/src/lib/evas/common/evas_font.h
index 3d59201..f9f8026 100644
--- a/src/lib/evas/common/evas_font.h
+++ b/src/lib/evas/common/evas_font.h
@@ -80,7 +80,7 @@ EAPI void              evas_common_font_query_advance        
(RGBA_Font *fn, con
 EAPI int               evas_common_font_query_char_coords    (RGBA_Font *fn, 
const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch);
 EAPI int               evas_common_font_query_pen_coords     (RGBA_Font *fn, 
const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, 
int *ch);
 EAPI int               evas_common_font_query_char_at_coords (RGBA_Font *fn, 
const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int 
*ch);
-EAPI int               evas_common_font_query_last_up_to_pos (RGBA_Font *fn, 
const Evas_Text_Props *intl_props, int x, int y);
+EAPI int               evas_common_font_query_last_up_to_pos (RGBA_Font *fn, 
const Evas_Text_Props *intl_props, int x, int y, int width_offset);
 EAPI int               evas_common_font_query_run_font_end_get(RGBA_Font *fn, 
RGBA_Font_Int **script_fi, RGBA_Font_Int **cur_fi, Evas_Script_Type script, 
const Eina_Unicode *text, int run_len);
 EAPI void              evas_common_font_ascent_descent_get(RGBA_Font *fn, 
const Evas_Text_Props *text_props, int *ascent, int *descent);
 
diff --git a/src/lib/evas/common/evas_font_query.c 
b/src/lib/evas/common/evas_font_query.c
index 2deb838..c52486b 100644
--- a/src/lib/evas/common/evas_font_query.c
+++ b/src/lib/evas/common/evas_font_query.c
@@ -813,7 +813,7 @@ end:
  * @return the position found, -1 on failure.
  */
 EAPI int
-evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Evas_Text_Props 
*text_props, int x, int y)
+evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Evas_Text_Props 
*text_props, int x, int y, int width_offset)
 {
    int asc, desc;
    int ret=-1;
@@ -845,6 +845,14 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const 
Evas_Text_Props *text
                   pen_x = full_adv - (gli->pen_after - start_pen);
                   /* If invisible, skip */
                   if (gli->index == 0) continue;
+
+                  /* FIXME: Should we care glyph's width for RTL?
+                     I think if width+x_bear/advance stacked from left side,
+                     we don't need to care glyph's width to find linebreak 
position
+                     or ellipsis position.
+                     Even if (x < (pen_x + gli->x_bear + gli->width)))) is 
removed,
+                     the whole test suite is passed.
+                   */
                   if ((x >= pen_x) &&
                         (((i == 0) && (x <= full_adv)) ||
                          (x < (full_adv - (gli[-1].pen_after - start_pen)) ||
@@ -875,7 +883,7 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const 
Evas_Text_Props *text
 
              if ((x >= EVAS_FONT_WALK_PEN_X) &&
                    ((x < (EVAS_FONT_WALK_PEN_X_AFTER)) ||
-                    (x < (EVAS_FONT_WALK_PEN_X +
+                    (x + width_offset < (EVAS_FONT_WALK_PEN_X +
                           _glyph_itr->x_bear + _glyph_itr->width))) &&
                    (y >= -asc) && (y <= desc))
                {
diff --git a/src/lib/evas/include/evas_private.h 
b/src/lib/evas/include/evas_private.h
index 98d0c16..4491af6 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1483,7 +1483,7 @@ struct _Evas_Func
 
    void (*image_scale_hint_set)            (void *data, void *image, int hint);
    int  (*image_scale_hint_get)            (void *data, void *image);
-   int  (*font_last_up_to_pos)             (void *data, Evas_Font_Set *font, 
const Evas_Text_Props *intl_props, int x, int y);
+   int  (*font_last_up_to_pos)             (void *data, Evas_Font_Set *font, 
const Evas_Text_Props *intl_props, int x, int y, int width_offset);
 
    Eina_Bool (*image_map_draw)                  (void *data, void *context, 
void *surface, void *image, RGBA_Map *m, int smooth, int level, Eina_Bool 
do_async);
    void *(*image_map_surface_new)          (void *data, int w, int h, int 
alpha);
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c 
b/src/modules/evas/engines/software_generic/evas_engine.c
index 0d2bced..e509ea3 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -3316,9 +3316,9 @@ eng_font_char_at_coords_get(void *data EINA_UNUSED, 
Evas_Font_Set *font, const E
 }
 
 static int
-eng_font_last_up_to_pos(void *data EINA_UNUSED, Evas_Font_Set *font, const 
Evas_Text_Props *text_props, int x, int y)
+eng_font_last_up_to_pos(void *data EINA_UNUSED, Evas_Font_Set *font, const 
Evas_Text_Props *text_props, int x, int y, int width_offset)
 {
-   return evas_common_font_query_last_up_to_pos((RGBA_Font *) font, 
text_props, x, y);
+   return evas_common_font_query_last_up_to_pos((RGBA_Font *) font, 
text_props, x, y, width_offset);
 }
 
 static int

-- 


Reply via email to