]> git.wh0rd.org - fontconfig.git/blobdiff - src/fccache.c
Change files from ISO-Latin-1 to UTF-8
[fontconfig.git] / src / fccache.c
index 4416412783453ea74e778725e122cc4069855a3e..9e47e86121d7901604027141fa7fea1db14f61a4 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $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
@@ -188,9 +188,19 @@ FcCacheWritePath (FILE *f, const FcChar8 *dir, const FcChar8 *file)
     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)
@@ -241,7 +251,8 @@ FcCacheFontSetAdd (FcFontSet            *set,
                   const FcChar8    *dir,
                   int              dir_len,
                   const FcChar8    *file,
-                  const FcChar8    *name)
+                  const FcChar8    *name,
+                  FcConfig         *config)
 {
     FcChar8    path_buf[8192], *path;
     int                len;
@@ -258,10 +269,17 @@ FcCacheFontSetAdd (FcFontSet          *set,
            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);
@@ -279,7 +297,7 @@ FcCacheFontSetAdd (FcFontSet            *set,
            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);
@@ -309,14 +327,14 @@ FcCacheHash (const FcChar8 *string, int len)
  * 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)
@@ -361,7 +379,7 @@ FcFilePathInfoGet (const FcChar8    *path)
     FcFilePathInfo  i;
     FcChar8        *slash;
 
-    slash = (FcChar8 *) strrchr ((const char *) path, '/');
+    slash = FcStrLastSlash (path);
     if (slash)
     {
         i.dir = path;
@@ -427,13 +445,29 @@ static FcGlobalCacheInfo *
 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
      */
@@ -441,13 +475,9 @@ FcGlobalCacheDirAdd (FcGlobalCache  *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;
@@ -484,6 +514,25 @@ FcGlobalCacheDirDestroy (FcGlobalCacheDir *d)
     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'.
@@ -493,7 +542,8 @@ FcBool
 FcGlobalCacheScanDir (FcFontSet                *set,
                      FcStrSet          *dirs,
                      FcGlobalCache     *cache,
-                     const FcChar8     *dir)
+                     const FcChar8     *dir,
+                     FcConfig          *config)
 {
     FcGlobalCacheDir   *d = FcGlobalCacheDirGet (cache, dir,
                                                  strlen ((const char *) dir),
@@ -518,7 +568,7 @@ FcGlobalCacheScanDir (FcFontSet             *set,
      * 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");
@@ -536,7 +586,7 @@ FcGlobalCacheScanDir (FcFontSet             *set,
                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;
@@ -552,7 +602,7 @@ FcGlobalCacheScanDir (FcFontSet             *set,
        
         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;
@@ -602,7 +652,7 @@ FcGlobalCacheFileGet (FcGlobalCache *cache,
        }
     }
     if (count)
-       *count = max;
+       *count = max + 1;
     return match;
 }
     
@@ -739,7 +789,7 @@ FcGlobalCacheLoad (FcGlobalCache    *cache,
        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)
@@ -779,7 +829,7 @@ FcGlobalCacheUpdate (FcGlobalCache  *cache,
        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);
@@ -809,9 +859,11 @@ FcGlobalCacheSave (FcGlobalCache    *cache,
     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)
@@ -923,7 +975,7 @@ FcDirCacheValid (const FcChar8 *dir)
 }
 
 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;
@@ -968,7 +1020,7 @@ FcDirCacheReadDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
           (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);
@@ -1002,7 +1054,7 @@ FcFileBaseName (const FcChar8 *cache, const FcChar8 *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);