forked from old/legacy-imlib2
parent
c8f22c965e
commit
b9c591d390
|
@ -327,6 +327,10 @@ extern "C"
|
|||
/* 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,
|
||||
|
|
|
@ -3092,7 +3092,7 @@ imlib_load_font(const char *font_name)
|
|||
}
|
||||
|
||||
/**
|
||||
* 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,10 +3100,58 @@ imlib_free_font(void)
|
|||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x The x coordinate of the top left corner.
|
||||
* @param y The y coordinate of the top left corner.
|
||||
|
|
|
@ -50,6 +50,9 @@ struct _Imlib_Font
|
|||
|
||||
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 @@ char **imlib_font_list_fonts(int *num_ret);
|
|||
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);
|
||||
|
|
|
@ -245,6 +245,31 @@ imlib_render_str(ImlibImage * im, ImlibFont * fn, int drx, int dry,
|
|||
/* 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 @@ imlib_font_draw(ImlibImage * dst, DATA32 col, ImlibFont * fn, int x, int y,
|
|||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -185,6 +185,9 @@ imlib_font_load(const char *name, int size)
|
|||
|
||||
fn->references = 1;
|
||||
|
||||
fn->fallback_prev = NULL;
|
||||
fn->fallback_next = NULL;
|
||||
|
||||
fonts = imlib_object_list_prepend(fonts, fn);
|
||||
return fn;
|
||||
}
|
||||
|
@ -200,6 +203,36 @@ imlib_font_free(ImlibFont * fn)
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
font_modify_cache_cb(Imlib_Hash * hash, const char *key, void *data,
|
||||
void *fdata)
|
||||
|
|
|
@ -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 @@ imlib_font_query_size(ImlibFont * fn, const char *text, int *w, int *h)
|
|||
{
|
||||
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 @@ imlib_font_query_size(ImlibFont * fn, const char *text, int *w, int *h)
|
|||
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 @@ imlib_font_query_inset(ImlibFont * fn, const char *text)
|
|||
{
|
||||
FT_UInt index;
|
||||
Imlib_Font_Glyph *fg;
|
||||
ImlibFont *fn_in_chain;
|
||||
int chr;
|
||||
int gl;
|
||||
|
||||
|
@ -89,8 +94,8 @@ imlib_font_query_inset(ImlibFont * fn, const char *text)
|
|||
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 @@ imlib_font_query_advance(ImlibFont * fn, const char *text, int *h_adv,
|
|||
{
|
||||
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 @@ imlib_font_query_advance(ImlibFont * fn, const char *text, int *h_adv,
|
|||
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 @@ imlib_font_query_char_coords(ImlibFont * fn, const char *text, int pos,
|
|||
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 @@ imlib_font_query_char_coords(ImlibFont * fn, const char *text, int pos,
|
|||
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 @@ imlib_font_query_text_at_pos(ImlibFont * fn, const char *text, int x, int y,
|
|||
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 @@ imlib_font_query_text_at_pos(ImlibFont * fn, const char *text, int x, int y,
|
|||
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue