On Tue, 2009-09-29 at 21:23 -0700, Enlightenment SVN wrote:
> Log:
> From: Tom <[email protected]> (tasn)
>
> Hey raster,
>
> Here is the non intrusive patch I talked to you about. Please apply it as it
> introduces some fixes, some improvements and mostly and underlying
> infrastructure for future RTL improvements.
>
> (note hebrew & yiddish seem fine, but things expedite test seems to show are
> wrong (why i don't know as i dont speak the langs- just comparing to pango /
> gtk output):
>
> arabic seems lsightl wrong (maybe composition chars not working?)
> gujarati - also seems wrong
> malayam - also looks wrong
> persian - looks wrong
> sinhala - looks wrong
> tamil - looks wrong
>
> these are what, appear to me, to look wrong. why they look wrong, i don't
> know. i'm guessing its compositiong not being handled. but i dont's peak,
> read or write any of these languages so i am unsure of what it really should
> be like, why and how to fix it.
>
> anyone want to put up a hand? (everything else is displaying fine as best i
> can tell - the langauges i read/speak/somewhat understand are working fine).
>
this change causes a lot of problems. I'm constantly getting glibc
corruption and free problems. E freezes always if places or drawer are
present and visible. Typing something in everything, or using the
winlist will almost always cause a freeze as well. Using the E menus
also cause freezes. It always dies when passing through a part of evas
that deals with texts.
>
> Author: raster
> Date: 2009-09-29 21:23:21 -0700 (Tue, 29 Sep 2009)
> New Revision: 42814
>
> Modified:
> trunk/evas/src/lib/Evas.h trunk/evas/src/lib/canvas/evas_object_text.c
> trunk/evas/src/lib/canvas/evas_object_textblock.c
> trunk/evas/src/lib/engines/common/evas_font_draw.c
> trunk/evas/src/lib/engines/common/evas_font_main.c
> trunk/evas/src/lib/engines/common/evas_font_query.c
> trunk/evas/src/lib/engines/common/evas_intl/evas_intl_arabic.c
> trunk/evas/src/lib/engines/common/evas_intl/evas_intl_arabic.h
> trunk/evas/src/lib/engines/common/evas_intl_utils.c
> trunk/evas/src/lib/engines/common/evas_intl_utils.h
> trunk/evas/src/lib/include/evas_private.h
> trunk/evas/src/modules/engines/cairo_x11/evas_engine.c
> trunk/evas/src/modules/engines/software_16/evas_engine.c
> trunk/evas/src/modules/engines/software_generic/evas_engine.c
>
> Modified: trunk/evas/src/lib/Evas.h
> ===================================================================
> --- trunk/evas/src/lib/Evas.h 2009-09-30 03:53:17 UTC (rev 42813)
> +++ trunk/evas/src/lib/Evas.h 2009-09-30 04:23:21 UTC (rev 42814)
> @@ -647,6 +647,7 @@
> EAPI Evas_Coord evas_object_text_inset_get (const
> Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE;
> EAPI Eina_Bool evas_object_text_char_pos_get (const
> Evas_Object *obj, int pos, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw,
> Evas_Coord *ch) EINA_ARG_NONNULL(1);
> EAPI int evas_object_text_char_coords_get (const
> Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord *cx, Evas_Coord *cy,
> Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
> + EAPI int evas_object_text_last_up_to_pos(const Evas_Object
> *obj, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
> EAPI Evas_Text_Style_Type evas_object_text_style_get (const
> Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE;
> EAPI void evas_object_text_style_set (Evas_Object
> *obj, Evas_Text_Style_Type type) EINA_ARG_NONNULL(1);
> EAPI void evas_object_text_shadow_color_set (Evas_Object
> *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
>
> Modified: trunk/evas/src/lib/canvas/evas_object_text.c
> ===================================================================
> --- trunk/evas/src/lib/canvas/evas_object_text.c 2009-09-30 03:53:17 UTC
> (rev 42813)
> +++ trunk/evas/src/lib/canvas/evas_object_text.c 2009-09-30 04:23:21 UTC
> (rev 42814)
> @@ -614,13 +614,47 @@
> return ret;
> }
>
> +
> /**
> + * Returns the logical position of the last char in the text
> + * up to the pos given. this is NOT the position of the last char
> + * because of the possibilty of RTL in the text.
> * To be documented.
> *
> * FIXME: To be fixed.
> *
> */
> EAPI int
> +evas_object_text_last_up_to_pos(const Evas_Object *obj, Evas_Coord x,
> Evas_Coord y)
> +{
> + Evas_Object_Text *o;
> + int inset;
> +
> + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
> + return -1;
> + MAGIC_CHECK_END();
> + o = (Evas_Object_Text *)(obj->object_data);
> + MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
> + return -1;
> + MAGIC_CHECK_END();
> + if (!o->engine_data) return -1;
> + if (!o->cur.text) return -1;
> + inset =
> + ENFN->font_inset_get(ENDT, o->engine_data, o->cur.text);
> + return ENFN->font_last_up_to_pos(ENDT,
> + o->engine_data,
> + o->cur.text,
> + x + inset,
> + y - o->max_ascent);
> +}
> +
> +/**
> + * To be documented.
> + *
> + * FIXME: To be fixed.
> + *
> + */
> +EAPI int
> evas_object_text_char_coords_get(const Evas_Object *obj, Evas_Coord x,
> Evas_Coord y, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
> {
> Evas_Object_Text *o;
>
> Modified: trunk/evas/src/lib/canvas/evas_object_textblock.c
> ===================================================================
> --- trunk/evas/src/lib/canvas/evas_object_textblock.c 2009-09-30 03:53:17 UTC
> (rev 42813)
> +++ trunk/evas/src/lib/canvas/evas_object_textblock.c 2009-09-30 04:23:21 UTC
> (rev 42814)
> @@ -1579,17 +1579,16 @@
> static int
> _layout_text_cutoff_get(Ctxt *c, Evas_Object_Textblock_Format *fmt,
> Evas_Object_Textblock_Item *it)
> {
> - int cx, cy, cw, ch;
>
> if (fmt->font.font)
> - return c->ENFN->font_char_at_coords_get(c->ENDT, fmt->font.font,
> it->text,
> + return c->ENFN->font_last_up_to_pos(c->ENDT, fmt->font.font, it->text,
> c->w -
> c->o->style_pad.l -
> c->o->style_pad.r -
> c->marginl -
> c->marginr -
> c->x,
> - 0, &cx, &cy, &cw, &ch);
> + 0);
> return -1;
> }
>
> @@ -1629,7 +1628,6 @@
> if (_is_white(chr)) break;
> tp = p;
> }
> - p = tp;
> if (p < 0) p = 0;
> if ((p >= 0) && (_is_white(chr)))
> evas_common_font_utf8_get_next((unsigned char *)(str), &p);
> @@ -1916,7 +1914,10 @@
> {
> _layout_item_text_cutoff(c, it, wrap);
> twrap = wrap;
> - ch = evas_common_font_utf8_get_next((unsigned
> char *)str, &twrap);
> + /*we don't want to move next, that's why it's
> + * commented out.
> + * ch =
> evas_common_font_utf8_get_next((unsigned char *)str, &twrap);
> + */
> str = str + twrap;
> }
> /* intersects a word */
>
> Modified: trunk/evas/src/lib/engines/common/evas_font_draw.c
> ===================================================================
> --- trunk/evas/src/lib/engines/common/evas_font_draw.c 2009-09-30
> 03:53:17 UTC (rev 42813)
> +++ trunk/evas/src/lib/engines/common/evas_font_draw.c 2009-09-30
> 04:23:21 UTC (rev 42814)
> @@ -2,11 +2,6 @@
> * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
> */
>
> -/* Internationalization (RTL and Arabic contextualizing)
> - * was added by Tom Hacohen ([email protected])
> - */
> -
> -
> #include "evas_common.h"
> #include "evas_private.h"
> #include "evas_blend_private.h"
> @@ -182,13 +177,14 @@
>
>
> static void
> -evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc,
> RGBA_Font *fn, int x, int y, const char *text,
> +evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc,
> RGBA_Font *fn, int x, int y, const char *in_text,
> RGBA_Gfx_Func func, int ext_x, int ext_y, int
> ext_w, int ext_h, RGBA_Font_Int *fi,
> int im_w, int im_h __UNUSED__, int use_kerning
> )
> {
> int pen_x, pen_y;
> int chr;
> + const char *text = in_text;
> FT_Face pface = NULL;
> FT_UInt prev_index;
> DATA32 *im;
> @@ -196,18 +192,17 @@
> int char_index = 0; /* the index of the current char */
>
> #ifdef INTERNATIONAL_SUPPORT
> - int bidi_err = 0;
> + int len = 0;
> /*FIXME: should get the direction by parmater */
> - FriBidiCharType direction = FRIBIDI_TYPE_ON;
> - FriBidiLevel *level_list;
> + EvasIntlParType direction = FRIBIDI_TYPE_ON;
> + EvasIntlLevel *level_list;
>
> /* change the text to visual ordering and update the level list
> * for as minimum impact on the code as possible just use text as an
> * holder, will change in the future.*/
> - {
> - char *tmp = evas_intl_utf8_to_visual(text, &bidi_err, &direction,
> &level_list);
> - text = (tmp) ? tmp : text;
> - }
> + char *visual_text = evas_intl_utf8_to_visual(in_text, &len, &direction,
> NULL, NULL, &level_list);
> + text = (visual_text) ? visual_text : in_text;
> +
> #endif
>
> pen_x = x;
> @@ -222,6 +217,7 @@
> int gl, kern;
>
> gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
> +
> if (gl == 0) break;
> index = evas_common_font_glyph_search(fn, &fi, gl);
> /* hmmm kerning means i can't sanely do my own cached metric tables! */
> @@ -395,11 +391,8 @@
> prev_index = index;
> }
> #ifdef INTERNATIONAL_SUPPORT
> - if (bidi_err >= 0)
> - {
> - free(level_list);
> - free(text);
> - }
> + if (level_list) free(level_list);
> + if (visual_text) free(visual_text);
> #endif
> }
>
>
> Modified: trunk/evas/src/lib/engines/common/evas_font_main.c
> ===================================================================
> --- trunk/evas/src/lib/engines/common/evas_font_main.c 2009-09-30
> 03:53:17 UTC (rev 42813)
> +++ trunk/evas/src/lib/engines/common/evas_font_main.c 2009-09-30
> 04:23:21 UTC (rev 42814)
> @@ -136,9 +136,11 @@
> int index = *iindex, len, r;
> unsigned char d, d2, d3, d4;
>
> + /* if this char is the null terminator, exit */
> + if (!buf[index])
> + return 0;
> +
> d = buf[index++];
> - if (!d)
> - return 0;
>
> while (buf[index] && ((buf[index] & 0xc0) == 0x80))
> index++;
> @@ -196,7 +198,9 @@
>
> int r;
> int index = *iindex;
> - if (index <= 0)
> + /* although when index == 0 there's no previous char, we still want to get
> + * the current char */
> + if (index < 0)
> return 0;
>
> /* First obtain the codepoint at iindex */
>
> Modified: trunk/evas/src/lib/engines/common/evas_font_query.c
> ===================================================================
> --- trunk/evas/src/lib/engines/common/evas_font_query.c 2009-09-30
> 03:53:17 UTC (rev 42813)
> +++ trunk/evas/src/lib/engines/common/evas_font_query.c 2009-09-30
> 04:23:21 UTC (rev 42814)
> @@ -1,5 +1,7 @@
> #include "evas_common.h"
>
> +#include "evas_intl_utils.h" /*defines INTERNATIONAL_SUPPORT if possible */
> +
> EAPI int
> evas_common_font_query_kerning(RGBA_Font_Int* fi,
> FT_UInt prev, FT_UInt index,
> @@ -57,7 +59,10 @@
> return error;
> }
>
> -/* string extents */
> +/* string extents
> + * Note: no need for special rtl handling
> + * we can assume there's not between languages kerning
> + * and that spaces get the same wide anywhere. */
> EAPI void
> evas_common_font_query_size(RGBA_Font *fn, const char *text, int *w, int *h)
> {
> @@ -126,6 +131,7 @@
> if (h) *h = evas_common_font_max_ascent_get(fn) +
> evas_common_font_max_descent_get(fn);
> }
>
> +
> /* text x inset */
> EAPI int
> evas_common_font_query_inset(RGBA_Font *fn, const char *text)
> @@ -163,7 +169,10 @@
> return fg->glyph_out->left;
> }
>
> -/* h & v advance */
> +/* h & v advance
> + * Note: no need for special rtl handling
> + * we can assume there's not between languages kerning
> + * and that spaces get the same wide anywhere. */
> EAPI void
> evas_common_font_query_advance(RGBA_Font *fn, const char *text, int *h_adv,
> int *v_adv)
> {
> @@ -216,19 +225,34 @@
> if (h_adv) *h_adv = pen_x - start_x;
> }
>
> +
> /* x y w h for char at char pos */
> EAPI int
> -evas_common_font_query_char_coords(RGBA_Font *fn, const char *text, int pos,
> int *cx, int *cy, int *cw, int *ch)
> +evas_common_font_query_char_coords(RGBA_Font *fn, const char *in_text, int
> pos, int *cx, int *cy, int *cw, int *ch)
> {
> int use_kerning;
> int pen_x, pen_y;
> int prev_chr_end;
> int chr;
> int asc, desc;
> + int char_index = 0; /* the index of the current char */
> + int position;
> + const char *text = in_text;
> + int ret_val = 0;
> FT_UInt prev_index;
> RGBA_Font_Int *fi;
> FT_Face pface = NULL;
>
> +#ifdef INTERNATIONAL_SUPPORT
> + int len = 0;
> + EvasIntlParType direction = FRIBIDI_TYPE_ON;
> + EvasIntlLevel *level_list;
> + EvasIntlStrIndex *logical_to_visual;
> +
> + char *visual_text = evas_intl_utf8_to_visual(in_text, &len, &direction,
> &logical_to_visual, NULL, &level_list);
> + text = (visual_text) ? visual_text : in_text;
> +#endif
> +
> fi = fn->fonts->data;
>
> pen_x = 0;
> @@ -239,7 +263,27 @@
> prev_chr_end = 0;
> asc = evas_common_font_max_ascent_get(fn);
> desc = evas_common_font_max_descent_get(fn);
> - for (chr = 0; text[chr];)
> +
> + /* find the actual index, not the byte position */
> + position = 0;
> + chr = 0;
> + while (in_text[chr] && chr < pos) {
> + evas_common_font_utf8_get_next((unsigned char *)in_text, &chr);
> + position++;
> + }
> + /* if it's a bad position, break */
> + if (chr != pos) goto end;
> + /* if it's the end, the correct position is one after */
> + if (!in_text[chr]) position++;
> +
> +#ifdef INTERNATIONAL_SUPPORT
> + /* if it's an in string position (not end), get logical position */
> + if (position < len)
> + position = evas_intl_position_logical_to_visual(logical_to_visual,
> position);
> +#endif
> +
> +
> + for (char_index = 0, chr = 0; text[chr]; char_index++)
> {
> int pchr;
> FT_UInt index;
> @@ -249,17 +293,34 @@
>
> pchr = chr;
> gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
> +
> if (gl == 0) break;
> +
> index = evas_common_font_glyph_search(fn, &fi, gl);
> kern = 0;
> /* hmmm kerning means i can't sanely do my own cached metric tables!
> */
> /* grrr - this means font face sharing is kinda... not an option if */
> /* you want performance */
> if ((use_kerning) && (prev_index) && (index) &&
> - (pface == fi->src->ft.face))
> - if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
> - pen_x += kern;
> + (pface == fi->src->ft.face))
> + {
> +#ifdef INTERNATIONAL_SUPPORT
> + /* if it's rtl, the kerning matching should be reversed, i.e prev
> + * index is now the index and the other way around. */
> + if (evas_intl_is_rtl_char(level_list, char_index))
> + {
> + if (evas_common_font_query_kerning(fi, index, prev_index,
> &kern))
> + pen_x += kern;
> + }
> + else
> +#endif
> + {
>
> + if (evas_common_font_query_kerning(fi, prev_index, index,
> &kern))
> + pen_x += kern;
> + }
> + }
> +
> pface = fi->src->ft.face;
> fg = evas_common_font_int_cache_glyph_get(fi, index);
> if (!fg) continue;
> @@ -280,34 +341,57 @@
> chr_w += (chr_x - prev_chr_end);
> chr_x = prev_chr_end;
> }
> - if (pchr == pos)
> + /* we need to see if the char at the visual position is the char wanted
> */
> + if (char_index == position)
> {
> if (cx) *cx = chr_x;
> if (cy) *cy = -asc;
> if (cw) *cw = chr_w;
> if (ch) *ch = asc + desc;
> - return 1;
> + ret_val = 1;
> + goto end;
> }
> prev_chr_end = chr_x + chr_w;
> pen_x += fg->glyph->advance.x >> 16;
> prev_index = index;
> }
> - return 0;
> +end:
> +
> +#ifdef INTERNATIONAL_SUPPORT
> + if (level_list) free(level_list);
> + if (logical_to_visual) free(logical_to_visual);
> + if (visual_text) free(visual_text);
> +#endif
> +
> + return ret_val;
> }
>
> /* char pos of text at xy pos */
> EAPI int
> -evas_common_font_query_text_at_pos(RGBA_Font *fn, const char *text, int x,
> int y, int *cx, int *cy, int *cw, int *ch)
> +evas_common_font_query_text_at_pos(RGBA_Font *fn, const char *in_text, int
> x, int y, int *cx, int *cy, int *cw, int *ch)
> {
> int use_kerning;
> int pen_x, pen_y;
> int prev_chr_end;
> int chr;
> int asc, desc;
> + int char_index = 0; /* the index of the current char */
> + const char *text = in_text;
> + int ret_val = -1;
> FT_UInt prev_index;
> RGBA_Font_Int *fi;
> FT_Face pface = NULL;
> +
> +#ifdef INTERNATIONAL_SUPPORT
> + int len = 0;
> + EvasIntlParType direction = FRIBIDI_TYPE_ON;
> + EvasIntlLevel *level_list;
> + EvasIntlStrIndex *visual_to_logical;
>
> + char *visual_text = evas_intl_utf8_to_visual(in_text, &len, &direction,
> NULL, &visual_to_logical, &level_list);
> + text = (visual_text) ? visual_text : in_text;
> +#endif
> +
> fi = fn->fonts->data;
>
> pen_x = 0;
> @@ -318,6 +402,130 @@
> prev_chr_end = 0;
> asc = evas_common_font_max_ascent_get(fn);
> desc = evas_common_font_max_descent_get(fn);
> +
> + for (char_index = 0, chr = 0; text[chr]; char_index++)
> + {
> + int pchr;
> + FT_UInt index;
> + RGBA_Font_Glyph *fg;
> + int chr_x, chr_y, chr_w;
> + int gl, kern;
> +
> +
> +
> + gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
> + if (gl == 0) break;
> + index = evas_common_font_glyph_search(fn, &fi, gl);
> + kern = 0;
> + /* hmmm kerning means i can't sanely do my own cached metric tables!
> */
> + /* grrr - this means font face sharing is kinda... not an option if */
> + /* you want performance */
> + if ((use_kerning) && (prev_index) && (index) &&
> + (pface == fi->src->ft.face))
> + {
> +#ifdef INTERNATIONAL_SUPPORT
> + /* if it's rtl, the kerning matching should be reversed, i.e prev
> + * index is now the index and the other way around. */
> + if (evas_intl_is_rtl_char(level_list, char_index))
> + {
> + if (evas_common_font_query_kerning(fi, index, prev_index,
> &kern))
> + pen_x += kern;
> + }
> + else
> +#endif
> + {
> +
> + if (evas_common_font_query_kerning(fi, prev_index, index,
> &kern))
> + pen_x += kern;
> + }
> + }
> +
> + pface = fi->src->ft.face;
> + fg = evas_common_font_int_cache_glyph_get(fi, index);
> + if (!fg) continue;
> +
> + if (kern < 0) kern = 0;
> + chr_x = ((pen_x - kern) + (fg->glyph_out->left));
> + chr_y = (pen_y + (fg->glyph_out->top));
> + chr_w = fg->glyph_out->bitmap.width + kern;
> +/* if (text[chr]) */
> + {
> + int advw;
> +
> + advw = ((fg->glyph->advance.x + (kern << 16)) >> 16);
> + if (chr_w < advw) chr_w = advw;
> + }
> + if (chr_x > prev_chr_end)
> + {
> + chr_w += (chr_x - prev_chr_end);
> + chr_x = prev_chr_end;
> + }
> + if ((x >= chr_x) && (x <= (chr_x + chr_w)) &&
> + (y >= -asc) && (y <= desc))
> + {
> + if (cx) *cx = chr_x;
> + if (cy) *cy = -asc;
> + if (cw) *cw = chr_w;
> + if (ch) *ch = asc + desc;
> +#ifdef INTERNATIONAL_SUPPORT
> + {
> + int i;
> + int logical_chr;
> + int position =
> evas_intl_position_visual_to_logical(visual_to_logical, char_index);
> +
> +
> + /* ensure even if the list won't run */
> + pchr = 0;
> + for (logical_chr = 0, i = 0; i <= position; i++) {
> + pchr = logical_chr;
> + evas_common_font_utf8_get_next((unsigned char
> *)in_text, &logical_chr);
> + }
> + }
> +#endif
> + ret_val = pchr;
> + goto end;
> + }
> + prev_chr_end = chr_x + chr_w;
> + pen_x += fg->glyph->advance.x >> 16;
> + prev_index = index;
> + }
> +
> +end:
> +
> +#ifdef INTERNATIONAL_SUPPORT
> + if (level_list) free(level_list);
> + if (visual_to_logical) free(visual_to_logical);
> + if (visual_text) free(visual_text);
> +#endif
> +
> + return ret_val;
> +}
> +
> +/* last char pos of text at xy pos
> + * Note: no need for special rtl handling
> + * because the string is in logical order, which is correct */
> +EAPI int
> +evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const char *text, int
> x, int y)
> +{
> + int use_kerning;
> + int pen_x, pen_y;
> + int prev_chr_end;
> + int chr;
> + int asc, desc;
> + FT_UInt prev_index;
> + RGBA_Font_Int *fi;
> + FT_Face pface = NULL;
> +
> + fi = fn->fonts->data;
> +
> + pen_x = 0;
> + pen_y = 0;
> + evas_common_font_size_use(fn);
> + use_kerning = FT_HAS_KERNING(fi->src->ft.face);
> + prev_index = 0;
> + prev_chr_end = 0;
> + asc = evas_common_font_max_ascent_get(fn);
> + desc = evas_common_font_max_descent_get(fn);
> for (chr = 0; text[chr];)
> {
> int pchr;
> @@ -362,10 +570,6 @@
> if ((x >= chr_x) && (x <= (chr_x + chr_w)) &&
> (y >= -asc) && (y <= desc))
> {
> - if (cx) *cx = chr_x;
> - if (cy) *cy = -asc;
> - if (cw) *cw = chr_w;
> - if (ch) *ch = asc + desc;
> return pchr;
> }
> prev_chr_end = chr_x + chr_w;
> @@ -374,3 +578,137 @@
> }
> return -1;
> }
> +#if 0
> +/* last char pos of text at xy pos */
> +EAPI int
> +evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const char *in_text,
> int x, int y)
> +{
> + int use_kerning;
> + int pen_x, pen_y;
> + int prev_chr_end;
> + int chr;
> + int asc, desc;
> + int char_index = 0; /* the index of the current char */
> + const char *text = in_text;
> + int ret_val = -1;
> + FT_UInt prev_index;
> + RGBA_Font_Int *fi;
> + FT_Face pface = NULL;
> +
> +#ifdef INTERNATIONAL_SUPPORT
> + int len = 0;
> + EvasIntlParType direction = FRIBIDI_TYPE_ON;
> + EvasIntlLevel *level_list;
> + EvasIntlStrIndex *visual_to_logical;
> +
> + char *visual_text = evas_intl_utf8_to_visual(in_text, &len, &direction,
> NULL, &visual_to_logical, &level_list);
> + text = (visual_text) ? visual_text : in_text;
> +#endif
> +
> + fi = fn->fonts->data;
> +
> + pen_x = 0;
> + pen_y = 0;
> + evas_common_font_size_use(fn);
> + use_kerning = FT_HAS_KERNING(fi->src->ft.face);
> + prev_index = 0;
> + prev_chr_end = 0;
> + asc = evas_common_font_max_ascent_get(fn);
> + desc = evas_common_font_max_descent_get(fn);
> +
> + for (char_index = 0, chr = 0; text[chr]; char_index++)
> + {
> + int pchr;
> + FT_UInt index;
> + RGBA_Font_Glyph *fg;
> + int chr_x, chr_y, chr_w;
> + int gl, kern;
> +
> +
> +
> + gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
> + if (gl == 0) break;
> + index = evas_common_font_glyph_search(fn, &fi, gl);
> + kern = 0;
> + /* hmmm kerning means i can't sanely do my own cached metric tables!
> */
> + /* grrr - this means font face sharing is kinda... not an option if */
> + /* you want performance */
> + if ((use_kerning) && (prev_index) && (index) &&
> + (pface == fi->src->ft.face))
> + {
> +#ifdef INTERNATIONAL_SUPPORT
> + /* if it's rtl, the kerning matching should be reversed, i.e prev
> + * index is now the index and the other way around. */
> + if (evas_intl_is_rtl_char(level_list, char_index))
> + {
> + if (evas_common_font_query_kerning(fi, index, prev_index,
> &kern))
> + pen_x += kern;
> + }
> + else
> +#endif
> + {
> +
> + if (evas_common_font_query_kerning(fi, prev_index, index,
> &kern))
> + pen_x += kern;
> + }
> + }
> +
> + pface = fi->src->ft.face;
> + fg = evas_common_font_int_cache_glyph_get(fi, index);
> + if (!fg) continue;
> +
> + if (kern < 0) kern = 0;
> + chr_x = ((pen_x - kern) + (fg->glyph_out->left));
> + chr_y = (pen_y + (fg->glyph_out->top));
> + chr_w = fg->glyph_out->bitmap.width + kern;
> +/* if (text[chr]) */
> + {
> + int advw;
> +
> + advw = ((fg->glyph->advance.x + (kern << 16)) >> 16);
> + if (chr_w < advw) chr_w = advw;
> + }
> + if (chr_x > prev_chr_end)
> + {
> + chr_w += (chr_x - prev_chr_end);
> + chr_x = prev_chr_end;
> + }
> + if ((x >= chr_x) && (x <= (chr_x + chr_w)) &&
> + (y >= -asc) && (y <= desc))
> + {
> +#ifdef INTERNATIONAL_SUPPORT
> + {
> + /* returs the char at the same position as the char found,
> + * though in the logical string which ensures it's the last
> + */
> + int i;
> + int logical_chr;
> +
> + /* ensure even if the list won't run */
> + pchr = 0;
> + for (logical_chr = 0, i = 0; i <= char_index; i++) {
> + pchr = logical_chr;
> + evas_common_font_utf8_get_next((unsigned char
> *)in_text, &logical_chr);
> + }
> + }
> +#endif
> + ret_val = pchr;
> + goto end;
> + }
> + prev_chr_end = chr_x + chr_w;
> + pen_x += fg->glyph->advance.x >> 16;
> + prev_index = index;
> + }
> +
> +end:
> +
> +#ifdef INTERNATIONAL_SUPPORT
> + if (level_list) free(level_list);
> + if (visual_to_logical) free(visual_to_logical);
> + if (visual_text) free(visual_text);
> +#endif
> +
> + return ret_val;
> +}
> +
> +#endif
> \ No newline at end of file
>
> Modified: trunk/evas/src/lib/engines/common/evas_intl/evas_intl_arabic.c
> ===================================================================
> --- trunk/evas/src/lib/engines/common/evas_intl/evas_intl_arabic.c
> 2009-09-30 03:53:17 UTC (rev 42813)
> +++ trunk/evas/src/lib/engines/common/evas_intl/evas_intl_arabic.c
> 2009-09-30 04:23:21 UTC (rev 42814)
> @@ -1,7 +1,3 @@
> -/* Authors:
> - * Tom Hacohen ([email protected])
> - */
> -
> #include "../evas_intl_utils.h"
>
> #ifdef ARABIC_SUPPORT
> @@ -118,7 +114,7 @@
>
> /* check for empty string */
> if (!*text)
> - return;
> + return 0;
>
> len = _evas_intl_arabic_text_to_isolated(text);
> /*FIXME: make it skip vowels */
>
> Modified: trunk/evas/src/lib/engines/common/evas_intl/evas_intl_arabic.h
> ===================================================================
> --- trunk/evas/src/lib/engines/common/evas_intl/evas_intl_arabic.h
> 2009-09-30 03:53:17 UTC (rev 42813)
> +++ trunk/evas/src/lib/engines/common/evas_intl/evas_intl_arabic.h
> 2009-09-30 04:23:21 UTC (rev 42814)
> @@ -1,7 +1,9 @@
> #ifndef _EVAS_INTL_ARABIC
> #define _EVAS_INTL_ARABIC
>
> +#include "evas_intl_utils.h"
> +
> int
> -evas_intl_arabic_to_context(FriBidiChar *text);
> +evas_intl_arabic_to_context(EvasIntlChar *text);
>
> #endif
>
> Modified: trunk/evas/src/lib/engines/common/evas_intl_utils.c
> ===================================================================
> --- trunk/evas/src/lib/engines/common/evas_intl_utils.c 2009-09-30
> 03:53:17 UTC (rev 42813)
> +++ trunk/evas/src/lib/engines/common/evas_intl_utils.c 2009-09-30
> 04:23:21 UTC (rev 42814)
> @@ -1,23 +1,27 @@
> -/* Authors:
> - * Tom Hacohen ([email protected])
> - */
> -
> #include <string.h>
> #include <stdlib.h>
>
> #include "evas_common.h"
> #include "evas_intl_utils.h"
>
> -#ifdef USE_FRIBIDI
> +#ifdef INTERNATIONAL_SUPPORT
> #include <fribidi/fribidi.h>
>
> #define UTF8_BYTES_PER_CHAR 4
>
> /* FIXME: fribidi_utf8_to_unicode should use char len and not byte len!*/
> char *
> -evas_intl_utf8_to_visual(const char *text, int *ret_len, FriBidiCharType
> *direction, FriBidiLevel **embedding_level_list)
> +evas_intl_utf8_to_visual(const char *text,
> + int *ret_len,
> + EvasIntlParType *direction,
> + EvasIntlStrIndex **position_L_to_V_list,
> + EvasIntlStrIndex **position_V_to_L_list,
> + EvasIntlLevel **embedding_level_list)
> {
> FriBidiChar *unicode_in, *unicode_out;
> + EvasIntlStrIndex *tmp_L_to_V_list = NULL;
> + EvasIntlStrIndex *tmp_V_to_L_list = NULL;
> + EvasIntlLevel *tmp_level_list = NULL;
> char *text_out;
> size_t len;
> size_t byte_len;
> @@ -27,15 +31,6 @@
>
> len = evas_string_char_len_get(text);
>
> - /* if there's nothing to do, return text
> - * one char draws are quite common */
> - if (len <= 1)
> - {
> - *ret_len = len;
> - *embedding_level_list = NULL;
> - return strdup(text);
> - }
> -
> byte_len = strlen(text); /* we need the actual number of bytes, not
> number of chars */
>
> unicode_in = (FriBidiChar *)alloca(sizeof(FriBidiChar) * (len + 1));
> @@ -51,33 +46,59 @@
> unicode_out = (FriBidiChar *)alloca(sizeof(FriBidiChar) * (len + 1));
> if (!unicode_out)
> {
> - len = -2;
> - goto error1;
> - }
> -
> - *embedding_level_list = (FriBidiLevel *)malloc(sizeof(FriBidiLevel) *
> len);
> - if (!*embedding_level_list)
> - {
> - len = -3;
> + len = -1;
> goto error2;
> }
>
> + if (embedding_level_list)
> + {
> + *embedding_level_list = (EvasIntlLevel
> *)malloc(sizeof(EvasIntlLevel) * len);
> + if (!*embedding_level_list)
> + {
> + len = -1;
> + goto error3;
> + }
> + tmp_level_list = *embedding_level_list;
> + }
> +
> + if (position_L_to_V_list)
> + {
> + *position_L_to_V_list = (EvasIntlStrIndex
> *)malloc(sizeof(EvasIntlStrIndex) * len);
> + if (!*position_L_to_V_list)
> + {
> + len = -1;
> + goto error4;
> + }
> + tmp_L_to_V_list = *position_L_to_V_list;
> + }
> +
> + if (position_V_to_L_list)
> + {
> + *position_V_to_L_list = (EvasIntlStrIndex
> *)malloc(sizeof(EvasIntlStrIndex) * len);
> + if (!*position_V_to_L_list)
> + {
> + len = -1;
> + goto error5;
> + }
> + tmp_V_to_L_list = *position_V_to_L_list;
> + }
> +
> #ifdef ARABIC_SUPPORT
> /* fix arabic context */
> evas_intl_arabic_to_context(unicode_in);
> #endif
> if (!fribidi_log2vis(unicode_in, len, direction,
> - unicode_out, NULL, NULL, *embedding_level_list))
> + unicode_out, tmp_L_to_V_list, tmp_V_to_L_list, tmp_level_list))
> {
> - len = -4;
> - goto error2;
> + len = -2;
> + goto error5;
> }
>
> text_out = malloc(UTF8_BYTES_PER_CHAR * len + 1);
> if (!text_out)
> {
> - len = -5;
> - goto error2;
> + len = -1;
> + goto error6;
> }
>
> fribidi_unicode_to_utf8(unicode_out, len, text_out);
> @@ -85,9 +106,20 @@
> *ret_len = len;
> return text_out;
>
> - /* ERROR HANDLING */
> +/* ERROR HANDLING */
> +error6:
> + free(unicode_out);
> +error5:
> + free(*position_V_to_L_list);
> + *position_V_to_L_list = NULL;
> +error4:
> + free(*position_L_to_V_list);
> + *position_L_to_V_list = NULL;
> +error3:
> + free(*embedding_level_list);
> + *embedding_level_list = NULL;
> error2:
> - free(*embedding_level_list);
> + free(unicode_in);
> error1:
>
> *ret_len = len;
> @@ -95,7 +127,7 @@
> }
>
> int
> -evas_intl_is_rtl_char(FriBidiLevel *embedded_level_list, FriBidiStrIndex i)
> +evas_intl_is_rtl_char(EvasIntlLevel *embedded_level_list, EvasIntlStrIndex i)
> {
> if(embedded_level_list || i < 0)
> return 0;
>
> Modified: trunk/evas/src/lib/engines/common/evas_intl_utils.h
> ===================================================================
> --- trunk/evas/src/lib/engines/common/evas_intl_utils.h 2009-09-30
> 03:53:17 UTC (rev 42813)
> +++ trunk/evas/src/lib/engines/common/evas_intl_utils.h 2009-09-30
> 04:23:21 UTC (rev 42814)
> @@ -4,25 +4,44 @@
> #include "config.h"
>
> #ifdef HAVE_FRIBIDI
> -#define USE_FRIBIDI 1
> +#define USE_FRIBIDI
> #define INTERNATIONAL_SUPPORT
> #endif
>
> #ifdef USE_FRIBIDI
> #include <fribidi/fribidi.h>
>
> +/* abstract fribidi */
> +typedef FriBidiChar EvasIntlChar;
> +typedef FriBidiCharType EvasIntlParType;
> +typedef FriBidiStrIndex EvasIntlStrIndex;
> +typedef FriBidiLevel EvasIntlLevel;
> +
> +
> /* whether should fix arabic specifix issues */
> -#define ARABIC_SUPPORT 1
> +#define ARABIC_SUPPORT
>
> #ifdef ARABIC_SUPPORT
> #include "evas_intl/evas_intl_arabic.h"
> #endif
>
> +#define evas_intl_position_logical_to_visual(list, position) \
> + (list) ? list[position] : position;
> +
> +#define evas_intl_position_visual_to_logical(list, position) \
> + (list) ? list[position] : position;
> +
> +
> int
> -evas_intl_is_rtl_char(FriBidiLevel *embedded_level_list, FriBidiStrIndex i);
> +evas_intl_is_rtl_char(EvasIntlLevel *embedded_level_list, EvasIntlStrIndex
> i);
>
> char *
> -evas_intl_utf8_to_visual(const char *text, int *ret_len, FriBidiCharType
> *direction, FriBidiLevel **embedding_level_list);
> +evas_intl_utf8_to_visual(const char *text,
> + int *ret_len,
> + EvasIntlParType *direction,
> + EvasIntlStrIndex **position_L_to_V_list,
> + EvasIntlStrIndex **position_V_to_L_list,
> + EvasIntlLevel **embedding_level_list);
> #endif
>
> #endif
>
> Modified: trunk/evas/src/lib/include/evas_private.h
> ===================================================================
> --- trunk/evas/src/lib/include/evas_private.h 2009-09-30 03:53:17 UTC (rev
> 42813)
> +++ trunk/evas/src/lib/include/evas_private.h 2009-09-30 04:23:21 UTC (rev
> 42814)
> @@ -671,6 +671,7 @@
>
> void (*image_scale_hint_set) (void *data, void *image, int
> hint);
> int (*image_scale_hint_get) (void *data, void *image);
> + int (*font_last_up_to_pos) (void *data, void *font, const
> char *text, int x, int y);
> };
>
> struct _Evas_Image_Load_Func
>
> Modified: trunk/evas/src/modules/engines/cairo_x11/evas_engine.c
> ===================================================================
> --- trunk/evas/src/modules/engines/cairo_x11/evas_engine.c 2009-09-30
> 03:53:17 UTC (rev 42813)
> +++ trunk/evas/src/modules/engines/cairo_x11/evas_engine.c 2009-09-30
> 04:23:21 UTC (rev 42814)
> @@ -122,6 +122,8 @@
> static void eng_font_hinting_set(void *data, void *font, int hinting);
> static int eng_font_hinting_can_hint(void *data, int hinting);
>
> +static int eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const
> char *text, int x, int y);
> +
> typedef struct _Render_Engine Render_Engine;
>
> struct _Render_Engine
> @@ -246,7 +248,9 @@
> eng_font_hinting_can_hint,
>
> eng_image_scale_hint_set,
> - eng_image_scale_hint_get
> + eng_image_scale_hint_get,
> + /* more font draw functions */
> + eng_font_last_up_to_pos
> };
>
> static void *
> @@ -1480,6 +1484,12 @@
> re = (Render_Engine *)data;
> }
>
> +static int
> +eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const char *text,
> int x, int y)
> +{
> + return evas_common_font_query_last_up_to_pos(font, text, x, y);
> +}
> +
> static Eina_Bool
> eng_canvas_alpha_get(void *data, void *context)
> {
>
> Modified: trunk/evas/src/modules/engines/software_16/evas_engine.c
> ===================================================================
> --- trunk/evas/src/modules/engines/software_16/evas_engine.c 2009-09-30
> 03:53:17 UTC (rev 42813)
> +++ trunk/evas/src/modules/engines/software_16/evas_engine.c 2009-09-30
> 04:23:21 UTC (rev 42814)
> @@ -772,6 +772,12 @@
> return evas_common_font_query_text_at_pos(font, text, x, y, cx, cy, cw,
> ch);
> }
>
> +static int
> +eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const char *text,
> int x, int y)
> +{
> + return evas_common_font_query_last_up_to_pos(font, text, x, y);
> +}
> +
> static void
> eng_font_draw(void *data __UNUSED__, void *context, void *surface, void
> *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__,
> int oh __UNUSED__, const char *text)
> {
> @@ -978,7 +984,9 @@
> eng_font_hinting_set,
> eng_font_hinting_can_hint,
> eng_image_scale_hint_set,
> - eng_image_scale_hint_get
> + eng_image_scale_hint_get,
> + /* more font draw functions */
> + eng_font_last_up_to_pos
> /* FUTURE software generic calls go here */
> };
>
>
> Modified: trunk/evas/src/modules/engines/software_generic/evas_engine.c
> ===================================================================
> --- trunk/evas/src/modules/engines/software_generic/evas_engine.c
> 2009-09-30 03:53:17 UTC (rev 42813)
> +++ trunk/evas/src/modules/engines/software_generic/evas_engine.c
> 2009-09-30 04:23:21 UTC (rev 42814)
> @@ -917,6 +917,12 @@
> return evas_common_font_query_text_at_pos(font, text, x, y, cx, cy, cw,
> ch);
> }
>
> +static int
> +eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const char *text,
> int x, int y)
> +{
> + return evas_common_font_query_last_up_to_pos(font, text, x, y);
> +}
> +
> static void
> eng_font_draw(void *data __UNUSED__, void *context, void *surface, void
> *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__,
> int oh __UNUSED__, const char *text)
> {
> @@ -1115,8 +1121,11 @@
> eng_font_hinting_set,
> eng_font_hinting_can_hint,
> eng_image_scale_hint_set,
> - eng_image_scale_hint_get
> + eng_image_scale_hint_get,
> + /* more font draw functions */
> + eng_font_last_up_to_pos
> /* FUTURE software generic calls go here */
> +
> };
>
> /*
>
>
> ------------------------------------------------------------------------------
> Come build with us! The BlackBerry® Developer Conference in SF, CA
> is the only developer event you need to attend this year. Jumpstart your
> developing skills, take BlackBerry mobile applications to market and stay
> ahead of the curve. Join us from November 9-12, 2009. Register now!
> http://p.sf.net/sfu/devconf
> _______________________________________________
> enlightenment-svn mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/enlightenment-svn
------------------------------------------------------------------------------
Come build with us! The BlackBerry® Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9-12, 2009. Register now!
http://p.sf.net/sfu/devconf
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel