13da084b3Smrg/* 23da084b3SmrgCopyright (c) 1998-2001 by Juliusz Chroboczek 33da084b3Smrg 43da084b3SmrgPermission is hereby granted, free of charge, to any person obtaining a copy 53da084b3Smrgof this software and associated documentation files (the "Software"), to deal 63da084b3Smrgin the Software without restriction, including without limitation the rights 73da084b3Smrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 83da084b3Smrgcopies of the Software, and to permit persons to whom the Software is 93da084b3Smrgfurnished to do so, subject to the following conditions: 103da084b3Smrg 113da084b3SmrgThe above copyright notice and this permission notice shall be included in 123da084b3Smrgall copies or substantial portions of the Software. 133da084b3Smrg 143da084b3SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 153da084b3SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 163da084b3SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 173da084b3SmrgAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 183da084b3SmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 193da084b3SmrgOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 203da084b3SmrgTHE SOFTWARE. 213da084b3Smrg*/ 223da084b3Smrg 233da084b3Smrg/* Backend-independent encoding code */ 243da084b3Smrg 252a53b785Smrg#ifdef HAVE_CONFIG_H 262a53b785Smrg#include <config.h> 272a53b785Smrg#endif 282a53b785Smrg 293da084b3Smrg#include <string.h> 303da084b3Smrg#include <strings.h> 313da084b3Smrg#include <stdlib.h> 3255acc8fcSmrg 333da084b3Smrg#define FALSE 0 343da084b3Smrg#define TRUE 1 353da084b3Smrg#define MAXFONTNAMELEN 1024 363da084b3Smrg#define MAXFONTFILENAMELEN 1024 373da084b3Smrg 383da084b3Smrg#include <X11/fonts/fontenc.h> 393da084b3Smrg#include "fontencI.h" 402a53b785Smrg#include "reallocarray.h" 413da084b3Smrg 423da084b3Smrg/* Functions local to this file */ 433da084b3Smrg 44e1c0d025Smrgstatic FontEncPtr FontEncLoad(const char *, const char *); 453da084b3Smrg 463da084b3Smrg/* Early versions of this code only knew about hardwired encodings, 473da084b3Smrg hence the following data. Now that the code knows how to load an 483da084b3Smrg encoding from a file, most of these tables could go away. */ 493da084b3Smrg 503da084b3Smrg/* At any rate, no new hardcoded encodings will be added. */ 513da084b3Smrg 52e1c0d025Smrgstatic FontMapRec iso10646[] = { 53e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, NULL, NULL, NULL, NULL, NULL}, 54e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 553da084b3Smrg}; 563da084b3Smrg 573da084b3Smrg/* Notice that the Apple encodings do not have all the characters in 583da084b3Smrg the corresponding ISO 8859, and therefore the table has some holes. 593da084b3Smrg There's not much more we can do with fonts without a Unicode cmap 603da084b3Smrg unless we are willing to combine cmaps (which we are not). */ 613da084b3Smrg 6248c85eb7Smrgstatic const unsigned short 63e1c0d025Smrg iso8859_1_apple_roman[] = { 64e1c0d025Smrg 0xCA, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4, 0x00, 0xA4, 65e1c0d025Smrg 0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0x00, 0xA8, 0xF8, 66e1c0d025Smrg 0xA1, 0xB1, 0x00, 0x00, 0xAB, 0xB5, 0xA6, 0xE1, 67e1c0d025Smrg 0xFC, 0x00, 0xBC, 0xC8, 0x00, 0x00, 0x00, 0xC0, 68e1c0d025Smrg 0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82, 69e1c0d025Smrg 0xE9, 0x83, 0xE6, 0xE8, 0xED, 0xEA, 0xEB, 0xEC, 70e1c0d025Smrg 0x00, 0x84, 0xF1, 0xEE, 0xEF, 0xCD, 0x85, 0x00, 71e1c0d025Smrg 0xAF, 0xF4, 0xF2, 0xF3, 0x86, 0x00, 0x00, 0xA7, 72e1c0d025Smrg 0x88, 0x87, 0x89, 0x8B, 0x8A, 0x8C, 0xBE, 0x8D, 73e1c0d025Smrg 0x8F, 0x8E, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, 74e1c0d025Smrg 0x00, 0x96, 0x98, 0x97, 0x99, 0x9B, 0x9A, 0xD6, 75e1c0d025Smrg 0xBF, 0x9D, 0x9C, 0x9E, 0x9F, 0x00, 0x00, 0xD8 76e1c0d025Smrg}; 773da084b3Smrg 783da084b3Smrg/* Cannot use simple_recode because need to eliminate 0x80<=code<0xA0 */ 793da084b3Smrgstatic unsigned 803da084b3Smrgiso8859_1_to_apple_roman(unsigned isocode, void *client_data) 813da084b3Smrg{ 82e1c0d025Smrg if (isocode <= 0x80) 833da084b3Smrg return isocode; 84e1c0d025Smrg else if (isocode >= 0xA0) 85e1c0d025Smrg return iso8859_1_apple_roman[isocode - 0xA0]; 863da084b3Smrg else 873da084b3Smrg return 0; 883da084b3Smrg} 893da084b3Smrg 90e1c0d025Smrgstatic FontMapRec iso8859_1[] = { 91e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 2, 2, NULL, NULL, NULL, NULL, NULL}, /* ISO 8859-1 */ 92e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, NULL, NULL, NULL, NULL, NULL}, /* ISO 8859-1 coincides with Unicode */ 93e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 1, 0, iso8859_1_to_apple_roman, NULL, NULL, NULL, 94e1c0d025Smrg NULL}, 95e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 963da084b3Smrg}; 973da084b3Smrg 98e1c0d025Smrgstatic const unsigned short iso8859_2_tophalf[] = { 99e1c0d025Smrg 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, 100e1c0d025Smrg 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, 101e1c0d025Smrg 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, 102e1c0d025Smrg 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, 103e1c0d025Smrg 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, 104e1c0d025Smrg 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, 105e1c0d025Smrg 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 106e1c0d025Smrg 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, 107e1c0d025Smrg 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 108e1c0d025Smrg 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, 109e1c0d025Smrg 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, 110e1c0d025Smrg 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 111e1c0d025Smrg}; 112e1c0d025Smrg 113e1c0d025Smrgstatic FontEncSimpleMapRec iso8859_2_to_unicode_map = 114e1c0d025Smrg { 0x60, 0, 0xA0, iso8859_2_tophalf }; 115e1c0d025Smrg 116e1c0d025Smrgstatic const unsigned short iso8859_2_apple_centeuro[] = { 117e1c0d025Smrg 0xCA, 0x84, 0x00, 0xFC, 0x00, 0xBB, 0xE5, 0xA4, 118e1c0d025Smrg 0xAC, 0xE1, 0x00, 0xE8, 0x8F, 0x00, 0xEB, 0xFB, 119e1c0d025Smrg 0xA1, 0x88, 0x00, 0xB8, 0x00, 0xBC, 0xE6, 0xFF, 120e1c0d025Smrg 0x00, 0xE4, 0x00, 0xE9, 0x90, 0x00, 0xEC, 0xFD, 121e1c0d025Smrg 0xD9, 0xE7, 0x00, 0x00, 0x80, 0xBD, 0x8C, 0x00, 122e1c0d025Smrg 0x89, 0x83, 0xA2, 0x00, 0x9D, 0xEA, 0x00, 0x91, 123e1c0d025Smrg 0x00, 0xC1, 0xC5, 0xEE, 0xEF, 0xCC, 0x85, 0x00, 124e1c0d025Smrg 0xDB, 0xF1, 0xF2, 0xF4, 0x86, 0xF8, 0x00, 0xA7, 125e1c0d025Smrg 0xDA, 0x87, 0x00, 0x00, 0x8A, 0xBE, 0x8D, 0x00, 126e1c0d025Smrg 0x8B, 0x8E, 0xAB, 0x00, 0x9E, 0x92, 0x00, 0x93, 127e1c0d025Smrg 0x00, 0xC4, 0xCB, 0x97, 0x99, 0xCE, 0x9A, 0xD6, 128e1c0d025Smrg 0xDE, 0xF3, 0x9C, 0xF5, 0x9F, 0xF9, 0x00, 0x00 129e1c0d025Smrg}; 1303da084b3Smrg 1313da084b3Smrgstatic unsigned 1323da084b3Smrgiso8859_2_to_apple_centeuro(unsigned isocode, void *client_data) 1333da084b3Smrg{ 134e1c0d025Smrg if (isocode <= 0x80) 1353da084b3Smrg return isocode; 136e1c0d025Smrg else if (isocode >= 0xA0) 137e1c0d025Smrg return iso8859_2_apple_centeuro[isocode - 0xA0]; 1383da084b3Smrg else 1393da084b3Smrg return 0; 1403da084b3Smrg} 1413da084b3Smrg 142e1c0d025Smrgstatic FontMapRec iso8859_2[] = { 143e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, 144e1c0d025Smrg FontEncSimpleRecode, NULL, &iso8859_2_to_unicode_map, NULL, NULL}, 145e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 1, 29, iso8859_2_to_apple_centeuro, NULL, NULL, 146e1c0d025Smrg NULL, NULL}, 147e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 1483da084b3Smrg}; 1493da084b3Smrg 150e1c0d025Smrgstatic const unsigned short iso8859_3_tophalf[] = { 151e1c0d025Smrg 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0x0000, 0x0124, 0x00A7, 152e1c0d025Smrg 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0x0000, 0x017B, 153e1c0d025Smrg 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, 154e1c0d025Smrg 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0x0000, 0x017C, 155e1c0d025Smrg 0x00C0, 0x00C1, 0x00C2, 0x0000, 0x00C4, 0x010A, 0x0108, 0x00C7, 156e1c0d025Smrg 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 157e1c0d025Smrg 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, 158e1c0d025Smrg 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF, 159e1c0d025Smrg 0x00E0, 0x00E1, 0x00E2, 0x0000, 0x00E4, 0x010B, 0x0109, 0x00E7, 160e1c0d025Smrg 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 161e1c0d025Smrg 0x0000, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, 162e1c0d025Smrg 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9 1633da084b3Smrg}; 1643da084b3Smrg 165e1c0d025Smrgstatic FontEncSimpleMapRec iso8859_3_to_unicode_map = 166e1c0d025Smrg { 0x60, 0, 0xA0, iso8859_3_tophalf }; 1673da084b3Smrg 168e1c0d025Smrgstatic FontMapRec iso8859_3[] = { 169e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, 170e1c0d025Smrg FontEncSimpleRecode, NULL, &iso8859_3_to_unicode_map, NULL, NULL}, 171e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 1723da084b3Smrg}; 1733da084b3Smrg 174e1c0d025Smrgstatic const unsigned short iso8859_4_tophalf[] = { 175e1c0d025Smrg 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7, 176e1c0d025Smrg 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF, 177e1c0d025Smrg 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7, 178e1c0d025Smrg 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B, 179e1c0d025Smrg 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, 180e1c0d025Smrg 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A, 181e1c0d025Smrg 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 182e1c0d025Smrg 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF, 183e1c0d025Smrg 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, 184e1c0d025Smrg 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B, 185e1c0d025Smrg 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 186e1c0d025Smrg 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9, 187e1c0d025Smrg}; 1883da084b3Smrg 189e1c0d025Smrgstatic FontEncSimpleMapRec iso8859_4_to_unicode_map = 190e1c0d025Smrg { 0x60, 0, 0xA0, iso8859_4_tophalf }; 191e1c0d025Smrg 192e1c0d025Smrgstatic FontMapRec iso8859_4[] = { 193e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, FontEncSimpleRecode, NULL, 194e1c0d025Smrg &iso8859_4_to_unicode_map, NULL, NULL}, 195e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 1963da084b3Smrg}; 1973da084b3Smrg 198e1c0d025Smrgstatic const unsigned short iso8859_5_tophalf[] = { 199e1c0d025Smrg 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 200e1c0d025Smrg 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F, 201e1c0d025Smrg 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 202e1c0d025Smrg 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 203e1c0d025Smrg 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 204e1c0d025Smrg 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 205e1c0d025Smrg 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 206e1c0d025Smrg 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 207e1c0d025Smrg 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 208e1c0d025Smrg 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 209e1c0d025Smrg 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 210e1c0d025Smrg 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F 211e1c0d025Smrg}; 2123da084b3Smrg 213e1c0d025Smrgstatic FontEncSimpleMapRec iso8859_5_to_unicode_map = 214e1c0d025Smrg { 0x60, 0, 0xA0, iso8859_5_tophalf }; 215e1c0d025Smrg 216e1c0d025Smrgstatic const unsigned short iso8859_5_apple_cyrillic[] = { 217e1c0d025Smrg 0xCA, 0xDD, 0xAB, 0xAE, 0xB8, 0xC1, 0xA7, 0xBA, 218e1c0d025Smrg 0xB7, 0xBC, 0xBE, 0xCB, 0xCD, 0x00, 0xD8, 0xDA, 219e1c0d025Smrg 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 220e1c0d025Smrg 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 221e1c0d025Smrg 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 222e1c0d025Smrg 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 223e1c0d025Smrg 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 224e1c0d025Smrg 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 225e1c0d025Smrg 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 226e1c0d025Smrg 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xDF, 227e1c0d025Smrg 0xDC, 0xDE, 0xAC, 0xAF, 0xB9, 0xCF, 0xB4, 0xBB, 228e1c0d025Smrg 0xC0, 0xBD, 0xBF, 0xCC, 0xCE, 0xA4, 0xD9, 0xDB 229e1c0d025Smrg}; 2303da084b3Smrg 2313da084b3Smrgstatic unsigned 2323da084b3Smrgiso8859_5_to_apple_cyrillic(unsigned isocode, void *client_data) 2333da084b3Smrg{ 234e1c0d025Smrg if (isocode <= 0x80) 2353da084b3Smrg return isocode; 236e1c0d025Smrg else if (isocode >= 0xA0) 237e1c0d025Smrg return iso8859_5_apple_cyrillic[isocode - 0x80]; 238e1c0d025Smrg else 239e1c0d025Smrg return 0; 2403da084b3Smrg} 2413da084b3Smrg 242e1c0d025Smrgstatic FontMapRec iso8859_5[] = { 243e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, FontEncSimpleRecode, NULL, 244e1c0d025Smrg &iso8859_5_to_unicode_map, NULL, NULL}, 245e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 1, 7, iso8859_5_to_apple_cyrillic, NULL, NULL, 246e1c0d025Smrg NULL, NULL}, 247e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 2483da084b3Smrg}; 2493da084b3Smrg 2503da084b3Smrg/* ISO 8859-6 seems useless for serving fonts (not enough presentation 2513da084b3Smrg * forms). What do Arabic-speakers use? */ 2523da084b3Smrg 2533da084b3Smrgstatic unsigned 2543da084b3Smrgiso8859_6_to_unicode(unsigned isocode, void *client_data) 2553da084b3Smrg{ 256e1c0d025Smrg if (isocode <= 0xA0 || isocode == 0xA4 || isocode == 0xAD) 2573da084b3Smrg return isocode; 258e1c0d025Smrg else if (isocode == 0xAC || isocode == 0xBB || 259e1c0d025Smrg isocode == 0xBF || 260e1c0d025Smrg (isocode >= 0xC1 && isocode <= 0xDA) || 261e1c0d025Smrg (isocode >= 0xE0 && isocode <= 0xEF) || 262e1c0d025Smrg (isocode >= 0xF0 && isocode <= 0xF2)) 263e1c0d025Smrg return isocode - 0xA0 + 0x0600; 2643da084b3Smrg else 2653da084b3Smrg return 0; 2663da084b3Smrg} 2673da084b3Smrg 268e1c0d025Smrgstatic FontMapRec iso8859_6[] = { 269e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, iso8859_6_to_unicode, NULL, NULL, NULL, NULL}, 270e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 2713da084b3Smrg}; 2723da084b3Smrg 27348c85eb7Smrgstatic unsigned 2743da084b3Smrgiso8859_7_to_unicode(unsigned isocode, void *client_data) 2753da084b3Smrg{ 276e1c0d025Smrg if (isocode <= 0xA0 || 277e1c0d025Smrg (isocode >= 0xA3 && isocode <= 0xAD) || 278e1c0d025Smrg (isocode >= 0xB0 && isocode <= 0xB3) || 279e1c0d025Smrg isocode == 0xB7 || isocode == 0xBB || isocode == 0xBD) 2803da084b3Smrg return isocode; 281e1c0d025Smrg else if (isocode == 0xA1) 28252fd71cdSmrg return 0x2018; 283e1c0d025Smrg else if (isocode == 0xA2) 28452fd71cdSmrg return 0x2019; 285e1c0d025Smrg else if (isocode == 0xAF) 2863da084b3Smrg return 0x2015; 287e1c0d025Smrg else if (isocode == 0xD2) /* unassigned */ 28848c85eb7Smrg return 0; 28952fd71cdSmrg else if (isocode >= 0xB4 && isocode <= 0xFE) 290e1c0d025Smrg return isocode - 0xA0 + 0x0370; 2913da084b3Smrg else 2923da084b3Smrg return 0; 2933da084b3Smrg} 2943da084b3Smrg 295e1c0d025Smrgstatic FontMapRec iso8859_7[] = { 296e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, iso8859_7_to_unicode, NULL, NULL, NULL, NULL}, 297e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 2983da084b3Smrg}; 2993da084b3Smrg 3003da084b3Smrgstatic unsigned 3013da084b3Smrgiso8859_8_to_unicode(unsigned isocode, void *client_data) 3023da084b3Smrg{ 303e1c0d025Smrg if (isocode == 0xA1) 3043da084b3Smrg return 0; 305e1c0d025Smrg else if (isocode < 0xBF) 3063da084b3Smrg return isocode; 307e1c0d025Smrg else if (isocode == 0xDF) 3083da084b3Smrg return 0x2017; 309e1c0d025Smrg else if (isocode >= 0xE0 && isocode <= 0xFA) 310e1c0d025Smrg return isocode + 0x04F0; 31148c85eb7Smrg else 3123da084b3Smrg return 0; 3133da084b3Smrg} 3143da084b3Smrg 315e1c0d025Smrgstatic FontMapRec iso8859_8[] = { 316e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, iso8859_8_to_unicode, NULL, NULL, NULL, NULL}, 317e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 3183da084b3Smrg}; 3193da084b3Smrg 3203da084b3Smrgstatic unsigned 3213da084b3Smrgiso8859_9_to_unicode(unsigned isocode, void *client_data) 3223da084b3Smrg{ 323e1c0d025Smrg switch (isocode) { 324e1c0d025Smrg case 0xD0: 325e1c0d025Smrg return 0x011E; 326e1c0d025Smrg case 0xDD: 327e1c0d025Smrg return 0x0130; 328e1c0d025Smrg case 0xDE: 329e1c0d025Smrg return 0x015E; 330e1c0d025Smrg case 0xF0: 331e1c0d025Smrg return 0x011F; 332e1c0d025Smrg case 0xFD: 333e1c0d025Smrg return 0x0131; 334e1c0d025Smrg case 0xFE: 335e1c0d025Smrg return 0x015F; 336e1c0d025Smrg default: 337e1c0d025Smrg return isocode; 3383da084b3Smrg } 3393da084b3Smrg} 3403da084b3Smrg 341e1c0d025Smrgstatic FontMapRec iso8859_9[] = { 342e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, iso8859_9_to_unicode, NULL, NULL, NULL, NULL}, 343e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 3443da084b3Smrg}; 3453da084b3Smrg 346e1c0d025Smrgstatic const unsigned short iso8859_10_tophalf[] = { 347e1c0d025Smrg 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7, 348e1c0d025Smrg 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A, 349e1c0d025Smrg 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7, 350e1c0d025Smrg 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2014, 0x016B, 0x014B, 351e1c0d025Smrg 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, 352e1c0d025Smrg 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF, 353e1c0d025Smrg 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168, 354e1c0d025Smrg 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 355e1c0d025Smrg 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, 356e1c0d025Smrg 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF, 357e1c0d025Smrg 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169, 358e1c0d025Smrg 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138 359e1c0d025Smrg}; 360e1c0d025Smrg 361e1c0d025Smrgstatic FontEncSimpleMapRec iso8859_10_to_unicode_map = 362e1c0d025Smrg { 0x60, 0, 0xA0, iso8859_10_tophalf }; 363e1c0d025Smrg 364e1c0d025Smrgstatic FontMapRec iso8859_10[] = { 365e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, FontEncSimpleRecode, NULL, 366e1c0d025Smrg &iso8859_10_to_unicode_map, NULL, NULL}, 367e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 3683da084b3Smrg}; 3693da084b3Smrg 3703da084b3Smrgstatic unsigned 3713da084b3Smrgiso8859_15_to_unicode(unsigned isocode, void *client_data) 3723da084b3Smrg{ 373e1c0d025Smrg switch (isocode) { 374e1c0d025Smrg case 0xA4: 375e1c0d025Smrg return 0x20AC; 376e1c0d025Smrg case 0xA6: 377e1c0d025Smrg return 0x0160; 378e1c0d025Smrg case 0xA8: 379e1c0d025Smrg return 0x0161; 380e1c0d025Smrg case 0xB4: 381e1c0d025Smrg return 0x017D; 382e1c0d025Smrg case 0xB8: 383e1c0d025Smrg return 0x017E; 384e1c0d025Smrg case 0xBC: 385e1c0d025Smrg return 0x0152; 386e1c0d025Smrg case 0xBD: 387e1c0d025Smrg return 0x0153; 388e1c0d025Smrg case 0xBE: 389e1c0d025Smrg return 0x0178; 390e1c0d025Smrg default: 391e1c0d025Smrg return isocode; 3923da084b3Smrg } 3933da084b3Smrg} 3943da084b3Smrg 395e1c0d025Smrgstatic FontMapRec iso8859_15[] = { 396e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, iso8859_15_to_unicode, NULL, NULL, NULL, 397e1c0d025Smrg NULL}, 398e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 3993da084b3Smrg}; 4003da084b3Smrg 401e1c0d025Smrgstatic const unsigned short koi8_r_tophalf[] = { 402e1c0d025Smrg 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, 403e1c0d025Smrg 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590, 404e1c0d025Smrg 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2022, 0x221A, 0x2248, 405e1c0d025Smrg 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7, 406e1c0d025Smrg 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, 407e1c0d025Smrg 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E, 408e1c0d025Smrg 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, 409e1c0d025Smrg 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9, 410e1c0d025Smrg 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 411e1c0d025Smrg 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 412e1c0d025Smrg 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, 413e1c0d025Smrg 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A, 414e1c0d025Smrg 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 415e1c0d025Smrg 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 416e1c0d025Smrg 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, 417e1c0d025Smrg 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A 418e1c0d025Smrg}; 419e1c0d025Smrg 420e1c0d025Smrgstatic FontEncSimpleMapRec koi8_r_to_unicode_map = 421e1c0d025Smrg { 0x80, 0, 0x80, koi8_r_tophalf }; 422e1c0d025Smrg 423e1c0d025Smrgstatic FontMapRec koi8_r[] = { 424e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, FontEncSimpleRecode, NULL, 425e1c0d025Smrg &koi8_r_to_unicode_map, NULL, NULL}, 426e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 4273da084b3Smrg}; 4283da084b3Smrg 42948c85eb7Smrgstatic unsigned 4303da084b3Smrgkoi8_ru_to_unicode(unsigned koicode, void *client_data) 4313da084b3Smrg{ 432e1c0d025Smrg switch (koicode) { 433e1c0d025Smrg case 0x93: 434e1c0d025Smrg return 0x201C; 435e1c0d025Smrg case 0x96: 436e1c0d025Smrg return 0x201D; 437e1c0d025Smrg case 0x97: 438e1c0d025Smrg return 0x2014; 439e1c0d025Smrg case 0x98: 440e1c0d025Smrg return 0x2116; 441e1c0d025Smrg case 0x99: 442e1c0d025Smrg return 0x2122; 443e1c0d025Smrg case 0x9B: 444e1c0d025Smrg return 0x00BB; 445e1c0d025Smrg case 0x9C: 446e1c0d025Smrg return 0x00AE; 447e1c0d025Smrg case 0x9D: 448e1c0d025Smrg return 0x00AB; 449e1c0d025Smrg case 0x9F: 450e1c0d025Smrg return 0x00A4; 451e1c0d025Smrg case 0xA4: 452e1c0d025Smrg return 0x0454; 453e1c0d025Smrg case 0xA6: 454e1c0d025Smrg return 0x0456; 455e1c0d025Smrg case 0xA7: 456e1c0d025Smrg return 0x0457; 457e1c0d025Smrg case 0xAD: 458e1c0d025Smrg return 0x0491; 459e1c0d025Smrg case 0xAE: 460e1c0d025Smrg return 0x045E; 461e1c0d025Smrg case 0xB4: 462e1c0d025Smrg return 0x0404; 463e1c0d025Smrg case 0xB6: 464e1c0d025Smrg return 0x0406; 465e1c0d025Smrg case 0xB7: 466e1c0d025Smrg return 0x0407; 467e1c0d025Smrg case 0xBD: 468e1c0d025Smrg return 0x0490; 469e1c0d025Smrg case 0xBE: 470e1c0d025Smrg return 0x040E; 471e1c0d025Smrg default: 472e1c0d025Smrg return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); 473e1c0d025Smrg } 4743da084b3Smrg} 4753da084b3Smrg 476e1c0d025Smrgstatic FontMapRec koi8_ru[] = { 477e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, koi8_ru_to_unicode, NULL, NULL, NULL, NULL}, 478e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 4793da084b3Smrg}; 4803da084b3Smrg 4813da084b3Smrg/* koi8-e, ISO-IR-111 or ECMA-Cyrillic */ 4823da084b3Smrg 483e1c0d025Smrgstatic const unsigned short koi8_e_A0_BF[] = { 484e1c0d025Smrg 0x00A0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, 485e1c0d025Smrg 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00AD, 0x045E, 0x045F, 486e1c0d025Smrg 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, 487e1c0d025Smrg 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00A4, 0x040E, 0x040F 488e1c0d025Smrg}; 4893da084b3Smrg 4903da084b3Smrgstatic unsigned 4913da084b3Smrgkoi8_e_to_unicode(unsigned koicode, void *client_data) 4923da084b3Smrg{ 493e1c0d025Smrg if (koicode < 0xA0) 4943da084b3Smrg return koicode; 495e1c0d025Smrg else if (koicode < 0xC0) 496e1c0d025Smrg return koi8_e_A0_BF[koicode - 0xA0]; 49748c85eb7Smrg else 4983da084b3Smrg return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); 4993da084b3Smrg} 5003da084b3Smrg 501e1c0d025Smrgstatic FontMapRec koi8_e[] = { 502e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, koi8_e_to_unicode, NULL, NULL, NULL, NULL}, 503e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 5043da084b3Smrg}; 5053da084b3Smrg 5063da084b3Smrg/* Koi8 unified */ 5073da084b3Smrg 508e1c0d025Smrgstatic const unsigned short koi8_uni_80_BF[] = { 509e1c0d025Smrg 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, 510e1c0d025Smrg 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590, 511e1c0d025Smrg 0x2591, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 512e1c0d025Smrg 0x00A9, 0x2122, 0x00A0, 0x00BB, 0x00AE, 0x00AB, 0x00B7, 0x00A4, 513e1c0d025Smrg 0x00A0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, 514e1c0d025Smrg 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x0491, 0x045E, 0x045F, 515e1c0d025Smrg 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, 516e1c0d025Smrg 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x0490, 0x040E, 0x040F 517e1c0d025Smrg}; 5183da084b3Smrg 51948c85eb7Smrgstatic unsigned 5203da084b3Smrgkoi8_uni_to_unicode(unsigned koicode, void *client_data) 5213da084b3Smrg{ 522e1c0d025Smrg if (koicode < 0x80) 5233da084b3Smrg return koicode; 524e1c0d025Smrg else if (koicode < 0xC0) 525e1c0d025Smrg return koi8_uni_80_BF[koicode - 0x80]; 5263da084b3Smrg else 5273da084b3Smrg return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); 5283da084b3Smrg} 5293da084b3Smrg 530e1c0d025Smrgstatic FontMapRec koi8_uni[] = { 531e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, koi8_uni_to_unicode, NULL, NULL, NULL, NULL}, 532e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 5333da084b3Smrg}; 5343da084b3Smrg 5353da084b3Smrg/* Ukrainian variant of Koi8-R; see RFC 2319 */ 5363da084b3Smrg 53748c85eb7Smrgstatic unsigned 5383da084b3Smrgkoi8_u_to_unicode(unsigned koicode, void *client_data) 5393da084b3Smrg{ 540e1c0d025Smrg switch (koicode) { 541e1c0d025Smrg case 0xA4: 542e1c0d025Smrg return 0x0454; 543e1c0d025Smrg case 0xA6: 544e1c0d025Smrg return 0x0456; 545e1c0d025Smrg case 0xA7: 546e1c0d025Smrg return 0x0457; 547e1c0d025Smrg case 0xAD: 548e1c0d025Smrg return 0x0491; 549e1c0d025Smrg case 0xB4: 550e1c0d025Smrg return 0x0404; 551e1c0d025Smrg case 0xB6: 552e1c0d025Smrg return 0x0406; 553e1c0d025Smrg case 0xB7: 554e1c0d025Smrg return 0x0407; 555e1c0d025Smrg case 0xBD: 556e1c0d025Smrg return 0x0490; 557e1c0d025Smrg default: 558e1c0d025Smrg return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); 5593da084b3Smrg } 5603da084b3Smrg} 5613da084b3Smrg 562e1c0d025Smrgstatic FontMapRec koi8_u[] = { 563e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, koi8_u_to_unicode, NULL, NULL, NULL}, 564e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 5653da084b3Smrg}; 5663da084b3Smrg 5673da084b3Smrg/* Microsoft Symbol, which is only meaningful for TrueType fonts, is 5683da084b3Smrg treated specially in ftenc.c, where we add usFirstCharIndex-0x20 to 5693da084b3Smrg the glyph index before applying the cmap. Lovely design. */ 5703da084b3Smrg 571e1c0d025Smrgstatic FontMapRec microsoft_symbol[] = { 572e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 3, 0, NULL, NULL, NULL, NULL, NULL}, 573e1c0d025Smrg /* You never know */ 574e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 3, 1, NULL, NULL, NULL, NULL, NULL}, 575e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 576e1c0d025Smrg}; 5773da084b3Smrg 578e1c0d025Smrgstatic FontMapRec apple_roman[] = { 579e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 1, 0, NULL, NULL, NULL, NULL, NULL}, 580e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 581e1c0d025Smrg}; 5823da084b3Smrg 5833da084b3Smrg/* The data for recodings */ 5843da084b3Smrg 5853da084b3Smrg/* For compatibility with X11R6.4. Losers. */ 586e1c0d025Smrgstatic char *iso8859_15_aliases[2] = { "fcd8859-15", NULL }; 587e1c0d025Smrg 588e1c0d025Smrgstatic FontEncRec initial_encodings[] = { 589e1c0d025Smrg {"iso10646-1", NULL, 256 * 256, 0, iso10646, NULL, 0, 0}, /* Unicode */ 590e1c0d025Smrg {"iso8859-1", NULL, 256, 0, iso8859_1, NULL, 0, 0}, /* Latin 1 (West European) */ 591e1c0d025Smrg {"iso8859-2", NULL, 256, 0, iso8859_2, NULL, 0, 0}, /* Latin 2 (East European) */ 592e1c0d025Smrg {"iso8859-3", NULL, 256, 0, iso8859_3, NULL, 0, 0}, /* Latin 3 (South European) */ 593e1c0d025Smrg {"iso8859-4", NULL, 256, 0, iso8859_4, NULL, 0, 0}, /* Latin 4 (North European) */ 594e1c0d025Smrg {"iso8859-5", NULL, 256, 0, iso8859_5, NULL, 0, 0}, /* Cyrillic */ 595e1c0d025Smrg {"iso8859-6", NULL, 256, 0, iso8859_6, NULL, 0, 0}, /* Arabic */ 596e1c0d025Smrg {"iso8859-7", NULL, 256, 0, iso8859_7, NULL, 0, 0}, /* Greek */ 597e1c0d025Smrg {"iso8859-8", NULL, 256, 0, iso8859_8, NULL, 0, 0}, /* Hebrew */ 598e1c0d025Smrg {"iso8859-9", NULL, 256, 0, iso8859_9, NULL, 0, 0}, /* Latin 5 (Turkish) */ 599e1c0d025Smrg {"iso8859-10", NULL, 256, 0, iso8859_10, NULL, 0, 0}, /* Latin 6 (Nordic) */ 600e1c0d025Smrg {"iso8859-15", iso8859_15_aliases, 256, 0, iso8859_15, NULL, 0, 0}, /* Latin 9 */ 601e1c0d025Smrg {"koi8-r", NULL, 256, 0, koi8_r, NULL, 0, 0}, /* Russian */ 602e1c0d025Smrg {"koi8-ru", NULL, 256, 0, koi8_ru, NULL, 0, 0}, /* Ukrainian */ 603e1c0d025Smrg {"koi8-uni", NULL, 256, 0, koi8_uni, NULL, 0, 0}, /* Russian/Ukrainian/Bielorussian */ 604e1c0d025Smrg {"koi8-e", NULL, 256, 0, koi8_e, NULL, 0, 0}, /* ``European'' */ 605e1c0d025Smrg {"koi8-u", NULL, 256, 0, koi8_u, NULL, 0, 0}, /* Ukrainian too */ 606e1c0d025Smrg {"microsoft-symbol", NULL, 256, 0, microsoft_symbol, NULL, 0, 0}, 607e1c0d025Smrg {"apple-roman", NULL, 256, 0, apple_roman, NULL, 0, 0}, 608e1c0d025Smrg {NULL, NULL, 0, 0, NULL, NULL, 0, 0} 6093da084b3Smrg}; 6103da084b3Smrg 611e1c0d025Smrgstatic FontEncPtr font_encodings = NULL; 6123da084b3Smrg 6133da084b3Smrgstatic void 6143da084b3Smrgdefine_initial_encoding_info(void) 6153da084b3Smrg{ 6163da084b3Smrg FontEncPtr encoding; 6173da084b3Smrg FontMapPtr mapping; 6183da084b3Smrg 6193da084b3Smrg font_encodings = initial_encodings; 620e1c0d025Smrg for (encoding = font_encodings; ; encoding++) { 6213da084b3Smrg encoding->next = encoding + 1; 622e1c0d025Smrg for (mapping = encoding->mappings; ; mapping++) { 623e1c0d025Smrg mapping->next = mapping + 1; 6243da084b3Smrg mapping->encoding = encoding; 625e1c0d025Smrg if (mapping->next->type == 0) { 6263da084b3Smrg mapping->next = NULL; 6273da084b3Smrg break; 6283da084b3Smrg } 6293da084b3Smrg } 630e1c0d025Smrg if (!encoding->next->name) { 6313da084b3Smrg encoding->next = NULL; 6323da084b3Smrg break; 6333da084b3Smrg } 6343da084b3Smrg } 6353da084b3Smrg} 6363da084b3Smrg 637e1c0d025Smrgchar * 6383da084b3SmrgFontEncFromXLFD(const char *name, int length) 6393da084b3Smrg{ 6403da084b3Smrg const char *p; 6413da084b3Smrg char *q; 6423da084b3Smrg static char charset[MAXFONTNAMELEN]; 6433da084b3Smrg int len; 6443da084b3Smrg 645e1c0d025Smrg if (length > MAXFONTNAMELEN - 1) 6463da084b3Smrg return NULL; 6473da084b3Smrg 648e1c0d025Smrg if (name == NULL) 6493da084b3Smrg p = NULL; 6503da084b3Smrg else { 6513da084b3Smrg p = name + length - 1; 652e1c0d025Smrg while (p > name && *p != '-') 6533da084b3Smrg p--; 6543da084b3Smrg p--; 655e1c0d025Smrg while (p >= name && *p != '-') 6563da084b3Smrg p--; 657e1c0d025Smrg if (p <= name) 6583da084b3Smrg p = NULL; 6593da084b3Smrg } 6603da084b3Smrg 6613da084b3Smrg /* now p either is null or points at the '-' before the charset registry */ 662d63fdb69Smrg 663e1c0d025Smrg if (p == NULL) 6643da084b3Smrg return NULL; 66548c85eb7Smrg 6663da084b3Smrg len = length - (p - name) - 1; 667e1c0d025Smrg memcpy(charset, p + 1, len); 6683da084b3Smrg charset[len] = 0; 66948c85eb7Smrg 6703da084b3Smrg /* check for a subset specification */ 671e1c0d025Smrg if ((q = strchr(charset, (int) '['))) 6723da084b3Smrg *q = 0; 67348c85eb7Smrg 6743da084b3Smrg return charset; 6753da084b3Smrg} 6763da084b3Smrg 6773da084b3Smrgunsigned 678e1c0d025SmrgFontEncRecode(unsigned code, FontMapPtr mapping) 6793da084b3Smrg{ 6803da084b3Smrg FontEncPtr encoding = mapping->encoding; 681e1c0d025Smrg 682e1c0d025Smrg if (encoding && mapping->recode) { 683e1c0d025Smrg if (encoding->row_size == 0) { 6843da084b3Smrg /* linear encoding */ 685e1c0d025Smrg if (code < encoding->first || code >= encoding->size) 6863da084b3Smrg return 0; 687e1c0d025Smrg } 688e1c0d025Smrg else { 6893da084b3Smrg /* matrix encoding */ 690e1c0d025Smrg int row = code / 0x100, col = code & 0xFF; 691e1c0d025Smrg 692e1c0d025Smrg if (row < encoding->first || row >= encoding->size || 693e1c0d025Smrg col < encoding->first_col || col >= encoding->row_size) 6943da084b3Smrg return 0; 6953da084b3Smrg } 696e1c0d025Smrg return (*mapping->recode) (code, mapping->client_data); 697e1c0d025Smrg } 698e1c0d025Smrg else 6993da084b3Smrg return code; 7003da084b3Smrg} 7013da084b3Smrg 702e1c0d025Smrgchar * 7033da084b3SmrgFontEncName(unsigned code, FontMapPtr mapping) 7043da084b3Smrg{ 7053da084b3Smrg FontEncPtr encoding = mapping->encoding; 706e1c0d025Smrg 707e1c0d025Smrg if (encoding && mapping->name) { 708e1c0d025Smrg if ((encoding->row_size == 0 && code >= encoding->size) || 709e1c0d025Smrg (encoding->row_size != 0 && 710e1c0d025Smrg (code / 0x100 >= encoding->size || 711e1c0d025Smrg (code & 0xFF) >= encoding->row_size))) 7123da084b3Smrg return NULL; 713e1c0d025Smrg return (*mapping->name) (code, mapping->client_data); 714e1c0d025Smrg } 715e1c0d025Smrg else 7163da084b3Smrg return NULL; 7173da084b3Smrg} 7183da084b3Smrg 7193da084b3SmrgFontEncPtr 7203da084b3SmrgFontEncFind(const char *encoding_name, const char *filename) 7213da084b3Smrg{ 7223da084b3Smrg FontEncPtr encoding; 7233da084b3Smrg char **alias; 72448c85eb7Smrg 725e1c0d025Smrg if (font_encodings == NULL) 726e1c0d025Smrg define_initial_encoding_info(); 72748c85eb7Smrg 728e1c0d025Smrg for (encoding = font_encodings; encoding; encoding = encoding->next) { 729e1c0d025Smrg if (!strcasecmp(encoding->name, encoding_name)) 7303da084b3Smrg return encoding; 731e1c0d025Smrg if (encoding->aliases) 732e1c0d025Smrg for (alias = encoding->aliases; *alias; alias++) 733e1c0d025Smrg if (!strcasecmp(*alias, encoding_name)) 7343da084b3Smrg return encoding; 735e1c0d025Smrg } 7363da084b3Smrg 737e1c0d025Smrg /* Unknown charset, try to load a definition file */ 7383da084b3Smrg return FontEncLoad(encoding_name, filename); 7393da084b3Smrg} 7403da084b3Smrg 7413da084b3SmrgFontMapPtr 7423da084b3SmrgFontMapFind(FontEncPtr encoding, int type, int pid, int eid) 7433da084b3Smrg{ 7443da084b3Smrg FontMapPtr mapping; 745e1c0d025Smrg 746e1c0d025Smrg if (encoding == NULL) 7473da084b3Smrg return NULL; 7483da084b3Smrg 749e1c0d025Smrg for (mapping = encoding->mappings; mapping; mapping = mapping->next) { 750e1c0d025Smrg if (mapping->type != type) 7513da084b3Smrg continue; 752e1c0d025Smrg if (pid > 0 && mapping->pid != pid) 7533da084b3Smrg continue; 754e1c0d025Smrg if (eid > 0 && mapping->eid != eid) 7553da084b3Smrg continue; 7563da084b3Smrg return mapping; 7573da084b3Smrg } 7583da084b3Smrg return NULL; 7593da084b3Smrg} 7603da084b3Smrg 7613da084b3SmrgFontMapPtr 7623da084b3SmrgFontEncMapFind(const char *encoding_name, int type, int pid, int eid, 7633da084b3Smrg const char *filename) 7643da084b3Smrg{ 7653da084b3Smrg FontEncPtr encoding; 7663da084b3Smrg FontMapPtr mapping; 7673da084b3Smrg 7683da084b3Smrg encoding = FontEncFind(encoding_name, filename); 769e1c0d025Smrg if (encoding == NULL) 7703da084b3Smrg return NULL; 7713da084b3Smrg mapping = FontMapFind(encoding, type, pid, eid); 7723da084b3Smrg return mapping; 7733da084b3Smrg} 7743da084b3Smrg 7753da084b3Smrgstatic FontEncPtr 7763da084b3SmrgFontEncLoad(const char *encoding_name, const char *filename) 7773da084b3Smrg{ 7783da084b3Smrg FontEncPtr encoding; 77948c85eb7Smrg 7803da084b3Smrg encoding = FontEncReallyLoad(encoding_name, filename); 7813da084b3Smrg if (encoding == NULL) { 7823da084b3Smrg return NULL; 783e1c0d025Smrg } 784e1c0d025Smrg else { 7853da084b3Smrg char **alias; 7863da084b3Smrg int found = 0; 78748c85eb7Smrg 7883da084b3Smrg /* Check whether the name is already known for this encoding */ 789e1c0d025Smrg if (strcasecmp(encoding->name, encoding_name) == 0) { 7903da084b3Smrg found = 1; 791e1c0d025Smrg } 792e1c0d025Smrg else { 793e1c0d025Smrg if (encoding->aliases) { 794e1c0d025Smrg for (alias = encoding->aliases; *alias; alias++) 795e1c0d025Smrg if (!strcasecmp(*alias, encoding_name)) { 7963da084b3Smrg found = 1; 7973da084b3Smrg break; 7983da084b3Smrg } 7993da084b3Smrg } 8003da084b3Smrg } 80148c85eb7Smrg 802e1c0d025Smrg if (!found) { 8033da084b3Smrg /* Add a new alias. This works because we know that this 8043da084b3Smrg particular encoding has been allocated dynamically */ 8053da084b3Smrg char **new_aliases; 8063da084b3Smrg char *new_name; 8073da084b3Smrg int numaliases = 0; 80848c85eb7Smrg 80955acc8fcSmrg new_name = strdup(encoding_name); 810e1c0d025Smrg if (new_name == NULL) 8113da084b3Smrg return NULL; 812e1c0d025Smrg if (encoding->aliases) { 813e1c0d025Smrg for (alias = encoding->aliases; *alias; alias++) 8143da084b3Smrg numaliases++; 8153da084b3Smrg } 8162a53b785Smrg new_aliases = Xmallocarray(numaliases + 2, sizeof(char *)); 817e1c0d025Smrg if (new_aliases == NULL) { 81855acc8fcSmrg free(new_name); 8193da084b3Smrg return NULL; 8203da084b3Smrg } 821e1c0d025Smrg if (encoding->aliases) { 822e1c0d025Smrg memcpy(new_aliases, encoding->aliases, 823e1c0d025Smrg numaliases * sizeof(char *)); 82455acc8fcSmrg free(encoding->aliases); 8253da084b3Smrg } 8263da084b3Smrg new_aliases[numaliases] = new_name; 827e1c0d025Smrg new_aliases[numaliases + 1] = NULL; 8283da084b3Smrg encoding->aliases = new_aliases; 8293da084b3Smrg } 83048c85eb7Smrg 8313da084b3Smrg /* register the new encoding */ 832e1c0d025Smrg encoding->next = font_encodings; 833e1c0d025Smrg font_encodings = encoding; 83448c85eb7Smrg 8353da084b3Smrg return encoding; 8363da084b3Smrg } 8373da084b3Smrg} 8383da084b3Smrg 8393da084b3Smrgunsigned 8403da084b3SmrgFontEncSimpleRecode(unsigned code, void *client_data) 8413da084b3Smrg{ 8423da084b3Smrg FontEncSimpleMapPtr map; 8433da084b3Smrg unsigned index; 8443da084b3Smrg 8453da084b3Smrg map = client_data; 8463da084b3Smrg 847e1c0d025Smrg if (code > 0xFFFF || (map->row_size && (code & 0xFF) >= map->row_size)) 8483da084b3Smrg return 0; 8493da084b3Smrg 850e1c0d025Smrg if (map->row_size) 851e1c0d025Smrg index = (code & 0xFF) + (code >> 8) * map->row_size; 8523da084b3Smrg else 8533da084b3Smrg index = code; 8543da084b3Smrg 855e1c0d025Smrg if (map->map && index >= map->first && index < map->first + map->len) 856e1c0d025Smrg return map->map[index - map->first]; 857e1c0d025Smrg else 858e1c0d025Smrg return code; 8593da084b3Smrg} 8603da084b3Smrg 8613da084b3Smrgchar * 8623da084b3SmrgFontEncSimpleName(unsigned code, void *client_data) 8633da084b3Smrg{ 8643da084b3Smrg FontEncSimpleNamePtr map; 8653da084b3Smrg 8663da084b3Smrg map = client_data; 867e1c0d025Smrg if (map && code >= map->first && code < map->first + map->len) 868e1c0d025Smrg return map->map[code - map->first]; 8693da084b3Smrg else 8703da084b3Smrg return NULL; 8713da084b3Smrg} 8723da084b3Smrg 8733da084b3Smrgunsigned 8743da084b3SmrgFontEncUndefinedRecode(unsigned code, void *client_data) 8753da084b3Smrg{ 8763da084b3Smrg return code; 8773da084b3Smrg} 8783da084b3Smrg 8793da084b3Smrgchar * 8803da084b3SmrgFontEncUndefinedName(unsigned code, void *client_data) 8813da084b3Smrg{ 8823da084b3Smrg return NULL; 8833da084b3Smrg} 8843da084b3Smrg 8853da084b3Smrg#define FONTENC_SEGMENT_SIZE 256 8863da084b3Smrg#define FONTENC_SEGMENTS 256 8873da084b3Smrg#define FONTENC_INVERSE_CODES (FONTENC_SEGMENT_SIZE * FONTENC_SEGMENTS) 8883da084b3Smrg 8893da084b3Smrgstatic unsigned int 890e1c0d025Smrgreverse_reverse(unsigned i, void *data) 8913da084b3Smrg{ 8923da084b3Smrg int s, j; 893e1c0d025Smrg unsigned **map = (unsigned **) data; 8943da084b3Smrg 895e1c0d025Smrg if (i >= FONTENC_INVERSE_CODES) 8963da084b3Smrg return 0; 8973da084b3Smrg 898e1c0d025Smrg if (map == NULL) 8993da084b3Smrg return 0; 9003da084b3Smrg 9013da084b3Smrg s = i / FONTENC_SEGMENT_SIZE; 9023da084b3Smrg j = i % FONTENC_SEGMENT_SIZE; 9033da084b3Smrg 904e1c0d025Smrg if (map[s] == NULL) 9053da084b3Smrg return 0; 9063da084b3Smrg else 9073da084b3Smrg return map[s][j]; 9083da084b3Smrg} 9093da084b3Smrg 9103da084b3Smrgstatic int 9113da084b3Smrgtree_set(unsigned int **map, unsigned int i, unsigned int j) 9123da084b3Smrg{ 9133da084b3Smrg int s, c; 9143da084b3Smrg 915e1c0d025Smrg if (i >= FONTENC_INVERSE_CODES) 9163da084b3Smrg return FALSE; 9173da084b3Smrg 9183da084b3Smrg s = i / FONTENC_SEGMENT_SIZE; 9193da084b3Smrg c = i % FONTENC_SEGMENT_SIZE; 9203da084b3Smrg 921e1c0d025Smrg if (map[s] == NULL) { 92248c85eb7Smrg map[s] = calloc(FONTENC_SEGMENT_SIZE, sizeof(int)); 923e1c0d025Smrg if (map[s] == NULL) 9243da084b3Smrg return FALSE; 925e1c0d025Smrg } 9263da084b3Smrg 9273da084b3Smrg map[s][c] = j; 9283da084b3Smrg return TRUE; 9293da084b3Smrg} 9303da084b3Smrg 9313da084b3SmrgFontMapReversePtr 9323da084b3SmrgFontMapReverse(FontMapPtr mapping) 9333da084b3Smrg{ 9343da084b3Smrg FontEncPtr encoding = mapping->encoding; 9353da084b3Smrg FontMapReversePtr reverse = NULL; 9363da084b3Smrg unsigned int **map = NULL; 9373da084b3Smrg int i, j, k; 9383da084b3Smrg 939e1c0d025Smrg if (encoding == NULL) 940e1c0d025Smrg goto bail; 9413da084b3Smrg 942e1c0d025Smrg map = calloc(FONTENC_SEGMENTS, sizeof(int *)); 943e1c0d025Smrg if (map == NULL) 944e1c0d025Smrg goto bail; 9453da084b3Smrg 946e1c0d025Smrg if (encoding->row_size == 0) { 947e1c0d025Smrg for (i = encoding->first; i < encoding->size; i++) { 9483da084b3Smrg k = FontEncRecode(i, mapping); 949e1c0d025Smrg if (k != 0) 950e1c0d025Smrg if (!tree_set(map, k, i)) 9513da084b3Smrg goto bail; 9523da084b3Smrg } 953e1c0d025Smrg } 954e1c0d025Smrg else { 955e1c0d025Smrg for (i = encoding->first; i < encoding->size; i++) { 956e1c0d025Smrg for (j = encoding->first_col; j < encoding->row_size; j++) { 957e1c0d025Smrg k = FontEncRecode(i * 256 + j, mapping); 958e1c0d025Smrg if (k != 0) 959e1c0d025Smrg if (!tree_set(map, k, i * 256 + j)) 9603da084b3Smrg goto bail; 9613da084b3Smrg } 9623da084b3Smrg } 9633da084b3Smrg } 9643da084b3Smrg 9653da084b3Smrg reverse = malloc(sizeof(FontMapReverseRec)); 966e1c0d025Smrg if (!reverse) 967e1c0d025Smrg goto bail; 9683da084b3Smrg 9693da084b3Smrg reverse->reverse = reverse_reverse; 9703da084b3Smrg reverse->data = map; 9713da084b3Smrg return reverse; 9723da084b3Smrg 973e1c0d025Smrg bail: 97455acc8fcSmrg free(map); 97555acc8fcSmrg free(reverse); 9763da084b3Smrg return NULL; 9773da084b3Smrg} 9783da084b3Smrg 9793da084b3Smrgvoid 9803da084b3SmrgFontMapReverseFree(FontMapReversePtr delendum) 9813da084b3Smrg{ 982e1c0d025Smrg unsigned int **map = (unsigned int **) delendum; 9833da084b3Smrg int i; 98448c85eb7Smrg 985e1c0d025Smrg if (map == NULL) 9863da084b3Smrg return; 9873da084b3Smrg 988e1c0d025Smrg for (i = 0; i < FONTENC_SEGMENTS; i++) 989e1c0d025Smrg free(map[i]); 9903da084b3Smrg 99155acc8fcSmrg free(map); 9923da084b3Smrg return; 9933da084b3Smrg} 994