update.
[chise/xemacs-chise.git-] / src / mule-charset.c
1 /* Functions to handle multilingual characters.
2    Copyright (C) 1992, 1995 Free Software Foundation, Inc.
3    Copyright (C) 1995 Sun Microsystems, Inc.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* Synched up with: FSF 20.3.  Not in FSF. */
23
24 /* Rewritten by Ben Wing <ben@xemacs.org>. */
25
26 #include <config.h>
27 #include "lisp.h"
28
29 #include "buffer.h"
30 #include "chartab.h"
31 #include "elhash.h"
32 #include "lstream.h"
33 #include "device.h"
34 #include "faces.h"
35 #include "mule-ccl.h"
36
37 /* The various pre-defined charsets. */
38
39 Lisp_Object Vcharset_ascii;
40 Lisp_Object Vcharset_control_1;
41 Lisp_Object Vcharset_latin_iso8859_1;
42 Lisp_Object Vcharset_latin_iso8859_2;
43 Lisp_Object Vcharset_latin_iso8859_3;
44 Lisp_Object Vcharset_latin_iso8859_4;
45 Lisp_Object Vcharset_thai_tis620;
46 Lisp_Object Vcharset_greek_iso8859_7;
47 Lisp_Object Vcharset_arabic_iso8859_6;
48 Lisp_Object Vcharset_hebrew_iso8859_8;
49 Lisp_Object Vcharset_katakana_jisx0201;
50 Lisp_Object Vcharset_latin_jisx0201;
51 Lisp_Object Vcharset_cyrillic_iso8859_5;
52 Lisp_Object Vcharset_latin_iso8859_9;
53 Lisp_Object Vcharset_japanese_jisx0208_1978;
54 Lisp_Object Vcharset_chinese_gb2312;
55 Lisp_Object Vcharset_japanese_jisx0208;
56 Lisp_Object Vcharset_korean_ksc5601;
57 Lisp_Object Vcharset_japanese_jisx0212;
58 Lisp_Object Vcharset_chinese_cns11643_1;
59 Lisp_Object Vcharset_chinese_cns11643_2;
60 #ifdef UTF2000
61 Lisp_Object Vcharset_chinese_cns11643_3;
62 Lisp_Object Vcharset_chinese_cns11643_4;
63 Lisp_Object Vcharset_chinese_cns11643_5;
64 Lisp_Object Vcharset_chinese_cns11643_6;
65 Lisp_Object Vcharset_chinese_cns11643_7;
66 Lisp_Object Vcharset_ucs_bmp;
67 Lisp_Object Vcharset_latin_viscii_lower;
68 Lisp_Object Vcharset_latin_viscii_upper;
69 #endif
70 Lisp_Object Vcharset_chinese_big5_1;
71 Lisp_Object Vcharset_chinese_big5_2;
72
73 #ifdef ENABLE_COMPOSITE_CHARS
74 Lisp_Object Vcharset_composite;
75
76 /* Hash tables for composite chars.  One maps string representing
77    composed chars to their equivalent chars; one goes the
78    other way. */
79 Lisp_Object Vcomposite_char_char2string_hash_table;
80 Lisp_Object Vcomposite_char_string2char_hash_table;
81
82 static int composite_char_row_next;
83 static int composite_char_col_next;
84
85 #endif /* ENABLE_COMPOSITE_CHARS */
86
87 /* Table of charsets indexed by leading byte. */
88 Lisp_Object charset_by_leading_byte[NUM_LEADING_BYTES];
89
90 /* Table of charsets indexed by type/final-byte/direction. */
91 #ifdef UTF2000
92 Lisp_Object charset_by_attributes[4][128];
93 #else
94 Lisp_Object charset_by_attributes[4][128][2];
95 #endif
96
97 #ifndef UTF2000
98 /* Table of number of bytes in the string representation of a character
99    indexed by the first byte of that representation.
100
101    rep_bytes_by_first_byte(c) is more efficient than the equivalent
102    canonical computation:
103
104    (BYTE_ASCII_P (c) ? 1 : XCHARSET_REP_BYTES (CHARSET_BY_LEADING_BYTE (c))) */
105
106 Bytecount rep_bytes_by_first_byte[0xA0] =
107 { /* 0x00 - 0x7f are for straight ASCII */
108   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
109   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
110   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
111   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
112   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
113   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
114   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
115   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
116   /* 0x80 - 0x8f are for Dimension-1 official charsets */
117 #ifdef CHAR_IS_UCS4
118   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
119 #else
120   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
121 #endif
122   /* 0x90 - 0x9d are for Dimension-2 official charsets */
123   /* 0x9e is for Dimension-1 private charsets */
124   /* 0x9f is for Dimension-2 private charsets */
125   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4
126 };
127 #endif
128
129 #ifdef UTF2000
130 Emchar_to_byte_table*
131 make_byte_from_character_table ()
132 {
133   Emchar_to_byte_table* table
134     = (Emchar_to_byte_table*) xmalloc (sizeof (Emchar_to_byte_table));
135
136   table->base = NULL;
137   return table;
138 }
139
140 void
141 put_byte_from_character_table (Emchar ch, unsigned char val,
142                                Emchar_to_byte_table* table)
143 {
144   if (table->base == NULL)
145     {
146       table->base = xmalloc (128);
147       table->offset = ch - (ch % 128);
148       table->size = 128;
149       table->base[ch - table->offset] = val;
150     }
151   else
152     {
153       int i = ch - table->offset;
154
155       if (i < 0)
156         {
157           size_t new_size = table->size - i;
158           size_t j;
159
160           new_size += 128 - (new_size % 128);
161           table->base = xrealloc (table->base, new_size);
162           memmove (table->base + (new_size - table->size), table->base,
163                    table->size);
164           for (j = 0; j < (new_size - table->size); j++)
165             table->base[j] = 0;
166           table->offset -= (new_size - table->size);
167           table->base[ch - table->offset] = val;
168           table->size = new_size;
169         }
170       else if (i >= table->size)
171         {
172           size_t new_size = i + 1;
173           size_t j;
174
175           new_size += 128 - (new_size % 128);
176           table->base = xrealloc (table->base, new_size);
177           for (j = table->size; j < new_size; j++)
178             table->base[j] = 0;
179           table->base[i] = val;
180           table->size = new_size;
181         }
182       else
183         {
184           table->base[i] = val;
185         }
186     }
187 }
188
189 unsigned char
190 get_byte_from_character_table (Emchar ch, Emchar_to_byte_table* table)
191 {
192   size_t i = ch - table->offset;
193   if (i < table->size)
194     return table->base[i];
195   else
196     return 0;
197 }
198
199 #define CHAR96(ft,b)    (MIN_CHAR_96 + (ft - '0') * 96 + (b & 0x7f) - 32)
200
201 Emchar latin_jisx0201_to_ucs[94] =
202 {
203   0x0021 /* 0x21        EXCLAMATION MARK */,
204   0x0022 /* 0x22        QUOTATION MARK */,
205   0x0023 /* 0x23        NUMBER SIGN */,
206   0x0024 /* 0x24        DOLLAR SIGN */,
207   0x0025 /* 0x25        PERCENT SIGN */,
208   0x0026 /* 0x26        AMPERSAND */,
209   0x0027 /* 0x27        APOSTROPHE */,
210   0x0028 /* 0x28        LEFT PARENTHESIS */,
211   0x0029 /* 0x29        RIGHT PARENTHESIS */,
212   0x002A /* 0x2A        ASTERISK */,
213   0x002B /* 0x2B        PLUS SIGN */,
214   0x002C /* 0x2C        COMMA */,
215   0x002D /* 0x2D        HYPHEN-MINUS */,
216   0x002E /* 0x2E        FULL STOP */,
217   0x002F /* 0x2F        SOLIDUS */,
218   0x0030 /* 0x30        DIGIT ZERO */,
219   0x0031 /* 0x31        DIGIT ONE */,
220   0x0032 /* 0x32        DIGIT TWO */,
221   0x0033 /* 0x33        DIGIT THREE */,
222   0x0034 /* 0x34        DIGIT FOUR */,
223   0x0035 /* 0x35        DIGIT FIVE */,
224   0x0036 /* 0x36        DIGIT SIX */,
225   0x0037 /* 0x37        DIGIT SEVEN */,
226   0x0038 /* 0x38        DIGIT EIGHT */,
227   0x0039 /* 0x39        DIGIT NINE */,
228   0x003A /* 0x3A        COLON */,
229   0x003B /* 0x3B        SEMICOLON */,
230   0x003C /* 0x3C        LESS-THAN SIGN */,
231   0x003D /* 0x3D        EQUALS SIGN */,
232   0x003E /* 0x3E        GREATER-THAN SIGN */,
233   0x003F /* 0x3F        QUESTION MARK */,
234   0x0040 /* 0x40        COMMERCIAL AT */,
235   0x0041 /* 0x41        LATIN CAPITAL LETTER A */,
236   0x0042 /* 0x42        LATIN CAPITAL LETTER B */,
237   0x0043 /* 0x43        LATIN CAPITAL LETTER C */,
238   0x0044 /* 0x44        LATIN CAPITAL LETTER D */,
239   0x0045 /* 0x45        LATIN CAPITAL LETTER E */,
240   0x0046 /* 0x46        LATIN CAPITAL LETTER F */,
241   0x0047 /* 0x47        LATIN CAPITAL LETTER G */,
242   0x0048 /* 0x48        LATIN CAPITAL LETTER H */,
243   0x0049 /* 0x49        LATIN CAPITAL LETTER I */,
244   0x004A /* 0x4A        LATIN CAPITAL LETTER J */,
245   0x004B /* 0x4B        LATIN CAPITAL LETTER K */,
246   0x004C /* 0x4C        LATIN CAPITAL LETTER L */,
247   0x004D /* 0x4D        LATIN CAPITAL LETTER M */,
248   0x004E /* 0x4E        LATIN CAPITAL LETTER N */,
249   0x004F /* 0x4F        LATIN CAPITAL LETTER O */,
250   0x0050 /* 0x50        LATIN CAPITAL LETTER P */,
251   0x0051 /* 0x51        LATIN CAPITAL LETTER Q */,
252   0x0052 /* 0x52        LATIN CAPITAL LETTER R */,
253   0x0053 /* 0x53        LATIN CAPITAL LETTER S */,
254   0x0054 /* 0x54        LATIN CAPITAL LETTER T */,
255   0x0055 /* 0x55        LATIN CAPITAL LETTER U */,
256   0x0056 /* 0x56        LATIN CAPITAL LETTER V */,
257   0x0057 /* 0x57        LATIN CAPITAL LETTER W */,
258   0x0058 /* 0x58        LATIN CAPITAL LETTER X */,
259   0x0059 /* 0x59        LATIN CAPITAL LETTER Y */,
260   0x005A /* 0x5A        LATIN CAPITAL LETTER Z */,
261   0x005B /* 0x5B        LEFT SQUARE BRACKET */,
262   0x00A5 /* 0x5C        YEN SIGN */,
263   0x005D /* 0x5D        RIGHT SQUARE BRACKET */,
264   0x005E /* 0x5E        CIRCUMFLEX ACCENT */,
265   0x005F /* 0x5F        LOW LINE */,
266   0x0060 /* 0x60        GRAVE ACCENT */,
267   0x0061 /* 0x61        LATIN SMALL LETTER A */,
268   0x0062 /* 0x62        LATIN SMALL LETTER B */,
269   0x0063 /* 0x63        LATIN SMALL LETTER C */,
270   0x0064 /* 0x64        LATIN SMALL LETTER D */,
271   0x0065 /* 0x65        LATIN SMALL LETTER E */,
272   0x0066 /* 0x66        LATIN SMALL LETTER F */,
273   0x0067 /* 0x67        LATIN SMALL LETTER G */,
274   0x0068 /* 0x68        LATIN SMALL LETTER H */,
275   0x0069 /* 0x69        LATIN SMALL LETTER I */,
276   0x006A /* 0x6A        LATIN SMALL LETTER J */,
277   0x006B /* 0x6B        LATIN SMALL LETTER K */,
278   0x006C /* 0x6C        LATIN SMALL LETTER L */,
279   0x006D /* 0x6D        LATIN SMALL LETTER M */,
280   0x006E /* 0x6E        LATIN SMALL LETTER N */,
281   0x006F /* 0x6F        LATIN SMALL LETTER O */,
282   0x0070 /* 0x70        LATIN SMALL LETTER P */,
283   0x0071 /* 0x71        LATIN SMALL LETTER Q */,
284   0x0072 /* 0x72        LATIN SMALL LETTER R */,
285   0x0073 /* 0x73        LATIN SMALL LETTER S */,
286   0x0074 /* 0x74        LATIN SMALL LETTER T */,
287   0x0075 /* 0x75        LATIN SMALL LETTER U */,
288   0x0076 /* 0x76        LATIN SMALL LETTER V */,
289   0x0077 /* 0x77        LATIN SMALL LETTER W */,
290   0x0078 /* 0x78        LATIN SMALL LETTER X */,
291   0x0079 /* 0x79        LATIN SMALL LETTER Y */,
292   0x007A /* 0x7A        LATIN SMALL LETTER Z */,
293   0x007B /* 0x7B        LEFT CURLY BRACKET */,
294   0x007C /* 0x7C        VERTICAL LINE */,
295   0x007D /* 0x7D        RIGHT CURLY BRACKET */,
296   0x203E /* 0x7E        OVERLINE */
297 };
298
299 Emchar latin_iso8859_2_to_ucs[96] =
300 {
301   0x00A0 /* 0xA0        NO-BREAK SPACE */,
302   0x0104 /* 0xA1        LATIN CAPITAL LETTER A WITH OGONEK */,
303   0x02D8 /* 0xA2        BREVE */,
304   0x0141 /* 0xA3        LATIN CAPITAL LETTER L WITH STROKE */,
305   0x00A4 /* 0xA4        CURRENCY SIGN */,
306   0x013D /* 0xA5        LATIN CAPITAL LETTER L WITH CARON */,
307   0x015A /* 0xA6        LATIN CAPITAL LETTER S WITH ACUTE */,
308   0x00A7 /* 0xA7        SECTION SIGN */,
309   0x00A8 /* 0xA8        DIAERESIS */,
310   0x0160 /* 0xA9        LATIN CAPITAL LETTER S WITH CARON */,
311   0x015E /* 0xAA        LATIN CAPITAL LETTER S WITH CEDILLA */,
312   0x0164 /* 0xAB        LATIN CAPITAL LETTER T WITH CARON */,
313   0x0179 /* 0xAC        LATIN CAPITAL LETTER Z WITH ACUTE */,
314   0x00AD /* 0xAD        SOFT HYPHEN */,
315   0x017D /* 0xAE        LATIN CAPITAL LETTER Z WITH CARON */,
316   0x017B /* 0xAF        LATIN CAPITAL LETTER Z WITH DOT ABOVE */,
317   0x00B0 /* 0xB0        DEGREE SIGN */,
318   0x0105 /* 0xB1        LATIN SMALL LETTER A WITH OGONEK */,
319   0x02DB /* 0xB2        OGONEK */,
320   0x0142 /* 0xB3        LATIN SMALL LETTER L WITH STROKE */,
321   0x00B4 /* 0xB4        ACUTE ACCENT */,
322   0x013E /* 0xB5        LATIN SMALL LETTER L WITH CARON */,
323   0x015B /* 0xB6        LATIN SMALL LETTER S WITH ACUTE */,
324   0x02C7 /* 0xB7        CARON */,
325   0x00B8 /* 0xB8        CEDILLA */,
326   0x0161 /* 0xB9        LATIN SMALL LETTER S WITH CARON */,
327   0x015F /* 0xBA        LATIN SMALL LETTER S WITH CEDILLA */,
328   0x0165 /* 0xBB        LATIN SMALL LETTER T WITH CARON */,
329   0x017A /* 0xBC        LATIN SMALL LETTER Z WITH ACUTE */,
330   0x02DD /* 0xBD        DOUBLE ACUTE ACCENT */,
331   0x017E /* 0xBE        LATIN SMALL LETTER Z WITH CARON */,
332   0x017C /* 0xBF        LATIN SMALL LETTER Z WITH DOT ABOVE */,
333   0x0154 /* 0xC0        LATIN CAPITAL LETTER R WITH ACUTE */,
334   0x00C1 /* 0xC1        LATIN CAPITAL LETTER A WITH ACUTE */,
335   0x00C2 /* 0xC2        LATIN CAPITAL LETTER A WITH CIRCUMFLEX */,
336   0x0102 /* 0xC3        LATIN CAPITAL LETTER A WITH BREVE */,
337   0x00C4 /* 0xC4        LATIN CAPITAL LETTER A WITH DIAERESIS */,
338   0x0139 /* 0xC5        LATIN CAPITAL LETTER L WITH ACUTE */,
339   0x0106 /* 0xC6        LATIN CAPITAL LETTER C WITH ACUTE */,
340   0x00C7 /* 0xC7        LATIN CAPITAL LETTER C WITH CEDILLA */,
341   0x010C /* 0xC8        LATIN CAPITAL LETTER C WITH CARON */,
342   0x00C9 /* 0xC9        LATIN CAPITAL LETTER E WITH ACUTE */,
343   0x0118 /* 0xCA        LATIN CAPITAL LETTER E WITH OGONEK */,
344   0x00CB /* 0xCB        LATIN CAPITAL LETTER E WITH DIAERESIS */,
345   0x011A /* 0xCC        LATIN CAPITAL LETTER E WITH CARON */,
346   0x00CD /* 0xCD        LATIN CAPITAL LETTER I WITH ACUTE */,
347   0x00CE /* 0xCE        LATIN CAPITAL LETTER I WITH CIRCUMFLEX */,
348   0x010E /* 0xCF        LATIN CAPITAL LETTER D WITH CARON */,
349   0x0110 /* 0xD0        LATIN CAPITAL LETTER D WITH STROKE */,
350   0x0143 /* 0xD1        LATIN CAPITAL LETTER N WITH ACUTE */,
351   0x0147 /* 0xD2        LATIN CAPITAL LETTER N WITH CARON */,
352   0x00D3 /* 0xD3        LATIN CAPITAL LETTER O WITH ACUTE */,
353   0x00D4 /* 0xD4        LATIN CAPITAL LETTER O WITH CIRCUMFLEX */,
354   0x0150 /* 0xD5        LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */,
355   0x00D6 /* 0xD6        LATIN CAPITAL LETTER O WITH DIAERESIS */,
356   0x00D7 /* 0xD7        MULTIPLICATION SIGN */,
357   0x0158 /* 0xD8        LATIN CAPITAL LETTER R WITH CARON */,
358   0x016E /* 0xD9        LATIN CAPITAL LETTER U WITH RING ABOVE */,
359   0x00DA /* 0xDA        LATIN CAPITAL LETTER U WITH ACUTE */,
360   0x0170 /* 0xDB        LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */,
361   0x00DC /* 0xDC        LATIN CAPITAL LETTER U WITH DIAERESIS */,
362   0x00DD /* 0xDD        LATIN CAPITAL LETTER Y WITH ACUTE */,
363   0x0162 /* 0xDE        LATIN CAPITAL LETTER T WITH CEDILLA */,
364   0x00DF /* 0xDF        LATIN SMALL LETTER SHARP S */,
365   0x0155 /* 0xE0        LATIN SMALL LETTER R WITH ACUTE */,
366   0x00E1 /* 0xE1        LATIN SMALL LETTER A WITH ACUTE */,
367   0x00E2 /* 0xE2        LATIN SMALL LETTER A WITH CIRCUMFLEX */,
368   0x0103 /* 0xE3        LATIN SMALL LETTER A WITH BREVE */,
369   0x00E4 /* 0xE4        LATIN SMALL LETTER A WITH DIAERESIS */,
370   0x013A /* 0xE5        LATIN SMALL LETTER L WITH ACUTE */,
371   0x0107 /* 0xE6        LATIN SMALL LETTER C WITH ACUTE */,
372   0x00E7 /* 0xE7        LATIN SMALL LETTER C WITH CEDILLA */,
373   0x010D /* 0xE8        LATIN SMALL LETTER C WITH CARON */,
374   0x00E9 /* 0xE9        LATIN SMALL LETTER E WITH ACUTE */,
375   0x0119 /* 0xEA        LATIN SMALL LETTER E WITH OGONEK */,
376   0x00EB /* 0xEB        LATIN SMALL LETTER E WITH DIAERESIS */,
377   0x011B /* 0xEC        LATIN SMALL LETTER E WITH CARON */,
378   0x00ED /* 0xED        LATIN SMALL LETTER I WITH ACUTE */,
379   0x00EE /* 0xEE        LATIN SMALL LETTER I WITH CIRCUMFLEX */,
380   0x010F /* 0xEF        LATIN SMALL LETTER D WITH CARON */,
381   0x0111 /* 0xF0        LATIN SMALL LETTER D WITH STROKE */,
382   0x0144 /* 0xF1        LATIN SMALL LETTER N WITH ACUTE */,
383   0x0148 /* 0xF2        LATIN SMALL LETTER N WITH CARON */,
384   0x00F3 /* 0xF3        LATIN SMALL LETTER O WITH ACUTE */,
385   0x00F4 /* 0xF4        LATIN SMALL LETTER O WITH CIRCUMFLEX */,
386   0x0151 /* 0xF5        LATIN SMALL LETTER O WITH DOUBLE ACUTE */,
387   0x00F6 /* 0xF6        LATIN SMALL LETTER O WITH DIAERESIS */,
388   0x00F7 /* 0xF7        DIVISION SIGN */,
389   0x0159 /* 0xF8        LATIN SMALL LETTER R WITH CARON */,
390   0x016F /* 0xF9        LATIN SMALL LETTER U WITH RING ABOVE */,
391   0x00FA /* 0xFA        LATIN SMALL LETTER U WITH ACUTE */,
392   0x0171 /* 0xFB        LATIN SMALL LETTER U WITH DOUBLE ACUTE */,
393   0x00FC /* 0xFC        LATIN SMALL LETTER U WITH DIAERESIS */,
394   0x00FD /* 0xFD        LATIN SMALL LETTER Y WITH ACUTE */,
395   0x0163 /* 0xFE        LATIN SMALL LETTER T WITH CEDILLA */,
396   0x02D9 /* 0xFF        DOT ABOVE */
397 };
398
399 Emchar latin_iso8859_3_to_ucs[96] =
400 {
401   0x00A0 /* 0xA0        NO-BREAK SPACE */,
402   0x0126 /* 0xA1        LATIN CAPITAL LETTER H WITH STROKE */,
403   0x02D8 /* 0xA2        BREVE */,
404   0x00A3 /* 0xA3        POUND SIGN */,
405   0x00A4 /* 0xA4        CURRENCY SIGN */,
406   CHAR96('C', 0xA5),
407   0x0124 /* 0xA6        LATIN CAPITAL LETTER H WITH CIRCUMFLEX */,
408   0x00A7 /* 0xA7        SECTION SIGN */,
409   0x00A8 /* 0xA8        DIAERESIS */,
410   0x0130 /* 0xA9        LATIN CAPITAL LETTER I WITH DOT ABOVE */,
411   0x015E /* 0xAA        LATIN CAPITAL LETTER S WITH CEDILLA */,
412   0x011E /* 0xAB        LATIN CAPITAL LETTER G WITH BREVE */,
413   0x0134 /* 0xAC        LATIN CAPITAL LETTER J WITH CIRCUMFLEX */,
414   0x00AD /* 0xAD        SOFT HYPHEN */,
415   CHAR96('C', 0xAE),
416   0x017B /* 0xAF        LATIN CAPITAL LETTER Z WITH DOT ABOVE */,
417   0x00B0 /* 0xB0        DEGREE SIGN */,
418   0x0127 /* 0xB1        LATIN SMALL LETTER H WITH STROKE */,
419   0x00B2 /* 0xB2        SUPERSCRIPT TWO */,
420   0x00B3 /* 0xB3        SUPERSCRIPT THREE */,
421   0x00B4 /* 0xB4        ACUTE ACCENT */,
422   0x00B5 /* 0xB5        MICRO SIGN */,
423   0x0125 /* 0xB6        LATIN SMALL LETTER H WITH CIRCUMFLEX */,
424   0x00B7 /* 0xB7        MIDDLE DOT */,
425   0x00B8 /* 0xB8        CEDILLA */,
426   0x0131 /* 0xB9        LATIN SMALL LETTER DOTLESS I */,
427   0x015F /* 0xBA        LATIN SMALL LETTER S WITH CEDILLA */,
428   0x011F /* 0xBB        LATIN SMALL LETTER G WITH BREVE */,
429   0x0135 /* 0xBC        LATIN SMALL LETTER J WITH CIRCUMFLEX */,
430   0x00BD /* 0xBD        VULGAR FRACTION ONE HALF */,
431   CHAR96('C', 0xBE),
432   0x017C /* 0xBF        LATIN SMALL LETTER Z WITH DOT ABOVE */,
433   0x00C0 /* 0xC0        LATIN CAPITAL LETTER A WITH GRAVE */,
434   0x00C1 /* 0xC1        LATIN CAPITAL LETTER A WITH ACUTE */,
435   0x00C2 /* 0xC2        LATIN CAPITAL LETTER A WITH CIRCUMFLEX */,
436   CHAR96('C', 0xC3),
437   0x00C4 /* 0xC4        LATIN CAPITAL LETTER A WITH DIAERESIS */,
438   0x010A /* 0xC5        LATIN CAPITAL LETTER C WITH DOT ABOVE */,
439   0x0108 /* 0xC6        LATIN CAPITAL LETTER C WITH CIRCUMFLEX */,
440   0x00C7 /* 0xC7        LATIN CAPITAL LETTER C WITH CEDILLA */,
441   0x00C8 /* 0xC8        LATIN CAPITAL LETTER E WITH GRAVE */,
442   0x00C9 /* 0xC9        LATIN CAPITAL LETTER E WITH ACUTE */,
443   0x00CA /* 0xCA        LATIN CAPITAL LETTER E WITH CIRCUMFLEX */,
444   0x00CB /* 0xCB        LATIN CAPITAL LETTER E WITH DIAERESIS */,
445   0x00CC /* 0xCC        LATIN CAPITAL LETTER I WITH GRAVE */,
446   0x00CD /* 0xCD        LATIN CAPITAL LETTER I WITH ACUTE */,
447   0x00CE /* 0xCE        LATIN CAPITAL LETTER I WITH CIRCUMFLEX */,
448   0x00CF /* 0xCF        LATIN CAPITAL LETTER I WITH DIAERESIS */,
449   CHAR96('C', 0xD0),
450   0x00D1 /* 0xD1        LATIN CAPITAL LETTER N WITH TILDE */,
451   0x00D2 /* 0xD2        LATIN CAPITAL LETTER O WITH GRAVE */,
452   0x00D3 /* 0xD3        LATIN CAPITAL LETTER O WITH ACUTE */,
453   0x00D4 /* 0xD4        LATIN CAPITAL LETTER O WITH CIRCUMFLEX */,
454   0x0120 /* 0xD5        LATIN CAPITAL LETTER G WITH DOT ABOVE */,
455   0x00D6 /* 0xD6        LATIN CAPITAL LETTER O WITH DIAERESIS */,
456   0x00D7 /* 0xD7        MULTIPLICATION SIGN */,
457   0x011C /* 0xD8        LATIN CAPITAL LETTER G WITH CIRCUMFLEX */,
458   0x00D9 /* 0xD9        LATIN CAPITAL LETTER U WITH GRAVE */,
459   0x00DA /* 0xDA        LATIN CAPITAL LETTER U WITH ACUTE */,
460   0x00DB /* 0xDB        LATIN CAPITAL LETTER U WITH CIRCUMFLEX */,
461   0x00DC /* 0xDC        LATIN CAPITAL LETTER U WITH DIAERESIS */,
462   0x016C /* 0xDD        LATIN CAPITAL LETTER U WITH BREVE */,
463   0x015C /* 0xDE        LATIN CAPITAL LETTER S WITH CIRCUMFLEX */,
464   0x00DF /* 0xDF        LATIN SMALL LETTER SHARP S */,
465   0x00E0 /* 0xE0        LATIN SMALL LETTER A WITH GRAVE */,
466   0x00E1 /* 0xE1        LATIN SMALL LETTER A WITH ACUTE */,
467   0x00E2 /* 0xE2        LATIN SMALL LETTER A WITH CIRCUMFLEX */,
468   CHAR96('C', 0xE3),
469   0x00E4 /* 0xE4        LATIN SMALL LETTER A WITH DIAERESIS */,
470   0x010B /* 0xE5        LATIN SMALL LETTER C WITH DOT ABOVE */,
471   0x0109 /* 0xE6        LATIN SMALL LETTER C WITH CIRCUMFLEX */,
472   0x00E7 /* 0xE7        LATIN SMALL LETTER C WITH CEDILLA */,
473   0x00E8 /* 0xE8        LATIN SMALL LETTER E WITH GRAVE */,
474   0x00E9 /* 0xE9        LATIN SMALL LETTER E WITH ACUTE */,
475   0x00EA /* 0xEA        LATIN SMALL LETTER E WITH CIRCUMFLEX */,
476   0x00EB /* 0xEB        LATIN SMALL LETTER E WITH DIAERESIS */,
477   0x00EC /* 0xEC        LATIN SMALL LETTER I WITH GRAVE */,
478   0x00ED /* 0xED        LATIN SMALL LETTER I WITH ACUTE */,
479   0x00EE /* 0xEE        LATIN SMALL LETTER I WITH CIRCUMFLEX */,
480   0x00EF /* 0xEF        LATIN SMALL LETTER I WITH DIAERESIS */,
481   CHAR96('C', 0xF0),
482   0x00F1 /* 0xF1        LATIN SMALL LETTER N WITH TILDE */,
483   0x00F2 /* 0xF2        LATIN SMALL LETTER O WITH GRAVE */,
484   0x00F3 /* 0xF3        LATIN SMALL LETTER O WITH ACUTE */,
485   0x00F4 /* 0xF4        LATIN SMALL LETTER O WITH CIRCUMFLEX */,
486   0x0121 /* 0xF5        LATIN SMALL LETTER G WITH DOT ABOVE */,
487   0x00F6 /* 0xF6        LATIN SMALL LETTER O WITH DIAERESIS */,
488   0x00F7 /* 0xF7        DIVISION SIGN */,
489   0x011D /* 0xF8        LATIN SMALL LETTER G WITH CIRCUMFLEX */,
490   0x00F9 /* 0xF9        LATIN SMALL LETTER U WITH GRAVE */,
491   0x00FA /* 0xFA        LATIN SMALL LETTER U WITH ACUTE */,
492   0x00FB /* 0xFB        LATIN SMALL LETTER U WITH CIRCUMFLEX */,
493   0x00FC /* 0xFC        LATIN SMALL LETTER U WITH DIAERESIS */,
494   0x016D /* 0xFD        LATIN SMALL LETTER U WITH BREVE */,
495   0x015D /* 0xFE        LATIN SMALL LETTER S WITH CIRCUMFLEX */,
496   0x02D9 /* 0xFF        DOT ABOVE */
497 };
498
499 Emchar latin_iso8859_4_to_ucs[96] =
500 {
501   0x00A0 /* 0xA0        NO-BREAK SPACE */,
502   0x0104 /* 0xA1        LATIN CAPITAL LETTER A WITH OGONEK */,
503   0x0138 /* 0xA2        LATIN SMALL LETTER KRA */,
504   0x0156 /* 0xA3        LATIN CAPITAL LETTER R WITH CEDILLA */,
505   0x00A4 /* 0xA4        CURRENCY SIGN */,
506   0x0128 /* 0xA5        LATIN CAPITAL LETTER I WITH TILDE */,
507   0x013B /* 0xA6        LATIN CAPITAL LETTER L WITH CEDILLA */,
508   0x00A7 /* 0xA7        SECTION SIGN */,
509   0x00A8 /* 0xA8        DIAERESIS */,
510   0x0160 /* 0xA9        LATIN CAPITAL LETTER S WITH CARON */,
511   0x0112 /* 0xAA        LATIN CAPITAL LETTER E WITH MACRON */,
512   0x0122 /* 0xAB        LATIN CAPITAL LETTER G WITH CEDILLA */,
513   0x0166 /* 0xAC        LATIN CAPITAL LETTER T WITH STROKE */,
514   0x00AD /* 0xAD        SOFT HYPHEN */,
515   0x017D /* 0xAE        LATIN CAPITAL LETTER Z WITH CARON */,
516   0x00AF /* 0xAF        MACRON */,
517   0x00B0 /* 0xB0        DEGREE SIGN */,
518   0x0105 /* 0xB1        LATIN SMALL LETTER A WITH OGONEK */,
519   0x02DB /* 0xB2        OGONEK */,
520   0x0157 /* 0xB3        LATIN SMALL LETTER R WITH CEDILLA */,
521   0x00B4 /* 0xB4        ACUTE ACCENT */,
522   0x0129 /* 0xB5        LATIN SMALL LETTER I WITH TILDE */,
523   0x013C /* 0xB6        LATIN SMALL LETTER L WITH CEDILLA */,
524   0x02C7 /* 0xB7        CARON */,
525   0x00B8 /* 0xB8        CEDILLA */,
526   0x0161 /* 0xB9        LATIN SMALL LETTER S WITH CARON */,
527   0x0113 /* 0xBA        LATIN SMALL LETTER E WITH MACRON */,
528   0x0123 /* 0xBB        LATIN SMALL LETTER G WITH CEDILLA */,
529   0x0167 /* 0xBC        LATIN SMALL LETTER T WITH STROKE */,
530   0x014A /* 0xBD        LATIN CAPITAL LETTER ENG */,
531   0x017E /* 0xBE        LATIN SMALL LETTER Z WITH CARON */,
532   0x014B /* 0xBF        LATIN SMALL LETTER ENG */,
533   0x0100 /* 0xC0        LATIN CAPITAL LETTER A WITH MACRON */,
534   0x00C1 /* 0xC1        LATIN CAPITAL LETTER A WITH ACUTE */,
535   0x00C2 /* 0xC2        LATIN CAPITAL LETTER A WITH CIRCUMFLEX */,
536   0x00C3 /* 0xC3        LATIN CAPITAL LETTER A WITH TILDE */,
537   0x00C4 /* 0xC4        LATIN CAPITAL LETTER A WITH DIAERESIS */,
538   0x00C5 /* 0xC5        LATIN CAPITAL LETTER A WITH RING ABOVE */,
539   0x00C6 /* 0xC6        LATIN CAPITAL LETTER AE */,
540   0x012E /* 0xC7        LATIN CAPITAL LETTER I WITH OGONEK */,
541   0x010C /* 0xC8        LATIN CAPITAL LETTER C WITH CARON */,
542   0x00C9 /* 0xC9        LATIN CAPITAL LETTER E WITH ACUTE */,
543   0x0118 /* 0xCA        LATIN CAPITAL LETTER E WITH OGONEK */,
544   0x00CB /* 0xCB        LATIN CAPITAL LETTER E WITH DIAERESIS */,
545   0x0116 /* 0xCC        LATIN CAPITAL LETTER E WITH DOT ABOVE */,
546   0x00CD /* 0xCD        LATIN CAPITAL LETTER I WITH ACUTE */,
547   0x00CE /* 0xCE        LATIN CAPITAL LETTER I WITH CIRCUMFLEX */,
548   0x012A /* 0xCF        LATIN CAPITAL LETTER I WITH MACRON */,
549   0x0110 /* 0xD0        LATIN CAPITAL LETTER D WITH STROKE */,
550   0x0145 /* 0xD1        LATIN CAPITAL LETTER N WITH CEDILLA */,
551   0x014C /* 0xD2        LATIN CAPITAL LETTER O WITH MACRON */,
552   0x0136 /* 0xD3        LATIN CAPITAL LETTER K WITH CEDILLA */,
553   0x00D4 /* 0xD4        LATIN CAPITAL LETTER O WITH CIRCUMFLEX */,
554   0x00D5 /* 0xD5        LATIN CAPITAL LETTER O WITH TILDE */,
555   0x00D6 /* 0xD6        LATIN CAPITAL LETTER O WITH DIAERESIS */,
556   0x00D7 /* 0xD7        MULTIPLICATION SIGN */,
557   0x00D8 /* 0xD8        LATIN CAPITAL LETTER O WITH STROKE */,
558   0x0172 /* 0xD9        LATIN CAPITAL LETTER U WITH OGONEK */,
559   0x00DA /* 0xDA        LATIN CAPITAL LETTER U WITH ACUTE */,
560   0x00DB /* 0xDB        LATIN CAPITAL LETTER U WITH CIRCUMFLEX */,
561   0x00DC /* 0xDC        LATIN CAPITAL LETTER U WITH DIAERESIS */,
562   0x0168 /* 0xDD        LATIN CAPITAL LETTER U WITH TILDE */,
563   0x016A /* 0xDE        LATIN CAPITAL LETTER U WITH MACRON */,
564   0x00DF /* 0xDF        LATIN SMALL LETTER SHARP S */,
565   0x0101 /* 0xE0        LATIN SMALL LETTER A WITH MACRON */,
566   0x00E1 /* 0xE1        LATIN SMALL LETTER A WITH ACUTE */,
567   0x00E2 /* 0xE2        LATIN SMALL LETTER A WITH CIRCUMFLEX */,
568   0x00E3 /* 0xE3        LATIN SMALL LETTER A WITH TILDE */,
569   0x00E4 /* 0xE4        LATIN SMALL LETTER A WITH DIAERESIS */,
570   0x00E5 /* 0xE5        LATIN SMALL LETTER A WITH RING ABOVE */,
571   0x00E6 /* 0xE6        LATIN SMALL LETTER AE */,
572   0x012F /* 0xE7        LATIN SMALL LETTER I WITH OGONEK */,
573   0x010D /* 0xE8        LATIN SMALL LETTER C WITH CARON */,
574   0x00E9 /* 0xE9        LATIN SMALL LETTER E WITH ACUTE */,
575   0x0119 /* 0xEA        LATIN SMALL LETTER E WITH OGONEK */,
576   0x00EB /* 0xEB        LATIN SMALL LETTER E WITH DIAERESIS */,
577   0x0117 /* 0xEC        LATIN SMALL LETTER E WITH DOT ABOVE */,
578   0x00ED /* 0xED        LATIN SMALL LETTER I WITH ACUTE */,
579   0x00EE /* 0xEE        LATIN SMALL LETTER I WITH CIRCUMFLEX */,
580   0x012B /* 0xEF        LATIN SMALL LETTER I WITH MACRON */,
581   0x0111 /* 0xF0        LATIN SMALL LETTER D WITH STROKE */,
582   0x0146 /* 0xF1        LATIN SMALL LETTER N WITH CEDILLA */,
583   0x014D /* 0xF2        LATIN SMALL LETTER O WITH MACRON */,
584   0x0137 /* 0xF3        LATIN SMALL LETTER K WITH CEDILLA */,
585   0x00F4 /* 0xF4        LATIN SMALL LETTER O WITH CIRCUMFLEX */,
586   0x00F5 /* 0xF5        LATIN SMALL LETTER O WITH TILDE */,
587   0x00F6 /* 0xF6        LATIN SMALL LETTER O WITH DIAERESIS */,
588   0x00F7 /* 0xF7        DIVISION SIGN */,
589   0x00F8 /* 0xF8        LATIN SMALL LETTER O WITH STROKE */,
590   0x0173 /* 0xF9        LATIN SMALL LETTER U WITH OGONEK */,
591   0x00FA /* 0xFA        LATIN SMALL LETTER U WITH ACUTE */,
592   0x00FB /* 0xFB        LATIN SMALL LETTER U WITH CIRCUMFLEX */,
593   0x00FC /* 0xFC        LATIN SMALL LETTER U WITH DIAERESIS */,
594   0x0169 /* 0xFD        LATIN SMALL LETTER U WITH TILDE */,
595   0x016B /* 0xFE        LATIN SMALL LETTER U WITH MACRON */,
596   0x02D9 /* 0xFF        DOT ABOVE */
597 };
598
599 Emchar latin_iso8859_9_to_ucs[96] =
600 {
601   0x00A0 /* 0xA0        NO-BREAK SPACE */,
602   0x00A1 /* 0xA1        INVERTED EXCLAMATION MARK */,
603   0x00A2 /* 0xA2        CENT SIGN */,
604   0x00A3 /* 0xA3        POUND SIGN */,
605   0x00A4 /* 0xA4        CURRENCY SIGN */,
606   0x00A5 /* 0xA5        YEN SIGN */,
607   0x00A6 /* 0xA6        BROKEN BAR */,
608   0x00A7 /* 0xA7        SECTION SIGN */,
609   0x00A8 /* 0xA8        DIAERESIS */,
610   0x00A9 /* 0xA9        COPYRIGHT SIGN */,
611   0x00AA /* 0xAA        FEMININE ORDINAL INDICATOR */,
612   0x00AB /* 0xAB        LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */,
613   0x00AC /* 0xAC        NOT SIGN */,
614   0x00AD /* 0xAD        SOFT HYPHEN */,
615   0x00AE /* 0xAE        REGISTERED SIGN */,
616   0x00AF /* 0xAF        MACRON */,
617   0x00B0 /* 0xB0        DEGREE SIGN */,
618   0x00B1 /* 0xB1        PLUS-MINUS SIGN */,
619   0x00B2 /* 0xB2        SUPERSCRIPT TWO */,
620   0x00B3 /* 0xB3        SUPERSCRIPT THREE */,
621   0x00B4 /* 0xB4        ACUTE ACCENT */,
622   0x00B5 /* 0xB5        MICRO SIGN */,
623   0x00B6 /* 0xB6        PILCROW SIGN */,
624   0x00B7 /* 0xB7        MIDDLE DOT */,
625   0x00B8 /* 0xB8        CEDILLA */,
626   0x00B9 /* 0xB9        SUPERSCRIPT ONE */,
627   0x00BA /* 0xBA        MASCULINE ORDINAL INDICATOR */,
628   0x00BB /* 0xBB        RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */,
629   0x00BC /* 0xBC        VULGAR FRACTION ONE QUARTER */,
630   0x00BD /* 0xBD        VULGAR FRACTION ONE HALF */,
631   0x00BE /* 0xBE        VULGAR FRACTION THREE QUARTERS */,
632   0x00BF /* 0xBF        INVERTED QUESTION MARK */,
633   0x00C0 /* 0xC0        LATIN CAPITAL LETTER A WITH GRAVE */,
634   0x00C1 /* 0xC1        LATIN CAPITAL LETTER A WITH ACUTE */,
635   0x00C2 /* 0xC2        LATIN CAPITAL LETTER A WITH CIRCUMFLEX */,
636   0x00C3 /* 0xC3        LATIN CAPITAL LETTER A WITH TILDE */,
637   0x00C4 /* 0xC4        LATIN CAPITAL LETTER A WITH DIAERESIS */,
638   0x00C5 /* 0xC5        LATIN CAPITAL LETTER A WITH RING ABOVE */,
639   0x00C6 /* 0xC6        LATIN CAPITAL LETTER AE */,
640   0x00C7 /* 0xC7        LATIN CAPITAL LETTER C WITH CEDILLA */,
641   0x00C8 /* 0xC8        LATIN CAPITAL LETTER E WITH GRAVE */,
642   0x00C9 /* 0xC9        LATIN CAPITAL LETTER E WITH ACUTE */,
643   0x00CA /* 0xCA        LATIN CAPITAL LETTER E WITH CIRCUMFLEX */,
644   0x00CB /* 0xCB        LATIN CAPITAL LETTER E WITH DIAERESIS */,
645   0x00CC /* 0xCC        LATIN CAPITAL LETTER I WITH GRAVE */,
646   0x00CD /* 0xCD        LATIN CAPITAL LETTER I WITH ACUTE */,
647   0x00CE /* 0xCE        LATIN CAPITAL LETTER I WITH CIRCUMFLEX */,
648   0x00CF /* 0xCF        LATIN CAPITAL LETTER I WITH DIAERESIS */,
649   0x011E /* 0xD0        LATIN CAPITAL LETTER G WITH BREVE */,
650   0x00D1 /* 0xD1        LATIN CAPITAL LETTER N WITH TILDE */,
651   0x00D2 /* 0xD2        LATIN CAPITAL LETTER O WITH GRAVE */,
652   0x00D3 /* 0xD3        LATIN CAPITAL LETTER O WITH ACUTE */,
653   0x00D4 /* 0xD4        LATIN CAPITAL LETTER O WITH CIRCUMFLEX */,
654   0x00D5 /* 0xD5        LATIN CAPITAL LETTER O WITH TILDE */,
655   0x00D6 /* 0xD6        LATIN CAPITAL LETTER O WITH DIAERESIS */,
656   0x00D7 /* 0xD7        MULTIPLICATION SIGN */,
657   0x00D8 /* 0xD8        LATIN CAPITAL LETTER O WITH STROKE */,
658   0x00D9 /* 0xD9        LATIN CAPITAL LETTER U WITH GRAVE */,
659   0x00DA /* 0xDA        LATIN CAPITAL LETTER U WITH ACUTE */,
660   0x00DB /* 0xDB        LATIN CAPITAL LETTER U WITH CIRCUMFLEX */,
661   0x00DC /* 0xDC        LATIN CAPITAL LETTER U WITH DIAERESIS */,
662   0x0130 /* 0xDD        LATIN CAPITAL LETTER I WITH DOT ABOVE */,
663   0x015E /* 0xDE        LATIN CAPITAL LETTER S WITH CEDILLA */,
664   0x00DF /* 0xDF        LATIN SMALL LETTER SHARP S */,
665   0x00E0 /* 0xE0        LATIN SMALL LETTER A WITH GRAVE */,
666   0x00E1 /* 0xE1        LATIN SMALL LETTER A WITH ACUTE */,
667   0x00E2 /* 0xE2        LATIN SMALL LETTER A WITH CIRCUMFLEX */,
668   0x00E3 /* 0xE3        LATIN SMALL LETTER A WITH TILDE */,
669   0x00E4 /* 0xE4        LATIN SMALL LETTER A WITH DIAERESIS */,
670   0x00E5 /* 0xE5        LATIN SMALL LETTER A WITH RING ABOVE */,
671   0x00E6 /* 0xE6        LATIN SMALL LETTER AE */,
672   0x00E7 /* 0xE7        LATIN SMALL LETTER C WITH CEDILLA */,
673   0x00E8 /* 0xE8        LATIN SMALL LETTER E WITH GRAVE */,
674   0x00E9 /* 0xE9        LATIN SMALL LETTER E WITH ACUTE */,
675   0x00EA /* 0xEA        LATIN SMALL LETTER E WITH CIRCUMFLEX */,
676   0x00EB /* 0xEB        LATIN SMALL LETTER E WITH DIAERESIS */,
677   0x00EC /* 0xEC        LATIN SMALL LETTER I WITH GRAVE */,
678   0x00ED /* 0xED        LATIN SMALL LETTER I WITH ACUTE */,
679   0x00EE /* 0xEE        LATIN SMALL LETTER I WITH CIRCUMFLEX */,
680   0x00EF /* 0xEF        LATIN SMALL LETTER I WITH DIAERESIS */,
681   0x011F /* 0xF0        LATIN SMALL LETTER G WITH BREVE */,
682   0x00F1 /* 0xF1        LATIN SMALL LETTER N WITH TILDE */,
683   0x00F2 /* 0xF2        LATIN SMALL LETTER O WITH GRAVE */,
684   0x00F3 /* 0xF3        LATIN SMALL LETTER O WITH ACUTE */,
685   0x00F4 /* 0xF4        LATIN SMALL LETTER O WITH CIRCUMFLEX */,
686   0x00F5 /* 0xF5        LATIN SMALL LETTER O WITH TILDE */,
687   0x00F6 /* 0xF6        LATIN SMALL LETTER O WITH DIAERESIS */,
688   0x00F7 /* 0xF7        DIVISION SIGN */,
689   0x00F8 /* 0xF8        LATIN SMALL LETTER O WITH STROKE */,
690   0x00F9 /* 0xF9        LATIN SMALL LETTER U WITH GRAVE */,
691   0x00FA /* 0xFA        LATIN SMALL LETTER U WITH ACUTE */,
692   0x00FB /* 0xFB        LATIN SMALL LETTER U WITH CIRCUMFLEX */,
693   0x00FC /* 0xFC        LATIN SMALL LETTER U WITH DIAERESIS */,
694   0x0131 /* 0xFD        LATIN SMALL LETTER DOTLESS I */,
695   0x015F /* 0xFE        LATIN SMALL LETTER S WITH CEDILLA */,
696   0x00FF /* 0xFF        LATIN SMALL LETTER Y WITH DIAERESIS */,
697 };
698
699 Emchar latin_viscii_lower_to_ucs[96] =
700 {
701   CHAR96('1', 0x20),
702   0x1eaf /* 0x21 */,
703   0x1eb1 /* 0x22 */,
704   0x1eb7 /* 0x23 */,
705   0x1ea5 /* 0x24 */,
706   0x1ea7 /* 0x25 */,
707   0x1ea9 /* 0x26 */,
708   0x1ead /* 0x27 */,
709   0x1ebd /* 0x28 */,
710   0x1eb9 /* 0x29 */,
711   0x1ebf /* 0x2a */,
712   0x1ec1 /* 0x2b */,
713   0x1ec3 /* 0x2c */,
714   0x1ec5 /* 0x2d */,
715   0x1ec7 /* 0x2e */,
716   0x1ed1 /* 0x2f */,
717   0x1ed3 /* 0x30 */,
718   0x1ed5 /* 0x31 */,
719   0x1ed7 /* 0x32 */,
720   CHAR96('1', 0x33),
721   CHAR96('1', 0x34),
722   0x1ed9 /* 0x35 */,
723   0x1edd /* 0x36 */,
724   0x1edf /* 0x37 */,
725   0x1ecb /* 0x38 */,
726   CHAR96('1', 0x39),
727   CHAR96('1', 0x3A),
728   CHAR96('1', 0x3B),
729   CHAR96('1', 0x3C),
730   0x01a1 /* 0x3d */,
731   0x1edb /* 0x3e */,
732   CHAR96('1', 0x3F),
733   CHAR96('1', 0x40),
734   CHAR96('1', 0x41),
735   CHAR96('1', 0x42),
736   CHAR96('1', 0x43),
737   CHAR96('1', 0x44),
738   CHAR96('1', 0x45),
739   0x1eb3 /* 0x46 */,
740   0x1eb5 /* 0x47 */,
741   CHAR96('1', 0x48),
742   CHAR96('1', 0x49),
743   CHAR96('1', 0x4A),
744   CHAR96('1', 0x4B),
745   CHAR96('1', 0x4C),
746   CHAR96('1', 0x4D),
747   CHAR96('1', 0x4E),
748   0x1ef3 /* 0x4f */,
749   CHAR96('1', 0x50),
750   0x1ee9 /* 0x51 */,
751   CHAR96('1', 0x52),
752   CHAR96('1', 0x53),
753   CHAR96('1', 0x54),
754   0x1ea1 /* 0x55 */,
755   0x1ef7 /* 0x56 */,
756   0x1eeb /* 0x57 */,
757   0x1eed /* 0x58 */,
758   CHAR96('1', 0x59),
759   CHAR96('1', 0x5A),
760   0x1ef9 /* 0x5b */,
761   0x1ef5 /* 0x5c */,
762   CHAR96('1', 0x5D),
763   0x1ee1 /* 0x5e */,
764   0x01b0 /* 0x5f */,
765   0x00e0 /* 0x60 */,
766   0x00e1 /* 0x61 */,
767   0x00e2 /* 0x62 */,
768   0x00e3 /* 0x63 */,
769   0x1ea3 /* 0x64 */,
770   0x0103 /* 0x65 */,
771   0x1eef /* 0x66 */,
772   0x1eab /* 0x67 */,
773   0x00e8 /* 0x68 */,
774   0x00e9 /* 0x69 */,
775   0x00ea /* 0x6a */,
776   0x1ebb /* 0x6b */,
777   0x00ec /* 0x6c */,
778   0x00ed /* 0x6d */,
779   0x0129 /* 0x6e */,
780   0x1ec9 /* 0x6f */,
781   0x0111 /* 0x70 */,
782   0x1ef1 /* 0x71 */,
783   0x00f2 /* 0x72 */,
784   0x00f3 /* 0x73 */,
785   0x00f4 /* 0x74 */,
786   0x00f5 /* 0x75 */,
787   0x1ecf /* 0x76 */,
788   0x1ecd /* 0x77 */,
789   0x1ee5 /* 0x78 */,
790   0x00f9 /* 0x79 */,
791   0x00fa /* 0x7a */,
792   0x0169 /* 0x7b */,
793   0x1ee7 /* 0x7c */,
794   0x00fd /* 0x7d */,
795   0x1ee3 /* 0x7e */,
796   CHAR96('1', 0x7F)
797 };
798
799 Emchar latin_viscii_upper_to_ucs[96] =
800 {
801   CHAR96('2', 0x20),
802   0x1eae /* 0x21 */,
803   0x1eb0 /* 0x22 */,
804   0x1eb6 /* 0x23 */,
805   0x1ea4 /* 0x24 */,
806   0x1ea6 /* 0x25 */,
807   0x1ea8 /* 0x26 */,
808   0x1eac /* 0x27 */,
809   0x1ebc /* 0x28 */,
810   0x1eb8 /* 0x29 */,
811   0x1ebe /* 0x2a */,
812   0x1ec0 /* 0x2b */,
813   0x1ec2 /* 0x2c */,
814   0x1ec4 /* 0x2d */,
815   0x1ec6 /* 0x2e */,
816   0x1ed0 /* 0x2f */,
817   0x1ed2 /* 0x30 */,
818   0x1ed4 /* 0x31 */,
819   0x1ed6 /* 0x32 */,
820   CHAR96('2', 0x33),
821   CHAR96('2', 0x34),
822   0x1ed8 /* 0x35 */,
823   0x1edc /* 0x36 */,
824   0x1ede /* 0x37 */,
825   0x1eca /* 0x38 */,
826   CHAR96('2', 0x39),
827   CHAR96('2', 0x3a),
828   CHAR96('2', 0x3b),
829   CHAR96('2', 0x3c),
830   0x01a0 /* 0x3d */,
831   0x1eda /* 0x3e */,
832   CHAR96('2', 0x3f),
833   CHAR96('2', 0x40),
834   CHAR96('2', 0x41),
835   CHAR96('2', 0x42),
836   CHAR96('2', 0x43),
837   CHAR96('2', 0x44),
838   CHAR96('2', 0x45),
839   0x1eb2 /* 0x46 */,
840   0x1eb4 /* 0x47 */,
841   CHAR96('2', 0x48),
842   CHAR96('2', 0x49),
843   CHAR96('2', 0x4a),
844   CHAR96('2', 0x4b),
845   CHAR96('2', 0x4c),
846   CHAR96('2', 0x4d),
847   CHAR96('2', 0x4e),
848   0x1ef2 /* 0x4f */,
849   CHAR96('2', 0x50),
850   0x1ee8 /* 0x51 */,
851   CHAR96('2', 0x52),
852   CHAR96('2', 0x53),
853   CHAR96('2', 0x54),
854   0x1ea0 /* 0x55 */,
855   0x1ef6 /* 0x56 */,
856   0x1eea /* 0x57 */,
857   0x1eec /* 0x58 */,
858   CHAR96('2', 0x59),
859   CHAR96('2', 0x5a),
860   0x1ef8 /* 0x5b */,
861   0x1ef4 /* 0x5c */,
862   CHAR96('2', 0x5d),
863   0x1ee0 /* 0x5e */,
864   0x01af /* 0x5f */,
865   0x00c0 /* 0x60 */,
866   0x00c1 /* 0x61 */,
867   0x00c2 /* 0x62 */,
868   0x00c3 /* 0x63 */,
869   0x1ea2 /* 0x64 */,
870   0x0102 /* 0x65 */,
871   0x1eee /* 0x66 */,
872   0x1eaa /* 0x67 */,
873   0x00c8 /* 0x68 */,
874   0x00c9 /* 0x69 */,
875   0x00ca /* 0x6a */,
876   0x1eba /* 0x6b */,
877   0x00cc /* 0x6c */,
878   0x00cd /* 0x6d */,
879   0x0128 /* 0x6e */,
880   0x1ec8 /* 0x6f */,
881   0x0110 /* 0x70 */,
882   0x1ef0 /* 0x71 */,
883   0x00d2 /* 0x72 */,
884   0x00d3 /* 0x73 */,
885   0x00d4 /* 0x74 */,
886   0x00d5 /* 0x75 */,
887   0x1ece /* 0x76 */,
888   0x1ecc /* 0x77 */,
889   0x1ee4 /* 0x78 */,
890   0x00d9 /* 0x79 */,
891   0x00da /* 0x7a */,
892   0x0168 /* 0x7b */,
893   0x1ee6 /* 0x7c */,
894   0x00dd /* 0x7d */,
895   0x1ee2 /* 0x7e */,
896   CHAR96('2', 0x7f)
897 };
898
899 Emchar latin_tcvn5712_to_ucs[96] =
900 {
901   0x00A0 /* 0xA0  NO-BREAK SPACE */,
902   0x0102 /* 0xA1  LATIN CAPITAL LETTER A WITH BREVE */,
903   0x00C2 /* 0xA2  LATIN CAPITAL LETTER A WITH CIRCUMFLEX */,
904   0x00CA /* 0xA3  LATIN CAPITAL LETTER E WITH CIRCUMFLEX */,
905   0x00D4 /* 0xA4  LATIN CAPITAL LETTER O WITH CIRCUMFLEX */,
906   0x01A0 /* 0xA5  LATIN CAPITAL LETTER O WITH HORN */,
907   0x01AF /* 0xA6  LATIN CAPITAL LETTER U WITH HORN */,
908   0x0110 /* 0xA7  LATIN CAPITAL LETTER D WITH STROKE */,
909   0x0103 /* 0xA8  LATIN SMALL LETTER A WITH BREVE */,
910   0x00E2 /* 0xA9  LATIN SMALL LETTER A WITH CIRCUMFLEX */,
911   0x00EA /* 0xAA  LATIN SMALL LETTER E WITH CIRCUMFLEX */,
912   0x00F4 /* 0xAB  LATIN SMALL LETTER O WITH CIRCUMFLEX */,
913   0x01A1 /* 0xAC  LATIN SMALL LETTER O WITH HORN */,
914   0x01B0 /* 0xAD  LATIN SMALL LETTER U WITH HORN */,
915   0x0111 /* 0xAE  LATIN SMALL LETTER D WITH STROKE */,
916   0x1EB0 /* 0xAF  LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */,
917   0x0300 /* 0xB0  COMBINING GRAVE ACCENT */,
918   0x0309 /* 0xB1  COMBINING HOOK ABOVE */,
919   0x0303 /* 0xB2  COMBINING TILDE */,
920   0x0301 /* 0xB3  COMBINING ACUTE ACCENT */,
921   0x0323 /* 0xB4  COMBINING DOT BELOW */,
922   0x00E0 /* 0xB5  LATIN SMALL LETTER A WITH GRAVE */,
923   0x1EA3 /* 0xB6  LATIN SMALL LETTER A WITH HOOK ABOVE */,
924   0x00E3 /* 0xB7  LATIN SMALL LETTER A WITH TILDE */,
925   0x00E1 /* 0xB8  LATIN SMALL LETTER A WITH ACUTE */,
926   0x1EA1 /* 0xB9  LATIN SMALL LETTER A WITH DOT BELOW */,
927   0x1EB2 /* 0xBA  LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */,
928   0x1EB1 /* 0xBB  LATIN SMALL LETTER A WITH BREVE AND GRAVE */,
929   0x1EB3 /* 0xBC  LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */,
930   0x1EB5 /* 0xBD  LATIN SMALL LETTER A WITH BREVE AND TILDE */,
931   0x1EAF /* 0xBE  LATIN SMALL LETTER A WITH BREVE AND ACUTE */,
932   0x1EB4 /* 0xBF  LATIN CAPITAL LETTER A WITH BREVE AND TILDE */,
933   0x1EAE /* 0xC0  LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */,
934   0x1EA6 /* 0xC1  LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */,
935   0x1EA8 /* 0xC2  LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */,
936   0x1EAA /* 0xC3  LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */,
937   0x1EA4 /* 0xC4  LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */,
938   0x1EC0 /* 0xC5  LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */,
939   0x1EB7 /* 0xC6  LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */,
940   0x1EA7 /* 0xC7  LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */,
941   0x1EA9 /* 0xC8  LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */,
942   0x1EAB /* 0xC9  LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */,
943   0x1EA5 /* 0xCA  LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */,
944   0x1EAD /* 0xCB  LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */,
945   0x00E8 /* 0xCC  LATIN SMALL LETTER E WITH GRAVE */,
946   0x1EC2 /* 0xCD  LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */,
947   0x1EBB /* 0xCE  LATIN SMALL LETTER E WITH HOOK ABOVE */,
948   0x1EBD /* 0xCF  LATIN SMALL LETTER E WITH TILDE */,
949   0x00E9 /* 0xD0  LATIN SMALL LETTER E WITH ACUTE */,
950   0x1EB9 /* 0xD1  LATIN SMALL LETTER E WITH DOT BELOW */,
951   0x1EC1 /* 0xD2  LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */,
952   0x1EC3 /* 0xD3  LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */,
953   0x1EC5 /* 0xD4  LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */,
954   0x1EBF /* 0xD5  LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */,
955   0x1EC7 /* 0xD6  LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */,
956   0x00EC /* 0xD7  LATIN SMALL LETTER I WITH GRAVE */,
957   0x1EC9 /* 0xD8  LATIN SMALL LETTER I WITH HOOK ABOVE */,
958   0x1EC4 /* 0xD9  LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */,
959   0x1EBE /* 0xDA  LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */,
960   0x1ED2 /* 0xDB  LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */,
961   0x0129 /* 0xDC  LATIN SMALL LETTER I WITH TILDE */,
962   0x00ED /* 0xDD  LATIN SMALL LETTER I WITH ACUTE */,
963   0x1ECB /* 0xDE  LATIN SMALL LETTER I WITH DOT BELOW */,
964   0x00F2 /* 0xDF  LATIN SMALL LETTER O WITH GRAVE */,
965   0x1ED4 /* 0xE0  LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */,
966   0x1ECF /* 0xE1  LATIN SMALL LETTER O WITH HOOK ABOVE */,
967   0x00F5 /* 0xE2  LATIN SMALL LETTER O WITH TILDE */,
968   0x00F3 /* 0xE3  LATIN SMALL LETTER O WITH ACUTE */,
969   0x1ECD /* 0xE4  LATIN SMALL LETTER O WITH DOT BELOW */,
970   0x1ED3 /* 0xE5  LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */,
971   0x1ED5 /* 0xE6  LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */,
972   0x1ED7 /* 0xE7  LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */,
973   0x1ED1 /* 0xE8  LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */,
974   0x1ED9 /* 0xE9  LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */,
975   0x1EDD /* 0xEA  LATIN SMALL LETTER O WITH HORN AND GRAVE */,
976   0x1EDF /* 0xEB  LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */,
977   0x1EE1 /* 0xEC  LATIN SMALL LETTER O WITH HORN AND TILDE */,
978   0x1EDB /* 0xED  LATIN SMALL LETTER O WITH HORN AND ACUTE */,
979   0x1EE3 /* 0xEE  LATIN SMALL LETTER O WITH HORN AND DOT BELOW */,
980   0x00F9 /* 0xEF  LATIN SMALL LETTER U WITH GRAVE */,
981   0x1ED6 /* 0xF0  LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */,
982   0x1EE7 /* 0xF1  LATIN SMALL LETTER U WITH HOOK ABOVE */,
983   0x0169 /* 0xF2  LATIN SMALL LETTER U WITH TILDE */,
984   0x00FA /* 0xF3  LATIN SMALL LETTER U WITH ACUTE */,
985   0x1EE5 /* 0xF4  LATIN SMALL LETTER U WITH DOT BELOW */,
986   0x1EEB /* 0xF5  LATIN SMALL LETTER U WITH HORN AND GRAVE */,
987   0x1EED /* 0xF6  LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */,
988   0x1EEF /* 0xF7  LATIN SMALL LETTER U WITH HORN AND TILDE */,
989   0x1EE9 /* 0xF8  LATIN SMALL LETTER U WITH HORN AND ACUTE */,
990   0x1EF1 /* 0xF9  LATIN SMALL LETTER U WITH HORN AND DOT BELOW */,
991   0x1EF3 /* 0xFA  LATIN SMALL LETTER Y WITH GRAVE */,
992   0x1EF7 /* 0xFB  LATIN SMALL LETTER Y WITH HOOK ABOVE */,
993   0x1EF9 /* 0xFC  LATIN SMALL LETTER Y WITH TILDE */,
994   0x00FD /* 0xFD  LATIN SMALL LETTER Y WITH ACUTE */,
995   0x1EF5 /* 0xFE  LATIN SMALL LETTER Y WITH DOT BELOW */,
996   0x1ED0 /* 0xFF  LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
997 };
998
999 Charset_ID latin_a_char_to_charset[128] = {
1000   /* U+0100 */ LEADING_BYTE_LATIN_ISO8859_4,
1001   /* U+0101 */ LEADING_BYTE_LATIN_ISO8859_4,
1002   /* U+0102 */ LEADING_BYTE_LATIN_ISO8859_2,
1003   /* U+0103 */ LEADING_BYTE_LATIN_ISO8859_2,
1004   /* U+0104 */ LEADING_BYTE_LATIN_ISO8859_2,
1005   /* U+0105 */ LEADING_BYTE_LATIN_ISO8859_2,
1006   /* U+0106 */ LEADING_BYTE_LATIN_ISO8859_2,
1007   /* U+0107 */ LEADING_BYTE_LATIN_ISO8859_2,
1008   /* U+0108 */ LEADING_BYTE_LATIN_ISO8859_3,
1009   /* U+0109 */ LEADING_BYTE_LATIN_ISO8859_3,
1010   /* U+010A */ LEADING_BYTE_LATIN_ISO8859_3,
1011   /* U+010B */ LEADING_BYTE_LATIN_ISO8859_3,
1012   /* U+010C */ LEADING_BYTE_LATIN_ISO8859_2,
1013   /* U+010D */ LEADING_BYTE_LATIN_ISO8859_2,
1014   /* U+010E */ LEADING_BYTE_LATIN_ISO8859_2,
1015   /* U+010F */ LEADING_BYTE_LATIN_ISO8859_2,
1016   /* U+0110 */ LEADING_BYTE_LATIN_ISO8859_2,
1017   /* U+0111 */ LEADING_BYTE_LATIN_ISO8859_2,
1018   /* U+0112 */ LEADING_BYTE_LATIN_ISO8859_4,
1019   /* U+0113 */ LEADING_BYTE_LATIN_ISO8859_4,
1020   /* U+0114 */ LEADING_BYTE_UCS_BMP,
1021   /* U+0115 */ LEADING_BYTE_UCS_BMP,
1022   /* U+0116 */ LEADING_BYTE_LATIN_ISO8859_4,
1023   /* U+0117 */ LEADING_BYTE_LATIN_ISO8859_4,
1024   /* U+0118 */ LEADING_BYTE_LATIN_ISO8859_2,
1025   /* U+0119 */ LEADING_BYTE_LATIN_ISO8859_2,
1026   /* U+011A */ LEADING_BYTE_LATIN_ISO8859_2,
1027   /* U+011B */ LEADING_BYTE_LATIN_ISO8859_2,
1028   /* U+011C */ LEADING_BYTE_LATIN_ISO8859_3,
1029   /* U+011D */ LEADING_BYTE_LATIN_ISO8859_3,
1030   /* U+011E */ LEADING_BYTE_LATIN_ISO8859_3,
1031   /* U+011F */ LEADING_BYTE_LATIN_ISO8859_3,
1032   /* U+0120 */ LEADING_BYTE_LATIN_ISO8859_3,
1033   /* U+0121 */ LEADING_BYTE_LATIN_ISO8859_3,
1034   /* U+0122 */ LEADING_BYTE_LATIN_ISO8859_4,
1035   /* U+0123 */ LEADING_BYTE_LATIN_ISO8859_4,
1036   /* U+0124 */ LEADING_BYTE_LATIN_ISO8859_3,
1037   /* U+0125 */ LEADING_BYTE_LATIN_ISO8859_3,
1038   /* U+0126 */ LEADING_BYTE_LATIN_ISO8859_3,
1039   /* U+0127 */ LEADING_BYTE_LATIN_ISO8859_3,
1040   /* U+0128 */ LEADING_BYTE_LATIN_ISO8859_4,
1041   /* U+0129 */ LEADING_BYTE_LATIN_ISO8859_4,
1042   /* U+012A */ LEADING_BYTE_LATIN_ISO8859_4,
1043   /* U+012B */ LEADING_BYTE_LATIN_ISO8859_4,
1044   /* U+012C */ LEADING_BYTE_UCS_BMP,
1045   /* U+012D */ LEADING_BYTE_UCS_BMP,
1046   /* U+012E */ LEADING_BYTE_LATIN_ISO8859_4,
1047   /* U+012F */ LEADING_BYTE_LATIN_ISO8859_4,
1048   /* U+0130 */ LEADING_BYTE_LATIN_ISO8859_3,
1049   /* U+0131 */ LEADING_BYTE_LATIN_ISO8859_3,
1050   /* U+0132 */ LEADING_BYTE_JAPANESE_JISX0212,
1051   /* U+0133 */ LEADING_BYTE_JAPANESE_JISX0212,
1052   /* U+0134 */ LEADING_BYTE_LATIN_ISO8859_3,
1053   /* U+0135 */ LEADING_BYTE_LATIN_ISO8859_3,
1054   /* U+0136 */ LEADING_BYTE_LATIN_ISO8859_4,
1055   /* U+0137 */ LEADING_BYTE_LATIN_ISO8859_4,
1056   /* U+0138 */ LEADING_BYTE_LATIN_ISO8859_4,
1057   /* U+0139 */ LEADING_BYTE_LATIN_ISO8859_2,
1058   /* U+013A */ LEADING_BYTE_LATIN_ISO8859_2,
1059   /* U+013B */ LEADING_BYTE_LATIN_ISO8859_4,
1060   /* U+013C */ LEADING_BYTE_LATIN_ISO8859_4,
1061   /* U+013D */ LEADING_BYTE_LATIN_ISO8859_2,
1062   /* U+013E */ LEADING_BYTE_LATIN_ISO8859_2,
1063   /* U+013F */ LEADING_BYTE_JAPANESE_JISX0212,
1064   /* U+0140 */ LEADING_BYTE_JAPANESE_JISX0212,
1065   /* U+0141 */ LEADING_BYTE_LATIN_ISO8859_2,
1066   /* U+0142 */ LEADING_BYTE_LATIN_ISO8859_2,
1067   /* U+0143 */ LEADING_BYTE_LATIN_ISO8859_2,
1068   /* U+0144 */ LEADING_BYTE_LATIN_ISO8859_2,
1069   /* U+0145 */ LEADING_BYTE_LATIN_ISO8859_4,
1070   /* U+0146 */ LEADING_BYTE_LATIN_ISO8859_4,
1071   /* U+0147 */ LEADING_BYTE_LATIN_ISO8859_2,
1072   /* U+0148 */ LEADING_BYTE_LATIN_ISO8859_2,
1073   /* U+0149 */ LEADING_BYTE_JAPANESE_JISX0212,
1074   /* U+014A */ LEADING_BYTE_LATIN_ISO8859_4,
1075   /* U+014B */ LEADING_BYTE_LATIN_ISO8859_4,
1076   /* U+014C */ LEADING_BYTE_LATIN_ISO8859_4,
1077   /* U+014D */ LEADING_BYTE_LATIN_ISO8859_4,
1078   /* U+014E */ LEADING_BYTE_UCS_BMP,
1079   /* U+014F */ LEADING_BYTE_UCS_BMP,
1080   /* U+0150 */ LEADING_BYTE_LATIN_ISO8859_2,
1081   /* U+0151 */ LEADING_BYTE_LATIN_ISO8859_2,
1082   /* U+0152 */ LEADING_BYTE_JAPANESE_JISX0212,
1083   /* U+0153 */ LEADING_BYTE_JAPANESE_JISX0212,
1084   /* U+0154 */ LEADING_BYTE_LATIN_ISO8859_2,
1085   /* U+0155 */ LEADING_BYTE_LATIN_ISO8859_2,
1086   /* U+0156 */ LEADING_BYTE_LATIN_ISO8859_4,
1087   /* U+0157 */ LEADING_BYTE_LATIN_ISO8859_4,
1088   /* U+0158 */ LEADING_BYTE_LATIN_ISO8859_2,
1089   /* U+0159 */ LEADING_BYTE_LATIN_ISO8859_2,
1090   /* U+015A */ LEADING_BYTE_LATIN_ISO8859_2,
1091   /* U+015B */ LEADING_BYTE_LATIN_ISO8859_2,
1092   /* U+015C */ LEADING_BYTE_LATIN_ISO8859_3,
1093   /* U+015D */ LEADING_BYTE_LATIN_ISO8859_3,
1094   /* U+015E */ LEADING_BYTE_LATIN_ISO8859_2,
1095   /* U+015F */ LEADING_BYTE_LATIN_ISO8859_2,
1096   /* U+0160 */ LEADING_BYTE_LATIN_ISO8859_2,
1097   /* U+0161 */ LEADING_BYTE_LATIN_ISO8859_2,
1098   /* U+0162 */ LEADING_BYTE_LATIN_ISO8859_2,
1099   /* U+0163 */ LEADING_BYTE_LATIN_ISO8859_2,
1100   /* U+0164 */ LEADING_BYTE_LATIN_ISO8859_2,
1101   /* U+0165 */ LEADING_BYTE_LATIN_ISO8859_2,
1102   /* U+0166 */ LEADING_BYTE_LATIN_ISO8859_4,
1103   /* U+0167 */ LEADING_BYTE_LATIN_ISO8859_4,
1104   /* U+0168 */ LEADING_BYTE_LATIN_ISO8859_4,
1105   /* U+0169 */ LEADING_BYTE_LATIN_ISO8859_4,
1106   /* U+016A */ LEADING_BYTE_LATIN_ISO8859_4,
1107   /* U+016B */ LEADING_BYTE_LATIN_ISO8859_4,
1108   /* U+016C */ LEADING_BYTE_LATIN_ISO8859_3,
1109   /* U+016D */ LEADING_BYTE_LATIN_ISO8859_3,
1110   /* U+016E */ LEADING_BYTE_LATIN_ISO8859_2,
1111   /* U+016F */ LEADING_BYTE_LATIN_ISO8859_2,
1112   /* U+0170 */ LEADING_BYTE_LATIN_ISO8859_2,
1113   /* U+0171 */ LEADING_BYTE_LATIN_ISO8859_2,
1114   /* U+0172 */ LEADING_BYTE_LATIN_ISO8859_4,
1115   /* U+0173 */ LEADING_BYTE_LATIN_ISO8859_4,
1116   /* U+0174 */ LEADING_BYTE_JAPANESE_JISX0212,
1117   /* U+0175 */ LEADING_BYTE_JAPANESE_JISX0212,
1118   /* U+0176 */ LEADING_BYTE_JAPANESE_JISX0212,
1119   /* U+0177 */ LEADING_BYTE_JAPANESE_JISX0212,
1120   /* U+0178 */ LEADING_BYTE_JAPANESE_JISX0212,
1121   /* U+0179 */ LEADING_BYTE_LATIN_ISO8859_2,
1122   /* U+017A */ LEADING_BYTE_LATIN_ISO8859_2,
1123   /* U+017B */ LEADING_BYTE_LATIN_ISO8859_2,
1124   /* U+017C */ LEADING_BYTE_LATIN_ISO8859_2,
1125   /* U+017D */ LEADING_BYTE_LATIN_ISO8859_2,
1126   /* U+017E */ LEADING_BYTE_LATIN_ISO8859_2,
1127   /* U+017F */ LEADING_BYTE_UCS_BMP
1128 };
1129
1130 unsigned char latin_a_char_to_byte1[128] = {
1131   /* U+0100 */ 0xC0 - 0x80,
1132   /* U+0101 */ 0xE0 - 0x80,
1133   /* U+0102 */ 0xC3 - 0x80,
1134   /* U+0103 */ 0xE3 - 0x80,
1135   /* U+0104 */ 0xA1 - 0x80,
1136   /* U+0105 */ 0xB1 - 0x80,
1137   /* U+0106 */ 0xC6 - 0x80,
1138   /* U+0107 */ 0xE6 - 0x80,
1139   /* U+0108 */ 0xC6 - 0x80,
1140   /* U+0109 */ 0xE6 - 0x80,
1141   /* U+010A */ 0xC5 - 0x80,
1142   /* U+010B */ 0xE5 - 0x80,
1143   /* U+010C */ 0xC8 - 0x80,
1144   /* U+010D */ 0xE8 - 0x80,
1145   /* U+010E */ 0xCF - 0x80,
1146   /* U+010F */ 0xEF - 0x80,
1147   /* U+0110 */ 0xD0 - 0x80,
1148   /* U+0111 */ 0xF0 - 0x80,
1149   /* U+0112 */ 0xAA - 0x80,
1150   /* U+0113 */ 0xBA - 0x80,
1151   /* U+0114 */ 0x01,
1152   /* U+0115 */ 0x01,
1153   /* U+0116 */ 0xCC - 0x80,
1154   /* U+0117 */ 0xEC - 0x80,
1155   /* U+0118 */ 0xCA - 0x80,
1156   /* U+0119 */ 0xEA - 0x80,
1157   /* U+011A */ 0xCC - 0x80,
1158   /* U+011B */ 0xEC - 0x80,
1159   /* U+011C */ 0xD8 - 0x80,
1160   /* U+011D */ 0xF8 - 0x80,
1161   /* U+011E */ 0xAB - 0x80,
1162   /* U+011F */ 0xBB - 0x80,
1163   /* U+0120 */ 0xD5 - 0x80,
1164   /* U+0121 */ 0xF5 - 0x80,
1165   /* U+0122 */ 0xAB - 0x80,
1166   /* U+0123 */ 0xBB - 0x80,
1167   /* U+0124 */ 0xA6 - 0x80,
1168   /* U+0125 */ 0xB6 - 0x80,
1169   /* U+0126 */ 0xA1 - 0x80,
1170   /* U+0127 */ 0xB1 - 0x80,
1171   /* U+0128 */ 0xA5 - 0x80,
1172   /* U+0129 */ 0xB5 - 0x80,
1173   /* U+012A */ 0xCF - 0x80,
1174   /* U+012B */ 0xEF - 0x80,
1175   /* U+012C */ 0x01,
1176   /* U+012D */ 0x01,
1177   /* U+012E */ 0xC7 - 0x80,
1178   /* U+012F */ 0xE7 - 0x80,
1179   /* U+0130 */ 0xA9 - 0x80,
1180   /* U+0131 */ 0xB9 - 0x80,
1181   /* U+0132 */ 0x29,
1182   /* U+0133 */ 0x29,
1183   /* U+0134 */ 0xAC - 0x80,
1184   /* U+0135 */ 0xBC - 0x80,
1185   /* U+0136 */ 0xD3 - 0x80,
1186   /* U+0137 */ 0xF3 - 0x80,
1187   /* U+0138 */ 0xA2 - 0x80,
1188   /* U+0139 */ 0xC5 - 0x80,
1189   /* U+013A */ 0xE5 - 0x80,
1190   /* U+013B */ 0xA6 - 0x80,
1191   /* U+013C */ 0xB6 - 0x80,
1192   /* U+013D */ 0xA5 - 0x80,
1193   /* U+013E */ 0xB5 - 0x80,
1194   /* U+013F */ 0x29,
1195   /* U+0140 */ 0x29,
1196   /* U+0141 */ 0xA3 - 0x80,
1197   /* U+0142 */ 0xB3 - 0x80,
1198   /* U+0143 */ 0xD1 - 0x80,
1199   /* U+0144 */ 0xF1 - 0x80,
1200   /* U+0145 */ 0xD1 - 0x80,
1201   /* U+0146 */ 0xF1 - 0x80,
1202   /* U+0147 */ 0xD2 - 0x80,
1203   /* U+0148 */ 0xF2 - 0x80,
1204   /* U+0149 */ 0x29,
1205   /* U+014A */ 0xBD - 0x80,
1206   /* U+014B */ 0xBF - 0x80,
1207   /* U+014C */ 0xD2 - 0x80,
1208   /* U+014D */ 0xF2 - 0x80,
1209   /* U+014E */ 0x01,
1210   /* U+014F */ 0x01,
1211   /* U+0150 */ 0xD5 - 0x80,
1212   /* U+0151 */ 0xF5 - 0x80,
1213   /* U+0152 */ 0x29,
1214   /* U+0153 */ 0x29,
1215   /* U+0154 */ 0xC0 - 0x80,
1216   /* U+0155 */ 0xE0 - 0x80,
1217   /* U+0156 */ 0xA3 - 0x80,
1218   /* U+0157 */ 0xB3 - 0x80,
1219   /* U+0158 */ 0xD8 - 0x80,
1220   /* U+0159 */ 0xF8 - 0x80,
1221   /* U+015A */ 0xA6 - 0x80,
1222   /* U+015B */ 0xB6 - 0x80,
1223   /* U+015C */ 0xDE - 0x80,
1224   /* U+015D */ 0xFE - 0x80,
1225   /* U+015E */ 0xAA - 0x80,
1226   /* U+015F */ 0xBA - 0x80,
1227   /* U+0160 */ 0xA9 - 0x80,
1228   /* U+0161 */ 0xB9 - 0x80,
1229   /* U+0162 */ 0xDE - 0x80,
1230   /* U+0163 */ 0xFE - 0x80,
1231   /* U+0164 */ 0xAB - 0x80,
1232   /* U+0165 */ 0xBB - 0x80,
1233   /* U+0166 */ 0xAC - 0x80,
1234   /* U+0167 */ 0xBC - 0x80,
1235   /* U+0168 */ 0xDD - 0x80,
1236   /* U+0169 */ 0xFD - 0x80,
1237   /* U+016A */ 0xDE - 0x80,
1238   /* U+016B */ 0xFE - 0x80,
1239   /* U+016C */ 0xDD - 0x80,
1240   /* U+016D */ 0xFD - 0x80,
1241   /* U+016E */ 0xD9 - 0x80,
1242   /* U+016F */ 0xF9 - 0x80,
1243   /* U+0170 */ 0xDB - 0x80,
1244   /* U+0171 */ 0xFB - 0x80,
1245   /* U+0172 */ 0xD9 - 0x80,
1246   /* U+0173 */ 0xF9 - 0x80,
1247   /* U+0174 */ 0x2A,
1248   /* U+0175 */ 0x2B,
1249   /* U+0176 */ 0x2A,
1250   /* U+0177 */ 0x2B,
1251   /* U+0178 */ 0x2A,
1252   /* U+0179 */ 0xAC - 0x80,
1253   /* U+017A */ 0xBC - 0x80,
1254   /* U+017B */ 0xAF - 0x80,
1255   /* U+017C */ 0xBF - 0x80,
1256   /* U+017D */ 0xAE - 0x80,
1257   /* U+017E */ 0xBE - 0x80,
1258   /* U+017F */ 0x01
1259 };
1260
1261 unsigned char latin_a_char_to_byte2[128] = {
1262   /* U+0100 */ 0x00,
1263   /* U+0101 */ 0x00,
1264   /* U+0102 */ 0x00,
1265   /* U+0103 */ 0x00,
1266   /* U+0104 */ 0x00,
1267   /* U+0105 */ 0x00,
1268   /* U+0106 */ 0x00,
1269   /* U+0107 */ 0x00,
1270   /* U+0108 */ 0x00,
1271   /* U+0109 */ 0x00,
1272   /* U+010A */ 0x00,
1273   /* U+010B */ 0x00,
1274   /* U+010C */ 0x00,
1275   /* U+010D */ 0x00,
1276   /* U+010E */ 0x00,
1277   /* U+010F */ 0x00,
1278   /* U+0110 */ 0x00,
1279   /* U+0111 */ 0x00,
1280   /* U+0112 */ 0x00,
1281   /* U+0113 */ 0x00,
1282   /* U+0114 */ 0x14,
1283   /* U+0115 */ 0x15,
1284   /* U+0116 */ 0x00,
1285   /* U+0117 */ 0x00,
1286   /* U+0118 */ 0x00,
1287   /* U+0119 */ 0x00,
1288   /* U+011A */ 0x00,
1289   /* U+011B */ 0x00,
1290   /* U+011C */ 0x00,
1291   /* U+011D */ 0x00,
1292   /* U+011E */ 0x00,
1293   /* U+011F */ 0x00,
1294   /* U+0120 */ 0x00,
1295   /* U+0121 */ 0x00,
1296   /* U+0122 */ 0x00,
1297   /* U+0123 */ 0x00,
1298   /* U+0124 */ 0x00,
1299   /* U+0125 */ 0x00,
1300   /* U+0126 */ 0x00,
1301   /* U+0127 */ 0x00,
1302   /* U+0128 */ 0x00,
1303   /* U+0129 */ 0x00,
1304   /* U+012A */ 0x00,
1305   /* U+012B */ 0x00,
1306   /* U+012C */ 0x2C,
1307   /* U+012D */ 0x2D,
1308   /* U+012E */ 0x00,
1309   /* U+012F */ 0x00,
1310   /* U+0130 */ 0x00,
1311   /* U+0131 */ 0x00,
1312   /* U+0132 */ 0x26,
1313   /* U+0133 */ 0x46,
1314   /* U+0134 */ 0x00,
1315   /* U+0135 */ 0x00,
1316   /* U+0136 */ 0x00,
1317   /* U+0137 */ 0x00,
1318   /* U+0138 */ 0x00,
1319   /* U+0139 */ 0x00,
1320   /* U+013A */ 0x00,
1321   /* U+013B */ 0x00,
1322   /* U+013C */ 0x00,
1323   /* U+013D */ 0x00,
1324   /* U+013E */ 0x00,
1325   /* U+013F */ 0x29,
1326   /* U+0140 */ 0x49,
1327   /* U+0141 */ 0x00,
1328   /* U+0142 */ 0x00,
1329   /* U+0143 */ 0x00,
1330   /* U+0144 */ 0x00,
1331   /* U+0145 */ 0x00,
1332   /* U+0146 */ 0x00,
1333   /* U+0147 */ 0x00,
1334   /* U+0148 */ 0x00,
1335   /* U+0149 */ 0x4A,
1336   /* U+014A */ 0x00,
1337   /* U+014B */ 0x00,
1338   /* U+014C */ 0x00,
1339   /* U+014D */ 0x00,
1340   /* U+014E */ 0x4E,
1341   /* U+014F */ 0x4F,
1342   /* U+0150 */ 0x00,
1343   /* U+0151 */ 0x00,
1344   /* U+0152 */ 0x2D,
1345   /* U+0153 */ 0x4D,
1346   /* U+0154 */ 0x00,
1347   /* U+0155 */ 0x00,
1348   /* U+0156 */ 0x00,
1349   /* U+0157 */ 0x00,
1350   /* U+0158 */ 0x00,
1351   /* U+0159 */ 0x00,
1352   /* U+015A */ 0x00,
1353   /* U+015B */ 0x00,
1354   /* U+015C */ 0x00,
1355   /* U+015D */ 0x00,
1356   /* U+015E */ 0x00,
1357   /* U+015F */ 0x00,
1358   /* U+0160 */ 0x00,
1359   /* U+0161 */ 0x00,
1360   /* U+0162 */ 0x00,
1361   /* U+0163 */ 0x00,
1362   /* U+0164 */ 0x00,
1363   /* U+0165 */ 0x00,
1364   /* U+0166 */ 0x00,
1365   /* U+0167 */ 0x00,
1366   /* U+0168 */ 0x00,
1367   /* U+0169 */ 0x00,
1368   /* U+016A */ 0x00,
1369   /* U+016B */ 0x00,
1370   /* U+016C */ 0x00,
1371   /* U+016D */ 0x00,
1372   /* U+016E */ 0x00,
1373   /* U+016F */ 0x00,
1374   /* U+0170 */ 0x00,
1375   /* U+0171 */ 0x00,
1376   /* U+0172 */ 0x00,
1377   /* U+0173 */ 0x00,
1378   /* U+0174 */ 0x71,
1379   /* U+0175 */ 0x71,
1380   /* U+0176 */ 0x74,
1381   /* U+0177 */ 0x74,
1382   /* U+0178 */ 0x73,
1383   /* U+0179 */ 0x00,
1384   /* U+017A */ 0x00,
1385   /* U+017B */ 0x00,
1386   /* U+017C */ 0x00,
1387   /* U+017D */ 0x00,
1388   /* U+017E */ 0x00,
1389   /* U+017F */ 0x7F
1390 };
1391
1392 Lisp_Object Vutf_2000_version;
1393 #endif
1394
1395 #ifndef UTF2000
1396 int leading_code_private_11;
1397 #endif
1398
1399 Lisp_Object Qcharsetp;
1400
1401 /* Qdoc_string, Qdimension, Qchars defined in general.c */
1402 Lisp_Object Qregistry, Qfinal, Qgraphic;
1403 Lisp_Object Qdirection;
1404 Lisp_Object Qreverse_direction_charset;
1405 Lisp_Object Qleading_byte;
1406 Lisp_Object Qshort_name, Qlong_name;
1407
1408 Lisp_Object Qascii,
1409   Qcontrol_1,
1410   Qlatin_iso8859_1,
1411   Qlatin_iso8859_2,
1412   Qlatin_iso8859_3,
1413   Qlatin_iso8859_4,
1414   Qthai_tis620,
1415   Qgreek_iso8859_7,
1416   Qarabic_iso8859_6,
1417   Qhebrew_iso8859_8,
1418   Qkatakana_jisx0201,
1419   Qlatin_jisx0201,
1420   Qcyrillic_iso8859_5,
1421   Qlatin_iso8859_9,
1422   Qjapanese_jisx0208_1978,
1423   Qchinese_gb2312,
1424   Qjapanese_jisx0208,
1425   Qkorean_ksc5601,
1426   Qjapanese_jisx0212,
1427   Qchinese_cns11643_1,
1428   Qchinese_cns11643_2,
1429 #ifdef UTF2000
1430   Qchinese_cns11643_3,
1431   Qchinese_cns11643_4,
1432   Qchinese_cns11643_5,
1433   Qchinese_cns11643_6,
1434   Qchinese_cns11643_7,
1435   Qucs_bmp,
1436   Qlatin_viscii_lower,
1437   Qlatin_viscii_upper,
1438 #endif
1439   Qchinese_big5_1,
1440   Qchinese_big5_2,
1441   Qcomposite;
1442
1443 Lisp_Object Ql2r, Qr2l;
1444
1445 Lisp_Object Vcharset_hash_table;
1446
1447 static Charset_ID next_allocated_1_byte_leading_byte;
1448 static Charset_ID next_allocated_2_byte_leading_byte;
1449
1450 /* Composite characters are characters constructed by overstriking two
1451    or more regular characters.
1452
1453    1) The old Mule implementation involves storing composite characters
1454       in a buffer as a tag followed by all of the actual characters
1455       used to make up the composite character.  I think this is a bad
1456       idea; it greatly complicates code that wants to handle strings
1457       one character at a time because it has to deal with the possibility
1458       of great big ungainly characters.  It's much more reasonable to
1459       simply store an index into a table of composite characters.
1460
1461    2) The current implementation only allows for 16,384 separate
1462       composite characters over the lifetime of the XEmacs process.
1463       This could become a potential problem if the user
1464       edited lots of different files that use composite characters.
1465       Due to FSF bogosity, increasing the number of allowable
1466       composite characters under Mule would decrease the number
1467       of possible faces that can exist.  Mule already has shrunk
1468       this to 2048, and further shrinkage would become uncomfortable.
1469       No such problems exist in XEmacs.
1470
1471       Composite characters could be represented as 0x80 C1 C2 C3,
1472       where each C[1-3] is in the range 0xA0 - 0xFF.  This allows
1473       for slightly under 2^20 (one million) composite characters
1474       over the XEmacs process lifetime, and you only need to
1475       increase the size of a Mule character from 19 to 21 bits.
1476       Or you could use 0x80 C1 C2 C3 C4, allowing for about
1477       85 million (slightly over 2^26) composite characters. */
1478
1479 \f
1480 /************************************************************************/
1481 /*                       Basic Emchar functions                         */
1482 /************************************************************************/
1483
1484 /* Convert a non-ASCII Mule character C into a one-character Mule-encoded
1485    string in STR.  Returns the number of bytes stored.
1486    Do not call this directly.  Use the macro set_charptr_emchar() instead.
1487  */
1488
1489 Bytecount
1490 non_ascii_set_charptr_emchar (Bufbyte *str, Emchar c)
1491 {
1492   Bufbyte *p;
1493 #ifndef UTF2000
1494   Charset_ID lb;
1495   int c1, c2;
1496   Lisp_Object charset;
1497 #endif
1498
1499   p = str;
1500 #ifdef UTF2000
1501   if ( c <= 0x7f )
1502     {
1503       *p++ = c;
1504     }
1505   else if ( c <= 0x7ff )
1506     {
1507       *p++ = (c >> 6) | 0xc0;
1508       *p++ = (c & 0x3f) | 0x80;
1509     }
1510   else if ( c <= 0xffff )
1511     {
1512       *p++ =  (c >> 12) | 0xe0;
1513       *p++ = ((c >>  6) & 0x3f) | 0x80;
1514       *p++ =  (c        & 0x3f) | 0x80;
1515     }
1516   else if ( c <= 0x1fffff )
1517     {
1518       *p++ =  (c >> 18) | 0xf0;
1519       *p++ = ((c >> 12) & 0x3f) | 0x80;
1520       *p++ = ((c >>  6) & 0x3f) | 0x80;
1521       *p++ =  (c        & 0x3f) | 0x80;
1522     }
1523   else if ( c <= 0x3ffffff )
1524     {
1525       *p++ =  (c >> 24) | 0xf8;
1526       *p++ = ((c >> 18) & 0x3f) | 0x80;
1527       *p++ = ((c >> 12) & 0x3f) | 0x80;
1528       *p++ = ((c >>  6) & 0x3f) | 0x80;
1529       *p++ =  (c        & 0x3f) | 0x80;
1530     }
1531   else
1532     {
1533       *p++ =  (c >> 30) | 0xfc;
1534       *p++ = ((c >> 24) & 0x3f) | 0x80;
1535       *p++ = ((c >> 18) & 0x3f) | 0x80;
1536       *p++ = ((c >> 12) & 0x3f) | 0x80;
1537       *p++ = ((c >>  6) & 0x3f) | 0x80;
1538       *p++ =  (c        & 0x3f) | 0x80;
1539     }
1540 #else
1541   BREAKUP_CHAR (c, charset, c1, c2);
1542   lb = CHAR_LEADING_BYTE (c);
1543   if (LEADING_BYTE_PRIVATE_P (lb))
1544     *p++ = PRIVATE_LEADING_BYTE_PREFIX (lb);
1545   *p++ = lb;
1546   if (EQ (charset, Vcharset_control_1))
1547     c1 += 0x20;
1548   *p++ = c1 | 0x80;
1549   if (c2)
1550     *p++ = c2 | 0x80;
1551 #endif
1552   return (p - str);
1553 }
1554
1555 /* Return the first character from a Mule-encoded string in STR,
1556    assuming it's non-ASCII.  Do not call this directly.
1557    Use the macro charptr_emchar() instead. */
1558
1559 Emchar
1560 non_ascii_charptr_emchar (CONST Bufbyte *str)
1561 {
1562 #ifdef UTF2000
1563   Bufbyte b;
1564   Emchar ch;
1565   int len;
1566
1567   b = *str++;
1568   if ( b >= 0xfc )
1569     {
1570       ch = (b & 0x01);
1571       len = 5;
1572     }
1573   else if ( b >= 0xf8 )
1574     {
1575       ch = b & 0x03;
1576       len = 4;
1577     }
1578   else if ( b >= 0xf0 )
1579     {
1580       ch = b & 0x07;
1581       len = 3;
1582     }
1583   else if ( b >= 0xe0 )
1584     {
1585       ch = b & 0x0f;
1586       len = 2;
1587     }
1588   else if ( b >= 0xc0 )
1589     {
1590       ch = b & 0x1f;
1591       len = 1;
1592     }
1593   else
1594     {
1595       ch = b;
1596       len = 0;
1597     }
1598   for( ; len > 0; len-- )
1599     {
1600       b = *str++;
1601       ch = ( ch << 6 ) | ( b & 0x3f );
1602     }
1603   return ch;
1604 #else
1605   Bufbyte i0 = *str, i1, i2 = 0;
1606   Lisp_Object charset;
1607
1608   if (i0 == LEADING_BYTE_CONTROL_1)
1609     return (Emchar) (*++str - 0x20);
1610
1611   if (LEADING_BYTE_PREFIX_P (i0))
1612     i0 = *++str;
1613
1614   i1 = *++str & 0x7F;
1615
1616   charset = CHARSET_BY_LEADING_BYTE (i0);
1617   if (XCHARSET_DIMENSION (charset) == 2)
1618     i2 = *++str & 0x7F;
1619
1620   return MAKE_CHAR (charset, i1, i2);
1621 #endif
1622 }
1623
1624 /* Return whether CH is a valid Emchar, assuming it's non-ASCII.
1625    Do not call this directly.  Use the macro valid_char_p() instead. */
1626
1627 #ifndef UTF2000
1628 int
1629 non_ascii_valid_char_p (Emchar ch)
1630 {
1631   int f1, f2, f3;
1632
1633   /* Must have only lowest 19 bits set */
1634   if (ch & ~0x7FFFF)
1635     return 0;
1636
1637   f1 = CHAR_FIELD1 (ch);
1638   f2 = CHAR_FIELD2 (ch);
1639   f3 = CHAR_FIELD3 (ch);
1640
1641   if (f1 == 0)
1642     {
1643       Lisp_Object charset;
1644
1645       if (f2 < MIN_CHAR_FIELD2_OFFICIAL ||
1646           (f2 > MAX_CHAR_FIELD2_OFFICIAL && f2 < MIN_CHAR_FIELD2_PRIVATE) ||
1647            f2 > MAX_CHAR_FIELD2_PRIVATE)
1648         return 0;
1649       if (f3 < 0x20)
1650         return 0;
1651
1652       if (f3 != 0x20 && f3 != 0x7F)
1653         return 1;
1654
1655       /*
1656          NOTE: This takes advantage of the fact that
1657          FIELD2_TO_OFFICIAL_LEADING_BYTE and
1658          FIELD2_TO_PRIVATE_LEADING_BYTE are the same.
1659          */
1660       charset = CHARSET_BY_LEADING_BYTE (f2 + FIELD2_TO_OFFICIAL_LEADING_BYTE);
1661       return (XCHARSET_CHARS (charset) == 96);
1662     }
1663   else
1664     {
1665       Lisp_Object charset;
1666
1667       if (f1 < MIN_CHAR_FIELD1_OFFICIAL ||
1668           (f1 > MAX_CHAR_FIELD1_OFFICIAL && f1 < MIN_CHAR_FIELD1_PRIVATE) ||
1669           f1 > MAX_CHAR_FIELD1_PRIVATE)
1670         return 0;
1671       if (f2 < 0x20 || f3 < 0x20)
1672         return 0;
1673
1674 #ifdef ENABLE_COMPOSITE_CHARS
1675       if (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE == LEADING_BYTE_COMPOSITE)
1676         {
1677           if (UNBOUNDP (Fgethash (make_int (ch),
1678                                   Vcomposite_char_char2string_hash_table,
1679                                   Qunbound)))
1680             return 0;
1681           return 1;
1682         }
1683 #endif /* ENABLE_COMPOSITE_CHARS */
1684
1685       if (f2 != 0x20 && f2 != 0x7F && f3 != 0x20 && f3 != 0x7F)
1686         return 1;
1687
1688       if (f1 <= MAX_CHAR_FIELD1_OFFICIAL)
1689         charset =
1690           CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE);
1691       else
1692         charset =
1693           CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_PRIVATE_LEADING_BYTE);
1694
1695       return (XCHARSET_CHARS (charset) == 96);
1696     }
1697 }
1698 #endif
1699
1700 \f
1701 /************************************************************************/
1702 /*                       Basic string functions                         */
1703 /************************************************************************/
1704
1705 /* Copy the character pointed to by PTR into STR, assuming it's
1706    non-ASCII.  Do not call this directly.  Use the macro
1707    charptr_copy_char() instead. */
1708
1709 Bytecount
1710 non_ascii_charptr_copy_char (CONST Bufbyte *ptr, Bufbyte *str)
1711 {
1712   Bufbyte *strptr = str;
1713   *strptr = *ptr++;
1714   switch (REP_BYTES_BY_FIRST_BYTE (*strptr))
1715     {
1716       /* Notice fallthrough. */
1717 #ifdef UTF2000
1718     case 6: *++strptr = *ptr++;
1719     case 5: *++strptr = *ptr++;
1720 #endif
1721     case 4: *++strptr = *ptr++;
1722     case 3: *++strptr = *ptr++;
1723     case 2: *++strptr = *ptr;
1724       break;
1725     default:
1726       abort ();
1727     }
1728   return strptr + 1 - str;
1729 }
1730
1731 \f
1732 /************************************************************************/
1733 /*                        streams of Emchars                            */
1734 /************************************************************************/
1735
1736 /* Treat a stream as a stream of Emchar's rather than a stream of bytes.
1737    The functions below are not meant to be called directly; use
1738    the macros in insdel.h. */
1739
1740 Emchar
1741 Lstream_get_emchar_1 (Lstream *stream, int ch)
1742 {
1743   Bufbyte str[MAX_EMCHAR_LEN];
1744   Bufbyte *strptr = str;
1745
1746   str[0] = (Bufbyte) ch;
1747   switch (REP_BYTES_BY_FIRST_BYTE (ch))
1748     {
1749       /* Notice fallthrough. */
1750 #ifdef UTF2000
1751     case 6:
1752       ch = Lstream_getc (stream);
1753       assert (ch >= 0);
1754       *++strptr = (Bufbyte) ch;
1755     case 5:
1756       ch = Lstream_getc (stream);
1757       assert (ch >= 0);
1758       *++strptr = (Bufbyte) ch;
1759 #endif
1760     case 4:
1761       ch = Lstream_getc (stream);
1762       assert (ch >= 0);
1763       *++strptr = (Bufbyte) ch;
1764     case 3:
1765       ch = Lstream_getc (stream);
1766       assert (ch >= 0);
1767       *++strptr = (Bufbyte) ch;
1768     case 2:
1769       ch = Lstream_getc (stream);
1770       assert (ch >= 0);
1771       *++strptr = (Bufbyte) ch;
1772       break;
1773     default:
1774       abort ();
1775     }
1776   return charptr_emchar (str);
1777 }
1778
1779 int
1780 Lstream_fput_emchar (Lstream *stream, Emchar ch)
1781 {
1782   Bufbyte str[MAX_EMCHAR_LEN];
1783   Bytecount len = set_charptr_emchar (str, ch);
1784   return Lstream_write (stream, str, len);
1785 }
1786
1787 void
1788 Lstream_funget_emchar (Lstream *stream, Emchar ch)
1789 {
1790   Bufbyte str[MAX_EMCHAR_LEN];
1791   Bytecount len = set_charptr_emchar (str, ch);
1792   Lstream_unread (stream, str, len);
1793 }
1794
1795 \f
1796 /************************************************************************/
1797 /*                            charset object                            */
1798 /************************************************************************/
1799
1800 static Lisp_Object
1801 mark_charset (Lisp_Object obj, void (*markobj) (Lisp_Object))
1802 {
1803   struct Lisp_Charset *cs = XCHARSET (obj);
1804
1805   markobj (cs->short_name);
1806   markobj (cs->long_name);
1807   markobj (cs->doc_string);
1808   markobj (cs->registry);
1809   markobj (cs->ccl_program);
1810   return cs->name;
1811 }
1812
1813 static void
1814 print_charset (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1815 {
1816   struct Lisp_Charset *cs = XCHARSET (obj);
1817   char buf[200];
1818
1819   if (print_readably)
1820     error ("printing unreadable object #<charset %s 0x%x>",
1821            string_data (XSYMBOL (CHARSET_NAME (cs))->name),
1822            cs->header.uid);
1823
1824   write_c_string ("#<charset ", printcharfun);
1825   print_internal (CHARSET_NAME (cs), printcharfun, 0);
1826   write_c_string (" ", printcharfun);
1827   print_internal (CHARSET_SHORT_NAME (cs), printcharfun, 1);
1828   write_c_string (" ", printcharfun);
1829   print_internal (CHARSET_LONG_NAME (cs), printcharfun, 1);
1830   write_c_string (" ", printcharfun);
1831   print_internal (CHARSET_DOC_STRING (cs), printcharfun, 1);
1832   sprintf (buf, " %s %s cols=%d g%d final='%c' reg=",
1833            CHARSET_TYPE (cs) == CHARSET_TYPE_94    ? "94" :
1834            CHARSET_TYPE (cs) == CHARSET_TYPE_96    ? "96" :
1835            CHARSET_TYPE (cs) == CHARSET_TYPE_94X94 ? "94x94" :
1836            "96x96",
1837            CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? "l2r" : "r2l",
1838            CHARSET_COLUMNS (cs),
1839            CHARSET_GRAPHIC (cs),
1840            CHARSET_FINAL (cs));
1841   write_c_string (buf, printcharfun);
1842   print_internal (CHARSET_REGISTRY (cs), printcharfun, 0);
1843   sprintf (buf, " 0x%x>", cs->header.uid);
1844   write_c_string (buf, printcharfun);
1845 }
1846
1847 static const struct lrecord_description charset_description[] = {
1848   { XD_LISP_OBJECT, offsetof(struct Lisp_Charset, name), 7 },
1849   { XD_END }
1850 };
1851
1852 DEFINE_LRECORD_IMPLEMENTATION ("charset", charset,
1853                                mark_charset, print_charset, 0, 0, 0,
1854                                charset_description,
1855                                struct Lisp_Charset);
1856 /* Make a new charset. */
1857
1858 static Lisp_Object
1859 make_charset (Charset_ID id, Lisp_Object name,
1860               unsigned char type, unsigned char columns, unsigned char graphic,
1861               Bufbyte final, unsigned char direction, Lisp_Object short_name,
1862               Lisp_Object long_name, Lisp_Object doc,
1863               Lisp_Object reg,
1864               Emchar* decoding_table)
1865 {
1866   Lisp_Object obj;
1867   struct Lisp_Charset *cs =
1868     alloc_lcrecord_type (struct Lisp_Charset, &lrecord_charset);
1869   XSETCHARSET (obj, cs);
1870
1871   CHARSET_ID            (cs) = id;
1872   CHARSET_NAME          (cs) = name;
1873   CHARSET_SHORT_NAME    (cs) = short_name;
1874   CHARSET_LONG_NAME     (cs) = long_name;
1875   CHARSET_DIRECTION     (cs) = direction;
1876   CHARSET_TYPE          (cs) = type;
1877   CHARSET_COLUMNS       (cs) = columns;
1878   CHARSET_GRAPHIC       (cs) = graphic;
1879   CHARSET_FINAL         (cs) = final;
1880   CHARSET_DOC_STRING    (cs) = doc;
1881   CHARSET_REGISTRY      (cs) = reg;
1882   CHARSET_CCL_PROGRAM   (cs) = Qnil;
1883   CHARSET_REVERSE_DIRECTION_CHARSET (cs) = Qnil;
1884 #ifdef UTF2000
1885   CHARSET_DECODING_TABLE(cs) = decoding_table;
1886 #endif
1887
1888   switch ( CHARSET_TYPE (cs) )
1889     {
1890     case CHARSET_TYPE_94:
1891       CHARSET_DIMENSION (cs) = 1;
1892       CHARSET_CHARS (cs) = 94;
1893 #ifdef UTF2000
1894       if (decoding_table != NULL)
1895         {
1896           size_t i;
1897           CHARSET_TO_BYTE1_TABLE(cs) = make_byte_from_character_table();
1898           for (i = 0; i < 94; i++)
1899             {
1900               Emchar c = decoding_table[i];
1901
1902               if (c <= 0xffff)
1903                 put_byte_from_character_table (c, i + 33,
1904                                                CHARSET_TO_BYTE1_TABLE(cs));
1905             }
1906         }
1907       else
1908         CHARSET_TO_BYTE1_TABLE(cs) = NULL;
1909       CHARSET_TO_BYTE2_TABLE(cs) = NULL;
1910 #endif
1911       break;
1912     case CHARSET_TYPE_96:
1913       CHARSET_DIMENSION (cs) = 1;
1914       CHARSET_CHARS (cs) = 96;
1915 #ifdef UTF2000
1916       if (decoding_table != NULL)
1917         {
1918           size_t i;
1919           CHARSET_TO_BYTE1_TABLE(cs) = make_byte_from_character_table();
1920           for (i = 0; i < 96; i++)
1921             {
1922               Emchar c = decoding_table[i];
1923
1924               if (c <= 0xffff)
1925                 put_byte_from_character_table (c, i + 32,
1926                                                CHARSET_TO_BYTE1_TABLE(cs));
1927             }
1928         }
1929       else
1930         CHARSET_TO_BYTE1_TABLE(cs) = NULL;
1931       CHARSET_TO_BYTE2_TABLE(cs) = NULL;
1932 #endif
1933       break;
1934     case CHARSET_TYPE_94X94:
1935       CHARSET_DIMENSION (cs) = 2;
1936       CHARSET_CHARS (cs) = 94;
1937 #ifdef UTF2000
1938       CHARSET_TO_BYTE1_TABLE(cs) = NULL;
1939       CHARSET_TO_BYTE2_TABLE(cs) = NULL;
1940 #endif
1941       break;
1942     case CHARSET_TYPE_96X96:
1943       CHARSET_DIMENSION (cs) = 2;
1944       CHARSET_CHARS (cs) = 96;
1945 #ifdef UTF2000
1946       CHARSET_TO_BYTE1_TABLE(cs) = NULL;
1947       CHARSET_TO_BYTE2_TABLE(cs) = NULL;
1948 #endif
1949       break;
1950 #ifdef UTF2000
1951     case CHARSET_TYPE_128X128:
1952       CHARSET_DIMENSION (cs) = 2;
1953       CHARSET_CHARS (cs) = 128;
1954 #ifdef UTF2000
1955       CHARSET_TO_BYTE1_TABLE(cs) = NULL;
1956       CHARSET_TO_BYTE2_TABLE(cs) = NULL;
1957 #endif
1958       break;
1959     case CHARSET_TYPE_256X256:
1960       CHARSET_DIMENSION (cs) = 2;
1961       CHARSET_CHARS (cs) = 256;
1962 #ifdef UTF2000
1963       CHARSET_TO_BYTE1_TABLE(cs) = NULL;
1964       CHARSET_TO_BYTE2_TABLE(cs) = NULL;
1965 #endif
1966       break;
1967 #endif
1968     }
1969
1970 #ifndef UTF2000
1971   if (id == LEADING_BYTE_ASCII)
1972     CHARSET_REP_BYTES (cs) = 1;
1973   else if (id < 0xA0)
1974     CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 1;
1975   else
1976     CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 2;
1977 #endif
1978   
1979   if (final)
1980     {
1981       /* some charsets do not have final characters.  This includes
1982          ASCII, Control-1, Composite, and the two faux private
1983          charsets. */
1984 #if UTF2000
1985       assert (NILP (charset_by_attributes[type][final]));
1986       charset_by_attributes[type][final] = obj;
1987 #else
1988       assert (NILP (charset_by_attributes[type][final][direction]));
1989       charset_by_attributes[type][final][direction] = obj;
1990 #endif
1991     }
1992
1993   assert (NILP (charset_by_leading_byte[id - MIN_LEADING_BYTE]));
1994   charset_by_leading_byte[id - MIN_LEADING_BYTE] = obj;
1995 #ifndef UTF2000
1996   if (id < 0xA0)
1997     /* official leading byte */
1998     rep_bytes_by_first_byte[id] = CHARSET_REP_BYTES (cs);
1999 #endif
2000
2001   /* Some charsets are "faux" and don't have names or really exist at
2002      all except in the leading-byte table. */
2003   if (!NILP (name))
2004     Fputhash (name, obj, Vcharset_hash_table);
2005   return obj;
2006 }
2007
2008 static int
2009 get_unallocated_leading_byte (int dimension)
2010 {
2011   Charset_ID lb;
2012
2013   if (dimension == 1)
2014     {
2015       if (next_allocated_1_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_1)
2016         lb = 0;
2017       else
2018         lb = next_allocated_1_byte_leading_byte++;
2019     }
2020   else
2021     {
2022       if (next_allocated_2_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_2)
2023         lb = 0;
2024       else
2025         lb = next_allocated_2_byte_leading_byte++;
2026     }
2027
2028   if (!lb)
2029     signal_simple_error
2030       ("No more character sets free for this dimension",
2031        make_int (dimension));
2032
2033   return lb;
2034 }
2035
2036 \f
2037 /************************************************************************/
2038 /*                      Basic charset Lisp functions                    */
2039 /************************************************************************/
2040
2041 DEFUN ("charsetp", Fcharsetp, 1, 1, 0, /*
2042 Return non-nil if OBJECT is a charset.
2043 */
2044        (object))
2045 {
2046   return CHARSETP (object) ? Qt : Qnil;
2047 }
2048
2049 DEFUN ("find-charset", Ffind_charset, 1, 1, 0, /*
2050 Retrieve the charset of the given name.
2051 If CHARSET-OR-NAME is a charset object, it is simply returned.
2052 Otherwise, CHARSET-OR-NAME should be a symbol.  If there is no such charset,
2053 nil is returned.  Otherwise the associated charset object is returned.
2054 */
2055        (charset_or_name))
2056 {
2057   if (CHARSETP (charset_or_name))
2058     return charset_or_name;
2059
2060   CHECK_SYMBOL (charset_or_name);
2061   return Fgethash (charset_or_name, Vcharset_hash_table, Qnil);
2062 }
2063
2064 DEFUN ("get-charset", Fget_charset, 1, 1, 0, /*
2065 Retrieve the charset of the given name.
2066 Same as `find-charset' except an error is signalled if there is no such
2067 charset instead of returning nil.
2068 */
2069        (name))
2070 {
2071   Lisp_Object charset = Ffind_charset (name);
2072
2073   if (NILP (charset))
2074     signal_simple_error ("No such charset", name);
2075   return charset;
2076 }
2077
2078 /* We store the charsets in hash tables with the names as the key and the
2079    actual charset object as the value.  Occasionally we need to use them
2080    in a list format.  These routines provide us with that. */
2081 struct charset_list_closure
2082 {
2083   Lisp_Object *charset_list;
2084 };
2085
2086 static int
2087 add_charset_to_list_mapper (Lisp_Object key, Lisp_Object value,
2088                             void *charset_list_closure)
2089 {
2090   /* This function can GC */
2091   struct charset_list_closure *chcl =
2092     (struct charset_list_closure*) charset_list_closure;
2093   Lisp_Object *charset_list = chcl->charset_list;
2094
2095   *charset_list = Fcons (XCHARSET_NAME (value), *charset_list);
2096   return 0;
2097 }
2098
2099 DEFUN ("charset-list", Fcharset_list, 0, 0, 0, /*
2100 Return a list of the names of all defined charsets.
2101 */
2102        ())
2103 {
2104   Lisp_Object charset_list = Qnil;
2105   struct gcpro gcpro1;
2106   struct charset_list_closure charset_list_closure;
2107
2108   GCPRO1 (charset_list);
2109   charset_list_closure.charset_list = &charset_list;
2110   elisp_maphash (add_charset_to_list_mapper, Vcharset_hash_table,
2111                  &charset_list_closure);
2112   UNGCPRO;
2113
2114   return charset_list;
2115 }
2116
2117 DEFUN ("charset-name", Fcharset_name, 1, 1, 0, /*
2118 Return the name of the given charset.
2119 */
2120        (charset))
2121 {
2122   return XCHARSET_NAME (Fget_charset (charset));
2123 }
2124
2125 DEFUN ("make-charset", Fmake_charset, 3, 3, 0, /*
2126 Define a new character set.
2127 This function is for use with Mule support.
2128 NAME is a symbol, the name by which the character set is normally referred.
2129 DOC-STRING is a string describing the character set.
2130 PROPS is a property list, describing the specific nature of the
2131 character set.  Recognized properties are:
2132
2133 'short-name     Short version of the charset name (ex: Latin-1)
2134 'long-name      Long version of the charset name (ex: ISO8859-1 (Latin-1))
2135 'registry       A regular expression matching the font registry field for
2136                 this character set.
2137 'dimension      Number of octets used to index a character in this charset.
2138                 Either 1 or 2.  Defaults to 1.
2139 'columns        Number of columns used to display a character in this charset.
2140                 Only used in TTY mode. (Under X, the actual width of a
2141                 character can be derived from the font used to display the
2142                 characters.) If unspecified, defaults to the dimension
2143                 (this is almost always the correct value).
2144 'chars          Number of characters in each dimension (94 or 96).
2145                 Defaults to 94.  Note that if the dimension is 2, the
2146                 character set thus described is 94x94 or 96x96.
2147 'final          Final byte of ISO 2022 escape sequence.  Must be
2148                 supplied.  Each combination of (DIMENSION, CHARS) defines a
2149                 separate namespace for final bytes.  Note that ISO
2150                 2022 restricts the final byte to the range
2151                 0x30 - 0x7E if dimension == 1, and 0x30 - 0x5F if
2152                 dimension == 2.  Note also that final bytes in the range
2153                 0x30 - 0x3F are reserved for user-defined (not official)
2154                 character sets.
2155 'graphic        0 (use left half of font on output) or 1 (use right half
2156                 of font on output).  Defaults to 0.  For example, for
2157                 a font whose registry is ISO8859-1, the left half
2158                 (octets 0x20 - 0x7F) is the `ascii' character set, while
2159                 the right half (octets 0xA0 - 0xFF) is the `latin-1'
2160                 character set.  With 'graphic set to 0, the octets
2161                 will have their high bit cleared; with it set to 1,
2162                 the octets will have their high bit set.
2163 'direction      'l2r (left-to-right) or 'r2l (right-to-left).
2164                 Defaults to 'l2r.
2165 'ccl-program    A compiled CCL program used to convert a character in
2166                 this charset into an index into the font.  This is in
2167                 addition to the 'graphic property.  The CCL program
2168                 is passed the octets of the character, with the high
2169                 bit cleared and set depending upon whether the value
2170                 of the 'graphic property is 0 or 1.
2171 */
2172        (name, doc_string, props))
2173 {
2174   int id, dimension = 1, chars = 94, graphic = 0, final = 0, columns = -1;
2175   int direction = CHARSET_LEFT_TO_RIGHT;
2176   int type;
2177   Lisp_Object registry = Qnil;
2178   Lisp_Object charset;
2179   Lisp_Object rest, keyword, value;
2180   Lisp_Object ccl_program = Qnil;
2181   Lisp_Object short_name = Qnil, long_name = Qnil;
2182
2183   CHECK_SYMBOL (name);
2184   if (!NILP (doc_string))
2185     CHECK_STRING (doc_string);
2186
2187   charset = Ffind_charset (name);
2188   if (!NILP (charset))
2189     signal_simple_error ("Cannot redefine existing charset", name);
2190
2191   EXTERNAL_PROPERTY_LIST_LOOP (rest, keyword, value, props)
2192     {
2193       if (EQ (keyword, Qshort_name))
2194         {
2195           CHECK_STRING (value);
2196           short_name = value;
2197         }
2198
2199       if (EQ (keyword, Qlong_name))
2200         {
2201           CHECK_STRING (value);
2202           long_name = value;
2203         }
2204
2205       else if (EQ (keyword, Qdimension))
2206         {
2207           CHECK_INT (value);
2208           dimension = XINT (value);
2209           if (dimension < 1 || dimension > 2)
2210             signal_simple_error ("Invalid value for 'dimension", value);
2211         }
2212
2213       else if (EQ (keyword, Qchars))
2214         {
2215           CHECK_INT (value);
2216           chars = XINT (value);
2217           if (chars != 94 && chars != 96)
2218             signal_simple_error ("Invalid value for 'chars", value);
2219         }
2220
2221       else if (EQ (keyword, Qcolumns))
2222         {
2223           CHECK_INT (value);
2224           columns = XINT (value);
2225           if (columns != 1 && columns != 2)
2226             signal_simple_error ("Invalid value for 'columns", value);
2227         }
2228
2229       else if (EQ (keyword, Qgraphic))
2230         {
2231           CHECK_INT (value);
2232           graphic = XINT (value);
2233           if (graphic < 0 || graphic > 1)
2234             signal_simple_error ("Invalid value for 'graphic", value);
2235         }
2236
2237       else if (EQ (keyword, Qregistry))
2238         {
2239           CHECK_STRING (value);
2240           registry = value;
2241         }
2242
2243       else if (EQ (keyword, Qdirection))
2244         {
2245           if (EQ (value, Ql2r))
2246             direction = CHARSET_LEFT_TO_RIGHT;
2247           else if (EQ (value, Qr2l))
2248             direction = CHARSET_RIGHT_TO_LEFT;
2249           else
2250             signal_simple_error ("Invalid value for 'direction", value);
2251         }
2252
2253       else if (EQ (keyword, Qfinal))
2254         {
2255           CHECK_CHAR_COERCE_INT (value);
2256           final = XCHAR (value);
2257           if (final < '0' || final > '~')
2258             signal_simple_error ("Invalid value for 'final", value);
2259         }
2260
2261       else if (EQ (keyword, Qccl_program))
2262         {
2263           CHECK_VECTOR (value);
2264           ccl_program = value;
2265         }
2266
2267       else
2268         signal_simple_error ("Unrecognized property", keyword);
2269     }
2270
2271   if (!final)
2272     error ("'final must be specified");
2273   if (dimension == 2 && final > 0x5F)
2274     signal_simple_error
2275       ("Final must be in the range 0x30 - 0x5F for dimension == 2",
2276        make_char (final));
2277
2278   if (dimension == 1)
2279     type = (chars == 94) ? CHARSET_TYPE_94    : CHARSET_TYPE_96;
2280   else
2281     type = (chars == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96;
2282
2283   if (!NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_LEFT_TO_RIGHT)) ||
2284       !NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_RIGHT_TO_LEFT)))
2285     error
2286       ("Character set already defined for this DIMENSION/CHARS/FINAL combo");
2287
2288 #ifdef UTF2000
2289   if (dimension == 1)
2290     {
2291       if (chars == 94)
2292         {
2293           /* id = CHARSET_ID_OFFSET_94 + final; */
2294           id = get_unallocated_leading_byte (dimension);
2295         }
2296       else if (chars == 96)
2297         {
2298           id = get_unallocated_leading_byte (dimension);
2299         }
2300       else
2301         {
2302           abort ();
2303         }
2304     }
2305   else if (dimension == 2)
2306     {
2307       if (chars == 94)
2308         {
2309           id = get_unallocated_leading_byte (dimension);
2310         }
2311       else if (chars == 96)
2312         {
2313           id = get_unallocated_leading_byte (dimension);
2314         }
2315       else
2316         {
2317           abort ();
2318         }
2319     }
2320   else
2321     {
2322       abort ();
2323     }
2324 #else
2325   id = get_unallocated_leading_byte (dimension);
2326 #endif
2327
2328   if (NILP (doc_string))
2329     doc_string = build_string ("");
2330
2331   if (NILP (registry))
2332     registry = build_string ("");
2333
2334   if (NILP (short_name))
2335     XSETSTRING (short_name, XSYMBOL (name)->name);
2336
2337   if (NILP (long_name))
2338     long_name = doc_string;
2339
2340   if (columns == -1)
2341     columns = dimension;
2342   charset = make_charset (id, name, type, columns, graphic,
2343                           final, direction, short_name, long_name,
2344                           doc_string, registry,
2345                           NULL);
2346   if (!NILP (ccl_program))
2347     XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2348   return charset;
2349 }
2350
2351 DEFUN ("make-reverse-direction-charset", Fmake_reverse_direction_charset,
2352        2, 2, 0, /*
2353 Make a charset equivalent to CHARSET but which goes in the opposite direction.
2354 NEW-NAME is the name of the new charset.  Return the new charset.
2355 */
2356        (charset, new_name))
2357 {
2358   Lisp_Object new_charset = Qnil;
2359   int id, dimension, columns, graphic, final;
2360   int direction, type;
2361   Lisp_Object registry, doc_string, short_name, long_name;
2362   struct Lisp_Charset *cs;
2363
2364   charset = Fget_charset (charset);
2365   if (!NILP (XCHARSET_REVERSE_DIRECTION_CHARSET (charset)))
2366     signal_simple_error ("Charset already has reverse-direction charset",
2367                          charset);
2368
2369   CHECK_SYMBOL (new_name);
2370   if (!NILP (Ffind_charset (new_name)))
2371     signal_simple_error ("Cannot redefine existing charset", new_name);
2372
2373   cs = XCHARSET (charset);
2374
2375   type      = CHARSET_TYPE      (cs);
2376   columns   = CHARSET_COLUMNS   (cs);
2377   dimension = CHARSET_DIMENSION (cs);
2378   id = get_unallocated_leading_byte (dimension);
2379
2380   graphic = CHARSET_GRAPHIC (cs);
2381   final = CHARSET_FINAL (cs);
2382   direction = CHARSET_RIGHT_TO_LEFT;
2383   if (CHARSET_DIRECTION (cs) == CHARSET_RIGHT_TO_LEFT)
2384     direction = CHARSET_LEFT_TO_RIGHT;
2385   doc_string = CHARSET_DOC_STRING (cs);
2386   short_name = CHARSET_SHORT_NAME (cs);
2387   long_name = CHARSET_LONG_NAME (cs);
2388   registry = CHARSET_REGISTRY (cs);
2389
2390   new_charset = make_charset (id, new_name, type, columns,
2391                               graphic, final, direction, short_name, long_name,
2392                               doc_string, registry,
2393                               NULL);
2394
2395   CHARSET_REVERSE_DIRECTION_CHARSET (cs) = new_charset;
2396   XCHARSET_REVERSE_DIRECTION_CHARSET (new_charset) = charset;
2397
2398   return new_charset;
2399 }
2400
2401 /* #### Reverse direction charsets not yet implemented.  */
2402 #if 0
2403 DEFUN ("charset-reverse-direction-charset", Fcharset_reverse_direction_charset,
2404        1, 1, 0, /*
2405 Return the reverse-direction charset parallel to CHARSET, if any.
2406 This is the charset with the same properties (in particular, the same
2407 dimension, number of characters per dimension, and final byte) as
2408 CHARSET but whose characters are displayed in the opposite direction.
2409 */
2410        (charset))
2411 {
2412   charset = Fget_charset (charset);
2413   return XCHARSET_REVERSE_DIRECTION_CHARSET (charset);
2414 }
2415 #endif
2416
2417 DEFUN ("charset-from-attributes", Fcharset_from_attributes, 3, 4, 0, /*
2418 Return a charset with the given DIMENSION, CHARS, FINAL, and DIRECTION.
2419 If DIRECTION is omitted, both directions will be checked (left-to-right
2420 will be returned if character sets exist for both directions).
2421 */
2422        (dimension, chars, final, direction))
2423 {
2424   int dm, ch, fi, di = -1;
2425   int type;
2426   Lisp_Object obj = Qnil;
2427
2428   CHECK_INT (dimension);
2429   dm = XINT (dimension);
2430   if (dm < 1 || dm > 2)
2431     signal_simple_error ("Invalid value for DIMENSION", dimension);
2432
2433   CHECK_INT (chars);
2434   ch = XINT (chars);
2435   if (ch != 94 && ch != 96)
2436     signal_simple_error ("Invalid value for CHARS", chars);
2437
2438   CHECK_CHAR_COERCE_INT (final);
2439   fi = XCHAR (final);
2440   if (fi < '0' || fi > '~')
2441     signal_simple_error ("Invalid value for FINAL", final);
2442
2443   if (EQ (direction, Ql2r))
2444     di = CHARSET_LEFT_TO_RIGHT;
2445   else if (EQ (direction, Qr2l))
2446     di = CHARSET_RIGHT_TO_LEFT;
2447   else if (!NILP (direction))
2448     signal_simple_error ("Invalid value for DIRECTION", direction);
2449
2450   if (dm == 2 && fi > 0x5F)
2451     signal_simple_error
2452       ("Final must be in the range 0x30 - 0x5F for dimension == 2", final);
2453
2454   if (dm == 1)
2455     type = (ch == 94) ? CHARSET_TYPE_94    : CHARSET_TYPE_96;
2456   else
2457     type = (ch == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96;
2458
2459   if (di == -1)
2460     {
2461       obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_LEFT_TO_RIGHT);
2462       if (NILP (obj))
2463         obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_RIGHT_TO_LEFT);
2464     }
2465   else
2466     obj = CHARSET_BY_ATTRIBUTES (type, fi, di);
2467
2468   if (CHARSETP (obj))
2469     return XCHARSET_NAME (obj);
2470   return obj;
2471 }
2472
2473 DEFUN ("charset-short-name", Fcharset_short_name, 1, 1, 0, /*
2474 Return short name of CHARSET.
2475 */
2476        (charset))
2477 {
2478   return XCHARSET_SHORT_NAME (Fget_charset (charset));
2479 }
2480
2481 DEFUN ("charset-long-name", Fcharset_long_name, 1, 1, 0, /*
2482 Return long name of CHARSET.
2483 */
2484        (charset))
2485 {
2486   return XCHARSET_LONG_NAME (Fget_charset (charset));
2487 }
2488
2489 DEFUN ("charset-description", Fcharset_description, 1, 1, 0, /*
2490 Return description of CHARSET.
2491 */
2492        (charset))
2493 {
2494   return XCHARSET_DOC_STRING (Fget_charset (charset));
2495 }
2496
2497 DEFUN ("charset-dimension", Fcharset_dimension, 1, 1, 0, /*
2498 Return dimension of CHARSET.
2499 */
2500        (charset))
2501 {
2502   return make_int (XCHARSET_DIMENSION (Fget_charset (charset)));
2503 }
2504
2505 DEFUN ("charset-property", Fcharset_property, 2, 2, 0, /*
2506 Return property PROP of CHARSET.
2507 Recognized properties are those listed in `make-charset', as well as
2508 'name and 'doc-string.
2509 */
2510        (charset, prop))
2511 {
2512   struct Lisp_Charset *cs;
2513
2514   charset = Fget_charset (charset);
2515   cs = XCHARSET (charset);
2516
2517   CHECK_SYMBOL (prop);
2518   if (EQ (prop, Qname))        return CHARSET_NAME (cs);
2519   if (EQ (prop, Qshort_name))  return CHARSET_SHORT_NAME (cs);
2520   if (EQ (prop, Qlong_name))   return CHARSET_LONG_NAME (cs);
2521   if (EQ (prop, Qdoc_string))  return CHARSET_DOC_STRING (cs);
2522   if (EQ (prop, Qdimension))   return make_int (CHARSET_DIMENSION (cs));
2523   if (EQ (prop, Qcolumns))     return make_int (CHARSET_COLUMNS (cs));
2524   if (EQ (prop, Qgraphic))     return make_int (CHARSET_GRAPHIC (cs));
2525   if (EQ (prop, Qfinal))       return make_char (CHARSET_FINAL (cs));
2526   if (EQ (prop, Qchars))       return make_int (CHARSET_CHARS (cs));
2527   if (EQ (prop, Qregistry))    return CHARSET_REGISTRY (cs);
2528   if (EQ (prop, Qccl_program)) return CHARSET_CCL_PROGRAM (cs);
2529   if (EQ (prop, Qdirection))
2530     return CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? Ql2r : Qr2l;
2531   if (EQ (prop, Qreverse_direction_charset))
2532     {
2533       Lisp_Object obj = CHARSET_REVERSE_DIRECTION_CHARSET (cs);
2534       if (NILP (obj))
2535         return Qnil;
2536       else
2537         return XCHARSET_NAME (obj);
2538     }
2539   signal_simple_error ("Unrecognized charset property name", prop);
2540   return Qnil; /* not reached */
2541 }
2542
2543 DEFUN ("charset-id", Fcharset_id, 1, 1, 0, /*
2544 Return charset identification number of CHARSET.
2545 */
2546         (charset))
2547 {
2548   return make_int(XCHARSET_LEADING_BYTE (Fget_charset (charset)));
2549 }
2550
2551 /* #### We need to figure out which properties we really want to
2552    allow to be set. */
2553
2554 DEFUN ("set-charset-ccl-program", Fset_charset_ccl_program, 2, 2, 0, /*
2555 Set the 'ccl-program property of CHARSET to CCL-PROGRAM.
2556 */
2557        (charset, ccl_program))
2558 {
2559   charset = Fget_charset (charset);
2560   CHECK_VECTOR (ccl_program);
2561   XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2562   return Qnil;
2563 }
2564
2565 static void
2566 invalidate_charset_font_caches (Lisp_Object charset)
2567 {
2568   /* Invalidate font cache entries for charset on all devices. */
2569   Lisp_Object devcons, concons, hash_table;
2570   DEVICE_LOOP_NO_BREAK (devcons, concons)
2571     {
2572       struct device *d = XDEVICE (XCAR (devcons));
2573       hash_table = Fgethash (charset, d->charset_font_cache, Qunbound);
2574       if (!UNBOUNDP (hash_table))
2575         Fclrhash (hash_table);
2576     }
2577 }
2578
2579 /* Japanese folks may want to (set-charset-registry 'ascii "jisx0201") */
2580 DEFUN ("set-charset-registry", Fset_charset_registry, 2, 2, 0, /*
2581 Set the 'registry property of CHARSET to REGISTRY.
2582 */
2583        (charset, registry))
2584 {
2585   charset = Fget_charset (charset);
2586   CHECK_STRING (registry);
2587   XCHARSET_REGISTRY (charset) = registry;
2588   invalidate_charset_font_caches (charset);
2589   face_property_was_changed (Vdefault_face, Qfont, Qglobal);
2590   return Qnil;
2591 }
2592
2593 \f
2594 /************************************************************************/
2595 /*              Lisp primitives for working with characters             */
2596 /************************************************************************/
2597
2598 DEFUN ("make-char", Fmake_char, 2, 3, 0, /*
2599 Make a character from CHARSET and octets ARG1 and ARG2.
2600 ARG2 is required only for characters from two-dimensional charsets.
2601 For example, (make-char 'latin-iso8859-2 185) will return the Latin 2
2602 character s with caron.
2603 */
2604        (charset, arg1, arg2))
2605 {
2606   struct Lisp_Charset *cs;
2607   int a1, a2;
2608   int lowlim, highlim;
2609
2610   charset = Fget_charset (charset);
2611   cs = XCHARSET (charset);
2612
2613   if      (EQ (charset, Vcharset_ascii))     lowlim =  0, highlim = 127;
2614   else if (EQ (charset, Vcharset_control_1)) lowlim =  0, highlim =  31;
2615 #ifdef UTF2000
2616   else if (CHARSET_CHARS (cs) == 256)        lowlim =  0, highlim = 255;
2617 #endif
2618   else if (CHARSET_CHARS (cs) == 94)         lowlim = 33, highlim = 126;
2619   else  /* CHARSET_CHARS (cs) == 96) */      lowlim = 32, highlim = 127;
2620
2621   CHECK_INT (arg1);
2622   /* It is useful (and safe, according to Olivier Galibert) to strip
2623      the 8th bit off ARG1 and ARG2 becaue it allows programmers to
2624      write (make-char 'latin-iso8859-2 CODE) where code is the actual
2625      Latin 2 code of the character.  */
2626 #ifdef UTF2000
2627   a1 = XINT (arg1);
2628   if (highlim < 128)
2629     a1 &= 0x7f;
2630 #else
2631   a1 = XINT (arg1);
2632 #endif
2633   if (a1 < lowlim || a1 > highlim)
2634     args_out_of_range_3 (arg1, make_int (lowlim), make_int (highlim));
2635
2636   if (CHARSET_DIMENSION (cs) == 1)
2637     {
2638       if (!NILP (arg2))
2639         signal_simple_error
2640           ("Charset is of dimension one; second octet must be nil", arg2);
2641       return make_char (MAKE_CHAR (charset, a1, 0));
2642     }
2643
2644   CHECK_INT (arg2);
2645 #ifdef UTF2000
2646   a2 = XINT (arg2);
2647   if (highlim < 128)
2648     a2 &= 0x7f;
2649 #else
2650   a2 = XINT (arg2) & 0x7f;
2651 #endif
2652   if (a2 < lowlim || a2 > highlim)
2653     args_out_of_range_3 (arg2, make_int (lowlim), make_int (highlim));
2654
2655   return make_char (MAKE_CHAR (charset, a1, a2));
2656 }
2657
2658 DEFUN ("char-charset", Fchar_charset, 1, 1, 0, /*
2659 Return the character set of char CH.
2660 */
2661        (ch))
2662 {
2663   CHECK_CHAR_COERCE_INT (ch);
2664
2665   return XCHARSET_NAME (CHAR_CHARSET (XCHAR (ch)));
2666 }
2667
2668 DEFUN ("split-char", Fsplit_char, 1, 1, 0, /*
2669 Return list of charset and one or two position-codes of CHAR.
2670 */
2671        (character))
2672 {
2673   /* This function can GC */
2674   struct gcpro gcpro1, gcpro2;
2675   Lisp_Object charset = Qnil;
2676   Lisp_Object rc = Qnil;
2677   int c1, c2;
2678
2679   GCPRO2 (charset, rc);
2680   CHECK_CHAR_COERCE_INT (character);
2681
2682   BREAKUP_CHAR (XCHAR (character), charset, c1, c2);
2683
2684   if (XCHARSET_DIMENSION (Fget_charset (charset)) == 2)
2685     {
2686       rc = list3 (XCHARSET_NAME (charset), make_int (c1), make_int (c2));
2687     }
2688   else
2689     {
2690       rc = list2 (XCHARSET_NAME (charset), make_int (c1));
2691     }
2692   UNGCPRO;
2693
2694   return rc;
2695 }
2696
2697 \f
2698 #ifdef ENABLE_COMPOSITE_CHARS
2699 /************************************************************************/
2700 /*                     composite character functions                    */
2701 /************************************************************************/
2702
2703 Emchar
2704 lookup_composite_char (Bufbyte *str, int len)
2705 {
2706   Lisp_Object lispstr = make_string (str, len);
2707   Lisp_Object ch = Fgethash (lispstr,
2708                              Vcomposite_char_string2char_hash_table,
2709                              Qunbound);
2710   Emchar emch;
2711
2712   if (UNBOUNDP (ch))
2713     {
2714       if (composite_char_row_next >= 128)
2715         signal_simple_error ("No more composite chars available", lispstr);
2716       emch = MAKE_CHAR (Vcharset_composite, composite_char_row_next,
2717                         composite_char_col_next);
2718       Fputhash (make_char (emch), lispstr,
2719                 Vcomposite_char_char2string_hash_table);
2720       Fputhash (lispstr, make_char (emch),
2721                 Vcomposite_char_string2char_hash_table);
2722       composite_char_col_next++;
2723       if (composite_char_col_next >= 128)
2724         {
2725           composite_char_col_next = 32;
2726           composite_char_row_next++;
2727         }
2728     }
2729   else
2730     emch = XCHAR (ch);
2731   return emch;
2732 }
2733
2734 Lisp_Object
2735 composite_char_string (Emchar ch)
2736 {
2737   Lisp_Object str = Fgethash (make_char (ch),
2738                               Vcomposite_char_char2string_hash_table,
2739                               Qunbound);
2740   assert (!UNBOUNDP (str));
2741   return str;
2742 }
2743
2744 xxDEFUN ("make-composite-char", Fmake_composite_char, 1, 1, 0, /*
2745 Convert a string into a single composite character.
2746 The character is the result of overstriking all the characters in
2747 the string.
2748 */
2749        (string))
2750 {
2751   CHECK_STRING (string);
2752   return make_char (lookup_composite_char (XSTRING_DATA (string),
2753                                            XSTRING_LENGTH (string)));
2754 }
2755
2756 xxDEFUN ("composite-char-string", Fcomposite_char_string, 1, 1, 0, /*
2757 Return a string of the characters comprising a composite character.
2758 */
2759        (ch))
2760 {
2761   Emchar emch;
2762
2763   CHECK_CHAR (ch);
2764   emch = XCHAR (ch);
2765   if (CHAR_LEADING_BYTE (emch) != LEADING_BYTE_COMPOSITE)
2766     signal_simple_error ("Must be composite char", ch);
2767   return composite_char_string (emch);
2768 }
2769 #endif /* ENABLE_COMPOSITE_CHARS */
2770
2771 \f
2772 /************************************************************************/
2773 /*                            initialization                            */
2774 /************************************************************************/
2775
2776 void
2777 syms_of_mule_charset (void)
2778 {
2779   DEFSUBR (Fcharsetp);
2780   DEFSUBR (Ffind_charset);
2781   DEFSUBR (Fget_charset);
2782   DEFSUBR (Fcharset_list);
2783   DEFSUBR (Fcharset_name);
2784   DEFSUBR (Fmake_charset);
2785   DEFSUBR (Fmake_reverse_direction_charset);
2786   /*  DEFSUBR (Freverse_direction_charset); */
2787   DEFSUBR (Fcharset_from_attributes);
2788   DEFSUBR (Fcharset_short_name);
2789   DEFSUBR (Fcharset_long_name);
2790   DEFSUBR (Fcharset_description);
2791   DEFSUBR (Fcharset_dimension);
2792   DEFSUBR (Fcharset_property);
2793   DEFSUBR (Fcharset_id);
2794   DEFSUBR (Fset_charset_ccl_program);
2795   DEFSUBR (Fset_charset_registry);
2796
2797   DEFSUBR (Fmake_char);
2798   DEFSUBR (Fchar_charset);
2799   DEFSUBR (Fsplit_char);
2800
2801 #ifdef ENABLE_COMPOSITE_CHARS
2802   DEFSUBR (Fmake_composite_char);
2803   DEFSUBR (Fcomposite_char_string);
2804 #endif
2805
2806   defsymbol (&Qcharsetp, "charsetp");
2807   defsymbol (&Qregistry, "registry");
2808   defsymbol (&Qfinal, "final");
2809   defsymbol (&Qgraphic, "graphic");
2810   defsymbol (&Qdirection, "direction");
2811   defsymbol (&Qreverse_direction_charset, "reverse-direction-charset");
2812   defsymbol (&Qshort_name, "short-name");
2813   defsymbol (&Qlong_name, "long-name");
2814
2815   defsymbol (&Ql2r, "l2r");
2816   defsymbol (&Qr2l, "r2l");
2817
2818   /* Charsets, compatible with FSF 20.3
2819      Naming convention is Script-Charset[-Edition] */
2820   defsymbol (&Qascii,                   "ascii");
2821   defsymbol (&Qcontrol_1,               "control-1");
2822   defsymbol (&Qlatin_iso8859_1,         "latin-iso8859-1");
2823   defsymbol (&Qlatin_iso8859_2,         "latin-iso8859-2");
2824   defsymbol (&Qlatin_iso8859_3,         "latin-iso8859-3");
2825   defsymbol (&Qlatin_iso8859_4,         "latin-iso8859-4");
2826   defsymbol (&Qthai_tis620,             "thai-tis620");
2827   defsymbol (&Qgreek_iso8859_7,         "greek-iso8859-7");
2828   defsymbol (&Qarabic_iso8859_6,        "arabic-iso8859-6");
2829   defsymbol (&Qhebrew_iso8859_8,        "hebrew-iso8859-8");
2830   defsymbol (&Qkatakana_jisx0201,       "katakana-jisx0201");
2831   defsymbol (&Qlatin_jisx0201,          "latin-jisx0201");
2832   defsymbol (&Qcyrillic_iso8859_5,      "cyrillic-iso8859-5");
2833   defsymbol (&Qlatin_iso8859_9,         "latin-iso8859-9");
2834   defsymbol (&Qjapanese_jisx0208_1978,  "japanese-jisx0208-1978");
2835   defsymbol (&Qchinese_gb2312,          "chinese-gb2312");
2836   defsymbol (&Qjapanese_jisx0208,       "japanese-jisx0208");
2837   defsymbol (&Qkorean_ksc5601,          "korean-ksc5601");
2838   defsymbol (&Qjapanese_jisx0212,       "japanese-jisx0212");
2839   defsymbol (&Qchinese_cns11643_1,      "chinese-cns11643-1");
2840   defsymbol (&Qchinese_cns11643_2,      "chinese-cns11643-2");
2841 #ifdef UTF2000
2842   defsymbol (&Qchinese_cns11643_3,      "chinese-cns11643-3");
2843   defsymbol (&Qchinese_cns11643_4,      "chinese-cns11643-4");
2844   defsymbol (&Qchinese_cns11643_5,      "chinese-cns11643-5");
2845   defsymbol (&Qchinese_cns11643_6,      "chinese-cns11643-6");
2846   defsymbol (&Qchinese_cns11643_7,      "chinese-cns11643-7");
2847   defsymbol (&Qucs_bmp,                 "ucs-bmp");
2848   defsymbol (&Qlatin_viscii_lower,      "vietnamese-viscii-lower");
2849   defsymbol (&Qlatin_viscii_upper,      "vietnamese-viscii-upper");
2850 #endif
2851   defsymbol (&Qchinese_big5_1,          "chinese-big5-1");
2852   defsymbol (&Qchinese_big5_2,          "chinese-big5-2");
2853
2854   defsymbol (&Qcomposite,               "composite");
2855 }
2856
2857 void
2858 vars_of_mule_charset (void)
2859 {
2860   int i, j;
2861 #ifndef UTF2000
2862   int k;
2863 #endif
2864
2865   /* Table of charsets indexed by leading byte. */
2866   for (i = 0; i < countof (charset_by_leading_byte); i++)
2867     charset_by_leading_byte[i] = Qnil;
2868
2869 #ifdef UTF2000
2870   /* Table of charsets indexed by type/final-byte. */
2871   for (i = 0; i < countof (charset_by_attributes); i++)
2872     for (j = 0; j < countof (charset_by_attributes[0]); j++)
2873         charset_by_attributes[i][j] = Qnil;
2874 #else
2875   /* Table of charsets indexed by type/final-byte/direction. */
2876   for (i = 0; i < countof (charset_by_attributes); i++)
2877     for (j = 0; j < countof (charset_by_attributes[0]); j++)
2878       for (k = 0; k < countof (charset_by_attributes[0][0]); k++)
2879         charset_by_attributes[i][j][k] = Qnil;
2880 #endif
2881
2882   next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1;
2883 #ifdef UTF2000
2884   next_allocated_2_byte_leading_byte = LEADING_BYTE_CHINESE_BIG5_2 + 1;
2885 #else
2886   next_allocated_2_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_2;
2887 #endif
2888
2889 #ifndef UTF2000
2890   leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
2891   DEFVAR_INT ("leading-code-private-11", &leading_code_private_11 /*
2892 Leading-code of private TYPE9N charset of column-width 1.
2893 */ );
2894   leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
2895 #endif
2896
2897 #ifdef UTF2000
2898   Vutf_2000_version = build_string("0.7 (Hirano)");
2899   DEFVAR_LISP ("utf-2000-version", &Vutf_2000_version /*
2900 Version number of UTF-2000.
2901 */ );
2902 #endif
2903 }
2904
2905 void
2906 complex_vars_of_mule_charset (void)
2907 {
2908   staticpro (&Vcharset_hash_table);
2909   Vcharset_hash_table =
2910     make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
2911
2912   /* Predefined character sets.  We store them into variables for
2913      ease of access. */
2914
2915 #ifdef UTF2000
2916   Vcharset_ucs_bmp =
2917     make_charset (LEADING_BYTE_UCS_BMP, Qucs_bmp,
2918                   CHARSET_TYPE_256X256, 1, 0, 0,
2919                   CHARSET_LEFT_TO_RIGHT,
2920                   build_string ("BMP"),
2921                   build_string ("BMP"),
2922                   build_string ("BMP"),
2923                   build_string (""),
2924                   NULL);
2925 #endif
2926   Vcharset_ascii =
2927     make_charset (LEADING_BYTE_ASCII, Qascii,
2928                   CHARSET_TYPE_94, 1, 0, 'B',
2929                   CHARSET_LEFT_TO_RIGHT,
2930                   build_string ("ASCII"),
2931                   build_string ("ASCII)"),
2932                   build_string ("ASCII (ISO646 IRV)"),
2933                   build_string ("\\(iso8859-[0-9]*\\|-ascii\\)"),
2934                   NULL);
2935   Vcharset_control_1 =
2936     make_charset (LEADING_BYTE_CONTROL_1, Qcontrol_1,
2937                   CHARSET_TYPE_94, 1, 1, 0,
2938                   CHARSET_LEFT_TO_RIGHT,
2939                   build_string ("C1"),
2940                   build_string ("Control characters"),
2941                   build_string ("Control characters 128-191"),
2942                   build_string (""),
2943                   NULL);
2944   Vcharset_latin_iso8859_1 =
2945     make_charset (LEADING_BYTE_LATIN_ISO8859_1, Qlatin_iso8859_1,
2946                   CHARSET_TYPE_96, 1, 1, 'A',
2947                   CHARSET_LEFT_TO_RIGHT,
2948                   build_string ("Latin-1"),
2949                   build_string ("ISO8859-1 (Latin-1)"),
2950                   build_string ("ISO8859-1 (Latin-1)"),
2951                   build_string ("iso8859-1"),
2952                   NULL);
2953   Vcharset_latin_iso8859_2 =
2954     make_charset (LEADING_BYTE_LATIN_ISO8859_2, Qlatin_iso8859_2,
2955                   CHARSET_TYPE_96, 1, 1, 'B',
2956                   CHARSET_LEFT_TO_RIGHT,
2957                   build_string ("Latin-2"),
2958                   build_string ("ISO8859-2 (Latin-2)"),
2959                   build_string ("ISO8859-2 (Latin-2)"),
2960                   build_string ("iso8859-2"),
2961                   latin_iso8859_2_to_ucs);
2962   Vcharset_latin_iso8859_3 =
2963     make_charset (LEADING_BYTE_LATIN_ISO8859_3, Qlatin_iso8859_3,
2964                   CHARSET_TYPE_96, 1, 1, 'C',
2965                   CHARSET_LEFT_TO_RIGHT,
2966                   build_string ("Latin-3"),
2967                   build_string ("ISO8859-3 (Latin-3)"),
2968                   build_string ("ISO8859-3 (Latin-3)"),
2969                   build_string ("iso8859-3"),
2970                   latin_iso8859_3_to_ucs);
2971   Vcharset_latin_iso8859_4 =
2972     make_charset (LEADING_BYTE_LATIN_ISO8859_4, Qlatin_iso8859_4,
2973                   CHARSET_TYPE_96, 1, 1, 'D',
2974                   CHARSET_LEFT_TO_RIGHT,
2975                   build_string ("Latin-4"),
2976                   build_string ("ISO8859-4 (Latin-4)"),
2977                   build_string ("ISO8859-4 (Latin-4)"),
2978                   build_string ("iso8859-4"),
2979                   latin_iso8859_4_to_ucs);
2980   Vcharset_thai_tis620 =
2981     make_charset (LEADING_BYTE_THAI_TIS620, Qthai_tis620,
2982                   CHARSET_TYPE_96, 1, 1, 'T',
2983                   CHARSET_LEFT_TO_RIGHT,
2984                   build_string ("TIS620"),
2985                   build_string ("TIS620 (Thai)"),
2986                   build_string ("TIS620.2529 (Thai)"),
2987                   build_string ("tis620"),
2988                   NULL);
2989   Vcharset_greek_iso8859_7 =
2990     make_charset (LEADING_BYTE_GREEK_ISO8859_7, Qgreek_iso8859_7,
2991                   CHARSET_TYPE_96, 1, 1, 'F',
2992                   CHARSET_LEFT_TO_RIGHT,
2993                   build_string ("ISO8859-7"),
2994                   build_string ("ISO8859-7 (Greek)"),
2995                   build_string ("ISO8859-7 (Greek)"),
2996                   build_string ("iso8859-7"),
2997                   NULL);
2998   Vcharset_arabic_iso8859_6 =
2999     make_charset (LEADING_BYTE_ARABIC_ISO8859_6, Qarabic_iso8859_6,
3000                   CHARSET_TYPE_96, 1, 1, 'G',
3001                   CHARSET_RIGHT_TO_LEFT,
3002                   build_string ("ISO8859-6"),
3003                   build_string ("ISO8859-6 (Arabic)"),
3004                   build_string ("ISO8859-6 (Arabic)"),
3005                   build_string ("iso8859-6"),
3006                   NULL);
3007   Vcharset_hebrew_iso8859_8 =
3008     make_charset (LEADING_BYTE_HEBREW_ISO8859_8, Qhebrew_iso8859_8,
3009                   CHARSET_TYPE_96, 1, 1, 'H',
3010                   CHARSET_RIGHT_TO_LEFT,
3011                   build_string ("ISO8859-8"),
3012                   build_string ("ISO8859-8 (Hebrew)"),
3013                   build_string ("ISO8859-8 (Hebrew)"),
3014                   build_string ("iso8859-8"),
3015                   NULL);
3016   Vcharset_katakana_jisx0201 =
3017     make_charset (LEADING_BYTE_KATAKANA_JISX0201, Qkatakana_jisx0201,
3018                   CHARSET_TYPE_94, 1, 1, 'I',
3019                   CHARSET_LEFT_TO_RIGHT,
3020                   build_string ("JISX0201 Kana"),
3021                   build_string ("JISX0201.1976 (Japanese Kana)"),
3022                   build_string ("JISX0201.1976 Japanese Kana"),
3023                   build_string ("jisx0201.1976"),
3024                   NULL);
3025   Vcharset_latin_jisx0201 =
3026     make_charset (LEADING_BYTE_LATIN_JISX0201, Qlatin_jisx0201,
3027                   CHARSET_TYPE_94, 1, 0, 'J',
3028                   CHARSET_LEFT_TO_RIGHT,
3029                   build_string ("JISX0201 Roman"),
3030                   build_string ("JISX0201.1976 (Japanese Roman)"),
3031                   build_string ("JISX0201.1976 Japanese Roman"),
3032                   build_string ("jisx0201.1976"),
3033                   latin_jisx0201_to_ucs);
3034   Vcharset_cyrillic_iso8859_5 =
3035     make_charset (LEADING_BYTE_CYRILLIC_ISO8859_5, Qcyrillic_iso8859_5,
3036                   CHARSET_TYPE_96, 1, 1, 'L',
3037                   CHARSET_LEFT_TO_RIGHT,
3038                   build_string ("ISO8859-5"),
3039                   build_string ("ISO8859-5 (Cyrillic)"),
3040                   build_string ("ISO8859-5 (Cyrillic)"),
3041                   build_string ("iso8859-5"),
3042                   NULL);
3043   Vcharset_latin_iso8859_9 =
3044     make_charset (LEADING_BYTE_LATIN_ISO8859_9, Qlatin_iso8859_9,
3045                   CHARSET_TYPE_96, 1, 1, 'M',
3046                   CHARSET_LEFT_TO_RIGHT,
3047                   build_string ("Latin-5"),
3048                   build_string ("ISO8859-9 (Latin-5)"),
3049                   build_string ("ISO8859-9 (Latin-5)"),
3050                   build_string ("iso8859-9"),
3051                   latin_iso8859_9_to_ucs);
3052   Vcharset_japanese_jisx0208_1978 =
3053     make_charset (LEADING_BYTE_JAPANESE_JISX0208_1978, Qjapanese_jisx0208_1978,
3054                   CHARSET_TYPE_94X94, 2, 0, '@',
3055                   CHARSET_LEFT_TO_RIGHT,
3056                   build_string ("JISX0208.1978"),
3057                   build_string ("JISX0208.1978 (Japanese)"),
3058                   build_string
3059                   ("JISX0208.1978 Japanese Kanji (so called \"old JIS\")"),
3060                   build_string ("\\(jisx0208\\|jisc6226\\)\\.1978"),
3061                   NULL);
3062   Vcharset_chinese_gb2312 =
3063     make_charset (LEADING_BYTE_CHINESE_GB2312, Qchinese_gb2312,
3064                   CHARSET_TYPE_94X94, 2, 0, 'A',
3065                   CHARSET_LEFT_TO_RIGHT,
3066                   build_string ("GB2312"),
3067                   build_string ("GB2312)"),
3068                   build_string ("GB2312 Chinese simplified"),
3069                   build_string ("gb2312"),
3070                   NULL);
3071   Vcharset_japanese_jisx0208 =
3072     make_charset (LEADING_BYTE_JAPANESE_JISX0208, Qjapanese_jisx0208,
3073                   CHARSET_TYPE_94X94, 2, 0, 'B',
3074                   CHARSET_LEFT_TO_RIGHT,
3075                   build_string ("JISX0208"),
3076                   build_string ("JISX0208.1983/1990 (Japanese)"),
3077                   build_string ("JISX0208.1983/1990 Japanese Kanji"),
3078                   build_string ("jisx0208.19\\(83\\|90\\)"),
3079                   NULL);
3080   Vcharset_korean_ksc5601 =
3081     make_charset (LEADING_BYTE_KOREAN_KSC5601, Qkorean_ksc5601,
3082                   CHARSET_TYPE_94X94, 2, 0, 'C',
3083                   CHARSET_LEFT_TO_RIGHT,
3084                   build_string ("KSC5601"),
3085                   build_string ("KSC5601 (Korean"),
3086                   build_string ("KSC5601 Korean Hangul and Hanja"),
3087                   build_string ("ksc5601"),
3088                   NULL);
3089   Vcharset_japanese_jisx0212 =
3090     make_charset (LEADING_BYTE_JAPANESE_JISX0212, Qjapanese_jisx0212,
3091                   CHARSET_TYPE_94X94, 2, 0, 'D',
3092                   CHARSET_LEFT_TO_RIGHT,
3093                   build_string ("JISX0212"),
3094                   build_string ("JISX0212 (Japanese)"),
3095                   build_string ("JISX0212 Japanese Supplement"),
3096                   build_string ("jisx0212"),
3097                   NULL);
3098
3099 #define CHINESE_CNS_PLANE_RE(n) "cns11643[.-]\\(.*[.-]\\)?" n "$"
3100   Vcharset_chinese_cns11643_1 =
3101     make_charset (LEADING_BYTE_CHINESE_CNS11643_1, Qchinese_cns11643_1,
3102                   CHARSET_TYPE_94X94, 2, 0, 'G',
3103                   CHARSET_LEFT_TO_RIGHT,
3104                   build_string ("CNS11643-1"),
3105                   build_string ("CNS11643-1 (Chinese traditional)"),
3106                   build_string
3107                   ("CNS 11643 Plane 1 Chinese traditional"),
3108                   build_string (CHINESE_CNS_PLANE_RE("1")),
3109                   NULL);
3110   Vcharset_chinese_cns11643_2 =
3111     make_charset (LEADING_BYTE_CHINESE_CNS11643_2, Qchinese_cns11643_2,
3112                   CHARSET_TYPE_94X94, 2, 0, 'H',
3113                   CHARSET_LEFT_TO_RIGHT,
3114                   build_string ("CNS11643-2"),
3115                   build_string ("CNS11643-2 (Chinese traditional)"),
3116                   build_string
3117                   ("CNS 11643 Plane 2 Chinese traditional"),
3118                   build_string (CHINESE_CNS_PLANE_RE("2")),
3119                   NULL);
3120 #ifdef UTF2000
3121   Vcharset_chinese_cns11643_3 =
3122     make_charset (LEADING_BYTE_CHINESE_CNS11643_3, Qchinese_cns11643_3,
3123                   CHARSET_TYPE_94X94, 2, 0, 'I',
3124                   CHARSET_LEFT_TO_RIGHT,
3125                   build_string ("CNS11643-3"),
3126                   build_string ("CNS11643-3 (Chinese traditional)"),
3127                   build_string
3128                   ("CNS 11643 Plane 3 Chinese traditional"),
3129                   build_string (CHINESE_CNS_PLANE_RE("3")),
3130                   NULL);
3131   Vcharset_chinese_cns11643_4 =
3132     make_charset (LEADING_BYTE_CHINESE_CNS11643_4, Qchinese_cns11643_4,
3133                   CHARSET_TYPE_94X94, 2, 0, 'J',
3134                   CHARSET_LEFT_TO_RIGHT,
3135                   build_string ("CNS11643-4"),
3136                   build_string ("CNS11643-4 (Chinese traditional)"),
3137                   build_string
3138                   ("CNS 11643 Plane 4 Chinese traditional"),
3139                   build_string (CHINESE_CNS_PLANE_RE("4")),
3140                   NULL);
3141   Vcharset_chinese_cns11643_5 =
3142     make_charset (LEADING_BYTE_CHINESE_CNS11643_5, Qchinese_cns11643_5,
3143                   CHARSET_TYPE_94X94, 2, 0, 'K',
3144                   CHARSET_LEFT_TO_RIGHT,
3145                   build_string ("CNS11643-5"),
3146                   build_string ("CNS11643-5 (Chinese traditional)"),
3147                   build_string
3148                   ("CNS 11643 Plane 5 Chinese traditional"),
3149                   build_string (CHINESE_CNS_PLANE_RE("5")),
3150                   NULL);
3151   Vcharset_chinese_cns11643_6 =
3152     make_charset (LEADING_BYTE_CHINESE_CNS11643_6, Qchinese_cns11643_6,
3153                   CHARSET_TYPE_94X94, 2, 0, 'L',
3154                   CHARSET_LEFT_TO_RIGHT,
3155                   build_string ("CNS11643-6"),
3156                   build_string ("CNS11643-6 (Chinese traditional)"),
3157                   build_string
3158                   ("CNS 11643 Plane 6 Chinese traditional"),
3159                   build_string (CHINESE_CNS_PLANE_RE("6")),
3160                   NULL);
3161   Vcharset_chinese_cns11643_7 =
3162     make_charset (LEADING_BYTE_CHINESE_CNS11643_7, Qchinese_cns11643_7,
3163                   CHARSET_TYPE_94X94, 2, 0, 'M',
3164                   CHARSET_LEFT_TO_RIGHT,
3165                   build_string ("CNS11643-7"),
3166                   build_string ("CNS11643-7 (Chinese traditional)"),
3167                   build_string
3168                   ("CNS 11643 Plane 7 Chinese traditional"),
3169                   build_string (CHINESE_CNS_PLANE_RE("7")),
3170                   NULL);
3171   Vcharset_latin_viscii_lower =
3172     make_charset (LEADING_BYTE_LATIN_VISCII_LOWER, Qlatin_viscii_lower,
3173                   CHARSET_TYPE_96, 1, 1, '1',
3174                   CHARSET_LEFT_TO_RIGHT,
3175                   build_string ("VISCII lower"),
3176                   build_string ("VISCII lower (Vietnamese)"),
3177                   build_string ("VISCII lower (Vietnamese)"),
3178                   build_string ("VISCII1.1"),
3179                   latin_viscii_lower_to_ucs);
3180   Vcharset_latin_viscii_upper =
3181     make_charset (LEADING_BYTE_LATIN_VISCII_UPPER, Qlatin_viscii_upper,
3182                   CHARSET_TYPE_96, 1, 1, '2',
3183                   CHARSET_LEFT_TO_RIGHT,
3184                   build_string ("VISCII upper"),
3185                   build_string ("VISCII upper (Vietnamese)"),
3186                   build_string ("VISCII upper (Vietnamese)"),
3187                   build_string ("VISCII1.1"),
3188                   latin_viscii_upper_to_ucs);
3189 #endif
3190   Vcharset_chinese_big5_1 =
3191     make_charset (LEADING_BYTE_CHINESE_BIG5_1, Qchinese_big5_1,
3192                   CHARSET_TYPE_94X94, 2, 0, '0',
3193                   CHARSET_LEFT_TO_RIGHT,
3194                   build_string ("Big5"),
3195                   build_string ("Big5 (Level-1)"),
3196                   build_string
3197                   ("Big5 Level-1 Chinese traditional"),
3198                   build_string ("big5"),
3199                   NULL);
3200   Vcharset_chinese_big5_2 =
3201     make_charset (LEADING_BYTE_CHINESE_BIG5_2, Qchinese_big5_2,
3202                   CHARSET_TYPE_94X94, 2, 0, '1',
3203                   CHARSET_LEFT_TO_RIGHT,
3204                   build_string ("Big5"),
3205                   build_string ("Big5 (Level-2)"),
3206                   build_string
3207                   ("Big5 Level-2 Chinese traditional"),
3208                   build_string ("big5"),
3209                   NULL);
3210
3211 #ifdef ENABLE_COMPOSITE_CHARS
3212   /* #### For simplicity, we put composite chars into a 96x96 charset.
3213      This is going to lead to problems because you can run out of
3214      room, esp. as we don't yet recycle numbers. */
3215   Vcharset_composite =
3216     make_charset (LEADING_BYTE_COMPOSITE, Qcomposite,
3217                   CHARSET_TYPE_96X96, 2, 0, 0,
3218                   CHARSET_LEFT_TO_RIGHT,
3219                   build_string ("Composite"),
3220                   build_string ("Composite characters"),
3221                   build_string ("Composite characters"),
3222                   build_string (""));
3223
3224   composite_char_row_next = 32;
3225   composite_char_col_next = 32;
3226
3227   Vcomposite_char_string2char_hash_table =
3228     make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
3229   Vcomposite_char_char2string_hash_table =
3230     make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3231   staticpro (&Vcomposite_char_string2char_hash_table);
3232   staticpro (&Vcomposite_char_char2string_hash_table);
3233 #endif /* ENABLE_COMPOSITE_CHARS */
3234
3235 }