2 * $RCSId: xc/lib/fontconfig/src/fcfreetype.c,v 1.11 2002/08/31 22:17:32 keithp Exp $
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
52 #include FT_FREETYPE_H
53 #include FT_TRUETYPE_TABLES_H
54 #include FT_SFNT_NAMES_H
55 #include FT_TRUETYPE_IDS_H
56 #include FT_TYPE1_TABLES_H
57 #if HAVE_FT_GET_X11_FONT_FORMAT
60 #if HAVE_FT_GET_BDF_PROPERTY
67 #if HAVE_WARNING_CPP_DIRECTIVE
68 #if !HAVE_FT_GET_BDF_PROPERTY
69 #warning "No FT_Get_BDF_Property: Please install freetype 2.1.4 or later"
72 #if !HAVE_FT_GET_PS_FONT_INFO
73 #warning "No FT_Get_PS_Font_Info: Please install freetype 2.1.1 or later"
78 * Keep Han languages separated by eliminating languages
79 * that the codePageRange bits says aren't supported
84 const FcChar8 lang
[6];
85 } FcCodePageRange
[] = {
92 #define NUM_CODE_PAGE_RANGE (int) (sizeof FcCodePageRange / sizeof FcCodePageRange[0])
95 FcFreeTypeIsExclusiveLang (const FcChar8
*lang
)
99 for (i
= 0; i
< NUM_CODE_PAGE_RANGE
; i
++)
101 if (FcLangCompare (lang
, FcCodePageRange
[i
].lang
) == FcLangEqual
)
108 const FT_UShort platform_id
;
109 const FT_UShort encoding_id
;
110 const char fromcode
[12];
113 #define TT_ENCODING_DONT_CARE 0xffff
114 #define FC_ENCODING_MAC_ROMAN "MACINTOSH"
116 static const FcFtEncoding fcFtEncoding
[] = {
117 { TT_PLATFORM_APPLE_UNICODE
, TT_ENCODING_DONT_CARE
, "UCS-2BE" },
118 { TT_PLATFORM_MACINTOSH
, TT_MAC_ID_ROMAN
, "MACINTOSH" },
119 { TT_PLATFORM_MACINTOSH
, TT_MAC_ID_JAPANESE
, "SJIS" },
120 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_UNICODE_CS
, "UTF-16BE" },
121 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_SJIS
, "SJIS-WIN" },
122 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_GB2312
, "GB3212" },
123 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_BIG_5
, "BIG-5" },
124 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_WANSUNG
, "Wansung" },
125 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_JOHAB
, "Johab" },
126 { TT_PLATFORM_MICROSOFT
, TT_MS_ID_UCS_4
, "UCS4" },
127 { TT_PLATFORM_ISO
, TT_ISO_ID_7BIT_ASCII
, "ASCII" },
128 { TT_PLATFORM_ISO
, TT_ISO_ID_10646
, "UCS-2BE" },
129 { TT_PLATFORM_ISO
, TT_ISO_ID_8859_1
, "ISO-8859-1" },
132 #define NUM_FC_FT_ENCODING (int) (sizeof (fcFtEncoding) / sizeof (fcFtEncoding[0]))
135 const FT_UShort platform_id
;
136 const FT_UShort language_id
;
140 #define TT_LANGUAGE_DONT_CARE 0xffff
142 static const FcFtLanguage fcFtLanguage
[] = {
143 { TT_PLATFORM_APPLE_UNICODE
, TT_LANGUAGE_DONT_CARE
, "" },
144 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ENGLISH
, "en" },
145 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FRENCH
, "fr" },
146 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GERMAN
, "de" },
147 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ITALIAN
, "it" },
148 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_DUTCH
, "nl" },
149 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SWEDISH
, "sv" },
150 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SPANISH
, "es" },
151 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_DANISH
, "da" },
152 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_PORTUGUESE
, "pt" },
153 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_NORWEGIAN
, "no" },
154 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_HEBREW
, "he" },
155 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_JAPANESE
, "ja" },
156 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ARABIC
, "ar" },
157 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FINNISH
, "fi" },
158 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GREEK
, "el" },
159 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ICELANDIC
, "is" },
160 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALTESE
, "mt" },
161 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TURKISH
, "tr" },
162 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CROATIAN
, "hr" },
163 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CHINESE_TRADITIONAL
, "zh-tw" },
164 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_URDU
, "ur" },
165 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_HINDI
, "hi" },
166 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_THAI
, "th" },
167 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KOREAN
, "ko" },
168 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LITHUANIAN
, "lt" },
169 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_POLISH
, "pl" },
170 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_HUNGARIAN
, "hu" },
171 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ESTONIAN
, "et" },
172 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LETTISH
, "lv" },
173 /* { TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SAAMISK, ??? */
174 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FAEROESE
, "fo" },
175 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FARSI
, "fa" },
176 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_RUSSIAN
, "ru" },
177 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CHINESE_SIMPLIFIED
, "zh-cn" },
178 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_FLEMISH
, "nl" },
179 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_IRISH
, "ga" },
180 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ALBANIAN
, "sq" },
181 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ROMANIAN
, "ro" },
182 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CZECH
, "cs" },
183 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SLOVAK
, "sk" },
184 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SLOVENIAN
, "sl" },
185 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_YIDDISH
, "yi" },
186 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SERBIAN
, "sr" },
187 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MACEDONIAN
, "mk" },
188 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BULGARIAN
, "bg" },
189 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_UKRAINIAN
, "uk" },
190 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BYELORUSSIAN
, "be" },
191 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_UZBEK
, "uz" },
192 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KAZAKH
, "kk" },
193 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI
, "az" },
194 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT
, "az" },
195 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT
, "ar" },
196 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ARMENIAN
, "hy" },
197 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GEORGIAN
, "ka" },
198 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MOLDAVIAN
, "mo" },
199 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KIRGHIZ
, "ky" },
200 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TAJIKI
, "tg" },
201 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TURKMEN
, "tk" },
202 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MONGOLIAN
, "mo" },
203 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT
,"mo" },
204 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT
, "mo" },
205 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_PASHTO
, "ps" },
206 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KURDISH
, "ku" },
207 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KASHMIRI
, "ks" },
208 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SINDHI
, "sd" },
209 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TIBETAN
, "bo" },
210 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_NEPALI
, "ne" },
211 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SANSKRIT
, "sa" },
212 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MARATHI
, "mr" },
213 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BENGALI
, "bn" },
214 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ASSAMESE
, "as" },
215 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GUJARATI
, "gu" },
216 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_PUNJABI
, "pa" },
217 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ORIYA
, "or" },
218 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAYALAM
, "ml" },
219 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KANNADA
, "kn" },
220 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TAMIL
, "ta" },
221 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TELUGU
, "te" },
222 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SINHALESE
, "si" },
223 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BURMESE
, "my" },
224 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_KHMER
, "km" },
225 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LAO
, "lo" },
226 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_VIETNAMESE
, "vi" },
227 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_INDONESIAN
, "id" },
228 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TAGALOG
, "tl" },
229 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAY_ROMAN_SCRIPT
, "ms" },
230 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAY_ARABIC_SCRIPT
, "ms" },
231 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AMHARIC
, "am" },
232 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TIGRINYA
, "ti" },
233 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GALLA
, "om" },
234 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SOMALI
, "so" },
235 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SWAHILI
, "sw" },
236 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_RUANDA
, "rw" },
237 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_RUNDI
, "rn" },
238 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CHEWA
, "ny" },
239 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MALAGASY
, "mg" },
240 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_ESPERANTO
, "eo" },
241 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_WELSH
, "cy" },
242 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BASQUE
, "eu" },
243 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_CATALAN
, "ca" },
244 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_LATIN
, "la" },
245 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_QUECHUA
, "qu" },
246 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GUARANI
, "gn" },
247 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AYMARA
, "ay" },
248 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TATAR
, "tt" },
249 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_UIGHUR
, "ug" },
250 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_DZONGKHA
, "dz" },
251 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_JAVANESE
, "jw" },
252 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SUNDANESE
, "su" },
254 #if 0 /* these seem to be errors that have been dropped */
256 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SCOTTISH_GAELIC
},
257 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_IRISH_GAELIC
},
261 /* The following codes are new as of 2000-03-10 */
262 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GALICIAN
, "gl" },
263 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AFRIKAANS
, "af" },
264 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_BRETON
, "br" },
265 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_INUKTITUT
, "iu" },
266 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_SCOTTISH_GAELIC
, "gd" },
267 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_MANX_GAELIC
, "gv" },
268 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_IRISH_GAELIC
, "ga" },
269 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_TONGAN
, "to" },
270 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GREEK_POLYTONIC
, "el" },
271 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_GREELANDIC
, "ik" },
272 { TT_PLATFORM_MACINTOSH
, TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT
,"az" },
274 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_SAUDI_ARABIA
, "ar" },
275 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_IRAQ
, "ar" },
276 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_EGYPT
, "ar" },
277 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_LIBYA
, "ar" },
278 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_ALGERIA
, "ar" },
279 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_MOROCCO
, "ar" },
280 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_TUNISIA
, "ar" },
281 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_OMAN
, "ar" },
282 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_YEMEN
, "ar" },
283 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_SYRIA
, "ar" },
284 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_JORDAN
, "ar" },
285 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_LEBANON
, "ar" },
286 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_KUWAIT
, "ar" },
287 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_UAE
, "ar" },
288 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_BAHRAIN
, "ar" },
289 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_QATAR
, "ar" },
290 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BULGARIAN_BULGARIA
, "bg" },
291 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CATALAN_SPAIN
, "ca" },
292 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_TAIWAN
, "zh-tw" },
293 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_PRC
, "zh-cn" },
294 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_HONG_KONG
, "zh-hk" },
295 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_SINGAPORE
, "zh-sg" },
297 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_MACAU
, "zh-mo" },
299 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CZECH_CZECH_REPUBLIC
, "cs" },
300 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DANISH_DENMARK
, "da" },
301 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_GERMANY
, "de" },
302 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_SWITZERLAND
, "de" },
303 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_AUSTRIA
, "de" },
304 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_LUXEMBOURG
, "de" },
305 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GERMAN_LIECHTENSTEI
, "de" },
306 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GREEK_GREECE
, "el" },
307 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_UNITED_STATES
, "en" },
308 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_UNITED_KINGDOM
, "en" },
309 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_AUSTRALIA
, "en" },
310 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_CANADA
, "en" },
311 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_NEW_ZEALAND
, "en" },
312 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_IRELAND
, "en" },
313 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_SOUTH_AFRICA
, "en" },
314 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_JAMAICA
, "en" },
315 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_CARIBBEAN
, "en" },
316 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_BELIZE
, "en" },
317 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_TRINIDAD
, "en" },
318 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_ZIMBABWE
, "en" },
319 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_PHILIPPINES
, "en" },
320 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT
,"es" },
321 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_MEXICO
, "es" },
322 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT
,"es" },
323 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_GUATEMALA
, "es" },
324 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_COSTA_RICA
, "es" },
325 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PANAMA
, "es" },
326 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC
,"es" },
327 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_VENEZUELA
, "es" },
328 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_COLOMBIA
, "es" },
329 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PERU
, "es" },
330 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_ARGENTINA
, "es" },
331 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_ECUADOR
, "es" },
332 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_CHILE
, "es" },
333 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_URUGUAY
, "es" },
334 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PARAGUAY
, "es" },
335 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_BOLIVIA
, "es" },
336 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_EL_SALVADOR
, "es" },
337 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_HONDURAS
, "es" },
338 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_NICARAGUA
, "es" },
339 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_PUERTO_RICO
, "es" },
340 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FINNISH_FINLAND
, "fi" },
341 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_FRANCE
, "fr" },
342 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_BELGIUM
, "fr" },
343 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_CANADA
, "fr" },
344 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_SWITZERLAND
, "fr" },
345 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_LUXEMBOURG
, "fr" },
346 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_MONACO
, "fr" },
347 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HEBREW_ISRAEL
, "he" },
348 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HUNGARIAN_HUNGARY
, "hu" },
349 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ICELANDIC_ICELAND
, "is" },
350 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ITALIAN_ITALY
, "it" },
351 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ITALIAN_SWITZERLAND
, "it" },
352 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_JAPANESE_JAPAN
, "ja" },
353 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA
,"ko" },
354 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KOREAN_JOHAB_KOREA
, "ko" },
355 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DUTCH_NETHERLANDS
, "nl" },
356 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DUTCH_BELGIUM
, "nl" },
357 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL
, "no" },
358 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK
, "nn" },
359 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_POLISH_POLAND
, "pl" },
360 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PORTUGUESE_BRAZIL
, "pt" },
361 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PORTUGUESE_PORTUGAL
, "pt" },
362 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND
,"rm" },
363 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ROMANIAN_ROMANIA
, "ro" },
364 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MOLDAVIAN_MOLDAVIA
, "mo" },
365 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_RUSSIAN_RUSSIA
, "ru" },
366 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_RUSSIAN_MOLDAVIA
, "ru" },
367 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CROATIAN_CROATIA
, "hr" },
368 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SERBIAN_SERBIA_LATIN
, "sr" },
369 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC
, "sr" },
370 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SLOVAK_SLOVAKIA
, "sk" },
371 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ALBANIAN_ALBANIA
, "sq" },
372 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SWEDISH_SWEDEN
, "sv" },
373 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SWEDISH_FINLAND
, "sv" },
374 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_THAI_THAILAND
, "th" },
375 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TURKISH_TURKEY
, "tr" },
376 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_URDU_PAKISTAN
, "ur" },
377 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_INDONESIAN_INDONESIA
, "id" },
378 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_UKRAINIAN_UKRAINE
, "uk" },
379 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BELARUSIAN_BELARUS
, "be" },
380 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SLOVENE_SLOVENIA
, "sl" },
381 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ESTONIAN_ESTONIA
, "et" },
382 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LATVIAN_LATVIA
, "lv" },
383 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LITHUANIAN_LITHUANIA
, "lt" },
384 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA
,"lt" },
386 #ifdef TT_MS_LANGID_MAORI_NEW_ZELAND
387 /* this seems to be an error that have been dropped */
388 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MAORI_NEW_ZEALAND
, "mi" },
391 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FARSI_IRAN
, "fa" },
392 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_VIETNAMESE_VIET_NAM
, "vi" },
393 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARMENIAN_ARMENIA
, "hy" },
394 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN
, "az" },
395 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC
, "az" },
396 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BASQUE_SPAIN
, "eu" },
397 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SORBIAN_GERMANY
, "wen" },
398 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MACEDONIAN_MACEDONIA
, "mk" },
399 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SUTU_SOUTH_AFRICA
, "st" },
400 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TSONGA_SOUTH_AFRICA
, "ts" },
401 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TSWANA_SOUTH_AFRICA
, "tn" },
402 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_VENDA_SOUTH_AFRICA
, "ven" },
403 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_XHOSA_SOUTH_AFRICA
, "xh" },
404 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ZULU_SOUTH_AFRICA
, "zu" },
405 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA
, "af" },
406 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GEORGIAN_GEORGIA
, "ka" },
407 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS
, "fo" },
408 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HINDI_INDIA
, "hi" },
409 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALTESE_MALTA
, "mt" },
410 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SAAMI_LAPONIA
, "se" },
412 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM
,"gd" },
413 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_IRISH_GAELIC_IRELAND
, "ga" },
415 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALAY_MALAYSIA
, "ms" },
416 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM
, "ms" },
417 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KAZAK_KAZAKSTAN
, "kk" },
418 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SWAHILI_KENYA
, "sw" },
419 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN
, "uz" },
420 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC
, "uz" },
421 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TATAR_TATARSTAN
, "tt" },
422 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BENGALI_INDIA
, "bn" },
423 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PUNJABI_INDIA
, "pa" },
424 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GUJARATI_INDIA
, "gu" },
425 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ORIYA_INDIA
, "or" },
426 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAMIL_INDIA
, "ta" },
427 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TELUGU_INDIA
, "te" },
428 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KANNADA_INDIA
, "kn" },
429 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MALAYALAM_INDIA
, "ml" },
430 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ASSAMESE_INDIA
, "as" },
431 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MARATHI_INDIA
, "mr" },
432 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SANSKRIT_INDIA
, "sa" },
433 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KONKANI_INDIA
, "kok" },
435 /* new as of 2001-01-01 */
436 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ARABIC_GENERAL
, "ar" },
437 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHINESE_GENERAL
, "zh" },
438 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_GENERAL
, "en" },
439 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_WEST_INDIES
, "fr" },
440 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_REUNION
, "fr" },
441 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_CONGO
, "fr" },
443 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_SENEGAL
, "fr" },
444 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_CAMEROON
, "fr" },
445 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_COTE_D_IVOIRE
, "fr" },
446 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_MALI
, "fr" },
447 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA
,"bs" },
448 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_URDU_INDIA
, "ur" },
449 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAJIK_TAJIKISTAN
, "tg" },
450 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_YIDDISH_GERMANY
, "yi" },
451 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN
, "ky" },
453 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TURKMEN_TURKMENISTAN
, "tk" },
454 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MONGOLIAN_MONGOLIA
, "mn" },
456 /* the following seems to be inconsistent;
457 here is the current "official" way: */
458 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIBETAN_BHUTAN
, "bo" },
459 /* and here is what is used by Passport SDK */
460 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIBETAN_CHINA
, "bo" },
461 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DZONGHKA_BHUTAN
, "dz" },
462 /* end of inconsistency */
464 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_WELSH_WALES
, "cy" },
465 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KHMER_CAMBODIA
, "km" },
466 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LAO_LAOS
, "lo" },
467 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BURMESE_MYANMAR
, "my" },
468 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GALICIAN_SPAIN
, "gl" },
469 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MANIPURI_INDIA
, "mni" },
470 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SINDHI_INDIA
, "sd" },
471 /* the following one is only encountered in Microsoft RTF specification */
472 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KASHMIRI_PAKISTAN
, "ks" },
473 /* the following one is not in the Passport list, looks like an omission */
474 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KASHMIRI_INDIA
, "ks" },
475 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NEPALI_NEPAL
, "ne" },
476 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_NEPALI_INDIA
, "ne" },
477 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRISIAN_NETHERLANDS
, "fy" },
479 /* new as of 2001-03-01 (from Office Xp) */
480 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_HONG_KONG
, "en" },
481 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_INDIA
, "en" },
482 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_MALAYSIA
, "en" },
483 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_ENGLISH_SINGAPORE
, "en" },
484 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SYRIAC_SYRIA
, "syr" },
485 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SINHALESE_SRI_LANKA
, "si" },
486 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_CHEROKEE_UNITED_STATES
, "chr" },
487 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_INUKTITUT_CANADA
, "iu" },
488 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_AMHARIC_ETHIOPIA
, "am" },
490 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAMAZIGHT_MOROCCO
},
491 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN
},
493 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PASHTO_AFGHANISTAN
, "ps" },
494 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FILIPINO_PHILIPPINES
, "phi" },
495 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_DHIVEHI_MALDIVES
, "div" },
497 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_OROMO_ETHIOPIA
, "om" },
498 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIGRIGNA_ETHIOPIA
, "ti" },
499 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_TIGRIGNA_ERYTHREA
, "ti" },
501 /* New additions from Windows Xp/Passport SDK 2001-11-10. */
503 /* don't ask what this one means... It is commented out currently. */
505 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GREEK_GREECE2
},
508 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_UNITED_STATES
, "es" },
509 /* The following two IDs blatantly violate MS specs by using a */
510 /* sublanguage >,. */
511 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SPANISH_LATIN_AMERICA
, "es" },
512 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_NORTH_AFRICA
, "fr" },
514 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_MOROCCO
, "fr" },
515 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FRENCH_HAITI
, "fr" },
516 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_BENGALI_BANGLADESH
, "bn" },
517 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN
, "ar" },
518 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN
,"mn" },
520 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_EDO_NIGERIA
},
521 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_FULFULDE_NIGERIA
},
522 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_IBIBIO_NIGERIA
},
524 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HAUSA_NIGERIA
, "ha" },
525 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_YORUBA_NIGERIA
, "yo" },
526 /* language codes from, to, are (still) unknown. */
527 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_IGBO_NIGERIA
, "ibo" },
528 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_KANURI_NIGERIA
, "kau" },
529 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_GUARANI_PARAGUAY
, "gn" },
530 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_HAWAIIAN_UNITED_STATES
, "haw" },
531 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_LATIN
, "la" },
532 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_SOMALI_SOMALIA
, "so" },
534 /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */
535 /* not written (but OTOH the peculiar writing system is worth */
537 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_YI_CHINA
},
539 { TT_PLATFORM_MICROSOFT
, TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES
,"pap" },
542 #define NUM_FC_FT_LANGUAGE (int) (sizeof (fcFtLanguage) / sizeof (fcFtLanguage[0]))
545 FT_UShort language_id
;
549 static const FcMacRomanFake fcMacRomanFake
[] = {
550 { TT_MS_LANGID_JAPANESE_JAPAN
, "SJIS-WIN" },
551 { TT_MS_LANGID_ENGLISH_UNITED_STATES
, "ASCII" },
555 FcFontCapabilities(FT_Face face
);
557 #define NUM_FC_MAC_ROMAN_FAKE (int) (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0]))
564 * A shift-JIS will have many high bits turned on
567 FcLooksLikeSJIS (FcChar8
*string
, int len
)
569 int nhigh
= 0, nlow
= 0;
573 if (*string
++ & 0x80) nhigh
++;
577 * Heuristic -- if more than 1/3 of the bytes have the high-bit set,
578 * this is likely to be SJIS and not ROMAN
580 if (nhigh
* 2 > nlow
)
586 FcSfntNameTranscode (FT_SfntName
*sname
)
589 const char *fromcode
;
595 for (i
= 0; i
< NUM_FC_FT_ENCODING
; i
++)
596 if (fcFtEncoding
[i
].platform_id
== sname
->platform_id
&&
597 (fcFtEncoding
[i
].encoding_id
== TT_ENCODING_DONT_CARE
||
598 fcFtEncoding
[i
].encoding_id
== sname
->encoding_id
))
600 if (i
== NUM_FC_FT_ENCODING
)
602 fromcode
= fcFtEncoding
[i
].fromcode
;
605 * Many names encoded for TT_PLATFORM_MACINTOSH are broken
606 * in various ways. Kludge around them.
608 if (!strcmp (fromcode
, FC_ENCODING_MAC_ROMAN
))
610 if (sname
->language_id
== TT_MAC_LANGID_ENGLISH
&&
611 FcLooksLikeSJIS (sname
->string
, sname
->string_len
))
615 else if (sname
->language_id
>= 0x100)
618 * "real" Mac language IDs are all less than 150.
619 * Names using one of the MS language IDs are assumed
620 * to use an associated encoding (Yes, this is a kludge)
625 for (f
= 0; f
< NUM_FC_MAC_ROMAN_FAKE
; f
++)
626 if (fcMacRomanFake
[f
].language_id
== sname
->language_id
)
628 fromcode
= fcMacRomanFake
[f
].fromcode
;
635 if (!strcmp (fromcode
, "UCS-2BE") || !strcmp (fromcode
, "UTF-16BE"))
637 FcChar8
*src
= sname
->string
;
638 int src_len
= sname
->string_len
;
646 * Convert Utf16 to Utf8
649 if (!FcUtf16Len (src
, FcEndianBig
, src_len
, &len
, &wchar
))
653 * Allocate plenty of space. Freed below
655 utf8
= malloc (len
* FC_UTF8_MAX_LEN
+ 1);
661 while ((ilen
= FcUtf16ToUcs4 (src
, FcEndianBig
, &ucs4
, src_len
)) > 0)
665 olen
= FcUcs4ToUtf8 (ucs4
, u8
);
671 if (!strcmp (fromcode
, "ASCII") || !strcmp (fromcode
, "ISO-8859-1"))
673 FcChar8
*src
= sname
->string
;
674 int src_len
= sname
->string_len
;
680 * Convert Latin1 to Utf8. Freed below
682 utf8
= malloc (src_len
* 2 + 1);
691 olen
= FcUcs4ToUtf8 (ucs4
, u8
);
697 if (!strcmp (fromcode
, FC_ENCODING_MAC_ROMAN
))
700 const FcCharMap
*map
= FcFreeTypeGetPrivateMap (ft_encoding_apple_roman
);
701 FcChar8
*src
= (FcChar8
*) sname
->string
;
702 int src_len
= sname
->string_len
;
705 * Convert AppleRoman to Utf8
710 utf8
= malloc (sname
->string_len
* 3 + 1);
717 FcChar32 ucs4
= FcFreeTypePrivateToUcs4 (*src
++, map
);
718 int olen
= FcUcs4ToUtf8 (ucs4
, u8
);
726 cd
= iconv_open ("UTF-8", fromcode
);
727 if (cd
&& cd
!= (iconv_t
) (-1))
729 size_t in_bytes_left
= sname
->string_len
;
730 size_t out_bytes_left
= sname
->string_len
* FC_UTF8_MAX_LEN
;
731 char *inbuf
, *outbuf
;
733 utf8
= malloc (out_bytes_left
+ 1);
740 outbuf
= (char *) utf8
;
741 inbuf
= (char *) sname
->string
;
743 while (in_bytes_left
)
745 size_t did
= iconv (cd
,
746 &inbuf
, &in_bytes_left
,
747 &outbuf
, &out_bytes_left
);
748 if (did
== (size_t) (-1))
762 if (FcStrCmpIgnoreBlanksAndCase (utf8
, (FcChar8
*) "") == 0)
770 static const FcChar8
*
771 FcSfntNameLanguage (FT_SfntName
*sname
)
774 FT_UShort platform_id
= sname
->platform_id
;
775 FT_UShort language_id
= sname
->language_id
;
778 * Many names encoded for TT_PLATFORM_MACINTOSH are broken
779 * in various ways. Kludge around them.
781 if (platform_id
== TT_PLATFORM_MACINTOSH
&&
782 sname
->encoding_id
== TT_MAC_ID_ROMAN
&&
783 FcLooksLikeSJIS (sname
->string
, sname
->string_len
))
785 language_id
= TT_MAC_LANGID_JAPANESE
;
788 for (i
= 0; i
< NUM_FC_FT_LANGUAGE
; i
++)
789 if (fcFtLanguage
[i
].platform_id
== platform_id
&&
790 (fcFtLanguage
[i
].language_id
== TT_LANGUAGE_DONT_CARE
||
791 fcFtLanguage
[i
].language_id
== language_id
))
793 if (fcFtLanguage
[i
].lang
[0] == '\0')
796 return (FcChar8
*) fcFtLanguage
[i
].lang
;
801 /* Order is significant. For example, some B&H fonts are hinted by
802 URW++, and both strings appear in the notice. */
804 static const char notice_foundry_data
[] =
807 "Bitstream\0bitstream\0"
808 "Monotype\0monotype\0"
809 "Linotype\0linotype\0"
810 "LINOTYPE-HELL\0linotype\0"
813 "International Typeface Corporation\0itc\0"
814 "Tiro Typeworks\0tiro\0"
816 "Microsoft\0microsoft\0"
819 "HanYang System\0hanyang";
821 struct _notice_foundry
{
822 /* these are the offsets into the
823 * notice_foundry_data array.
825 unsigned char notice_offset
;
826 unsigned char foundry_offset
;
829 static const struct _notice_foundry FcNoticeFoundries
[] = {
847 #define NUM_NOTICE_FOUNDRIES (int) (sizeof (FcNoticeFoundries) / sizeof (FcNoticeFoundries[0]))
849 static const FcChar8
*
850 FcNoticeFoundry(const FT_String
*notice
)
855 for(i
= 0; i
< NUM_NOTICE_FOUNDRIES
; i
++)
857 const struct _notice_foundry
*nf
= &FcNoticeFoundries
[i
];
858 const char *n
= notice_foundry_data
+ nf
->notice_offset
;
859 const char *f
= notice_foundry_data
+ nf
->foundry_offset
;
861 if (strstr ((const char *) notice
, n
))
862 return (const FcChar8
*) f
;
868 FcVendorMatch(const FT_Char vendor
[4], const FT_Char
*vendor_string
)
870 /* vendor is not necessarily NUL-terminated. */
873 len
= strlen((char *) vendor_string
);
874 if (memcmp(vendor
, vendor_string
, len
) != 0)
876 for (i
= len
; i
< 4; i
++)
877 if (vendor
[i
] != ' ' && vendor
[i
] != '\0')
882 /* This table is partly taken from ttmkfdir by Joerg Pommnitz. */
884 /* It should not contain useless entries (such as UNKN) nor duplicate
885 entries for padding both with spaces and NULs. */
887 static const struct {
888 const FT_Char vendor
[5];
889 const FcChar8 foundry
[13];
890 } FcVendorFoundries
[] = {
896 { "ATEC", "alltype"},
898 { "BITS", "bitstream"},
900 { "DYNA", "dynalab"},
905 { "IMPR", "impress"},
906 { "LARA", "larabiefonts"},
907 { "LEAF", "interleaf"},
908 { "LETR", "letraset"},
909 { "LINO", "linotype"},
910 { "MACR", "macromedia"},
911 { "MONO", "monotype"},
912 { "MS", "microsoft"},
915 { "PARA", "paratype"},
922 #define NUM_VENDOR_FOUNDRIES (int) (sizeof (FcVendorFoundries) / sizeof (FcVendorFoundries[0]))
924 static const FcChar8
*
925 FcVendorFoundry(const FT_Char vendor
[4])
930 for(i
= 0; i
< NUM_VENDOR_FOUNDRIES
; i
++)
931 if (FcVendorMatch (vendor
, FcVendorFoundries
[i
].vendor
))
932 return FcVendorFoundries
[i
].foundry
;
936 typedef struct _FcStringConst
{
942 FcStringIsConst (const FcChar8
*string
,
943 const FcStringConst
*c
,
948 for (i
= 0; i
< nc
; i
++)
949 if (FcStrCmpIgnoreBlanksAndCase (string
, c
[i
].name
) == 0)
955 FcStringContainsConst (const FcChar8
*string
,
956 const FcStringConst
*c
,
961 for (i
= 0; i
< nc
; i
++)
962 if (FcStrContainsIgnoreBlanksAndCase (string
, c
[i
].name
))
967 typedef FcChar8
*FC8
;
969 static const FcStringConst weightConsts
[] = {
970 { (FC8
) "thin", FC_WEIGHT_THIN
},
971 { (FC8
) "extralight", FC_WEIGHT_EXTRALIGHT
},
972 { (FC8
) "ultralight", FC_WEIGHT_ULTRALIGHT
},
973 { (FC8
) "light", FC_WEIGHT_LIGHT
},
974 { (FC8
) "book", FC_WEIGHT_BOOK
},
975 { (FC8
) "regular", FC_WEIGHT_REGULAR
},
976 { (FC8
) "normal", FC_WEIGHT_NORMAL
},
977 { (FC8
) "medium", FC_WEIGHT_MEDIUM
},
978 { (FC8
) "demibold", FC_WEIGHT_DEMIBOLD
},
979 { (FC8
) "demi", FC_WEIGHT_DEMIBOLD
},
980 { (FC8
) "semibold", FC_WEIGHT_SEMIBOLD
},
981 { (FC8
) "extrabold", FC_WEIGHT_EXTRABOLD
},
982 { (FC8
) "superbold", FC_WEIGHT_EXTRABOLD
},
983 { (FC8
) "ultrabold", FC_WEIGHT_ULTRABOLD
},
984 { (FC8
) "bold", FC_WEIGHT_BOLD
},
985 { (FC8
) "black", FC_WEIGHT_BLACK
},
986 { (FC8
) "heavy", FC_WEIGHT_HEAVY
},
989 #define NUM_WEIGHT_CONSTS (int) (sizeof (weightConsts) / sizeof (weightConsts[0]))
991 #define FcIsWeight(s) FcStringIsConst(s,weightConsts,NUM_WEIGHT_CONSTS)
992 #define FcContainsWeight(s) FcStringContainsConst (s,weightConsts,NUM_WEIGHT_CONSTS)
994 static const FcStringConst widthConsts
[] = {
995 { (FC8
) "ultracondensed", FC_WIDTH_ULTRACONDENSED
},
996 { (FC8
) "extracondensed", FC_WIDTH_EXTRACONDENSED
},
997 { (FC8
) "semicondensed", FC_WIDTH_SEMICONDENSED
},
998 { (FC8
) "condensed", FC_WIDTH_CONDENSED
}, /* must be after *condensed */
999 { (FC8
) "normal", FC_WIDTH_NORMAL
},
1000 { (FC8
) "semiexpanded", FC_WIDTH_SEMIEXPANDED
},
1001 { (FC8
) "extraexpanded", FC_WIDTH_EXTRAEXPANDED
},
1002 { (FC8
) "ultraexpanded", FC_WIDTH_ULTRAEXPANDED
},
1003 { (FC8
) "expanded", FC_WIDTH_EXPANDED
}, /* must be after *expanded */
1006 #define NUM_WIDTH_CONSTS (int) (sizeof (widthConsts) / sizeof (widthConsts[0]))
1008 #define FcIsWidth(s) FcStringIsConst(s,widthConsts,NUM_WIDTH_CONSTS)
1009 #define FcContainsWidth(s) FcStringContainsConst (s,widthConsts,NUM_WIDTH_CONSTS)
1011 static const FcStringConst slantConsts
[] = {
1012 { (FC8
) "italic", FC_SLANT_ITALIC
},
1013 { (FC8
) "kursiv", FC_SLANT_ITALIC
},
1014 { (FC8
) "oblique", FC_SLANT_OBLIQUE
},
1017 #define NUM_SLANT_CONSTS (int) (sizeof (slantConsts) / sizeof (slantConsts[0]))
1019 #define FcIsSlant(s) FcStringIsConst(s,slantConsts,NUM_SLANT_CONSTS)
1020 #define FcContainsSlant(s) FcStringContainsConst (s,slantConsts,NUM_SLANT_CONSTS)
1022 static const FcStringConst decorativeConsts
[] = {
1023 { (FC8
) "shadow", FcTrue
},
1024 { (FC8
) "smallcaps", FcTrue
},
1025 { (FC8
) "antiqua", FcTrue
},
1026 { (FC8
) "romansc", FcTrue
},
1027 { (FC8
) "embosed", FcTrue
},
1028 { (FC8
) "romansmallcaps", FcTrue
},
1031 #define NUM_DECORATIVE_CONSTS (int) (sizeof (decorativeConsts) / sizeof (decorativeConsts[0]))
1033 #define FcIsDecorative(s) FcStringIsConst(s,decorativeConsts,NUM_DECORATIVE_CONSTS)
1034 #define FcContainsDecorative(s) FcStringContainsConst (s,decorativeConsts,NUM_DECORATIVE_CONSTS)
1037 FcGetPixelSize (FT_Face face
, int i
)
1039 #if HAVE_FT_GET_BDF_PROPERTY
1040 if (face
->num_fixed_sizes
== 1)
1042 BDF_PropertyRec prop
;
1045 rc
= FT_Get_BDF_Property (face
, "PIXEL_SIZE", &prop
);
1046 if (rc
== 0 && prop
.type
== BDF_PROPERTY_TYPE_INTEGER
)
1047 return (double) prop
.u
.integer
;
1050 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
1051 return (double) face
->available_sizes
[i
].y_ppem
/ 64.0;
1053 return (double) face
->available_sizes
[i
].height
;
1058 FcStringInPatternElement (FcPattern
*pat
, const char *elt
, FcChar8
*string
)
1062 for (e
= 0; FcPatternGetString (pat
, elt
, e
, &old
) == FcResultMatch
; e
++)
1063 if (!FcStrCmpIgnoreBlanksAndCase (old
, string
))
1070 static const FT_UShort platform_order
[] = {
1071 TT_PLATFORM_MICROSOFT
,
1072 TT_PLATFORM_APPLE_UNICODE
,
1073 TT_PLATFORM_MACINTOSH
,
1075 #define NUM_PLATFORM_ORDER (sizeof (platform_order) / sizeof (platform_order[0]))
1077 static const FT_UShort nameid_order
[] = {
1078 TT_NAME_ID_PREFERRED_FAMILY
,
1079 TT_NAME_ID_FONT_FAMILY
,
1080 TT_NAME_ID_MAC_FULL_NAME
,
1081 TT_NAME_ID_FULL_NAME
,
1082 TT_NAME_ID_PREFERRED_SUBFAMILY
,
1083 TT_NAME_ID_FONT_SUBFAMILY
,
1084 TT_NAME_ID_TRADEMARK
,
1085 TT_NAME_ID_MANUFACTURER
,
1088 #define NUM_NAMEID_ORDER (sizeof (nameid_order) / sizeof (nameid_order[0]))
1090 FcFreeTypeQueryFace (const FT_Face face
,
1091 const FcChar8
*file
,
1099 FcBool decorative
= FcFalse
;
1104 FcChar8
*family
= 0;
1107 const FcChar8
*foundry
= 0;
1110 #if HAVE_FT_GET_PS_FONT_INFO
1111 PS_FontInfoRec psfontinfo
;
1113 #if HAVE_FT_GET_BDF_PROPERTY
1114 BDF_PropertyRec prop
;
1117 const FcChar8
*exclusiveLang
= 0;
1119 FT_UInt snamei
, snamec
;
1122 int nfamily_lang
= 0;
1124 int nstyle_lang
= 0;
1126 int nfullname_lang
= 0;
1133 pat
= FcPatternCreate ();
1137 if (!FcPatternAddBool (pat
, FC_OUTLINE
,
1138 (face
->face_flags
& FT_FACE_FLAG_SCALABLE
) != 0))
1141 if (!FcPatternAddBool (pat
, FC_SCALABLE
,
1142 (face
->face_flags
& FT_FACE_FLAG_SCALABLE
) != 0))
1147 * Get the OS/2 table
1149 os2
= (TT_OS2
*) FT_Get_Sfnt_Table (face
, ft_sfnt_os2
);
1152 * Look first in the OS/2 table for the foundry, if
1153 * not found here, the various notices will be searched for
1154 * that information, either from the sfnt name tables or
1155 * the Postscript FontInfo dictionary. Finally, the
1156 * BDF properties will queried.
1159 if (os2
&& os2
->version
>= 0x0001 && os2
->version
!= 0xffff)
1160 foundry
= FcVendorFoundry(os2
->achVendID
);
1162 if (FcDebug () & FC_DBG_SCANV
)
1165 * Grub through the name table looking for family
1166 * and style names. FreeType makes quite a hash
1169 snamec
= FT_Get_Sfnt_Name_Count (face
);
1170 for (p
= 0; p
<= NUM_PLATFORM_ORDER
; p
++)
1172 if (p
< NUM_PLATFORM_ORDER
)
1173 platform
= platform_order
[p
];
1178 * Order nameids so preferred names appear first
1179 * in the resulting list
1181 for (n
= 0; n
< NUM_NAMEID_ORDER
; n
++)
1183 nameid
= nameid_order
[n
];
1185 for (snamei
= 0; snamei
< snamec
; snamei
++)
1188 const FcChar8
*lang
;
1189 const char *elt
= 0, *eltlang
= 0;
1190 int *np
= 0, *nlangp
= 0;
1192 if (FT_Get_Sfnt_Name (face
, snamei
, &sname
) != 0)
1194 if (sname
.name_id
!= nameid
)
1198 * Sort platforms in preference order, accepting
1199 * all other platforms last
1201 if (p
< NUM_PLATFORM_ORDER
)
1203 if (sname
.platform_id
!= platform
)
1210 for (sp
= 0; sp
< NUM_PLATFORM_ORDER
; sp
++)
1211 if (sname
.platform_id
== platform_order
[sp
])
1213 if (sp
!= NUM_PLATFORM_ORDER
)
1216 utf8
= FcSfntNameTranscode (&sname
);
1217 lang
= FcSfntNameLanguage (&sname
);
1222 switch (sname
.name_id
) {
1223 case TT_NAME_ID_PREFERRED_FAMILY
:
1224 case TT_NAME_ID_FONT_FAMILY
:
1226 case TT_NAME_ID_PS_NAME
:
1227 case TT_NAME_ID_UNIQUE_ID
:
1229 if (FcDebug () & FC_DBG_SCANV
)
1230 printf ("found family (n %2d p %d e %d l 0x%04x) %s\n",
1231 sname
.name_id
, sname
.platform_id
,
1232 sname
.encoding_id
, sname
.language_id
,
1236 eltlang
= FC_FAMILYLANG
;
1238 nlangp
= &nfamily_lang
;
1240 case TT_NAME_ID_MAC_FULL_NAME
:
1241 case TT_NAME_ID_FULL_NAME
:
1242 if (FcDebug () & FC_DBG_SCANV
)
1243 printf ("found full (n %2d p %d e %d l 0x%04x) %s\n",
1244 sname
.name_id
, sname
.platform_id
,
1245 sname
.encoding_id
, sname
.language_id
,
1249 eltlang
= FC_FULLNAMELANG
;
1251 nlangp
= &nfullname_lang
;
1253 case TT_NAME_ID_PREFERRED_SUBFAMILY
:
1254 case TT_NAME_ID_FONT_SUBFAMILY
:
1255 if (FcDebug () & FC_DBG_SCANV
)
1256 printf ("found style (n %2d p %d e %d l 0x%04x) %s\n",
1257 sname
.name_id
, sname
.platform_id
,
1258 sname
.encoding_id
, sname
.language_id
,
1262 eltlang
= FC_STYLELANG
;
1264 nlangp
= &nstyle_lang
;
1266 case TT_NAME_ID_TRADEMARK
:
1267 case TT_NAME_ID_MANUFACTURER
:
1268 /* If the foundry wasn't found in the OS/2 table, look here */
1270 foundry
= FcNoticeFoundry((FT_String
*) utf8
);
1275 if (FcStringInPatternElement (pat
, elt
, utf8
))
1281 /* add new element */
1282 if (!FcPatternAddString (pat
, elt
, utf8
))
1290 /* pad lang list with 'xx' to line up with elt */
1291 while (*nlangp
< *np
)
1293 if (!FcPatternAddString (pat
, eltlang
, (FcChar8
*) "xx"))
1297 if (!FcPatternAddString (pat
, eltlang
, lang
))
1309 if (!nfamily
&& face
->family_name
&&
1310 FcStrCmpIgnoreBlanksAndCase ((FcChar8
*) face
->family_name
, (FcChar8
*) "") != 0)
1312 if (FcDebug () & FC_DBG_SCANV
)
1313 printf ("using FreeType family \"%s\"\n", face
->family_name
);
1314 if (!FcPatternAddString (pat
, FC_FAMILY
, (FcChar8
*) face
->family_name
))
1319 if (!nstyle
&& face
->style_name
&&
1320 FcStrCmpIgnoreBlanksAndCase ((FcChar8
*) face
->style_name
, (FcChar8
*) "") != 0)
1322 if (FcDebug () & FC_DBG_SCANV
)
1323 printf ("using FreeType style \"%s\"\n", face
->style_name
);
1324 if (!FcPatternAddString (pat
, FC_STYLE
, (FcChar8
*) face
->style_name
))
1331 FcChar8
*start
, *end
;
1334 start
= (FcChar8
*) strrchr ((char *) file
, '/');
1338 start
= (FcChar8
*) file
;
1339 end
= (FcChar8
*) strrchr ((char *) start
, '.');
1341 end
= start
+ strlen ((char *) start
);
1343 family
= malloc (end
- start
+ 1);
1344 strncpy ((char *) family
, (char *) start
, end
- start
);
1345 family
[end
- start
] = '\0';
1346 if (FcDebug () & FC_DBG_SCANV
)
1347 printf ("using filename for family %s\n", family
);
1348 if (!FcPatternAddString (pat
, FC_FAMILY
, family
))
1357 if (!FcPatternAddString (pat
, FC_FILE
, file
))
1360 if (!FcPatternAddInteger (pat
, FC_INDEX
, id
))
1365 * don't even try this -- CJK 'monospace' fonts are really
1366 * dual width, and most other fonts don't bother to set
1367 * the attribute. Sigh.
1369 if ((face
->face_flags
& FT_FACE_FLAG_FIXED_WIDTH
) != 0)
1370 if (!FcPatternAddInteger (pat
, FC_SPACING
, FC_MONO
))
1375 * Find the font revision (if available)
1377 head
= (TT_Header
*) FT_Get_Sfnt_Table (face
, ft_sfnt_head
);
1380 if (!FcPatternAddInteger (pat
, FC_FONTVERSION
, head
->Font_Revision
))
1385 if (!FcPatternAddInteger (pat
, FC_FONTVERSION
, 0))
1389 if (os2
&& os2
->version
>= 0x0001 && os2
->version
!= 0xffff)
1391 for (i
= 0; i
< NUM_CODE_PAGE_RANGE
; i
++)
1395 if (FcCodePageRange
[i
].bit
< 32)
1397 bits
= os2
->ulCodePageRange1
;
1398 bit
= FcCodePageRange
[i
].bit
;
1402 bits
= os2
->ulCodePageRange2
;
1403 bit
= FcCodePageRange
[i
].bit
- 32;
1405 if (bits
& (1 << bit
))
1408 * If the font advertises support for multiple
1409 * "exclusive" languages, then include support
1410 * for any language found to have coverage
1417 exclusiveLang
= FcCodePageRange
[i
].lang
;
1422 if (os2
&& os2
->version
!= 0xffff)
1424 if (os2
->usWeightClass
== 0)
1426 else if (os2
->usWeightClass
< 150)
1427 weight
= FC_WEIGHT_THIN
;
1428 else if (os2
->usWeightClass
< 250)
1429 weight
= FC_WEIGHT_EXTRALIGHT
;
1430 else if (os2
->usWeightClass
< 350)
1431 weight
= FC_WEIGHT_LIGHT
;
1432 else if (os2
->usWeightClass
< 450)
1433 weight
= FC_WEIGHT_REGULAR
;
1434 else if (os2
->usWeightClass
< 550)
1435 weight
= FC_WEIGHT_MEDIUM
;
1436 else if (os2
->usWeightClass
< 650)
1437 weight
= FC_WEIGHT_SEMIBOLD
;
1438 else if (os2
->usWeightClass
< 750)
1439 weight
= FC_WEIGHT_BOLD
;
1440 else if (os2
->usWeightClass
< 850)
1441 weight
= FC_WEIGHT_EXTRABOLD
;
1442 else if (os2
->usWeightClass
< 950)
1443 weight
= FC_WEIGHT_BLACK
;
1444 if ((FcDebug() & FC_DBG_SCANV
) && weight
!= -1)
1445 printf ("\tos2 weight class %d maps to weight %d\n",
1446 os2
->usWeightClass
, weight
);
1448 switch (os2
->usWidthClass
) {
1449 case 1: width
= FC_WIDTH_ULTRACONDENSED
; break;
1450 case 2: width
= FC_WIDTH_EXTRACONDENSED
; break;
1451 case 3: width
= FC_WIDTH_CONDENSED
; break;
1452 case 4: width
= FC_WIDTH_SEMICONDENSED
; break;
1453 case 5: width
= FC_WIDTH_NORMAL
; break;
1454 case 6: width
= FC_WIDTH_SEMIEXPANDED
; break;
1455 case 7: width
= FC_WIDTH_EXPANDED
; break;
1456 case 8: width
= FC_WIDTH_EXTRAEXPANDED
; break;
1457 case 9: width
= FC_WIDTH_ULTRAEXPANDED
; break;
1459 if ((FcDebug() & FC_DBG_SCANV
) && width
!= -1)
1460 printf ("\tos2 width class %d maps to width %d\n",
1461 os2
->usWidthClass
, width
);
1463 if (os2
&& (complex = FcFontCapabilities(face
)))
1465 if (!FcPatternAddString (pat
, FC_CAPABILITY
, complex))
1474 * Type 1: Check for FontInfo dictionary information
1475 * Code from g2@magestudios.net (Gerard Escalante)
1478 #if HAVE_FT_GET_PS_FONT_INFO
1479 if (FT_Get_PS_Font_Info(face
, &psfontinfo
) == 0)
1481 if (weight
== -1 && psfontinfo
.weight
)
1483 weight
= FcIsWeight ((FcChar8
*) psfontinfo
.weight
);
1484 if (FcDebug() & FC_DBG_SCANV
)
1485 printf ("\tType1 weight %s maps to %d\n",
1486 psfontinfo
.weight
, weight
);
1491 * Don't bother with italic_angle; FreeType already extracts that
1492 * information for us and sticks it into style_flags
1494 if (psfontinfo
.italic_angle
)
1495 slant
= FC_SLANT_ITALIC
;
1497 slant
= FC_SLANT_ROMAN
;
1501 foundry
= FcNoticeFoundry(psfontinfo
.notice
);
1503 #endif /* HAVE_FT_GET_PS_FONT_INFO */
1505 #if HAVE_FT_GET_BDF_PROPERTY
1507 * Finally, look for a FOUNDRY BDF property if no other
1508 * mechanism has managed to locate a foundry
1514 rc
= FT_Get_BDF_Property(face
, "FOUNDRY", &prop
);
1515 if(rc
== 0 && prop
.type
== BDF_PROPERTY_TYPE_ATOM
)
1516 foundry
= (FcChar8
*) prop
.u
.atom
;
1521 if (FT_Get_BDF_Property(face
, "RELATIVE_SETWIDTH", &prop
) == 0 &&
1522 (prop
.type
== BDF_PROPERTY_TYPE_INTEGER
||
1523 prop
.type
== BDF_PROPERTY_TYPE_CARDINAL
))
1527 if (prop
.type
== BDF_PROPERTY_TYPE_INTEGER
)
1528 value
= prop
.u
.integer
;
1530 value
= (FT_Int32
) prop
.u
.cardinal
;
1531 switch ((value
+ 5) / 10) {
1532 case 1: width
= FC_WIDTH_ULTRACONDENSED
; break;
1533 case 2: width
= FC_WIDTH_EXTRACONDENSED
; break;
1534 case 3: width
= FC_WIDTH_CONDENSED
; break;
1535 case 4: width
= FC_WIDTH_SEMICONDENSED
; break;
1536 case 5: width
= FC_WIDTH_NORMAL
; break;
1537 case 6: width
= FC_WIDTH_SEMIEXPANDED
; break;
1538 case 7: width
= FC_WIDTH_EXPANDED
; break;
1539 case 8: width
= FC_WIDTH_EXTRAEXPANDED
; break;
1540 case 9: width
= FC_WIDTH_ULTRAEXPANDED
; break;
1544 FT_Get_BDF_Property (face
, "SETWIDTH_NAME", &prop
) == 0 &&
1545 prop
.type
== BDF_PROPERTY_TYPE_ATOM
)
1547 width
= FcIsWidth ((FcChar8
*) prop
.u
.atom
);
1548 if (FcDebug () & FC_DBG_SCANV
)
1549 printf ("\tsetwidth %s maps to %d\n", prop
.u
.atom
, width
);
1555 * Look for weight, width and slant names in the style value
1557 for (st
= 0; FcPatternGetString (pat
, FC_STYLE
, st
, &style
) == FcResultMatch
; st
++)
1561 weight
= FcContainsWeight (style
);
1562 if (FcDebug() & FC_DBG_SCANV
)
1563 printf ("\tStyle %s maps to weight %d\n", style
, weight
);
1567 width
= FcContainsWidth (style
);
1568 if (FcDebug() & FC_DBG_SCANV
)
1569 printf ("\tStyle %s maps to width %d\n", style
, width
);
1573 slant
= FcContainsSlant (style
);
1574 if (FcDebug() & FC_DBG_SCANV
)
1575 printf ("\tStyle %s maps to slant %d\n", style
, slant
);
1577 if (decorative
== FcFalse
)
1579 decorative
= FcContainsDecorative (style
) > 0;
1580 if (FcDebug() & FC_DBG_SCANV
)
1581 printf ("\tStyle %s maps to decorative %d\n", style
, decorative
);
1585 * Pull default values from the FreeType flags if more
1586 * specific values not found above
1590 slant
= FC_SLANT_ROMAN
;
1591 if (face
->style_flags
& FT_STYLE_FLAG_ITALIC
)
1592 slant
= FC_SLANT_ITALIC
;
1597 weight
= FC_WEIGHT_MEDIUM
;
1598 if (face
->style_flags
& FT_STYLE_FLAG_BOLD
)
1599 weight
= FC_WEIGHT_BOLD
;
1603 width
= FC_WIDTH_NORMAL
;
1606 foundry
= (FcChar8
*) "unknown";
1608 if (!FcPatternAddInteger (pat
, FC_SLANT
, slant
))
1611 if (!FcPatternAddInteger (pat
, FC_WEIGHT
, weight
))
1614 if (!FcPatternAddInteger (pat
, FC_WIDTH
, width
))
1617 if (!FcPatternAddString (pat
, FC_FOUNDRY
, foundry
))
1620 if (!FcPatternAddBool (pat
, FC_DECORATIVE
, decorative
))
1624 * Compute the unicode coverage for the font
1626 cs
= FcFreeTypeCharSetAndSpacing (face
, blanks
, &spacing
);
1630 #if HAVE_FT_GET_BDF_PROPERTY
1631 /* For PCF fonts, override the computed spacing with the one from
1633 if(FT_Get_BDF_Property(face
, "SPACING", &prop
) == 0 &&
1634 prop
.type
== BDF_PROPERTY_TYPE_ATOM
) {
1635 if(!strcmp(prop
.u
.atom
, "c") || !strcmp(prop
.u
.atom
, "C"))
1636 spacing
= FC_CHARCELL
;
1637 else if(!strcmp(prop
.u
.atom
, "m") || !strcmp(prop
.u
.atom
, "M"))
1639 else if(!strcmp(prop
.u
.atom
, "p") || !strcmp(prop
.u
.atom
, "P"))
1640 spacing
= FC_PROPORTIONAL
;
1645 * Skip over PCF fonts that have no encoded characters; they're
1646 * usually just Unicode fonts transcoded to some legacy encoding
1647 * ftglue.c forces us to approximate whether a font is a PCF font
1648 * or not by whether it has any BDF properties. Try PIXEL_SIZE;
1649 * I don't know how to get a list of BDF properties on the font. -PL
1651 if (FcCharSetCount (cs
) == 0)
1653 #if HAVE_FT_GET_BDF_PROPERTY
1654 if(FT_Get_BDF_Property(face
, "PIXEL_SIZE", &prop
) == 0)
1659 if (!FcPatternAddCharSet (pat
, FC_CHARSET
, cs
))
1662 ls
= FcFreeTypeLangSet (cs
, exclusiveLang
);
1666 if (!FcPatternAddLangSet (pat
, FC_LANG
, ls
))
1668 FcLangSetDestroy (ls
);
1672 FcLangSetDestroy (ls
);
1674 if (spacing
!= FC_PROPORTIONAL
)
1675 if (!FcPatternAddInteger (pat
, FC_SPACING
, spacing
))
1678 if (!(face
->face_flags
& FT_FACE_FLAG_SCALABLE
))
1680 for (i
= 0; i
< face
->num_fixed_sizes
; i
++)
1681 if (!FcPatternAddDouble (pat
, FC_PIXEL_SIZE
,
1682 FcGetPixelSize (face
, i
)))
1684 if (!FcPatternAddBool (pat
, FC_ANTIALIAS
, FcFalse
))
1686 #if HAVE_FT_GET_BDF_PROPERTY
1687 if(face
->num_fixed_sizes
== 1) {
1691 /* skip bitmap fonts which do not even have a family name */
1692 rc
= FT_Get_BDF_Property(face
, "FAMILY_NAME", &prop
);
1693 if (rc
!= 0 || prop
.type
!= BDF_PROPERTY_TYPE_ATOM
)
1696 rc
= FT_Get_BDF_Property(face
, "POINT_SIZE", &prop
);
1697 if(rc
== 0 && prop
.type
== BDF_PROPERTY_TYPE_INTEGER
)
1698 value
= prop
.u
.integer
;
1699 else if(rc
== 0 && prop
.type
== BDF_PROPERTY_TYPE_CARDINAL
)
1700 value
= prop
.u
.cardinal
;
1703 if(!FcPatternAddDouble(pat
, FC_SIZE
, value
/ 10.0))
1706 rc
= FT_Get_BDF_Property(face
, "RESOLUTION_Y", &prop
);
1707 if(rc
== 0 && prop
.type
== BDF_PROPERTY_TYPE_INTEGER
)
1708 value
= prop
.u
.integer
;
1709 else if(rc
== 0 && prop
.type
== BDF_PROPERTY_TYPE_CARDINAL
)
1710 value
= prop
.u
.cardinal
;
1713 if(!FcPatternAddDouble(pat
, FC_DPI
, (double)value
))
1721 #if HAVE_FT_GET_X11_FONT_FORMAT
1723 * Use the (not well documented or supported) X-specific function
1724 * from FreeType to figure out the font format
1727 const char *font_format
= FT_Get_X11_Font_Format (face
);
1729 FcPatternAddString (pat
, FC_FONTFORMAT
, (FcChar8
*) font_format
);
1734 * Drop our reference to the charset
1736 FcCharSetDestroy (cs
);
1741 FcCharSetDestroy (cs
);
1743 FcPatternDestroy (pat
);
1749 FcFreeTypeQuery(const FcChar8
*file
,
1755 FT_Library ftLibrary
;
1756 FcPattern
*pat
= NULL
;
1758 if (FT_Init_FreeType (&ftLibrary
))
1761 if (FT_New_Face (ftLibrary
, (char *) file
, id
, &face
))
1764 *count
= face
->num_faces
;
1766 pat
= FcFreeTypeQueryFace (face
, file
, id
, blanks
);
1768 FT_Done_Face (face
);
1770 FT_Done_FreeType (ftLibrary
);
1775 * For our purposes, this approximation is sufficient
1777 #if !HAVE_FT_GET_NEXT_CHAR
1778 #define FT_Get_Next_Char(face, ucs4, gi) ((ucs4) >= 0xffffff ? \
1780 (*(gi) = 1), (ucs4) + 1)
1781 #warning "No FT_Get_Next_Char: Please install freetype version 2.1.0 or newer"
1784 typedef struct _FcCharEnt
{
1786 unsigned char encode
;
1790 const FcCharEnt
*ent
;
1794 typedef struct _FcFontDecode
{
1795 FT_Encoding encoding
;
1796 const FcCharMap
*map
;
1800 static const FcCharEnt AppleRomanEnt
[] = {
1801 { 0x0020, 0x20 }, /* SPACE */
1802 { 0x0021, 0x21 }, /* EXCLAMATION MARK */
1803 { 0x0022, 0x22 }, /* QUOTATION MARK */
1804 { 0x0023, 0x23 }, /* NUMBER SIGN */
1805 { 0x0024, 0x24 }, /* DOLLAR SIGN */
1806 { 0x0025, 0x25 }, /* PERCENT SIGN */
1807 { 0x0026, 0x26 }, /* AMPERSAND */
1808 { 0x0027, 0x27 }, /* APOSTROPHE */
1809 { 0x0028, 0x28 }, /* LEFT PARENTHESIS */
1810 { 0x0029, 0x29 }, /* RIGHT PARENTHESIS */
1811 { 0x002A, 0x2A }, /* ASTERISK */
1812 { 0x002B, 0x2B }, /* PLUS SIGN */
1813 { 0x002C, 0x2C }, /* COMMA */
1814 { 0x002D, 0x2D }, /* HYPHEN-MINUS */
1815 { 0x002E, 0x2E }, /* FULL STOP */
1816 { 0x002F, 0x2F }, /* SOLIDUS */
1817 { 0x0030, 0x30 }, /* DIGIT ZERO */
1818 { 0x0031, 0x31 }, /* DIGIT ONE */
1819 { 0x0032, 0x32 }, /* DIGIT TWO */
1820 { 0x0033, 0x33 }, /* DIGIT THREE */
1821 { 0x0034, 0x34 }, /* DIGIT FOUR */
1822 { 0x0035, 0x35 }, /* DIGIT FIVE */
1823 { 0x0036, 0x36 }, /* DIGIT SIX */
1824 { 0x0037, 0x37 }, /* DIGIT SEVEN */
1825 { 0x0038, 0x38 }, /* DIGIT EIGHT */
1826 { 0x0039, 0x39 }, /* DIGIT NINE */
1827 { 0x003A, 0x3A }, /* COLON */
1828 { 0x003B, 0x3B }, /* SEMICOLON */
1829 { 0x003C, 0x3C }, /* LESS-THAN SIGN */
1830 { 0x003D, 0x3D }, /* EQUALS SIGN */
1831 { 0x003E, 0x3E }, /* GREATER-THAN SIGN */
1832 { 0x003F, 0x3F }, /* QUESTION MARK */
1833 { 0x0040, 0x40 }, /* COMMERCIAL AT */
1834 { 0x0041, 0x41 }, /* LATIN CAPITAL LETTER A */
1835 { 0x0042, 0x42 }, /* LATIN CAPITAL LETTER B */
1836 { 0x0043, 0x43 }, /* LATIN CAPITAL LETTER C */
1837 { 0x0044, 0x44 }, /* LATIN CAPITAL LETTER D */
1838 { 0x0045, 0x45 }, /* LATIN CAPITAL LETTER E */
1839 { 0x0046, 0x46 }, /* LATIN CAPITAL LETTER F */
1840 { 0x0047, 0x47 }, /* LATIN CAPITAL LETTER G */
1841 { 0x0048, 0x48 }, /* LATIN CAPITAL LETTER H */
1842 { 0x0049, 0x49 }, /* LATIN CAPITAL LETTER I */
1843 { 0x004A, 0x4A }, /* LATIN CAPITAL LETTER J */
1844 { 0x004B, 0x4B }, /* LATIN CAPITAL LETTER K */
1845 { 0x004C, 0x4C }, /* LATIN CAPITAL LETTER L */
1846 { 0x004D, 0x4D }, /* LATIN CAPITAL LETTER M */
1847 { 0x004E, 0x4E }, /* LATIN CAPITAL LETTER N */
1848 { 0x004F, 0x4F }, /* LATIN CAPITAL LETTER O */
1849 { 0x0050, 0x50 }, /* LATIN CAPITAL LETTER P */
1850 { 0x0051, 0x51 }, /* LATIN CAPITAL LETTER Q */
1851 { 0x0052, 0x52 }, /* LATIN CAPITAL LETTER R */
1852 { 0x0053, 0x53 }, /* LATIN CAPITAL LETTER S */
1853 { 0x0054, 0x54 }, /* LATIN CAPITAL LETTER T */
1854 { 0x0055, 0x55 }, /* LATIN CAPITAL LETTER U */
1855 { 0x0056, 0x56 }, /* LATIN CAPITAL LETTER V */
1856 { 0x0057, 0x57 }, /* LATIN CAPITAL LETTER W */
1857 { 0x0058, 0x58 }, /* LATIN CAPITAL LETTER X */
1858 { 0x0059, 0x59 }, /* LATIN CAPITAL LETTER Y */
1859 { 0x005A, 0x5A }, /* LATIN CAPITAL LETTER Z */
1860 { 0x005B, 0x5B }, /* LEFT SQUARE BRACKET */
1861 { 0x005C, 0x5C }, /* REVERSE SOLIDUS */
1862 { 0x005D, 0x5D }, /* RIGHT SQUARE BRACKET */
1863 { 0x005E, 0x5E }, /* CIRCUMFLEX ACCENT */
1864 { 0x005F, 0x5F }, /* LOW LINE */
1865 { 0x0060, 0x60 }, /* GRAVE ACCENT */
1866 { 0x0061, 0x61 }, /* LATIN SMALL LETTER A */
1867 { 0x0062, 0x62 }, /* LATIN SMALL LETTER B */
1868 { 0x0063, 0x63 }, /* LATIN SMALL LETTER C */
1869 { 0x0064, 0x64 }, /* LATIN SMALL LETTER D */
1870 { 0x0065, 0x65 }, /* LATIN SMALL LETTER E */
1871 { 0x0066, 0x66 }, /* LATIN SMALL LETTER F */
1872 { 0x0067, 0x67 }, /* LATIN SMALL LETTER G */
1873 { 0x0068, 0x68 }, /* LATIN SMALL LETTER H */
1874 { 0x0069, 0x69 }, /* LATIN SMALL LETTER I */
1875 { 0x006A, 0x6A }, /* LATIN SMALL LETTER J */
1876 { 0x006B, 0x6B }, /* LATIN SMALL LETTER K */
1877 { 0x006C, 0x6C }, /* LATIN SMALL LETTER L */
1878 { 0x006D, 0x6D }, /* LATIN SMALL LETTER M */
1879 { 0x006E, 0x6E }, /* LATIN SMALL LETTER N */
1880 { 0x006F, 0x6F }, /* LATIN SMALL LETTER O */
1881 { 0x0070, 0x70 }, /* LATIN SMALL LETTER P */
1882 { 0x0071, 0x71 }, /* LATIN SMALL LETTER Q */
1883 { 0x0072, 0x72 }, /* LATIN SMALL LETTER R */
1884 { 0x0073, 0x73 }, /* LATIN SMALL LETTER S */
1885 { 0x0074, 0x74 }, /* LATIN SMALL LETTER T */
1886 { 0x0075, 0x75 }, /* LATIN SMALL LETTER U */
1887 { 0x0076, 0x76 }, /* LATIN SMALL LETTER V */
1888 { 0x0077, 0x77 }, /* LATIN SMALL LETTER W */
1889 { 0x0078, 0x78 }, /* LATIN SMALL LETTER X */
1890 { 0x0079, 0x79 }, /* LATIN SMALL LETTER Y */
1891 { 0x007A, 0x7A }, /* LATIN SMALL LETTER Z */
1892 { 0x007B, 0x7B }, /* LEFT CURLY BRACKET */
1893 { 0x007C, 0x7C }, /* VERTICAL LINE */
1894 { 0x007D, 0x7D }, /* RIGHT CURLY BRACKET */
1895 { 0x007E, 0x7E }, /* TILDE */
1896 { 0x00A0, 0xCA }, /* NO-BREAK SPACE */
1897 { 0x00A1, 0xC1 }, /* INVERTED EXCLAMATION MARK */
1898 { 0x00A2, 0xA2 }, /* CENT SIGN */
1899 { 0x00A3, 0xA3 }, /* POUND SIGN */
1900 { 0x00A5, 0xB4 }, /* YEN SIGN */
1901 { 0x00A7, 0xA4 }, /* SECTION SIGN */
1902 { 0x00A8, 0xAC }, /* DIAERESIS */
1903 { 0x00A9, 0xA9 }, /* COPYRIGHT SIGN */
1904 { 0x00AA, 0xBB }, /* FEMININE ORDINAL INDICATOR */
1905 { 0x00AB, 0xC7 }, /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
1906 { 0x00AC, 0xC2 }, /* NOT SIGN */
1907 { 0x00AE, 0xA8 }, /* REGISTERED SIGN */
1908 { 0x00AF, 0xF8 }, /* MACRON */
1909 { 0x00B0, 0xA1 }, /* DEGREE SIGN */
1910 { 0x00B1, 0xB1 }, /* PLUS-MINUS SIGN */
1911 { 0x00B4, 0xAB }, /* ACUTE ACCENT */
1912 { 0x00B5, 0xB5 }, /* MICRO SIGN */
1913 { 0x00B6, 0xA6 }, /* PILCROW SIGN */
1914 { 0x00B7, 0xE1 }, /* MIDDLE DOT */
1915 { 0x00B8, 0xFC }, /* CEDILLA */
1916 { 0x00BA, 0xBC }, /* MASCULINE ORDINAL INDICATOR */
1917 { 0x00BB, 0xC8 }, /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
1918 { 0x00BF, 0xC0 }, /* INVERTED QUESTION MARK */
1919 { 0x00C0, 0xCB }, /* LATIN CAPITAL LETTER A WITH GRAVE */
1920 { 0x00C1, 0xE7 }, /* LATIN CAPITAL LETTER A WITH ACUTE */
1921 { 0x00C2, 0xE5 }, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
1922 { 0x00C3, 0xCC }, /* LATIN CAPITAL LETTER A WITH TILDE */
1923 { 0x00C4, 0x80 }, /* LATIN CAPITAL LETTER A WITH DIAERESIS */
1924 { 0x00C5, 0x81 }, /* LATIN CAPITAL LETTER A WITH RING ABOVE */
1925 { 0x00C6, 0xAE }, /* LATIN CAPITAL LETTER AE */
1926 { 0x00C7, 0x82 }, /* LATIN CAPITAL LETTER C WITH CEDILLA */
1927 { 0x00C8, 0xE9 }, /* LATIN CAPITAL LETTER E WITH GRAVE */
1928 { 0x00C9, 0x83 }, /* LATIN CAPITAL LETTER E WITH ACUTE */
1929 { 0x00CA, 0xE6 }, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
1930 { 0x00CB, 0xE8 }, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
1931 { 0x00CC, 0xED }, /* LATIN CAPITAL LETTER I WITH GRAVE */
1932 { 0x00CD, 0xEA }, /* LATIN CAPITAL LETTER I WITH ACUTE */
1933 { 0x00CE, 0xEB }, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
1934 { 0x00CF, 0xEC }, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
1935 { 0x00D1, 0x84 }, /* LATIN CAPITAL LETTER N WITH TILDE */
1936 { 0x00D2, 0xF1 }, /* LATIN CAPITAL LETTER O WITH GRAVE */
1937 { 0x00D3, 0xEE }, /* LATIN CAPITAL LETTER O WITH ACUTE */
1938 { 0x00D4, 0xEF }, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
1939 { 0x00D5, 0xCD }, /* LATIN CAPITAL LETTER O WITH TILDE */
1940 { 0x00D6, 0x85 }, /* LATIN CAPITAL LETTER O WITH DIAERESIS */
1941 { 0x00D8, 0xAF }, /* LATIN CAPITAL LETTER O WITH STROKE */
1942 { 0x00D9, 0xF4 }, /* LATIN CAPITAL LETTER U WITH GRAVE */
1943 { 0x00DA, 0xF2 }, /* LATIN CAPITAL LETTER U WITH ACUTE */
1944 { 0x00DB, 0xF3 }, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
1945 { 0x00DC, 0x86 }, /* LATIN CAPITAL LETTER U WITH DIAERESIS */
1946 { 0x00DF, 0xA7 }, /* LATIN SMALL LETTER SHARP S */
1947 { 0x00E0, 0x88 }, /* LATIN SMALL LETTER A WITH GRAVE */
1948 { 0x00E1, 0x87 }, /* LATIN SMALL LETTER A WITH ACUTE */
1949 { 0x00E2, 0x89 }, /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
1950 { 0x00E3, 0x8B }, /* LATIN SMALL LETTER A WITH TILDE */
1951 { 0x00E4, 0x8A }, /* LATIN SMALL LETTER A WITH DIAERESIS */
1952 { 0x00E5, 0x8C }, /* LATIN SMALL LETTER A WITH RING ABOVE */
1953 { 0x00E6, 0xBE }, /* LATIN SMALL LETTER AE */
1954 { 0x00E7, 0x8D }, /* LATIN SMALL LETTER C WITH CEDILLA */
1955 { 0x00E8, 0x8F }, /* LATIN SMALL LETTER E WITH GRAVE */
1956 { 0x00E9, 0x8E }, /* LATIN SMALL LETTER E WITH ACUTE */
1957 { 0x00EA, 0x90 }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
1958 { 0x00EB, 0x91 }, /* LATIN SMALL LETTER E WITH DIAERESIS */
1959 { 0x00EC, 0x93 }, /* LATIN SMALL LETTER I WITH GRAVE */
1960 { 0x00ED, 0x92 }, /* LATIN SMALL LETTER I WITH ACUTE */
1961 { 0x00EE, 0x94 }, /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
1962 { 0x00EF, 0x95 }, /* LATIN SMALL LETTER I WITH DIAERESIS */
1963 { 0x00F1, 0x96 }, /* LATIN SMALL LETTER N WITH TILDE */
1964 { 0x00F2, 0x98 }, /* LATIN SMALL LETTER O WITH GRAVE */
1965 { 0x00F3, 0x97 }, /* LATIN SMALL LETTER O WITH ACUTE */
1966 { 0x00F4, 0x99 }, /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
1967 { 0x00F5, 0x9B }, /* LATIN SMALL LETTER O WITH TILDE */
1968 { 0x00F6, 0x9A }, /* LATIN SMALL LETTER O WITH DIAERESIS */
1969 { 0x00F7, 0xD6 }, /* DIVISION SIGN */
1970 { 0x00F8, 0xBF }, /* LATIN SMALL LETTER O WITH STROKE */
1971 { 0x00F9, 0x9D }, /* LATIN SMALL LETTER U WITH GRAVE */
1972 { 0x00FA, 0x9C }, /* LATIN SMALL LETTER U WITH ACUTE */
1973 { 0x00FB, 0x9E }, /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
1974 { 0x00FC, 0x9F }, /* LATIN SMALL LETTER U WITH DIAERESIS */
1975 { 0x00FF, 0xD8 }, /* LATIN SMALL LETTER Y WITH DIAERESIS */
1976 { 0x0131, 0xF5 }, /* LATIN SMALL LETTER DOTLESS I */
1977 { 0x0152, 0xCE }, /* LATIN CAPITAL LIGATURE OE */
1978 { 0x0153, 0xCF }, /* LATIN SMALL LIGATURE OE */
1979 { 0x0178, 0xD9 }, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
1980 { 0x0192, 0xC4 }, /* LATIN SMALL LETTER F WITH HOOK */
1981 { 0x02C6, 0xF6 }, /* MODIFIER LETTER CIRCUMFLEX ACCENT */
1982 { 0x02C7, 0xFF }, /* CARON */
1983 { 0x02D8, 0xF9 }, /* BREVE */
1984 { 0x02D9, 0xFA }, /* DOT ABOVE */
1985 { 0x02DA, 0xFB }, /* RING ABOVE */
1986 { 0x02DB, 0xFE }, /* OGONEK */
1987 { 0x02DC, 0xF7 }, /* SMALL TILDE */
1988 { 0x02DD, 0xFD }, /* DOUBLE ACUTE ACCENT */
1989 { 0x03A9, 0xBD }, /* GREEK CAPITAL LETTER OMEGA */
1990 { 0x03C0, 0xB9 }, /* GREEK SMALL LETTER PI */
1991 { 0x2013, 0xD0 }, /* EN DASH */
1992 { 0x2014, 0xD1 }, /* EM DASH */
1993 { 0x2018, 0xD4 }, /* LEFT SINGLE QUOTATION MARK */
1994 { 0x2019, 0xD5 }, /* RIGHT SINGLE QUOTATION MARK */
1995 { 0x201A, 0xE2 }, /* SINGLE LOW-9 QUOTATION MARK */
1996 { 0x201C, 0xD2 }, /* LEFT DOUBLE QUOTATION MARK */
1997 { 0x201D, 0xD3 }, /* RIGHT DOUBLE QUOTATION MARK */
1998 { 0x201E, 0xE3 }, /* DOUBLE LOW-9 QUOTATION MARK */
1999 { 0x2020, 0xA0 }, /* DAGGER */
2000 { 0x2021, 0xE0 }, /* DOUBLE DAGGER */
2001 { 0x2022, 0xA5 }, /* BULLET */
2002 { 0x2026, 0xC9 }, /* HORIZONTAL ELLIPSIS */
2003 { 0x2030, 0xE4 }, /* PER MILLE SIGN */
2004 { 0x2039, 0xDC }, /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */
2005 { 0x203A, 0xDD }, /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */
2006 { 0x2044, 0xDA }, /* FRACTION SLASH */
2007 { 0x20AC, 0xDB }, /* EURO SIGN */
2008 { 0x2122, 0xAA }, /* TRADE MARK SIGN */
2009 { 0x2202, 0xB6 }, /* PARTIAL DIFFERENTIAL */
2010 { 0x2206, 0xC6 }, /* INCREMENT */
2011 { 0x220F, 0xB8 }, /* N-ARY PRODUCT */
2012 { 0x2211, 0xB7 }, /* N-ARY SUMMATION */
2013 { 0x221A, 0xC3 }, /* SQUARE ROOT */
2014 { 0x221E, 0xB0 }, /* INFINITY */
2015 { 0x222B, 0xBA }, /* INTEGRAL */
2016 { 0x2248, 0xC5 }, /* ALMOST EQUAL TO */
2017 { 0x2260, 0xAD }, /* NOT EQUAL TO */
2018 { 0x2264, 0xB2 }, /* LESS-THAN OR EQUAL TO */
2019 { 0x2265, 0xB3 }, /* GREATER-THAN OR EQUAL TO */
2020 { 0x25CA, 0xD7 }, /* LOZENGE */
2021 { 0xF8FF, 0xF0 }, /* Apple logo */
2022 { 0xFB01, 0xDE }, /* LATIN SMALL LIGATURE FI */
2023 { 0xFB02, 0xDF }, /* LATIN SMALL LIGATURE FL */
2026 static const FcCharMap AppleRoman
= {
2028 sizeof (AppleRomanEnt
) / sizeof (AppleRomanEnt
[0])
2031 static const FcCharEnt AdobeSymbolEnt
[] = {
2032 { 0x0020, 0x20 }, /* SPACE # space */
2033 { 0x0021, 0x21 }, /* EXCLAMATION MARK # exclam */
2034 { 0x0023, 0x23 }, /* NUMBER SIGN # numbersign */
2035 { 0x0025, 0x25 }, /* PERCENT SIGN # percent */
2036 { 0x0026, 0x26 }, /* AMPERSAND # ampersand */
2037 { 0x0028, 0x28 }, /* LEFT PARENTHESIS # parenleft */
2038 { 0x0029, 0x29 }, /* RIGHT PARENTHESIS # parenright */
2039 { 0x002B, 0x2B }, /* PLUS SIGN # plus */
2040 { 0x002C, 0x2C }, /* COMMA # comma */
2041 { 0x002E, 0x2E }, /* FULL STOP # period */
2042 { 0x002F, 0x2F }, /* SOLIDUS # slash */
2043 { 0x0030, 0x30 }, /* DIGIT ZERO # zero */
2044 { 0x0031, 0x31 }, /* DIGIT ONE # one */
2045 { 0x0032, 0x32 }, /* DIGIT TWO # two */
2046 { 0x0033, 0x33 }, /* DIGIT THREE # three */
2047 { 0x0034, 0x34 }, /* DIGIT FOUR # four */
2048 { 0x0035, 0x35 }, /* DIGIT FIVE # five */
2049 { 0x0036, 0x36 }, /* DIGIT SIX # six */
2050 { 0x0037, 0x37 }, /* DIGIT SEVEN # seven */
2051 { 0x0038, 0x38 }, /* DIGIT EIGHT # eight */
2052 { 0x0039, 0x39 }, /* DIGIT NINE # nine */
2053 { 0x003A, 0x3A }, /* COLON # colon */
2054 { 0x003B, 0x3B }, /* SEMICOLON # semicolon */
2055 { 0x003C, 0x3C }, /* LESS-THAN SIGN # less */
2056 { 0x003D, 0x3D }, /* EQUALS SIGN # equal */
2057 { 0x003E, 0x3E }, /* GREATER-THAN SIGN # greater */
2058 { 0x003F, 0x3F }, /* QUESTION MARK # question */
2059 { 0x005B, 0x5B }, /* LEFT SQUARE BRACKET # bracketleft */
2060 { 0x005D, 0x5D }, /* RIGHT SQUARE BRACKET # bracketright */
2061 { 0x005F, 0x5F }, /* LOW LINE # underscore */
2062 { 0x007B, 0x7B }, /* LEFT CURLY BRACKET # braceleft */
2063 { 0x007C, 0x7C }, /* VERTICAL LINE # bar */
2064 { 0x007D, 0x7D }, /* RIGHT CURLY BRACKET # braceright */
2065 { 0x00A0, 0x20 }, /* NO-BREAK SPACE # space */
2066 { 0x00AC, 0xD8 }, /* NOT SIGN # logicalnot */
2067 { 0x00B0, 0xB0 }, /* DEGREE SIGN # degree */
2068 { 0x00B1, 0xB1 }, /* PLUS-MINUS SIGN # plusminus */
2069 { 0x00B5, 0x6D }, /* MICRO SIGN # mu */
2070 { 0x00D7, 0xB4 }, /* MULTIPLICATION SIGN # multiply */
2071 { 0x00F7, 0xB8 }, /* DIVISION SIGN # divide */
2072 { 0x0192, 0xA6 }, /* LATIN SMALL LETTER F WITH HOOK # florin */
2073 { 0x0391, 0x41 }, /* GREEK CAPITAL LETTER ALPHA # Alpha */
2074 { 0x0392, 0x42 }, /* GREEK CAPITAL LETTER BETA # Beta */
2075 { 0x0393, 0x47 }, /* GREEK CAPITAL LETTER GAMMA # Gamma */
2076 { 0x0394, 0x44 }, /* GREEK CAPITAL LETTER DELTA # Delta */
2077 { 0x0395, 0x45 }, /* GREEK CAPITAL LETTER EPSILON # Epsilon */
2078 { 0x0396, 0x5A }, /* GREEK CAPITAL LETTER ZETA # Zeta */
2079 { 0x0397, 0x48 }, /* GREEK CAPITAL LETTER ETA # Eta */
2080 { 0x0398, 0x51 }, /* GREEK CAPITAL LETTER THETA # Theta */
2081 { 0x0399, 0x49 }, /* GREEK CAPITAL LETTER IOTA # Iota */
2082 { 0x039A, 0x4B }, /* GREEK CAPITAL LETTER KAPPA # Kappa */
2083 { 0x039B, 0x4C }, /* GREEK CAPITAL LETTER LAMDA # Lambda */
2084 { 0x039C, 0x4D }, /* GREEK CAPITAL LETTER MU # Mu */
2085 { 0x039D, 0x4E }, /* GREEK CAPITAL LETTER NU # Nu */
2086 { 0x039E, 0x58 }, /* GREEK CAPITAL LETTER XI # Xi */
2087 { 0x039F, 0x4F }, /* GREEK CAPITAL LETTER OMICRON # Omicron */
2088 { 0x03A0, 0x50 }, /* GREEK CAPITAL LETTER PI # Pi */
2089 { 0x03A1, 0x52 }, /* GREEK CAPITAL LETTER RHO # Rho */
2090 { 0x03A3, 0x53 }, /* GREEK CAPITAL LETTER SIGMA # Sigma */
2091 { 0x03A4, 0x54 }, /* GREEK CAPITAL LETTER TAU # Tau */
2092 { 0x03A5, 0x55 }, /* GREEK CAPITAL LETTER UPSILON # Upsilon */
2093 { 0x03A6, 0x46 }, /* GREEK CAPITAL LETTER PHI # Phi */
2094 { 0x03A7, 0x43 }, /* GREEK CAPITAL LETTER CHI # Chi */
2095 { 0x03A8, 0x59 }, /* GREEK CAPITAL LETTER PSI # Psi */
2096 { 0x03A9, 0x57 }, /* GREEK CAPITAL LETTER OMEGA # Omega */
2097 { 0x03B1, 0x61 }, /* GREEK SMALL LETTER ALPHA # alpha */
2098 { 0x03B2, 0x62 }, /* GREEK SMALL LETTER BETA # beta */
2099 { 0x03B3, 0x67 }, /* GREEK SMALL LETTER GAMMA # gamma */
2100 { 0x03B4, 0x64 }, /* GREEK SMALL LETTER DELTA # delta */
2101 { 0x03B5, 0x65 }, /* GREEK SMALL LETTER EPSILON # epsilon */
2102 { 0x03B6, 0x7A }, /* GREEK SMALL LETTER ZETA # zeta */
2103 { 0x03B7, 0x68 }, /* GREEK SMALL LETTER ETA # eta */
2104 { 0x03B8, 0x71 }, /* GREEK SMALL LETTER THETA # theta */
2105 { 0x03B9, 0x69 }, /* GREEK SMALL LETTER IOTA # iota */
2106 { 0x03BA, 0x6B }, /* GREEK SMALL LETTER KAPPA # kappa */
2107 { 0x03BB, 0x6C }, /* GREEK SMALL LETTER LAMDA # lambda */
2108 { 0x03BC, 0x6D }, /* GREEK SMALL LETTER MU # mu */
2109 { 0x03BD, 0x6E }, /* GREEK SMALL LETTER NU # nu */
2110 { 0x03BE, 0x78 }, /* GREEK SMALL LETTER XI # xi */
2111 { 0x03BF, 0x6F }, /* GREEK SMALL LETTER OMICRON # omicron */
2112 { 0x03C0, 0x70 }, /* GREEK SMALL LETTER PI # pi */
2113 { 0x03C1, 0x72 }, /* GREEK SMALL LETTER RHO # rho */
2114 { 0x03C2, 0x56 }, /* GREEK SMALL LETTER FINAL SIGMA # sigma1 */
2115 { 0x03C3, 0x73 }, /* GREEK SMALL LETTER SIGMA # sigma */
2116 { 0x03C4, 0x74 }, /* GREEK SMALL LETTER TAU # tau */
2117 { 0x03C5, 0x75 }, /* GREEK SMALL LETTER UPSILON # upsilon */
2118 { 0x03C6, 0x66 }, /* GREEK SMALL LETTER PHI # phi */
2119 { 0x03C7, 0x63 }, /* GREEK SMALL LETTER CHI # chi */
2120 { 0x03C8, 0x79 }, /* GREEK SMALL LETTER PSI # psi */
2121 { 0x03C9, 0x77 }, /* GREEK SMALL LETTER OMEGA # omega */
2122 { 0x03D1, 0x4A }, /* GREEK THETA SYMBOL # theta1 */
2123 { 0x03D2, 0xA1 }, /* GREEK UPSILON WITH HOOK SYMBOL # Upsilon1 */
2124 { 0x03D5, 0x6A }, /* GREEK PHI SYMBOL # phi1 */
2125 { 0x03D6, 0x76 }, /* GREEK PI SYMBOL # omega1 */
2126 { 0x2022, 0xB7 }, /* BULLET # bullet */
2127 { 0x2026, 0xBC }, /* HORIZONTAL ELLIPSIS # ellipsis */
2128 { 0x2032, 0xA2 }, /* PRIME # minute */
2129 { 0x2033, 0xB2 }, /* DOUBLE PRIME # second */
2130 { 0x2044, 0xA4 }, /* FRACTION SLASH # fraction */
2131 { 0x20AC, 0xA0 }, /* EURO SIGN # Euro */
2132 { 0x2111, 0xC1 }, /* BLACK-LETTER CAPITAL I # Ifraktur */
2133 { 0x2118, 0xC3 }, /* SCRIPT CAPITAL P # weierstrass */
2134 { 0x211C, 0xC2 }, /* BLACK-LETTER CAPITAL R # Rfraktur */
2135 { 0x2126, 0x57 }, /* OHM SIGN # Omega */
2136 { 0x2135, 0xC0 }, /* ALEF SYMBOL # aleph */
2137 { 0x2190, 0xAC }, /* LEFTWARDS ARROW # arrowleft */
2138 { 0x2191, 0xAD }, /* UPWARDS ARROW # arrowup */
2139 { 0x2192, 0xAE }, /* RIGHTWARDS ARROW # arrowright */
2140 { 0x2193, 0xAF }, /* DOWNWARDS ARROW # arrowdown */
2141 { 0x2194, 0xAB }, /* LEFT RIGHT ARROW # arrowboth */
2142 { 0x21B5, 0xBF }, /* DOWNWARDS ARROW WITH CORNER LEFTWARDS # carriagereturn */
2143 { 0x21D0, 0xDC }, /* LEFTWARDS DOUBLE ARROW # arrowdblleft */
2144 { 0x21D1, 0xDD }, /* UPWARDS DOUBLE ARROW # arrowdblup */
2145 { 0x21D2, 0xDE }, /* RIGHTWARDS DOUBLE ARROW # arrowdblright */
2146 { 0x21D3, 0xDF }, /* DOWNWARDS DOUBLE ARROW # arrowdbldown */
2147 { 0x21D4, 0xDB }, /* LEFT RIGHT DOUBLE ARROW # arrowdblboth */
2148 { 0x2200, 0x22 }, /* FOR ALL # universal */
2149 { 0x2202, 0xB6 }, /* PARTIAL DIFFERENTIAL # partialdiff */
2150 { 0x2203, 0x24 }, /* THERE EXISTS # existential */
2151 { 0x2205, 0xC6 }, /* EMPTY SET # emptyset */
2152 { 0x2206, 0x44 }, /* INCREMENT # Delta */
2153 { 0x2207, 0xD1 }, /* NABLA # gradient */
2154 { 0x2208, 0xCE }, /* ELEMENT OF # element */
2155 { 0x2209, 0xCF }, /* NOT AN ELEMENT OF # notelement */
2156 { 0x220B, 0x27 }, /* CONTAINS AS MEMBER # suchthat */
2157 { 0x220F, 0xD5 }, /* N-ARY PRODUCT # product */
2158 { 0x2211, 0xE5 }, /* N-ARY SUMMATION # summation */
2159 { 0x2212, 0x2D }, /* MINUS SIGN # minus */
2160 { 0x2215, 0xA4 }, /* DIVISION SLASH # fraction */
2161 { 0x2217, 0x2A }, /* ASTERISK OPERATOR # asteriskmath */
2162 { 0x221A, 0xD6 }, /* SQUARE ROOT # radical */
2163 { 0x221D, 0xB5 }, /* PROPORTIONAL TO # proportional */
2164 { 0x221E, 0xA5 }, /* INFINITY # infinity */
2165 { 0x2220, 0xD0 }, /* ANGLE # angle */
2166 { 0x2227, 0xD9 }, /* LOGICAL AND # logicaland */
2167 { 0x2228, 0xDA }, /* LOGICAL OR # logicalor */
2168 { 0x2229, 0xC7 }, /* INTERSECTION # intersection */
2169 { 0x222A, 0xC8 }, /* UNION # union */
2170 { 0x222B, 0xF2 }, /* INTEGRAL # integral */
2171 { 0x2234, 0x5C }, /* THEREFORE # therefore */
2172 { 0x223C, 0x7E }, /* TILDE OPERATOR # similar */
2173 { 0x2245, 0x40 }, /* APPROXIMATELY EQUAL TO # congruent */
2174 { 0x2248, 0xBB }, /* ALMOST EQUAL TO # approxequal */
2175 { 0x2260, 0xB9 }, /* NOT EQUAL TO # notequal */
2176 { 0x2261, 0xBA }, /* IDENTICAL TO # equivalence */
2177 { 0x2264, 0xA3 }, /* LESS-THAN OR EQUAL TO # lessequal */
2178 { 0x2265, 0xB3 }, /* GREATER-THAN OR EQUAL TO # greaterequal */
2179 { 0x2282, 0xCC }, /* SUBSET OF # propersubset */
2180 { 0x2283, 0xC9 }, /* SUPERSET OF # propersuperset */
2181 { 0x2284, 0xCB }, /* NOT A SUBSET OF # notsubset */
2182 { 0x2286, 0xCD }, /* SUBSET OF OR EQUAL TO # reflexsubset */
2183 { 0x2287, 0xCA }, /* SUPERSET OF OR EQUAL TO # reflexsuperset */
2184 { 0x2295, 0xC5 }, /* CIRCLED PLUS # circleplus */
2185 { 0x2297, 0xC4 }, /* CIRCLED TIMES # circlemultiply */
2186 { 0x22A5, 0x5E }, /* UP TACK # perpendicular */
2187 { 0x22C5, 0xD7 }, /* DOT OPERATOR # dotmath */
2188 { 0x2320, 0xF3 }, /* TOP HALF INTEGRAL # integraltp */
2189 { 0x2321, 0xF5 }, /* BOTTOM HALF INTEGRAL # integralbt */
2190 { 0x2329, 0xE1 }, /* LEFT-POINTING ANGLE BRACKET # angleleft */
2191 { 0x232A, 0xF1 }, /* RIGHT-POINTING ANGLE BRACKET # angleright */
2192 { 0x25CA, 0xE0 }, /* LOZENGE # lozenge */
2193 { 0x2660, 0xAA }, /* BLACK SPADE SUIT # spade */
2194 { 0x2663, 0xA7 }, /* BLACK CLUB SUIT # club */
2195 { 0x2665, 0xA9 }, /* BLACK HEART SUIT # heart */
2196 { 0x2666, 0xA8 }, /* BLACK DIAMOND SUIT # diamond */
2197 { 0xF6D9, 0xD3 }, /* COPYRIGHT SIGN SERIF # copyrightserif (CUS) */
2198 { 0xF6DA, 0xD2 }, /* REGISTERED SIGN SERIF # registerserif (CUS) */
2199 { 0xF6DB, 0xD4 }, /* TRADE MARK SIGN SERIF # trademarkserif (CUS) */
2200 { 0xF8E5, 0x60 }, /* RADICAL EXTENDER # radicalex (CUS) */
2201 { 0xF8E6, 0xBD }, /* VERTICAL ARROW EXTENDER # arrowvertex (CUS) */
2202 { 0xF8E7, 0xBE }, /* HORIZONTAL ARROW EXTENDER # arrowhorizex (CUS) */
2203 { 0xF8E8, 0xE2 }, /* REGISTERED SIGN SANS SERIF # registersans (CUS) */
2204 { 0xF8E9, 0xE3 }, /* COPYRIGHT SIGN SANS SERIF # copyrightsans (CUS) */
2205 { 0xF8EA, 0xE4 }, /* TRADE MARK SIGN SANS SERIF # trademarksans (CUS) */
2206 { 0xF8EB, 0xE6 }, /* LEFT PAREN TOP # parenlefttp (CUS) */
2207 { 0xF8EC, 0xE7 }, /* LEFT PAREN EXTENDER # parenleftex (CUS) */
2208 { 0xF8ED, 0xE8 }, /* LEFT PAREN BOTTOM # parenleftbt (CUS) */
2209 { 0xF8EE, 0xE9 }, /* LEFT SQUARE BRACKET TOP # bracketlefttp (CUS) */
2210 { 0xF8EF, 0xEA }, /* LEFT SQUARE BRACKET EXTENDER # bracketleftex (CUS) */
2211 { 0xF8F0, 0xEB }, /* LEFT SQUARE BRACKET BOTTOM # bracketleftbt (CUS) */
2212 { 0xF8F1, 0xEC }, /* LEFT CURLY BRACKET TOP # bracelefttp (CUS) */
2213 { 0xF8F2, 0xED }, /* LEFT CURLY BRACKET MID # braceleftmid (CUS) */
2214 { 0xF8F3, 0xEE }, /* LEFT CURLY BRACKET BOTTOM # braceleftbt (CUS) */
2215 { 0xF8F4, 0xEF }, /* CURLY BRACKET EXTENDER # braceex (CUS) */
2216 { 0xF8F5, 0xF4 }, /* INTEGRAL EXTENDER # integralex (CUS) */
2217 { 0xF8F6, 0xF6 }, /* RIGHT PAREN TOP # parenrighttp (CUS) */
2218 { 0xF8F7, 0xF7 }, /* RIGHT PAREN EXTENDER # parenrightex (CUS) */
2219 { 0xF8F8, 0xF8 }, /* RIGHT PAREN BOTTOM # parenrightbt (CUS) */
2220 { 0xF8F9, 0xF9 }, /* RIGHT SQUARE BRACKET TOP # bracketrighttp (CUS) */
2221 { 0xF8FA, 0xFA }, /* RIGHT SQUARE BRACKET EXTENDER # bracketrightex (CUS) */
2222 { 0xF8FB, 0xFB }, /* RIGHT SQUARE BRACKET BOTTOM # bracketrightbt (CUS) */
2223 { 0xF8FC, 0xFC }, /* RIGHT CURLY BRACKET TOP # bracerighttp (CUS) */
2224 { 0xF8FD, 0xFD }, /* RIGHT CURLY BRACKET MID # bracerightmid (CUS) */
2225 { 0xF8FE, 0xFE }, /* RIGHT CURLY BRACKET BOTTOM # bracerightbt (CUS) */
2228 static const FcCharMap AdobeSymbol
= {
2230 sizeof (AdobeSymbolEnt
) / sizeof (AdobeSymbolEnt
[0]),
2233 static const FcFontDecode fcFontDecoders
[] = {
2234 { ft_encoding_unicode
, 0, (1 << 21) - 1 },
2235 { ft_encoding_symbol
, &AdobeSymbol
, (1 << 16) - 1 },
2236 { ft_encoding_apple_roman
, &AppleRoman
, (1 << 16) - 1 },
2239 #define NUM_DECODE (int) (sizeof (fcFontDecoders) / sizeof (fcFontDecoders[0]))
2241 static const FcChar32 prefer_unicode
[] = {
2242 0x20ac, /* EURO SIGN */
2245 #define NUM_PREFER_UNICODE (int) (sizeof (prefer_unicode) / sizeof (prefer_unicode[0]))
2248 FcFreeTypeUcs4ToPrivate (FcChar32 ucs4
, const FcCharMap
*map
)
2254 high
= map
->nent
- 1;
2255 if (ucs4
< map
->ent
[low
].bmp
|| map
->ent
[high
].bmp
< ucs4
)
2259 mid
= (high
+ low
) >> 1;
2260 bmp
= map
->ent
[mid
].bmp
;
2262 return (FT_ULong
) map
->ent
[mid
].encode
;
2272 FcFreeTypePrivateToUcs4 (FcChar32
private, const FcCharMap
*map
)
2276 for (i
= 0; i
< map
->nent
; i
++)
2277 if (map
->ent
[i
].encode
== private)
2278 return (FcChar32
) map
->ent
[i
].bmp
;
2283 FcFreeTypeGetPrivateMap (FT_Encoding encoding
)
2287 for (i
= 0; i
< NUM_DECODE
; i
++)
2288 if (fcFontDecoders
[i
].encoding
== encoding
)
2289 return fcFontDecoders
[i
].map
;
2293 #include "../fc-glyphname/fcglyphname.h"
2296 FcHashGlyphName (const FcChar8
*name
)
2301 while ((c
= *name
++))
2303 h
= ((h
<< 1) | (h
>> 31)) ^ c
;
2308 #if HAVE_FT_HAS_PS_GLYPH_NAMES
2310 * Use Type1 glyph names for fonts which have reliable names
2311 * and which export an Adobe Custom mapping
2314 FcFreeTypeUseNames (FT_Face face
)
2318 if (!FT_Has_PS_Glyph_Names (face
))
2320 for (map
= 0; map
< face
->num_charmaps
; map
++)
2321 if (face
->charmaps
[map
]->encoding
== ft_encoding_adobe_custom
)
2326 static const FcChar8
*
2327 FcUcs4ToGlyphName (FcChar32 ucs4
)
2329 int i
= (int) (ucs4
% FC_GLYPHNAME_HASH
);
2333 while ((gn
= ucs_to_name
[i
]) != -1)
2335 if (glyphs
[gn
].ucs
== ucs4
)
2336 return glyphs
[gn
].name
;
2339 r
= (int) (ucs4
% FC_GLYPHNAME_REHASH
);
2344 if (i
>= FC_GLYPHNAME_HASH
)
2345 i
-= FC_GLYPHNAME_HASH
;
2351 FcGlyphNameToUcs4 (FcChar8
*name
)
2353 FcChar32 h
= FcHashGlyphName (name
);
2354 int i
= (int) (h
% FC_GLYPHNAME_HASH
);
2358 while ((gn
= name_to_ucs
[i
]) != -1)
2360 if (!strcmp ((char *) name
, (char *) glyphs
[gn
].name
))
2361 return glyphs
[gn
].ucs
;
2364 r
= (int) (h
% FC_GLYPHNAME_REHASH
);
2369 if (i
>= FC_GLYPHNAME_HASH
)
2370 i
-= FC_GLYPHNAME_HASH
;
2376 * Work around a bug in some FreeType versions which fail
2377 * to correctly bounds check glyph name buffers and overwrite
2378 * the stack. As Postscript names have a limit of 127 characters,
2379 * this should be sufficient.
2382 #if FC_GLYPHNAME_MAXLEN < 127
2383 # define FC_GLYPHNAME_BUFLEN 127
2385 # define FC_GLYPHNAME_BUFLEN FC_GLYPHNAME_MAXLEN
2389 * Search through a font for a glyph by name. This is
2390 * currently a linear search as there doesn't appear to be
2391 * any defined order within the font
2394 FcFreeTypeGlyphNameIndex (FT_Face face
, const FcChar8
*name
)
2397 FcChar8 name_buf
[FC_GLYPHNAME_BUFLEN
+ 2];
2399 for (gindex
= 0; gindex
< (FT_UInt
) face
->num_glyphs
; gindex
++)
2401 if (FT_Get_Glyph_Name (face
, gindex
, name_buf
, FC_GLYPHNAME_BUFLEN
+1) == 0)
2402 if (!strcmp ((char *) name
, (char *) name_buf
))
2410 * Map a UCS4 glyph to a glyph index. Use all available encoding
2411 * tables to try and find one that works. This information is expected
2412 * to be cached by higher levels, so performance isn't critical
2416 FcFreeTypeCharIndex (FT_Face face
, FcChar32 ucs4
)
2418 int initial
, offset
, decode
;
2429 * Find the current encoding
2433 for (; initial
< NUM_DECODE
; initial
++)
2434 if (fcFontDecoders
[initial
].encoding
== face
->charmap
->encoding
)
2436 if (initial
== NUM_DECODE
)
2439 for (p
= 0; p
< NUM_PREFER_UNICODE
; p
++)
2440 if (ucs4
== prefer_unicode
[p
])
2446 * Check each encoding for the glyph, starting with the current one
2448 for (offset
= 0; offset
< NUM_DECODE
; offset
++)
2450 decode
= (initial
+ offset
) % NUM_DECODE
;
2451 if (!face
->charmap
|| face
->charmap
->encoding
!= fcFontDecoders
[decode
].encoding
)
2452 if (FT_Select_Charmap (face
, fcFontDecoders
[decode
].encoding
) != 0)
2454 if (fcFontDecoders
[decode
].map
)
2456 charcode
= FcFreeTypeUcs4ToPrivate (ucs4
, fcFontDecoders
[decode
].map
);
2457 if (charcode
== ~0U)
2462 glyphindex
= FT_Get_Char_Index (face
, (FT_ULong
) charcode
);
2466 #if HAVE_FT_HAS_PS_GLYPH_NAMES
2468 * Check postscript name table if present
2470 if (FcFreeTypeUseNames (face
))
2472 const FcChar8
*name
= FcUcs4ToGlyphName (ucs4
);
2475 glyphindex
= FcFreeTypeGlyphNameIndex (face
, name
);
2485 FcFreeTypeCheckGlyph (FT_Face face
, FcChar32 ucs4
,
2486 FT_UInt glyph
, FcBlanks
*blanks
,
2489 FT_Int load_flags
= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
| FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
;
2493 * When using scalable fonts, only report those glyphs
2494 * which can be scaled; otherwise those fonts will
2495 * only be available at some sizes, and never when
2496 * transformed. Avoid this by simply reporting bitmap-only
2499 if (face
->face_flags
& FT_FACE_FLAG_SCALABLE
)
2500 load_flags
|= FT_LOAD_NO_BITMAP
;
2502 if (FT_Load_Glyph (face
, glyph
, load_flags
))
2509 *advance
= slot
->metrics
.horiAdvance
;
2511 switch (slot
->format
) {
2512 case ft_glyph_format_bitmap
:
2514 * Bitmaps are assumed to be reasonable; if
2515 * this proves to be a rash assumption, this
2516 * code can be easily modified
2519 case ft_glyph_format_outline
:
2521 * Glyphs with contours are always OK
2523 if (slot
->outline
.n_contours
!= 0)
2526 * Glyphs with no contours are only OK if
2527 * they're members of the Blanks set specified
2528 * in the configuration. If blanks isn't set,
2529 * then allow any glyph to be blank
2531 if (!blanks
|| FcBlanksIsMember (blanks
, ucs4
))
2533 /* fall through ... */
2540 #define FC_MIN(a,b) ((a) < (b) ? (a) : (b))
2541 #define FC_MAX(a,b) ((a) > (b) ? (a) : (b))
2542 #define FC_ABS(a) ((a) < 0 ? -(a) : (a))
2543 #define APPROXIMATELY_EQUAL(x,y) (FC_ABS ((x) - (y)) <= FC_MAX (FC_ABS (x), FC_ABS (y)) / 33)
2546 FcFreeTypeCharSetAndSpacing (FT_Face face
, FcBlanks
*blanks
, int *spacing
)
2548 FcChar32 page
, off
, ucs4
;
2550 FcChar32 font_max
= 0;
2554 const FcCharMap
*map
;
2558 FT_Pos advance
, advance_one
= 0, advance_two
= 0;
2559 FcBool has_advance
= FcFalse
, fixed_advance
= FcTrue
, dual_advance
= FcFalse
;
2561 fcs
= FcCharSetCreate ();
2566 printf ("Family %s style %s\n", face
->family_name
, face
->style_name
);
2568 for (o
= 0; o
< NUM_DECODE
; o
++)
2570 if (FT_Select_Charmap (face
, fcFontDecoders
[o
].encoding
) != 0)
2572 map
= fcFontDecoders
[o
].map
;
2576 * Non-Unicode tables are easy; there's a list of all possible
2579 for (i
= 0; i
< map
->nent
; i
++)
2581 ucs4
= map
->ent
[i
].bmp
;
2582 glyph
= FT_Get_Char_Index (face
, map
->ent
[i
].encode
);
2584 FcFreeTypeCheckGlyph (face
, ucs4
, glyph
, blanks
, &advance
))
2587 * ignore glyphs with zero advance. They’re
2588 * combining characters, and while their behaviour
2589 * isn’t well defined for monospaced applications in
2590 * Unicode, there are many fonts which include
2591 * zero-width combining characters in otherwise
2598 has_advance
= FcTrue
;
2599 advance_one
= advance
;
2601 else if (!APPROXIMATELY_EQUAL (advance
, advance_one
))
2605 dual_advance
= FcTrue
;
2606 fixed_advance
= FcFalse
;
2607 advance_two
= advance
;
2609 else if (!APPROXIMATELY_EQUAL (advance
, advance_two
))
2610 dual_advance
= FcFalse
;
2614 leaf
= FcCharSetFindLeafCreate (fcs
, ucs4
);
2617 leaf
->map
[(ucs4
& 0xff) >> 5] |= (1 << (ucs4
& 0x1f));
2619 if (ucs4
> font_max
)
2629 ucs4
= FT_Get_First_Char (face
, &glyph
);
2632 if (FcFreeTypeCheckGlyph (face
, ucs4
, glyph
, blanks
, &advance
))
2638 has_advance
= FcTrue
;
2639 advance_one
= advance
;
2641 else if (!APPROXIMATELY_EQUAL (advance
, advance_one
))
2645 dual_advance
= FcTrue
;
2646 fixed_advance
= FcFalse
;
2647 advance_two
= advance
;
2649 else if (!APPROXIMATELY_EQUAL (advance
, advance_two
))
2650 dual_advance
= FcFalse
;
2654 if ((ucs4
>> 8) != page
)
2657 leaf
= FcCharSetFindLeafCreate (fcs
, ucs4
);
2662 leaf
->map
[off
>> 5] |= (1 << (off
& 0x1f));
2664 if (ucs4
> font_max
)
2668 ucs4
= FT_Get_Next_Char (face
, ucs4
, &glyph
);
2671 for (ucs4
= 0; ucs4
< 0x10000; ucs4
++)
2673 FcBool FT_Has
, FC_Has
;
2675 FT_Has
= FT_Get_Char_Index (face
, ucs4
) != 0;
2676 FC_Has
= FcCharSetHasChar (fcs
, ucs4
);
2677 if (FT_Has
!= FC_Has
)
2679 printf ("0x%08x FT says %d FC says %d\n", ucs4
, FT_Has
, FC_Has
);
2685 #if HAVE_FT_HAS_PS_GLYPH_NAMES
2687 * Add mapping from PS glyph names if available
2689 if (FcFreeTypeUseNames (face
))
2691 FcChar8 name_buf
[FC_GLYPHNAME_BUFLEN
+ 2];
2693 for (glyph
= 0; glyph
< (FT_UInt
) face
->num_glyphs
; glyph
++)
2695 if (FT_Get_Glyph_Name (face
, glyph
, name_buf
, FC_GLYPHNAME_BUFLEN
+1) == 0)
2697 ucs4
= FcGlyphNameToUcs4 (name_buf
);
2698 if (ucs4
!= 0xffff &&
2699 FcFreeTypeCheckGlyph (face
, ucs4
, glyph
, blanks
, &advance
))
2705 has_advance
= FcTrue
;
2706 advance_one
= advance
;
2708 else if (!APPROXIMATELY_EQUAL (advance
, advance_one
))
2712 dual_advance
= FcTrue
;
2713 fixed_advance
= FcFalse
;
2714 advance_two
= advance
;
2716 else if (!APPROXIMATELY_EQUAL (advance
, advance_two
))
2717 dual_advance
= FcFalse
;
2720 leaf
= FcCharSetFindLeafCreate (fcs
, ucs4
);
2723 leaf
->map
[(ucs4
& 0xff) >> 5] |= (1 << (ucs4
& 0x1f));
2725 if (ucs4
> font_max
)
2734 printf ("%d glyphs %d encoded\n", (int) face
->num_glyphs
, FcCharSetCount (fcs
));
2735 for (ucs4
= 0; ucs4
<= font_max
; ucs4
++)
2737 FcBool has_char
= (glyph
= FcFreeTypeCharIndex (face
, ucs4
)) != 0;
2738 FcBool has_bit
= FcCharSetHasChar (fcs
, ucs4
);
2740 if (has_char
&& !has_bit
)
2742 if (!FcFreeTypeCheckGlyph (face
, ucs4
, glyph
, blanks
, &advance
))
2743 printf ("Bitmap missing broken char 0x%x\n", ucs4
);
2745 printf ("Bitmap missing char 0x%x\n", ucs4
);
2747 else if (!has_char
&& has_bit
)
2748 printf ("Bitmap extra char 0x%x\n", ucs4
);
2753 else if (dual_advance
&& APPROXIMATELY_EQUAL (2 * FC_MIN (advance_one
, advance_two
), FC_MAX (advance_one
, advance_two
)))
2756 *spacing
= FC_PROPORTIONAL
;
2759 FcCharSetDestroy (fcs
);
2765 FcFreeTypeCharSet (FT_Face face
, FcBlanks
*blanks
)
2769 return FcFreeTypeCharSetAndSpacing (face
, blanks
, &spacing
);
2773 #define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' )
2774 #define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
2775 #define TTAG_SILF FT_MAKE_TAG( 'S', 'i', 'l', 'f')
2776 #define TT_Err_Ok FT_Err_Ok
2777 #define TT_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle
2778 #define TTO_Err_Empty_Script 0x1005
2779 #define TTO_Err_Invalid_SubTable 0x1001
2781 #define OTLAYOUT_HEAD "otlayout:"
2782 #define OTLAYOUT_HEAD_LEN 9
2783 #define OTLAYOUT_ID_LEN 4
2784 /* space + head + id */
2785 #define OTLAYOUT_LEN (1 + OTLAYOUT_HEAD_LEN + OTLAYOUT_ID_LEN)
2788 * This is a bit generous; the registry has only lower case and space
2789 * except for 'DFLT'.
2791 #define FcIsSpace(x) (040 == (x))
2792 #define FcIsValidScript(x) (FcIsLower(x) || FcIsUpper (x) || FcIsSpace(x))
2795 addtag(FcChar8
*complex, FT_ULong tag
)
2797 FcChar8 tagstring
[OTLAYOUT_ID_LEN
+ 1];
2799 tagstring
[0] = (FcChar8
)(tag
>> 24),
2800 tagstring
[1] = (FcChar8
)(tag
>> 16),
2801 tagstring
[2] = (FcChar8
)(tag
>> 8),
2802 tagstring
[3] = (FcChar8
)(tag
);
2803 tagstring
[4] = '\0';
2805 /* skip tags which aren't alphabetic, under the assumption that
2806 * they're probably broken
2808 if (!FcIsValidScript(tagstring
[0]) ||
2809 !FcIsValidScript(tagstring
[1]) ||
2810 !FcIsValidScript(tagstring
[2]) ||
2811 !FcIsValidScript(tagstring
[3]))
2814 if (*complex != '\0')
2815 strcat ((char *) complex, " ");
2816 strcat ((char *) complex, "otlayout:");
2817 strcat ((char *) complex, (char *) tagstring
);
2821 compareulong (const void *a
, const void *b
)
2823 const FT_ULong
*ua
= (const FT_ULong
*) a
;
2824 const FT_ULong
*ub
= (const FT_ULong
*) b
;
2830 GetScriptTags(FT_Face face
, FT_ULong tabletag
, FT_ULong
**stags
, FT_UShort
*script_count
)
2832 FT_ULong cur_offset
, new_offset
, base_offset
;
2833 FT_Stream stream
= face
->stream
;
2839 return TT_Err_Invalid_Face_Handle
;
2841 memory
= stream
->memory
;
2843 if (( error
= ftglue_face_goto_table( face
, tabletag
, stream
) ))
2846 base_offset
= ftglue_stream_pos ( stream
);
2850 if ( ftglue_stream_seek ( stream
, base_offset
+ 4L ) || ftglue_stream_frame_enter( stream
, 2L ) )
2853 new_offset
= GET_UShort() + base_offset
;
2855 ftglue_stream_frame_exit( stream
);
2857 cur_offset
= ftglue_stream_pos( stream
);
2859 if ( ftglue_stream_seek( stream
, new_offset
) != TT_Err_Ok
)
2862 base_offset
= ftglue_stream_pos( stream
);
2864 if ( ftglue_stream_frame_enter( stream
, 2L ) )
2867 *script_count
= GET_UShort ();
2869 ftglue_stream_frame_exit( stream
);
2871 *stags
= ftglue_alloc(memory
, *script_count
* sizeof( FT_ULong
), &error
);
2877 for ( n
= 0; n
< *script_count
; n
++ )
2879 if ( ftglue_stream_frame_enter( stream
, 6L ) )
2882 (*stags
)[p
] = GET_ULong ();
2883 new_offset
= GET_UShort () + base_offset
;
2885 ftglue_stream_frame_exit( stream
);
2887 cur_offset
= ftglue_stream_pos( stream
);
2889 error
= ftglue_stream_seek( stream
, new_offset
);
2891 if ( error
== TT_Err_Ok
)
2894 (void)ftglue_stream_seek( stream
, cur_offset
);
2899 error
= TTO_Err_Invalid_SubTable
;
2903 /* sort the tag list before returning it */
2904 qsort(*stags
, *script_count
, sizeof(FT_ULong
), compareulong
);
2910 ftglue_free( memory
, *stags
);
2916 FcFontCapabilities(FT_Face face
)
2918 FcBool issilgraphitefont
= 0;
2921 FT_ULong
*gsubtags
=NULL
, *gpostags
=NULL
;
2922 FT_UShort gsub_count
=0, gpos_count
=0;
2924 FT_Memory memory
= face
->stream
->memory
;
2925 FcChar8
*complex = NULL
;
2926 int indx1
= 0, indx2
= 0;
2928 err
= FT_Load_Sfnt_Table(face
, TTAG_SILF
, 0, 0, &len
);
2929 issilgraphitefont
= ( err
== FT_Err_Ok
);
2931 if (GetScriptTags(face
, TTAG_GPOS
, &gpostags
, &gpos_count
) != FT_Err_Ok
)
2933 if (GetScriptTags(face
, TTAG_GSUB
, &gsubtags
, &gsub_count
) != FT_Err_Ok
)
2936 if (!issilgraphitefont
&& !gsub_count
&& !gpos_count
)
2939 maxsize
= (((FT_ULong
) gpos_count
+ (FT_ULong
) gsub_count
) * OTLAYOUT_LEN
+
2940 (issilgraphitefont
? 13 : 0));
2941 complex = malloc (sizeof (FcChar8
) * maxsize
);
2946 if (issilgraphitefont
)
2947 strcpy((char *) complex, "ttable:Silf ");
2949 while ((indx1
< gsub_count
) || (indx2
< gpos_count
)) {
2950 if (indx1
== gsub_count
) {
2951 addtag(complex, gpostags
[indx2
]);
2953 } else if ((indx2
== gpos_count
) || (gsubtags
[indx1
] < gpostags
[indx2
])) {
2954 addtag(complex, gsubtags
[indx1
]);
2956 } else if (gsubtags
[indx1
] == gpostags
[indx2
]) {
2957 addtag(complex, gsubtags
[indx1
]);
2961 addtag(complex, gpostags
[indx2
]);
2965 if (FcDebug () & FC_DBG_SCANV
)
2966 printf("complex features in this font: %s\n", complex);
2968 ftglue_free(memory
, gsubtags
);
2969 ftglue_free(memory
, gpostags
);
2973 #define __fcfreetype__
2974 #include "fcaliastail.h"
2975 #undef __fcfreetype__