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
This commit is contained in:
Patrick Lam 2006-02-06 19:25:45 +00:00
parent 86e75dfb5d
commit a0aa54f6ee
2 changed files with 62 additions and 27 deletions

View File

@ -1,3 +1,12 @@
2006-02-06 Takashi Iwai <tiwai@suse.de>
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 <dmueller@suse.de> 2006-02-06 Dirk Mueller <dmueller@suse.de>
reviewed by: plam reviewed by: plam

View File

@ -383,10 +383,45 @@ FcConfigGetConfigDirs (FcConfig *config)
return FcStrListCreate (config->configDirs); 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 FcBool
FcConfigAddFontDir (FcConfig *config, FcConfigAddFontDir (FcConfig *config,
const FcChar8 *d) 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); return FcStrSetAddFilename (config->fontDirs, d);
} }
@ -397,6 +432,7 @@ FcConfigAddFontDirSubdirs (FcConfig *config,
DIR *dir; DIR *dir;
struct dirent *e; struct dirent *e;
FcChar8 *subdir; FcChar8 *subdir;
FcBool added = FcFalse;
if (!(dir = opendir ((char *) d))) if (!(dir = opendir ((char *) d)))
return FcFalse; return FcFalse;
@ -415,52 +451,42 @@ FcConfigAddFontDirSubdirs (FcConfig *config,
strcat ((char *)subdir, e->d_name); strcat ((char *)subdir, e->d_name);
if (FcFileIsDir (subdir)) if (FcFileIsDir (subdir))
{ {
FcConfigAddFontDir (config, subdir); if (FcConfigInodeMatchFontDir(config, subdir))
continue; /* already added */
FcStrSetAddFilename (config->fontDirs, subdir);
FcConfigAddFontDirSubdirs (config, subdir); FcConfigAddFontDirSubdirs (config, subdir);
added = FcTrue;
} }
} }
} }
free (subdir); free (subdir);
closedir (dir); closedir (dir);
return FcTrue; return added;
} }
const FcChar8 * const FcChar8 *
FcConfigNormalizeFontDir (FcConfig *config, FcConfigNormalizeFontDir (FcConfig *config,
const FcChar8 *d) const FcChar8 *d)
{ {
/* If this is a bottleneck, we can cache the fontDir inodes. */ FcChar8 *d0;
ino_t di;
dev_t dd;
int n, n0; int n, n0;
struct stat s; FcBool added = FcFalse;
if (stat ((char *)d, &s) == -1) d0 = FcConfigInodeMatchFontDir(config, d);
return 0; if (d0)
di = s.st_ino; dd = s.st_dev; return d0;
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.... */ /* Ok, we didn't find it in fontDirs; let's add subdirs.... */
for (n = 0, n0 = config->fontDirs->num; n < n0; n++) 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) if (FcConfigAddFontDirSubdirs (config, config->fontDirs->strs[n]))
continue; added = FcTrue;
if (di == s.st_ino && dd == s.st_dev)
return config->fontDirs->strs[n];
} }
/* if it fails, then really give up. */ /* ... and try again. */
if (added)
return FcConfigInodeMatchFontDir(config, d);
return 0; return 0;
} }