From a68bc0b27ef9f7ba4e5eebef31a779d112fadc03 Mon Sep 17 00:00:00 2001 From: tasn Date: Thu, 2 Sep 2010 11:49:00 +0000 Subject: [PATCH] Evas textblock+font engine: Implemented evas_textblock_cursor_geometry_get. Fixed evas_common_font_char_coords to work correctly with the NULL character in RTL text. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@51834 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/Evas.h | 7 +++ src/lib/canvas/evas_object_textblock.c | 77 +++++++++++++++++++++++++++----- src/lib/engines/common/evas_font_query.c | 20 +++++++++ 3 files changed, 92 insertions(+), 12 deletions(-) diff --git a/src/lib/Evas.h b/src/lib/Evas.h index e0434df..eb144f3 100644 --- a/src/lib/Evas.h +++ b/src/lib/Evas.h @@ -1337,6 +1337,12 @@ typedef void (*Evas_Object_Image_Pixels_Get_Cb) (void *data, Evas_Object *o); EVAS_TEXTBLOCK_TEXT_MARKUP } Evas_Textblock_Text_Type; + typedef enum _Evas_Textblock_Cursor_Type + { + EVAS_TEXTBLOCK_CURSOR_UNDER, + EVAS_TEXTBLOCK_CURSOR_BEFORE + } Evas_Textblock_Cursor_Type; + EAPI Evas_Object *evas_object_textblock_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC; EAPI const char *evas_textblock_escape_string_get(const char *escape) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE; @@ -1403,6 +1409,7 @@ typedef void (*Evas_Object_Image_Pixels_Get_Cb) (void *data, Evas_Object *o); EAPI int evas_textblock_cursor_paragraph_text_length_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE; EAPI char *evas_textblock_cursor_range_text_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2, Evas_Textblock_Text_Type format) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2) EINA_PURE; + EAPI int evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_Textblock_Cursor_Type ctype) EINA_ARG_NONNULL(1); EAPI int evas_textblock_cursor_char_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1); EAPI int evas_textblock_cursor_line_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1); EAPI Eina_Bool evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1); diff --git a/src/lib/canvas/evas_object_textblock.c b/src/lib/canvas/evas_object_textblock.c index fd56002..c9b7e9d 100644 --- a/src/lib/canvas/evas_object_textblock.c +++ b/src/lib/canvas/evas_object_textblock.c @@ -6421,6 +6421,68 @@ evas_textblock_cursor_format_is_visible_get(const Evas_Textblock_Cursor *cur) EINA_TRUE : EINA_FALSE; } +/** + * Returns the geometry of the cursor. Depends on the type of cursor requested. + * This should be used instead of char_geometry_get because there are weird + * special cases with BiDi text. + * in '_' cursor mode (i.e a line below the char) it's the same as char_geometry + * get, except for the case of the last char of a line which depends on the + * paragraph direction. + * + * in '|' cursor mode (i.e a line between two chars) it is very varyable. + * For example consider the following visual string: + * "abcCBA" (ABC are rtl chars), a cursor pointing on A should actually draw + * a '|' between the c and the C. + * + * @param cur the cursor. + * @param cx the x of the cursor + * @param cy the y of the cursor + * @param cw the w of the cursor + * @param ch the h of the cursor + * @return line number of the char on success, -1 on error. + */ +EAPI int +evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_Textblock_Cursor_Type ctype) +{ + if (ctype == EVAS_TEXTBLOCK_CURSOR_UNDER) + { + return evas_textblock_cursor_char_geometry_get(cur, cx, cy, cw, ch); + } + else if (ctype == EVAS_TEXTBLOCK_CURSOR_BEFORE) + { + /*FIXME: Rough sketch, not yet implemented - VERY buggy. */ + /* In the case of a "before cursor", we should get the coordinates + * of just after the previous char (which in bidi text may not be + * just before the current char). */ + Evas_Coord x, y, h, w; + int ret; + + if (cur->pos > 0) + { + Evas_Textblock_Cursor cur2; + cur2.obj = cur->obj; + evas_textblock_cursor_copy(cur, &cur2); + cur2.pos--; + ret = evas_textblock_cursor_char_geometry_get(&cur2, &x, &y, &w, &h); + } + else + { + ret = evas_textblock_cursor_char_geometry_get(cur, &x, &y, &w, &h); + w = 0; + } + if (ret > 0) + { + if (cx) *cx = x + w; + if (cy) *cy = y + h; + if (cw) *cw = 0; + if (ch) *ch = 0; + } + return ret; + } + + return -1; +} + /** * Returns the geometry of the char at cur. @@ -6498,27 +6560,18 @@ evas_textblock_cursor_char_geometry_get(const Evas_Textblock_Cursor *cur, Evas_C ret = -1; if (pos < 0) pos = 0; - if (it->format->font.font) + if (it->format->font.font) { ret = cur->ENFN->font_char_coords_get(cur->ENDT, it->format->font.font, it->text, &it->bidi_props, pos, &x, &y, &w, &h); } - if (ret <= 0) - { - if (it->format->font.font) - cur->ENFN->font_string_size_get(cur->ENDT, it->format->font.font, - it->text, &it->bidi_props, &w, &h); - x = w; - y = 0; - w = 0; - } - x = ln->x + it->x - it->inset + x; + x += ln->x + it->x - it->inset; if (x < ln->x) { - x = ln->x; w -= (ln->x - x); + x = ln->x; } y = ln->y; h = ln->h; diff --git a/src/lib/engines/common/evas_font_query.c b/src/lib/engines/common/evas_font_query.c index 19f7001..c5a2fd7 100644 --- a/src/lib/engines/common/evas_font_query.c +++ b/src/lib/engines/common/evas_font_query.c @@ -374,6 +374,26 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c #else position = pos; #endif + /* If it's the null, choose location according to the direction. */ + if (!text[position]) + { + /* if it's rtl then the location is the left of the string, + * otherwise, the right. */ + if (intl_props && + EVAS_BIDI_PARAGRAPH_DIRECTION_IS_RTL(intl_props->props)) + { + if (cx) *cx = 0; + if (ch) *ch = asc + desc; + } + else + { + evas_common_font_query_size(fn, text, intl_props, cx, ch); + } + if (cy) *cy = 0; + if (cw) *cw = 0; + ret_val = 1; + goto end; + } last_adv = 0; for (char_index = 0; *text ; text++, char_index++) -- 2.7.4