From 1f9bfe697d9a5c696303e02a602de22221e7a17c Mon Sep 17 00:00:00 2001 From: tasn Date: Sun, 30 Jan 2011 10:34:07 +0000 Subject: [PATCH] Evas font engine: Added evas_common_font_query_pen_coords. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@56432 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/engines/common/evas_font.h | 1 + src/lib/engines/common/evas_font_query.c | 99 ++++++++++++++++++++++ src/lib/include/evas_private.h | 1 + src/modules/engines/cairo_x11/evas_engine.c | 21 ++++- src/modules/engines/quartz/evas_engine.c | 9 ++ src/modules/engines/quartz/evas_quartz_private.h | 1 + src/modules/engines/software_16/evas_engine.c | 9 +- src/modules/engines/software_8/evas_engine.c | 10 ++- src/modules/engines/software_generic/evas_engine.c | 9 +- 9 files changed, 154 insertions(+), 6 deletions(-) diff --git a/src/lib/engines/common/evas_font.h b/src/lib/engines/common/evas_font.h index ddacb8e..5dd93e1 100644 --- a/src/lib/engines/common/evas_font.h +++ b/src/lib/engines/common/evas_font.h @@ -60,6 +60,7 @@ EAPI void evas_common_font_query_size (RGBA_Font *fn, con EAPI int evas_common_font_query_inset (RGBA_Font *fn, const Eina_Unicode *text); EAPI void evas_common_font_query_advance (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *h_adv, int *v_adv); EAPI int evas_common_font_query_char_coords (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch); +EAPI int evas_common_font_query_pen_coords (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch); EAPI int evas_common_font_query_char_at_coords (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch); EAPI int evas_common_font_query_last_up_to_pos (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y); diff --git a/src/lib/engines/common/evas_font_query.c b/src/lib/engines/common/evas_font_query.c index b132b51..aed3478 100644 --- a/src/lib/engines/common/evas_font_query.c +++ b/src/lib/engines/common/evas_font_query.c @@ -292,6 +292,105 @@ end: return ret_val; } +/* x y w h for pen at char pos for null it returns the position right after + * the last char with 0 as width and height. This is the same as char_coords + * but it returns the pen_x and adv instead of x and w. + * BiDi handling: We receive the shaped string + other props from intl_props, + * We care about the actual drawing location of the string, this is why we need + * the visual string. We need to know how it's printed. After that we need to calculate + * the reverse kerning in case of rtl parts. "pos" passed to this function is an + * index in bytes, that is the actual byte location of the string, we need to find + * the index in order to find it in the visual string. + */ + +EAPI int +evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch) +{ + int asc, desc; + int position = 0; + const Eina_Unicode *text = in_text; + int ret_val = 0; + int use_kerning; + RGBA_Font_Int *fi; + EVAS_FONT_WALK_TEXT_INIT(); + _INIT_FI_AND_KERNING(); + +#ifdef BIDI_SUPPORT + int len = 0; + EvasBiDiStrIndex *visual_to_logical = NULL; + Eina_Unicode *visual_text; + + visual_text = eina_unicode_strdup(in_text); + if (visual_text) + { + evas_bidi_props_reorder_line(visual_text, intl_props->start, + eina_unicode_strlen(visual_text), intl_props->props, + &visual_to_logical); + text = visual_text; + } + else + { + text = in_text; + } + len = eina_unicode_strlen(text); +#endif + + asc = evas_common_font_max_ascent_get(fn); + desc = evas_common_font_max_descent_get(fn); + +#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); +#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. */ +#ifdef BIDI_SUPPORT + if (evas_bidi_is_rtl_char(intl_props, 0)) + { + if (cpen_x) *cpen_x = 0; + if (ch) *ch = asc + desc; + } + else +#endif + { + evas_common_font_query_advance(fn, text, intl_props, cpen_x, ch); + } + if (cy) *cy = 0; + if (cadv) *cadv = 0; + ret_val = 1; + goto end; + } + + EVAS_FONT_WALK_TEXT_START() + { + EVAS_FONT_WALK_TEXT_WORK(); + /* we need to see if the char at the visual position is the char wanted */ + if (char_index == position) + { + if (cpen_x) *cpen_x = pen_x; + if (cy) *cy = -asc; + if (cadv) *cadv = adv; + if (ch) *ch = asc + desc; + ret_val = 1; + goto end; + } + } + EVAS_FONT_WALK_TEXT_END(); +end: + +#ifdef BIDI_SUPPORT + if (visual_to_logical) free(visual_to_logical); + if (visual_text) free(visual_text); +#endif + + return ret_val; +} + /* char pos of text at xy pos * BiDi handling: Since we are looking for the char at the specific coords, * we have to get the visual string (to which the coords relate to), do diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h index f080bd6..6b839a2 100644 --- a/src/lib/include/evas_private.h +++ b/src/lib/include/evas_private.h @@ -668,6 +668,7 @@ struct _Evas_Func void (*image_content_hint_set) (void *data, void *surface, int hint); int (*image_content_hint_get) (void *data, void *surface); + int (*font_pen_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch); }; struct _Evas_Image_Load_Func diff --git a/src/modules/engines/cairo_x11/evas_engine.c b/src/modules/engines/cairo_x11/evas_engine.c index 528a273..8cccee3 100644 --- a/src/modules/engines/cairo_x11/evas_engine.c +++ b/src/modules/engines/cairo_x11/evas_engine.c @@ -93,6 +93,7 @@ static int eng_font_inset_get(void *data, void *font, char *text); static int eng_font_h_advance_get(void *data, void *font, char *text); static int eng_font_v_advance_get(void *data, void *font, char *text); static int eng_font_char_coords_get(void *data, void *font, char *text, int pos, int *cx, int *cy, int *cw, int *ch); +static int eng_font_pen_coords_get(void *data, void *font, char *text, int pos, int *cpen_x, int *cy, int *cadv, int *ch); static int eng_font_char_at_coords_get(void *data, void *font, char *text, int x, int y, int *cx, int *cy, int *cw, int *ch); static void eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, char *text); static void eng_font_cache_flush(void *data); @@ -211,9 +212,13 @@ static Evas_Func eng_func = eng_image_scale_hint_get, /* more font draw functions */ eng_font_last_up_to_pos, - NULL, // image_map4_draw - NULL, // image_map_surface_new - NULL // image_map_surface_free + NULL, // ORD(image_map4_draw); + NULL, // ORD(image_map_surface_new); + NULL, // ORD(image_map_surface_free); + NULL, // eng_image_content_hint_set - software doesn't use it + NULL, // eng_image_content_hint_get - software doesn't use it + eng_font_pen_coords_get + /* FUTURE software generic calls go here */ }; static void * @@ -1273,6 +1278,16 @@ eng_font_char_coords_get(void *data, void *font, char *text, int pos, int *cx, i } static int +eng_font_pen_coords_get(void *data, void *font, char *text, int pos, int *cpen_x, int *cy, int *cadv, int *ch) +{ + Render_Engine *re; + + /* FIXME, use cairo font subsystem */ + re = (Render_Engine *)data; + return 0; +} + +static int eng_font_char_at_coords_get(void *data, void *font, char *text, int x, int y, int *cx, int *cy, int *cw, int *ch) { Render_Engine *re; diff --git a/src/modules/engines/quartz/evas_engine.c b/src/modules/engines/quartz/evas_engine.c index 28508ff..743a39f 100644 --- a/src/modules/engines/quartz/evas_engine.c +++ b/src/modules/engines/quartz/evas_engine.c @@ -1096,6 +1096,15 @@ eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_Bi return 1; } +/*FIXME: this is *NOT* implemennted correctly, look at the other engines to + * see what needed to be done */ +static int +eng_font_pen_coords_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch) +{ + return eng_font_char_coords_get(data, font, text, intl_props, pos, cpen_x, + cy, cadv, ch) +} + static int eng_font_char_at_coords_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch) { diff --git a/src/modules/engines/quartz/evas_quartz_private.h b/src/modules/engines/quartz/evas_quartz_private.h index 3254f75..cb4bf46 100644 --- a/src/modules/engines/quartz/evas_quartz_private.h +++ b/src/modules/engines/quartz/evas_quartz_private.h @@ -80,6 +80,7 @@ static int eng_font_inset_get(void *data, void *font, const char *text); static int eng_font_h_advance_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props); static int eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props); static int eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch); +static int eng_font_pen_coords_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch); static int eng_font_char_at_coords_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch); static void eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text, const Evas_BiDi_Props *intl_props); static void eng_font_hinting_set(void *data, void *font, int hinting); diff --git a/src/modules/engines/software_16/evas_engine.c b/src/modules/engines/software_16/evas_engine.c index 86855ab..c31c4ca 100644 --- a/src/modules/engines/software_16/evas_engine.c +++ b/src/modules/engines/software_16/evas_engine.c @@ -535,6 +535,12 @@ eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *te } static int +eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch) +{ + return evas_common_font_query_pen_coords(font, text, intl_props, pos, cpen_x, cy, cadv, ch); +} + +static int eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch) { return evas_common_font_query_char_coords(font, text, intl_props, pos, cx, cy, cw, ch); @@ -723,7 +729,8 @@ static Evas_Func func = NULL, // ORD(image_map_surface_new); NULL, // ORD(image_map_surface_free); NULL, // eng_image_content_hint_set - software doesn't use it - NULL // eng_image_content_hint_get - software doesn't use it + NULL, // eng_image_content_hint_get - software doesn't use it + eng_font_pen_coords_get /* FUTURE software generic calls go here */ }; diff --git a/src/modules/engines/software_8/evas_engine.c b/src/modules/engines/software_8/evas_engine.c index a9462d2..a02c89d 100644 --- a/src/modules/engines/software_8/evas_engine.c +++ b/src/modules/engines/software_8/evas_engine.c @@ -592,6 +592,13 @@ eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *te } static int +eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, + int pos, int *cpen, int *cy, int *cadv, int *ch) +{ + return evas_common_font_query_pen_coords(font, text, intl_props, pos, cpen, cy, cadv, ch); +} + +static int eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch) { @@ -768,7 +775,8 @@ static Evas_Func func = { NULL, // ORD(image_map_surface_new); NULL, // ORD(image_map_surface_free); NULL, // eng_image_content_hint_set - software doesn't use it - NULL // eng_image_content_hint_get - software doesn't use it + NULL, // eng_image_content_hint_get - software doesn't use it + eng_font_pen_coords_get /* FUTURE software generic calls go here */ }; diff --git a/src/modules/engines/software_generic/evas_engine.c b/src/modules/engines/software_generic/evas_engine.c index 9249943..d79c4dc 100644 --- a/src/modules/engines/software_generic/evas_engine.c +++ b/src/modules/engines/software_generic/evas_engine.c @@ -705,6 +705,12 @@ eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *te } static int +eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch) +{ + return evas_common_font_query_pen_coords(font, text, intl_props, pos, cpen_x, cy, cadv, ch); +} + +static int eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch) { return evas_common_font_query_char_coords(font, text, intl_props, pos, cx, cy, cw, ch); @@ -890,7 +896,8 @@ static Evas_Func func = eng_image_map_surface_new, eng_image_map_surface_free, NULL, // eng_image_content_hint_set - software doesn't use it - NULL // eng_image_content_hint_get - software doesn't use it + NULL, // eng_image_content_hint_get - software doesn't use it + eng_font_pen_coords_get /* FUTURE software generic calls go here */ }; -- 2.7.4