Re: how to detect `fontconfig needs a long time'
Masamichi Hosoda <[email protected]>
| Newsgroups | gmane.comp.fonts.fontconfig |
|---|---|
| Message-ID | <[email protected]> |
>>> OK. So how can an application find out that the font cache >>> creation (or update) is very time consuming? Is it at least >>> possible to catch the situation of a first run? >> >> current implementation assumes the users will runs fc-cache to >> create caches before running. as such APIs isn't available at this >> point, so no, it isn't. though we discussed a bit these days, if it >> is wrong assumption, we may need to think about another way IMHO. > > Given that many applications that use fontconfig are ported to Windows > today, the assumption of running `fc-cache' in advance is becoming > much weaker IMHO – there is no longer a global fontconfig cache, since > every program comes with its own stuff.[*] I hate this approach a lot, > but we have to face the reality on this platform... I propose to export an inner API, FcDirCacheValidConfig (). I've attached the patch `0001-Export-FcDirCacheValidConfig'. Currently there is no way for applications to detect `fontconfig needs a long time' for cache updating. There is also no way for applications to find out whether font cache updating is necessary or not, in a short time. The already exported FcDirCacheValid () API updates all caches. In other words, it takes a long time when updating is necessary. I've investigated the point where FcDirCacheValid () takes a long time. As a result, I noticed that inner API, FcDirCacheValidConfig () does not take a long time, that is, it does not update the cache. So applications can find out whether updating caches are necessary or not by this function, in a short time. I've attached `is_neccesary_update.cc' as a sample application using this function. It can display directories that require cache updates. An application may be able to estimate `fontconfig needs a long time' for cache updating, since it become to be able to find out the directories that requires cache updates. _______________________________________________ Fontconfig mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/fontconfig
0001-Export-FcDirCacheValidConfig.patch
(text/x-patch, 2 KB)
From b46df92964e9b3c225c59efb6c1aa81dad28c874 Mon Sep 17 00:00:00 2001 From: Masamichi Hosoda <[email protected]> Date: Wed, 23 Nov 2016 20:57:49 +0900 Subject: [PATCH] Export FcDirCacheValidConfig () FcDirCacheValidConfig () does not update caches. So applications can find out whether updating caches are necessary or not by this function. --- doc/fcdircache.fncs | 11 +++++++++++ fontconfig/fontconfig.h | 3 +++ src/fccache.c | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/doc/fcdircache.fncs b/doc/fcdircache.fncs index faeba29..6b1fe6c 100644 --- a/doc/fcdircache.fncs +++ b/doc/fcdircache.fncs @@ -41,6 +41,17 @@ Returns FcTrue if <parameter>dir</parameter> has an associated valid cache file, else returns FcFalse @@ +@RET@ FcBool +@FUNC@ FcDirCacheValidConfig +@TYPE1@ const FcChar8 * @ARG1@ dir +@TYPE2@ FcConfig * @ARG2@ config +@PURPOSE@ check directory cache without cache updating +@DESC@ +Returns FcTrue if <parameter>dir</parameter> has an associated valid cache +file, else returns FcFalse. This function does not update caches. +@SINCE@ 2.12.2 +@@ + @RET@ FcCache * @FUNC@ FcDirCacheLoad @TYPE1@ const FcChar8 * @ARG1@ dir diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index 5c72b22..6598a27 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -347,6 +347,9 @@ FcPublic FcBool FcDirCacheValid (const FcChar8 *cache_file); FcPublic FcBool +FcDirCacheValidConfig (const FcChar8 *cache_file, FcConfig *config); + +FcPublic FcBool FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose); FcPublic void diff --git a/src/fccache.c b/src/fccache.c index 6f3c68a..0948482 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -844,7 +844,7 @@ FcDirCacheValidateHelper (FcConfig *config, int fd, struct stat *fd_stat, struct return ret; } -static FcBool +FcBool FcDirCacheValidConfig (const FcChar8 *dir, FcConfig *config) { return FcDirCacheProcess (config, dir, -- 2.8.3
is_neccesary_update.cc
(text/plain, 1.9 KB)
#include <cstdio>
#include <iostream>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <fontconfig/fontconfig.h>
int check_cache (FcConfig *config);
int scan_dirs (FcStrList *list, FcConfig *config);
int scan_dir (const FcChar8 *dir, FcConfig *config);
int main ()
{
FcInitLoadConfig ();
FcConfig *config = FcConfigCreate ();
FcChar8 *default_conf = FcConfigFilename (NULL);
FcConfigParseAndLoad (config, default_conf, FcTrue);
FcStrFree (default_conf);
int ret = check_cache (config);
std::cout << std::endl << "font cache updating is ";
if (ret)
std::cout << "neccesary (" << ret << " dirs) " << std::endl;
else
std::cout << "not neccesary" << std::endl;
return 0;
}
int check_cache (FcConfig *config)
{
FcStrList *list = FcConfigGetConfigDirs (config);
int ret = scan_dirs (list, config);
FcStrListDone (list);
return ret;
}
int scan_dirs (FcStrList *list, FcConfig *config)
{
int ret = 0;
const FcChar8 *dir;
while ((dir = FcStrListNext (list)))
ret += scan_dir (dir, config);
return ret;
}
int scan_dir (const FcChar8 *dir, FcConfig *config)
{
std::cout << dir << " - " << std::flush;
struct stat statb;
if (stat ((char *)dir, &statb) == -1)
{
switch (errno)
{
case ENOENT:
case ENOTDIR:
std::cout << "no such directory" << std::endl;
return 0;
default:
perror ("");
return 0;
}
}
int ret = 0;
if (FcDirCacheValidConfig (dir, config))
{
std::cout << "valid" << std::endl;
}
else
{
std::cout << "***INVALID*** - neccesary updating" << std::endl;
ret++;
}
DIR *dp = opendir ((char*)dir);
struct dirent *dent;
while ((dent = readdir (dp)) != NULL)
{
if (dent->d_type == DT_DIR && dent->d_name[0] != '.')
{
std::string subdir ((char*)dir);
subdir += "/";
subdir += dent->d_name;
ret += scan_dir ((FcChar8*)subdir.c_str (), config);
}
}
closedir (dp);
return ret;
}