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>
reviewed by: plam

View File

@ -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;
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];
}
d0 = FcConfigInodeMatchFontDir(config, d);
if (d0)
return d0;
/* 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 (FcConfigAddFontDirSubdirs (config, config->fontDirs->strs[n]))
added = FcTrue;
}
/* if it fails, then really give up. */
/* ... and try again. */
if (added)
return FcConfigInodeMatchFontDir(config, d);
return 0;
}