/*
- * $XFree86: xc/lib/fontconfig/src/fccache.c,v 1.12 2002/08/22 07:36:44 keithp Exp $
+ * $RCSId: xc/lib/fontconfig/src/fccache.c,v 1.12 2002/08/22 07:36:44 keithp Exp $
*
- * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ * Copyright © 2000 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
if (dir)
if (!FcCacheWriteChars (f, dir))
return FcFalse;
+#ifdef _WIN32
+ if (dir &&
+ dir[strlen((const char *) dir) - 1] != '/' &&
+ dir[strlen((const char *) dir) - 1] != '\\')
+ {
+ if (!FcCacheWriteChars (f, "\\"))
+ return FcFalse;
+ }
+#else
if (dir && dir[strlen((const char *) dir) - 1] != '/')
if (PUTC ('/', f) == EOF)
return FcFalse;
+#endif
if (!FcCacheWriteChars (f, file))
return FcFalse;
if (PUTC ('"', f) == EOF)
const FcChar8 *dir,
int dir_len,
const FcChar8 *file,
- const FcChar8 *name)
+ const FcChar8 *name,
+ FcConfig *config)
{
FcChar8 path_buf[8192], *path;
int len;
return FcFalse;
}
strncpy ((char *) path, (const char *) dir, dir_len);
+#ifdef _WIN32
+ if (dir[dir_len - 1] != '/' && dir[dir_len - 1] != '\\' )
+ path[dir_len++] = '\\';
+#else
if (dir[dir_len - 1] != '/')
path[dir_len++] = '/';
+#endif
strcpy ((char *) path + dir_len, (const char *) file);
- if (!FcStrCmp (name, FC_FONT_FILE_DIR))
+ if (config && !FcConfigAcceptFilename (config, path))
+ ret = FcTrue;
+ else if (!FcStrCmp (name, FC_FONT_FILE_DIR))
{
if (FcDebug () & FC_DBG_CACHEV)
printf (" dir cache dir \"%s\"\n", path);
if (FcDebug () & FC_DBG_CACHEV)
printf (" dir cache file \"%s\"\n", file);
ret = FcPatternAddString (font, FC_FILE, path);
- if (ret)
+ if (ret && (!config || FcConfigAcceptFont (config, font)))
{
frozen = FcPatternFreeze (font);
ret = (frozen != 0);
* Verify the saved timestamp for a file
*/
FcBool
-FcGlobalCacheCheckTime (FcGlobalCacheInfo *info)
+FcGlobalCacheCheckTime (const FcChar8 *file, FcGlobalCacheInfo *info)
{
struct stat statb;
- if (stat ((char *) info->file, &statb) < 0)
+ if (stat ((char *) file, &statb) < 0)
{
if (FcDebug () & FC_DBG_CACHE)
- printf (" file missing\n");
+ printf (" file %s missing\n", file);
return FcFalse;
}
if (statb.st_mtime != info->time)
FcFilePathInfo i;
FcChar8 *slash;
- slash = (FcChar8 *) strrchr ((const char *) path, '/');
+ slash = FcStrLastSlash (path);
if (slash)
{
i.dir = path;
FcGlobalCacheDirAdd (FcGlobalCache *cache,
const FcChar8 *dir,
time_t time,
- FcBool replace)
+ FcBool replace,
+ FcBool create_missing)
{
FcGlobalCacheDir *d;
FcFilePathInfo i;
FcGlobalCacheSubdir *subdir;
FcGlobalCacheDir *parent;
+ i = FcFilePathInfoGet (dir);
+ parent = FcGlobalCacheDirGet (cache, i.dir, i.dir_len, create_missing);
+ /*
+ * Tricky here -- directories containing fonts.cache-1 files
+ * need entries only when the parent doesn't have a cache file.
+ * That is, when the parent already exists in the cache, is
+ * referenced and has a "real" timestamp. The time of 0 is
+ * special and marks directories which got stuck in the
+ * global cache for this very reason. Yes, it could
+ * use a separate boolean field, and probably should.
+ */
+ if (!parent || (!create_missing &&
+ (!parent->info.referenced ||
+ (parent->info.time == 0))))
+ return 0;
/*
* Add this directory to the cache
*/
if (!d)
return 0;
d->info.time = time;
- i = FcFilePathInfoGet (dir);
/*
* Add this directory to the subdirectory list of the parent
*/
- parent = FcGlobalCacheDirGet (cache, i.dir, i.dir_len, FcTrue);
- if (!parent)
- return 0;
subdir = malloc (sizeof (FcGlobalCacheSubdir));
if (!subdir)
return 0;
free (d);
}
+/*
+ * If the parent is in the global cache and referenced, add
+ * an entry for 'dir' to the global cache. This is used
+ * for directories with fonts.cache files
+ */
+
+void
+FcGlobalCacheReferenceSubdir (FcGlobalCache *cache,
+ const FcChar8 *dir)
+{
+ FcGlobalCacheInfo *info;
+ info = FcGlobalCacheDirAdd (cache, dir, 0, FcFalse, FcFalse);
+ if (info && !info->referenced)
+ {
+ info->referenced = FcTrue;
+ cache->referenced++;
+ }
+}
+
/*
* Check to see if the global cache contains valid data for 'dir'.
* If so, scan the global cache for files and directories in 'dir'.
FcGlobalCacheScanDir (FcFontSet *set,
FcStrSet *dirs,
FcGlobalCache *cache,
- const FcChar8 *dir)
+ const FcChar8 *dir,
+ FcConfig *config)
{
FcGlobalCacheDir *d = FcGlobalCacheDirGet (cache, dir,
strlen ((const char *) dir),
* See if the timestamp recorded in the global cache
* matches the directory time, if not, return False
*/
- if (!FcGlobalCacheCheckTime (&d->info))
+ if (!FcGlobalCacheCheckTime (d->info.file, &d->info))
{
if (FcDebug () & FC_DBG_CACHE)
printf ("\tdir cache entry time mismatch\n");
printf ("FcGlobalCacheScanDir add file %s\n", f->info.file);
any_in_cache = FcTrue;
if (!FcCacheFontSetAdd (set, dirs, dir, dir_len,
- f->info.file, f->name))
+ f->info.file, f->name, config))
{
cache->broken = FcTrue;
return FcFalse;
any_in_cache = FcTrue;
if (!FcCacheFontSetAdd (set, dirs, dir, dir_len,
- info.base, FC_FONT_FILE_DIR))
+ info.base, FC_FONT_FILE_DIR, config))
{
cache->broken = FcTrue;
return FcFalse;
}
}
if (count)
- *count = max;
+ *count = max + 1;
return match;
}
if (FcDebug () & FC_DBG_CACHEV)
printf ("FcGlobalCacheLoad \"%s\" \"%20.20s\"\n", file, name);
if (!FcStrCmp (name, FC_FONT_FILE_DIR))
- info = FcGlobalCacheDirAdd (cache, file, time, FcFalse);
+ info = FcGlobalCacheDirAdd (cache, file, time, FcFalse, FcTrue);
else
info = FcGlobalCacheFileAdd (cache, file, id, time, name, FcFalse);
if (!info)
return FcFalse;
if (S_ISDIR (statb.st_mode))
info = FcGlobalCacheDirAdd (cache, file, statb.st_mtime,
- FcTrue);
+ FcTrue, FcTrue);
else
info = FcGlobalCacheFileAdd (cache, file, id, statb.st_mtime,
name, FcTrue);
if (cache->broken)
return FcFalse;
+#if defined (HAVE_GETUID) && defined (HAVE_GETEUID)
/* Set-UID programs can't safely update the cache */
if (getuid () != geteuid ())
return FcFalse;
+#endif
atomic = FcAtomicCreate (cache_file);
if (!atomic)
}
FcBool
-FcDirCacheReadDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
+FcDirCacheReadDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *config)
{
FcChar8 *cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE);
FILE *f;
(name = FcCacheReadString (f, name_buf, sizeof (name_buf))))
{
if (!FcCacheFontSetAdd (set, dirs, cache_file, dir_len,
- file, name))
+ file, name, config))
goto bail3;
if (file != file_buf)
free (file);
{
const FcChar8 *cache_slash;
- cache_slash = (const FcChar8 *) strrchr ((const char *) cache, '/');
+ cache_slash = FcStrLastSlash (cache);
if (cache_slash && !strncmp ((const char *) cache, (const char *) file,
(cache_slash + 1) - cache))
return file + ((cache_slash + 1) - cache);