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.

SVN revision: 51834
This commit is contained in:
Tom Hacohen 2010-09-02 11:49:00 +00:00
parent b37a2117d1
commit e8c59bf0e8
3 changed files with 92 additions and 12 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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++)