Evas textblock: Implemented cursor_word_start/end

SVN revision: 66119
This commit is contained in:
Tom Hacohen 2011-12-12 15:25:46 +00:00
parent f147928c84
commit 4e29867a30
4 changed files with 157 additions and 0 deletions

View File

@ -544,3 +544,9 @@
* Fix rounding error in map clip bounds calculation
2011-12-12 Tom Hacohen (TAsn)
* Textblock: Added evas_textblock_cursor_word_start/end.
Those functions let you jump to the start/end of the word under the
cursor.

View File

@ -8477,6 +8477,24 @@ EAPI Eina_Bool evas_textblock_cursor_char_next(Evas_Textblock
*/
EAPI Eina_Bool evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Moves the cursor to the start of the word under the cursor.
*
* @param cur the cursor to move.
* @return #EINA_TRUE on success #EINA_FALSE otherwise.
* @since 1.2.0
*/
EAPI Eina_Bool evas_textblock_cursor_word_start(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Moves the cursor to the end of the word under the cursor.
*
* @param cur the cursor to move.
* @return #EINA_TRUE on success #EINA_FALSE otherwise.
* @since 1.2.0
*/
EAPI Eina_Bool evas_textblock_cursor_word_end(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
/**
* Go to the first char in the node the cursor is pointing on.
*

View File

@ -67,6 +67,7 @@
#ifdef HAVE_LINEBREAK
#include "linebreak.h"
#include "wordbreak.h"
#endif
/* save typing */
@ -5734,6 +5735,111 @@ evas_textblock_cursor_format_prev(Evas_Textblock_Cursor *cur)
return EINA_FALSE;
}
#ifdef HAVE_LINEBREAK
/* BREAK_AFTER: true if we can break after the current char.
* Both macros assume str[i] is not the terminating nul */
#define BREAK_AFTER(i) \
(breaks[i] == WORDBREAK_BREAK)
#else
#define BREAK_AFTER(i) \
((!str[i + 1]) || \
(_is_white(str[i]) && !_is_white(str[i + 1])) || \
(!_is_white(str[i]) && _is_white(str[i + 1])))
#endif
EAPI Eina_Bool
evas_textblock_cursor_word_start(Evas_Textblock_Cursor *cur)
{
const Eina_Unicode *text;
size_t i;
#ifdef HAVE_LINEBREAK
char *breaks;
#endif
if (!cur) return EINA_FALSE;
if (!cur->node) return EINA_FALSE;
text = eina_ustrbuf_string_get(cur->node->unicode);
#ifdef HAVE_LINEBREAK
{
const char *lang = ""; /* FIXME: get lang */
size_t len = eina_ustrbuf_length_get(cur->node->unicode);
breaks = malloc(len);
set_wordbreaks_utf32((const utf32_t *) text, len, lang, breaks);
}
#endif
i = cur->pos;
/* Skip the first one. This ensures we don't point to the nul, and also
* we just don't care about it anyway. */
if (i > 0) i--;
for ( ; i > 0 ; i--)
{
if (BREAK_AFTER(i))
{
/* Advance to the current char */
i++;
break;
}
}
cur->pos = i;
#ifdef HAVE_LINEBREAK
free(breaks);
#endif
return EINA_TRUE;
}
EAPI Eina_Bool
evas_textblock_cursor_word_end(Evas_Textblock_Cursor *cur)
{
const Eina_Unicode *text;
size_t i;
#ifdef HAVE_LINEBREAK
char *breaks;
#endif
if (!cur) return EINA_FALSE;
if (!cur->node) return EINA_FALSE;
text = eina_ustrbuf_string_get(cur->node->unicode);
#ifdef HAVE_LINEBREAK
{
const char *lang = ""; /* FIXME: get lang */
size_t len = eina_ustrbuf_length_get(cur->node->unicode);
breaks = malloc(len);
set_wordbreaks_utf32((const utf32_t *) text, len, lang, breaks);
}
#endif
i = cur->pos;
for ( ; text[i] ; i++)
{
if (BREAK_AFTER(i))
{
/* This is the one to break after. */
break;
}
}
cur->pos = i;
#ifdef HAVE_LINEBREAK
free(breaks);
#endif
return EINA_TRUE;;
}
EAPI Eina_Bool
evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
{
@ -8828,6 +8934,7 @@ evas_object_textblock_init(Evas_Object *obj)
{
linebreak_init = EINA_TRUE;
init_linebreak();
init_wordbreak();
}
#endif

View File

@ -568,6 +568,32 @@ START_TEST(evas_textblock_cursor)
fail_if(evas_textblock_cursor_compare(main_cur, cur));
}
{
const char *buf_wb = "a This is_a t:e.s't a";
evas_object_textblock_text_markup_set(tb, buf_wb);
/* Word start/end */
evas_textblock_cursor_pos_set(cur, 3);
evas_textblock_cursor_word_start(cur);
fail_if(2 != evas_textblock_cursor_pos_get(cur));
evas_textblock_cursor_word_end(cur);
fail_if(5 != evas_textblock_cursor_pos_get(cur));
evas_textblock_cursor_pos_set(cur, 13);
evas_textblock_cursor_word_end(cur);
fail_if(18 != evas_textblock_cursor_pos_get(cur));
evas_textblock_cursor_word_start(cur);
fail_if(12 != evas_textblock_cursor_pos_get(cur));
evas_textblock_cursor_word_start(cur);
fail_if(12 != evas_textblock_cursor_pos_get(cur));
evas_textblock_cursor_word_start(cur);
fail_if(12 != evas_textblock_cursor_pos_get(cur));
evas_textblock_cursor_word_end(cur);
fail_if(18 != evas_textblock_cursor_pos_get(cur));
evas_textblock_cursor_word_end(cur);
fail_if(18 != evas_textblock_cursor_pos_get(cur));
}
END_TB_TEST();
}
END_TEST