forked from enlightenment/efl
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
This commit is contained in:
parent
b6ead19a94
commit
20ef85e307
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
/* 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);
|
||||
}
|
||||
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue