Evas: Multiple changes that all relate to the Harfbuzz integration:
authortasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 30 Jan 2011 10:36:39 +0000 (10:36 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 30 Jan 2011 10:36:39 +0000 (10:36 +0000)
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.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@56455 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

37 files changed:
src/lib/canvas/evas_object_text.c
src/lib/canvas/evas_object_textblock.c
src/lib/engines/common/Makefile.am
src/lib/engines/common/evas_font.h
src/lib/engines/common/evas_font_default_walk.x [new file with mode: 0644]
src/lib/engines/common/evas_font_draw.c
src/lib/engines/common/evas_font_main.c
src/lib/engines/common/evas_font_ot.c [new file with mode: 0644]
src/lib/engines/common/evas_font_ot.h [new file with mode: 0644]
src/lib/engines/common/evas_font_ot_walk.x [new file with mode: 0644]
src/lib/engines/common/evas_font_private.h
src/lib/engines/common/evas_font_query.c
src/lib/engines/common/evas_pipe.c
src/lib/engines/common/evas_pipe.h
src/lib/engines/common/evas_text_utils.c [new file with mode: 0644]
src/lib/engines/common/evas_text_utils.h [new file with mode: 0644]
src/lib/engines/common/language/evas_bidi_utils.h
src/lib/engines/common/language/evas_language_utils.c [new file with mode: 0644]
src/lib/engines/common/language/evas_language_utils.h [new file with mode: 0644]
src/lib/engines/common/language/evas_script_utils.c [deleted file]
src/lib/engines/common/language/evas_script_utils.h [deleted file]
src/lib/include/evas_common.h
src/lib/include/evas_private.h
src/modules/engines/cairo_x11/evas_engine.c
src/modules/engines/direct3d/evas_engine.c
src/modules/engines/directfb/evas_engine.c
src/modules/engines/gl_glew/evas_engine.c
src/modules/engines/gl_sdl/evas_engine.c
src/modules/engines/gl_x11/evas_engine.c
src/modules/engines/quartz/evas_engine.c
src/modules/engines/quartz/evas_quartz_private.h
src/modules/engines/software_16/evas_engine.c
src/modules/engines/software_16_sdl/evas_engine.c
src/modules/engines/software_8/evas_engine.c
src/modules/engines/software_generic/evas_engine.c
src/modules/engines/software_sdl/evas_engine.c
src/modules/engines/xrender_x11/evas_engine.c

index 0dccb75..4f16ab8 100644 (file)
@@ -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 */
index f4f4e94..09dcbe4 100644 (file)
@@ -318,7 +318,7 @@ struct _Evas_Object_Textblock_Item
    size_t                               visual_pos;
 #endif
    Evas_Coord                           adv, x, w, h;
-   Evas_BiDi_Props                      bidi_props;
+   Evas_Text_Props                      text_props;
 };
 
 struct _Evas_Object_Textblock_Text_Item
@@ -632,6 +632,38 @@ _format_unref_free(const Evas_Object *obj, Evas_Object_Textblock_Format *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.
  * @param obj The evas object, must not be NULL.
  * @param ln the layout line to be freed, must not be NULL.
@@ -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
index fe58d88..c3f9dd8 100644 (file)
@@ -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
index b96f437..bf5a570 100644 (file)
@@ -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/src/lib/engines/common/evas_font_default_walk.x b/src/lib/engines/common/evas_font_default_walk.x
new file mode 100644 (file)
index 0000000..b06315c
--- /dev/null
@@ -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
index e1135fb..52275c6 100644 (file)
@@ -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,301 @@ 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;
+        EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
+          {
+             int chr_x, chr_y, chr_w;
 
-        if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl))
-             continue;
+             if (EVAS_FONT_CHARACTER_IS_INVISIBLE(gl))
+               continue;
 
-        EVAS_FONT_WALK_TEXT_WORK(EINA_TRUE);
+             EVAS_FONT_WALK_OT_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;
-          }
+             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) + bear_x;
-       chr_y = (pen_y) + bear_y;
-        chr_w = width;
+             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 (chr_x < (ext_x + ext_w))
                {
-                  if ((j > 0) && (chr_x + w > ext_x))
+                  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 ((fg->ext_dat) && (dc->font_ext.func.gl_draw))
+                       if ((j > 0) && (chr_x + w > ext_x))
                          {
-                            /* 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))
+                            if ((fg->ext_dat) && (dc->font_ext.func.gl_draw))
                               {
-                                 for (i = 0; i < h; i++)
+                                 /* 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))
                                    {
-                                      int dx, dy;
-                                      int in_x, in_w;
+                                      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);
+                                           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)
+                                           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++)
                                         {
-                                           if ((dx < (ext_x + ext_w)) &&
-                                               (dy >= (ext_y)) &&
-                                               (dy < (ext_y + ext_h)))
+                                           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
                                              {
-                                                if (dx + w > (ext_x + ext_w))
-                                                  in_w += (dx + w) - (ext_x + ext_w);
-                                                if (dx < ext_x)
+                                                tp = tmpbuf;
+                                                dp = data + (i * fg->glyph_out->bitmap.pitch);
+                                                for (bi = 0; bi < w; bi += 8)
                                                   {
-                                                     in_w += ext_x - dx;
-                                                     in_x = ext_x - dx;
-                                                     dx = ext_x;
+                                                     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 (in_w < w)
+                                                if ((dx < (ext_x + ext_w)) &&
+                                                      (dy >= (ext_y)) &&
+                                                      (dy < (ext_y + ext_h)))
                                                   {
-                                                     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, tmpbuf + in_x, dc->col.col,
+                                                                im + (dy * im_w) + dx, w - in_w);
+                                                       }
                                                   }
                                              }
                                         }
                                    }
                               }
+                         }
+                    }
+               }
+             else
+               break;
+          }
+        EVAS_FONT_WALK_OT_TEXT_END();
+     }
+   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
                               {
-                                 DATA8 *tmpbuf = NULL, *dp, *tp, bits;
-                                 int bi, bj;
-                                 const DATA8 bitrepl[2] = {0x0, 0xff};
-
-                                 tmpbuf = alloca(w);
-                                 for (i = 0; i < h; i++)
+                                 if ((fg->glyph_out->bitmap.num_grays == 256) &&
+                                       (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
                                    {
-                                      int dx, dy;
-                                      int in_x, in_w, end;
+                                      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);
+                                           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)
+                                           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++)
+                                                if ((dx < (ext_x + ext_w)) &&
+                                                      (dy >= (ext_y)) &&
+                                                      (dy < (ext_y + ext_h)))
                                                   {
-                                                     *tp = bitrepl[(bits >> (7 - bj)) & 0x1];
-                                                     tp++;
+                                                     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);
+                                                       }
                                                   }
-                                                dp++;
                                              }
-                                           if ((dx < (ext_x + ext_w)) &&
-                                               (dy >= (ext_y)) &&
-                                               (dy < (ext_y + ext_h)))
+                                        }
+                                   }
+                                 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
                                              {
-                                                if (dx + w > (ext_x + ext_w))
-                                                  in_w += (dx + w) - (ext_x + ext_w);
-                                                if (dx < ext_x)
+                                                tp = tmpbuf;
+                                                dp = data + (i * fg->glyph_out->bitmap.pitch);
+                                                for (bi = 0; bi < w; bi += 8)
                                                   {
-                                                     in_w += ext_x - dx;
-                                                     in_x = ext_x - dx;
-                                                     dx = ext_x;
+                                                     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 (in_w < w)
+                                                if ((dx < (ext_x + ext_w)) &&
+                                                      (dy >= (ext_y)) &&
+                                                      (dy < (ext_y + ext_h)))
                                                   {
-                                                     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 +806,17 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
                          }
                     }
                }
+             else
+               break;
           }
-        else
-          break;
+        EVAS_FONT_WALK_DEFAULT_TEXT_END();
      }
-   EVAS_FONT_WALK_TEXT_END();
-#ifdef BIDI_SUPPORT
-   if (visual_text) free(visual_text);
-#endif
   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;
index 8a11a10..9d37b4f 100644 (file)
@@ -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/src/lib/engines/common/evas_font_ot.c b/src/lib/engines/common/evas_font_ot.c
new file mode 100644 (file)
index 0000000..558c943
--- /dev/null
@@ -0,0 +1,140 @@
+#include "evas_font_ot.h"
+
+#ifdef OT_SUPPORT
+# include <hb.h>
+# include <hb-ft.h>
+#endif
+
+#include "evas_common.h"
+
+#include <Eina.h>
+#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/src/lib/engines/common/evas_font_ot.h b/src/lib/engines/common/evas_font_ot.h
new file mode 100644 (file)
index 0000000..b963ea0
--- /dev/null
@@ -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 <stdlib.h>
+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/src/lib/engines/common/evas_font_ot_walk.x b/src/lib/engines/common/evas_font_ot_walk.x
new file mode 100644 (file)
index 0000000..cbc5b2c
--- /dev/null
@@ -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
index b6f8386..b98d8ab 100644 (file)
@@ -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 */
index 8d80673..d3df7ec 100644 (file)
@@ -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_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_TEXT_WORK(EINA_FALSE);
+        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_TEXT_WORK(EINA_TRUE);
-
-        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;
-         }
+        EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
+          {
+             int chr_x, chr_w;
+             int found = 0, items = 1, item_pos = 1;
+
+             EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
+             if (visible)
+               {
+                  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);
+               }
+
+             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_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);
+               }
+
+             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();
      }
-   EVAS_FONT_WALK_TEXT_END();
-end:
-
-#ifdef BIDI_SUPPORT
-   if (visual_text) free(visual_text);
+   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))
+   asc = evas_common_font_max_ascent_get(fn);
+   desc = evas_common_font_max_descent_get(fn);
+#ifdef OT_SUPPORT
+   if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
      {
-        visual_text = eina_unicode_strdup(in_text);
-
-        if (visual_text)
+        EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
           {
-             evas_bidi_reverse_string(visual_text);
-             text = visual_text;
+             EVAS_FONT_WALK_OT_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_OT_X_ADV)) &&
+                   (y >= -asc) && (y <= desc))
+               {
+                  int items = 1, item_pos = 1;
+
+                  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();
      }
-   if (!visual_text)
-     {
-        text = in_text;
-     }
-   len = eina_unicode_strlen(text);
+   else
 #endif
-
-   asc = evas_common_font_max_ascent_get(fn);
-   desc = evas_common_font_max_descent_get(fn);
-
-   EVAS_FONT_WALK_TEXT_START()
      {
-       int chr_x, chr_w;
-
-        EVAS_FONT_WALK_TEXT_WORK(EINA_TRUE);
-
-        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;
-         }
+        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()
+
+#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_TEXT_WORK(EINA_FALSE);
-
-       if ((x >= pen_x) && (x <= (pen_x + adv)) &&
-           (y >= -asc) && (y <= desc))
-         {
-            ret = char_index;
-             goto end;
-         }
+        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;
 }
+
index fbe546b..a2322f4 100644 (file)
@@ -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]++;
index 5ee8eed..73213b6 100644 (file)
@@ -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/src/lib/engines/common/evas_text_utils.c b/src/lib/engines/common/evas_text_utils.c
new file mode 100644 (file)
index 0000000..e5fd81c
--- /dev/null
@@ -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/src/lib/engines/common/evas_text_utils.h b/src/lib/engines/common/evas_text_utils.h
new file mode 100644 (file)
index 0000000..ccc4d20
--- /dev/null
@@ -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
index 37266c6..aa9ee91 100644 (file)
@@ -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/src/lib/engines/common/language/evas_language_utils.c b/src/lib/engines/common/language/evas_language_utils.c
new file mode 100644 (file)
index 0000000..bd9732b
--- /dev/null
@@ -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 <Eina.h>
+
+#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 <hb.h>
+# ifdef HAVE_HARFBUZZ_GLIB
+#  include <hb-glib.h>
+# 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/src/lib/engines/common/language/evas_language_utils.h b/src/lib/engines/common/language/evas_language_utils.h
new file mode 100644 (file)
index 0000000..e4958c6
--- /dev/null
@@ -0,0 +1,128 @@
+#ifndef _EVAS_LANGUAGE_UTILS
+#define _EVAS_LANGUAGE_UTILS
+
+#include <Eina.h>
+#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/src/lib/engines/common/language/evas_script_utils.c b/src/lib/engines/common/language/evas_script_utils.c
deleted file mode 100644 (file)
index 7b932d1..0000000
+++ /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 <Eina.h>
-
-#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/src/lib/engines/common/language/evas_script_utils.h b/src/lib/engines/common/language/evas_script_utils.h
deleted file mode 100644 (file)
index 4ee70bf..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _EVAS_SCRIPT_UTILS
-#define _EVAS_SCRIPT_UTILS
-
-#include <Eina.h>
-#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
-
index fa15f5a..4cefba9 100644 (file)
@@ -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;
index c81ca8f..d90d280 100644 (file)
@@ -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
index 8cccee3..13ec8ff 100644 (file)
@@ -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)
 {
index be5938b..561a8ee 100644 (file)
@@ -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;
index cecc69c..f2517e2 100644 (file)
@@ -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;
index 5f40812..4ece31d 100644 (file)
@@ -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;
 
index ec8edbf..cfc460a 100644 (file)
@@ -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;
 
index d80a6ad..ccf3f9a 100644 (file)
@@ -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;
 
index 743a39f..0a14e70 100644 (file)
@@ -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;
index cb4bf46..f4997ed 100644 (file)
@@ -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);
 
index c31c4ca..999198d 100644 (file)
@@ -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 */
 };
 
index 3166107..a477575 100644 (file)
@@ -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;
index a02c89d..e6d6db2 100644 (file)
@@ -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 */
 };
 
index d79c4dc..fe87137 100644 (file)
@@ -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 */
 };
 
index d7d9e22..9145999 100644 (file)
@@ -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;
index b16ebdd..ce84c43 100644 (file)
@@ -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;