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>
|
||||
* 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])
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -574,6 +574,10 @@ FcSubstPrint (const FcSubst *subst);
|
|||
int
|
||||
FcDebug (void);
|
||||
|
||||
/* fcdefault.c */
|
||||
FcChar8 *
|
||||
FcGetDefaultLang (void);
|
||||
|
||||
/* fcdir.c */
|
||||
|
||||
FcBool
|
||||
|
|
60
src/fclist.c
60
src/fclist.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue