From f82fe9b115187bc1b33f5675aead087c25698c4d Mon Sep 17 00:00:00 2001 From: tasn Date: Thu, 5 May 2011 13:38:09 +0000 Subject: [PATCH] Evas textblock: Wrapping is now absolute to the paragraph. This is not yet noticable, still need to use the new info. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@59215 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/canvas/evas_object_textblock.c | 142 +++++++++++++++++++++------------ 1 file changed, 89 insertions(+), 53 deletions(-) diff --git a/src/lib/canvas/evas_object_textblock.c b/src/lib/canvas/evas_object_textblock.c index dee1091..7ac0161 100644 --- a/src/lib/canvas/evas_object_textblock.c +++ b/src/lib/canvas/evas_object_textblock.c @@ -3016,21 +3016,25 @@ _layout_update_par(Ctxt *c) /* -1 means no wrap */ static int _layout_get_charwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt, - const Evas_Object_Textblock_Text_Item *ti, const char *breaks) + const Evas_Object_Textblock_Text_Item *ti, size_t line_start, + const char *breaks) { int wrap; const Eina_Unicode *str = GET_ITEM_TEXT(ti); /* Currently not being used, because it doesn't contain relevant * information */ (void) breaks; + /* Currently not being used, because we don't enforce the ligature breaking + here just yet. */ + (void) line_start; wrap = _layout_text_cutoff_get(c, fmt, ti); if (wrap == 0) GET_NEXT(str, ti, wrap); if ((wrap < 0) || IS_AT_END(ti, (size_t) wrap)) - wrap = -1; + return -1; - return wrap; + return wrap + ti->parent.text_pos; } /* -1 means no wrap */ @@ -3038,27 +3042,41 @@ _layout_get_charwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt, /* Allow break means: if we can break after the current char */ #define ALLOW_BREAK(i) \ - ((((i) + ti->parent.text_pos) > 0) ? \ - (breaks[ti->parent.text_pos + (i)] == LINEBREAK_ALLOWBREAK) : \ - (EINA_FALSE)) + (breaks[i] == LINEBREAK_ALLOWBREAK) #else #define ALLOW_BREAK(i) \ - ((((i) + ti->parent.text_pos) > 0) ? \ - (_is_white(str[(i)])) : \ - (EINA_FALSE)) + (_is_white(str[i])) #endif +#define MOVE_PREV_UNTIL(line_start, ind) \ + do \ + { \ + if ((line_start) < (ind)) \ + (ind)--; \ + } \ + while (0) + +#define MOVE_NEXT_UNTIL(len, ind) \ + do \ + { \ + if ((ind) < (len)) \ + (ind)++; \ + } \ + while (0) static int _layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt, const Evas_Object_Textblock_Text_Item *ti, Eina_Bool mixed_wrap, - const char *breaks) + int line_start, const char *breaks) { int wrap = -1; int orig_wrap; - const Eina_Unicode *str = GET_ITEM_TEXT(ti); + const Eina_Unicode *str = eina_ustrbuf_string_get( + ti->parent.text_node->unicode); + int item_start = ti->parent.text_pos; + int len = eina_ustrbuf_length_get(ti->parent.text_node->unicode); #ifndef HAVE_LINEBREAK /* Not used without liblinebreak ATM. */ (void) breaks; @@ -3068,75 +3086,76 @@ _layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt, /* Avoiding too small textblocks to even contain one char. * FIXME: This can cause breaking inside ligatures. */ - orig_wrap = wrap; - if (wrap > 0) + if (wrap < 0) + return -1; + + orig_wrap = wrap = wrap + item_start; + + if (wrap > line_start) { /* The wrapping point found is the first char of the next string the rest works on the last char of the previous string. If it's a whitespace, then it's ok, and no need to go back because we'll remove it anyway. */ if (!_is_white(str[wrap])) - GET_PREV(str, wrap); + MOVE_PREV_UNTIL(line_start, wrap); /* If there's a breakable point inside the text, scan backwards until * we find it */ - do + while (wrap >= line_start) { if (ALLOW_BREAK(wrap)) break; wrap--; } - while (wrap >= 0); - if (wrap >= 0) + if (wrap >= line_start) { /* We found a suitable wrapping point, break here. */ - GET_NEXT(str, ti, wrap); + MOVE_NEXT_UNTIL(len, wrap); return wrap; } else { - /* If there are already items in this line, we - * should just try creating a new line for it */ - if (c->ln->items) + /* If this is the start of the line, we should just try creating a + new line for it */ + if (line_start < item_start) { return 0; } if (mixed_wrap) { - return ((orig_wrap >= 0) && - !IS_AT_END(ti, (size_t) orig_wrap)) ? orig_wrap : -1; + return ((orig_wrap >= line_start) && (orig_wrap < len)) ? + ((int) orig_wrap) : -1; } else { /* Scan forward to find the next wrapping point */ - wrap = orig_wrap; - do - { - if (ALLOW_BREAK(wrap)) - break; - wrap++; - } - while (!IS_AT_END(ti, (size_t) wrap)); - - - if (!IS_AT_END(ti, (size_t) wrap)) - { - GET_NEXT(str, ti, wrap); - return wrap; - } - else - { - return -1; - } + wrap = item_start; } } - } - else if (wrap == 0) + + /* If we need to find the position after the cutting point */ + if (wrap == line_start) { - /* Just to avoid too small textblocks */ - GET_NEXT(str, ti, wrap); + while (wrap < len) + { + if (ALLOW_BREAK(wrap)) + break; + wrap++; + } + + + if (wrap < len) + { + MOVE_NEXT_UNTIL(len, wrap); + return wrap; + } + else + { + return -1; + } return wrap; } @@ -3146,17 +3165,21 @@ _layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt, /* -1 means no wrap */ static int _layout_get_wordwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt, - const Evas_Object_Textblock_Text_Item *ti, const char *breaks) + const Evas_Object_Textblock_Text_Item *ti, size_t line_start, + const char *breaks) { - return _layout_get_word_mixwrap_common(c, fmt, ti, EINA_FALSE, breaks); + return _layout_get_word_mixwrap_common(c, fmt, ti, EINA_FALSE, line_start, + breaks); } /* -1 means no wrap */ static int _layout_get_mixedwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt, - const Evas_Object_Textblock_Text_Item *ti, const char *breaks) + const Evas_Object_Textblock_Text_Item *ti, size_t line_start, + const char *breaks) { - return _layout_get_word_mixwrap_common(c, fmt, ti, EINA_TRUE, breaks); + return _layout_get_word_mixwrap_common(c, fmt, ti, EINA_TRUE, line_start, + breaks); } /* Should be moved inside _layout_ellipsis_item_new once we fix the hack in @@ -3377,6 +3400,7 @@ _layout_visualize_par(Ctxt *c) { Evas_Object_Textblock_Text_Item *ti = _ITEM_TEXT(it); int wrap; + size_t line_start; #ifdef HAVE_LINEBREAK /* If we haven't calculated the linebreaks yet, @@ -3397,22 +3421,34 @@ _layout_visualize_par(Ctxt *c) } } #endif + if (c->ln->items) + line_start = c->ln->items->text_pos; + else + line_start = ti->parent.text_pos; adv_line = 1; if (it->format->wrap_word) wrap = _layout_get_wordwrap(c, it->format, ti, - line_breaks); + line_start, line_breaks); else if (it->format->wrap_char) wrap = _layout_get_charwrap(c, it->format, ti, - line_breaks); + line_start, line_breaks); else if (it->format->wrap_mixed) wrap = _layout_get_mixedwrap(c, it->format, ti, - line_breaks); + line_start, line_breaks); else wrap = -1; if (wrap > 0) { + if ((size_t) wrap < ti->parent.text_pos) + wrap = 0; + else + wrap -= ti->parent.text_pos; + } + + if (wrap > 0) + { _layout_item_text_split_strip_white(c, ti, i, wrap); } else if (wrap == 0) -- 2.7.4