Enlightenment CVS committal
Author : raster
Project : e17
Module : libs/evas
Dir : e17/libs/evas/src/lib/canvas
Modified Files:
evas_object_text.c
Log Message:
optimize font searching... fixed that fixme.
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/evas/src/lib/canvas/evas_object_text.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -3 -r1.12 -r1.13
--- evas_object_text.c 7 Jun 2003 02:32:30 -0000 1.12
+++ evas_object_text.c 16 Jul 2003 04:00:47 -0000 1.13
@@ -25,6 +25,403 @@
void *engine_data;
};
+
+
+
+/* font dir cache */
+typedef struct _Evas_Font_Dir Evas_Font_Dir;
+typedef struct _Evas_Font Evas_Font;
+typedef struct _Evas_Font_Alias Evas_Font_Alias;
+
+struct _Evas_Font_Dir
+{
+ Evas_Hash *lookup;
+ Evas_List *fonts;
+ Evas_List *aliases;
+ DATA64 dir_mod_time;
+ DATA64 fonts_dir_mod_time;
+ DATA64 fonts_alias_mod_time;
+};
+
+struct _Evas_Font
+{
+ char type;
+ struct {
+ char *prop[14];
+ } x;
+ struct {
+ char *name;
+ } simple;
+ char *path;
+};
+
+struct _Evas_Font_Alias
+{
+ char *alias;
+ Evas_Font *fn;
+};
+
+/* font dir cache */
+static Evas_Hash *font_dirs = NULL;
+
+/* private methods for font dir cache */
+static char *object_text_font_cache_find(char *dir, char *font);
+static Evas_Font_Dir *object_text_font_cache_dir_update(char *dir, Evas_Font_Dir *fd);
+static Evas_Font *object_text_font_cache_font_find_x(Evas_Font_Dir *fd, char *font);
+static Evas_Font *object_text_font_cache_font_find_file(Evas_Font_Dir *fd, char
*font);
+static Evas_Font *object_text_font_cache_font_find_alias(Evas_Font_Dir *fd, char
*font);
+static Evas_Font *object_text_font_cache_font_find(Evas_Font_Dir *fd, char *font);
+static Evas_Font_Dir *object_text_font_cache_dir_add(char *dir);
+static void object_text_font_cache_dir_del(char *dir, Evas_Font_Dir *fd);
+static int evas_object_text_font_string_parse(char *buffer, char dest[14][256]);
+
+static char *
+object_text_font_cache_find(char *dir, char *font)
+{
+ Evas_Font_Dir *fd;
+
+ fd = evas_hash_find(font_dirs, dir);
+ fd = object_text_font_cache_dir_update(dir, fd);
+ if (fd)
+ {
+ Evas_Font *fn;
+
+ fn = object_text_font_cache_font_find(fd, font);
+ if (fn) return fn->path;
+ }
+ return NULL;
+}
+
+static Evas_Font_Dir *
+object_text_font_cache_dir_update(char *dir, Evas_Font_Dir *fd)
+{
+ DATA64 mt;
+ char *tmp;
+
+ if (fd)
+ {
+ mt = evas_file_modified_time(dir);
+ if (mt != fd->dir_mod_time)
+ object_text_font_cache_dir_del(dir, fd);
+ else
+ {
+ tmp = evas_file_path_join(dir, "fonts.dir");
+ if (tmp)
+ {
+ mt = evas_file_modified_time(tmp);
+ free(tmp);
+ if (mt != fd->fonts_dir_mod_time)
+ object_text_font_cache_dir_del(dir, fd);
+ else
+ {
+ tmp = evas_file_path_join(dir, "fonts.alias");
+ if (tmp)
+ {
+ mt = evas_file_modified_time(tmp);
+ free(tmp);
+ }
+ if (mt != fd->fonts_alias_mod_time)
+ object_text_font_cache_dir_del(dir, fd);
+ else
+ return fd;
+ }
+ }
+ }
+ }
+ return object_text_font_cache_dir_add(dir);
+}
+
+static Evas_Font *
+object_text_font_cache_font_find_x(Evas_Font_Dir *fd, char *font)
+{
+ Evas_List *l;
+ char font_prop[14][256];
+ int num;
+
+ num = evas_object_text_font_string_parse(font, font_prop);
+ if (num != 14) return NULL;
+ for (l = fd->fonts; l; l = l->next)
+ {
+ Evas_Font *fn;
+
+ fn = l->data;
+ if (fn->type == 1)
+ {
+ int i;
+ int match = 0;
+
+ for (i = 0; i < 14; i++)
+ {
+ if ((font_prop[i][0] == '*') && (font_prop[i][1] == 0))
+ match++;
+ else
+ {
+ if (!strcasecmp(font_prop[i], fn->x.prop[i])) match++;
+ else break;
+ }
+ }
+ if (match == 14) return fn;
+ }
+ }
+ return NULL;
+}
+
+static Evas_Font *
+object_text_font_cache_font_find_file(Evas_Font_Dir *fd, char *font)
+{
+ Evas_List *l;
+
+ for (l = fd->fonts; l; l = l->next)
+ {
+ Evas_Font *fn;
+
+ fn = l->data;
+ if (fn->type == 0)
+ {
+ if (!strcasecmp(font, fn->simple.name)) return fn;
+ }
+ }
+ return NULL;
+}
+
+static Evas_Font *
+object_text_font_cache_font_find_alias(Evas_Font_Dir *fd, char *font)
+{
+ Evas_List *l;
+
+ for (l = fd->aliases; l; l = l->next)
+ {
+ Evas_Font_Alias *fa;
+
+ fa = l->data;
+ if (!strcasecmp(fa->alias, font)) return fa->fn;
+ }
+ return NULL;
+}
+
+static Evas_Font *
+object_text_font_cache_font_find(Evas_Font_Dir *fd, char *font)
+{
+ Evas_Font *fn;
+
+ fn = evas_hash_find(fd->lookup, font);
+ if (fn) return fn;
+ fn = object_text_font_cache_font_find_alias(fd, font);
+ if (!fn) fn = object_text_font_cache_font_find_x(fd, font);
+ if (!fn) fn = object_text_font_cache_font_find_file(fd, font);
+ if (!fn) return NULL;
+ fd->lookup = evas_hash_add(fd->lookup, font, fn);
+ return fn;
+}
+
+static Evas_Font_Dir *
+object_text_font_cache_dir_add(char *dir)
+{
+ Evas_Font_Dir *fd;
+ char *tmp;
+ Evas_List *fdir;
+
+ fd = calloc(1, sizeof(Evas_Font_Dir));
+ if (!fd) return NULL;
+ font_dirs = evas_hash_add(font_dirs, dir, fd);
+
+ /* READ fonts.alias, fonts.dir and directory listing */
+
+ /* fonts.dir */
+ tmp = evas_file_path_join(dir, "fonts.dir");
+ if (tmp)
+ {
+ FILE *f;
+
+ f = fopen(tmp, "r");
+ if (f)
+ {
+ int num;
+ char fname[4096], fdef[4096];
+
+ if (fscanf(f, "%i\n", &num) != 1) goto cant_read;
+ /* read font lines */
+ while (fscanf(f, "%4090s %[^\n]\n", fname, fdef) == 2)
+ {
+ char font_prop[14][256];
+ int i;
+ int match;
+
+ /* skip comments */
+ if ((fdef[0] == '!') || (fdef[0] == '#')) continue;
+ /* parse font def */
+ num = evas_object_text_font_string_parse((char *)fdef, font_prop);
+ if (num == 14)
+ {
+ Evas_Font *fn;
+
+ fn = calloc(1, sizeof(Evas_Font));
+ if (fn)
+ {
+ fn->type = 1;
+ for (i = 0; i < 14; i++)
+ {
+ fn->x.prop[i] = strdup(font_prop[i]);
+ /* FIXME: what if strdup fails! */
+ }
+ fn->path = evas_file_path_join(dir, fname);
+ /* FIXME; what is evas_file_path_join fails! */
+ fd->fonts = evas_list_append(fd->fonts, fn);
+ }
+ }
+ }
+ cant_read: ;
+ fclose(f);
+ }
+ free(tmp);
+ }
+
+ /* directoy listing */
+ fdir = evas_file_path_list(dir, "*.ttf", 0);
+ while (fdir)
+ {
+ tmp = evas_file_path_join(dir, fdir->data);
+ if (tmp)
+ {
+ Evas_Font *fn;
+
+ fn = calloc(1, sizeof(Evas_Font));
+ if (fn)
+ {
+ fn->type = 0;
+ fn->simple.name = strdup(fdir->data);
+ if (fn->simple.name)
+ {
+ char *p;
+
+ p = strrchr(fn->simple.name, '.');
+ if (p) *p = 0;
+ }
+ fn->path = evas_file_path_join(dir, fdir->data);
+ fd->fonts = evas_list_append(fd->fonts, fn);
+ }
+ free(tmp);
+ }
+ free(fdir->data);
+ fdir = evas_list_remove(fdir, fdir->data);
+ }
+
+ /* fonts.alias */
+ tmp = evas_file_path_join(dir, "fonts.alias");
+ if (tmp)
+ {
+ FILE *f;
+
+ f = fopen(tmp, "r");
+ if (f)
+ {
+ char fname[4096], fdef[4096];
+
+ /* read font alias lines */
+ while (fscanf(f, "%4090s %[^\n]\n", fname, fdef) == 2)
+ {
+ Evas_Font_Alias *fa;
+
+ /* skip comments */
+ if ((fdef[0] == '!') || (fdef[0] == '#')) continue;
+ fa = calloc(1, sizeof(Evas_Font_Alias));
+ if (fa)
+ {
+ fa->alias = strdup(fname);
+ fa->fn = object_text_font_cache_font_find_x(fd, fdef);
+ if ((!fa->alias) || (!fa->fn))
+ {
+ if (fa->alias) free(fa->alias);
+ free(fa);
+ }
+ else
+ fd->aliases = evas_list_append(fd->aliases, fa);
+ }
+ }
+ fclose(f);
+ }
+ free(tmp);
+ }
+
+ fd->dir_mod_time = evas_file_modified_time(dir);
+ tmp = evas_file_path_join(dir, "fonts.dir");
+ if (tmp)
+ {
+ fd->fonts_dir_mod_time = evas_file_modified_time(tmp);
+ free(tmp);
+ }
+ tmp = evas_file_path_join(dir, "fonts.alias");
+ if (tmp)
+ {
+ fd->fonts_alias_mod_time = evas_file_modified_time(tmp);
+ free(tmp);
+ }
+
+ return fd;
+}
+
+static void
+object_text_font_cache_dir_del(char *dir, Evas_Font_Dir *fd)
+{
+ font_dirs = evas_hash_del(font_dirs, dir, fd);
+ if (fd->lookup) evas_hash_free(fd->lookup);
+ while (fd->fonts)
+ {
+ Evas_Font *fn;
+ int i;
+
+ fn = fd->fonts->data;
+ fd->fonts = evas_list_remove(fd->fonts, fn);
+ for (i = 0; i < 14; i++)
+ {
+ if (fn->x.prop[i]) free(fn->x.prop[i]);
+ }
+ if (fn->simple.name) free(fn->simple.name);
+ if (fn->path) free(fn->path);
+ free(fn);
+ }
+ while (fd->aliases)
+ {
+ Evas_Font_Alias *fa;
+
+ fa = fd->aliases->data;
+ fd->aliases = evas_list_remove(fd->aliases, fa);
+ if (fa->alias) free(fa->alias);
+ free(fa);
+ }
+ free(fd);
+}
+
+static int
+evas_object_text_font_string_parse(char *buffer, char dest[14][256])
+{
+ char *p;
+ int n, m, i;
+
+ n = 0;
+ m = 0;
+ p = buffer;
+ if (p[0] != '-') return 0;
+ i = 1;
+ while (p[i])
+ {
+ dest[n][m] = p[i];
+ if ((p[i] == '-') || (m == 256))
+ {
+ dest[n][m] = 0;
+ n++;
+ m = -1;
+ }
+ i++;
+ m++;
+ if (n == 14) return n;
+ }
+ dest[n][m] = 0;
+ n++;
+ return n;
+}
+
+
/* private methods for text objects */
static void evas_object_text_init(Evas_Object *obj);
static void *evas_object_text_new(void);
@@ -36,8 +433,6 @@
static int evas_object_text_is_opaque(Evas_Object *obj);
static int evas_object_text_was_opaque(Evas_Object *obj);
-static int evas_object_text_font_string_parse(char *buffer, char dest[14][256]);
-
static Evas_Object_Func object_func =
{
/* methods (compulsory) */
@@ -121,222 +516,16 @@
for (l = obj->layer->evas->font_path; l; l = l->next)
{
- char *tmp, *font_tmp;
- Evas_List *dir;
- char *falias;
-
- /* try fonts.dir & fonts.alias */
- /* FIXME: This is NOT optimal at ALL! MUST fix it! */
- /* first only read on first scan or if modified time changed */
- /* and cache results in data structs attached to the paths */
- falias = NULL;
- tmp = evas_file_path_join(l->data, "fonts.alias");
- if (tmp)
- {
- FILE *f;
-
- f = fopen(tmp, "r");
- if (f)
- {
- char fname[4096], fdef[4096];
- /* read font alias lines */
- while (fscanf(f, "%4090s %[^\n]\n", fname, fdef) == 2)
- {
- char font_prop2[14][256];
- int i;
- int match;
-
- /* skip comments */
- if ((fdef[0] == '!') || (fdef[0] == '#')) continue;
- if (!strcasecmp(fname, (char *)font))
- {
- falias = strdup(fdef);
- goto alias_done;
- }
- }
- alias_done: ;
- fclose(f);
- }
- free(tmp);
- }
- tmp = evas_file_path_join(l->data, "fonts.dir");
- if (tmp)
- {
- FILE *f;
-
- f = fopen(tmp, "r");
- if (f)
- {
- int num;
- char fname[4096], fdef[4096];
- char font_prop[14][256];
-
- if (fscanf(f, "%i\n", &num) != 1) goto cant_read;
- /* parse font name */
- if (falias)
- num = evas_object_text_font_string_parse(falias, font_prop);
- else
- num = evas_object_text_font_string_parse((char *)font,
font_prop);
- if (num != 14) goto cant_read;
- /* read font lines */
- while (fscanf(f, "%4090s %[^\n]\n", fname, fdef) == 2)
- {
- char font_prop2[14][256];
- int i;
- int match;
-
- /* skip comments */
- if ((fdef[0] == '!') || (fdef[0] == '#')) continue;
- /* parse font def */
- num = evas_object_text_font_string_parse((char *)fdef,
font_prop2);
- if (num == 14)
- {
- match = 0;
- for (i = 0; i < 14; i++)
- {
- if ((font_prop[i][0] == '*') &&
- (font_prop[i][1] == 0))
- match++;
- else
- {
- if (!strcasecmp(font_prop[i],
- font_prop2[i]))
- match++;
- }
- }
- if (match == 14)
- {
- char *tmp2;
-
- tmp2 = evas_file_path_join(l->data, fname);
- if (tmp2)
- {
- o->engine_data =
obj->layer->evas->engine.func->font_load(obj->layer->evas->engine.data.output,
-
tmp2, size);
- if (o->engine_data)
- {
- free(tmp);
- free(tmp2);
- fclose(f);
- if (falias) free(falias);
- goto done;
- }
- free(tmp2);
- }
- }
- }
- }
- cant_read: ;
- fclose(f);
- }
- free(tmp);
- }
- /* try file itself */
- if (falias)
- tmp = evas_file_path_join(l->data, (char *)falias);
- else
- tmp = evas_file_path_join(l->data, (char *)font);
- if (tmp)
+ char *f_file;
+
+ f_file = object_text_font_cache_find(l->data, font);
+ if (f_file)
{
- char *tmp2;
-
o->engine_data =
obj->layer->evas->engine.func->font_load(obj->layer->evas->engine.data.output,
- tmp, size);
- if (o->engine_data)
- {
- free(tmp);
- if (falias) free(falias);
- goto done;
- }
- tmp2 = malloc(strlen(tmp) + 4 + 1);
- if (tmp2)
- {
- strcpy(tmp2, tmp);
- strcat(tmp2, ".ttf");
- o->engine_data =
obj->layer->evas->engine.func->font_load(obj->layer->evas->engine.data.output,
- tmp2,
size);
- if (o->engine_data)
- {
- free(tmp);
- free(tmp2);
- if (falias) free(falias);
- goto done;
- }
- strcpy(tmp2, tmp);
- strcat(tmp2, ".TTF");
- o->engine_data =
obj->layer->evas->engine.func->font_load(obj->layer->evas->engine.data.output,
- tmp2,
size);
- if (o->engine_data)
- {
- free(tmp);
- free(tmp2);
- if (falias) free(falias);
- goto done;
- }
- free(tmp2);
- }
- free(tmp);
+ f_file,
size);
+ if (o->engine_data) break;
}
- dir = evas_file_path_list(l->data, (char *)font, 0);
- while (dir)
- {
- tmp = evas_file_path_join(l->data, dir->data);
- if (tmp)
- {
- o->engine_data =
obj->layer->evas->engine.func->font_load(obj->layer->evas->engine.data.output,
- tmp,
size);
- if (o->engine_data)
- {
- while (dir)
- {
- free(dir->data);
- dir = evas_list_remove(dir, dir->data);
- }
- free(tmp);
- if (falias) free(falias);
- goto done;
- }
- free(tmp);
- }
- free(dir->data);
- dir = evas_list_remove(dir, dir->data);
- }
- font_tmp = malloc(strlen(font) + 4 + 1);
- if (font_tmp)
- {
- strcpy(font_tmp, font);
- strcat(font_tmp, ".ttf");
- dir = evas_file_path_list(l->data, font_tmp, 0);
- while (dir)
- {
- tmp = evas_file_path_join(l->data, dir->data);
- if (tmp)
- {
- o->engine_data =
obj->layer->evas->engine.func->font_load(obj->layer->evas->engine.data.output,
-
tmp, size);
- if (o->engine_data)
- {
- while (dir)
- {
- free(dir->data);
- dir = evas_list_remove(dir, dir->data);
- }
- free(font_tmp);
- free(tmp);
- if (falias) free(falias);
- goto done;
- }
- free(tmp);
- }
- free(dir->data);
- dir = evas_list_remove(dir, dir->data);
- }
- free(font_tmp);
- }
- if (falias) free(falias);
- falias = NULL;
}
- done: ;
}
if (o->cur.font) free(o->cur.font);
if (font) o->cur.font = strdup(font);
@@ -1145,33 +1334,4 @@
/* currently fulyl opque over the entire gradient it occupies */
o = (Evas_Object_Text *)(obj->object_data);
return 0;
-}
-
-static int
-evas_object_text_font_string_parse(char *buffer, char dest[14][256])
-{
- char *p;
- int n, m, i;
-
- n = 0;
- m = 0;
- p = buffer;
- if (p[0] != '-') return 0;
- i = 1;
- while (p[i])
- {
- dest[n][m] = p[i];
- if ((p[i] == '-') || (m == 256))
- {
- dest[n][m] = 0;
- n++;
- m = -1;
- }
- i++;
- m++;
- if (n == 14) return n;
- }
- dest[n][m] = 0;
- n++;
- return n;
}
-------------------------------------------------------
This SF.net email is sponsored by: VM Ware
With VMware you can run multiple operating systems on a single machine.
WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual machines at the
same time. Free trial click here: http://www.vmware.com/wl/offer/345/0
_______________________________________________
enlightenment-cvs mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs