2 Copyright (c) 1998-2001 by Juliusz Chroboczek
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 /* Backend-independent encoding code */
27 #if defined(__SCO__) || defined(__UNIXWARE__)
35 #define MAXFONTNAMELEN 1024
36 #define MAXFONTFILENAMELEN 1024
38 #include <X11/fonts/fontenc.h>
41 /* Functions local to this file */
43 static FontEncPtr FontEncLoad(const char*, const char*);
45 /* Early versions of this code only knew about hardwired encodings,
46 hence the following data. Now that the code knows how to load an
47 encoding from a file, most of these tables could go away. */
49 /* At any rate, no new hardcoded encodings will be added. */
51 static FontMapRec iso10646[]=
53 {FONT_ENCODING_UNICODE,0,0,NULL,NULL,NULL,NULL,NULL},
54 {0,0,0,NULL,NULL,NULL,NULL,NULL}
57 /* Notice that the Apple encodings do not have all the characters in
58 the corresponding ISO 8859, and therefore the table has some holes.
59 There's not much more we can do with fonts without a Unicode cmap
60 unless we are willing to combine cmaps (which we are not). */
62 static const unsigned short
63 iso8859_1_apple_roman[]=
64 { 0xCA, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4, 0x00, 0xA4,
65 0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0x00, 0xA8, 0xF8,
66 0xA1, 0xB1, 0x00, 0x00, 0xAB, 0xB5, 0xA6, 0xE1,
67 0xFC, 0x00, 0xBC, 0xC8, 0x00, 0x00, 0x00, 0xC0,
68 0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82,
69 0xE9, 0x83, 0xE6, 0xE8, 0xED, 0xEA, 0xEB, 0xEC,
70 0x00, 0x84, 0xF1, 0xEE, 0xEF, 0xCD, 0x85, 0x00,
71 0xAF, 0xF4, 0xF2, 0xF3, 0x86, 0x00, 0x00, 0xA7,
72 0x88, 0x87, 0x89, 0x8B, 0x8A, 0x8C, 0xBE, 0x8D,
73 0x8F, 0x8E, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95,
74 0x00, 0x96, 0x98, 0x97, 0x99, 0x9B, 0x9A, 0xD6,
75 0xBF, 0x9D, 0x9C, 0x9E, 0x9F, 0x00, 0x00, 0xD8 };
77 /* Cannot use simple_recode because need to eliminate 0x80<=code<0xA0 */
79 iso8859_1_to_apple_roman(unsigned isocode, void *client_data)
83 else if(isocode>=0xA0)
84 return iso8859_1_apple_roman[isocode-0xA0];
89 static FontMapRec iso8859_1[]=
91 {FONT_ENCODING_TRUETYPE,2,2,NULL,NULL,NULL,NULL,NULL}, /* ISO 8859-1 */
92 {FONT_ENCODING_UNICODE,0,0,NULL,NULL,NULL,NULL,NULL}, /* ISO 8859-1 coincides with Unicode*/
93 {FONT_ENCODING_TRUETYPE,1,0,iso8859_1_to_apple_roman,NULL,NULL,NULL,NULL},
94 {0,0,0,NULL,NULL,NULL,NULL,NULL}
97 static const unsigned short iso8859_2_tophalf[]=
98 { 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
99 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
100 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
101 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
102 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
103 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
104 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
105 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
106 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
107 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
108 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
109 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 };
111 static FontEncSimpleMapRec iso8859_2_to_unicode_map=
112 {0x60, 0, 0xA0, iso8859_2_tophalf };
114 static const unsigned short iso8859_2_apple_centeuro[]=
115 { 0xCA, 0x84, 0x00, 0xFC, 0x00, 0xBB, 0xE5, 0xA4,
116 0xAC, 0xE1, 0x00, 0xE8, 0x8F, 0x00, 0xEB, 0xFB,
117 0xA1, 0x88, 0x00, 0xB8, 0x00, 0xBC, 0xE6, 0xFF,
118 0x00, 0xE4, 0x00, 0xE9, 0x90, 0x00, 0xEC, 0xFD,
119 0xD9, 0xE7, 0x00, 0x00, 0x80, 0xBD, 0x8C, 0x00,
120 0x89, 0x83, 0xA2, 0x00, 0x9D, 0xEA, 0x00, 0x91,
121 0x00, 0xC1, 0xC5, 0xEE, 0xEF, 0xCC, 0x85, 0x00,
122 0xDB, 0xF1, 0xF2, 0xF4, 0x86, 0xF8, 0x00, 0xA7,
123 0xDA, 0x87, 0x00, 0x00, 0x8A, 0xBE, 0x8D, 0x00,
124 0x8B, 0x8E, 0xAB, 0x00, 0x9E, 0x92, 0x00, 0x93,
125 0x00, 0xC4, 0xCB, 0x97, 0x99, 0xCE, 0x9A, 0xD6,
126 0xDE, 0xF3, 0x9C, 0xF5, 0x9F, 0xF9, 0x00, 0x00 };
129 iso8859_2_to_apple_centeuro(unsigned isocode, void *client_data)
133 else if(isocode>=0xA0)
134 return iso8859_2_apple_centeuro[isocode-0xA0];
140 static FontMapRec iso8859_2[]=
142 {FONT_ENCODING_UNICODE,0,0,
143 FontEncSimpleRecode,NULL,&iso8859_2_to_unicode_map,NULL,NULL},
144 {FONT_ENCODING_TRUETYPE,1,29,iso8859_2_to_apple_centeuro,NULL,NULL,NULL,NULL},
145 {0,0,0,NULL,NULL,NULL,NULL,NULL}
148 static const unsigned short iso8859_3_tophalf[]=
149 { 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0x0000, 0x0124, 0x00A7,
150 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0x0000, 0x017B,
151 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7,
152 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0x0000, 0x017C,
153 0x00C0, 0x00C1, 0x00C2, 0x0000, 0x00C4, 0x010A, 0x0108, 0x00C7,
154 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
155 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7,
156 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF,
157 0x00E0, 0x00E1, 0x00E2, 0x0000, 0x00E4, 0x010B, 0x0109, 0x00E7,
158 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
159 0x0000, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7,
160 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9};
162 static FontEncSimpleMapRec iso8859_3_to_unicode_map=
163 { 0x60, 0, 0xA0, iso8859_3_tophalf };
165 static FontMapRec iso8859_3[]=
167 {FONT_ENCODING_UNICODE,0,0,
168 FontEncSimpleRecode,NULL,&iso8859_3_to_unicode_map,NULL,NULL},
169 {0,0,0,NULL,NULL,NULL,NULL,NULL}
173 static const unsigned short iso8859_4_tophalf[]=
174 { 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7,
175 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF,
176 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7,
177 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B,
178 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
179 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A,
180 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
181 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF,
182 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
183 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B,
184 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
185 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9,
188 static FontEncSimpleMapRec iso8859_4_to_unicode_map=
189 { 0x60, 0, 0xA0, iso8859_4_tophalf };
191 static FontMapRec iso8859_4[]=
193 {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,NULL,
194 &iso8859_4_to_unicode_map,NULL,NULL},
195 {0,0,0,NULL,NULL,NULL,NULL,NULL}
198 static const unsigned short iso8859_5_tophalf[]=
199 { 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
200 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F,
201 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
202 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
203 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
204 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
205 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
206 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
207 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
208 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
209 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
210 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F};
212 static FontEncSimpleMapRec iso8859_5_to_unicode_map=
213 { 0x60, 0, 0xA0, iso8859_5_tophalf };
215 static const unsigned short
216 iso8859_5_apple_cyrillic[]=
217 { 0xCA, 0xDD, 0xAB, 0xAE, 0xB8, 0xC1, 0xA7, 0xBA,
218 0xB7, 0xBC, 0xBE, 0xCB, 0xCD, 0x00, 0xD8, 0xDA,
219 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
220 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
221 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
222 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
223 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
224 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
225 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
226 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xDF,
227 0xDC, 0xDE, 0xAC, 0xAF, 0xB9, 0xCF, 0xB4, 0xBB,
228 0xC0, 0xBD, 0xBF, 0xCC, 0xCE, 0xA4, 0xD9, 0xDB };
231 iso8859_5_to_apple_cyrillic(unsigned isocode, void *client_data)
235 else if(isocode>=0xA0)
236 return iso8859_5_apple_cyrillic[isocode-0x80];
240 static FontMapRec iso8859_5[]=
242 {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,NULL,
243 &iso8859_5_to_unicode_map,NULL,NULL},
244 {FONT_ENCODING_TRUETYPE,1,7,iso8859_5_to_apple_cyrillic,NULL,NULL,NULL,NULL},
245 {0,0,0,NULL,NULL,NULL,NULL,NULL}
248 /* ISO 8859-6 seems useless for serving fonts (not enough presentation
249 * forms). What do Arabic-speakers use? */
252 iso8859_6_to_unicode(unsigned isocode, void *client_data)
254 if(isocode<=0xA0 || isocode==0xA4 || isocode==0xAD)
256 else if(isocode==0xAC || isocode==0xBB ||
257 (isocode>=0xBF && isocode<=0xDA) ||
258 (isocode>=0xE0 && isocode<=0xEF) ||
259 (isocode>=0xF0 && isocode<=0xF2))
260 return isocode-0xA0+0x0600;
265 static FontMapRec iso8859_6[]=
267 {FONT_ENCODING_UNICODE,0,0,iso8859_6_to_unicode,NULL,NULL,NULL,NULL},
268 {0,0,0,NULL,NULL,NULL,NULL,NULL}
272 iso8859_7_to_unicode(unsigned isocode, void *client_data)
275 (isocode>=0xA3 && isocode<=0xAD) ||
276 (isocode>=0xB0 && isocode<=0xB3) ||
277 isocode==0xB7 || isocode==0xBB || isocode==0xBD)
279 else if(isocode==0xA1)
281 else if(isocode==0xA2)
283 else if(isocode==0xAF)
285 else if(isocode>=0xB4)
286 return isocode-0xA0+0x0370;
291 static FontMapRec iso8859_7[]=
293 {FONT_ENCODING_UNICODE,0,0,iso8859_7_to_unicode,NULL,NULL,NULL,NULL},
294 {0,0,0,NULL,NULL,NULL,NULL,NULL}
298 iso8859_8_to_unicode(unsigned isocode, void *client_data)
302 else if(isocode<0xBF)
304 else if(isocode==0xDF)
306 else if(isocode>=0xE0 && isocode<=0xFA)
307 return isocode+0x04F0;
312 static FontMapRec iso8859_8[]=
314 {FONT_ENCODING_UNICODE,0,0,iso8859_8_to_unicode,NULL,NULL,NULL,NULL},
315 {0,0,0,NULL,NULL,NULL,NULL,NULL}
319 iso8859_9_to_unicode(unsigned isocode, void *client_data)
322 case 0xD0: return 0x011E;
323 case 0xDD: return 0x0130;
324 case 0xDE: return 0x015E;
325 case 0xF0: return 0x011F;
326 case 0xFD: return 0x0131;
327 case 0xFE: return 0x015F;
328 default: return isocode;
332 static FontMapRec iso8859_9[]=
334 {FONT_ENCODING_UNICODE,0,0,iso8859_9_to_unicode,NULL,NULL,NULL,NULL},
335 {0,0,0,NULL,NULL,NULL,NULL,NULL}
338 static const unsigned short iso8859_10_tophalf[]=
339 { 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7,
340 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A,
341 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7,
342 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2014, 0x016B, 0x014B,
343 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
344 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF,
345 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168,
346 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
347 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
348 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF,
349 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169,
350 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138};
352 static FontEncSimpleMapRec iso8859_10_to_unicode_map=
353 { 0x60, 0, 0xA0, iso8859_10_tophalf };
355 static FontMapRec iso8859_10[]=
357 {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,NULL,
358 &iso8859_10_to_unicode_map,NULL,NULL},
359 {0,0,0,NULL,NULL,NULL,NULL,NULL}
363 iso8859_15_to_unicode(unsigned isocode, void *client_data)
366 case 0xA4: return 0x20AC;
367 case 0xA6: return 0x0160;
368 case 0xA8: return 0x0161;
369 case 0xB4: return 0x017D;
370 case 0xB8: return 0x017E;
371 case 0xBC: return 0x0152;
372 case 0xBD: return 0x0153;
373 case 0xBE: return 0x0178;
374 default: return isocode;
378 static FontMapRec iso8859_15[]=
380 {FONT_ENCODING_UNICODE,0,0,iso8859_15_to_unicode,NULL,NULL,NULL,NULL},
381 {0,0,0,NULL,NULL,NULL,NULL,NULL}
384 static const unsigned short koi8_r_tophalf[]=
385 { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
386 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
387 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2022, 0x221A, 0x2248,
388 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
389 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
390 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
391 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
392 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9,
393 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
394 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
395 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
396 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
397 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
398 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
399 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
400 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A};
402 static FontEncSimpleMapRec koi8_r_to_unicode_map=
403 { 0x80, 0, 0x80, koi8_r_tophalf };
406 static FontMapRec koi8_r[]=
408 {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,NULL,
409 &koi8_r_to_unicode_map,NULL,NULL},
410 {0,0,0,NULL,NULL,NULL,NULL,NULL}
414 koi8_ru_to_unicode(unsigned koicode, void *client_data)
417 case 0x93: return 0x201C;
418 case 0x96: return 0x201D;
419 case 0x97: return 0x2014;
420 case 0x98: return 0x2116;
421 case 0x99: return 0x2122;
422 case 0x9B: return 0x00BB;
423 case 0x9C: return 0x00AE;
424 case 0x9D: return 0x00AB;
425 case 0x9F: return 0x00A4;
426 case 0xA4: return 0x0454;
427 case 0xA6: return 0x0456;
428 case 0xA7: return 0x0457;
429 case 0xAD: return 0x0491;
430 case 0xAE: return 0x045E;
431 case 0xB4: return 0x0404;
432 case 0xB6: return 0x0406;
433 case 0xB7: return 0x0407;
434 case 0xBD: return 0x0490;
435 case 0xBE: return 0x040E;
436 default: return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map);
440 static FontMapRec koi8_ru[]=
442 {FONT_ENCODING_UNICODE,0,0,koi8_ru_to_unicode,NULL,NULL,NULL,NULL},
443 {0,0,0,NULL,NULL,NULL,NULL,NULL}
446 /* koi8-e, ISO-IR-111 or ECMA-Cyrillic */
448 static const unsigned short koi8_e_A0_BF[]=
449 { 0x00A0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457,
450 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00AD, 0x045E, 0x045F,
451 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407,
452 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00A4, 0x040E, 0x040F };
455 koi8_e_to_unicode(unsigned koicode, void *client_data)
459 else if(koicode<0xC0)
460 return koi8_e_A0_BF[koicode-0xA0];
462 return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map);
465 static FontMapRec koi8_e[]=
467 {FONT_ENCODING_UNICODE,0,0,koi8_e_to_unicode,NULL,NULL,NULL,NULL},
468 {0,0,0,NULL,NULL,NULL,NULL,NULL}
473 static const unsigned short koi8_uni_80_BF[]=
474 { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
475 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
476 0x2591, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
477 0x00A9, 0x2122, 0x00A0, 0x00BB, 0x00AE, 0x00AB, 0x00B7, 0x00A4,
478 0x00A0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457,
479 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x0491, 0x045E, 0x045F,
480 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407,
481 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x0490, 0x040E, 0x040F };
484 koi8_uni_to_unicode(unsigned koicode, void *client_data)
488 else if(koicode<0xC0)
489 return koi8_uni_80_BF[koicode-0x80];
491 return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map);
494 static FontMapRec koi8_uni[]=
496 {FONT_ENCODING_UNICODE,0,0,koi8_uni_to_unicode,NULL,NULL,NULL,NULL},
497 {0,0,0,NULL,NULL,NULL,NULL,NULL}
500 /* Ukrainian variant of Koi8-R; see RFC 2319 */
503 koi8_u_to_unicode(unsigned koicode, void *client_data)
506 case 0xA4: return 0x0454;
507 case 0xA6: return 0x0456;
508 case 0xA7: return 0x0457;
509 case 0xAD: return 0x0491;
510 case 0xB4: return 0x0404;
511 case 0xB6: return 0x0406;
512 case 0xB7: return 0x0407;
513 case 0xBD: return 0x0490;
514 default: return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map);
518 static FontMapRec koi8_u[]=
520 {FONT_ENCODING_UNICODE,0,0,koi8_u_to_unicode,NULL,NULL,NULL},
521 {0,0,0,NULL,NULL,NULL,NULL,NULL}
524 /* Microsoft Symbol, which is only meaningful for TrueType fonts, is
525 treated specially in ftenc.c, where we add usFirstCharIndex-0x20 to
526 the glyph index before applying the cmap. Lovely design. */
528 static FontMapRec microsoft_symbol[]=
529 {{FONT_ENCODING_TRUETYPE,3,0,NULL,NULL,NULL,NULL,NULL},
531 {FONT_ENCODING_TRUETYPE,3,1,NULL,NULL,NULL,NULL,NULL},
532 {0,0,0,NULL,NULL,NULL,NULL,NULL}};
534 static FontMapRec apple_roman[]=
535 {{FONT_ENCODING_TRUETYPE,1,0,NULL,NULL,NULL,NULL,NULL},
536 {0,0,0,NULL,NULL,NULL,NULL,NULL}};
538 /* The data for recodings */
540 /* For compatibility with X11R6.4. Losers. */
541 static char *iso8859_15_aliases[2]={"fcd8859-15",NULL};
543 static FontEncRec initial_encodings[]=
545 {"iso10646-1",NULL,256*256,0,iso10646,NULL,0,0}, /* Unicode */
546 {"iso8859-1",NULL,256,0,iso8859_1,NULL,0,0}, /* Latin 1 (West European) */
547 {"iso8859-2",NULL,256,0,iso8859_2,NULL,0,0}, /* Latin 2 (East European) */
548 {"iso8859-3",NULL,256,0,iso8859_3,NULL,0,0}, /* Latin 3 (South European) */
549 {"iso8859-4",NULL,256,0,iso8859_4,NULL,0,0}, /* Latin 4 (North European) */
550 {"iso8859-5",NULL,256,0,iso8859_5,NULL,0,0}, /* Cyrillic */
551 {"iso8859-6",NULL,256,0,iso8859_6,NULL,0,0}, /* Arabic */
552 {"iso8859-7",NULL,256,0,iso8859_7,NULL,0,0}, /* Greek */
553 {"iso8859-8",NULL,256,0,iso8859_8,NULL,0,0}, /* Hebrew */
554 {"iso8859-9",NULL,256,0,iso8859_9,NULL,0,0}, /* Latin 5 (Turkish) */
555 {"iso8859-10",NULL,256,0,iso8859_10,NULL,0,0}, /* Latin 6 (Nordic) */
556 {"iso8859-15",iso8859_15_aliases,256,0,iso8859_15,NULL,0,0}, /* Latin 9 */
557 {"koi8-r",NULL,256,0,koi8_r,NULL,0,0}, /* Russian */
558 {"koi8-ru",NULL,256,0,koi8_ru,NULL,0,0}, /* Ukrainian */
559 {"koi8-uni",NULL,256,0,koi8_uni,NULL,0,0}, /* Russian/Ukrainian/Bielorussian */
560 {"koi8-e",NULL,256,0,koi8_e,NULL,0,0}, /* ``European'' */
561 {"koi8-u",NULL,256,0,koi8_u,NULL,0,0}, /* Ukrainian too */
562 {"microsoft-symbol",NULL,256,0,microsoft_symbol,NULL,0,0},
563 {"apple-roman",NULL,256,0,apple_roman,NULL,0,0},
564 {NULL,NULL,0,0,NULL,NULL,0,0}
567 static FontEncPtr font_encodings=NULL;
570 define_initial_encoding_info(void)
575 font_encodings = initial_encodings;
576 for(encoding = font_encodings; ; encoding++) {
577 encoding->next = encoding + 1;
578 for(mapping = encoding->mappings; ; mapping++) {
579 mapping->next = mapping+1;
580 mapping->encoding = encoding;
581 if(mapping->next->type == 0) {
582 mapping->next = NULL;
586 if(!encoding->next->name) {
587 encoding->next = NULL;
595 FontEncFromXLFD(const char *name, int length)
599 static char charset[MAXFONTNAMELEN];
602 if(length > MAXFONTNAMELEN - 1)
608 p = name + length - 1;
609 while(p > name && *p != '-')
612 while(p >= name && *p != '-')
618 /* now p either is null or points at the '-' before the charset registry */
623 len = length - (p - name) - 1;
624 memcpy(charset, p+1, len);
627 /* check for a subset specification */
628 if((q = strchr(charset, (int)'[')))
635 FontEncRecode(unsigned code, FontMapPtr mapping)
637 FontEncPtr encoding = mapping->encoding;
638 if(encoding && mapping->recode) {
639 if(encoding->row_size == 0) {
640 /* linear encoding */
641 if(code < encoding->first || code>=encoding->size)
644 /* matrix encoding */
645 int row = code/0x100, col = code&0xFF;
646 if(row < encoding->first || row >= encoding->size ||
647 col < encoding->first_col || col >= encoding->row_size)
650 return (*mapping->recode)(code, mapping->client_data);
656 FontEncName(unsigned code, FontMapPtr mapping)
658 FontEncPtr encoding = mapping->encoding;
659 if(encoding && mapping->name) {
660 if((encoding->row_size == 0 && code >= encoding->size) ||
661 (encoding->row_size != 0 &&
662 (code/0x100 >= encoding->size ||
663 (code&0xFF) >= encoding->row_size)))
665 return (*mapping->name)(code, mapping->client_data);
671 FontEncFind(const char *encoding_name, const char *filename)
676 if(font_encodings == NULL) define_initial_encoding_info();
678 for(encoding = font_encodings; encoding; encoding = encoding->next) {
679 if(!strcasecmp(encoding->name, encoding_name))
681 if(encoding->aliases)
682 for(alias=encoding->aliases; *alias; alias++)
683 if(!strcasecmp(*alias, encoding_name))
687 /* Unknown charset, try to load a definition file */
688 return FontEncLoad(encoding_name, filename);
692 FontMapFind(FontEncPtr encoding, int type, int pid, int eid)
698 for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
699 if(mapping->type != type)
701 if(pid > 0 && mapping->pid != pid)
703 if(eid > 0 && mapping->eid != eid)
711 FontEncMapFind(const char *encoding_name, int type, int pid, int eid,
712 const char *filename)
717 encoding = FontEncFind(encoding_name, filename);
720 mapping = FontMapFind(encoding, type, pid, eid);
725 FontEncLoad(const char *encoding_name, const char *filename)
729 encoding = FontEncReallyLoad(encoding_name, filename);
730 if (encoding == NULL) {
736 /* Check whether the name is already known for this encoding */
737 if(strcasecmp(encoding->name, encoding_name) == 0) {
740 if(encoding->aliases) {
741 for(alias=encoding->aliases; *alias; alias++)
742 if(!strcasecmp(*alias, encoding_name)) {
750 /* Add a new alias. This works because we know that this
751 particular encoding has been allocated dynamically */
756 new_name = strdup(encoding_name);
759 if(encoding->aliases) {
760 for(alias = encoding->aliases; *alias; alias++)
763 new_aliases = malloc((numaliases+2)*sizeof(char*));
764 if(new_aliases == NULL) {
768 if(encoding->aliases) {
769 memcpy(new_aliases, encoding->aliases, numaliases*sizeof(char*));
770 free(encoding->aliases);
772 new_aliases[numaliases] = new_name;
773 new_aliases[numaliases+1] = NULL;
774 encoding->aliases = new_aliases;
777 /* register the new encoding */
778 encoding->next=font_encodings;
779 font_encodings=encoding;
786 FontEncSimpleRecode(unsigned code, void *client_data)
788 FontEncSimpleMapPtr map;
793 if(code > 0xFFFF || (map->row_size && (code&0xFF) >= map->row_size))
797 index = (code&0xFF)+(code>>8)*map->row_size;
801 if(map->map && index>=map->first && index<map->first+map->len)
802 return map->map[index-map->first];
808 FontEncSimpleName(unsigned code, void *client_data)
810 FontEncSimpleNamePtr map;
813 if(map && code >= map->first && code<map->first+map->len)
814 return map->map[code-map->first];
820 FontEncUndefinedRecode(unsigned code, void *client_data)
826 FontEncUndefinedName(unsigned code, void *client_data)
831 #define FONTENC_SEGMENT_SIZE 256
832 #define FONTENC_SEGMENTS 256
833 #define FONTENC_INVERSE_CODES (FONTENC_SEGMENT_SIZE * FONTENC_SEGMENTS)
836 reverse_reverse(unsigned i, void* data)
839 unsigned **map = (unsigned**)data;
841 if(i >= FONTENC_INVERSE_CODES)
847 s = i / FONTENC_SEGMENT_SIZE;
848 j = i % FONTENC_SEGMENT_SIZE;
857 tree_set(unsigned int **map, unsigned int i, unsigned int j)
861 if(i >= FONTENC_INVERSE_CODES)
864 s = i / FONTENC_SEGMENT_SIZE;
865 c = i % FONTENC_SEGMENT_SIZE;
868 map[s] = calloc(FONTENC_SEGMENT_SIZE, sizeof(int));
878 FontMapReverse(FontMapPtr mapping)
880 FontEncPtr encoding = mapping->encoding;
881 FontMapReversePtr reverse = NULL;
882 unsigned int **map = NULL;
885 if(encoding == NULL) goto bail;
887 map = calloc(FONTENC_SEGMENTS, sizeof(int*));
888 if(map == NULL) goto bail;
890 if(encoding->row_size == 0) {
891 for(i = encoding->first; i < encoding->size; i++) {
892 k = FontEncRecode(i, mapping);
894 if(!tree_set(map, k, i))
898 for(i = encoding->first; i < encoding->size; i++) {
899 for(j = encoding->first_col; j < encoding->row_size; j++) {
900 k = FontEncRecode(i*256 + j, mapping);
902 if(!tree_set(map, k, i*256+j))
908 reverse = malloc(sizeof(FontMapReverseRec));
909 if(!reverse) goto bail;
911 reverse->reverse = reverse_reverse;
922 FontMapReverseFree(FontMapReversePtr delendum)
924 unsigned int **map = (unsigned int**)delendum;
930 for(i = 0; i < FONTENC_SEGMENTS; i++)