Enlightenment CVS committal

Author  : raster
Project : e17
Module  : libs/imlib2

Dir     : e17/libs/imlib2/src/lib


Modified Files:
        Imlib2.h api.c font.h font_draw.c font_load.c font_query.c 


Log Message:


font chaining patch

===================================================================
RCS file: /cvs/e/e17/libs/imlib2/src/lib/Imlib2.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -3 -r1.5 -r1.6
--- Imlib2.h    6 Sep 2006 07:40:33 -0000       1.5
+++ Imlib2.h    23 Jul 2007 14:27:44 -0000      1.6
@@ -327,6 +327,10 @@
 /* fonts and text */
    EAPI Imlib_Font imlib_load_font(const char *font_name);
    EAPI void imlib_free_font(void);
+   EAPI int imlib_insert_font_into_fallback_chain(Imlib_Font font, Imlib_Font 
fallback_font);
+   EAPI void imlib_remove_font_from_fallback_chain(Imlib_Font fallback_font);
+   EAPI Imlib_Font imlib_get_prev_font_in_fallback_chain(Imlib_Font fn);
+   EAPI Imlib_Font imlib_get_next_font_in_fallback_chain(Imlib_Font fn);
    EAPI void imlib_text_draw(int x, int y, const char *text);
    EAPI void imlib_text_draw_with_return_metrics(int x, int y, const char 
*text,
                                                  int *width_return,
===================================================================
RCS file: /cvs/e/e17/libs/imlib2/src/lib/api.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -3 -r1.15 -r1.16
--- api.c       20 May 2007 13:26:25 -0000      1.15
+++ api.c       23 Jul 2007 14:27:44 -0000      1.16
@@ -3092,7 +3092,7 @@
 }
 
 /**
- * Frees the current font.
+ * Removes the current font from any fallback chain it's in and frees it.
  **/
 EAPI void
 imlib_free_font(void)
@@ -3100,8 +3100,56 @@
    if (!ctx)
       ctx = imlib_context_new();
    CHECK_PARAM_POINTER("imlib_free_font", "font", ctx->font);
+   imlib_remove_font_from_fallback_chain(ctx->font);
    imlib_font_free(ctx->font);
    ctx->font = NULL;
+}
+
+
+/**
+ * @param font A previously loaded font.
+ * @param fallback_font A previously loaded font to be chained to the given 
font.
+ * @return 0 on success.
+ *
+ * This arranges for the given fallback font to be used if a glyph does not 
exist in the given font when text is being rendered.
+ * Fonts can be arranged in an aribitrarily long chain and attempts will be 
made in order on the chain.
+ * Cycles in the chain are not possible since the given fallback font is 
removed from any chain it's already in.
+ * A fallback font may be a member of only one chain.  Adding it as the 
fallback font to another font will remove it from it's first fallback chain.
+ **/
+EAPI int 
+imlib_insert_font_into_fallback_chain(Imlib_Font font, Imlib_Font 
fallback_font)
+{
+   CHECK_PARAM_POINTER_RETURN("imlib_insert_font_into_fallback_chain", "font", 
font, 1);
+   CHECK_PARAM_POINTER_RETURN("imlib_insert_font_into_fallback_chain", 
"fallback_font", fallback_font, 1);
+   return imlib_insert_font_into_fallback_chain_imp(font,fallback_font);
+}
+
+/**
+ * @param fallback_font A font previously added to a fallback chain
+ * @return 0 on success.
+ *
+ * This removes the given font from any fallback chain it may be in.
+ * Removing this font joins its previous and next font together in the 
fallback chain.
+ **/
+EAPI void 
+imlib_remove_font_from_fallback_chain(Imlib_Font fallback_font)
+{
+   CHECK_PARAM_POINTER("imlib_remove_font_from_fallback_chain", 
"fallback_font", fallback_font);
+   imlib_remove_font_from_fallback_chain_imp(fallback_font);
+}
+
+EAPI Imlib_Font 
+imlib_get_prev_font_in_fallback_chain(Imlib_Font fn)
+{
+   CHECK_PARAM_POINTER_RETURN("imlib_get_prev_font_in_fallback_chain", "fn", 
fn, 0);
+   return ((ImlibFont*)fn)->fallback_prev;
+}
+
+EAPI Imlib_Font 
+imlib_get_next_font_in_fallback_chain(Imlib_Font fn)
+{
+   CHECK_PARAM_POINTER_RETURN("imlib_get_next_font_in_fallback_chain", "fn", 
fn, 0);
+   return ((ImlibFont*)fn)->fallback_next;
 }
 
 /**
===================================================================
RCS file: /cvs/e/e17/libs/imlib2/src/lib/font.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -3 -r1.3 -r1.4
--- font.h      19 May 2007 18:32:34 -0000      1.3
+++ font.h      23 Jul 2007 14:27:44 -0000      1.4
@@ -50,6 +50,9 @@
 
    int                 references;
 
+   /* using a double-linked list for the fallback chain */
+   struct _Imlib_Font  *fallback_prev;
+   struct _Imlib_Font  *fallback_next;
 };
 
 struct _Imlib_Font_Glyph
@@ -76,6 +79,8 @@
 ImlibFont          *imlib_font_load_joined(const char *name);
 ImlibFont          *imlib_font_load(const char *name, int size);
 void                imlib_font_free(ImlibFont * fn);
+int                 imlib_insert_font_into_fallback_chain_imp(ImlibFont * fn, 
ImlibFont *fallback);
+void                imlib_remove_font_from_fallback_chain_imp(ImlibFont * fn);
 int                 imlib_font_cache_get(void);
 void                imlib_font_cache_set(int size);
 void                imlib_font_flush(void);
===================================================================
RCS file: /cvs/e/e17/libs/imlib2/src/lib/font_draw.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -3 -r1.9 -r1.10
--- font_draw.c 20 May 2007 13:26:25 -0000      1.9
+++ font_draw.c 23 Jul 2007 14:27:44 -0000      1.10
@@ -245,6 +245,31 @@
    /* TODO this function is purely my art -- check once more */
 }
 
+/* 
+ * This function returns the first font in the fallback chain to contain the 
requested glyph.
+ * The glyph index is returned in ret_index
+ * If the glyph is not found, then the given font pointer is returned and 
ret_index will be set to 0
+ */
+ImlibFont *
+imlib_find_glyph_in_font_chain(ImlibFont * first_fn, int gl, int *ret_index)
+{
+       ImlibFont *fn = first_fn;
+       do 
+       {
+               int index = FT_Get_Char_Index(fn->ft.face, gl);
+               if(index<=0)
+                       fn = fn->fallback_next;
+               else
+               {
+                       (*ret_index) = index;
+                       return fn;
+               }
+       } while(fn);
+
+       (*ret_index) = 0;
+       return first_fn;
+}
+
 void
 imlib_font_draw(ImlibImage * dst, DATA32 col, ImlibFont * fn, int x, int y,
                 const char *text, int *nextx, int *nexty, int clx, int cly,
@@ -310,22 +335,23 @@
      {
         FT_UInt             index;
         Imlib_Font_Glyph   *fg;
+       ImlibFont          *fn_in_chain;
         int                 chr_x, chr_y;
         int                 gl;
 
         gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
         if (gl == 0)
            break;
-        index = FT_Get_Char_Index(fn->ft.face, gl);
+       fn_in_chain = imlib_find_glyph_in_font_chain(fn, gl, &index);
         if ((use_kerning) && (prev_index) && (index))
           {
              FT_Vector           delta;
 
-             FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
+             FT_Get_Kerning(fn_in_chain->ft.face, prev_index, index, 
ft_kerning_default,
                             &delta);
              pen_x += delta.x << 2;
           }
-        fg = imlib_font_cache_glyph_get(fn, index);
+        fg = imlib_font_cache_glyph_get(fn_in_chain, index);
         if (!fg)
            continue;
 
===================================================================
RCS file: /cvs/e/e17/libs/imlib2/src/lib/font_load.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -3 -r1.3 -r1.4
--- font_load.c 19 May 2007 18:32:34 -0000      1.3
+++ font_load.c 23 Jul 2007 14:27:44 -0000      1.4
@@ -185,6 +185,9 @@
 
    fn->references = 1;
 
+   fn->fallback_prev = NULL;
+   fn->fallback_next = NULL;
+
    fonts = imlib_object_list_prepend(fonts, fn);
    return fn;
 }
@@ -198,6 +201,36 @@
         imlib_font_modify_cache_by(fn, 1);
         imlib_font_flush();
      }
+}
+
+int
+imlib_insert_font_into_fallback_chain_imp(ImlibFont * fn, ImlibFont *fallback)
+{
+       /* avoid infinite recursion */
+       if(fn == fallback)
+               return 1; 
+       
+       /* now remove the given fallback font from any chain it's already in */
+       imlib_remove_font_from_fallback_chain_imp(fallback);
+
+       /* insert fallback into fn's font chain */
+       ImlibFont *tmp=fn->fallback_next;
+       fn->fallback_next = fallback;
+       fallback->fallback_prev = fn;
+       fallback->fallback_next = tmp;
+       if (tmp)
+               tmp->fallback_prev = fallback;
+       return 0;
+}
+
+void
+imlib_remove_font_from_fallback_chain_imp(ImlibFont *fn)
+{
+       /* if fn has a previous font in its font chain, then make its 
fallback_next fn's fallback_next since fn is going away */
+       if(fn->fallback_prev)
+               fn->fallback_prev->fallback_next=fn->fallback_next;
+       fn->fallback_prev = NULL;
+       fn->fallback_next = NULL;
 }
 
 static int
===================================================================
RCS file: /cvs/e/e17/libs/imlib2/src/lib/font_query.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -3 -r1.3 -r1.4
--- font_query.c        19 May 2007 18:32:34 -0000      1.3
+++ font_query.c        23 Jul 2007 14:27:44 -0000      1.4
@@ -15,6 +15,9 @@
 #include "rgbadraw.h"
 #include "rotate.h"
 
+extern ImlibFont *
+imlib_find_glyph_in_font_chain(ImlibFont * first_fn, int gl, int *ret_index); 
/* defined in font_draw.c */
+
 extern FT_Library   ft_lib;
 
 /* string extents */
@@ -37,22 +40,23 @@
      {
         FT_UInt             index;
         Imlib_Font_Glyph   *fg;
+       ImlibFont         *fn_in_chain;
         int                 chr_x, chr_y, chr_w;
         int                 gl;
 
         gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
         if (gl == 0)
            break;
-        index = FT_Get_Char_Index(fn->ft.face, gl);
+       fn_in_chain = imlib_find_glyph_in_font_chain(fn, gl, &index);
         if ((use_kerning) && (prev_index) && (index))
           {
              FT_Vector           delta;
 
-             FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
+             FT_Get_Kerning(fn_in_chain->ft.face, prev_index, index, 
ft_kerning_default,
                             &delta);
              pen_x += delta.x << 2;
           }
-        fg = imlib_font_cache_glyph_get(fn, index);
+        fg = imlib_font_cache_glyph_get(fn_in_chain, index);
         if (!fg)
            continue;
 
@@ -71,7 +75,7 @@
    if (w)
       *w = (pen_x >> 8) - start_x;
    if (h)
-      *h = imlib_font_max_ascent_get(fn) - imlib_font_max_descent_get(fn);
+      *h = imlib_font_max_ascent_get(fn) - imlib_font_max_descent_get(fn); /* 
TODO: compute this inside the loop since we now may be dealing with multiple 
fonts */
 }
 
 /* text x inset */
@@ -80,6 +84,7 @@
 {
    FT_UInt             index;
    Imlib_Font_Glyph   *fg;
+   ImlibFont         *fn_in_chain;
    int                 chr;
    int                 gl;
 
@@ -89,8 +94,8 @@
    gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
    if (gl == 0)
       return 0;
-   index = FT_Get_Char_Index(fn->ft.face, gl);
-   fg = imlib_font_cache_glyph_get(fn, index);
+   fn_in_chain = imlib_find_glyph_in_font_chain(fn, gl, &index);
+   fg = imlib_font_cache_glyph_get(fn_in_chain, index);
    if (!fg)
       return 0;
    return -fg->glyph_out->left;
@@ -116,22 +121,23 @@
      {
         FT_UInt             index;
         Imlib_Font_Glyph   *fg;
+       ImlibFont         *fn_in_chain;
         int                 chr_x, chr_y, chr_w;
         int                 gl;
 
         gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
         if (gl == 0)
            break;
-        index = FT_Get_Char_Index(fn->ft.face, gl);
+       fn_in_chain = imlib_find_glyph_in_font_chain(fn, gl, &index);
         if ((use_kerning) && (prev_index) && (index))
           {
              FT_Vector           delta;
 
-             FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
+             FT_Get_Kerning(fn_in_chain->ft.face, prev_index, index, 
ft_kerning_default,
                             &delta);
              pen_x += delta.x << 2;
           }
-        fg = imlib_font_cache_glyph_get(fn, index);
+        fg = imlib_font_cache_glyph_get(fn_in_chain, index);
         if (!fg)
            continue;
 
@@ -143,7 +149,7 @@
         prev_index = index;
      }
    if (v_adv)
-      *v_adv = imlib_font_get_line_advance(fn);
+      *v_adv = imlib_font_get_line_advance(fn); /* TODO: compute this in the 
loop since we may be dealing with multiple fonts */
    if (h_adv)
       *h_adv = (pen_x >> 8) - start_x;
 }
@@ -172,6 +178,7 @@
         int                 pchr;
         FT_UInt             index;
         Imlib_Font_Glyph   *fg;
+       ImlibFont         *fn_in_chain;
         int                 chr_x, chr_y, chr_w;
         int                 gl, kern;
         FT_Vector           delta;
@@ -180,16 +187,16 @@
         gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
         if (gl == 0)
            break;
-        index = FT_Get_Char_Index(fn->ft.face, gl);
+       fn_in_chain = imlib_find_glyph_in_font_chain(fn, gl, &index);
         kern = 0;
         if ((use_kerning) && (prev_index) && (index))
           {
-             FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
+             FT_Get_Kerning(fn_in_chain->ft.face, prev_index, index, 
ft_kerning_default,
                             &delta);
              kern = delta.x << 2;
              pen_x += kern;
           }
-        fg = imlib_font_cache_glyph_get(fn, index);
+        fg = imlib_font_cache_glyph_get(fn_in_chain, index);
         if (!fg)
            continue;
 
@@ -254,6 +261,7 @@
         int                 pchr;
         FT_UInt             index;
         Imlib_Font_Glyph   *fg;
+       ImlibFont         *fn_in_chain;
         int                 chr_x, chr_y, chr_w;
         int                 gl, kern;
         FT_Vector           delta;
@@ -262,16 +270,16 @@
         gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
         if (gl == 0)
            break;
-        index = FT_Get_Char_Index(fn->ft.face, gl);
+       fn_in_chain = imlib_find_glyph_in_font_chain(fn, gl, &index);
         kern = 0;
         if ((use_kerning) && (prev_index) && (index))
           {
-             FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
+             FT_Get_Kerning(fn_in_chain->ft.face, prev_index, index, 
ft_kerning_default,
                             &delta);
              kern = delta.x << 2;
              pen_x += kern;
           }
-        fg = imlib_font_cache_glyph_get(fn, index);
+        fg = imlib_font_cache_glyph_get(fn_in_chain, index);
         if (!fg)
            continue;
 



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to