X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffcdir.c;h=145226072571abe2d4a6880ee1727359edb26501;hb=cf65c0557e9fa1b86003d1ec8643f44f4344ebd2;hp=8f7738d2dbe2dcbf5e516a4dab677df7cb3ddce6;hpb=46b51147d10db21a4d5992074bcdc9022f45856b;p=fontconfig.git diff --git a/src/fcdir.c b/src/fcdir.c index 8f7738d..1452260 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -45,99 +45,31 @@ FcFileScanConfig (FcFontSet *set, FcConfig *config) { int id; - FcChar8 *name; FcPattern *font; FcBool ret = FcTrue; - FcBool isDir; int count = 0; - FcGlobalCacheFile *cache_file; - FcGlobalCacheDir *cache_dir; - FcBool need_scan; if (config && !FcConfigAcceptFilename (config, file)) return FcTrue; - if (force) - cache = 0; + if (FcFileIsDir (file)) + return FcStrSetAdd (dirs, file); + id = 0; do { - need_scan = FcTrue; font = 0; - /* - * Check the cache - */ - if (cache) - { - if ((cache_file = FcGlobalCacheFileGet (cache, file, id, &count))) - { - /* - * Found a cache entry for the file - */ - if (FcGlobalCacheCheckTime (file, &cache_file->info)) - { - name = cache_file->name; - need_scan = FcFalse; - FcGlobalCacheReferenced (cache, &cache_file->info); - /* "." means the file doesn't contain a font */ - if (FcStrCmp (name, FC_FONT_FILE_INVALID) != 0) - { - font = FcNameParse (name); - if (font) - if (!FcPatternAddString (font, FC_FILE, file)) - ret = FcFalse; - } - } - } - else if ((cache_dir = FcGlobalCacheDirGet (cache, file, - strlen ((const char *) file), - FcFalse))) - { - if (FcGlobalCacheCheckTime (cache_dir->info.file, - &cache_dir->info)) - { - font = 0; - need_scan = FcFalse; - FcGlobalCacheReferenced (cache, &cache_dir->info); - if (!FcStrSetAdd (dirs, file)) - ret = FcFalse; - } - } - } /* * Nothing in the cache, scan the file */ - if (need_scan) + if (FcDebug () & FC_DBG_SCAN) { - if (FcDebug () & FC_DBG_SCAN) - { - printf ("\tScanning file %s...", file); - fflush (stdout); - } - 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); - } - /* - * Update the cache - */ - if (cache && font) - { - FcChar8 *unparse; - - unparse = FcNameUnparse (font); - if (unparse) - { - (void) FcGlobalCacheUpdate (cache, file, id, unparse); - FcStrFree (unparse); - } - } + printf ("\tScanning file %s...", file); + fflush (stdout); } + font = FcFreeTypeQuery (file, id, blanks, &count); + if (FcDebug () & FC_DBG_SCAN) + printf ("done\n"); /* * Add the font */ @@ -150,6 +82,8 @@ FcFileScanConfig (FcFontSet *set, ret = FcFalse; } } + else if (font) + FcPatternDestroy (font); id++; } while (font && ret && id < count); return ret; @@ -166,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' @@ -182,29 +126,28 @@ FcDirScanConfig (FcFontSet *set, { DIR *d; struct dirent *e; + FcChar8 **dirlist; + int dirlistlen, dirlistalloc; FcChar8 *file; FcChar8 *base; FcBool ret = FcTrue; + FcFontSet *tmpSet; + int i; if (config && !FcConfigAcceptFilename (config, dir)) return FcTrue; if (!force) { - /* - * Check fonts.cache- file - */ - if (FcDirCacheReadDir (set, dirs, dir, config)) - { - if (cache) - FcGlobalCacheReferenceSubdir (cache, dir); - return FcTrue; - } - /* * Check ~/.fonts.cache- file */ - if (cache && FcGlobalCacheScanDir (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; } @@ -221,7 +164,6 @@ FcDirScanConfig (FcFontSet *set, printf ("\tScanning dir %s\n", dir); d = opendir ((char *) dir); - if (!d) { free (file); @@ -230,23 +172,88 @@ FcDirScanConfig (FcFontSet *set, return FcTrue; return FcFalse; } - while (ret && (e = readdir (d))) + + tmpSet = FcFontSetCreate(); + if (!tmpSet) + { + ret = FcFalse; + goto bail0; + } + + 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 (set, 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, 0, 0); - + FcGlobalCacheUpdate (cache, dirs, (char *)dir, tmpSet, config); + + for (i = 0; i < tmpSet->nfont; i++) + FcFontSetAdd (set, tmpSet->fonts[i]); + + if (tmpSet->fonts) + { + FcMemFree (FC_MEM_FONTPTR, tmpSet->sfont * sizeof (FcPattern *)); + 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; } @@ -262,7 +269,7 @@ FcDirScan (FcFontSet *set, } FcBool -FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir) +FcDirSave (FcFontSet *set, FcStrSet * dirs, const FcChar8 *dir) { - return FcDirCacheWriteDir (set, dirs, dir); + return FcDirCacheWrite (set, dirs, dir, FcConfigGetCurrent ()); }