3 #define AROS_ALMOST_COMPATIBLE
4 #include <exec/lists.h>
5 #include <proto/alib.h>
6 #include <private/vapor/vapor.h>
12 #include <proto/dos.h>
14 #include FT_FREETYPE_H
15 #include FT_TRUETYPE_TABLES_H
16 #include FT_SFNT_NAMES_H
17 #include "system/directory.h"
18 #include "system/functions.h"
19 #include "freetype/ttnameid.h"
23 #include "fontcache.h"
25 #define FC_DBG_SCANV 1
27 static FT_Library ftLibrary
;
29 void kprintf(char *fmt
,...);
33 //#define FcDebug() 0xffffffffUL
35 #define FcResultMatch TRUE
46 /* return an id for next insertion. if not found returns 0 */
48 static int fcPatternCheckEntry(struct fontpattern
*pat
, int element
)
50 struct patternentry
*pe
;
52 ITERATELIST(pe
, &pat
->entries
)
54 if (pe
->element
== element
)
55 return pe
->id
+ 1; /* elements with high ids are at the begining of the list */
62 static int fcPatternAddEntry(struct fontpattern
*pat
, int element
, int type
, union patternvalue
*value
, int excluding
)
64 struct patternentry
*pe
= calloc(1, sizeof(*pe
));
68 pe
->element
= element
;
70 pe
->id
= fcPatternCheckEntry(pat
, element
);
71 pe
->excluding
= excluding
;
73 if (type
== FC_ETYPE_STRING
)
75 if (FcDebug () & FC_DBG_SCANV
)
76 kprintf("adding string entry to pattern. elt:%d. value:%s, id:%d, excluding:%d\n", element
, value
->s
, pe
->id
, excluding
);
77 pe
->value
.s
= value
->s
!= NULL
? strdup(value
->s
) : NULL
;
81 if (FcDebug () & FC_DBG_SCANV
)
82 kprintf("adding int entry to pattern. elt:%d. value:%d, id:%d, excluding:%d\n", element
, value
->i
, pe
->id
, excluding
);
83 pe
->value
.p
= value
->p
;
86 ADDHEAD(&pat
->entries
, pe
); /* add to head so elements with high ids are first. this is 'normal' mode */
91 static int fcPatternAddEntryRaw(struct fontpattern
*pat
, int element
, int type
, union patternvalue
*value
, int id
)
93 struct patternentry
*pe
= calloc(1, sizeof(*pe
));
97 pe
->element
= element
;
100 pe
->value
.p
= value
->p
; /* no duplication. string is preallocated */
102 ADDTAIL(&pat
->entries
, pe
); /* when loading from cache we put entries in the order they were written in */
109 int fcPatternAddString(struct fontpattern
*pat
, int element
, char *value
)
111 union patternvalue v
;
113 return fcPatternAddEntry(pat
, element
, FC_ETYPE_STRING
, &v
, FALSE
); /* value is copied */
116 int fcPatternAddInteger(struct fontpattern
*pat
, int element
, int value
)
118 union patternvalue v
;
120 return fcPatternAddEntry(pat
, element
, FC_ETYPE_INTEGER
, &v
, FALSE
);
123 int fcPatternAddExcludingInteger(struct fontpattern
*pat
, int element
, int value
)
125 union patternvalue v
;
127 return fcPatternAddEntry(pat
, element
, FC_ETYPE_INTEGER
, &v
, TRUE
);
131 /* if elt is found but is not string then return NULL! */
133 char *fcPatternGetString(struct fontpattern
*pat
, int element
, int id
)
135 struct patternentry
*pe
;
137 ITERATELIST(pe
, &pat
->entries
)
139 if (pe
->element
== element
&& pe
->id
== id
)
141 if (pe
->type
!= FC_ETYPE_STRING
)
142 kprintf("***ERROR*** Getting element %d as string!\n", element
);
151 int fcPatternGetInteger(struct fontpattern
*pat
, int element
, int id
)
153 struct patternentry
*pe
;
155 ITERATELIST(pe
, &pat
->entries
)
157 if (pe
->element
== element
&& pe
->id
== id
)
159 if (pe
->type
!= FC_ETYPE_INTEGER
)
160 kprintf("***ERROR*** Getting element %d as integer!\n", element
);
169 struct patternentry
*fcPatternGetEntry(struct fontpattern
*pat
, int element
, int id
)
171 struct patternentry
*pe
;
173 ITERATELIST(pe
, &pat
->entries
)
175 if (pe
->element
== element
&& pe
->id
== id
)
188 const unsigned short platform_id
;
189 const unsigned short encoding_id
;
190 const char fromcode
[12];
193 typedef struct _FcCharEnt
{
195 unsigned char encode
;
198 typedef struct _FcCharMap
{
199 const FcCharEnt
*ent
;
203 typedef struct _FcFontDecode
{
204 FT_Encoding encoding
;
205 const FcCharMap
*map
;
209 /* Keep Han languages separated by eliminating languages that the codePageRange bits says aren't supported */
211 static const struct {
213 const FcChar8 lang
[6];
214 } FcCodePageRange
[] = {
221 #define NUM_CODE_PAGE_RANGE (int) (sizeof FcCodePageRange / sizeof FcCodePageRange[0])
224 FcBool
FcFreeTypeIsExclusiveLang (const FcChar8
*lang
)
228 for (i
= 0; i
< NUM_CODE_PAGE_RANGE
; i
++)
230 if (FcLangCompare (lang
, FcCodePageRange
[i
].lang
) == FcLangEqual
)
237 #define TT_ENCODING_DONT_CARE 0xffff
238 #define FC_ENCODING_MAC_ROMAN "MACINTOSH"
240 static const FcFtEncoding fcFtEncoding
[] = {
241 { TT_PLATFORM_APPLE_UNICODE
, TT_ENCODING_DONT_CARE
, "UCS-2BE" },
242 { TT_PLATFORM_MACINTOSH
, TT_MAC_ID_ROMAN
, "MACINTOSH" },
243 { TT_PLATFORM_MACINTOSH
, TT_MAC_ID_JAPANESE
, "SJIS" },
244 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_UNICODE_CS
, "UTF-16BE" },
245 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_SJIS
, "SJIS-WIN" },
246 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_GB2312
, "GB2312" },
247 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_BIG_5
, "BIG-5" },
248 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_WANSUNG
, "Wansung" },
249 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_JOHAB
, "Johab" },
250 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_UCS_4
, "UCS-2BE" },
251 { TT_PLATFORM_ISO
, TT_ISO_ID_7BIT_ASCII
, "ASCII" },
252 { TT_PLATFORM_ISO
, TT_ISO_ID_10646
, "UCS-2BE" },
253 { TT_PLATFORM_ISO
, TT_ISO_ID_8859_1
, "ISO-8859-1" },
256 #define NUM_FC_FT_ENCODING (int) (sizeof (fcFtEncoding) / sizeof (fcFtEncoding[0]))
259 const FT_UShort platform_id
;
260 const FT_UShort language_id
;
264 #define TT_LANGUAGE_DONT_CARE 0xffff
266 static const FcFtLanguage fcFtLanguage
[] = {
267 { TT_PLATFORM_APPLE_UNICODE
, TT_LANGUAGE_DONT_CARE
, "" },
268 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ENGLISH
, "en" },
269 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FRENCH
, "fr" },
270 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GERMAN
, "de" },
271 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ITALIAN
, "it" },
272 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_DUTCH
, "nl" },
273 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SWEDISH
, "sv" },
274 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SPANISH
, "es" },
275 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_DANISH
, "da" },
276 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_PORTUGUESE
, "pt" },
277 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_NORWEGIAN
, "no" },
278 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_HEBREW
, "he" },
279 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_JAPANESE
, "ja" },
280 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ARABIC
, "ar" },
281 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FINNISH
, "fi" },
282 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GREEK
, "el" },
283 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ICELANDIC
, "is" },
284 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALTESE
, "mt" },
285 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TURKISH
, "tr" },
286 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CROATIAN
, "hr" },
287 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CHINESE_TRADITIONAL
, "zh-tw" },
288 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_URDU
, "ur" },
289 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_HINDI
, "hi" },
290 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_THAI
, "th" },
291 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KOREAN
, "ko" },
292 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LITHUANIAN
, "lt" },
293 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_POLISH
, "pl" },
294 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_HUNGARIAN
, "hu" },
295 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ESTONIAN
, "et" },
296 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LETTISH
, "lv" },
297 /* { TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SAAMISK, ??? */
298 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FAEROESE
, "fo" },
299 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FARSI
, "fa" },
300 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_RUSSIAN
, "ru" },
301 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CHINESE_SIMPLIFIED
, "zh-cn" },
302 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FLEMISH
, "nl" },
303 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_IRISH
, "ga" },
304 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ALBANIAN
, "sq" },
305 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ROMANIAN
, "ro" },
306 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CZECH
, "cs" },
307 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SLOVAK
, "sk" },
308 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SLOVENIAN
, "sl" },
309 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_YIDDISH
, "yi" },
310 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SERBIAN
, "sr" },
311 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MACEDONIAN
, "mk" },
312 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BULGARIAN
, "bg" },
313 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_UKRAINIAN
, "uk" },
314 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BYELORUSSIAN
, "be" },
315 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_UZBEK
, "uz" },
316 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KAZAKH
, "kk" },
317 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI
, "az" },
318 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT
, "az" },
319 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT
, "ar" },
320 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ARMENIAN
, "hy" },
321 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GEORGIAN
, "ka" },
322 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MOLDAVIAN
, "mo" },
323 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KIRGHIZ
, "ky" },
324 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TAJIKI
, "tg" },
325 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TURKMEN
, "tk" },
326 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MONGOLIAN
, "mo" },
327 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT
,"mo" },
328 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT
, "mo" },
329 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_PASHTO
, "ps" },
330 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KURDISH
, "ku" },
331 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KASHMIRI
, "ks" },
332 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SINDHI
, "sd" },
333 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TIBETAN
, "bo" },
334 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_NEPALI
, "ne" },
335 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SANSKRIT
, "sa" },
336 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MARATHI
, "mr" },
337 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BENGALI
, "bn" },
338 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ASSAMESE
, "as" },
339 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GUJARATI
, "gu" },
340 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_PUNJABI
, "pa" },
341 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ORIYA
, "or" },
342 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAYALAM
, "ml" },
343 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KANNADA
, "kn" },
344 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TAMIL
, "ta" },
345 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TELUGU
, "te" },
346 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SINHALESE
, "si" },
347 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BURMESE
, "my" },
348 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KHMER
, "km" },
349 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LAO
, "lo" },
350 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_VIETNAMESE
, "vi" },
351 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_INDONESIAN
, "id" },
352 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TAGALOG
, "tl" },
353 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAY_ROMAN_SCRIPT
, "ms" },
354 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAY_ARABIC_SCRIPT
, "ms" },
355 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AMHARIC
, "am" },
356 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TIGRINYA
, "ti" },
357 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GALLA
, "om" },
358 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SOMALI
, "so" },
359 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SWAHILI
, "sw" },
360 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_RUANDA
, "rw" },
361 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_RUNDI
, "rn" },
362 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CHEWA
, "ny" },
363 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAGASY
, "mg" },
364 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ESPERANTO
, "eo" },
365 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_WELSH
, "cy" },
366 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BASQUE
, "eu" },
367 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CATALAN
, "ca" },
368 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LATIN
, "la" },
369 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_QUECHUA
, "qu" },
370 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GUARANI
, "gn" },
371 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AYMARA
, "ay" },
372 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TATAR
, "tt" },
373 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_UIGHUR
, "ug" },
374 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_DZONGKHA
, "dz" },
375 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_JAVANESE
, "jw" },
376 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SUNDANESE
, "su" },
378 #if 0 /* these seem to be errors that have been dropped */
380 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SCOTTISH_GAELIC
},
381 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_IRISH_GAELIC
},
385 /* The following codes are new as of 2000-03-10 */
386 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GALICIAN
, "gl" },
387 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AFRIKAANS
, "af" },
388 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BRETON
, "br" },
389 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_INUKTITUT
, "iu" },
390 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SCOTTISH_GAELIC
, "gd" },
391 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MANX_GAELIC
, "gv" },
392 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_IRISH_GAELIC
, "ga" },
393 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TONGAN
, "to" },
394 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GREEK_POLYTONIC
, "el" },
395 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GREELANDIC
, "ik" },
396 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT
,"az" },
398 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_SAUDI_ARABIA
, "ar" },
399 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_IRAQ
, "ar" },
400 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_EGYPT
, "ar" },
401 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_LIBYA
, "ar" },
402 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_ALGERIA
, "ar" },
403 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_MOROCCO
, "ar" },
404 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_TUNISIA
, "ar" },
405 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_OMAN
, "ar" },
406 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_YEMEN
, "ar" },
407 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_SYRIA
, "ar" },
408 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_JORDAN
, "ar" },
409 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_LEBANON
, "ar" },
410 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_KUWAIT
, "ar" },
411 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_UAE
, "ar" },
412 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_BAHRAIN
, "ar" },
413 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_QATAR
, "ar" },
414 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BULGARIAN_BULGARIA
, "bg" },
415 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CATALAN_SPAIN
, "ca" },
416 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_TAIWAN
, "zh-tw" },
417 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_PRC
, "zh-cn" },
418 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_HONG_KONG
, "zh-hk" },
419 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_SINGAPORE
, "zh-sg" },
421 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_MACAU
, "zh-mo" },
423 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CZECH_CZECH_REPUBLIC
, "cs" },
424 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DANISH_DENMARK
, "da" },
425 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_GERMANY
, "de" },
426 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_SWITZERLAND
, "de" },
427 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_AUSTRIA
, "de" },
428 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_LUXEMBOURG
, "de" },
429 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_LIECHTENSTEI
, "de" },
430 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GREEK_GREECE
, "el" },
431 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_UNITED_STATES
, "en" },
432 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_UNITED_KINGDOM
, "en" },
433 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_AUSTRALIA
, "en" },
434 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_CANADA
, "en" },
435 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_NEW_ZEALAND
, "en" },
436 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_IRELAND
, "en" },
437 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_SOUTH_AFRICA
, "en" },
438 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_JAMAICA
, "en" },
439 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_CARIBBEAN
, "en" },
440 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_BELIZE
, "en" },
441 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_TRINIDAD
, "en" },
442 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_ZIMBABWE
, "en" },
443 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_PHILIPPINES
, "en" },
444 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT
,"es" },
445 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_MEXICO
, "es" },
446 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT
,"es" },
447 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_GUATEMALA
, "es" },
448 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_COSTA_RICA
, "es" },
449 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PANAMA
, "es" },
450 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC
,"es" },
451 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_VENEZUELA
, "es" },
452 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_COLOMBIA
, "es" },
453 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PERU
, "es" },
454 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_ARGENTINA
, "es" },
455 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_ECUADOR
, "es" },
456 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_CHILE
, "es" },
457 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_URUGUAY
, "es" },
458 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PARAGUAY
, "es" },
459 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_BOLIVIA
, "es" },
460 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_EL_SALVADOR
, "es" },
461 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_HONDURAS
, "es" },
462 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_NICARAGUA
, "es" },
463 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PUERTO_RICO
, "es" },
464 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FINNISH_FINLAND
, "fi" },
465 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_FRANCE
, "fr" },
466 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_BELGIUM
, "fr" },
467 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_CANADA
, "fr" },
468 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_SWITZERLAND
, "fr" },
469 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_LUXEMBOURG
, "fr" },
470 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_MONACO
, "fr" },
471 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HEBREW_ISRAEL
, "he" },
472 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HUNGARIAN_HUNGARY
, "hu" },
473 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ICELANDIC_ICELAND
, "is" },
474 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ITALIAN_ITALY
, "it" },
475 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ITALIAN_SWITZERLAND
, "it" },
476 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_JAPANESE_JAPAN
, "ja" },
477 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA
,"ko" },
478 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KOREAN_JOHAB_KOREA
, "ko" },
479 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DUTCH_NETHERLANDS
, "nl" },
480 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DUTCH_BELGIUM
, "nl" },
481 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL
, "no" },
482 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK
, "nn" },
483 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_POLISH_POLAND
, "pl" },
484 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PORTUGUESE_BRAZIL
, "pt" },
485 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PORTUGUESE_PORTUGAL
, "pt" },
486 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND
,"rm" },
487 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ROMANIAN_ROMANIA
, "ro" },
488 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MOLDAVIAN_MOLDAVIA
, "mo" },
489 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_RUSSIAN_RUSSIA
, "ru" },
490 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_RUSSIAN_MOLDAVIA
, "ru" },
491 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CROATIAN_CROATIA
, "hr" },
492 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SERBIAN_SERBIA_LATIN
, "sr" },
493 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC
, "sr" },
494 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SLOVAK_SLOVAKIA
, "sk" },
495 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ALBANIAN_ALBANIA
, "sq" },
496 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SWEDISH_SWEDEN
, "sv" },
497 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SWEDISH_FINLAND
, "sv" },
498 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_THAI_THAILAND
, "th" },
499 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TURKISH_TURKEY
, "tr" },
500 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_URDU_PAKISTAN
, "ur" },
501 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_INDONESIAN_INDONESIA
, "id" },
502 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_UKRAINIAN_UKRAINE
, "uk" },
503 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BELARUSIAN_BELARUS
, "be" },
504 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SLOVENE_SLOVENIA
, "sl" },
505 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ESTONIAN_ESTONIA
, "et" },
506 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LATVIAN_LATVIA
, "lv" },
507 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LITHUANIAN_LITHUANIA
, "lt" },
508 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA
,"lt" },
510 #ifdef TT_MS_LANGID_MAORI_NEW_ZELAND
511 /* this seems to be an error that have been dropped */
512 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MAORI_NEW_ZEALAND
, "mi" },
515 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FARSI_IRAN
, "fa" },
516 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_VIETNAMESE_VIET_NAM
, "vi" },
517 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARMENIAN_ARMENIA
, "hy" },
518 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN
, "az" },
519 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC
, "az" },
520 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BASQUE_SPAIN
, "eu" },
521 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SORBIAN_GERMANY
, "wen" },
522 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MACEDONIAN_MACEDONIA
, "mk" },
523 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SUTU_SOUTH_AFRICA
, "st" },
524 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TSONGA_SOUTH_AFRICA
, "ts" },
525 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TSWANA_SOUTH_AFRICA
, "tn" },
526 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_VENDA_SOUTH_AFRICA
, "ven" },
527 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_XHOSA_SOUTH_AFRICA
, "xh" },
528 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ZULU_SOUTH_AFRICA
, "zu" },
529 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA
, "af" },
530 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GEORGIAN_GEORGIA
, "ka" },
531 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS
, "fo" },
532 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HINDI_INDIA
, "hi" },
533 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALTESE_MALTA
, "mt" },
534 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SAAMI_LAPONIA
, "se" },
536 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM
,"gd" },
537 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_IRISH_GAELIC_IRELAND
, "ga" },
539 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALAY_MALAYSIA
, "ms" },
540 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM
, "ms" },
541 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KAZAK_KAZAKSTAN
, "kk" },
542 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SWAHILI_KENYA
, "sw" },
543 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN
, "uz" },
544 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC
, "uz" },
545 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TATAR_TATARSTAN
, "tt" },
546 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BENGALI_INDIA
, "bn" },
547 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PUNJABI_INDIA
, "pa" },
548 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GUJARATI_INDIA
, "gu" },
549 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ORIYA_INDIA
, "or" },
550 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAMIL_INDIA
, "ta" },
551 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TELUGU_INDIA
, "te" },
552 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KANNADA_INDIA
, "kn" },
553 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALAYALAM_INDIA
, "ml" },
554 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ASSAMESE_INDIA
, "as" },
555 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MARATHI_INDIA
, "mr" },
556 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SANSKRIT_INDIA
, "sa" },
557 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KONKANI_INDIA
, "kok" },
559 /* new as of 2001-01-01 */
560 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_GENERAL
, "ar" },
561 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_GENERAL
, "zh" },
562 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_GENERAL
, "en" },
563 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_WEST_INDIES
, "fr" },
564 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_REUNION
, "fr" },
565 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_CONGO
, "fr" },
567 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_SENEGAL
, "fr" },
568 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_CAMEROON
, "fr" },
569 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_COTE_D_IVOIRE
, "fr" },
570 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_MALI
, "fr" },
571 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA
,"bs" },
572 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_URDU_INDIA
, "ur" },
573 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAJIK_TAJIKISTAN
, "tg" },
574 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_YIDDISH_GERMANY
, "yi" },
575 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN
, "ky" },
577 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TURKMEN_TURKMENISTAN
, "tk" },
578 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MONGOLIAN_MONGOLIA
, "mn" },
580 /* the following seems to be inconsistent;
581 here is the current "official" way: */
582 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIBETAN_BHUTAN
, "bo" },
583 /* and here is what is used by Passport SDK */
584 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIBETAN_CHINA
, "bo" },
585 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DZONGHKA_BHUTAN
, "dz" },
586 /* end of inconsistency */
588 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_WELSH_WALES
, "cy" },
589 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KHMER_CAMBODIA
, "km" },
590 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LAO_LAOS
, "lo" },
591 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BURMESE_MYANMAR
, "my" },
592 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GALICIAN_SPAIN
, "gl" },
593 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MANIPURI_INDIA
, "mni" },
594 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SINDHI_INDIA
, "sd" },
595 /* the following one is only encountered in Microsoft RTF specification */
596 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KASHMIRI_PAKISTAN
, "ks" },
597 /* the following one is not in the Passport list, looks like an omission */
598 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KASHMIRI_INDIA
, "ks" },
599 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NEPALI_NEPAL
, "ne" },
600 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NEPALI_INDIA
, "ne" },
601 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRISIAN_NETHERLANDS
, "fy" },
603 /* new as of 2001-03-01 (from Office Xp) */
604 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_HONG_KONG
, "en" },
605 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_INDIA
, "en" },
606 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_MALAYSIA
, "en" },
607 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_SINGAPORE
, "en" },
608 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SYRIAC_SYRIA
, "syr" },
609 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SINHALESE_SRI_LANKA
, "si" },
610 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHEROKEE_UNITED_STATES
, "chr" },
611 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_INUKTITUT_CANADA
, "iu" },
612 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AMHARIC_ETHIOPIA
, "am" },
614 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAMAZIGHT_MOROCCO
},
615 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN
},
617 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PASHTO_AFGHANISTAN
, "ps" },
618 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FILIPINO_PHILIPPINES
, "phi" },
619 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DHIVEHI_MALDIVES
, "div" },
621 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_OROMO_ETHIOPIA
, "om" },
622 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIGRIGNA_ETHIOPIA
, "ti" },
623 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIGRIGNA_ERYTHREA
, "ti" },
625 /* New additions from Windows Xp/Passport SDK 2001-11-10. */
627 /* don't ask what this one means... It is commented out currently. */
629 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GREEK_GREECE2
},
632 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_UNITED_STATES
, "es" },
633 /* The following two IDs blatantly violate MS specs by using a */
634 /* sublanguage >,. */
635 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_LATIN_AMERICA
, "es" },
636 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_NORTH_AFRICA
, "fr" },
638 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_MOROCCO
, "fr" },
639 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_HAITI
, "fr" },
640 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BENGALI_BANGLADESH
, "bn" },
641 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN
, "ar" },
642 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN
,"mn" },
644 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_EDO_NIGERIA
},
645 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FULFULDE_NIGERIA
},
646 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_IBIBIO_NIGERIA
},
648 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HAUSA_NIGERIA
, "ha" },
649 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_YORUBA_NIGERIA
, "yo" },
650 /* language codes from, to, are (still) unknown. */
651 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_IGBO_NIGERIA
, "ibo" },
652 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KANURI_NIGERIA
, "kau" },
653 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GUARANI_PARAGUAY
, "gn" },
654 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HAWAIIAN_UNITED_STATES
, "haw" },
655 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LATIN
, "la" },
656 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SOMALI_SOMALIA
, "so" },
658 /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */
659 /* not written (but OTOH the peculiar writing system is worth */
661 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_YI_CHINA
},
663 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES
,"pap" },
666 #define NUM_FC_FT_LANGUAGE (int) (sizeof (fcFtLanguage) / sizeof (fcFtLanguage[0]))
669 static const FT_UShort platform_order
[] = {
670 TT_PLATFORM_MICROSOFT
,
671 TT_PLATFORM_APPLE_UNICODE
,
672 TT_PLATFORM_MACINTOSH
,
674 #define NUM_PLATFORM_ORDER (sizeof (platform_order) / sizeof (platform_order[0]))
676 static const FT_UShort nameid_order
[] = {
677 #ifdef TT_NAME_ID_WWS_FAMILY
678 TT_NAME_ID_WWS_FAMILY
,
680 TT_NAME_ID_PREFERRED_FAMILY
,
681 TT_NAME_ID_FONT_FAMILY
,
682 TT_NAME_ID_MAC_FULL_NAME
,
683 TT_NAME_ID_FULL_NAME
,
684 #ifdef TT_NAME_ID_WWS_SUBFAMILY
685 TT_NAME_ID_WWS_SUBFAMILY
,
687 TT_NAME_ID_PREFERRED_SUBFAMILY
,
688 TT_NAME_ID_FONT_SUBFAMILY
,
689 TT_NAME_ID_TRADEMARK
,
690 TT_NAME_ID_MANUFACTURER
,
693 #define NUM_NAMEID_ORDER (sizeof (nameid_order) / sizeof (nameid_order[0]))
696 unsigned short language_id
;
700 static const FcMacRomanFake fcMacRomanFake
[] = {
701 { TT_MS_LANGID_JAPANESE_JAPAN
, "SJIS-WIN" },
702 { TT_MS_LANGID_ENGLISH_UNITED_STATES
, "ASCII" },
705 #define NUM_FC_MAC_ROMAN_FAKE (int) (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0]))
708 typedef struct _FcStringConst
{
713 static int FcStringContainsConst (const FcChar8
*string
, const FcStringConst
*c
, int nc
)
717 for (i
= 0; i
< nc
; i
++)
719 if (c
[i
].name
[0] == '<')
721 if (FcStrContainsWord (string
, c
[i
].name
+ 1))
726 if (FcStrContainsIgnoreBlanksAndCase (string
, c
[i
].name
))
733 typedef FcChar8
*FC8
;
735 static const FcStringConst weightConsts
[] = {
736 { (FC8
) "thin", FC_WEIGHT_THIN
},
737 { (FC8
) "extralight", FC_WEIGHT_EXTRALIGHT
},
738 { (FC8
) "ultralight", FC_WEIGHT_ULTRALIGHT
},
739 { (FC8
) "light", FC_WEIGHT_LIGHT
},
740 { (FC8
) "book", FC_WEIGHT_BOOK
},
741 { (FC8
) "regular", FC_WEIGHT_REGULAR
},
742 { (FC8
) "normal", FC_WEIGHT_NORMAL
},
743 { (FC8
) "medium", FC_WEIGHT_MEDIUM
},
744 { (FC8
) "demibold", FC_WEIGHT_DEMIBOLD
},
745 { (FC8
) "demi", FC_WEIGHT_DEMIBOLD
},
746 { (FC8
) "semibold", FC_WEIGHT_SEMIBOLD
},
747 { (FC8
) "extrabold", FC_WEIGHT_EXTRABOLD
},
748 { (FC8
) "superbold", FC_WEIGHT_EXTRABOLD
},
749 { (FC8
) "ultrabold", FC_WEIGHT_ULTRABOLD
},
750 { (FC8
) "bold", FC_WEIGHT_BOLD
},
751 { (FC8
) "ultrablack", FC_WEIGHT_ULTRABLACK
},
752 { (FC8
) "superblack", FC_WEIGHT_EXTRABLACK
},
753 { (FC8
) "extrablack", FC_WEIGHT_EXTRABLACK
},
754 { (FC8
) "<ultra", FC_WEIGHT_ULTRABOLD
}, /* only if a word */
755 { (FC8
) "black", FC_WEIGHT_BLACK
},
756 { (FC8
) "heavy", FC_WEIGHT_HEAVY
},
759 #define NUM_WEIGHT_CONSTS (int) (sizeof (weightConsts) / sizeof (weightConsts[0]))
761 #define FcIsWeight(s) FcStringIsConst(s,weightConsts,NUM_WEIGHT_CONSTS)
762 #define FcContainsWeight(s) FcStringContainsConst (s,weightConsts,NUM_WEIGHT_CONSTS)
764 static const FcStringConst widthConsts
[] = {
765 { (FC8
) "ultracondensed", FC_WIDTH_ULTRACONDENSED
},
766 { (FC8
) "extracondensed", FC_WIDTH_EXTRACONDENSED
},
767 { (FC8
) "semicondensed", FC_WIDTH_SEMICONDENSED
},
768 { (FC8
) "condensed", FC_WIDTH_CONDENSED
}, /* must be after *condensed */
769 { (FC8
) "normal", FC_WIDTH_NORMAL
},
770 { (FC8
) "semiexpanded", FC_WIDTH_SEMIEXPANDED
},
771 { (FC8
) "extraexpanded", FC_WIDTH_EXTRAEXPANDED
},
772 { (FC8
) "ultraexpanded", FC_WIDTH_ULTRAEXPANDED
},
773 { (FC8
) "expanded", FC_WIDTH_EXPANDED
}, /* must be after *expanded */
774 { (FC8
) "extended", FC_WIDTH_EXPANDED
},
777 #define NUM_WIDTH_CONSTS (int) (sizeof (widthConsts) / sizeof (widthConsts[0]))
779 #define FcIsWidth(s) FcStringIsConst(s,widthConsts,NUM_WIDTH_CONSTS)
780 #define FcContainsWidth(s) FcStringContainsConst (s,widthConsts,NUM_WIDTH_CONSTS)
782 static const FcStringConst slantConsts
[] = {
783 { (FC8
) "italic", FC_SLANT_ITALIC
},
784 { (FC8
) "kursiv", FC_SLANT_ITALIC
},
785 { (FC8
) "oblique", FC_SLANT_OBLIQUE
},
788 #define NUM_SLANT_CONSTS (int) (sizeof (slantConsts) / sizeof (slantConsts[0]))
790 #define FcIsSlant(s) FcStringIsConst(s,slantConsts,NUM_SLANT_CONSTS)
791 #define FcContainsSlant(s) FcStringContainsConst (s,slantConsts,NUM_SLANT_CONSTS)
794 struct fontpattern
*fcPatternAlloc(void)
796 struct fontpattern
*pat
= calloc(1, sizeof(struct fontpattern
));
800 NewList(&pat
->entries
);
806 void fcPatternDestroy(struct fontpattern
*pat
)
810 struct patternentry
*pe
, *pen
;
812 ITERATELISTSAFE(pe
, pen
, &pat
->entries
)
814 if (pe
->type
== FC_ETYPE_STRING
)
816 if (pe
->value
.s
!= NULL
)
831 struct fontpattern
*fcQueryFace(const FT_Face face
, char *fname
, int id
)
837 static const FcCharEnt AppleRomanEnt
[] = {
838 { 0x0020, 0x20 }, /* SPACE */
839 { 0x0021, 0x21 }, /* EXCLAMATION MARK */
840 { 0x0022, 0x22 }, /* QUOTATION MARK */
841 { 0x0023, 0x23 }, /* NUMBER SIGN */
842 { 0x0024, 0x24 }, /* DOLLAR SIGN */
843 { 0x0025, 0x25 }, /* PERCENT SIGN */
844 { 0x0026, 0x26 }, /* AMPERSAND */
845 { 0x0027, 0x27 }, /* APOSTROPHE */
846 { 0x0028, 0x28 }, /* LEFT PARENTHESIS */
847 { 0x0029, 0x29 }, /* RIGHT PARENTHESIS */
848 { 0x002A, 0x2A }, /* ASTERISK */
849 { 0x002B, 0x2B }, /* PLUS SIGN */
850 { 0x002C, 0x2C }, /* COMMA */
851 { 0x002D, 0x2D }, /* HYPHEN-MINUS */
852 { 0x002E, 0x2E }, /* FULL STOP */
853 { 0x002F, 0x2F }, /* SOLIDUS */
854 { 0x0030, 0x30 }, /* DIGIT ZERO */
855 { 0x0031, 0x31 }, /* DIGIT ONE */
856 { 0x0032, 0x32 }, /* DIGIT TWO */
857 { 0x0033, 0x33 }, /* DIGIT THREE */
858 { 0x0034, 0x34 }, /* DIGIT FOUR */
859 { 0x0035, 0x35 }, /* DIGIT FIVE */
860 { 0x0036, 0x36 }, /* DIGIT SIX */
861 { 0x0037, 0x37 }, /* DIGIT SEVEN */
862 { 0x0038, 0x38 }, /* DIGIT EIGHT */
863 { 0x0039, 0x39 }, /* DIGIT NINE */
864 { 0x003A, 0x3A }, /* COLON */
865 { 0x003B, 0x3B }, /* SEMICOLON */
866 { 0x003C, 0x3C }, /* LESS-THAN SIGN */
867 { 0x003D, 0x3D }, /* EQUALS SIGN */
868 { 0x003E, 0x3E }, /* GREATER-THAN SIGN */
869 { 0x003F, 0x3F }, /* QUESTION MARK */
870 { 0x0040, 0x40 }, /* COMMERCIAL AT */
871 { 0x0041, 0x41 }, /* LATIN CAPITAL LETTER A */
872 { 0x0042, 0x42 }, /* LATIN CAPITAL LETTER B */
873 { 0x0043, 0x43 }, /* LATIN CAPITAL LETTER C */
874 { 0x0044, 0x44 }, /* LATIN CAPITAL LETTER D */
875 { 0x0045, 0x45 }, /* LATIN CAPITAL LETTER E */
876 { 0x0046, 0x46 }, /* LATIN CAPITAL LETTER F */
877 { 0x0047, 0x47 }, /* LATIN CAPITAL LETTER G */
878 { 0x0048, 0x48 }, /* LATIN CAPITAL LETTER H */
879 { 0x0049, 0x49 }, /* LATIN CAPITAL LETTER I */
880 { 0x004A, 0x4A }, /* LATIN CAPITAL LETTER J */
881 { 0x004B, 0x4B }, /* LATIN CAPITAL LETTER K */
882 { 0x004C, 0x4C }, /* LATIN CAPITAL LETTER L */
883 { 0x004D, 0x4D }, /* LATIN CAPITAL LETTER M */
884 { 0x004E, 0x4E }, /* LATIN CAPITAL LETTER N */
885 { 0x004F, 0x4F }, /* LATIN CAPITAL LETTER O */
886 { 0x0050, 0x50 }, /* LATIN CAPITAL LETTER P */
887 { 0x0051, 0x51 }, /* LATIN CAPITAL LETTER Q */
888 { 0x0052, 0x52 }, /* LATIN CAPITAL LETTER R */
889 { 0x0053, 0x53 }, /* LATIN CAPITAL LETTER S */
890 { 0x0054, 0x54 }, /* LATIN CAPITAL LETTER T */
891 { 0x0055, 0x55 }, /* LATIN CAPITAL LETTER U */
892 { 0x0056, 0x56 }, /* LATIN CAPITAL LETTER V */
893 { 0x0057, 0x57 }, /* LATIN CAPITAL LETTER W */
894 { 0x0058, 0x58 }, /* LATIN CAPITAL LETTER X */
895 { 0x0059, 0x59 }, /* LATIN CAPITAL LETTER Y */
896 { 0x005A, 0x5A }, /* LATIN CAPITAL LETTER Z */
897 { 0x005B, 0x5B }, /* LEFT SQUARE BRACKET */
898 { 0x005C, 0x5C }, /* REVERSE SOLIDUS */
899 { 0x005D, 0x5D }, /* RIGHT SQUARE BRACKET */
900 { 0x005E, 0x5E }, /* CIRCUMFLEX ACCENT */
901 { 0x005F, 0x5F }, /* LOW LINE */
902 { 0x0060, 0x60 }, /* GRAVE ACCENT */
903 { 0x0061, 0x61 }, /* LATIN SMALL LETTER A */
904 { 0x0062, 0x62 }, /* LATIN SMALL LETTER B */
905 { 0x0063, 0x63 }, /* LATIN SMALL LETTER C */
906 { 0x0064, 0x64 }, /* LATIN SMALL LETTER D */
907 { 0x0065, 0x65 }, /* LATIN SMALL LETTER E */
908 { 0x0066, 0x66 }, /* LATIN SMALL LETTER F */
909 { 0x0067, 0x67 }, /* LATIN SMALL LETTER G */
910 { 0x0068, 0x68 }, /* LATIN SMALL LETTER H */
911 { 0x0069, 0x69 }, /* LATIN SMALL LETTER I */
912 { 0x006A, 0x6A }, /* LATIN SMALL LETTER J */
913 { 0x006B, 0x6B }, /* LATIN SMALL LETTER K */
914 { 0x006C, 0x6C }, /* LATIN SMALL LETTER L */
915 { 0x006D, 0x6D }, /* LATIN SMALL LETTER M */
916 { 0x006E, 0x6E }, /* LATIN SMALL LETTER N */
917 { 0x006F, 0x6F }, /* LATIN SMALL LETTER O */
918 { 0x0070, 0x70 }, /* LATIN SMALL LETTER P */
919 { 0x0071, 0x71 }, /* LATIN SMALL LETTER Q */
920 { 0x0072, 0x72 }, /* LATIN SMALL LETTER R */
921 { 0x0073, 0x73 }, /* LATIN SMALL LETTER S */
922 { 0x0074, 0x74 }, /* LATIN SMALL LETTER T */
923 { 0x0075, 0x75 }, /* LATIN SMALL LETTER U */
924 { 0x0076, 0x76 }, /* LATIN SMALL LETTER V */
925 { 0x0077, 0x77 }, /* LATIN SMALL LETTER W */
926 { 0x0078, 0x78 }, /* LATIN SMALL LETTER X */
927 { 0x0079, 0x79 }, /* LATIN SMALL LETTER Y */
928 { 0x007A, 0x7A }, /* LATIN SMALL LETTER Z */
929 { 0x007B, 0x7B }, /* LEFT CURLY BRACKET */
930 { 0x007C, 0x7C }, /* VERTICAL LINE */
931 { 0x007D, 0x7D }, /* RIGHT CURLY BRACKET */
932 { 0x007E, 0x7E }, /* TILDE */
933 { 0x00A0, 0xCA }, /* NO-BREAK SPACE */
934 { 0x00A1, 0xC1 }, /* INVERTED EXCLAMATION MARK */
935 { 0x00A2, 0xA2 }, /* CENT SIGN */
936 { 0x00A3, 0xA3 }, /* POUND SIGN */
937 { 0x00A5, 0xB4 }, /* YEN SIGN */
938 { 0x00A7, 0xA4 }, /* SECTION SIGN */
939 { 0x00A8, 0xAC }, /* DIAERESIS */
940 { 0x00A9, 0xA9 }, /* COPYRIGHT SIGN */
941 { 0x00AA, 0xBB }, /* FEMININE ORDINAL INDICATOR */
942 { 0x00AB, 0xC7 }, /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
943 { 0x00AC, 0xC2 }, /* NOT SIGN */
944 { 0x00AE, 0xA8 }, /* REGISTERED SIGN */
945 { 0x00AF, 0xF8 }, /* MACRON */
946 { 0x00B0, 0xA1 }, /* DEGREE SIGN */
947 { 0x00B1, 0xB1 }, /* PLUS-MINUS SIGN */
948 { 0x00B4, 0xAB }, /* ACUTE ACCENT */
949 { 0x00B5, 0xB5 }, /* MICRO SIGN */
950 { 0x00B6, 0xA6 }, /* PILCROW SIGN */
951 { 0x00B7, 0xE1 }, /* MIDDLE DOT */
952 { 0x00B8, 0xFC }, /* CEDILLA */
953 { 0x00BA, 0xBC }, /* MASCULINE ORDINAL INDICATOR */
954 { 0x00BB, 0xC8 }, /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
955 { 0x00BF, 0xC0 }, /* INVERTED QUESTION MARK */
956 { 0x00C0, 0xCB }, /* LATIN CAPITAL LETTER A WITH GRAVE */
957 { 0x00C1, 0xE7 }, /* LATIN CAPITAL LETTER A WITH ACUTE */
958 { 0x00C2, 0xE5 }, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
959 { 0x00C3, 0xCC }, /* LATIN CAPITAL LETTER A WITH TILDE */
960 { 0x00C4, 0x80 }, /* LATIN CAPITAL LETTER A WITH DIAERESIS */
961 { 0x00C5, 0x81 }, /* LATIN CAPITAL LETTER A WITH RING ABOVE */
962 { 0x00C6, 0xAE }, /* LATIN CAPITAL LETTER AE */
963 { 0x00C7, 0x82 }, /* LATIN CAPITAL LETTER C WITH CEDILLA */
964 { 0x00C8, 0xE9 }, /* LATIN CAPITAL LETTER E WITH GRAVE */
965 { 0x00C9, 0x83 }, /* LATIN CAPITAL LETTER E WITH ACUTE */
966 { 0x00CA, 0xE6 }, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
967 { 0x00CB, 0xE8 }, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
968 { 0x00CC, 0xED }, /* LATIN CAPITAL LETTER I WITH GRAVE */
969 { 0x00CD, 0xEA }, /* LATIN CAPITAL LETTER I WITH ACUTE */
970 { 0x00CE, 0xEB }, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
971 { 0x00CF, 0xEC }, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
972 { 0x00D1, 0x84 }, /* LATIN CAPITAL LETTER N WITH TILDE */
973 { 0x00D2, 0xF1 }, /* LATIN CAPITAL LETTER O WITH GRAVE */
974 { 0x00D3, 0xEE }, /* LATIN CAPITAL LETTER O WITH ACUTE */
975 { 0x00D4, 0xEF }, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
976 { 0x00D5, 0xCD }, /* LATIN CAPITAL LETTER O WITH TILDE */
977 { 0x00D6, 0x85 }, /* LATIN CAPITAL LETTER O WITH DIAERESIS */
978 { 0x00D8, 0xAF }, /* LATIN CAPITAL LETTER O WITH STROKE */
979 { 0x00D9, 0xF4 }, /* LATIN CAPITAL LETTER U WITH GRAVE */
980 { 0x00DA, 0xF2 }, /* LATIN CAPITAL LETTER U WITH ACUTE */
981 { 0x00DB, 0xF3 }, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
982 { 0x00DC, 0x86 }, /* LATIN CAPITAL LETTER U WITH DIAERESIS */
983 { 0x00DF, 0xA7 }, /* LATIN SMALL LETTER SHARP S */
984 { 0x00E0, 0x88 }, /* LATIN SMALL LETTER A WITH GRAVE */
985 { 0x00E1, 0x87 }, /* LATIN SMALL LETTER A WITH ACUTE */
986 { 0x00E2, 0x89 }, /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
987 { 0x00E3, 0x8B }, /* LATIN SMALL LETTER A WITH TILDE */
988 { 0x00E4, 0x8A }, /* LATIN SMALL LETTER A WITH DIAERESIS */
989 { 0x00E5, 0x8C }, /* LATIN SMALL LETTER A WITH RING ABOVE */
990 { 0x00E6, 0xBE }, /* LATIN SMALL LETTER AE */
991 { 0x00E7, 0x8D }, /* LATIN SMALL LETTER C WITH CEDILLA */
992 { 0x00E8, 0x8F }, /* LATIN SMALL LETTER E WITH GRAVE */
993 { 0x00E9, 0x8E }, /* LATIN SMALL LETTER E WITH ACUTE */
994 { 0x00EA, 0x90 }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
995 { 0x00EB, 0x91 }, /* LATIN SMALL LETTER E WITH DIAERESIS */
996 { 0x00EC, 0x93 }, /* LATIN SMALL LETTER I WITH GRAVE */
997 { 0x00ED, 0x92 }, /* LATIN SMALL LETTER I WITH ACUTE */
998 { 0x00EE, 0x94 }, /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
999 { 0x00EF, 0x95 }, /* LATIN SMALL LETTER I WITH DIAERESIS */
1000 { 0x00F1, 0x96 }, /* LATIN SMALL LETTER N WITH TILDE */
1001 { 0x00F2, 0x98 }, /* LATIN SMALL LETTER O WITH GRAVE */
1002 { 0x00F3, 0x97 }, /* LATIN SMALL LETTER O WITH ACUTE */
1003 { 0x00F4, 0x99 }, /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
1004 { 0x00F5, 0x9B }, /* LATIN SMALL LETTER O WITH TILDE */
1005 { 0x00F6, 0x9A }, /* LATIN SMALL LETTER O WITH DIAERESIS */
1006 { 0x00F7, 0xD6 }, /* DIVISION SIGN */
1007 { 0x00F8, 0xBF }, /* LATIN SMALL LETTER O WITH STROKE */
1008 { 0x00F9, 0x9D }, /* LATIN SMALL LETTER U WITH GRAVE */
1009 { 0x00FA, 0x9C }, /* LATIN SMALL LETTER U WITH ACUTE */
1010 { 0x00FB, 0x9E }, /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
1011 { 0x00FC, 0x9F }, /* LATIN SMALL LETTER U WITH DIAERESIS */
1012 { 0x00FF, 0xD8 }, /* LATIN SMALL LETTER Y WITH DIAERESIS */
1013 { 0x0131, 0xF5 }, /* LATIN SMALL LETTER DOTLESS I */
1014 { 0x0152, 0xCE }, /* LATIN CAPITAL LIGATURE OE */
1015 { 0x0153, 0xCF }, /* LATIN SMALL LIGATURE OE */
1016 { 0x0178, 0xD9 }, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
1017 { 0x0192, 0xC4 }, /* LATIN SMALL LETTER F WITH HOOK */
1018 { 0x02C6, 0xF6 }, /* MODIFIER LETTER CIRCUMFLEX ACCENT */
1019 { 0x02C7, 0xFF }, /* CARON */
1020 { 0x02D8, 0xF9 }, /* BREVE */
1021 { 0x02D9, 0xFA }, /* DOT ABOVE */
1022 { 0x02DA, 0xFB }, /* RING ABOVE */
1023 { 0x02DB, 0xFE }, /* OGONEK */
1024 { 0x02DC, 0xF7 }, /* SMALL TILDE */
1025 { 0x02DD, 0xFD }, /* DOUBLE ACUTE ACCENT */
1026 { 0x03A9, 0xBD }, /* GREEK CAPITAL LETTER OMEGA */
1027 { 0x03C0, 0xB9 }, /* GREEK SMALL LETTER PI */
1028 { 0x2013, 0xD0 }, /* EN DASH */
1029 { 0x2014, 0xD1 }, /* EM DASH */
1030 { 0x2018, 0xD4 }, /* LEFT SINGLE QUOTATION MARK */
1031 { 0x2019, 0xD5 }, /* RIGHT SINGLE QUOTATION MARK */
1032 { 0x201A, 0xE2 }, /* SINGLE LOW-9 QUOTATION MARK */
1033 { 0x201C, 0xD2 }, /* LEFT DOUBLE QUOTATION MARK */
1034 { 0x201D, 0xD3 }, /* RIGHT DOUBLE QUOTATION MARK */
1035 { 0x201E, 0xE3 }, /* DOUBLE LOW-9 QUOTATION MARK */
1036 { 0x2020, 0xA0 }, /* DAGGER */
1037 { 0x2021, 0xE0 }, /* DOUBLE DAGGER */
1038 { 0x2022, 0xA5 }, /* BULLET */
1039 { 0x2026, 0xC9 }, /* HORIZONTAL ELLIPSIS */
1040 { 0x2030, 0xE4 }, /* PER MILLE SIGN */
1041 { 0x2039, 0xDC }, /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */
1042 { 0x203A, 0xDD }, /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */
1043 { 0x2044, 0xDA }, /* FRACTION SLASH */
1044 { 0x20AC, 0xDB }, /* EURO SIGN */
1045 { 0x2122, 0xAA }, /* TRADE MARK SIGN */
1046 { 0x2202, 0xB6 }, /* PARTIAL DIFFERENTIAL */
1047 { 0x2206, 0xC6 }, /* INCREMENT */
1048 { 0x220F, 0xB8 }, /* N-ARY PRODUCT */
1049 { 0x2211, 0xB7 }, /* N-ARY SUMMATION */
1050 { 0x221A, 0xC3 }, /* SQUARE ROOT */
1051 { 0x221E, 0xB0 }, /* INFINITY */
1052 { 0x222B, 0xBA }, /* INTEGRAL */
1053 { 0x2248, 0xC5 }, /* ALMOST EQUAL TO */
1054 { 0x2260, 0xAD }, /* NOT EQUAL TO */
1055 { 0x2264, 0xB2 }, /* LESS-THAN OR EQUAL TO */
1056 { 0x2265, 0xB3 }, /* GREATER-THAN OR EQUAL TO */
1057 { 0x25CA, 0xD7 }, /* LOZENGE */
1058 { 0xF8FF, 0xF0 }, /* Apple logo */
1059 { 0xFB01, 0xDE }, /* LATIN SMALL LIGATURE FI */
1060 { 0xFB02, 0xDF }, /* LATIN SMALL LIGATURE FL */
1063 static const FcCharMap AppleRoman
= {
1065 sizeof (AppleRomanEnt
) / sizeof (AppleRomanEnt
[0])
1070 static const FcCharEnt AdobeSymbolEnt
[] = {
1071 { 0x0020, 0x20 }, /* SPACE # space */
1072 { 0x0021, 0x21 }, /* EXCLAMATION MARK # exclam */
1073 { 0x0023, 0x23 }, /* NUMBER SIGN # numbersign */
1074 { 0x0025, 0x25 }, /* PERCENT SIGN # percent */
1075 { 0x0026, 0x26 }, /* AMPERSAND # ampersand */
1076 { 0x0028, 0x28 }, /* LEFT PARENTHESIS # parenleft */
1077 { 0x0029, 0x29 }, /* RIGHT PARENTHESIS # parenright */
1078 { 0x002B, 0x2B }, /* PLUS SIGN # plus */
1079 { 0x002C, 0x2C }, /* COMMA # comma */
1080 { 0x002E, 0x2E }, /* FULL STOP # period */
1081 { 0x002F, 0x2F }, /* SOLIDUS # slash */
1082 { 0x0030, 0x30 }, /* DIGIT ZERO # zero */
1083 { 0x0031, 0x31 }, /* DIGIT ONE # one */
1084 { 0x0032, 0x32 }, /* DIGIT TWO # two */
1085 { 0x0033, 0x33 }, /* DIGIT THREE # three */
1086 { 0x0034, 0x34 }, /* DIGIT FOUR # four */
1087 { 0x0035, 0x35 }, /* DIGIT FIVE # five */
1088 { 0x0036, 0x36 }, /* DIGIT SIX # six */
1089 { 0x0037, 0x37 }, /* DIGIT SEVEN # seven */
1090 { 0x0038, 0x38 }, /* DIGIT EIGHT # eight */
1091 { 0x0039, 0x39 }, /* DIGIT NINE # nine */
1092 { 0x003A, 0x3A }, /* COLON # colon */
1093 { 0x003B, 0x3B }, /* SEMICOLON # semicolon */
1094 { 0x003C, 0x3C }, /* LESS-THAN SIGN # less */
1095 { 0x003D, 0x3D }, /* EQUALS SIGN # equal */
1096 { 0x003E, 0x3E }, /* GREATER-THAN SIGN # greater */
1097 { 0x003F, 0x3F }, /* QUESTION MARK # question */
1098 { 0x005B, 0x5B }, /* LEFT SQUARE BRACKET # bracketleft */
1099 { 0x005D, 0x5D }, /* RIGHT SQUARE BRACKET # bracketright */
1100 { 0x005F, 0x5F }, /* LOW LINE # underscore */
1101 { 0x007B, 0x7B }, /* LEFT CURLY BRACKET # braceleft */
1102 { 0x007C, 0x7C }, /* VERTICAL LINE # bar */
1103 { 0x007D, 0x7D }, /* RIGHT CURLY BRACKET # braceright */
1104 { 0x00A0, 0x20 }, /* NO-BREAK SPACE # space */
1105 { 0x00AC, 0xD8 }, /* NOT SIGN # logicalnot */
1106 { 0x00B0, 0xB0 }, /* DEGREE SIGN # degree */
1107 { 0x00B1, 0xB1 }, /* PLUS-MINUS SIGN # plusminus */
1108 { 0x00B5, 0x6D }, /* MICRO SIGN # mu */
1109 { 0x00D7, 0xB4 }, /* MULTIPLICATION SIGN # multiply */
1110 { 0x00F7, 0xB8 }, /* DIVISION SIGN # divide */
1111 { 0x0192, 0xA6 }, /* LATIN SMALL LETTER F WITH HOOK # florin */
1112 { 0x0391, 0x41 }, /* GREEK CAPITAL LETTER ALPHA # Alpha */
1113 { 0x0392, 0x42 }, /* GREEK CAPITAL LETTER BETA # Beta */
1114 { 0x0393, 0x47 }, /* GREEK CAPITAL LETTER GAMMA # Gamma */
1115 { 0x0394, 0x44 }, /* GREEK CAPITAL LETTER DELTA # Delta */
1116 { 0x0395, 0x45 }, /* GREEK CAPITAL LETTER EPSILON # Epsilon */
1117 { 0x0396, 0x5A }, /* GREEK CAPITAL LETTER ZETA # Zeta */
1118 { 0x0397, 0x48 }, /* GREEK CAPITAL LETTER ETA # Eta */
1119 { 0x0398, 0x51 }, /* GREEK CAPITAL LETTER THETA # Theta */
1120 { 0x0399, 0x49 }, /* GREEK CAPITAL LETTER IOTA # Iota */
1121 { 0x039A, 0x4B }, /* GREEK CAPITAL LETTER KAPPA # Kappa */
1122 { 0x039B, 0x4C }, /* GREEK CAPITAL LETTER LAMDA # Lambda */
1123 { 0x039C, 0x4D }, /* GREEK CAPITAL LETTER MU # Mu */
1124 { 0x039D, 0x4E }, /* GREEK CAPITAL LETTER NU # Nu */
1125 { 0x039E, 0x58 }, /* GREEK CAPITAL LETTER XI # Xi */
1126 { 0x039F, 0x4F }, /* GREEK CAPITAL LETTER OMICRON # Omicron */
1127 { 0x03A0, 0x50 }, /* GREEK CAPITAL LETTER PI # Pi */
1128 { 0x03A1, 0x52 }, /* GREEK CAPITAL LETTER RHO # Rho */
1129 { 0x03A3, 0x53 }, /* GREEK CAPITAL LETTER SIGMA # Sigma */
1130 { 0x03A4, 0x54 }, /* GREEK CAPITAL LETTER TAU # Tau */
1131 { 0x03A5, 0x55 }, /* GREEK CAPITAL LETTER UPSILON # Upsilon */
1132 { 0x03A6, 0x46 }, /* GREEK CAPITAL LETTER PHI # Phi */
1133 { 0x03A7, 0x43 }, /* GREEK CAPITAL LETTER CHI # Chi */
1134 { 0x03A8, 0x59 }, /* GREEK CAPITAL LETTER PSI # Psi */
1135 { 0x03A9, 0x57 }, /* GREEK CAPITAL LETTER OMEGA # Omega */
1136 { 0x03B1, 0x61 }, /* GREEK SMALL LETTER ALPHA # alpha */
1137 { 0x03B2, 0x62 }, /* GREEK SMALL LETTER BETA # beta */
1138 { 0x03B3, 0x67 }, /* GREEK SMALL LETTER GAMMA # gamma */
1139 { 0x03B4, 0x64 }, /* GREEK SMALL LETTER DELTA # delta */
1140 { 0x03B5, 0x65 }, /* GREEK SMALL LETTER EPSILON # epsilon */
1141 { 0x03B6, 0x7A }, /* GREEK SMALL LETTER ZETA # zeta */
1142 { 0x03B7, 0x68 }, /* GREEK SMALL LETTER ETA # eta */
1143 { 0x03B8, 0x71 }, /* GREEK SMALL LETTER THETA # theta */
1144 { 0x03B9, 0x69 }, /* GREEK SMALL LETTER IOTA # iota */
1145 { 0x03BA, 0x6B }, /* GREEK SMALL LETTER KAPPA # kappa */
1146 { 0x03BB, 0x6C }, /* GREEK SMALL LETTER LAMDA # lambda */
1147 { 0x03BC, 0x6D }, /* GREEK SMALL LETTER MU # mu */
1148 { 0x03BD, 0x6E }, /* GREEK SMALL LETTER NU # nu */
1149 { 0x03BE, 0x78 }, /* GREEK SMALL LETTER XI # xi */
1150 { 0x03BF, 0x6F }, /* GREEK SMALL LETTER OMICRON # omicron */
1151 { 0x03C0, 0x70 }, /* GREEK SMALL LETTER PI # pi */
1152 { 0x03C1, 0x72 }, /* GREEK SMALL LETTER RHO # rho */
1153 { 0x03C2, 0x56 }, /* GREEK SMALL LETTER FINAL SIGMA # sigma1 */
1154 { 0x03C3, 0x73 }, /* GREEK SMALL LETTER SIGMA # sigma */
1155 { 0x03C4, 0x74 }, /* GREEK SMALL LETTER TAU # tau */
1156 { 0x03C5, 0x75 }, /* GREEK SMALL LETTER UPSILON # upsilon */
1157 { 0x03C6, 0x66 }, /* GREEK SMALL LETTER PHI # phi */
1158 { 0x03C7, 0x63 }, /* GREEK SMALL LETTER CHI # chi */
1159 { 0x03C8, 0x79 }, /* GREEK SMALL LETTER PSI # psi */
1160 { 0x03C9, 0x77 }, /* GREEK SMALL LETTER OMEGA # omega */
1161 { 0x03D1, 0x4A }, /* GREEK THETA SYMBOL # theta1 */
1162 { 0x03D2, 0xA1 }, /* GREEK UPSILON WITH HOOK SYMBOL # Upsilon1 */
1163 { 0x03D5, 0x6A }, /* GREEK PHI SYMBOL # phi1 */
1164 { 0x03D6, 0x76 }, /* GREEK PI SYMBOL # omega1 */
1165 { 0x2022, 0xB7 }, /* BULLET # bullet */
1166 { 0x2026, 0xBC }, /* HORIZONTAL ELLIPSIS # ellipsis */
1167 { 0x2032, 0xA2 }, /* PRIME # minute */
1168 { 0x2033, 0xB2 }, /* DOUBLE PRIME # second */
1169 { 0x2044, 0xA4 }, /* FRACTION SLASH # fraction */
1170 { 0x20AC, 0xA0 }, /* EURO SIGN # Euro */
1171 { 0x2111, 0xC1 }, /* BLACK-LETTER CAPITAL I # Ifraktur */
1172 { 0x2118, 0xC3 }, /* SCRIPT CAPITAL P # weierstrass */
1173 { 0x211C, 0xC2 }, /* BLACK-LETTER CAPITAL R # Rfraktur */
1174 { 0x2126, 0x57 }, /* OHM SIGN # Omega */
1175 { 0x2135, 0xC0 }, /* ALEF SYMBOL # aleph */
1176 { 0x2190, 0xAC }, /* LEFTWARDS ARROW # arrowleft */
1177 { 0x2191, 0xAD }, /* UPWARDS ARROW # arrowup */
1178 { 0x2192, 0xAE }, /* RIGHTWARDS ARROW # arrowright */
1179 { 0x2193, 0xAF }, /* DOWNWARDS ARROW # arrowdown */
1180 { 0x2194, 0xAB }, /* LEFT RIGHT ARROW # arrowboth */
1181 { 0x21B5, 0xBF }, /* DOWNWARDS ARROW WITH CORNER LEFTWARDS # carriagereturn */
1182 { 0x21D0, 0xDC }, /* LEFTWARDS DOUBLE ARROW # arrowdblleft */
1183 { 0x21D1, 0xDD }, /* UPWARDS DOUBLE ARROW # arrowdblup */
1184 { 0x21D2, 0xDE }, /* RIGHTWARDS DOUBLE ARROW # arrowdblright */
1185 { 0x21D3, 0xDF }, /* DOWNWARDS DOUBLE ARROW # arrowdbldown */
1186 { 0x21D4, 0xDB }, /* LEFT RIGHT DOUBLE ARROW # arrowdblboth */
1187 { 0x2200, 0x22 }, /* FOR ALL # universal */
1188 { 0x2202, 0xB6 }, /* PARTIAL DIFFERENTIAL # partialdiff */
1189 { 0x2203, 0x24 }, /* THERE EXISTS # existential */
1190 { 0x2205, 0xC6 }, /* EMPTY SET # emptyset */
1191 { 0x2206, 0x44 }, /* INCREMENT # Delta */
1192 { 0x2207, 0xD1 }, /* NABLA # gradient */
1193 { 0x2208, 0xCE }, /* ELEMENT OF # element */
1194 { 0x2209, 0xCF }, /* NOT AN ELEMENT OF # notelement */
1195 { 0x220B, 0x27 }, /* CONTAINS AS MEMBER # suchthat */
1196 { 0x220F, 0xD5 }, /* N-ARY PRODUCT # product */
1197 { 0x2211, 0xE5 }, /* N-ARY SUMMATION # summation */
1198 { 0x2212, 0x2D }, /* MINUS SIGN # minus */
1199 { 0x2215, 0xA4 }, /* DIVISION SLASH # fraction */
1200 { 0x2217, 0x2A }, /* ASTERISK OPERATOR # asteriskmath */
1201 { 0x221A, 0xD6 }, /* SQUARE ROOT # radical */
1202 { 0x221D, 0xB5 }, /* PROPORTIONAL TO # proportional */
1203 { 0x221E, 0xA5 }, /* INFINITY # infinity */
1204 { 0x2220, 0xD0 }, /* ANGLE # angle */
1205 { 0x2227, 0xD9 }, /* LOGICAL AND # logicaland */
1206 { 0x2228, 0xDA }, /* LOGICAL OR # logicalor */
1207 { 0x2229, 0xC7 }, /* INTERSECTION # intersection */
1208 { 0x222A, 0xC8 }, /* UNION # union */
1209 { 0x222B, 0xF2 }, /* INTEGRAL # integral */
1210 { 0x2234, 0x5C }, /* THEREFORE # therefore */
1211 { 0x223C, 0x7E }, /* TILDE OPERATOR # similar */
1212 { 0x2245, 0x40 }, /* APPROXIMATELY EQUAL TO # congruent */
1213 { 0x2248, 0xBB }, /* ALMOST EQUAL TO # approxequal */
1214 { 0x2260, 0xB9 }, /* NOT EQUAL TO # notequal */
1215 { 0x2261, 0xBA }, /* IDENTICAL TO # equivalence */
1216 { 0x2264, 0xA3 }, /* LESS-THAN OR EQUAL TO # lessequal */
1217 { 0x2265, 0xB3 }, /* GREATER-THAN OR EQUAL TO # greaterequal */
1218 { 0x2282, 0xCC }, /* SUBSET OF # propersubset */
1219 { 0x2283, 0xC9 }, /* SUPERSET OF # propersuperset */
1220 { 0x2284, 0xCB }, /* NOT A SUBSET OF # notsubset */
1221 { 0x2286, 0xCD }, /* SUBSET OF OR EQUAL TO # reflexsubset */
1222 { 0x2287, 0xCA }, /* SUPERSET OF OR EQUAL TO # reflexsuperset */
1223 { 0x2295, 0xC5 }, /* CIRCLED PLUS # circleplus */
1224 { 0x2297, 0xC4 }, /* CIRCLED TIMES # circlemultiply */
1225 { 0x22A5, 0x5E }, /* UP TACK # perpendicular */
1226 { 0x22C5, 0xD7 }, /* DOT OPERATOR # dotmath */
1227 { 0x2320, 0xF3 }, /* TOP HALF INTEGRAL # integraltp */
1228 { 0x2321, 0xF5 }, /* BOTTOM HALF INTEGRAL # integralbt */
1229 { 0x2329, 0xE1 }, /* LEFT-POINTING ANGLE BRACKET # angleleft */
1230 { 0x232A, 0xF1 }, /* RIGHT-POINTING ANGLE BRACKET # angleright */
1231 { 0x25CA, 0xE0 }, /* LOZENGE # lozenge */
1232 { 0x2660, 0xAA }, /* BLACK SPADE SUIT # spade */
1233 { 0x2663, 0xA7 }, /* BLACK CLUB SUIT # club */
1234 { 0x2665, 0xA9 }, /* BLACK HEART SUIT # heart */
1235 { 0x2666, 0xA8 }, /* BLACK DIAMOND SUIT # diamond */
1236 { 0xF6D9, 0xD3 }, /* COPYRIGHT SIGN SERIF # copyrightserif (CUS) */
1237 { 0xF6DA, 0xD2 }, /* REGISTERED SIGN SERIF # registerserif (CUS) */
1238 { 0xF6DB, 0xD4 }, /* TRADE MARK SIGN SERIF # trademarkserif (CUS) */
1239 { 0xF8E5, 0x60 }, /* RADICAL EXTENDER # radicalex (CUS) */
1240 { 0xF8E6, 0xBD }, /* VERTICAL ARROW EXTENDER # arrowvertex (CUS) */
1241 { 0xF8E7, 0xBE }, /* HORIZONTAL ARROW EXTENDER # arrowhorizex (CUS) */
1242 { 0xF8E8, 0xE2 }, /* REGISTERED SIGN SANS SERIF # registersans (CUS) */
1243 { 0xF8E9, 0xE3 }, /* COPYRIGHT SIGN SANS SERIF # copyrightsans (CUS) */
1244 { 0xF8EA, 0xE4 }, /* TRADE MARK SIGN SANS SERIF # trademarksans (CUS) */
1245 { 0xF8EB, 0xE6 }, /* LEFT PAREN TOP # parenlefttp (CUS) */
1246 { 0xF8EC, 0xE7 }, /* LEFT PAREN EXTENDER # parenleftex (CUS) */
1247 { 0xF8ED, 0xE8 }, /* LEFT PAREN BOTTOM # parenleftbt (CUS) */
1248 { 0xF8EE, 0xE9 }, /* LEFT SQUARE BRACKET TOP # bracketlefttp (CUS) */
1249 { 0xF8EF, 0xEA }, /* LEFT SQUARE BRACKET EXTENDER # bracketleftex (CUS) */
1250 { 0xF8F0, 0xEB }, /* LEFT SQUARE BRACKET BOTTOM # bracketleftbt (CUS) */
1251 { 0xF8F1, 0xEC }, /* LEFT CURLY BRACKET TOP # bracelefttp (CUS) */
1252 { 0xF8F2, 0xED }, /* LEFT CURLY BRACKET MID # braceleftmid (CUS) */
1253 { 0xF8F3, 0xEE }, /* LEFT CURLY BRACKET BOTTOM # braceleftbt (CUS) */
1254 { 0xF8F4, 0xEF }, /* CURLY BRACKET EXTENDER # braceex (CUS) */
1255 { 0xF8F5, 0xF4 }, /* INTEGRAL EXTENDER # integralex (CUS) */
1256 { 0xF8F6, 0xF6 }, /* RIGHT PAREN TOP # parenrighttp (CUS) */
1257 { 0xF8F7, 0xF7 }, /* RIGHT PAREN EXTENDER # parenrightex (CUS) */
1258 { 0xF8F8, 0xF8 }, /* RIGHT PAREN BOTTOM # parenrightbt (CUS) */
1259 { 0xF8F9, 0xF9 }, /* RIGHT SQUARE BRACKET TOP # bracketrighttp (CUS) */
1260 { 0xF8FA, 0xFA }, /* RIGHT SQUARE BRACKET EXTENDER # bracketrightex (CUS) */
1261 { 0xF8FB, 0xFB }, /* RIGHT SQUARE BRACKET BOTTOM # bracketrightbt (CUS) */
1262 { 0xF8FC, 0xFC }, /* RIGHT CURLY BRACKET TOP # bracerighttp (CUS) */
1263 { 0xF8FD, 0xFD }, /* RIGHT CURLY BRACKET MID # bracerightmid (CUS) */
1264 { 0xF8FE, 0xFE }, /* RIGHT CURLY BRACKET BOTTOM # bracerightbt (CUS) */
1269 static const FcCharMap AdobeSymbol
= {
1271 sizeof (AdobeSymbolEnt
) / sizeof (AdobeSymbolEnt
[0]),
1275 static const FcFontDecode fcFontDecoders
[] = {
1276 { ft_encoding_unicode
, 0, (1 << 21) - 1 },
1277 { ft_encoding_symbol
, &AdobeSymbol
, (1 << 16) - 1 },
1278 { ft_encoding_apple_roman
, &AppleRoman
, (1 << 16) - 1 },
1281 #define NUM_DECODE (int) (sizeof (fcFontDecoders) / sizeof (fcFontDecoders[0]))
1283 static FcChar32
FcFreeTypePrivateToUcs4 (FcChar32
private, const FcCharMap
*map
);
1285 const FcCharMap
*FcFreeTypeGetPrivateMap(FT_Encoding encoding
)
1289 for (i
= 0; i
< NUM_DECODE
; i
++)
1290 if (fcFontDecoders
[i
].encoding
== encoding
)
1291 return fcFontDecoders
[i
].map
;
1295 /* A shift-JIS will have many high bits turned on */
1296 static FcBool
FcLooksLikeSJIS (FcChar8
*string
, int len
)
1298 int nhigh
= 0, nlow
= 0;
1302 if (*string
++ & 0x80)
1307 /* Heuristic -- if more than 1/3 of the bytes have the high-bit set, this is likely to be SJIS and not ROMAN */
1308 if (nhigh
* 2 > nlow
)
1314 static char *fcSfntNameTranscode(FT_SfntName
*sname
)
1317 const char *fromcode
;
1320 for (i
= 0; i
< NUM_FC_FT_ENCODING
; i
++)
1321 if (fcFtEncoding
[i
].platform_id
== sname
->platform_id
&&
1322 (fcFtEncoding
[i
].encoding_id
== TT_ENCODING_DONT_CARE
||
1323 fcFtEncoding
[i
].encoding_id
== sname
->encoding_id
))
1326 if (i
== NUM_FC_FT_ENCODING
)
1328 fromcode
= fcFtEncoding
[i
].fromcode
;
1330 /* Many names encoded for TT_PLATFORM_MACINTOSH are broken in various ways. Kludge around them. */
1332 if (!strcmp (fromcode
, FC_ENCODING_MAC_ROMAN
))
1334 if (sname
->language_id
== TT_MAC_LANGID_ENGLISH
&&
1335 FcLooksLikeSJIS (sname
->string
, sname
->string_len
))
1339 else if (sname
->language_id
>= 0x100)
1341 /* "real" Mac language IDs are all less than 150.
1342 * Names using one of the MS language IDs are assumed
1343 * to use an associated encoding (Yes, this is a kludge)
1348 for (f
= 0; f
< NUM_FC_MAC_ROMAN_FAKE
; f
++)
1349 if (fcMacRomanFake
[f
].language_id
== sname
->language_id
)
1351 fromcode
= fcMacRomanFake
[f
].fromcode
;
1358 if (!strcmp (fromcode
, "UCS-2BE") || !strcmp (fromcode
, "UTF-16BE"))
1360 char *src
= sname
->string
;
1361 int src_len
= sname
->string_len
;
1368 /* Convert Utf16 to Utf8 */
1370 if (!FcUtf16Len(src
, FcEndianBig
, src_len
, &len
, &wchar
))
1373 /* Allocate plenty of space. Freed below */
1374 utf8
= malloc (len
* FC_UTF8_MAX_LEN
+ 1);
1380 while ((ilen
= FcUtf16ToUcs4 (src
, FcEndianBig
, &ucs4
, src_len
)) > 0)
1384 olen
= FcUcs4ToUtf8 (ucs4
, u8
);
1391 if (!strcmp (fromcode
, "ASCII") || !strcmp (fromcode
, "ISO-8859-1"))
1393 FcChar8
*src
= sname
->string
;
1394 int src_len
= sname
->string_len
;
1399 /* Convert Latin1 to Utf8. Freed below */
1400 utf8
= malloc (src_len
* 2 + 1);
1409 olen
= FcUcs4ToUtf8 (ucs4
, u8
);
1415 if (!strcmp (fromcode
, FC_ENCODING_MAC_ROMAN
))
1418 const FcCharMap
*map
= FcFreeTypeGetPrivateMap (ft_encoding_apple_roman
);
1419 FcChar8
*src
= (FcChar8
*) sname
->string
;
1420 int src_len
= sname
->string_len
;
1422 /* Convert AppleRoman to Utf8 */
1426 utf8
= malloc (sname
->string_len
* 3 + 1);
1433 FcChar32 ucs4
= FcFreeTypePrivateToUcs4 (*src
++, map
);
1434 int olen
= FcUcs4ToUtf8 (ucs4
, u8
);
1444 if (FcStrCmpIgnoreBlanksAndCase (utf8
, (FcChar8
*) "") == 0)
1452 static const char *fcSfntNameLanguage(FT_SfntName
*sname
)
1455 FT_UShort platform_id
= sname
->platform_id
;
1456 FT_UShort language_id
= sname
->language_id
;
1458 /* Many names encoded for TT_PLATFORM_MACINTOSH are broken in various ways. Kludge around them. */
1459 if (platform_id
== TT_PLATFORM_MACINTOSH
&& sname
->encoding_id
== TT_MAC_ID_ROMAN
&& FcLooksLikeSJIS (sname
->string
, sname
->string_len
))
1461 language_id
= TT_MAC_LANGID_JAPANESE
;
1464 for (i
= 0; i
< NUM_FC_FT_LANGUAGE
; i
++)
1465 if (fcFtLanguage
[i
].platform_id
== platform_id
&& (fcFtLanguage
[i
].language_id
== TT_LANGUAGE_DONT_CARE
|| fcFtLanguage
[i
].language_id
== language_id
))
1467 if (fcFtLanguage
[i
].lang
[0] == '\0')
1470 return (char *)fcFtLanguage
[i
].lang
;
1475 static int fcStringInPatternElement(struct fontpattern
*pat
, const int elt
, char *string
)
1480 char *old
= fcPatternGetString(pat
, elt
, e
);
1481 if (old
!= NULL
&& !FcStrCmpIgnoreBlanksAndCase(old
, string
))
1485 e
++; /* try next element, otherwise bail out */
1495 struct fontpattern
*fcQueryFace(const FT_Face face
, char *fname
, int id
)
1497 struct fontpattern
*pat
= NULL
;
1503 struct fontlangset
*ls
;
1504 struct fontcharset
*cs
;
1507 #if HAVE_FT_GET_PS_FONT_INFO
1508 PS_FontInfoRec psfontinfo
;
1510 #if HAVE_FT_GET_BDF_PROPERTY
1511 BDF_PropertyRec prop
;
1514 char *exclusiveLang
= 0;
1516 unsigned int snamei
, snamec
;
1527 pat
= fcPatternAlloc();
1531 /* Get the OS/2 table */
1532 os2
= (TT_OS2
*)FT_Get_Sfnt_Table(face
, ft_sfnt_os2
);
1534 /* Grub through the name table looking for family and style names. FreeType makes quite a hash of them */
1535 snamec
= FT_Get_Sfnt_Name_Count(face
);
1536 for (p
= 0; p
<= NUM_PLATFORM_ORDER
; p
++)
1538 if (p
< NUM_PLATFORM_ORDER
)
1539 platform
= platform_order
[p
];
1543 /* Order nameids so preferred names appear first in the resulting list */
1544 for (n
= 0; n
< NUM_NAMEID_ORDER
; n
++)
1546 nameid
= nameid_order
[n
];
1548 for (snamei
= 0; snamei
< snamec
; snamei
++)
1553 if (FT_Get_Sfnt_Name (face
, snamei
, &sname
) != 0)
1555 if (sname
.name_id
!= nameid
)
1558 /* Sort platforms in preference order, accepting all other platforms last */
1559 if (p
< NUM_PLATFORM_ORDER
)
1561 if (sname
.platform_id
!= platform
)
1568 for (sp
= 0; sp
< NUM_PLATFORM_ORDER
; sp
++)
1569 if (sname
.platform_id
== platform_order
[sp
])
1572 if (sp
!= NUM_PLATFORM_ORDER
)
1575 utf8
= fcSfntNameTranscode(&sname
);
1580 switch (sname
.name_id
) {
1581 #ifdef TT_NAME_ID_WWS_FAMILY
1582 case TT_NAME_ID_WWS_FAMILY
:
1584 case TT_NAME_ID_PREFERRED_FAMILY
:
1585 case TT_NAME_ID_FONT_FAMILY
:
1587 case TT_NAME_ID_PS_NAME
:
1588 case TT_NAME_ID_UNIQUE_ID
:
1591 if (FcDebug () & FC_DBG_SCANV
)
1592 kprintf ("found family (n %2d p %d e %d l 0x%04x) %s\n",
1593 sname
.name_id
, sname
.platform_id
,
1594 sname
.encoding_id
, sname
.language_id
,
1599 case TT_NAME_ID_MAC_FULL_NAME
:
1600 case TT_NAME_ID_FULL_NAME
:
1602 if (FcDebug () & FC_DBG_SCANV
)
1603 kprintf ("found full (n %2d p %d e %d l 0x%04x) %s\n",
1604 sname
.name_id
, sname
.platform_id
,
1605 sname
.encoding_id
, sname
.language_id
,
1611 #ifdef TT_NAME_ID_WWS_SUBFAMILY
1612 case TT_NAME_ID_WWS_SUBFAMILY
:
1614 case TT_NAME_ID_PREFERRED_SUBFAMILY
:
1615 case TT_NAME_ID_FONT_SUBFAMILY
:
1617 if (FcDebug () & FC_DBG_SCANV
)
1618 kprintf ("found style (n %2d p %d e %d l 0x%04x) %s\n",
1619 sname
.name_id
, sname
.platform_id
,
1620 sname
.encoding_id
, sname
.language_id
,
1630 if (fcStringInPatternElement(pat
, elt
, utf8
))
1636 /* add new element */
1637 if (!fcPatternAddString (pat
, elt
, utf8
))
1651 if (!nfamily
&& face
->family_name
&& FcStrCmpIgnoreBlanksAndCase ((FcChar8
*) face
->family_name
, (FcChar8
*) "") != 0)
1654 if (FcDebug () & FC_DBG_SCANV
)
1655 kprintf ("using FreeType family \"%s\"\n", face
->family_name
);
1657 if (!fcPatternAddString (pat
, FC_FAMILY
, (FcChar8
*) face
->family_name
))
1662 if (!nstyle
&& face
->style_name
&& FcStrCmpIgnoreBlanksAndCase ((FcChar8
*) face
->style_name
, (FcChar8
*) "") != 0)
1664 if (FcDebug () & FC_DBG_SCANV
)
1665 kprintf ("using FreeType style \"%s\"\n", face
->style_name
);
1667 if (!fcPatternAddString (pat
, FC_STYLE
, (FcChar8
*) face
->style_name
))
1674 FcChar8
*start
, *end
;
1677 start
= (FcChar8
*) strrchr ((char *) fname
, '/');
1681 start
= (FcChar8
*) fname
;
1682 end
= (FcChar8
*) strrchr ((char *) start
, '.');
1684 end
= start
+ strlen ((char *) start
);
1686 family
= malloc (end
- start
+ 1);
1687 strncpy ((char *) family
, (char *) start
, end
- start
);
1688 family
[end
- start
] = '\0';
1690 if (FcDebug () & FC_DBG_SCANV
)
1691 kprintf ("using filename for family %s\n", family
);
1693 if (!fcPatternAddString (pat
, FC_FAMILY
, family
))
1702 if (!fcPatternAddString (pat
, FC_FILE
, fname
))
1705 if (!fcPatternAddInteger (pat
, FC_INDEX
, id
))
1708 if (os2
&& os2
->version
>= 0x0001 && os2
->version
!= 0xffff)
1710 for (i
= 0; i
< NUM_CODE_PAGE_RANGE
; i
++)
1714 if (FcCodePageRange
[i
].bit
< 32)
1716 bits
= os2
->ulCodePageRange1
;
1717 bit
= FcCodePageRange
[i
].bit
;
1721 bits
= os2
->ulCodePageRange2
;
1722 bit
= FcCodePageRange
[i
].bit
- 32;
1724 if (bits
& (1 << bit
))
1726 /* If the font advertises support for multiple
1727 * "exclusive" languages, then include support
1728 * for any language found to have coverage
1736 exclusiveLang
= FcCodePageRange
[i
].lang
;
1741 if (os2
&& os2
&& (unsigned)(((os2
->sFamilyClass
>> 8) & 0xff) - 1) < 5) /* kiero: from ftmanager source. too lazy to google for it... */
1743 fcPatternAddInteger(pat
, FC_SERIF
, TRUE
);
1747 if (os2
&& os2
->version
!= 0xffff)
1749 if (os2
->usWeightClass
== 0)
1751 else if (os2
->usWeightClass
< 150)
1752 weight
= FC_WEIGHT_THIN
;
1753 else if (os2
->usWeightClass
< 250)
1754 weight
= FC_WEIGHT_EXTRALIGHT
;
1755 else if (os2
->usWeightClass
< 350)
1756 weight
= FC_WEIGHT_LIGHT
;
1757 else if (os2
->usWeightClass
< 450)
1758 weight
= FC_WEIGHT_REGULAR
;
1759 else if (os2
->usWeightClass
< 550)
1760 weight
= FC_WEIGHT_MEDIUM
;
1761 else if (os2
->usWeightClass
< 650)
1762 weight
= FC_WEIGHT_SEMIBOLD
;
1763 else if (os2
->usWeightClass
< 750)
1764 weight
= FC_WEIGHT_BOLD
;
1765 else if (os2
->usWeightClass
< 850)
1766 weight
= FC_WEIGHT_EXTRABOLD
;
1767 else if (os2
->usWeightClass
< 925)
1768 weight
= FC_WEIGHT_BLACK
;
1769 else if (os2
->usWeightClass
< 1000)
1770 weight
= FC_WEIGHT_EXTRABLACK
;
1772 if ((FcDebug() & FC_DBG_SCANV
) && weight
!= -1)
1773 kprintf ("\tos2 weight class %d maps to weight %d\n",
1774 os2
->usWeightClass
, weight
);
1777 switch (os2
->usWidthClass
) {
1778 case 1: width
= FC_WIDTH_ULTRACONDENSED
; break;
1779 case 2: width
= FC_WIDTH_EXTRACONDENSED
; break;
1780 case 3: width
= FC_WIDTH_CONDENSED
; break;
1781 case 4: width
= FC_WIDTH_SEMICONDENSED
; break;
1782 case 5: width
= FC_WIDTH_NORMAL
; break;
1783 case 6: width
= FC_WIDTH_SEMIEXPANDED
; break;
1784 case 7: width
= FC_WIDTH_EXPANDED
; break;
1785 case 8: width
= FC_WIDTH_EXTRAEXPANDED
; break;
1786 case 9: width
= FC_WIDTH_ULTRAEXPANDED
; break;
1789 if ((FcDebug() & FC_DBG_SCANV
) && width
!= -1)
1790 kprintf ("\tos2 width class %d maps to width %d\n",
1791 os2
->usWidthClass
, width
);
1795 /* Type 1: Check for FontInfo dictionary information Code from g2@magestudios.net (Gerard Escalante) */
1797 #if HAVE_FT_GET_PS_FONT_INFO
1798 if (FT_Get_PS_Font_Info(face
, &psfontinfo
) == 0)
1800 if (weight
== -1 && psfontinfo
.weight
)
1802 weight
= FcIsWeight ((FcChar8
*) psfontinfo
.weight
);
1803 if (FcDebug() & FC_DBG_SCANV
)
1804 kprintf ("\tType1 weight %s maps to %d\n",
1805 psfontinfo
.weight
, weight
);
1811 #endif /* HAVE_FT_GET_PS_FONT_INFO */
1813 #if HAVE_FT_GET_BDF_PROPERTY
1817 if (FT_Get_BDF_Property(face
, "RELATIVE_SETWIDTH", &prop
) == 0 &&
1818 (prop
.type
== BDF_PROPERTY_TYPE_INTEGER
||
1819 prop
.type
== BDF_PROPERTY_TYPE_CARDINAL
))
1823 if (prop
.type
== BDF_PROPERTY_TYPE_INTEGER
)
1824 value
= prop
.u
.integer
;
1826 value
= (FT_Int32
) prop
.u
.cardinal
;
1827 switch ((value
+ 5) / 10) {
1828 case 1: width
= FC_WIDTH_ULTRACONDENSED
; break;
1829 case 2: width
= FC_WIDTH_EXTRACONDENSED
; break;
1830 case 3: width
= FC_WIDTH_CONDENSED
; break;
1831 case 4: width
= FC_WIDTH_SEMICONDENSED
; break;
1832 case 5: width
= FC_WIDTH_NORMAL
; break;
1833 case 6: width
= FC_WIDTH_SEMIEXPANDED
; break;
1834 case 7: width
= FC_WIDTH_EXPANDED
; break;
1835 case 8: width
= FC_WIDTH_EXTRAEXPANDED
; break;
1836 case 9: width
= FC_WIDTH_ULTRAEXPANDED
; break;
1839 if (width
== -1 && FT_Get_BDF_Property (face
, "SETWIDTH_NAME", &prop
) == 0 && prop
.type
== BDF_PROPERTY_TYPE_ATOM
)
1841 width
= FcIsWidth ((FcChar8
*) prop
.u
.atom
);
1842 if (FcDebug () & FC_DBG_SCANV
)
1843 kprintf ("\tsetwidth %s maps to %d\n", prop
.u
.atom
, width
);
1848 /* Look for weight, width and slant names in the style value */
1851 style
= fcPatternGetString (pat
, FC_STYLE
, st
);
1857 weight
= FcContainsWeight (style
);
1859 if (FcDebug() & FC_DBG_SCANV
)
1860 kprintf ("\tStyle %s maps to weight %d\n", style
, weight
);
1865 width
= FcContainsWidth (style
);
1866 if (FcDebug() & FC_DBG_SCANV
)
1867 kprintf ("\tStyle %s maps to width %d\n", style
, width
);
1872 slant
= FcContainsSlant (style
);
1874 if (FcDebug() & FC_DBG_SCANV
)
1875 kprintf ("\tStyle %s maps to slant %d\n", style
, slant
);
1879 /* Pull default values from the FreeType flags if more specific values not found above */
1882 slant
= FC_SLANT_ROMAN
;
1883 if (face
->style_flags
& FT_STYLE_FLAG_ITALIC
)
1884 slant
= FC_SLANT_ITALIC
;
1889 weight
= FC_WEIGHT_MEDIUM
;
1890 if (face
->style_flags
& FT_STYLE_FLAG_BOLD
)
1891 weight
= FC_WEIGHT_BOLD
;
1895 width
= FC_WIDTH_NORMAL
;
1898 if (!fcPatternAddInteger (pat
, FC_SLANT
, slant
))
1901 if (!fcPatternAddInteger (pat
, FC_WEIGHT
, weight
))
1904 if (!fcPatternAddInteger (pat
, FC_WIDTH
, width
))
1907 /* Compute the unicode coverage for the font */
1909 cs
= FcFreeTypeCharSetAndSpacing (face
, blanks
, &spacing
);
1914 #if HAVE_FT_GET_BDF_PROPERTY
1915 /* For PCF fonts, override the computed spacing with the one from the property */
1916 if(FT_Get_BDF_Property(face
, "SPACING", &prop
) == 0 && prop
.type
== BDF_PROPERTY_TYPE_ATOM
)
1918 if(!strcmp(prop
.u
.atom
, "c") || !strcmp(prop
.u
.atom
, "C"))
1919 spacing
= FC_CHARCELL
;
1920 else if(!strcmp(prop
.u
.atom
, "m") || !strcmp(prop
.u
.atom
, "M"))
1922 else if(!strcmp(prop
.u
.atom
, "p") || !strcmp(prop
.u
.atom
, "P"))
1923 spacing
= FC_PROPORTIONAL
;
1927 if (spacing
!= FC_PROPORTIONAL
)
1928 if (!fcPatternAddInteger (pat
, FC_SPACING
, spacing
))
1933 /* Skip over PCF fonts that have no encoded characters; they're
1934 * usually just Unicode fonts transcoded to some legacy encoding
1935 * FT forces us to approximate whether a font is a PCF font
1936 * or not by whether it has any BDF properties. Try PIXEL_SIZE;
1937 * I don't know how to get a list of BDF properties on the font. -PL
1940 if (FcCharSetCount (cs
) == 0)
1942 #if HAVE_FT_GET_BDF_PROPERTY
1943 if(FT_Get_BDF_Property(face
, "PIXEL_SIZE", &prop
) == 0)
1948 ls
= FcFreeTypeLangSet (cs
, exclusiveLang
);
1952 if (!fcPatternAddLangSet (pat
, FC_LANG
, ls
))
1954 FcLangSetDestroy (ls
);
1958 FcLangSetDestroy (ls
);
1961 /* Drop our reference to the charset */
1962 FcCharSetDestroy (cs
);
1970 FcCharSetDestroy (cs
);
1974 fcPatternDestroy (pat
);
1983 struct List entries
;
1988 static struct fontpattern
*fcQueryFont(char *fname
, int id
, int *count
)
1991 struct fontpattern
*pat
= NULL
;
1993 if (FT_New_Face(ftLibrary
, fname
, id
, &face
))
1995 D(kprintf("failed to open tt font:%s, %d\n", fname
, id
));
1998 *count
= face
->num_faces
;
2000 pat
= fcQueryFace(face
, fname
, id
);
2012 static DirectoryTraverseResult
callback(struct FileInfoBlock
*fib
, char *path
, int level
, void *data
)
2014 struct fontcache
*cache
= (struct fontcache
*)data
;
2017 if (strMatch(path
, "#?.(ttf|pfb)"))
2019 struct fontpattern
*pat
;
2020 if (FcDebug () & FC_DBG_SCANV
)
2021 kprintf("scanning:%s\n", path
);
2022 pat
= fcQueryFont(path
, 0, &ccount
);
2023 if (FcDebug () & FC_DBG_SCANV
)
2024 kprintf("scanning:%s done. pattern:%p\n", path
, pat
);
2027 ADDTAIL(&cache
->entries
, pat
);
2028 //else (don't abort scanning. ikn future add different error codes to distinguish between lack of memory and broken font files)
2029 // return DIRECTORY_TRAVERSE_ABORT;
2032 return DIRECTORY_TRAVERSE_CONTINUE
;
2035 void fcDestroy(struct fontcache
*cache
)
2037 /* TODO. not really high priority as it will be dispose anyway */
2040 struct fontcache
*fcCreate(char *directories
[])
2042 struct fontcache
*cache
= calloc(1, sizeof(*cache
));
2043 NewList(&cache
->entries
);
2045 if (FcDebug () & FC_DBG_SCANV
)
2046 kprintf("FCCache: Initialize cache system...\n");
2048 if (!FT_Init_FreeType(&ftLibrary
))
2052 char *dir
= *directories
++;
2053 BPTR dirlock
= Lock(dir
, ACCESS_READ
);
2055 if (dirlock
!= NULL
)
2060 result
= directoryTraverse(dir
, DIRECTORY_SCAN_RECURSIVE
, callback
, cache
);
2062 if (result
!= DIRECTORY_TRAVERSE_OK
)
2071 FT_Done_FreeType(ftLibrary
);
2075 D(kprintf("**********ERROR: Failed to initiclize freetype library\n"));
2080 struct fontpattern
*fcMatch(struct fontcache
*cache
, struct fontpattern
*pat
, int *matchingcriteria
)
2082 struct fontpattern
*cpat
;
2083 struct fontpattern
*bestmatch
= NULL
;
2084 int bestmatchweight
= 0;
2086 /* Find best match by calcularing weighted compatibility value */
2088 ITERATELIST(cpat
, &cache
->entries
)
2090 struct patternentry
*cpe
, *pe
;
2091 int cmatchingcriteria
[FC_LAST_CRITERIA
] = {0};
2094 ITERATELIST(pe
, &pat
->entries
) /* pe - for each entry in criteria pattern. assume that caller is not stupid and doesn't pass elements with 0-weight */
2096 ITERATELIST(cpe
, &cpat
->entries
) /* cpe - for each entry in pattern in cache */
2100 if (cpe
->element
== pe
->element
)
2102 /* first go special elements */
2104 if (cpe
->element
== FC_FILE
)
2106 char *filepart
= FilePart(cpe
->value
.s
);
2107 if (filepart
!= NULL
) /* paranoid? */
2109 if (0 == stricmp(filepart
, pe
->value
.s
))
2113 else /* then generic attributes */
2116 if (cpe
->type
== FC_ETYPE_STRING
)
2118 /* TODO: make all strings uppercase and kill blanks */
2119 if (0 == FcStrCmpIgnoreBlanksAndCase(cpe
->value
.s
, pe
->value
.s
))
2124 else if (cpe
->type
== FC_ETYPE_INTEGER
)
2126 if (cpe
->value
.i
== pe
->value
.i
)
2136 if (pe
->excluding
) /* if the match was found and the criteria is excluding we lower the score */
2138 /* if any attribute did match earlier then we don't go below 1 as it still matches better than font with zero matches */
2139 weight
-= fcelementpriority
[cpe
->element
];
2143 /* if only excluding attributes were found earlier (<0) then we automaticly bump it to be >0 */
2144 weight
+= fcelementpriority
[cpe
->element
];
2148 cmatchingcriteria
[cpe
->element
] = TRUE
;
2156 if (weight
> bestmatchweight
)
2159 bestmatchweight
= weight
;
2160 if (matchingcriteria
!= NULL
)
2161 memcpy(matchingcriteria
, cmatchingcriteria
, sizeof(cmatchingcriteria
));
2165 /* we can still land with no font matching! do we need some fallback? */
2167 if (bestmatch
== NULL
)
2169 if (FcDebug () & FC_DBG_SCANV
)
2170 kprintf("*****ERROR: No match for pattern\n");
2176 static int writeint(FILE *f
, int val
)
2178 return fwrite(&val
, sizeof(val
), 1, f
);
2181 static int writestring(FILE *f
, char *str
)
2183 int l
= strlen(str
);
2184 int rc
= writeint(f
, l
+ 1);
2186 rc
= fwrite(str
, l
+ 1, 1, f
);
2191 int fcSave(struct fontcache
*fontcache
, char *fname
)
2193 struct fontpattern
*pat
;
2194 FILE *f
= fopen(fname
, "w");
2199 D(kprintf("writting fontcache to %s\n", fname
));
2201 /* write some header + version number */
2203 fprintf(f
, "FCDTVER1");
2205 /* now for each pattern */
2207 ITERATELIST(pat
, &fontcache
->entries
)
2209 struct patternentry
*pe
;
2213 * write number of entries for pattern
2214 * for each pattern entry:
2218 * for int: write value
2219 * for string: write lenght including null termination
2220 * write string contents including null termination
2223 ListLength(&pat
->entries
, elements
);
2224 writeint(f
, elements
);
2226 ITERATELIST(pe
, &pat
->entries
)
2228 writeint(f
, pe
->element
);
2229 writeint(f
, pe
->id
);
2230 writeint(f
, pe
->type
);
2231 if (pe
->type
== FC_ETYPE_STRING
)
2232 writestring(f
, pe
->value
.s
);
2234 writeint(f
, pe
->value
.i
);
2244 static int readint(FILE *f
)
2247 fread(&val
, sizeof(val
), 1, f
);
2251 static char *readstring(FILE *f
)
2262 fread(val
, l
, 1, f
);
2266 struct fontcache
*fcLoad(char *fname
)
2270 struct fontcache
*fontcache
;
2272 f
= fopen(fname
, "r");
2276 fontcache
= calloc(1, sizeof(*fontcache
));
2278 if (fontcache
== NULL
)
2284 NewList(&fontcache
->entries
);
2285 fread(header
, sizeof(header
), 1, f
);
2287 if (memcmp(header
, "FCDTVER1", sizeof(header
)))
2290 fcDestroy(fontcache
);
2294 D(kprintf("loading font cache from %s\n", fname
));
2298 struct fontpattern
*pat
;
2299 int entries
= readint(f
);
2300 if (entries
== 0) /* this means end of stream here */
2303 pat
= fcPatternAlloc();
2307 for(i
=0; i
<entries
; i
++)
2309 int element
= readint(f
);
2310 int id
= readint(f
);
2311 int type
= readint(f
);
2312 union patternvalue val
;
2313 if (type
== FC_ETYPE_STRING
)
2314 val
.s
= readstring(f
);
2318 fcPatternAddEntryRaw(pat
, element
, type
, &val
, id
);
2321 ADDTAIL(&fontcache
->entries
, pat
);
2334 int fcAddPattern(struct fontcache
*fontcache
, struct fontpattern
*pat
)
2336 if (fontcache
!= NULL
&& pat
!= NULL
)
2338 ADDTAIL(&fontcache
->entries
, pat
);
2349 struct Task
*this = FindTask(NULL
);
2350 this->tc_ETask
->MaxHits
= 1;
2357 /* scan all fonts installed in any given user directory */
2359 char *dirs
[] = {"sys:fonts", "mossys:fonts", NULL
};
2361 struct fontcache
*cache
= fcCreate(dirs
);
2363 fcSave(cache
, "ram:cache1");
2364 cache
= fcLoad("ram:cache1");
2365 fcSave(cache
, "ram:cache2");
2367 /* try to match simple slanted font */
2371 struct fontpattern
*pat
= fcPatternAlloc();
2372 struct fontpattern
*cpat
;
2374 fcPatternAddString(pat
, FC_FAMILY
, "Times");
2375 //fcPatternAddString(pat, FC_FILE, "n019003l.pfb");
2377 cpat
= fcMatch(cache
, pat
, NULL
);
2380 char *name
= fcPatternGetString(cpat
, FC_FILE
, 0);
2381 char *family
= fcPatternGetString(cpat
, FC_FAMILY
, 0);
2390 struct fontpattern
*pat
= fcPatternAlloc();
2391 struct fontpattern
*cpat
;
2393 //fcPatternAddString(pat, FC_FAMILY, "Helvetica");
2394 fcPatternAddString(pat
, FC_FILE
, "n019003l.pfb");
2396 cpat
= fcMatch(cache
, pat
, NULL
);
2399 char *name
= fcPatternGetString(cpat
, FC_FILE
, 0);
2400 char *family
= fcPatternGetString(cpat
, FC_FAMILY
, 0);
2419 static FcChar32
FcFreeTypePrivateToUcs4 (FcChar32
private, const FcCharMap
*map
)
2423 for (i
= 0; i
< map
->nent
; i
++)
2424 if (map
->ent
[i
].encode
== private)
2425 return (FcChar32
) map
->ent
[i
].bmp
;