1. move font dir to its own
2. textblokc object stub. this is for an etxo-style text object. nothing much there yet. SVN revision: 12825
This commit is contained in:
parent
f505f667cd
commit
ee2346b2c8
|
@ -429,7 +429,9 @@ extern "C" {
|
|||
|
||||
EAPI void evas_font_cache_flush (Evas *e);
|
||||
EAPI void evas_font_cache_set (Evas *e, int size);
|
||||
EAPI int evas_font_cache_get (Evas *e);
|
||||
EAPI int evas_font_cache_get (Evas *e);
|
||||
|
||||
EAPI Evas_Object *evas_object_textblock_add (Evas *e);
|
||||
|
||||
EAPI void evas_object_del (Evas_Object *obj);
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ evas_object_polygon.c \
|
|||
evas_object_rectangle.c \
|
||||
evas_object_smart.c \
|
||||
evas_object_text.c \
|
||||
evas_object_textblock.c \
|
||||
evas_font_dir.c \
|
||||
evas_rectangle.c \
|
||||
evas_render.c \
|
||||
evas_smart.c \
|
||||
|
|
|
@ -0,0 +1,392 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_private.h"
|
||||
#include "Evas.h"
|
||||
#ifdef BUILD_FONT_LOADER_EET
|
||||
#include <Eet.h>
|
||||
#endif
|
||||
|
||||
/* font dir cache */
|
||||
static Evas_Hash *font_dirs = NULL;
|
||||
|
||||
/* private methods for font dir cache */
|
||||
static Evas_Bool font_cache_dir_free(Evas_Hash *hash, const char *key, void *data, void *fdata);
|
||||
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]);
|
||||
|
||||
void
|
||||
evas_font_dir_cache_free(void)
|
||||
{
|
||||
if (!font_dirs) return;
|
||||
|
||||
evas_hash_foreach (font_dirs, font_cache_dir_free, NULL);
|
||||
evas_hash_free (font_dirs);
|
||||
font_dirs = NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* private stuff */
|
||||
static Evas_Bool
|
||||
font_cache_dir_free(Evas_Hash *hash, const char *key, void *data, void *fdata)
|
||||
{
|
||||
object_text_font_cache_dir_del((char *) key, data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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);
|
||||
font_dirs = evas_hash_del(font_dirs, 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);
|
||||
font_dirs = evas_hash_del(font_dirs, 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);
|
||||
font_dirs = evas_hash_del(font_dirs, 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;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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;
|
||||
}
|
|
@ -29,428 +29,6 @@ struct _Evas_Object_Text
|
|||
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 Evas_Bool font_cache_dir_free(Evas_Hash *hash, const char *key,
|
||||
void *data, void *fdata)
|
||||
{
|
||||
object_text_font_cache_dir_del((char *) key, data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
evas_font_dir_cache_free(void)
|
||||
{
|
||||
if (!font_dirs) return;
|
||||
|
||||
evas_hash_foreach (font_dirs, font_cache_dir_free, NULL);
|
||||
evas_hash_free (font_dirs);
|
||||
font_dirs = NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
font_dirs = evas_hash_del(font_dirs, 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);
|
||||
font_dirs = evas_hash_del(font_dirs, 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);
|
||||
font_dirs = evas_hash_del(font_dirs, 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;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_private.h"
|
||||
#include "Evas.h"
|
||||
|
||||
/* private magic number for textblock objects */
|
||||
static const char o_type[] = "textblock";
|
||||
|
||||
/* private struct for textblock object internal data */
|
||||
typedef struct _Evas_Object_Textblock Evas_Object_Textblock;
|
||||
|
||||
struct _Evas_Object_Textblock
|
||||
{
|
||||
DATA32 magic;
|
||||
struct {
|
||||
char *text;
|
||||
char *font;
|
||||
char *source;
|
||||
Evas_Font_Size size;
|
||||
} cur, prev;
|
||||
char changed : 1;
|
||||
|
||||
void *engine_data;
|
||||
};
|
||||
|
||||
/* private methods for textblock objects */
|
||||
static void evas_object_textblock_init(Evas_Object *obj);
|
||||
static void *evas_object_textblock_new(void);
|
||||
static void evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y);
|
||||
static void evas_object_textblock_free(Evas_Object *obj);
|
||||
static void evas_object_textblock_render_pre(Evas_Object *obj);
|
||||
static void evas_object_textblock_render_post(Evas_Object *obj);
|
||||
|
||||
static int evas_object_textblock_is_opaque(Evas_Object *obj);
|
||||
static int evas_object_textblock_was_opaque(Evas_Object *obj);
|
||||
|
||||
static Evas_Object_Func object_func =
|
||||
{
|
||||
/* methods (compulsory) */
|
||||
evas_object_textblock_free,
|
||||
evas_object_textblock_render,
|
||||
evas_object_textblock_render_pre,
|
||||
evas_object_textblock_render_post,
|
||||
/* these are optional. NULL = nothing */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
evas_object_textblock_is_opaque,
|
||||
evas_object_textblock_was_opaque,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* the actual api call to add a rect */
|
||||
/* it has no other api calls as all properties are standard */
|
||||
|
||||
/**
|
||||
* Adds a textblock to the given evas.
|
||||
* @param e The given evas.
|
||||
* @return The new textblock object.
|
||||
* @todo Find a documentation group to put this under.
|
||||
*/
|
||||
Evas_Object *
|
||||
evas_object_textblock_add(Evas *e)
|
||||
{
|
||||
Evas_Object *obj;
|
||||
|
||||
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
|
||||
return NULL;
|
||||
MAGIC_CHECK_END();
|
||||
obj = evas_object_new();
|
||||
evas_object_textblock_init(obj);
|
||||
evas_object_inject(obj, e);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* all nice and private */
|
||||
static void
|
||||
evas_object_textblock_init(Evas_Object *obj)
|
||||
{
|
||||
/* alloc image ob, setup methods and default values */
|
||||
obj->object_data = evas_object_textblock_new();
|
||||
/* set up default settings for this kind of object */
|
||||
obj->cur.color.r = 255;
|
||||
obj->cur.color.g = 255;
|
||||
obj->cur.color.b = 255;
|
||||
obj->cur.color.a = 255;
|
||||
obj->cur.geometry.x = 0.0;
|
||||
obj->cur.geometry.y = 0.0;
|
||||
obj->cur.geometry.w = 0.0;
|
||||
obj->cur.geometry.h = 0.0;
|
||||
obj->cur.layer = 0;
|
||||
/* set up object-specific settings */
|
||||
obj->prev = obj->cur;
|
||||
/* set up methods (compulsory) */
|
||||
obj->func = &object_func;
|
||||
obj->type = o_type;
|
||||
}
|
||||
|
||||
static void *
|
||||
evas_object_textblock_new(void)
|
||||
{
|
||||
Evas_Object_Textblock *o;
|
||||
|
||||
/* alloc obj private data */
|
||||
o = calloc(1, sizeof(Evas_Object_Textblock));
|
||||
o->magic = MAGIC_OBJ_TEXTBLOCK;
|
||||
return o;
|
||||
}
|
||||
|
||||
static void
|
||||
evas_object_textblock_free(Evas_Object *obj)
|
||||
{
|
||||
Evas_Object_Textblock *o;
|
||||
|
||||
/* frees private object data. very simple here */
|
||||
o = (Evas_Object_Textblock *)(obj->object_data);
|
||||
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXTBLOCK);
|
||||
return;
|
||||
MAGIC_CHECK_END();
|
||||
/* free obj */
|
||||
o->magic = 0;
|
||||
free(o);
|
||||
}
|
||||
|
||||
static void
|
||||
evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
|
||||
{
|
||||
Evas_Object_Textblock *o;
|
||||
|
||||
/* render object to surface with context, and offxet by x,y */
|
||||
o = (Evas_Object_Textblock *)(obj->object_data);
|
||||
obj->layer->evas->engine.func->context_multiplier_unset(output,
|
||||
context);
|
||||
obj->layer->evas->engine.func->context_color_set(output,
|
||||
context,
|
||||
obj->cur.cache.clip.r,
|
||||
obj->cur.cache.clip.g,
|
||||
obj->cur.cache.clip.b,
|
||||
obj->cur.cache.clip.a);
|
||||
if (o->engine_data)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
evas_object_textblock_render_pre(Evas_Object *obj)
|
||||
{
|
||||
Evas_List *updates = NULL;
|
||||
Evas_Object_Textblock *o;
|
||||
int is_v, was_v;
|
||||
|
||||
/* dont pre-render the obj twice! */
|
||||
if (obj->pre_render_done) return;
|
||||
obj->pre_render_done = 1;
|
||||
/* pre-render phase. this does anything an object needs to do just before */
|
||||
/* rendering. this could mean loading the image data, retrieving it from */
|
||||
/* elsewhere, decoding video etc. */
|
||||
/* then when this is done the object needs to figure if it changed and */
|
||||
/* if so what and where and add the appropriate redraw textblocks */
|
||||
o = (Evas_Object_Textblock *)(obj->object_data);
|
||||
/* if someone is clipping this obj - go calculate the clipper */
|
||||
if (obj->cur.clipper)
|
||||
{
|
||||
evas_object_clip_recalc(obj->cur.clipper);
|
||||
obj->cur.clipper->func->render_pre(obj->cur.clipper);
|
||||
}
|
||||
/* now figure what changed and add draw rects */
|
||||
/* if it just became visible or invisible */
|
||||
is_v = evas_object_is_visible(obj);
|
||||
was_v = evas_object_was_visible(obj);
|
||||
if (is_v != was_v)
|
||||
{
|
||||
updates = evas_object_render_pre_visible_change(updates, obj, is_v, was_v);
|
||||
goto done;
|
||||
}
|
||||
/* it's not visible - we accounted for it appearing or not so just abort */
|
||||
if (!is_v) goto done;
|
||||
/* clipper changed this is in addition to anything else for obj */
|
||||
updates = evas_object_render_pre_clipper_change(updates, obj);
|
||||
/* if we restacked (layer or just within a layer) and don't clip anyone */
|
||||
if (obj->restack)
|
||||
{
|
||||
updates = evas_object_render_pre_prev_cur_add(updates, obj);
|
||||
goto done;
|
||||
}
|
||||
/* if it changed color */
|
||||
if ((obj->cur.color.r != obj->prev.color.r) ||
|
||||
(obj->cur.color.g != obj->prev.color.g) ||
|
||||
(obj->cur.color.b != obj->prev.color.b) ||
|
||||
(obj->cur.color.a != obj->prev.color.a))
|
||||
{
|
||||
updates = evas_object_render_pre_prev_cur_add(updates, obj);
|
||||
goto done;
|
||||
}
|
||||
if (o->changed)
|
||||
{
|
||||
/* FIXME: calc sub-area changes */
|
||||
}
|
||||
done:
|
||||
evas_object_render_pre_effect_updates(updates, obj, is_v, was_v);
|
||||
}
|
||||
|
||||
static void
|
||||
evas_object_textblock_render_post(Evas_Object *obj)
|
||||
{
|
||||
Evas_Object_Textblock *o;
|
||||
|
||||
/* this moves the current data to the previous state parts of the object */
|
||||
/* in whatever way is safest for the object. also if we don't need object */
|
||||
/* data anymore we can free it if the object deems this is a good idea */
|
||||
o = (Evas_Object_Textblock *)(obj->object_data);
|
||||
/* remove those pesky changes */
|
||||
while (obj->clip.changes)
|
||||
{
|
||||
Evas_Rectangle *r;
|
||||
|
||||
r = (Evas_Rectangle *)obj->clip.changes->data;
|
||||
obj->clip.changes = evas_list_remove(obj->clip.changes, r);
|
||||
free(r);
|
||||
}
|
||||
/* move cur to prev safely for object data */
|
||||
obj->prev = obj->cur;
|
||||
o->prev = o->cur;
|
||||
o->changed = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
evas_object_textblock_is_opaque(Evas_Object *obj)
|
||||
{
|
||||
Evas_Object_Textblock *o;
|
||||
|
||||
/* this returns 1 if the internal object data implies that the object is */
|
||||
/* currently fulyl opque over the entire gradient it occupies */
|
||||
o = (Evas_Object_Textblock *)(obj->object_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
evas_object_textblock_was_opaque(Evas_Object *obj)
|
||||
{
|
||||
Evas_Object_Textblock *o;
|
||||
|
||||
/* this returns 1 if the internal object data implies that the object was */
|
||||
/* currently fulyl opque over the entire gradient it occupies */
|
||||
o = (Evas_Object_Textblock *)(obj->object_data);
|
||||
return 0;
|
||||
}
|
|
@ -50,6 +50,9 @@ typedef struct _Evas_Rectangle Evas_Rectangle;
|
|||
typedef struct _Evas Evas;
|
||||
typedef struct _Evas_Layer Evas_Layer;
|
||||
typedef struct _Evas_Object Evas_Object;
|
||||
typedef struct _Evas_Font_Dir Evas_Font_Dir;
|
||||
typedef struct _Evas_Font Evas_Font;
|
||||
typedef struct _Evas_Font_Alias Evas_Font_Alias;
|
||||
typedef struct _Evas_Data_Node Evas_Data_Node;
|
||||
typedef struct _Evas_Func_Node Evas_Func_Node;
|
||||
typedef struct _Evas_Func Evas_Func;
|
||||
|
@ -92,6 +95,7 @@ typedef char Evas_Bool;
|
|||
#define MAGIC_OBJ_IMAGE 0x71777775
|
||||
#define MAGIC_OBJ_TEXT 0x71777776
|
||||
#define MAGIC_OBJ_SMART 0x71777777
|
||||
#define MAGIC_OBJ_TEXTBLOCK 0x71777778
|
||||
#define MAGIC_SMART 0x72777770
|
||||
|
||||
#ifdef MAGIC_DEBUG
|
||||
|
@ -448,6 +452,34 @@ struct _Evas_Data_Node
|
|||
void *data;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct _Evas_Object_Func
|
||||
{
|
||||
void (*free) (Evas_Object *obj);
|
||||
|
@ -628,7 +660,9 @@ int evas_object_intercept_call_stack_below(Evas_Object *obj, Evas_Object *below)
|
|||
int evas_object_intercept_call_layer_set(Evas_Object *obj, int l);
|
||||
void evas_object_grabs_cleanup(Evas_Object *obj);
|
||||
void evas_key_grab_free(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers);
|
||||
|
||||
void evas_font_dir_cache_free(void);
|
||||
char *object_text_font_cache_find(char *dir, char *font);
|
||||
|
||||
extern int _evas_alloc_error;
|
||||
|
||||
typedef struct _Evas_Imaging_Image Evas_Imaging_Image;
|
||||
|
|
Loading…
Reference in New Issue