From a0aa54f6ee032efbca25bdf734ba62dd642b04a1 Mon Sep 17 00:00:00 2001 From: Patrick Lam Date: Mon, 6 Feb 2006 19:25:45 +0000 Subject: [PATCH] Don't rescan when trying to normalize a non-declared font dir. Don't add font dirs multiple times (even if they're aliased). reviewed by: plam --- ChangeLog | 9 +++++++ src/fccfg.c | 78 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 61 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 330e768..89d4355 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-02-06 Takashi Iwai + reviewed by: plam + + * src/fccfg.c (FcConfigInodeMatchFontDir, FcConfigAddFontDir, + FcConfigAddFontDirSubdirs, FcConfigNormalizeFontDir): + + Don't rescan when trying to normalize a non-declared font dir. + Don't add font dirs multiple times (even if they're aliased). + 2006-02-06 Dirk Mueller reviewed by: plam diff --git a/src/fccfg.c b/src/fccfg.c index 0e17edb..cae41b0 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -383,10 +383,45 @@ FcConfigGetConfigDirs (FcConfig *config) return FcStrListCreate (config->configDirs); } +static FcChar8 * +FcConfigInodeMatchFontDir (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 */ + /* FcStrSetMember doesn't tell us the index so that we can return + * the config-owned copy. */ + for (n = 0; n < config->fontDirs->num; n++) + { + if (!FcStrCmp (config->fontDirs->strs[n], d)) + 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 0; +} + FcBool FcConfigAddFontDir (FcConfig *config, const FcChar8 *d) { + /* Avoid adding d if it's an alias of something else, too. */ + if (FcConfigInodeMatchFontDir(config, d)) + return FcTrue; return FcStrSetAddFilename (config->fontDirs, d); } @@ -397,6 +432,7 @@ FcConfigAddFontDirSubdirs (FcConfig *config, DIR *dir; struct dirent *e; FcChar8 *subdir; + FcBool added = FcFalse; if (!(dir = opendir ((char *) d))) return FcFalse; @@ -415,52 +451,42 @@ FcConfigAddFontDirSubdirs (FcConfig *config, strcat ((char *)subdir, e->d_name); if (FcFileIsDir (subdir)) { - FcConfigAddFontDir (config, subdir); + if (FcConfigInodeMatchFontDir(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 *d0; 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; + d0 = FcConfigInodeMatchFontDir(config, d); + if (d0) + return d0; - for (n = 0; n < config->fontDirs->num; n++) + /* Ok, we didn't find it in fontDirs; let's add subdirs.... */ + for (n = 0, n0 = config->fontDirs->num; n < n0; 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 (FcConfigAddFontDirSubdirs (config, config->fontDirs->strs[n])) + added = FcTrue; } - /* 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]); - /* ... 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 FcConfigInodeMatchFontDir(config, d); - /* if it fails, then really give up. */ return 0; } -- 2.39.5