forked from enlightenment/efl
Evas font-engine: Add cluster support to the font-engine. Cursor handling is now correct for clusters as well.
SVN revision: 56462
This commit is contained in:
parent
c012ee700c
commit
c09000741b
|
@ -31,8 +31,59 @@ evas_common_font_ot_is_enabled(void)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef OT_SUPPORT
|
||||
/* FIXME: doc. returns #items */
|
||||
EAPI int
|
||||
evas_common_font_ot_cluster_size_get(Evas_Text_Props *props, size_t char_index, int orig_len)
|
||||
{
|
||||
int i;
|
||||
int items;
|
||||
int left_bound, right_bound;
|
||||
size_t base_cluster = EVAS_FONT_OT_POS_GET(props->ot_data->items[char_index]);
|
||||
for (i = (int) char_index ;
|
||||
(i >= 0) &&
|
||||
(EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ;
|
||||
i--)
|
||||
;
|
||||
left_bound = i;
|
||||
for (i = (int) char_index + 1;
|
||||
(i < (int) props->ot_data->len) &&
|
||||
(EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ;
|
||||
i++)
|
||||
;
|
||||
right_bound = i;
|
||||
if (right_bound == left_bound)
|
||||
{
|
||||
items = 1;
|
||||
}
|
||||
else if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
|
||||
{
|
||||
if (left_bound < 0)
|
||||
{
|
||||
items = orig_len -
|
||||
props->ot_data->items[left_bound + 1].source_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
items = props->ot_data->items[left_bound].source_pos -
|
||||
props->ot_data->items[left_bound + 1].source_pos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (right_bound == (int) props->ot_data->len)
|
||||
{
|
||||
items = orig_len - props->ot_data->items[left_bound].source_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
items = props->ot_data->items[right_bound - 1].source_pos -
|
||||
props->ot_data->items[right_bound].source_pos;
|
||||
}
|
||||
}
|
||||
return (items > 0) ? items : 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_common_font_ot_shape(hb_buffer_t *buffer, FT_Face face)
|
||||
{
|
||||
|
|
|
@ -279,23 +279,29 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
|
|||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
|
||||
{
|
||||
Evas_Coord cluster_start, last_end;
|
||||
int prev_cluster = -1;
|
||||
int found = 0, items = 0, item_pos = 1;
|
||||
int last_is_visible;
|
||||
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
|
||||
{
|
||||
int chr_x, chr_w;
|
||||
int found = 0, items = 1, item_pos = 1;
|
||||
|
||||
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
|
||||
if (visible)
|
||||
|
||||
if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS)
|
||||
{
|
||||
chr_x = (pen_x) + EVAS_FONT_WALK_OT_X_OFF +
|
||||
EVAS_FONT_WALK_OT_X_BEAR;
|
||||
chr_w = EVAS_FONT_WALK_OT_WIDTH;
|
||||
if (found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
chr_x = pen_x;
|
||||
chr_w = 0;
|
||||
cluster_start = (pen_x) + EVAS_FONT_WALK_OT_X_OFF +
|
||||
EVAS_FONT_WALK_OT_X_BEAR;
|
||||
}
|
||||
}
|
||||
last_is_visible = visible;
|
||||
last_end = pen_x + EVAS_FONT_WALK_OT_X_OFF +
|
||||
EVAS_FONT_WALK_OT_X_BEAR + EVAS_FONT_WALK_OT_WIDTH;
|
||||
/* we need to see if the char at the visual position is the char wanted */
|
||||
if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
|
||||
(EVAS_FONT_WALK_OT_POS <= (size_t) position) &&
|
||||
|
@ -303,14 +309,8 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
|
|||
(EVAS_FONT_WALK_OT_IS_LAST)))
|
||||
{
|
||||
found = 1;
|
||||
items = EVAS_FONT_WALK_OT_POS_NEXT - EVAS_FONT_WALK_OT_POS;
|
||||
if (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_NEXT)
|
||||
{
|
||||
/* If there was only one char, take the original lens
|
||||
* for the number of items. */
|
||||
items = EVAS_FONT_WALK_ORIG_LEN -
|
||||
EVAS_FONT_WALK_OT_POS;
|
||||
}
|
||||
items = evas_common_font_ot_cluster_size_get(intl_props,
|
||||
char_index, EVAS_FONT_WALK_ORIG_LEN);
|
||||
item_pos = position - EVAS_FONT_WALK_OT_POS + 1;
|
||||
}
|
||||
else if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) &&
|
||||
|
@ -319,30 +319,36 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
|
|||
(((size_t) position) >= EVAS_FONT_WALK_OT_POS))
|
||||
{
|
||||
found = 1;
|
||||
items = EVAS_FONT_WALK_OT_POS_PREV - EVAS_FONT_WALK_OT_POS;
|
||||
if (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_PREV)
|
||||
{
|
||||
/* If there was only one char, take the original lens
|
||||
* for the number of items. */
|
||||
items = EVAS_FONT_WALK_ORIG_LEN -
|
||||
EVAS_FONT_WALK_OT_POS;
|
||||
}
|
||||
items = evas_common_font_ot_cluster_size_get(intl_props,
|
||||
char_index, EVAS_FONT_WALK_ORIG_LEN);
|
||||
item_pos = items - (position - EVAS_FONT_WALK_OT_POS);
|
||||
}
|
||||
|
||||
prev_cluster = EVAS_FONT_WALK_OT_POS;
|
||||
}
|
||||
EVAS_FONT_WALK_OT_TEXT_END();
|
||||
if (found)
|
||||
{
|
||||
if (cx) *cx = chr_x +
|
||||
(EVAS_FONT_WALK_OT_WIDTH / items) * (item_pos - 1);
|
||||
Evas_Coord cluster_w;
|
||||
cluster_w = last_end - cluster_start;
|
||||
if (cy) *cy = -asc;
|
||||
if (cw) *cw = chr_w / items;
|
||||
if (ch) *ch = asc + desc;
|
||||
if (last_is_visible)
|
||||
{
|
||||
if (cx) *cx = cluster_start +
|
||||
(cluster_w / items) *
|
||||
(item_pos - 1);
|
||||
if (cw) *cw = (cluster_w / items);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cx) *cx = cluster_start;
|
||||
if (cw) *cw = 0;
|
||||
}
|
||||
ret_val = 1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
EVAS_FONT_WALK_OT_TEXT_END();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
@ -432,25 +438,35 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
|
|||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
|
||||
{
|
||||
Evas_Coord cluster_start;
|
||||
int prev_cluster = -1;
|
||||
int found = 0, items = 0, item_pos = 1;
|
||||
int last_is_visible = 1;
|
||||
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
|
||||
{
|
||||
int found = 0, items = 1, item_pos = 1;
|
||||
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
|
||||
/* we need to see if the char at the visual position is the char wanted */
|
||||
|
||||
if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS)
|
||||
{
|
||||
if (found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cluster_start = pen_x;
|
||||
}
|
||||
}
|
||||
last_is_visible = visible;
|
||||
|
||||
if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
|
||||
(EVAS_FONT_WALK_OT_POS <= (size_t) position) &&
|
||||
((((size_t) position) < EVAS_FONT_WALK_OT_POS_NEXT) ||
|
||||
(EVAS_FONT_WALK_OT_IS_LAST)))
|
||||
{
|
||||
found = 1;
|
||||
items = EVAS_FONT_WALK_OT_POS_NEXT - EVAS_FONT_WALK_OT_POS;
|
||||
if (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_NEXT)
|
||||
{
|
||||
/* If there was only one char, take the original lens
|
||||
* for the number of items. */
|
||||
items = EVAS_FONT_WALK_ORIG_LEN -
|
||||
EVAS_FONT_WALK_OT_POS;
|
||||
}
|
||||
items = evas_common_font_ot_cluster_size_get(intl_props,
|
||||
char_index, EVAS_FONT_WALK_ORIG_LEN);
|
||||
item_pos = position - EVAS_FONT_WALK_OT_POS + 1;
|
||||
}
|
||||
else if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) &&
|
||||
|
@ -459,41 +475,27 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
|
|||
(((size_t) position) >= EVAS_FONT_WALK_OT_POS))
|
||||
{
|
||||
found = 1;
|
||||
items = EVAS_FONT_WALK_OT_POS_PREV - EVAS_FONT_WALK_OT_POS;
|
||||
if (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_PREV)
|
||||
{
|
||||
/* If there was only one char, take the original lens
|
||||
* for the number of items. */
|
||||
items = EVAS_FONT_WALK_ORIG_LEN -
|
||||
EVAS_FONT_WALK_OT_POS;
|
||||
}
|
||||
items = evas_common_font_ot_cluster_size_get(intl_props,
|
||||
char_index, EVAS_FONT_WALK_ORIG_LEN);
|
||||
item_pos = items - (position - EVAS_FONT_WALK_OT_POS);
|
||||
}
|
||||
|
||||
prev_cluster = EVAS_FONT_WALK_OT_POS;
|
||||
}
|
||||
EVAS_FONT_WALK_OT_TEXT_END();
|
||||
|
||||
if (found)
|
||||
{
|
||||
Evas_Coord cluster_adv;
|
||||
cluster_adv = pen_x - cluster_start;
|
||||
if (cy) *cy = -asc;
|
||||
if (ch) *ch = asc + desc;
|
||||
/* FIXME: A hack to make combining chars work nice, should
|
||||
* change to take the base char's adv. */
|
||||
if (visible)
|
||||
if (last_is_visible)
|
||||
{
|
||||
if (EVAS_FONT_WALK_OT_X_ADV > 0)
|
||||
{
|
||||
if (cpen_x) *cpen_x = pen_x +
|
||||
(EVAS_FONT_WALK_OT_X_ADV / items) *
|
||||
if (cpen_x) *cpen_x = cluster_start +
|
||||
(cluster_adv / items) *
|
||||
(item_pos - 1);
|
||||
if (cadv) *cadv = (EVAS_FONT_WALK_OT_X_ADV / items);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cpen_x) *cpen_x = pen_x +
|
||||
EVAS_FONT_WALK_OT_X_OFF +
|
||||
EVAS_FONT_WALK_OT_X_BEAR +
|
||||
(EVAS_FONT_WALK_OT_WIDTH / items) *
|
||||
(item_pos - 1);
|
||||
if (cadv) *cadv = (EVAS_FONT_WALK_OT_WIDTH / items);
|
||||
}
|
||||
if (cadv) *cadv = (cluster_adv / items);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -504,8 +506,6 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
|
|||
goto end;
|
||||
}
|
||||
}
|
||||
EVAS_FONT_WALK_OT_TEXT_END();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
@ -577,9 +577,24 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
|
|||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
|
||||
{
|
||||
Evas_Coord cluster_start;
|
||||
int prev_cluster = -1;
|
||||
int found = 0, items = 0;
|
||||
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
|
||||
{
|
||||
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
|
||||
if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS)
|
||||
{
|
||||
if (found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cluster_start = pen_x;
|
||||
}
|
||||
}
|
||||
|
||||
if (!visible) continue;
|
||||
|
||||
/* we need to see if the char at the visual position is the char,
|
||||
|
@ -588,48 +603,41 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
|
|||
if ((x >= pen_x) && (x <= (pen_x + EVAS_FONT_WALK_OT_X_ADV)) &&
|
||||
(y >= -asc) && (y <= desc))
|
||||
{
|
||||
int items = 1, item_pos = 1;
|
||||
items = evas_common_font_ot_cluster_size_get(intl_props,
|
||||
char_index, EVAS_FONT_WALK_ORIG_LEN);
|
||||
found = 1;
|
||||
}
|
||||
|
||||
prev_cluster = EVAS_FONT_WALK_OT_POS;
|
||||
}
|
||||
EVAS_FONT_WALK_OT_TEXT_END();
|
||||
if (found)
|
||||
{
|
||||
int item_pos;
|
||||
Evas_Coord cluster_adv;
|
||||
cluster_adv = pen_x - cluster_start;
|
||||
|
||||
if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR)
|
||||
{
|
||||
double part;
|
||||
items = EVAS_FONT_WALK_OT_POS_NEXT -
|
||||
EVAS_FONT_WALK_OT_POS;
|
||||
/* If it's the last/first char in a ltr/rtl string */
|
||||
if (items == 0)
|
||||
{
|
||||
items = EVAS_FONT_WALK_ORIG_LEN -
|
||||
EVAS_FONT_WALK_OT_POS;
|
||||
}
|
||||
part = EVAS_FONT_WALK_OT_X_ADV / items;
|
||||
item_pos = (int) ((x - pen_x) / part);
|
||||
part = cluster_adv / items;
|
||||
item_pos = (int) ((x - cluster_start) / part);
|
||||
}
|
||||
else
|
||||
{
|
||||
double part;
|
||||
items = EVAS_FONT_WALK_OT_POS_PREV -
|
||||
EVAS_FONT_WALK_OT_POS;
|
||||
/* If it's the last/first char in a ltr/rtl string */
|
||||
if (items == 0)
|
||||
{
|
||||
items = EVAS_FONT_WALK_ORIG_LEN -
|
||||
EVAS_FONT_WALK_OT_POS;
|
||||
part = cluster_adv / items;
|
||||
item_pos = items - ((int) ((x - cluster_start) / part)) - 1;
|
||||
}
|
||||
part = EVAS_FONT_WALK_OT_X_ADV / items;
|
||||
item_pos = items - ((int) ((x - pen_x) / part)) - 1;
|
||||
}
|
||||
if (cx) *cx = pen_x + EVAS_FONT_WALK_OT_X_OFF +
|
||||
EVAS_FONT_WALK_OT_X_BEAR +
|
||||
((EVAS_FONT_WALK_OT_X_ADV / items) * (item_pos - 1));
|
||||
if (cx) *cx = pen_x +
|
||||
((cluster_adv / items) * (item_pos - 1));
|
||||
if (cy) *cy = -asc;
|
||||
if (cw) *cw = (EVAS_FONT_WALK_OT_X_ADV / items);
|
||||
if (cw) *cw = (cluster_adv / items);
|
||||
if (ch) *ch = asc + desc;
|
||||
ret_val = EVAS_FONT_WALK_OT_POS + item_pos;
|
||||
ret_val = prev_cluster + item_pos;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
EVAS_FONT_WALK_OT_TEXT_END();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue