Support localized font family and style names. This has been reported to

break old apps like xfd, but modern (gtk+/qt/mozilla) apps work fine.
reviewed by: plam
This commit is contained in:
Patrick Lam 2005-10-22 14:21:14 +00:00
parent e58b50e88c
commit 904426816d
4 changed files with 130 additions and 51 deletions

View File

@ -1,3 +1,10 @@
2005-10-22 Zhe Su <zsu@novell.com>
reviewed by: plam
Support localized font family and style names.
This has been reported to break old apps like xfd, but modern
(gtk+/qt/mozilla) apps work fine.
2005-10-21 Patrick Lam <plam@mit.edu>
* src/fccache.c (FcGlobalCacheLoad):

View File

@ -37,6 +37,67 @@ static struct {
#define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0])
FcChar8 *
FcGetDefaultLang (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"))
{
ctype = getenv ("LC_ALL");
if (!ctype)
{
ctype = getenv ("LC_CTYPE");
if (!ctype)
ctype = getenv ("LANG");
}
}
/* ignore missing or empty ctype */
if (ctype && *ctype != '\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';
}
}
}
/* set default lang to en */
if (!lang_local [0])
strcpy (lang_local, "en");
return (FcChar8 *) lang_local;
}
void
FcDefaultSubstitute (FcPattern *pattern)
{
@ -91,54 +152,7 @@ FcDefaultSubstitute (FcPattern *pattern)
if (FcPatternGet (pattern, FC_LANG, 0, &v) == FcResultNoMatch)
{
char *lang;
char *territory;
char *after;
int lang_len, territory_len;
char lang_local[128];
char *ctype = setlocale (LC_CTYPE, NULL);
/*
* Check if setlocale (LC_ALL, "") has been called
*/
if (!ctype || !strcmp (ctype, "C"))
{
ctype = getenv ("LC_ALL");
if (!ctype)
{
ctype = getenv ("LC_CTYPE");
if (!ctype)
ctype = getenv ("LANG");
}
}
if (ctype)
{
lang = ctype;
territory = strchr (ctype, '_');
if (territory)
{
lang_len = territory - lang;
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, lang, lang_len);
lang_local[lang_len] = '-';
strncpy (lang_local + lang_len + 1, territory, territory_len);
lang_local[lang_len + 1 + territory_len] = '\0';
FcPatternAddString (pattern, FC_LANG, (FcChar8 *) lang_local);
}
}
else
FcPatternAddString (pattern, FC_LANG, (FcChar8 *) lang);
}
FcPatternAddString (pattern, FC_LANG, FcGetDefaultLang ());
}
if (FcPatternGet (pattern, FC_FONTVERSION, 0, &v) == FcResultNoMatch)
{

View File

@ -574,6 +574,10 @@ FcSubstPrint (const FcSubst *subst);
int
FcDebug (void);
/* fcdefault.c */
FcChar8 *
FcGetDefaultLang (void);
/* fcdir.c */
FcBool

View File

@ -337,6 +337,34 @@ FcListHashTableCleanup (FcListHashTable *table)
table->entries = 0;
}
static int
FcGetDefaultObjectLangIndex (FcPattern *font, const char *object)
{
FcChar8 *lang = FcGetDefaultLang ();
FcPatternElt *e = FcPatternFindElt (font, object);
FcValueListPtr v;
FcValue value;
int idx = -1;
int i;
if (e)
{
for (v = e->values, i = 0; FcValueListPtrU(v); v = FcValueListPtrU(v)->next, ++i)
{
value = FcValueCanonicalize (&FcValueListPtrU (v)->value);
if (value.type == FcTypeString)
{
FcLangResult res = FcLangCompare (value.u.s, lang);
if (res == FcLangEqual || (res == FcLangDifferentCountry && idx < 0))
idx = i;
}
}
}
return (idx > 0) ? idx : 0;
}
static FcBool
FcListAppend (FcListHashTable *table,
FcPattern *font,
@ -347,6 +375,11 @@ FcListAppend (FcListHashTable *table,
FcValueListPtr v;
FcChar32 hash;
FcListBucket **prev, *bucket;
int familyidx = -1;
int fullnameidx = -1;
int styleidx = -1;
int defidx = 0;
int idx;
hash = FcListPatternHash (font, os);
for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE];
@ -368,15 +401,36 @@ FcListAppend (FcListHashTable *table,
for (o = 0; o < os->nobject; o++)
{
if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG))
{
if (familyidx < 0)
familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG);
defidx = familyidx;
}
else if (!strcmp (os->objects[o], FC_FULLNAME) || !strcmp (os->objects[o], FC_FULLNAMELANG))
{
if (fullnameidx < 0)
fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG);
defidx = fullnameidx;
}
else if (!strcmp (os->objects[o], FC_STYLE) || !strcmp (os->objects[o], FC_STYLELANG))
{
if (styleidx < 0)
styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG);
defidx = styleidx;
}
else
defidx = 0;
e = FcPatternFindElt (font, os->objects[o]);
if (e)
{
for (v = e->values; FcValueListPtrU(v);
v = FcValueListPtrU(v)->next)
for (v = e->values, idx = 0; FcValueListPtrU(v);
v = FcValueListPtrU(v)->next, ++idx)
{
if (!FcPatternAdd (bucket->pattern,
os->objects[o],
FcValueCanonicalize(&FcValueListPtrU(v)->value), FcTrue))
FcValueCanonicalize(&FcValueListPtrU(v)->value), defidx != idx))
goto bail2;
}
}