2008-11-05 09:21:04 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2017-09-22 03:06:10 -07:00
|
|
|
#ifdef _WIN32
|
2008-11-05 09:21:04 -08:00
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
#include <Eet.h>
|
2008-11-05 09:21:04 -08:00
|
|
|
|
2006-03-18 20:29:57 -08:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
#include <fontconfig/fontconfig.h>
|
2014-02-03 05:58:25 -08:00
|
|
|
#include <fontconfig/fcfreetype.h>
|
2006-03-18 20:29:57 -08:00
|
|
|
#endif
|
2005-01-08 02:02:18 -08:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
#include "evas_font.h"
|
|
|
|
|
|
|
|
/* General types - used for script type chceking */
|
|
|
|
#define OPAQUE_TYPE(type) struct __##type { int a; }; \
|
|
|
|
typedef struct __##type type
|
|
|
|
|
|
|
|
OPAQUE_TYPE(Evas_Font_Set); /* General type for RGBA_Font */
|
|
|
|
OPAQUE_TYPE(Evas_Font_Instance); /* General type for RGBA_Font_Int */
|
2008-12-20 05:22:46 -08:00
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
/* font dir cache */
|
2008-12-09 09:56:31 -08:00
|
|
|
static Eina_Hash *font_dirs = NULL;
|
2008-10-21 09:31:05 -07:00
|
|
|
static Eina_List *fonts_cache = NULL;
|
|
|
|
static Eina_List *fonts_zero = NULL;
|
2014-03-11 04:15:55 -07:00
|
|
|
static Eina_List *global_font_path = NULL;
|
2005-03-31 23:14:16 -08:00
|
|
|
|
|
|
|
typedef struct _Fndat Fndat;
|
|
|
|
|
|
|
|
struct _Fndat
|
|
|
|
{
|
2011-08-01 01:20:52 -07:00
|
|
|
Evas_Font_Description *fdesc;
|
2011-04-12 02:05:47 -07:00
|
|
|
const char *source;
|
2011-08-01 01:20:52 -07:00
|
|
|
Evas_Font_Size size;
|
2011-05-29 06:35:45 -07:00
|
|
|
Evas_Font_Set *font;
|
2011-04-12 02:05:47 -07:00
|
|
|
int ref;
|
|
|
|
Font_Rend_Flags wanted_rend;
|
2017-09-25 02:34:22 -07:00
|
|
|
Efl_Text_Font_Bitmap_Scalable bitmap_scalable;
|
2009-12-14 09:27:51 -08:00
|
|
|
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
FcFontSet *set;
|
|
|
|
FcPattern *p_nm;
|
2014-06-13 07:29:59 -07:00
|
|
|
|
|
|
|
Eina_Bool file_font : 1; /* Indicates this is a font that uses a file rather than fontconfig. */
|
2009-12-14 09:27:51 -08:00
|
|
|
#endif
|
2005-03-31 23:14:16 -08:00
|
|
|
};
|
2005-01-08 02:02:18 -08:00
|
|
|
|
|
|
|
/* private methods for font dir cache */
|
2009-06-17 03:01:52 -07:00
|
|
|
static Eina_Bool font_cache_dir_free(const Eina_Hash *hash, const void *key, void *data, void *fdata);
|
2005-01-08 02:02:18 -08:00
|
|
|
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]);
|
|
|
|
|
2013-09-25 06:53:37 -07:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
static FcConfig *fc_config = NULL;
|
|
|
|
#endif
|
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
/* FIXME move these helper function to eina_file or eina_path */
|
|
|
|
/* get the casefold feature! */
|
|
|
|
#include <fnmatch.h>
|
2018-01-02 21:23:10 -08:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/param.h>
|
2017-11-06 18:22:09 -08:00
|
|
|
int
|
|
|
|
_file_path_is_full_path(const char *path)
|
|
|
|
{
|
|
|
|
if (!path) return 0;
|
|
|
|
#ifdef _WIN32
|
|
|
|
if (evil_path_is_absolute(path)) return 1;
|
|
|
|
#else
|
|
|
|
if (path[0] == '/') return 1;
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DATA64
|
|
|
|
_file_modified_time(const char *file)
|
|
|
|
{
|
|
|
|
struct stat st;
|
|
|
|
|
|
|
|
if (stat(file, &st) < 0) return 0;
|
|
|
|
if (st.st_ctime > st.st_mtime) return (DATA64)st.st_ctime;
|
|
|
|
else return (DATA64)st.st_mtime;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Eina_List *
|
|
|
|
_file_path_list(char *path, const char *match, int match_case)
|
|
|
|
{
|
|
|
|
Eina_File_Direct_Info *info;
|
|
|
|
Eina_Iterator *it;
|
|
|
|
Eina_List *files = NULL;
|
|
|
|
int flags;
|
|
|
|
|
|
|
|
flags = FNM_PATHNAME;
|
|
|
|
#ifdef FNM_CASEFOLD
|
|
|
|
if (!match_case)
|
|
|
|
flags |= FNM_CASEFOLD;
|
|
|
|
#elif defined FNM_IGNORECASE
|
|
|
|
if (!match_case)
|
|
|
|
flags |= FNM_IGNORECASE;
|
|
|
|
#else
|
|
|
|
/*#warning "Your libc does not provide case-insensitive matching!"*/
|
|
|
|
#endif
|
|
|
|
|
|
|
|
it = eina_file_direct_ls(path);
|
|
|
|
EINA_ITERATOR_FOREACH(it, info)
|
|
|
|
{
|
|
|
|
if (match)
|
|
|
|
{
|
|
|
|
if (fnmatch(match, info->path + info->name_start, flags) == 0)
|
|
|
|
files = eina_list_append(files, strdup(info->path + info->name_start));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
files = eina_list_append(files, strdup(info->path + info->name_start));
|
|
|
|
}
|
|
|
|
if (it) eina_iterator_free(it);
|
|
|
|
return files;
|
|
|
|
}
|
|
|
|
|
2013-09-25 06:53:37 -07:00
|
|
|
static void
|
|
|
|
evas_font_init(void)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
2017-01-21 02:00:46 -08:00
|
|
|
if (!fc_config)
|
2017-07-10 23:46:03 -07:00
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
char *path;
|
|
|
|
|
|
|
|
fc_config = FcInitLoadConfigAndFonts();
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(global_font_path, l, path)
|
|
|
|
FcConfigAppFontAddDir(fc_config, (const FcChar8 *) path);
|
|
|
|
}
|
2013-09-25 06:53:37 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
void
|
|
|
|
evas_font_dir_cache_free(void)
|
|
|
|
{
|
2012-08-03 21:34:49 -07:00
|
|
|
if (font_dirs)
|
|
|
|
{
|
|
|
|
eina_hash_foreach(font_dirs, font_cache_dir_free, NULL);
|
|
|
|
eina_hash_free(font_dirs);
|
|
|
|
font_dirs = NULL;
|
|
|
|
}
|
2013-09-25 06:53:37 -07:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
if (fc_config)
|
|
|
|
{
|
|
|
|
FcConfigDestroy(fc_config);
|
|
|
|
fc_config = NULL;
|
|
|
|
}
|
|
|
|
#endif
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
|
|
|
|
2006-05-31 11:33:46 -07:00
|
|
|
const char *
|
2005-01-08 02:39:09 -08:00
|
|
|
evas_font_dir_cache_find(char *dir, char *font)
|
2005-01-08 02:02:18 -08:00
|
|
|
{
|
2008-12-09 09:56:31 -08:00
|
|
|
Evas_Font_Dir *fd = NULL;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
if (!font_dirs) font_dirs = eina_hash_string_superfast_new(NULL);
|
|
|
|
else fd = eina_hash_find(font_dirs, dir);
|
2005-01-08 02:02:18 -08:00
|
|
|
fd = object_text_font_cache_dir_update(dir, fd);
|
|
|
|
if (fd)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
Evas_Font *fn;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
fn = object_text_font_cache_font_find(fd, font);
|
|
|
|
if (fn)
|
|
|
|
{
|
|
|
|
return fn->path;
|
|
|
|
}
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-10-21 09:31:05 -07:00
|
|
|
static Eina_List *
|
2005-05-21 20:02:15 -07:00
|
|
|
evas_font_set_get(const char *name)
|
2005-03-20 07:57:55 -08:00
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *fonts = NULL;
|
2005-03-20 07:57:55 -08:00
|
|
|
char *p;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
p = strchr(name, ',');
|
|
|
|
if (!p)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
fonts = eina_list_append(fonts, eina_stringshare_add(name));
|
2005-03-20 07:57:55 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
const char *pp;
|
|
|
|
char *nm;
|
|
|
|
|
|
|
|
pp = name;
|
|
|
|
while (p)
|
|
|
|
{
|
|
|
|
nm = alloca(p - pp + 1);
|
|
|
|
strncpy(nm, pp, p - pp);
|
|
|
|
nm[p - pp] = 0;
|
|
|
|
fonts = eina_list_append(fonts, eina_stringshare_add(nm));
|
|
|
|
pp = p + 1;
|
|
|
|
p = strchr(pp, ',');
|
|
|
|
if (!p) fonts = eina_list_append(fonts, eina_stringshare_add(pp));
|
|
|
|
}
|
2005-03-20 07:57:55 -08:00
|
|
|
}
|
|
|
|
return fonts;
|
|
|
|
}
|
|
|
|
|
2008-10-31 03:46:46 -07:00
|
|
|
void
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_fonts_zero_free()
|
2008-10-31 03:46:46 -07:00
|
|
|
{
|
|
|
|
Fndat *fd;
|
|
|
|
|
2009-06-15 07:37:14 -07:00
|
|
|
EINA_LIST_FREE(fonts_zero, fd)
|
|
|
|
{
|
2011-08-01 01:20:52 -07:00
|
|
|
if (fd->fdesc) evas_font_desc_unref(fd->fdesc);
|
2017-11-06 18:22:09 -08:00
|
|
|
if (fd->source) eina_stringshare_del(fd->source);
|
|
|
|
evas_common_font_free((RGBA_Font *)fd->font);
|
2009-12-14 09:55:26 -08:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
2017-11-06 18:22:09 -08:00
|
|
|
if (fd->set) FcFontSetDestroy(fd->set);
|
|
|
|
if (fd->p_nm) FcPatternDestroy(fd->p_nm);
|
2009-12-14 09:55:26 -08:00
|
|
|
#endif
|
2017-11-06 18:22:09 -08:00
|
|
|
free(fd);
|
2009-06-15 07:37:14 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_fonts_zero_pressure()
|
2009-06-15 07:37:14 -07:00
|
|
|
{
|
|
|
|
Fndat *fd;
|
|
|
|
|
|
|
|
while (fonts_zero
|
2017-11-06 18:22:09 -08:00
|
|
|
&& eina_list_count(fonts_zero) > 4) /* 4 is arbitrary */
|
2008-10-31 03:46:46 -07:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
fd = eina_list_data_get(fonts_zero);
|
2008-10-31 03:46:46 -07:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
if (fd->ref != 0) break;
|
|
|
|
fonts_zero = eina_list_remove_list(fonts_zero, fonts_zero);
|
2009-06-15 07:37:14 -07:00
|
|
|
|
2011-08-01 01:20:52 -07:00
|
|
|
if (fd->fdesc) evas_font_desc_unref(fd->fdesc);
|
2017-11-06 18:22:09 -08:00
|
|
|
if (fd->source) eina_stringshare_del(fd->source);
|
|
|
|
evas_common_font_free((RGBA_Font *)fd->font);
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
if (fd->set) FcFontSetDestroy(fd->set);
|
|
|
|
if (fd->p_nm) FcPatternDestroy(fd->p_nm);
|
|
|
|
#endif
|
|
|
|
free(fd);
|
|
|
|
|
|
|
|
if (eina_list_count(fonts_zero) < 5) break;
|
2008-10-31 03:46:46 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-31 23:14:16 -08:00
|
|
|
void
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_font_free(void *font)
|
2005-03-31 23:14:16 -08:00
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l;
|
|
|
|
Fndat *fd;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-10-21 09:31:05 -07:00
|
|
|
EINA_LIST_FOREACH(fonts_cache, l, fd)
|
2005-03-31 23:14:16 -08:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
if (fd->font == font)
|
|
|
|
{
|
|
|
|
fd->ref--;
|
|
|
|
if (fd->ref == 0)
|
|
|
|
{
|
|
|
|
fonts_cache = eina_list_remove_list(fonts_cache, l);
|
|
|
|
fonts_zero = eina_list_append(fonts_zero, fd);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2005-03-31 23:14:16 -08:00
|
|
|
}
|
2009-06-15 07:37:14 -07:00
|
|
|
while (fonts_zero
|
2017-11-06 18:22:09 -08:00
|
|
|
&& eina_list_count(fonts_zero) > 42) /* 42 is arbitrary */
|
2005-03-31 23:14:16 -08:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
fd = eina_list_data_get(fonts_zero);
|
2009-06-15 07:37:14 -07:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
if (fd->ref != 0) break;
|
|
|
|
fonts_zero = eina_list_remove_list(fonts_zero, fonts_zero);
|
2009-06-15 07:37:14 -07:00
|
|
|
|
2011-08-01 01:20:52 -07:00
|
|
|
if (fd->fdesc) evas_font_desc_unref(fd->fdesc);
|
2017-11-06 18:22:09 -08:00
|
|
|
if (fd->source) eina_stringshare_del(fd->source);
|
|
|
|
evas_common_font_free((RGBA_Font *)fd->font);
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
if (fd->set) FcFontSetDestroy(fd->set);
|
|
|
|
if (fd->p_nm) FcPatternDestroy(fd->p_nm);
|
|
|
|
#endif
|
|
|
|
free(fd);
|
|
|
|
|
|
|
|
if (eina_list_count(fonts_zero) < 43) break;
|
2005-03-31 23:14:16 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-14 09:55:26 -08:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
2011-05-29 06:35:45 -07:00
|
|
|
static Evas_Font_Set *
|
2017-11-06 18:22:09 -08:00
|
|
|
_evas_load_fontconfig(Evas_Font_Set *font, FcFontSet *set, int size,
|
2017-09-25 02:34:22 -07:00
|
|
|
Font_Rend_Flags wanted_rend, Efl_Text_Font_Bitmap_Scalable bitmap_scalable)
|
2009-12-14 09:27:51 -08:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Do loading for all in family */
|
|
|
|
for (i = 0; i < set->nfont; i++)
|
|
|
|
{
|
2017-09-28 23:16:21 -07:00
|
|
|
FcValue filename;
|
|
|
|
|
|
|
|
if (FcPatternGet(set->fonts[i], FC_FILE, 0, &filename) == FcResultMatch)
|
|
|
|
{
|
|
|
|
if (font)
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_common_font_add((RGBA_Font *)font, (char *)filename.u.s, size, wanted_rend, bitmap_scalable);
|
2017-09-28 23:16:21 -07:00
|
|
|
else
|
2017-11-06 18:22:09 -08:00
|
|
|
font = (Evas_Font_Set *)evas_common_font_load((char *)filename.u.s, size, wanted_rend, bitmap_scalable);
|
2017-09-28 23:16:21 -07:00
|
|
|
}
|
2009-12-14 09:27:51 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return font;
|
|
|
|
}
|
2009-12-14 09:55:26 -08:00
|
|
|
#endif
|
2009-12-14 09:27:51 -08:00
|
|
|
|
2011-08-01 01:20:52 -07:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
/* In sync with Evas_Font_Style, Evas_Font_Weight and Evas_Font_Width */
|
|
|
|
static int _fc_slant_map[] =
|
|
|
|
{
|
|
|
|
FC_SLANT_ROMAN,
|
|
|
|
FC_SLANT_OBLIQUE,
|
|
|
|
FC_SLANT_ITALIC
|
|
|
|
};
|
|
|
|
|
2012-09-12 04:55:45 -07:00
|
|
|
/* Apparently EXTRABLACK is not always available, hardcode. */
|
|
|
|
# ifndef FC_WEIGHT_EXTRABLACK
|
|
|
|
# define FC_WEIGHT_EXTRABLACK 215
|
|
|
|
# endif
|
2011-08-01 01:20:52 -07:00
|
|
|
static int _fc_weight_map[] =
|
|
|
|
{
|
|
|
|
FC_WEIGHT_NORMAL,
|
|
|
|
FC_WEIGHT_THIN,
|
|
|
|
FC_WEIGHT_ULTRALIGHT,
|
evas: Add ExtraLight, ExtraBold for font weight.
Summary:
Evas supports UltraLight, UltraBold as font weight.
These terms have same weight value as ExtraLight, ExtraBold.
Some applications, for example, fontforge, use ExtraLight, ExtraBold terms for these weight values.
So, it would be better to support these terms, too.
@feature
Test Plan: None
Reviewers: tasn, woohyun, herdsman
Reviewed By: herdsman
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D3126
2015-11-26 00:16:13 -08:00
|
|
|
FC_WEIGHT_EXTRALIGHT,
|
2011-08-01 01:20:52 -07:00
|
|
|
FC_WEIGHT_LIGHT,
|
|
|
|
FC_WEIGHT_BOOK,
|
|
|
|
FC_WEIGHT_MEDIUM,
|
|
|
|
FC_WEIGHT_SEMIBOLD,
|
|
|
|
FC_WEIGHT_BOLD,
|
|
|
|
FC_WEIGHT_ULTRABOLD,
|
evas: Add ExtraLight, ExtraBold for font weight.
Summary:
Evas supports UltraLight, UltraBold as font weight.
These terms have same weight value as ExtraLight, ExtraBold.
Some applications, for example, fontforge, use ExtraLight, ExtraBold terms for these weight values.
So, it would be better to support these terms, too.
@feature
Test Plan: None
Reviewers: tasn, woohyun, herdsman
Reviewed By: herdsman
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D3126
2015-11-26 00:16:13 -08:00
|
|
|
FC_WEIGHT_EXTRABOLD,
|
2011-08-01 01:20:52 -07:00
|
|
|
FC_WEIGHT_BLACK,
|
|
|
|
FC_WEIGHT_EXTRABLACK
|
|
|
|
};
|
|
|
|
|
|
|
|
# ifdef FC_WIDTH
|
|
|
|
static int _fc_width_map[] =
|
|
|
|
{
|
|
|
|
FC_WIDTH_NORMAL,
|
|
|
|
FC_WIDTH_ULTRACONDENSED,
|
|
|
|
FC_WIDTH_EXTRACONDENSED,
|
|
|
|
FC_WIDTH_CONDENSED,
|
|
|
|
FC_WIDTH_SEMICONDENSED,
|
|
|
|
FC_WIDTH_SEMIEXPANDED,
|
|
|
|
FC_WIDTH_EXPANDED,
|
|
|
|
FC_WIDTH_EXTRAEXPANDED,
|
|
|
|
FC_WIDTH_ULTRAEXPANDED
|
|
|
|
};
|
|
|
|
# endif
|
|
|
|
|
2014-01-29 06:36:02 -08:00
|
|
|
static int _fc_spacing_map[] =
|
|
|
|
{
|
|
|
|
FC_PROPORTIONAL,
|
|
|
|
FC_DUAL,
|
|
|
|
FC_MONO,
|
|
|
|
FC_CHARCELL
|
|
|
|
};
|
|
|
|
|
2011-08-01 01:20:52 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
struct _Style_Map
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
int type;
|
|
|
|
};
|
|
|
|
typedef struct _Style_Map Style_Map;
|
|
|
|
|
|
|
|
static Style_Map _style_width_map[] =
|
|
|
|
{
|
|
|
|
{"normal", EVAS_FONT_WIDTH_NORMAL},
|
|
|
|
{"ultracondensed", EVAS_FONT_WIDTH_ULTRACONDENSED},
|
|
|
|
{"extracondensed", EVAS_FONT_WIDTH_EXTRACONDENSED},
|
|
|
|
{"condensed", EVAS_FONT_WIDTH_CONDENSED},
|
|
|
|
{"semicondensed", EVAS_FONT_WIDTH_SEMICONDENSED},
|
|
|
|
{"semiexpanded", EVAS_FONT_WIDTH_SEMIEXPANDED},
|
|
|
|
{"expanded", EVAS_FONT_WIDTH_EXPANDED},
|
|
|
|
{"extraexpanded", EVAS_FONT_WIDTH_EXTRAEXPANDED},
|
|
|
|
{"ultraexpanded", EVAS_FONT_WIDTH_ULTRAEXPANDED},
|
|
|
|
};
|
|
|
|
|
|
|
|
static Style_Map _style_weight_map[] =
|
|
|
|
{
|
|
|
|
{"normal", EVAS_FONT_WEIGHT_NORMAL},
|
|
|
|
{"thin", EVAS_FONT_WEIGHT_THIN},
|
|
|
|
{"ultralight", EVAS_FONT_WEIGHT_ULTRALIGHT},
|
evas: Add ExtraLight, ExtraBold for font weight.
Summary:
Evas supports UltraLight, UltraBold as font weight.
These terms have same weight value as ExtraLight, ExtraBold.
Some applications, for example, fontforge, use ExtraLight, ExtraBold terms for these weight values.
So, it would be better to support these terms, too.
@feature
Test Plan: None
Reviewers: tasn, woohyun, herdsman
Reviewed By: herdsman
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D3126
2015-11-26 00:16:13 -08:00
|
|
|
{"extralight", EVAS_FONT_WEIGHT_EXTRALIGHT},
|
2011-08-01 01:20:52 -07:00
|
|
|
{"light", EVAS_FONT_WEIGHT_LIGHT},
|
|
|
|
{"book", EVAS_FONT_WEIGHT_BOOK},
|
|
|
|
{"medium", EVAS_FONT_WEIGHT_MEDIUM},
|
|
|
|
{"semibold", EVAS_FONT_WEIGHT_SEMIBOLD},
|
|
|
|
{"bold", EVAS_FONT_WEIGHT_BOLD},
|
|
|
|
{"ultrabold", EVAS_FONT_WEIGHT_ULTRABOLD},
|
2016-02-11 02:17:46 -08:00
|
|
|
{"extrabold", EVAS_FONT_WEIGHT_EXTRABOLD},
|
2011-08-01 01:20:52 -07:00
|
|
|
{"black", EVAS_FONT_WEIGHT_BLACK},
|
|
|
|
{"extrablack", EVAS_FONT_WEIGHT_EXTRABLACK}
|
|
|
|
};
|
|
|
|
|
|
|
|
static Style_Map _style_slant_map[] =
|
|
|
|
{
|
|
|
|
{"normal", EVAS_FONT_SLANT_NORMAL},
|
|
|
|
{"oblique", EVAS_FONT_SLANT_OBLIQUE},
|
|
|
|
{"italic", EVAS_FONT_SLANT_ITALIC}
|
|
|
|
};
|
|
|
|
|
2014-01-29 06:36:02 -08:00
|
|
|
static Style_Map _style_spacing_map[] =
|
|
|
|
{
|
|
|
|
{"proportional", EVAS_FONT_SPACING_PROPORTIONAL},
|
|
|
|
{"dualwidth", EVAS_FONT_SPACING_DUAL},
|
|
|
|
{"monospace", EVAS_FONT_SPACING_MONO},
|
|
|
|
{"charcell", EVAS_FONT_SPACING_CHARCELL}
|
|
|
|
};
|
|
|
|
|
2011-08-01 01:20:52 -07:00
|
|
|
#define _STYLE_MAP_LEN(x) (sizeof(x) / sizeof(*(x)))
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
* Find a certain attribute from the map in the style.
|
|
|
|
* @return the index of the found one.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
_evas_font_style_find_internal(const char *style, const char *style_end,
|
|
|
|
Style_Map _map[], size_t map_len)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
while (style < style_end)
|
|
|
|
{
|
|
|
|
for (i = 0 ; i < map_len ; i++)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
const char *cur = _map[i].name;
|
|
|
|
len = strlen(cur);
|
|
|
|
if (!strncasecmp(style, cur, len) &&
|
2017-11-06 18:22:09 -08:00
|
|
|
(!cur[len] || (cur[len] == ' ')))
|
2011-08-01 01:20:52 -07:00
|
|
|
{
|
|
|
|
return _map[i].type;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
style = strchr(style, ' ');
|
|
|
|
if (!style)
|
|
|
|
break;
|
|
|
|
|
|
|
|
while (*style && (*style == ' '))
|
|
|
|
style++;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
evas_font_style_find(const char *start, const char *end,
|
|
|
|
Evas_Font_Style style)
|
2011-04-13 03:55:59 -07:00
|
|
|
{
|
2011-08-01 01:20:52 -07:00
|
|
|
#define _RET_STYLE(x) \
|
|
|
|
return _evas_font_style_find_internal(start, end, \
|
|
|
|
_style_##x##_map, _STYLE_MAP_LEN(_style_##x##_map));
|
|
|
|
switch (style)
|
|
|
|
{
|
|
|
|
case EVAS_FONT_STYLE_SLANT:
|
|
|
|
_RET_STYLE(slant);
|
|
|
|
case EVAS_FONT_STYLE_WEIGHT:
|
|
|
|
_RET_STYLE(weight);
|
|
|
|
case EVAS_FONT_STYLE_WIDTH:
|
|
|
|
_RET_STYLE(width);
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#undef _RET_STYLE
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_font_desc_unref(Evas_Font_Description *fdesc)
|
|
|
|
{
|
|
|
|
if (--(fdesc->ref) == 0)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(fdesc->name);
|
2016-06-27 18:49:37 -07:00
|
|
|
eina_stringshare_del(fdesc->style);
|
2011-08-01 01:21:09 -07:00
|
|
|
eina_stringshare_del(fdesc->fallbacks);
|
2011-08-01 01:21:12 -07:00
|
|
|
eina_stringshare_del(fdesc->lang);
|
2011-08-01 01:20:52 -07:00
|
|
|
free(fdesc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Evas_Font_Description *
|
|
|
|
evas_font_desc_ref(Evas_Font_Description *fdesc)
|
|
|
|
{
|
|
|
|
fdesc->ref++;
|
|
|
|
return fdesc;
|
|
|
|
}
|
|
|
|
|
|
|
|
Evas_Font_Description *
|
|
|
|
evas_font_desc_new(void)
|
|
|
|
{
|
|
|
|
Evas_Font_Description *fdesc;
|
|
|
|
fdesc = calloc(1, sizeof(*fdesc));
|
|
|
|
fdesc->ref = 1;
|
2011-09-05 00:13:23 -07:00
|
|
|
fdesc->is_new = EINA_TRUE;
|
2011-08-01 01:20:52 -07:00
|
|
|
|
|
|
|
return fdesc;
|
|
|
|
}
|
|
|
|
|
|
|
|
Evas_Font_Description *
|
|
|
|
evas_font_desc_dup(const Evas_Font_Description *fdesc)
|
|
|
|
{
|
|
|
|
Evas_Font_Description *new;
|
|
|
|
new = evas_font_desc_new();
|
|
|
|
memcpy(new, fdesc, sizeof(*new));
|
|
|
|
new->ref = 1;
|
2011-09-05 00:13:23 -07:00
|
|
|
new->is_new = EINA_TRUE;
|
2011-08-01 01:20:52 -07:00
|
|
|
new->name = eina_stringshare_ref(new->name);
|
2014-02-19 02:44:34 -08:00
|
|
|
new->fallbacks = eina_stringshare_ref(new->fallbacks);
|
|
|
|
new->lang = eina_stringshare_ref(new->lang);
|
2016-06-28 03:17:24 -07:00
|
|
|
new->style = eina_stringshare_ref(new->style);
|
2011-08-01 01:20:52 -07:00
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
evas_font_desc_cmp(const Evas_Font_Description *a,
|
|
|
|
const Evas_Font_Description *b)
|
|
|
|
{
|
|
|
|
/* FIXME: Do actual comparison, i.e less than and bigger than. */
|
|
|
|
return !((a->name == b->name) && (a->weight == b->weight) &&
|
2017-11-06 18:22:09 -08:00
|
|
|
(a->slant == b->slant) && (a->width == b->width) &&
|
Evas font: add comparison for fallbacks in evas_font_desc_cmp()
Summary:
fallbacks string also has to be compared to load proper fdesc.
If a font which does not have fallback fonts is loaded,
fallback fonts can't be appended to the same font.
@fix
Reviewers: tasn, woohyun, herdsman, zmike, devilhorns
Reviewed By: herdsman
Subscribers: #committers, zmike, raster, Blackmole, z-wony, cedric, jpeg
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D3707
2018-06-29 13:09:08 -07:00
|
|
|
(a->spacing == b->spacing) && (a->lang == b->lang) &&
|
|
|
|
(a->fallbacks == b->fallbacks));
|
2011-08-01 01:20:52 -07:00
|
|
|
}
|
|
|
|
|
2016-01-26 02:48:42 -08:00
|
|
|
const char *
|
|
|
|
evas_font_lang_normalize(const char *lang)
|
|
|
|
{
|
|
|
|
if (!lang || !strcmp(lang, "none")) return NULL;
|
|
|
|
|
|
|
|
if (!strcmp(lang, "auto"))
|
|
|
|
return evas_common_language_from_locale_full_get();
|
|
|
|
|
|
|
|
return lang;
|
|
|
|
}
|
|
|
|
|
2011-08-01 01:20:52 -07:00
|
|
|
void
|
|
|
|
evas_font_name_parse(Evas_Font_Description *fdesc, const char *name)
|
|
|
|
{
|
|
|
|
const char *end;
|
2011-04-13 03:55:59 -07:00
|
|
|
|
2011-08-01 01:20:52 -07:00
|
|
|
end = strchr(name, ':');
|
|
|
|
if (!end)
|
2011-08-01 01:21:12 -07:00
|
|
|
eina_stringshare_replace(&(fdesc->name), name);
|
2011-08-01 01:20:52 -07:00
|
|
|
else
|
2011-08-01 01:21:12 -07:00
|
|
|
eina_stringshare_replace_length(&(fdesc->name), name, end - name);
|
2011-08-01 01:20:52 -07:00
|
|
|
|
|
|
|
while (end)
|
2011-04-13 03:55:59 -07:00
|
|
|
{
|
2011-08-01 01:20:52 -07:00
|
|
|
const char *tend;
|
|
|
|
name = end;
|
|
|
|
end = strchr(end + 1, ':');
|
|
|
|
if (!end)
|
|
|
|
tend = name + strlen(name);
|
|
|
|
else
|
|
|
|
tend = end;
|
|
|
|
|
|
|
|
if (!strncmp(name, ":style=", 7))
|
2011-04-13 03:55:59 -07:00
|
|
|
{
|
2014-02-01 17:59:33 -08:00
|
|
|
#define _SET_STYLE(x, len) \
|
|
|
|
fdesc->x = _evas_font_style_find_internal(name + len, tend, \
|
2011-08-01 01:20:52 -07:00
|
|
|
_style_##x##_map, _STYLE_MAP_LEN(_style_##x##_map));
|
2016-06-27 18:49:37 -07:00
|
|
|
eina_stringshare_replace_length(&(fdesc->style), name + 7, tend - (name + 7));
|
2014-02-01 17:59:33 -08:00
|
|
|
_SET_STYLE(slant, 7);
|
|
|
|
_SET_STYLE(weight, 7);
|
|
|
|
_SET_STYLE(width, 7);
|
2014-01-29 06:10:40 -08:00
|
|
|
}
|
|
|
|
else if (!strncmp(name, ":slant=", 7))
|
|
|
|
{
|
2014-02-01 17:59:33 -08:00
|
|
|
_SET_STYLE(slant, 7);
|
2014-01-29 06:10:40 -08:00
|
|
|
}
|
|
|
|
else if (!strncmp(name, ":weight=", 8))
|
|
|
|
{
|
2014-02-01 17:59:33 -08:00
|
|
|
_SET_STYLE(weight, 8);
|
2014-01-29 06:10:40 -08:00
|
|
|
}
|
|
|
|
else if (!strncmp(name, ":width=", 7))
|
|
|
|
{
|
2014-02-01 17:59:33 -08:00
|
|
|
_SET_STYLE(width, 7);
|
2014-01-29 06:36:02 -08:00
|
|
|
}
|
|
|
|
else if (!strncmp(name, ":spacing=", 9))
|
|
|
|
{
|
2014-02-01 17:59:33 -08:00
|
|
|
_SET_STYLE(spacing, 9);
|
2011-08-01 01:20:52 -07:00
|
|
|
#undef _SET_STYLE
|
2011-04-13 03:55:59 -07:00
|
|
|
}
|
2011-08-01 01:20:52 -07:00
|
|
|
else if (!strncmp(name, ":lang=", 6))
|
2011-04-13 03:55:59 -07:00
|
|
|
{
|
2011-08-01 01:21:12 -07:00
|
|
|
const char *tmp = name + 6;
|
|
|
|
eina_stringshare_replace_length(&(fdesc->lang), tmp, tend - tmp);
|
2016-01-26 02:48:42 -08:00
|
|
|
eina_stringshare_replace(&(fdesc->lang), evas_font_lang_normalize(fdesc->lang));
|
2011-04-13 03:55:59 -07:00
|
|
|
}
|
2016-02-17 01:23:06 -08:00
|
|
|
else if (!strncmp(name, ":fallbacks=", 11))
|
|
|
|
{
|
|
|
|
const char *tmp = name + 11;
|
|
|
|
eina_stringshare_replace_length(&(fdesc->fallbacks), tmp, tend - tmp);
|
|
|
|
}
|
2011-04-13 03:55:59 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-31 07:03:38 -08:00
|
|
|
void *
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_font_load(const Eina_List *font_paths, int hinting, Evas_Font_Description *fdesc, const char *source, Evas_Font_Size size, Efl_Text_Font_Bitmap_Scalable bitmap_scalable)
|
2005-01-31 07:03:38 -08:00
|
|
|
{
|
2009-12-14 09:27:51 -08:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
FcPattern *p_nm = NULL;
|
|
|
|
FcFontSet *set = NULL;
|
2014-06-13 07:29:59 -07:00
|
|
|
Eina_Bool file_font = EINA_FALSE;
|
2009-12-14 09:27:51 -08:00
|
|
|
#endif
|
|
|
|
|
2011-05-29 06:35:45 -07:00
|
|
|
Evas_Font_Set *font = NULL;
|
2013-11-26 03:32:42 -08:00
|
|
|
Eina_List *fonts, *l, *l_next;
|
2005-03-31 23:14:16 -08:00
|
|
|
Fndat *fd;
|
2013-03-12 01:07:50 -07:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
2012-07-26 04:31:36 -07:00
|
|
|
Fndat *found_fd = NULL;
|
2013-03-12 01:07:50 -07:00
|
|
|
#endif
|
2008-10-21 09:31:05 -07:00
|
|
|
char *nm;
|
2011-04-12 02:05:47 -07:00
|
|
|
Font_Rend_Flags wanted_rend = 0;
|
|
|
|
|
2011-08-01 01:20:52 -07:00
|
|
|
if (!fdesc) return NULL;
|
2011-09-05 00:13:23 -07:00
|
|
|
fdesc->is_new = EINA_FALSE;
|
2011-05-12 01:38:21 -07:00
|
|
|
|
2011-08-01 01:20:52 -07:00
|
|
|
if (fdesc->slant != EVAS_FONT_SLANT_NORMAL)
|
2011-08-01 02:11:42 -07:00
|
|
|
wanted_rend |= FONT_REND_SLANT;
|
2011-08-01 01:20:52 -07:00
|
|
|
if (fdesc->weight == EVAS_FONT_WEIGHT_BOLD)
|
2011-08-01 02:11:42 -07:00
|
|
|
wanted_rend |= FONT_REND_WEIGHT;
|
2005-03-31 23:14:16 -08:00
|
|
|
|
2013-09-25 06:53:37 -07:00
|
|
|
evas_font_init();
|
|
|
|
|
2008-10-21 09:31:05 -07:00
|
|
|
EINA_LIST_FOREACH(fonts_cache, l, fd)
|
2005-03-31 23:14:16 -08:00
|
|
|
{
|
2011-08-01 01:20:52 -07:00
|
|
|
if (!evas_font_desc_cmp(fdesc, fd->fdesc))
|
2017-11-06 18:22:09 -08:00
|
|
|
{
|
|
|
|
if (((!source) && (!fd->source)) ||
|
|
|
|
((source) && (fd->source) && (!strcmp(source, fd->source))))
|
|
|
|
{
|
|
|
|
if ((size == fd->size) &&
|
|
|
|
(wanted_rend == fd->wanted_rend) &&
|
|
|
|
(bitmap_scalable == fd->bitmap_scalable))
|
|
|
|
{
|
|
|
|
fonts_cache = eina_list_promote_list(fonts_cache, l);
|
|
|
|
fd->ref++;
|
|
|
|
return fd->font;
|
|
|
|
}
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
else if (fd->set && fd->p_nm && !fd->file_font)
|
|
|
|
{
|
|
|
|
found_fd = fd;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
2005-03-31 23:14:16 -08:00
|
|
|
}
|
2007-05-05 03:30:11 -07:00
|
|
|
|
2012-07-31 03:51:11 -07:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
2012-07-26 04:31:36 -07:00
|
|
|
if (found_fd)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
font = _evas_load_fontconfig(font, found_fd->set, size, wanted_rend, bitmap_scalable);
|
2012-07-26 04:31:36 -07:00
|
|
|
goto on_find;
|
|
|
|
}
|
2012-07-31 03:51:11 -07:00
|
|
|
#endif
|
2012-07-26 04:31:36 -07:00
|
|
|
|
2013-11-26 03:32:42 -08:00
|
|
|
EINA_LIST_FOREACH_SAFE(fonts_zero, l, l_next, fd)
|
2005-03-31 23:14:16 -08:00
|
|
|
{
|
2011-08-01 01:20:52 -07:00
|
|
|
if (!evas_font_desc_cmp(fdesc, fd->fdesc))
|
2017-11-06 18:22:09 -08:00
|
|
|
{
|
|
|
|
if (((!source) && (!fd->source)) ||
|
|
|
|
((source) && (fd->source) && (!strcmp(source, fd->source))))
|
|
|
|
{
|
|
|
|
if ((size == fd->size) &&
|
|
|
|
(wanted_rend == fd->wanted_rend))
|
|
|
|
{
|
|
|
|
fonts_zero = eina_list_remove_list(fonts_zero, l);
|
|
|
|
fonts_cache = eina_list_prepend(fonts_cache, fd);
|
|
|
|
fd->ref++;
|
|
|
|
return fd->font;
|
|
|
|
}
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
else if (fd->set && fd->p_nm && !fd->file_font)
|
|
|
|
{
|
|
|
|
found_fd = fd;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
2005-03-31 23:14:16 -08:00
|
|
|
}
|
2011-04-12 02:05:47 -07:00
|
|
|
|
2012-07-31 03:51:11 -07:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
2012-07-26 04:31:36 -07:00
|
|
|
if (found_fd)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
font = _evas_load_fontconfig(font, found_fd->set, size, wanted_rend, bitmap_scalable);
|
2012-07-26 04:31:36 -07:00
|
|
|
goto on_find;
|
|
|
|
}
|
2012-07-31 03:51:11 -07:00
|
|
|
#endif
|
2012-07-26 04:31:36 -07:00
|
|
|
|
2011-08-01 01:20:52 -07:00
|
|
|
fonts = evas_font_set_get(fdesc->name);
|
2008-10-21 09:31:05 -07:00
|
|
|
EINA_LIST_FOREACH(fonts, l, nm) /* Load each font in append */
|
2005-01-31 07:03:38 -08:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
if (l == fonts || !font) /* First iteration OR no font */
|
|
|
|
{
|
|
|
|
if (source) /* Load Font from "eet" source */
|
|
|
|
{
|
|
|
|
Eet_File *ef;
|
|
|
|
char fake_name[PATH_MAX];
|
|
|
|
|
|
|
|
eina_file_path_join(fake_name, PATH_MAX, source, nm);
|
|
|
|
font = (Evas_Font_Set *)evas_common_font_load(fake_name, size, wanted_rend, bitmap_scalable);
|
|
|
|
if (!font) /* Load from fake name failed, probably not cached */
|
|
|
|
{
|
|
|
|
/* read original!!! */
|
|
|
|
ef = eet_open(source, EET_FILE_MODE_READ);
|
|
|
|
if (ef)
|
|
|
|
{
|
|
|
|
void *fdata;
|
|
|
|
int fsize = 0;
|
|
|
|
|
|
|
|
fdata = eet_read(ef, nm, &fsize);
|
|
|
|
if (fdata)
|
|
|
|
{
|
|
|
|
font = (Evas_Font_Set *)evas_common_font_memory_load(source, nm, size, fdata, fsize, wanted_rend, bitmap_scalable);
|
|
|
|
free(fdata);
|
|
|
|
}
|
|
|
|
eet_close(ef);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!font) /* Source load failed */
|
|
|
|
{
|
|
|
|
if (_file_path_is_full_path((char *)nm)) /* Try filename */
|
|
|
|
font = (Evas_Font_Set *)evas_common_font_load((char *)nm, size, wanted_rend, bitmap_scalable);
|
|
|
|
else /* search font path */
|
|
|
|
{
|
|
|
|
const Eina_List *ll;
|
|
|
|
char *dir;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(font_paths, ll, dir)
|
|
|
|
{
|
|
|
|
const char *f_file;
|
|
|
|
|
|
|
|
f_file = evas_font_dir_cache_find(dir, (char *)nm);
|
|
|
|
if (f_file)
|
|
|
|
{
|
|
|
|
font = (Evas_Font_Set *)evas_common_font_load(f_file, size, wanted_rend, bitmap_scalable);
|
|
|
|
if (font) break;
|
|
|
|
}
|
2014-03-11 04:15:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!font)
|
|
|
|
{
|
|
|
|
EINA_LIST_FOREACH(global_font_path, ll, dir)
|
|
|
|
{
|
|
|
|
const char *f_file;
|
|
|
|
|
|
|
|
f_file = evas_font_dir_cache_find(dir, (char *)nm);
|
|
|
|
if (f_file)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
font = (Evas_Font_Set *)evas_common_font_load(f_file, size, wanted_rend, bitmap_scalable);
|
2014-03-11 04:15:55 -07:00
|
|
|
if (font) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-11-06 18:22:09 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else /* Base font loaded, append others */
|
|
|
|
{
|
|
|
|
void *ok = NULL;
|
|
|
|
|
|
|
|
if (source)
|
|
|
|
{
|
|
|
|
Eet_File *ef;
|
|
|
|
char fake_name[PATH_MAX];
|
|
|
|
|
|
|
|
eina_file_path_join(fake_name, PATH_MAX, source, nm);
|
|
|
|
if (!evas_common_font_add((RGBA_Font *)font, fake_name, size, wanted_rend, bitmap_scalable))
|
|
|
|
{
|
|
|
|
/* read original!!! */
|
|
|
|
ef = eet_open(source, EET_FILE_MODE_READ);
|
|
|
|
if (ef)
|
|
|
|
{
|
|
|
|
void *fdata;
|
|
|
|
int fsize = 0;
|
|
|
|
|
|
|
|
fdata = eet_read(ef, nm, &fsize);
|
|
|
|
if ((fdata) && (fsize > 0))
|
|
|
|
{
|
|
|
|
ok = evas_common_font_memory_add((RGBA_Font *)font, source, nm, size, fdata, fsize, wanted_rend, bitmap_scalable);
|
|
|
|
}
|
|
|
|
eet_close(ef);
|
|
|
|
free(fdata);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ok = (void *)1;
|
|
|
|
}
|
|
|
|
if (!ok)
|
|
|
|
{
|
|
|
|
if (_file_path_is_full_path((char *)nm))
|
|
|
|
evas_common_font_add((RGBA_Font *)font, (char *)nm, size, wanted_rend, bitmap_scalable);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const Eina_List *ll;
|
|
|
|
char *dir;
|
|
|
|
RGBA_Font *fn = NULL;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(font_paths, ll, dir)
|
|
|
|
{
|
|
|
|
const char *f_file;
|
|
|
|
|
|
|
|
f_file = evas_font_dir_cache_find(dir, (char *)nm);
|
|
|
|
if (f_file)
|
|
|
|
{
|
|
|
|
fn = evas_common_font_add((RGBA_Font *)font, f_file, size, wanted_rend, bitmap_scalable);
|
|
|
|
if (fn)
|
|
|
|
break;
|
|
|
|
}
|
2014-03-11 04:15:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!fn)
|
|
|
|
{
|
|
|
|
EINA_LIST_FOREACH(global_font_path, ll, dir)
|
|
|
|
{
|
|
|
|
const char *f_file;
|
|
|
|
|
|
|
|
f_file = evas_font_dir_cache_find(dir, (char *)nm);
|
|
|
|
if (f_file)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
fn = evas_common_font_add((RGBA_Font *)font, f_file, size, wanted_rend, bitmap_scalable);
|
2014-03-11 04:15:55 -07:00
|
|
|
if (fn)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-11-06 18:22:09 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
eina_stringshare_del(nm);
|
2005-01-31 07:03:38 -08:00
|
|
|
}
|
2014-08-24 21:05:21 -07:00
|
|
|
eina_list_free(fonts);
|
2006-03-19 03:17:43 -08:00
|
|
|
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
if (!font) /* Search using fontconfig */
|
2006-06-08 22:11:37 -07:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
FcResult res;
|
2006-04-08 19:42:21 -07:00
|
|
|
|
2011-08-01 01:20:52 -07:00
|
|
|
p_nm = FcPatternBuild (NULL,
|
|
|
|
FC_WEIGHT, FcTypeInteger, _fc_weight_map[fdesc->weight],
|
|
|
|
FC_SLANT, FcTypeInteger, _fc_slant_map[fdesc->slant],
|
2014-01-29 06:36:02 -08:00
|
|
|
FC_SPACING, FcTypeInteger, _fc_spacing_map[fdesc->spacing],
|
2011-08-01 01:20:52 -07:00
|
|
|
#ifdef FC_WIDTH
|
|
|
|
FC_WIDTH, FcTypeInteger, _fc_width_map[fdesc->width],
|
|
|
|
#endif
|
|
|
|
NULL);
|
|
|
|
FcPatternAddString (p_nm, FC_FAMILY, (FcChar8*) fdesc->name);
|
|
|
|
|
2016-06-27 18:49:37 -07:00
|
|
|
if (fdesc->style)
|
|
|
|
FcPatternAddString (p_nm, FC_STYLE, (FcChar8*) fdesc->style);
|
|
|
|
|
2011-08-01 01:21:09 -07:00
|
|
|
/* Handle font fallbacks */
|
|
|
|
if (fdesc->fallbacks)
|
|
|
|
{
|
Evas font: fix inifinite loop problem for fallback fonts
Summary:
When multiple fallback fonts was passed to evas_font_load(),
the while loop could run forever. I think it is never tested.
@fix
Test Plan:
Set the following textblock style and set it to a textblock object.
"font=Sans font_fallbacks=Ubuntu,Inconsolata,BlahBlah font_size=..."
Run and see application is in stuck.
Reviewers: tasn, woohyun, herdsman, devilhorns
Subscribers: #committers, zmike, raster, Blackmole, z-wony, cedric, jpeg
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D3703
2018-06-28 08:50:50 -07:00
|
|
|
const char *start, *end;
|
|
|
|
start = fdesc->fallbacks;
|
|
|
|
|
|
|
|
while (start)
|
2011-08-01 01:21:09 -07:00
|
|
|
{
|
|
|
|
end = strchr(start, ',');
|
|
|
|
if (end)
|
|
|
|
{
|
2011-08-08 07:40:33 -07:00
|
|
|
char *tmp = alloca((end - start) + 1);
|
|
|
|
strncpy(tmp, start, end - start);
|
|
|
|
tmp[end - start] = 0;
|
2011-08-08 07:47:35 -07:00
|
|
|
FcPatternAddString (p_nm, FC_FAMILY, (FcChar8*) tmp);
|
2018-06-30 00:15:00 -07:00
|
|
|
start = end + 1;
|
2011-08-01 01:21:09 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FcPatternAddString (p_nm, FC_FAMILY, (FcChar8*) start);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-01 01:21:12 -07:00
|
|
|
if (fdesc->lang)
|
|
|
|
FcPatternAddString (p_nm, FC_LANG, (FcChar8 *) fdesc->lang);
|
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
FcConfigSubstitute(fc_config, p_nm, FcMatchPattern);
|
|
|
|
FcDefaultSubstitute(p_nm);
|
|
|
|
|
|
|
|
/* do matching */
|
|
|
|
set = FcFontSort(fc_config, p_nm, FcTrue, NULL, &res);
|
|
|
|
if (!set)
|
|
|
|
{
|
|
|
|
//FIXME add ERR log capability
|
|
|
|
//ERR("No fontconfig font matches '%s'. It was the last resource, no font found!", fdesc->name);
|
|
|
|
FcPatternDestroy(p_nm);
|
|
|
|
p_nm = NULL;
|
|
|
|
}
|
|
|
|
else
|
2010-10-06 01:53:06 -07:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
font = _evas_load_fontconfig(font, set, size, wanted_rend, bitmap_scalable);
|
2010-10-06 01:53:06 -07:00
|
|
|
}
|
2006-03-19 03:17:43 -08:00
|
|
|
}
|
2014-02-03 05:58:25 -08:00
|
|
|
else /* Add a fallback list from fontconfig according to the found font. */
|
|
|
|
{
|
2014-02-21 01:47:30 -08:00
|
|
|
#if FC_MAJOR >= 2 && FC_MINOR >= 11
|
2017-11-06 18:22:09 -08:00
|
|
|
FcResult res;
|
2014-02-03 05:58:25 -08:00
|
|
|
|
|
|
|
FT_Face face = evas_common_font_freetype_face_get((RGBA_Font *) font);
|
|
|
|
|
2014-06-13 07:29:59 -07:00
|
|
|
file_font = EINA_TRUE;
|
|
|
|
|
2014-02-03 05:58:25 -08:00
|
|
|
if (face)
|
|
|
|
{
|
|
|
|
p_nm = FcFreeTypeQueryFace(face, (FcChar8 *) "", 0, NULL);
|
|
|
|
FcConfigSubstitute(fc_config, p_nm, FcMatchPattern);
|
|
|
|
FcDefaultSubstitute(p_nm);
|
|
|
|
|
|
|
|
/* do matching */
|
|
|
|
set = FcFontSort(fc_config, p_nm, FcTrue, NULL, &res);
|
|
|
|
if (!set)
|
|
|
|
{
|
|
|
|
FcPatternDestroy(p_nm);
|
|
|
|
p_nm = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
font = _evas_load_fontconfig(font, set, size, wanted_rend, bitmap_scalable);
|
2014-02-03 05:58:25 -08:00
|
|
|
}
|
|
|
|
}
|
2014-02-21 01:47:30 -08:00
|
|
|
#endif
|
2014-02-03 05:58:25 -08:00
|
|
|
}
|
2006-03-19 03:17:43 -08:00
|
|
|
#endif
|
2006-06-08 22:11:37 -07:00
|
|
|
|
2011-11-20 05:55:17 -08:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
2009-12-14 09:27:51 -08:00
|
|
|
on_find:
|
2011-11-20 05:55:17 -08:00
|
|
|
#endif
|
2005-03-31 23:14:16 -08:00
|
|
|
fd = calloc(1, sizeof(Fndat));
|
|
|
|
if (fd)
|
|
|
|
{
|
2011-08-22 07:45:23 -07:00
|
|
|
fd->fdesc = evas_font_desc_ref(fdesc);
|
|
|
|
if (source) fd->source = eina_stringshare_add(source);
|
|
|
|
fd->font = font;
|
2011-04-12 02:05:47 -07:00
|
|
|
fd->wanted_rend = wanted_rend;
|
2011-08-22 07:45:19 -07:00
|
|
|
fd->size = size;
|
2017-09-25 02:34:22 -07:00
|
|
|
fd->bitmap_scalable = bitmap_scalable;
|
2011-08-22 07:45:23 -07:00
|
|
|
fd->ref = 1;
|
|
|
|
fonts_cache = eina_list_prepend(fonts_cache, fd);
|
2009-12-14 09:27:51 -08:00
|
|
|
#ifdef HAVE_FONTCONFIG
|
2011-08-22 07:45:23 -07:00
|
|
|
fd->set = set;
|
|
|
|
fd->p_nm = p_nm;
|
2014-06-13 07:29:59 -07:00
|
|
|
fd->file_font = file_font;
|
2009-12-14 09:27:51 -08:00
|
|
|
#endif
|
2005-03-31 23:14:16 -08:00
|
|
|
}
|
2007-05-05 03:30:11 -07:00
|
|
|
|
2006-02-27 20:07:49 -08:00
|
|
|
if (font)
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_common_font_hinting_set((RGBA_Font *)font, hinting);
|
2005-01-31 07:03:38 -08:00
|
|
|
return font;
|
|
|
|
}
|
|
|
|
|
2006-02-28 19:48:02 -08:00
|
|
|
void
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_font_load_hinting_set(void *font, int hinting)
|
2006-02-28 19:48:02 -08:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_common_font_hinting_set((RGBA_Font *) font, hinting);
|
2006-02-28 19:48:02 -08:00
|
|
|
}
|
2005-01-31 07:03:38 -08:00
|
|
|
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_font_dir_available_list(const Eina_List *font_paths)
|
2006-04-30 04:39:44 -07:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
const Eina_List *l;
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *ll;
|
|
|
|
Eina_List *available = NULL;
|
2008-10-21 09:54:30 -07:00
|
|
|
char *dir;
|
2006-04-30 04:39:44 -07:00
|
|
|
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
/* Add font config fonts */
|
|
|
|
FcPattern *p;
|
2006-06-08 22:11:37 -07:00
|
|
|
FcFontSet *set = NULL;
|
2006-04-30 04:39:44 -07:00
|
|
|
FcObjectSet *os;
|
|
|
|
int i;
|
2006-06-08 22:11:37 -07:00
|
|
|
|
2013-09-25 06:53:37 -07:00
|
|
|
evas_font_init();
|
|
|
|
|
2006-04-30 04:39:44 -07:00
|
|
|
p = FcPatternCreate();
|
|
|
|
os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL);
|
2006-06-08 22:11:37 -07:00
|
|
|
|
2013-09-25 06:53:37 -07:00
|
|
|
if (p && os) set = FcFontList(fc_config, p, os);
|
2006-06-08 22:11:37 -07:00
|
|
|
|
2006-04-30 04:39:44 -07:00
|
|
|
if (p) FcPatternDestroy(p);
|
|
|
|
if (os) FcObjectSetDestroy(os);
|
|
|
|
|
|
|
|
if (set)
|
2006-06-08 22:11:37 -07:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
for (i = 0; i < set->nfont; i++)
|
|
|
|
{
|
|
|
|
char *font;
|
2006-06-08 22:11:37 -07:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
font = (char *)FcNameUnparse(set->fonts[i]);
|
|
|
|
available = eina_list_append(available, eina_stringshare_add(font));
|
|
|
|
free(font);
|
|
|
|
}
|
2006-06-08 22:11:37 -07:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
FcFontSetDestroy(set);
|
2006-04-30 04:39:44 -07:00
|
|
|
}
|
|
|
|
#endif
|
2006-06-08 22:11:37 -07:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
/* Add fonts in font_paths*/
|
|
|
|
if (font_paths)
|
2014-03-11 04:15:55 -07:00
|
|
|
{
|
|
|
|
if (!font_dirs) font_dirs = eina_hash_string_superfast_new(NULL);
|
2006-06-08 22:11:37 -07:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
EINA_LIST_FOREACH(font_paths, l, dir)
|
2014-03-11 04:15:55 -07:00
|
|
|
{
|
|
|
|
Evas_Font_Dir *fd;
|
|
|
|
|
|
|
|
fd = eina_hash_find(font_dirs, dir);
|
|
|
|
fd = object_text_font_cache_dir_update(dir, fd);
|
|
|
|
if (fd && fd->aliases)
|
|
|
|
{
|
|
|
|
Evas_Font_Alias *fa;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(fd->aliases, ll, fa)
|
|
|
|
available = eina_list_append(available, eina_stringshare_add((char *)fa->alias));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-12-09 09:56:31 -08:00
|
|
|
|
2014-03-11 04:15:55 -07:00
|
|
|
if (global_font_path)
|
2006-04-30 04:39:44 -07:00
|
|
|
{
|
2014-03-11 04:15:55 -07:00
|
|
|
if (!font_dirs) font_dirs = eina_hash_string_superfast_new(NULL);
|
2006-06-08 22:11:37 -07:00
|
|
|
|
2014-03-11 04:15:55 -07:00
|
|
|
EINA_LIST_FOREACH(global_font_path, l, dir)
|
|
|
|
{
|
|
|
|
Evas_Font_Dir *fd;
|
2006-06-08 22:11:37 -07:00
|
|
|
|
2014-03-11 04:15:55 -07:00
|
|
|
fd = eina_hash_find(font_dirs, dir);
|
|
|
|
fd = object_text_font_cache_dir_update(dir, fd);
|
|
|
|
if (fd && fd->aliases)
|
|
|
|
{
|
|
|
|
Evas_Font_Alias *fa;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(fd->aliases, ll, fa)
|
|
|
|
available = eina_list_append(available, eina_stringshare_add((char *)fa->alias));
|
|
|
|
}
|
|
|
|
}
|
2006-04-30 04:39:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return available;
|
|
|
|
}
|
|
|
|
|
2006-06-08 22:11:37 -07:00
|
|
|
void
|
2008-10-21 09:31:05 -07:00
|
|
|
evas_font_dir_available_list_free(Eina_List *available)
|
2006-04-30 04:39:44 -07:00
|
|
|
{
|
|
|
|
while (available)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
eina_stringshare_del(available->data);
|
|
|
|
available = eina_list_remove(available, available->data);
|
2006-04-30 04:39:44 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
/* private stuff */
|
2008-10-26 09:19:09 -07:00
|
|
|
static Eina_Bool
|
2012-11-04 03:51:42 -08:00
|
|
|
font_cache_dir_free(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, void *fdata EINA_UNUSED)
|
2005-01-08 02:02:18 -08:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
char file_path[PATH_MAX];
|
2005-01-08 02:02:18 -08:00
|
|
|
DATA64 mt;
|
|
|
|
|
|
|
|
if (fd)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
mt = _file_modified_time(dir);
|
|
|
|
if (mt != fd->dir_mod_time)
|
|
|
|
{
|
|
|
|
eina_hash_del(font_dirs, dir, fd);
|
|
|
|
object_text_font_cache_dir_del(dir, fd);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
eina_file_path_join(file_path, PATH_MAX, dir, "fonts.dir");
|
|
|
|
mt = _file_modified_time(file_path);
|
|
|
|
if (mt != fd->fonts_dir_mod_time)
|
|
|
|
{
|
|
|
|
eina_hash_del(font_dirs, dir, fd);
|
|
|
|
object_text_font_cache_dir_del(dir, fd);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
eina_file_path_join(file_path, PATH_MAX, dir, "fonts.alias");
|
|
|
|
mt = _file_modified_time(file_path);
|
|
|
|
if (mt != fd->fonts_alias_mod_time)
|
|
|
|
{
|
|
|
|
eina_hash_del(font_dirs, dir, fd);
|
|
|
|
object_text_font_cache_dir_del(dir, fd);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
}
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
|
|
|
return object_text_font_cache_dir_add(dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Font *
|
|
|
|
object_text_font_cache_font_find_x(Evas_Font_Dir *fd, char *font)
|
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l;
|
2005-01-08 02:02:18 -08:00
|
|
|
char font_prop[14][256];
|
|
|
|
int num;
|
2008-10-21 09:31:05 -07:00
|
|
|
Evas_Font *fn;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
num = evas_object_text_font_string_parse(font, font_prop);
|
|
|
|
if (num != 14) return NULL;
|
2008-10-21 09:31:05 -07:00
|
|
|
EINA_LIST_FOREACH(fd->fonts, l, fn)
|
2005-01-08 02:02:18 -08:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
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;
|
|
|
|
}
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Font *
|
|
|
|
object_text_font_cache_font_find_file(Evas_Font_Dir *fd, char *font)
|
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l;
|
|
|
|
Evas_Font *fn;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-10-21 09:31:05 -07:00
|
|
|
EINA_LIST_FOREACH(fd->fonts, l, fn)
|
2005-01-08 02:02:18 -08:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
if (fn->type == 0)
|
|
|
|
{
|
|
|
|
if (!strcasecmp(font, fn->simple.name)) return fn;
|
|
|
|
}
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Font *
|
|
|
|
object_text_font_cache_font_find_alias(Evas_Font_Dir *fd, char *font)
|
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l;
|
|
|
|
Evas_Font_Alias *fa;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-10-21 09:31:05 -07:00
|
|
|
EINA_LIST_FOREACH(fd->aliases, l, fa)
|
|
|
|
if (!strcasecmp(fa->alias, font)) return fa->fn;
|
2005-01-08 02:02:18 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Font *
|
|
|
|
object_text_font_cache_font_find(Evas_Font_Dir *fd, char *font)
|
|
|
|
{
|
|
|
|
Evas_Font *fn;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
fn = eina_hash_find(fd->lookup, font);
|
2005-01-08 02:02:18 -08:00
|
|
|
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;
|
2008-12-09 09:56:31 -08:00
|
|
|
eina_hash_add(fd->lookup, font, fn);
|
2005-01-08 02:02:18 -08:00
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Font_Dir *
|
|
|
|
object_text_font_cache_dir_add(char *dir)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
char file_path[PATH_MAX];
|
2005-01-08 02:02:18 -08:00
|
|
|
Evas_Font_Dir *fd;
|
2017-11-06 18:22:09 -08:00
|
|
|
char *file;
|
|
|
|
char tmp2[PATH_MAX];
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *fdir;
|
2008-12-09 09:56:31 -08:00
|
|
|
Evas_Font *fn;
|
2017-11-06 18:22:09 -08:00
|
|
|
FILE *f;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
fd = calloc(1, sizeof(Evas_Font_Dir));
|
|
|
|
if (!fd) return NULL;
|
2008-12-09 09:56:31 -08:00
|
|
|
fd->lookup = eina_hash_string_superfast_new(NULL);
|
|
|
|
|
|
|
|
eina_hash_add(font_dirs, dir, fd);
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
/* READ fonts.alias, fonts.dir and directory listing */
|
|
|
|
|
|
|
|
/* fonts.dir */
|
2017-11-06 18:22:09 -08:00
|
|
|
eina_file_path_join(file_path, PATH_MAX, dir, "fonts.dir");
|
|
|
|
|
|
|
|
f = fopen(file_path, "rb");
|
|
|
|
if (f)
|
2005-01-08 02:02:18 -08:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
fn = calloc(1, sizeof(Evas_Font));
|
|
|
|
if (fn)
|
|
|
|
{
|
|
|
|
fn->type = 1;
|
|
|
|
for (i = 0; i < 14; i++)
|
|
|
|
fn->x.prop[i] = eina_stringshare_add(font_prop[i]);
|
|
|
|
eina_file_path_join(tmp2, PATH_MAX, dir, fname);
|
|
|
|
fn->path = eina_stringshare_add(tmp2);
|
|
|
|
fd->fonts = eina_list_append(fd->fonts, fn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cant_read: ;
|
|
|
|
fclose(f);
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
/* directoy listing */
|
2017-11-06 18:22:09 -08:00
|
|
|
fdir = _file_path_list(dir, "*.ttf", 0);
|
2015-12-01 15:03:27 -08:00
|
|
|
EINA_LIST_FREE(fdir, file)
|
2005-01-08 02:02:18 -08:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
eina_file_path_join(file_path, PATH_MAX, dir, file);
|
|
|
|
fn = calloc(1, sizeof(Evas_Font));
|
|
|
|
if (fn)
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
fn->type = 0;
|
|
|
|
strcpy(tmp2, file);
|
|
|
|
p = strrchr(tmp2, '.');
|
|
|
|
if (p) *p = 0;
|
|
|
|
fn->simple.name = eina_stringshare_add(tmp2);
|
|
|
|
eina_file_path_join(tmp2, PATH_MAX, dir, file);
|
|
|
|
fn->path = eina_stringshare_add(tmp2);
|
|
|
|
fd->fonts = eina_list_append(fd->fonts, fn);
|
|
|
|
}
|
|
|
|
free(file);
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
/* fonts.alias */
|
2017-11-06 18:22:09 -08:00
|
|
|
eina_file_path_join(file_path, PATH_MAX, dir, "fonts.alias");
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
f = fopen(file_path, "rb");
|
|
|
|
if (f)
|
2005-01-08 02:02:18 -08:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
char fname[4096], fdef[4096];
|
|
|
|
|
|
|
|
/* read font alias lines */
|
|
|
|
while (fscanf(f, "%4090s %4090[^\n]\n", fname, fdef) == 2)
|
|
|
|
{
|
|
|
|
Evas_Font_Alias *fa;
|
|
|
|
|
|
|
|
/* skip comments */
|
|
|
|
if ((fname[0] == '!') || (fname[0] == '#')) continue;
|
|
|
|
fa = calloc(1, sizeof(Evas_Font_Alias));
|
|
|
|
if (fa)
|
|
|
|
{
|
|
|
|
fa->alias = eina_stringshare_add(fname);
|
|
|
|
fa->fn = object_text_font_cache_font_find_x(fd, fdef);
|
|
|
|
if ((!fa->alias) || (!fa->fn))
|
|
|
|
{
|
|
|
|
if (fa->alias) eina_stringshare_del(fa->alias);
|
|
|
|
free(fa);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fd->aliases = eina_list_append(fd->aliases, fa);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(f);
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
fd->dir_mod_time = _file_modified_time(dir);
|
|
|
|
|
|
|
|
eina_file_path_join(file_path, PATH_MAX, dir, "fonts.dir");
|
|
|
|
fd->fonts_dir_mod_time = _file_modified_time(file_path);
|
|
|
|
|
|
|
|
eina_file_path_join(file_path, PATH_MAX, dir, "fonts.alias");
|
|
|
|
fd->fonts_alias_mod_time = _file_modified_time(file_path);
|
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
object_text_font_cache_dir_del(char *dir EINA_UNUSED, Evas_Font_Dir *fd)
|
2005-01-08 02:02:18 -08:00
|
|
|
{
|
2008-12-09 09:56:31 -08:00
|
|
|
if (fd->lookup) eina_hash_free(fd->lookup);
|
2005-01-08 02:02:18 -08:00
|
|
|
while (fd->fonts)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
Evas_Font *fn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
fn = fd->fonts->data;
|
|
|
|
fd->fonts = eina_list_remove(fd->fonts, fn);
|
|
|
|
for (i = 0; i < 14; i++)
|
|
|
|
{
|
|
|
|
if (fn->x.prop[i]) eina_stringshare_del(fn->x.prop[i]);
|
|
|
|
}
|
|
|
|
if (fn->simple.name) eina_stringshare_del(fn->simple.name);
|
|
|
|
if (fn->path) eina_stringshare_del(fn->path);
|
|
|
|
free(fn);
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
|
|
|
while (fd->aliases)
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
Evas_Font_Alias *fa;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
fa = fd->aliases->data;
|
|
|
|
fd->aliases = eina_list_remove(fd->aliases, fa);
|
|
|
|
if (fa->alias) eina_stringshare_del(fa->alias);
|
|
|
|
free(fa);
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
|
|
|
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])
|
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
dest[n][m] = p[i];
|
|
|
|
if ((p[i] == '-') || (m == 255))
|
|
|
|
{
|
|
|
|
dest[n][m] = 0;
|
|
|
|
n++;
|
|
|
|
m = -1;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
m++;
|
|
|
|
if (n == 14) return n;
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
|
|
|
dest[n][m] = 0;
|
|
|
|
n++;
|
|
|
|
return n;
|
|
|
|
}
|
2011-07-13 01:54:49 -07:00
|
|
|
|
2014-03-11 04:15:55 -07:00
|
|
|
EAPI void
|
|
|
|
evas_font_path_global_append(const char *path)
|
|
|
|
{
|
|
|
|
if (!path) return;
|
|
|
|
global_font_path = eina_list_append(global_font_path, eina_stringshare_add(path));
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
if (fc_config)
|
|
|
|
FcConfigAppFontAddDir(fc_config, (const FcChar8 *) path);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_font_path_global_prepend(const char *path)
|
|
|
|
{
|
|
|
|
if (!path) return;
|
|
|
|
global_font_path = eina_list_prepend(global_font_path, eina_stringshare_add(path));
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
if (fc_config)
|
|
|
|
FcConfigAppFontAddDir(fc_config, (const FcChar8 *) path);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_font_path_global_clear(void)
|
|
|
|
{
|
|
|
|
while (global_font_path)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(global_font_path->data);
|
|
|
|
global_font_path = eina_list_remove(global_font_path, global_font_path->data);
|
|
|
|
}
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
if (fc_config)
|
|
|
|
FcConfigAppFontClear(fc_config);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const Eina_List *
|
|
|
|
evas_font_path_global_list(void)
|
|
|
|
{
|
|
|
|
return global_font_path;
|
|
|
|
}
|
|
|
|
|
2015-03-19 02:01:41 -07:00
|
|
|
EAPI void
|
|
|
|
evas_font_reinit(void)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_FONTCONFIG
|
|
|
|
Eina_List *l;
|
|
|
|
char *path;
|
|
|
|
|
2017-01-21 02:00:46 -08:00
|
|
|
if (fc_config)
|
|
|
|
{
|
|
|
|
FcConfigDestroy(fc_config);
|
|
|
|
fc_config = FcInitLoadConfigAndFonts();
|
2015-03-19 02:01:41 -07:00
|
|
|
|
2017-01-21 02:00:46 -08:00
|
|
|
EINA_LIST_FOREACH(global_font_path, l, path)
|
|
|
|
FcConfigAppFontAddDir(fc_config, (const FcChar8 *) path);
|
|
|
|
}
|
2015-03-19 02:01:41 -07:00
|
|
|
#endif
|
|
|
|
}
|