Beispiel #1
0
FcStrSet *FcGetDefaultLangs(void) {
    FcStrSet *result;
retry:
    result = (FcStrSet *)fc_atomic_ptr_get(&default_langs);
    if (!result) {
        char *langs;

        result = FcStrSetCreate();

        langs = getenv("FC_LANG");
        if (!langs || !langs[0]) langs = getenv("LC_ALL");
        if (!langs || !langs[0]) langs = getenv("LC_CTYPE");
        if (!langs || !langs[0]) langs = getenv("LANG");
        if (langs && langs[0]) {
            if (!FcStrSetAddLangs(result, langs))
                FcStrSetAdd(result, (const FcChar8 *)"en");
        } else
            FcStrSetAdd(result, (const FcChar8 *)"en");

        FcRefSetConst(&result->ref);
        if (!fc_atomic_ptr_cmpexch(&default_langs, NULL, result)) {
            FcRefInit(&result->ref, 1);
            FcStrSetDestroy(result);
            goto retry;
        }
    }

    return result;
}
static FcBool
FcCacheDirsValid (FcConfig *config, FcCache *cache)
{
    FcStrSet *dirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
    FcBool ret = FcFalse;
    const FcChar8 *sysroot = FcConfigGetSysRoot (config);
    FcChar8 *d;

    if (!dirs)
	goto bail;
    if (sysroot)
	d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL);
    else
	d = FcStrdup (FcCacheDir (cache));
    if (!FcDirScanOnly (dirs, d, config))
	goto bail1;
    ret = cache->dirs_count == dirs->num;
    if (FcDebug () & FC_DBG_CACHE)
	printf ("%s: cache: %d, fs: %d\n", d, cache->dirs_count, dirs->num);

bail1:
    FcStrSetDestroy (dirs);
    FcStrFree (d);
bail:
    return ret;
}
Beispiel #3
0
Datei: fclang.c Projekt: orlv/fos
void
FcLangSetDestroy (FcLangSet *ls)
{
    if (ls->extra)
	FcStrSetDestroy (ls->extra);
    FcMemFree (FC_MEM_LANGSET, sizeof (FcLangSet));
    free (ls);
}
Beispiel #4
0
FcChar8 *FcGetDefaultLang(void) {
    FcChar8 *lang;
retry:
    lang = fc_atomic_ptr_get(&default_lang);
    if (!lang) {
        FcStrSet *langs = FcGetDefaultLangs();
        lang = FcStrdup(langs->strs[0]);
        FcStrSetDestroy(langs);

        if (!fc_atomic_ptr_cmpexch(&default_lang, NULL, lang)) {
            free(lang);
            goto retry;
        }
    }

    return lang;
}
Beispiel #5
0
void
FcDefaultFini (void)
{
    FcChar8  *lang;
    FcStrSet *langs;

    lang = fc_atomic_ptr_get (&default_lang);
    if (lang && fc_atomic_ptr_cmpexch (&default_lang, lang, NULL)) {
	free (lang);
    }

    langs = fc_atomic_ptr_get (&default_langs);
    if (langs && fc_atomic_ptr_cmpexch (&default_langs, langs, NULL)) {
	FcRefInit (&langs->ref, 1);
	FcStrSetDestroy (langs);
    }
}
Beispiel #6
0
void
FcConfigDestroy (FcConfig *config)
{
    FcSetName	set;
    FcExprPage	*page;

    if (--config->ref > 0)
	return;

    if (config == _fcConfig)
	_fcConfig = 0;

    FcStrSetDestroy (config->configDirs);
    FcStrSetDestroy (config->fontDirs);
    FcStrSetDestroy (config->cacheDirs);
    FcStrSetDestroy (config->configFiles);
    FcStrSetDestroy (config->acceptGlobs);
    FcStrSetDestroy (config->rejectGlobs);
    FcFontSetDestroy (config->acceptPatterns);
    FcFontSetDestroy (config->rejectPatterns);

    if (config->blanks)
	FcBlanksDestroy (config->blanks);

    FcSubstDestroy (config->substPattern);
    FcSubstDestroy (config->substFont);
    FcSubstDestroy (config->substScan);
    for (set = FcSetSystem; set <= FcSetApplication; set++)
	if (config->fonts[set])
	    FcFontSetDestroy (config->fonts[set]);

    page = config->expr_pool;
    while (page)
    {
      FcExprPage *next = page->next_page;
      FcMemFree (FC_MEM_EXPR, sizeof (FcExprPage));
      free (page);
      page = next;
    }

    free (config);
    FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig));
}
Beispiel #7
0
void
FcConfigDestroy (FcConfig *config)
{
    FcSetName	set;
    FcExprPage	*page;

    if (FcRefDec (&config->ref) != 1)
	return;

    (void) fc_atomic_ptr_cmpexch (&_fcConfig, config, NULL);

    FcStrSetDestroy (config->configDirs);
    FcStrSetDestroy (config->fontDirs);
    FcStrSetDestroy (config->cacheDirs);
    FcStrSetDestroy (config->configFiles);
    FcStrSetDestroy (config->acceptGlobs);
    FcStrSetDestroy (config->rejectGlobs);
    FcFontSetDestroy (config->acceptPatterns);
    FcFontSetDestroy (config->rejectPatterns);

    if (config->blanks)
	FcBlanksDestroy (config->blanks);

    FcSubstDestroy (config->substPattern);
    FcSubstDestroy (config->substFont);
    FcSubstDestroy (config->substScan);
    for (set = FcSetSystem; set <= FcSetApplication; set++)
	if (config->fonts[set])
	    FcFontSetDestroy (config->fonts[set]);

    page = config->expr_pool;
    while (page)
    {
      FcExprPage *next = page->next_page;
      free (page);
      page = next;
    }
    if (config->sysRoot)
	FcStrFree (config->sysRoot);

    free (config);
}
Beispiel #8
0
int
main (int argc, char **argv)
{
    int         brief = 0;
    FcChar8     *format = NULL;
    int		i;
    FcFontSet   *fs;
#if HAVE_GETOPT_LONG || HAVE_GETOPT
    int		c;

    setlocale (LC_ALL, "");
#if HAVE_GETOPT_LONG
    while ((c = getopt_long (argc, argv, "bf:Vh", longopts, NULL)) != -1)
#else
    while ((c = getopt (argc, argv, "bf:Vh")) != -1)
#endif
    {
	switch (c) {
	case 'b':
	    brief = 1;
	    break;
	case 'f':
	    format = (FcChar8 *) strdup (optarg);
	    break;
	case 'V':
	    fprintf (stderr, "fontconfig version %d.%d.%d\n",
		     FC_MAJOR, FC_MINOR, FC_REVISION);
	    exit (0);
	case 'h':
	    usage (argv[0], 0);
	default:
	    usage (argv[0], 1);
	}
    }
    i = optind;
#else
    i = 1;
#endif

    if (i == argc)
	usage (argv[0], 1);

    fs = FcFontSetCreate ();

    for (; i < argc; i++)
    {
	const FcChar8 *file = (FcChar8*) argv[i];

	if (!FcFileIsDir (file))
	    FcFileScan (fs, NULL, NULL, NULL, file, FcTrue);
	else
	{
	    FcStrSet *dirs = FcStrSetCreate ();
	    FcStrList *strlist = FcStrListCreate (dirs);
	    do
	    {
		FcDirScan (fs, dirs, NULL, NULL, file, FcTrue);
	    }
	    while ((file = FcStrListNext (strlist)));
	    FcStrListDone (strlist);
	    FcStrSetDestroy (dirs);
	}
    }

    for (i = 0; i < fs->nfont; i++)
    {
	FcPattern *pat = fs->fonts[i];

	if (brief)
	{
	    FcPatternDel (pat, FC_CHARSET);
	    FcPatternDel (pat, FC_LANG);
	}

	if (format)
	{
	    FcChar8 *s;

	    s = FcPatternFormat (pat, format);
	    if (s)
	    {
		printf ("%s", s);
		FcStrFree (s);
	    }
	}
	else
	{
	    FcPatternPrint (pat);
	}
    }

    FcFontSetDestroy (fs);

    FcFini ();
    return i > 0 ? 0 : 1;
}
Beispiel #9
0
int
main (int argc, char **argv)
{
    int		i;
    int		ret = 0;
    FcFontSet	*fs;
    FcStrSet    *dirs;
    FcStrSet	*args = NULL;
    FcStrList	*arglist;
    FcCache	*cache;
    FcConfig	*config;
    FcChar8	*arg;
    int		verbose = 0;
    int		recurse = 0;
    FcBool	first = FcTrue;
#if HAVE_GETOPT_LONG || HAVE_GETOPT
    int		c;

#if HAVE_GETOPT_LONG
    while ((c = getopt_long (argc, argv, "Vvrh", longopts, NULL)) != -1)
#else
    while ((c = getopt (argc, argv, "Vvrh")) != -1)
#endif
    {
	switch (c) {
	case 'V':
	    fprintf (stderr, "fontconfig version %d.%d.%d\n", 
		     FC_MAJOR, FC_MINOR, FC_REVISION);
	    exit (0);
	case 'v':
	    verbose++;
	    break;
	case 'r':
	    recurse++;
	    break;
	case 'h':
	    usage (argv[0], 0);
	default:
	    usage (argv[0], 1);
	}
    }
    i = optind;
#else
    i = 1;
#endif

    config = FcInitLoadConfig ();
    if (!config)
    {
	fprintf (stderr, "%s: Can't init font config library\n", argv[0]);
	return 1;
    }
    FcConfigSetCurrent (config);
    
    args = FcStrSetCreate ();
    if (!args)
    {
	fprintf (stderr, "%s: malloc failure\n", argv[0]);
	return 1;
    }
    if (i < argc)
    {
	for (; i < argc; i++)
	{
	    if (!FcStrSetAddFilename (args, (const FcChar8 *) argv[i]))
	    {
		fprintf (stderr, "%s: malloc failure\n", argv[0]);
		return 1;
	    }
	}
	arglist = FcStrListCreate (args);
	if (!arglist)
	{
	    fprintf (stderr, "%s: malloc failure\n", argv[0]);
	    return 1;
	}
    }
    else
    {
	recurse++;
	arglist = FcConfigGetFontDirs (config);
	while ((arg = FcStrListNext (arglist)))
	    if (!FcStrSetAdd (args, arg))
	    {
		fprintf (stderr, "%s: malloc failure\n", argv[0]);
		return 1;
	    }
	FcStrListDone (arglist);
    }
    arglist = FcStrListCreate (args);
    if (!arglist)
    {
	fprintf (stderr, "%s: malloc failure\n", argv[0]);
	return 1;
    }

    while ((arg = FcStrListNext (arglist)))
    {
	int	    j;
	FcChar8	    *cache_file = NULL;
	struct stat file_stat;
	
	if (FcFileIsDir (arg))
	    cache = FcDirCacheLoad (arg, config, &cache_file);
	else
	    cache = FcDirCacheLoadFile (arg, &file_stat);
	if (!cache)
	{
	    perror ((char *) arg);
	    ret++;
	    continue;
	}
	
	dirs = FcStrSetCreate ();
	fs = FcCacheCopySet (cache);
	for (j = 0; j < FcCacheNumSubdir (cache); j++) 
	{
	    FcStrSetAdd (dirs, FcCacheSubdir (cache, j));
	    if (recurse)
		FcStrSetAdd (args, FcCacheSubdir (cache, j));
	}

	if (verbose)
	{
	    if (!first)
		printf ("\n");
	    printf ("Directory: %s\nCache: %s\n--------\n",
		    FcCacheDir(cache), cache_file ? cache_file : arg);
	    first = FcFalse;
	}
        cache_print_set (fs, dirs, FcCacheDir (cache), verbose);

	FcStrSetDestroy (dirs);

	FcFontSetDestroy (fs);
	FcDirCacheUnload (cache);
	if (cache_file)
	    FcStrFree (cache_file);
    }

    FcFini ();
    return 0;
}
Beispiel #10
0
FcConfig *
FcConfigCreate (void)
{
    FcSetName	set;
    FcConfig	*config;

    config = malloc (sizeof (FcConfig));
    if (!config)
	goto bail0;

    config->configDirs = FcStrSetCreate ();
    if (!config->configDirs)
	goto bail1;

    config->configFiles = FcStrSetCreate ();
    if (!config->configFiles)
	goto bail2;

    config->fontDirs = FcStrSetCreate ();
    if (!config->fontDirs)
	goto bail3;

    config->acceptGlobs = FcStrSetCreate ();
    if (!config->acceptGlobs)
	goto bail4;

    config->rejectGlobs = FcStrSetCreate ();
    if (!config->rejectGlobs)
	goto bail5;

    config->acceptPatterns = FcFontSetCreate ();
    if (!config->acceptPatterns)
	goto bail6;

    config->rejectPatterns = FcFontSetCreate ();
    if (!config->rejectPatterns)
	goto bail7;

    config->cacheDirs = FcStrSetCreate ();
    if (!config->cacheDirs)
	goto bail8;

    config->blanks = 0;

    config->substPattern = 0;
    config->substFont = 0;
    config->substScan = 0;
    config->maxObjects = 0;
    for (set = FcSetSystem; set <= FcSetApplication; set++)
	config->fonts[set] = 0;

    config->rescanTime = time(0);
    config->rescanInterval = 30;

    config->expr_pool = NULL;

    config->sysRoot = NULL;

    FcRefInit (&config->ref, 1);

    return config;

bail8:
    FcFontSetDestroy (config->rejectPatterns);
bail7:
    FcFontSetDestroy (config->acceptPatterns);
bail6:
    FcStrSetDestroy (config->rejectGlobs);
bail5:
    FcStrSetDestroy (config->acceptGlobs);
bail4:
    FcStrSetDestroy (config->fontDirs);
bail3:
    FcStrSetDestroy (config->configFiles);
bail2:
    FcStrSetDestroy (config->configDirs);
bail1:
    free (config);
bail0:
    return 0;
}
Beispiel #11
0
int
main (int argc, char **argv)
{
    FcStrSet	*dirs;
    FcStrList	*list;
    FcBool    	verbose = FcFalse;
    FcBool	force = FcFalse;
    FcBool	really_force = FcFalse;
    FcBool	systemOnly = FcFalse;
    FcConfig	*config;
    int		i;
    int		changed;
    int		ret;
#if HAVE_GETOPT_LONG || HAVE_GETOPT
    int		c;

#if HAVE_GETOPT_LONG
    while ((c = getopt_long (argc, argv, "frsVvh", longopts, NULL)) != -1)
#else
    while ((c = getopt (argc, argv, "frsVvh")) != -1)
#endif
    {
	switch (c) {
	case 'r':
	    really_force = FcTrue;
	    /* fall through */
	case 'f':
	    force = FcTrue;
	    break;
	case 's':
	    systemOnly = FcTrue;
	    break;
	case 'V':
	    fprintf (stderr, "fontconfig version %d.%d.%d\n", 
		     FC_MAJOR, FC_MINOR, FC_REVISION);
	    exit (0);
	case 'v':
	    verbose = FcTrue;
	    break;
	case 'h':
	    usage (argv[0], 0);
	default:
	    usage (argv[0], 1);
	}
    }
    i = optind;
#else
    i = 1;
#endif

    if (systemOnly)
	FcConfigEnableHome (FcFalse);
    config = FcInitLoadConfig ();
    if (!config)
    {
	fprintf (stderr, "%s: Can't init font config library\n", argv[0]);
	return 1;
    }
    FcConfigSetCurrent (config);

    if (argv[i])
    {
	dirs = FcStrSetCreate ();
	if (!dirs)
	{
	    fprintf (stderr, "%s: Can't create list of directories\n",
		     argv[0]);
	    return 1;
	}
	while (argv[i])
	{
	    if (!FcStrSetAddFilename (dirs, (FcChar8 *) argv[i]))
	    {
		fprintf (stderr, "%s: Can't add directory\n", argv[0]);
		return 1;
	    }
	    i++;
	}
	list = FcStrListCreate (dirs);
	FcStrSetDestroy (dirs);
    }
    else
	list = FcConfigGetConfigDirs (config);

    if ((processed_dirs = FcStrSetCreate()) == NULL) {
	fprintf(stderr, "Cannot malloc\n");
	return 1;
    }
	
    changed = 0;
    ret = scanDirs (list, config, force, really_force, verbose, &changed);

    /*
     * Try to create CACHEDIR.TAG anyway.
     * This expects the fontconfig cache directory already exists.
     * If it doesn't, it won't be simply created.
     */
    FcCacheCreateTagFile (config);

    FcStrSetDestroy (processed_dirs);

    cleanCacheDirectories (config, verbose);

    /* 
     * Now we need to sleep a second  (or two, to be extra sure), to make
     * sure that timestamps for changes after this run of fc-cache are later
     * then any timestamps we wrote.  We don't use gettimeofday() because
     * sleep(3) can't be interrupted by a signal here -- this isn't in the
     * library, and there aren't any signals flying around here.
     */
    FcConfigDestroy (config);
    FcFini ();
    if (changed)
	sleep (2);
    if (verbose)
	printf ("%s: %s\n", argv[0], ret ? "failed" : "succeeded");
    return ret;
}
Beispiel #12
0
static int
scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, FcBool verbose, int *changed)
{
    int		    ret = 0;
    const FcChar8   *dir;
    FcStrSet	    *subdirs;
    FcStrList	    *sublist;
    FcCache	    *cache;
    struct stat	    statb;
    FcBool	    was_valid;
    int		    i;
    
    /*
     * Now scan all of the directories into separate databases
     * and write out the results
     */
    while ((dir = FcStrListNext (list)))
    {
	if (verbose)
	{
	    printf ("%s: ", dir);
	    fflush (stdout);
	}
	
	if (!dir)
	{
	    if (verbose)
		printf ("skipping, no such directory\n");
	    continue;
	}
	
	if (FcStrSetMember (processed_dirs, dir))
	{
	    if (verbose)
		printf ("skipping, looped directory detected\n");
	    continue;
	}

	if (stat ((char *) dir, &statb) == -1)
	{
	    switch (errno) {
	    case ENOENT:
	    case ENOTDIR:
		if (verbose)
		    printf ("skipping, no such directory\n");
		break;
	    default:
		fprintf (stderr, "\"%s\": ", dir);
		perror ("");
		ret++;
		break;
	    }
	    continue;
	}

	if (!S_ISDIR (statb.st_mode))
	{
	    fprintf (stderr, "\"%s\": not a directory, skipping\n", dir);
	    continue;
	}

	if (really_force)
	    FcDirCacheUnlink (dir, config);

	cache = NULL;
	was_valid = FcFalse;
	if (!force) {
	    cache = FcDirCacheLoad (dir, config, NULL);
	    if (cache)
		was_valid = FcTrue;
	}
	
	if (!cache)
	{
	    (*changed)++;
	    cache = FcDirCacheRead (dir, FcTrue, config);
	    if (!cache)
	    {
		fprintf (stderr, "%s: error scanning\n", dir);
		ret++;
		continue;
	    }
	}

	if (was_valid)
	{
	    if (verbose)
		printf ("skipping, existing cache is valid: %d fonts, %d dirs\n",
			FcCacheNumFont (cache), FcCacheNumSubdir (cache));
	}
	else
	{
	    if (verbose)
		printf ("caching, new cache contents: %d fonts, %d dirs\n", 
			FcCacheNumFont (cache), FcCacheNumSubdir (cache));

	    if (!FcDirCacheValid (dir))
	    {
		fprintf (stderr, "%s: failed to write cache\n", dir);
		(void) FcDirCacheUnlink (dir, config);
		ret++;
	    }
	}
	
	subdirs = FcStrSetCreate ();
	if (!subdirs)
	{
	    fprintf (stderr, "%s: Can't create subdir set\n", dir);
	    ret++;
	    FcDirCacheUnload (cache);
	    continue;
	}
	for (i = 0; i < FcCacheNumSubdir (cache); i++)
	    FcStrSetAdd (subdirs, FcCacheSubdir (cache, i));
	
	FcDirCacheUnload (cache);
	
	sublist = FcStrListCreate (subdirs);
	FcStrSetDestroy (subdirs);
	if (!sublist)
	{
	    fprintf (stderr, "%s: Can't create subdir list\n", dir);
	    ret++;
	    continue;
	}
	FcStrSetAdd (processed_dirs, dir);
	ret += scanDirs (sublist, config, force, really_force, verbose, changed);
    }
    FcStrListDone (list);
    return ret;
}
/*
 * Scan the specified directory and construct a cache of its contents
 */
FcCache *
FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
{
    FcStrSet		*dirs;
    FcBool		ret = FcTrue;
    FcFontSet		*set;
    FcCache		*cache = NULL;
    struct stat		dir_stat;

    if (FcDebug () & FC_DBG_FONTSET)
	printf ("cache scan dir %s\n", dir);

    if (FcStatChecksum ((char *) dir, &dir_stat) < 0)
    {
	if (errno != ENOENT)
	    ret = FcFalse;
	goto bail;
    }

    set = FcFontSetCreate();
    if (!set)
    {
	ret = FcFalse;
	goto bail;
    }

    dirs = FcStrSetCreate ();
    if (!dirs)
    {
	ret = FcFalse;
	goto bail1;
    }

    /*
     * Scan the dir
     */
    if (!FcDirScanConfig (set, dirs, NULL, dir, FcTrue, config))
    {
	ret = FcFalse;
	goto bail2;
    }

    /*
     * Build the cache object
     */
    cache = FcDirCacheBuild (set, dir, &dir_stat, dirs);
    if (!cache)
    {
	ret = FcFalse;
	goto bail2;
    }
    
    /*
     * Write out the cache file, ignoring any troubles
     */
    FcDirCacheWrite (cache, config);
    
 bail2:
    FcStrSetDestroy (dirs);
 bail1:
    FcFontSetDestroy (set);
 bail:
    return cache;
}
FcBool
FcDirScanConfig (FcFontSet	*set,
		 FcStrSet	*dirs,
		 FcBlanks	*blanks,
		 const FcChar8	*dir,
		 FcBool		force, /* XXX unused */
		 FcConfig	*config)
{
    DIR			*d;
    struct dirent	*e;
    FcStrSet		*files;
    FcChar8		*file;
    FcChar8		*base;
    FcBool		ret = FcTrue;
    int			i;

    if (!force)
	return FcFalse;

    if (!set && !dirs)
	return FcTrue;

    if (!blanks)
	blanks = FcConfigGetBlanks (config);

    /* freed below */
    file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
    if (!file) {
	ret = FcFalse;
	goto bail;
    }

    strcpy ((char *) file, (char *) dir);
    strcat ((char *) file, "/");
    base = file + strlen ((char *) file);
    
    if (FcDebug () & FC_DBG_SCAN)
	printf ("\tScanning dir %s\n", dir);
	
    d = opendir ((char *) dir);
    if (!d)
    {
	/* Don't complain about missing directories */
	if (errno != ENOENT)
	    ret = FcFalse;
	goto bail;
    }

    files = FcStrSetCreate ();
    if (!files)
    {
	ret = FcFalse;
	goto bail1;
    }
    while ((e = readdir (d)))
    {
	if (e->d_name[0] != '.' && strlen (e->d_name) < FC_MAX_FILE_LEN)
	{
	    strcpy ((char *) base, (char *) e->d_name);
	    if (!FcStrSetAdd (files, file)) {
		ret = FcFalse;
		goto bail2;
	    }
	}
    }

    /*
     * Sort files to make things prettier
     */
    qsort(files->strs, files->num, sizeof(FcChar8 *), cmpstringp);

    /*
     * Scan file files to build font patterns
     */
    for (i = 0; i < files->num; i++)
	FcFileScanConfig (set, dirs, blanks, files->strs[i], config);
    
bail2:
    FcStrSetDestroy (files);
bail1:
    closedir (d);
bail:
    return ret;
}
void
font_config_magic_class::
add_entry(FcPattern *p)
{
  FcMagicValue<FcChar8*> family_name, file_name, foundary_name, font_style;
  FcMagicValue<int> font_index, font_weight, font_slant;
  FcMagicValue<FcLangSet*> lang;
  
  FcGetMagicValue(p, FC_FILE, file_name);
  if(file_name.m_exists)
    {
      FontEntry entry_key;
      WRATHFontConfig::FontSpecification entry;
      
      GetPairFromFcMagicValue(entry_key.m_filename, file_name);
      
      FcGetMagicValue(p, FC_INDEX, font_index);
      GetPairFromFcMagicValue(entry_key.m_face_index, font_index);
      
      entry.font()=WRATHFontDatabase::fetch_font_entry(entry_key.m_filename, entry_key.m_face_index);
      
      FcGetMagicValue(p, FC_FAMILY, family_name);
      GetPairFromFcMagicValue(entry.m_fontconfig_details.m_family_name, family_name);
      
      FcGetMagicValue(p, FC_FOUNDRY, foundary_name);
      GetPairFromFcMagicValue(entry.m_fontconfig_details.m_foundary_name, foundary_name);
      
      FcGetMagicValue(p, FC_WEIGHT, font_weight);
      GetPairFromFcMagicValue(entry.m_fontconfig_details.m_weight, font_weight);
      
      FcGetMagicValue(p, FC_SLANT, font_slant);
      GetPairFromFcMagicValue(entry.m_fontconfig_details.m_slant, font_slant);
      
      FcGetMagicValue(p, FC_STYLE, font_style);
      GetPairFromFcMagicValue(entry.m_fontconfig_details.m_style, font_style);
      
      #if (FC_MAJOR>=2 && FC_MINOR>=7) || (FC_MAJOR>=3)   
      {        
        FcGetMagicValue(p, FC_LANG, lang);
        if(lang.m_exists)
          {
            FcStrSet *langs_as_strs;
            FcStrList *iter;
            FcChar8 *current;
            
            langs_as_strs=FcLangSetGetLangs(lang.m_value); //do we need to free this thing??
            iter=FcStrListCreate(langs_as_strs);
            
            for(current=FcStrListNext(iter); current; current=FcStrListNext(iter))
              {
                const char *str(reinterpret_cast<const char*>(current));
                entry.m_fontconfig_details.m_languages.insert(std::string(str));
              }
            FcStrListDone(iter);
            FcStrSetDestroy(langs_as_strs);
          }
      }
      #endif
              
      WRATHassert(m_font_list.find(entry.font())==m_font_list.end());
      m_font_list[entry.font()]=entry;
    }
}