]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcdir.c
Eliminate NormalizeDir. Eliminate gratuitous stat/access calls per dir.
[fontconfig.git] / src / fcdir.c
index 4ee84def97190cddd50c9ad34ceedb0f6661cd00..145226072571abe2d4a6880ee1727359edb26501 100644 (file)
@@ -47,14 +47,14 @@ FcFileScanConfig (FcFontSet *set,
     int                        id;
     FcPattern          *font;
     FcBool             ret = FcTrue;
-    FcBool             isDir;
     int                        count = 0;
     
     if (config && !FcConfigAcceptFilename (config, file))
        return FcTrue;
 
-    if (force)
-       cache = 0;
+    if (FcFileIsDir (file))
+       return FcStrSetAdd (dirs, file);
+
     id = 0;
     do
     {
@@ -70,12 +70,6 @@ FcFileScanConfig (FcFontSet  *set,
        font = FcFreeTypeQuery (file, id, blanks, &count);
        if (FcDebug () & FC_DBG_SCAN)
            printf ("done\n");
-       isDir = FcFalse;
-       if (!font && FcFileIsDir (file))
-       {
-           isDir = FcTrue;
-           ret = FcStrSetAdd (dirs, file);
-       }
        /*
         * Add the font
         */
@@ -106,6 +100,16 @@ FcFileScan (FcFontSet          *set,
     return FcFileScanConfig (set, dirs, cache, blanks, file, force, 0);
 }
 
+/*
+ * Strcmp helper that takes pointers to pointers, copied from qsort(3) manpage
+ */
+
+static int
+cmpstringp(const void *p1, const void *p2)
+{
+    return strcmp(* (char **) p1, * (char **) p2);
+}
+
 /*
  * Scan 'dir', adding font files to 'set' and
  * subdirectories to 'dirs'
@@ -122,6 +126,8 @@ FcDirScanConfig (FcFontSet  *set,
 {
     DIR                        *d;
     struct dirent      *e;
+    FcChar8            **dirlist;
+    int                        dirlistlen, dirlistalloc;
     FcChar8            *file;
     FcChar8            *base;
     FcBool             ret = FcTrue;
@@ -136,7 +142,12 @@ FcDirScanConfig (FcFontSet *set,
        /*
         * Check ~/.fonts.cache-<version> file
         */
-       if (cache && FcGlobalCacheReadDir (set, dirs, cache, dir, config))
+       if (cache && FcGlobalCacheReadDir (set, dirs, cache, (char *)dir, config))
+           return FcTrue;
+
+       if (FcDirCacheValid (dir, config) && 
+           FcDirCacheHasCurrentArch (dir, config) &&
+           FcDirCacheRead (set, dirs, dir, config))
            return FcTrue;
     }
     
@@ -163,28 +174,62 @@ FcDirScanConfig (FcFontSet        *set,
     }
 
     tmpSet = FcFontSetCreate();
-    if (!tmpSet)
-    {  
-       free (file);
-       return FcFalse;
+    if (!tmpSet) 
+    {
+       ret = FcFalse;
+       goto bail0;
     }
 
-    while (ret && (e = readdir (d)))
+    dirlistlen = 0;
+    dirlistalloc = 8;
+    dirlist = malloc(dirlistalloc * sizeof(FcChar8 *));
+    if (!dirlist) 
+    {
+       ret = FcFalse;
+       goto bail1;
+    }
+    while ((e = readdir (d)))
     {
        if (e->d_name[0] != '.' && strlen (e->d_name) < FC_MAX_FILE_LEN)
        {
-           strcpy ((char *) base, (char *) e->d_name);
-           ret = FcFileScanConfig (tmpSet, dirs, cache, blanks, file, force, config);
+           if (dirlistlen == dirlistalloc)
+           {
+                FcChar8        **tmp_dirlist;
+
+               dirlistalloc *= 2;
+               tmp_dirlist = realloc(dirlist, 
+                                      dirlistalloc * sizeof(FcChar8 *));
+               if (!tmp_dirlist) 
+                {
+                   ret = FcFalse;
+                   goto bail2;
+               }
+                dirlist = tmp_dirlist;
+           }
+           dirlist[dirlistlen] = malloc(strlen (e->d_name) + 1);
+           if (!dirlist[dirlistlen]) 
+            {
+               ret = FcFalse;
+               goto bail2;
+           }
+           strcpy((char *)dirlist[dirlistlen], e->d_name);
+           dirlistlen++;
        }
     }
-    free (file);
-    closedir (d);
+    qsort(dirlist, dirlistlen, sizeof(FcChar8 *), cmpstringp);
+    i = 0;
+    while (ret && i < dirlistlen)
+    {
+       strcpy ((char *) base, (char *) dirlist[i]);
+       ret = FcFileScanConfig (tmpSet, dirs, cache, blanks, file, force, config);
+       i++;
+    }
     /*
      * Now that the directory has been scanned,
      * add the cache entry 
      */
     if (ret && cache)
-       FcGlobalCacheUpdate (cache, dir, tmpSet);
+       FcGlobalCacheUpdate (cache, dirs, (char *)dir, tmpSet, config);
 
     for (i = 0; i < tmpSet->nfont; i++)
        FcFontSetAdd (set, tmpSet->fonts[i]);
@@ -195,8 +240,20 @@ FcDirScanConfig (FcFontSet *set,
        free (tmpSet->fonts);
     }
     FcMemFree (FC_MEM_FONTSET, sizeof (FcFontSet));
+
+ bail2:
+    for (i = 0; i < dirlistlen; i++)
+       free(dirlist[i]);
+
+    free (dirlist);
+
+ bail1:
     free (tmpSet);
-       
+    
+ bail0:
+    closedir (d);
+    
+    free (file);
     return ret;
 }
 
@@ -212,7 +269,7 @@ FcDirScan (FcFontSet            *set,
 }
 
 FcBool
-FcDirSave (FcFontSet *set, const FcChar8 *dir)
+FcDirSave (FcFontSet *set, FcStrSet * dirs, const FcChar8 *dir)
 {
-    return FcDirCacheWrite (set, dir);
+    return FcDirCacheWrite (set, dirs, dir, FcConfigGetCurrent ());
 }