Evas bidi + font-engine + everything affected: Changed Evas_BiDi_Props to only include the direction of the text and reverse when needed. We don't need to do full processing at this stage, because we should have split to bidi runs before.

SVN revision: 56443
This commit is contained in:
Tom Hacohen 2011-01-30 10:35:17 +00:00
parent e4b4cf3344
commit 99a7eff130
7 changed files with 124 additions and 83 deletions

View File

@ -26,7 +26,8 @@ struct _Evas_Object_Text
} outline, shadow, glow, glow2;
unsigned char style;
Evas_BiDi_Props intl_props;
Evas_BiDi_Paragraph_Props *bidi_par_props;
Evas_BiDi_Props bidi_props;
} cur, prev;
float ascent, descent;
@ -235,7 +236,7 @@ evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size siz
o->ascent = ENFN->font_ascent_get(ENDT, o->engine_data);
ENFN->font_string_size_get(ENDT,
o->engine_data,
o->cur.text, &o->cur.intl_props,
o->cur.text, &o->cur.bidi_props,
&w, &h);
o->ascent = ENFN->font_ascent_get(ENDT, o->engine_data);
o->descent = ENFN->font_descent_get(ENDT, o->engine_data);
@ -351,11 +352,11 @@ evas_object_text_text_set(Evas_Object *obj, const char *_text)
obj->layer->evas->pointer.x,
obj->layer->evas->pointer.y, 1, 1);
/* DO II */
/*Update intl_props*/
/*Update bidi_props*/
#ifdef BIDI_SUPPORT
evas_bidi_paragraph_props_unref(o->cur.intl_props.props);
o->cur.intl_props.props = evas_bidi_paragraph_props_get(text);
evas_bidi_shape_string(text, o->cur.intl_props.props, 0, len);
evas_bidi_paragraph_props_unref(o->cur.bidi_par_props);
o->cur.bidi_par_props = evas_bidi_paragraph_props_get(text);
evas_bidi_shape_string(text, o->cur.bidi_par_props, 0, len);
#endif
if (o->cur.text) eina_ustringshare_del(o->cur.text);
if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text);
@ -380,7 +381,7 @@ evas_object_text_text_set(Evas_Object *obj, const char *_text)
ENFN->font_string_size_get(ENDT,
o->engine_data,
o->cur.text, &o->cur.intl_props,
o->cur.text, &o->cur.bidi_props,
&w, &h);
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
obj->cur.geometry.w = w + l + r;
@ -560,7 +561,8 @@ evas_object_text_horiz_advance_get(const Evas_Object *obj)
MAGIC_CHECK_END();
if (!o->engine_data) return 0;
if (!o->cur.text) return 0;
return ENFN->font_h_advance_get(ENDT, o->engine_data, o->cur.text, &o->cur.intl_props);
return ENFN->font_h_advance_get(ENDT, o->engine_data, o->cur.text,
&o->cur.bidi_props);
}
/**
@ -583,7 +585,8 @@ evas_object_text_vert_advance_get(const Evas_Object *obj)
MAGIC_CHECK_END();
if (!o->engine_data) return 0;
if (!o->cur.text) return o->ascent + o->descent;
return ENFN->font_v_advance_get(ENDT, o->engine_data, o->cur.text, &o->cur.intl_props);
return ENFN->font_v_advance_get(ENDT, o->engine_data, o->cur.text,
&o->cur.bidi_props);
}
/**
@ -620,7 +623,8 @@ evas_object_text_char_pos_get(const Evas_Object *obj, int pos, Evas_Coord *cx, E
MAGIC_CHECK_END();
if (!o->engine_data) return EINA_FALSE;
if (!o->cur.text) return EINA_FALSE;
ret = ENFN->font_char_coords_get(ENDT, o->engine_data, o->cur.text, &o->cur.intl_props,
ret = ENFN->font_char_coords_get(ENDT, o->engine_data, o->cur.text,
&o->cur.bidi_props,
pos, &x, &y, &w, &h);
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
y += o->max_ascent - t;
@ -672,9 +676,9 @@ evas_object_text_last_up_to_pos(const Evas_Object *obj, Evas_Coord x, Evas_Coord
if (!o->cur.text) return -1;
return ENFN->font_last_up_to_pos(ENDT,
o->engine_data,
o->cur.text, &o->cur.intl_props,
o->cur.text, &o->cur.bidi_props,
x,
y - o->max_ascent);
y - o->max_ascent);
}
/**
@ -701,7 +705,7 @@ evas_object_text_char_coords_get(const Evas_Object *obj, Evas_Coord x, Evas_Coor
if (!o->cur.text) return -1;
ret = ENFN->font_char_at_coords_get(ENDT,
o->engine_data,
o->cur.text, &o->cur.intl_props,
o->cur.text, &o->cur.bidi_props,
x,
y - o->max_ascent,
&rx, &ry,
@ -1519,7 +1523,7 @@ evas_object_text_new(void)
o->magic = MAGIC_OBJ_TEXT;
o->prev = o->cur;
#ifdef BIDI_SUPPORT
o->cur.intl_props.props = evas_bidi_paragraph_props_new();
o->cur.bidi_par_props = evas_bidi_paragraph_props_new();
#endif
return o;
}
@ -1541,7 +1545,8 @@ evas_object_text_free(Evas_Object *obj)
if (o->cur.source) eina_stringshare_del(o->cur.source);
if (o->engine_data) evas_font_free(obj->layer->evas, o->engine_data);
#ifdef BIDI_SUPPORT
evas_bidi_props_clean(&o->cur.intl_props);
evas_bidi_paragraph_props_unref(o->cur.bidi_par_props);
evas_bidi_props_clean(&o->cur.bidi_props);
#endif
o->magic = 0;
EVAS_MEMPOOL_FREE(_mp_obj, o);
@ -1628,7 +1633,7 @@ evas_object_text_render(Evas_Object *obj, void *output, void *context, void *sur
obj->cur.geometry.h, \
obj->cur.geometry.w, \
obj->cur.geometry.h, \
o->cur.text, &o->cur.intl_props);
o->cur.text, &o->cur.bidi_props);
#if 0
#define DRAW_TEXT(ox, oy) \
if ((o->engine_data) && (o->cur.text)) \
@ -1644,7 +1649,7 @@ evas_object_text_render(Evas_Object *obj, void *output, void *context, void *sur
obj->cur.cache.geometry.h, \
obj->cur.geometry.w, \
obj->cur.geometry.h, \
o->cur.text, &o->cur.intl_props);
o->cur.text, &o->cur.bidi_props);
#endif
/* shadows */
if (o->cur.style == EVAS_TEXT_STYLE_SHADOW)
@ -1969,7 +1974,7 @@ _evas_object_text_rehint(Evas_Object *obj)
ENFN->font_string_size_get(ENDT,
o->engine_data,
o->cur.text, &o->cur.intl_props,
o->cur.text, &o->cur.bidi_props,
&w, &h);
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
obj->cur.geometry.w = w + l + r;

View File

@ -318,7 +318,7 @@ struct _Evas_Object_Textblock_Item
size_t visual_pos;
#endif
Evas_Coord adv, x, w, h;
Evas_BiDi_Props bidi_props;
Evas_BiDi_Props bidi_props;
};
struct _Evas_Object_Textblock_Text_Item
@ -2513,8 +2513,10 @@ _layout_text_add_and_split_item(Ctxt *c, Evas_Object_Textblock_Format *fmt,
{
new_ti->parent.text_node = ti->parent.text_node;
new_ti->parent.text_pos = ti->parent.text_pos + cutoff;
new_ti->parent.bidi_props.start = new_ti->parent.text_pos;
new_ti->parent.bidi_props.props = new_ti->parent.text_node->bidi_props;
new_ti->parent.bidi_props.dir = (evas_bidi_is_rtl_char(
new_ti->parent.text_node->bidi_props,
new_ti->parent.text_pos,
0)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
ti = new_ti;
len -= cutoff;
}
@ -2626,8 +2628,10 @@ skip:
ti->parent.text_pos = start + str - tbase;
if (ti->parent.text_node)
{
ti->parent.bidi_props.start = ti->parent.text_pos;
ti->parent.bidi_props.props = ti->parent.text_node->bidi_props;
ti->parent.bidi_props.dir = (evas_bidi_is_rtl_char(
ti->parent.text_node->bidi_props,
ti->parent.text_pos,
0)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
}
tw = th = 0;
if (fmt->font.font)
@ -2844,8 +2848,10 @@ _layout_format_item_add(Ctxt *c, Evas_Object_Textblock_Node_Format *n, const cha
fi->parent.text_node = n->text_node;
/* FIXME: make it more efficient */
fi->parent.text_pos = _evas_textblock_node_format_pos_get(n);
fi->parent.bidi_props.props = n->text_node->bidi_props;
fi->parent.bidi_props.start = fi->parent.text_pos;
fi->parent.bidi_props.dir = (evas_bidi_is_rtl_char(
fi->parent.text_node->bidi_props,
fi->parent.text_pos,
0)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
}
return fi;
}

View File

@ -251,8 +251,7 @@ cleanup:
void
evas_bidi_props_copy_and_ref(const Evas_BiDi_Props *src, Evas_BiDi_Props *dst)
{
dst->start = src->start;
dst->props = evas_bidi_paragraph_props_ref(src->props);
dst->dir = src->dir;
}
/**
@ -330,6 +329,18 @@ error:
return EINA_TRUE;
}
/**
* @internal
* Reverses the string according to the props
*
* @param str the string to reverse.
*/
void
evas_bidi_reverse_string(Eina_Unicode *str)
{
eina_unicode_reverse(str);
}
/**
* @internal
@ -390,6 +401,24 @@ evas_bidi_position_logical_to_visual(EvasBiDiStrIndex *v_to_l, int len, EvasBiDi
return position;
}
/**
* @internal
* Returns the reversed pos of the index.
*
* @param dir the direction of the string
* @param len the length of the map.
* @param position the position to convert.
* @return on success the visual position, on failure the same position.
*/
EvasBiDiStrIndex
evas_bidi_position_reverse(const Evas_BiDi_Props *props, int len, EvasBiDiStrIndex position)
{
if (!props || position >= len)
return position;
return (props->dir == EVAS_BIDI_DIRECTION_RTL) ? (len - 1) - position : position;
}
/**
* @internal
* Checks if the char is rtl oriented. I.e even a neutral char can become rtl
@ -482,8 +511,7 @@ void
evas_bidi_props_clean(Evas_BiDi_Props *bidi_props)
{
if (!bidi_props) return;
evas_bidi_paragraph_props_unref(bidi_props->props);
bidi_props->props = NULL;
bidi_props->dir = EVAS_BIDI_DIRECTION_NATURAL;
}
/**
* @}

View File

@ -76,8 +76,7 @@ struct _Evas_BiDi_Paragraph_Props {
};
struct _Evas_BiDi_Props {
Evas_BiDi_Paragraph_Props *props;
size_t start;
Evas_BiDi_Direction dir;
};
@ -104,6 +103,9 @@ struct _Evas_BiDi_Props {
EvasBiDiStrIndex
evas_bidi_position_logical_to_visual(EvasBiDiStrIndex *v_to_l, int len, EvasBiDiStrIndex position);
EvasBiDiStrIndex
evas_bidi_position_reverse(const Evas_BiDi_Props *props, int len, EvasBiDiStrIndex position);
Eina_Bool
evas_bidi_is_rtl_str(const Eina_Unicode *str);
@ -116,6 +118,9 @@ evas_bidi_end_of_run_get(const Evas_BiDi_Paragraph_Props *bidi_props, size_t sta
Eina_Bool
evas_bidi_props_reorder_line(Eina_Unicode *eina_ustr, size_t start, size_t len, const Evas_BiDi_Paragraph_Props *props, EvasBiDiStrIndex **_v_to_l);
void
evas_bidi_reverse_string(Eina_Unicode *str) EINA_ARG_NONNULL(1);
Evas_BiDi_Paragraph_Props *
evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr) EINA_ARG_NONNULL(1) EINA_MALLOC EINA_WARN_UNUSED_RESULT;

View File

@ -494,22 +494,22 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
#endif
#ifdef BIDI_SUPPORT
Eina_Unicode *visual_text;
Eina_Unicode *visual_text = NULL;
visual_text = eina_unicode_strdup(in_text);
if (visual_text)
if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL))
{
evas_bidi_props_reorder_line(visual_text, intl_props->start,
eina_unicode_strlen(visual_text), intl_props->props, NULL);
text = visual_text;
visual_text = eina_unicode_strdup(in_text);
if (visual_text)
{
evas_bidi_reverse_string(visual_text);
text = visual_text;
}
}
else
if (!visual_text)
{
text = in_text;
}
#else
intl_props = NULL;
#endif
if (fi->src->current_size != fi->size)
{

View File

@ -51,8 +51,7 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi);
/* i.e prev index is now the index and the other way */ \
/* around. There is a slight exception when there are */ \
/* compositing chars involved.*/ \
if (intl_props && \
evas_bidi_is_rtl_char(intl_props->props, intl_props->start, char_index) && \
if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL) && \
adv > 0) \
{ \
if (evas_common_font_query_kerning(fi, index, prev_index, &kern)) \

View File

@ -213,19 +213,20 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
_INIT_FI_AND_KERNING();
#ifdef BIDI_SUPPORT
int len = 0;
EvasBiDiStrIndex *visual_to_logical = NULL;
Eina_Unicode *visual_text;
Eina_Unicode *visual_text = NULL;
int len;
visual_text = eina_unicode_strdup(in_text);
if (visual_text)
if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL))
{
evas_bidi_props_reorder_line(visual_text, intl_props->start,
eina_unicode_strlen(visual_text), intl_props->props,
&visual_to_logical);
text = visual_text;
visual_text = eina_unicode_strdup(in_text);
if (visual_text)
{
evas_bidi_reverse_string(visual_text);
text = visual_text;
}
}
else
if (!visual_text)
{
text = in_text;
}
@ -237,7 +238,7 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
#ifdef BIDI_SUPPORT
/* Get the position in the visual string because those are the coords we care about */
position = evas_bidi_position_logical_to_visual(visual_to_logical, len, pos);
position = evas_bidi_position_reverse(intl_props, len, pos);
#else
position = pos;
#endif
@ -247,7 +248,7 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
/* if it's rtl then the location is the left of the string,
* otherwise, the right. */
#ifdef BIDI_SUPPORT
if (evas_bidi_is_rtl_char(intl_props->props, intl_props->start, 0))
if (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)
{
if (cx) *cx = 0;
if (ch) *ch = asc + desc;
@ -287,7 +288,6 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
end:
#ifdef BIDI_SUPPORT
if (visual_to_logical) free(visual_to_logical);
if (visual_text) free(visual_text);
#endif
@ -319,19 +319,20 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
_INIT_FI_AND_KERNING();
#ifdef BIDI_SUPPORT
int len = 0;
EvasBiDiStrIndex *visual_to_logical = NULL;
Eina_Unicode *visual_text;
Eina_Unicode *visual_text = NULL;
int len;
visual_text = eina_unicode_strdup(in_text);
if (visual_text)
if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL))
{
evas_bidi_props_reorder_line(visual_text, intl_props->start,
eina_unicode_strlen(visual_text), intl_props->props,
&visual_to_logical);
text = visual_text;
visual_text = eina_unicode_strdup(in_text);
if (visual_text)
{
evas_bidi_reverse_string(visual_text);
text = visual_text;
}
}
else
if (!visual_text)
{
text = in_text;
}
@ -343,7 +344,7 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
#ifdef BIDI_SUPPORT
/* Get the position in the visual string because those are the coords we care about */
position = evas_bidi_position_logical_to_visual(visual_to_logical, len, pos);
position = evas_bidi_position_reverse(intl_props, len, pos);
#else
position = pos;
#endif
@ -353,7 +354,7 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
/* if it's rtl then the location is the left of the string,
* otherwise, the right. */
#ifdef BIDI_SUPPORT
if (evas_bidi_is_rtl_char(intl_props->props, 0, 0))
if (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)
{
if (cpen_x) *cpen_x = 0;
if (ch) *ch = asc + desc;
@ -387,7 +388,6 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
end:
#ifdef BIDI_SUPPORT
if (visual_to_logical) free(visual_to_logical);
if (visual_text) free(visual_text);
#endif
@ -417,20 +417,20 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
#endif
#ifdef BIDI_SUPPORT
int len = 0;
EvasBiDiStrIndex *visual_to_logical = NULL;
Eina_Unicode *visual_text;
Eina_Unicode *visual_text = NULL;
int len;
visual_text = eina_unicode_strdup(in_text);
if (visual_text)
if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL))
{
evas_bidi_props_reorder_line(visual_text, intl_props->start,
eina_unicode_strlen(visual_text), intl_props->props,
&visual_to_logical);
text = visual_text;
visual_text = eina_unicode_strdup(in_text);
if (visual_text)
{
evas_bidi_reverse_string(visual_text);
text = visual_text;
}
}
else
if (!visual_text)
{
text = in_text;
}
@ -463,8 +463,7 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
/* we found the char position of the wanted char in the
* visual string, we now need to translate it to the
* position in the logical string */
position = evas_bidi_position_visual_to_logical(visual_to_logical,
position);
position = evas_bidi_position_reverse(intl_props, len, position);
#endif
ret_val = position;
goto end;
@ -474,7 +473,6 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
end:
#ifdef BIDI_SUPPORT
if (visual_to_logical) free(visual_to_logical);
if (visual_text) free(visual_text);
#endif