[Fontconfig] fontconfig: Branch 'master' - 4 commits

Akira TAGOH akira at tagoh.org
Fri Jun 8 00:11:54 PDT 2012


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


More information about the Fontconfig mailing list