(ucs_to_latin_jisx0201): Deleted.
[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 #endif
1908       break;
1909     case CHARSET_TYPE_96:
1910       CHARSET_DIMENSION (cs) = 1;
1911       CHARSET_CHARS (cs) = 96;
1912       if (decoding_table != NULL)
1913         {
1914           size_t i;
1915           CHARSET_TO_BYTE1_TABLE(cs) = make_byte_from_character_table();
1916           for (i = 0; i < 96; i++)
1917             {
1918               Emchar c = decoding_table[i];
1919
1920               if (c <= 0xffff)
1921                 put_byte_from_character_table (c, i + 32,
1922                                                CHARSET_TO_BYTE1_TABLE(cs));
1923             }
1924         }
1925       break;
1926     case CHARSET_TYPE_94X94:
1927       CHARSET_DIMENSION (cs) = 2;
1928       CHARSET_CHARS (cs) = 94;
1929       break;
1930     case CHARSET_TYPE_96X96:
1931       CHARSET_DIMENSION (cs) = 2;
1932       CHARSET_CHARS (cs) = 96;
1933       break;
1934 #ifdef UTF2000
1935     case CHARSET_TYPE_128X128:
1936       CHARSET_DIMENSION (cs) = 2;
1937       CHARSET_CHARS (cs) = 128;
1938       break;
1939     case CHARSET_TYPE_256X256:
1940       CHARSET_DIMENSION (cs) = 2;
1941       CHARSET_CHARS (cs) = 256;
1942       break;
1943 #endif
1944     }
1945
1946 #ifndef UTF2000
1947   if (id == LEADING_BYTE_ASCII)
1948     CHARSET_REP_BYTES (cs) = 1;
1949   else if (id < 0xA0)
1950     CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 1;
1951   else
1952     CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 2;
1953 #endif
1954   
1955   if (final)
1956     {
1957       /* some charsets do not have final characters.  This includes
1958          ASCII, Control-1, Composite, and the two faux private
1959          charsets. */
1960 #if UTF2000
1961       assert (NILP (charset_by_attributes[type][final]));
1962       charset_by_attributes[type][final] = obj;
1963 #else
1964       assert (NILP (charset_by_attributes[type][final][direction]));
1965       charset_by_attributes[type][final][direction] = obj;
1966 #endif
1967     }
1968
1969   assert (NILP (charset_by_leading_byte[id - MIN_LEADING_BYTE]));
1970   charset_by_leading_byte[id - MIN_LEADING_BYTE] = obj;
1971 #ifndef UTF2000
1972   if (id < 0xA0)
1973     /* official leading byte */
1974     rep_bytes_by_first_byte[id] = CHARSET_REP_BYTES (cs);
1975 #endif
1976
1977   /* Some charsets are "faux" and don't have names or really exist at
1978      all except in the leading-byte table. */
1979   if (!NILP (name))
1980     Fputhash (name, obj, Vcharset_hash_table);
1981   return obj;
1982 }
1983
1984 static int
1985 get_unallocated_leading_byte (int dimension)
1986 {
1987   Charset_ID lb;
1988
1989   if (dimension == 1)
1990     {
1991       if (next_allocated_1_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_1)
1992         lb = 0;
1993       else
1994         lb = next_allocated_1_byte_leading_byte++;
1995     }
1996   else
1997     {
1998       if (next_allocated_2_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_2)
1999         lb = 0;
2000       else
2001         lb = next_allocated_2_byte_leading_byte++;
2002     }
2003
2004   if (!lb)
2005     signal_simple_error
2006       ("No more character sets free for this dimension",
2007        make_int (dimension));
2008
2009   return lb;
2010 }
2011
2012 \f
2013 /************************************************************************/
2014 /*                      Basic charset Lisp functions                    */
2015 /************************************************************************/
2016
2017 DEFUN ("charsetp", Fcharsetp, 1, 1, 0, /*
2018 Return non-nil if OBJECT is a charset.
2019 */
2020        (object))
2021 {
2022   return CHARSETP (object) ? Qt : Qnil;
2023 }
2024
2025 DEFUN ("find-charset", Ffind_charset, 1, 1, 0, /*
2026 Retrieve the charset of the given name.
2027 If CHARSET-OR-NAME is a charset object, it is simply returned.
2028 Otherwise, CHARSET-OR-NAME should be a symbol.  If there is no such charset,
2029 nil is returned.  Otherwise the associated charset object is returned.
2030 */
2031        (charset_or_name))
2032 {
2033   if (CHARSETP (charset_or_name))
2034     return charset_or_name;
2035
2036   CHECK_SYMBOL (charset_or_name);
2037   return Fgethash (charset_or_name, Vcharset_hash_table, Qnil);
2038 }
2039
2040 DEFUN ("get-charset", Fget_charset, 1, 1, 0, /*
2041 Retrieve the charset of the given name.
2042 Same as `find-charset' except an error is signalled if there is no such
2043 charset instead of returning nil.
2044 */
2045        (name))
2046 {
2047   Lisp_Object charset = Ffind_charset (name);
2048
2049   if (NILP (charset))
2050     signal_simple_error ("No such charset", name);
2051   return charset;
2052 }
2053
2054 /* We store the charsets in hash tables with the names as the key and the
2055    actual charset object as the value.  Occasionally we need to use them
2056    in a list format.  These routines provide us with that. */
2057 struct charset_list_closure
2058 {
2059   Lisp_Object *charset_list;
2060 };
2061
2062 static int
2063 add_charset_to_list_mapper (Lisp_Object key, Lisp_Object value,
2064                             void *charset_list_closure)
2065 {
2066   /* This function can GC */
2067   struct charset_list_closure *chcl =
2068     (struct charset_list_closure*) charset_list_closure;
2069   Lisp_Object *charset_list = chcl->charset_list;
2070
2071   *charset_list = Fcons (XCHARSET_NAME (value), *charset_list);
2072   return 0;
2073 }
2074
2075 DEFUN ("charset-list", Fcharset_list, 0, 0, 0, /*
2076 Return a list of the names of all defined charsets.
2077 */
2078        ())
2079 {
2080   Lisp_Object charset_list = Qnil;
2081   struct gcpro gcpro1;
2082   struct charset_list_closure charset_list_closure;
2083
2084   GCPRO1 (charset_list);
2085   charset_list_closure.charset_list = &charset_list;
2086   elisp_maphash (add_charset_to_list_mapper, Vcharset_hash_table,
2087                  &charset_list_closure);
2088   UNGCPRO;
2089
2090   return charset_list;
2091 }
2092
2093 DEFUN ("charset-name", Fcharset_name, 1, 1, 0, /*
2094 Return the name of the given charset.
2095 */
2096        (charset))
2097 {
2098   return XCHARSET_NAME (Fget_charset (charset));
2099 }
2100
2101 DEFUN ("make-charset", Fmake_charset, 3, 3, 0, /*
2102 Define a new character set.
2103 This function is for use with Mule support.
2104 NAME is a symbol, the name by which the character set is normally referred.
2105 DOC-STRING is a string describing the character set.
2106 PROPS is a property list, describing the specific nature of the
2107 character set.  Recognized properties are:
2108
2109 'short-name     Short version of the charset name (ex: Latin-1)
2110 'long-name      Long version of the charset name (ex: ISO8859-1 (Latin-1))
2111 'registry       A regular expression matching the font registry field for
2112                 this character set.
2113 'dimension      Number of octets used to index a character in this charset.
2114                 Either 1 or 2.  Defaults to 1.
2115 'columns        Number of columns used to display a character in this charset.
2116                 Only used in TTY mode. (Under X, the actual width of a
2117                 character can be derived from the font used to display the
2118                 characters.) If unspecified, defaults to the dimension
2119                 (this is almost always the correct value).
2120 'chars          Number of characters in each dimension (94 or 96).
2121                 Defaults to 94.  Note that if the dimension is 2, the
2122                 character set thus described is 94x94 or 96x96.
2123 'final          Final byte of ISO 2022 escape sequence.  Must be
2124                 supplied.  Each combination of (DIMENSION, CHARS) defines a
2125                 separate namespace for final bytes.  Note that ISO
2126                 2022 restricts the final byte to the range
2127                 0x30 - 0x7E if dimension == 1, and 0x30 - 0x5F if
2128                 dimension == 2.  Note also that final bytes in the range
2129                 0x30 - 0x3F are reserved for user-defined (not official)
2130                 character sets.
2131 'graphic        0 (use left half of font on output) or 1 (use right half
2132                 of font on output).  Defaults to 0.  For example, for
2133                 a font whose registry is ISO8859-1, the left half
2134                 (octets 0x20 - 0x7F) is the `ascii' character set, while
2135                 the right half (octets 0xA0 - 0xFF) is the `latin-1'
2136                 character set.  With 'graphic set to 0, the octets
2137                 will have their high bit cleared; with it set to 1,
2138                 the octets will have their high bit set.
2139 'direction      'l2r (left-to-right) or 'r2l (right-to-left).
2140                 Defaults to 'l2r.
2141 'ccl-program    A compiled CCL program used to convert a character in
2142                 this charset into an index into the font.  This is in
2143                 addition to the 'graphic property.  The CCL program
2144                 is passed the octets of the character, with the high
2145                 bit cleared and set depending upon whether the value
2146                 of the 'graphic property is 0 or 1.
2147 */
2148        (name, doc_string, props))
2149 {
2150   int id, dimension = 1, chars = 94, graphic = 0, final = 0, columns = -1;
2151   int direction = CHARSET_LEFT_TO_RIGHT;
2152   int type;
2153   Lisp_Object registry = Qnil;
2154   Lisp_Object charset;
2155   Lisp_Object rest, keyword, value;
2156   Lisp_Object ccl_program = Qnil;
2157   Lisp_Object short_name = Qnil, long_name = Qnil;
2158
2159   CHECK_SYMBOL (name);
2160   if (!NILP (doc_string))
2161     CHECK_STRING (doc_string);
2162
2163   charset = Ffind_charset (name);
2164   if (!NILP (charset))
2165     signal_simple_error ("Cannot redefine existing charset", name);
2166
2167   EXTERNAL_PROPERTY_LIST_LOOP (rest, keyword, value, props)
2168     {
2169       if (EQ (keyword, Qshort_name))
2170         {
2171           CHECK_STRING (value);
2172           short_name = value;
2173         }
2174
2175       if (EQ (keyword, Qlong_name))
2176         {
2177           CHECK_STRING (value);
2178           long_name = value;
2179         }
2180
2181       else if (EQ (keyword, Qdimension))
2182         {
2183           CHECK_INT (value);
2184           dimension = XINT (value);
2185           if (dimension < 1 || dimension > 2)
2186             signal_simple_error ("Invalid value for 'dimension", value);
2187         }
2188
2189       else if (EQ (keyword, Qchars))
2190         {
2191           CHECK_INT (value);
2192           chars = XINT (value);
2193           if (chars != 94 && chars != 96)
2194             signal_simple_error ("Invalid value for 'chars", value);
2195         }
2196
2197       else if (EQ (keyword, Qcolumns))
2198         {
2199           CHECK_INT (value);
2200           columns = XINT (value);
2201           if (columns != 1 && columns != 2)
2202             signal_simple_error ("Invalid value for 'columns", value);
2203         }
2204
2205       else if (EQ (keyword, Qgraphic))
2206         {
2207           CHECK_INT (value);
2208           graphic = XINT (value);
2209           if (graphic < 0 || graphic > 1)
2210             signal_simple_error ("Invalid value for 'graphic", value);
2211         }
2212
2213       else if (EQ (keyword, Qregistry))
2214         {
2215           CHECK_STRING (value);
2216           registry = value;
2217         }
2218
2219       else if (EQ (keyword, Qdirection))
2220         {
2221           if (EQ (value, Ql2r))
2222             direction = CHARSET_LEFT_TO_RIGHT;
2223           else if (EQ (value, Qr2l))
2224             direction = CHARSET_RIGHT_TO_LEFT;
2225           else
2226             signal_simple_error ("Invalid value for 'direction", value);
2227         }
2228
2229       else if (EQ (keyword, Qfinal))
2230         {
2231           CHECK_CHAR_COERCE_INT (value);
2232           final = XCHAR (value);
2233           if (final < '0' || final > '~')
2234             signal_simple_error ("Invalid value for 'final", value);
2235         }
2236
2237       else if (EQ (keyword, Qccl_program))
2238         {
2239           CHECK_VECTOR (value);
2240           ccl_program = value;
2241         }
2242
2243       else
2244         signal_simple_error ("Unrecognized property", keyword);
2245     }
2246
2247   if (!final)
2248     error ("'final must be specified");
2249   if (dimension == 2 && final > 0x5F)
2250     signal_simple_error
2251       ("Final must be in the range 0x30 - 0x5F for dimension == 2",
2252        make_char (final));
2253
2254   if (dimension == 1)
2255     type = (chars == 94) ? CHARSET_TYPE_94    : CHARSET_TYPE_96;
2256   else
2257     type = (chars == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96;
2258
2259   if (!NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_LEFT_TO_RIGHT)) ||
2260       !NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_RIGHT_TO_LEFT)))
2261     error
2262       ("Character set already defined for this DIMENSION/CHARS/FINAL combo");
2263
2264 #ifdef UTF2000
2265   if (dimension == 1)
2266     {
2267       if (chars == 94)
2268         {
2269           /* id = CHARSET_ID_OFFSET_94 + final; */
2270           id = get_unallocated_leading_byte (dimension);
2271         }
2272       else if (chars == 96)
2273         {
2274           id = get_unallocated_leading_byte (dimension);
2275         }
2276       else
2277         {
2278           abort ();
2279         }
2280     }
2281   else if (dimension == 2)
2282     {
2283       if (chars == 94)
2284         {
2285           id = get_unallocated_leading_byte (dimension);
2286         }
2287       else if (chars == 96)
2288         {
2289           id = get_unallocated_leading_byte (dimension);
2290         }
2291       else
2292         {
2293           abort ();
2294         }
2295     }
2296   else
2297     {
2298       abort ();
2299     }
2300 #else
2301   id = get_unallocated_leading_byte (dimension);
2302 #endif
2303
2304   if (NILP (doc_string))
2305     doc_string = build_string ("");
2306
2307   if (NILP (registry))
2308     registry = build_string ("");
2309
2310   if (NILP (short_name))
2311     XSETSTRING (short_name, XSYMBOL (name)->name);
2312
2313   if (NILP (long_name))
2314     long_name = doc_string;
2315
2316   if (columns == -1)
2317     columns = dimension;
2318   charset = make_charset (id, name, type, columns, graphic,
2319                           final, direction, short_name, long_name,
2320                           doc_string, registry,
2321                           NULL);
2322   if (!NILP (ccl_program))
2323     XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2324   return charset;
2325 }
2326
2327 DEFUN ("make-reverse-direction-charset", Fmake_reverse_direction_charset,
2328        2, 2, 0, /*
2329 Make a charset equivalent to CHARSET but which goes in the opposite direction.
2330 NEW-NAME is the name of the new charset.  Return the new charset.
2331 */
2332        (charset, new_name))
2333 {
2334   Lisp_Object new_charset = Qnil;
2335   int id, dimension, columns, graphic, final;
2336   int direction, type;
2337   Lisp_Object registry, doc_string, short_name, long_name;
2338   struct Lisp_Charset *cs;
2339
2340   charset = Fget_charset (charset);
2341   if (!NILP (XCHARSET_REVERSE_DIRECTION_CHARSET (charset)))
2342     signal_simple_error ("Charset already has reverse-direction charset",
2343                          charset);
2344
2345   CHECK_SYMBOL (new_name);
2346   if (!NILP (Ffind_charset (new_name)))
2347     signal_simple_error ("Cannot redefine existing charset", new_name);
2348
2349   cs = XCHARSET (charset);
2350
2351   type      = CHARSET_TYPE      (cs);
2352   columns   = CHARSET_COLUMNS   (cs);
2353   dimension = CHARSET_DIMENSION (cs);
2354   id = get_unallocated_leading_byte (dimension);
2355
2356   graphic = CHARSET_GRAPHIC (cs);
2357   final = CHARSET_FINAL (cs);
2358   direction = CHARSET_RIGHT_TO_LEFT;
2359   if (CHARSET_DIRECTION (cs) == CHARSET_RIGHT_TO_LEFT)
2360     direction = CHARSET_LEFT_TO_RIGHT;
2361   doc_string = CHARSET_DOC_STRING (cs);
2362   short_name = CHARSET_SHORT_NAME (cs);
2363   long_name = CHARSET_LONG_NAME (cs);
2364   registry = CHARSET_REGISTRY (cs);
2365
2366   new_charset = make_charset (id, new_name, type, columns,
2367                               graphic, final, direction, short_name, long_name,
2368                               doc_string, registry,
2369                               NULL);
2370
2371   CHARSET_REVERSE_DIRECTION_CHARSET (cs) = new_charset;
2372   XCHARSET_REVERSE_DIRECTION_CHARSET (new_charset) = charset;
2373
2374   return new_charset;
2375 }
2376
2377 /* #### Reverse direction charsets not yet implemented.  */
2378 #if 0
2379 DEFUN ("charset-reverse-direction-charset", Fcharset_reverse_direction_charset,
2380        1, 1, 0, /*
2381 Return the reverse-direction charset parallel to CHARSET, if any.
2382 This is the charset with the same properties (in particular, the same
2383 dimension, number of characters per dimension, and final byte) as
2384 CHARSET but whose characters are displayed in the opposite direction.
2385 */
2386        (charset))
2387 {
2388   charset = Fget_charset (charset);
2389   return XCHARSET_REVERSE_DIRECTION_CHARSET (charset);
2390 }
2391 #endif
2392
2393 DEFUN ("charset-from-attributes", Fcharset_from_attributes, 3, 4, 0, /*
2394 Return a charset with the given DIMENSION, CHARS, FINAL, and DIRECTION.
2395 If DIRECTION is omitted, both directions will be checked (left-to-right
2396 will be returned if character sets exist for both directions).
2397 */
2398        (dimension, chars, final, direction))
2399 {
2400   int dm, ch, fi, di = -1;
2401   int type;
2402   Lisp_Object obj = Qnil;
2403
2404   CHECK_INT (dimension);
2405   dm = XINT (dimension);
2406   if (dm < 1 || dm > 2)
2407     signal_simple_error ("Invalid value for DIMENSION", dimension);
2408
2409   CHECK_INT (chars);
2410   ch = XINT (chars);
2411   if (ch != 94 && ch != 96)
2412     signal_simple_error ("Invalid value for CHARS", chars);
2413
2414   CHECK_CHAR_COERCE_INT (final);
2415   fi = XCHAR (final);
2416   if (fi < '0' || fi > '~')
2417     signal_simple_error ("Invalid value for FINAL", final);
2418
2419   if (EQ (direction, Ql2r))
2420     di = CHARSET_LEFT_TO_RIGHT;
2421   else if (EQ (direction, Qr2l))
2422     di = CHARSET_RIGHT_TO_LEFT;
2423   else if (!NILP (direction))
2424     signal_simple_error ("Invalid value for DIRECTION", direction);
2425
2426   if (dm == 2 && fi > 0x5F)
2427     signal_simple_error
2428       ("Final must be in the range 0x30 - 0x5F for dimension == 2", final);
2429
2430   if (dm == 1)
2431     type = (ch == 94) ? CHARSET_TYPE_94    : CHARSET_TYPE_96;
2432   else
2433     type = (ch == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96;
2434
2435   if (di == -1)
2436     {
2437       obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_LEFT_TO_RIGHT);
2438       if (NILP (obj))
2439         obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_RIGHT_TO_LEFT);
2440     }
2441   else
2442     obj = CHARSET_BY_ATTRIBUTES (type, fi, di);
2443
2444   if (CHARSETP (obj))
2445     return XCHARSET_NAME (obj);
2446   return obj;
2447 }
2448
2449 DEFUN ("charset-short-name", Fcharset_short_name, 1, 1, 0, /*
2450 Return short name of CHARSET.
2451 */
2452        (charset))
2453 {
2454   return XCHARSET_SHORT_NAME (Fget_charset (charset));
2455 }
2456
2457 DEFUN ("charset-long-name", Fcharset_long_name, 1, 1, 0, /*
2458 Return long name of CHARSET.
2459 */
2460        (charset))
2461 {
2462   return XCHARSET_LONG_NAME (Fget_charset (charset));
2463 }
2464
2465 DEFUN ("charset-description", Fcharset_description, 1, 1, 0, /*
2466 Return description of CHARSET.
2467 */
2468        (charset))
2469 {
2470   return XCHARSET_DOC_STRING (Fget_charset (charset));
2471 }
2472
2473 DEFUN ("charset-dimension", Fcharset_dimension, 1, 1, 0, /*
2474 Return dimension of CHARSET.
2475 */
2476        (charset))
2477 {
2478   return make_int (XCHARSET_DIMENSION (Fget_charset (charset)));
2479 }
2480
2481 DEFUN ("charset-property", Fcharset_property, 2, 2, 0, /*
2482 Return property PROP of CHARSET.
2483 Recognized properties are those listed in `make-charset', as well as
2484 'name and 'doc-string.
2485 */
2486        (charset, prop))
2487 {
2488   struct Lisp_Charset *cs;
2489
2490   charset = Fget_charset (charset);
2491   cs = XCHARSET (charset);
2492
2493   CHECK_SYMBOL (prop);
2494   if (EQ (prop, Qname))        return CHARSET_NAME (cs);
2495   if (EQ (prop, Qshort_name))  return CHARSET_SHORT_NAME (cs);
2496   if (EQ (prop, Qlong_name))   return CHARSET_LONG_NAME (cs);
2497   if (EQ (prop, Qdoc_string))  return CHARSET_DOC_STRING (cs);
2498   if (EQ (prop, Qdimension))   return make_int (CHARSET_DIMENSION (cs));
2499   if (EQ (prop, Qcolumns))     return make_int (CHARSET_COLUMNS (cs));
2500   if (EQ (prop, Qgraphic))     return make_int (CHARSET_GRAPHIC (cs));
2501   if (EQ (prop, Qfinal))       return make_char (CHARSET_FINAL (cs));
2502   if (EQ (prop, Qchars))       return make_int (CHARSET_CHARS (cs));
2503   if (EQ (prop, Qregistry))    return CHARSET_REGISTRY (cs);
2504   if (EQ (prop, Qccl_program)) return CHARSET_CCL_PROGRAM (cs);
2505   if (EQ (prop, Qdirection))
2506     return CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? Ql2r : Qr2l;
2507   if (EQ (prop, Qreverse_direction_charset))
2508     {
2509       Lisp_Object obj = CHARSET_REVERSE_DIRECTION_CHARSET (cs);
2510       if (NILP (obj))
2511         return Qnil;
2512       else
2513         return XCHARSET_NAME (obj);
2514     }
2515   signal_simple_error ("Unrecognized charset property name", prop);
2516   return Qnil; /* not reached */
2517 }
2518
2519 DEFUN ("charset-id", Fcharset_id, 1, 1, 0, /*
2520 Return charset identification number of CHARSET.
2521 */
2522         (charset))
2523 {
2524   return make_int(XCHARSET_LEADING_BYTE (Fget_charset (charset)));
2525 }
2526
2527 /* #### We need to figure out which properties we really want to
2528    allow to be set. */
2529
2530 DEFUN ("set-charset-ccl-program", Fset_charset_ccl_program, 2, 2, 0, /*
2531 Set the 'ccl-program property of CHARSET to CCL-PROGRAM.
2532 */
2533        (charset, ccl_program))
2534 {
2535   charset = Fget_charset (charset);
2536   CHECK_VECTOR (ccl_program);
2537   XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2538   return Qnil;
2539 }
2540
2541 static void
2542 invalidate_charset_font_caches (Lisp_Object charset)
2543 {
2544   /* Invalidate font cache entries for charset on all devices. */
2545   Lisp_Object devcons, concons, hash_table;
2546   DEVICE_LOOP_NO_BREAK (devcons, concons)
2547     {
2548       struct device *d = XDEVICE (XCAR (devcons));
2549       hash_table = Fgethash (charset, d->charset_font_cache, Qunbound);
2550       if (!UNBOUNDP (hash_table))
2551         Fclrhash (hash_table);
2552     }
2553 }
2554
2555 /* Japanese folks may want to (set-charset-registry 'ascii "jisx0201") */
2556 DEFUN ("set-charset-registry", Fset_charset_registry, 2, 2, 0, /*
2557 Set the 'registry property of CHARSET to REGISTRY.
2558 */
2559        (charset, registry))
2560 {
2561   charset = Fget_charset (charset);
2562   CHECK_STRING (registry);
2563   XCHARSET_REGISTRY (charset) = registry;
2564   invalidate_charset_font_caches (charset);
2565   face_property_was_changed (Vdefault_face, Qfont, Qglobal);
2566   return Qnil;
2567 }
2568
2569 \f
2570 /************************************************************************/
2571 /*              Lisp primitives for working with characters             */
2572 /************************************************************************/
2573
2574 DEFUN ("make-char", Fmake_char, 2, 3, 0, /*
2575 Make a character from CHARSET and octets ARG1 and ARG2.
2576 ARG2 is required only for characters from two-dimensional charsets.
2577 For example, (make-char 'latin-iso8859-2 185) will return the Latin 2
2578 character s with caron.
2579 */
2580        (charset, arg1, arg2))
2581 {
2582   struct Lisp_Charset *cs;
2583   int a1, a2;
2584   int lowlim, highlim;
2585
2586   charset = Fget_charset (charset);
2587   cs = XCHARSET (charset);
2588
2589   if      (EQ (charset, Vcharset_ascii))     lowlim =  0, highlim = 127;
2590   else if (EQ (charset, Vcharset_control_1)) lowlim =  0, highlim =  31;
2591 #ifdef UTF2000
2592   else if (CHARSET_CHARS (cs) == 256)        lowlim =  0, highlim = 255;
2593 #endif
2594   else if (CHARSET_CHARS (cs) == 94)         lowlim = 33, highlim = 126;
2595   else  /* CHARSET_CHARS (cs) == 96) */      lowlim = 32, highlim = 127;
2596
2597   CHECK_INT (arg1);
2598   /* It is useful (and safe, according to Olivier Galibert) to strip
2599      the 8th bit off ARG1 and ARG2 becaue it allows programmers to
2600      write (make-char 'latin-iso8859-2 CODE) where code is the actual
2601      Latin 2 code of the character.  */
2602 #ifdef UTF2000
2603   a1 = XINT (arg1);
2604   if (highlim < 128)
2605     a1 &= 0x7f;
2606 #else
2607   a1 = XINT (arg1);
2608 #endif
2609   if (a1 < lowlim || a1 > highlim)
2610     args_out_of_range_3 (arg1, make_int (lowlim), make_int (highlim));
2611
2612   if (CHARSET_DIMENSION (cs) == 1)
2613     {
2614       if (!NILP (arg2))
2615         signal_simple_error
2616           ("Charset is of dimension one; second octet must be nil", arg2);
2617       return make_char (MAKE_CHAR (charset, a1, 0));
2618     }
2619
2620   CHECK_INT (arg2);
2621 #ifdef UTF2000
2622   a2 = XINT (arg2);
2623   if (highlim < 128)
2624     a2 &= 0x7f;
2625 #else
2626   a2 = XINT (arg2) & 0x7f;
2627 #endif
2628   if (a2 < lowlim || a2 > highlim)
2629     args_out_of_range_3 (arg2, make_int (lowlim), make_int (highlim));
2630
2631   return make_char (MAKE_CHAR (charset, a1, a2));
2632 }
2633
2634 DEFUN ("char-charset", Fchar_charset, 1, 1, 0, /*
2635 Return the character set of char CH.
2636 */
2637        (ch))
2638 {
2639   CHECK_CHAR_COERCE_INT (ch);
2640
2641   return XCHARSET_NAME (CHAR_CHARSET (XCHAR (ch)));
2642 }
2643
2644 DEFUN ("split-char", Fsplit_char, 1, 1, 0, /*
2645 Return list of charset and one or two position-codes of CHAR.
2646 */
2647        (character))
2648 {
2649   /* This function can GC */
2650   struct gcpro gcpro1, gcpro2;
2651   Lisp_Object charset = Qnil;
2652   Lisp_Object rc = Qnil;
2653   int c1, c2;
2654
2655   GCPRO2 (charset, rc);
2656   CHECK_CHAR_COERCE_INT (character);
2657
2658   BREAKUP_CHAR (XCHAR (character), charset, c1, c2);
2659
2660   if (XCHARSET_DIMENSION (Fget_charset (charset)) == 2)
2661     {
2662       rc = list3 (XCHARSET_NAME (charset), make_int (c1), make_int (c2));
2663     }
2664   else
2665     {
2666       rc = list2 (XCHARSET_NAME (charset), make_int (c1));
2667     }
2668   UNGCPRO;
2669
2670   return rc;
2671 }
2672
2673 \f
2674 #ifdef ENABLE_COMPOSITE_CHARS
2675 /************************************************************************/
2676 /*                     composite character functions                    */
2677 /************************************************************************/
2678
2679 Emchar
2680 lookup_composite_char (Bufbyte *str, int len)
2681 {
2682   Lisp_Object lispstr = make_string (str, len);
2683   Lisp_Object ch = Fgethash (lispstr,
2684                              Vcomposite_char_string2char_hash_table,
2685                              Qunbound);
2686   Emchar emch;
2687
2688   if (UNBOUNDP (ch))
2689     {
2690       if (composite_char_row_next >= 128)
2691         signal_simple_error ("No more composite chars available", lispstr);
2692       emch = MAKE_CHAR (Vcharset_composite, composite_char_row_next,
2693                         composite_char_col_next);
2694       Fputhash (make_char (emch), lispstr,
2695                 Vcomposite_char_char2string_hash_table);
2696       Fputhash (lispstr, make_char (emch),
2697                 Vcomposite_char_string2char_hash_table);
2698       composite_char_col_next++;
2699       if (composite_char_col_next >= 128)
2700         {
2701           composite_char_col_next = 32;
2702           composite_char_row_next++;
2703         }
2704     }
2705   else
2706     emch = XCHAR (ch);
2707   return emch;
2708 }
2709
2710 Lisp_Object
2711 composite_char_string (Emchar ch)
2712 {
2713   Lisp_Object str = Fgethash (make_char (ch),
2714                               Vcomposite_char_char2string_hash_table,
2715                               Qunbound);
2716   assert (!UNBOUNDP (str));
2717   return str;
2718 }
2719
2720 xxDEFUN ("make-composite-char", Fmake_composite_char, 1, 1, 0, /*
2721 Convert a string into a single composite character.
2722 The character is the result of overstriking all the characters in
2723 the string.
2724 */
2725        (string))
2726 {
2727   CHECK_STRING (string);
2728   return make_char (lookup_composite_char (XSTRING_DATA (string),
2729                                            XSTRING_LENGTH (string)));
2730 }
2731
2732 xxDEFUN ("composite-char-string", Fcomposite_char_string, 1, 1, 0, /*
2733 Return a string of the characters comprising a composite character.
2734 */
2735        (ch))
2736 {
2737   Emchar emch;
2738
2739   CHECK_CHAR (ch);
2740   emch = XCHAR (ch);
2741   if (CHAR_LEADING_BYTE (emch) != LEADING_BYTE_COMPOSITE)
2742     signal_simple_error ("Must be composite char", ch);
2743   return composite_char_string (emch);
2744 }
2745 #endif /* ENABLE_COMPOSITE_CHARS */
2746
2747 \f
2748 /************************************************************************/
2749 /*                            initialization                            */
2750 /************************************************************************/
2751
2752 void
2753 syms_of_mule_charset (void)
2754 {
2755   DEFSUBR (Fcharsetp);
2756   DEFSUBR (Ffind_charset);
2757   DEFSUBR (Fget_charset);
2758   DEFSUBR (Fcharset_list);
2759   DEFSUBR (Fcharset_name);
2760   DEFSUBR (Fmake_charset);
2761   DEFSUBR (Fmake_reverse_direction_charset);
2762   /*  DEFSUBR (Freverse_direction_charset); */
2763   DEFSUBR (Fcharset_from_attributes);
2764   DEFSUBR (Fcharset_short_name);
2765   DEFSUBR (Fcharset_long_name);
2766   DEFSUBR (Fcharset_description);
2767   DEFSUBR (Fcharset_dimension);
2768   DEFSUBR (Fcharset_property);
2769   DEFSUBR (Fcharset_id);
2770   DEFSUBR (Fset_charset_ccl_program);
2771   DEFSUBR (Fset_charset_registry);
2772
2773   DEFSUBR (Fmake_char);
2774   DEFSUBR (Fchar_charset);
2775   DEFSUBR (Fsplit_char);
2776
2777 #ifdef ENABLE_COMPOSITE_CHARS
2778   DEFSUBR (Fmake_composite_char);
2779   DEFSUBR (Fcomposite_char_string);
2780 #endif
2781
2782   defsymbol (&Qcharsetp, "charsetp");
2783   defsymbol (&Qregistry, "registry");
2784   defsymbol (&Qfinal, "final");
2785   defsymbol (&Qgraphic, "graphic");
2786   defsymbol (&Qdirection, "direction");
2787   defsymbol (&Qreverse_direction_charset, "reverse-direction-charset");
2788   defsymbol (&Qshort_name, "short-name");
2789   defsymbol (&Qlong_name, "long-name");
2790
2791   defsymbol (&Ql2r, "l2r");
2792   defsymbol (&Qr2l, "r2l");
2793
2794   /* Charsets, compatible with FSF 20.3
2795      Naming convention is Script-Charset[-Edition] */
2796   defsymbol (&Qascii,                   "ascii");
2797   defsymbol (&Qcontrol_1,               "control-1");
2798   defsymbol (&Qlatin_iso8859_1,         "latin-iso8859-1");
2799   defsymbol (&Qlatin_iso8859_2,         "latin-iso8859-2");
2800   defsymbol (&Qlatin_iso8859_3,         "latin-iso8859-3");
2801   defsymbol (&Qlatin_iso8859_4,         "latin-iso8859-4");
2802   defsymbol (&Qthai_tis620,             "thai-tis620");
2803   defsymbol (&Qgreek_iso8859_7,         "greek-iso8859-7");
2804   defsymbol (&Qarabic_iso8859_6,        "arabic-iso8859-6");
2805   defsymbol (&Qhebrew_iso8859_8,        "hebrew-iso8859-8");
2806   defsymbol (&Qkatakana_jisx0201,       "katakana-jisx0201");
2807   defsymbol (&Qlatin_jisx0201,          "latin-jisx0201");
2808   defsymbol (&Qcyrillic_iso8859_5,      "cyrillic-iso8859-5");
2809   defsymbol (&Qlatin_iso8859_9,         "latin-iso8859-9");
2810   defsymbol (&Qjapanese_jisx0208_1978,  "japanese-jisx0208-1978");
2811   defsymbol (&Qchinese_gb2312,          "chinese-gb2312");
2812   defsymbol (&Qjapanese_jisx0208,       "japanese-jisx0208");
2813   defsymbol (&Qkorean_ksc5601,          "korean-ksc5601");
2814   defsymbol (&Qjapanese_jisx0212,       "japanese-jisx0212");
2815   defsymbol (&Qchinese_cns11643_1,      "chinese-cns11643-1");
2816   defsymbol (&Qchinese_cns11643_2,      "chinese-cns11643-2");
2817 #ifdef UTF2000
2818   defsymbol (&Qchinese_cns11643_3,      "chinese-cns11643-3");
2819   defsymbol (&Qchinese_cns11643_4,      "chinese-cns11643-4");
2820   defsymbol (&Qchinese_cns11643_5,      "chinese-cns11643-5");
2821   defsymbol (&Qchinese_cns11643_6,      "chinese-cns11643-6");
2822   defsymbol (&Qchinese_cns11643_7,      "chinese-cns11643-7");
2823   defsymbol (&Qucs_bmp,                 "ucs-bmp");
2824   defsymbol (&Qlatin_viscii_lower,      "vietnamese-viscii-lower");
2825   defsymbol (&Qlatin_viscii_upper,      "vietnamese-viscii-upper");
2826 #endif
2827   defsymbol (&Qchinese_big5_1,          "chinese-big5-1");
2828   defsymbol (&Qchinese_big5_2,          "chinese-big5-2");
2829
2830   defsymbol (&Qcomposite,               "composite");
2831 }
2832
2833 void
2834 vars_of_mule_charset (void)
2835 {
2836   int i, j;
2837 #ifndef UTF2000
2838   int k;
2839 #endif
2840
2841   /* Table of charsets indexed by leading byte. */
2842   for (i = 0; i < countof (charset_by_leading_byte); i++)
2843     charset_by_leading_byte[i] = Qnil;
2844
2845 #ifdef UTF2000
2846   /* Table of charsets indexed by type/final-byte. */
2847   for (i = 0; i < countof (charset_by_attributes); i++)
2848     for (j = 0; j < countof (charset_by_attributes[0]); j++)
2849         charset_by_attributes[i][j] = Qnil;
2850 #else
2851   /* Table of charsets indexed by type/final-byte/direction. */
2852   for (i = 0; i < countof (charset_by_attributes); i++)
2853     for (j = 0; j < countof (charset_by_attributes[0]); j++)
2854       for (k = 0; k < countof (charset_by_attributes[0][0]); k++)
2855         charset_by_attributes[i][j][k] = Qnil;
2856 #endif
2857
2858   next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1;
2859 #ifdef UTF2000
2860   next_allocated_2_byte_leading_byte = LEADING_BYTE_CHINESE_BIG5_2 + 1;
2861 #else
2862   next_allocated_2_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_2;
2863 #endif
2864
2865 #ifndef UTF2000
2866   leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
2867   DEFVAR_INT ("leading-code-private-11", &leading_code_private_11 /*
2868 Leading-code of private TYPE9N charset of column-width 1.
2869 */ );
2870   leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
2871 #endif
2872
2873 #ifdef UTF2000
2874   Vutf_2000_version = build_string("0.7 (Hirano)");
2875   DEFVAR_LISP ("utf-2000-version", &Vutf_2000_version /*
2876 Version number of UTF-2000.
2877 */ );
2878 #endif
2879 }
2880
2881 void
2882 complex_vars_of_mule_charset (void)
2883 {
2884   staticpro (&Vcharset_hash_table);
2885   Vcharset_hash_table =
2886     make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
2887
2888   /* Predefined character sets.  We store them into variables for
2889      ease of access. */
2890
2891 #ifdef UTF2000
2892   Vcharset_ucs_bmp =
2893     make_charset (LEADING_BYTE_UCS_BMP, Qucs_bmp,
2894                   CHARSET_TYPE_256X256, 1, 0, 0,
2895                   CHARSET_LEFT_TO_RIGHT,
2896                   build_string ("BMP"),
2897                   build_string ("BMP"),
2898                   build_string ("BMP"),
2899                   build_string (""),
2900                   NULL);
2901 #endif
2902   Vcharset_ascii =
2903     make_charset (LEADING_BYTE_ASCII, Qascii,
2904                   CHARSET_TYPE_94, 1, 0, 'B',
2905                   CHARSET_LEFT_TO_RIGHT,
2906                   build_string ("ASCII"),
2907                   build_string ("ASCII)"),
2908                   build_string ("ASCII (ISO646 IRV)"),
2909                   build_string ("\\(iso8859-[0-9]*\\|-ascii\\)"),
2910                   NULL);
2911   Vcharset_control_1 =
2912     make_charset (LEADING_BYTE_CONTROL_1, Qcontrol_1,
2913                   CHARSET_TYPE_94, 1, 1, 0,
2914                   CHARSET_LEFT_TO_RIGHT,
2915                   build_string ("C1"),
2916                   build_string ("Control characters"),
2917                   build_string ("Control characters 128-191"),
2918                   build_string (""),
2919                   NULL);
2920   Vcharset_latin_iso8859_1 =
2921     make_charset (LEADING_BYTE_LATIN_ISO8859_1, Qlatin_iso8859_1,
2922                   CHARSET_TYPE_96, 1, 1, 'A',
2923                   CHARSET_LEFT_TO_RIGHT,
2924                   build_string ("Latin-1"),
2925                   build_string ("ISO8859-1 (Latin-1)"),
2926                   build_string ("ISO8859-1 (Latin-1)"),
2927                   build_string ("iso8859-1"),
2928                   NULL);
2929   Vcharset_latin_iso8859_2 =
2930     make_charset (LEADING_BYTE_LATIN_ISO8859_2, Qlatin_iso8859_2,
2931                   CHARSET_TYPE_96, 1, 1, 'B',
2932                   CHARSET_LEFT_TO_RIGHT,
2933                   build_string ("Latin-2"),
2934                   build_string ("ISO8859-2 (Latin-2)"),
2935                   build_string ("ISO8859-2 (Latin-2)"),
2936                   build_string ("iso8859-2"),
2937                   latin_iso8859_2_to_ucs);
2938   Vcharset_latin_iso8859_3 =
2939     make_charset (LEADING_BYTE_LATIN_ISO8859_3, Qlatin_iso8859_3,
2940                   CHARSET_TYPE_96, 1, 1, 'C',
2941                   CHARSET_LEFT_TO_RIGHT,
2942                   build_string ("Latin-3"),
2943                   build_string ("ISO8859-3 (Latin-3)"),
2944                   build_string ("ISO8859-3 (Latin-3)"),
2945                   build_string ("iso8859-3"),
2946                   latin_iso8859_3_to_ucs);
2947   Vcharset_latin_iso8859_4 =
2948     make_charset (LEADING_BYTE_LATIN_ISO8859_4, Qlatin_iso8859_4,
2949                   CHARSET_TYPE_96, 1, 1, 'D',
2950                   CHARSET_LEFT_TO_RIGHT,
2951                   build_string ("Latin-4"),
2952                   build_string ("ISO8859-4 (Latin-4)"),
2953                   build_string ("ISO8859-4 (Latin-4)"),
2954                   build_string ("iso8859-4"),
2955                   latin_iso8859_4_to_ucs);
2956   Vcharset_thai_tis620 =
2957     make_charset (LEADING_BYTE_THAI_TIS620, Qthai_tis620,
2958                   CHARSET_TYPE_96, 1, 1, 'T',
2959                   CHARSET_LEFT_TO_RIGHT,
2960                   build_string ("TIS620"),
2961                   build_string ("TIS620 (Thai)"),
2962                   build_string ("TIS620.2529 (Thai)"),
2963                   build_string ("tis620"),
2964                   NULL);
2965   Vcharset_greek_iso8859_7 =
2966     make_charset (LEADING_BYTE_GREEK_ISO8859_7, Qgreek_iso8859_7,
2967                   CHARSET_TYPE_96, 1, 1, 'F',
2968                   CHARSET_LEFT_TO_RIGHT,
2969                   build_string ("ISO8859-7"),
2970                   build_string ("ISO8859-7 (Greek)"),
2971                   build_string ("ISO8859-7 (Greek)"),
2972                   build_string ("iso8859-7"),
2973                   NULL);
2974   Vcharset_arabic_iso8859_6 =
2975     make_charset (LEADING_BYTE_ARABIC_ISO8859_6, Qarabic_iso8859_6,
2976                   CHARSET_TYPE_96, 1, 1, 'G',
2977                   CHARSET_RIGHT_TO_LEFT,
2978                   build_string ("ISO8859-6"),
2979                   build_string ("ISO8859-6 (Arabic)"),
2980                   build_string ("ISO8859-6 (Arabic)"),
2981                   build_string ("iso8859-6"),
2982                   NULL);
2983   Vcharset_hebrew_iso8859_8 =
2984     make_charset (LEADING_BYTE_HEBREW_ISO8859_8, Qhebrew_iso8859_8,
2985                   CHARSET_TYPE_96, 1, 1, 'H',
2986                   CHARSET_RIGHT_TO_LEFT,
2987                   build_string ("ISO8859-8"),
2988                   build_string ("ISO8859-8 (Hebrew)"),
2989                   build_string ("ISO8859-8 (Hebrew)"),
2990                   build_string ("iso8859-8"),
2991                   NULL);
2992   Vcharset_katakana_jisx0201 =
2993     make_charset (LEADING_BYTE_KATAKANA_JISX0201, Qkatakana_jisx0201,
2994                   CHARSET_TYPE_94, 1, 1, 'I',
2995                   CHARSET_LEFT_TO_RIGHT,
2996                   build_string ("JISX0201 Kana"),
2997                   build_string ("JISX0201.1976 (Japanese Kana)"),
2998                   build_string ("JISX0201.1976 Japanese Kana"),
2999                   build_string ("jisx0201.1976"),
3000                   NULL);
3001   Vcharset_latin_jisx0201 =
3002     make_charset (LEADING_BYTE_LATIN_JISX0201, Qlatin_jisx0201,
3003                   CHARSET_TYPE_94, 1, 0, 'J',
3004                   CHARSET_LEFT_TO_RIGHT,
3005                   build_string ("JISX0201 Roman"),
3006                   build_string ("JISX0201.1976 (Japanese Roman)"),
3007                   build_string ("JISX0201.1976 Japanese Roman"),
3008                   build_string ("jisx0201.1976"),
3009                   latin_jisx0201_to_ucs);
3010   Vcharset_cyrillic_iso8859_5 =
3011     make_charset (LEADING_BYTE_CYRILLIC_ISO8859_5, Qcyrillic_iso8859_5,
3012                   CHARSET_TYPE_96, 1, 1, 'L',
3013                   CHARSET_LEFT_TO_RIGHT,
3014                   build_string ("ISO8859-5"),
3015                   build_string ("ISO8859-5 (Cyrillic)"),
3016                   build_string ("ISO8859-5 (Cyrillic)"),
3017                   build_string ("iso8859-5"),
3018                   NULL);
3019   Vcharset_latin_iso8859_9 =
3020     make_charset (LEADING_BYTE_LATIN_ISO8859_9, Qlatin_iso8859_9,
3021                   CHARSET_TYPE_96, 1, 1, 'M',
3022                   CHARSET_LEFT_TO_RIGHT,
3023                   build_string ("Latin-5"),
3024                   build_string ("ISO8859-9 (Latin-5)"),
3025                   build_string ("ISO8859-9 (Latin-5)"),
3026                   build_string ("iso8859-9"),
3027                   latin_iso8859_9_to_ucs);
3028   Vcharset_japanese_jisx0208_1978 =
3029     make_charset (LEADING_BYTE_JAPANESE_JISX0208_1978, Qjapanese_jisx0208_1978,
3030                   CHARSET_TYPE_94X94, 2, 0, '@',
3031                   CHARSET_LEFT_TO_RIGHT,
3032                   build_string ("JISX0208.1978"),
3033                   build_string ("JISX0208.1978 (Japanese)"),
3034                   build_string
3035                   ("JISX0208.1978 Japanese Kanji (so called \"old JIS\")"),
3036                   build_string ("\\(jisx0208\\|jisc6226\\)\\.1978"),
3037                   NULL);
3038   Vcharset_chinese_gb2312 =
3039     make_charset (LEADING_BYTE_CHINESE_GB2312, Qchinese_gb2312,
3040                   CHARSET_TYPE_94X94, 2, 0, 'A',
3041                   CHARSET_LEFT_TO_RIGHT,
3042                   build_string ("GB2312"),
3043                   build_string ("GB2312)"),
3044                   build_string ("GB2312 Chinese simplified"),
3045                   build_string ("gb2312"),
3046                   NULL);
3047   Vcharset_japanese_jisx0208 =
3048     make_charset (LEADING_BYTE_JAPANESE_JISX0208, Qjapanese_jisx0208,
3049                   CHARSET_TYPE_94X94, 2, 0, 'B',
3050                   CHARSET_LEFT_TO_RIGHT,
3051                   build_string ("JISX0208"),
3052                   build_string ("JISX0208.1983/1990 (Japanese)"),
3053                   build_string ("JISX0208.1983/1990 Japanese Kanji"),
3054                   build_string ("jisx0208.19\\(83\\|90\\)"),
3055                   NULL);
3056   Vcharset_korean_ksc5601 =
3057     make_charset (LEADING_BYTE_KOREAN_KSC5601, Qkorean_ksc5601,
3058                   CHARSET_TYPE_94X94, 2, 0, 'C',
3059                   CHARSET_LEFT_TO_RIGHT,
3060                   build_string ("KSC5601"),
3061                   build_string ("KSC5601 (Korean"),
3062                   build_string ("KSC5601 Korean Hangul and Hanja"),
3063                   build_string ("ksc5601"),
3064                   NULL);
3065   Vcharset_japanese_jisx0212 =
3066     make_charset (LEADING_BYTE_JAPANESE_JISX0212, Qjapanese_jisx0212,
3067                   CHARSET_TYPE_94X94, 2, 0, 'D',
3068                   CHARSET_LEFT_TO_RIGHT,
3069                   build_string ("JISX0212"),
3070                   build_string ("JISX0212 (Japanese)"),
3071                   build_string ("JISX0212 Japanese Supplement"),
3072                   build_string ("jisx0212"),
3073                   NULL);
3074
3075 #define CHINESE_CNS_PLANE_RE(n) "cns11643[.-]\\(.*[.-]\\)?" n "$"
3076   Vcharset_chinese_cns11643_1 =
3077     make_charset (LEADING_BYTE_CHINESE_CNS11643_1, Qchinese_cns11643_1,
3078                   CHARSET_TYPE_94X94, 2, 0, 'G',
3079                   CHARSET_LEFT_TO_RIGHT,
3080                   build_string ("CNS11643-1"),
3081                   build_string ("CNS11643-1 (Chinese traditional)"),
3082                   build_string
3083                   ("CNS 11643 Plane 1 Chinese traditional"),
3084                   build_string (CHINESE_CNS_PLANE_RE("1")),
3085                   NULL);
3086   Vcharset_chinese_cns11643_2 =
3087     make_charset (LEADING_BYTE_CHINESE_CNS11643_2, Qchinese_cns11643_2,
3088                   CHARSET_TYPE_94X94, 2, 0, 'H',
3089                   CHARSET_LEFT_TO_RIGHT,
3090                   build_string ("CNS11643-2"),
3091                   build_string ("CNS11643-2 (Chinese traditional)"),
3092                   build_string
3093                   ("CNS 11643 Plane 2 Chinese traditional"),
3094                   build_string (CHINESE_CNS_PLANE_RE("2")),
3095                   NULL);
3096 #ifdef UTF2000
3097   Vcharset_chinese_cns11643_3 =
3098     make_charset (LEADING_BYTE_CHINESE_CNS11643_3, Qchinese_cns11643_3,
3099                   CHARSET_TYPE_94X94, 2, 0, 'I',
3100                   CHARSET_LEFT_TO_RIGHT,
3101                   build_string ("CNS11643-3"),
3102                   build_string ("CNS11643-3 (Chinese traditional)"),
3103                   build_string
3104                   ("CNS 11643 Plane 3 Chinese traditional"),
3105                   build_string (CHINESE_CNS_PLANE_RE("3")),
3106                   NULL);
3107   Vcharset_chinese_cns11643_4 =
3108     make_charset (LEADING_BYTE_CHINESE_CNS11643_4, Qchinese_cns11643_4,
3109                   CHARSET_TYPE_94X94, 2, 0, 'J',
3110                   CHARSET_LEFT_TO_RIGHT,
3111                   build_string ("CNS11643-4"),
3112                   build_string ("CNS11643-4 (Chinese traditional)"),
3113                   build_string
3114                   ("CNS 11643 Plane 4 Chinese traditional"),
3115                   build_string (CHINESE_CNS_PLANE_RE("4")),
3116                   NULL);
3117   Vcharset_chinese_cns11643_5 =
3118     make_charset (LEADING_BYTE_CHINESE_CNS11643_5, Qchinese_cns11643_5,
3119                   CHARSET_TYPE_94X94, 2, 0, 'K',
3120                   CHARSET_LEFT_TO_RIGHT,
3121                   build_string ("CNS11643-5"),
3122                   build_string ("CNS11643-5 (Chinese traditional)"),
3123                   build_string
3124                   ("CNS 11643 Plane 5 Chinese traditional"),
3125                   build_string (CHINESE_CNS_PLANE_RE("5")),
3126                   NULL);
3127   Vcharset_chinese_cns11643_6 =
3128     make_charset (LEADING_BYTE_CHINESE_CNS11643_6, Qchinese_cns11643_6,
3129                   CHARSET_TYPE_94X94, 2, 0, 'L',
3130                   CHARSET_LEFT_TO_RIGHT,
3131                   build_string ("CNS11643-6"),
3132                   build_string ("CNS11643-6 (Chinese traditional)"),
3133                   build_string
3134                   ("CNS 11643 Plane 6 Chinese traditional"),
3135                   build_string (CHINESE_CNS_PLANE_RE("6")),
3136                   NULL);
3137   Vcharset_chinese_cns11643_7 =
3138     make_charset (LEADING_BYTE_CHINESE_CNS11643_7, Qchinese_cns11643_7,
3139                   CHARSET_TYPE_94X94, 2, 0, 'M',
3140                   CHARSET_LEFT_TO_RIGHT,
3141                   build_string ("CNS11643-7"),
3142                   build_string ("CNS11643-7 (Chinese traditional)"),
3143                   build_string
3144                   ("CNS 11643 Plane 7 Chinese traditional"),
3145                   build_string (CHINESE_CNS_PLANE_RE("7")),
3146                   NULL);
3147   Vcharset_latin_viscii_lower =
3148     make_charset (LEADING_BYTE_LATIN_VISCII_LOWER, Qlatin_viscii_lower,
3149                   CHARSET_TYPE_96, 1, 1, '1',
3150                   CHARSET_LEFT_TO_RIGHT,
3151                   build_string ("VISCII lower"),
3152                   build_string ("VISCII lower (Vietnamese)"),
3153                   build_string ("VISCII lower (Vietnamese)"),
3154                   build_string ("VISCII1.1"),
3155                   latin_viscii_lower_to_ucs);
3156   Vcharset_latin_viscii_upper =
3157     make_charset (LEADING_BYTE_LATIN_VISCII_UPPER, Qlatin_viscii_upper,
3158                   CHARSET_TYPE_96, 1, 1, '2',
3159                   CHARSET_LEFT_TO_RIGHT,
3160                   build_string ("VISCII upper"),
3161                   build_string ("VISCII upper (Vietnamese)"),
3162                   build_string ("VISCII upper (Vietnamese)"),
3163                   build_string ("VISCII1.1"),
3164                   latin_viscii_upper_to_ucs);
3165 #endif
3166   Vcharset_chinese_big5_1 =
3167     make_charset (LEADING_BYTE_CHINESE_BIG5_1, Qchinese_big5_1,
3168                   CHARSET_TYPE_94X94, 2, 0, '0',
3169                   CHARSET_LEFT_TO_RIGHT,
3170                   build_string ("Big5"),
3171                   build_string ("Big5 (Level-1)"),
3172                   build_string
3173                   ("Big5 Level-1 Chinese traditional"),
3174                   build_string ("big5"),
3175                   NULL);
3176   Vcharset_chinese_big5_2 =
3177     make_charset (LEADING_BYTE_CHINESE_BIG5_2, Qchinese_big5_2,
3178                   CHARSET_TYPE_94X94, 2, 0, '1',
3179                   CHARSET_LEFT_TO_RIGHT,
3180                   build_string ("Big5"),
3181                   build_string ("Big5 (Level-2)"),
3182                   build_string
3183                   ("Big5 Level-2 Chinese traditional"),
3184                   build_string ("big5"),
3185                   NULL);
3186
3187 #ifdef ENABLE_COMPOSITE_CHARS
3188   /* #### For simplicity, we put composite chars into a 96x96 charset.
3189      This is going to lead to problems because you can run out of
3190      room, esp. as we don't yet recycle numbers. */
3191   Vcharset_composite =
3192     make_charset (LEADING_BYTE_COMPOSITE, Qcomposite,
3193                   CHARSET_TYPE_96X96, 2, 0, 0,
3194                   CHARSET_LEFT_TO_RIGHT,
3195                   build_string ("Composite"),
3196                   build_string ("Composite characters"),
3197                   build_string ("Composite characters"),
3198                   build_string (""));
3199
3200   composite_char_row_next = 32;
3201   composite_char_col_next = 32;
3202
3203   Vcomposite_char_string2char_hash_table =
3204     make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
3205   Vcomposite_char_char2string_hash_table =
3206     make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3207   staticpro (&Vcomposite_char_string2char_hash_table);
3208   staticpro (&Vcomposite_char_char2string_hash_table);
3209 #endif /* ENABLE_COMPOSITE_CHARS */
3210
3211 }