summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoungbok Shin <youngb.shin@samsung.com>2017-04-10 12:15:19 +0900
committerChris Michael <cp.michael@samsung.com>2017-04-11 11:51:50 -0400
commit703d8f55fda7077fd689892994bcf942f0abe6a2 (patch)
tree15c7b263e25f6df336d7036da5800ce46893af1e
parent3f6b27c4d64f33601a249e48f9496ff4aeda181c (diff)
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
-rw-r--r--src/lib/evas/canvas/evas_object_text.c8
-rw-r--r--src/lib/evas/canvas/evas_object_textblock.c24
-rw-r--r--src/lib/evas/common/evas_font.h2
-rw-r--r--src/lib/evas/common/evas_font_query.c12
-rw-r--r--src/lib/evas/include/evas_private.h2
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c4
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 c91e9d2fc6..6e6f5100fd 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,
309 o->font, 309 o->font,
310 &it->text_props, 310 &it->text_props,
311 cx - x, 311 cx - x,
312 cy); 312 cy, 0);
313 break; 313 break;
314 } 314 }
315 x += it->adv; 315 x += it->adv;
@@ -327,7 +327,7 @@ _evas_object_text_last_up_to_pos(const Evas_Object *eo_obj,
327 o->font, 327 o->font,
328 &it->text_props, 328 &it->text_props,
329 cx - it->x, 329 cx - it->x,
330 cy); 330 cy, 0);
331 } 331 }
332 } 332 }
333 } 333 }
@@ -893,7 +893,7 @@ _evas_object_text_layout(Evas_Object *eo_obj, Evas_Text_Data *o, Eina_Unicode *t
893 o->font, 893 o->font,
894 &itr->text_props, 894 &itr->text_props,
895 ellipsis_coord - (advance + l + r), 895 ellipsis_coord - (advance + l + r),
896 0); 896 0, start_ellip_it->w);
897 if (cut >= 0) 897 if (cut >= 0)
898 { 898 {
899 start_ellip_it->text_pos = itr->text_pos; 899 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
948 o->font, 948 o->font,
949 &itr->text_props, 949 &itr->text_props,
950 ellip_frame - (advance + l + r), 950 ellip_frame - (advance + l + r),
951 0); 951 0, end_ellip_it->w);
952 if (cut >= 0) 952 if (cut >= 0)
953 { 953 {
954 end_ellip_it->text_pos = itr->text_pos + cut; 954 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 db58b6286d..4de5938db2 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)
3922 */ 3922 */
3923static int 3923static int
3924_layout_text_cutoff_get(Ctxt *c, Evas_Object_Textblock_Format *fmt, 3924_layout_text_cutoff_get(Ctxt *c, Evas_Object_Textblock_Format *fmt,
3925 const Evas_Object_Textblock_Text_Item *ti) 3925 const Evas_Object_Textblock_Text_Item *ti, int width_offset)
3926{ 3926{
3927 if (fmt->font.font) 3927 if (fmt->font.font)
3928 { 3928 {
@@ -3933,7 +3933,7 @@ _layout_text_cutoff_get(Ctxt *c, Evas_Object_Textblock_Format *fmt,
3933 x = 0; 3933 x = 0;
3934 Evas_Object_Protected_Data *obj = efl_data_scope_get(c->obj, EFL_CANVAS_OBJECT_CLASS); 3934 Evas_Object_Protected_Data *obj = efl_data_scope_get(c->obj, EFL_CANVAS_OBJECT_CLASS);
3935 return ENFN->font_last_up_to_pos(ENDT, fmt->font.font, 3935 return ENFN->font_last_up_to_pos(ENDT, fmt->font.font,
3936 &ti->text_props, x, 0); 3936 &ti->text_props, x, 0, width_offset);
3937 } 3937 }
3938 return -1; 3938 return -1;
3939} 3939}
@@ -4706,7 +4706,7 @@ _layout_get_charwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt,
4706 if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) 4706 if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT)
4707 wrap = 0; 4707 wrap = 0;
4708 else 4708 else
4709 wrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it)); 4709 wrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), 0);
4710 4710
4711 if (wrap < 0) 4711 if (wrap < 0)
4712 return -1; 4712 return -1;
@@ -4767,13 +4767,13 @@ _layout_get_hyphenationwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt,
4767 Evas_Coord cw; 4767 Evas_Coord cw;
4768 4768
4769 /* Get cutoff */ 4769 /* Get cutoff */
4770 swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it)); 4770 swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), 0);
4771 4771
4772 /* Get cutoff considering an additional hyphen item */ 4772 /* Get cutoff considering an additional hyphen item */
4773 cw = c->w; 4773 cw = c->w;
4774 c->hyphen_ti = _layout_hyphen_item_new(c, _ITEM_TEXT(it)); 4774 c->hyphen_ti = _layout_hyphen_item_new(c, _ITEM_TEXT(it));
4775 c->w -= c->hyphen_ti->parent.w; 4775 c->w -= c->hyphen_ti->parent.w;
4776 hyphen_swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it)); 4776 hyphen_swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), c->hyphen_ti->parent.w);
4777 c->w = cw; 4777 c->w = cw;
4778 4778
4779 /* Stronger condition than '< 0' for hyphenations */ 4779 /* Stronger condition than '< 0' for hyphenations */
@@ -4924,7 +4924,7 @@ _layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt,
4924 if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) 4924 if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT)
4925 swrap = 0; 4925 swrap = 0;
4926 else 4926 else
4927 swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it)); 4927 swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), 0);
4928 /* Avoiding too small textblocks to even contain one char. 4928 /* Avoiding too small textblocks to even contain one char.
4929 * FIXME: This can cause breaking inside ligatures. */ 4929 * FIXME: This can cause breaking inside ligatures. */
4930 4930
@@ -5098,7 +5098,7 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
5098 // XXX: with RTL considerations in mind, we need to take max(adv, w) as the 5098 // XXX: with RTL considerations in mind, we need to take max(adv, w) as the
5099 // line may be reordered in a way that the item placement will cause the 5099 // line may be reordered in a way that the item placement will cause the
5100 // formatted width to exceed the width constraints. 5100 // formatted width to exceed the width constraints.
5101 if (ellip_ti->parent.adv > ellip_ti->parent.w) 5101 if (c->par->is_bidi && ellip_ti->parent.adv > ellip_ti->parent.w)
5102 { 5102 {
5103 ellip_w = ellip_ti->parent.adv; 5103 ellip_w = ellip_ti->parent.adv;
5104 } 5104 }
@@ -5124,7 +5124,7 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
5124 { 5124 {
5125 ti = _ITEM_TEXT(last_it); 5125 ti = _ITEM_TEXT(last_it);
5126 5126
5127 wrap = _layout_text_cutoff_get(c, last_it->format, ti); 5127 wrap = _layout_text_cutoff_get(c, last_it->format, ti, ellip_ti->parent.w);
5128 5128
5129 if ((wrap > 0) && !IS_AT_END(ti, (size_t) wrap)) 5129 if ((wrap > 0) && !IS_AT_END(ti, (size_t) wrap))
5130 { 5130 {
@@ -5246,7 +5246,7 @@ _calc_items_width(Ctxt *c)
5246} 5246}
5247 5247
5248static inline int 5248static inline int
5249_item_get_cutoff(Ctxt *c, Evas_Object_Textblock_Item *it, Evas_Coord x) 5249_item_get_cutoff(Ctxt *c, Evas_Object_Textblock_Item *it, Evas_Coord x, Evas_Coord width_offset)
5250{ 5250{
5251 int pos = -1; 5251 int pos = -1;
5252 Evas_Object_Textblock_Text_Item *ti; 5252 Evas_Object_Textblock_Text_Item *ti;
@@ -5256,7 +5256,7 @@ _item_get_cutoff(Ctxt *c, Evas_Object_Textblock_Item *it, Evas_Coord x)
5256 if (ti && ti->parent.format->font.font) 5256 if (ti && ti->parent.format->font.font)
5257 { 5257 {
5258 pos = ENFN->font_last_up_to_pos(ENDT, ti->parent.format->font.font, 5258 pos = ENFN->font_last_up_to_pos(ENDT, ti->parent.format->font.font,
5259 &ti->text_props, x, 0); 5259 &ti->text_props, x, 0, width_offset);
5260 } 5260 }
5261 return pos; 5261 return pos;
5262} 5262}
@@ -5319,7 +5319,7 @@ _layout_par_ellipsis_items(Ctxt *c, double ellip)
5319 5319
5320 5320
5321 pos = (it && it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ? 5321 pos = (it && it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ?
5322 (_item_get_cutoff(c, it, l - off)) : -1; 5322 (_item_get_cutoff(c, it, l - off, ellip_ti->parent.w)) : -1;
5323 if (pos >= 0) 5323 if (pos >= 0)
5324 { 5324 {
5325 _layout_item_text_split_strip_white(c, _ITEM_TEXT(it), i, pos); 5325 _layout_item_text_split_strip_white(c, _ITEM_TEXT(it), i, pos);
@@ -5340,7 +5340,7 @@ _layout_par_ellipsis_items(Ctxt *c, double ellip)
5340 } 5340 }
5341 5341
5342 pos = (it && it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ? 5342 pos = (it && it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ?
5343 (_item_get_cutoff(c, it, h - off)) : -1; 5343 (_item_get_cutoff(c, it, h - off, 0)) : -1;
5344 if (pos >= 0) 5344 if (pos >= 0)
5345 _layout_item_text_split_strip_white(c, _ITEM_TEXT(it), j, pos + 1); 5345 _layout_item_text_split_strip_white(c, _ITEM_TEXT(it), j, pos + 1);
5346 if (it) 5346 if (it)
diff --git a/src/lib/evas/common/evas_font.h b/src/lib/evas/common/evas_font.h
index 3d59201776..f9f8026c85 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
80EAPI 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); 80EAPI 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);
81EAPI 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); 81EAPI 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);
82EAPI 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); 82EAPI 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);
83EAPI int evas_common_font_query_last_up_to_pos (RGBA_Font *fn, const Evas_Text_Props *intl_props, int x, int y); 83EAPI 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);
84EAPI 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); 84EAPI 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);
85EAPI void evas_common_font_ascent_descent_get(RGBA_Font *fn, const Evas_Text_Props *text_props, int *ascent, int *descent); 85EAPI void evas_common_font_ascent_descent_get(RGBA_Font *fn, const Evas_Text_Props *text_props, int *ascent, int *descent);
86 86
diff --git a/src/lib/evas/common/evas_font_query.c b/src/lib/evas/common/evas_font_query.c
index 2deb8386e4..c52486b3cb 100644
--- a/src/lib/evas/common/evas_font_query.c
+++ b/src/lib/evas/common/evas_font_query.c
@@ -813,7 +813,7 @@ end:
813 * @return the position found, -1 on failure. 813 * @return the position found, -1 on failure.
814 */ 814 */
815EAPI int 815EAPI int
816evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Evas_Text_Props *text_props, int x, int y) 816evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Evas_Text_Props *text_props, int x, int y, int width_offset)
817{ 817{
818 int asc, desc; 818 int asc, desc;
819 int ret=-1; 819 int ret=-1;
@@ -845,6 +845,14 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Evas_Text_Props *text
845 pen_x = full_adv - (gli->pen_after - start_pen); 845 pen_x = full_adv - (gli->pen_after - start_pen);
846 /* If invisible, skip */ 846 /* If invisible, skip */
847 if (gli->index == 0) continue; 847 if (gli->index == 0) continue;
848
849 /* FIXME: Should we care glyph's width for RTL?
850 I think if width+x_bear/advance stacked from left side,
851 we don't need to care glyph's width to find linebreak position
852 or ellipsis position.
853 Even if (x < (pen_x + gli->x_bear + gli->width)))) is removed,
854 the whole test suite is passed.
855 */
848 if ((x >= pen_x) && 856 if ((x >= pen_x) &&
849 (((i == 0) && (x <= full_adv)) || 857 (((i == 0) && (x <= full_adv)) ||
850 (x < (full_adv - (gli[-1].pen_after - start_pen)) || 858 (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
875 883
876 if ((x >= EVAS_FONT_WALK_PEN_X) && 884 if ((x >= EVAS_FONT_WALK_PEN_X) &&
877 ((x < (EVAS_FONT_WALK_PEN_X_AFTER)) || 885 ((x < (EVAS_FONT_WALK_PEN_X_AFTER)) ||
878 (x < (EVAS_FONT_WALK_PEN_X + 886 (x + width_offset < (EVAS_FONT_WALK_PEN_X +
879 _glyph_itr->x_bear + _glyph_itr->width))) && 887 _glyph_itr->x_bear + _glyph_itr->width))) &&
880 (y >= -asc) && (y <= desc)) 888 (y >= -asc) && (y <= desc))
881 { 889 {
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 98d0c16d21..4491af676a 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1483,7 +1483,7 @@ struct _Evas_Func
1483 1483
1484 void (*image_scale_hint_set) (void *data, void *image, int hint); 1484 void (*image_scale_hint_set) (void *data, void *image, int hint);
1485 int (*image_scale_hint_get) (void *data, void *image); 1485 int (*image_scale_hint_get) (void *data, void *image);
1486 int (*font_last_up_to_pos) (void *data, Evas_Font_Set *font, const Evas_Text_Props *intl_props, int x, int y); 1486 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);
1487 1487
1488 Eina_Bool (*image_map_draw) (void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level, Eina_Bool do_async); 1488 Eina_Bool (*image_map_draw) (void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level, Eina_Bool do_async);
1489 void *(*image_map_surface_new) (void *data, int w, int h, int alpha); 1489 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 0d2bced46e..e509ea3a36 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
3316} 3316}
3317 3317
3318static int 3318static int
3319eng_font_last_up_to_pos(void *data EINA_UNUSED, Evas_Font_Set *font, const Evas_Text_Props *text_props, int x, int y) 3319eng_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)
3320{ 3320{
3321 return evas_common_font_query_last_up_to_pos((RGBA_Font *) font, text_props, x, y); 3321 return evas_common_font_query_last_up_to_pos((RGBA_Font *) font, text_props, x, y, width_offset);
3322} 3322}
3323 3323
3324static int 3324static int