Commit 82f4243f authored by Keith Packard's avatar Keith Packard

Switch to RFC 3066 based lang names

parent 899e3526
/*
* $XFree86: xc/lib/fontconfig/fontconfig/fontconfig.h,v 1.18 2002/06/19 20:08:22 keithp Exp $
* $XFree86: xc/lib/fontconfig/fontconfig/fontconfig.h,v 1.19 2002/06/30 23:45:17 keithp Exp $
*
* Copyright 2001 Keith Packard, member of The XFree86 Project, Inc.
*
......@@ -613,6 +613,9 @@ FcPatternHash (const FcPattern *p);
FcBool
FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append);
FcBool
FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append);
FcResult
FcPatternGet (FcPattern *p, const char *object, int id, FcValue *v);
......
......@@ -29,12 +29,12 @@ EXPATLIB=-lexpat
REQUIREDLIBS=$(LDPRELIBS) $(FREETYPE2LIB) $(EXPATLIB)
SRCS=fcatomic.c fcblanks.c fccache.c fccfg.c fccharset.c fcdbg.c \
fcdefault.c fcdir.c fcfreetype.c fcfs.c fcinit.c fclist.c fcmatch.c \
fcmatrix.c fcname.c fcpat.c fcstr.c fcxml.c
fcdefault.c fcdir.c fcfreetype.c fcfs.c fcinit.c fclang.c fclist.c \
fcmatch.c fcmatrix.c fcname.c fcpat.c fcstr.c fcxml.c
OBJS=fcatomic.o fcblanks.o fccache.o fccfg.o fccharset.o fcdbg.o \
fcdefault.o fcdir.o fcfreetype.o fcfs.o fcinit.o fclist.o fcmatch.o \
fcmatrix.o fcname.o fcpat.o fcstr.o fcxml.o
fcdefault.o fcdir.o fcfreetype.o fcfs.o fcinit.o fclang.o fclist.o \
fcmatch.o fcmatrix.o fcname.o fcpat.o fcstr.o fcxml.o
#include <Library.tmpl>
......
/*
* $XFree86: xc/lib/fontconfig/src/fccharset.c,v 1.13 2002/06/26 22:56:51 keithp Exp $
* $XFree86: xc/lib/fontconfig/src/fccharset.c,v 1.14 2002/06/29 20:31:02 keithp Exp $
*
* Copyright 2001 Keith Packard, member of The XFree86 Project, Inc.
*
......@@ -111,7 +111,7 @@ FcCharSetFindLeafPos (const FcCharSet *fcs, FcChar32 ucs4)
else
high = mid - 1;
}
if (numbers[high] < ucs4)
if (high < 0 || numbers[high] < ucs4)
high++;
return -(high + 1);
}
......@@ -711,7 +711,7 @@ FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result)
* it's not exactly human readable output. As a special case, 0 is encoded as a space
*/
static unsigned char charToValue[256] = {
static const unsigned char charToValue[256] = {
/* "" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/* "\b" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/* "\020" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
......@@ -746,7 +746,7 @@ static unsigned char charToValue[256] = {
/* "\370" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
static FcChar8 valueToChar[0x55] = {
static const FcChar8 valueToChar[0x55] = {
/* 0x00 */ '!', '#', '$', '%', '&', '(', ')', '*',
/* 0x08 */ '+', '.', '/', '0', '1', '2', '3', '4',
/* 0x10 */ '5', '6', '7', '8', '9', ';', '<', '>',
......
/*
* $XFree86: xc/lib/fontconfig/src/fcfreetype.c,v 1.4 2002/05/31 23:21:25 keithp Exp $
* $XFree86: xc/lib/fontconfig/src/fcfreetype.c,v 1.5 2002/06/29 20:31:02 keithp Exp $
*
* Copyright 2001 Keith Packard, member of The XFree86 Project, Inc.
*
......@@ -29,140 +29,201 @@
#include <freetype/freetype.h>
#include <freetype/internal/ftobjs.h>
#include <freetype/tttables.h>
#include "fcknownsets.h"
static const FcChar8 *fcLangLatin1[] = {
(FcChar8 *) "br", /* Breton */
(FcChar8 *) "ca", /* Catalan */
(FcChar8 *) "da", /* Danish */
(FcChar8 *) "de", /* German */
(FcChar8 *) "en", /* English */
(FcChar8 *) "es", /* Spanish */
(FcChar8 *) "eu", /* Basque */
(FcChar8 *) "fi", /* Finnish */
(FcChar8 *) "fo", /* Faroese */
(FcChar8 *) "fr", /* French */
(FcChar8 *) "ga", /* Irish */
(FcChar8 *) "gd", /* Scottish */
(FcChar8 *) "gl", /* Galician */
(FcChar8 *) "is", /* Islandic */
(FcChar8 *) "it", /* Italian */
(FcChar8 *) "kl", /* Greenlandic */
(FcChar8 *) "la", /* Latin */
(FcChar8 *) "nl", /* Dutch */
(FcChar8 *) "no", /* Norwegian */
(FcChar8 *) "pt", /* Portuguese */
(FcChar8 *) "rm", /* Rhaeto-Romanic */
(FcChar8 *) "sq", /* Albanian */
(FcChar8 *) "sv", /* Swedish */
0
};
static const FcChar8 *fcLangLatin2[] = {
(FcChar8 *) "cs", /* Czech */
(FcChar8 *) "de", /* German */
(FcChar8 *) "en", /* English */
(FcChar8 *) "fi", /* Finnish */
(FcChar8 *) "hr", /* Croatian */
(FcChar8 *) "hu", /* Hungarian */
(FcChar8 *) "la", /* Latin */
(FcChar8 *) "pl", /* Polish */
(FcChar8 *) "ro", /* Romanian */
(FcChar8 *) "sk", /* Slovak */
(FcChar8 *) "sl", /* Slovenian */
(FcChar8 *) "sq", /* Albanian */
0
};
static const FcChar8 *fcLangCyrillic[] = {
(FcChar8 *) "az", /* Azerbaijani */
(FcChar8 *) "ba", /* Bashkir */
(FcChar8 *) "bg", /* Bulgarian */
(FcChar8 *) "be", /* Byelorussian */
(FcChar8 *) "kk", /* Kazakh */
(FcChar8 *) "ky", /* Kirghiz */
(FcChar8 *) "mk", /* Macedonian */
(FcChar8 *) "mo", /* Moldavian */
(FcChar8 *) "mn", /* Mongolian */
(FcChar8 *) "ru", /* Russian */
(FcChar8 *) "sr", /* Serbian */
(FcChar8 *) "tg", /* Tadzhik */
(FcChar8 *) "tt", /* Tatar */
(FcChar8 *) "tk", /* Turkmen */
(FcChar8 *) "uz", /* Uzbek */
(FcChar8 *) "uk", /* Ukrainian */
0,
};
static const FcChar8 *fcLangGreek[] = {
(FcChar8 *) "el", /* Greek */
0
};
static const FcChar8 *fcLangTurkish[] = {
(FcChar8 *) "tr", /* Turkish */
0
};
static const FcChar8 *fcLangHebrew[] = {
(FcChar8 *) "he", /* Hebrew */
(FcChar8 *) "yi", /* Yiddish */
0
};
static const FcChar8 *fcLangArabic[] = {
(FcChar8 *) "ar", /* arabic */
0
};
static const FcChar8 *fcLangWindowsBaltic[] = {
(FcChar8 *) "da", /* Danish */
(FcChar8 *) "de", /* German */
(FcChar8 *) "en", /* English */
(FcChar8 *) "et", /* Estonian */
(FcChar8 *) "fi", /* Finnish */
(FcChar8 *) "la", /* Latin */
(FcChar8 *) "lt", /* Lithuanian */
(FcChar8 *) "lv", /* Latvian */
(FcChar8 *) "no", /* Norwegian */
(FcChar8 *) "pl", /* Polish */
(FcChar8 *) "sl", /* Slovenian */
(FcChar8 *) "sv", /* Swedish */
0
};
static const FcChar8 *fcLangVietnamese[] = {
(FcChar8 *) "vi", /* Vietnamese */
0,
};
static const FcChar8 *fcLangThai[] = {
(FcChar8 *) "th", /* Thai */
0,
};
static const FcChar8 *fcLangJapanese[] = {
(FcChar8 *) "ja", /* Japanese */
0,
};
static const FcChar8 *fcLangSimplifiedChinese[] = {
(FcChar8 *) "zh-cn", /* Chinese-China */
0,
};
static const FcChar8 *fcLangKorean[] = {
(FcChar8 *) "ko", /* Korean */
0,
};
static const FcChar8 *fcLangTraditionalChinese[] = {
(FcChar8 *) "zh-tw", /* Chinese-Taiwan */
0,
};
static const FcChar8 *fcLangEnglish[] = {
(FcChar8 *) "en", /* English */
0,
};
/*
* Elide some of the less useful bits
*/
static const struct {
int bit;
FcChar8 *name;
int bit;
const FcChar8 **lang;
} FcCodePageRange[] = {
{ 0, (FcChar8 *) FC_LANG_LATIN_1 },
{ 1, (FcChar8 *) FC_LANG_LATIN_2 },
{ 2, (FcChar8 *) FC_LANG_CYRILLIC },
{ 3, (FcChar8 *) FC_LANG_GREEK },
{ 4, (FcChar8 *) FC_LANG_TURKISH },
{ 5, (FcChar8 *) FC_LANG_HEBREW },
{ 6, (FcChar8 *) FC_LANG_ARABIC },
{ 7, (FcChar8 *) FC_LANG_WINDOWS_BALTIC },
{ 8, (FcChar8 *) FC_LANG_VIETNAMESE },
{ 0, fcLangLatin1 },
{ 1, fcLangLatin2 },
{ 2, fcLangCyrillic },
{ 3, fcLangGreek },
{ 4, fcLangTurkish },
{ 5, fcLangHebrew },
{ 6, fcLangArabic },
{ 7, fcLangWindowsBaltic },
{ 8, fcLangVietnamese },
/* 9-15 reserved for Alternate ANSI */
{ 16, (FcChar8 *) FC_LANG_THAI },
{ 17, (FcChar8 *) FC_LANG_JAPANESE },
{ 18, (FcChar8 *) FC_LANG_SIMPLIFIED_CHINESE },
{ 19, (FcChar8 *) FC_LANG_KOREAN_WANSUNG },
{ 20, (FcChar8 *) FC_LANG_TRADITIONAL_CHINESE },
{ 21, (FcChar8 *) FC_LANG_KOREAN_JOHAB },
{ 16, fcLangThai },
{ 17, fcLangJapanese },
{ 18, fcLangSimplifiedChinese },
{ 19, fcLangKorean },
{ 20, fcLangTraditionalChinese },
{ 21, fcLangKorean },
/* 22-28 reserved for Alternate ANSI & OEM */
{ 29, (FcChar8 *) FC_LANG_MACINTOSH },
{ 30, (FcChar8 *) FC_LANG_OEM },
{ 31, (FcChar8 *) FC_LANG_SYMBOL },
/* { 29, fcLangMacintosh }, */
/* { 30, fcLangOem }, */
/* { 31, fcLangSymbol },*/
/* 32-47 reserved for OEM */
{ 48, (FcChar8 *) FC_LANG_IBM_GREEK },
{ 49, (FcChar8 *) FC_LANG_MSDOS_RUSSIAN },
{ 50, (FcChar8 *) FC_LANG_MSDOS_NORDIC },
{ 51, (FcChar8 *) FC_LANG_ARABIC_864 },
{ 52, (FcChar8 *) FC_LANG_MSDOS_CANADIAN_FRENCH },
{ 53, (FcChar8 *) FC_LANG_HEBREW_862 },
{ 54, (FcChar8 *) FC_LANG_MSDOS_ICELANDIC },
{ 55, (FcChar8 *) FC_LANG_MSDOS_PORTUGUESE },
{ 56, (FcChar8 *) FC_LANG_IBM_TURKISH },
{ 57, (FcChar8 *) FC_LANG_IBM_CYRILLIC },
{ 58, (FcChar8 *) FC_LANG_LATIN_2 },
{ 59, (FcChar8 *) FC_LANG_MSDOS_BALTIC },
{ 60, (FcChar8 *) FC_LANG_GREEK_437_G },
{ 61, (FcChar8 *) FC_LANG_ARABIC_ASMO_708 },
{ 62, (FcChar8 *) FC_LANG_WE_LATIN_1 },
{ 63, (FcChar8 *) FC_LANG_US },
{ 48, fcLangGreek },
{ 49, fcLangCyrillic },
/* { 50, fcLangMsdosNordic }, */
{ 51, fcLangArabic },
/* { 52, fcLangMSDOS_CANADIAN_FRENCH }, */
{ 53, fcLangHebrew },
/* { 54, fcLangMSDOS_ICELANDIC }, */
/* { 55, fcLangMSDOS_PORTUGUESE }, */
{ 56, fcLangTurkish },
{ 57, fcLangCyrillic },
{ 58, fcLangLatin2 },
{ 59, fcLangWindowsBaltic },
{ 60, fcLangGreek },
{ 61, fcLangArabic },
{ 62, fcLangLatin1 },
{ 63, fcLangEnglish },
};
#define NUM_CODE_PAGE_RANGE (sizeof FcCodePageRange / sizeof FcCodePageRange[0])
static const struct {
const FcCharSet *set;
FcChar32 size;
FcChar32 missing_tolerance;
FcChar8 *name;
} FcCodePageSet[] = {
{
&fcCharSet_Latin1_1252,
fcCharSet_Latin1_1252_size,
8,
(FcChar8 *) FC_LANG_LATIN_1,
},
{
&fcCharSet_Latin2_1250,
fcCharSet_Latin2_1250_size,
8,
(FcChar8 *) FC_LANG_LATIN_2,
},
{
&fcCharSet_Cyrillic_1251,
fcCharSet_Cyrillic_1251_size,
16,
(FcChar8 *) FC_LANG_CYRILLIC,
},
{
&fcCharSet_Greek_1253,
fcCharSet_Greek_1253_size,
8,
(FcChar8 *) FC_LANG_GREEK,
},
{
&fcCharSet_Turkish_1254,
fcCharSet_Turkish_1254_size,
16,
(FcChar8 *) FC_LANG_TURKISH,
},
{
&fcCharSet_Hebrew_1255,
fcCharSet_Hebrew_1255_size,
16,
(FcChar8 *) FC_LANG_HEBREW,
},
{
&fcCharSet_Arabic_1256,
fcCharSet_Arabic_1256_size,
16,
(FcChar8 *) FC_LANG_ARABIC,
},
{
&fcCharSet_Windows_Baltic_1257,
fcCharSet_Windows_Baltic_1257_size,
16,
(FcChar8 *) FC_LANG_WINDOWS_BALTIC,
},
{
&fcCharSet_Thai_874,
fcCharSet_Thai_874_size,
16,
(FcChar8 *) FC_LANG_THAI,
},
{
&fcCharSet_Japanese_932,
fcCharSet_Japanese_932_size,
500,
(FcChar8 *) FC_LANG_JAPANESE,
},
{
&fcCharSet_SimplifiedChinese_936,
fcCharSet_SimplifiedChinese_936_size,
500,
(FcChar8 *) FC_LANG_SIMPLIFIED_CHINESE,
},
{
&fcCharSet_Korean_949,
fcCharSet_Korean_949_size,
500,
(FcChar8 *) FC_LANG_KOREAN_WANSUNG,
},
{
&fcCharSet_TraditionalChinese_950,
fcCharSet_TraditionalChinese_950_size,
500,
(FcChar8 *) FC_LANG_TRADITIONAL_CHINESE,
},
};
FcBool
FcFreeTypeHasLang (FcPattern *pattern, const FcChar8 *lang)
{
FcChar8 *old;
int i;
#define NUM_CODE_PAGE_SET (sizeof FcCodePageSet / sizeof FcCodePageSet[0])
for (i = 0; FcPatternGetString (pattern, FC_LANG, i, &old) == FcResultMatch; i++)
if (!FcStrCmp (lang, old))
return FcTrue;
return FcFalse;
}
FcPattern *
FcFreeTypeQuery (const FcChar8 *file,
......@@ -179,9 +240,10 @@ FcFreeTypeQuery (const FcChar8 *file,
FT_Library ftLibrary;
const FcChar8 *family;
TT_OS2 *os2;
FcBool hasLang = FcFalse;
FcChar32 codepoints;
FcBool matchCodePage[NUM_CODE_PAGE_SET];
FcChar8 *lang;
FcBool hasLang = FcFalse;
if (FT_Init_FreeType (&ftLibrary))
return 0;
......@@ -273,10 +335,16 @@ FcFreeTypeQuery (const FcChar8 *file,
}
if (bits & (1 << bit))
{
if (!FcPatternAddString (pat, FC_LANG,
FcCodePageRange[i].name))
goto bail1;
hasLang = FcTrue;
int j;
const FcChar8 *lang;
for (j = 0; (lang = FcCodePageRange[i].lang[j]); j++)
if (!FcFreeTypeHasLang (pat, lang))
{
if (!FcPatternAddString (pat, FC_LANG, lang))
goto bail1;
hasLang = FcTrue;
}
}
}
}
......@@ -302,79 +370,19 @@ FcFreeTypeQuery (const FcChar8 *file,
if (!FcPatternAddCharSet (pat, FC_CHARSET, cs))
goto bail2;
if (!hasLang || (FcDebug() & FC_DBG_SCANV))
if (!hasLang)
{
if (!FcFreeTypeSetLang (pat, cs))
goto bail2;
/*
* Use the Unicode coverage to set lang if it wasn't
* set from the OS/2 tables
* Make sure it has a lang entry
*/
if (FcDebug() & FC_DBG_SCANV)
printf ("%s: ", family);
for (i = 0; i < NUM_CODE_PAGE_SET; i++)
{
FcChar32 missing;
missing = FcCharSetSubtractCount (FcCodePageSet[i].set,
cs);
matchCodePage[i] = missing <= FcCodePageSet[i].missing_tolerance;
if (FcDebug() & FC_DBG_SCANV)
printf ("%s(%d) ", FcCodePageSet[i].name, missing);
}
if (FcDebug() & FC_DBG_SCANV)
printf ("\n");
if (hasLang)
{
FcChar8 *lang;
int j;
/*
* Validate the lang selections
*/
for (i = 0; FcPatternGetString (pat, FC_LANG, i, &lang) == FcResultMatch; i++)
{
for (j = 0; j < NUM_CODE_PAGE_SET; j++)
if (!strcmp ((char *) FcCodePageSet[j].name,
(char *) lang))
{
if (!matchCodePage[j])
printf ("%s(%s): missing lang %s\n", file, family, lang);
}
}
for (j = 0; j < NUM_CODE_PAGE_SET; j++)
{
if (!matchCodePage[j])
continue;
lang = 0;
for (i = 0; FcPatternGetString (pat, FC_LANG, i, &lang) == FcResultMatch; i++)
{
if (!strcmp ((char *) FcCodePageSet[j].name, (char *) lang))
break;
lang = 0;
}
if (!lang)
printf ("%s(%s): extra lang %s\n", file, family, FcCodePageSet[j].name);
}
}
else
{
/*
* None provided, use the charset derived ones
*/
for (i = 0; i < NUM_CODE_PAGE_SET; i++)
if (matchCodePage[i])
{
if (!FcPatternAddString (pat, FC_LANG,
FcCodePageRange[i].name))
goto bail1;
hasLang = TRUE;
}
}
if (FcPatternGetString (pat, FC_LANG, 0, &lang) != FcResultMatch)
if (!FcPatternAddString (pat, FC_LANG, (FcChar8 *) "x-unknown"))
goto bail2;
}
if (!hasLang)
if (!FcPatternAddString (pat, FC_LANG, (FcChar8 *) FC_LANG_UNKNOWN))
goto bail1;
/*
* Drop our reference to the charset
*/
......
......@@ -163,6 +163,10 @@ typedef struct _FcCharLeaf {
FcChar32 map[256/32];
} FcCharLeaf;
typedef enum _FcLangResult {
FcLangEqual, FcLangDifferentCountry, FcLangDifferentLang
} FcLangResult;
struct _FcCharSet {
int ref; /* reference count */
FcBool constant; /* in hash table constant */
......@@ -393,6 +397,10 @@ FcDebug (void);
int
FcFontDebug (void);
/* fcfreetype.c */
FcBool
FcFreeTypeHasLang (FcPattern *pattern, const FcChar8 *lang);
/* fcfs.c */
/* fcgram.y */
int
......@@ -460,6 +468,16 @@ FcMemAlloc (int kind, int size);
void
FcMemFree (int kind, int size);
/* fclang.c */
FcBool
FcFreeTypeSetLang (FcPattern *pattern, FcCharSet *charset);
FcLangResult
FcLangCompare (const FcChar8 *s1, const FcChar8 *s2);
const FcCharSet *
FcCharSetForLang (const FcChar8 *lang);
/* fclist.c */
/* fcmatch.c */
......@@ -479,6 +497,13 @@ FcPatternFindElt (const FcPattern *p, const char *object);
FcPatternElt *
FcPatternInsertElt (FcPattern *p, const char *object);
FcBool
FcPatternAddWithBinding (FcPattern *p,
const char *object,
FcValue value,
FcValueBinding binding,
FcBool append);
/* fcrender.c */
/* fcmatrix.c */
......@@ -510,4 +535,7 @@ FcStrBufString (FcStrBuf *buf, const FcChar8 *s);
FcBool
FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
#endif /* _FC_INT_H_ */
/*
* $XFree86: xc/lib/fontconfig/src/fcmatch.c,v 1.14 2002/06/19 21:32:18 keithp Exp $
* $XFree86: xc/lib/fontconfig/src/fcmatch.c,v 1.15 2002/06/29 20:31:02 keithp Exp $
*
* Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
*
......@@ -48,6 +48,33 @@ FcCompareString (char *object, FcValue value1, FcValue value2)
return (double) FcStrCmpIgnoreCase (value1.u.s, value2.u.s) != 0;
}
static double
FcCompareFamily (char *object, FcValue value1, FcValue value2)
{
if (value2.type != FcTypeString || value1.type != FcTypeString)
return -1.0;
return (double) FcStrCmpIgnoreBlanksAndCase (value1.u.s, value2.u.s) != 0;
}
static double
FcCompareLang (char *object, FcValue value1, FcValue value2)
{
FcLangResult result;
if (value2.type != FcTypeString || value1.type != FcTypeString)
return -1.0;
result = FcLangCompare (value1.u.s, value2.u.s);
switch (result) {
case FcLangEqual:
return 0;
case FcLangDifferentCountry:
return 1;
case FcLangDifferentLang:
default:
return 2;
}
}
static double
FcCompareBool (char *object, FcValue value1, FcValue value2)
{
......@@ -115,10 +142,10 @@ static FcMatcher _FcMatchers [] = {
{ FC_CHARSET, FcCompareCharSet, 1, 1 },
#define MATCH_CHARSET 1
{ FC_FAMILY, FcCompareString, 2, 4 },
{ FC_FAMILY, FcCompareFamily, 2, 4 },
#define MATCH_FAMILY 2
{ FC_LANG, FcCompareString, 3, 3 },
{ FC_LANG, FcCompareLang, 3, 3 },
#define MATCH_LANG 3
{ FC_SPACING, FcCompareInteger, 5, 5 },
......@@ -545,6 +572,11 @@ FcSortWalk (FcSortNode **n, int nnode, FcFontSet *fs, FcCharSet **cs, FcBool tri
ncs = FcCharSetCopy (ncs);
*cs = ncs;
FcPatternReference (node->pattern);
if (FcDebug () & FC_DBG_MATCH)
{
printf ("Add ");
FcPatternPrint (node->pattern);
}
if (!FcFontSetAdd (fs, node->pattern))
{
FcPatternDestroy (node->pattern);
......@@ -582,6 +614,11 @@ FcFontSetSort (FcConfig *config,
int f;
int i;