fontset patch from winfred

SVN revision: 29880
This commit is contained in:
Carsten Haitzler 2007-05-06 13:54:43 +00:00
parent f30c5145f7
commit 82e00e2412
9 changed files with 447 additions and 150 deletions

View File

@ -1468,9 +1468,10 @@ and vertically)</blockquote>
<blockquote>This function will load a truetype font from the first directory <blockquote>This function will load a truetype font from the first directory
in the font path that contains that font. The font name format is "font_name/size". in the font path that contains that font. The font name format is "font_name/size".
For example. If there is a font file called blum.ttf somewhere in the font For example: if there is a font file called blum.ttf somewhere in the font
path you might use "blum/20" to load a 20 pixel sized font of blum. If path you might use "blum/20" to load a 20 pixel sized font of blum;&nbsp;
the font cannot be found NULL is returned.</blockquote> or "blum/20, vera/20, mono/20" to load one or all fonts of the comma
separated list. If the font cannot be found NULL is returned.</blockquote>
<b><tt><font color="#660000"><font size=+2>void imlib_free_font(void);</font></font></tt></b> <b><tt><font color="#660000"><font size=+2>void imlib_free_font(void);</font></font></tt></b>

View File

@ -3078,16 +3078,21 @@ imlib_image_tile(void)
* @return NULL if no font found. * @return NULL if no font found.
* *
* Loads a truetype font from the first directory in the font path that * Loads a truetype font from the first directory in the font path that
* contains that font. The font name @p font_name format is "font_name/size". For * contains that font. The font name @p font_name format is "font_name/size"
* example. If there is a font file called blum.ttf somewhere in the * or a comma separated list of "font_name/size" elements.
* For example: if there is a font file called blum.ttf somewhere in the
* font path you might use "blum/20" to load a 20 pixel sized font of * font path you might use "blum/20" to load a 20 pixel sized font of
* blum. If the font cannot be found NULL is returned. * blum;&nbsp; or "blum/20, vera/20, mono/20" to load one or all fonts
* of the comma separated list. If the font cannot be found NULL is returned.
* *
**/ **/
EAPI Imlib_Font EAPI Imlib_Font
imlib_load_font(const char *font_name) imlib_load_font(const char *font_name)
{ {
return imlib_font_load_joined(font_name); if(strchr(font_name, ',') != NULL)
return imlib_font_load_fontset(font_name);
else
return imlib_font_load_joined(font_name);
} }
/** /**
@ -3096,11 +3101,20 @@ imlib_load_font(const char *font_name)
EAPI void EAPI void
imlib_free_font(void) imlib_free_font(void)
{ {
ImlibFont *fn;
if (!ctx) if (!ctx)
ctx = imlib_context_new(); ctx = imlib_context_new();
CHECK_PARAM_POINTER("imlib_free_font", "font", ctx->font); CHECK_PARAM_POINTER("imlib_free_font", "font", ctx->font);
imlib_font_free(ctx->font);
ctx->font = NULL; fn = (ImlibFont*)ctx->font; ctx->font = NULL;
if(fn->next_in_set == NULL)
{
imlib_font_free(fn);
return;
}
imlib_font_free_fontset(fn);
} }
/** /**

View File

@ -1,3 +1,4 @@
#include <math.h>
#include "color_helpers.h" #include "color_helpers.h"
/* /*
* Color space conversion helper routines * Color space conversion helper routines

View File

@ -50,6 +50,7 @@ struct _Imlib_Font
int references; int references;
struct _Imlib_Font *next_in_set;
}; };
struct _Imlib_Font_Glyph struct _Imlib_Font_Glyph
@ -83,6 +84,12 @@ void imlib_font_modify_cache_by(ImlibFont * fn, int dir);
void imlib_font_modify_cache_by(ImlibFont * fn, int dir); void imlib_font_modify_cache_by(ImlibFont * fn, int dir);
void imlib_font_flush_last(void); void imlib_font_flush_last(void);
ImlibFont *imlib_font_find(const char *name, int size); ImlibFont *imlib_font_find(const char *name, int size);
ImlibFont *imlib_font_load_fontset(const char *font_name);
void imlib_font_free_fontset(ImlibFont *fn_list);
ImlibFont *imlib_font_find_face_in_fontset(ImlibFont *fn,
ImlibFont *fn_list, unsigned long uni_id,
int encoding_id, int force_missing_glyph,
FT_UInt *out_glyph_id, int *out_missing);
void imlib_font_query_size(ImlibFont * fn, const char *text, void imlib_font_query_size(ImlibFont * fn, const char *text,
int *w, int *h); int *w, int *h);

View File

@ -67,7 +67,7 @@ imlib_font_cache_glyph_get(ImlibFont * fn, FT_UInt index)
} }
void void
imlib_render_str(ImlibImage * im, ImlibFont * fn, int drx, int dry, imlib_render_str(ImlibImage * im, ImlibFont *fn_list, int drx, int dry,
const char *text, DATA8 r, DATA8 g, DATA8 b, DATA8 a, const char *text, DATA8 r, DATA8 g, DATA8 b, DATA8 a,
char dir, double angle, int *retw, int *reth, int blur, char dir, double angle, int *retw, int *reth, int blur,
int *nextx, int *nexty, ImlibOp op, int clx, int cly, int *nextx, int *nexty, ImlibOp op, int clx, int cly,
@ -78,8 +78,9 @@ imlib_render_str(ImlibImage * im, ImlibFont * fn, int drx, int dry,
DATA32 *data, col; DATA32 *data, col;
int nx, ny; int nx, ny;
imlib_font_query_advance(fn, text, &w, NULL); imlib_font_query_advance(fn_list, text, &w, NULL);
h = imlib_font_max_ascent_get(fn) - imlib_font_max_descent_get(fn); h = imlib_font_max_ascent_get(fn_list)
- imlib_font_max_descent_get(fn_list);
data = malloc(w * h * sizeof(DATA32)); data = malloc(w * h * sizeof(DATA32));
if (!data) if (!data)
@ -97,10 +98,10 @@ imlib_render_str(ImlibImage * im, ImlibFont * fn, int drx, int dry,
/* TODO check for endianess */ /* TODO check for endianess */
col = (a << 24) | (r << 16) | (g << 8) | b; col = (a << 24) | (r << 16) | (g << 8) | b;
ascent = imlib_font_max_ascent_get(fn); ascent = imlib_font_max_ascent_get(fn_list);
imlib_font_draw(im2, col, fn, 0, ascent, text, &nx, &ny, 0, 0, w, h);
imlib_font_draw(im2, col, fn_list, 0, ascent, text, &nx, &ny, clx, cly,
clw, clh);
/* OK, now we have small ImlibImage with text rendered, /* OK, now we have small ImlibImage with text rendered,
* have to blend it on im */ * have to blend it on im */
@ -246,13 +247,13 @@ imlib_render_str(ImlibImage * im, ImlibFont * fn, int drx, int dry,
} }
void void
imlib_font_draw(ImlibImage * dst, DATA32 col, ImlibFont * fn, int x, int y, imlib_font_draw(ImlibImage * dst, DATA32 col, ImlibFont *fn_list, int x, int y,
const char *text, int *nextx, int *nexty, int clx, int cly, const char *text, int *nextx, int *nexty, int clx, int cly,
int clw, int clh) int clw, int clh)
{ {
int use_kerning; ImlibFont *fn;
int pen_x, pen_y; int pen_x, pen_y;
int chr; int chr, missing_glyph;
FT_UInt prev_index; FT_UInt prev_index;
int ext_x, ext_y, ext_w, ext_h; int ext_x, ext_y, ext_w, ext_h;
DATA32 *im; DATA32 *im;
@ -304,8 +305,8 @@ imlib_font_draw(ImlibImage * dst, DATA32 col, ImlibFont * fn, int x, int y,
pen_x = x << 8; pen_x = x << 8;
pen_y = y << 8; pen_y = y << 8;
use_kerning = FT_HAS_KERNING(fn->ft.face); prev_index = 0; fn = NULL; missing_glyph = 1;
prev_index = 0;
for (chr = 0; text[chr];) for (chr = 0; text[chr];)
{ {
FT_UInt index; FT_UInt index;
@ -316,18 +317,24 @@ imlib_font_draw(ImlibImage * dst, DATA32 col, ImlibFont * fn, int x, int y,
gl = imlib_font_utf8_get_next((unsigned char *)text, &chr); gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
if (gl == 0) if (gl == 0)
break; break;
index = FT_Get_Char_Index(fn->ft.face, gl); if(missing_glyph)
if ((use_kerning) && (prev_index) && (index)) fn = fn_list;
{ fn =
FT_Vector delta; imlib_font_find_face_in_fontset(fn, fn_list, gl,
FT_ENCODING_UNICODE, 0, &index, &missing_glyph);
FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default, if(FT_HAS_KERNING(fn->ft.face) && (prev_index) && (index))
&delta); {
pen_x += delta.x << 2; FT_Vector delta;
FT_Get_Kerning(fn->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, index);
if (!fg) if(!fg)
continue; continue;
chr_x = (pen_x + (fg->glyph_out->left << 8)) >> 8; chr_x = (pen_x + (fg->glyph_out->left << 8)) >> 8;
chr_y = (pen_y + (fg->glyph_out->top << 8)) >> 8; chr_y = (pen_y + (fg->glyph_out->top << 8)) >> 8;
@ -418,5 +425,5 @@ imlib_font_draw(ImlibImage * dst, DATA32 col, ImlibFont * fn, int x, int y,
if (nextx) if (nextx)
*nextx = (pen_x >> 8) - x; *nextx = (pen_x >> 8) - x;
if (nexty) if (nexty)
*nexty = imlib_font_get_line_advance(fn); *nexty = imlib_font_get_line_advance(fn_list);
} }

View File

@ -30,13 +30,13 @@ static int font_flush_free_glyph_cb(Imlib_Hash * hash, const char *key,
/* FIXME now! listdir() from evas_object_text.c */ /* FIXME now! listdir() from evas_object_text.c */
/* separate fontname and size, find font file, start imlib_font_load() then */ /* separate fontname and size, find font file
ImlibFont * */
imlib_font_load_joined(const char *fontname) static char*
imlib_font_find_file(const char *fontname, int *out_size)
{ {
int j, size; int j, size;
char *name = NULL, *file = NULL, *tmp = NULL; char *name = NULL, *file = NULL, *tmp = NULL;
ImlibFont *fn;
/* split font name (in format name/size) */ /* split font name (in format name/size) */
for (j = strlen(fontname) - 1; (j >= 0) && (fontname[j] != '/'); j--); for (j = strlen(fontname) - 1; (j >= 0) && (fontname[j] != '/'); j--);
@ -103,7 +103,20 @@ imlib_font_load_joined(const char *fontname)
free(tmp); free(tmp);
} }
} }
free(name); free(name); *out_size = size;
return file;
}
/* find font file, start imlib_font_load() */
ImlibFont *
imlib_font_load_joined(const char *fontname)
{
char *file;
ImlibFont *fn;
int size;
file = imlib_font_find_file(fontname, &size);
/* didnt find a file? abort */ /* didnt find a file? abort */
if (!file) if (!file)
return NULL; return NULL;
@ -112,17 +125,13 @@ imlib_font_load_joined(const char *fontname)
return fn; return fn;
} }
ImlibFont * static ImlibFont *
imlib_font_load(const char *name, int size) imlib_font_create_font_struct(const char *name, int size)
{ {
int error; int error;
ImlibFont *fn; ImlibFont *fn;
char *file; char *file;
fn = imlib_font_find(name, size);
if (fn)
return fn;
imlib_font_init(); imlib_font_init();
fn = malloc(sizeof(ImlibFont)); fn = malloc(sizeof(ImlibFont));
@ -180,15 +189,193 @@ imlib_font_load(const char *name, int size)
fn->size = size; fn->size = size;
fn->glyphs = NULL; fn->glyphs = NULL;
fn->next_in_set = NULL;
fn->usage = 0; fn->usage = 0;
fn->references = 1; fn->references = 1;
fonts = imlib_object_list_prepend(fonts, fn);
return fn; return fn;
} }
ImlibFont *
imlib_font_load(const char *name, int size)
{
ImlibFont *fn;
fn = imlib_font_find(name, size);
if (fn)
return fn;
if((fn = imlib_font_create_font_struct(name, size)) != NULL)
fonts = imlib_object_list_prepend(fonts, fn);
return fn;
}
#define MAX_FONTNAMES 31
static char *skip_white(char *s)
{
while(isspace(*s)) ++s;
return s;
}
/* Skip duplicates */
static void collect_fontnames(const char *fon_s, char *names[])
{
char *s, *comma, *buf, *last, *name;
int i, j;
buf = strdup(fon_s);
i = 0;
s = skip_white(buf);
while(*s)
{
names[i] = NULL;
if((comma = strchr(s, ',')))
*comma = 0;
last = s + strlen(s) - 1;
while(last > s && isspace(*last)) --last; *++last = 0;
j = 0;
while((name = names[j]) != NULL)
{
if(strcmp(name, s) == 0)
break;
++j;
}
if(name == NULL)
{
names[i] = strdup(s);
if(++i > MAX_FONTNAMES)
break;
}
if(comma == NULL)
break;
s = skip_white(comma + 1);
}
names[i] = NULL; free(buf);
}
/* font_name contains a comma separated list of "name/size" elements.
* sets must be disjoint: if two sets begin with the same font,
* the existing set's chain would be destroyed.
*/
ImlibFont *
imlib_font_load_fontset(const char *font_name)
{
ImlibFont *head, *tail, *fn;
char *name, *file;
int i, size;
char *names[MAX_FONTNAMES + 1];
collect_fontnames(font_name, names);
if(names[0] == NULL)
return NULL;
head = tail = NULL; i = 0;
while((name = names[i]))
{
if((file = imlib_font_find_file(name, &size)) != NULL)
{
if((fn = imlib_font_create_font_struct(file, size)) != NULL)
{
if(tail)
tail->next_in_set = fn;
else
head = fn;
tail = fn;
}
free(file);
}
free(name); ++i;
}
return head;
}
ImlibFont *
imlib_font_find_face_in_fontset(ImlibFont *fn, ImlibFont *fn_list,
unsigned long uni_id, int encoding_id,
int force_missing_glyph, FT_UInt *out_glyph_id,
int *out_missing)
{
FT_Face face;
FT_UInt glyph_id;
ImlibFont *first_invalid;
if(!fn)
fn = fn_list;
if(out_missing)
*out_missing = 0;
if(fn->ft.face == NULL)
{
FT_New_Face(ft_lib, fn->file, 0, &face);
fn->ft.face = face;
}
first_invalid = NULL;
repeat_upto_invalid:
while(fn)
{
if(fn == first_invalid)
{
first_invalid = NULL;
break;
}
face = fn->ft.face;
if(face->charmap != NULL
|| FT_Select_Charmap(face, encoding_id) == 0
)
{
FT_Set_Char_Size(face, 0, fn->size * 64, 96, 96);
if(force_missing_glyph)
glyph_id = 0;
else
glyph_id = FT_Get_Char_Index(face, uni_id);
if(glyph_id || force_missing_glyph)
{
*out_glyph_id = glyph_id;
return fn;
}
if(first_invalid == NULL)
first_invalid = fn;
}
fn = fn->next_in_set;
}/* while(fn) */
if(first_invalid)
{
fn = fn_list;
goto repeat_upto_invalid;
}
if(out_missing)
*out_missing = 1;
return
imlib_font_find_face_in_fontset(NULL, fn_list, 0, encoding_id, 1,
out_glyph_id, NULL);
}
void
imlib_font_free_fontset(ImlibFont *fn_list)
{
ImlibFont *fn;
while((fn = fn_list))
{
fn_list = fn_list->next_in_set;
/* imlib_font_free(fn); */
imlib_hash_free(fn->glyphs);
if (fn->file)
free(fn->file);
if (fn->name)
free(fn->name);
FT_Done_Face(fn->ft.face);
free(fn);
}
}
void void
imlib_font_free(ImlibFont * fn) imlib_font_free(ImlibFont * fn)
{ {

View File

@ -38,78 +38,130 @@ imlib_font_init(void)
} }
int int
imlib_font_ascent_get(ImlibFont * fn) imlib_font_ascent_get(ImlibFont *fn_list)
{ {
int val; ImlibFont *fn;
int ret; int val;
int ret, maxret;
maxret = 0; fn = fn_list;
while(fn)
{
val = (int)fn->ft.face->ascender; val = (int)fn->ft.face->ascender;
fn->ft.face->units_per_EM = 2048; /* nasy hack - need to have correct fn->ft.face->units_per_EM = 2048; /* nasty hack - need to have correct
* val */ * val */
ret = ret =
(val * fn->ft.face->size->metrics.y_scale) / (val * fn->ft.face->size->metrics.y_scale) /
(fn->ft.face->units_per_EM * fn->ft.face->units_per_EM); (fn->ft.face->units_per_EM * fn->ft.face->units_per_EM);
return ret; if(ret > maxret)
maxret = ret;
fn = fn->next_in_set;
}
return maxret;
} }
int int
imlib_font_descent_get(ImlibFont * fn) imlib_font_descent_get(ImlibFont *fn_list)
{ {
int val; ImlibFont *fn;
int ret; int val;
int ret, maxret;
maxret = 0; fn = fn_list;
while(fn)
{
val = -(int)fn->ft.face->descender; val = -(int)fn->ft.face->descender;
fn->ft.face->units_per_EM = 2048; /* nasy hack - need to have correct fn->ft.face->units_per_EM = 2048; /* nasty hack - need to have correct
* val */ * val */
ret = ret =
(val * fn->ft.face->size->metrics.y_scale) / (val * fn->ft.face->size->metrics.y_scale) /
(fn->ft.face->units_per_EM * fn->ft.face->units_per_EM); (fn->ft.face->units_per_EM * fn->ft.face->units_per_EM);
return ret; /* NOTE by szukw000: as long as the descent value is positive:
* 'ret > maxret'; otherwise 'ret < maxret'.
*/
if(ret > maxret)
maxret = ret;
fn = fn->next_in_set;
}
return maxret;
} }
int int
imlib_font_max_ascent_get(ImlibFont * fn) imlib_font_max_ascent_get(ImlibFont *fn_list)
{ {
int val; ImlibFont *fn;
int ret; int val;
int ret, maxret;
maxret = 0; fn = fn_list;
while(fn)
{
val = (int)fn->ft.face->bbox.yMax; val = (int)fn->ft.face->bbox.yMax;
fn->ft.face->units_per_EM = 2048; /* nasy hack - need to have correct fn->ft.face->units_per_EM = 2048; /* nasty hack - need to have correct
* val */ * val */
ret = ret =
(val * fn->ft.face->size->metrics.y_scale) / (val * fn->ft.face->size->metrics.y_scale) /
(fn->ft.face->units_per_EM * fn->ft.face->units_per_EM); (fn->ft.face->units_per_EM * fn->ft.face->units_per_EM);
return ret; if(ret > maxret)
maxret = ret;
fn = fn->next_in_set;
}
return maxret;
} }
int int
imlib_font_max_descent_get(ImlibFont * fn) imlib_font_max_descent_get(ImlibFont *fn_list)
{ {
int val; ImlibFont *fn;
int ret; int val;
int ret, maxret;
maxret = 0; fn = fn_list;
while(fn)
{
val = (int)fn->ft.face->bbox.yMin; val = (int)fn->ft.face->bbox.yMin;
fn->ft.face->units_per_EM = 2048; /* nasy hack - need to have correct fn->ft.face->units_per_EM = 2048; /* nasty hack - need to have correct
* val */ * val */
ret = ret =
(val * fn->ft.face->size->metrics.y_scale) / (val * fn->ft.face->size->metrics.y_scale) /
(fn->ft.face->units_per_EM * fn->ft.face->units_per_EM); (fn->ft.face->units_per_EM * fn->ft.face->units_per_EM);
return ret; /* NOTE by szukw000: as long as the max_descent value is negative:
* 'ret < maxret'; otherwise: 'ret > maxret'.
*/
if(ret < maxret)
maxret = ret;
fn = fn->next_in_set;
}
return maxret;
} }
int int
imlib_font_get_line_advance(ImlibFont * fn) imlib_font_get_line_advance(ImlibFont * fn_list)
{ {
int val; ImlibFont *fn;
int ret; int val, maxret, ret;
val = (int)fn->ft.face->height; maxret = 0;
fn->ft.face->units_per_EM = 2048; /* nasy hack - need to have correct fn = fn_list;
* val */ while(fn)
ret = {
(val * fn->ft.face->size->metrics.y_scale) / val = (int)fn->ft.face->height;
(fn->ft.face->units_per_EM * fn->ft.face->units_per_EM); /* nasty hack - need to have correct val */
return ret; fn->ft.face->units_per_EM = 2048;
ret =
(val * fn->ft.face->size->metrics.y_scale) /
(fn->ft.face->units_per_EM * fn->ft.face->units_per_EM);
if(ret > maxret)
maxret = ret;
fn = fn->next_in_set;
}
return maxret;
} }
int int

View File

@ -19,20 +19,20 @@ extern FT_Library ft_lib;
/* string extents */ /* string extents */
void void
imlib_font_query_size(ImlibFont * fn, const char *text, int *w, int *h) imlib_font_query_size(ImlibFont *fn_list, const char *text, int *w, int *h)
{ {
int use_kerning; ImlibFont *fn;
int pen_x, pen_y; int pen_x, pen_y;
int start_x, end_x; int start_x, end_x;
int chr; int chr, missing_glyph;
FT_UInt prev_index; FT_UInt prev_index;
start_x = 0; start_x = 0;
end_x = 0; end_x = 0;
pen_x = 0; pen_x = 0;
pen_y = 0; pen_y = 0;
use_kerning = FT_HAS_KERNING(fn->ft.face); prev_index = 0; fn = NULL; missing_glyph = 1;
prev_index = 0;
for (chr = 0; text[chr];) for (chr = 0; text[chr];)
{ {
FT_UInt index; FT_UInt index;
@ -43,8 +43,13 @@ imlib_font_query_size(ImlibFont * fn, const char *text, int *w, int *h)
gl = imlib_font_utf8_get_next((unsigned char *)text, &chr); gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
if (gl == 0) if (gl == 0)
break; break;
index = FT_Get_Char_Index(fn->ft.face, gl); if(missing_glyph)
if ((use_kerning) && (prev_index) && (index)) fn = fn_list;
fn =
imlib_font_find_face_in_fontset(fn, fn_list, gl,
FT_ENCODING_UNICODE, 0, &index, &missing_glyph);
if(FT_HAS_KERNING(fn->ft.face) && (prev_index) && (index))
{ {
FT_Vector delta; FT_Vector delta;
@ -71,16 +76,18 @@ imlib_font_query_size(ImlibFont * fn, const char *text, int *w, int *h)
if (w) if (w)
*w = (pen_x >> 8) - start_x; *w = (pen_x >> 8) - start_x;
if (h) if (h)
*h = imlib_font_max_ascent_get(fn) - imlib_font_max_descent_get(fn); *h = imlib_font_max_ascent_get(fn_list)
- imlib_font_max_descent_get(fn_list);
} }
/* text x inset */ /* text x inset */
int int
imlib_font_query_inset(ImlibFont * fn, const char *text) imlib_font_query_inset(ImlibFont *fn_list, const char *text)
{ {
ImlibFont *fn;
FT_UInt index; FT_UInt index;
Imlib_Font_Glyph *fg; Imlib_Font_Glyph *fg;
int chr; int chr, missing_glyph;
int gl; int gl;
chr = 0; chr = 0;
@ -89,7 +96,11 @@ imlib_font_query_inset(ImlibFont * fn, const char *text)
gl = imlib_font_utf8_get_next((unsigned char *)text, &chr); gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
if (gl == 0) if (gl == 0)
return 0; return 0;
index = FT_Get_Char_Index(fn->ft.face, gl); missing_glyph = 1;
fn =
imlib_font_find_face_in_fontset(fn_list, fn_list, gl,
FT_ENCODING_UNICODE, 0, &index, &missing_glyph);
fg = imlib_font_cache_glyph_get(fn, index); fg = imlib_font_cache_glyph_get(fn, index);
if (!fg) if (!fg)
return 0; return 0;
@ -97,76 +108,82 @@ imlib_font_query_inset(ImlibFont * fn, const char *text)
} }
/* h & v advance */ /* h & v advance */
void void imlib_font_query_advance(ImlibFont *fn_list, const char *text,
imlib_font_query_advance(ImlibFont * fn, const char *text, int *h_adv, int *h_adv, int *v_adv)
int *v_adv)
{ {
int use_kerning; ImlibFont *fn;
int pen_x, pen_y; int pen_x, pen_y;
int start_x; int start_x;
int chr; int chr, missing_glyph;
FT_UInt prev_index; FT_UInt prev_index;
start_x = 0; start_x = 0;
pen_x = 0; pen_x = 0;
pen_y = 0; pen_y = 0;
use_kerning = FT_HAS_KERNING(fn->ft.face);
prev_index = 0;
for (chr = 0; text[chr];)
{
FT_UInt index;
Imlib_Font_Glyph *fg;
int chr_x, chr_y, chr_w;
int gl;
gl = imlib_font_utf8_get_next((unsigned char *)text, &chr); prev_index = 0; fn = NULL; missing_glyph = 1;
if (gl == 0)
break;
index = FT_Get_Char_Index(fn->ft.face, gl);
if ((use_kerning) && (prev_index) && (index))
{
FT_Vector delta;
FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default, for (chr = 0; text[chr];)
&delta); {
pen_x += delta.x << 2; FT_UInt index;
} Imlib_Font_Glyph *fg;
fg = imlib_font_cache_glyph_get(fn, index); int chr_x, chr_y, chr_w;
if (!fg) int gl;
continue;
chr_x = (pen_x >> 8) + fg->glyph_out->left; gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
chr_y = (pen_y >> 8) + fg->glyph_out->top; if (gl == 0)
chr_w = fg->glyph_out->bitmap.width; break;
if(missing_glyph)
fn = fn_list;
fn =
imlib_font_find_face_in_fontset(fn, fn_list, gl,
FT_ENCODING_UNICODE, 0, &index, &missing_glyph);
pen_x += fg->glyph->advance.x >> 8; if(FT_HAS_KERNING(fn->ft.face) && (prev_index) && (index))
prev_index = index; {
} FT_Vector delta;
if (v_adv)
*v_adv = imlib_font_get_line_advance(fn); FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
if (h_adv) &delta);
pen_x += delta.x << 2;
}
fg = imlib_font_cache_glyph_get(fn, index);
if (!fg)
continue;
chr_x = (pen_x >> 8) + fg->glyph_out->left;
chr_y = (pen_y >> 8) + fg->glyph_out->top;
chr_w = fg->glyph_out->bitmap.width;
pen_x += fg->glyph->advance.x >> 8;
prev_index = index;
}
if (v_adv)
*v_adv = imlib_font_get_line_advance(fn_list);
if (h_adv)
*h_adv = (pen_x >> 8) - start_x; *h_adv = (pen_x >> 8) - start_x;
} }
/* x y w h for char at char pos */ /* x y w h for char at char pos */
int int
imlib_font_query_char_coords(ImlibFont * fn, const char *text, int pos, imlib_font_query_char_coords(ImlibFont *fn_list, const char *text, int pos,
int *cx, int *cy, int *cw, int *ch) int *cx, int *cy, int *cw, int *ch)
{ {
int use_kerning; ImlibFont *fn;
int pen_x, pen_y; int pen_x, pen_y;
int prev_chr_end; int prev_chr_end;
int chr; int chr, missing_glyph;
int asc, desc; int asc, desc;
FT_UInt prev_index; FT_UInt prev_index;
pen_x = 0; pen_x = 0;
pen_y = 0; pen_y = 0;
use_kerning = FT_HAS_KERNING(fn->ft.face);
prev_index = 0; prev_index = 0; fn = NULL; missing_glyph = 1;
prev_chr_end = 0; prev_chr_end = 0;
asc = imlib_font_max_ascent_get(fn); asc = imlib_font_max_ascent_get(fn_list);
desc = imlib_font_max_descent_get(fn); desc = imlib_font_max_descent_get(fn_list);
for (chr = 0; text[chr];) for (chr = 0; text[chr];)
{ {
int pchr; int pchr;
@ -180,9 +197,14 @@ imlib_font_query_char_coords(ImlibFont * fn, const char *text, int pos,
gl = imlib_font_utf8_get_next((unsigned char *)text, &chr); gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
if (gl == 0) if (gl == 0)
break; break;
index = FT_Get_Char_Index(fn->ft.face, gl); if(missing_glyph)
fn = fn_list;
fn =
imlib_font_find_face_in_fontset(fn, fn_list, gl,
FT_ENCODING_UNICODE, 0, &index, &missing_glyph);
kern = 0; kern = 0;
if ((use_kerning) && (prev_index) && (index)) if(FT_HAS_KERNING(fn->ft.face) && (prev_index) && (index))
{ {
FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default, FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
&delta); &delta);
@ -232,23 +254,24 @@ imlib_font_query_char_coords(ImlibFont * fn, const char *text, int pos,
/* char pos of text at xy pos */ /* char pos of text at xy pos */
int int
imlib_font_query_text_at_pos(ImlibFont * fn, const char *text, int x, int y, imlib_font_query_text_at_pos(ImlibFont *fn_list, const char *text, int x, int y,
int *cx, int *cy, int *cw, int *ch) int *cx, int *cy, int *cw, int *ch)
{ {
int use_kerning; ImlibFont *fn;
int pen_x, pen_y; int pen_x, pen_y;
int prev_chr_end; int prev_chr_end;
int chr; int chr, missing_glyph;
int asc, desc; int asc, desc;
FT_UInt prev_index; FT_UInt prev_index;
pen_x = 0; pen_x = 0;
pen_y = 0; pen_y = 0;
use_kerning = FT_HAS_KERNING(fn->ft.face);
prev_index = 0; prev_index = 0; fn = NULL; missing_glyph = 1;
prev_chr_end = 0; prev_chr_end = 0;
asc = imlib_font_max_ascent_get(fn); asc = imlib_font_max_ascent_get(fn_list);
desc = imlib_font_max_descent_get(fn); desc = imlib_font_max_descent_get(fn_list);
for (chr = 0; text[chr];) for (chr = 0; text[chr];)
{ {
int pchr; int pchr;
@ -262,9 +285,14 @@ 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); gl = imlib_font_utf8_get_next((unsigned char *)text, &chr);
if (gl == 0) if (gl == 0)
break; break;
index = FT_Get_Char_Index(fn->ft.face, gl); if(missing_glyph)
fn = fn_list;
fn =
imlib_font_find_face_in_fontset(fn, fn_list, gl,
FT_ENCODING_UNICODE, 0, &index, &missing_glyph);
kern = 0; kern = 0;
if ((use_kerning) && (prev_index) && (index)) if(FT_HAS_KERNING(fn->ft.face) && (prev_index) && (index))
{ {
FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default, FT_Get_Kerning(fn->ft.face, prev_index, index, ft_kerning_default,
&delta); &delta);

View File

@ -536,7 +536,7 @@ __imlib_Polygon_DrawToData(ImlibPoly poly, char close, DATA32 color,
while (j < nactive_edges) while (j < nactive_edges)
{ {
int lx, rx; int lx, rx;
int e_lx, e_rx; int e_lx = 0, e_rx = 0;
PolyEdge *e; PolyEdge *e;
e = edge + j; e = edge + j;
@ -760,7 +760,7 @@ __imlib_Polygon_DrawToData_AA(ImlibPoly poly, char close, DATA32 color,
while (j < nactive_edges) while (j < nactive_edges)
{ {
int lx, rx; int lx, rx;
int e_lx, e_rx; int e_lx = 0, e_rx = 0;
PolyEdge *e; PolyEdge *e;
e = edge + j; e = edge + j;
@ -1107,8 +1107,8 @@ __imlib_Polygon_FillToData(ImlibPoly poly, DATA32 color,
while (j < nactive_edges) while (j < nactive_edges)
{ {
int lx, rx; int lx, rx;
int le_lx, le_rx; int le_lx = 0, le_rx = 0;
int re_lx, re_rx; int re_lx = 0, re_rx = 0;
PolyEdge *le, *re; PolyEdge *le, *re;
if (j < (nactive_edges - 1)) if (j < (nactive_edges - 1))
@ -1395,8 +1395,8 @@ __imlib_Polygon_FillToData_AA(ImlibPoly poly, DATA32 color,
while (j < nactive_edges) while (j < nactive_edges)
{ {
int lx, rx; int lx, rx;
int le_lx, le_rx; int le_lx = 0, le_rx = 0;
int re_lx, re_rx; int re_lx = 0, re_rx = 0;
PolyEdge *le, *re; PolyEdge *le, *re;
if (j < (nactive_edges - 1)) if (j < (nactive_edges - 1))