Patch by Takashi IWAI <tiwai@xxxxxxx> (CC:): If FcConfigNormalizeFontDir () was called with a directory which is not a subdirectory of a directory from a .conf file, the list of all subdirectories was added to the list of known directories. When doing this again, the list of subdirectories was added again. Takashi's patch fixes this.
--- src/fccfg.c-dist 2006-01-31 16:19:48.000000000 +0100 +++ src/fccfg.c 2006-01-31 16:42:41.000000000 +0100 @@ -383,10 +383,46 @@ FcConfigGetConfigDirs (FcConfig *confi return FcStrListCreate (config->configDirs); } +static FcChar8 * +FcConfigLookupAllDirs (FcConfig *config, const FcChar8 *d) +{ + int n; + ino_t di; + dev_t dd; + struct stat s; + + /* first we do string matches rather than file accesses */ + for (n = 0; n < config->fontDirs->num; n++) + { + if (config->fontDirs->strs[n] == d || + strcmp ((char *)config->fontDirs->strs[n], (char *)d) == 0) + return config->fontDirs->strs[n]; + } + + /* If this is a bottleneck, we can cache the fontDir inodes. */ + 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]; + } + return NULL; +} + FcBool FcConfigAddFontDir (FcConfig *config, const FcChar8 *d) { +#if 1 /* to be sure */ + /* already exists? */ + if (FcConfigLookupAllDirs(config, d)) + return FcTrue; +#endif return FcStrSetAddFilename (config->fontDirs, d); } @@ -397,6 +433,7 @@ FcConfigAddFontDirSubdirs (FcConfig DIR *dir; struct dirent *e; FcChar8 *subdir; + FcBool added = FcFalse; if (!(dir = opendir ((char *) d))) return FcFalse; @@ -415,53 +452,42 @@ FcConfigAddFontDirSubdirs (FcConfig strcat ((char *)subdir, e->d_name); if (FcFileIsDir (subdir)) { - FcConfigAddFontDir (config, subdir); + if (FcConfigLookupAllDirs(config, subdir)) + continue; /* already added */ + FcStrSetAddFilename (config->fontDirs, subdir); FcConfigAddFontDirSubdirs (config, subdir); + added = FcTrue; } } } free (subdir); closedir (dir); - return FcTrue; + return added; } 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; + FcChar8 *res; int n, n0; - struct stat s; + FcBool added = FcFalse; - 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]; - } + res = FcConfigLookupAllDirs(config, d); + if (res) + return res; /* Ok, we didn't find it in fontDirs; let's add subdirs.... */ - for (n = 0, n0 = config->fontDirs->num; n < n0; n++) - FcConfigAddFontDirSubdirs (config, config->fontDirs->strs[n]); + for (n = 0, n0 = config->fontDirs->num; n < n0; n++) { + if (FcConfigAddFontDirSubdirs (config, config->fontDirs->strs[n])) + added = FcTrue; + } /* ... 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 (added) + return FcConfigLookupAllDirs(config, d); - /* if it fails, then really give up. */ - return 0; + return NULL; } FcBool
-- Mike FABIAN <mfabian@xxxxxxx> http://www.suse.de/~mfabian 睡眠不足はいい仕事の敵だ。
_______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/fontconfig