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