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:
parent
e58b50e88c
commit
904426816d
|
@ -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>
|
2005-10-21 Patrick Lam <plam@mit.edu>
|
||||||
* src/fccache.c (FcGlobalCacheLoad):
|
* src/fccache.c (FcGlobalCacheLoad):
|
||||||
|
|
||||||
|
|
110
src/fcdefault.c
110
src/fcdefault.c
|
@ -37,6 +37,67 @@ static struct {
|
||||||
|
|
||||||
#define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0])
|
#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
|
void
|
||||||
FcDefaultSubstitute (FcPattern *pattern)
|
FcDefaultSubstitute (FcPattern *pattern)
|
||||||
{
|
{
|
||||||
|
@ -91,54 +152,7 @@ FcDefaultSubstitute (FcPattern *pattern)
|
||||||
|
|
||||||
if (FcPatternGet (pattern, FC_LANG, 0, &v) == FcResultNoMatch)
|
if (FcPatternGet (pattern, FC_LANG, 0, &v) == FcResultNoMatch)
|
||||||
{
|
{
|
||||||
char *lang;
|
FcPatternAddString (pattern, FC_LANG, FcGetDefaultLang ());
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (FcPatternGet (pattern, FC_FONTVERSION, 0, &v) == FcResultNoMatch)
|
if (FcPatternGet (pattern, FC_FONTVERSION, 0, &v) == FcResultNoMatch)
|
||||||
{
|
{
|
||||||
|
|
|
@ -574,6 +574,10 @@ FcSubstPrint (const FcSubst *subst);
|
||||||
int
|
int
|
||||||
FcDebug (void);
|
FcDebug (void);
|
||||||
|
|
||||||
|
/* fcdefault.c */
|
||||||
|
FcChar8 *
|
||||||
|
FcGetDefaultLang (void);
|
||||||
|
|
||||||
/* fcdir.c */
|
/* fcdir.c */
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
|
60
src/fclist.c
60
src/fclist.c
|
@ -337,6 +337,34 @@ FcListHashTableCleanup (FcListHashTable *table)
|
||||||
table->entries = 0;
|
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
|
static FcBool
|
||||||
FcListAppend (FcListHashTable *table,
|
FcListAppend (FcListHashTable *table,
|
||||||
FcPattern *font,
|
FcPattern *font,
|
||||||
|
@ -347,6 +375,11 @@ FcListAppend (FcListHashTable *table,
|
||||||
FcValueListPtr v;
|
FcValueListPtr v;
|
||||||
FcChar32 hash;
|
FcChar32 hash;
|
||||||
FcListBucket **prev, *bucket;
|
FcListBucket **prev, *bucket;
|
||||||
|
int familyidx = -1;
|
||||||
|
int fullnameidx = -1;
|
||||||
|
int styleidx = -1;
|
||||||
|
int defidx = 0;
|
||||||
|
int idx;
|
||||||
|
|
||||||
hash = FcListPatternHash (font, os);
|
hash = FcListPatternHash (font, os);
|
||||||
for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE];
|
for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE];
|
||||||
|
@ -368,15 +401,36 @@ FcListAppend (FcListHashTable *table,
|
||||||
|
|
||||||
for (o = 0; o < os->nobject; o++)
|
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]);
|
e = FcPatternFindElt (font, os->objects[o]);
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
for (v = e->values; FcValueListPtrU(v);
|
for (v = e->values, idx = 0; FcValueListPtrU(v);
|
||||||
v = FcValueListPtrU(v)->next)
|
v = FcValueListPtrU(v)->next, ++idx)
|
||||||
{
|
{
|
||||||
if (!FcPatternAdd (bucket->pattern,
|
if (!FcPatternAdd (bucket->pattern,
|
||||||
os->objects[o],
|
os->objects[o],
|
||||||
FcValueCanonicalize(&FcValueListPtrU(v)->value), FcTrue))
|
FcValueCanonicalize(&FcValueListPtrU(v)->value), defidx != idx))
|
||||||
goto bail2;
|
goto bail2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue