]> git.wh0rd.org - fontconfig.git/blobdiff - src/fccfg.c
Stop trampling the directory name when writing out caches. (with Mike
[fontconfig.git] / src / fccfg.c
index eefbca982e356e02d085b6e5bb87742241b2cad8..6e5174b505df51090ea4d8c5deae6b12eff6f3f9 100644 (file)
@@ -22,6 +22,8 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <dirent.h>
+#include <sys/types.h>
 #include "fcint.h"
 
 #if defined (_WIN32) && (defined (PIC) || defined (DLL_EXPORT))
@@ -325,7 +327,7 @@ FcConfigBuildFonts (FcConfig *config)
        FcFontSetPrint (fonts);
 
     if (config->cache)
-       FcGlobalCacheSave (cache, config->cache);
+       FcGlobalCacheSave (cache, config->cache, config);
     FcGlobalCacheDestroy (cache);
     FcStrSetDestroy (oldDirs);
 
@@ -388,6 +390,80 @@ FcConfigAddFontDir (FcConfig           *config,
     return FcStrSetAddFilename (config->fontDirs, d);
 }
 
+static FcBool
+FcConfigAddFontDirSubdirs (FcConfig        *config,
+                          const FcChar8   *d)
+{
+    DIR *dir;
+    struct dirent *e;
+    FcChar8 *subdir;
+    
+    if (!(dir = opendir ((char *) d)))
+       return FcFalse;
+    if (!(subdir = (FcChar8 *) malloc (strlen ((char *) d) + FC_MAX_FILE_LEN + 2)))
+    {
+       fprintf (stderr, "out of memory");
+       return FcFalse;
+    }
+    while ((e = readdir (dir)))
+    {
+       if (strcmp (e->d_name, ".") && strcmp (e->d_name, "..") &&
+           strlen (e->d_name) < FC_MAX_FILE_LEN)
+       {
+           strcpy ((char *)subdir, (char *)d);
+           strcat ((char *)subdir, "/");
+           strcat ((char *)subdir, e->d_name);
+           if (FcFileIsDir (subdir))
+           {
+               FcConfigAddFontDir (config, subdir);
+               FcConfigAddFontDirSubdirs (config, subdir);
+           }
+       }
+    }
+    free (subdir);
+    closedir (dir);
+    return FcTrue;
+}
+
+const FcChar8 *
+FcConfigNormalizeFontDir (FcConfig     *config, 
+                         const FcChar8 *d)
+{
+    /* If this is a bottleneck, we can cache the fontDir inodes. */
+    ino_t      di;
+    dev_t      dd;
+    int                n;
+    struct stat s;
+
+    if (stat ((char *)d, &s) == -1)
+       return 0;
+    di = s.st_ino; dd = s.st_dev;
+
+    for (n = 0; n < config->fontDirs->num; n++)
+    {
+       if (stat ((char *)config->fontDirs->strs[n], &s) == -1)
+           continue;
+       if (di == s.st_ino && dd == s.st_dev)
+           return config->fontDirs->strs[n];
+    }
+
+    /* Ok, we didn't find it in fontDirs; let's add subdirs.... */
+    for (n = 0; n < config->fontDirs->num; n++)
+       FcConfigAddFontDirSubdirs (config, config->fontDirs->strs[n]);
+
+    /* ... and try again. */
+    for (n = 0; n < config->fontDirs->num; n++)
+    {
+       if (stat ((char *)config->fontDirs->strs[n], &s) == -1)
+           continue;
+       if (di == s.st_ino && dd == s.st_dev)
+           return config->fontDirs->strs[n];
+    }
+
+    /* if it fails, then really give up. */
+    return 0;
+}
+
 FcBool
 FcConfigAddDir (FcConfig           *config,
                const FcChar8       *d)
@@ -803,7 +879,6 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
     case FcOpString:
        v.type = FcTypeString;
        v.u.s = FcStrStaticName(e->u.sval);
-       v = FcValueSave (v);
        break;
     case FcOpMatrix:
        v.type = FcTypeMatrix;
@@ -823,7 +898,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
        r = FcPatternGet (p, e->u.field, 0, &v);
        if (r != FcResultMatch)
            v.type = FcTypeVoid;
-        v = FcValueSave (v);
+       v = FcValueSave (v);
        break;
     case FcOpConst:
        if (FcNameConstant (e->u.constant, &v.u.i))