fontenc.c revision 52fd71cd
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 253da084b3Smrg#include <string.h> 263da084b3Smrg#include <strings.h> 273da084b3Smrg#include <stdlib.h> 2855acc8fcSmrg 293da084b3Smrg#define FALSE 0 303da084b3Smrg#define TRUE 1 313da084b3Smrg#define MAXFONTNAMELEN 1024 323da084b3Smrg#define MAXFONTFILENAMELEN 1024 333da084b3Smrg 343da084b3Smrg#include <X11/fonts/fontenc.h> 353da084b3Smrg#include "fontencI.h" 363da084b3Smrg 373da084b3Smrg/* Functions local to this file */ 383da084b3Smrg 39e1c0d025Smrgstatic FontEncPtr FontEncLoad(const char *, const char *); 403da084b3Smrg 413da084b3Smrg/* Early versions of this code only knew about hardwired encodings, 423da084b3Smrg hence the following data. Now that the code knows how to load an 433da084b3Smrg encoding from a file, most of these tables could go away. */ 443da084b3Smrg 453da084b3Smrg/* At any rate, no new hardcoded encodings will be added. */ 463da084b3Smrg 47e1c0d025Smrgstatic FontMapRec iso10646[] = { 48e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, NULL, NULL, NULL, NULL, NULL}, 49e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 503da084b3Smrg}; 513da084b3Smrg 523da084b3Smrg/* Notice that the Apple encodings do not have all the characters in 533da084b3Smrg the corresponding ISO 8859, and therefore the table has some holes. 543da084b3Smrg There's not much more we can do with fonts without a Unicode cmap 553da084b3Smrg unless we are willing to combine cmaps (which we are not). */ 563da084b3Smrg 5748c85eb7Smrgstatic const unsigned short 58e1c0d025Smrg iso8859_1_apple_roman[] = { 59e1c0d025Smrg 0xCA, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4, 0x00, 0xA4, 60e1c0d025Smrg 0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0x00, 0xA8, 0xF8, 61e1c0d025Smrg 0xA1, 0xB1, 0x00, 0x00, 0xAB, 0xB5, 0xA6, 0xE1, 62e1c0d025Smrg 0xFC, 0x00, 0xBC, 0xC8, 0x00, 0x00, 0x00, 0xC0, 63e1c0d025Smrg 0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82, 64e1c0d025Smrg 0xE9, 0x83, 0xE6, 0xE8, 0xED, 0xEA, 0xEB, 0xEC, 65e1c0d025Smrg 0x00, 0x84, 0xF1, 0xEE, 0xEF, 0xCD, 0x85, 0x00, 66e1c0d025Smrg 0xAF, 0xF4, 0xF2, 0xF3, 0x86, 0x00, 0x00, 0xA7, 67e1c0d025Smrg 0x88, 0x87, 0x89, 0x8B, 0x8A, 0x8C, 0xBE, 0x8D, 68e1c0d025Smrg 0x8F, 0x8E, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, 69e1c0d025Smrg 0x00, 0x96, 0x98, 0x97, 0x99, 0x9B, 0x9A, 0xD6, 70e1c0d025Smrg 0xBF, 0x9D, 0x9C, 0x9E, 0x9F, 0x00, 0x00, 0xD8 71e1c0d025Smrg}; 723da084b3Smrg 733da084b3Smrg/* Cannot use simple_recode because need to eliminate 0x80<=code<0xA0 */ 743da084b3Smrgstatic unsigned 753da084b3Smrgiso8859_1_to_apple_roman(unsigned isocode, void *client_data) 763da084b3Smrg{ 77e1c0d025Smrg if (isocode <= 0x80) 783da084b3Smrg return isocode; 79e1c0d025Smrg else if (isocode >= 0xA0) 80e1c0d025Smrg return iso8859_1_apple_roman[isocode - 0xA0]; 813da084b3Smrg else 823da084b3Smrg return 0; 833da084b3Smrg} 843da084b3Smrg 85e1c0d025Smrgstatic FontMapRec iso8859_1[] = { 86e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 2, 2, NULL, NULL, NULL, NULL, NULL}, /* ISO 8859-1 */ 87e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, NULL, NULL, NULL, NULL, NULL}, /* ISO 8859-1 coincides with Unicode */ 88e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 1, 0, iso8859_1_to_apple_roman, NULL, NULL, NULL, 89e1c0d025Smrg NULL}, 90e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 913da084b3Smrg}; 923da084b3Smrg 93e1c0d025Smrgstatic const unsigned short iso8859_2_tophalf[] = { 94e1c0d025Smrg 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, 95e1c0d025Smrg 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, 96e1c0d025Smrg 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, 97e1c0d025Smrg 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, 98e1c0d025Smrg 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, 99e1c0d025Smrg 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, 100e1c0d025Smrg 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 101e1c0d025Smrg 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, 102e1c0d025Smrg 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 103e1c0d025Smrg 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, 104e1c0d025Smrg 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, 105e1c0d025Smrg 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 106e1c0d025Smrg}; 107e1c0d025Smrg 108e1c0d025Smrgstatic FontEncSimpleMapRec iso8859_2_to_unicode_map = 109e1c0d025Smrg { 0x60, 0, 0xA0, iso8859_2_tophalf }; 110e1c0d025Smrg 111e1c0d025Smrgstatic const unsigned short iso8859_2_apple_centeuro[] = { 112e1c0d025Smrg 0xCA, 0x84, 0x00, 0xFC, 0x00, 0xBB, 0xE5, 0xA4, 113e1c0d025Smrg 0xAC, 0xE1, 0x00, 0xE8, 0x8F, 0x00, 0xEB, 0xFB, 114e1c0d025Smrg 0xA1, 0x88, 0x00, 0xB8, 0x00, 0xBC, 0xE6, 0xFF, 115e1c0d025Smrg 0x00, 0xE4, 0x00, 0xE9, 0x90, 0x00, 0xEC, 0xFD, 116e1c0d025Smrg 0xD9, 0xE7, 0x00, 0x00, 0x80, 0xBD, 0x8C, 0x00, 117e1c0d025Smrg 0x89, 0x83, 0xA2, 0x00, 0x9D, 0xEA, 0x00, 0x91, 118e1c0d025Smrg 0x00, 0xC1, 0xC5, 0xEE, 0xEF, 0xCC, 0x85, 0x00, 119e1c0d025Smrg 0xDB, 0xF1, 0xF2, 0xF4, 0x86, 0xF8, 0x00, 0xA7, 120e1c0d025Smrg 0xDA, 0x87, 0x00, 0x00, 0x8A, 0xBE, 0x8D, 0x00, 121e1c0d025Smrg 0x8B, 0x8E, 0xAB, 0x00, 0x9E, 0x92, 0x00, 0x93, 122e1c0d025Smrg 0x00, 0xC4, 0xCB, 0x97, 0x99, 0xCE, 0x9A, 0xD6, 123e1c0d025Smrg 0xDE, 0xF3, 0x9C, 0xF5, 0x9F, 0xF9, 0x00, 0x00 124e1c0d025Smrg}; 1253da084b3Smrg 1263da084b3Smrgstatic unsigned 1273da084b3Smrgiso8859_2_to_apple_centeuro(unsigned isocode, void *client_data) 1283da084b3Smrg{ 129e1c0d025Smrg if (isocode <= 0x80) 1303da084b3Smrg return isocode; 131e1c0d025Smrg else if (isocode >= 0xA0) 132e1c0d025Smrg return iso8859_2_apple_centeuro[isocode - 0xA0]; 1333da084b3Smrg else 1343da084b3Smrg return 0; 1353da084b3Smrg} 1363da084b3Smrg 137e1c0d025Smrgstatic FontMapRec iso8859_2[] = { 138e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, 139e1c0d025Smrg FontEncSimpleRecode, NULL, &iso8859_2_to_unicode_map, NULL, NULL}, 140e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 1, 29, iso8859_2_to_apple_centeuro, NULL, NULL, 141e1c0d025Smrg NULL, NULL}, 142e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 1433da084b3Smrg}; 1443da084b3Smrg 145e1c0d025Smrgstatic const unsigned short iso8859_3_tophalf[] = { 146e1c0d025Smrg 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0x0000, 0x0124, 0x00A7, 147e1c0d025Smrg 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0x0000, 0x017B, 148e1c0d025Smrg 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, 149e1c0d025Smrg 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0x0000, 0x017C, 150e1c0d025Smrg 0x00C0, 0x00C1, 0x00C2, 0x0000, 0x00C4, 0x010A, 0x0108, 0x00C7, 151e1c0d025Smrg 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 152e1c0d025Smrg 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, 153e1c0d025Smrg 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF, 154e1c0d025Smrg 0x00E0, 0x00E1, 0x00E2, 0x0000, 0x00E4, 0x010B, 0x0109, 0x00E7, 155e1c0d025Smrg 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 156e1c0d025Smrg 0x0000, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, 157e1c0d025Smrg 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9 1583da084b3Smrg}; 1593da084b3Smrg 160e1c0d025Smrgstatic FontEncSimpleMapRec iso8859_3_to_unicode_map = 161e1c0d025Smrg { 0x60, 0, 0xA0, iso8859_3_tophalf }; 1623da084b3Smrg 163e1c0d025Smrgstatic FontMapRec iso8859_3[] = { 164e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, 165e1c0d025Smrg FontEncSimpleRecode, NULL, &iso8859_3_to_unicode_map, NULL, NULL}, 166e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 1673da084b3Smrg}; 1683da084b3Smrg 169e1c0d025Smrgstatic const unsigned short iso8859_4_tophalf[] = { 170e1c0d025Smrg 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7, 171e1c0d025Smrg 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF, 172e1c0d025Smrg 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7, 173e1c0d025Smrg 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B, 174e1c0d025Smrg 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, 175e1c0d025Smrg 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A, 176e1c0d025Smrg 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 177e1c0d025Smrg 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF, 178e1c0d025Smrg 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, 179e1c0d025Smrg 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B, 180e1c0d025Smrg 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 181e1c0d025Smrg 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9, 182e1c0d025Smrg}; 1833da084b3Smrg 184e1c0d025Smrgstatic FontEncSimpleMapRec iso8859_4_to_unicode_map = 185e1c0d025Smrg { 0x60, 0, 0xA0, iso8859_4_tophalf }; 186e1c0d025Smrg 187e1c0d025Smrgstatic FontMapRec iso8859_4[] = { 188e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, FontEncSimpleRecode, NULL, 189e1c0d025Smrg &iso8859_4_to_unicode_map, NULL, NULL}, 190e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 1913da084b3Smrg}; 1923da084b3Smrg 193e1c0d025Smrgstatic const unsigned short iso8859_5_tophalf[] = { 194e1c0d025Smrg 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 195e1c0d025Smrg 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F, 196e1c0d025Smrg 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 197e1c0d025Smrg 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 198e1c0d025Smrg 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 199e1c0d025Smrg 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 200e1c0d025Smrg 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 201e1c0d025Smrg 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 202e1c0d025Smrg 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 203e1c0d025Smrg 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 204e1c0d025Smrg 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 205e1c0d025Smrg 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F 206e1c0d025Smrg}; 2073da084b3Smrg 208e1c0d025Smrgstatic FontEncSimpleMapRec iso8859_5_to_unicode_map = 209e1c0d025Smrg { 0x60, 0, 0xA0, iso8859_5_tophalf }; 210e1c0d025Smrg 211e1c0d025Smrgstatic const unsigned short iso8859_5_apple_cyrillic[] = { 212e1c0d025Smrg 0xCA, 0xDD, 0xAB, 0xAE, 0xB8, 0xC1, 0xA7, 0xBA, 213e1c0d025Smrg 0xB7, 0xBC, 0xBE, 0xCB, 0xCD, 0x00, 0xD8, 0xDA, 214e1c0d025Smrg 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 215e1c0d025Smrg 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 216e1c0d025Smrg 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 217e1c0d025Smrg 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 218e1c0d025Smrg 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 219e1c0d025Smrg 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 220e1c0d025Smrg 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 221e1c0d025Smrg 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xDF, 222e1c0d025Smrg 0xDC, 0xDE, 0xAC, 0xAF, 0xB9, 0xCF, 0xB4, 0xBB, 223e1c0d025Smrg 0xC0, 0xBD, 0xBF, 0xCC, 0xCE, 0xA4, 0xD9, 0xDB 224e1c0d025Smrg}; 2253da084b3Smrg 2263da084b3Smrgstatic unsigned 2273da084b3Smrgiso8859_5_to_apple_cyrillic(unsigned isocode, void *client_data) 2283da084b3Smrg{ 229e1c0d025Smrg if (isocode <= 0x80) 2303da084b3Smrg return isocode; 231e1c0d025Smrg else if (isocode >= 0xA0) 232e1c0d025Smrg return iso8859_5_apple_cyrillic[isocode - 0x80]; 233e1c0d025Smrg else 234e1c0d025Smrg return 0; 2353da084b3Smrg} 2363da084b3Smrg 237e1c0d025Smrgstatic FontMapRec iso8859_5[] = { 238e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, FontEncSimpleRecode, NULL, 239e1c0d025Smrg &iso8859_5_to_unicode_map, NULL, NULL}, 240e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 1, 7, iso8859_5_to_apple_cyrillic, NULL, NULL, 241e1c0d025Smrg NULL, NULL}, 242e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 2433da084b3Smrg}; 2443da084b3Smrg 2453da084b3Smrg/* ISO 8859-6 seems useless for serving fonts (not enough presentation 2463da084b3Smrg * forms). What do Arabic-speakers use? */ 2473da084b3Smrg 2483da084b3Smrgstatic unsigned 2493da084b3Smrgiso8859_6_to_unicode(unsigned isocode, void *client_data) 2503da084b3Smrg{ 251e1c0d025Smrg if (isocode <= 0xA0 || isocode == 0xA4 || isocode == 0xAD) 2523da084b3Smrg return isocode; 253e1c0d025Smrg else if (isocode == 0xAC || isocode == 0xBB || 254e1c0d025Smrg isocode == 0xBF || 255e1c0d025Smrg (isocode >= 0xC1 && isocode <= 0xDA) || 256e1c0d025Smrg (isocode >= 0xE0 && isocode <= 0xEF) || 257e1c0d025Smrg (isocode >= 0xF0 && isocode <= 0xF2)) 258e1c0d025Smrg return isocode - 0xA0 + 0x0600; 2593da084b3Smrg else 2603da084b3Smrg return 0; 2613da084b3Smrg} 2623da084b3Smrg 263e1c0d025Smrgstatic FontMapRec iso8859_6[] = { 264e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, iso8859_6_to_unicode, NULL, NULL, NULL, NULL}, 265e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 2663da084b3Smrg}; 2673da084b3Smrg 26848c85eb7Smrgstatic unsigned 2693da084b3Smrgiso8859_7_to_unicode(unsigned isocode, void *client_data) 2703da084b3Smrg{ 271e1c0d025Smrg if (isocode <= 0xA0 || 272e1c0d025Smrg (isocode >= 0xA3 && isocode <= 0xAD) || 273e1c0d025Smrg (isocode >= 0xB0 && isocode <= 0xB3) || 274e1c0d025Smrg isocode == 0xB7 || isocode == 0xBB || isocode == 0xBD) 2753da084b3Smrg return isocode; 276e1c0d025Smrg else if (isocode == 0xA1) 27752fd71cdSmrg return 0x2018; 278e1c0d025Smrg else if (isocode == 0xA2) 27952fd71cdSmrg return 0x2019; 280e1c0d025Smrg else if (isocode == 0xAF) 2813da084b3Smrg return 0x2015; 282e1c0d025Smrg else if (isocode == 0xD2) /* unassigned */ 28348c85eb7Smrg return 0; 28452fd71cdSmrg else if (isocode >= 0xB4 && isocode <= 0xFE) 285e1c0d025Smrg return isocode - 0xA0 + 0x0370; 2863da084b3Smrg else 2873da084b3Smrg return 0; 2883da084b3Smrg} 2893da084b3Smrg 290e1c0d025Smrgstatic FontMapRec iso8859_7[] = { 291e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, iso8859_7_to_unicode, NULL, NULL, NULL, NULL}, 292e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 2933da084b3Smrg}; 2943da084b3Smrg 2953da084b3Smrgstatic unsigned 2963da084b3Smrgiso8859_8_to_unicode(unsigned isocode, void *client_data) 2973da084b3Smrg{ 298e1c0d025Smrg if (isocode == 0xA1) 2993da084b3Smrg return 0; 300e1c0d025Smrg else if (isocode < 0xBF) 3013da084b3Smrg return isocode; 302e1c0d025Smrg else if (isocode == 0xDF) 3033da084b3Smrg return 0x2017; 304e1c0d025Smrg else if (isocode >= 0xE0 && isocode <= 0xFA) 305e1c0d025Smrg return isocode + 0x04F0; 30648c85eb7Smrg else 3073da084b3Smrg return 0; 3083da084b3Smrg} 3093da084b3Smrg 310e1c0d025Smrgstatic FontMapRec iso8859_8[] = { 311e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, iso8859_8_to_unicode, NULL, NULL, NULL, NULL}, 312e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 3133da084b3Smrg}; 3143da084b3Smrg 3153da084b3Smrgstatic unsigned 3163da084b3Smrgiso8859_9_to_unicode(unsigned isocode, void *client_data) 3173da084b3Smrg{ 318e1c0d025Smrg switch (isocode) { 319e1c0d025Smrg case 0xD0: 320e1c0d025Smrg return 0x011E; 321e1c0d025Smrg case 0xDD: 322e1c0d025Smrg return 0x0130; 323e1c0d025Smrg case 0xDE: 324e1c0d025Smrg return 0x015E; 325e1c0d025Smrg case 0xF0: 326e1c0d025Smrg return 0x011F; 327e1c0d025Smrg case 0xFD: 328e1c0d025Smrg return 0x0131; 329e1c0d025Smrg case 0xFE: 330e1c0d025Smrg return 0x015F; 331e1c0d025Smrg default: 332e1c0d025Smrg return isocode; 3333da084b3Smrg } 3343da084b3Smrg} 3353da084b3Smrg 336e1c0d025Smrgstatic FontMapRec iso8859_9[] = { 337e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, iso8859_9_to_unicode, NULL, NULL, NULL, NULL}, 338e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 3393da084b3Smrg}; 3403da084b3Smrg 341e1c0d025Smrgstatic const unsigned short iso8859_10_tophalf[] = { 342e1c0d025Smrg 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7, 343e1c0d025Smrg 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A, 344e1c0d025Smrg 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7, 345e1c0d025Smrg 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2014, 0x016B, 0x014B, 346e1c0d025Smrg 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, 347e1c0d025Smrg 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF, 348e1c0d025Smrg 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168, 349e1c0d025Smrg 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 350e1c0d025Smrg 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, 351e1c0d025Smrg 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF, 352e1c0d025Smrg 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169, 353e1c0d025Smrg 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138 354e1c0d025Smrg}; 355e1c0d025Smrg 356e1c0d025Smrgstatic FontEncSimpleMapRec iso8859_10_to_unicode_map = 357e1c0d025Smrg { 0x60, 0, 0xA0, iso8859_10_tophalf }; 358e1c0d025Smrg 359e1c0d025Smrgstatic FontMapRec iso8859_10[] = { 360e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, FontEncSimpleRecode, NULL, 361e1c0d025Smrg &iso8859_10_to_unicode_map, NULL, NULL}, 362e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 3633da084b3Smrg}; 3643da084b3Smrg 3653da084b3Smrgstatic unsigned 3663da084b3Smrgiso8859_15_to_unicode(unsigned isocode, void *client_data) 3673da084b3Smrg{ 368e1c0d025Smrg switch (isocode) { 369e1c0d025Smrg case 0xA4: 370e1c0d025Smrg return 0x20AC; 371e1c0d025Smrg case 0xA6: 372e1c0d025Smrg return 0x0160; 373e1c0d025Smrg case 0xA8: 374e1c0d025Smrg return 0x0161; 375e1c0d025Smrg case 0xB4: 376e1c0d025Smrg return 0x017D; 377e1c0d025Smrg case 0xB8: 378e1c0d025Smrg return 0x017E; 379e1c0d025Smrg case 0xBC: 380e1c0d025Smrg return 0x0152; 381e1c0d025Smrg case 0xBD: 382e1c0d025Smrg return 0x0153; 383e1c0d025Smrg case 0xBE: 384e1c0d025Smrg return 0x0178; 385e1c0d025Smrg default: 386e1c0d025Smrg return isocode; 3873da084b3Smrg } 3883da084b3Smrg} 3893da084b3Smrg 390e1c0d025Smrgstatic FontMapRec iso8859_15[] = { 391e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, iso8859_15_to_unicode, NULL, NULL, NULL, 392e1c0d025Smrg NULL}, 393e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 3943da084b3Smrg}; 3953da084b3Smrg 396e1c0d025Smrgstatic const unsigned short koi8_r_tophalf[] = { 397e1c0d025Smrg 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, 398e1c0d025Smrg 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590, 399e1c0d025Smrg 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2022, 0x221A, 0x2248, 400e1c0d025Smrg 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7, 401e1c0d025Smrg 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, 402e1c0d025Smrg 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E, 403e1c0d025Smrg 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, 404e1c0d025Smrg 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9, 405e1c0d025Smrg 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 406e1c0d025Smrg 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 407e1c0d025Smrg 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, 408e1c0d025Smrg 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A, 409e1c0d025Smrg 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 410e1c0d025Smrg 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 411e1c0d025Smrg 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, 412e1c0d025Smrg 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A 413e1c0d025Smrg}; 414e1c0d025Smrg 415e1c0d025Smrgstatic FontEncSimpleMapRec koi8_r_to_unicode_map = 416e1c0d025Smrg { 0x80, 0, 0x80, koi8_r_tophalf }; 417e1c0d025Smrg 418e1c0d025Smrgstatic FontMapRec koi8_r[] = { 419e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, FontEncSimpleRecode, NULL, 420e1c0d025Smrg &koi8_r_to_unicode_map, NULL, NULL}, 421e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 4223da084b3Smrg}; 4233da084b3Smrg 42448c85eb7Smrgstatic unsigned 4253da084b3Smrgkoi8_ru_to_unicode(unsigned koicode, void *client_data) 4263da084b3Smrg{ 427e1c0d025Smrg switch (koicode) { 428e1c0d025Smrg case 0x93: 429e1c0d025Smrg return 0x201C; 430e1c0d025Smrg case 0x96: 431e1c0d025Smrg return 0x201D; 432e1c0d025Smrg case 0x97: 433e1c0d025Smrg return 0x2014; 434e1c0d025Smrg case 0x98: 435e1c0d025Smrg return 0x2116; 436e1c0d025Smrg case 0x99: 437e1c0d025Smrg return 0x2122; 438e1c0d025Smrg case 0x9B: 439e1c0d025Smrg return 0x00BB; 440e1c0d025Smrg case 0x9C: 441e1c0d025Smrg return 0x00AE; 442e1c0d025Smrg case 0x9D: 443e1c0d025Smrg return 0x00AB; 444e1c0d025Smrg case 0x9F: 445e1c0d025Smrg return 0x00A4; 446e1c0d025Smrg case 0xA4: 447e1c0d025Smrg return 0x0454; 448e1c0d025Smrg case 0xA6: 449e1c0d025Smrg return 0x0456; 450e1c0d025Smrg case 0xA7: 451e1c0d025Smrg return 0x0457; 452e1c0d025Smrg case 0xAD: 453e1c0d025Smrg return 0x0491; 454e1c0d025Smrg case 0xAE: 455e1c0d025Smrg return 0x045E; 456e1c0d025Smrg case 0xB4: 457e1c0d025Smrg return 0x0404; 458e1c0d025Smrg case 0xB6: 459e1c0d025Smrg return 0x0406; 460e1c0d025Smrg case 0xB7: 461e1c0d025Smrg return 0x0407; 462e1c0d025Smrg case 0xBD: 463e1c0d025Smrg return 0x0490; 464e1c0d025Smrg case 0xBE: 465e1c0d025Smrg return 0x040E; 466e1c0d025Smrg default: 467e1c0d025Smrg return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); 468e1c0d025Smrg } 4693da084b3Smrg} 4703da084b3Smrg 471e1c0d025Smrgstatic FontMapRec koi8_ru[] = { 472e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, koi8_ru_to_unicode, NULL, NULL, NULL, NULL}, 473e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 4743da084b3Smrg}; 4753da084b3Smrg 4763da084b3Smrg/* koi8-e, ISO-IR-111 or ECMA-Cyrillic */ 4773da084b3Smrg 478e1c0d025Smrgstatic const unsigned short koi8_e_A0_BF[] = { 479e1c0d025Smrg 0x00A0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, 480e1c0d025Smrg 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00AD, 0x045E, 0x045F, 481e1c0d025Smrg 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, 482e1c0d025Smrg 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00A4, 0x040E, 0x040F 483e1c0d025Smrg}; 4843da084b3Smrg 4853da084b3Smrgstatic unsigned 4863da084b3Smrgkoi8_e_to_unicode(unsigned koicode, void *client_data) 4873da084b3Smrg{ 488e1c0d025Smrg if (koicode < 0xA0) 4893da084b3Smrg return koicode; 490e1c0d025Smrg else if (koicode < 0xC0) 491e1c0d025Smrg return koi8_e_A0_BF[koicode - 0xA0]; 49248c85eb7Smrg else 4933da084b3Smrg return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); 4943da084b3Smrg} 4953da084b3Smrg 496e1c0d025Smrgstatic FontMapRec koi8_e[] = { 497e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, koi8_e_to_unicode, NULL, NULL, NULL, NULL}, 498e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 4993da084b3Smrg}; 5003da084b3Smrg 5013da084b3Smrg/* Koi8 unified */ 5023da084b3Smrg 503e1c0d025Smrgstatic const unsigned short koi8_uni_80_BF[] = { 504e1c0d025Smrg 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, 505e1c0d025Smrg 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590, 506e1c0d025Smrg 0x2591, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 507e1c0d025Smrg 0x00A9, 0x2122, 0x00A0, 0x00BB, 0x00AE, 0x00AB, 0x00B7, 0x00A4, 508e1c0d025Smrg 0x00A0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, 509e1c0d025Smrg 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x0491, 0x045E, 0x045F, 510e1c0d025Smrg 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, 511e1c0d025Smrg 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x0490, 0x040E, 0x040F 512e1c0d025Smrg}; 5133da084b3Smrg 51448c85eb7Smrgstatic unsigned 5153da084b3Smrgkoi8_uni_to_unicode(unsigned koicode, void *client_data) 5163da084b3Smrg{ 517e1c0d025Smrg if (koicode < 0x80) 5183da084b3Smrg return koicode; 519e1c0d025Smrg else if (koicode < 0xC0) 520e1c0d025Smrg return koi8_uni_80_BF[koicode - 0x80]; 5213da084b3Smrg else 5223da084b3Smrg return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); 5233da084b3Smrg} 5243da084b3Smrg 525e1c0d025Smrgstatic FontMapRec koi8_uni[] = { 526e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, koi8_uni_to_unicode, NULL, NULL, NULL, NULL}, 527e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 5283da084b3Smrg}; 5293da084b3Smrg 5303da084b3Smrg/* Ukrainian variant of Koi8-R; see RFC 2319 */ 5313da084b3Smrg 53248c85eb7Smrgstatic unsigned 5333da084b3Smrgkoi8_u_to_unicode(unsigned koicode, void *client_data) 5343da084b3Smrg{ 535e1c0d025Smrg switch (koicode) { 536e1c0d025Smrg case 0xA4: 537e1c0d025Smrg return 0x0454; 538e1c0d025Smrg case 0xA6: 539e1c0d025Smrg return 0x0456; 540e1c0d025Smrg case 0xA7: 541e1c0d025Smrg return 0x0457; 542e1c0d025Smrg case 0xAD: 543e1c0d025Smrg return 0x0491; 544e1c0d025Smrg case 0xB4: 545e1c0d025Smrg return 0x0404; 546e1c0d025Smrg case 0xB6: 547e1c0d025Smrg return 0x0406; 548e1c0d025Smrg case 0xB7: 549e1c0d025Smrg return 0x0407; 550e1c0d025Smrg case 0xBD: 551e1c0d025Smrg return 0x0490; 552e1c0d025Smrg default: 553e1c0d025Smrg return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); 5543da084b3Smrg } 5553da084b3Smrg} 5563da084b3Smrg 557e1c0d025Smrgstatic FontMapRec koi8_u[] = { 558e1c0d025Smrg {FONT_ENCODING_UNICODE, 0, 0, koi8_u_to_unicode, NULL, NULL, NULL}, 559e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 5603da084b3Smrg}; 5613da084b3Smrg 5623da084b3Smrg/* Microsoft Symbol, which is only meaningful for TrueType fonts, is 5633da084b3Smrg treated specially in ftenc.c, where we add usFirstCharIndex-0x20 to 5643da084b3Smrg the glyph index before applying the cmap. Lovely design. */ 5653da084b3Smrg 566e1c0d025Smrgstatic FontMapRec microsoft_symbol[] = { 567e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 3, 0, NULL, NULL, NULL, NULL, NULL}, 568e1c0d025Smrg /* You never know */ 569e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 3, 1, NULL, NULL, NULL, NULL, NULL}, 570e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 571e1c0d025Smrg}; 5723da084b3Smrg 573e1c0d025Smrgstatic FontMapRec apple_roman[] = { 574e1c0d025Smrg {FONT_ENCODING_TRUETYPE, 1, 0, NULL, NULL, NULL, NULL, NULL}, 575e1c0d025Smrg {0, 0, 0, NULL, NULL, NULL, NULL, NULL} 576e1c0d025Smrg}; 5773da084b3Smrg 5783da084b3Smrg/* The data for recodings */ 5793da084b3Smrg 5803da084b3Smrg/* For compatibility with X11R6.4. Losers. */ 581e1c0d025Smrgstatic char *iso8859_15_aliases[2] = { "fcd8859-15", NULL }; 582e1c0d025Smrg 583e1c0d025Smrgstatic FontEncRec initial_encodings[] = { 584e1c0d025Smrg {"iso10646-1", NULL, 256 * 256, 0, iso10646, NULL, 0, 0}, /* Unicode */ 585e1c0d025Smrg {"iso8859-1", NULL, 256, 0, iso8859_1, NULL, 0, 0}, /* Latin 1 (West European) */ 586e1c0d025Smrg {"iso8859-2", NULL, 256, 0, iso8859_2, NULL, 0, 0}, /* Latin 2 (East European) */ 587e1c0d025Smrg {"iso8859-3", NULL, 256, 0, iso8859_3, NULL, 0, 0}, /* Latin 3 (South European) */ 588e1c0d025Smrg {"iso8859-4", NULL, 256, 0, iso8859_4, NULL, 0, 0}, /* Latin 4 (North European) */ 589e1c0d025Smrg {"iso8859-5", NULL, 256, 0, iso8859_5, NULL, 0, 0}, /* Cyrillic */ 590e1c0d025Smrg {"iso8859-6", NULL, 256, 0, iso8859_6, NULL, 0, 0}, /* Arabic */ 591e1c0d025Smrg {"iso8859-7", NULL, 256, 0, iso8859_7, NULL, 0, 0}, /* Greek */ 592e1c0d025Smrg {"iso8859-8", NULL, 256, 0, iso8859_8, NULL, 0, 0}, /* Hebrew */ 593e1c0d025Smrg {"iso8859-9", NULL, 256, 0, iso8859_9, NULL, 0, 0}, /* Latin 5 (Turkish) */ 594e1c0d025Smrg {"iso8859-10", NULL, 256, 0, iso8859_10, NULL, 0, 0}, /* Latin 6 (Nordic) */ 595e1c0d025Smrg {"iso8859-15", iso8859_15_aliases, 256, 0, iso8859_15, NULL, 0, 0}, /* Latin 9 */ 596e1c0d025Smrg {"koi8-r", NULL, 256, 0, koi8_r, NULL, 0, 0}, /* Russian */ 597e1c0d025Smrg {"koi8-ru", NULL, 256, 0, koi8_ru, NULL, 0, 0}, /* Ukrainian */ 598e1c0d025Smrg {"koi8-uni", NULL, 256, 0, koi8_uni, NULL, 0, 0}, /* Russian/Ukrainian/Bielorussian */ 599e1c0d025Smrg {"koi8-e", NULL, 256, 0, koi8_e, NULL, 0, 0}, /* ``European'' */ 600e1c0d025Smrg {"koi8-u", NULL, 256, 0, koi8_u, NULL, 0, 0}, /* Ukrainian too */ 601e1c0d025Smrg {"microsoft-symbol", NULL, 256, 0, microsoft_symbol, NULL, 0, 0}, 602e1c0d025Smrg {"apple-roman", NULL, 256, 0, apple_roman, NULL, 0, 0}, 603e1c0d025Smrg {NULL, NULL, 0, 0, NULL, NULL, 0, 0} 6043da084b3Smrg}; 6053da084b3Smrg 606e1c0d025Smrgstatic FontEncPtr font_encodings = NULL; 6073da084b3Smrg 6083da084b3Smrgstatic void 6093da084b3Smrgdefine_initial_encoding_info(void) 6103da084b3Smrg{ 6113da084b3Smrg FontEncPtr encoding; 6123da084b3Smrg FontMapPtr mapping; 6133da084b3Smrg 6143da084b3Smrg font_encodings = initial_encodings; 615e1c0d025Smrg for (encoding = font_encodings; ; encoding++) { 6163da084b3Smrg encoding->next = encoding + 1; 617e1c0d025Smrg for (mapping = encoding->mappings; ; mapping++) { 618e1c0d025Smrg mapping->next = mapping + 1; 6193da084b3Smrg mapping->encoding = encoding; 620e1c0d025Smrg if (mapping->next->type == 0) { 6213da084b3Smrg mapping->next = NULL; 6223da084b3Smrg break; 6233da084b3Smrg } 6243da084b3Smrg } 625e1c0d025Smrg if (!encoding->next->name) { 6263da084b3Smrg encoding->next = NULL; 6273da084b3Smrg break; 6283da084b3Smrg } 6293da084b3Smrg } 6303da084b3Smrg} 6313da084b3Smrg 632e1c0d025Smrgchar * 6333da084b3SmrgFontEncFromXLFD(const char *name, int length) 6343da084b3Smrg{ 6353da084b3Smrg const char *p; 6363da084b3Smrg char *q; 6373da084b3Smrg static char charset[MAXFONTNAMELEN]; 6383da084b3Smrg int len; 6393da084b3Smrg 640e1c0d025Smrg if (length > MAXFONTNAMELEN - 1) 6413da084b3Smrg return NULL; 6423da084b3Smrg 643e1c0d025Smrg if (name == NULL) 6443da084b3Smrg p = NULL; 6453da084b3Smrg else { 6463da084b3Smrg p = name + length - 1; 647e1c0d025Smrg while (p > name && *p != '-') 6483da084b3Smrg p--; 6493da084b3Smrg p--; 650e1c0d025Smrg while (p >= name && *p != '-') 6513da084b3Smrg p--; 652e1c0d025Smrg if (p <= name) 6533da084b3Smrg p = NULL; 6543da084b3Smrg } 6553da084b3Smrg 6563da084b3Smrg /* now p either is null or points at the '-' before the charset registry */ 657d63fdb69Smrg 658e1c0d025Smrg if (p == NULL) 6593da084b3Smrg return NULL; 66048c85eb7Smrg 6613da084b3Smrg len = length - (p - name) - 1; 662e1c0d025Smrg memcpy(charset, p + 1, len); 6633da084b3Smrg charset[len] = 0; 66448c85eb7Smrg 6653da084b3Smrg /* check for a subset specification */ 666e1c0d025Smrg if ((q = strchr(charset, (int) '['))) 6673da084b3Smrg *q = 0; 66848c85eb7Smrg 6693da084b3Smrg return charset; 6703da084b3Smrg} 6713da084b3Smrg 6723da084b3Smrgunsigned 673e1c0d025SmrgFontEncRecode(unsigned code, FontMapPtr mapping) 6743da084b3Smrg{ 6753da084b3Smrg FontEncPtr encoding = mapping->encoding; 676e1c0d025Smrg 677e1c0d025Smrg if (encoding && mapping->recode) { 678e1c0d025Smrg if (encoding->row_size == 0) { 6793da084b3Smrg /* linear encoding */ 680e1c0d025Smrg if (code < encoding->first || code >= encoding->size) 6813da084b3Smrg return 0; 682e1c0d025Smrg } 683e1c0d025Smrg else { 6843da084b3Smrg /* matrix encoding */ 685e1c0d025Smrg int row = code / 0x100, col = code & 0xFF; 686e1c0d025Smrg 687e1c0d025Smrg if (row < encoding->first || row >= encoding->size || 688e1c0d025Smrg col < encoding->first_col || col >= encoding->row_size) 6893da084b3Smrg return 0; 6903da084b3Smrg } 691e1c0d025Smrg return (*mapping->recode) (code, mapping->client_data); 692e1c0d025Smrg } 693e1c0d025Smrg else 6943da084b3Smrg return code; 6953da084b3Smrg} 6963da084b3Smrg 697e1c0d025Smrgchar * 6983da084b3SmrgFontEncName(unsigned code, FontMapPtr mapping) 6993da084b3Smrg{ 7003da084b3Smrg FontEncPtr encoding = mapping->encoding; 701e1c0d025Smrg 702e1c0d025Smrg if (encoding && mapping->name) { 703e1c0d025Smrg if ((encoding->row_size == 0 && code >= encoding->size) || 704e1c0d025Smrg (encoding->row_size != 0 && 705e1c0d025Smrg (code / 0x100 >= encoding->size || 706e1c0d025Smrg (code & 0xFF) >= encoding->row_size))) 7073da084b3Smrg return NULL; 708e1c0d025Smrg return (*mapping->name) (code, mapping->client_data); 709e1c0d025Smrg } 710e1c0d025Smrg else 7113da084b3Smrg return NULL; 7123da084b3Smrg} 7133da084b3Smrg 7143da084b3SmrgFontEncPtr 7153da084b3SmrgFontEncFind(const char *encoding_name, const char *filename) 7163da084b3Smrg{ 7173da084b3Smrg FontEncPtr encoding; 7183da084b3Smrg char **alias; 71948c85eb7Smrg 720e1c0d025Smrg if (font_encodings == NULL) 721e1c0d025Smrg define_initial_encoding_info(); 72248c85eb7Smrg 723e1c0d025Smrg for (encoding = font_encodings; encoding; encoding = encoding->next) { 724e1c0d025Smrg if (!strcasecmp(encoding->name, encoding_name)) 7253da084b3Smrg return encoding; 726e1c0d025Smrg if (encoding->aliases) 727e1c0d025Smrg for (alias = encoding->aliases; *alias; alias++) 728e1c0d025Smrg if (!strcasecmp(*alias, encoding_name)) 7293da084b3Smrg return encoding; 730e1c0d025Smrg } 7313da084b3Smrg 732e1c0d025Smrg /* Unknown charset, try to load a definition file */ 7333da084b3Smrg return FontEncLoad(encoding_name, filename); 7343da084b3Smrg} 7353da084b3Smrg 7363da084b3SmrgFontMapPtr 7373da084b3SmrgFontMapFind(FontEncPtr encoding, int type, int pid, int eid) 7383da084b3Smrg{ 7393da084b3Smrg FontMapPtr mapping; 740e1c0d025Smrg 741e1c0d025Smrg if (encoding == NULL) 7423da084b3Smrg return NULL; 7433da084b3Smrg 744e1c0d025Smrg for (mapping = encoding->mappings; mapping; mapping = mapping->next) { 745e1c0d025Smrg if (mapping->type != type) 7463da084b3Smrg continue; 747e1c0d025Smrg if (pid > 0 && mapping->pid != pid) 7483da084b3Smrg continue; 749e1c0d025Smrg if (eid > 0 && mapping->eid != eid) 7503da084b3Smrg continue; 7513da084b3Smrg return mapping; 7523da084b3Smrg } 7533da084b3Smrg return NULL; 7543da084b3Smrg} 7553da084b3Smrg 7563da084b3SmrgFontMapPtr 7573da084b3SmrgFontEncMapFind(const char *encoding_name, int type, int pid, int eid, 7583da084b3Smrg const char *filename) 7593da084b3Smrg{ 7603da084b3Smrg FontEncPtr encoding; 7613da084b3Smrg FontMapPtr mapping; 7623da084b3Smrg 7633da084b3Smrg encoding = FontEncFind(encoding_name, filename); 764e1c0d025Smrg if (encoding == NULL) 7653da084b3Smrg return NULL; 7663da084b3Smrg mapping = FontMapFind(encoding, type, pid, eid); 7673da084b3Smrg return mapping; 7683da084b3Smrg} 7693da084b3Smrg 7703da084b3Smrgstatic FontEncPtr 7713da084b3SmrgFontEncLoad(const char *encoding_name, const char *filename) 7723da084b3Smrg{ 7733da084b3Smrg FontEncPtr encoding; 77448c85eb7Smrg 7753da084b3Smrg encoding = FontEncReallyLoad(encoding_name, filename); 7763da084b3Smrg if (encoding == NULL) { 7773da084b3Smrg return NULL; 778e1c0d025Smrg } 779e1c0d025Smrg else { 7803da084b3Smrg char **alias; 7813da084b3Smrg int found = 0; 78248c85eb7Smrg 7833da084b3Smrg /* Check whether the name is already known for this encoding */ 784e1c0d025Smrg if (strcasecmp(encoding->name, encoding_name) == 0) { 7853da084b3Smrg found = 1; 786e1c0d025Smrg } 787e1c0d025Smrg else { 788e1c0d025Smrg if (encoding->aliases) { 789e1c0d025Smrg for (alias = encoding->aliases; *alias; alias++) 790e1c0d025Smrg if (!strcasecmp(*alias, encoding_name)) { 7913da084b3Smrg found = 1; 7923da084b3Smrg break; 7933da084b3Smrg } 7943da084b3Smrg } 7953da084b3Smrg } 79648c85eb7Smrg 797e1c0d025Smrg if (!found) { 7983da084b3Smrg /* Add a new alias. This works because we know that this 7993da084b3Smrg particular encoding has been allocated dynamically */ 8003da084b3Smrg char **new_aliases; 8013da084b3Smrg char *new_name; 8023da084b3Smrg int numaliases = 0; 80348c85eb7Smrg 80455acc8fcSmrg new_name = strdup(encoding_name); 805e1c0d025Smrg if (new_name == NULL) 8063da084b3Smrg return NULL; 807e1c0d025Smrg if (encoding->aliases) { 808e1c0d025Smrg for (alias = encoding->aliases; *alias; alias++) 8093da084b3Smrg numaliases++; 8103da084b3Smrg } 811e1c0d025Smrg new_aliases = malloc((numaliases + 2) * sizeof(char *)); 812e1c0d025Smrg if (new_aliases == NULL) { 81355acc8fcSmrg free(new_name); 8143da084b3Smrg return NULL; 8153da084b3Smrg } 816e1c0d025Smrg if (encoding->aliases) { 817e1c0d025Smrg memcpy(new_aliases, encoding->aliases, 818e1c0d025Smrg numaliases * sizeof(char *)); 81955acc8fcSmrg free(encoding->aliases); 8203da084b3Smrg } 8213da084b3Smrg new_aliases[numaliases] = new_name; 822e1c0d025Smrg new_aliases[numaliases + 1] = NULL; 8233da084b3Smrg encoding->aliases = new_aliases; 8243da084b3Smrg } 82548c85eb7Smrg 8263da084b3Smrg /* register the new encoding */ 827e1c0d025Smrg encoding->next = font_encodings; 828e1c0d025Smrg font_encodings = encoding; 82948c85eb7Smrg 8303da084b3Smrg return encoding; 8313da084b3Smrg } 8323da084b3Smrg} 8333da084b3Smrg 8343da084b3Smrgunsigned 8353da084b3SmrgFontEncSimpleRecode(unsigned code, void *client_data) 8363da084b3Smrg{ 8373da084b3Smrg FontEncSimpleMapPtr map; 8383da084b3Smrg unsigned index; 8393da084b3Smrg 8403da084b3Smrg map = client_data; 8413da084b3Smrg 842e1c0d025Smrg if (code > 0xFFFF || (map->row_size && (code & 0xFF) >= map->row_size)) 8433da084b3Smrg return 0; 8443da084b3Smrg 845e1c0d025Smrg if (map->row_size) 846e1c0d025Smrg index = (code & 0xFF) + (code >> 8) * map->row_size; 8473da084b3Smrg else 8483da084b3Smrg index = code; 8493da084b3Smrg 850e1c0d025Smrg if (map->map && index >= map->first && index < map->first + map->len) 851e1c0d025Smrg return map->map[index - map->first]; 852e1c0d025Smrg else 853e1c0d025Smrg return code; 8543da084b3Smrg} 8553da084b3Smrg 8563da084b3Smrgchar * 8573da084b3SmrgFontEncSimpleName(unsigned code, void *client_data) 8583da084b3Smrg{ 8593da084b3Smrg FontEncSimpleNamePtr map; 8603da084b3Smrg 8613da084b3Smrg map = client_data; 862e1c0d025Smrg if (map && code >= map->first && code < map->first + map->len) 863e1c0d025Smrg return map->map[code - map->first]; 8643da084b3Smrg else 8653da084b3Smrg return NULL; 8663da084b3Smrg} 8673da084b3Smrg 8683da084b3Smrgunsigned 8693da084b3SmrgFontEncUndefinedRecode(unsigned code, void *client_data) 8703da084b3Smrg{ 8713da084b3Smrg return code; 8723da084b3Smrg} 8733da084b3Smrg 8743da084b3Smrgchar * 8753da084b3SmrgFontEncUndefinedName(unsigned code, void *client_data) 8763da084b3Smrg{ 8773da084b3Smrg return NULL; 8783da084b3Smrg} 8793da084b3Smrg 8803da084b3Smrg#define FONTENC_SEGMENT_SIZE 256 8813da084b3Smrg#define FONTENC_SEGMENTS 256 8823da084b3Smrg#define FONTENC_INVERSE_CODES (FONTENC_SEGMENT_SIZE * FONTENC_SEGMENTS) 8833da084b3Smrg 8843da084b3Smrgstatic unsigned int 885e1c0d025Smrgreverse_reverse(unsigned i, void *data) 8863da084b3Smrg{ 8873da084b3Smrg int s, j; 888e1c0d025Smrg unsigned **map = (unsigned **) data; 8893da084b3Smrg 890e1c0d025Smrg if (i >= FONTENC_INVERSE_CODES) 8913da084b3Smrg return 0; 8923da084b3Smrg 893e1c0d025Smrg if (map == NULL) 8943da084b3Smrg return 0; 8953da084b3Smrg 8963da084b3Smrg s = i / FONTENC_SEGMENT_SIZE; 8973da084b3Smrg j = i % FONTENC_SEGMENT_SIZE; 8983da084b3Smrg 899e1c0d025Smrg if (map[s] == NULL) 9003da084b3Smrg return 0; 9013da084b3Smrg else 9023da084b3Smrg return map[s][j]; 9033da084b3Smrg} 9043da084b3Smrg 9053da084b3Smrgstatic int 9063da084b3Smrgtree_set(unsigned int **map, unsigned int i, unsigned int j) 9073da084b3Smrg{ 9083da084b3Smrg int s, c; 9093da084b3Smrg 910e1c0d025Smrg if (i >= FONTENC_INVERSE_CODES) 9113da084b3Smrg return FALSE; 9123da084b3Smrg 9133da084b3Smrg s = i / FONTENC_SEGMENT_SIZE; 9143da084b3Smrg c = i % FONTENC_SEGMENT_SIZE; 9153da084b3Smrg 916e1c0d025Smrg if (map[s] == NULL) { 91748c85eb7Smrg map[s] = calloc(FONTENC_SEGMENT_SIZE, sizeof(int)); 918e1c0d025Smrg if (map[s] == NULL) 9193da084b3Smrg return FALSE; 920e1c0d025Smrg } 9213da084b3Smrg 9223da084b3Smrg map[s][c] = j; 9233da084b3Smrg return TRUE; 9243da084b3Smrg} 9253da084b3Smrg 9263da084b3SmrgFontMapReversePtr 9273da084b3SmrgFontMapReverse(FontMapPtr mapping) 9283da084b3Smrg{ 9293da084b3Smrg FontEncPtr encoding = mapping->encoding; 9303da084b3Smrg FontMapReversePtr reverse = NULL; 9313da084b3Smrg unsigned int **map = NULL; 9323da084b3Smrg int i, j, k; 9333da084b3Smrg 934e1c0d025Smrg if (encoding == NULL) 935e1c0d025Smrg goto bail; 9363da084b3Smrg 937e1c0d025Smrg map = calloc(FONTENC_SEGMENTS, sizeof(int *)); 938e1c0d025Smrg if (map == NULL) 939e1c0d025Smrg goto bail; 9403da084b3Smrg 941e1c0d025Smrg if (encoding->row_size == 0) { 942e1c0d025Smrg for (i = encoding->first; i < encoding->size; i++) { 9433da084b3Smrg k = FontEncRecode(i, mapping); 944e1c0d025Smrg if (k != 0) 945e1c0d025Smrg if (!tree_set(map, k, i)) 9463da084b3Smrg goto bail; 9473da084b3Smrg } 948e1c0d025Smrg } 949e1c0d025Smrg else { 950e1c0d025Smrg for (i = encoding->first; i < encoding->size; i++) { 951e1c0d025Smrg for (j = encoding->first_col; j < encoding->row_size; j++) { 952e1c0d025Smrg k = FontEncRecode(i * 256 + j, mapping); 953e1c0d025Smrg if (k != 0) 954e1c0d025Smrg if (!tree_set(map, k, i * 256 + j)) 9553da084b3Smrg goto bail; 9563da084b3Smrg } 9573da084b3Smrg } 9583da084b3Smrg } 9593da084b3Smrg 9603da084b3Smrg reverse = malloc(sizeof(FontMapReverseRec)); 961e1c0d025Smrg if (!reverse) 962e1c0d025Smrg goto bail; 9633da084b3Smrg 9643da084b3Smrg reverse->reverse = reverse_reverse; 9653da084b3Smrg reverse->data = map; 9663da084b3Smrg return reverse; 9673da084b3Smrg 968e1c0d025Smrg bail: 96955acc8fcSmrg free(map); 97055acc8fcSmrg free(reverse); 9713da084b3Smrg return NULL; 9723da084b3Smrg} 9733da084b3Smrg 9743da084b3Smrgvoid 9753da084b3SmrgFontMapReverseFree(FontMapReversePtr delendum) 9763da084b3Smrg{ 977e1c0d025Smrg unsigned int **map = (unsigned int **) delendum; 9783da084b3Smrg int i; 97948c85eb7Smrg 980e1c0d025Smrg if (map == NULL) 9813da084b3Smrg return; 9823da084b3Smrg 983e1c0d025Smrg for (i = 0; i < FONTENC_SEGMENTS; i++) 984e1c0d025Smrg free(map[i]); 9853da084b3Smrg 98655acc8fcSmrg free(map); 9873da084b3Smrg return; 9883da084b3Smrg} 989