From 82e00e241262473502f40118b593011a1d719526 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sun, 6 May 2007 13:54:43 +0000 Subject: [PATCH] fontset patch from winfred SVN revision: 29880 --- doc/index.html | 7 +- src/lib/api.c | 26 +++-- src/lib/color_helpers.c | 1 + src/lib/font.h | 7 ++ src/lib/font_draw.c | 49 +++++---- src/lib/font_load.c | 213 +++++++++++++++++++++++++++++++++++++--- src/lib/font_main.c | 112 +++++++++++++++------ src/lib/font_query.c | 170 ++++++++++++++++++-------------- src/lib/polygon.c | 12 +-- 9 files changed, 447 insertions(+), 150 deletions(-) diff --git a/doc/index.html b/doc/index.html index 2ec4735..d151866 100644 --- a/doc/index.html +++ b/doc/index.html @@ -1468,9 +1468,10 @@ and vertically)
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". -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 -the font cannot be found NULL is returned.
+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;  +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. void imlib_free_font(void); diff --git a/src/lib/api.c b/src/lib/api.c index 186a56e..96923af 100644 --- a/src/lib/api.c +++ b/src/lib/api.c @@ -3078,16 +3078,21 @@ imlib_image_tile(void) * @return NULL if no font found. * * 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 - * example. If there is a font file called blum.ttf somewhere in the + * contains that font. The font name @p font_name format is "font_name/size" + * 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 - * blum. If the font cannot be found NULL is returned. + * blum;  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 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 imlib_free_font(void) { + ImlibFont *fn; + if (!ctx) ctx = imlib_context_new(); 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); } /** diff --git a/src/lib/color_helpers.c b/src/lib/color_helpers.c index 85d73a1..c08a362 100644 --- a/src/lib/color_helpers.c +++ b/src/lib/color_helpers.c @@ -1,3 +1,4 @@ +#include #include "color_helpers.h" /* * Color space conversion helper routines diff --git a/src/lib/font.h b/src/lib/font.h index 526acb3..9ff274e 100644 --- a/src/lib/font.h +++ b/src/lib/font.h @@ -50,6 +50,7 @@ struct _Imlib_Font int references; + struct _Imlib_Font *next_in_set; }; 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_flush_last(void); 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, int *w, int *h); diff --git a/src/lib/font_draw.c b/src/lib/font_draw.c index 1255d98..371bd79 100644 --- a/src/lib/font_draw.c +++ b/src/lib/font_draw.c @@ -67,7 +67,7 @@ imlib_font_cache_glyph_get(ImlibFont * fn, FT_UInt index) } 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, char dir, double angle, int *retw, int *reth, int blur, 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; int nx, ny; - imlib_font_query_advance(fn, text, &w, NULL); - h = imlib_font_max_ascent_get(fn) - imlib_font_max_descent_get(fn); + imlib_font_query_advance(fn_list, text, &w, NULL); + h = imlib_font_max_ascent_get(fn_list) + - imlib_font_max_descent_get(fn_list); data = malloc(w * h * sizeof(DATA32)); if (!data) @@ -97,10 +98,10 @@ imlib_render_str(ImlibImage * im, ImlibFont * fn, int drx, int dry, /* TODO check for endianess */ col = (a << 24) | (r << 16) | (g << 8) | b; - ascent = imlib_font_max_ascent_get(fn); - - imlib_font_draw(im2, col, fn, 0, ascent, text, &nx, &ny, 0, 0, w, h); + ascent = imlib_font_max_ascent_get(fn_list); + 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, * have to blend it on im */ @@ -246,13 +247,13 @@ imlib_render_str(ImlibImage * im, ImlibFont * fn, int drx, int dry, } 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, int clw, int clh) { - int use_kerning; + ImlibFont *fn; int pen_x, pen_y; - int chr; + int chr, missing_glyph; FT_UInt prev_index; int ext_x, ext_y, ext_w, ext_h; DATA32 *im; @@ -304,8 +305,8 @@ imlib_font_draw(ImlibImage * dst, DATA32 col, ImlibFont * fn, int x, int y, pen_x = x << 8; pen_y = y << 8; - use_kerning = FT_HAS_KERNING(fn->ft.face); - prev_index = 0; + prev_index = 0; fn = NULL; missing_glyph = 1; + for (chr = 0; text[chr];) { 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); if (gl == 0) break; - index = FT_Get_Char_Index(fn->ft.face, gl); - if ((use_kerning) && (prev_index) && (index)) - { - FT_Vector delta; + if(missing_glyph) + fn = fn_list; + fn = + 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, - &delta); - pen_x += delta.x << 2; + if(FT_HAS_KERNING(fn->ft.face) && (prev_index) && (index)) + { + 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); - if (!fg) - continue; + if(!fg) + continue; chr_x = (pen_x + (fg->glyph_out->left << 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) *nextx = (pen_x >> 8) - x; if (nexty) - *nexty = imlib_font_get_line_advance(fn); + *nexty = imlib_font_get_line_advance(fn_list); } diff --git a/src/lib/font_load.c b/src/lib/font_load.c index c86f3c3..2fc665c 100644 --- a/src/lib/font_load.c +++ b/src/lib/font_load.c @@ -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 */ -/* separate fontname and size, find font file, start imlib_font_load() then */ -ImlibFont * -imlib_font_load_joined(const char *fontname) +/* separate fontname and size, find font file +*/ +static char* +imlib_font_find_file(const char *fontname, int *out_size) { int j, size; char *name = NULL, *file = NULL, *tmp = NULL; - ImlibFont *fn; /* split font name (in format name/size) */ for (j = strlen(fontname) - 1; (j >= 0) && (fontname[j] != '/'); j--); @@ -103,7 +103,20 @@ imlib_font_load_joined(const char *fontname) 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 */ if (!file) return NULL; @@ -112,17 +125,13 @@ imlib_font_load_joined(const char *fontname) return fn; } -ImlibFont * -imlib_font_load(const char *name, int size) +static ImlibFont * +imlib_font_create_font_struct(const char *name, int size) { int error; ImlibFont *fn; char *file; - fn = imlib_font_find(name, size); - if (fn) - return fn; - imlib_font_init(); fn = malloc(sizeof(ImlibFont)); @@ -180,15 +189,193 @@ imlib_font_load(const char *name, int size) fn->size = size; fn->glyphs = NULL; - + fn->next_in_set = NULL; fn->usage = 0; fn->references = 1; - fonts = imlib_object_list_prepend(fonts, 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 imlib_font_free(ImlibFont * fn) { diff --git a/src/lib/font_main.c b/src/lib/font_main.c index 5ec01ce..7afb5fb 100644 --- a/src/lib/font_main.c +++ b/src/lib/font_main.c @@ -38,78 +38,130 @@ imlib_font_init(void) } int -imlib_font_ascent_get(ImlibFont * fn) +imlib_font_ascent_get(ImlibFont *fn_list) { - int val; - int ret; + ImlibFont *fn; + int val; + int ret, maxret; + maxret = 0; fn = fn_list; + + while(fn) + { 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 */ ret = (val * fn->ft.face->size->metrics.y_scale) / (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 -imlib_font_descent_get(ImlibFont * fn) +imlib_font_descent_get(ImlibFont *fn_list) { - int val; - int ret; + ImlibFont *fn; + int val; + int ret, maxret; + maxret = 0; fn = fn_list; + + while(fn) + { 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 */ ret = (val * fn->ft.face->size->metrics.y_scale) / (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 -imlib_font_max_ascent_get(ImlibFont * fn) +imlib_font_max_ascent_get(ImlibFont *fn_list) { - int val; - int ret; + ImlibFont *fn; + int val; + int ret, maxret; + maxret = 0; fn = fn_list; + + while(fn) + { 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 */ ret = (val * fn->ft.face->size->metrics.y_scale) / (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 -imlib_font_max_descent_get(ImlibFont * fn) +imlib_font_max_descent_get(ImlibFont *fn_list) { - int val; - int ret; + ImlibFont *fn; + int val; + int ret, maxret; + maxret = 0; fn = fn_list; + + while(fn) + { 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 */ ret = (val * fn->ft.face->size->metrics.y_scale) / (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 -imlib_font_get_line_advance(ImlibFont * fn) +imlib_font_get_line_advance(ImlibFont * fn_list) { - int val; - int ret; + ImlibFont *fn; + int val, maxret, ret; - val = (int)fn->ft.face->height; - fn->ft.face->units_per_EM = 2048; /* nasy hack - need to have correct - * val */ - ret = - (val * fn->ft.face->size->metrics.y_scale) / - (fn->ft.face->units_per_EM * fn->ft.face->units_per_EM); - return ret; + maxret = 0; + fn = fn_list; + while(fn) + { + val = (int)fn->ft.face->height; +/* nasty hack - need to have correct val */ + 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 diff --git a/src/lib/font_query.c b/src/lib/font_query.c index b7cf837..cc062ac 100644 --- a/src/lib/font_query.c +++ b/src/lib/font_query.c @@ -19,20 +19,20 @@ extern FT_Library ft_lib; /* string extents */ 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 start_x, end_x; - int chr; + int chr, missing_glyph; FT_UInt prev_index; start_x = 0; end_x = 0; pen_x = 0; pen_y = 0; - use_kerning = FT_HAS_KERNING(fn->ft.face); - prev_index = 0; + prev_index = 0; fn = NULL; missing_glyph = 1; + for (chr = 0; text[chr];) { 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); if (gl == 0) break; - index = FT_Get_Char_Index(fn->ft.face, gl); - if ((use_kerning) && (prev_index) && (index)) + if(missing_glyph) + 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; @@ -71,16 +76,18 @@ 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_list) + - imlib_font_max_descent_get(fn_list); } /* text x inset */ 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; Imlib_Font_Glyph *fg; - int chr; + int chr, missing_glyph; int gl; 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); if (gl == 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); if (!fg) return 0; @@ -97,76 +108,82 @@ imlib_font_query_inset(ImlibFont * fn, const char *text) } /* h & v advance */ -void -imlib_font_query_advance(ImlibFont * fn, const char *text, int *h_adv, - int *v_adv) +void imlib_font_query_advance(ImlibFont *fn_list, const char *text, + int *h_adv, int *v_adv) { - int use_kerning; - int pen_x, pen_y; - int start_x; - int chr; - FT_UInt prev_index; + ImlibFont *fn; + int pen_x, pen_y; + int start_x; + int chr, missing_glyph; + FT_UInt prev_index; - start_x = 0; - pen_x = 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; + start_x = 0; + pen_x = 0; + pen_y = 0; - gl = imlib_font_utf8_get_next((unsigned char *)text, &chr); - if (gl == 0) - break; - index = FT_Get_Char_Index(fn->ft.face, gl); - if ((use_kerning) && (prev_index) && (index)) - { - FT_Vector delta; + prev_index = 0; fn = NULL; missing_glyph = 1; - 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); - if (!fg) - continue; + for (chr = 0; text[chr];) + { + FT_UInt index; + Imlib_Font_Glyph *fg; + int chr_x, chr_y, chr_w; + int gl; - 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; + gl = imlib_font_utf8_get_next((unsigned char *)text, &chr); + if (gl == 0) + 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; - prev_index = index; - } - if (v_adv) - *v_adv = imlib_font_get_line_advance(fn); - if (h_adv) + if(FT_HAS_KERNING(fn->ft.face) && (prev_index) && (index)) + { + 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); + 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; } /* x y w h for char at char pos */ 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 use_kerning; + ImlibFont *fn; int pen_x, pen_y; int prev_chr_end; - int chr; + int chr, missing_glyph; int asc, desc; FT_UInt prev_index; pen_x = 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; - asc = imlib_font_max_ascent_get(fn); - desc = imlib_font_max_descent_get(fn); + asc = imlib_font_max_ascent_get(fn_list); + desc = imlib_font_max_descent_get(fn_list); + for (chr = 0; text[chr];) { 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); if (gl == 0) 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; - 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, &delta); @@ -232,23 +254,24 @@ imlib_font_query_char_coords(ImlibFont * fn, const char *text, int pos, /* char pos of text at xy pos */ 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 use_kerning; + ImlibFont *fn; int pen_x, pen_y; int prev_chr_end; - int chr; + int chr, missing_glyph; int asc, desc; FT_UInt prev_index; pen_x = 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; - asc = imlib_font_max_ascent_get(fn); - desc = imlib_font_max_descent_get(fn); + asc = imlib_font_max_ascent_get(fn_list); + desc = imlib_font_max_descent_get(fn_list); + for (chr = 0; text[chr];) { 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); if (gl == 0) 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; - 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, &delta); diff --git a/src/lib/polygon.c b/src/lib/polygon.c index 1cb6644..1019b44 100644 --- a/src/lib/polygon.c +++ b/src/lib/polygon.c @@ -536,7 +536,7 @@ __imlib_Polygon_DrawToData(ImlibPoly poly, char close, DATA32 color, while (j < nactive_edges) { int lx, rx; - int e_lx, e_rx; + int e_lx = 0, e_rx = 0; PolyEdge *e; e = edge + j; @@ -760,7 +760,7 @@ __imlib_Polygon_DrawToData_AA(ImlibPoly poly, char close, DATA32 color, while (j < nactive_edges) { int lx, rx; - int e_lx, e_rx; + int e_lx = 0, e_rx = 0; PolyEdge *e; e = edge + j; @@ -1107,8 +1107,8 @@ __imlib_Polygon_FillToData(ImlibPoly poly, DATA32 color, while (j < nactive_edges) { int lx, rx; - int le_lx, le_rx; - int re_lx, re_rx; + int le_lx = 0, le_rx = 0; + int re_lx = 0, re_rx = 0; PolyEdge *le, *re; if (j < (nactive_edges - 1)) @@ -1395,8 +1395,8 @@ __imlib_Polygon_FillToData_AA(ImlibPoly poly, DATA32 color, while (j < nactive_edges) { int lx, rx; - int le_lx, le_rx; - int re_lx, re_rx; + int le_lx = 0, le_rx = 0; + int re_lx = 0, re_rx = 0; PolyEdge *le, *re; if (j < (nactive_edges - 1))