From ff18fa8399e853626cccfbb3135e34015d635d31 Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Sun, 30 Jan 2011 10:36:39 +0000 Subject: [PATCH] Evas: Multiple changes that all relate to the Harfbuzz integration: 1. Started feeding Evas_Text_Props to the font engine instead of Evas_BiDi_Props because no we have more general text properties as well - i.e, OpenType stuff. 2. Full Harfbuzz integration which gets compiled in by default (if harfbuzz is present) but only works if the environment variable EVAS_USE_OT is set to 1 (because OT is way slower than regular text rendering). 3. Cleaned the font querying/drawing functions. 4. Added font_shaped function to all of the engines, which by default calls teh harfbuzz stuff (default on linux that is). 5. Moved some source files around a bit to make more sense. SVN revision: 56455 --- legacy/evas/src/lib/canvas/evas_object_text.c | 34 +- .../src/lib/canvas/evas_object_textblock.c | 167 +++--- .../evas/src/lib/engines/common/Makefile.am | 8 +- .../evas/src/lib/engines/common/evas_font.h | 16 +- .../engines/common/evas_font_default_walk.x | 203 +++++++ .../src/lib/engines/common/evas_font_draw.c | 425 +++++++++----- .../src/lib/engines/common/evas_font_main.c | 3 + .../src/lib/engines/common/evas_font_ot.c | 140 +++++ .../src/lib/engines/common/evas_font_ot.h | 70 +++ .../lib/engines/common/evas_font_ot_walk.x | 168 ++++++ .../lib/engines/common/evas_font_private.h | 65 +-- .../src/lib/engines/common/evas_font_query.c | 550 ++++++++++++------ .../evas/src/lib/engines/common/evas_pipe.c | 11 +- .../evas/src/lib/engines/common/evas_pipe.h | 2 +- .../src/lib/engines/common/evas_text_utils.c | 59 ++ .../src/lib/engines/common/evas_text_utils.h | 32 + .../engines/common/language/evas_bidi_utils.h | 5 +- .../common/language/evas_language_utils.c | 146 +++++ .../common/language/evas_language_utils.h | 128 ++++ .../common/language/evas_script_utils.c | 42 -- .../common/language/evas_script_utils.h | 11 - legacy/evas/src/lib/include/evas_common.h | 4 +- legacy/evas/src/lib/include/evas_private.h | 20 +- .../modules/engines/cairo_x11/evas_engine.c | 15 +- .../modules/engines/direct3d/evas_engine.c | 2 +- .../modules/engines/directfb/evas_engine.c | 2 +- .../src/modules/engines/gl_glew/evas_engine.c | 2 +- .../src/modules/engines/gl_sdl/evas_engine.c | 2 +- .../src/modules/engines/gl_x11/evas_engine.c | 2 +- .../src/modules/engines/quartz/evas_engine.c | 23 +- .../engines/quartz/evas_quartz_private.h | 15 +- .../modules/engines/software_16/evas_engine.c | 38 +- .../engines/software_16_sdl/evas_engine.c | 2 +- .../modules/engines/software_8/evas_engine.c | 38 +- .../engines/software_generic/evas_engine.c | 44 +- .../engines/software_sdl/evas_engine.c | 2 +- .../modules/engines/xrender_x11/evas_engine.c | 2 +- 37 files changed, 1906 insertions(+), 592 deletions(-) create mode 100644 legacy/evas/src/lib/engines/common/evas_font_default_walk.x create mode 100644 legacy/evas/src/lib/engines/common/evas_font_ot.c create mode 100644 legacy/evas/src/lib/engines/common/evas_font_ot.h create mode 100644 legacy/evas/src/lib/engines/common/evas_font_ot_walk.x create mode 100644 legacy/evas/src/lib/engines/common/evas_text_utils.c create mode 100644 legacy/evas/src/lib/engines/common/evas_text_utils.h create mode 100644 legacy/evas/src/lib/engines/common/language/evas_language_utils.c create mode 100644 legacy/evas/src/lib/engines/common/language/evas_language_utils.h delete mode 100644 legacy/evas/src/lib/engines/common/language/evas_script_utils.c delete mode 100644 legacy/evas/src/lib/engines/common/language/evas_script_utils.h diff --git a/legacy/evas/src/lib/canvas/evas_object_text.c b/legacy/evas/src/lib/canvas/evas_object_text.c index 0dccb757aa..4f16ab82a7 100644 --- a/legacy/evas/src/lib/canvas/evas_object_text.c +++ b/legacy/evas/src/lib/canvas/evas_object_text.c @@ -45,7 +45,7 @@ struct _Evas_Object_Text_Item Eina_Unicode *text; /*The shaped text */ size_t text_pos; size_t visual_pos; - Evas_BiDi_Props bidi_props; + Evas_Text_Props text_props; Evas_Coord x, w, h, adv; }; @@ -115,7 +115,7 @@ _evas_object_text_char_coords_get(const Evas_Object *obj, (pos < it->text_pos + eina_unicode_strlen(it->text))) { return ENFN->font_char_coords_get(ENDT, o->engine_data, it->text, - &it->bidi_props, pos - it->text_pos, x, y, w, h); + &it->text_props, pos - it->text_pos, x, y, w, h); } } return 0; @@ -125,9 +125,7 @@ _evas_object_text_char_coords_get(const Evas_Object *obj, static void _evas_object_text_item_clean(Evas_Object_Text_Item *it) { -#ifdef BIDI_SUPPORT - evas_bidi_props_clean(&it->bidi_props); -#endif + evas_common_text_props_content_unref(&it->text_props); if (it->text) { free(it->text); @@ -166,7 +164,7 @@ _evas_object_text_last_up_to_pos(const Evas_Object *obj, { return ENFN->font_last_up_to_pos(ENDT, o->engine_data, - it->text, &it->bidi_props, + it->text, &it->text_props, cx - x, cy); } @@ -191,7 +189,7 @@ _evas_object_text_char_at_coords(const Evas_Object *obj, { return ENFN->font_char_at_coords_get(ENDT, o->engine_data, - it->text, &it->bidi_props, + it->text, &it->text_props, cx, cy, rx, ry, @@ -232,7 +230,7 @@ _evas_object_text_vert_advance_get(const Evas_Object *obj, { Evas_Coord tmp; tmp = ENFN->font_v_advance_get(ENDT, o->engine_data, it->text, - &it->bidi_props); + &it->text_props); if (tmp > adv) { adv = tmp; @@ -510,19 +508,17 @@ _evas_object_text_item_new(Evas_Object *obj, Evas_Object_Text *o, it->text_pos = pos; it->visual_pos = visual_pos; eina_unicode_strncpy(it->text, str + pos, len); -#ifdef BIDI_SUPPORT - it->bidi_props.dir = (evas_bidi_is_rtl_char( - o->bidi_par_props, - 0, - it->text_pos)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR; - evas_bidi_shape_string(it->text, o->bidi_par_props, pos, len); -#endif + evas_common_text_props_bidi_set(&it->text_props, o->bidi_par_props, + it->text_pos); + evas_common_text_props_script_set(&it->text_props, it->text); + ENFN->font_shape(ENDT, o->engine_data, it->text, &it->text_props, + o->bidi_par_props, it->text_pos, eina_unicode_strlen(it->text)); ENFN->font_string_size_get(ENDT, o->engine_data, - it->text, &it->bidi_props, + it->text, &it->text_props, &it->w, &it->h); it->adv = ENFN->font_h_advance_get(ENDT, o->engine_data, it->text, - &it->bidi_props); + &it->text_props); o->items = (Evas_Object_Text_Item *) eina_inlist_append(EINA_INLIST_GET(o->items), EINA_INLIST_GET(it)); return it; @@ -606,7 +602,7 @@ _evas_object_text_layout(Evas_Object *obj, Evas_Object_Text *o, const Eina_Unico cutoff = len; do { - cutoff = evas_common_script_end_of_run_get( + cutoff = evas_common_language_script_end_of_run_get( text, o->bidi_par_props, pos, cutoff); @@ -1935,7 +1931,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, \ - it->text, &it->bidi_props); + it->text, &it->text_props); EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it) { /* shadows */ diff --git a/legacy/evas/src/lib/canvas/evas_object_textblock.c b/legacy/evas/src/lib/canvas/evas_object_textblock.c index f4f4e94785..09dcbe47c0 100644 --- a/legacy/evas/src/lib/canvas/evas_object_textblock.c +++ b/legacy/evas/src/lib/canvas/evas_object_textblock.c @@ -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_Text_Props text_props; }; struct _Evas_Object_Textblock_Text_Item @@ -630,6 +630,38 @@ _format_unref_free(const Evas_Object *obj, Evas_Object_Textblock_Format *fmt) free(fmt); } +/** + * @internal + * Free a layout item + * @param obj The evas object, must not be NULL. + * @param ln the layout line on which the item is in, must not be NULL. + * @param it the layout item to be freed + */ +static void +_item_free(const Evas_Object *obj, Evas_Object_Textblock_Line *ln, Evas_Object_Textblock_Item *it) +{ + if (it->type == EVAS_TEXTBLOCK_ITEM_TEXT) + { + Evas_Object_Textblock_Text_Item *ti = _ITEM_TEXT(it); + + if (ti->text) free(ti->text); + _format_unref_free(obj, ti->format); + } + else + { + Evas_Object_Textblock_Format_Item *fi = _ITEM_FORMAT(it); + + if (fi->item) eina_stringshare_del(fi->item); + } + evas_common_text_props_content_unref(&it->text_props); + if (ln) + { + ln->items = (Evas_Object_Textblock_Item *) eina_inlist_remove( + EINA_INLIST_GET(ln->items), EINA_INLIST_GET(ln->items)); + } + free(it); +} + /** * @internal * Free a layout line. @@ -642,22 +674,7 @@ _line_free(const Evas_Object *obj, Evas_Object_Textblock_Line *ln) while (ln->items) { Evas_Object_Textblock_Item *it = ln->items; - if (ln->items->type == EVAS_TEXTBLOCK_ITEM_TEXT) - { - Evas_Object_Textblock_Text_Item *ti = _ITEM_TEXT(it); - - if (ti->text) free(ti->text); - _format_unref_free(obj, ti->format); - } - else - { - Evas_Object_Textblock_Format_Item *fi = _ITEM_FORMAT(it); - - if (fi->item) eina_stringshare_del(fi->item); - } - ln->items = (Evas_Object_Textblock_Item *) eina_inlist_remove( - EINA_INLIST_GET(ln->items), EINA_INLIST_GET(ln->items)); - free(it); + _item_free(obj, ln, it); } if (ln) free(ln); } @@ -2251,7 +2268,7 @@ _layout_text_cutoff_get(Ctxt *c, Evas_Object_Textblock_Format *fmt, Evas_Object_ { if (fmt->font.font) return c->ENFN->font_last_up_to_pos(c->ENDT, fmt->font.font, ti->text, - &ti->parent.bidi_props, + &ti->parent.text_props, c->w - c->o->style_pad.l - c->o->style_pad.r - @@ -2279,6 +2296,9 @@ _layout_item_text_cutoff(Ctxt *c __UNUSED__, Evas_Object_Textblock_Text_Item *ti ts[cut] = 0; ti->text = eina_unicode_strdup(ts); free(ts); + c->ENFN->font_shape(c->ENDT, ti->format->font.font, ti->text, + &ti->parent.text_props, ti->parent.text_node->bidi_props, + ti->parent.text_pos, cut); } /** @@ -2353,11 +2373,11 @@ _layout_strip_trailing_whitespace(Ctxt *c, Evas_Object_Textblock_Format *fmt __U adv = 0; if (ti->format->font.font) adv = c->ENFN->font_h_advance_get(c->ENDT, ti->format->font.font, - ti->text, &ti->parent.bidi_props); + ti->text, &ti->parent.text_props); tw = th = 0; if (ti->format->font.font) c->ENFN->font_string_size_get(c->ENDT, ti->format->font.font, - ti->text, &ti->parent.bidi_props, &tw, &th); + ti->text, &ti->parent.text_props, &tw, &th); it->w = tw; it->h = th; it->adv = adv; @@ -2379,17 +2399,7 @@ _layout_item_abort(Ctxt *c, Evas_Object_Textblock_Format *fmt, Evas_Object_Textb /*FIXME: handle it in some way? */ if (it->type != EVAS_TEXTBLOCK_ITEM_TEXT) return 0; - if (ti->text) free(ti->text); - _format_unref_free(c->obj, ti->format); - -#ifdef BIDI_SUPPORT - /* FIXME: this also unrefs the paragraph props, we should either - * really count the usage of the paragraph props in the items, or just - * not use clean here. I prefer the latter but that might break if we'll - * start doing fancy stuff in clean in the future. */ - /* evas_bidi_props_clean(&it->bidi_props); */ -#endif - free(ti); + _item_free(c->obj, NULL, _ITEM(ti)); if (c->ln->items) { it = (Evas_Object_Textblock_Item *)(EINA_INLIST_GET(c->ln->items))->last; @@ -2473,6 +2483,7 @@ _layout_text_add_and_split_item(Ctxt *c, Evas_Object_Textblock_Format *fmt, int cutoff, len; + cutoff = 0; len = eina_unicode_strlen(ti->text); do { @@ -2481,21 +2492,38 @@ _layout_text_add_and_split_item(Ctxt *c, Evas_Object_Textblock_Format *fmt, * no text nodes, make sure it's the case. */ if (ti->parent.text_node) { - cutoff = evas_common_script_end_of_run_get( - eina_ustrbuf_string_get(ti->parent.text_node->unicode), + cutoff = evas_common_language_script_end_of_run_get( + ti->text, ti->parent.text_node->bidi_props, ti->parent.text_pos, len); if (cutoff > 0) { new_ti = _layout_text_item_new(c, fmt, ti->text + cutoff); _layout_item_text_cutoff(c, ti, cutoff); + new_ti->parent.text_node = ti->parent.text_node; + new_ti->parent.text_pos = ti->parent.text_pos + cutoff; + evas_common_text_props_bidi_set(&new_ti->parent.text_props, + new_ti->parent.text_node->bidi_props, + new_ti->parent.text_pos); + evas_common_text_props_script_set (&new_ti->parent.text_props, + new_ti->text); + /* FIXME: I possibly can use the alread calculated lengths */ + c->ENFN->font_shape(c->ENDT, ti->format->font.font, ti->text, + &ti->parent.text_props, + ti->parent.text_node->bidi_props, + ti->parent.text_pos, cutoff); + c->ENFN->font_shape(c->ENDT, new_ti->format->font.font, + new_ti->text, + &new_ti->parent.text_props, + new_ti->parent.text_node->bidi_props, + new_ti->parent.text_pos, len - cutoff); } } tw = th = 0; if (fmt->font.font) c->ENFN->font_string_size_get(c->ENDT, fmt->font.font, ti->text, - &ti->parent.bidi_props, &tw, &th); + &ti->parent.text_props, &tw, &th); ti->parent.w = tw; ti->parent.h = th; inset = 0; @@ -2507,7 +2535,7 @@ _layout_text_add_and_split_item(Ctxt *c, Evas_Object_Textblock_Format *fmt, adv = 0; if (fmt->font.font) adv = c->ENFN->font_h_advance_get(c->ENDT, fmt->font.font, - ti->text, &ti->parent.bidi_props); + ti->text, &ti->parent.text_props); ti->parent.adv = adv; c->x += adv; c->ln->items = (Evas_Object_Textblock_Item *) @@ -2516,16 +2544,6 @@ _layout_text_add_and_split_item(Ctxt *c, Evas_Object_Textblock_Format *fmt, if (cutoff > 0) { - new_ti->parent.text_node = ti->parent.text_node; - new_ti->parent.text_pos = ti->parent.text_pos + cutoff; -#ifdef BIDI_SUPPORT - 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; -#else - new_ti->parent.bidi_props.dir = EVAS_BIDI_DIRECTION_LTR; -#endif ti = new_ti; len -= cutoff; } @@ -2611,11 +2629,6 @@ _layout_text_append(Ctxt *c, Evas_Object_Textblock_Format *fmt, Evas_Object_Text alloc_str[off] = 0; } str = alloc_str; - - /* Shape the string */ -# ifdef BIDI_SUPPORT - evas_bidi_shape_string(alloc_str, n->bidi_props, start, off); -# endif } } @@ -2636,19 +2649,18 @@ skip: ti->parent.text_pos = start + str - tbase; if (ti->parent.text_node) { -#ifdef BIDI_SUPPORT - 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; -#else - ti->parent.bidi_props.dir = EVAS_BIDI_DIRECTION_LTR; -#endif + evas_common_text_props_bidi_set(&ti->parent.text_props, + ti->parent.text_node->bidi_props, ti->parent.text_pos); + evas_common_text_props_script_set (&ti->parent.text_props, + ti->text); + c->ENFN->font_shape(c->ENDT, ti->format->font.font, ti->text, + &ti->parent.text_props, ti->parent.text_node->bidi_props, + ti->parent.text_pos, eina_unicode_strlen(ti->text)); } tw = th = 0; if (fmt->font.font) c->ENFN->font_string_size_get(c->ENDT, fmt->font.font, ti->text, - &ti->parent.bidi_props, &tw, &th); + &ti->parent.text_props, &tw, &th); /* Check if we need to wrap, i.e the text is bigger than the width * Only calculate wrapping if the width of the object is > 0 */ if ((c->w >= 0) && @@ -2698,10 +2710,7 @@ skip: else { empty_item = 1; - /* FIXME: use proper cleaning here */ - if (ti->text) free(ti->text); - _format_unref_free(c->obj, ti->format); - free(ti); + _item_free(c->obj, NULL, _ITEM(ti)); if (c->ln->items) { ti = _ITEM_TEXT((EINA_INLIST_GET(c->ln->items))->last); @@ -2860,14 +2869,8 @@ _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); -#ifdef BIDI_SUPPORT - 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; -#else - fi->parent.bidi_props.dir = EVAS_BIDI_DIRECTION_LTR; -#endif + evas_common_text_props_bidi_set(&fi->parent.text_props, + fi->parent.text_node->bidi_props, fi->parent.text_pos); } return fi; } @@ -6821,7 +6824,7 @@ evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord * @return line number of the char on success, -1 on error. */ static int -_evas_textblock_cursor_char_pen_geometry_common_get(int (*query_func) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch), const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) +_evas_textblock_cursor_char_pen_geometry_common_get(int (*query_func) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch), const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) { Evas_Object_Textblock *o; Evas_Object_Textblock_Line *ln = NULL; @@ -6876,7 +6879,7 @@ _evas_textblock_cursor_char_pen_geometry_common_get(int (*query_func) (void *dat { ret = query_func(cur->ENDT, ti->format->font.font, - ti->text, &ti->parent.bidi_props, + ti->text, &ti->parent.text_props, pos, &x, &y, &w, &h); } @@ -7058,7 +7061,7 @@ evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, E pos = cur->ENFN->font_char_at_coords_get( cur->ENDT, ti->format->font.font, - ti->text, &ti->parent.bidi_props, + ti->text, &ti->parent.text_props, x - it->x - ln->x, 0, &cx, &cy, &cw, &ch); if (pos < 0) @@ -7145,7 +7148,7 @@ _evas_textblock_range_calc_x_w(const Evas_Object_Textblock_Item *it, if ((start && !switch_items) || (!start && switch_items)) { #ifdef BIDI_SUPPORT - if (it->bidi_props.dir == EVAS_BIDI_DIRECTION_RTL) + if (it->text_props.bidi.dir == EVAS_BIDI_DIRECTION_RTL) { *w = *x + *w; *x = 0; @@ -7159,7 +7162,7 @@ _evas_textblock_range_calc_x_w(const Evas_Object_Textblock_Item *it, else { #ifdef BIDI_SUPPORT - if (it->bidi_props.dir == EVAS_BIDI_DIRECTION_RTL) + if (it->text_props.bidi.dir == EVAS_BIDI_DIRECTION_RTL) { *x = *x + *w; *w = it->adv - *x; @@ -7255,7 +7258,7 @@ _evas_textblock_cursor_range_in_line_geometry_get( ti = _ITEM_TEXT(it1); ret = cur->ENFN->font_pen_coords_get(cur->ENDT, ti->format->font.font, - ti->text, &ti->parent.bidi_props, + ti->text, &ti->parent.text_props, start, &x1, &y, &w1, &h); if (!ret) @@ -7264,7 +7267,7 @@ _evas_textblock_cursor_range_in_line_geometry_get( } ret = cur->ENFN->font_pen_coords_get(cur->ENDT, ti->format->font.font, - ti->text, &ti->parent.bidi_props, + ti->text, &ti->parent.text_props, end, &x2, &y, &w2, &h); if (!ret) @@ -7286,7 +7289,7 @@ _evas_textblock_cursor_range_in_line_geometry_get( } #ifdef BIDI_SUPPORT - if (ti->parent.bidi_props.dir == EVAS_BIDI_DIRECTION_RTL) + if (ti->parent.text_props.bidi.dir == EVAS_BIDI_DIRECTION_RTL) { x = x1 + w1; w = x2 + w2 - x; @@ -7324,7 +7327,7 @@ _evas_textblock_cursor_range_in_line_geometry_get( ret = cur->ENFN->font_pen_coords_get(cur->ENDT, ti->format->font.font, - ti->text, &ti->parent.bidi_props, + ti->text, &ti->parent.text_props, start, &x, &y, &w, &h); if (!ret) @@ -7378,7 +7381,7 @@ _evas_textblock_cursor_range_in_line_geometry_get( ret = cur->ENFN->font_pen_coords_get(cur->ENDT, ti->format->font.font, - ti->text, &ti->parent.bidi_props, + ti->text, &ti->parent.text_props, end, &x, &y, &w, &h); if (!ret) @@ -7836,7 +7839,7 @@ evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void if (ti->format->font.font) ENFN->font_draw(output, context, surface, ti->format->font.font, \ obj->cur.geometry.x + ln->x + ti->parent.x + x + (ox), \ obj->cur.geometry.y + ln->y + yoff + y + (oy), \ - ti->parent.w, ti->parent.h, ti->parent.w, ti->parent.h, ti->text, &ti->parent.bidi_props); + ti->parent.w, ti->parent.h, ti->parent.w, ti->parent.h, ti->text, &ti->parent.text_props); #define ITEM_WALK_LINE_SKIP_DROP() \ if ((ln->y + ln->h) <= 0) continue; \ if (ln->y > obj->cur.geometry.h) break diff --git a/legacy/evas/src/lib/engines/common/Makefile.am b/legacy/evas/src/lib/engines/common/Makefile.am index fe58d886cb..c3f9dd8426 100644 --- a/legacy/evas/src/lib/engines/common/Makefile.am +++ b/legacy/evas/src/lib/engines/common/Makefile.am @@ -60,7 +60,9 @@ evas_tiler.c \ evas_regionbuf.c \ evas_pipe.c \ language/evas_bidi_utils.c \ -language/evas_script_utils.c \ +language/evas_language_utils.c \ +evas_text_utils.c \ +evas_font_ot.c \ evas_map_image.c \ evas_map_image.h @@ -100,7 +102,9 @@ evas_scale_smooth_scaler_up.c \ evas_scale_span.h \ evas_pipe.h \ language/evas_bidi_utils.h \ -language/evas_script_utils.h \ +language/evas_language_utils.h \ +evas_text_utils.h \ +evas_font_ot.h \ evas_map_image_internal.c \ evas_map_image_core.c \ evas_map_image_loop.c diff --git a/legacy/evas/src/lib/engines/common/evas_font.h b/legacy/evas/src/lib/engines/common/evas_font.h index b96f437226..bf5a570ae4 100644 --- a/legacy/evas/src/lib/engines/common/evas_font.h +++ b/legacy/evas/src/lib/engines/common/evas_font.h @@ -1,6 +1,6 @@ #ifndef _EVAS_FONT_H #define _EVAS_FONT_H -#include "language/evas_bidi_utils.h" +#include "evas_text_utils.h" /* main */ @@ -17,7 +17,7 @@ EAPI int evas_common_font_get_line_advance (RGBA_Font *fn); /* draw */ -EAPI void evas_common_font_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props); +EAPI void evas_common_font_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text, const Evas_Text_Props *intl_props); EAPI int evas_common_font_glyph_search (RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl); EAPI RGBA_Font_Glyph *evas_common_font_int_cache_glyph_get (RGBA_Font_Int *fi, FT_UInt index); EAPI void evas_common_font_draw_init (void); @@ -56,13 +56,13 @@ EAPI void evas_common_font_all_clear (void); /* query */ EAPI int evas_common_font_query_kerning (RGBA_Font_Int* fi, FT_UInt left, FT_UInt right, int* kerning); -EAPI void evas_common_font_query_size (RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h); +EAPI void evas_common_font_query_size (RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *w, int *h); 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); +EAPI void evas_common_font_query_advance (RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_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_Text_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_Text_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_Text_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_Text_Props *intl_props, int x, int y); #ifdef EVAS_FRAME_QUEUING EAPI void evas_common_font_draw_finish(void); diff --git a/legacy/evas/src/lib/engines/common/evas_font_default_walk.x b/legacy/evas/src/lib/engines/common/evas_font_default_walk.x new file mode 100644 index 0000000000..b06315cc91 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_font_default_walk.x @@ -0,0 +1,203 @@ +#ifndef _EVAS_FONT_DEFAULT_WALK_X +#define _EVAS_FONT_DEFAULT_WALK_X +/* Macros for text walking */ + +/** + * @def EVAS_FONT_UPDATE_KERN() + * @internal + * This macro updates pen_x and kern according to kerning. + * This macro assumes the following variables exist: + * intl_props, char_index, adv, fi, kern, pen_x + */ +#ifdef BIDI_SUPPORT +#define EVAS_FONT_UPDATE_KERN(is_visual) \ + do \ + { \ + /* if it's rtl, the kerning matching should be reversed, */ \ + /* 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 && (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && \ + visible && !is_visual) \ + { \ + if (evas_common_font_query_kerning(fi, index, prev_index, &kern)) \ + pen_x += kern; \ + } \ + else \ + { \ + if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \ + pen_x += kern; \ + } \ + } \ + while (0) +#else +#define EVAS_FONT_UPDATE_KERN(is_visual) \ + do \ + { \ + (void) is_visual; \ + if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \ + pen_x += kern; \ + } \ + while (0) +#endif + +/** + * @def EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START + * @internal + * This runs through the variable text while updating char_index, + * which is the current index in the text. This macro exposes (inside + * the loop) the following vars: + * adv - advancement + * gl - the current unicode code point + * bear_x, bear_y, width - info about the bitmap + * pen_x, pen_y - (also available outside of the loop, but updated here) + * fg - the font glyph. + * index, prev_index - font indexes. + * Does not end with a ; + * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT + * @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK + * @see EVAS_FONT_WALK_DEFAULT_TEXT_END + */ +#define EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() \ + do \ + { \ + const Eina_Unicode *_base_text; \ + int _char_index_d, _i; \ + int visible; \ + prev_index = 0; \ + _base_text = text; \ + for ( ; *text ; text++); \ + _i = text - _base_text; \ + if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \ + { \ + char_index = text - _base_text - 1; \ + text--; \ + _char_index_d = -1; \ + } \ + else \ + { \ + char_index = 0; \ + text = _base_text; \ + _char_index_d = 1; \ + } \ + for ( ; _i > 0 ; char_index += _char_index_d, text += _char_index_d, _i--) \ + { \ + FT_UInt index; \ + RGBA_Font_Glyph *fg; \ + int gl, kern; \ + gl = *text; \ + if (gl == 0) break; +/** + * @def EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START + * @internal + * FIXME: update + * This runs through the variable text while updating char_index, + * which is the current index in the text. This macro exposes (inside + * the loop) the following vars: + * adv - advancement + * gl - the current unicode code point + * bear_x, bear_y, width - info about the bitmap + * pen_x, pen_y - (also available outside of the loop, but updated here) + * fg - the font glyph. + * index, prev_index - font indexes. + * Does not end with a ; + * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT + * @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK + * @see EVAS_FONT_WALK_DEFAULT_TEXT_END + */ +#define EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START() \ + do \ + { \ + int visible; \ + prev_index = 0; \ + for (char_index = 0 ; *text ; text++, char_index++) \ + { \ + FT_UInt index; \ + RGBA_Font_Glyph *fg; \ + int gl, kern; \ + gl = *text; \ + if (gl == 0) break; + +/*FIXME: doc */ +#define EVAS_FONT_WALK_DEFAULT_X_OFF (kern) +#define EVAS_FONT_WALK_DEFAULT_Y_OFF (0) +#define EVAS_FONT_WALK_DEFAULT_X_BEAR (fg->glyph_out->left) +#define EVAS_FONT_WALK_DEFAULT_Y_BEAR (fg->glyph_out->top) +#define EVAS_FONT_WALK_DEFAULT_X_ADV (fg->glyph->advance.x >> 16) +#define EVAS_FONT_WALK_DEFAULT_Y_ADV (0) +#define EVAS_FONT_WALK_DEFAULT_WIDTH (fg->glyph_out->bitmap.width) +#define EVAS_FONT_WALK_DEFAULT_POS (char_index) +#define EVAS_FONT_WALK_DEFAULT_IS_LAST \ + (!text[char_index]) +#define EVAS_FONT_WALK_DEFAULT_IS_FIRST \ + (!char_index) +#define EVAS_FONT_WALK_DEFAULT_POS_NEXT \ + ((!EVAS_FONT_WALK_DEFAULT_IS_LAST) ? \ + (char_index + 1) : \ + (char_index) \ + ) +#define EVAS_FONT_WALK_DEFAULT_POS_PREV \ + ((!EVAS_FONT_WALK_DEFAULT_IS_FIRST) ? \ + (char_index - 1) : \ + EVAS_FONT_WALK_DEFAULT_POS \ + ) +#define EVAS_FONT_WALK_DEFAULT_LEN (EVAS_FONT_WALK_ORIG_LEN) +/** + * @def EVAS_FONT_WALK_DEFAULT_TEXT_WORK + * @internal + * This macro actually updates the values mentioned in EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START + * according to the current positing in the walk. + * @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START + * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT + * @see EVAS_FONT_WALK_DEFAULT_TEXT_END + */ +#define EVAS_FONT_WALK_DEFAULT_TEXT_WORK(is_visual) \ + index = evas_common_font_glyph_search(fn, &fi, gl); \ + LKL(fi->ft_mutex); \ + fg = evas_common_font_int_cache_glyph_get(fi, index); \ + if (!fg) \ + { \ + LKU(fi->ft_mutex); \ + continue; \ + } \ + kern = 0; \ + if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl)) \ + { \ + visible = 0; \ + } \ + else \ + { \ + visible = 1; \ + } \ + /* 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)) \ + { \ + EVAS_FONT_UPDATE_KERN(is_visual); \ + } \ + \ + pface = fi->src->ft.face; \ + LKU(fi->ft_mutex); \ + +/** + * @def EVAS_FONT_WALK_DEFAULT_TEXT_END + * @internal + * Closes EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START, needs to end with a ; + * @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START + * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT + * @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK + */ +#define EVAS_FONT_WALK_DEFAULT_TEXT_END() \ + if (visible) \ + { \ + pen_x += EVAS_FONT_WALK_DEFAULT_X_ADV; \ + } \ + prev_index = index; \ + } \ + } \ + while(0) + + +#endif diff --git a/legacy/evas/src/lib/engines/common/evas_font_draw.c b/legacy/evas/src/lib/engines/common/evas_font_draw.c index e1135fbc9f..52275c64d7 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_draw.c +++ b/legacy/evas/src/lib/engines/common/evas_font_draw.c @@ -5,6 +5,8 @@ #include "language/evas_bidi_utils.h" /*defines BIDI_SUPPORT if possible */ #include "evas_font_private.h" /* for Frame-Queuing support */ +#include "evas_font_ot.h" + #define WORD_CACHE_MAXLEN 50 /* How many to cache */ #define WORD_CACHE_NWORDS 40 @@ -48,7 +50,7 @@ struct cinfo #if defined(METRIC_CACHE) || defined(WORD_CACHE) LK(lock_words); // for word cache call static Eina_Inlist *words = NULL; -static struct prword *evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *text, Evas_BiDi_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning); +static struct prword *evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *text, Evas_Text_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning); #endif EAPI void @@ -395,7 +397,7 @@ evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl) */ static void evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *in_text, - const Evas_BiDi_Props *intl_props, RGBA_Gfx_Func func, int ext_x, int ext_y, int ext_w, + const Evas_Text_Props *intl_props, 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 ) { @@ -414,7 +416,7 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font struct prword *word; word = - evas_font_word_prerender(dc, text, (Evas_BiDi_Props *)intl_props, + evas_font_word_prerender(dc, text, (Evas_Text_Props *)intl_props, len, fn, fi, use_kerning); if (word) { @@ -493,27 +495,6 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font } #endif -#ifdef BIDI_SUPPORT - Eina_Unicode *visual_text = NULL; - - if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)) - { - visual_text = eina_unicode_strdup(in_text); - - if (visual_text) - { - evas_bidi_reverse_string(visual_text); - text = visual_text; - } - } - if (!visual_text) - { - text = in_text; - } -#else - /*Suppress warnings */ - (void) intl_props; -#endif if (fi->src->current_size != fi->size) { FTLOCK(); @@ -522,144 +503,149 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font fi->src->current_size = fi->size; } + pen_x = x; pen_y = y; im = dst->image.data; - EVAS_FONT_WALK_TEXT_START() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - int chr_x, chr_y, chr_w; - - if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl)) - continue; - - EVAS_FONT_WALK_TEXT_WORK(EINA_TRUE); - - if (dc->font_ext.func.gl_new) + EVAS_FONT_WALK_OT_TEXT_VISUAL_START() { - /* extension calls */ - fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg); - fg->ext_dat_free = dc->font_ext.func.gl_free; - } + int chr_x, chr_y, chr_w; - chr_x = (pen_x) + bear_x; - chr_y = (pen_y) + bear_y; - chr_w = width; + if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl)) + continue; - if (chr_x < (ext_x + ext_w)) - { - DATA8 *data; - int i, j, w, h; + EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE); - data = fg->glyph_out->bitmap.buffer; - j = fg->glyph_out->bitmap.pitch; - w = fg->glyph_out->bitmap.width; - if (j < w) j = w; - h = fg->glyph_out->bitmap.rows; - /* - if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays) - && (fg->glyph_out->bitmap.num_grays == 256) - ) - */ + if (dc->font_ext.func.gl_new) { - if ((j > 0) && (chr_x + w > ext_x)) - { - if ((fg->ext_dat) && (dc->font_ext.func.gl_draw)) - { - /* ext glyph draw */ - dc->font_ext.func.gl_draw(dc->font_ext.data, - (void *)dst, - dc, fg, chr_x, - y - (chr_y - y)); - } - else - { - if ((fg->glyph_out->bitmap.num_grays == 256) && - (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)) - { - for (i = 0; i < h; i++) - { - int dx, dy; - int in_x, in_w; + /* extension calls */ + fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg); + fg->ext_dat_free = dc->font_ext.func.gl_free; + } - in_x = 0; - in_w = 0; - dx = chr_x; - dy = y - (chr_y - i - y); -#ifdef EVAS_SLI - if (((dy) % dc->sli.h) == dc->sli.y) -#endif + chr_x = (pen_x) + EVAS_FONT_WALK_OT_X_OFF + EVAS_FONT_WALK_OT_X_BEAR; + chr_y = (pen_y) + EVAS_FONT_WALK_OT_Y_OFF + EVAS_FONT_WALK_OT_Y_BEAR; + chr_w = EVAS_FONT_WALK_OT_WIDTH; + + if (chr_x < (ext_x + ext_w)) + { + DATA8 *data; + int i, j, w, h; + + data = fg->glyph_out->bitmap.buffer; + j = fg->glyph_out->bitmap.pitch; + w = fg->glyph_out->bitmap.width; + if (j < w) j = w; + h = fg->glyph_out->bitmap.rows; + /* + if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays) + && (fg->glyph_out->bitmap.num_grays == 256) + ) + */ + { + if ((j > 0) && (chr_x + w > ext_x)) + { + if ((fg->ext_dat) && (dc->font_ext.func.gl_draw)) + { + /* ext glyph draw */ + dc->font_ext.func.gl_draw(dc->font_ext.data, + (void *)dst, + dc, fg, chr_x, + y - (chr_y - y)); + } + else + { + if ((fg->glyph_out->bitmap.num_grays == 256) && + (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)) + { + for (i = 0; i < h; i++) { - if ((dx < (ext_x + ext_w)) && - (dy >= (ext_y)) && - (dy < (ext_y + ext_h))) + int dx, dy; + int in_x, in_w; + + in_x = 0; + in_w = 0; + dx = chr_x; + dy = y - (chr_y - i - y); +#ifdef EVAS_SLI + if (((dy) % dc->sli.h) == dc->sli.y) +#endif { - if (dx + w > (ext_x + ext_w)) - in_w += (dx + w) - (ext_x + ext_w); - if (dx < ext_x) + if ((dx < (ext_x + ext_w)) && + (dy >= (ext_y)) && + (dy < (ext_y + ext_h))) { - in_w += ext_x - dx; - in_x = ext_x - dx; - dx = ext_x; - } - if (in_w < w) - { - func(NULL, data + (i * j) + in_x, dc->col.col, - im + (dy * im_w) + dx, w - in_w); + if (dx + w > (ext_x + ext_w)) + in_w += (dx + w) - (ext_x + ext_w); + if (dx < ext_x) + { + in_w += ext_x - dx; + in_x = ext_x - dx; + dx = ext_x; + } + if (in_w < w) + { + func(NULL, data + (i * j) + in_x, dc->col.col, + im + (dy * im_w) + dx, w - in_w); + } } } } } - } - else - { - DATA8 *tmpbuf = NULL, *dp, *tp, bits; - int bi, bj; - const DATA8 bitrepl[2] = {0x0, 0xff}; - - tmpbuf = alloca(w); - for (i = 0; i < h; i++) + else { - int dx, dy; - int in_x, in_w, end; + DATA8 *tmpbuf = NULL, *dp, *tp, bits; + int bi, bj; + const DATA8 bitrepl[2] = {0x0, 0xff}; - in_x = 0; - in_w = 0; - dx = chr_x; - dy = y - (chr_y - i - y); -#ifdef EVAS_SLI - if (((dy) % dc->sli.h) == dc->sli.y) -#endif + tmpbuf = alloca(w); + for (i = 0; i < h; i++) { - tp = tmpbuf; - dp = data + (i * fg->glyph_out->bitmap.pitch); - for (bi = 0; bi < w; bi += 8) + int dx, dy; + int in_x, in_w, end; + + in_x = 0; + in_w = 0; + dx = chr_x; + dy = y - (chr_y - i - y); +#ifdef EVAS_SLI + if (((dy) % dc->sli.h) == dc->sli.y) +#endif { - bits = *dp; - if ((w - bi) < 8) end = w - bi; - else end = 8; - for (bj = 0; bj < end; bj++) + tp = tmpbuf; + dp = data + (i * fg->glyph_out->bitmap.pitch); + for (bi = 0; bi < w; bi += 8) { - *tp = bitrepl[(bits >> (7 - bj)) & 0x1]; - tp++; + bits = *dp; + if ((w - bi) < 8) end = w - bi; + else end = 8; + for (bj = 0; bj < end; bj++) + { + *tp = bitrepl[(bits >> (7 - bj)) & 0x1]; + tp++; + } + dp++; } - dp++; - } - if ((dx < (ext_x + ext_w)) && - (dy >= (ext_y)) && - (dy < (ext_y + ext_h))) - { - if (dx + w > (ext_x + ext_w)) - in_w += (dx + w) - (ext_x + ext_w); - if (dx < ext_x) + if ((dx < (ext_x + ext_w)) && + (dy >= (ext_y)) && + (dy < (ext_y + ext_h))) { - in_w += ext_x - dx; - in_x = ext_x - dx; - dx = ext_x; - } - if (in_w < w) - { - func(NULL, tmpbuf + in_x, dc->col.col, - im + (dy * im_w) + dx, w - in_w); + if (dx + w > (ext_x + ext_w)) + in_w += (dx + w) - (ext_x + ext_w); + if (dx < ext_x) + { + in_w += ext_x - dx; + in_x = ext_x - dx; + dx = ext_x; + } + if (in_w < w) + { + func(NULL, tmpbuf + in_x, dc->col.col, + im + (dy * im_w) + dx, w - in_w); + } } } } @@ -668,20 +654,169 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font } } } + else + break; } - else - break; + EVAS_FONT_WALK_OT_TEXT_END(); } - EVAS_FONT_WALK_TEXT_END(); -#ifdef BIDI_SUPPORT - if (visual_text) free(visual_text); + else #endif + { + EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() + { + int chr_x, chr_y, chr_w; + + if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl)) + continue; + + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE); + + if (dc->font_ext.func.gl_new) + { + /* extension calls */ + fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg); + fg->ext_dat_free = dc->font_ext.func.gl_free; + } + + chr_x = (pen_x) + EVAS_FONT_WALK_DEFAULT_X_OFF + EVAS_FONT_WALK_DEFAULT_X_BEAR; + chr_y = (pen_y) + EVAS_FONT_WALK_DEFAULT_Y_OFF + EVAS_FONT_WALK_DEFAULT_Y_BEAR; + chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH; + + if (chr_x < (ext_x + ext_w)) + { + DATA8 *data; + int i, j, w, h; + + data = fg->glyph_out->bitmap.buffer; + j = fg->glyph_out->bitmap.pitch; + w = fg->glyph_out->bitmap.width; + if (j < w) j = w; + h = fg->glyph_out->bitmap.rows; + /* + if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays) + && (fg->glyph_out->bitmap.num_grays == 256) + ) + */ + { + if ((j > 0) && (chr_x + w > ext_x)) + { + if ((fg->ext_dat) && (dc->font_ext.func.gl_draw)) + { + /* ext glyph draw */ + dc->font_ext.func.gl_draw(dc->font_ext.data, + (void *)dst, + dc, fg, chr_x, + y - (chr_y - y)); + } + else + { + if ((fg->glyph_out->bitmap.num_grays == 256) && + (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)) + { + for (i = 0; i < h; i++) + { + int dx, dy; + int in_x, in_w; + + in_x = 0; + in_w = 0; + dx = chr_x; + dy = y - (chr_y - i - y); +#ifdef EVAS_SLI + if (((dy) % dc->sli.h) == dc->sli.y) +#endif + { + if ((dx < (ext_x + ext_w)) && + (dy >= (ext_y)) && + (dy < (ext_y + ext_h))) + { + if (dx + w > (ext_x + ext_w)) + in_w += (dx + w) - (ext_x + ext_w); + if (dx < ext_x) + { + in_w += ext_x - dx; + in_x = ext_x - dx; + dx = ext_x; + } + if (in_w < w) + { + func(NULL, data + (i * j) + in_x, dc->col.col, + im + (dy * im_w) + dx, w - in_w); + } + } + } + } + } + else + { + DATA8 *tmpbuf = NULL, *dp, *tp, bits; + int bi, bj; + const DATA8 bitrepl[2] = {0x0, 0xff}; + + tmpbuf = alloca(w); + for (i = 0; i < h; i++) + { + int dx, dy; + int in_x, in_w, end; + + in_x = 0; + in_w = 0; + dx = chr_x; + dy = y - (chr_y - i - y); +#ifdef EVAS_SLI + if (((dy) % dc->sli.h) == dc->sli.y) +#endif + { + tp = tmpbuf; + dp = data + (i * fg->glyph_out->bitmap.pitch); + for (bi = 0; bi < w; bi += 8) + { + bits = *dp; + if ((w - bi) < 8) end = w - bi; + else end = 8; + for (bj = 0; bj < end; bj++) + { + *tp = bitrepl[(bits >> (7 - bj)) & 0x1]; + tp++; + } + dp++; + } + if ((dx < (ext_x + ext_w)) && + (dy >= (ext_y)) && + (dy < (ext_y + ext_h))) + { + if (dx + w > (ext_x + ext_w)) + in_w += (dx + w) - (ext_x + ext_w); + if (dx < ext_x) + { + in_w += ext_x - dx; + in_x = ext_x - dx; + dx = ext_x; + } + if (in_w < w) + { + func(NULL, tmpbuf + in_x, dc->col.col, + im + (dy * im_w) + dx, w - in_w); + } + } + } + } + } + } + } + } + } + else + break; + } + EVAS_FONT_WALK_DEFAULT_TEXT_END(); + } evas_common_font_int_use_trim(); } EAPI void evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text, - const Evas_BiDi_Props *intl_props) + const Evas_Text_Props *intl_props) { int ext_x, ext_y, ext_w, ext_h; int im_w, im_h; @@ -766,7 +901,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int /* Only used if cache is on */ #if defined(METRIC_CACHE) || defined(WORD_CACHE) struct prword * -evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Evas_BiDi_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning) +evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Evas_Text_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning) { int pen_x, pen_y; struct cinfo *metrics; diff --git a/legacy/evas/src/lib/engines/common/evas_font_main.c b/legacy/evas/src/lib/engines/common/evas_font_main.c index 8a11a10e98..9d37b4f504 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_main.c +++ b/legacy/evas/src/lib/engines/common/evas_font_main.c @@ -9,6 +9,7 @@ static int initialised = 0; LK(lock_font_draw); // for freetype2 API calls LK(lock_bidi); // for evas bidi internal usage. +LK(lock_ot); // for evas bidi internal usage. EAPI void evas_common_font_init(void) @@ -23,6 +24,7 @@ evas_common_font_init(void) evas_common_font_draw_init(); LKI(lock_font_draw); LKI(lock_bidi); + LKI(lock_ot); } EAPI void @@ -36,6 +38,7 @@ evas_common_font_shutdown(void) LKD(lock_font_draw); LKD(lock_bidi); + LKD(lock_ot); evas_common_font_load_shutdown(); evas_common_font_cache_set(0); diff --git a/legacy/evas/src/lib/engines/common/evas_font_ot.c b/legacy/evas/src/lib/engines/common/evas_font_ot.c new file mode 100644 index 0000000000..558c943b5c --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_font_ot.c @@ -0,0 +1,140 @@ +#include "evas_font_ot.h" + +#ifdef OT_SUPPORT +# include +# include +#endif + +#include "evas_common.h" + +#include +#include "evas_font_private.h" + +EAPI Eina_Bool +evas_common_font_ot_is_enabled(void) +{ +#ifdef OT_SUPPORT + static int ret = -1; + const char *env; + if (ret != -1) + { + return ret; + } + + env = getenv("EVAS_USE_OT"); + if (env && atoi(env)) + { + ret = EINA_TRUE; + return ret; + } +#endif + return EINA_FALSE; +} + + +#ifdef OT_SUPPORT +static void +_evas_common_font_ot_shape(hb_buffer_t *buffer, FT_Face face) +{ + hb_face_t *hb_face; + hb_font_t *hb_font; + + hb_face = hb_ft_face_create(face, NULL); + hb_font = hb_ft_font_create(face, NULL); + + hb_shape(hb_font, hb_face, buffer, NULL, 0); + hb_font_destroy(hb_font); + hb_face_destroy(hb_face); +} + +EAPI Eina_Bool +evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text, + Evas_Text_Props *props, int len) +{ + RGBA_Font *fn = (RGBA_Font *) _fn; + RGBA_Font_Int *fi; + hb_buffer_t *buffer; + hb_glyph_position_t *positions; + hb_glyph_info_t *infos; + int slen; + unsigned int i; + if (!evas_common_font_ot_is_enabled()) return EINA_TRUE; + if (props->ot_data) + { + evas_common_font_ot_props_unref(props->ot_data); + } + props->ot_data = calloc(1, sizeof(Evas_Font_OT_Data)); + props->ot_data->refcount = 1; + + fi = fn->fonts->data; + if (fi->src->current_size != fi->size) + { + FTLOCK(); + FT_Activate_Size(fi->ft.size); + FTUNLOCK(); + fi->src->current_size = fi->size; + } + /* Load the font needed for this script */ + evas_common_font_glyph_search(fn, &fi, *text); + + if (len < 0) + { + slen = eina_unicode_strlen(text); + } + else + { + slen = len; + } + + buffer = hb_buffer_create(slen); + hb_buffer_set_unicode_funcs(buffer, evas_common_language_unicode_funcs_get()); + hb_buffer_set_language(buffer, hb_language_from_string( + evas_common_language_from_locale_get())); + hb_buffer_set_script(buffer, props->script); + hb_buffer_set_direction(buffer, + (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? + HB_DIRECTION_RTL : HB_DIRECTION_LTR); + /* FIXME: add run-time conversions if needed, which is very unlikely */ + hb_buffer_add_utf32(buffer, (const uint32_t *) text, slen, 0, slen); + + _evas_common_font_ot_shape(buffer, fi->src->ft.face); + + props->ot_data->len = hb_buffer_get_length(buffer); + props->ot_data->items = calloc(props->ot_data->len, + sizeof(Evas_Font_OT_Data_Item)); + positions = hb_buffer_get_glyph_positions(buffer); + infos = hb_buffer_get_glyph_infos(buffer); + for (i = 0 ; i < props->ot_data->len ; i++) + { + props->ot_data->items[i].index = infos[i].codepoint; + props->ot_data->items[i].source_pos = infos[i].cluster; + props->ot_data->items[i].x_advance = positions[i].x_advance; + props->ot_data->items[i].x_offset = positions[i].x_offset; + props->ot_data->items[i].y_offset = positions[i].y_offset; + } + + hb_buffer_destroy(buffer); + + return EINA_FALSE; +} + +EAPI void +evas_common_font_ot_props_ref(Evas_Font_OT_Data *data) +{ + data->refcount++; +} + +EAPI void +evas_common_font_ot_props_unref(Evas_Font_OT_Data *data) +{ + OTLOCK(); + if (--data->refcount == 0) + { + if (data->items) + free(data->items); + free(data); + } + OTUNLOCK(); +} +#endif + diff --git a/legacy/evas/src/lib/engines/common/evas_font_ot.h b/legacy/evas/src/lib/engines/common/evas_font_ot.h new file mode 100644 index 0000000000..b963ea0e6e --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_font_ot.h @@ -0,0 +1,70 @@ +#ifndef _EVAS_FONT_OT_H +# define _EVAS_FONT_OT_H + +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif + +# ifdef HAVE_HARFBUZZ +# define OT_SUPPORT +# define USE_HARFBUZZ +# endif + +# ifdef OT_SUPPORT +#include +typedef struct _Evas_Font_OT_Data Evas_Font_OT_Data; +typedef struct _Evas_Font_OT_Data_Item Evas_Font_OT_Data_Item; +struct _Evas_Font_OT_Data +{ + int refcount; + size_t len; + Evas_Font_OT_Data_Item *items; +}; +#endif + +#include "Evas.h" + +#ifdef OT_SUPPORT +struct _Evas_Font_OT_Data_Item +{ + unsigned int index; /* Should conform to FT */ + size_t source_pos; + Evas_Coord x_offset; + Evas_Coord y_offset; + Evas_Coord x_advance; +}; +# else +typedef void *Evas_Font_OT_Data; +# endif + +# ifdef OT_SUPPORT +# define EVAS_FONT_OT_X_OFF_GET(a) ((a).x_offset) +# define EVAS_FONT_OT_Y_OFF_GET(a) ((a).y_offset) +# define EVAS_FONT_OT_X_ADV_GET(a) ((a).x_advance) +//# define EVAS_FONT_OT_Y_ADV_GET(a) ((a).y_advance) +# define EVAS_FONT_OT_INDEX_GET(a) ((a).index) +# define EVAS_FONT_OT_POS_GET(a) ((a).source_pos) +#else +# define EVAS_FONT_OT_X_OFF_GET(a) (0) +# define EVAS_FONT_OT_Y_OFF_GET(a) (0) +# define EVAS_FONT_OT_X_ADV_GET(a) (0) +//# define EVAS_FONT_OT_POS_Y_ADV_GET(a) (0) +# define EVAS_FONT_OT_INDEX_GET(a) (0) /* FIXME!!! */ +# define EVAS_FONT_OT_POS_GET(a) (0) /* FIXME!!! */ +# endif + +EAPI Eina_Bool +evas_common_font_ot_is_enabled(void); + +EAPI void +evas_common_font_ot_props_ref(Evas_Font_OT_Data *data); + +EAPI void +evas_common_font_ot_props_unref(Evas_Font_OT_Data *data); + +#include "evas_text_utils.h" +EAPI Eina_Bool +evas_common_font_ot_populate_text_props(void *fn, const Eina_Unicode *text, + Evas_Text_Props *props, int len); +#endif + diff --git a/legacy/evas/src/lib/engines/common/evas_font_ot_walk.x b/legacy/evas/src/lib/engines/common/evas_font_ot_walk.x new file mode 100644 index 0000000000..cbc5b2c390 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_font_ot_walk.x @@ -0,0 +1,168 @@ +#ifndef _EVAS_FONT_OT_WALK_X +#define _EVAS_FONT_OT_WALK_X +# include "evas_font_ot.h" +# include "language/evas_language_utils.h" + +/* Macros for text walking */ + +/** + * @def EVAS_FONT_WALK_OT_TEXT_VISUAL_START + * @internal + * This runs through the variable text while updating char_index, + * which is the current index in the text. This macro exposes (inside + * the loop) the following vars: + * adv - advancement + * gl - the current unicode code point + * bear_x, bear_y, width - info about the bitmap + * pen_x, pen_y - (also available outside of the loop, but updated here) + * fg - the font glyph. + * index, prev_index - font indexes. + * Does not end with a ; + * @see EVAS_FONT_WALK_OT_TEXT_INIT + * @see EVAS_FONT_WALK_OT_TEXT_WORK + * @see EVAS_FONT_WALK_OT_TEXT_END + */ +#define EVAS_FONT_WALK_OT_TEXT_VISUAL_START() \ + do \ + { \ + int visible; \ + prev_index = 0; \ + /* Load the glyph according to the first letter of the script, preety + * bad, but will have to do */ \ + evas_common_font_glyph_search(fn, &fi, *text); \ + for (char_index = 0 ; char_index < intl_props->ot_data->len ; char_index++) \ + { \ + FT_UInt index; \ + RGBA_Font_Glyph *fg; \ + int gl, kern; \ + gl = 0; /* FIXME: hack */ +/** + * @def EVAS_FONT_WALK_OT_TEXT_LOGICAL_START + * @internal + * FIXME: not up to date + * This runs through the variable text while updating char_index, + * which is the current index in the text. This macro exposes (inside + * the loop) the following vars: + * adv - advancement + * gl - the current unicode code point + * bear_x, bear_y, width - info about the bitmap + * pen_x, pen_y - (also available outside of the loop, but updated here) + * fg - the font glyph. + * index, prev_index - font indexes. + * Does not end with a ; + * @see EVAS_FONT_WALK_OT_TEXT_INIT + * @see EVAS_FONT_WALK_OT_TEXT_WORK + * @see EVAS_FONT_WALK_OT_TEXT_END + */ +#define EVAS_FONT_WALK_OT_TEXT_LOGICAL_START() \ + do \ + { \ + int _char_index_d, _i; \ + int visible; \ + /* Load the glyph according to the first letter of the script, preety + * bad, but will have to do */ \ + evas_common_font_glyph_search(fn, &fi, *text); \ + prev_index = 0; \ + _i = intl_props->ot_data->len; \ + if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \ + { \ + char_index = intl_props->ot_data->len - 1; \ + _char_index_d = -1; \ + } \ + else \ + { \ + char_index = 0; \ + _char_index_d = 1; \ + } \ + for ( ; _i > 0 ; char_index += _char_index_d, _i--) \ + { \ + FT_UInt index; \ + RGBA_Font_Glyph *fg; \ + int gl, kern; \ + gl = 0; /* FIXME: hack */ + +/*FIXME: doc */ +#define EVAS_FONT_WALK_OT_X_OFF \ + (EVAS_FONT_OT_X_OFF_GET( \ + intl_props->ot_data->items[char_index]) >> 6) +#define EVAS_FONT_WALK_OT_Y_OFF \ + (EVAS_FONT_OT_Y_OFF_GET( \ + intl_props->ot_data->items[char_index]) >> 6) +#define EVAS_FONT_WALK_OT_X_BEAR (fg->glyph_out->left) +#define EVAS_FONT_WALK_OT_Y_BEAR (fg->glyph_out->top) +#define EVAS_FONT_WALK_OT_X_ADV \ + (EVAS_FONT_OT_X_ADV_GET( \ + intl_props->ot_data->items[char_index]) >> 6) +#define EVAS_FONT_WALK_OT_WIDTH (fg->glyph_out->bitmap.width) +#define EVAS_FONT_WALK_OT_POS \ + (EVAS_FONT_OT_POS_GET( \ + intl_props->ot_data->items[char_index])) +#define EVAS_FONT_WALK_OT_IS_LAST \ + (char_index + 1 == intl_props->ot_data->len) +#define EVAS_FONT_WALK_OT_IS_FIRST \ + (!char_index) +#define EVAS_FONT_WALK_OT_POS_NEXT \ + ((!EVAS_FONT_WALK_OT_IS_LAST) ? \ + EVAS_FONT_OT_POS_GET( \ + intl_props->ot_data->items[char_index + 1]) : \ + EVAS_FONT_WALK_OT_POS \ + ) +#define EVAS_FONT_WALK_OT_POS_PREV \ + ((char_index > 0) ? \ + EVAS_FONT_OT_POS_GET( \ + intl_props->ot_data->items[char_index - 1]) : \ + EVAS_FONT_WALK_OT_POS \ + ) +#define EVAS_FONT_WALK_OT_LEN (intl_props->ot_data->len) +/** + * @def EVAS_FONT_WALK_OT_TEXT_WORK + * @internal + * This macro actually updates the values mentioned in EVAS_FONT_WALK_OT_TEXT_VISUAL_START + * according to the current positing in the walk. + * @see EVAS_FONT_WALK_OT_TEXT_VISUAL_START + * @see EVAS_FONT_WALK_OT_TEXT_INIT + * @see EVAS_FONT_WALK_OT_TEXT_END + */ +#define EVAS_FONT_WALK_OT_TEXT_WORK(is_visual) \ + index = EVAS_FONT_OT_INDEX_GET(intl_props->ot_data->items[char_index]); \ + LKL(fi->ft_mutex); \ + fg = evas_common_font_int_cache_glyph_get(fi, index); \ + if (!fg) \ + { \ + LKU(fi->ft_mutex); \ + continue; \ + } \ + kern = 0; \ + if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl)) \ + { \ + visible = 0; \ + } \ + else \ + { \ + visible = 1; \ + } \ + \ + pface = fi->src->ft.face; \ + LKU(fi->ft_mutex); + +/** + * @def EVAS_FONT_WALK_OT_TEXT_END + * @internal + * Closes EVAS_FONT_WALK_OT_TEXT_VISUAL_START, needs to end with a ; + * @see EVAS_FONT_WALK_OT_TEXT_VISUAL_START + * @see EVAS_FONT_WALK_OT_TEXT_INIT + * @see EVAS_FONT_WALK_OT_TEXT_WORK + */ +#define EVAS_FONT_WALK_OT_TEXT_END() \ + if (visible) \ + { \ + pen_x += EVAS_FONT_WALK_OT_X_ADV; \ + } \ + prev_index = index; \ + } \ + /* FIXME: clean up */ \ + } \ + while(0) + + +#endif diff --git a/legacy/evas/src/lib/engines/common/evas_font_private.h b/legacy/evas/src/lib/engines/common/evas_font_private.h index b6f83860f1..b98d8ab138 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_private.h +++ b/legacy/evas/src/lib/engines/common/evas_font_private.h @@ -1,9 +1,11 @@ #ifndef _EVAS_FONT_PRIVATE_H # define _EVAS_FONT_PRIVATE_H +#include "evas_font_ot.h" #ifdef BUILD_PTHREAD extern LK(lock_font_draw); // for freetype2 API calls extern LK(lock_bidi); // for fribidi API calls +extern LK(lock_ot); // for harfbuzz calls #endif # if defined(EVAS_FRAME_QUEUING) || defined(BUILD_PIPE_RENDER) @@ -12,13 +14,15 @@ extern LK(lock_bidi); // for fribidi API calls # define BIDILOCK() LKL(lock_bidi) # define BIDIUNLOCK() LKU(lock_bidi) + +# define OTLOCK() LKL(lock_ot) +# define OTUNLOCK() LKU(lock_ot) # else # define FTLOCK(x) # define FTUNLOCK(x) # define BIDILOCK() # define BIDIUNLOCK() -# endif void evas_common_font_source_unload(RGBA_Font_Source *fs); void evas_common_font_source_reload(RGBA_Font_Source *fs); @@ -29,51 +33,23 @@ void evas_common_font_int_use_trim(void); void evas_common_font_int_unload(RGBA_Font_Int *fi); void evas_common_font_int_reload(RGBA_Font_Int *fi); /* Macros for text walking */ +# define OTLOCK() +# define OTUNLOCK() +# endif -#define EVAS_FONT_CHARACTER_IS_INVISIBLE(x) ( \ +# define EVAS_FONT_CHARACTER_IS_INVISIBLE(x) ( \ ((0x200C <= (x)) && ((x) <= 0x200D)) || /* ZWNJ..ZWH */ \ ((0x200E <= (x)) && ((x) <= 0x200F)) || /* BIDI stuff */ \ ((0x202A <= (x)) && ((x) <= 0x202E)) /* BIDI stuff */ \ ) -/** - * @def EVAS_FONT_UPDATE_KERN() - * @internal - * This macro updates pen_x and kern according to kerning. - * This macro assumes the following variables exist: - * intl_props, char_index, adv, fi, kern, pen_x - */ -#ifdef BIDI_SUPPORT -#define EVAS_FONT_UPDATE_KERN(is_visual) \ - do \ - { \ - /* if it's rtl, the kerning matching should be reversed, */ \ - /* 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 && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL) && \ - visible && !is_visual) \ - { \ - if (evas_common_font_query_kerning(fi, index, prev_index, &kern)) \ - pen_x += kern; \ - } \ - else \ - { \ - if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \ - pen_x += kern; \ - } \ - } \ - while (0) -#else -#define EVAS_FONT_UPDATE_KERN(is_visual) \ - do \ - { \ - (void) is_visual; \ - if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \ - pen_x += kern; \ - } \ - while (0) -#endif +# define EVAS_FONT_WALK_ORIG_LEN (_len) + +# ifdef OT_SUPPORT +# include "evas_font_ot_walk.x" +# endif + +# include "evas_font_default_walk.x" /** * @def EVAS_FONT_WALK_TEXT_INIT @@ -84,13 +60,16 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi); * @see EVAS_FONT_WALK_TEXT_WORK * @see EVAS_FONT_WALK_TEXT_END */ -#define EVAS_FONT_WALK_TEXT_INIT() \ +# define EVAS_FONT_WALK_TEXT_INIT() \ int pen_x = 0, pen_y = 0; \ - int char_index; \ + size_t char_index; \ FT_UInt prev_index; \ FT_Face pface = NULL; \ + int _len = eina_unicode_strlen(text); \ + (void) _len; /* We don't have to use it */ \ (void) pen_y; /* Sometimes it won't be used */ +<<<<<<< HEAD /** * @def EVAS_FONT_WALK_TEXT_START * @internal @@ -185,4 +164,6 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi); } \ while(0) +======= +>>>>>>> Evas: Multiple changes that all relate to the Harfbuzz integration: #endif /* !_EVAS_FONT_PRIVATE_H */ diff --git a/legacy/evas/src/lib/engines/common/evas_font_query.c b/legacy/evas/src/lib/engines/common/evas_font_query.c index 8d80673fe8..d3df7ec537 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_query.c +++ b/legacy/evas/src/lib/engines/common/evas_font_query.c @@ -58,6 +58,7 @@ evas_common_font_query_kerning(RGBA_Font_Int* fi, } /* text x inset */ +/* FIXME: should use OT info when available. */ EAPI int evas_common_font_query_inset(RGBA_Font *fn, const Eina_Unicode *text) { @@ -137,7 +138,7 @@ evas_common_font_query_inset(RGBA_Font *fn, const Eina_Unicode *text) */ EAPI void -evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props __UNUSED__, int *w, int *h) +evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *intl_props __UNUSED__, int *w, int *h) { int keep_width = 0; int prev_pen_x = 0; @@ -146,15 +147,37 @@ evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_ EVAS_FONT_WALK_TEXT_INIT(); _INIT_FI_AND_KERNING(); - EVAS_FONT_WALK_TEXT_START() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE); - /* Keep the width because we'll need it for the last char */ - keep_width = width + bear_x; - /* Keep the previous pen_x, before it's advanced in TEXT_END */ - prev_pen_x = pen_x; + EVAS_FONT_WALK_OT_TEXT_VISUAL_START() + { + EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE); + if (!visible) continue; + /* Keep the width because we'll need it for the last char */ + keep_width = EVAS_FONT_WALK_OT_WIDTH + EVAS_FONT_WALK_OT_X_OFF + + EVAS_FONT_WALK_OT_X_BEAR; + /* Keep the previous pen_x, before it's advanced in TEXT_END */ + prev_pen_x = pen_x; + } + EVAS_FONT_WALK_OT_TEXT_END(); + } + else +#endif + { + EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START() + { + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE); + if (!visible) continue; + /* Keep the width because we'll need it for the last char */ + keep_width = EVAS_FONT_WALK_DEFAULT_WIDTH + + EVAS_FONT_WALK_DEFAULT_X_OFF + + EVAS_FONT_WALK_DEFAULT_X_BEAR; + /* Keep the previous pen_x, before it's advanced in TEXT_END */ + prev_pen_x = pen_x; + } + EVAS_FONT_WALK_DEFAULT_TEXT_END(); } - EVAS_FONT_WALK_TEXT_END(); if (w) *w = prev_pen_x + keep_width; if (h) *h = evas_common_font_max_ascent_get(fn) + evas_common_font_max_descent_get(fn); evas_common_font_int_use_trim(); @@ -168,7 +191,7 @@ evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_ * this way, we are safe. */ 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) +evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *h_adv, int *v_adv) { int use_kerning; RGBA_Font_Int *fi; @@ -179,11 +202,26 @@ evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Ev (void) intl_props; #endif - EVAS_FONT_WALK_TEXT_START() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE); + EVAS_FONT_WALK_OT_TEXT_VISUAL_START() + { + EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE); + if (!visible) continue; + } + EVAS_FONT_WALK_OT_TEXT_END(); + } + else +#endif + { + EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START() + { + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE); + if (!visible) continue; + } + EVAS_FONT_WALK_DEFAULT_TEXT_END(); } - EVAS_FONT_WALK_TEXT_END(); if (v_adv) *v_adv = evas_common_font_get_line_advance(fn); if (h_adv) *h_adv = pen_x; @@ -201,7 +239,7 @@ evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Ev */ EAPI int -evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch) +evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch) { int asc, desc; int position = 0; @@ -212,43 +250,17 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c EVAS_FONT_WALK_TEXT_INIT(); _INIT_FI_AND_KERNING(); -#ifdef BIDI_SUPPORT - Eina_Unicode *visual_text = NULL; - int len; - - if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)) - { - visual_text = eina_unicode_strdup(in_text); - - if (visual_text) - { - evas_bidi_reverse_string(visual_text); - text = visual_text; - } - } - if (!visual_text) - { - 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_reverse(intl_props, 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 (intl_props->dir == EVAS_BIDI_DIRECTION_RTL) + if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) { if (cx) *cx = 0; if (ch) *ch = asc + desc; @@ -264,32 +276,106 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c goto end; } - EVAS_FONT_WALK_TEXT_START() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - int chr_x, chr_y, chr_w; + EVAS_FONT_WALK_OT_TEXT_VISUAL_START() + { + int chr_x, chr_w; + int found = 0, items = 1, item_pos = 1; - EVAS_FONT_WALK_TEXT_WORK(EINA_TRUE); + EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE); + if (visible) + { + chr_x = (pen_x) + EVAS_FONT_WALK_OT_X_OFF + + EVAS_FONT_WALK_OT_X_BEAR; + chr_w = EVAS_FONT_WALK_OT_WIDTH; + } + else + { + chr_x = pen_x; + chr_w = 0; + } + /* 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) && + ((((size_t) position) < EVAS_FONT_WALK_OT_POS_NEXT) || + (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_NEXT))) + { + 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; + } + item_pos = position - EVAS_FONT_WALK_OT_POS + 1; + } + else if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && + ((EVAS_FONT_WALK_OT_POS_PREV > (size_t) position) || + (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_PREV)) && + (((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; + } + item_pos = items - (position - EVAS_FONT_WALK_OT_POS); + } - chr_x = (pen_x) + bear_x; - chr_y = (pen_y) + bear_y; - chr_w = width; - /* 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; - ret_val = 1; - goto end; - } + if (found) + { + if (cx) *cx = chr_x + + (EVAS_FONT_WALK_OT_WIDTH / items) * (item_pos - 1); + if (cy) *cy = -asc; + if (cw) *cw = chr_w / items; + if (ch) *ch = asc + desc; + ret_val = 1; + goto end; + } + } + EVAS_FONT_WALK_OT_TEXT_END(); } - EVAS_FONT_WALK_TEXT_END(); -end: - -#ifdef BIDI_SUPPORT - if (visual_text) free(visual_text); + else #endif + { + EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() + { + int chr_x, chr_w; + + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE); + if (visible) + { + chr_x = (pen_x) + EVAS_FONT_WALK_DEFAULT_X_OFF + + EVAS_FONT_WALK_DEFAULT_X_BEAR; + chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH; + } + else + { + chr_x = pen_x; + chr_w = 0; + } + /* we need to see if the char at the visual position is the char wanted */ + if (EVAS_FONT_WALK_DEFAULT_POS == (size_t) position) + { + if (cx) *cx = chr_x + EVAS_FONT_WALK_DEFAULT_WIDTH; + if (cy) *cy = -asc; + if (cw) *cw = chr_w; + if (ch) *ch = asc + desc; + ret_val = 1; + goto end; + } + } + EVAS_FONT_WALK_DEFAULT_TEXT_END(); + } +end: evas_common_font_int_use_trim(); return ret_val; @@ -307,7 +393,7 @@ end: */ 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) +evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch) { int asc, desc; int position = 0; @@ -318,43 +404,17 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co EVAS_FONT_WALK_TEXT_INIT(); _INIT_FI_AND_KERNING(); -#ifdef BIDI_SUPPORT - Eina_Unicode *visual_text = NULL; - int len; - - if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)) - { - visual_text = eina_unicode_strdup(in_text); - - if (visual_text) - { - evas_bidi_reverse_string(visual_text); - text = visual_text; - } - } - if (!visual_text) - { - 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_reverse(intl_props, 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 (intl_props->dir == EVAS_BIDI_DIRECTION_RTL) + if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) { if (cpen_x) *cpen_x = 0; if (ch) *ch = asc + desc; @@ -369,27 +429,125 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co ret_val = 1; goto end; } - - EVAS_FONT_WALK_TEXT_START() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - EVAS_FONT_WALK_TEXT_WORK(EINA_TRUE); - /* 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: + 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 ((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_POS == EVAS_FONT_WALK_OT_POS_NEXT))) + { + 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; + } + item_pos = position - EVAS_FONT_WALK_OT_POS + 1; + } + else if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && + ((EVAS_FONT_WALK_OT_POS_PREV > (size_t) position) || + (EVAS_FONT_WALK_OT_POS == EVAS_FONT_WALK_OT_POS_PREV)) && + (((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; + } + item_pos = items - (position - EVAS_FONT_WALK_OT_POS); + } -#ifdef BIDI_SUPPORT - if (visual_text) free(visual_text); + if (found) + { + 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 (EVAS_FONT_WALK_OT_X_ADV > 0) + { + if (cpen_x) *cpen_x = pen_x + + (EVAS_FONT_WALK_OT_X_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); + } + } + else + { + if (cpen_x) *cpen_x = pen_x; + if (cadv) *cadv = 0; + } + ret_val = 1; + goto end; + } + } + EVAS_FONT_WALK_OT_TEXT_END(); + } + else #endif + { + EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() + { + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE); + + if ((EVAS_FONT_WALK_DEFAULT_POS == (size_t) position)) + { + 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 (EVAS_FONT_WALK_DEFAULT_X_ADV > 0) + { + if (cpen_x) *cpen_x = pen_x + + EVAS_FONT_WALK_DEFAULT_X_ADV; + if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_X_ADV; + } + else + { + if (cpen_x) *cpen_x = pen_x + + EVAS_FONT_WALK_DEFAULT_X_OFF + + EVAS_FONT_WALK_DEFAULT_X_BEAR + + EVAS_FONT_WALK_DEFAULT_WIDTH; + if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_WIDTH; + } + } + else + { + if (cpen_x) *cpen_x = pen_x; + if (cadv) *cadv = 0; + } + ret_val = 1; + goto end; + } + } + EVAS_FONT_WALK_DEFAULT_TEXT_END(); + } +end: return ret_val; } @@ -402,7 +560,7 @@ end: */ EAPI int -evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch) +evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch) { int asc, desc; const Eina_Unicode *text = in_text; @@ -416,65 +574,92 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text (void) intl_props; #endif -#ifdef BIDI_SUPPORT - Eina_Unicode *visual_text = NULL; - int len; - - if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)) - { - visual_text = eina_unicode_strdup(in_text); - - if (visual_text) - { - evas_bidi_reverse_string(visual_text); - text = visual_text; - } - } - if (!visual_text) - { - 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); - - EVAS_FONT_WALK_TEXT_START() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - int chr_x, chr_w; + EVAS_FONT_WALK_OT_TEXT_VISUAL_START() + { + EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE); + if (!visible) continue; - EVAS_FONT_WALK_TEXT_WORK(EINA_TRUE); + /* we need to see if the char at the visual position is the char, + * we check that by checking if it's before the current pen + * position and the next */ + if ((x >= pen_x) && (x <= (pen_x + EVAS_FONT_WALK_OT_X_ADV)) && + (y >= -asc) && (y <= desc)) + { + int items = 1, item_pos = 1; - chr_x = (pen_x) + bear_x; - chr_w = width; - /* we need to see if the char at the visual position is the char, - * we check that by checking if it's before the current pen position - * and the next */ - if ((x >= pen_x) && (x <= (pen_x + adv)) && - (y >= -asc) && (y <= desc)) - { - int position = char_index; - if (cx) *cx = chr_x; - if (cy) *cy = -asc; - if (cw) *cw = chr_w; - if (ch) *ch = asc + desc; -#ifdef BIDI_SUPPORT - /* 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_reverse(intl_props, len, position); -#endif - ret_val = position; - goto end; - } + 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); + } + 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 = 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 (cy) *cy = -asc; + if (cw) *cw = (EVAS_FONT_WALK_OT_X_ADV / items); + if (ch) *ch = asc + desc; + ret_val = EVAS_FONT_WALK_OT_POS + item_pos; + goto end; + } + } + EVAS_FONT_WALK_OT_TEXT_END(); + } + else +#endif + { + EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() + { + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE); + if (!visible) continue; + + /* we need to see if the char at the visual position is the char, + * we check that by checking if it's before the current pen position + * and the next */ + if ((x >= pen_x) && (x <= (pen_x + EVAS_FONT_WALK_DEFAULT_X_ADV)) + && (y >= -asc) && (y <= desc)) + { + if (cx) *cx = pen_x + EVAS_FONT_WALK_DEFAULT_X_OFF + + EVAS_FONT_WALK_DEFAULT_X_BEAR + + EVAS_FONT_WALK_DEFAULT_X_ADV; + if (cy) *cy = -asc; + if (cw) *cw = EVAS_FONT_WALK_DEFAULT_X_ADV; + if (ch) *ch = asc + desc; + ret_val = EVAS_FONT_WALK_DEFAULT_POS; + goto end; + } + } + EVAS_FONT_WALK_DEFAULT_TEXT_END(); } - EVAS_FONT_WALK_TEXT_END(); end: -#ifdef BIDI_SUPPORT - if (visual_text) free(visual_text); -#endif evas_common_font_int_use_trim(); return ret_val; @@ -488,7 +673,7 @@ end: */ EAPI int -evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_BiDi_Props *intl_props __UNUSED__, int x, int y) +evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props __UNUSED__, int x, int y) { int asc, desc; int ret=-1; @@ -500,21 +685,46 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Eina_Unicode *in_text asc = evas_common_font_max_ascent_get(fn); desc = evas_common_font_max_descent_get(fn); - EVAS_FONT_WALK_TEXT_START() - { - EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE); - if ((x >= pen_x) && (x <= (pen_x + adv)) && - (y >= -asc) && (y <= desc)) - { - ret = char_index; - goto end; - } +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) + { + EVAS_FONT_WALK_OT_TEXT_LOGICAL_START() + { + EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE); + if (!visible) continue; + + if ((x >= pen_x) && (x <= (pen_x + EVAS_FONT_WALK_OT_X_ADV)) && + (y >= -asc) && (y <= desc)) + { + ret = EVAS_FONT_WALK_OT_POS; + goto end; + } + } + EVAS_FONT_WALK_OT_TEXT_END(); + } + else +#endif + { + EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START() + { + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE); + if (!visible) continue; + + if ((x >= pen_x) && + (x <= (pen_x + EVAS_FONT_WALK_DEFAULT_X_ADV)) && + (y >= -asc) && (y <= desc)) + { + ret = char_index; + goto end; + } + } + EVAS_FONT_WALK_DEFAULT_TEXT_END(); } - EVAS_FONT_WALK_TEXT_END(); end: evas_common_font_int_use_trim(); return ret; } + diff --git a/legacy/evas/src/lib/engines/common/evas_pipe.c b/legacy/evas/src/lib/engines/common/evas_pipe.c index fbe546b5c0..a2322f4f1c 100644 --- a/legacy/evas/src/lib/engines/common/evas_pipe.c +++ b/legacy/evas/src/lib/engines/common/evas_pipe.c @@ -1177,9 +1177,7 @@ evas_common_pipe_op_text_free(RGBA_Pipe_Op *op) #else evas_common_font_free(op->op.text.font); #endif -#ifdef BIDI_SUPPORT - evas_bidi_props_clean(&(op->op.text.intl_props)); -#endif + evas_common_text_props_content_unref(&(op->op.text.intl_props)); free(op->op.text.text); evas_common_pipe_op_free(op); } @@ -1230,7 +1228,7 @@ evas_common_pipe_text_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Threa EAPI void evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, - RGBA_Font *fn, int x, int y, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props) + RGBA_Font *fn, int x, int y, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { RGBA_Pipe_Op *op; @@ -1240,9 +1238,8 @@ evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, op->op.text.x = x; op->op.text.y = y; op->op.text.text = eina_unicode_strdup(text); -#ifdef BIDI_SUPPORT - evas_bidi_props_copy_and_ref(intl_props, &(op->op.text.intl_props)); -#endif + evas_common_text_props_content_copy_and_ref(intl_props, + &(op->op.text.intl_props)); #ifdef EVAS_FRAME_QUEUING LKL(fn->ref_fq_add); fn->ref_fq[0]++; diff --git a/legacy/evas/src/lib/engines/common/evas_pipe.h b/legacy/evas/src/lib/engines/common/evas_pipe.h index 5ee8eeda82..73213b6114 100644 --- a/legacy/evas/src/lib/engines/common/evas_pipe.h +++ b/legacy/evas/src/lib/engines/common/evas_pipe.h @@ -92,7 +92,7 @@ EAPI void evas_common_pipe_free(RGBA_Image *im); EAPI void evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h); EAPI void evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1); EAPI void evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points, int x, int y); -EAPI void evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props); +EAPI void evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text, const Evas_Text_Props *intl_props); EAPI void evas_common_pipe_image_load(RGBA_Image *im); EAPI void evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int smooth, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h); EAPI void evas_common_pipe_map4_begin(RGBA_Image *root); diff --git a/legacy/evas/src/lib/engines/common/evas_text_utils.c b/legacy/evas/src/lib/engines/common/evas_text_utils.c new file mode 100644 index 0000000000..e5fd81c6a0 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_text_utils.c @@ -0,0 +1,59 @@ +#include "evas_text_utils.h" +#include "language/evas_bidi_utils.h" +#include "language/evas_language_utils.h" +#include "evas_font_ot.h" + +void +evas_common_text_props_bidi_set(Evas_Text_Props *props, + Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start) +{ +#ifdef BIDI_SUPPORT + props->bidi.dir = (evas_bidi_is_rtl_char( + bidi_par_props, + 0, + start)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR; +#else + (void) start; + (void) bidi_par_props; + props->bidi.dir = EVAS_BIDI_DIRECTION_LTR; +#endif +} + +void +evas_common_text_props_script_set(Evas_Text_Props *props, + const Eina_Unicode *str) +{ + props->script = evas_common_language_script_type_get(str); +} + +void +evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst, + const Evas_Text_Props *src) +{ + memcpy(dst, src, sizeof(Evas_Text_Props)); +#ifdef OT_SUPPORT + if (dst->ot_data) + { + evas_common_font_ot_props_ref(dst->ot_data); + } +#endif +} + +void +evas_common_text_props_content_unref(Evas_Text_Props *props) +{ +#ifdef OT_SUPPORT + if (props->ot_data) + { + evas_common_font_ot_props_unref(props->ot_data); + } +#else + (void) props; +#endif +#ifdef BIDI_SUPPORT + evas_bidi_props_clean(&props->bidi); +#else + (void) props; +#endif +} + diff --git a/legacy/evas/src/lib/engines/common/evas_text_utils.h b/legacy/evas/src/lib/engines/common/evas_text_utils.h new file mode 100644 index 0000000000..ccc4d20ceb --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_text_utils.h @@ -0,0 +1,32 @@ +#ifndef _EVAS_TEXT_UTILS_H +# define _EVAS_TEXT_UTILS_H + +typedef struct _Evas_Text_Props Evas_Text_Props; + +# include "evas_font_ot.h" +# include "language/evas_bidi_utils.h" +# include "language/evas_language_utils.h" + +struct _Evas_Text_Props +{ + Evas_BiDi_Props bidi; + Evas_Script_Type script; + Evas_Font_OT_Data *ot_data; +}; + +void +evas_common_text_props_bidi_set(Evas_Text_Props *props, + Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start); + +void +evas_common_text_props_script_set(Evas_Text_Props *props, + const Eina_Unicode *str); + +void +evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst, + const Evas_Text_Props *src); + +void +evas_common_text_props_content_unref(Evas_Text_Props *props); + +#endif diff --git a/legacy/evas/src/lib/engines/common/language/evas_bidi_utils.h b/legacy/evas/src/lib/engines/common/language/evas_bidi_utils.h index 37266c6bc8..aa9ee91a2a 100644 --- a/legacy/evas/src/lib/engines/common/language/evas_bidi_utils.h +++ b/legacy/evas/src/lib/engines/common/language/evas_bidi_utils.h @@ -74,8 +74,9 @@ struct _Evas_BiDi_Paragraph_Props { #endif }; -#include "evas_common.h" -struct _Evas_BiDi_Props { +#include "Evas.h" +struct _Evas_BiDi_Props +{ Evas_BiDi_Direction dir; }; diff --git a/legacy/evas/src/lib/engines/common/language/evas_language_utils.c b/legacy/evas/src/lib/engines/common/language/evas_language_utils.c new file mode 100644 index 0000000000..bd9732b8d9 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/language/evas_language_utils.c @@ -0,0 +1,146 @@ +/** + * @internal + * @addtogroup Evas_Utils + * + * @{ + */ +/** + * @internal + * @defgroup Evas_Script Evas Script (language) utility functions + * + * This set of functions and types helps evas handle scripts correctly. + * @todo Document types, structures and macros. + * + * @{ + */ +#include + +#include "evas_language_utils.h" +#include "evas_bidi_utils.h" /* Used for fallback. */ +#include "../evas_font_ot.h" /* Used for harfbuzz info */ + +#ifdef USE_HARFBUZZ +# include +# ifdef HAVE_HARFBUZZ_GLIB +# include +# endif +#endif + +/* FIXME: rename and move */ +void * +evas_common_language_unicode_funcs_get(void) +{ +#if defined(USE_HARFBUZZ) && defined(HAVE_HARFBUZZ_GLIB) + return hb_glib_get_unicode_funcs(); +#endif + return NULL; +} + +static Evas_Script_Type +_get_script(Eina_Unicode unicode) +{ +#ifdef USE_HARFBUZZ + static hb_unicode_funcs_t *funcs; + if (!funcs) + funcs = evas_common_language_unicode_funcs_get(); + return hb_unicode_get_script(funcs, unicode); +#else + (void) unicode; +#endif + return EVAS_SCRIPT_COMMON; +} + +int +evas_common_language_script_end_of_run_get(const Eina_Unicode *str, + const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, int len) +{ + /* FIXME: Use the standard segmentation instead */ + if (evas_common_font_ot_is_enabled()) + { + Evas_Script_Type first = EVAS_SCRIPT_UNKNOWN; + int i; + for (i = 0 ; (i < len) ; i++, str++) + { + Evas_Script_Type tmp; + tmp = _get_script(*str); + /* Arabic is the first script in the array that's not + * common/inherited. */ + if ((first == EVAS_SCRIPT_UNKNOWN) && (tmp >= EVAS_SCRIPT_ARABIC)) + { + first = tmp; + continue; + } + if ((first != tmp) && (tmp >= EVAS_SCRIPT_ARABIC)) + { + break; + } + } +#ifdef BIDI_SUPPORT + { + int bidi_end; + bidi_end = evas_bidi_end_of_run_get(bidi_props, start, len); + if (bidi_end > 0) + { + i = (i < bidi_end) ? i : bidi_end; + } + } +#else + (void) bidi_props; + (void) start; +#endif + return (i < len) ? i : 0; + } + else + { +#ifdef BIDI_SUPPORT + return evas_bidi_end_of_run_get(bidi_props, start, len); +#endif + } + return 0; +} + +Evas_Script_Type +evas_common_language_script_type_get(const Eina_Unicode *str) +{ + Evas_Script_Type script = EVAS_SCRIPT_COMMON; + /* Arabic is the first script in the array that's not a common/inherited */ + for ( ; *str && ((script = _get_script(*str)) < EVAS_SCRIPT_ARABIC) ; str++) + ; + return script; +} + +const char * +evas_common_language_from_locale_get(void) +{ + static char lang[6]; /* FIXME: Maximum length I know about */ + if (*lang) return lang; + + const char *locale; + locale = getenv("LANG"); + if (locale && *locale) + { + char *itr; + strncpy(lang, locale, 5); + lang[5] = '\0'; + itr = lang; + while (*itr) + { + if (*itr == '_') + { + *itr = '\0'; + } + itr++; + } + return lang; + } + + return ""; +} + +/* + * @} + */ +/* + * @} + */ + diff --git a/legacy/evas/src/lib/engines/common/language/evas_language_utils.h b/legacy/evas/src/lib/engines/common/language/evas_language_utils.h new file mode 100644 index 0000000000..e4958c6b02 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/language/evas_language_utils.h @@ -0,0 +1,128 @@ +#ifndef _EVAS_LANGUAGE_UTILS +#define _EVAS_LANGUAGE_UTILS + +#include +#include "evas_bidi_utils.h" + +/* Unicode Script property - conforming to HARFBUZZ's */ +typedef enum +{ + EVAS_SCRIPT_INVALID_CODE = -1, + EVAS_SCRIPT_COMMON = 0, /* Zyyy */ + EVAS_SCRIPT_INHERITED, /* Qaai */ + EVAS_SCRIPT_ARABIC, /* Arab */ + EVAS_SCRIPT_ARMENIAN, /* Armn */ + EVAS_SCRIPT_BENGALI, /* Beng */ + EVAS_SCRIPT_BOPOMOFO, /* Bopo */ + EVAS_SCRIPT_CHEROKEE, /* Cher */ + EVAS_SCRIPT_COPTIC, /* Qaac */ + EVAS_SCRIPT_CYRILLIC, /* Cyrl (Cyrs) */ + EVAS_SCRIPT_DESERET, /* Dsrt */ + EVAS_SCRIPT_DEVANAGARI, /* Deva */ + EVAS_SCRIPT_ETHIOPIC, /* Ethi */ + EVAS_SCRIPT_GEORGIAN, /* Geor (Geon, Geoa) */ + EVAS_SCRIPT_GOTHIC, /* Goth */ + EVAS_SCRIPT_GREEK, /* Grek */ + EVAS_SCRIPT_GUJARATI, /* Gujr */ + EVAS_SCRIPT_GURMUKHI, /* Guru */ + EVAS_SCRIPT_HAN, /* Hani */ + EVAS_SCRIPT_HANGUL, /* Hang */ + EVAS_SCRIPT_HEBREW, /* Hebr */ + EVAS_SCRIPT_HIRAGANA, /* Hira */ + EVAS_SCRIPT_KANNADA, /* Knda */ + EVAS_SCRIPT_KATAKANA, /* Kana */ + EVAS_SCRIPT_KHMER, /* Khmr */ + EVAS_SCRIPT_LAO, /* Laoo */ + EVAS_SCRIPT_LATIN, /* Latn (Latf, Latg) */ + EVAS_SCRIPT_MALAYALAM, /* Mlym */ + EVAS_SCRIPT_MONGOLIAN, /* Mong */ + EVAS_SCRIPT_MYANMAR, /* Mymr */ + EVAS_SCRIPT_OGHAM, /* Ogam */ + EVAS_SCRIPT_OLD_ITALIC, /* Ital */ + EVAS_SCRIPT_ORIYA, /* Orya */ + EVAS_SCRIPT_RUNIC, /* Runr */ + EVAS_SCRIPT_SINHALA, /* Sinh */ + EVAS_SCRIPT_SYRIAC, /* Syrc (Syrj, Syrn, Syre) */ + EVAS_SCRIPT_TAMIL, /* Taml */ + EVAS_SCRIPT_TELUGU, /* Telu */ + EVAS_SCRIPT_THAANA, /* Thaa */ + EVAS_SCRIPT_THAI, /* Thai */ + EVAS_SCRIPT_TIBETAN, /* Tibt */ + EVAS_SCRIPT_CANADIAN_ABORIGINAL, /* Cans */ + EVAS_SCRIPT_YI, /* Yiii */ + EVAS_SCRIPT_TAGALOG, /* Tglg */ + EVAS_SCRIPT_HANUNOO, /* Hano */ + EVAS_SCRIPT_BUHID, /* Buhd */ + EVAS_SCRIPT_TAGBANWA, /* Tagb */ + + /* Unicode-4.0 additions */ + EVAS_SCRIPT_BRAILLE, /* Brai */ + EVAS_SCRIPT_CYPRIOT, /* Cprt */ + EVAS_SCRIPT_LIMBU, /* Limb */ + EVAS_SCRIPT_OSMANYA, /* Osma */ + EVAS_SCRIPT_SHAVIAN, /* Shaw */ + EVAS_SCRIPT_LINEAR_B, /* Linb */ + EVAS_SCRIPT_TAI_LE, /* Tale */ + EVAS_SCRIPT_UGARITIC, /* Ugar */ + + /* Unicode-4.1 additions */ + EVAS_SCRIPT_NEW_TAI_LUE, /* Talu */ + EVAS_SCRIPT_BUGINESE, /* Bugi */ + EVAS_SCRIPT_GLAGOLITIC, /* Glag */ + EVAS_SCRIPT_TIFINAGH, /* Tfng */ + EVAS_SCRIPT_SYLOTI_NAGRI, /* Sylo */ + EVAS_SCRIPT_OLD_PERSIAN, /* Xpeo */ + EVAS_SCRIPT_KHAROSHTHI, /* Khar */ + + /* Unicode-5.0 additions */ + EVAS_SCRIPT_UNKNOWN, /* Zzzz */ + EVAS_SCRIPT_BALINESE, /* Bali */ + EVAS_SCRIPT_CUNEIFORM, /* Xsux */ + EVAS_SCRIPT_PHOENICIAN, /* Phnx */ + EVAS_SCRIPT_PHAGS_PA, /* Phag */ + EVAS_SCRIPT_NKO, /* Nkoo */ + + /* Unicode-5.1 additions */ + EVAS_SCRIPT_KAYAH_LI, /* Kali */ + EVAS_SCRIPT_LEPCHA, /* Lepc */ + EVAS_SCRIPT_REJANG, /* Rjng */ + EVAS_SCRIPT_SUNDANESE, /* Sund */ + EVAS_SCRIPT_SAURASHTRA, /* Saur */ + EVAS_SCRIPT_CHAM, /* Cham */ + EVAS_SCRIPT_OL_CHIKI, /* Olck */ + EVAS_SCRIPT_VAI, /* Vaii */ + EVAS_SCRIPT_CARIAN, /* Cari */ + EVAS_SCRIPT_LYCIAN, /* Lyci */ + EVAS_SCRIPT_LYDIAN, /* Lydi */ + + /* Unicode-5.2 additions */ + EVAS_SCRIPT_AVESTAN, /* Avst */ + EVAS_SCRIPT_BAMUM, /* Bamu */ + EVAS_SCRIPT_EGYPTIAN_HIEROGLYPHS, /* Egyp */ + EVAS_SCRIPT_IMPERIAL_ARAMAIC, /* Armi */ + EVAS_SCRIPT_INSCRIPTIONAL_PAHLAVI, /* Phli */ + EVAS_SCRIPT_INSCRIPTIONAL_PARTHIAN, /* Prti */ + EVAS_SCRIPT_JAVANESE, /* Java */ + EVAS_SCRIPT_KAITHI, /* Kthi */ + EVAS_SCRIPT_LISU, /* Lisu */ + EVAS_SCRIPT_MEITEI_MAYEK, /* Mtei */ + EVAS_SCRIPT_OLD_SOUTH_ARABIAN, /* Sarb */ + EVAS_SCRIPT_OLD_TURKIC, /* Orkh */ + EVAS_SCRIPT_SAMARITAN, /* Samr */ + EVAS_SCRIPT_TAI_THAM, /* Lana */ + EVAS_SCRIPT_TAI_VIET /* Tavt */ +} Evas_Script_Type; + +int +evas_common_language_script_end_of_run_get(const Eina_Unicode *str, const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, int len); + +Evas_Script_Type +evas_common_language_script_type_get(const Eina_Unicode *str); + +const char * +evas_common_language_from_locale_get(void); + +void * +evas_common_language_unicode_funcs_get(void); +#endif + diff --git a/legacy/evas/src/lib/engines/common/language/evas_script_utils.c b/legacy/evas/src/lib/engines/common/language/evas_script_utils.c deleted file mode 100644 index 7b932d15f7..0000000000 --- a/legacy/evas/src/lib/engines/common/language/evas_script_utils.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @internal - * @addtogroup Evas_Utils - * - * @{ - */ -/** - * @internal - * @defgroup Evas_Script Evas Script (language) utility functions - * - * This set of functions and types helps evas handle scripts correctly. - * @todo Document types, structures and macros. - * - * @{ - */ -#include - -#include "evas_script_utils.h" -#include "evas_bidi_utils.h" /* Used for fallback. */ -int -evas_common_script_end_of_run_get(const Eina_Unicode *str, - const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, int len) -{ - /* FIXME: Currently we fall back to bidi runs, should fix */ - (void) str; -#ifdef BIDI_SUPPORT - return evas_bidi_end_of_run_get(bidi_props, start, len); -#else - (void) bidi_props; - (void) start; - (void) len; - return 0; -#endif -} - -/* - * @} - */ -/* - * @} - */ - diff --git a/legacy/evas/src/lib/engines/common/language/evas_script_utils.h b/legacy/evas/src/lib/engines/common/language/evas_script_utils.h deleted file mode 100644 index 4ee70bf3e2..0000000000 --- a/legacy/evas/src/lib/engines/common/language/evas_script_utils.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _EVAS_SCRIPT_UTILS -#define _EVAS_SCRIPT_UTILS - -#include -#include "evas_bidi_utils.h" - -int -evas_common_script_end_of_run_get(const Eina_Unicode *str, const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, int len); - -#endif - diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index fa15f5a98a..4cefba91a3 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -688,7 +688,7 @@ struct _RGBA_Draw_Context #ifdef BUILD_PIPE_RENDER #include "../engines/common/evas_map_image.h" -#include "../engines/common/language/evas_bidi_utils.h" +#include "../engines/common/evas_text_utils.h" struct _RGBA_Pipe_Op { @@ -710,7 +710,7 @@ struct _RGBA_Pipe_Op RGBA_Font *font; int x, y; Eina_Unicode *text; - Evas_BiDi_Props intl_props; + Evas_Text_Props intl_props; } text; struct { RGBA_Image *src; diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index c81ca8fa50..d90d280c6c 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -11,8 +11,9 @@ #include "../file/evas_module.h" #include "../file/evas_path.h" +#include "../engines/common/evas_text_utils.h" #include "../engines/common/language/evas_bidi_utils.h" -#include "../engines/common/language/evas_script_utils.h" +#include "../engines/common/language/evas_language_utils.h" #ifdef EVAS_MAGIC_DEBUG /* complain when peole pass in wrong object types etc. */ @@ -640,13 +641,13 @@ struct _Evas_Func int (*font_descent_get) (void *data, void *font); int (*font_max_ascent_get) (void *data, void *font); int (*font_max_descent_get) (void *data, void *font); - void (*font_string_size_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h); + void (*font_string_size_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *w, int *h); int (*font_inset_get) (void *data, void *font, const Eina_Unicode *text); - int (*font_h_advance_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props); - int (*font_v_advance_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props); - int (*font_char_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch); - int (*font_char_at_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch); - void (*font_draw) (void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props); + int (*font_h_advance_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props); + int (*font_v_advance_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props); + int (*font_char_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch); + int (*font_char_at_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch); + void (*font_draw) (void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const Eina_Unicode *text, const Evas_Text_Props *intl_props); void (*font_cache_flush) (void *data); void (*font_cache_set) (void *data, int bytes); @@ -661,7 +662,7 @@ struct _Evas_Func 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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y); + int (*font_last_up_to_pos) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y); void (*image_map4_draw) (void *data, void *context, void *surface, void *image, RGBA_Map_Point *p, int smooth, int level); void *(*image_map_surface_new) (void *data, int w, int h, int alpha); @@ -669,7 +670,8 @@ 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); + int (*font_pen_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch); + Eina_Bool (*font_shape) (void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len); }; struct _Evas_Image_Load_Func diff --git a/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c b/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c index 8cccee3057..13ec8ff2e4 100644 --- a/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c @@ -94,6 +94,7 @@ 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 Eina_Bool eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len); 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); @@ -217,7 +218,8 @@ static Evas_Func eng_func = 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 + eng_font_pen_coords_get, + eng_font_shape /* FUTURE software generic calls go here */ }; @@ -1287,6 +1289,17 @@ eng_font_pen_coords_get(void *data, void *font, char *text, int pos, int *cpen_x return 0; } + +static Eina_Bool +eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len) +{ + Render_Engine *re; + + /* FIXME, use cairo font subsystem */ + re = (Render_Engine *)data; + return EINA_TRUE; +} + 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) { diff --git a/legacy/evas/src/modules/engines/direct3d/evas_engine.c b/legacy/evas/src/modules/engines/direct3d/evas_engine.c index be5938bef3..561a8ee2d7 100644 --- a/legacy/evas/src/modules/engines/direct3d/evas_engine.c +++ b/legacy/evas/src/modules/engines/direct3d/evas_engine.c @@ -388,7 +388,7 @@ eng_image_scale_hint_get(void *data __UNUSED__, void *image) } 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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { Render_Engine *re = (Render_Engine *)data; RGBA_Image im; diff --git a/legacy/evas/src/modules/engines/directfb/evas_engine.c b/legacy/evas/src/modules/engines/directfb/evas_engine.c index cecc69c4be..f2517e2c8d 100644 --- a/legacy/evas/src/modules/engines/directfb/evas_engine.c +++ b/legacy/evas/src/modules/engines/directfb/evas_engine.c @@ -1037,7 +1037,7 @@ evas_engine_dfb_output_idle_flush(void *data) * memory. */ static void -evas_engine_dfb_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +evas_engine_dfb_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { DirectFB_Engine_Image_Entry *eim = surface; IDirectFBSurface *screen; diff --git a/legacy/evas/src/modules/engines/gl_glew/evas_engine.c b/legacy/evas/src/modules/engines/gl_glew/evas_engine.c index 5f4081231f..4ece31dd23 100644 --- a/legacy/evas/src/modules/engines/gl_glew/evas_engine.c +++ b/legacy/evas/src/modules/engines/gl_glew/evas_engine.c @@ -748,7 +748,7 @@ eng_image_map_surface_free(void *data __UNUSED__, void *surface) } 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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { Render_Engine *re; diff --git a/legacy/evas/src/modules/engines/gl_sdl/evas_engine.c b/legacy/evas/src/modules/engines/gl_sdl/evas_engine.c index ec8edbf0ce..cfc460abb0 100644 --- a/legacy/evas/src/modules/engines/gl_sdl/evas_engine.c +++ b/legacy/evas/src/modules/engines/gl_sdl/evas_engine.c @@ -817,7 +817,7 @@ eng_image_scale_hint_get(void *data __UNUSED__, void *image) } static void -eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { Render_Engine *re; diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c index d80a6ad072..ccf3f9add9 100644 --- a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c @@ -1827,7 +1827,7 @@ eng_image_stride_get(void *data __UNUSED__, void *image, int *stride) } static void -eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { Render_Engine *re; diff --git a/legacy/evas/src/modules/engines/quartz/evas_engine.c b/legacy/evas/src/modules/engines/quartz/evas_engine.c index 743a39fbd8..0a14e7006b 100644 --- a/legacy/evas/src/modules/engines/quartz/evas_engine.c +++ b/legacy/evas/src/modules/engines/quartz/evas_engine.c @@ -1026,7 +1026,7 @@ eng_font_max_descent_get(void *data, void *font) } static void -eng_font_string_size_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int *w, int *h) +eng_font_string_size_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int *w, int *h) { Render_Engine *re = (Render_Engine *)data; Evas_Quartz_Font *loaded_font = (Evas_Quartz_Font *)font; @@ -1056,7 +1056,7 @@ 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) +eng_font_h_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props) { int w; @@ -1067,7 +1067,7 @@ eng_font_h_advance_get(void *data, void *font, const char *text, const Evas_BiDi } static int -eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props) +eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props) { int h; @@ -1077,7 +1077,7 @@ eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_BiDi } 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) +eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch) { Evas_Quartz_Font *loaded_font = (Evas_Quartz_Font *)font; @@ -1099,14 +1099,23 @@ eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_Bi /*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) +eng_font_pen_coords_get(void *data, void *font, const char *text, const Evas_Text_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 Eina_Bool +eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props __UNUSED__, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len) +{ +#ifdef BIDI_SUPPORT + return !evas_bidi_shape_string(text, par_props, pos, len); +#endif + return EINA_TRUE; +} + 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) +eng_font_char_at_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch) { // Return the index of the character at the given point, also lookup it's origin x, y, w, and h. Evas_Quartz_Font *loaded_font = (Evas_Quartz_Font *)font; @@ -1145,7 +1154,7 @@ eng_font_hinting_can_hint(void *data, int hinting) } 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) +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_Text_Props *intl_props) { Render_Engine *re = (Render_Engine *)data; Evas_Quartz_Context *ctxt = (Evas_Quartz_Context *)context; diff --git a/legacy/evas/src/modules/engines/quartz/evas_quartz_private.h b/legacy/evas/src/modules/engines/quartz/evas_quartz_private.h index cb4bf46cf8..f4997edb84 100644 --- a/legacy/evas/src/modules/engines/quartz/evas_quartz_private.h +++ b/legacy/evas/src/modules/engines/quartz/evas_quartz_private.h @@ -75,14 +75,15 @@ static int eng_font_ascent_get(void *data, void *font); static int eng_font_descent_get(void *data, void *font); static int eng_font_max_ascent_get(void *data, void *font); static int eng_font_max_descent_get(void *data, void *font); -static void eng_font_string_size_get(void *data, void *font, const char *text, const Evas_BiDi_Props *intl_props, int *w, int *h); +static void eng_font_string_size_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int *w, int *h); 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 int eng_font_h_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props); +static int eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props); +static int eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_Text_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_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch); +static Eina_Bool eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len); +static int eng_font_char_at_coords_get(void *data, void *font, const char *text, const Evas_Text_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_Text_Props *intl_props); static void eng_font_hinting_set(void *data, void *font, int hinting); static int eng_font_hinting_can_hint(void *data, int hinting); diff --git a/legacy/evas/src/modules/engines/software_16/evas_engine.c b/legacy/evas/src/modules/engines/software_16/evas_engine.c index c31c4ca546..999198d661 100644 --- a/legacy/evas/src/modules/engines/software_16/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_16/evas_engine.c @@ -505,7 +505,7 @@ eng_font_max_descent_get(void *data __UNUSED__, void *font) } static void -eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h) +eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *w, int *h) { evas_common_font_query_size(font, text, intl_props, w, h); } @@ -517,7 +517,7 @@ eng_font_inset_get(void *data __UNUSED__, void *font, const Eina_Unicode *text) } static int -eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { int h, v; @@ -526,7 +526,7 @@ eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *te } static int -eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { int h, v; @@ -535,31 +535,50 @@ 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) +eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_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 Eina_Bool +eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len) +{ +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled()) + { + return evas_common_font_ot_populate_text_props(font, text, + intl_props, len); + } + else +#endif + { +#ifdef BIDI_SUPPORT + return !evas_bidi_shape_string(text, par_props, pos, len); +#endif + } + return EINA_TRUE; +} + 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) +eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_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); } static int -eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch) +eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch) { return evas_common_font_query_char_at_coords(font, text, intl_props, x, y, cx, cy, cw, ch); } static int -eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y) +eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y) { return evas_common_font_query_last_up_to_pos(font, text, intl_props, 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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +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 Eina_Unicode *text, const Evas_Text_Props *intl_props) { static RGBA_Image *im = NULL; Soft16_Image *dst = surface; @@ -730,7 +749,8 @@ static Evas_Func func = 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 + eng_font_pen_coords_get, + eng_font_shape /* FUTURE software generic calls go here */ }; diff --git a/legacy/evas/src/modules/engines/software_16_sdl/evas_engine.c b/legacy/evas/src/modules/engines/software_16_sdl/evas_engine.c index 31661073b7..a47757507b 100644 --- a/legacy/evas/src/modules/engines/software_16_sdl/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_16_sdl/evas_engine.c @@ -873,7 +873,7 @@ evas_engine_sdl16_image_format_get(void *data __UNUSED__, void *image __UNUSED__ } static void -evas_engine_sdl16_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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +evas_engine_sdl16_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 Eina_Unicode *text, const Evas_Text_Props *intl_props) { static RGBA_Image *im = NULL; SDL_Engine_Image_Entry *eim = surface; diff --git a/legacy/evas/src/modules/engines/software_8/evas_engine.c b/legacy/evas/src/modules/engines/software_8/evas_engine.c index a02c89dab9..e6d6db2a64 100644 --- a/legacy/evas/src/modules/engines/software_8/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_8/evas_engine.c @@ -561,7 +561,7 @@ eng_font_max_descent_get(void *data __UNUSED__, void *font) } static void -eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, +eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *w, int *h) { evas_common_font_query_size(font, text, intl_props, w, h); @@ -574,7 +574,7 @@ eng_font_inset_get(void *data __UNUSED__, void *font, const Eina_Unicode *text) } static int -eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { int h, v; @@ -583,7 +583,7 @@ eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *te } static int -eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { int h, v; @@ -592,28 +592,47 @@ 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, +eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_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 Eina_Bool +eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len) +{ +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled()) + { + return evas_common_font_ot_populate_text_props(font, text, + intl_props, len); + } + else +#endif + { +#ifdef BIDI_SUPPORT + return !evas_bidi_shape_string(text, par_props, pos, len); +#endif + } + return EINA_TRUE; +} + static int -eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, +eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_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); } static int -eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, +eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch) { return evas_common_font_query_char_at_coords(font, text, intl_props, x, y, cx, cy, cw, ch); } static int -eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, +eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y) { return evas_common_font_query_last_up_to_pos(font, text, intl_props, x, y); @@ -621,7 +640,7 @@ eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *t 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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props) + int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { evas_common_font_draw(surface, context, font, x, y, text, intl_props); evas_common_draw_context_font_ext_set(context, NULL, NULL, NULL, NULL); @@ -776,7 +795,8 @@ static Evas_Func func = { 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 + eng_font_pen_coords_get, + eng_font_shape /* FUTURE software generic calls go here */ }; diff --git a/legacy/evas/src/modules/engines/software_generic/evas_engine.c b/legacy/evas/src/modules/engines/software_generic/evas_engine.c index d79c4dc504..fe87137728 100644 --- a/legacy/evas/src/modules/engines/software_generic/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_generic/evas_engine.c @@ -675,7 +675,7 @@ eng_font_max_descent_get(void *data __UNUSED__, void *font) } static void -eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int *w, int *h) +eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *w, int *h) { evas_common_font_query_size(font, text, intl_props, w, h); } @@ -687,7 +687,7 @@ eng_font_inset_get(void *data __UNUSED__, void *font, const Eina_Unicode *text) } static int -eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { int h, v; @@ -696,7 +696,7 @@ eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *te } static int -eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { int h, v; @@ -705,31 +705,56 @@ 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) +eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_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 Eina_Bool +eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len) +{ + (void) font; + (void) text; + (void) intl_props; + (void) par_props; + (void) pos; + (void) len; +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled()) + { + return evas_common_font_ot_populate_text_props(font, text, + intl_props, len); + } + else +#endif + { +#ifdef BIDI_SUPPORT + return !evas_bidi_shape_string(text, par_props, pos, len); +#endif + } + return EINA_TRUE; +} + 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) +eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_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); } static int -eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch) +eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch) { return evas_common_font_query_char_at_coords(font, text, intl_props, x, y, cx, cy, cw, ch); } static int -eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props, int x, int y) +eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y) { return evas_common_font_query_last_up_to_pos(font, text, intl_props, 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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +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 Eina_Unicode *text, const Evas_Text_Props *intl_props) { #ifdef BUILD_PIPE_RENDER if ((cpunum > 1) @@ -897,7 +922,8 @@ static Evas_Func func = 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 - eng_font_pen_coords_get + eng_font_pen_coords_get, + eng_font_shape /* FUTURE software generic calls go here */ }; diff --git a/legacy/evas/src/modules/engines/software_sdl/evas_engine.c b/legacy/evas/src/modules/engines/software_sdl/evas_engine.c index d7d9e22954..914599949c 100644 --- a/legacy/evas/src/modules/engines/software_sdl/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_sdl/evas_engine.c @@ -738,7 +738,7 @@ evas_engine_sdl_image_format_get(void *data __UNUSED__, void *image __UNUSED__) } static void -evas_engine_sdl_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 Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +evas_engine_sdl_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 Eina_Unicode *text, const Evas_Text_Props *intl_props) { SDL_Engine_Image_Entry *eim = surface; int mustlock_im = 0; diff --git a/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c b/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c index b16ebddffb..ce84c43e20 100644 --- a/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c @@ -1172,7 +1172,7 @@ eng_image_cache_get(void *data) } static void -eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_BiDi_Props *intl_props) +eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *intl_props) { Render_Engine *re; RGBA_Image *im;