fontenc.c revision 55acc8fc
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
273da084b3Smrg#if defined(__SCO__) || defined(__UNIXWARE__)
283da084b3Smrg#include <strings.h>
293da084b3Smrg#endif
303da084b3Smrg
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"
403da084b3Smrg
413da084b3Smrg/* Functions local to this file */
423da084b3Smrg
433da084b3Smrgstatic FontEncPtr FontEncLoad(const char*, const char*);
443da084b3Smrg
453da084b3Smrg/* Early versions of this code only knew about hardwired encodings,
463da084b3Smrg   hence the following data.  Now that the code knows how to load an
473da084b3Smrg   encoding from a file, most of these tables could go away. */
483da084b3Smrg
493da084b3Smrg/* At any rate, no new hardcoded encodings will be added. */
503da084b3Smrg
513da084b3Smrgstatic FontMapRec iso10646[]=
523da084b3Smrg{
533da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,NULL,NULL,NULL,NULL,NULL},
543da084b3Smrg    {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
623da084b3Smrgstatic const unsigned short
633da084b3Smrgiso8859_1_apple_roman[]=
643da084b3Smrg{ 0xCA, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4, 0x00, 0xA4,
653da084b3Smrg  0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0x00, 0xA8, 0xF8,
663da084b3Smrg  0xA1, 0xB1, 0x00, 0x00, 0xAB, 0xB5, 0xA6, 0xE1,
673da084b3Smrg  0xFC, 0x00, 0xBC, 0xC8, 0x00, 0x00, 0x00, 0xC0,
683da084b3Smrg  0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82,
693da084b3Smrg  0xE9, 0x83, 0xE6, 0xE8, 0xED, 0xEA, 0xEB, 0xEC,
703da084b3Smrg  0x00, 0x84, 0xF1, 0xEE, 0xEF, 0xCD, 0x85, 0x00,
713da084b3Smrg  0xAF, 0xF4, 0xF2, 0xF3, 0x86, 0x00, 0x00, 0xA7,
723da084b3Smrg  0x88, 0x87, 0x89, 0x8B, 0x8A, 0x8C, 0xBE, 0x8D,
733da084b3Smrg  0x8F, 0x8E, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95,
743da084b3Smrg  0x00, 0x96, 0x98, 0x97, 0x99, 0x9B, 0x9A, 0xD6,
753da084b3Smrg  0xBF, 0x9D, 0x9C, 0x9E, 0x9F, 0x00, 0x00, 0xD8 };
763da084b3Smrg
773da084b3Smrg/* Cannot use simple_recode because need to eliminate 0x80<=code<0xA0 */
783da084b3Smrgstatic unsigned
793da084b3Smrgiso8859_1_to_apple_roman(unsigned isocode, void *client_data)
803da084b3Smrg{
813da084b3Smrg    if(isocode<=0x80)
823da084b3Smrg        return isocode;
833da084b3Smrg    else if(isocode>=0xA0)
843da084b3Smrg        return iso8859_1_apple_roman[isocode-0xA0];
853da084b3Smrg    else
863da084b3Smrg        return 0;
873da084b3Smrg}
883da084b3Smrg
893da084b3Smrgstatic FontMapRec iso8859_1[]=
903da084b3Smrg{
913da084b3Smrg    {FONT_ENCODING_TRUETYPE,2,2,NULL,NULL,NULL,NULL,NULL}, /* ISO 8859-1 */
923da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,NULL,NULL,NULL,NULL,NULL}, /* ISO 8859-1 coincides with Unicode*/
933da084b3Smrg    {FONT_ENCODING_TRUETYPE,1,0,iso8859_1_to_apple_roman,NULL,NULL,NULL,NULL},
943da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
953da084b3Smrg};
963da084b3Smrg
973da084b3Smrgstatic const unsigned short iso8859_2_tophalf[]=
983da084b3Smrg{ 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
993da084b3Smrg  0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
1003da084b3Smrg  0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
1013da084b3Smrg  0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
1023da084b3Smrg  0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
1033da084b3Smrg  0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
1043da084b3Smrg  0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
1053da084b3Smrg  0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
1063da084b3Smrg  0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
1073da084b3Smrg  0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
1083da084b3Smrg  0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
1093da084b3Smrg  0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 };
1103da084b3Smrg
1113da084b3Smrgstatic FontEncSimpleMapRec iso8859_2_to_unicode_map=
1123da084b3Smrg{0x60, 0, 0xA0, iso8859_2_tophalf };
1133da084b3Smrg
1143da084b3Smrgstatic const unsigned short iso8859_2_apple_centeuro[]=
1153da084b3Smrg{ 0xCA, 0x84, 0x00, 0xFC, 0x00, 0xBB, 0xE5, 0xA4,
1163da084b3Smrg  0xAC, 0xE1, 0x00, 0xE8, 0x8F, 0x00, 0xEB, 0xFB,
1173da084b3Smrg  0xA1, 0x88, 0x00, 0xB8, 0x00, 0xBC, 0xE6, 0xFF,
1183da084b3Smrg  0x00, 0xE4, 0x00, 0xE9, 0x90, 0x00, 0xEC, 0xFD,
1193da084b3Smrg  0xD9, 0xE7, 0x00, 0x00, 0x80, 0xBD, 0x8C, 0x00,
1203da084b3Smrg  0x89, 0x83, 0xA2, 0x00, 0x9D, 0xEA, 0x00, 0x91,
1213da084b3Smrg  0x00, 0xC1, 0xC5, 0xEE, 0xEF, 0xCC, 0x85, 0x00,
1223da084b3Smrg  0xDB, 0xF1, 0xF2, 0xF4, 0x86, 0xF8, 0x00, 0xA7,
1233da084b3Smrg  0xDA, 0x87, 0x00, 0x00, 0x8A, 0xBE, 0x8D, 0x00,
1243da084b3Smrg  0x8B, 0x8E, 0xAB, 0x00, 0x9E, 0x92, 0x00, 0x93,
1253da084b3Smrg  0x00, 0xC4, 0xCB, 0x97, 0x99, 0xCE, 0x9A, 0xD6,
1263da084b3Smrg  0xDE, 0xF3, 0x9C, 0xF5, 0x9F, 0xF9, 0x00, 0x00 };
1273da084b3Smrg
1283da084b3Smrgstatic unsigned
1293da084b3Smrgiso8859_2_to_apple_centeuro(unsigned isocode, void *client_data)
1303da084b3Smrg{
1313da084b3Smrg    if(isocode<=0x80)
1323da084b3Smrg        return isocode;
1333da084b3Smrg    else if(isocode>=0xA0)
1343da084b3Smrg        return iso8859_2_apple_centeuro[isocode-0xA0];
1353da084b3Smrg    else
1363da084b3Smrg        return 0;
1373da084b3Smrg}
1383da084b3Smrg
1393da084b3Smrg
1403da084b3Smrgstatic FontMapRec iso8859_2[]=
1413da084b3Smrg{
1423da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,
1433da084b3Smrg     FontEncSimpleRecode,NULL,&iso8859_2_to_unicode_map,NULL,NULL},
1443da084b3Smrg    {FONT_ENCODING_TRUETYPE,1,29,iso8859_2_to_apple_centeuro,NULL,NULL,NULL,NULL},
1453da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
1463da084b3Smrg};
1473da084b3Smrg
1483da084b3Smrgstatic const unsigned short iso8859_3_tophalf[]=
1493da084b3Smrg{ 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0x0000, 0x0124, 0x00A7,
1503da084b3Smrg  0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0x0000, 0x017B,
1513da084b3Smrg  0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7,
1523da084b3Smrg  0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0x0000, 0x017C,
1533da084b3Smrg  0x00C0, 0x00C1, 0x00C2, 0x0000, 0x00C4, 0x010A, 0x0108, 0x00C7,
1543da084b3Smrg  0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
1553da084b3Smrg  0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7,
1563da084b3Smrg  0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF,
1573da084b3Smrg  0x00E0, 0x00E1, 0x00E2, 0x0000, 0x00E4, 0x010B, 0x0109, 0x00E7,
1583da084b3Smrg  0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
1593da084b3Smrg  0x0000, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7,
1603da084b3Smrg  0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9};
1613da084b3Smrg
1623da084b3Smrgstatic FontEncSimpleMapRec iso8859_3_to_unicode_map=
1633da084b3Smrg{ 0x60, 0, 0xA0, iso8859_3_tophalf };
1643da084b3Smrg
1653da084b3Smrgstatic FontMapRec iso8859_3[]=
1663da084b3Smrg{
1673da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,
1683da084b3Smrg     FontEncSimpleRecode,NULL,&iso8859_3_to_unicode_map,NULL,NULL},
1693da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
1703da084b3Smrg};
1713da084b3Smrg
1723da084b3Smrg
1733da084b3Smrgstatic const unsigned short iso8859_4_tophalf[]=
1743da084b3Smrg{ 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7,
1753da084b3Smrg  0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF,
1763da084b3Smrg  0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7,
1773da084b3Smrg  0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B,
1783da084b3Smrg  0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
1793da084b3Smrg  0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A,
1803da084b3Smrg  0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
1813da084b3Smrg  0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF,
1823da084b3Smrg  0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
1833da084b3Smrg  0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B,
1843da084b3Smrg  0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
1853da084b3Smrg  0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9,
1863da084b3Smrg};
1873da084b3Smrg
1883da084b3Smrgstatic FontEncSimpleMapRec iso8859_4_to_unicode_map=
1893da084b3Smrg{ 0x60, 0, 0xA0, iso8859_4_tophalf };
1903da084b3Smrg
1913da084b3Smrgstatic FontMapRec iso8859_4[]=
1923da084b3Smrg{
1933da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,NULL,
1943da084b3Smrg     &iso8859_4_to_unicode_map,NULL,NULL},
1953da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
1963da084b3Smrg};
1973da084b3Smrg
1983da084b3Smrgstatic const unsigned short iso8859_5_tophalf[]=
1993da084b3Smrg{ 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
2003da084b3Smrg  0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F,
2013da084b3Smrg  0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
2023da084b3Smrg  0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
2033da084b3Smrg  0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
2043da084b3Smrg  0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
2053da084b3Smrg  0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
2063da084b3Smrg  0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
2073da084b3Smrg  0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
2083da084b3Smrg  0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
2093da084b3Smrg  0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
2103da084b3Smrg  0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F};
2113da084b3Smrg
2123da084b3Smrgstatic FontEncSimpleMapRec iso8859_5_to_unicode_map=
2133da084b3Smrg{ 0x60, 0, 0xA0, iso8859_5_tophalf };
2143da084b3Smrg
2153da084b3Smrgstatic const unsigned short
2163da084b3Smrgiso8859_5_apple_cyrillic[]=
2173da084b3Smrg{ 0xCA, 0xDD, 0xAB, 0xAE, 0xB8, 0xC1, 0xA7, 0xBA,
2183da084b3Smrg  0xB7, 0xBC, 0xBE, 0xCB, 0xCD, 0x00, 0xD8, 0xDA,
2193da084b3Smrg  0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
2203da084b3Smrg  0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
2213da084b3Smrg  0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
2223da084b3Smrg  0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
2233da084b3Smrg  0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
2243da084b3Smrg  0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
2253da084b3Smrg  0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
2263da084b3Smrg  0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xDF,
2273da084b3Smrg  0xDC, 0xDE, 0xAC, 0xAF, 0xB9, 0xCF, 0xB4, 0xBB,
2283da084b3Smrg  0xC0, 0xBD, 0xBF, 0xCC, 0xCE, 0xA4, 0xD9, 0xDB };
2293da084b3Smrg
2303da084b3Smrgstatic unsigned
2313da084b3Smrgiso8859_5_to_apple_cyrillic(unsigned isocode, void *client_data)
2323da084b3Smrg{
2333da084b3Smrg    if(isocode<=0x80)
2343da084b3Smrg        return isocode;
2353da084b3Smrg    else if(isocode>=0xA0)
2363da084b3Smrg        return iso8859_5_apple_cyrillic[isocode-0x80];
2373da084b3Smrg    else return 0;
2383da084b3Smrg}
2393da084b3Smrg
2403da084b3Smrgstatic FontMapRec iso8859_5[]=
2413da084b3Smrg{
2423da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,NULL,
2433da084b3Smrg     &iso8859_5_to_unicode_map,NULL,NULL},
2443da084b3Smrg    {FONT_ENCODING_TRUETYPE,1,7,iso8859_5_to_apple_cyrillic,NULL,NULL,NULL,NULL},
2453da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
2463da084b3Smrg};
2473da084b3Smrg
2483da084b3Smrg/* ISO 8859-6 seems useless for serving fonts (not enough presentation
2493da084b3Smrg * forms).  What do Arabic-speakers use? */
2503da084b3Smrg
2513da084b3Smrgstatic unsigned
2523da084b3Smrgiso8859_6_to_unicode(unsigned isocode, void *client_data)
2533da084b3Smrg{
2543da084b3Smrg    if(isocode<=0xA0 || isocode==0xA4 || isocode==0xAD)
2553da084b3Smrg        return isocode;
2563da084b3Smrg    else if(isocode==0xAC || isocode==0xBB ||
2573da084b3Smrg            (isocode>=0xBF && isocode<=0xDA) ||
2583da084b3Smrg            (isocode>=0xE0 && isocode<=0xEF) ||
2593da084b3Smrg            (isocode>=0xF0 && isocode<=0xF2))
2603da084b3Smrg        return isocode-0xA0+0x0600;
2613da084b3Smrg    else
2623da084b3Smrg        return 0;
2633da084b3Smrg}
2643da084b3Smrg
2653da084b3Smrgstatic FontMapRec iso8859_6[]=
2663da084b3Smrg{
2673da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,iso8859_6_to_unicode,NULL,NULL,NULL,NULL},
2683da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
2693da084b3Smrg};
2703da084b3Smrg
2713da084b3Smrgstatic unsigned
2723da084b3Smrgiso8859_7_to_unicode(unsigned isocode, void *client_data)
2733da084b3Smrg{
2743da084b3Smrg    if(isocode<=0xA0 ||
2753da084b3Smrg       (isocode>=0xA3 && isocode<=0xAD) ||
2763da084b3Smrg       (isocode>=0xB0 && isocode<=0xB3) ||
2773da084b3Smrg       isocode==0xB7 || isocode==0xBB || isocode==0xBD)
2783da084b3Smrg        return isocode;
2793da084b3Smrg    else if(isocode==0xA1)
2803da084b3Smrg        return 0x02BD;
2813da084b3Smrg    else if(isocode==0xA2)
2823da084b3Smrg        return 0x02BC;
2833da084b3Smrg    else if(isocode==0xAF)
2843da084b3Smrg        return 0x2015;
2853da084b3Smrg    else if(isocode>=0xB4)
2863da084b3Smrg        return isocode-0xA0+0x0370;
2873da084b3Smrg    else
2883da084b3Smrg        return 0;
2893da084b3Smrg}
2903da084b3Smrg
2913da084b3Smrgstatic FontMapRec iso8859_7[]=
2923da084b3Smrg{
2933da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,iso8859_7_to_unicode,NULL,NULL,NULL,NULL},
2943da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
2953da084b3Smrg};
2963da084b3Smrg
2973da084b3Smrgstatic unsigned
2983da084b3Smrgiso8859_8_to_unicode(unsigned isocode, void *client_data)
2993da084b3Smrg{
3003da084b3Smrg    if(isocode==0xA1)
3013da084b3Smrg        return 0;
3023da084b3Smrg    else if(isocode<0xBF)
3033da084b3Smrg        return isocode;
3043da084b3Smrg    else if(isocode==0xDF)
3053da084b3Smrg        return 0x2017;
3063da084b3Smrg    else if(isocode>=0xE0 && isocode<=0xFA)
3073da084b3Smrg        return isocode+0x04F0;
3083da084b3Smrg    else
3093da084b3Smrg        return 0;
3103da084b3Smrg}
3113da084b3Smrg
3123da084b3Smrgstatic FontMapRec iso8859_8[]=
3133da084b3Smrg{
3143da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,iso8859_8_to_unicode,NULL,NULL,NULL,NULL},
3153da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
3163da084b3Smrg};
3173da084b3Smrg
3183da084b3Smrgstatic unsigned
3193da084b3Smrgiso8859_9_to_unicode(unsigned isocode, void *client_data)
3203da084b3Smrg{
3213da084b3Smrg    switch(isocode) {
3223da084b3Smrg    case 0xD0: return 0x011E;
3233da084b3Smrg    case 0xDD: return 0x0130;
3243da084b3Smrg    case 0xDE: return 0x015E;
3253da084b3Smrg    case 0xF0: return 0x011F;
3263da084b3Smrg    case 0xFD: return 0x0131;
3273da084b3Smrg    case 0xFE: return 0x015F;
3283da084b3Smrg    default: return isocode;
3293da084b3Smrg    }
3303da084b3Smrg}
3313da084b3Smrg
3323da084b3Smrgstatic FontMapRec iso8859_9[]=
3333da084b3Smrg{
3343da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,iso8859_9_to_unicode,NULL,NULL,NULL,NULL},
3353da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
3363da084b3Smrg};
3373da084b3Smrg
3383da084b3Smrgstatic const unsigned short iso8859_10_tophalf[]=
3393da084b3Smrg{ 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7,
3403da084b3Smrg  0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A,
3413da084b3Smrg  0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7,
3423da084b3Smrg  0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2014, 0x016B, 0x014B,
3433da084b3Smrg  0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
3443da084b3Smrg  0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF,
3453da084b3Smrg  0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168,
3463da084b3Smrg  0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
3473da084b3Smrg  0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
3483da084b3Smrg  0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF,
3493da084b3Smrg  0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169,
3503da084b3Smrg  0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138};
3513da084b3Smrg
3523da084b3Smrgstatic FontEncSimpleMapRec iso8859_10_to_unicode_map=
3533da084b3Smrg{ 0x60, 0, 0xA0, iso8859_10_tophalf };
3543da084b3Smrg
3553da084b3Smrgstatic FontMapRec iso8859_10[]=
3563da084b3Smrg{
3573da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,NULL,
3583da084b3Smrg     &iso8859_10_to_unicode_map,NULL,NULL},
3593da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
3603da084b3Smrg};
3613da084b3Smrg
3623da084b3Smrgstatic unsigned
3633da084b3Smrgiso8859_15_to_unicode(unsigned isocode, void *client_data)
3643da084b3Smrg{
3653da084b3Smrg    switch(isocode) {
3663da084b3Smrg    case 0xA4: return 0x20AC;
3673da084b3Smrg    case 0xA6: return 0x0160;
3683da084b3Smrg    case 0xA8: return 0x0161;
3693da084b3Smrg    case 0xB4: return 0x017D;
3703da084b3Smrg    case 0xB8: return 0x017E;
3713da084b3Smrg    case 0xBC: return 0x0152;
3723da084b3Smrg    case 0xBD: return 0x0153;
3733da084b3Smrg    case 0xBE: return 0x0178;
3743da084b3Smrg    default: return isocode;
3753da084b3Smrg    }
3763da084b3Smrg}
3773da084b3Smrg
3783da084b3Smrgstatic FontMapRec iso8859_15[]=
3793da084b3Smrg{
3803da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,iso8859_15_to_unicode,NULL,NULL,NULL,NULL},
3813da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
3823da084b3Smrg};
3833da084b3Smrg
3843da084b3Smrgstatic const unsigned short koi8_r_tophalf[]=
3853da084b3Smrg{ 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
3863da084b3Smrg  0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
3873da084b3Smrg  0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2022, 0x221A, 0x2248,
3883da084b3Smrg  0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
3893da084b3Smrg  0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
3903da084b3Smrg  0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
3913da084b3Smrg  0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
3923da084b3Smrg  0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9,
3933da084b3Smrg  0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
3943da084b3Smrg  0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
3953da084b3Smrg  0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
3963da084b3Smrg  0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
3973da084b3Smrg  0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
3983da084b3Smrg  0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
3993da084b3Smrg  0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
4003da084b3Smrg  0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A};
4013da084b3Smrg
4023da084b3Smrgstatic FontEncSimpleMapRec koi8_r_to_unicode_map=
4033da084b3Smrg{ 0x80, 0, 0x80, koi8_r_tophalf };
4043da084b3Smrg
4053da084b3Smrg
4063da084b3Smrgstatic FontMapRec koi8_r[]=
4073da084b3Smrg{
4083da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,NULL,
4093da084b3Smrg     &koi8_r_to_unicode_map,NULL,NULL},
4103da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
4113da084b3Smrg};
4123da084b3Smrg
4133da084b3Smrgstatic unsigned
4143da084b3Smrgkoi8_ru_to_unicode(unsigned koicode, void *client_data)
4153da084b3Smrg{
4163da084b3Smrg    switch(koicode) {
4173da084b3Smrg    case 0x93: return 0x201C;
4183da084b3Smrg    case 0x96: return 0x201D;
4193da084b3Smrg    case 0x97: return 0x2014;
4203da084b3Smrg    case 0x98: return 0x2116;
4213da084b3Smrg    case 0x99: return 0x2122;
4223da084b3Smrg    case 0x9B: return 0x00BB;
4233da084b3Smrg    case 0x9C: return 0x00AE;
4243da084b3Smrg    case 0x9D: return 0x00AB;
4253da084b3Smrg    case 0x9F: return 0x00A4;
4263da084b3Smrg    case 0xA4: return 0x0454;
4273da084b3Smrg    case 0xA6: return 0x0456;
4283da084b3Smrg    case 0xA7: return 0x0457;
4293da084b3Smrg    case 0xAD: return 0x0491;
4303da084b3Smrg    case 0xAE: return 0x045E;
4313da084b3Smrg    case 0xB4: return 0x0404;
4323da084b3Smrg    case 0xB6: return 0x0406;
4333da084b3Smrg    case 0xB7: return 0x0407;
4343da084b3Smrg    case 0xBD: return 0x0490;
4353da084b3Smrg    case 0xBE: return 0x040E;
4363da084b3Smrg    default: return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map);
4373da084b3Smrg  }
4383da084b3Smrg}
4393da084b3Smrg
4403da084b3Smrgstatic FontMapRec koi8_ru[]=
4413da084b3Smrg{
4423da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,koi8_ru_to_unicode,NULL,NULL,NULL,NULL},
4433da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
4443da084b3Smrg};
4453da084b3Smrg
4463da084b3Smrg/* koi8-e, ISO-IR-111 or ECMA-Cyrillic */
4473da084b3Smrg
4483da084b3Smrgstatic const unsigned short koi8_e_A0_BF[]=
4493da084b3Smrg{ 0x00A0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457,
4503da084b3Smrg  0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00AD, 0x045E, 0x045F,
4513da084b3Smrg  0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407,
4523da084b3Smrg  0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00A4, 0x040E, 0x040F };
4533da084b3Smrg
4543da084b3Smrgstatic unsigned
4553da084b3Smrgkoi8_e_to_unicode(unsigned koicode, void *client_data)
4563da084b3Smrg{
4573da084b3Smrg    if(koicode<0xA0)
4583da084b3Smrg        return koicode;
4593da084b3Smrg    else if(koicode<0xC0)
4603da084b3Smrg        return koi8_e_A0_BF[koicode-0xA0];
4613da084b3Smrg    else
4623da084b3Smrg        return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map);
4633da084b3Smrg}
4643da084b3Smrg
4653da084b3Smrgstatic FontMapRec koi8_e[]=
4663da084b3Smrg{
4673da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,koi8_e_to_unicode,NULL,NULL,NULL,NULL},
4683da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
4693da084b3Smrg};
4703da084b3Smrg
4713da084b3Smrg/* Koi8 unified */
4723da084b3Smrg
4733da084b3Smrgstatic const unsigned short koi8_uni_80_BF[]=
4743da084b3Smrg{ 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
4753da084b3Smrg  0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
4763da084b3Smrg  0x2591, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
4773da084b3Smrg  0x00A9, 0x2122, 0x00A0, 0x00BB, 0x00AE, 0x00AB, 0x00B7, 0x00A4,
4783da084b3Smrg  0x00A0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457,
4793da084b3Smrg  0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x0491, 0x045E, 0x045F,
4803da084b3Smrg  0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407,
4813da084b3Smrg  0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x0490, 0x040E, 0x040F };
4823da084b3Smrg
4833da084b3Smrgstatic unsigned
4843da084b3Smrgkoi8_uni_to_unicode(unsigned koicode, void *client_data)
4853da084b3Smrg{
4863da084b3Smrg    if(koicode<0x80)
4873da084b3Smrg        return koicode;
4883da084b3Smrg    else if(koicode<0xC0)
4893da084b3Smrg        return koi8_uni_80_BF[koicode-0x80];
4903da084b3Smrg    else
4913da084b3Smrg        return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map);
4923da084b3Smrg}
4933da084b3Smrg
4943da084b3Smrgstatic FontMapRec koi8_uni[]=
4953da084b3Smrg{
4963da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,koi8_uni_to_unicode,NULL,NULL,NULL,NULL},
4973da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
4983da084b3Smrg};
4993da084b3Smrg
5003da084b3Smrg/* Ukrainian variant of Koi8-R; see RFC 2319 */
5013da084b3Smrg
5023da084b3Smrgstatic unsigned
5033da084b3Smrgkoi8_u_to_unicode(unsigned koicode, void *client_data)
5043da084b3Smrg{
5053da084b3Smrg    switch(koicode) {
5063da084b3Smrg    case 0xA4: return 0x0454;
5073da084b3Smrg    case 0xA6: return 0x0456;
5083da084b3Smrg    case 0xA7: return 0x0457;
5093da084b3Smrg    case 0xAD: return 0x0491;
5103da084b3Smrg    case 0xB4: return 0x0404;
5113da084b3Smrg    case 0xB6: return 0x0406;
5123da084b3Smrg    case 0xB7: return 0x0407;
5133da084b3Smrg    case 0xBD: return 0x0490;
5143da084b3Smrg    default: return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map);
5153da084b3Smrg    }
5163da084b3Smrg}
5173da084b3Smrg
5183da084b3Smrgstatic FontMapRec koi8_u[]=
5193da084b3Smrg{
5203da084b3Smrg    {FONT_ENCODING_UNICODE,0,0,koi8_u_to_unicode,NULL,NULL,NULL},
5213da084b3Smrg    {0,0,0,NULL,NULL,NULL,NULL,NULL}
5223da084b3Smrg};
5233da084b3Smrg
5243da084b3Smrg/* Microsoft Symbol, which is only meaningful for TrueType fonts, is
5253da084b3Smrg   treated specially in ftenc.c, where we add usFirstCharIndex-0x20 to
5263da084b3Smrg   the glyph index before applying the cmap.  Lovely design. */
5273da084b3Smrg
5283da084b3Smrgstatic FontMapRec microsoft_symbol[]=
5293da084b3Smrg{{FONT_ENCODING_TRUETYPE,3,0,NULL,NULL,NULL,NULL,NULL},
5303da084b3Smrg /* You never know */
5313da084b3Smrg {FONT_ENCODING_TRUETYPE,3,1,NULL,NULL,NULL,NULL,NULL},
5323da084b3Smrg {0,0,0,NULL,NULL,NULL,NULL,NULL}};
5333da084b3Smrg
5343da084b3Smrgstatic FontMapRec apple_roman[]=
5353da084b3Smrg{{FONT_ENCODING_TRUETYPE,1,0,NULL,NULL,NULL,NULL,NULL},
5363da084b3Smrg {0,0,0,NULL,NULL,NULL,NULL,NULL}};
5373da084b3Smrg
5383da084b3Smrg/* The data for recodings */
5393da084b3Smrg
5403da084b3Smrg/* For compatibility with X11R6.4.  Losers. */
5413da084b3Smrgstatic char *iso8859_15_aliases[2]={"fcd8859-15",NULL};
5423da084b3Smrg
5433da084b3Smrgstatic FontEncRec initial_encodings[]=
5443da084b3Smrg{
5453da084b3Smrg    {"iso10646-1",NULL,256*256,0,iso10646,NULL,0,0}, /* Unicode */
5463da084b3Smrg    {"iso8859-1",NULL,256,0,iso8859_1,NULL,0,0}, /* Latin 1 (West European) */
5473da084b3Smrg    {"iso8859-2",NULL,256,0,iso8859_2,NULL,0,0}, /* Latin 2 (East European) */
5483da084b3Smrg    {"iso8859-3",NULL,256,0,iso8859_3,NULL,0,0}, /* Latin 3 (South European) */
5493da084b3Smrg    {"iso8859-4",NULL,256,0,iso8859_4,NULL,0,0}, /* Latin 4 (North European) */
5503da084b3Smrg    {"iso8859-5",NULL,256,0,iso8859_5,NULL,0,0}, /* Cyrillic */
5513da084b3Smrg    {"iso8859-6",NULL,256,0,iso8859_6,NULL,0,0}, /* Arabic */
5523da084b3Smrg    {"iso8859-7",NULL,256,0,iso8859_7,NULL,0,0}, /* Greek */
5533da084b3Smrg    {"iso8859-8",NULL,256,0,iso8859_8,NULL,0,0}, /* Hebrew */
5543da084b3Smrg    {"iso8859-9",NULL,256,0,iso8859_9,NULL,0,0}, /* Latin 5 (Turkish) */
5553da084b3Smrg    {"iso8859-10",NULL,256,0,iso8859_10,NULL,0,0}, /* Latin 6 (Nordic) */
5563da084b3Smrg    {"iso8859-15",iso8859_15_aliases,256,0,iso8859_15,NULL,0,0}, /* Latin 9 */
5573da084b3Smrg    {"koi8-r",NULL,256,0,koi8_r,NULL,0,0},       /* Russian */
5583da084b3Smrg    {"koi8-ru",NULL,256,0,koi8_ru,NULL,0,0},     /* Ukrainian */
5593da084b3Smrg    {"koi8-uni",NULL,256,0,koi8_uni,NULL,0,0},   /* Russian/Ukrainian/Bielorussian */
5603da084b3Smrg    {"koi8-e",NULL,256,0,koi8_e,NULL,0,0},       /* ``European'' */
5613da084b3Smrg    {"koi8-u",NULL,256,0,koi8_u,NULL,0,0},       /* Ukrainian too */
5623da084b3Smrg    {"microsoft-symbol",NULL,256,0,microsoft_symbol,NULL,0,0},
5633da084b3Smrg    {"apple-roman",NULL,256,0,apple_roman,NULL,0,0},
5643da084b3Smrg    {NULL,NULL,0,0,NULL,NULL,0,0}
5653da084b3Smrg};
5663da084b3Smrg
5673da084b3Smrgstatic FontEncPtr font_encodings=NULL;
5683da084b3Smrg
5693da084b3Smrgstatic void
5703da084b3Smrgdefine_initial_encoding_info(void)
5713da084b3Smrg{
5723da084b3Smrg    FontEncPtr encoding;
5733da084b3Smrg    FontMapPtr mapping;
5743da084b3Smrg
5753da084b3Smrg    font_encodings = initial_encodings;
5763da084b3Smrg    for(encoding = font_encodings; ; encoding++) {
5773da084b3Smrg        encoding->next = encoding + 1;
5783da084b3Smrg        for(mapping = encoding->mappings; ; mapping++) {
5793da084b3Smrg            mapping->next = mapping+1;
5803da084b3Smrg            mapping->encoding = encoding;
5813da084b3Smrg            if(mapping->next->type == 0) {
5823da084b3Smrg                mapping->next = NULL;
5833da084b3Smrg                break;
5843da084b3Smrg            }
5853da084b3Smrg        }
5863da084b3Smrg        if(!encoding->next->name) {
5873da084b3Smrg            encoding->next = NULL;
5883da084b3Smrg            break;
5893da084b3Smrg        }
5903da084b3Smrg    }
5913da084b3Smrg}
5923da084b3Smrg
5933da084b3Smrg
5943da084b3Smrgchar*
5953da084b3SmrgFontEncFromXLFD(const char *name, int length)
5963da084b3Smrg{
5973da084b3Smrg    const char *p;
5983da084b3Smrg    char *q;
5993da084b3Smrg    static char charset[MAXFONTNAMELEN];
6003da084b3Smrg    int len;
6013da084b3Smrg
6023da084b3Smrg    if(length > MAXFONTNAMELEN - 1)
6033da084b3Smrg        return NULL;
6043da084b3Smrg
6053da084b3Smrg    if(name == NULL)
6063da084b3Smrg        p = NULL;
6073da084b3Smrg    else {
6083da084b3Smrg        p = name + length - 1;
6093da084b3Smrg        while(p > name && *p != '-')
6103da084b3Smrg            p--;
6113da084b3Smrg        p--;
6123da084b3Smrg        while(p >= name && *p != '-')
6133da084b3Smrg            p--;
6143da084b3Smrg        if(p <= name)
6153da084b3Smrg            p = NULL;
6163da084b3Smrg    }
6173da084b3Smrg
6183da084b3Smrg    /* now p either is null or points at the '-' before the charset registry */
619d63fdb69Smrg
620d63fdb69Smrg    if(p == NULL)
6213da084b3Smrg        return NULL;
6223da084b3Smrg
6233da084b3Smrg    len = length - (p - name) - 1;
6243da084b3Smrg    memcpy(charset, p+1, len);
6253da084b3Smrg    charset[len] = 0;
6263da084b3Smrg
6273da084b3Smrg    /* check for a subset specification */
6283da084b3Smrg    if((q = strchr(charset, (int)'[')))
6293da084b3Smrg        *q = 0;
6303da084b3Smrg
6313da084b3Smrg    return charset;
6323da084b3Smrg}
6333da084b3Smrg
6343da084b3Smrgunsigned
6353da084b3SmrgFontEncRecode(unsigned code,  FontMapPtr mapping)
6363da084b3Smrg{
6373da084b3Smrg    FontEncPtr encoding = mapping->encoding;
6383da084b3Smrg    if(encoding && mapping->recode) {
6393da084b3Smrg        if(encoding->row_size == 0) {
6403da084b3Smrg            /* linear encoding */
6413da084b3Smrg            if(code < encoding->first || code>=encoding->size)
6423da084b3Smrg                return 0;
6433da084b3Smrg        } else {
6443da084b3Smrg            /* matrix encoding */
6453da084b3Smrg            int row = code/0x100, col = code&0xFF;
6463da084b3Smrg            if(row < encoding->first || row >= encoding->size ||
6473da084b3Smrg               col < encoding->first_col || col >= encoding->row_size)
6483da084b3Smrg                return 0;
6493da084b3Smrg        }
6503da084b3Smrg        return (*mapping->recode)(code, mapping->client_data);
6513da084b3Smrg    } else
6523da084b3Smrg        return code;
6533da084b3Smrg}
6543da084b3Smrg
6553da084b3Smrgchar*
6563da084b3SmrgFontEncName(unsigned code, FontMapPtr mapping)
6573da084b3Smrg{
6583da084b3Smrg    FontEncPtr encoding = mapping->encoding;
6593da084b3Smrg    if(encoding && mapping->name) {
6603da084b3Smrg        if((encoding->row_size == 0 && code >= encoding->size) ||
6613da084b3Smrg           (encoding->row_size != 0 &&
6623da084b3Smrg            (code/0x100 >= encoding->size ||
6633da084b3Smrg             (code&0xFF) >= encoding->row_size)))
6643da084b3Smrg            return NULL;
6653da084b3Smrg        return (*mapping->name)(code, mapping->client_data);
6663da084b3Smrg    } else
6673da084b3Smrg        return NULL;
6683da084b3Smrg}
6693da084b3Smrg
6703da084b3SmrgFontEncPtr
6713da084b3SmrgFontEncFind(const char *encoding_name, const char *filename)
6723da084b3Smrg{
6733da084b3Smrg    FontEncPtr encoding;
6743da084b3Smrg    char **alias;
6753da084b3Smrg
6763da084b3Smrg    if(font_encodings == NULL) define_initial_encoding_info();
6773da084b3Smrg
6783da084b3Smrg    for(encoding = font_encodings; encoding; encoding = encoding->next) {
6793da084b3Smrg        if(!strcasecmp(encoding->name, encoding_name))
6803da084b3Smrg            return encoding;
6813da084b3Smrg        if(encoding->aliases)
6823da084b3Smrg            for(alias=encoding->aliases; *alias; alias++)
6833da084b3Smrg                if(!strcasecmp(*alias, encoding_name))
6843da084b3Smrg                    return encoding;
6853da084b3Smrg  }
6863da084b3Smrg
6873da084b3Smrg  /* Unknown charset, try to load a definition file */
6883da084b3Smrg    return FontEncLoad(encoding_name, filename);
6893da084b3Smrg}
6903da084b3Smrg
6913da084b3SmrgFontMapPtr
6923da084b3SmrgFontMapFind(FontEncPtr encoding, int type, int pid, int eid)
6933da084b3Smrg{
6943da084b3Smrg    FontMapPtr mapping;
6953da084b3Smrg    if(encoding == NULL)
6963da084b3Smrg        return NULL;
6973da084b3Smrg
6983da084b3Smrg    for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
6993da084b3Smrg        if(mapping->type != type)
7003da084b3Smrg            continue;
7013da084b3Smrg        if(pid > 0 && mapping->pid != pid)
7023da084b3Smrg            continue;
7033da084b3Smrg        if(eid > 0 && mapping->eid != eid)
7043da084b3Smrg            continue;
7053da084b3Smrg        return mapping;
7063da084b3Smrg    }
7073da084b3Smrg    return NULL;
7083da084b3Smrg}
7093da084b3Smrg
7103da084b3SmrgFontMapPtr
7113da084b3SmrgFontEncMapFind(const char *encoding_name, int type, int pid, int eid,
7123da084b3Smrg               const char *filename)
7133da084b3Smrg{
7143da084b3Smrg    FontEncPtr encoding;
7153da084b3Smrg    FontMapPtr mapping;
7163da084b3Smrg
7173da084b3Smrg    encoding = FontEncFind(encoding_name, filename);
7183da084b3Smrg    if(encoding == NULL)
7193da084b3Smrg        return NULL;
7203da084b3Smrg    mapping = FontMapFind(encoding, type, pid, eid);
7213da084b3Smrg    return mapping;
7223da084b3Smrg}
7233da084b3Smrg
7243da084b3Smrgstatic FontEncPtr
7253da084b3SmrgFontEncLoad(const char *encoding_name, const char *filename)
7263da084b3Smrg{
7273da084b3Smrg    FontEncPtr encoding;
7283da084b3Smrg
7293da084b3Smrg    encoding = FontEncReallyLoad(encoding_name, filename);
7303da084b3Smrg    if (encoding == NULL) {
7313da084b3Smrg        return NULL;
7323da084b3Smrg    } else {
7333da084b3Smrg        char **alias;
7343da084b3Smrg        int found = 0;
7353da084b3Smrg
7363da084b3Smrg        /* Check whether the name is already known for this encoding */
7373da084b3Smrg        if(strcasecmp(encoding->name, encoding_name) == 0) {
7383da084b3Smrg            found = 1;
7393da084b3Smrg        } else {
7403da084b3Smrg            if(encoding->aliases) {
7413da084b3Smrg                for(alias=encoding->aliases; *alias; alias++)
7423da084b3Smrg                    if(!strcasecmp(*alias, encoding_name)) {
7433da084b3Smrg                        found = 1;
7443da084b3Smrg                        break;
7453da084b3Smrg                    }
7463da084b3Smrg            }
7473da084b3Smrg        }
7483da084b3Smrg
7493da084b3Smrg        if(!found) {
7503da084b3Smrg            /* Add a new alias.  This works because we know that this
7513da084b3Smrg               particular encoding has been allocated dynamically */
7523da084b3Smrg            char **new_aliases;
7533da084b3Smrg            char *new_name;
7543da084b3Smrg            int numaliases = 0;
7553da084b3Smrg
75655acc8fcSmrg            new_name = strdup(encoding_name);
7573da084b3Smrg            if(new_name == NULL)
7583da084b3Smrg                return NULL;
7593da084b3Smrg            if(encoding->aliases) {
7603da084b3Smrg                for(alias = encoding->aliases; *alias; alias++)
7613da084b3Smrg                    numaliases++;
7623da084b3Smrg            }
76355acc8fcSmrg            new_aliases = malloc((numaliases+2)*sizeof(char*));
7643da084b3Smrg            if(new_aliases == NULL) {
76555acc8fcSmrg                free(new_name);
7663da084b3Smrg                return NULL;
7673da084b3Smrg            }
7683da084b3Smrg            if(encoding->aliases) {
7693da084b3Smrg                memcpy(new_aliases, encoding->aliases, numaliases*sizeof(char*));
77055acc8fcSmrg                free(encoding->aliases);
7713da084b3Smrg            }
7723da084b3Smrg            new_aliases[numaliases] = new_name;
7733da084b3Smrg            new_aliases[numaliases+1] = NULL;
7743da084b3Smrg            encoding->aliases = new_aliases;
7753da084b3Smrg        }
7763da084b3Smrg
7773da084b3Smrg        /* register the new encoding */
7783da084b3Smrg        encoding->next=font_encodings;
7793da084b3Smrg        font_encodings=encoding;
7803da084b3Smrg
7813da084b3Smrg        return encoding;
7823da084b3Smrg    }
7833da084b3Smrg}
7843da084b3Smrg
7853da084b3Smrgunsigned
7863da084b3SmrgFontEncSimpleRecode(unsigned code, void *client_data)
7873da084b3Smrg{
7883da084b3Smrg    FontEncSimpleMapPtr map;
7893da084b3Smrg    unsigned index;
7903da084b3Smrg
7913da084b3Smrg    map = client_data;
7923da084b3Smrg
7933da084b3Smrg    if(code > 0xFFFF || (map->row_size && (code&0xFF) >= map->row_size))
7943da084b3Smrg        return 0;
7953da084b3Smrg
7963da084b3Smrg    if(map->row_size)
7973da084b3Smrg        index = (code&0xFF)+(code>>8)*map->row_size;
7983da084b3Smrg    else
7993da084b3Smrg        index = code;
8003da084b3Smrg
8013da084b3Smrg  if(map->map && index>=map->first && index<map->first+map->len)
8023da084b3Smrg    return map->map[index-map->first];
8033da084b3Smrg  else
8043da084b3Smrg    return code;
8053da084b3Smrg}
8063da084b3Smrg
8073da084b3Smrgchar *
8083da084b3SmrgFontEncSimpleName(unsigned code, void *client_data)
8093da084b3Smrg{
8103da084b3Smrg    FontEncSimpleNamePtr map;
8113da084b3Smrg
8123da084b3Smrg    map = client_data;
8133da084b3Smrg    if(map && code >= map->first && code<map->first+map->len)
8143da084b3Smrg        return map->map[code-map->first];
8153da084b3Smrg    else
8163da084b3Smrg        return NULL;
8173da084b3Smrg}
8183da084b3Smrg
8193da084b3Smrgunsigned
8203da084b3SmrgFontEncUndefinedRecode(unsigned code, void *client_data)
8213da084b3Smrg{
8223da084b3Smrg    return code;
8233da084b3Smrg}
8243da084b3Smrg
8253da084b3Smrgchar *
8263da084b3SmrgFontEncUndefinedName(unsigned code, void *client_data)
8273da084b3Smrg{
8283da084b3Smrg    return NULL;
8293da084b3Smrg}
8303da084b3Smrg
8313da084b3Smrg#define FONTENC_SEGMENT_SIZE 256
8323da084b3Smrg#define FONTENC_SEGMENTS 256
8333da084b3Smrg#define FONTENC_INVERSE_CODES (FONTENC_SEGMENT_SIZE * FONTENC_SEGMENTS)
8343da084b3Smrg
8353da084b3Smrgstatic unsigned int
8363da084b3Smrgreverse_reverse(unsigned i, void* data)
8373da084b3Smrg{
8383da084b3Smrg    int s, j;
8393da084b3Smrg    unsigned **map = (unsigned**)data;
8403da084b3Smrg
8413da084b3Smrg    if(i >= FONTENC_INVERSE_CODES)
8423da084b3Smrg        return 0;
8433da084b3Smrg
8443da084b3Smrg    if(map == NULL)
8453da084b3Smrg        return 0;
8463da084b3Smrg
8473da084b3Smrg    s = i / FONTENC_SEGMENT_SIZE;
8483da084b3Smrg    j = i % FONTENC_SEGMENT_SIZE;
8493da084b3Smrg
8503da084b3Smrg    if(map[s] == NULL)
8513da084b3Smrg        return 0;
8523da084b3Smrg    else
8533da084b3Smrg        return map[s][j];
8543da084b3Smrg}
8553da084b3Smrg
8563da084b3Smrgstatic int
8573da084b3Smrgtree_set(unsigned int **map, unsigned int i, unsigned int j)
8583da084b3Smrg{
8593da084b3Smrg    int s, c;
8603da084b3Smrg
8613da084b3Smrg    if(i >= FONTENC_INVERSE_CODES)
8623da084b3Smrg        return FALSE;
8633da084b3Smrg
8643da084b3Smrg    s = i / FONTENC_SEGMENT_SIZE;
8653da084b3Smrg    c = i % FONTENC_SEGMENT_SIZE;
8663da084b3Smrg
8673da084b3Smrg    if(map[s] == NULL) {
8683da084b3Smrg        map[s] = calloc(FONTENC_SEGMENT_SIZE, sizeof(int));
8693da084b3Smrg        if(map[s] == NULL)
8703da084b3Smrg            return FALSE;
8713da084b3Smrg  }
8723da084b3Smrg
8733da084b3Smrg    map[s][c] = j;
8743da084b3Smrg    return TRUE;
8753da084b3Smrg}
8763da084b3Smrg
8773da084b3SmrgFontMapReversePtr
8783da084b3SmrgFontMapReverse(FontMapPtr mapping)
8793da084b3Smrg{
8803da084b3Smrg    FontEncPtr encoding = mapping->encoding;
8813da084b3Smrg    FontMapReversePtr reverse = NULL;
8823da084b3Smrg    unsigned int **map = NULL;
8833da084b3Smrg    int i, j, k;
8843da084b3Smrg
8853da084b3Smrg    if(encoding == NULL) goto bail;
8863da084b3Smrg
8873da084b3Smrg    map = calloc(FONTENC_SEGMENTS, sizeof(int*));
8883da084b3Smrg    if(map == NULL) goto bail;
8893da084b3Smrg
8903da084b3Smrg    if(encoding->row_size == 0) {
8913da084b3Smrg        for(i = encoding->first; i < encoding->size; i++) {
8923da084b3Smrg            k = FontEncRecode(i, mapping);
8933da084b3Smrg            if(k != 0)
8943da084b3Smrg                if(!tree_set(map, k, i))
8953da084b3Smrg                    goto bail;
8963da084b3Smrg        }
8973da084b3Smrg    } else {
8983da084b3Smrg        for(i = encoding->first; i < encoding->size; i++) {
8993da084b3Smrg            for(j = encoding->first_col; j < encoding->row_size; j++) {
9003da084b3Smrg                k = FontEncRecode(i*256 + j, mapping);
9013da084b3Smrg                if(k != 0)
9023da084b3Smrg                    if(!tree_set(map, k, i*256+j))
9033da084b3Smrg                        goto bail;
9043da084b3Smrg            }
9053da084b3Smrg        }
9063da084b3Smrg    }
9073da084b3Smrg
9083da084b3Smrg    reverse = malloc(sizeof(FontMapReverseRec));
9093da084b3Smrg    if(!reverse) goto bail;
9103da084b3Smrg
9113da084b3Smrg    reverse->reverse = reverse_reverse;
9123da084b3Smrg    reverse->data = map;
9133da084b3Smrg    return reverse;
9143da084b3Smrg
9153da084b3Smrg  bail:
91655acc8fcSmrg    free(map);
91755acc8fcSmrg    free(reverse);
9183da084b3Smrg    return NULL;
9193da084b3Smrg}
9203da084b3Smrg
9213da084b3Smrgvoid
9223da084b3SmrgFontMapReverseFree(FontMapReversePtr delendum)
9233da084b3Smrg{
9243da084b3Smrg    unsigned int **map = (unsigned int**)delendum;
9253da084b3Smrg    int i;
9263da084b3Smrg
9273da084b3Smrg    if(map == NULL)
9283da084b3Smrg        return;
9293da084b3Smrg
9303da084b3Smrg    for(i = 0; i < FONTENC_SEGMENTS; i++)
93155acc8fcSmrg	free(map[i]);
9323da084b3Smrg
93355acc8fcSmrg    free(map);
9343da084b3Smrg    return;
9353da084b3Smrg}
936