Revert "Snapshot." - didn't mean to commit this :(
authortasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 30 Jan 2011 13:58:06 +0000 (13:58 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 30 Jan 2011 13:58:06 +0000 (13:58 +0000)
This reverts commit 521198281e4ac616fee48d27aae9e6983d5950c3.

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

16 files changed:
src/lib/engines/common/Makefile.am
src/lib/engines/common/evas_font_default_walk.x
src/lib/engines/common/evas_font_draw.c
src/lib/engines/common/evas_font_glyph_info.c [deleted file]
src/lib/engines/common/evas_font_glyph_info.h [deleted file]
src/lib/engines/common/evas_font_ot.c
src/lib/engines/common/evas_font_ot.h
src/lib/engines/common/evas_font_ot_walk.x
src/lib/engines/common/evas_font_private.h
src/lib/engines/common/evas_font_query.c
src/lib/engines/common/evas_text_utils.c
src/lib/engines/common/evas_text_utils.h
src/modules/engines/quartz/evas_engine.c
src/modules/engines/software_16/evas_engine.c
src/modules/engines/software_8/evas_engine.c
src/modules/engines/software_generic/evas_engine.c

index 2128b18..c3f9dd8 100644 (file)
@@ -63,7 +63,6 @@ language/evas_bidi_utils.c \
 language/evas_language_utils.c \
 evas_text_utils.c \
 evas_font_ot.c \
-evas_font_glyph_info.c \
 evas_map_image.c \
 evas_map_image.h
 
@@ -106,7 +105,6 @@ language/evas_bidi_utils.h \
 language/evas_language_utils.h \
 evas_text_utils.h \
 evas_font_ot.h \
-evas_font_glyph_info.h \
 evas_map_image_internal.c \
 evas_map_image_core.c \
 evas_map_image_loop.c
index 2071e2d..08839e4 100644 (file)
 /* Macros for text walking */
 
 /**
- * @def EVAS_FONT_WALK_TEXT_INIT
+ * @def EVAS_FONT_UPDATE_KERN()
  * @internal
- * This macro defines the variables that will later be used with the following
- * macros, and by font handling functions.
- * @see EVAS_FONT_WALK_TEXT_START
- * @see EVAS_FONT_WALK_TEXT_WORK
- * @see EVAS_FONT_WALK_TEXT_END
+ * This macro updates kern according to kerning.
+ * This macro assumes the following variables exist:
+ * intl_props, char_index, fi, kern, index, prev_index
  */
-# define EVAS_FONT_WALK_TEXT_INIT() \
-        int _pen_x = 0, _pen_y = 0; \
-        size_t char_index; \
-        (void) _pen_y; /* Sometimes it won't be used */
+#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_TEXT_VISUAL_START
+ * @def EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START
  * @internal
  * This runs through the text in visual order while updating char_index,
  * which is the current index in the text.
  * Does not end with a ;
- * Take a look at EVAS_FONT_WALK_X_OFF and the like.
- * @see EVAS_FONT_WALK_TEXT_INIT
- * @see EVAS_FONT_WALK_TEXT_WORK
- * @see EVAS_FONT_WALK_TEXT_END
- * @see EVAS_FONT_WALK_TEXT_LOGICAL_START
+ * Take a look at EVAS_FONT_WALK_DEFAULT_X_OFF and the like.
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_END
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START
  */
-#define EVAS_FONT_WALK_TEXT_VISUAL_START() \
+#define EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() \
    do \
      { \
-        int visible = 1; \
-        for (char_index = 0 ; char_index < text_props->len ; char_index++) \
-          {
+        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_TEXT_LOGICAL_START
+ * @def EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START
  * @internal
  * This runs through the text in logical order while updating char_index,
  * which is the current index in the text.
  * Does not end with a ;
- * Take a look at EVAS_FONT_WALK_X_OFF and the like.
- * @see EVAS_FONT_WALK_TEXT_INIT
- * @see EVAS_FONT_WALK_TEXT_WORK
- * @see EVAS_FONT_WALK_TEXT_END
- * @see EVAS_FONT_WALK_TEXT_VISUAL_START
+ * Take a look at EVAS_FONT_WALK_DEFAULT_X_OFF and the like.
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_END
+ * @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START
  */
-#ifdef BIDI_SUPPORT
-#define EVAS_FONT_WALK_TEXT_LOGICAL_START() \
+#define EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START() \
    do \
      { \
-        int _char_index_d, _i; \
-        int visible = 1; \
-        _i = text_props->len; \
-        if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \
+        int visible; \
+        prev_index = 0; \
+        for (char_index = 0 ; *text ; text++, char_index++) \
           { \
-             char_index = text_props->len - 1; \
-             _char_index_d = -1; \
-          } \
-        else \
-          { \
-             char_index = 0; \
-             _char_index_d = 1; \
-          } \
-        for ( ; _i > 0 ; char_index += _char_index_d, _i--) \
-          {
-#else
-#define EVAS_FONT_WALK_TEXT_LOGICAL_START() EVAS_FONT_WALK_TEXT_VISUAL_START()
-#endif
+             FT_UInt index; \
+             RGBA_Font_Glyph *fg; \
+             int _gl, kern; \
+             _gl = *text; \
+             if (_gl == 0) break;
 
 /*FIXME: doc */
-#ifdef OT_SUPPORT
-# define EVAS_FONT_WALK_X_OFF \
-             ((text_props->info->ot) ? \
-             (EVAS_FONT_ROUND_26_6_TO_INT( \
-                EVAS_FONT_OT_X_OFF_GET( \
-                   text_props->info->ot[char_index]))) : \
-              (0))
-# define EVAS_FONT_WALK_Y_OFF \
-             ((text_props->info->ot) ? \
-             (EVAS_FONT_ROUND_26_6_TO_INT( \
-                EVAS_FONT_OT_Y_OFF_GET( \
-                   text_props->info->ot[char_index]))) : \
-              (0))
-# define EVAS_FONT_WALK_POS \
-             ((text_props->info->ot) ? \
-             (EVAS_FONT_OT_POS_GET( \
-                      text_props->info->ot[char_index])) : \
-              (char_index))
-# define EVAS_FONT_WALK_POS_NEXT \
-             ((text_props->info->ot) ? \
-              ((!EVAS_FONT_WALK_IS_LAST) ? \
-               EVAS_FONT_OT_POS_GET( \
-                                     text_props->info->ot[char_index + 1]) : \
-               EVAS_FONT_WALK_POS \
-              ) : \
-              ((!EVAS_FONT_WALK_IS_LAST) ? \
-               (char_index + 1) : EVAS_FONT_WALK_POS))
-# define EVAS_FONT_WALK_POS_PREV \
-             ((text_props->info->ot) ? \
-             ((char_index > 0) ? \
-             EVAS_FONT_OT_POS_GET( \
-                      text_props->info->ot[char_index - 1]) : \
-              EVAS_FONT_WALK_POS \
-             ) : \
-             ((char_index > 0) ? \
-              (char_index - 1) : EVAS_FONT_WALK_POS))
-#else
-# define EVAS_FONT_WALK_X_OFF 0
-# define EVAS_FONT_WALK_Y_OFF 0
-# define EVAS_FONT_WALK_POS (char_index)
-# define EVAS_FONT_WALK_POS_NEXT \
-             ((!EVAS_FONT_WALK_IS_LAST) ? \
-              (char_index + 1) : EVAS_FONT_WALK_POS)
-# define EVAS_FONT_WALK_POS_PREV \
-             ((char_index > 0) ? \
-              (char_index - 1) : EVAS_FONT_WALK_POS)
-#endif
-
-#define EVAS_FONT_WALK_X_BEAR (text_props->info->glyph[char_index].x_bear)
-#define EVAS_FONT_WALK_Y_BEAR (fg->glyph_out->top)
-#define _EVAS_FONT_WALK_X_ADV \
-                (text_props->info->glyph[char_index].advance)
-#define EVAS_FONT_WALK_WIDTH (text_props->info->glyph[char_index].width)
-
-#define EVAS_FONT_WALK_X_ADV \
-             (EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_X_ADV))
-#define EVAS_FONT_WALK_PEN_X (EVAS_FONT_ROUND_26_6_TO_INT(_pen_x))
-#define EVAS_FONT_WALK_PEN_Y (EVAS_FONT_ROUND_26_6_TO_INT(_pen_y))
-#define EVAS_FONT_WALK_Y_ADV (0)
-#define EVAS_FONT_WALK_IS_LAST \
-             (char_index + 1 == text_props->len)
-#define EVAS_FONT_WALK_IS_FIRST \
+#define EVAS_FONT_WALK_DEFAULT_X_OFF (0)
+#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 >> 10)
+#define EVAS_FONT_WALK_DEFAULT_X_ADV \
+             (EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_DEFAULT_X_ADV))
+#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_LEN (text_props->len)
-
+#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_TEXT_WORK
+ * @def EVAS_FONT_WALK_DEFAULT_TEXT_WORK
  * @internal
- * This macro actually updates the values mentioned in EVAS_FONT_WALK_TEXT_VISUAL_START
+ * 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_TEXT_VISUAL_START
- * @see EVAS_FONT_WALK_TEXT_INIT
- * @see EVAS_FONT_WALK_TEXT_END
+ * @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_TEXT_WORK() do {} while(0);
+#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_TEXT_END
+ * @def EVAS_FONT_WALK_DEFAULT_TEXT_END
  * @internal
- * Closes EVAS_FONT_WALK_TEXT_VISUAL_START, needs to end with a ;
- * @see EVAS_FONT_WALK_TEXT_VISUAL_START
- * @see EVAS_FONT_WALK_TEXT_INIT
- * @see EVAS_FONT_WALK_TEXT_WORK
+ * 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_TEXT_END() \
+#define EVAS_FONT_WALK_DEFAULT_TEXT_END() \
              if (visible) \
                { \
-                  _pen_x += _EVAS_FONT_WALK_X_ADV; \
+                  _pen_x += _EVAS_FONT_WALK_DEFAULT_X_ADV; \
                } \
+             prev_index = index; \
           } \
      } \
    while(0)
index 9e8cc5c..fde3c12 100644 (file)
@@ -49,7 +49,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, const Evas_Text_Props *text_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, const Evas_Text_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning);
 #endif
 
 EAPI void
@@ -389,20 +389,19 @@ evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl)
 }
 
 /* 
- * BiDi handling: We receive the shaped string + other props from text_props,
+ * BiDi handling: We receive the shaped string + other props from intl_props,
  * we need to reorder it so we'll have the visual string (the way we draw)
  * and then for kerning we have to switch the order of the kerning query (as the prev
  * is on the right, and not on the left).
  */
 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_Text_Props *text_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
                                )
 {
    const Eina_Unicode *text = in_text;
    DATA32 *im;
-   FT_Face pface = NULL;
    EVAS_FONT_WALK_TEXT_INIT();
 
 #if defined(METRIC_CACHE) || defined(WORD_CACHE)
@@ -416,7 +415,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, text_props,
+          evas_font_word_prerender(dc, text, intl_props,
                                    len, fn, fi, use_kerning);
         if (word)
           {
@@ -493,8 +492,6 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
 # endif
           }
      }
-#else
-   (void) use_kerning;
 #endif
 
    if (fi->src->current_size != fi->size)
@@ -507,172 +504,291 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
 
 
    im = dst->image.data;
-   /* Load the glyph according to the first letter of the script, preety
-    * bad, but will have to do */
-     {
-        /* Skip common chars */
-        const Eina_Unicode *tmp;
-        for (tmp = text ;
-              *tmp &&
-              evas_common_language_char_script_get(*tmp) ==
-              EVAS_SCRIPT_COMMON ;
-              tmp++)
-          ;
-        if (!*tmp && (tmp > text)) tmp--;
-        evas_common_font_glyph_search(fn, &fi, *tmp);
-     }
-   EVAS_FONT_WALK_TEXT_VISUAL_START()
+#ifdef OT_SUPPORT
+   if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
      {
-        FT_UInt index;
-        RGBA_Font_Glyph *fg;
-        int chr_x, chr_y, chr_w;
-
-        index = text_props->info->glyph[char_index].index;
-        LKL(fi->ft_mutex);
-        fg = evas_common_font_int_cache_glyph_get(fi, index);
-        if (!fg)
-          {
-             LKU(fi->ft_mutex);
-             continue;
-          }
-        if (EVAS_FONT_CHARACTER_IS_INVISIBLE(text[EVAS_FONT_WALK_POS]))
+        EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
           {
-             visible = 0;
-          }
-        else
-          {
-             visible = 1;
-          }
+             int chr_x, chr_y, chr_w;
 
-        pface = fi->src->ft.face;
-        LKU(fi->ft_mutex);
+             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 = x + EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
-        chr_y = y + EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
-        chr_w = EVAS_FONT_WALK_WIDTH;
+             chr_x = x + EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_OFF + EVAS_FONT_WALK_OT_X_BEAR;
+             chr_y = y + EVAS_FONT_WALK_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))
-                         {
-                            /* 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 ((j > 0) && (chr_x + w > ext_x))
                          {
-                            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))
+                              {
+                                 /* ext glyph draw */
+                                 dc->font_ext.func.gl_draw(dc->font_ext.data,
+                                       (void *)dst,
+                                       dc, fg, chr_x,
+                                       y - (chr_y - y));
+                              }
+                            else
                               {
-                                 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;
+                                      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;
+
+             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 = x + EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_DEFAULT_X_OFF + EVAS_FONT_WALK_DEFAULT_X_BEAR;
+             chr_y = y + EVAS_FONT_WALK_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);
+                                                       }
                                                   }
                                              }
                                         }
@@ -681,17 +797,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();
   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_Text_Props *text_props)
+                      const Evas_Text_Props *intl_props)
 {
    int ext_x, ext_y, ext_w, ext_h;
    int im_w, im_h;
@@ -743,7 +859,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
 
    if (!dc->cutout.rects)
      {
-        evas_common_font_draw_internal(dst, dc, fn, x, y, text, text_props,
+        evas_common_font_draw_internal(dst, dc, fn, x, y, text, intl_props,
                                        func, ext_x, ext_y, ext_w, ext_h, fi,
                                        im_w, im_h, use_kerning);
      }
@@ -759,7 +875,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
                {
                   r = rects->rects + i;
                   evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
-                  evas_common_font_draw_internal(dst, dc, fn, x, y, text, text_props,
+                  evas_common_font_draw_internal(dst, dc, fn, x, y, text, intl_props,
                                                  func, r->x, r->y, r->w, r->h, fi,
                                                  im_w, im_h, use_kerning);
                }
@@ -776,7 +892,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, const Evas_Text_Props *text_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, const Evas_Text_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning)
 {
    struct cinfo *metrics;
    const Eina_Unicode *text = in_text;
@@ -814,14 +930,14 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, con
    /* It's a bit hackish to use index and fg here as they are internal,
     * but that'll have to be good enough ATM */
 #ifdef OT_SUPPORT
-   if (evas_common_font_ot_is_enabled())
+   if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
      {
-        len = text_props->info->ot_data->len;
+        len = intl_props->ot_data->len;
         metrics = malloc(sizeof(struct cinfo) * len);
-        EVAS_FONT_WALK_TEXT_VISUAL_START()
+        EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
           {
              struct cinfo *ci = metrics + char_index;
-             EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE);
+             EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
              /* Currently broken with invisible chars if (!visible) continue; */
              ci->index = index;
              ci->fg = fg;
@@ -842,19 +958,19 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, con
              if (above > baseline) baseline = above;
              ci->pos.x = EVAS_FONT_WALK_PEN_X + ci->fg->glyph_out->left;
              ci->pos.y = EVAS_FONT_WALK_PEN_Y + ci->fg->glyph_out->top;
-             last_delta = EVAS_FONT_WALK_X_ADV -
+             last_delta = EVAS_FONT_WALK_OT_X_ADV -
                 (ci->bm.w + ci->fg->glyph_out->left);
           }
-        EVAS_FONT_WALK_TEXT_END();
+        EVAS_FONT_WALK_OT_TEXT_END();
      }
    else
 #endif
      {
         metrics = malloc(sizeof(struct cinfo) * len);
-        EVAS_FONT_WALK_TEXT_LOGICAL_START()
+        EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START()
           {
              struct cinfo *ci = metrics + char_index;
-             EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE);
+             EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
              /* Currently broken with invisible chars if (!visible) continue; */
              ci->index = index;
              ci->fg = fg;
@@ -875,10 +991,10 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, con
              if (above > baseline) baseline = above;
              ci->pos.x = EVAS_FONT_WALK_PEN_X + ci->fg->glyph_out->left;
              ci->pos.y = EVAS_FONT_WALK_PEN_Y + ci->fg->glyph_out->top;
-             last_delta = EVAS_FONT_WALK_X_ADV -
+             last_delta = EVAS_FONT_WALK_DEFAULT_X_ADV -
                 (ci->bm.w + ci->fg->glyph_out->left);
           }
-        EVAS_FONT_WALK_TEXT_END();
+        EVAS_FONT_WALK_DEFAULT_TEXT_END();
      }
 
    /* First loop done */
diff --git a/src/lib/engines/common/evas_font_glyph_info.c b/src/lib/engines/common/evas_font_glyph_info.c
deleted file mode 100644 (file)
index a2e9911..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-#include "evas_common.h"
-#include "evas_font_private.h" /* for Frame-Queuing support */
-#include "evas_font_ot.h"
-#include "evas_font_glyph_info.h"
-
-EAPI Eina_Bool
-evas_common_font_glyph_info_create(void *_fn, const Eina_Unicode *text,
-      Evas_Text_Props *text_props, int len)
-{
-   RGBA_Font *fn = (RGBA_Font *) _fn;
-   RGBA_Font_Int *fi;
-   size_t char_index;
-
-   if (text_props->info)
-     {
-        evas_common_text_props_content_unref(text_props);
-     }
-   text_props->info = calloc(1, sizeof(Evas_Text_Props_Info));
-
-   fi = fn->fonts->data;
-   /* evas_common_font_size_use(fn); */
-   evas_common_font_int_reload(fi);
-   if (fi->src->current_size != fi->size)
-     {
-        FTLOCK();
-        FT_Activate_Size(fi->ft.size);
-        FTUNLOCK();
-        fi->src->current_size = fi->size;
-     }
-
-#ifdef OT_SUPPORT
-   if (evas_common_font_ot_is_enabled())
-     {
-        evas_common_font_ot_populate_text_props(fn, text, text_props, len);
-
-        /* Load the glyph according to the first letter of the script, preety
-         * bad, but will have to do */
-          {
-             /* Skip common chars */
-             const Eina_Unicode *tmp;
-             for (tmp = text ;
-                   *tmp &&
-                   evas_common_language_char_script_get(*tmp) ==
-                   EVAS_SCRIPT_COMMON ;
-                   tmp++)
-               ;
-             if (!*tmp && (tmp > text)) tmp--;
-             evas_common_font_glyph_search(fn, &fi, *tmp);
-          }
-
-        for (char_index = 0 ; char_index < text_props->len ; char_index++)
-          {
-             FT_UInt index;
-             RGBA_Font_Glyph *fg;
-             index = text_props->info->glyph[char_index].index;
-             LKL(fi->ft_mutex);
-             fg = evas_common_font_int_cache_glyph_get(fi, index);
-             if (!fg)
-               {
-                  LKU(fi->ft_mutex);
-                  continue;
-               }
-             LKU(fi->ft_mutex);
-             text_props->info->glyph[char_index].x_bear =
-                fg->glyph_out->left;
-             text_props->info->glyph[char_index].width =
-                fg->glyph_out->bitmap.width;
-             /* text_props->info->glyph[char_index].advance =
-              * text_props->info->glyph[char_index].index =
-              * already done by the ot function */
-
-             /* FIXME add visible handling */
-          }
-     }
-   else
-#endif
-     {
-        /* We are walking the string in visual ordering */
-        Eina_Bool use_kerning;
-        FT_UInt prev_index;
-        FT_Face pface = NULL;
-        int adv_d, i;
-        FTLOCK();
-        use_kerning = FT_HAS_KERNING(fi->src->ft.face);
-        FTUNLOCK();
-        prev_index = 0;
-
-        i = len;
-        text_props->info->glyph = calloc(len,
-              sizeof(Evas_Font_Glyph_Info));
-
-        if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
-          {
-             text += len - 1;
-             adv_d = -1;
-          }
-        else
-          {
-             adv_d = 1;
-          }
-        char_index = 0;
-        for ( ; i > 0 ; char_index++, text += adv_d, i--)
-          {
-             FT_UInt index;
-             RGBA_Font_Glyph *fg;
-             int _gl, kern;
-             _gl = *text;
-             if (_gl == 0) break;
-
-             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 ((use_kerning) && (prev_index) && (index) &&
-                   (pface == fi->src->ft.face))
-               {
-#ifdef BIDI_SUPPORT
-                  /* 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 (text_props &&
-                        (text_props->bidi.dir != EVAS_BIDI_DIRECTION_RTL))
-                    {
-                       if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
-                         {
-                            text_props->info->glyph[char_index - 1].advance +=
-                               kern;
-                         }
-                    }
-                  else
-#endif
-                    {
-                       if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
-                         {
-                            text_props->info->glyph[char_index - 1].advance +=
-                               kern;
-                         }
-                    }
-               }
-
-             pface = fi->src->ft.face;
-             LKU(fi->ft_mutex);
-
-             text_props->info->glyph[char_index].index = index;
-             text_props->info->glyph[char_index].x_bear =
-                fg->glyph_out->left;
-             text_props->info->glyph[char_index].advance =
-                fg->glyph->advance.x >> 10;
-             text_props->info->glyph[char_index].width =
-                fg->glyph_out->bitmap.width;
-
-             prev_index = index;
-          }
-        text_props->len = len;
-     }
-   text_props->info->refcount = 1;
-   return EINA_TRUE;
-}
-
diff --git a/src/lib/engines/common/evas_font_glyph_info.h b/src/lib/engines/common/evas_font_glyph_info.h
deleted file mode 100644 (file)
index 2bbbf34..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _EVAS_FONT_METRICS_H
-# define _EVAS_FONT_METRICS_H
-/* Sorted in visual order when created */
-struct _Evas_Font_Glyph_Info
-{
-   unsigned int index; /* Should conform to FT */
-   Evas_Coord x_bear;
-#if 0
-   /* This one is rarely used, only in draw, in which we already get the glyph
-    * so it doesn't really save time. Leaving it here just so no one will
-    * add it thinking it was accidentally skipped */
-   Evas_Coord y_bear;
-#endif
-   Evas_Coord width;
-   Evas_Coord advance;
-};
-
-typedef struct _Evas_Font_Glyph_Info Evas_Font_Glyph_Info;
-
-EAPI Eina_Bool
-evas_common_font_glyph_info_create(void *_fn, const Eina_Unicode *text,
-      Evas_Text_Props *text_props, int len);
-
-#endif
-
index b0d1f0d..477a861 100644 (file)
@@ -34,22 +34,21 @@ evas_common_font_ot_is_enabled(void)
 #ifdef OT_SUPPORT
 /* FIXME: doc. returns #items */
 EAPI int
-evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index)
+evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index, int orig_len)
 {
    int i;
    int items;
    int left_bound, right_bound;
-   char_index += props->start;
-   size_t base_cluster = EVAS_FONT_OT_POS_GET(props->info->ot[char_index]);
+   size_t base_cluster = EVAS_FONT_OT_POS_GET(props->ot_data->items[char_index]);
    for (i = (int) char_index ;
-         (i >= (int) props->start) &&
-         (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ;
+         (i >= 0) &&
+         (EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ;
          i--)
      ;
    left_bound = i;
    for (i = (int) char_index + 1;
-         (i < (int) (props->start + props->len)) &&
-         (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ;
+         (i < (int) props->ot_data->len) &&
+         (EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ;
          i++)
      ;
    right_bound = i;
@@ -61,26 +60,26 @@ evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_i
      {
         if (left_bound < 0)
           {
-             items = props->start + props->len -
-                props->info->ot[left_bound + 1].source_cluster;
+             items = orig_len -
+                props->ot_data->items[left_bound + 1].source_cluster;
           }
         else
           {
-             items = props->info->ot[left_bound].source_cluster -
-                props->info->ot[left_bound + 1].source_cluster;
+             items = props->ot_data->items[left_bound].source_cluster -
+                props->ot_data->items[left_bound + 1].source_cluster;
           }
      }
    else
      {
-        if (right_bound == (int) props->len)
+        if (right_bound == (int) props->ot_data->len)
           {
-             items = props->start + props->len -
-                props->info->ot[right_bound - 1].source_cluster;
+             items = orig_len -
+                props->ot_data->items[right_bound - 1].source_cluster;
           }
         else
           {
-             items = props->info->ot[right_bound].source_cluster -
-                props->info->ot[right_bound - 1].source_cluster;
+             items = props->ot_data->items[right_bound].source_cluster -
+                props->ot_data->items[right_bound - 1].source_cluster;
           }
      }
    return (items > 0) ? items : 1;
@@ -115,6 +114,152 @@ _evas_common_font_ot_shape(hb_buffer_t *buffer, RGBA_Font_Source *src)
    hb_font_destroy(hb_font);
 }
 
+/* Won't work in the middle of ligatures */
+EAPI void
+evas_common_font_ot_cutoff_text_props(Evas_Text_Props *props, int cutoff)
+{
+   Evas_Font_OT_Data *new_data;
+   if ((cutoff <= 0) || (!props->ot_data) ||
+         (((size_t) cutoff) >= props->ot_data->len))
+     return;
+
+   new_data = malloc(sizeof(Evas_Font_OT_Data));
+   memcpy(new_data, props->ot_data, sizeof(Evas_Font_OT_Data));
+   new_data->refcount = 1;
+   new_data->len = cutoff;
+   new_data->items = malloc(cutoff * sizeof(Evas_Font_OT_Data_Item));
+
+   if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
+     {
+        memcpy(new_data->items,
+              props->ot_data->items + (props->ot_data->len - cutoff),
+              cutoff * sizeof(Evas_Font_OT_Data_Item));
+     }
+   else
+     {
+        memcpy(new_data->items,
+              props->ot_data->items,
+              cutoff * sizeof(Evas_Font_OT_Data_Item));
+     }
+
+   evas_common_font_ot_props_unref(props->ot_data);
+   props->ot_data = new_data;
+}
+
+/* Won't work in the middle of ligatures
+ * aissumes ext doesn't have an already init ot_data
+ * we assume there's at least one char in each part */
+EAPI void
+evas_common_font_ot_split_text_props(Evas_Text_Props *base,
+      Evas_Text_Props *ext, int cutoff)
+{
+   Evas_Font_OT_Data *new_data;
+   int i;
+   if ((cutoff <= 0) || (!base->ot_data) ||
+         (((size_t) cutoff) >= base->ot_data->len))
+     return;
+
+   ext->ot_data = calloc(1, sizeof(Evas_Font_OT_Data));
+   ext->ot_data->refcount = 1;
+   ext->ot_data->len = base->ot_data->len - cutoff;
+   ext->ot_data->items = calloc(ext->ot_data->len,
+         sizeof(Evas_Font_OT_Data_Item));
+
+   new_data = malloc(sizeof(Evas_Font_OT_Data));
+   memcpy(new_data, base->ot_data, sizeof(Evas_Font_OT_Data));
+   new_data->refcount = 1;
+   new_data->items = malloc(cutoff * sizeof(Evas_Font_OT_Data_Item));
+   new_data->len = cutoff;
+
+   if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
+     {
+        memcpy(ext->ot_data->items, base->ot_data->items,
+              ext->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
+        memcpy(new_data->items,
+              base->ot_data->items + ext->ot_data->len,
+              cutoff * sizeof(Evas_Font_OT_Data_Item));
+     }
+   else
+     {
+        memcpy(ext->ot_data->items, base->ot_data->items + cutoff,
+              ext->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
+        memcpy(new_data->items, base->ot_data->items,
+              cutoff * sizeof(Evas_Font_OT_Data_Item));
+     }
+   evas_common_font_ot_props_unref(base->ot_data);
+   base->ot_data = new_data;
+
+   /* Adjust the offset of the clusters */
+     {
+        size_t min;
+        min = ext->ot_data->items[0].source_cluster;
+        for (i = 1 ; i < (int) ext->ot_data->len ; i++)
+          {
+             if (ext->ot_data->items[i].source_cluster < min)
+               {
+                  min = ext->ot_data->items[i].source_cluster;
+               }
+          }
+        for (i = 0 ; i < (int) ext->ot_data->len ; i++)
+          {
+             ext->ot_data->items[i].source_cluster -= min;
+          }
+        ext->ot_data->offset = base->ot_data->offset + min;
+     }
+}
+
+/* Won't work in the middle of ligatures
+ * assumes both are init correctly and that both are from the
+ * same origin item, i.e both have the same script + direction.
+ * assume item1 is logically first */
+EAPI void
+evas_common_font_ot_merge_text_props(Evas_Text_Props *item1,
+      const Evas_Text_Props *item2)
+{
+   Evas_Font_OT_Data *new_data;
+   Evas_Font_OT_Data_Item *itr; /* Itr will be used for adding back
+                                         the offsets */
+   size_t len;
+   if (!item1->ot_data || !item2->ot_data)
+     return;
+   len = item1->ot_data->len + item2->ot_data->len;
+
+   new_data = malloc(sizeof(Evas_Font_OT_Data));
+   memcpy(new_data, item1->ot_data, sizeof(Evas_Font_OT_Data));
+   new_data->refcount = 1;
+   new_data->items = malloc(len * sizeof(Evas_Font_OT_Data_Item));
+   new_data->len = len;
+   if (item1->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
+     {
+        memcpy(new_data->items, item2->ot_data->items,
+              item2->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
+        memcpy(new_data->items + item2->ot_data->len, item1->ot_data->items,
+              item1->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
+        itr = new_data->items;
+     }
+   else
+     {
+        memcpy(new_data->items, item1->ot_data->items,
+              item1->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
+        memcpy(new_data->items + item1->ot_data->len, item2->ot_data->items,
+              item2->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
+        itr = new_data->items + item1->ot_data->len;
+     }
+   evas_common_font_ot_props_unref(item1->ot_data);
+   item1->ot_data = new_data;
+   /* Add back the offset of item2 to the newly created */
+   if (item2->ot_data->offset > 0)
+     {
+        int i;
+        for (i = 0 ; i < (int) item2->ot_data->len ; i++, itr++)
+          {
+             /* This must be > 0, just because this is how it works */
+             itr->source_cluster += item2->ot_data->offset -
+                item1->ot_data->offset;
+          }
+     }
+}
+
 EAPI Eina_Bool
 evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
       Evas_Text_Props *props, int len)
@@ -127,6 +272,12 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
    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;
    /* Load the font needed for this script */
@@ -172,20 +323,18 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
 
    _evas_common_font_ot_shape(buffer, fi->src);
 
-   props->len = hb_buffer_get_length(buffer);
-   props->info->ot = calloc(props->len,
-         sizeof(Evas_Font_OT_Info));
-   props->info->glyph = calloc(props->len,
-              sizeof(Evas_Font_Glyph_Info));
+   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->len ; i++)
+   for (i = 0 ; i < props->ot_data->len ; i++)
      {
-        props->info->ot[i].source_cluster = infos[i].cluster;
-        props->info->ot[i].x_offset = positions[i].x_offset;
-        props->info->ot[i].y_offset = positions[i].y_offset;
-        props->info->glyph[i].index = infos[i].codepoint;
-        props->info->glyph[i].advance = positions[i].x_advance;
+        props->ot_data->items[i].index = infos[i].codepoint;
+        props->ot_data->items[i].source_cluster = 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);
@@ -194,5 +343,23 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
    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
 
index 66ed10d..01c0ad1 100644 (file)
 
 # ifdef OT_SUPPORT
 #  include <stdlib.h>
-typedef struct _Evas_Font_OT_Info Evas_Font_OT_Info;
+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;
+   size_t offset; /* The offset from the start of the script segment,
+                     this is useful when it's a split item */
+};
 # else
-typedef void *Evas_Font_OT_Info;
+typedef void *Evas_Font_OT_Data;
 # endif
 
 # include "Evas.h"
 
 # ifdef OT_SUPPORT
-struct _Evas_Font_OT_Info
+struct _Evas_Font_OT_Data_Item
 {
+   unsigned int index; /* Should conform to FT */
    size_t source_cluster;
    Evas_Coord x_offset;
    Evas_Coord y_offset;
+   Evas_Coord x_advance;
 };
 # 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_cluster)
+# 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);
+
+EAPI void
 evas_common_font_ot_load_face(void *_font);
 
 EAPI void
@@ -45,7 +72,7 @@ evas_common_font_ot_unload_face(void *_font);
 
 # include "evas_text_utils.h"
 EAPI int
-evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index);
+evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index, int orig_len);
 
 EAPI Eina_Bool
 evas_common_font_ot_populate_text_props(void *fn, const Eina_Unicode *text,
index 971fb11..9c8c7df 100644 (file)
@@ -36,7 +36,7 @@
              if (!*tmp && (tmp > text)) tmp--; \
              evas_common_font_glyph_search(fn, &fi, *tmp); \
           } \
-        for (char_index = 0 ; char_index < intl_props->len ; char_index++) \
+        for (char_index = 0 ; char_index < intl_props->ot_data->len ; char_index++) \
           { \
              FT_UInt index; \
              RGBA_Font_Glyph *fg; \
              evas_common_font_glyph_search(fn, &fi, *tmp); \
           } \
         prev_index = 0; \
-        _i = intl_props->len; \
+        _i = intl_props->ot_data->len; \
         if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \
           { \
-             char_index = intl_props->len - 1; \
+             char_index = intl_props->ot_data->len - 1; \
              _char_index_d = -1; \
           } \
         else \
 #define EVAS_FONT_WALK_OT_X_OFF \
              (EVAS_FONT_ROUND_26_6_TO_INT( \
                 EVAS_FONT_OT_X_OFF_GET( \
-                   intl_props->info->ot[char_index])))
+                   intl_props->ot_data->items[char_index])))
 #define EVAS_FONT_WALK_OT_Y_OFF \
              (EVAS_FONT_ROUND_26_6_TO_INT( \
                 EVAS_FONT_OT_Y_OFF_GET( \
-                   intl_props->info->ot[char_index])))
-#define EVAS_FONT_WALK_OT_X_BEAR (intl_props->info->glyph[char_index].x_bear)
+                   intl_props->ot_data->items[char_index])))
+#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 \
-                (intl_props->info->glyph[char_index].advance)
+                (EVAS_FONT_OT_X_ADV_GET( \
+                   intl_props->ot_data->items[char_index]))
 #define EVAS_FONT_WALK_OT_X_ADV \
-             (EVAS_FONT_ROUND_26_6_TO_INT( \
-                _EVAS_FONT_WALK_OT_X_ADV))
-#define EVAS_FONT_WALK_OT_WIDTH (intl_props->info->glyph[char_index].width)
+             (EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_OT_X_ADV))
+#define EVAS_FONT_WALK_OT_WIDTH (fg->glyph_out->bitmap.width)
 #define EVAS_FONT_WALK_OT_POS \
              (EVAS_FONT_OT_POS_GET( \
-                      intl_props->info->ot[char_index]))
+                      intl_props->ot_data->items[char_index]))
 #define EVAS_FONT_WALK_OT_IS_LAST \
-             (char_index + 1 == intl_props->len)
+             (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->info->ot[char_index + 1]) : \
+                      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->info->ot[char_index - 1]) : \
+                      intl_props->ot_data->items[char_index - 1]) : \
               EVAS_FONT_WALK_OT_POS \
              )
-#define EVAS_FONT_WALK_OT_LEN (intl_props->len)
+#define EVAS_FONT_WALK_OT_LEN (intl_props->ot_data->len)
 /**
  * @def EVAS_FONT_WALK_OT_TEXT_WORK
  * @internal
  * @see EVAS_FONT_WALK_OT_TEXT_END
  */
 #define EVAS_FONT_WALK_OT_TEXT_WORK(is_visual) \
-             index = intl_props->info->glyph[char_index].index; \
+             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) \
index c85e215..0964359 100644 (file)
@@ -54,4 +54,26 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi);
 # endif
 
 # include "evas_font_default_walk.x"
+
+/**
+ * @def EVAS_FONT_WALK_TEXT_INIT
+ * @internal
+ * This macro defines the variables that will later be used with the following
+ * macros, and by font handling functions.
+ * @see EVAS_FONT_WALK_TEXT_START
+ * @see EVAS_FONT_WALK_TEXT_WORK
+ * @see EVAS_FONT_WALK_TEXT_END
+ */
+# define EVAS_FONT_WALK_TEXT_INIT() \
+        int _pen_x = 0, _pen_y = 0; \
+        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 */
+
+# define EVAS_FONT_WALK_PEN_X (EVAS_FONT_ROUND_26_6_TO_INT(_pen_x))
+# define EVAS_FONT_WALK_PEN_Y (EVAS_FONT_ROUND_26_6_TO_INT(_pen_y))
+
 #endif /* !_EVAS_FONT_PRIVATE_H */
index 0f21992..d21340c 100644 (file)
@@ -1,7 +1,6 @@
 #include "evas_common.h"
 #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"
 
 EAPI int
 evas_common_font_query_kerning(RGBA_Font_Int* fi,
@@ -105,62 +104,132 @@ evas_common_font_query_inset(RGBA_Font *fn, const Eina_Unicode *text)
   return fg->glyph_out->left;
 }
 
+/**
+ * @def _INIT_FI_AND_KERNINNG()
+ * @internal
+ * This macro inits fi and use_kerning.
+ * Assumes the following variables exist:
+ * fi, fn and use_kerning.
+ */
+#define _INIT_FI_AND_KERNING() \
+   do \
+     { \
+        fi = fn->fonts->data; \
+        /* evas_common_font_size_use(fn); */ \
+        evas_common_font_int_reload(fi); \
+        if (fi->src->current_size != fi->size) \
+          { \
+             FTLOCK(); \
+             FT_Activate_Size(fi->ft.size); \
+             FTUNLOCK(); \
+             fi->src->current_size = fi->size; \
+          } \
+        FTLOCK(); \
+        use_kerning = FT_HAS_KERNING(fi->src->ft.face); \
+        FTUNLOCK(); \
+     } \
+   while (0)
+
 /* size of the string (width and height) in pixels
- * BiDi handling: We receive the shaped string + other props from text_props,
+ * BiDi handling: We receive the shaped string + other props from intl_props,
  * We only care about the size, and the size does not depend on the visual order.
  * As long as we follow the logical string and get kerning data like we should,
  * we are fine.
  */
 
 EAPI void
-evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *text_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;
+   int use_kerning;
+   RGBA_Font_Int *fi;
    EVAS_FONT_WALK_TEXT_INIT();
+   _INIT_FI_AND_KERNING();
 
-   EVAS_FONT_WALK_TEXT_VISUAL_START()
+#ifdef OT_SUPPORT
+   if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
      {
-        EVAS_FONT_WALK_TEXT_WORK();
-        if (!visible) continue;
-        /* Keep the width because we'll need it for the last char */
-        keep_width = EVAS_FONT_WALK_WIDTH +
-           EVAS_FONT_WALK_X_OFF +
-           EVAS_FONT_WALK_X_BEAR;
-        /* Keep the previous EVAS_FONT_WALK_PEN_X, before it's advanced in TEXT_END */
-        prev_pen_x = EVAS_FONT_WALK_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 EVAS_FONT_WALK_PEN_X, before it's advanced in TEXT_END */
+             prev_pen_x = EVAS_FONT_WALK_PEN_X;
+          }
+        EVAS_FONT_WALK_OT_TEXT_END();
+     }
+   else
+#endif
+     {
+        EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_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 EVAS_FONT_WALK_PEN_X, before it's advanced in TEXT_END */
+             prev_pen_x = EVAS_FONT_WALK_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();
 }
 
 /* h & v advance
- * BiDi handling: We receive the shaped string + other props from text_props,
+ * BiDi handling: We receive the shaped string + other props from intl_props,
  * We don't care about the order, as heights will remain the same (we already did
  * shaping) and as long as we go through the logical string and match the kerning
  * this way, we are safe.
  */
 EAPI void
-evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *text_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;
    EVAS_FONT_WALK_TEXT_INIT();
+   _INIT_FI_AND_KERNING();
+#ifndef BIDI_SUPPORT
+   /* Suppress warnings */
+   (void) intl_props;
+#endif
 
-   EVAS_FONT_WALK_TEXT_LOGICAL_START()
+#ifdef OT_SUPPORT
+   if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
      {
-        EVAS_FONT_WALK_TEXT_WORK();
-        if (!visible) continue;
+        EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
+          {
+             EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
+             if (!visible) continue;
+          }
+        EVAS_FONT_WALK_OT_TEXT_END();
+     }
+   else
+#endif
+     {
+        EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START()
+          {
+             EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
+             if (!visible) continue;
+          }
+        EVAS_FONT_WALK_DEFAULT_TEXT_END();
      }
-   EVAS_FONT_WALK_TEXT_END();
 
    if (v_adv) *v_adv = evas_common_font_get_line_advance(fn);
    if (h_adv) *h_adv = EVAS_FONT_WALK_PEN_X;
+  evas_common_font_int_use_trim();
 }
 
 /* x y w h for char at char pos for null it returns the position right after
  * the last char with 0 as width and height.
- * BiDi handling: We receive the shaped string + other props from text_props,
+ * BiDi handling: We receive the shaped string + other props from intl_props,
  * We care about the actual drawing location of the string, this is why we need
  * the visual string. We need to know how it's printed. After that we need to calculate
  * the reverse kerning in case of rtl parts. "pos" passed to this function is an
@@ -169,24 +238,28 @@ 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_Text_Props *text_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;
+   const Eina_Unicode *text = in_text;
    int ret_val = 0;
+   int use_kerning;
+   RGBA_Font_Int *fi;
    EVAS_FONT_WALK_TEXT_INIT();
+   _INIT_FI_AND_KERNING();
 
    asc = evas_common_font_max_ascent_get(fn);
    desc = evas_common_font_max_descent_get(fn);
 
    position = pos;
    /* If it's the null, choose location according to the direction. */
-   if (text_props->len == position)
+   if (!text[position])
      {
         /* if it's rtl then the location is the left of the string,
          * otherwise, the right. */
 #ifdef BIDI_SUPPORT
-        if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
+        if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
           {
              if (cx) *cx = 0;
              if (ch) *ch = asc + desc;
@@ -194,7 +267,7 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
         else
 #endif
           {
-             evas_common_font_query_advance(fn, in_text, text_props, cx, ch);
+             evas_common_font_query_advance(fn, in_text, intl_props, cx, ch);
           }
         if (cy) *cy = 0;
         if (cw) *cw = 0;
@@ -202,95 +275,122 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
         goto end;
      }
 
-   Evas_Coord cluster_start, last_end;
-   int prev_cluster = -1;
-   int found = 0, items = 1, item_pos = 1;
-   int last_is_visible;
-   EVAS_FONT_WALK_TEXT_VISUAL_START()
+#ifdef OT_SUPPORT
+   if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
      {
-        EVAS_FONT_WALK_TEXT_WORK();
-
-        if (prev_cluster != (int) EVAS_FONT_WALK_POS)
+        Evas_Coord cluster_start, last_end;
+        int prev_cluster = -1;
+        int found = 0, items = 0, item_pos = 1;
+        int last_is_visible;
+        EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
           {
-             if (found)
+             EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
+
+             if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS)
                {
-                  break;
+                  if (found)
+                    {
+                       break;
+                    }
+                  else
+                    {
+                       cluster_start = EVAS_FONT_WALK_PEN_X +
+                          EVAS_FONT_WALK_OT_X_OFF +
+                          EVAS_FONT_WALK_OT_X_BEAR;
+                    }
                }
-             else
+             last_is_visible = visible;
+             last_end = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_OFF +
+                 EVAS_FONT_WALK_OT_X_BEAR + EVAS_FONT_WALK_OT_WIDTH;
+             /* 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_IS_LAST)))
                {
-                  cluster_start = EVAS_FONT_WALK_PEN_X +
-                     EVAS_FONT_WALK_X_OFF +
-                     EVAS_FONT_WALK_X_BEAR;
+                  found = 1;
+                  items = evas_common_font_ot_cluster_size_get(intl_props,
+                        char_index, EVAS_FONT_WALK_ORIG_LEN);
+                  item_pos = position - EVAS_FONT_WALK_OT_POS + 1;
                }
-          }
-        last_is_visible = visible;
-        last_end = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF +
-           EVAS_FONT_WALK_X_BEAR + EVAS_FONT_WALK_WIDTH;
-        /* we need to see if the char at the visual position is the char wanted */
-        if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
-              (EVAS_FONT_WALK_POS <= (size_t) position) &&
-              ((((size_t) position) < EVAS_FONT_WALK_POS_NEXT) ||
-               (EVAS_FONT_WALK_IS_LAST)))
-          {
-             found = 1;
-#ifdef OT_SUPPORT
-             if (evas_common_font_ot_is_enabled())
+             else if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) &&
+                   ((EVAS_FONT_WALK_OT_POS_PREV > (size_t) position) ||
+                    (EVAS_FONT_WALK_OT_IS_FIRST)) &&
+                   (((size_t) position) >= EVAS_FONT_WALK_OT_POS))
                {
-                  items = evas_common_font_ot_cluster_size_get(text_props,
-                        char_index);
+                  found = 1;
+                  items = evas_common_font_ot_cluster_size_get(intl_props,
+                        char_index, EVAS_FONT_WALK_ORIG_LEN);
+                  item_pos = items - (position - EVAS_FONT_WALK_OT_POS);
                }
-#endif
-             item_pos = position - EVAS_FONT_WALK_POS + 1;
+
+             prev_cluster = EVAS_FONT_WALK_OT_POS;
           }
-        else if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) &&
-              ((EVAS_FONT_WALK_POS_PREV > (size_t) position) ||
-               (EVAS_FONT_WALK_IS_FIRST)) &&
-              (((size_t) position) >= EVAS_FONT_WALK_POS))
+        EVAS_FONT_WALK_OT_TEXT_END();
+        if (found)
           {
-             found = 1;
-#ifdef OT_SUPPORT
-             if (evas_common_font_ot_is_enabled())
+             Evas_Coord cluster_w;
+             cluster_w = last_end - cluster_start;
+             if (cy) *cy = -asc;
+             if (ch) *ch = asc + desc;
+             if (last_is_visible)
                {
-                  items = evas_common_font_ot_cluster_size_get(text_props,
-                        char_index);
+                  if (cx) *cx = cluster_start +
+                    (cluster_w / items) *
+                       (item_pos - 1);
+                  if (cw) *cw = (cluster_w / items);
                }
-#endif
-             item_pos = items - (position - EVAS_FONT_WALK_POS);
+             else
+               {
+                  if (cx) *cx = cluster_start;
+                  if (cw) *cw = 0;
+               }
+             ret_val = 1;
+             goto end;
           }
-
-        prev_cluster = EVAS_FONT_WALK_POS;
      }
-   EVAS_FONT_WALK_TEXT_END();
-   if (found)
+   else
+#endif
      {
-        Evas_Coord cluster_w;
-        cluster_w = last_end - cluster_start;
-        if (cy) *cy = -asc;
-        if (ch) *ch = asc + desc;
-        if (last_is_visible)
-          {
-             if (cx) *cx = cluster_start +
-               (cluster_w / items) *
-                  (item_pos - 1);
-             if (cw) *cw = (cluster_w / items);
-          }
-        else
+        EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
           {
-             if (cx) *cx = cluster_start;
-             if (cw) *cw = 0;
+             int chr_x, chr_w;
+
+             EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE);
+             if (visible)
+               {
+                  chr_x = (EVAS_FONT_WALK_PEN_X) + EVAS_FONT_WALK_DEFAULT_X_OFF +
+                     EVAS_FONT_WALK_DEFAULT_X_BEAR;
+                  chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH;
+               }
+             else
+               {
+                  chr_x = EVAS_FONT_WALK_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;
+                  if (cy) *cy = -asc;
+                  if (cw) *cw = chr_w;
+                  if (ch) *ch = asc + desc;
+                  ret_val = 1;
+                  goto end;
+               }
           }
-        ret_val = 1;
-        goto end;
+        EVAS_FONT_WALK_DEFAULT_TEXT_END();
      }
 end:
 
-   return ret_val;
+  evas_common_font_int_use_trim();
+  return ret_val;
 }
 
 /* x y w h for pen at char pos for null it returns the position right after
  * the last char with 0 as width and height. This is the same as char_coords
  * but it returns the pen_x and adv instead of x and w.
- * BiDi handling: We receive the shaped string + other props from text_props,
+ * BiDi handling: We receive the shaped string + other props from intl_props,
  * We care about the actual drawing location of the string, this is why we need
  * the visual string. We need to know how it's printed. After that we need to calculate
  * the reverse kerning in case of rtl parts. "pos" passed to this function is an
@@ -299,24 +399,28 @@ end:
  */
 
 EAPI int
-evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *text_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;
+   const Eina_Unicode *text = in_text;
    int ret_val = 0;
+   int use_kerning;
+   RGBA_Font_Int *fi;
    EVAS_FONT_WALK_TEXT_INIT();
+   _INIT_FI_AND_KERNING();
 
    asc = evas_common_font_max_ascent_get(fn);
    desc = evas_common_font_max_descent_get(fn);
 
    position = pos;
    /* If it's the null, choose location according to the direction. */
-   if (text_props->len == position)
+   if (!text[position])
      {
         /* if it's rtl then the location is the left of the string,
          * otherwise, the right. */
 #ifdef BIDI_SUPPORT
-        if (text_props->bidi.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;
@@ -324,89 +428,122 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
         else
 #endif
           {
-             evas_common_font_query_advance(fn, in_text, text_props, cpen_x, ch);
+             evas_common_font_query_advance(fn, in_text, intl_props, cpen_x, ch);
           }
         if (cy) *cy = 0;
         if (cadv) *cadv = 0;
         ret_val = 1;
         goto end;
      }
-   Evas_Coord cluster_start;
-   int prev_cluster = -1;
-   int found = 0, items = 1, item_pos = 1;
-   int last_is_visible = 1;
-   EVAS_FONT_WALK_TEXT_VISUAL_START()
+#ifdef OT_SUPPORT
+   if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
      {
-        EVAS_FONT_WALK_TEXT_WORK();
-
-        if (prev_cluster != (int) EVAS_FONT_WALK_POS)
+        Evas_Coord cluster_start;
+        int prev_cluster = -1;
+        int found = 0, items = 0, item_pos = 1;
+        int last_is_visible = 1;
+        EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
           {
-             if (found)
+             EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
+
+             if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS)
                {
-                  break;
+                  if (found)
+                    {
+                       break;
+                    }
+                  else
+                    {
+                       cluster_start = EVAS_FONT_WALK_PEN_X;
+                    }
                }
-             else
+             last_is_visible = visible;
+
+             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_IS_LAST)))
                {
-                  cluster_start = EVAS_FONT_WALK_PEN_X;
+                  found = 1;
+                  items = evas_common_font_ot_cluster_size_get(intl_props,
+                        char_index, EVAS_FONT_WALK_ORIG_LEN);
+                  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_IS_FIRST)) &&
+                   (((size_t) position) >= EVAS_FONT_WALK_OT_POS))
+               {
+                  found = 1;
+                  items = evas_common_font_ot_cluster_size_get(intl_props,
+                        char_index, EVAS_FONT_WALK_ORIG_LEN);
+                  item_pos = items - (position - EVAS_FONT_WALK_OT_POS);
+               }
+
+             prev_cluster = EVAS_FONT_WALK_OT_POS;
           }
-        last_is_visible = visible;
+        EVAS_FONT_WALK_OT_TEXT_END();
 
-        if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
-              (EVAS_FONT_WALK_POS <= (size_t) position) &&
-              ((((size_t) position) < EVAS_FONT_WALK_POS_NEXT) ||
-               (EVAS_FONT_WALK_IS_LAST)))
+        if (found)
           {
-             found = 1;
-#ifdef OT_SUPPORT
-             if (evas_common_font_ot_is_enabled())
+             Evas_Coord cluster_adv;
+             cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start;
+             if (cy) *cy = -asc;
+             if (ch) *ch = asc + desc;
+             if (last_is_visible)
                {
-                  items = evas_common_font_ot_cluster_size_get(text_props,
-                        char_index);
+                  if (cpen_x) *cpen_x = cluster_start +
+                    (cluster_adv / items) *
+                       (item_pos - 1);
+                  if (cadv) *cadv = (cluster_adv / items);
                }
-#endif
-             item_pos = position - EVAS_FONT_WALK_POS + 1;
-          }
-        else if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) &&
-              ((EVAS_FONT_WALK_POS_PREV > (size_t) position) ||
-               (EVAS_FONT_WALK_IS_FIRST)) &&
-              (((size_t) position) >= EVAS_FONT_WALK_POS))
-          {
-             found = 1;
-#ifdef OT_SUPPORT
-             if (evas_common_font_ot_is_enabled())
+             else
                {
-                  items = evas_common_font_ot_cluster_size_get(text_props,
-                        char_index);
+                  if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X;
+                  if (cadv) *cadv = 0;
                }
-#endif
-             item_pos = items - (position - EVAS_FONT_WALK_POS);
+             ret_val = 1;
+             goto end;
           }
-
-        prev_cluster = EVAS_FONT_WALK_POS;
      }
-   EVAS_FONT_WALK_TEXT_END();
-
-   if (found)
+   else
+#endif
      {
-        Evas_Coord cluster_adv;
-        cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start;
-        if (cy) *cy = -asc;
-        if (ch) *ch = asc + desc;
-        if (last_is_visible)
-          {
-             if (cpen_x) *cpen_x = cluster_start +
-               (cluster_adv / items) *
-                  (item_pos - 1);
-             if (cadv) *cadv = (cluster_adv / items);
-          }
-        else
+        EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
           {
-             if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X;
-             if (cadv) *cadv = 0;
+             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 = EVAS_FONT_WALK_PEN_X;
+                            if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_X_ADV;
+                         }
+                       else
+                         {
+                            if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X +
+                              EVAS_FONT_WALK_DEFAULT_X_OFF +
+                              EVAS_FONT_WALK_DEFAULT_X_BEAR;
+                            if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_WIDTH;
+                         }
+                    }
+                  else
+                    {
+                       if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X;
+                       if (cadv) *cadv = 0;
+                    }
+                  ret_val = 1;
+                  goto end;
+               }
           }
-        ret_val = 1;
-        goto end;
+        EVAS_FONT_WALK_DEFAULT_TEXT_END();
      }
 end:
 
@@ -421,117 +558,179 @@ end:
  */
 
 EAPI int
-evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *text_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;
    int ret_val = -1;
+   int use_kerning;
+   RGBA_Font_Int *fi;
    EVAS_FONT_WALK_TEXT_INIT();
+   _INIT_FI_AND_KERNING();
+#ifndef BIDI_SUPPORT
+   /* Suppress warnings */
+   (void) intl_props;
+#endif
 
    asc = evas_common_font_max_ascent_get(fn);
    desc = evas_common_font_max_descent_get(fn);
-   Evas_Coord cluster_start;
-   int prev_cluster = -1;
-   int found = 0, items = 1;
-   EVAS_FONT_WALK_TEXT_VISUAL_START()
+#ifdef OT_SUPPORT
+   if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
      {
-        EVAS_FONT_WALK_TEXT_WORK();
-        if (prev_cluster != (int) EVAS_FONT_WALK_POS)
+        Evas_Coord cluster_start;
+        int prev_cluster = -1;
+        int found = 0, items = 0;
+        EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
           {
-             if (found)
+             EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
+             if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS)
                {
-                  break;
+                  if (found)
+                    {
+                       break;
+                    }
+                  else
+                    {
+                       cluster_start = EVAS_FONT_WALK_PEN_X;
+                    }
                }
-             else
+
+             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 >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_ADV)) &&
+                   (y >= -asc) && (y <= desc))
                {
-                  cluster_start = EVAS_FONT_WALK_PEN_X;
+                  items = evas_common_font_ot_cluster_size_get(intl_props,
+                        char_index, EVAS_FONT_WALK_ORIG_LEN);
+                  found = 1;
                }
-          }
 
-        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 >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_ADV)) &&
-              (y >= -asc) && (y <= desc))
+             prev_cluster = EVAS_FONT_WALK_OT_POS;
+          }
+        EVAS_FONT_WALK_OT_TEXT_END();
+        if (found)
           {
-#ifdef OT_SUPPORT
-             if (evas_common_font_ot_is_enabled())
+             int item_pos;
+             Evas_Coord cluster_adv;
+             cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start;
+
+             if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR)
                {
-                  items = evas_common_font_ot_cluster_size_get(text_props,
-                        char_index);
+                  double part;
+                  part = cluster_adv / items;
+                  item_pos = (int) ((x - cluster_start) / part);
                }
-#endif
-             found = 1;
+             else
+               {
+                  double part;
+                  part = cluster_adv / items;
+                  item_pos = items - ((int) ((x - cluster_start) / part)) - 1;
+               }
+             if (cx) *cx = EVAS_FONT_WALK_PEN_X +
+               ((cluster_adv / items) * (item_pos - 1));
+             if (cy) *cy = -asc;
+             if (cw) *cw = (cluster_adv / items);
+             if (ch) *ch = asc + desc;
+             ret_val = prev_cluster + item_pos;
+             goto end;
           }
-
-        prev_cluster = EVAS_FONT_WALK_POS;
      }
-   EVAS_FONT_WALK_TEXT_END();
-   if (found)
+   else
+#endif
      {
-        int item_pos;
-        Evas_Coord cluster_adv;
-        cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start;
-
-        if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR)
-          {
-             double part;
-             part = cluster_adv / items;
-             item_pos = (int) ((x - cluster_start) / part);
-          }
-        else
+        EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
           {
-             double part;
-             part = cluster_adv / items;
-             item_pos = items - ((int) ((x - cluster_start) / part)) - 1;
+             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 >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_DEFAULT_X_ADV))
+                   && (y >= -asc) && (y <= desc))
+               {
+                  if (cx) *cx = EVAS_FONT_WALK_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;
+               }
           }
-        if (cx) *cx = EVAS_FONT_WALK_PEN_X +
-          ((cluster_adv / items) * (item_pos - 1));
-        if (cy) *cy = -asc;
-        if (cw) *cw = (cluster_adv / items);
-        if (ch) *ch = asc + desc;
-        ret_val = prev_cluster + item_pos;
-        goto end;
+        EVAS_FONT_WALK_DEFAULT_TEXT_END();
      }
+
 end:
 
+   evas_common_font_int_use_trim();
    return ret_val;
 }
 
 /* position of the char after the last char in the text that will fit in xy.
- * BiDi handling: We receive the shaped string + other props from text_props,
+ * BiDi handling: We receive the shaped string + other props from intl_props,
  * All we care about is char sizes + kerning so we only really need to get the
  * shaped string to utf8, and then just go through it like in english, as it's
  * just the logical string, nothing special about that.
  */
 
 EAPI int
-evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *text_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;
+   const Eina_Unicode *text = in_text;
+   int use_kerning;
+   RGBA_Font_Int *fi;
    EVAS_FONT_WALK_TEXT_INIT();
+   _INIT_FI_AND_KERNING();
 
    asc = evas_common_font_max_ascent_get(fn);
    desc = evas_common_font_max_descent_get(fn);
 
-   EVAS_FONT_WALK_TEXT_LOGICAL_START()
+#ifdef OT_SUPPORT
+   if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
      {
-        EVAS_FONT_WALK_TEXT_WORK();
-        if (!visible) continue;
+        EVAS_FONT_WALK_OT_TEXT_LOGICAL_START()
+          {
+             EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
+             if (!visible) continue;
 
-        if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_ADV)) &&
-              (y >= -asc) && (y <= desc))
+             if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_ADV)) &&
+                   (y >= -asc) && (y <= desc))
+               {
+                  ret = EVAS_FONT_WALK_OT_POS;
+                  goto end;
+               }
+          }
+        EVAS_FONT_WALK_OT_TEXT_END();
+     }
+   else
+#endif
+     {
+        EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START()
           {
-             ret = EVAS_FONT_WALK_POS;
-             goto end;
+             EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
+             if (!visible) continue;
+
+             if ((x >= EVAS_FONT_WALK_PEN_X) &&
+                   (x <= (EVAS_FONT_WALK_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 15b21b6..026796e 100644 (file)
@@ -1,4 +1,3 @@
-#include "evas_common.h"
 #include "evas_text_utils.h"
 #include "language/evas_bidi_utils.h"
 #include "language/evas_language_utils.h"
@@ -38,34 +37,39 @@ evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst,
 void
 evas_common_text_props_content_ref(Evas_Text_Props *props)
 {
-   props->info->refcount++;
+#ifdef OT_SUPPORT
+   if (props->ot_data)
+     {
+        evas_common_font_ot_props_ref(props->ot_data);
+     }
+#endif
 }
 
 void
 evas_common_text_props_content_unref(Evas_Text_Props *props)
 {
-   /* We allow this, because sometimes we want to have props without info,
-    * and we don't want to diverge the code paths too much. */
-   if (!props->info)
-     return;
-
-   if (props->info->refcount == 0)
+#ifdef OT_SUPPORT
+   if (props->ot_data)
      {
-        ERR("Trying to unref props with refount == 0");
-        return;
+        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
+}
 
-   if (--(props->info->refcount) == 0)
-     {
-        if (props->info->glyph)
-          free(props->info->glyph);
+/* Won't work in the middle of ligatures */
+EAPI void
+evas_common_text_props_cutoff(Evas_Text_Props *props, int cutoff)
+{
 #ifdef OT_SUPPORT
-        if (props->info->ot)
-          free(props->info->ot);
+   evas_common_font_ot_cutoff_text_props(props, cutoff);
 #endif
-        free(props->info);
-        props->info = NULL;
-     }
 }
 
 /* Won't work in the middle of ligatures */
@@ -73,20 +77,12 @@ EAPI void
 evas_common_text_props_split(Evas_Text_Props *base,
       Evas_Text_Props *ext, int cutoff)
 {
-   evas_common_text_props_content_copy_and_ref(ext, base);
-   if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
-     {
-        ext->start = base->start;
-        base->start = cutoff;
-        ext->len = cutoff;
-        base->len = base->len - cutoff;
-     }
-   else
-     {
-        ext->start = cutoff;
-        ext->len = base->len - cutoff;
-        base->len = cutoff;
-     }
+   /* FIXME: move to their own functions */
+   memcpy(&ext->bidi, &base->bidi, sizeof(Evas_BiDi_Props));
+   memcpy(&ext->script, &base->script, sizeof(Evas_Script_Type));
+#ifdef OT_SUPPORT
+   evas_common_font_ot_split_text_props(base, ext, cutoff);
+#endif
 }
 
 /* Won't work in the middle of ligatures */
@@ -94,16 +90,9 @@ EAPI void
 evas_common_text_props_merge(Evas_Text_Props *item1,
       const Evas_Text_Props *item2)
 {
-   if (item1->info != item2->info)
-     {
-        ERR("tried merge back items that weren't together in the first place.");
-        return;
-     }
-   if (item1->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
-     {
-        item1->start = item2->start;
-     }
-
-   item1->len += item2->len;
+#ifdef OT_SUPPORT
+   evas_common_font_ot_merge_text_props(item1, item2);
+#endif
 }
 
+
index c8cfa38..ff18a4b 100644 (file)
@@ -2,29 +2,16 @@
 # define _EVAS_TEXT_UTILS_H
 
 typedef struct _Evas_Text_Props Evas_Text_Props;
-typedef struct _Evas_Text_Props_Info Evas_Text_Props_Info;
 
 # include "evas_font_ot.h"
 # include "language/evas_bidi_utils.h"
 # include "language/evas_language_utils.h"
-# include "evas_font_glyph_info.h"
 
 struct _Evas_Text_Props
 {
-   /* Start and len represent the start offset and the length in the
-    * glyphs_info and ot_data fields, they are both internal */
-   size_t start;
-   size_t len;
    Evas_BiDi_Props bidi;
    Evas_Script_Type script;
-   Evas_Text_Props_Info *info;
-};
-
-struct _Evas_Text_Props_Info
-{
-   unsigned int refcount;
-   Evas_Font_Glyph_Info *glyph;
-   Evas_Font_OT_Info *ot;
+   Evas_Font_OT_Data *ot_data;
 };
 
 void
@@ -46,6 +33,9 @@ void
 evas_common_text_props_content_unref(Evas_Text_Props *props);
 
 EAPI void
+evas_common_text_props_cutoff(Evas_Text_Props *props, int cutoff);
+
+EAPI void
 evas_common_text_props_split(Evas_Text_Props *base, Evas_Text_Props *ext,
       int cutoff);
 EAPI void
index 3c9692e..0a14e70 100644 (file)
@@ -1109,9 +1109,9 @@ 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
-   evas_bidi_shape_string(text, par_props, pos, len);
+   return !evas_bidi_shape_string(text, par_props, pos, len);
 #endif
-   return evas_common_font_glyph_info_create(font, text, intl_props, len);
+   return EINA_TRUE;
 }
 
 static int
index 6aa7ce8..999198d 100644 (file)
@@ -543,23 +543,17 @@ eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *t
 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_glyph_info_create(font, text, intl_props, len);
+        return evas_common_font_ot_populate_text_props(font, text,
+              intl_props, len);
      }
    else
 #endif
      {
 #ifdef BIDI_SUPPORT
-        evas_bidi_shape_string(text, par_props, pos, len);
-        return evas_common_font_glyph_info_create(font, text, intl_props, len);
+        return !evas_bidi_shape_string(text, par_props, pos, len);
 #endif
      }
    return EINA_TRUE;
index 8db0f4d..e6d6db2 100644 (file)
@@ -601,23 +601,17 @@ eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *t
 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_glyph_info_create(font, text, intl_props, len);
+        return evas_common_font_ot_populate_text_props(font, text,
+              intl_props, len);
      }
    else
 #endif
      {
 #ifdef BIDI_SUPPORT
-        evas_bidi_shape_string(text, par_props, pos, len);
-        return evas_common_font_glyph_info_create(font, text, intl_props, len);
+        return !evas_bidi_shape_string(text, par_props, pos, len);
 #endif
      }
    return EINA_TRUE;
index f66cc1c..fe87137 100644 (file)
@@ -722,7 +722,8 @@ eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_
 #ifdef OT_SUPPORT
    if (evas_common_font_ot_is_enabled())
      {
-        return evas_common_font_glyph_info_create(font, text, intl_props, len);
+        return evas_common_font_ot_populate_text_props(font, text,
+              intl_props, len);
      }
    else
 #endif