Well, please test if you didn''t play with it yet.
Thanks,
On Fri, Jun 8, 2012 at 4:05 PM, Akira TAGOH
<tagoh at kemper.freedesktop.org> wrote:> ?doc/fclangset.fncs ? ? ?| ? ?9 ++
> ?fc-lang/fc-lang.c ? ? ? | ? ?6 +
> ?fontconfig/fontconfig.h | ? ?3
> ?src/fccfg.c ? ? ? ? ? ? | ? 18 +++++
> ?src/fcdefault.c ? ? ? ? | ?106 +++++++++-----------------------
> ?src/fcint.h ? ? ? ? ? ? | ? ?6 +
> ?src/fclang.c ? ? ? ? ? ?| ?159
++++++++++++++++++++++++++++++++++++++++++++++++
> ?src/fcstr.c ? ? ? ? ? ? | ? 44 +++++++++++++
> ?8 files changed, 278 insertions(+), 73 deletions(-)
>
> New commits:
> commit 07e52eeb097a4e3c147e00ed7a6eb7652a611751
> Author: Akira TAGOH <akira at tagoh.org>
> Date: ? Fri Jun 8 15:54:48 2012 +0900
>
> ? ?fcdefault: no need to set FC_LANG in FcDefaultSubstitute() anymore
>
> diff --git a/src/fcdefault.c b/src/fcdefault.c
> index ce90a88..c6b5669 100644
> --- a/src/fcdefault.c
> +++ b/src/fcdefault.c
> @@ -126,10 +126,6 @@ FcDefaultSubstitute (FcPattern *pattern)
> ? ? ? ?FcPatternObjectAddDouble (pattern, FC_PIXEL_SIZE_OBJECT, size);
> ? ? }
>
> - ? ?if (FcPatternObjectGet (pattern, FC_LANG_OBJECT, 0, &v) ==
FcResultNoMatch)
> - ? ?{
> - ? ? ? FcPatternObjectAddString (pattern, FC_LANG_OBJECT, FcGetDefaultLang
());
> - ? ?}
> ? ? if (FcPatternObjectGet (pattern, FC_FONTVERSION_OBJECT, 0, &v) ==
FcResultNoMatch)
> ? ? {
> ? ? ? ?FcPatternObjectAddInteger (pattern, FC_FONTVERSION_OBJECT,
0x7fffffff);
> commit 550fd49d4fb8efab33d1fa1687b1b9bd352202fe
> Author: Akira TAGOH <akira at tagoh.org>
> Date: ? Tue May 22 14:17:10 2012 +0900
>
> ? ?Add the default language to the pattern prior to do build the
substitution
>
> ? ?the default language is referred from the FC_LANG environment variable
> ? ?or the current locale
>
> diff --git a/src/fccfg.c b/src/fccfg.c
> index b45d74a..c3d95e8 100644
> --- a/src/fccfg.c
> +++ b/src/fccfg.c
> @@ -1407,6 +1407,7 @@ FcConfigSubstituteWithPat (FcConfig ? ?*config,
> ? ? FcEdit ? ? ? ? *e;
> ? ? FcValueList ? ? ? ? ? ?*l;
> ? ? FcPattern ? ? ?*m;
> + ? ?FcStrSet ? ? ? *strs;
>
> ? ? if (!config)
> ? ? {
> @@ -1434,6 +1435,23 @@ FcConfigSubstituteWithPat (FcConfig ? ?*config,
> ? ? ? ?return FcFalse;
> ? ? FcMemAlloc (FC_MEM_SUBSTATE, config->maxObjects * sizeof
(FcSubState));
>
> + ? ?strs = FcGetDefaultLangs ();
> + ? ?if (strs)
> + ? ?{
> + ? ? ? FcStrList *l = FcStrListCreate (strs);
> + ? ? ? FcChar8 *lang;
> + ? ? ? FcValue v;
> +
> + ? ? ? FcStrSetDestroy (strs);
> + ? ? ? while (l && (lang = FcStrListNext (l)))
> + ? ? ? {
> + ? ? ? ? ? v.type = FcTypeString;
> + ? ? ? ? ? v.u.s = lang;
> + ? ? ? ? ? FcPatternObjectAddWithBinding (p, FC_LANG_OBJECT, v,
FcValueBindingWeak, FcTrue);
> + ? ? ? }
> + ? ? ? FcStrListDone (l);
> + ? ?}
> +
> ? ? if (FcDebug () & FC_DBG_EDIT)
> ? ? {
> ? ? ? ?printf ("FcConfigSubstitute ");
> commit 2261a64ce14d692f7c553f46e2158e70400dbc9c
> Author: Akira TAGOH <akira at tagoh.org>
> Date: ? Fri Jun 8 15:47:52 2012 +0900
>
> ? ?fcdefault: fallback if the environment variables are empty
>
> ? ?try to fallback if FC_LANG, LC_ALL, LC_CTYPE and LANG is empty
>
> diff --git a/src/fcdefault.c b/src/fcdefault.c
> index 674374c..ce90a88 100644
> --- a/src/fcdefault.c
> +++ b/src/fcdefault.c
> @@ -46,13 +46,13 @@ FcGetDefaultLangs (void)
> ? ? char *langs;
>
> ? ? langs = getenv ("FC_LANG");
> - ? ?if (!langs)
> + ? ?if (!langs || !langs[0])
> ? ? ? ?langs = getenv ("LC_ALL");
> - ? ?if (!langs)
> + ? ?if (!langs || !langs[0])
> ? ? ? ?langs = getenv ("LC_CTYPE");
> - ? ?if (!langs)
> + ? ?if (!langs || !langs[0])
> ? ? ? ?langs = getenv ("LANG");
> - ? ?if (langs)
> + ? ?if (langs && langs[0])
> ? ? {
> ? ? ? ?if (!FcStrSetAddLangs (result, langs))
> ? ? ? ? ? ?FcStrSetAdd (result, (const FcChar8 *) "en");
> commit bbc8fb5ba705e5257693f3b266fce12d2f81b50c
> Author: Akira TAGOH <akira at tagoh.org>
> Date: ? Thu Mar 29 20:25:20 2012 +0900
>
> ? ?Bug 32853 - Export API to get the default language
>
> ? ?Add a new API FcGetDefaultLangs() to export the string sets of the
default
> ? ?languages.
>
> diff --git a/doc/fclangset.fncs b/doc/fclangset.fncs
> index 0a44b38..e2a40b8 100644
> --- a/doc/fclangset.fncs
> +++ b/doc/fclangset.fncs
> @@ -154,6 +154,15 @@ has no matching language, this function returns
FcLangDifferentLang.
> ?@@
>
> ?@RET@ ? ? ? ? ?FcStrSet *
> + at FUNC@ ? ? ? ? FcGetDefaultLangs
> + at TYPE1@ ? ? ? ? ? ? ? ?void
> + at PURPOSE@ ? ? ?Get the default languages list
> + at DESC@
> +Returns a string set of the default languages according to the environment
variables on the system.
> +This function looks for them in order of FC_LANG, LC_ALL, LC_CTYPE and
LANG then.
> +If there are no valid values in those environment variables,
"en" will be set as fallback.
> +
> + at RET@ ? ? ? ? ?FcStrSet *
> ?@FUNC@ ? ? ? ? FcLangSetGetLangs
> ?@TYPE1@ ? ? ? ? ? ? ? ?const FcLangSet * ? ? ? ? ? ? ? @ARG1@ ? ? ? ? ?ls
> ?@PURPOSE@ ? ? ?get the list of languages in the langset
> diff --git a/fc-lang/fc-lang.c b/fc-lang/fc-lang.c
> index 51717f9..93200c4 100644
> --- a/fc-lang/fc-lang.c
> +++ b/fc-lang/fc-lang.c
> @@ -57,6 +57,12 @@ FcCacheObjectDereference (void *object)
> ?{
> ?}
>
> +FcPrivate FcChar8 *
> +FcLangNormalize (const FcChar8 *lang)
> +{
> + ? ?return NULL;
> +}
> +
> ?int FcDebugVal;
>
> ?FcChar8 *
> diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
> index 2671da7..21a476a 100644
> --- a/fontconfig/fontconfig.h
> +++ b/fontconfig/fontconfig.h
> @@ -497,6 +497,9 @@ FcPublic void
> ?FcFontSetPrint (const FcFontSet *s);
>
> ?/* fcdefault.c */
> +FcPublic FcStrSet *
> +FcGetDefaultLangs (void);
> +
> ?FcPublic void
> ?FcDefaultSubstitute (FcPattern *pattern);
>
> diff --git a/src/fcdefault.c b/src/fcdefault.c
> index 170a8a4..674374c 100644
> --- a/src/fcdefault.c
> +++ b/src/fcdefault.c
> @@ -23,7 +23,7 @@
> ?*/
>
> ?#include "fcint.h"
> -#include <locale.h>
> +#include <string.h>
>
> ?static const struct {
> ? ? FcObject ? field;
> @@ -39,81 +39,45 @@ static const struct {
>
> ?#define NUM_FC_BOOL_DEFAULTS ? (int) (sizeof FcBoolDefaults / sizeof
FcBoolDefaults[0])
>
> -FcChar8 *
> -FcGetDefaultLang (void)
> +FcStrSet *
> +FcGetDefaultLangs (void)
> ?{
> - ? ?static char ? ? ? ?lang_local [128] = {0};
> - ? ?char ? ? ? ?*ctype;
> - ? ?char ? ? ? ?*territory;
> - ? ?char ? ? ? ?*after;
> - ? ?int ? ? ? ? lang_len, territory_len;
> -
> - ? ?if (lang_local [0])
> - ? ? ? return (FcChar8 *) lang_local;
> -
> - ? ?ctype = setlocale (LC_CTYPE, NULL);
> -
> - ? ?/*
> - ? ? * Check if setlocale (LC_ALL, "") has been called
> - ? ? */
> - ? ?if (!ctype || !strcmp (ctype, "C"))
> + ? ?FcStrSet *result = FcStrSetCreate ();
> + ? ?char *langs;
> +
> + ? ?langs = getenv ("FC_LANG");
> + ? ?if (!langs)
> + ? ? ? langs = getenv ("LC_ALL");
> + ? ?if (!langs)
> + ? ? ? langs = getenv ("LC_CTYPE");
> + ? ?if (!langs)
> + ? ? ? langs = getenv ("LANG");
> + ? ?if (langs)
> ? ? {
> - ? ? ? ctype = getenv ("LC_ALL");
> - ? ? ? if (!ctype)
> - ? ? ? {
> - ? ? ? ? ? ctype = getenv ("LC_CTYPE");
> - ? ? ? ? ? if (!ctype)
> - ? ? ? ? ? ? ? ctype = getenv ("LANG");
> - ? ? ? }
> + ? ? ? if (!FcStrSetAddLangs (result, langs))
> + ? ? ? ? ? FcStrSetAdd (result, (const FcChar8 *) "en");
> ? ? }
> + ? ?else
> + ? ? ? FcStrSetAdd (result, (const FcChar8 *) "en");
> +
> + ? ?return result;
> +}
>
> - ? ?/* ignore missing or empty ctype */
> - ? ?if (ctype && *ctype != ''\0'')
> +FcChar8 *
> +FcGetDefaultLang (void)
> +{
> + ? ?static FcChar8 lang_local[128] = {0};
> + ? ?FcStrSet *langs;
> +
> + ? ?if (!lang_local[0])
> ? ? {
> - ? ? ? territory = strchr (ctype, ''_'');
> - ? ? ? if (territory)
> - ? ? ? {
> - ? ? ? ? ? lang_len = territory - ctype;
> - ? ? ? ? ? territory = territory + 1;
> - ? ? ? ? ? after = strchr (territory, ''.'');
> - ? ? ? ? ? if (!after)
> - ? ? ? ? ? {
> - ? ? ? ? ? ? ? after = strchr (territory, ''@'');
> - ? ? ? ? ? ? ? if (!after)
> - ? ? ? ? ? ? ? ? ? after = territory + strlen (territory);
> - ? ? ? ? ? }
> - ? ? ? ? ? territory_len = after - territory;
> - ? ? ? ? ? if (lang_len + 1 + territory_len + 1 <= (int) sizeof
(lang_local))
> - ? ? ? ? ? {
> - ? ? ? ? ? ? ? strncpy (lang_local, ctype, lang_len);
> - ? ? ? ? ? ? ? lang_local[lang_len] = ''-'';
> - ? ? ? ? ? ? ? strncpy (lang_local + lang_len + 1, territory,
territory_len);
> - ? ? ? ? ? ? ? lang_local[lang_len + 1 + territory_len] =
''\0'';
> - ? ? ? ? ? }
> - ? ? ? }
> - ? ? ? else
> - ? ? ? {
> - ? ? ? ? ? after = strchr (ctype, ''.'');
> - ? ? ? ? ? if (!after)
> - ? ? ? ? ? {
> - ? ? ? ? ? ? ? after = strchr (ctype, ''@'');
> - ? ? ? ? ? ? ? if (!after)
> - ? ? ? ? ? ? ? ? ? after = ctype + strlen (ctype);
> - ? ? ? ? ? }
> - ? ? ? ? ? lang_len = after - ctype;
> - ? ? ? ? ? if (lang_len + 1 <= (int) sizeof (lang_local))
> - ? ? ? ? ? {
> - ? ? ? ? ? ? ? strncpy (lang_local, ctype, lang_len);
> - ? ? ? ? ? ? ? lang_local[lang_len] = ''\0'';
> - ? ? ? ? ? }
> - ? ? ? }
> + ? ? ? langs = FcGetDefaultLangs ();
> + ? ? ? strncpy ((char *)lang_local, (const char *)langs->strs[0], 127);
> + ? ? ? lang_local[127] = 0;
> + ? ? ? FcStrSetDestroy (langs);
> ? ? }
>
> - ? ?/* set default lang to en */
> - ? ?if (!lang_local [0])
> - ? ? ? strcpy (lang_local, "en");
> -
> - ? ?return (FcChar8 *) lang_local;
> + ? ?return lang_local;
> ?}
>
> ?void
> diff --git a/src/fcint.h b/src/fcint.h
> index 3d06fc6..7cc4ed2 100644
> --- a/src/fcint.h
> +++ b/src/fcint.h
> @@ -816,6 +816,9 @@ FcPrivate FcLangSet *
> ?FcFreeTypeLangSet (const FcCharSet ?*charset,
> ? ? ? ? ? ? ? ? ? const FcChar8 ? ?*exclusiveLang);
>
> +FcPrivate FcChar8 *
> +FcLangNormalize (const FcChar8 *lang);
> +
> ?FcPrivate FcLangResult
> ?FcLangCompare (const FcChar8 *s1, const FcChar8 *s2);
>
> @@ -1039,6 +1042,9 @@ FcPrivate FcBool
> ?FcIsFsMtimeBroken (const FcChar8 *dir);
>
> ?/* fcstr.c */
> +FcPrivate FcBool
> +FcStrSetAddLangs (FcStrSet *strs, const char *languages);
> +
> ?FcPrivate void
> ?FcStrSetSort (FcStrSet * set);
>
> diff --git a/src/fclang.c b/src/fclang.c
> index be42b58..b7e70fc 100644
> --- a/src/fclang.c
> +++ b/src/fclang.c
> @@ -22,6 +22,7 @@
> ?* PERFORMANCE OF THIS SOFTWARE.
> ?*/
>
> +#include <string.h>
> ?#include "fcint.h"
> ?#include "fcftint.h"
>
> @@ -43,6 +44,9 @@ struct _FcLangSet {
> ? ? FcChar32 ? map[NUM_LANG_SET_MAP];
> ?};
>
> +static int FcLangSetIndex (const FcChar8 *lang);
> +
> +
> ?static void
> ?FcLangSetBitSet (FcLangSet ? ?*ls,
> ? ? ? ? ? ? ? ? unsigned int ?id)
> @@ -173,6 +177,161 @@ FcFreeTypeLangSet (const FcCharSet ?*charset,
> ? ? return ls;
> ?}
>
> +FcChar8 *
> +FcLangNormalize (const FcChar8 *lang)
> +{
> + ? ?FcChar8 *result = NULL, *s, *orig;
> + ? ?char *territory, *encoding, *modifier;
> + ? ?size_t llen, tlen = 0, mlen = 0;
> +
> + ? ?if (!lang || !*lang)
> + ? ? ? return NULL;
> +
> + ? ?if (FcStrCmpIgnoreCase (lang, (const FcChar8 *)"C") == 0 ||
> + ? ? ? FcStrCmpIgnoreCase (lang, (const FcChar8 *)"POSIX") == 0)
> + ? ?{
> + ? ? ? result = FcStrCopy ((const FcChar8 *)"en");
> + ? ? ? goto bail;
> + ? ?}
> +
> + ? ?s = FcStrCopy (lang);
> + ? ?if (!s)
> + ? ? ? goto bail;
> +
> + ? ?/* from the comments in glibc:
> + ? ? *
> + ? ? * LOCALE can consist of up to four recognized parts for the XPG
syntax:
> + ? ? *
> + ? ? * ? ? ? ? ? ?language[_territory[.codeset]][@modifier]
> + ? ? *
> + ? ? * Beside the first all of them are allowed to be missing. ?If the
> + ? ? * full specified locale is not found, the less specific one are
> + ? ? * looked for. ?The various part will be stripped off according to
> + ? ? * the following order:
> + ? ? * ? ? ? ? ? ?(1) codeset
> + ? ? * ? ? ? ? ? ?(2) normalized codeset
> + ? ? * ? ? ? ? ? ?(3) territory
> + ? ? * ? ? ? ? ? ?(4) modifier
> + ? ? *
> + ? ? * So since we don''t take care of the codeset part here, what
patterns
> + ? ? * we need to deal with is:
> + ? ? *
> + ? ? * ? 1. language_territory at modifier
> + ? ? * ? 2. language at modifier
> + ? ? * ? 3. language
> + ? ? *
> + ? ? * then. and maybe no need to try language_territory here.
> + ? ? */
> + ? ?modifier = strchr ((const char *) s, ''@'');
> + ? ?if (modifier)
> + ? ?{
> + ? ? ? *modifier = 0;
> + ? ? ? modifier++;
> + ? ? ? mlen = strlen (modifier);
> + ? ?}
> + ? ?encoding = strchr ((const char *) s, ''.'');
> + ? ?if (encoding)
> + ? ?{
> + ? ? ? *encoding = 0;
> + ? ? ? encoding++;
> + ? ? ? if (modifier)
> + ? ? ? {
> + ? ? ? ? ? memmove (encoding, modifier, mlen + 1);
> + ? ? ? ? ? modifier = encoding;
> + ? ? ? }
> + ? ?}
> + ? ?territory = strchr ((const char *) s, ''_'');
> + ? ?if (!territory)
> + ? ? ? territory = strchr ((const char *) s, ''-'');
> + ? ?if (territory)
> + ? ?{
> + ? ? ? *territory = 0;
> + ? ? ? territory++;
> + ? ? ? tlen = strlen (territory);
> + ? ?}
> + ? ?llen = strlen ((const char *) s);
> + ? ?if (llen < 2 || llen > 3)
> + ? ?{
> + ? ? ? fprintf (stderr, "Fontconfig warning: ignoring %s: not a valid
language tag\n",
> + ? ? ? ? ? ? ? ?lang);
> + ? ? ? goto bail0;
> + ? ?}
> + ? ?if (territory && (tlen < 2 || tlen > 3))
> + ? ?{
> + ? ? ? fprintf (stderr, "Fontconfig warning: ignoring %s: not a valid
region tag\n",
> + ? ? ? ? ? ? ? ?lang);
> + ? ? ? goto bail0;
> + ? ?}
> + ? ?if (territory)
> + ? ? ? territory[-1] = ''-'';
> + ? ?if (modifier)
> + ? ? ? modifier[-1] = ''@'';
> + ? ?orig = FcStrDowncase (s);
> + ? ?if (!orig)
> + ? ? ? goto bail0;
> + ? ?if (territory)
> + ? ?{
> + ? ? ? if (FcDebug () & FC_DBG_LANGSET)
> + ? ? ? ? ? printf("Checking the existence of %s.orth\n", s);
> + ? ? ? if (FcLangSetIndex (s) < 0)
> + ? ? ? {
> + ? ? ? ? ? memmove (territory - 1, territory + tlen, (mlen > 0 ? mlen +
1 : 0) + 1);
> + ? ? ? ? ? if (modifier)
> + ? ? ? ? ? ? ? modifier = territory;
> + ? ? ? }
> + ? ? ? else
> + ? ? ? {
> + ? ? ? ? ? result = s;
> + ? ? ? ? ? s = NULL;
> + ? ? ? ? ? goto bail1;
> + ? ? ? }
> + ? ?}
> + ? ?if (modifier)
> + ? ?{
> + ? ? ? if (FcDebug () & FC_DBG_LANGSET)
> + ? ? ? ? ? printf("Checking the existence of %s.orth\n", s);
> + ? ? ? if (FcLangSetIndex (s) < 0)
> + ? ? ? ? ? modifier[-1] = 0;
> + ? ? ? else
> + ? ? ? {
> + ? ? ? ? ? result = s;
> + ? ? ? ? ? s = NULL;
> + ? ? ? ? ? goto bail1;
> + ? ? ? }
> + ? ?}
> + ? ?if (FcDebug () & FC_DBG_LANGSET)
> + ? ? ? printf("Checking the existence of %s.orth\n", s);
> + ? ?if (FcLangSetIndex (s) < 0)
> + ? ?{
> + ? ? ? /* there seems no languages matched in orth.
> + ? ? ? ?* add the language as is for fallback.
> + ? ? ? ?*/
> + ? ? ? result = orig;
> + ? ? ? orig = NULL;
> + ? ?}
> + ? ?else
> + ? ?{
> + ? ? ? result = s;
> + ? ? ? s = NULL;
> + ? ?}
> + ?bail1:
> + ? ?if (orig)
> + ? ? ? free (orig);
> + ?bail0:
> + ? ?if (s)
> + ? ? ? free (s);
> + ?bail:
> + ? ?if (FcDebug () & FC_DBG_LANGSET)
> + ? ?{
> + ? ? ? if (result)
> + ? ? ? ? ? printf ("normalized: %s -> %s\n", lang, result);
> + ? ? ? else
> + ? ? ? ? ? printf ("Unable to normalize %s\n", lang);
> + ? ?}
> +
> + ? ?return result;
> +}
> +
> ?#define FcLangEnd(c) ? ((c) == ''-'' || (c) ==
''\0'')
>
> ?FcLangResult
> diff --git a/src/fcstr.c b/src/fcstr.c
> index e372af0..c446bcd 100644
> --- a/src/fcstr.c
> +++ b/src/fcstr.c
> @@ -1177,6 +1177,50 @@ FcStrSetAddFilename (FcStrSet *set, const FcChar8
*s)
> ?}
>
> ?FcBool
> +FcStrSetAddLangs (FcStrSet *strs, const char *languages)
> +{
> + ? ?const char *p = languages, *next;
> + ? ?FcChar8 lang[128] = {0}, *normalized_lang;
> + ? ?size_t len;
> + ? ?FcBool ret = FcFalse;
> +
> + ? ?if (!languages)
> + ? ? ? return FcFalse;
> +
> + ? ?while ((next = strchr (p, '':'')))
> + ? ?{
> + ? ? ? len = next - p;
> + ? ? ? len = FC_MIN (len, 128);
> + ? ? ? strncpy ((char *) lang, p, len);
> + ? ? ? lang[len] = 0;
> + ? ? ? /* ignore an empty item */
> + ? ? ? if (*lang)
> + ? ? ? {
> + ? ? ? ? ? normalized_lang = FcLangNormalize ((const FcChar8 *) lang);
> + ? ? ? ? ? if (normalized_lang)
> + ? ? ? ? ? {
> + ? ? ? ? ? ? ? FcStrSetAdd (strs, normalized_lang);
> + ? ? ? ? ? ? ? free (normalized_lang);
> + ? ? ? ? ? ? ? ret = FcTrue;
> + ? ? ? ? ? }
> + ? ? ? }
> + ? ? ? p = next + 1;
> + ? ?}
> + ? ?if (*p)
> + ? ?{
> + ? ? ? normalized_lang = FcLangNormalize ((const FcChar8 *) p);
> + ? ? ? if (normalized_lang)
> + ? ? ? {
> + ? ? ? ? ? FcStrSetAdd (strs, normalized_lang);
> + ? ? ? ? ? free (normalized_lang);
> + ? ? ? ? ? ret = FcTrue;
> + ? ? ? }
> + ? ?}
> +
> + ? ?return ret;
> +}
> +
> +FcBool
> ?FcStrSetDel (FcStrSet *set, const FcChar8 *s)
> ?{
> ? ? int ? ? ? ?i;
> _______________________________________________
> Fontconfig mailing list
> Fontconfig at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/fontconfig
--
Akira TAGOH