2 * fontconfig/src/fcfreetype.c
4 * Copyright © 2001 Keith Packard
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
26 Copyright © 2002-2003 by Juliusz Chroboczek
28 Permission is hereby granted, free of charge, to any person obtaining a copy
29 of this software and associated documentation files (the "Software"), to deal
30 in the Software without restriction, including without limitation the rights
31 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32 copies of the Software, and to permit persons to whom the Software is
33 furnished to do so, subject to the following conditions:
35 The above copyright notice and this permission notice shall be included in
36 all copies or substantial portions of the Software.
38 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53 #include FT_FREETYPE_H
54 #include FT_TRUETYPE_TABLES_H
55 #include FT_SFNT_NAMES_H
56 #include FT_TRUETYPE_IDS_H
57 #include FT_TYPE1_TABLES_H
58 #if HAVE_FT_GET_X11_FONT_FORMAT
61 #if HAVE_FT_GET_BDF_PROPERTY
68 #if HAVE_WARNING_CPP_DIRECTIVE
69 #if !HAVE_FT_GET_BDF_PROPERTY
70 #warning "No FT_Get_BDF_Property: Please install freetype 2.1.4 or later"
73 #if !HAVE_FT_GET_PS_FONT_INFO
74 #warning "No FT_Get_PS_Font_Info: Please install freetype 2.1.1 or later"
79 * Keep Han languages separated by eliminating languages
80 * that the codePageRange bits says aren't supported
85 const FcChar8 lang
[6];
86 } FcCodePageRange
[] = {
93 #define NUM_CODE_PAGE_RANGE (int) (sizeof FcCodePageRange / sizeof FcCodePageRange[0])
96 FcFreeTypeIsExclusiveLang (const FcChar8
*lang
)
100 for (i
= 0; i
< NUM_CODE_PAGE_RANGE
; i
++)
102 if (FcLangCompare (lang
, FcCodePageRange
[i
].lang
) == FcLangEqual
)
109 const FT_UShort platform_id
;
110 const FT_UShort encoding_id
;
111 const char fromcode
[12];
114 #define TT_ENCODING_DONT_CARE 0xffff
115 #define FC_ENCODING_MAC_ROMAN "MACINTOSH"
117 static const FcFtEncoding fcFtEncoding
[] = {
118 { TT_PLATFORM_APPLE_UNICODE
, TT_ENCODING_DONT_CARE
, "UCS-2BE" },
119 { TT_PLATFORM_MACINTOSH
, TT_MAC_ID_ROMAN
, "MACINTOSH" },
120 { TT_PLATFORM_MACINTOSH
, TT_MAC_ID_JAPANESE
, "SJIS" },
121 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_UNICODE_CS
, "UTF-16BE" },
122 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_SJIS
, "SJIS-WIN" },
123 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_GB2312
, "GB3212" },
124 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_BIG_5
, "BIG-5" },
125 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_WANSUNG
, "Wansung" },
126 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_JOHAB
, "Johab" },
127 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_UCS_4
, "UCS4" },
128 { TT_PLATFORM_ISO
, TT_ISO_ID_7BIT_ASCII
, "ASCII" },
129 { TT_PLATFORM_ISO
, TT_ISO_ID_10646
, "UCS-2BE" },
130 { TT_PLATFORM_ISO
, TT_ISO_ID_8859_1
, "ISO-8859-1" },
133 #define NUM_FC_FT_ENCODING (int) (sizeof (fcFtEncoding) / sizeof (fcFtEncoding[0]))
136 const FT_UShort platform_id
;
137 const FT_UShort language_id
;
141 #define TT_LANGUAGE_DONT_CARE 0xffff
143 static const FcFtLanguage fcFtLanguage
[] = {
144 { TT_PLATFORM_APPLE_UNICODE
, TT_LANGUAGE_DONT_CARE
, "" },
145 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ENGLISH
, "en" },
146 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FRENCH
, "fr" },
147 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GERMAN
, "de" },
148 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ITALIAN
, "it" },
149 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_DUTCH
, "nl" },
150 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SWEDISH
, "sv" },
151 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SPANISH
, "es" },
152 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_DANISH
, "da" },
153 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_PORTUGUESE
, "pt" },
154 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_NORWEGIAN
, "no" },
155 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_HEBREW
, "he" },
156 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_JAPANESE
, "ja" },
157 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ARABIC
, "ar" },
158 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FINNISH
, "fi" },
159 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GREEK
, "el" },
160 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ICELANDIC
, "is" },
161 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALTESE
, "mt" },
162 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TURKISH
, "tr" },
163 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CROATIAN
, "hr" },
164 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CHINESE_TRADITIONAL
, "zh-tw" },
165 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_URDU
, "ur" },
166 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_HINDI
, "hi" },
167 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_THAI
, "th" },
168 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KOREAN
, "ko" },
169 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LITHUANIAN
, "lt" },
170 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_POLISH
, "pl" },
171 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_HUNGARIAN
, "hu" },
172 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ESTONIAN
, "et" },
173 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LETTISH
, "lv" },
174 /* { TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SAAMISK, ??? */
175 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FAEROESE
, "fo" },
176 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FARSI
, "fa" },
177 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_RUSSIAN
, "ru" },
178 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CHINESE_SIMPLIFIED
, "zh-cn" },
179 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FLEMISH
, "nl" },
180 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_IRISH
, "ga" },
181 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ALBANIAN
, "sq" },
182 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ROMANIAN
, "ro" },
183 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CZECH
, "cs" },
184 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SLOVAK
, "sk" },
185 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SLOVENIAN
, "sl" },
186 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_YIDDISH
, "yi" },
187 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SERBIAN
, "sr" },
188 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MACEDONIAN
, "mk" },
189 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BULGARIAN
, "bg" },
190 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_UKRAINIAN
, "uk" },
191 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BYELORUSSIAN
, "be" },
192 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_UZBEK
, "uz" },
193 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KAZAKH
, "kk" },
194 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI
, "az" },
195 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT
, "az" },
196 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT
, "ar" },
197 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ARMENIAN
, "hy" },
198 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GEORGIAN
, "ka" },
199 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MOLDAVIAN
, "mo" },
200 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KIRGHIZ
, "ky" },
201 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TAJIKI
, "tg" },
202 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TURKMEN
, "tk" },
203 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MONGOLIAN
, "mo" },
204 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT
,"mo" },
205 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT
, "mo" },
206 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_PASHTO
, "ps" },
207 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KURDISH
, "ku" },
208 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KASHMIRI
, "ks" },
209 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SINDHI
, "sd" },
210 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TIBETAN
, "bo" },
211 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_NEPALI
, "ne" },
212 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SANSKRIT
, "sa" },
213 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MARATHI
, "mr" },
214 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BENGALI
, "bn" },
215 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ASSAMESE
, "as" },
216 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GUJARATI
, "gu" },
217 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_PUNJABI
, "pa" },
218 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ORIYA
, "or" },
219 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAYALAM
, "ml" },
220 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KANNADA
, "kn" },
221 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TAMIL
, "ta" },
222 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TELUGU
, "te" },
223 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SINHALESE
, "si" },
224 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BURMESE
, "my" },
225 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KHMER
, "km" },
226 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LAO
, "lo" },
227 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_VIETNAMESE
, "vi" },
228 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_INDONESIAN
, "id" },
229 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TAGALOG
, "tl" },
230 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAY_ROMAN_SCRIPT
, "ms" },
231 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAY_ARABIC_SCRIPT
, "ms" },
232 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AMHARIC
, "am" },
233 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TIGRINYA
, "ti" },
234 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GALLA
, "om" },
235 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SOMALI
, "so" },
236 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SWAHILI
, "sw" },
237 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_RUANDA
, "rw" },
238 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_RUNDI
, "rn" },
239 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CHEWA
, "ny" },
240 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAGASY
, "mg" },
241 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ESPERANTO
, "eo" },
242 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_WELSH
, "cy" },
243 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BASQUE
, "eu" },
244 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CATALAN
, "ca" },
245 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LATIN
, "la" },
246 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_QUECHUA
, "qu" },
247 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GUARANI
, "gn" },
248 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AYMARA
, "ay" },
249 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TATAR
, "tt" },
250 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_UIGHUR
, "ug" },
251 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_DZONGKHA
, "dz" },
252 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_JAVANESE
, "jw" },
253 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SUNDANESE
, "su" },
255 #if 0 /* these seem to be errors that have been dropped */
257 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SCOTTISH_GAELIC
},
258 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_IRISH_GAELIC
},
262 /* The following codes are new as of 2000-03-10 */
263 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GALICIAN
, "gl" },
264 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AFRIKAANS
, "af" },
265 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BRETON
, "br" },
266 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_INUKTITUT
, "iu" },
267 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SCOTTISH_GAELIC
, "gd" },
268 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MANX_GAELIC
, "gv" },
269 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_IRISH_GAELIC
, "ga" },
270 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TONGAN
, "to" },
271 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GREEK_POLYTONIC
, "el" },
272 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GREELANDIC
, "ik" },
273 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT
,"az" },
275 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_SAUDI_ARABIA
, "ar" },
276 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_IRAQ
, "ar" },
277 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_EGYPT
, "ar" },
278 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_LIBYA
, "ar" },
279 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_ALGERIA
, "ar" },
280 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_MOROCCO
, "ar" },
281 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_TUNISIA
, "ar" },
282 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_OMAN
, "ar" },
283 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_YEMEN
, "ar" },
284 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_SYRIA
, "ar" },
285 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_JORDAN
, "ar" },
286 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_LEBANON
, "ar" },
287 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_KUWAIT
, "ar" },
288 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_UAE
, "ar" },
289 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_BAHRAIN
, "ar" },
290 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_QATAR
, "ar" },
291 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BULGARIAN_BULGARIA
, "bg" },
292 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CATALAN_SPAIN
, "ca" },
293 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_TAIWAN
, "zh-tw" },
294 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_PRC
, "zh-cn" },
295 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_HONG_KONG
, "zh-hk" },
296 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_SINGAPORE
, "zh-sg" },
298 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_MACAU
, "zh-mo" },
300 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CZECH_CZECH_REPUBLIC
, "cs" },
301 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DANISH_DENMARK
, "da" },
302 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_GERMANY
, "de" },
303 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_SWITZERLAND
, "de" },
304 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_AUSTRIA
, "de" },
305 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_LUXEMBOURG
, "de" },
306 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_LIECHTENSTEI
, "de" },
307 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GREEK_GREECE
, "el" },
308 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_UNITED_STATES
, "en" },
309 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_UNITED_KINGDOM
, "en" },
310 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_AUSTRALIA
, "en" },
311 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_CANADA
, "en" },
312 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_NEW_ZEALAND
, "en" },
313 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_IRELAND
, "en" },
314 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_SOUTH_AFRICA
, "en" },
315 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_JAMAICA
, "en" },
316 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_CARIBBEAN
, "en" },
317 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_BELIZE
, "en" },
318 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_TRINIDAD
, "en" },
319 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_ZIMBABWE
, "en" },
320 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_PHILIPPINES
, "en" },
321 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT
,"es" },
322 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_MEXICO
, "es" },
323 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT
,"es" },
324 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_GUATEMALA
, "es" },
325 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_COSTA_RICA
, "es" },
326 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PANAMA
, "es" },
327 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC
,"es" },
328 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_VENEZUELA
, "es" },
329 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_COLOMBIA
, "es" },
330 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PERU
, "es" },
331 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_ARGENTINA
, "es" },
332 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_ECUADOR
, "es" },
333 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_CHILE
, "es" },
334 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_URUGUAY
, "es" },
335 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PARAGUAY
, "es" },
336 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_BOLIVIA
, "es" },
337 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_EL_SALVADOR
, "es" },
338 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_HONDURAS
, "es" },
339 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_NICARAGUA
, "es" },
340 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PUERTO_RICO
, "es" },
341 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FINNISH_FINLAND
, "fi" },
342 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_FRANCE
, "fr" },
343 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_BELGIUM
, "fr" },
344 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_CANADA
, "fr" },
345 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_SWITZERLAND
, "fr" },
346 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_LUXEMBOURG
, "fr" },
347 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_MONACO
, "fr" },
348 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HEBREW_ISRAEL
, "he" },
349 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HUNGARIAN_HUNGARY
, "hu" },
350 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ICELANDIC_ICELAND
, "is" },
351 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ITALIAN_ITALY
, "it" },
352 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ITALIAN_SWITZERLAND
, "it" },
353 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_JAPANESE_JAPAN
, "ja" },
354 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA
,"ko" },
355 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KOREAN_JOHAB_KOREA
, "ko" },
356 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DUTCH_NETHERLANDS
, "nl" },
357 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DUTCH_BELGIUM
, "nl" },
358 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL
, "no" },
359 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK
, "nn" },
360 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_POLISH_POLAND
, "pl" },
361 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PORTUGUESE_BRAZIL
, "pt" },
362 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PORTUGUESE_PORTUGAL
, "pt" },
363 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND
,"rm" },
364 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ROMANIAN_ROMANIA
, "ro" },
365 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MOLDAVIAN_MOLDAVIA
, "mo" },
366 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_RUSSIAN_RUSSIA
, "ru" },
367 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_RUSSIAN_MOLDAVIA
, "ru" },
368 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CROATIAN_CROATIA
, "hr" },
369 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SERBIAN_SERBIA_LATIN
, "sr" },
370 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC
, "sr" },
371 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SLOVAK_SLOVAKIA
, "sk" },
372 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ALBANIAN_ALBANIA
, "sq" },
373 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SWEDISH_SWEDEN
, "sv" },
374 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SWEDISH_FINLAND
, "sv" },
375 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_THAI_THAILAND
, "th" },
376 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TURKISH_TURKEY
, "tr" },
377 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_URDU_PAKISTAN
, "ur" },
378 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_INDONESIAN_INDONESIA
, "id" },
379 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_UKRAINIAN_UKRAINE
, "uk" },
380 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BELARUSIAN_BELARUS
, "be" },
381 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SLOVENE_SLOVENIA
, "sl" },
382 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ESTONIAN_ESTONIA
, "et" },
383 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LATVIAN_LATVIA
, "lv" },
384 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LITHUANIAN_LITHUANIA
, "lt" },
385 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA
,"lt" },
387 #ifdef TT_MS_LANGID_MAORI_NEW_ZELAND
388 /* this seems to be an error that have been dropped */
389 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MAORI_NEW_ZEALAND
, "mi" },
392 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FARSI_IRAN
, "fa" },
393 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_VIETNAMESE_VIET_NAM
, "vi" },
394 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARMENIAN_ARMENIA
, "hy" },
395 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN
, "az" },
396 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC
, "az" },
397 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BASQUE_SPAIN
, "eu" },
398 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SORBIAN_GERMANY
, "wen" },
399 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MACEDONIAN_MACEDONIA
, "mk" },
400 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SUTU_SOUTH_AFRICA
, "st" },
401 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TSONGA_SOUTH_AFRICA
, "ts" },
402 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TSWANA_SOUTH_AFRICA
, "tn" },
403 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_VENDA_SOUTH_AFRICA
, "ven" },
404 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_XHOSA_SOUTH_AFRICA
, "xh" },
405 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ZULU_SOUTH_AFRICA
, "zu" },
406 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA
, "af" },
407 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GEORGIAN_GEORGIA
, "ka" },
408 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS
, "fo" },
409 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HINDI_INDIA
, "hi" },
410 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALTESE_MALTA
, "mt" },
411 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SAAMI_LAPONIA
, "se" },
413 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM
,"gd" },
414 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_IRISH_GAELIC_IRELAND
, "ga" },
416 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALAY_MALAYSIA
, "ms" },
417 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM
, "ms" },
418 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KAZAK_KAZAKSTAN
, "kk" },
419 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SWAHILI_KENYA
, "sw" },
420 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN
, "uz" },
421 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC
, "uz" },
422 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TATAR_TATARSTAN
, "tt" },
423 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BENGALI_INDIA
, "bn" },
424 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PUNJABI_INDIA
, "pa" },
425 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GUJARATI_INDIA
, "gu" },
426 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ORIYA_INDIA
, "or" },
427 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAMIL_INDIA
, "ta" },
428 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TELUGU_INDIA
, "te" },
429 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KANNADA_INDIA
, "kn" },
430 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALAYALAM_INDIA
, "ml" },
431 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ASSAMESE_INDIA
, "as" },
432 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MARATHI_INDIA
, "mr" },
433 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SANSKRIT_INDIA
, "sa" },
434 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KONKANI_INDIA
, "kok" },
436 /* new as of 2001-01-01 */
437 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_GENERAL
, "ar" },
438 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_GENERAL
, "zh" },
439 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_GENERAL
, "en" },
440 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_WEST_INDIES
, "fr" },
441 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_REUNION
, "fr" },
442 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_CONGO
, "fr" },
444 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_SENEGAL
, "fr" },
445 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_CAMEROON
, "fr" },
446 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_COTE_D_IVOIRE
, "fr" },
447 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_MALI
, "fr" },
448 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA
,"bs" },
449 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_URDU_INDIA
, "ur" },
450 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAJIK_TAJIKISTAN
, "tg" },
451 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_YIDDISH_GERMANY
, "yi" },
452 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN
, "ky" },
454 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TURKMEN_TURKMENISTAN
, "tk" },
455 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MONGOLIAN_MONGOLIA
, "mn" },
457 /* the following seems to be inconsistent;
458 here is the current "official" way: */
459 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIBETAN_BHUTAN
, "bo" },
460 /* and here is what is used by Passport SDK */
461 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIBETAN_CHINA
, "bo" },
462 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DZONGHKA_BHUTAN
, "dz" },
463 /* end of inconsistency */
465 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_WELSH_WALES
, "cy" },
466 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KHMER_CAMBODIA
, "km" },
467 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LAO_LAOS
, "lo" },
468 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BURMESE_MYANMAR
, "my" },
469 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GALICIAN_SPAIN
, "gl" },
470 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MANIPURI_INDIA
, "mni" },
471 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SINDHI_INDIA
, "sd" },
472 /* the following one is only encountered in Microsoft RTF specification */
473 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KASHMIRI_PAKISTAN
, "ks" },
474 /* the following one is not in the Passport list, looks like an omission */
475 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KASHMIRI_INDIA
, "ks" },
476 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NEPALI_NEPAL
, "ne" },
477 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NEPALI_INDIA
, "ne" },
478 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRISIAN_NETHERLANDS
, "fy" },
480 /* new as of 2001-03-01 (from Office Xp) */
481 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_HONG_KONG
, "en" },
482 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_INDIA
, "en" },
483 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_MALAYSIA
, "en" },
484 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_SINGAPORE
, "en" },
485 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SYRIAC_SYRIA
, "syr" },
486 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SINHALESE_SRI_LANKA
, "si" },
487 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHEROKEE_UNITED_STATES
, "chr" },
488 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_INUKTITUT_CANADA
, "iu" },
489 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AMHARIC_ETHIOPIA
, "am" },
491 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAMAZIGHT_MOROCCO
},
492 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN
},
494 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PASHTO_AFGHANISTAN
, "ps" },
495 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FILIPINO_PHILIPPINES
, "phi" },
496 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DHIVEHI_MALDIVES
, "div" },
498 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_OROMO_ETHIOPIA
, "om" },
499 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIGRIGNA_ETHIOPIA
, "ti" },
500 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIGRIGNA_ERYTHREA
, "ti" },
502 /* New additions from Windows Xp/Passport SDK 2001-11-10. */
504 /* don't ask what this one means... It is commented out currently. */
506 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GREEK_GREECE2
},
509 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_UNITED_STATES
, "es" },
510 /* The following two IDs blatantly violate MS specs by using a */
511 /* sublanguage >,. */
512 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_LATIN_AMERICA
, "es" },
513 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_NORTH_AFRICA
, "fr" },
515 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_MOROCCO
, "fr" },
516 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_HAITI
, "fr" },
517 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BENGALI_BANGLADESH
, "bn" },
518 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN
, "ar" },
519 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN
,"mn" },
521 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_EDO_NIGERIA
},
522 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FULFULDE_NIGERIA
},
523 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_IBIBIO_NIGERIA
},
525 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HAUSA_NIGERIA
, "ha" },
526 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_YORUBA_NIGERIA
, "yo" },
527 /* language codes from, to, are (still) unknown. */
528 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_IGBO_NIGERIA
, "ibo" },
529 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KANURI_NIGERIA
, "kau" },
530 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GUARANI_PARAGUAY
, "gn" },
531 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HAWAIIAN_UNITED_STATES
, "haw" },
532 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LATIN
, "la" },
533 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SOMALI_SOMALIA
, "so" },
535 /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */
536 /* not written (but OTOH the peculiar writing system is worth */
538 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_YI_CHINA
},
540 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES
,"pap" },
543 #define NUM_FC_FT_LANGUAGE (int) (sizeof (fcFtLanguage) / sizeof (fcFtLanguage[0]))
546 FT_UShort language_id
;
550 static const FcMacRomanFake fcMacRomanFake
[] = {
551 { TT_MS_LANGID_JAPANESE_JAPAN
, "SJIS-WIN" },
552 { TT_MS_LANGID_ENGLISH_UNITED_STATES
, "ASCII" },
556 FcFontCapabilities(FT_Face face
);
558 #define NUM_FC_MAC_ROMAN_FAKE (int) (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0]))
565 * A shift-JIS will have many high bits turned on
568 FcLooksLikeSJIS (FcChar8
*string
, int len
)
570 int nhigh
= 0, nlow
= 0;
574 if (*string
++ & 0x80) nhigh
++;
578 * Heuristic -- if more than 1/3 of the bytes have the high-bit set,
579 * this is likely to be SJIS and not ROMAN
581 if (nhigh
* 2 > nlow
)
587 FcSfntNameTranscode (FT_SfntName
*sname
)
590 const char *fromcode
;
596 for (i
= 0; i
< NUM_FC_FT_ENCODING
; i
++)
597 if (fcFtEncoding
[i
].platform_id
== sname
->platform_id
&&
598 (fcFtEncoding
[i
].encoding_id
== TT_ENCODING_DONT_CARE
||
599 fcFtEncoding
[i
].encoding_id
== sname
->encoding_id
))
601 if (i
== NUM_FC_FT_ENCODING
)
603 fromcode
= fcFtEncoding
[i
].fromcode
;
606 * Many names encoded for TT_PLATFORM_MACINTOSH are broken
607 * in various ways. Kludge around them.
609 if (!strcmp (fromcode
, FC_ENCODING_MAC_ROMAN
))
611 if (sname
->language_id
== TT_MAC_LANGID_ENGLISH
&&
612 FcLooksLikeSJIS (sname
->string
, sname
->string_len
))
616 else if (sname
->language_id
>= 0x100)
619 * "real" Mac language IDs are all less than 150.
620 * Names using one of the MS language IDs are assumed
621 * to use an associated encoding (Yes, this is a kludge)
626 for (f
= 0; f
< NUM_FC_MAC_ROMAN_FAKE
; f
++)
627 if (fcMacRomanFake
[f
].language_id
== sname
->language_id
)
629 fromcode
= fcMacRomanFake
[f
].fromcode
;
636 if (!strcmp (fromcode
, "UCS-2BE") || !strcmp (fromcode
, "UTF-16BE"))
638 FcChar8
*src
= sname
->string
;
639 int src_len
= sname
->string_len
;
647 * Convert Utf16 to Utf8
650 if (!FcUtf16Len (src
, FcEndianBig
, src_len
, &len
, &wchar
))
654 * Allocate plenty of space. Freed below
656 utf8
= malloc (len
* FC_UTF8_MAX_LEN
+ 1);
662 while ((ilen
= FcUtf16ToUcs4 (src
, FcEndianBig
, &ucs4
, src_len
)) > 0)
666 olen
= FcUcs4ToUtf8 (ucs4
, u8
);
672 if (!strcmp (fromcode
, "ASCII") || !strcmp (fromcode
, "ISO-8859-1"))
674 FcChar8
*src
= sname
->string
;
675 int src_len
= sname
->string_len
;
681 * Convert Latin1 to Utf8. Freed below
683 utf8
= malloc (src_len
* 2 + 1);
692 olen
= FcUcs4ToUtf8 (ucs4
, u8
);
698 if (!strcmp (fromcode
, FC_ENCODING_MAC_ROMAN
))
701 const FcCharMap
*map
= FcFreeTypeGetPrivateMap (ft_encoding_apple_roman
);
702 FcChar8
*src
= (FcChar8
*) sname
->string
;
703 int src_len
= sname
->string_len
;
706 * Convert AppleRoman to Utf8
711 utf8
= malloc (sname
->string_len
* 3 + 1);
718 FcChar32 ucs4
= FcFreeTypePrivateToUcs4 (*src
++, map
);
719 int olen
= FcUcs4ToUtf8 (ucs4
, u8
);
727 cd
= iconv_open ("UTF-8", fromcode
);
728 if (cd
&& cd
!= (iconv_t
) (-1))
730 size_t in_bytes_left
= sname
->string_len
;
731 size_t out_bytes_left
= sname
->string_len
* FC_UTF8_MAX_LEN
;
732 char *inbuf
, *outbuf
;
734 utf8
= malloc (out_bytes_left
+ 1);
741 outbuf
= (char *) utf8
;
742 inbuf
= (char *) sname
->string
;
744 while (in_bytes_left
)
746 size_t did
= iconv (cd
,
747 &inbuf
, &in_bytes_left
,
748 &outbuf
, &out_bytes_left
);
749 if (did
== (size_t) (-1))
763 if (FcStrCmpIgnoreBlanksAndCase (utf8
, (FcChar8
*) "") == 0)
771 static const FcChar8
*
772 FcSfntNameLanguage (FT_SfntName
*sname
)
775 FT_UShort platform_id
= sname
->platform_id
;
776 FT_UShort language_id
= sname
->language_id
;
779 * Many names encoded for TT_PLATFORM_MACINTOSH are broken
780 * in various ways. Kludge around them.
782 if (platform_id
== TT_PLATFORM_MACINTOSH
&&
783 sname
->encoding_id
== TT_MAC_ID_ROMAN
&&
784 FcLooksLikeSJIS (sname
->string
, sname
->string_len
))
786 language_id
= TT_MAC_LANGID_JAPANESE
;
789 for (i
= 0; i
< NUM_FC_FT_LANGUAGE
; i
++)
790 if (fcFtLanguage
[i
].platform_id
== platform_id
&&
791 (fcFtLanguage
[i
].language_id
== TT_LANGUAGE_DONT_CARE
||
792 fcFtLanguage
[i
].language_id
== language_id
))
794 if (fcFtLanguage
[i
].lang
[0] == '\0')
797 return (FcChar8
*) fcFtLanguage
[i
].lang
;
802 /* Order is significant. For example, some B&H fonts are hinted by
803 URW++, and both strings appear in the notice. */
805 static const char notice_foundry_data
[] =
808 "Bitstream\0bitstream\0"
809 "Monotype\0monotype\0"
810 "Linotype\0linotype\0"
811 "LINOTYPE-HELL\0linotype\0"
814 "International Typeface Corporation\0itc\0"
815 "Tiro Typeworks\0tiro\0"
817 "Microsoft\0microsoft\0"
820 "HanYang System\0hanyang";
822 struct _notice_foundry
{
823 /* these are the offsets into the
824 * notice_foundry_data array.
826 unsigned char notice_offset
;
827 unsigned char foundry_offset
;
830 static const struct _notice_foundry FcNoticeFoundries
[] = {
848 #define NUM_NOTICE_FOUNDRIES (int) (sizeof (FcNoticeFoundries) / sizeof (FcNoticeFoundries[0]))
850 static const FcChar8
*
851 FcNoticeFoundry(const FT_String
*notice
)
856 for(i
= 0; i
< NUM_NOTICE_FOUNDRIES
; i
++)
858 const struct _notice_foundry
*nf
= &FcNoticeFoundries
[i
];
859 const char *n
= notice_foundry_data
+ nf
->notice_offset
;
860 const char *f
= notice_foundry_data
+ nf
->foundry_offset
;
862 if (strstr ((const char *) notice
, n
))
863 return (const FcChar8
*) f
;
869 FcVendorMatch(const FT_Char vendor
[4], const FT_Char
*vendor_string
)
871 /* vendor is not necessarily NUL-terminated. */
874 len
= strlen((char *) vendor_string
);
875 if (memcmp(vendor
, vendor_string
, len
) != 0)
877 for (i
= len
; i
< 4; i
++)
878 if (vendor
[i
] != ' ' && vendor
[i
] != '\0')
883 /* This table is partly taken from ttmkfdir by Joerg Pommnitz. */
885 /* It should not contain useless entries (such as UNKN) nor duplicate
886 entries for padding both with spaces and NULs. */
888 static const struct {
889 const FT_Char vendor
[5];
890 const FcChar8 foundry
[13];
891 } FcVendorFoundries
[] = {
897 { "ATEC", "alltype"},
899 { "BITS", "bitstream"},
901 { "DYNA", "dynalab"},
906 { "IMPR", "impress"},
907 { "LARA", "larabiefonts"},
908 { "LEAF", "interleaf"},
909 { "LETR", "letraset"},
910 { "LINO", "linotype"},
911 { "MACR", "macromedia"},
912 { "MONO", "monotype"},
913 { "MS", "microsoft"},
916 { "PARA", "paratype"},
923 #define NUM_VENDOR_FOUNDRIES (int) (sizeof (FcVendorFoundries) / sizeof (FcVendorFoundries[0]))
925 static const FcChar8
*
926 FcVendorFoundry(const FT_Char vendor
[4])
931 for(i
= 0; i
< NUM_VENDOR_FOUNDRIES
; i
++)
932 if (FcVendorMatch (vendor
, FcVendorFoundries
[i
].vendor
))
933 return FcVendorFoundries
[i
].foundry
;
937 typedef struct _FcStringConst
{
943 FcStringIsConst (const FcChar8
*string
,
944 const FcStringConst
*c
,
949 for (i
= 0; i
< nc
; i
++)
950 if (FcStrCmpIgnoreBlanksAndCase (string
, c
[i
].name
) == 0)
956 FcStringContainsConst (const FcChar8
*string
,
957 const FcStringConst
*c
,
962 for (i
= 0; i
< nc
; i
++)
964 if (c
[i
].name
[0] == '<')
966 if (FcStrContainsWord (string
, c
[i
].name
+ 1))
971 if (FcStrContainsIgnoreBlanksAndCase (string
, c
[i
].name
))
978 typedef FcChar8
*FC8
;
980 static const FcStringConst weightConsts
[] = {
981 { (FC8
) "thin", FC_WEIGHT_THIN
},
982 { (FC8
) "extralight", FC_WEIGHT_EXTRALIGHT
},
983 { (FC8
) "ultralight", FC_WEIGHT_ULTRALIGHT
},
984 { (FC8
) "light", FC_WEIGHT_LIGHT
},
985 { (FC8
) "book", FC_WEIGHT_BOOK
},
986 { (FC8
) "regular", FC_WEIGHT_REGULAR
},
987 { (FC8
) "normal", FC_WEIGHT_NORMAL
},
988 { (FC8
) "medium", FC_WEIGHT_MEDIUM
},
989 { (FC8
) "demibold", FC_WEIGHT_DEMIBOLD
},
990 { (FC8
) "demi", FC_WEIGHT_DEMIBOLD
},
991 { (FC8
) "semibold", FC_WEIGHT_SEMIBOLD
},
992 { (FC8
) "extrabold", FC_WEIGHT_EXTRABOLD
},
993 { (FC8
) "superbold", FC_WEIGHT_EXTRABOLD
},
994 { (FC8
) "ultrabold", FC_WEIGHT_ULTRABOLD
},
995 { (FC8
) "bold", FC_WEIGHT_BOLD
},
996 { (FC8
) "ultrablack", FC_WEIGHT_ULTRABLACK
},
997 { (FC8
) "superblack", FC_WEIGHT_EXTRABLACK
},
998 { (FC8
) "extrablack", FC_WEIGHT_EXTRABLACK
},
999 { (FC8
) "<ultra", FC_WEIGHT_ULTRABOLD
}, /* only if a word */
1000 { (FC8
) "black", FC_WEIGHT_BLACK
},
1001 { (FC8
) "heavy", FC_WEIGHT_HEAVY
},
1004 #define NUM_WEIGHT_CONSTS (int) (sizeof (weightConsts) / sizeof (weightConsts[0]))
1006 #define FcIsWeight(s) FcStringIsConst(s,weightConsts,NUM_WEIGHT_CONSTS)
1007 #define FcContainsWeight(s) FcStringContainsConst (s,weightConsts,NUM_WEIGHT_CONSTS)
1009 static const FcStringConst widthConsts
[] = {
1010 { (FC8
) "ultracondensed", FC_WIDTH_ULTRACONDENSED
},
1011 { (FC8
) "extracondensed", FC_WIDTH_EXTRACONDENSED
},
1012 { (FC8
) "semicondensed", FC_WIDTH_SEMICONDENSED
},
1013 { (FC8
) "condensed", FC_WIDTH_CONDENSED
}, /* must be after *condensed */
1014 { (FC8
) "normal", FC_WIDTH_NORMAL
},
1015 { (FC8
) "semiexpanded", FC_WIDTH_SEMIEXPANDED
},
1016 { (FC8
) "extraexpanded", FC_WIDTH_EXTRAEXPANDED
},
1017 { (FC8
) "ultraexpanded", FC_WIDTH_ULTRAEXPANDED
},
1018 { (FC8
) "expanded", FC_WIDTH_EXPANDED
}, /* must be after *expanded */
1019 { (FC8
) "extended", FC_WIDTH_EXPANDED
},
1022 #define NUM_WIDTH_CONSTS (int) (sizeof (widthConsts) / sizeof (widthConsts[0]))
1024 #define FcIsWidth(s) FcStringIsConst(s,widthConsts,NUM_WIDTH_CONSTS)
1025 #define FcContainsWidth(s) FcStringContainsConst (s,widthConsts,NUM_WIDTH_CONSTS)
1027 static const FcStringConst slantConsts
[] = {
1028 { (FC8
) "italic", FC_SLANT_ITALIC
},
1029 { (FC8
) "kursiv", FC_SLANT_ITALIC
},
1030 { (FC8
) "oblique", FC_SLANT_OBLIQUE
},
1033 #define NUM_SLANT_CONSTS (int) (sizeof (slantConsts) / sizeof (slantConsts[0]))
1035 #define FcIsSlant(s) FcStringIsConst(s,slantConsts,NUM_SLANT_CONSTS)
1036 #define FcContainsSlant(s) FcStringContainsConst (s,slantConsts,NUM_SLANT_CONSTS)
1038 static const FcStringConst decorativeConsts
[] = {
1039 { (FC8
) "shadow", FcTrue
},
1040 { (FC8
) "caps", FcTrue
},
1041 { (FC8
) "antiqua", FcTrue
},
1042 { (FC8
) "romansc", FcTrue
},
1043 { (FC8
) "embosed", FcTrue
},
1044 { (FC8
) "dunhill", FcTrue
},
1047 #define NUM_DECORATIVE_CONSTS (int) (sizeof (decorativeConsts) / sizeof (decorativeConsts[0]))
1049 #define FcIsDecorative(s) FcStringIsConst(s,decorativeConsts,NUM_DECORATIVE_CONSTS)
1050 #define FcContainsDecorative(s) FcStringContainsConst (s,decorativeConsts,NUM_DECORATIVE_CONSTS)
1053 FcGetPixelSize (FT_Face face
, int i
)
1055 #if HAVE_FT_GET_BDF_PROPERTY
1056 if (face
->num_fixed_sizes
== 1)
1058 BDF_PropertyRec prop
;
1061 rc
= FT_Get_BDF_Property (face
, "PIXEL_SIZE", &prop
);
1062 if (rc
== 0 && prop
.type
== BDF_PROPERTY_TYPE_INTEGER
)
1063 return (double) prop
.u
.integer
;
1066 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
1067 return (double) face
->available_sizes
[i
].y_ppem
/ 64.0;
1069 return (double) face
->available_sizes
[i
].height
;
1074 FcStringInPatternElement (FcPattern
*pat
, const char *elt
, FcChar8
*string
)
1078 for (e
= 0; FcPatternGetString (pat
, elt
, e
, &old
) == FcResultMatch
; e
++)
1079 if (!FcStrCmpIgnoreBlanksAndCase (old
, string
))
1086 static const FT_UShort platform_order
[] = {
1087 TT_PLATFORM_MICROSOFT
,
1088 TT_PLATFORM_APPLE_UNICODE
,
1089 TT_PLATFORM_MACINTOSH
,
1091 #define NUM_PLATFORM_ORDER (sizeof (platform_order) / sizeof (platform_order[0]))
1093 static const FT_UShort nameid_order
[] = {
1094 TT_NAME_ID_PREFERRED_FAMILY
,
1095 TT_NAME_ID_FONT_FAMILY
,
1096 TT_NAME_ID_MAC_FULL_NAME
,
1097 TT_NAME_ID_FULL_NAME
,
1098 TT_NAME_ID_PREFERRED_SUBFAMILY
,
1099 TT_NAME_ID_FONT_SUBFAMILY
,
1100 TT_NAME_ID_TRADEMARK
,
1101 TT_NAME_ID_MANUFACTURER
,
1104 #define NUM_NAMEID_ORDER (sizeof (nameid_order) / sizeof (nameid_order[0]))
1106 FcFreeTypeQueryFace (const FT_Face face
,
1107 const FcChar8
*file
,
1115 FcBool decorative
= FcFalse
;
1120 FcChar8
*family
= 0;
1123 const FcChar8
*foundry
= 0;
1126 #if HAVE_FT_GET_PS_FONT_INFO
1127 PS_FontInfoRec psfontinfo
;
1129 #if HAVE_FT_GET_BDF_PROPERTY
1130 BDF_PropertyRec prop
;
1133 const FcChar8
*exclusiveLang
= 0;
1135 FT_UInt snamei
, snamec
;
1138 int nfamily_lang
= 0;
1140 int nstyle_lang
= 0;
1142 int nfullname_lang
= 0;
1149 pat
= FcPatternCreate ();
1153 if (!FcPatternAddBool (pat
, FC_OUTLINE
,
1154 (face
->face_flags
& FT_FACE_FLAG_SCALABLE
) != 0))
1157 if (!FcPatternAddBool (pat
, FC_SCALABLE
,
1158 (face
->face_flags
& FT_FACE_FLAG_SCALABLE
) != 0))
1163 * Get the OS/2 table
1165 os2
= (TT_OS2
*) FT_Get_Sfnt_Table (face
, ft_sfnt_os2
);
1168 * Look first in the OS/2 table for the foundry, if
1169 * not found here, the various notices will be searched for
1170 * that information, either from the sfnt name tables or
1171 * the Postscript FontInfo dictionary. Finally, the
1172 * BDF properties will queried.
1175 if (os2
&& os2
->version
>= 0x0001 && os2
->version
!= 0xffff)
1176 foundry
= FcVendorFoundry(os2
->achVendID
);
1178 if (FcDebug () & FC_DBG_SCANV
)
1181 * Grub through the name table looking for family
1182 * and style names. FreeType makes quite a hash
1185 snamec
= FT_Get_Sfnt_Name_Count (face
);
1186 for (p
= 0; p
<= NUM_PLATFORM_ORDER
; p
++)
1188 if (p
< NUM_PLATFORM_ORDER
)
1189 platform
= platform_order
[p
];
1194 * Order nameids so preferred names appear first
1195 * in the resulting list
1197 for (n
= 0; n
< NUM_NAMEID_ORDER
; n
++)
1199 nameid
= nameid_order
[n
];
1201 for (snamei
= 0; snamei
< snamec
; snamei
++)
1204 const FcChar8
*lang
;
1205 const char *elt
= 0, *eltlang
= 0;
1206 int *np
= 0, *nlangp
= 0;
1208 if (FT_Get_Sfnt_Name (face
, snamei
, &sname
) != 0)
1210 if (sname
.name_id
!= nameid
)
1214 * Sort platforms in preference order, accepting
1215 * all other platforms last
1217 if (p
< NUM_PLATFORM_ORDER
)
1219 if (sname
.platform_id
!= platform
)
1226 for (sp
= 0; sp
< NUM_PLATFORM_ORDER
; sp
++)
1227 if (sname
.platform_id
== platform_order
[sp
])
1229 if (sp
!= NUM_PLATFORM_ORDER
)
1232 utf8
= FcSfntNameTranscode (&sname
);
1233 lang
= FcSfntNameLanguage (&sname
);
1238 switch (sname
.name_id
) {
1239 case TT_NAME_ID_PREFERRED_FAMILY
:
1240 case TT_NAME_ID_FONT_FAMILY
:
1242 case TT_NAME_ID_PS_NAME
:
1243 case TT_NAME_ID_UNIQUE_ID
:
1245 if (FcDebug () & FC_DBG_SCANV
)
1246 printf ("found family (n %2d p %d e %d l 0x%04x) %s\n",
1247 sname
.name_id
, sname
.platform_id
,
1248 sname
.encoding_id
, sname
.language_id
,
1252 eltlang
= FC_FAMILYLANG
;
1254 nlangp
= &nfamily_lang
;
1256 case TT_NAME_ID_MAC_FULL_NAME
:
1257 case TT_NAME_ID_FULL_NAME
:
1258 if (FcDebug () & FC_DBG_SCANV
)
1259 printf ("found full (n %2d p %d e %d l 0x%04x) %s\n",
1260 sname
.name_id
, sname
.platform_id
,
1261 sname
.encoding_id
, sname
.language_id
,
1265 eltlang
= FC_FULLNAMELANG
;
1267 nlangp
= &nfullname_lang
;
1269 case TT_NAME_ID_PREFERRED_SUBFAMILY
:
1270 case TT_NAME_ID_FONT_SUBFAMILY
:
1271 if (FcDebug () & FC_DBG_SCANV
)
1272 printf ("found style (n %2d p %d e %d l 0x%04x) %s\n",
1273 sname
.name_id
, sname
.platform_id
,
1274 sname
.encoding_id
, sname
.language_id
,
1278 eltlang
= FC_STYLELANG
;
1280 nlangp
= &nstyle_lang
;
1282 case TT_NAME_ID_TRADEMARK
:
1283 case TT_NAME_ID_MANUFACTURER
:
1284 /* If the foundry wasn't found in the OS/2 table, look here */
1286 foundry
= FcNoticeFoundry((FT_String
*) utf8
);
1291 if (FcStringInPatternElement (pat
, elt
, utf8
))
1297 /* add new element */
1298 if (!FcPatternAddString (pat
, elt
, utf8
))
1306 /* pad lang list with 'xx' to line up with elt */
1307 while (*nlangp
< *np
)
1309 if (!FcPatternAddString (pat
, eltlang
, (FcChar8
*) "xx"))
1313 if (!FcPatternAddString (pat
, eltlang
, lang
))
1325 if (!nfamily
&& face
->family_name
&&
1326 FcStrCmpIgnoreBlanksAndCase ((FcChar8
*) face
->family_name
, (FcChar8
*) "") != 0)
1328 if (FcDebug () & FC_DBG_SCANV
)
1329 printf ("using FreeType family \"%s\"\n", face
->family_name
);
1330 if (!FcPatternAddString (pat
, FC_FAMILY
, (FcChar8
*) face
->family_name
))
1335 if (!nstyle
&& face
->style_name
&&
1336 FcStrCmpIgnoreBlanksAndCase ((FcChar8
*) face
->style_name
, (FcChar8
*) "") != 0)
1338 if (FcDebug () & FC_DBG_SCANV
)
1339 printf ("using FreeType style \"%s\"\n", face
->style_name
);
1340 if (!FcPatternAddString (pat
, FC_STYLE
, (FcChar8
*) face
->style_name
))
1347 FcChar8
*start
, *end
;
1350 start
= (FcChar8
*) strrchr ((char *) file
, '/');
1354 start
= (FcChar8
*) file
;
1355 end
= (FcChar8
*) strrchr ((char *) start
, '.');
1357 end
= start
+ strlen ((char *) start
);
1359 family
= malloc (end
- start
+ 1);
1360 strncpy ((char *) family
, (char *) start
, end
- start
);
1361 family
[end
- start
] = '\0';
1362 if (FcDebug () & FC_DBG_SCANV
)
1363 printf ("using filename for family %s\n", family
);
1364 if (!FcPatternAddString (pat
, FC_FAMILY
, family
))
1373 if (!FcPatternAddString (pat
, FC_FILE
, file
))
1376 if (!FcPatternAddInteger (pat
, FC_INDEX
, id
))
1381 * don't even try this -- CJK 'monospace' fonts are really
1382 * dual width, and most other fonts don't bother to set
1383 * the attribute. Sigh.
1385 if ((face
->face_flags
& FT_FACE_FLAG_FIXED_WIDTH
) != 0)
1386 if (!FcPatternAddInteger (pat
, FC_SPACING
, FC_MONO
))
1391 * Find the font revision (if available)
1393 head
= (TT_Header
*) FT_Get_Sfnt_Table (face
, ft_sfnt_head
);
1396 if (!FcPatternAddInteger (pat
, FC_FONTVERSION
, head
->Font_Revision
))
1401 if (!FcPatternAddInteger (pat
, FC_FONTVERSION
, 0))
1405 if (os2
&& os2
->version
>= 0x0001 && os2
->version
!= 0xffff)
1407 for (i
= 0; i
< NUM_CODE_PAGE_RANGE
; i
++)
1411 if (FcCodePageRange
[i
].bit
< 32)
1413 bits
= os2
->ulCodePageRange1
;
1414 bit
= FcCodePageRange
[i
].bit
;
1418 bits
= os2
->ulCodePageRange2
;
1419 bit
= FcCodePageRange
[i
].bit
- 32;
1421 if (bits
& (1 << bit
))
1424 * If the font advertises support for multiple
1425 * "exclusive" languages, then include support
1426 * for any language found to have coverage
1433 exclusiveLang
= FcCodePageRange
[i
].lang
;
1438 if (os2
&& os2
->version
!= 0xffff)
1440 if (os2
->usWeightClass
== 0)
1442 else if (os2
->usWeightClass
< 150)
1443 weight
= FC_WEIGHT_THIN
;
1444 else if (os2
->usWeightClass
< 250)
1445 weight
= FC_WEIGHT_EXTRALIGHT
;
1446 else if (os2
->usWeightClass
< 350)
1447 weight
= FC_WEIGHT_LIGHT
;
1448 else if (os2
->usWeightClass
< 450)
1449 weight
= FC_WEIGHT_REGULAR
;
1450 else if (os2
->usWeightClass
< 550)
1451 weight
= FC_WEIGHT_MEDIUM
;
1452 else if (os2
->usWeightClass
< 650)
1453 weight
= FC_WEIGHT_SEMIBOLD
;
1454 else if (os2
->usWeightClass
< 750)
1455 weight
= FC_WEIGHT_BOLD
;
1456 else if (os2
->usWeightClass
< 850)
1457 weight
= FC_WEIGHT_EXTRABOLD
;
1458 else if (os2
->usWeightClass
< 925)
1459 weight
= FC_WEIGHT_BLACK
;
1460 else if (os2
->usWeightClass
< 1000)
1461 weight
= FC_WEIGHT_EXTRABLACK
;
1462 if ((FcDebug() & FC_DBG_SCANV
) && weight
!= -1)
1463 printf ("\tos2 weight class %d maps to weight %d\n",
1464 os2
->usWeightClass
, weight
);
1466 switch (os2
->usWidthClass
) {
1467 case 1: width
= FC_WIDTH_ULTRACONDENSED
; break;
1468 case 2: width
= FC_WIDTH_EXTRACONDENSED
; break;
1469 case 3: width
= FC_WIDTH_CONDENSED
; break;
1470 case 4: width
= FC_WIDTH_SEMICONDENSED
; break;
1471 case 5: width
= FC_WIDTH_NORMAL
; break;
1472 case 6: width
= FC_WIDTH_SEMIEXPANDED
; break;
1473 case 7: width
= FC_WIDTH_EXPANDED
; break;
1474 case 8: width
= FC_WIDTH_EXTRAEXPANDED
; break;
1475 case 9: width
= FC_WIDTH_ULTRAEXPANDED
; break;
1477 if ((FcDebug() & FC_DBG_SCANV
) && width
!= -1)
1478 printf ("\tos2 width class %d maps to width %d\n",
1479 os2
->usWidthClass
, width
);
1481 if (os2
&& (complex = FcFontCapabilities(face
)))
1483 if (!FcPatternAddString (pat
, FC_CAPABILITY
, complex))
1492 * Type 1: Check for FontInfo dictionary information
1493 * Code from g2@magestudios.net (Gerard Escalante)
1496 #if HAVE_FT_GET_PS_FONT_INFO
1497 if (FT_Get_PS_Font_Info(face
, &psfontinfo
) == 0)
1499 if (weight
== -1 && psfontinfo
.weight
)
1501 weight
= FcIsWeight ((FcChar8
*) psfontinfo
.weight
);
1502 if (FcDebug() & FC_DBG_SCANV
)
1503 printf ("\tType1 weight %s maps to %d\n",
1504 psfontinfo
.weight
, weight
);
1509 * Don't bother with italic_angle; FreeType already extracts that
1510 * information for us and sticks it into style_flags
1512 if (psfontinfo
.italic_angle
)
1513 slant
= FC_SLANT_ITALIC
;
1515 slant
= FC_SLANT_ROMAN
;
1519 foundry
= FcNoticeFoundry(psfontinfo
.notice
);
1521 #endif /* HAVE_FT_GET_PS_FONT_INFO */
1523 #if HAVE_FT_GET_BDF_PROPERTY
1525 * Finally, look for a FOUNDRY BDF property if no other
1526 * mechanism has managed to locate a foundry
1532 rc
= FT_Get_BDF_Property(face
, "FOUNDRY", &prop
);
1533 if(rc
== 0 && prop
.type
== BDF_PROPERTY_TYPE_ATOM
)
1534 foundry
= (FcChar8
*) prop
.u
.atom
;
1539 if (FT_Get_BDF_Property(face
, "RELATIVE_SETWIDTH", &prop
) == 0 &&
1540 (prop
.type
== BDF_PROPERTY_TYPE_INTEGER
||
1541 prop
.type
== BDF_PROPERTY_TYPE_CARDINAL
))
1545 if (prop
.type
== BDF_PROPERTY_TYPE_INTEGER
)
1546 value
= prop
.u
.integer
;
1548 value
= (FT_Int32
) prop
.u
.cardinal
;
1549 switch ((value
+ 5) / 10) {
1550 case 1: width
= FC_WIDTH_ULTRACONDENSED
; break;
1551 case 2: width
= FC_WIDTH_EXTRACONDENSED
; break;
1552 case 3: width
= FC_WIDTH_CONDENSED
; break;
1553 case 4: width
= FC_WIDTH_SEMICONDENSED
; break;
1554 case 5: width
= FC_WIDTH_NORMAL
; break;
1555 case 6: width
= FC_WIDTH_SEMIEXPANDED
; break;
1556 case 7: width
= FC_WIDTH_EXPANDED
; break;
1557 case 8: width
= FC_WIDTH_EXTRAEXPANDED
; break;
1558 case 9: width
= FC_WIDTH_ULTRAEXPANDED
; break;
1562 FT_Get_BDF_Property (face
, "SETWIDTH_NAME", &prop
) == 0 &&
1563 prop
.type
== BDF_PROPERTY_TYPE_ATOM
)
1565 width
= FcIsWidth ((FcChar8
*) prop
.u
.atom
);
1566 if (FcDebug () & FC_DBG_SCANV
)
1567 printf ("\tsetwidth %s maps to %d\n", prop
.u
.atom
, width
);
1573 * Look for weight, width and slant names in the style value
1575 for (st
= 0; FcPatternGetString (pat
, FC_STYLE
, st
, &style
) == FcResultMatch
; st
++)
1579 weight
= FcContainsWeight (style
);
1580 if (FcDebug() & FC_DBG_SCANV
)
1581 printf ("\tStyle %s maps to weight %d\n", style
, weight
);
1585 width
= FcContainsWidth (style
);
1586 if (FcDebug() & FC_DBG_SCANV
)
1587 printf ("\tStyle %s maps to width %d\n", style
, width
);
1591 slant
= FcContainsSlant (style
);
1592 if (FcDebug() & FC_DBG_SCANV
)
1593 printf ("\tStyle %s maps to slant %d\n", style
, slant
);
1595 if (decorative
== FcFalse
)
1597 decorative
= FcContainsDecorative (style
) > 0;
1598 if (FcDebug() & FC_DBG_SCANV
)
1599 printf ("\tStyle %s maps to decorative %d\n", style
, decorative
);
1603 * Pull default values from the FreeType flags if more
1604 * specific values not found above
1608 slant
= FC_SLANT_ROMAN
;
1609 if (face
->style_flags
& FT_STYLE_FLAG_ITALIC
)
1610 slant
= FC_SLANT_ITALIC
;
1615 weight
= FC_WEIGHT_MEDIUM
;
1616 if (face
->style_flags
& FT_STYLE_FLAG_BOLD
)
1617 weight
= FC_WEIGHT_BOLD
;
1621 width
= FC_WIDTH_NORMAL
;
1624 foundry
= (FcChar8
*) "unknown";
1626 if (!FcPatternAddInteger (pat
, FC_SLANT
, slant
))
1629 if (!FcPatternAddInteger (pat
, FC_WEIGHT
, weight
))
1632 if (!FcPatternAddInteger (pat
, FC_WIDTH
, width
))
1635 if (!FcPatternAddString (pat
, FC_FOUNDRY
, foundry
))
1638 if (!FcPatternAddBool (pat
, FC_DECORATIVE
, decorative
))
1642 * Compute the unicode coverage for the font
1644 cs
= FcFreeTypeCharSetAndSpacing (face
, blanks
, &spacing
);
1648 #if HAVE_FT_GET_BDF_PROPERTY
1649 /* For PCF fonts, override the computed spacing with the one from
1651 if(FT_Get_BDF_Property(face
, "SPACING", &prop
) == 0 &&
1652 prop
.type
== BDF_PROPERTY_TYPE_ATOM
) {
1653 if(!strcmp(prop
.u
.atom
, "c") || !strcmp(prop
.u
.atom
, "C"))
1654 spacing
= FC_CHARCELL
;
1655 else if(!strcmp(prop
.u
.atom
, "m") || !strcmp(prop
.u
.atom
, "M"))
1657 else if(!strcmp(prop
.u
.atom
, "p") || !strcmp(prop
.u
.atom
, "P"))
1658 spacing
= FC_PROPORTIONAL
;
1663 * Skip over PCF fonts that have no encoded characters; they're
1664 * usually just Unicode fonts transcoded to some legacy encoding
1665 * ftglue.c forces us to approximate whether a font is a PCF font
1666 * or not by whether it has any BDF properties. Try PIXEL_SIZE;
1667 * I don't know how to get a list of BDF properties on the font. -PL
1669 if (FcCharSetCount (cs
) == 0)
1671 #if HAVE_FT_GET_BDF_PROPERTY
1672 if(FT_Get_BDF_Property(face
, "PIXEL_SIZE", &prop
) == 0)
1677 if (!FcPatternAddCharSet (pat
, FC_CHARSET
, cs
))
1680 ls
= FcFreeTypeLangSet (cs
, exclusiveLang
);
1684 if (!FcPatternAddLangSet (pat
, FC_LANG
, ls
))
1686 FcLangSetDestroy (ls
);
1690 FcLangSetDestroy (ls
);
1692 if (spacing
!= FC_PROPORTIONAL
)
1693 if (!FcPatternAddInteger (pat
, FC_SPACING
, spacing
))
1696 if (!(face
->face_flags
& FT_FACE_FLAG_SCALABLE
))
1698 for (i
= 0; i
< face
->num_fixed_sizes
; i
++)
1699 if (!FcPatternAddDouble (pat
, FC_PIXEL_SIZE
,
1700 FcGetPixelSize (face
, i
)))
1702 if (!FcPatternAddBool (pat
, FC_ANTIALIAS
, FcFalse
))
1705 #if HAVE_FT_GET_X11_FONT_FORMAT
1707 * Use the (not well documented or supported) X-specific function
1708 * from FreeType to figure out the font format
1711 const char *font_format
= FT_Get_X11_Font_Format (face
);
1713 FcPatternAddString (pat
, FC_FONTFORMAT
, (FcChar8
*) font_format
);
1718 * Drop our reference to the charset
1720 FcCharSetDestroy (cs
);
1725 FcCharSetDestroy (cs
);
1727 FcPatternDestroy (pat
);
1733 FcFreeTypeQuery(const FcChar8
*file
,
1739 FT_Library ftLibrary
;
1740 FcPattern
*pat
= NULL
;
1742 if (FT_Init_FreeType (&ftLibrary
))
1745 if (FT_New_Face (ftLibrary
, (char *) file
, id
, &face
))
1748 *count
= face
->num_faces
;
1750 pat
= FcFreeTypeQueryFace (face
, file
, id
, blanks
);
1752 FT_Done_Face (face
);
1754 FT_Done_FreeType (ftLibrary
);
1759 * For our purposes, this approximation is sufficient
1761 #if !HAVE_FT_GET_NEXT_CHAR
1762 #define FT_Get_Next_Char(face, ucs4, gi) ((ucs4) >= 0xffffff ? \
1764 (*(gi) = 1), (ucs4) + 1)
1765 #warning "No FT_Get_Next_Char: Please install freetype version 2.1.0 or newer"
1768 typedef struct _FcCharEnt
{
1770 unsigned char encode
;
1774 const FcCharEnt
*ent
;
1778 typedef struct _FcFontDecode
{
1779 FT_Encoding encoding
;
1780 const FcCharMap
*map
;
1784 static const FcCharEnt AppleRomanEnt
[] = {
1785 { 0x0020, 0x20 }, /* SPACE */
1786 { 0x0021, 0x21 }, /* EXCLAMATION MARK */
1787 { 0x0022, 0x22 }, /* QUOTATION MARK */
1788 { 0x0023, 0x23 }, /* NUMBER SIGN */
1789 { 0x0024, 0x24 }, /* DOLLAR SIGN */
1790 { 0x0025, 0x25 }, /* PERCENT SIGN */
1791 { 0x0026, 0x26 }, /* AMPERSAND */
1792 { 0x0027, 0x27 }, /* APOSTROPHE */
1793 { 0x0028, 0x28 }, /* LEFT PARENTHESIS */
1794 { 0x0029, 0x29 }, /* RIGHT PARENTHESIS */
1795 { 0x002A, 0x2A }, /* ASTERISK */
1796 { 0x002B, 0x2B }, /* PLUS SIGN */
1797 { 0x002C, 0x2C }, /* COMMA */
1798 { 0x002D, 0x2D }, /* HYPHEN-MINUS */
1799 { 0x002E, 0x2E }, /* FULL STOP */
1800 { 0x002F, 0x2F }, /* SOLIDUS */
1801 { 0x0030, 0x30 }, /* DIGIT ZERO */
1802 { 0x0031, 0x31 }, /* DIGIT ONE */
1803 { 0x0032, 0x32 }, /* DIGIT TWO */
1804 { 0x0033, 0x33 }, /* DIGIT THREE */
1805 { 0x0034, 0x34 }, /* DIGIT FOUR */
1806 { 0x0035, 0x35 }, /* DIGIT FIVE */
1807 { 0x0036, 0x36 }, /* DIGIT SIX */
1808 { 0x0037, 0x37 }, /* DIGIT SEVEN */
1809 { 0x0038, 0x38 }, /* DIGIT EIGHT */
1810 { 0x0039, 0x39 }, /* DIGIT NINE */
1811 { 0x003A, 0x3A }, /* COLON */
1812 { 0x003B, 0x3B }, /* SEMICOLON */
1813 { 0x003C, 0x3C }, /* LESS-THAN SIGN */
1814 { 0x003D, 0x3D }, /* EQUALS SIGN */
1815 { 0x003E, 0x3E }, /* GREATER-THAN SIGN */
1816 { 0x003F, 0x3F }, /* QUESTION MARK */
1817 { 0x0040, 0x40 }, /* COMMERCIAL AT */
1818 { 0x0041, 0x41 }, /* LATIN CAPITAL LETTER A */
1819 { 0x0042, 0x42 }, /* LATIN CAPITAL LETTER B */
1820 { 0x0043, 0x43 }, /* LATIN CAPITAL LETTER C */
1821 { 0x0044, 0x44 }, /* LATIN CAPITAL LETTER D */
1822 { 0x0045, 0x45 }, /* LATIN CAPITAL LETTER E */
1823 { 0x0046, 0x46 }, /* LATIN CAPITAL LETTER F */
1824 { 0x0047, 0x47 }, /* LATIN CAPITAL LETTER G */
1825 { 0x0048, 0x48 }, /* LATIN CAPITAL LETTER H */
1826 { 0x0049, 0x49 }, /* LATIN CAPITAL LETTER I */
1827 { 0x004A, 0x4A }, /* LATIN CAPITAL LETTER J */
1828 { 0x004B, 0x4B }, /* LATIN CAPITAL LETTER K */
1829 { 0x004C, 0x4C }, /* LATIN CAPITAL LETTER L */
1830 { 0x004D, 0x4D }, /* LATIN CAPITAL LETTER M */
1831 { 0x004E, 0x4E }, /* LATIN CAPITAL LETTER N */
1832 { 0x004F, 0x4F }, /* LATIN CAPITAL LETTER O */
1833 { 0x0050, 0x50 }, /* LATIN CAPITAL LETTER P */
1834 { 0x0051, 0x51 }, /* LATIN CAPITAL LETTER Q */
1835 { 0x0052, 0x52 }, /* LATIN CAPITAL LETTER R */
1836 { 0x0053, 0x53 }, /* LATIN CAPITAL LETTER S */
1837 { 0x0054, 0x54 }, /* LATIN CAPITAL LETTER T */
1838 { 0x0055, 0x55 }, /* LATIN CAPITAL LETTER U */
1839 { 0x0056, 0x56 }, /* LATIN CAPITAL LETTER V */
1840 { 0x0057, 0x57 }, /* LATIN CAPITAL LETTER W */
1841 { 0x0058, 0x58 }, /* LATIN CAPITAL LETTER X */
1842 { 0x0059, 0x59 }, /* LATIN CAPITAL LETTER Y */
1843 { 0x005A, 0x5A }, /* LATIN CAPITAL LETTER Z */
1844 { 0x005B, 0x5B }, /* LEFT SQUARE BRACKET */
1845 { 0x005C, 0x5C }, /* REVERSE SOLIDUS */
1846 { 0x005D, 0x5D }, /* RIGHT SQUARE BRACKET */
1847 { 0x005E, 0x5E }, /* CIRCUMFLEX ACCENT */
1848 { 0x005F, 0x5F }, /* LOW LINE */
1849 { 0x0060, 0x60 }, /* GRAVE ACCENT */
1850 { 0x0061, 0x61 }, /* LATIN SMALL LETTER A */
1851 { 0x0062, 0x62 }, /* LATIN SMALL LETTER B */
1852 { 0x0063, 0x63 }, /* LATIN SMALL LETTER C */
1853 { 0x0064, 0x64 }, /* LATIN SMALL LETTER D */
1854 { 0x0065, 0x65 }, /* LATIN SMALL LETTER E */
1855 { 0x0066, 0x66 }, /* LATIN SMALL LETTER F */
1856 { 0x0067, 0x67 }, /* LATIN SMALL LETTER G */
1857 { 0x0068, 0x68 }, /* LATIN SMALL LETTER H */
1858 { 0x0069, 0x69 }, /* LATIN SMALL LETTER I */
1859 { 0x006A, 0x6A }, /* LATIN SMALL LETTER J */
1860 { 0x006B, 0x6B }, /* LATIN SMALL LETTER K */
1861 { 0x006C, 0x6C }, /* LATIN SMALL LETTER L */
1862 { 0x006D, 0x6D }, /* LATIN SMALL LETTER M */
1863 { 0x006E, 0x6E }, /* LATIN SMALL LETTER N */
1864 { 0x006F, 0x6F }, /* LATIN SMALL LETTER O */
1865 { 0x0070, 0x70 }, /* LATIN SMALL LETTER P */
1866 { 0x0071, 0x71 }, /* LATIN SMALL LETTER Q */
1867 { 0x0072, 0x72 }, /* LATIN SMALL LETTER R */
1868 { 0x0073, 0x73 }, /* LATIN SMALL LETTER S */
1869 { 0x0074, 0x74 }, /* LATIN SMALL LETTER T */
1870 { 0x0075, 0x75 }, /* LATIN SMALL LETTER U */
1871 { 0x0076, 0x76 }, /* LATIN SMALL LETTER V */
1872 { 0x0077, 0x77 }, /* LATIN SMALL LETTER W */
1873 { 0x0078, 0x78 }, /* LATIN SMALL LETTER X */
1874 { 0x0079, 0x79 }, /* LATIN SMALL LETTER Y */
1875 { 0x007A, 0x7A }, /* LATIN SMALL LETTER Z */
1876 { 0x007B, 0x7B }, /* LEFT CURLY BRACKET */
1877 { 0x007C, 0x7C }, /* VERTICAL LINE */
1878 { 0x007D, 0x7D }, /* RIGHT CURLY BRACKET */
1879 { 0x007E, 0x7E }, /* TILDE */
1880 { 0x00A0, 0xCA }, /* NO-BREAK SPACE */
1881 { 0x00A1, 0xC1 }, /* INVERTED EXCLAMATION MARK */
1882 { 0x00A2, 0xA2 }, /* CENT SIGN */
1883 { 0x00A3, 0xA3 }, /* POUND SIGN */
1884 { 0x00A5, 0xB4 }, /* YEN SIGN */
1885 { 0x00A7, 0xA4 }, /* SECTION SIGN */
1886 { 0x00A8, 0xAC }, /* DIAERESIS */
1887 { 0x00A9, 0xA9 }, /* COPYRIGHT SIGN */
1888 { 0x00AA, 0xBB }, /* FEMININE ORDINAL INDICATOR */
1889 { 0x00AB, 0xC7 }, /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
1890 { 0x00AC, 0xC2 }, /* NOT SIGN */
1891 { 0x00AE, 0xA8 }, /* REGISTERED SIGN */
1892 { 0x00AF, 0xF8 }, /* MACRON */
1893 { 0x00B0, 0xA1 }, /* DEGREE SIGN */
1894 { 0x00B1, 0xB1 }, /* PLUS-MINUS SIGN */
1895 { 0x00B4, 0xAB }, /* ACUTE ACCENT */
1896 { 0x00B5, 0xB5 }, /* MICRO SIGN */
1897 { 0x00B6, 0xA6 }, /* PILCROW SIGN */
1898 { 0x00B7, 0xE1 }, /* MIDDLE DOT */
1899 { 0x00B8, 0xFC }, /* CEDILLA */
1900 { 0x00BA, 0xBC }, /* MASCULINE ORDINAL INDICATOR */
1901 { 0x00BB, 0xC8 }, /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
1902 { 0x00BF, 0xC0 }, /* INVERTED QUESTION MARK */
1903 { 0x00C0, 0xCB }, /* LATIN CAPITAL LETTER A WITH GRAVE */
1904 { 0x00C1, 0xE7 }, /* LATIN CAPITAL LETTER A WITH ACUTE */
1905 { 0x00C2, 0xE5 }, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
1906 { 0x00C3, 0xCC }, /* LATIN CAPITAL LETTER A WITH TILDE */
1907 { 0x00C4, 0x80 }, /* LATIN CAPITAL LETTER A WITH DIAERESIS */
1908 { 0x00C5, 0x81 }, /* LATIN CAPITAL LETTER A WITH RING ABOVE */
1909 { 0x00C6, 0xAE }, /* LATIN CAPITAL LETTER AE */
1910 { 0x00C7, 0x82 }, /* LATIN CAPITAL LETTER C WITH CEDILLA */
1911 { 0x00C8, 0xE9 }, /* LATIN CAPITAL LETTER E WITH GRAVE */
1912 { 0x00C9, 0x83 }, /* LATIN CAPITAL LETTER E WITH ACUTE */
1913 { 0x00CA, 0xE6 }, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
1914 { 0x00CB, 0xE8 }, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
1915 { 0x00CC, 0xED }, /* LATIN CAPITAL LETTER I WITH GRAVE */
1916 { 0x00CD, 0xEA }, /* LATIN CAPITAL LETTER I WITH ACUTE */
1917 { 0x00CE, 0xEB }, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
1918 { 0x00CF, 0xEC }, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
1919 { 0x00D1, 0x84 }, /* LATIN CAPITAL LETTER N WITH TILDE */
1920 { 0x00D2, 0xF1 }, /* LATIN CAPITAL LETTER O WITH GRAVE */
1921 { 0x00D3, 0xEE }, /* LATIN CAPITAL LETTER O WITH ACUTE */
1922 { 0x00D4, 0xEF }, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
1923 { 0x00D5, 0xCD }, /* LATIN CAPITAL LETTER O WITH TILDE */
1924 { 0x00D6, 0x85 }, /* LATIN CAPITAL LETTER O WITH DIAERESIS */
1925 { 0x00D8, 0xAF }, /* LATIN CAPITAL LETTER O WITH STROKE */
1926 { 0x00D9, 0xF4 }, /* LATIN CAPITAL LETTER U WITH GRAVE */
1927 { 0x00DA, 0xF2 }, /* LATIN CAPITAL LETTER U WITH ACUTE */
1928 { 0x00DB, 0xF3 }, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
1929 { 0x00DC, 0x86 }, /* LATIN CAPITAL LETTER U WITH DIAERESIS */
1930 { 0x00DF, 0xA7 }, /* LATIN SMALL LETTER SHARP S */
1931 { 0x00E0, 0x88 }, /* LATIN SMALL LETTER A WITH GRAVE */
1932 { 0x00E1, 0x87 }, /* LATIN SMALL LETTER A WITH ACUTE */
1933 { 0x00E2, 0x89 }, /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
1934 { 0x00E3, 0x8B }, /* LATIN SMALL LETTER A WITH TILDE */
1935 { 0x00E4, 0x8A }, /* LATIN SMALL LETTER A WITH DIAERESIS */
1936 { 0x00E5, 0x8C }, /* LATIN SMALL LETTER A WITH RING ABOVE */
1937 { 0x00E6, 0xBE }, /* LATIN SMALL LETTER AE */
1938 { 0x00E7, 0x8D }, /* LATIN SMALL LETTER C WITH CEDILLA */
1939 { 0x00E8, 0x8F }, /* LATIN SMALL LETTER E WITH GRAVE */
1940 { 0x00E9, 0x8E }, /* LATIN SMALL LETTER E WITH ACUTE */
1941 { 0x00EA, 0x90 }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
1942 { 0x00EB, 0x91 }, /* LATIN SMALL LETTER E WITH DIAERESIS */
1943 { 0x00EC, 0x93 }, /* LATIN SMALL LETTER I WITH GRAVE */
1944 { 0x00ED, 0x92 }, /* LATIN SMALL LETTER I WITH ACUTE */
1945 { 0x00EE, 0x94 }, /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
1946 { 0x00EF, 0x95 }, /* LATIN SMALL LETTER I WITH DIAERESIS */
1947 { 0x00F1, 0x96 }, /* LATIN SMALL LETTER N WITH TILDE */
1948 { 0x00F2, 0x98 }, /* LATIN SMALL LETTER O WITH GRAVE */
1949 { 0x00F3, 0x97 }, /* LATIN SMALL LETTER O WITH ACUTE */
1950 { 0x00F4, 0x99 }, /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
1951 { 0x00F5, 0x9B }, /* LATIN SMALL LETTER O WITH TILDE */
1952 { 0x00F6, 0x9A }, /* LATIN SMALL LETTER O WITH DIAERESIS */
1953 { 0x00F7, 0xD6 }, /* DIVISION SIGN */
1954 { 0x00F8, 0xBF }, /* LATIN SMALL LETTER O WITH STROKE */
1955 { 0x00F9, 0x9D }, /* LATIN SMALL LETTER U WITH GRAVE */
1956 { 0x00FA, 0x9C }, /* LATIN SMALL LETTER U WITH ACUTE */
1957 { 0x00FB, 0x9E }, /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
1958 { 0x00FC, 0x9F }, /* LATIN SMALL LETTER U WITH DIAERESIS */
1959 { 0x00FF, 0xD8 }, /* LATIN SMALL LETTER Y WITH DIAERESIS */
1960 { 0x0131, 0xF5 }, /* LATIN SMALL LETTER DOTLESS I */
1961 { 0x0152, 0xCE }, /* LATIN CAPITAL LIGATURE OE */
1962 { 0x0153, 0xCF }, /* LATIN SMALL LIGATURE OE */
1963 { 0x0178, 0xD9 }, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
1964 { 0x0192, 0xC4 }, /* LATIN SMALL LETTER F WITH HOOK */
1965 { 0x02C6, 0xF6 }, /* MODIFIER LETTER CIRCUMFLEX ACCENT */
1966 { 0x02C7, 0xFF }, /* CARON */
1967 { 0x02D8, 0xF9 }, /* BREVE */
1968 { 0x02D9, 0xFA }, /* DOT ABOVE */
1969 { 0x02DA, 0xFB }, /* RING ABOVE */
1970 { 0x02DB, 0xFE }, /* OGONEK */
1971 { 0x02DC, 0xF7 }, /* SMALL TILDE */
1972 { 0x02DD, 0xFD }, /* DOUBLE ACUTE ACCENT */
1973 { 0x03A9, 0xBD }, /* GREEK CAPITAL LETTER OMEGA */
1974 { 0x03C0, 0xB9 }, /* GREEK SMALL LETTER PI */
1975 { 0x2013, 0xD0 }, /* EN DASH */
1976 { 0x2014, 0xD1 }, /* EM DASH */
1977 { 0x2018, 0xD4 }, /* LEFT SINGLE QUOTATION MARK */
1978 { 0x2019, 0xD5 }, /* RIGHT SINGLE QUOTATION MARK */
1979 { 0x201A, 0xE2 }, /* SINGLE LOW-9 QUOTATION MARK */
1980 { 0x201C, 0xD2 }, /* LEFT DOUBLE QUOTATION MARK */
1981 { 0x201D, 0xD3 }, /* RIGHT DOUBLE QUOTATION MARK */
1982 { 0x201E, 0xE3 }, /* DOUBLE LOW-9 QUOTATION MARK */
1983 { 0x2020, 0xA0 }, /* DAGGER */
1984 { 0x2021, 0xE0 }, /* DOUBLE DAGGER */
1985 { 0x2022, 0xA5 }, /* BULLET */
1986 { 0x2026, 0xC9 }, /* HORIZONTAL ELLIPSIS */
1987 { 0x2030, 0xE4 }, /* PER MILLE SIGN */
1988 { 0x2039, 0xDC }, /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */
1989 { 0x203A, 0xDD }, /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */
1990 { 0x2044, 0xDA }, /* FRACTION SLASH */
1991 { 0x20AC, 0xDB }, /* EURO SIGN */
1992 { 0x2122, 0xAA }, /* TRADE MARK SIGN */
1993 { 0x2202, 0xB6 }, /* PARTIAL DIFFERENTIAL */
1994 { 0x2206, 0xC6 }, /* INCREMENT */
1995 { 0x220F, 0xB8 }, /* N-ARY PRODUCT */
1996 { 0x2211, 0xB7 }, /* N-ARY SUMMATION */
1997 { 0x221A, 0xC3 }, /* SQUARE ROOT */
1998 { 0x221E, 0xB0 }, /* INFINITY */
1999 { 0x222B, 0xBA }, /* INTEGRAL */
2000 { 0x2248, 0xC5 }, /* ALMOST EQUAL TO */
2001 { 0x2260, 0xAD }, /* NOT EQUAL TO */
2002 { 0x2264, 0xB2 }, /* LESS-THAN OR EQUAL TO */
2003 { 0x2265, 0xB3 }, /* GREATER-THAN OR EQUAL TO */
2004 { 0x25CA, 0xD7 }, /* LOZENGE */
2005 { 0xF8FF, 0xF0 }, /* Apple logo */
2006 { 0xFB01, 0xDE }, /* LATIN SMALL LIGATURE FI */
2007 { 0xFB02, 0xDF }, /* LATIN SMALL LIGATURE FL */
2010 static const FcCharMap AppleRoman
= {
2012 sizeof (AppleRomanEnt
) / sizeof (AppleRomanEnt
[0])
2015 static const FcCharEnt AdobeSymbolEnt
[] = {
2016 { 0x0020, 0x20 }, /* SPACE # space */
2017 { 0x0021, 0x21 }, /* EXCLAMATION MARK # exclam */
2018 { 0x0023, 0x23 }, /* NUMBER SIGN # numbersign */
2019 { 0x0025, 0x25 }, /* PERCENT SIGN # percent */
2020 { 0x0026, 0x26 }, /* AMPERSAND # ampersand */
2021 { 0x0028, 0x28 }, /* LEFT PARENTHESIS # parenleft */
2022 { 0x0029, 0x29 }, /* RIGHT PARENTHESIS # parenright */
2023 { 0x002B, 0x2B }, /* PLUS SIGN # plus */
2024 { 0x002C, 0x2C }, /* COMMA # comma */
2025 { 0x002E, 0x2E }, /* FULL STOP # period */
2026 { 0x002F, 0x2F }, /* SOLIDUS # slash */
2027 { 0x0030, 0x30 }, /* DIGIT ZERO # zero */
2028 { 0x0031, 0x31 }, /* DIGIT ONE # one */
2029 { 0x0032, 0x32 }, /* DIGIT TWO # two */
2030 { 0x0033, 0x33 }, /* DIGIT THREE # three */
2031 { 0x0034, 0x34 }, /* DIGIT FOUR # four */
2032 { 0x0035, 0x35 }, /* DIGIT FIVE # five */
2033 { 0x0036, 0x36 }, /* DIGIT SIX # six */
2034 { 0x0037, 0x37 }, /* DIGIT SEVEN # seven */
2035 { 0x0038, 0x38 }, /* DIGIT EIGHT # eight */
2036 { 0x0039, 0x39 }, /* DIGIT NINE # nine */
2037 { 0x003A, 0x3A }, /* COLON # colon */
2038 { 0x003B, 0x3B }, /* SEMICOLON # semicolon */
2039 { 0x003C, 0x3C }, /* LESS-THAN SIGN # less */
2040 { 0x003D, 0x3D }, /* EQUALS SIGN # equal */
2041 { 0x003E, 0x3E }, /* GREATER-THAN SIGN # greater */
2042 { 0x003F, 0x3F }, /* QUESTION MARK # question */
2043 { 0x005B, 0x5B }, /* LEFT SQUARE BRACKET # bracketleft */
2044 { 0x005D, 0x5D }, /* RIGHT SQUARE BRACKET # bracketright */
2045 { 0x005F, 0x5F }, /* LOW LINE # underscore */
2046 { 0x007B, 0x7B }, /* LEFT CURLY BRACKET # braceleft */
2047 { 0x007C, 0x7C }, /* VERTICAL LINE # bar */
2048 { 0x007D, 0x7D }, /* RIGHT CURLY BRACKET # braceright */
2049 { 0x00A0, 0x20 }, /* NO-BREAK SPACE # space */
2050 { 0x00AC, 0xD8 }, /* NOT SIGN # logicalnot */
2051 { 0x00B0, 0xB0 }, /* DEGREE SIGN # degree */
2052 { 0x00B1, 0xB1 }, /* PLUS-MINUS SIGN # plusminus */
2053 { 0x00B5, 0x6D }, /* MICRO SIGN # mu */
2054 { 0x00D7, 0xB4 }, /* MULTIPLICATION SIGN # multiply */
2055 { 0x00F7, 0xB8 }, /* DIVISION SIGN # divide */
2056 { 0x0192, 0xA6 }, /* LATIN SMALL LETTER F WITH HOOK # florin */
2057 { 0x0391, 0x41 }, /* GREEK CAPITAL LETTER ALPHA # Alpha */
2058 { 0x0392, 0x42 }, /* GREEK CAPITAL LETTER BETA # Beta */
2059 { 0x0393, 0x47 }, /* GREEK CAPITAL LETTER GAMMA # Gamma */
2060 { 0x0394, 0x44 }, /* GREEK CAPITAL LETTER DELTA # Delta */
2061 { 0x0395, 0x45 }, /* GREEK CAPITAL LETTER EPSILON # Epsilon */
2062 { 0x0396, 0x5A }, /* GREEK CAPITAL LETTER ZETA # Zeta */
2063 { 0x0397, 0x48 }, /* GREEK CAPITAL LETTER ETA # Eta */
2064 { 0x0398, 0x51 }, /* GREEK CAPITAL LETTER THETA # Theta */
2065 { 0x0399, 0x49 }, /* GREEK CAPITAL LETTER IOTA # Iota */
2066 { 0x039A, 0x4B }, /* GREEK CAPITAL LETTER KAPPA # Kappa */
2067 { 0x039B, 0x4C }, /* GREEK CAPITAL LETTER LAMDA # Lambda */
2068 { 0x039C, 0x4D }, /* GREEK CAPITAL LETTER MU # Mu */
2069 { 0x039D, 0x4E }, /* GREEK CAPITAL LETTER NU # Nu */
2070 { 0x039E, 0x58 }, /* GREEK CAPITAL LETTER XI # Xi */
2071 { 0x039F, 0x4F }, /* GREEK CAPITAL LETTER OMICRON # Omicron */
2072 { 0x03A0, 0x50 }, /* GREEK CAPITAL LETTER PI # Pi */
2073 { 0x03A1, 0x52 }, /* GREEK CAPITAL LETTER RHO # Rho */
2074 { 0x03A3, 0x53 }, /* GREEK CAPITAL LETTER SIGMA # Sigma */
2075 { 0x03A4, 0x54 }, /* GREEK CAPITAL LETTER TAU # Tau */
2076 { 0x03A5, 0x55 }, /* GREEK CAPITAL LETTER UPSILON # Upsilon */
2077 { 0x03A6, 0x46 }, /* GREEK CAPITAL LETTER PHI # Phi */
2078 { 0x03A7, 0x43 }, /* GREEK CAPITAL LETTER CHI # Chi */
2079 { 0x03A8, 0x59 }, /* GREEK CAPITAL LETTER PSI # Psi */
2080 { 0x03A9, 0x57 }, /* GREEK CAPITAL LETTER OMEGA # Omega */
2081 { 0x03B1, 0x61 }, /* GREEK SMALL LETTER ALPHA # alpha */
2082 { 0x03B2, 0x62 }, /* GREEK SMALL LETTER BETA # beta */
2083 { 0x03B3, 0x67 }, /* GREEK SMALL LETTER GAMMA # gamma */
2084 { 0x03B4, 0x64 }, /* GREEK SMALL LETTER DELTA # delta */
2085 { 0x03B5, 0x65 }, /* GREEK SMALL LETTER EPSILON # epsilon */
2086 { 0x03B6, 0x7A }, /* GREEK SMALL LETTER ZETA # zeta */
2087 { 0x03B7, 0x68 }, /* GREEK SMALL LETTER ETA # eta */
2088 { 0x03B8, 0x71 }, /* GREEK SMALL LETTER THETA # theta */
2089 { 0x03B9, 0x69 }, /* GREEK SMALL LETTER IOTA # iota */
2090 { 0x03BA, 0x6B }, /* GREEK SMALL LETTER KAPPA # kappa */
2091 { 0x03BB, 0x6C }, /* GREEK SMALL LETTER LAMDA # lambda */
2092 { 0x03BC, 0x6D }, /* GREEK SMALL LETTER MU # mu */
2093 { 0x03BD, 0x6E }, /* GREEK SMALL LETTER NU # nu */
2094 { 0x03BE, 0x78 }, /* GREEK SMALL LETTER XI # xi */
2095 { 0x03BF, 0x6F }, /* GREEK SMALL LETTER OMICRON # omicron */
2096 { 0x03C0, 0x70 }, /* GREEK SMALL LETTER PI # pi */
2097 { 0x03C1, 0x72 }, /* GREEK SMALL LETTER RHO # rho */
2098 { 0x03C2, 0x56 }, /* GREEK SMALL LETTER FINAL SIGMA # sigma1 */
2099 { 0x03C3, 0x73 }, /* GREEK SMALL LETTER SIGMA # sigma */
2100 { 0x03C4, 0x74 }, /* GREEK SMALL LETTER TAU # tau */
2101 { 0x03C5, 0x75 }, /* GREEK SMALL LETTER UPSILON # upsilon */
2102 { 0x03C6, 0x66 }, /* GREEK SMALL LETTER PHI # phi */
2103 { 0x03C7, 0x63 }, /* GREEK SMALL LETTER CHI # chi */
2104 { 0x03C8, 0x79 }, /* GREEK SMALL LETTER PSI # psi */
2105 { 0x03C9, 0x77 }, /* GREEK SMALL LETTER OMEGA # omega */
2106 { 0x03D1, 0x4A }, /* GREEK THETA SYMBOL # theta1 */
2107 { 0x03D2, 0xA1 }, /* GREEK UPSILON WITH HOOK SYMBOL # Upsilon1 */
2108 { 0x03D5, 0x6A }, /* GREEK PHI SYMBOL # phi1 */
2109 { 0x03D6, 0x76 }, /* GREEK PI SYMBOL # omega1 */
2110 { 0x2022, 0xB7 }, /* BULLET # bullet */
2111 { 0x2026, 0xBC }, /* HORIZONTAL ELLIPSIS # ellipsis */
2112 { 0x2032, 0xA2 }, /* PRIME # minute */
2113 { 0x2033, 0xB2 }, /* DOUBLE PRIME # second */
2114 { 0x2044, 0xA4 }, /* FRACTION SLASH # fraction */
2115 { 0x20AC, 0xA0 }, /* EURO SIGN # Euro */
2116 { 0x2111, 0xC1 }, /* BLACK-LETTER CAPITAL I # Ifraktur */
2117 { 0x2118, 0xC3 }, /* SCRIPT CAPITAL P # weierstrass */
2118 { 0x211C, 0xC2 }, /* BLACK-LETTER CAPITAL R # Rfraktur */
2119 { 0x2126, 0x57 }, /* OHM SIGN # Omega */
2120 { 0x2135, 0xC0 }, /* ALEF SYMBOL # aleph */
2121 { 0x2190, 0xAC }, /* LEFTWARDS ARROW # arrowleft */
2122 { 0x2191, 0xAD }, /* UPWARDS ARROW # arrowup */
2123 { 0x2192, 0xAE }, /* RIGHTWARDS ARROW # arrowright */
2124 { 0x2193, 0xAF }, /* DOWNWARDS ARROW # arrowdown */
2125 { 0x2194, 0xAB }, /* LEFT RIGHT ARROW # arrowboth */
2126 { 0x21B5, 0xBF }, /* DOWNWARDS ARROW WITH CORNER LEFTWARDS # carriagereturn */
2127 { 0x21D0, 0xDC }, /* LEFTWARDS DOUBLE ARROW # arrowdblleft */
2128 { 0x21D1, 0xDD }, /* UPWARDS DOUBLE ARROW # arrowdblup */
2129 { 0x21D2, 0xDE }, /* RIGHTWARDS DOUBLE ARROW # arrowdblright */
2130 { 0x21D3, 0xDF }, /* DOWNWARDS DOUBLE ARROW # arrowdbldown */
2131 { 0x21D4, 0xDB }, /* LEFT RIGHT DOUBLE ARROW # arrowdblboth */
2132 { 0x2200, 0x22 }, /* FOR ALL # universal */
2133 { 0x2202, 0xB6 }, /* PARTIAL DIFFERENTIAL # partialdiff */
2134 { 0x2203, 0x24 }, /* THERE EXISTS # existential */
2135 { 0x2205, 0xC6 }, /* EMPTY SET # emptyset */
2136 { 0x2206, 0x44 }, /* INCREMENT # Delta */
2137 { 0x2207, 0xD1 }, /* NABLA # gradient */
2138 { 0x2208, 0xCE }, /* ELEMENT OF # element */
2139 { 0x2209, 0xCF }, /* NOT AN ELEMENT OF # notelement */
2140 { 0x220B, 0x27 }, /* CONTAINS AS MEMBER # suchthat */
2141 { 0x220F, 0xD5 }, /* N-ARY PRODUCT # product */
2142 { 0x2211, 0xE5 }, /* N-ARY SUMMATION # summation */
2143 { 0x2212, 0x2D }, /* MINUS SIGN # minus */
2144 { 0x2215, 0xA4 }, /* DIVISION SLASH # fraction */
2145 { 0x2217, 0x2A }, /* ASTERISK OPERATOR # asteriskmath */
2146 { 0x221A, 0xD6 }, /* SQUARE ROOT # radical */
2147 { 0x221D, 0xB5 }, /* PROPORTIONAL TO # proportional */
2148 { 0x221E, 0xA5 }, /* INFINITY # infinity */
2149 { 0x2220, 0xD0 }, /* ANGLE # angle */
2150 { 0x2227, 0xD9 }, /* LOGICAL AND # logicaland */
2151 { 0x2228, 0xDA }, /* LOGICAL OR # logicalor */
2152 { 0x2229, 0xC7 }, /* INTERSECTION # intersection */
2153 { 0x222A, 0xC8 }, /* UNION # union */
2154 { 0x222B, 0xF2 }, /* INTEGRAL # integral */
2155 { 0x2234, 0x5C }, /* THEREFORE # therefore */
2156 { 0x223C, 0x7E }, /* TILDE OPERATOR # similar */
2157 { 0x2245, 0x40 }, /* APPROXIMATELY EQUAL TO # congruent */
2158 { 0x2248, 0xBB }, /* ALMOST EQUAL TO # approxequal */
2159 { 0x2260, 0xB9 }, /* NOT EQUAL TO # notequal */
2160 { 0x2261, 0xBA }, /* IDENTICAL TO # equivalence */
2161 { 0x2264, 0xA3 }, /* LESS-THAN OR EQUAL TO # lessequal */
2162 { 0x2265, 0xB3 }, /* GREATER-THAN OR EQUAL TO # greaterequal */
2163 { 0x2282, 0xCC }, /* SUBSET OF # propersubset */
2164 { 0x2283, 0xC9 }, /* SUPERSET OF # propersuperset */
2165 { 0x2284, 0xCB }, /* NOT A SUBSET OF # notsubset */
2166 { 0x2286, 0xCD }, /* SUBSET OF OR EQUAL TO # reflexsubset */
2167 { 0x2287, 0xCA }, /* SUPERSET OF OR EQUAL TO # reflexsuperset */
2168 { 0x2295, 0xC5 }, /* CIRCLED PLUS # circleplus */
2169 { 0x2297, 0xC4 }, /* CIRCLED TIMES # circlemultiply */
2170 { 0x22A5, 0x5E }, /* UP TACK # perpendicular */
2171 { 0x22C5, 0xD7 }, /* DOT OPERATOR # dotmath */
2172 { 0x2320, 0xF3 }, /* TOP HALF INTEGRAL # integraltp */
2173 { 0x2321, 0xF5 }, /* BOTTOM HALF INTEGRAL # integralbt */
2174 { 0x2329, 0xE1 }, /* LEFT-POINTING ANGLE BRACKET # angleleft */
2175 { 0x232A, 0xF1 }, /* RIGHT-POINTING ANGLE BRACKET # angleright */
2176 { 0x25CA, 0xE0 }, /* LOZENGE # lozenge */
2177 { 0x2660, 0xAA }, /* BLACK SPADE SUIT # spade */
2178 { 0x2663, 0xA7 }, /* BLACK CLUB SUIT # club */
2179 { 0x2665, 0xA9 }, /* BLACK HEART SUIT # heart */
2180 { 0x2666, 0xA8 }, /* BLACK DIAMOND SUIT # diamond */
2181 { 0xF6D9, 0xD3 }, /* COPYRIGHT SIGN SERIF # copyrightserif (CUS) */
2182 { 0xF6DA, 0xD2 }, /* REGISTERED SIGN SERIF # registerserif (CUS) */
2183 { 0xF6DB, 0xD4 }, /* TRADE MARK SIGN SERIF # trademarkserif (CUS) */
2184 { 0xF8E5, 0x60 }, /* RADICAL EXTENDER # radicalex (CUS) */
2185 { 0xF8E6, 0xBD }, /* VERTICAL ARROW EXTENDER # arrowvertex (CUS) */
2186 { 0xF8E7, 0xBE }, /* HORIZONTAL ARROW EXTENDER # arrowhorizex (CUS) */
2187 { 0xF8E8, 0xE2 }, /* REGISTERED SIGN SANS SERIF # registersans (CUS) */
2188 { 0xF8E9, 0xE3 }, /* COPYRIGHT SIGN SANS SERIF # copyrightsans (CUS) */
2189 { 0xF8EA, 0xE4 }, /* TRADE MARK SIGN SANS SERIF # trademarksans (CUS) */
2190 { 0xF8EB, 0xE6 }, /* LEFT PAREN TOP # parenlefttp (CUS) */
2191 { 0xF8EC, 0xE7 }, /* LEFT PAREN EXTENDER # parenleftex (CUS) */
2192 { 0xF8ED, 0xE8 }, /* LEFT PAREN BOTTOM # parenleftbt (CUS) */
2193 { 0xF8EE, 0xE9 }, /* LEFT SQUARE BRACKET TOP # bracketlefttp (CUS) */
2194 { 0xF8EF, 0xEA }, /* LEFT SQUARE BRACKET EXTENDER # bracketleftex (CUS) */
2195 { 0xF8F0, 0xEB }, /* LEFT SQUARE BRACKET BOTTOM # bracketleftbt (CUS) */
2196 { 0xF8F1, 0xEC }, /* LEFT CURLY BRACKET TOP # bracelefttp (CUS) */
2197 { 0xF8F2, 0xED }, /* LEFT CURLY BRACKET MID # braceleftmid (CUS) */
2198 { 0xF8F3, 0xEE }, /* LEFT CURLY BRACKET BOTTOM # braceleftbt (CUS) */
2199 { 0xF8F4, 0xEF }, /* CURLY BRACKET EXTENDER # braceex (CUS) */
2200 { 0xF8F5, 0xF4 }, /* INTEGRAL EXTENDER # integralex (CUS) */
2201 { 0xF8F6, 0xF6 }, /* RIGHT PAREN TOP # parenrighttp (CUS) */
2202 { 0xF8F7, 0xF7 }, /* RIGHT PAREN EXTENDER # parenrightex (CUS) */
2203 { 0xF8F8, 0xF8 }, /* RIGHT PAREN BOTTOM # parenrightbt (CUS) */
2204 { 0xF8F9, 0xF9 }, /* RIGHT SQUARE BRACKET TOP # bracketrighttp (CUS) */
2205 { 0xF8FA, 0xFA }, /* RIGHT SQUARE BRACKET EXTENDER # bracketrightex (CUS) */
2206 { 0xF8FB, 0xFB }, /* RIGHT SQUARE BRACKET BOTTOM # bracketrightbt (CUS) */
2207 { 0xF8FC, 0xFC }, /* RIGHT CURLY BRACKET TOP # bracerighttp (CUS) */
2208 { 0xF8FD, 0xFD }, /* RIGHT CURLY BRACKET MID # bracerightmid (CUS) */
2209 { 0xF8FE, 0xFE }, /* RIGHT CURLY BRACKET BOTTOM # bracerightbt (CUS) */
2212 static const FcCharMap AdobeSymbol
= {
2214 sizeof (AdobeSymbolEnt
) / sizeof (AdobeSymbolEnt
[0]),
2217 static const FcFontDecode fcFontDecoders
[] = {
2218 { ft_encoding_unicode
, 0, (1 << 21) - 1 },
2219 { ft_encoding_symbol
, &AdobeSymbol
, (1 << 16) - 1 },
2220 { ft_encoding_apple_roman
, &AppleRoman
, (1 << 16) - 1 },
2223 #define NUM_DECODE (int) (sizeof (fcFontDecoders) / sizeof (fcFontDecoders[0]))
2225 static const FcChar32 prefer_unicode
[] = {
2226 0x20ac, /* EURO SIGN */
2229 #define NUM_PREFER_UNICODE (int) (sizeof (prefer_unicode) / sizeof (prefer_unicode[0]))
2232 FcFreeTypeUcs4ToPrivate (FcChar32 ucs4
, const FcCharMap
*map
)
2238 high
= map
->nent
- 1;
2239 if (ucs4
< map
->ent
[low
].bmp
|| map
->ent
[high
].bmp
< ucs4
)
2243 mid
= (high
+ low
) >> 1;
2244 bmp
= map
->ent
[mid
].bmp
;
2246 return (FT_ULong
) map
->ent
[mid
].encode
;
2256 FcFreeTypePrivateToUcs4 (FcChar32
private, const FcCharMap
*map
)
2260 for (i
= 0; i
< map
->nent
; i
++)
2261 if (map
->ent
[i
].encode
== private)
2262 return (FcChar32
) map
->ent
[i
].bmp
;
2267 FcFreeTypeGetPrivateMap (FT_Encoding encoding
)
2271 for (i
= 0; i
< NUM_DECODE
; i
++)
2272 if (fcFontDecoders
[i
].encoding
== encoding
)
2273 return fcFontDecoders
[i
].map
;
2277 #include "../fc-glyphname/fcglyphname.h"
2280 FcHashGlyphName (const FcChar8
*name
)
2285 while ((c
= *name
++))
2287 h
= ((h
<< 1) | (h
>> 31)) ^ c
;
2292 #if HAVE_FT_HAS_PS_GLYPH_NAMES
2294 * Use Type1 glyph names for fonts which have reliable names
2295 * and which export an Adobe Custom mapping
2298 FcFreeTypeUseNames (FT_Face face
)
2302 if (!FT_Has_PS_Glyph_Names (face
))
2304 for (map
= 0; map
< face
->num_charmaps
; map
++)
2305 if (face
->charmaps
[map
]->encoding
== ft_encoding_adobe_custom
)
2310 static const FcChar8
*
2311 FcUcs4ToGlyphName (FcChar32 ucs4
)
2313 int i
= (int) (ucs4
% FC_GLYPHNAME_HASH
);
2317 while ((gn
= ucs_to_name
[i
]) != -1)
2319 if (glyphs
[gn
].ucs
== ucs4
)
2320 return glyphs
[gn
].name
;
2323 r
= (int) (ucs4
% FC_GLYPHNAME_REHASH
);
2328 if (i
>= FC_GLYPHNAME_HASH
)
2329 i
-= FC_GLYPHNAME_HASH
;
2335 FcGlyphNameToUcs4 (FcChar8
*name
)
2337 FcChar32 h
= FcHashGlyphName (name
);
2338 int i
= (int) (h
% FC_GLYPHNAME_HASH
);
2342 while ((gn
= name_to_ucs
[i
]) != -1)
2344 if (!strcmp ((char *) name
, (char *) glyphs
[gn
].name
))
2345 return glyphs
[gn
].ucs
;
2348 r
= (int) (h
% FC_GLYPHNAME_REHASH
);
2353 if (i
>= FC_GLYPHNAME_HASH
)
2354 i
-= FC_GLYPHNAME_HASH
;
2360 * Work around a bug in some FreeType versions which fail
2361 * to correctly bounds check glyph name buffers and overwrite
2362 * the stack. As Postscript names have a limit of 127 characters,
2363 * this should be sufficient.
2366 #if FC_GLYPHNAME_MAXLEN < 127
2367 # define FC_GLYPHNAME_BUFLEN 127
2369 # define FC_GLYPHNAME_BUFLEN FC_GLYPHNAME_MAXLEN
2373 * Search through a font for a glyph by name. This is
2374 * currently a linear search as there doesn't appear to be
2375 * any defined order within the font
2378 FcFreeTypeGlyphNameIndex (FT_Face face
, const FcChar8
*name
)
2381 FcChar8 name_buf
[FC_GLYPHNAME_BUFLEN
+ 2];
2383 for (gindex
= 0; gindex
< (FT_UInt
) face
->num_glyphs
; gindex
++)
2385 if (FT_Get_Glyph_Name (face
, gindex
, name_buf
, FC_GLYPHNAME_BUFLEN
+1) == 0)
2386 if (!strcmp ((char *) name
, (char *) name_buf
))
2394 * Map a UCS4 glyph to a glyph index. Use all available encoding
2395 * tables to try and find one that works. This information is expected
2396 * to be cached by higher levels, so performance isn't critical
2400 FcFreeTypeCharIndex (FT_Face face
, FcChar32 ucs4
)
2402 int initial
, offset
, decode
;
2413 * Find the current encoding
2417 for (; initial
< NUM_DECODE
; initial
++)
2418 if (fcFontDecoders
[initial
].encoding
== face
->charmap
->encoding
)
2420 if (initial
== NUM_DECODE
)
2423 for (p
= 0; p
< NUM_PREFER_UNICODE
; p
++)
2424 if (ucs4
== prefer_unicode
[p
])
2430 * Check each encoding for the glyph, starting with the current one
2432 for (offset
= 0; offset
< NUM_DECODE
; offset
++)
2434 decode
= (initial
+ offset
) % NUM_DECODE
;
2435 if (!face
->charmap
|| face
->charmap
->encoding
!= fcFontDecoders
[decode
].encoding
)
2436 if (FT_Select_Charmap (face
, fcFontDecoders
[decode
].encoding
) != 0)
2438 if (fcFontDecoders
[decode
].map
)
2440 charcode
= FcFreeTypeUcs4ToPrivate (ucs4
, fcFontDecoders
[decode
].map
);
2441 if (charcode
== ~0U)
2446 glyphindex
= FT_Get_Char_Index (face
, (FT_ULong
) charcode
);
2450 #if HAVE_FT_HAS_PS_GLYPH_NAMES
2452 * Check postscript name table if present
2454 if (FcFreeTypeUseNames (face
))
2456 const FcChar8
*name
= FcUcs4ToGlyphName (ucs4
);
2459 glyphindex
= FcFreeTypeGlyphNameIndex (face
, name
);
2469 FcFreeTypeCheckGlyph (FT_Face face
, FcChar32 ucs4
,
2470 FT_UInt glyph
, FcBlanks
*blanks
,
2472 FcBool using_strike
)
2474 FT_Int load_flags
= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
| FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
;
2478 load_flags
&= ~FT_LOAD_NO_SCALE
;
2481 * When using scalable fonts, only report those glyphs
2482 * which can be scaled; otherwise those fonts will
2483 * only be available at some sizes, and never when
2484 * transformed. Avoid this by simply reporting bitmap-only
2487 if (face
->face_flags
& FT_FACE_FLAG_SCALABLE
)
2488 load_flags
|= FT_LOAD_NO_BITMAP
;
2490 if (FT_Load_Glyph (face
, glyph
, load_flags
))
2497 *advance
= slot
->metrics
.horiAdvance
;
2499 switch (slot
->format
) {
2500 case ft_glyph_format_bitmap
:
2502 * Bitmaps are assumed to be reasonable; if
2503 * this proves to be a rash assumption, this
2504 * code can be easily modified
2507 case ft_glyph_format_outline
:
2509 * Glyphs with contours are always OK
2511 if (slot
->outline
.n_contours
!= 0)
2514 * Glyphs with no contours are only OK if
2515 * they're members of the Blanks set specified
2516 * in the configuration. If blanks isn't set,
2517 * then allow any glyph to be blank
2519 if (!blanks
|| FcBlanksIsMember (blanks
, ucs4
))
2521 /* fall through ... */
2528 #define FC_MIN(a,b) ((a) < (b) ? (a) : (b))
2529 #define FC_MAX(a,b) ((a) > (b) ? (a) : (b))
2530 #define FC_ABS(a) ((a) < 0 ? -(a) : (a))
2531 #define APPROXIMATELY_EQUAL(x,y) (FC_ABS ((x) - (y)) <= FC_MAX (FC_ABS (x), FC_ABS (y)) / 33)
2534 FcFreeTypeCharSetAndSpacingForSize (FT_Face face
, FcBlanks
*blanks
, int *spacing
, FT_Int strike_index
)
2536 FcChar32 page
, off
, ucs4
;
2538 FcChar32 font_max
= 0;
2542 const FcCharMap
*map
;
2546 FT_Pos advance
, advance_one
= 0, advance_two
= 0;
2547 FcBool has_advance
= FcFalse
, fixed_advance
= FcTrue
, dual_advance
= FcFalse
;
2548 FcBool using_strike
= FcFalse
;
2550 fcs
= FcCharSetCreate ();
2554 if (strike_index
>= 0) {
2555 if (FT_Select_Size (face
, strike_index
) != FT_Err_Ok
)
2557 using_strike
= FcTrue
;
2561 printf ("Family %s style %s\n", face
->family_name
, face
->style_name
);
2563 for (o
= 0; o
< NUM_DECODE
; o
++)
2565 if (FT_Select_Charmap (face
, fcFontDecoders
[o
].encoding
) != 0)
2567 map
= fcFontDecoders
[o
].map
;
2571 * Non-Unicode tables are easy; there's a list of all possible
2574 for (i
= 0; i
< map
->nent
; i
++)
2576 ucs4
= map
->ent
[i
].bmp
;
2577 glyph
= FT_Get_Char_Index (face
, map
->ent
[i
].encode
);
2579 FcFreeTypeCheckGlyph (face
, ucs4
, glyph
, blanks
, &advance
, using_strike
))
2582 * ignore glyphs with zero advance. They’re
2583 * combining characters, and while their behaviour
2584 * isn’t well defined for monospaced applications in
2585 * Unicode, there are many fonts which include
2586 * zero-width combining characters in otherwise
2593 has_advance
= FcTrue
;
2594 advance_one
= advance
;
2596 else if (!APPROXIMATELY_EQUAL (advance
, advance_one
))
2600 dual_advance
= FcTrue
;
2601 fixed_advance
= FcFalse
;
2602 advance_two
= advance
;
2604 else if (!APPROXIMATELY_EQUAL (advance
, advance_two
))
2605 dual_advance
= FcFalse
;
2609 leaf
= FcCharSetFindLeafCreate (fcs
, ucs4
);
2612 leaf
->map
[(ucs4
& 0xff) >> 5] |= (1 << (ucs4
& 0x1f));
2614 if (ucs4
> font_max
)
2624 ucs4
= FT_Get_First_Char (face
, &glyph
);
2627 if (FcFreeTypeCheckGlyph (face
, ucs4
, glyph
, blanks
, &advance
, using_strike
))
2633 has_advance
= FcTrue
;
2634 advance_one
= advance
;
2636 else if (!APPROXIMATELY_EQUAL (advance
, advance_one
))
2640 dual_advance
= FcTrue
;
2641 fixed_advance
= FcFalse
;
2642 advance_two
= advance
;
2644 else if (!APPROXIMATELY_EQUAL (advance
, advance_two
))
2645 dual_advance
= FcFalse
;
2649 if ((ucs4
>> 8) != page
)
2652 leaf
= FcCharSetFindLeafCreate (fcs
, ucs4
);
2657 leaf
->map
[off
>> 5] |= (1 << (off
& 0x1f));
2659 if (ucs4
> font_max
)
2663 ucs4
= FT_Get_Next_Char (face
, ucs4
, &glyph
);
2666 for (ucs4
= 0; ucs4
< 0x10000; ucs4
++)
2668 FcBool FT_Has
, FC_Has
;
2670 FT_Has
= FT_Get_Char_Index (face
, ucs4
) != 0;
2671 FC_Has
= FcCharSetHasChar (fcs
, ucs4
);
2672 if (FT_Has
!= FC_Has
)
2674 printf ("0x%08x FT says %d FC says %d\n", ucs4
, FT_Has
, FC_Has
);
2680 #if HAVE_FT_HAS_PS_GLYPH_NAMES
2682 * Add mapping from PS glyph names if available
2684 if (FcFreeTypeUseNames (face
))
2686 FcChar8 name_buf
[FC_GLYPHNAME_BUFLEN
+ 2];
2688 for (glyph
= 0; glyph
< (FT_UInt
) face
->num_glyphs
; glyph
++)
2690 if (FT_Get_Glyph_Name (face
, glyph
, name_buf
, FC_GLYPHNAME_BUFLEN
+1) == 0)
2692 ucs4
= FcGlyphNameToUcs4 (name_buf
);
2693 if (ucs4
!= 0xffff &&
2694 FcFreeTypeCheckGlyph (face
, ucs4
, glyph
, blanks
, &advance
, using_strike
))
2700 has_advance
= FcTrue
;
2701 advance_one
= advance
;
2703 else if (!APPROXIMATELY_EQUAL (advance
, advance_one
))
2707 dual_advance
= FcTrue
;
2708 fixed_advance
= FcFalse
;
2709 advance_two
= advance
;
2711 else if (!APPROXIMATELY_EQUAL (advance
, advance_two
))
2712 dual_advance
= FcFalse
;
2715 leaf
= FcCharSetFindLeafCreate (fcs
, ucs4
);
2718 leaf
->map
[(ucs4
& 0xff) >> 5] |= (1 << (ucs4
& 0x1f));
2720 if (ucs4
> font_max
)
2729 printf ("%d glyphs %d encoded\n", (int) face
->num_glyphs
, FcCharSetCount (fcs
));
2730 for (ucs4
= 0; ucs4
<= font_max
; ucs4
++)
2732 FcBool has_char
= (glyph
= FcFreeTypeCharIndex (face
, ucs4
)) != 0;
2733 FcBool has_bit
= FcCharSetHasChar (fcs
, ucs4
);
2735 if (has_char
&& !has_bit
)
2737 if (!FcFreeTypeCheckGlyph (face
, ucs4
, glyph
, blanks
, &advance
, using_strike
))
2738 printf ("Bitmap missing broken char 0x%x\n", ucs4
);
2740 printf ("Bitmap missing char 0x%x\n", ucs4
);
2742 else if (!has_char
&& has_bit
)
2743 printf ("Bitmap extra char 0x%x\n", ucs4
);
2748 else if (dual_advance
&& APPROXIMATELY_EQUAL (2 * FC_MIN (advance_one
, advance_two
), FC_MAX (advance_one
, advance_two
)))
2751 *spacing
= FC_PROPORTIONAL
;
2754 FcCharSetDestroy (fcs
);
2760 FcFreeTypeCharSetAndSpacing (FT_Face face
, FcBlanks
*blanks
, int *spacing
)
2764 cs
= FcFreeTypeCharSetAndSpacingForSize (face
, blanks
, spacing
, -1);
2766 * Check for bitmap-only ttf fonts that are missing the glyf table.
2767 * In that case, pick a size and look for glyphs in that size instead
2769 if (FcCharSetCount (cs
) == 0)
2771 /* Check for non-scalable TT fonts */
2772 if (!(face
->face_flags
& FT_FACE_FLAG_SCALABLE
) &&
2773 face
->num_fixed_sizes
> 0 &&
2774 FT_Get_Sfnt_Table (face
, ft_sfnt_head
))
2776 FT_Int strike_index
= 0;
2779 /* Select the face closest to 16 pixels tall */
2780 for (i
= 1; i
< face
->num_fixed_sizes
; i
++) {
2781 if (abs (face
->available_sizes
[i
].height
- 16) <
2782 abs (face
->available_sizes
[strike_index
].height
- 16))
2785 FcCharSetDestroy (cs
);
2786 cs
= FcFreeTypeCharSetAndSpacingForSize (face
, blanks
, spacing
, strike_index
);
2793 FcFreeTypeCharSet (FT_Face face
, FcBlanks
*blanks
)
2797 return FcFreeTypeCharSetAndSpacing (face
, blanks
, &spacing
);
2801 #define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' )
2802 #define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
2803 #define TTAG_SILF FT_MAKE_TAG( 'S', 'i', 'l', 'f')
2804 #define TT_Err_Ok FT_Err_Ok
2805 #define TT_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle
2806 #define TTO_Err_Empty_Script 0x1005
2807 #define TTO_Err_Invalid_SubTable 0x1001
2809 #define OTLAYOUT_HEAD "otlayout:"
2810 #define OTLAYOUT_HEAD_LEN 9
2811 #define OTLAYOUT_ID_LEN 4
2812 /* space + head + id */
2813 #define OTLAYOUT_LEN (1 + OTLAYOUT_HEAD_LEN + OTLAYOUT_ID_LEN)
2816 * This is a bit generous; the registry has only lower case and space
2817 * except for 'DFLT'.
2819 #define FcIsSpace(x) (040 == (x))
2820 #define FcIsValidScript(x) (FcIsLower(x) || FcIsUpper (x) || FcIsSpace(x))
2823 addtag(FcChar8
*complex, FT_ULong tag
)
2825 FcChar8 tagstring
[OTLAYOUT_ID_LEN
+ 1];
2827 tagstring
[0] = (FcChar8
)(tag
>> 24),
2828 tagstring
[1] = (FcChar8
)(tag
>> 16),
2829 tagstring
[2] = (FcChar8
)(tag
>> 8),
2830 tagstring
[3] = (FcChar8
)(tag
);
2831 tagstring
[4] = '\0';
2833 /* skip tags which aren't alphabetic, under the assumption that
2834 * they're probably broken
2836 if (!FcIsValidScript(tagstring
[0]) ||
2837 !FcIsValidScript(tagstring
[1]) ||
2838 !FcIsValidScript(tagstring
[2]) ||
2839 !FcIsValidScript(tagstring
[3]))
2842 if (*complex != '\0')
2843 strcat ((char *) complex, " ");
2844 strcat ((char *) complex, "otlayout:");
2845 strcat ((char *) complex, (char *) tagstring
);
2849 compareulong (const void *a
, const void *b
)
2851 const FT_ULong
*ua
= (const FT_ULong
*) a
;
2852 const FT_ULong
*ub
= (const FT_ULong
*) b
;
2858 GetScriptTags(FT_Face face
, FT_ULong tabletag
, FT_ULong
**stags
, FT_UShort
*script_count
)
2860 FT_ULong cur_offset
, new_offset
, base_offset
;
2861 FT_Stream stream
= face
->stream
;
2867 return TT_Err_Invalid_Face_Handle
;
2869 memory
= stream
->memory
;
2871 if (( error
= ftglue_face_goto_table( face
, tabletag
, stream
) ))
2874 base_offset
= ftglue_stream_pos ( stream
);
2878 if ( ftglue_stream_seek ( stream
, base_offset
+ 4L ) || ftglue_stream_frame_enter( stream
, 2L ) )
2881 new_offset
= GET_UShort() + base_offset
;
2883 ftglue_stream_frame_exit( stream
);
2885 cur_offset
= ftglue_stream_pos( stream
);
2887 if ( ftglue_stream_seek( stream
, new_offset
) != TT_Err_Ok
)
2890 base_offset
= ftglue_stream_pos( stream
);
2892 if ( ftglue_stream_frame_enter( stream
, 2L ) )
2895 *script_count
= GET_UShort ();
2897 ftglue_stream_frame_exit( stream
);
2899 *stags
= ftglue_alloc(memory
, *script_count
* sizeof( FT_ULong
), &error
);
2905 for ( n
= 0; n
< *script_count
; n
++ )
2907 if ( ftglue_stream_frame_enter( stream
, 6L ) )
2910 (*stags
)[p
] = GET_ULong ();
2911 new_offset
= GET_UShort () + base_offset
;
2913 ftglue_stream_frame_exit( stream
);
2915 cur_offset
= ftglue_stream_pos( stream
);
2917 error
= ftglue_stream_seek( stream
, new_offset
);
2919 if ( error
== TT_Err_Ok
)
2922 (void)ftglue_stream_seek( stream
, cur_offset
);
2927 error
= TTO_Err_Invalid_SubTable
;
2931 /* sort the tag list before returning it */
2932 qsort(*stags
, *script_count
, sizeof(FT_ULong
), compareulong
);
2938 ftglue_free( memory
, *stags
);
2944 FcFontCapabilities(FT_Face face
)
2946 FcBool issilgraphitefont
= 0;
2949 FT_ULong
*gsubtags
=NULL
, *gpostags
=NULL
;
2950 FT_UShort gsub_count
=0, gpos_count
=0;
2952 FT_Memory memory
= face
->stream
->memory
;
2953 FcChar8
*complex = NULL
;
2954 int indx1
= 0, indx2
= 0;
2956 err
= FT_Load_Sfnt_Table(face
, TTAG_SILF
, 0, 0, &len
);
2957 issilgraphitefont
= ( err
== FT_Err_Ok
);
2959 if (GetScriptTags(face
, TTAG_GPOS
, &gpostags
, &gpos_count
) != FT_Err_Ok
)
2961 if (GetScriptTags(face
, TTAG_GSUB
, &gsubtags
, &gsub_count
) != FT_Err_Ok
)
2964 if (!issilgraphitefont
&& !gsub_count
&& !gpos_count
)
2967 maxsize
= (((FT_ULong
) gpos_count
+ (FT_ULong
) gsub_count
) * OTLAYOUT_LEN
+
2968 (issilgraphitefont
? 13 : 0));
2969 complex = malloc (sizeof (FcChar8
) * maxsize
);
2974 if (issilgraphitefont
)
2975 strcpy((char *) complex, "ttable:Silf ");
2977 while ((indx1
< gsub_count
) || (indx2
< gpos_count
)) {
2978 if (indx1
== gsub_count
) {
2979 addtag(complex, gpostags
[indx2
]);
2981 } else if ((indx2
== gpos_count
) || (gsubtags
[indx1
] < gpostags
[indx2
])) {
2982 addtag(complex, gsubtags
[indx1
]);
2984 } else if (gsubtags
[indx1
] == gpostags
[indx2
]) {
2985 addtag(complex, gsubtags
[indx1
]);
2989 addtag(complex, gpostags
[indx2
]);
2993 if (FcDebug () & FC_DBG_SCANV
)
2994 printf("complex features in this font: %s\n", complex);
2996 ftglue_free(memory
, gsubtags
);
2997 ftglue_free(memory
, gpostags
);
3001 #define __fcfreetype__
3002 #include "fcaliastail.h"
3003 #include "fcftaliastail.h"
3004 #undef __fcfreetype__