Re: how to detect `fontconfig needs a long time'

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>>> 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.
>From b46df92964e9b3c225c59efb6c1aa81dad28c874 Mon Sep 17 00:00:00 2001
From: Masamichi Hosoda <trueroad@xxxxxxxxxxx>
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

#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;
}
_______________________________________________
Fontconfig mailing list
Fontconfig@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/fontconfig

[Index of Archives]     [Fedora Fonts]     [Fedora Users]     [Fedora Cloud]     [Kernel]     [Fedora Packaging]     [Fedora Desktop]     [PAM]     [Gimp Graphics Editor]     [Yosemite News]

  Powered by Linux