From d175b8aa69c31fc155f05269350f6703e81886b7 Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Thu, 27 Feb 2014 10:39:52 +0000 Subject: [PATCH] Evas textblock: Fix clipping issues with some texts with width > advance. This happens with many texts. The issue occurs when the width of the last char is larger than it's advance. Before this patch, we didn't the width into account when calculating width, thus causing clipping issues in some cases. --- src/lib/evas/canvas/evas_object_textblock.c | 12 +++++++++--- src/lib/evas/common/evas_font_query.c | 6 ++++-- src/tests/evas/evas_test_textblock.c | 15 +++++++++------ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index 1298a828b4..4956ac9804 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -3350,7 +3350,7 @@ loop_advance: it->x = x; x += it->adv; - if ((it->x + it->adv) > c->ln->w) c->ln->w = it->x + it->adv; + if ((it->w > 0) && ((it->x + it->w) > c->ln->w)) c->ln->w = it->x + it->w; } c->ln->y = c->y - c->par->y; @@ -4595,7 +4595,7 @@ _layout_par(Ctxt *c) /* Check if we need to wrap, i.e the text is bigger than the width, or we already found a wrap point. */ if ((c->w >= 0) && - (((c->x + it->adv) > + (((c->x + it->w) > (c->w - c->o->style_pad.l - c->o->style_pad.r - c->marginl - c->marginr)) || (wrap > 0))) { @@ -10304,7 +10304,7 @@ static void _size_native_calc_line_finalize(const Evas_Object *eo_obj, Eina_List *items, Evas_Coord *ascent, Evas_Coord *descent, Evas_Coord *w, Textblock_Position position) { - Evas_Object_Textblock_Item *it; + Evas_Object_Textblock_Item *it, *last_it = NULL; Eina_List *i; it = eina_list_data_get(items); @@ -10358,7 +10358,13 @@ _size_native_calc_line_finalize(const Evas_Object *eo_obj, Eina_List *items, loop_advance: *w += it->adv; + + if (!last_it || (it->visual_pos > last_it->visual_pos)) + last_it = it; } + + if (last_it) + *w += last_it->w - last_it->adv; } /* FIXME: doc */ diff --git a/src/lib/evas/common/evas_font_query.c b/src/lib/evas/common/evas_font_query.c index eebab7092e..1c219ee3b3 100644 --- a/src/lib/evas/common/evas_font_query.c +++ b/src/lib/evas/common/evas_font_query.c @@ -822,7 +822,8 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Evas_Text_Props *text if (gli->index == 0) continue; if ((x >= pen_x) && (((i == 0) && (x <= full_adv)) || - (x <= (full_adv - (gli[-1].pen_after - start_pen)))) && + (x < (full_adv - (gli[-1].pen_after - start_pen)) || + (x <= (pen_x + gli->width)))) && (y >= -asc) && (y <= desc)) { #ifdef OT_SUPPORT @@ -848,7 +849,8 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Evas_Text_Props *text if (!EVAS_FONT_WALK_IS_VISIBLE) continue; if ((x >= EVAS_FONT_WALK_PEN_X) && - (x <= (EVAS_FONT_WALK_PEN_X_AFTER)) && + ((x < (EVAS_FONT_WALK_PEN_X_AFTER)) || + (x <= (EVAS_FONT_WALK_PEN_X + _glyph_itr->width))) && (y >= -asc) && (y <= desc)) { ret = EVAS_FONT_WALK_POS; diff --git a/src/tests/evas/evas_test_textblock.c b/src/tests/evas/evas_test_textblock.c index dfddefa278..7836e2e152 100644 --- a/src/tests/evas/evas_test_textblock.c +++ b/src/tests/evas/evas_test_textblock.c @@ -484,7 +484,7 @@ START_TEST(evas_textblock_cursor) evas_textblock_cursor_pen_geometry_get(cur, &x, &y, &w, &h); fail_if(0 != evas_textblock_cursor_line_geometry_get( cur, &lx, &ly, &lw, &lh)); - fail_if((x < lx) || (x + w > lx + lw) || + fail_if((x < lx) || (y < ly) || (y + h > ly + lh)); fail_if((lx != plx) || (ly != ply) || (lw != plw) || (lh != plh)); @@ -505,7 +505,7 @@ START_TEST(evas_textblock_cursor) evas_textblock_cursor_pen_geometry_get(cur, &x, &y, &w, &h); fail_if(1 != evas_textblock_cursor_line_geometry_get( cur, &lx, &ly, &lw, &lh)); - fail_if((x < lx) || (x + w > lx + lw) || + fail_if((x < lx) || (y < ly) || (y + h > ly + lh)); fail_if((lx != plx) || (ly != ply) || (lw != plw) || (lh != plh)); @@ -1596,6 +1596,7 @@ START_TEST(evas_textblock_wrapping) evas_object_resize(tb, bw + 1, bh); evas_object_textblock_size_formatted_get(tb, &w, &h); /* Wrap to minimum */ + ck_assert_int_eq(w, bw); fail_if(w != bw); fail_if(h <= bh); @@ -1607,7 +1608,8 @@ START_TEST(evas_textblock_wrapping) evas_object_textblock_size_native_get(tb, &nw, &nh); evas_object_resize(tb, nw, nh); evas_object_textblock_size_formatted_get(tb, &w, &h); - fail_if((w != nw) || (h != nh)); + ck_assert_int_eq(w, nw); + ck_assert_int_eq(h, nh); /* Reduce size until reaching the minimum, making sure we don't * get something wrong along the way */ @@ -1760,13 +1762,13 @@ START_TEST(evas_textblock_wrapping) evas_object_textblock_text_markup_set(tb, "return 0;"); evas_object_textblock_size_formatted_get(tb, &w, &h); - ck_assert_int_eq(w, 33); + ck_assert_int_eq(w, 32); ck_assert_int_eq(h, 25); evas_object_resize(tb, 400, 400); evas_object_textblock_size_formatted_get(tb, &w, &h); - ck_assert_int_eq(w, 45); + ck_assert_int_eq(w, 44); ck_assert_int_eq(h, 16); /* Complex compound clusters using Devanagari. */ @@ -2663,6 +2665,7 @@ START_TEST(evas_textblock_style) evas_object_textblock_line_number_geometry_get(tb, 1, &x[1], &y[1], &w2[1], &h2[1]); // check line 1 geometry relatively to line 0 + ck_assert_int_eq(w2[0], w2[1]); fail_if((x[0] != x[1]) || ((y[0] + h2[0]) != y[1]) || (w2[0] != w2[1]) || (h2[0] != h2[1])); evas_object_textblock_text_markup_set(tb, "Test
Test
Test"); @@ -2672,7 +2675,7 @@ START_TEST(evas_textblock_style) evas_object_textblock_line_number_geometry_get(tb, 2, &x[4], &y[4], &w2[4], &h2[4]); // check line 1 geometry relatively to line 0 - fail_if((x[2] != x[3]) || ((y[2] + h2[2]) != y[3]) || (w2[2] != w2[3]) || (h2[2] != h2[3])); + fail_if((x[2] != x[3]) || ((y[2] + h2[2]) != y[3]) || (w2[2] > w2[3]) || (h2[2] != h2[3])); // check padding is correct fail_if((x[2] != (x[0] + l)) || (y[2] != (y[0] + t)));