Evas textblock: Wrapping is now absolute to the paragraph.

This is not yet noticable, still need to use the new info.

SVN revision: 59215
This commit is contained in:
Tom Hacohen 2011-05-05 13:38:09 +00:00
parent c6751884b0
commit 9677320259
1 changed files with 89 additions and 53 deletions

View File

@ -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,20 +3421,32 @@ _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);