Skip broken caches. Cache files are auto-written, don't rewrite in fc-cache.
Validate cache contents and skip broken caches, looking down cache path for valid ones. Every time a directory is scanned, it will be written to a cache file if possible, so fc-cache doesn't need to re-write the cache file. This makes detecting when the cache was generated a bit tricky, so we guess that if the cache wasn't valid before running and is valid afterwards, the cache file was written. Also, allow empty charsets to be serialized with null leaves/numbers. Eliminate a leak in FcEdit by switching to FcObject sooner. Call FcFini from fc-match to make valgrind happy.
This commit is contained in:
parent
09f9f6f62a
commit
2d3387fd72
|
@ -130,6 +130,7 @@ scanDirs (FcStrList *list, FcConfig *config, char *program, FcBool force, FcBool
|
||||||
FcStrSet *subdirs;
|
FcStrSet *subdirs;
|
||||||
FcStrList *sublist;
|
FcStrList *sublist;
|
||||||
struct stat statb;
|
struct stat statb;
|
||||||
|
FcBool was_valid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now scan all of the directories into separate databases
|
* Now scan all of the directories into separate databases
|
||||||
|
@ -160,14 +161,14 @@ scanDirs (FcStrList *list, FcConfig *config, char *program, FcBool force, FcBool
|
||||||
set = FcFontSetCreate ();
|
set = FcFontSetCreate ();
|
||||||
if (!set)
|
if (!set)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Can't create font set\n");
|
fprintf (stderr, "%s: Can't create font set\n", dir);
|
||||||
ret++;
|
ret++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
subdirs = FcStrSetCreate ();
|
subdirs = FcStrSetCreate ();
|
||||||
if (!subdirs)
|
if (!subdirs)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Can't create directory set\n");
|
fprintf (stderr, "%s: Can't create directory set\n", dir);
|
||||||
ret++;
|
ret++;
|
||||||
FcFontSetDestroy (set);
|
FcFontSetDestroy (set);
|
||||||
continue;
|
continue;
|
||||||
|
@ -219,15 +220,18 @@ scanDirs (FcStrList *list, FcConfig *config, char *program, FcBool force, FcBool
|
||||||
if (really_force)
|
if (really_force)
|
||||||
FcDirCacheUnlink (dir, config);
|
FcDirCacheUnlink (dir, config);
|
||||||
|
|
||||||
|
if (!force)
|
||||||
|
was_valid = FcDirCacheValid (dir, config);
|
||||||
|
|
||||||
if (!FcDirScanConfig (set, subdirs, FcConfigGetBlanks (config), dir, force, config))
|
if (!FcDirScanConfig (set, subdirs, FcConfigGetBlanks (config), dir, force, config))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "\"%s\": error scanning\n", dir);
|
fprintf (stderr, "%s: error scanning\n", dir);
|
||||||
FcFontSetDestroy (set);
|
FcFontSetDestroy (set);
|
||||||
FcStrSetDestroy (subdirs);
|
FcStrSetDestroy (subdirs);
|
||||||
ret++;
|
ret++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!force && FcDirCacheValid (dir, config))
|
if (!force && was_valid)
|
||||||
{
|
{
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("skipping, %d fonts, %d dirs\n",
|
printf ("skipping, %d fonts, %d dirs\n",
|
||||||
|
@ -239,15 +243,10 @@ scanDirs (FcStrList *list, FcConfig *config, char *program, FcBool force, FcBool
|
||||||
printf ("caching, %d fonts, %d dirs\n",
|
printf ("caching, %d fonts, %d dirs\n",
|
||||||
set->nfont, nsubdirs (subdirs));
|
set->nfont, nsubdirs (subdirs));
|
||||||
|
|
||||||
/* This is the only reason we can't combine
|
|
||||||
* Valid w/HasCurrentArch... */
|
|
||||||
if (!FcDirCacheValid (dir, config))
|
if (!FcDirCacheValid (dir, config))
|
||||||
if (!FcDirCacheUnlink (dir, config))
|
|
||||||
ret++;
|
|
||||||
|
|
||||||
if (!FcDirSave (set, subdirs, dir))
|
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Can't save cache for \"%s\"\n", dir);
|
fprintf (stderr, "%s: failed to write cache\n", dir);
|
||||||
|
(void) FcDirCacheUnlink (dir, config);
|
||||||
ret++;
|
ret++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,7 +255,7 @@ scanDirs (FcStrList *list, FcConfig *config, char *program, FcBool force, FcBool
|
||||||
FcStrSetDestroy (subdirs);
|
FcStrSetDestroy (subdirs);
|
||||||
if (!sublist)
|
if (!sublist)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Can't create subdir list in \"%s\"\n", dir);
|
fprintf (stderr, "%s: Can't create subdir list\n", dir);
|
||||||
ret++;
|
ret++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,5 +187,6 @@ main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
FcFontSetDestroy (fs);
|
FcFontSetDestroy (fs);
|
||||||
}
|
}
|
||||||
|
FcFini ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
144
src/fccache.c
144
src/fccache.c
|
@ -39,9 +39,6 @@
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
|
||||||
FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, off_t *size);
|
|
||||||
|
|
||||||
struct MD5Context {
|
struct MD5Context {
|
||||||
FcChar32 buf[4];
|
FcChar32 buf[4];
|
||||||
FcChar32 bits[2];
|
FcChar32 bits[2];
|
||||||
|
@ -53,23 +50,6 @@ static void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len);
|
||||||
static void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
|
static void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
|
||||||
static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]);
|
static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]);
|
||||||
|
|
||||||
#define FC_DBG_CACHE_REF 1024
|
|
||||||
|
|
||||||
/* Does not check that the cache has the appropriate arch section. */
|
|
||||||
FcBool
|
|
||||||
FcDirCacheValid (const FcChar8 *dir, FcConfig *config)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
fd = FcDirCacheOpen (config, dir, NULL);
|
|
||||||
|
|
||||||
if (fd < 0)
|
|
||||||
return FcFalse;
|
|
||||||
close (fd);
|
|
||||||
|
|
||||||
return FcTrue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CACHEBASE_LEN (1 + 32 + 1 + sizeof (FC_ARCHITECTURE) + sizeof (FC_CACHE_SUFFIX))
|
#define CACHEBASE_LEN (1 + 32 + 1 + sizeof (FC_ARCHITECTURE) + sizeof (FC_CACHE_SUFFIX))
|
||||||
|
|
||||||
static const char bin2hex[] = { '0', '1', '2', '3',
|
static const char bin2hex[] = { '0', '1', '2', '3',
|
||||||
|
@ -209,27 +189,31 @@ FcCacheRead (FcConfig *config)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opens the cache file for 'dir' for reading.
|
/*
|
||||||
* This searches the list of cache dirs for the relevant cache file,
|
* Look for a cache file for the specified dir. Attempt
|
||||||
* returning the first one found.
|
* to use each one we find, stopping when the callback
|
||||||
|
* indicates success
|
||||||
*/
|
*/
|
||||||
static int
|
static FcBool
|
||||||
FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, off_t *size)
|
FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
|
||||||
|
FcBool (*callback) (int fd, off_t size, void *closure),
|
||||||
|
void *closure)
|
||||||
{
|
{
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
FcChar8 cache_base[CACHEBASE_LEN];
|
FcChar8 cache_base[CACHEBASE_LEN];
|
||||||
FcStrList *list;
|
FcStrList *list;
|
||||||
FcChar8 *cache_dir;
|
FcChar8 *cache_dir;
|
||||||
struct stat file_stat, dir_stat;
|
struct stat file_stat, dir_stat;
|
||||||
|
FcBool ret = FcFalse;
|
||||||
|
|
||||||
if (stat ((char *) dir, &dir_stat) < 0)
|
if (stat ((char *) dir, &dir_stat) < 0)
|
||||||
return -1;
|
return FcFalse;
|
||||||
|
|
||||||
FcDirCacheBasename (dir, cache_base);
|
FcDirCacheBasename (dir, cache_base);
|
||||||
|
|
||||||
list = FcStrListCreate (config->cacheDirs);
|
list = FcStrListCreate (config->cacheDirs);
|
||||||
if (!list)
|
if (!list)
|
||||||
return -1;
|
return FcFalse;
|
||||||
|
|
||||||
while ((cache_dir = FcStrListNext (list)))
|
while ((cache_dir = FcStrListNext (list)))
|
||||||
{
|
{
|
||||||
|
@ -242,43 +226,29 @@ FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, off_t *size)
|
||||||
if (fstat (fd, &file_stat) >= 0 &&
|
if (fstat (fd, &file_stat) >= 0 &&
|
||||||
dir_stat.st_mtime <= file_stat.st_mtime)
|
dir_stat.st_mtime <= file_stat.st_mtime)
|
||||||
{
|
{
|
||||||
if (size)
|
ret = (*callback) (fd, file_stat.st_size, closure);
|
||||||
*size = file_stat.st_size;
|
if (ret)
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
close (fd);
|
close (fd);
|
||||||
fd = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FcStrListDone (list);
|
FcStrListDone (list);
|
||||||
|
|
||||||
return fd;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static FcBool
|
||||||
FcDirCacheUnmap (FcCache *cache)
|
FcDirCacheLoad (int fd, off_t size, void *closure)
|
||||||
{
|
|
||||||
if (cache->magic == FC_CACHE_MAGIC_COPY)
|
|
||||||
{
|
|
||||||
free (cache);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if defined(HAVE_MMAP) || defined(__CYGWIN__)
|
|
||||||
munmap (cache, cache->size);
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
UnmapViewOfFile (cache);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read serialized state from the cache file */
|
|
||||||
FcCache *
|
|
||||||
FcDirCacheMap (int fd, off_t size)
|
|
||||||
{
|
{
|
||||||
FcCache *cache;
|
FcCache *cache;
|
||||||
FcBool allocated = FcFalse;
|
FcBool allocated = FcFalse;
|
||||||
|
|
||||||
if (size < sizeof (FcCache))
|
if (size < sizeof (FcCache))
|
||||||
return NULL;
|
return FcFalse;
|
||||||
#if defined(HAVE_MMAP) || defined(__CYGWIN__)
|
#if defined(HAVE_MMAP) || defined(__CYGWIN__)
|
||||||
cache = mmap (0, size, PROT_READ, MAP_SHARED, fd, 0);
|
cache = mmap (0, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
@ -299,12 +269,12 @@ FcDirCacheMap (int fd, off_t size)
|
||||||
{
|
{
|
||||||
cache = malloc (size);
|
cache = malloc (size);
|
||||||
if (!cache)
|
if (!cache)
|
||||||
return NULL;
|
return FcFalse;
|
||||||
|
|
||||||
if (read (fd, cache, size) != size)
|
if (read (fd, cache, size) != size)
|
||||||
{
|
{
|
||||||
free (cache);
|
free (cache);
|
||||||
return NULL;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
allocated = FcTrue;
|
allocated = FcTrue;
|
||||||
}
|
}
|
||||||
|
@ -321,42 +291,42 @@ FcDirCacheMap (int fd, off_t size)
|
||||||
UnmapViewOfFile (cache);
|
UnmapViewOfFile (cache);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return NULL;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark allocated caches so they're freed rather than unmapped */
|
/* Mark allocated caches so they're freed rather than unmapped */
|
||||||
if (allocated)
|
if (allocated)
|
||||||
cache->magic = FC_CACHE_MAGIC_COPY;
|
cache->magic = FC_CACHE_MAGIC_COPY;
|
||||||
|
|
||||||
|
*((FcCache **) closure) = cache;
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcCache *
|
||||||
|
FcDirCacheMap (int fd, off_t size)
|
||||||
|
{
|
||||||
|
FcCache *cache;
|
||||||
|
|
||||||
|
if (FcDirCacheLoad (fd, size, &cache))
|
||||||
return cache;
|
return cache;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs,
|
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs,
|
||||||
const FcChar8 *dir, FcConfig *config)
|
const FcChar8 *dir, FcConfig *config)
|
||||||
{
|
{
|
||||||
int fd;
|
|
||||||
FcCache *cache;
|
FcCache *cache;
|
||||||
off_t size;
|
|
||||||
int i;
|
int i;
|
||||||
FcFontSet *cache_set;
|
FcFontSet *cache_set;
|
||||||
intptr_t *cache_dirs;
|
intptr_t *cache_dirs;
|
||||||
FcPattern **cache_fonts;
|
FcPattern **cache_fonts;
|
||||||
|
|
||||||
fd = FcDirCacheOpen (config, dir, &size);
|
if (!FcDirCacheProcess (config, dir,
|
||||||
if (fd < 0)
|
FcDirCacheLoad,
|
||||||
|
&cache))
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
cache = FcDirCacheMap (fd, size);
|
|
||||||
|
|
||||||
if (!cache)
|
|
||||||
{
|
|
||||||
if (FcDebug() & FC_DBG_CACHE)
|
|
||||||
printf ("FcDirCacheRead failed to map cache for %s\n", dir);
|
|
||||||
close (fd);
|
|
||||||
return FcFalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
cache_set = FcCacheSet (cache);
|
cache_set = FcCacheSet (cache);
|
||||||
cache_fonts = FcFontSetFonts(cache_set);
|
cache_fonts = FcFontSetFonts(cache_set);
|
||||||
if (FcDebug() & FC_DBG_CACHE)
|
if (FcDebug() & FC_DBG_CACHE)
|
||||||
|
@ -383,10 +353,48 @@ FcDirCacheRead (FcFontSet * set, FcStrSet * dirs,
|
||||||
if (config)
|
if (config)
|
||||||
FcConfigAddFontDir (config, (FcChar8 *)dir);
|
FcConfigAddFontDir (config, (FcChar8 *)dir);
|
||||||
|
|
||||||
close (fd);
|
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FcBool
|
||||||
|
FcDirCacheValidate (int fd, off_t size, void *closure)
|
||||||
|
{
|
||||||
|
FcBool ret = FcTrue;
|
||||||
|
FcCache c;
|
||||||
|
struct stat file_stat;
|
||||||
|
|
||||||
|
if (read (fd, &c, sizeof (FcCache)) != sizeof (FcCache))
|
||||||
|
ret = FcFalse;
|
||||||
|
else if (fstat (fd, &file_stat) < 0)
|
||||||
|
ret = FcFalse;
|
||||||
|
else if (c.magic != FC_CACHE_MAGIC)
|
||||||
|
ret = FcFalse;
|
||||||
|
else if (file_stat.st_size != c.size)
|
||||||
|
ret = FcFalse;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcDirCacheValid (const FcChar8 *dir, FcConfig *config)
|
||||||
|
{
|
||||||
|
return FcDirCacheProcess (config, dir, FcDirCacheValidate, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FcDirCacheUnmap (FcCache *cache)
|
||||||
|
{
|
||||||
|
if (cache->magic == FC_CACHE_MAGIC_COPY)
|
||||||
|
{
|
||||||
|
free (cache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if defined(HAVE_MMAP) || defined(__CYGWIN__)
|
||||||
|
munmap (cache, cache->size);
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
UnmapViewOfFile (cache);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cache file is:
|
* Cache file is:
|
||||||
*
|
*
|
||||||
|
|
80
src/fccfg.c
80
src/fccfg.c
|
@ -77,39 +77,9 @@ FcConfigCreate (void)
|
||||||
if (!config->rejectPatterns)
|
if (!config->rejectPatterns)
|
||||||
goto bail7;
|
goto bail7;
|
||||||
|
|
||||||
config->cache = 0;
|
|
||||||
if (FcConfigHome())
|
|
||||||
if (!FcConfigSetCache (config, (FcChar8 *) ("~/" FC_USER_CACHE_FILE)))
|
|
||||||
goto bail8;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (config->cache == 0)
|
|
||||||
{
|
|
||||||
/* If no home, use the temp folder. */
|
|
||||||
FcChar8 dummy[1];
|
|
||||||
int templen = GetTempPath (1, dummy);
|
|
||||||
FcChar8 *temp = malloc (templen + 1);
|
|
||||||
|
|
||||||
if (temp)
|
|
||||||
{
|
|
||||||
FcChar8 *cache_dir;
|
|
||||||
|
|
||||||
GetTempPath (templen + 1, temp);
|
|
||||||
cache_dir = FcStrPlus (temp, FC_USER_CACHE_FILE);
|
|
||||||
free (temp);
|
|
||||||
if (!FcConfigSetCache (config, cache_dir))
|
|
||||||
{
|
|
||||||
FcStrFree (cache_dir);
|
|
||||||
goto bail8;
|
|
||||||
}
|
|
||||||
FcStrFree (cache_dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
config->cacheDirs = FcStrSetCreate ();
|
config->cacheDirs = FcStrSetCreate ();
|
||||||
if (!config->cacheDirs)
|
if (!config->cacheDirs)
|
||||||
goto bail9;
|
goto bail8;
|
||||||
|
|
||||||
config->blanks = 0;
|
config->blanks = 0;
|
||||||
|
|
||||||
|
@ -119,13 +89,13 @@ FcConfigCreate (void)
|
||||||
for (set = FcSetSystem; set <= FcSetApplication; set++)
|
for (set = FcSetSystem; set <= FcSetApplication; set++)
|
||||||
config->fonts[set] = 0;
|
config->fonts[set] = 0;
|
||||||
|
|
||||||
|
config->caches = NULL;
|
||||||
|
|
||||||
config->rescanTime = time(0);
|
config->rescanTime = time(0);
|
||||||
config->rescanInterval = 30;
|
config->rescanInterval = 30;
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
|
|
||||||
bail9:
|
|
||||||
FcStrFree (config->cache);
|
|
||||||
bail8:
|
bail8:
|
||||||
FcFontSetDestroy (config->rejectPatterns);
|
FcFontSetDestroy (config->rejectPatterns);
|
||||||
bail7:
|
bail7:
|
||||||
|
@ -226,6 +196,7 @@ void
|
||||||
FcConfigDestroy (FcConfig *config)
|
FcConfigDestroy (FcConfig *config)
|
||||||
{
|
{
|
||||||
FcSetName set;
|
FcSetName set;
|
||||||
|
FcCacheList *cl, *cl_next;
|
||||||
|
|
||||||
if (config == _fcConfig)
|
if (config == _fcConfig)
|
||||||
_fcConfig = 0;
|
_fcConfig = 0;
|
||||||
|
@ -242,15 +213,19 @@ FcConfigDestroy (FcConfig *config)
|
||||||
if (config->blanks)
|
if (config->blanks)
|
||||||
FcBlanksDestroy (config->blanks);
|
FcBlanksDestroy (config->blanks);
|
||||||
|
|
||||||
if (config->cache)
|
|
||||||
FcStrFree (config->cache);
|
|
||||||
|
|
||||||
FcSubstDestroy (config->substPattern);
|
FcSubstDestroy (config->substPattern);
|
||||||
FcSubstDestroy (config->substFont);
|
FcSubstDestroy (config->substFont);
|
||||||
for (set = FcSetSystem; set <= FcSetApplication; set++)
|
for (set = FcSetSystem; set <= FcSetApplication; set++)
|
||||||
if (config->fonts[set])
|
if (config->fonts[set])
|
||||||
FcFontSetDestroy (config->fonts[set]);
|
FcFontSetDestroy (config->fonts[set]);
|
||||||
|
|
||||||
|
for (cl = config->caches; cl; cl = cl_next)
|
||||||
|
{
|
||||||
|
cl_next = cl->next;
|
||||||
|
FcDirCacheUnmap (cl->cache);
|
||||||
|
free (cl);
|
||||||
|
}
|
||||||
|
|
||||||
free (config);
|
free (config);
|
||||||
FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig));
|
FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig));
|
||||||
}
|
}
|
||||||
|
@ -453,30 +428,10 @@ FcConfigGetConfigFiles (FcConfig *config)
|
||||||
return FcStrListCreate (config->configFiles);
|
return FcStrListCreate (config->configFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
FcBool
|
|
||||||
FcConfigSetCache (FcConfig *config,
|
|
||||||
const FcChar8 *c)
|
|
||||||
{
|
|
||||||
FcChar8 *new = FcStrCopyFilename (c);
|
|
||||||
|
|
||||||
if (!new)
|
|
||||||
return FcFalse;
|
|
||||||
if (config->cache)
|
|
||||||
FcStrFree (config->cache);
|
|
||||||
config->cache = new;
|
|
||||||
return FcTrue;
|
|
||||||
}
|
|
||||||
|
|
||||||
FcChar8 *
|
FcChar8 *
|
||||||
FcConfigGetCache (FcConfig *config)
|
FcConfigGetCache (FcConfig *config)
|
||||||
{
|
{
|
||||||
if (!config)
|
return NULL;
|
||||||
{
|
|
||||||
config = FcConfigGetCurrent ();
|
|
||||||
if (!config)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return config->cache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FcFontSet *
|
FcFontSet *
|
||||||
|
@ -502,7 +457,18 @@ FcConfigSetFonts (FcConfig *config,
|
||||||
config->fonts[set] = fonts;
|
config->fonts[set] = fonts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcConfigAddCache (FcConfig *config, FcCache *cache)
|
||||||
|
{
|
||||||
|
FcCacheList *cl = malloc (sizeof (FcCacheList));
|
||||||
|
|
||||||
|
if (!cl)
|
||||||
|
return FcFalse;
|
||||||
|
cl->cache = cache;
|
||||||
|
cl->next = config->caches;
|
||||||
|
config->caches = cl;
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
FcBlanks *
|
FcBlanks *
|
||||||
FcConfigGetBlanks (FcConfig *config)
|
FcConfigGetBlanks (FcConfig *config)
|
||||||
|
|
|
@ -1297,6 +1297,8 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs)
|
||||||
cs_serialized->ref = FC_REF_CONSTANT;
|
cs_serialized->ref = FC_REF_CONSTANT;
|
||||||
cs_serialized->num = cs->num;
|
cs_serialized->num = cs->num;
|
||||||
|
|
||||||
|
if (cs->num)
|
||||||
|
{
|
||||||
leaves = FcCharSetLeaves (cs);
|
leaves = FcCharSetLeaves (cs);
|
||||||
leaves_serialized = FcSerializePtr (serialize, leaves);
|
leaves_serialized = FcSerializePtr (serialize, leaves);
|
||||||
if (!leaves_serialized)
|
if (!leaves_serialized)
|
||||||
|
@ -1324,6 +1326,12 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs)
|
||||||
leaf_serialized);
|
leaf_serialized);
|
||||||
numbers_serialized[i] = numbers[i];
|
numbers_serialized[i] = numbers[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cs_serialized->leaves_offset = 0;
|
||||||
|
cs_serialized->numbers_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return cs_serialized;
|
return cs_serialized;
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,5 +288,5 @@ FcDirScan (FcFontSet *set,
|
||||||
FcBool
|
FcBool
|
||||||
FcDirSave (FcFontSet *set, FcStrSet * dirs, const FcChar8 *dir)
|
FcDirSave (FcFontSet *set, FcStrSet * dirs, const FcChar8 *dir)
|
||||||
{
|
{
|
||||||
return FcDirCacheWrite (set, dirs, dir, FcConfigGetCurrent ());
|
return FcFalse;
|
||||||
}
|
}
|
||||||
|
|
19
src/fcint.h
19
src/fcint.h
|
@ -405,6 +405,11 @@ struct _FcBlanks {
|
||||||
FcChar32 *blanks;
|
FcChar32 *blanks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _FcCacheList {
|
||||||
|
struct _FcCacheList *next;
|
||||||
|
FcCache *cache;
|
||||||
|
} FcCacheList;
|
||||||
|
|
||||||
struct _FcConfig {
|
struct _FcConfig {
|
||||||
/*
|
/*
|
||||||
* File names loaded from the configuration -- saved here as the
|
* File names loaded from the configuration -- saved here as the
|
||||||
|
@ -412,7 +417,6 @@ struct _FcConfig {
|
||||||
* and those directives may occur in any order
|
* and those directives may occur in any order
|
||||||
*/
|
*/
|
||||||
FcStrSet *configDirs; /* directories to scan for fonts */
|
FcStrSet *configDirs; /* directories to scan for fonts */
|
||||||
FcChar8 *cache; /* name of per-user cache file */
|
|
||||||
/*
|
/*
|
||||||
* Set of allowed blank chars -- used to
|
* Set of allowed blank chars -- used to
|
||||||
* trim fonts of bogus glyphs
|
* trim fonts of bogus glyphs
|
||||||
|
@ -455,6 +459,11 @@ struct _FcConfig {
|
||||||
* match preferrentially
|
* match preferrentially
|
||||||
*/
|
*/
|
||||||
FcFontSet *fonts[FcSetApplication + 1];
|
FcFontSet *fonts[FcSetApplication + 1];
|
||||||
|
/*
|
||||||
|
* Font cache information is mapped from cache files
|
||||||
|
* the configuration is destroyed, the files need to be unmapped
|
||||||
|
*/
|
||||||
|
FcCacheList *caches;
|
||||||
/*
|
/*
|
||||||
* Fontconfig can periodically rescan the system configuration
|
* Fontconfig can periodically rescan the system configuration
|
||||||
* and font directories. This rescanning occurs when font
|
* and font directories. This rescanning occurs when font
|
||||||
|
@ -525,10 +534,6 @@ FcBool
|
||||||
FcConfigAddConfigFile (FcConfig *config,
|
FcConfigAddConfigFile (FcConfig *config,
|
||||||
const FcChar8 *f);
|
const FcChar8 *f);
|
||||||
|
|
||||||
FcBool
|
|
||||||
FcConfigSetCache (FcConfig *config,
|
|
||||||
const FcChar8 *c);
|
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcConfigAddBlank (FcConfig *config,
|
FcConfigAddBlank (FcConfig *config,
|
||||||
FcChar32 blank);
|
FcChar32 blank);
|
||||||
|
@ -570,6 +575,10 @@ FcConfigAcceptFont (FcConfig *config,
|
||||||
FcFileTime
|
FcFileTime
|
||||||
FcConfigModifiedTime (FcConfig *config);
|
FcConfigModifiedTime (FcConfig *config);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcConfigAddCache (FcConfig *config, FcCache *cache);
|
||||||
|
|
||||||
|
/* fcserialize.c */
|
||||||
intptr_t
|
intptr_t
|
||||||
FcAlignSize (intptr_t size);
|
FcAlignSize (intptr_t size);
|
||||||
|
|
||||||
|
|
19
src/fcxml.c
19
src/fcxml.c
|
@ -668,7 +668,7 @@ FcTestCreate (FcConfigParse *parse,
|
||||||
|
|
||||||
static FcEdit *
|
static FcEdit *
|
||||||
FcEditCreate (FcConfigParse *parse,
|
FcEditCreate (FcConfigParse *parse,
|
||||||
const char *field,
|
FcObject object,
|
||||||
FcOp op,
|
FcOp op,
|
||||||
FcExpr *expr,
|
FcExpr *expr,
|
||||||
FcValueBinding binding)
|
FcValueBinding binding)
|
||||||
|
@ -680,7 +680,7 @@ FcEditCreate (FcConfigParse *parse,
|
||||||
const FcObjectType *o;
|
const FcObjectType *o;
|
||||||
|
|
||||||
e->next = 0;
|
e->next = 0;
|
||||||
e->object = FcObjectFromName (field);
|
e->object = object;
|
||||||
e->op = op;
|
e->op = op;
|
||||||
e->expr = expr;
|
e->expr = expr;
|
||||||
e->binding = binding;
|
e->binding = binding;
|
||||||
|
@ -1410,7 +1410,7 @@ FcParseAlias (FcConfigParse *parse)
|
||||||
if (prefer)
|
if (prefer)
|
||||||
{
|
{
|
||||||
edit = FcEditCreate (parse,
|
edit = FcEditCreate (parse,
|
||||||
FcConfigSaveField ("family"),
|
FC_FAMILY_OBJECT,
|
||||||
FcOpPrepend,
|
FcOpPrepend,
|
||||||
prefer,
|
prefer,
|
||||||
FcValueBindingWeak);
|
FcValueBindingWeak);
|
||||||
|
@ -1423,7 +1423,7 @@ FcParseAlias (FcConfigParse *parse)
|
||||||
{
|
{
|
||||||
next = edit;
|
next = edit;
|
||||||
edit = FcEditCreate (parse,
|
edit = FcEditCreate (parse,
|
||||||
FcConfigSaveField ("family"),
|
FC_FAMILY_OBJECT,
|
||||||
FcOpAppend,
|
FcOpAppend,
|
||||||
accept,
|
accept,
|
||||||
FcValueBindingWeak);
|
FcValueBindingWeak);
|
||||||
|
@ -1436,7 +1436,7 @@ FcParseAlias (FcConfigParse *parse)
|
||||||
{
|
{
|
||||||
next = edit;
|
next = edit;
|
||||||
edit = FcEditCreate (parse,
|
edit = FcEditCreate (parse,
|
||||||
FcConfigSaveField ("family"),
|
FC_FAMILY_OBJECT,
|
||||||
FcOpAppendLast,
|
FcOpAppendLast,
|
||||||
def,
|
def,
|
||||||
FcValueBindingWeak);
|
FcValueBindingWeak);
|
||||||
|
@ -1791,7 +1791,8 @@ FcParseEdit (FcConfigParse *parse)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr = FcPopBinary (parse, FcOpComma);
|
expr = FcPopBinary (parse, FcOpComma);
|
||||||
edit = FcEditCreate (parse, (char *) FcStrCopy (name), mode, expr, binding);
|
edit = FcEditCreate (parse, FcObjectFromName ((char *) name),
|
||||||
|
mode, expr, binding);
|
||||||
if (!edit)
|
if (!edit)
|
||||||
{
|
{
|
||||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||||
|
@ -2074,11 +2075,7 @@ FcEndElement(void *userData, const XML_Char *name)
|
||||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!FcStrUsesHome (data) || FcConfigHome ())
|
/* discard this data; no longer used */
|
||||||
{
|
|
||||||
if (!FcConfigSetCache (parse->config, data))
|
|
||||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
|
||||||
}
|
|
||||||
FcStrFree (data);
|
FcStrFree (data);
|
||||||
break;
|
break;
|
||||||
case FcElementInclude:
|
case FcElementInclude:
|
||||||
|
|
Loading…
Reference in New Issue