[Fontconfig] Sigh. What to do about per-user fonts...
Keith Packard
keithp at keithp.com
Fri Apr 28 01:26:30 PDT 2006
On Thu, 2006-04-27 at 18:27 -0700, Patrick Lam wrote:
> Right. That works best when you don't stick cache files in ~/.fonts
> directly, of course.
Here's just the cache dir piece of the patch, without the magic
avoid-the-rescan stuff added.
It's a huge patch because it rewrites all of the cache file lookup code.
Note that this *also* removes the collision avoidence code, which was
busted. It should still identify collisions and fail to save the cache
file in that case, which should be fairly harmless (just dumping stuff
in the per-user cache). Note that MD5 is a strong hash, so this
'shouldn't happen'.
-keith
Index: configure.in
===================================================================
RCS file: /cvs/fontconfig/fontconfig/configure.in,v
retrieving revision 1.66.2.12
diff -u -p -r1.66.2.12 configure.in
--- configure.in 25 Apr 2006 15:33:07 -0000 1.66.2.12
+++ configure.in 28 Apr 2006 08:15:26 -0000
@@ -1,5 +1,5 @@
dnl
-dnl $Id: configure.in,v 1.66.2.12 2006-04-25 15:33:07 plam Exp $
+dnl $Id: configure.in,v 1.66.2.12 2006/04/25 15:33:07 plam Exp $
dnl
dnl Copyright © 2003 Keith Packard
dnl
@@ -431,6 +431,22 @@ esac
AC_SUBST(FC_FONTPATH)
+#
+# Set default cache directory path
+#
+AC_ARG_WITH(cache-dir, [ --with-cache-dir=DIR Use DIR to store cache files (default /var/cache/fontconfig)], fc_cachedir="$withval", fc_cachedir=yes)
+
+case $fc_cachedir in
+no|yes)
+ fc_cachedir=`eval echo "${localstatedir}/cache/"${PACKAGE}`
+ ;;
+*)
+ ;;
+esac
+AC_SUBST(fc_cachedir)
+FC_CACHEDIR=${fc_cachedir}
+AC_SUBST(FC_CACHEDIR)
+
FC_FONTDATE=`LC_ALL=C date`
AC_SUBST(FC_FONTDATE)
@@ -516,12 +532,6 @@ fi
AC_SUBST(DOCDIR)
-#
-# Make /var/cache/fontconfig directory available to source code
-#
-
-pkgcachedir='${localstatedir}/cache/'${PACKAGE}
-AC_SUBST(pkgcachedir)
AC_OUTPUT([
Makefile
Index: fonts.conf.in
===================================================================
RCS file: /cvs/fontconfig/fontconfig/fonts.conf.in,v
retrieving revision 1.32.2.7
diff -u -p -r1.32.2.7 fonts.conf.in
--- fonts.conf.in 15 Apr 2006 00:25:20 -0000 1.32.2.7
+++ fonts.conf.in 28 Apr 2006 08:18:21 -0000
@@ -27,6 +27,11 @@
@FC_FONTPATH@
<dir>~/.fonts</dir>
+<!-- Font cache directory list -->
+
+ <cachedir>@FC_CACHEDIR@</cachedir>
+ <cachedir>~/.fonts/fontconfig</cachedir>
+
<!--
Accept deprecated 'mono' alias, replacing it with 'monospace'
-->
Index: fonts.dtd
===================================================================
RCS file: /cvs/fontconfig/fontconfig/fonts.dtd,v
retrieving revision 1.11
diff -u -p -r1.11 fonts.dtd
--- fonts.dtd 4 Dec 2004 19:41:10 -0000 1.11
+++ fonts.dtd 28 Apr 2006 06:39:21 -0000
@@ -23,6 +23,18 @@
<!ATTLIST cache xml:space (default|preserve) 'preserve'>
<!--
+ Add a directory that is searched for font cache files.
+ These hold per-directory cache data and are searched in
+ order for each directory. When writing cache files, the first
+ directory which allows the cache file to be created is used.
+
+ A leading '~' in a directory name is replaced with the users
+ home directory path.
+-->
+<!ELEMENT cachedir (#PCDATA)>
+<!ATTLIST cachedir xml:space (default|preserve) 'preserve'>
+
+<!--
Reference another configuration file; note that this
is another complete font configuration file and not
just a file included by the XML parser.
Index: fc-cache/fc-cache.c
===================================================================
RCS file: /cvs/fontconfig/fontconfig/fc-cache/fc-cache.c,v
retrieving revision 1.17.2.21
diff -u -p -r1.17.2.21 fc-cache.c
--- fc-cache/fc-cache.c 25 Apr 2006 05:57:41 -0000 1.17.2.21
+++ fc-cache/fc-cache.c 28 Apr 2006 07:47:05 -0000
@@ -230,7 +230,8 @@ scanDirs (FcStrList *list, FcConfig *con
ret++;
continue;
}
- if (!force && FcDirCacheValid (dir) && FcDirCacheHasCurrentArch (dir))
+ if (!force && FcDirCacheValid (dir, config) &&
+ FcDirCacheHasCurrentArch (dir, config))
{
if (verbose)
printf ("skipping, %d fonts, %d dirs\n",
@@ -244,14 +245,12 @@ scanDirs (FcStrList *list, FcConfig *con
/* This is the only reason we can't combine
* Valid w/HasCurrentArch... */
- if (!FcDirCacheValid (dir))
+ if (!FcDirCacheValid (dir, config))
if (!FcDirCacheUnlink (dir, config))
ret++;
if (!FcDirSave (set, subdirs, dir))
{
- if (!ret)
- fprintf (stderr, "Caches are currently saved to \"%s\"\n", PKGCACHEDIR);
fprintf (stderr, "Can't save cache for \"%s\"\n", dir);
ret++;
}
Index: fontconfig/fontconfig.h
===================================================================
RCS file: /cvs/fontconfig/fontconfig/fontconfig/fontconfig.h,v
retrieving revision 1.69.2.21
diff -u -p -r1.69.2.21 fontconfig.h
--- fontconfig/fontconfig.h 19 Apr 2006 16:17:19 -0000 1.69.2.21
+++ fontconfig/fontconfig.h 28 Apr 2006 07:28:41 -0000
@@ -276,10 +276,10 @@ typedef struct _FcStrSet FcStrSet;
_FCFUNCPROTOBEGIN
FcBool
-FcDirCacheValid (const FcChar8 *cache_file);
+FcDirCacheValid (const FcChar8 *cache_file, FcConfig *config);
FcBool
-FcDirCacheHasCurrentArch (const FcChar8 *dir);
+FcDirCacheHasCurrentArch (const FcChar8 *dir, FcConfig *config);
FcBool
FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config);
Index: src/Makefile.am
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/Makefile.am,v
retrieving revision 1.12.4.7
diff -u -p -r1.12.4.7 Makefile.am
--- src/Makefile.am 25 Apr 2006 15:33:07 -0000 1.12.4.7
+++ src/Makefile.am 28 Apr 2006 04:54:09 -0000
@@ -1,5 +1,5 @@
#
-# $Id: Makefile.am,v 1.12.4.7 2006-04-25 15:33:07 plam Exp $
+# $Id: Makefile.am,v 1.12.4.7 2006/04/25 15:33:07 plam Exp $
#
# Copyright © 2003 Keith Packard
#
@@ -63,8 +63,6 @@ uninstall-ms-import-lib:
endif
-AM_CPPFLAGS = -DPKGCACHEDIR='"${pkgcachedir}"'
-
INCLUDES = \
-I$(top_srcdir) \
-I$(top_srcdir)/src \
@@ -72,6 +70,7 @@ INCLUDES = \
$(LIBXML2_CFLAGS) \
$(EXPAT_CFLAGS) \
$(WARN_CFLAGS) \
+ -DFC_CACHEDIR='"$(FC_CACHEDIR)"' \
-DFONTCONFIG_PATH='"$(CONFDIR)"'
EXTRA_DIST = fontconfig.def.in
Index: src/fccache.c
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/fccache.c,v
retrieving revision 1.23.4.88
diff -u -p -r1.23.4.88 fccache.c
--- src/fccache.c 27 Apr 2006 07:11:44 -0000 1.23.4.88
+++ src/fccache.c 28 Apr 2006 08:05:19 -0000
@@ -45,10 +45,7 @@
#endif
static int
-FcDirCacheOpen (const FcChar8 * dir);
-
-static char *
-FcDirCacheHashName (const FcChar8 * dir, int collisions);
+FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, FcChar8 **cache_path);
static off_t
FcCacheSkipToArch (int fd, const char * arch);
@@ -746,7 +743,7 @@ FcCacheCopyOld (int fd, int fd_orig, off
* cache, and the hashed location has an up-to-date cache. Oh well,
* sucks to be you in that case! */
FcBool
-FcDirCacheValid (const FcChar8 *dir)
+FcDirCacheValid (const FcChar8 *dir, FcConfig *config)
{
struct stat file_stat, dir_stat;
int fd;
@@ -754,7 +751,7 @@ FcDirCacheValid (const FcChar8 *dir)
if (stat ((char *) dir, &dir_stat) < 0)
return FcFalse;
- fd = FcDirCacheOpen (dir);
+ fd = FcDirCacheOpen (config, dir, NULL);
if (fd < 0)
return FcFalse;
@@ -780,7 +777,7 @@ FcDirCacheValid (const FcChar8 *dir)
/* Assumes that the cache file in 'dir' exists.
* Checks that the cache has the appropriate arch section. */
FcBool
-FcDirCacheHasCurrentArch (const FcChar8 *dir)
+FcDirCacheHasCurrentArch (const FcChar8 *dir, FcConfig *config)
{
int fd;
off_t current_arch_start;
@@ -788,7 +785,7 @@ FcDirCacheHasCurrentArch (const FcChar8
FcCache metadata;
char subdirName[FC_MAX_FILE_LEN + 1 + 12 + 1];
- fd = FcDirCacheOpen (dir);
+ fd = FcDirCacheOpen (config, dir, NULL);
if (fd < 0)
goto bail;
@@ -825,57 +822,81 @@ FcDirCacheHasCurrentArch (const FcChar8
return FcFalse;
}
-FcBool
-FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config)
+#define CACHEBASE_LEN (1 + 32 + sizeof (FC_CACHE_SUFFIX))
+
+static const char bin2hex[] = { '0', '1', '2', '3',
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+ 'c', 'd', 'e', 'f' };
+
+static FcChar8 *
+FcDirCacheBasename (const FcChar8 * dir, FcChar8 cache_base[CACHEBASE_LEN])
{
- char *cache_hashed = 0;
- int fd, collisions;
- struct stat cache_stat;
- char dir_buf[FC_MAX_FILE_LEN];
+ unsigned char hash[16];
+ FcChar8 *hex_hash;
+ int cnt;
+ struct MD5Context ctx;
- dir = FcConfigNormalizeFontDir (config, dir);
+ MD5Init (&ctx);
+ MD5Update (&ctx, (unsigned char *)dir, strlen ((char *) dir));
- /* Remove any applicable hashed files. */
- fd = -1; collisions = 0;
- do
+ MD5Final (hash, &ctx);
+
+ cache_base[0] = '/';
+ hex_hash = cache_base + 1;
+ for (cnt = 0; cnt < 16; ++cnt)
{
- if (cache_hashed)
- FcStrFree ((FcChar8 *)cache_hashed);
+ hex_hash[2*cnt ] = bin2hex[hash[cnt] >> 4];
+ hex_hash[2*cnt+1] = bin2hex[hash[cnt] & 0xf];
+ }
+ hex_hash[2*cnt] = 0;
+ strcat ((char *) cache_base, FC_CACHE_SUFFIX);
- cache_hashed = FcDirCacheHashName (dir, collisions++);
- if (!cache_hashed)
- goto bail;
+ return cache_base;
+}
- if (fd > 0)
- close (fd);
- fd = open(cache_hashed, O_RDONLY | O_BINARY);
- if (fd == -1)
- {
- FcStrFree ((FcChar8 *)cache_hashed);
- return FcTrue;
- }
+FcBool
+FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config)
+{
+ int fd = -1;
+ FcChar8 *cache_hashed = NULL;
+ FcChar8 cache_base[CACHEBASE_LEN];
+ FcStrList *list;
+ FcChar8 *cache_dir;
+ char dir_buf[FC_MAX_FILE_LEN];
- if (!FcCacheReadString (fd, dir_buf, sizeof (dir_buf)) || !strlen(dir_buf))
- {
- FcStrFree ((FcChar8 *)cache_hashed);
- goto bail;
- }
- } while (strcmp ((char *) dir_buf, (char *) dir) != 0);
+ dir = FcConfigNormalizeFontDir (config, dir);
- close (fd);
+ FcDirCacheBasename (dir, cache_base);
- if (stat ((char *) cache_hashed, &cache_stat) == 0 &&
- unlink ((char *)cache_hashed) != 0)
+ list = FcStrListCreate (config->cacheDirs);
+ if (!list)
+ return FcFalse;
+
+ while ((cache_dir = FcStrListNext (list)))
{
- FcStrFree ((FcChar8 *)cache_hashed);
- goto bail;
+ cache_hashed = FcStrPlus (cache_dir, cache_base);
+ if (!cache_hashed)
+ break;
+ fd = open((char *) cache_hashed, O_RDONLY | O_BINARY);
+ FcStrFree (cache_hashed);
+ if (fd >= 0)
+ {
+ if (FcCacheReadString (fd, dir_buf, sizeof (dir_buf)) &&
+ strcmp (dir_buf, (char *) dir) == 0)
+ {
+ close (fd);
+ if (unlink ((char *) cache_hashed) < 0)
+ break;
+ } else
+ close (fd);
+ }
}
-
- FcStrFree ((FcChar8 *)cache_hashed);
+ FcStrListDone (list);
+ /* return FcFalse if something went wrong */
+ if (cache_dir)
+ return FcFalse;
return FcTrue;
-
- bail:
- return FcFalse;
}
static int
@@ -947,8 +968,8 @@ FcCacheReadDirs (FcConfig * config, FcGl
FcStrSetDestroy (subdirs);
continue;
}
- if (FcDirCacheValid (dir) &&
- FcDirCacheHasCurrentArch (dir) &&
+ if (FcDirCacheValid (dir, config) &&
+ FcDirCacheHasCurrentArch (dir, config) &&
FcDirCacheRead (set, subdirs, dir, config))
{
/* if an old entry is found in the global cache, disable it */
@@ -1007,87 +1028,53 @@ FcCacheRead (FcConfig *config, FcGlobalC
return 0;
}
-static const char bin2hex[] = { '0', '1', '2', '3',
- '4', '5', '6', '7',
- '8', '9', 'a', 'b',
- 'c', 'd', 'e', 'f' };
-
-static char *
-FcDirCacheHashName (const FcChar8 * dir, int collisions)
-{
- unsigned char hash[16], hex_hash[33];
- char *cache_hashed;
- unsigned char uscore = '_';
- int cnt, i;
- FcChar8 *tmp;
- struct MD5Context ctx;
-
- MD5Init (&ctx);
- MD5Update (&ctx, (unsigned char *)dir, strlen ((char *) dir));
-
- for (i = 0; i < collisions; i++)
- MD5Update (&ctx, &uscore, 1);
-
- MD5Final (hash, &ctx);
-
- for (cnt = 0; cnt < 16; ++cnt)
- {
- hex_hash[2*cnt] = bin2hex[hash[cnt] >> 4];
- hex_hash[2*cnt+1] = bin2hex[hash[cnt] & 0xf];
- }
- hex_hash[32] = 0;
-
- tmp = FcStrPlus ((FcChar8 *)hex_hash, (FcChar8 *)FC_CACHE_SUFFIX);
- if (!tmp)
- return 0;
-
- cache_hashed = (char *)FcStrPlus ((FcChar8 *)PKGCACHEDIR"/", tmp);
- free (tmp);
-
- return cache_hashed;
-}
-
-/* Opens the hashed name for cache_file.
- * This would fail in the unlikely event of a collision and subsequent
- * removal of the file which originally caused the collision. */
+/* Opens the cache file for 'dir' for reading.
+ * This searches the list of cache dirs for the relevant cache file,
+ * returning the first one found.
+ */
static int
-FcDirCacheOpen (const FcChar8 *dir)
+FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, FcChar8 **cache_path)
{
- FcBool found;
- int fd = -1, collisions = 0;
- char *cache_hashed;
+ int fd = -1;
+ FcChar8 *cache_hashed = NULL;
+ FcChar8 cache_base[CACHEBASE_LEN];
+ FcStrList *list;
+ FcChar8 *cache_dir;
char dir_buf[FC_MAX_FILE_LEN];
- struct stat dir_stat;
- if (stat ((char *)dir, &dir_stat) == -1)
- return -1;
+ FcDirCacheBasename (dir, cache_base);
- found = FcFalse;
- do
+ list = FcStrListCreate (config->cacheDirs);
+ if (!list)
+ return -1;
+
+ while ((cache_dir = FcStrListNext (list)))
{
- struct stat c;
-
- if (fd >= 0)
- close (fd);
-
- cache_hashed = FcDirCacheHashName (dir, collisions++);
- if (!cache_hashed)
- return -1;
-
- fd = open(cache_hashed, O_RDONLY | O_BINARY);
- FcStrFree ((FcChar8 *)cache_hashed);
-
- if (fd == -1)
+ cache_hashed = FcStrPlus (cache_dir, cache_base);
+ if (!cache_hashed)
break;
- if (!FcCacheReadString (fd, dir_buf, sizeof (dir_buf)) ||
- !strlen(dir_buf))
+ fd = open((char *) cache_hashed, O_RDONLY | O_BINARY);
+ if (fd >= 0)
break;
+ FcStrFree (cache_hashed);
+ }
+ FcStrListDone (list);
- if (stat ((char *)dir_buf, &c) == -1)
- continue;
-
- found = (c.st_ino == dir_stat.st_ino) && (c.st_dev == dir_stat.st_dev);
- } while (!found);
+ if (fd < 0)
+ return -1;
+
+ if (!FcCacheReadString (fd, dir_buf, sizeof (dir_buf)) ||
+ strcmp (dir_buf, (char *) dir) != 0)
+ {
+ close (fd);
+ FcStrFree (cache_hashed);
+ return -1;
+ }
+
+ if (cache_path)
+ *cache_path = cache_hashed;
+ else
+ FcStrFree (cache_hashed);
return fd;
}
@@ -1102,7 +1089,7 @@ FcDirCacheRead (FcFontSet * set, FcStrSe
off_t current_arch_start = 0;
char subdirName[FC_MAX_FILE_LEN + 1 + 12 + 1];
- fd = FcDirCacheOpen (dir);
+ fd = FcDirCacheOpen (config, dir, NULL);
if (fd < 0)
goto bail;
@@ -1276,56 +1263,77 @@ FcDirCacheProduce (FcFontSet *set, FcCac
return 0;
}
+static FcBool
+FcMakeDirectory (const FcChar8 *dir)
+{
+ FcChar8 *parent;
+ FcBool ret;
+
+ if (strlen ((char *) dir) == 0)
+ return FcFalse;
+
+ parent = FcStrDirname (dir);
+ if (!parent)
+ return FcFalse;
+ if (access ((char *) parent, W_OK|X_OK) == 0)
+ ret = mkdir ((char *) dir, 0777) == 0;
+ else if (access ((char *) parent, F_OK) == -1)
+ ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0777) == 0);
+ else
+ ret = FcFalse;
+ FcStrFree (parent);
+ return ret;
+}
+
/* write serialized state to the cache file */
FcBool
-FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
+FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *config)
{
- char *cache_hashed;
+ FcChar8 cache_base[CACHEBASE_LEN];
+ FcChar8 *cache_hashed;
int fd, fd_orig, i, dirs_count;
FcAtomic *atomic;
FcCache metadata;
off_t current_arch_start = 0, truncate_to;
- char dir_buf[FC_MAX_FILE_LEN];
- int collisions;
-
+ FcStrList *list;
char *current_arch_machine_name, * header;
void *current_dir_block = 0;
+ FcChar8 *cache_dir;
dir = FcConfigNormalizeFontDir (FcConfigGetCurrent(), dir);
if (!dir)
return FcFalse;
- /* Ensure that we're not trampling a cache for some other dir. */
- /* This is slightly different from FcDirCacheOpen, since it
- * needs the filename, not the file descriptor. */
- fd = -1; collisions = 0;
- do
- {
- cache_hashed = FcDirCacheHashName (dir, collisions++);
- if (!cache_hashed)
- goto bail0;
-
- if (fd > 0)
- close (fd);
- fd = open(cache_hashed, O_RDONLY | O_BINARY);
- if (fd == -1)
- break;
- if(!FcCacheReadString (fd, dir_buf, sizeof (dir_buf)) || !strlen(dir_buf))
- {
- close (fd);
- FcStrFree ((FcChar8 *)cache_hashed);
- continue;
- }
- close (fd);
-
- if (strcmp (dir_buf, (char *) dir) != 0)
- {
- FcStrFree ((FcChar8 *)cache_hashed);
- continue;
- }
+ /*
+ * Check for an existing cache file and dump stuff in the same place
+ */
+ fd = FcDirCacheOpen (config, dir, &cache_hashed);
- break;
- } while (1);
+ if (fd >= 0)
+ close (fd);
+ else {
+ list = FcStrListCreate (config->cacheDirs);
+ if (!list)
+ return FcFalse;
+ while ((cache_dir = FcStrListNext (list))) {
+ if (access ((char *) cache_dir, W_OK|X_OK) == 0)
+ break;
+ /*
+ * If the directory doesn't exist, try to create it
+ */
+ if (access ((char *) cache_dir, F_OK) == -1) {
+ if (FcMakeDirectory (cache_dir))
+ break;
+ }
+ }
+ FcStrListDone (list);
+ if (!cache_dir)
+ return FcFalse;
+ FcDirCacheBasename (dir, cache_base);
+ cache_hashed = FcStrPlus (cache_dir, cache_base);
+ if (!cache_hashed)
+ return FcFalse;
+ }
current_dir_block = FcDirCacheProduce (set, &metadata);
@@ -1453,7 +1461,6 @@ FcDirCacheWrite (FcFontSet *set, FcStrSe
FcAtomicDestroy (atomic);
bail1:
FcStrFree ((FcChar8 *)cache_hashed);
- bail0:
if (current_dir_block)
free (current_dir_block);
return FcFalse;
Index: src/fccfg.c
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/fccfg.c,v
retrieving revision 1.49.2.29
diff -u -p -r1.49.2.29 fccfg.c
--- src/fccfg.c 25 Apr 2006 05:57:41 -0000 1.49.2.29
+++ src/fccfg.c 28 Apr 2006 04:49:28 -0000
@@ -22,9 +22,9 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-#include "fcint.h"
#include <dirent.h>
#include <sys/types.h>
+#include "fcint.h"
#if defined (_WIN32) && (defined (PIC) || defined (DLL_EXPORT))
#define STRICT
@@ -100,13 +100,17 @@ FcConfigCreate (void)
if (!FcConfigSetCache (config, cache_dir))
{
FcStrFree (cache_dir);
- goto bail6;
+ goto bail7;
}
FcStrFree (cache_dir);
}
}
#endif
+ config->cacheDirs = FcStrSetCreate ();
+ if (!config->cacheDirs)
+ goto bail9;
+
config->blanks = 0;
config->substPattern = 0;
@@ -120,6 +124,8 @@ FcConfigCreate (void)
return config;
+bail9:
+ FcStrFree (config->cache);
bail8:
FcFontSetDestroy (config->rejectPatterns);
bail7:
@@ -226,6 +232,7 @@ FcConfigDestroy (FcConfig *config)
FcStrSetDestroy (config->configDirs);
FcStrSetDestroy (config->fontDirs);
+ FcStrSetDestroy (config->cacheDirs);
FcStrSetDestroy (config->configFiles);
FcStrSetDestroy (config->acceptGlobs);
FcStrSetDestroy (config->rejectGlobs);
@@ -513,6 +520,25 @@ FcConfigGetFontDirs (FcConfig *config)
}
FcBool
+FcConfigAddCacheDir (FcConfig *config,
+ const FcChar8 *d)
+{
+ return FcStrSetAddFilename (config->cacheDirs, d);
+}
+
+FcStrList *
+FcConfigGetCacheDirs (FcConfig *config)
+{
+ if (!config)
+ {
+ config = FcConfigGetCurrent ();
+ if (!config)
+ return 0;
+ }
+ return FcStrListCreate (config->cacheDirs);
+}
+
+FcBool
FcConfigAddConfigFile (FcConfig *config,
const FcChar8 *f)
{
Index: src/fcdir.c
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/fcdir.c,v
retrieving revision 1.20.4.19
diff -u -p -r1.20.4.19 fcdir.c
--- src/fcdir.c 10 Apr 2006 16:06:42 -0000 1.20.4.19
+++ src/fcdir.c 28 Apr 2006 07:34:56 -0000
@@ -151,8 +151,8 @@ FcDirScanConfig (FcFontSet *set,
if (cache && FcGlobalCacheReadDir (set, dirs, cache, (char *)dir, config))
return FcTrue;
- if (FcDirCacheValid (dir) &&
- FcDirCacheHasCurrentArch (dir) &&
+ if (FcDirCacheValid (dir, config) &&
+ FcDirCacheHasCurrentArch (dir, config) &&
FcDirCacheRead (set, dirs, dir, config))
return FcTrue;
}
@@ -277,5 +277,5 @@ FcDirScan (FcFontSet *set,
FcBool
FcDirSave (FcFontSet *set, FcStrSet * dirs, const FcChar8 *dir)
{
- return FcDirCacheWrite (set, dirs, dir);
+ return FcDirCacheWrite (set, dirs, dir, FcConfigGetCurrent ());
}
Index: src/fcinit.c
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/fcinit.c,v
retrieving revision 1.12.4.7
diff -u -p -r1.12.4.7 fcinit.c
--- src/fcinit.c 27 Apr 2006 07:54:07 -0000 1.12.4.7
+++ src/fcinit.c 28 Apr 2006 04:52:46 -0000
@@ -35,6 +35,8 @@ FcInitFallbackConfig (void)
goto bail0;
if (!FcConfigAddDir (config, (FcChar8 *) FC_DEFAULT_FONTS))
goto bail1;
+ if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR))
+ goto bail1;
return config;
bail1:
Index: src/fcint.h
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/fcint.h,v
retrieving revision 1.47.4.44
diff -u -p -r1.47.4.44 fcint.h
--- src/fcint.h 27 Apr 2006 07:54:07 -0000 1.47.4.44
+++ src/fcint.h 28 Apr 2006 07:33:21 -0000
@@ -389,6 +389,10 @@ struct _FcConfig {
*/
FcStrSet *fontDirs;
/*
+ * List of directories containing cache files.
+ */
+ FcStrSet *cacheDirs;
+ /*
* Names of all of the configuration files used
* to create this configuration
*/
@@ -476,7 +480,7 @@ FcFontSet *
FcCacheRead (FcConfig *config, FcGlobalCache * cache);
FcBool
-FcDirCacheWrite (FcFontSet *set, FcStrSet * dirs, const FcChar8 *dir);
+FcDirCacheWrite (FcFontSet *set, FcStrSet * dirs, const FcChar8 *dir, FcConfig *config);
FcBool
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir, FcConfig *config);
@@ -509,6 +513,13 @@ FcConfigAddDir (FcConfig *config,
const FcChar8 *d);
FcBool
+FcConfigAddCacheDir (FcConfig *config,
+ const FcChar8 *d);
+
+FcStrList *
+FcConfigGetCacheDirs (FcConfig *config);
+
+FcBool
FcConfigAddConfigFile (FcConfig *config,
const FcChar8 *f);
Index: src/fcxml.c
===================================================================
RCS file: /cvs/fontconfig/fontconfig/src/fcxml.c,v
retrieving revision 1.37.4.22
diff -u -p -r1.37.4.22 fcxml.c
--- src/fcxml.c 27 Apr 2006 07:54:07 -0000 1.37.4.22
+++ src/fcxml.c 28 Apr 2006 07:35:24 -0000
@@ -285,6 +285,7 @@ typedef enum _FcElement {
FcElementNone,
FcElementFontconfig,
FcElementDir,
+ FcElementCacheDir,
FcElementCache,
FcElementInclude,
FcElementConfig,
@@ -345,6 +346,7 @@ static const struct {
} fcElementMap[] = {
{ "fontconfig", FcElementFontconfig },
{ "dir", FcElementDir },
+ { "cachedir", FcElementCacheDir },
{ "cache", FcElementCache },
{ "include", FcElementInclude },
{ "config", FcElementConfig },
@@ -2053,6 +2055,21 @@ FcEndElement(void *userData, const XML_C
}
FcStrFree (data);
break;
+ case FcElementCacheDir:
+ data = FcStrBufDone (&parse->pstack->str);
+ if (!data)
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ break;
+ }
+ if (!FcStrUsesHome (data) || FcConfigHome ())
+ {
+ if (!FcConfigAddCacheDir (parse->config, data))
+ FcConfigMessage (parse, FcSevereError, "out of memory; cannot add cache directory %s", data);
+ }
+ FcStrFree (data);
+ break;
+
case FcElementCache:
data = FcStrBufDone (&parse->pstack->str);
if (!data)
Index: test/fonts.conf.in
===================================================================
RCS file: /cvs/fontconfig/fontconfig/test/fonts.conf.in,v
retrieving revision 1.1
diff -u -p -r1.1 fonts.conf.in
--- test/fonts.conf.in 1 Mar 2003 05:54:42 -0000 1.1
+++ test/fonts.conf.in 28 Apr 2006 08:08:01 -0000
@@ -1,4 +1,5 @@
<fontconfig>
<dir>@FONTDIR@</dir>
<cache>@CACHEFILE@</cache>
+<cachedir>@CACHEDIR@</cachedir>
</fontconfig>
Index: test/run-test.sh
===================================================================
RCS file: /cvs/fontconfig/fontconfig/test/run-test.sh,v
retrieving revision 1.3
diff -u -p -r1.3 run-test.sh
--- test/run-test.sh 27 Oct 2003 10:44:13 -0000 1.3
+++ test/run-test.sh 28 Apr 2006 08:08:19 -0000
@@ -3,6 +3,7 @@ TESTDIR=${srcdir-`pwd`}
FONTDIR=`pwd`/fonts
CACHEFILE=`pwd`/fonts.cache
+CACHEDIR=`pwd`/cache.dir
ECHO=true
@@ -39,7 +40,8 @@ dotest () {
}
sed "s!@FONTDIR@!$FONTDIR!
-s!@CACHEFILE@!$CACHEFILE!" < $TESTDIR/fonts.conf.in > fonts.conf
+s!@CACHEFILE@!$CACHEFILE!
+s!@CACHEDIR@!$CACHEDIR!" < $TESTDIR/fonts.conf.in > fonts.conf
FONTCONFIG_FILE=`pwd`/fonts.conf
export FONTCONFIG_FILE
@@ -89,4 +91,4 @@ mkdir $FONTDIR/a
cp $FONT2 $FONTDIR/a
check
-rm -rf $FONTDIR $CACHEFILE $FONTCONFIG_FILE out
+rm -rf $FONTDIR $CACHEFILE $CACHEDIR $FONTCONFIG_FILE out
--
keith.packard at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lists.freedesktop.org/archives/fontconfig/attachments/20060428/5b5af386/attachment-0001.pgp
More information about the Fontconfig
mailing list