1 /* Functions to handle multilingual characters.
2 Copyright (C) 1992, 1995 Free Software Foundation, Inc.
3 Copyright (C) 1995 Sun Microsystems, Inc.
4 Copyright (C) 1999,2000 MORIOKA Tomohiko
6 This file is part of XEmacs.
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Synched up with: FSF 20.3. Not in FSF. */
25 /* Rewritten by Ben Wing <ben@xemacs.org>. */
38 /* The various pre-defined charsets. */
40 Lisp_Object Vcharset_ascii;
41 Lisp_Object Vcharset_control_1;
42 Lisp_Object Vcharset_latin_iso8859_1;
43 Lisp_Object Vcharset_latin_iso8859_2;
44 Lisp_Object Vcharset_latin_iso8859_3;
45 Lisp_Object Vcharset_latin_iso8859_4;
46 Lisp_Object Vcharset_thai_tis620;
47 Lisp_Object Vcharset_greek_iso8859_7;
48 Lisp_Object Vcharset_arabic_iso8859_6;
49 Lisp_Object Vcharset_hebrew_iso8859_8;
50 Lisp_Object Vcharset_katakana_jisx0201;
51 Lisp_Object Vcharset_latin_jisx0201;
52 Lisp_Object Vcharset_cyrillic_iso8859_5;
53 Lisp_Object Vcharset_latin_iso8859_9;
54 Lisp_Object Vcharset_japanese_jisx0208_1978;
55 Lisp_Object Vcharset_chinese_gb2312;
56 Lisp_Object Vcharset_japanese_jisx0208;
57 Lisp_Object Vcharset_japanese_jisx0208_1990;
58 Lisp_Object Vcharset_korean_ksc5601;
59 Lisp_Object Vcharset_japanese_jisx0212;
60 Lisp_Object Vcharset_chinese_cns11643_1;
61 Lisp_Object Vcharset_chinese_cns11643_2;
63 Lisp_Object Vcharset_ucs;
64 Lisp_Object Vcharset_ucs_bmp;
65 Lisp_Object Vcharset_latin_viscii;
66 Lisp_Object Vcharset_latin_tcvn5712;
67 Lisp_Object Vcharset_latin_viscii_lower;
68 Lisp_Object Vcharset_latin_viscii_upper;
69 Lisp_Object Vcharset_ideograph_daikanwa;
70 Lisp_Object Vcharset_mojikyo;
71 Lisp_Object Vcharset_mojikyo_pj_1;
72 Lisp_Object Vcharset_mojikyo_pj_2;
73 Lisp_Object Vcharset_mojikyo_pj_3;
74 Lisp_Object Vcharset_mojikyo_pj_4;
75 Lisp_Object Vcharset_mojikyo_pj_5;
76 Lisp_Object Vcharset_mojikyo_pj_6;
77 Lisp_Object Vcharset_mojikyo_pj_7;
78 Lisp_Object Vcharset_mojikyo_pj_8;
79 Lisp_Object Vcharset_mojikyo_pj_9;
80 Lisp_Object Vcharset_mojikyo_pj_10;
81 Lisp_Object Vcharset_mojikyo_pj_11;
82 Lisp_Object Vcharset_mojikyo_pj_12;
83 Lisp_Object Vcharset_mojikyo_pj_13;
84 Lisp_Object Vcharset_mojikyo_pj_14;
85 Lisp_Object Vcharset_mojikyo_pj_15;
86 Lisp_Object Vcharset_mojikyo_pj_16;
87 Lisp_Object Vcharset_mojikyo_pj_17;
88 Lisp_Object Vcharset_mojikyo_pj_18;
89 Lisp_Object Vcharset_mojikyo_pj_19;
90 Lisp_Object Vcharset_mojikyo_pj_20;
91 Lisp_Object Vcharset_mojikyo_pj_21;
92 Lisp_Object Vcharset_ethiopic_ucs;
94 Lisp_Object Vcharset_chinese_big5_1;
95 Lisp_Object Vcharset_chinese_big5_2;
97 #ifdef ENABLE_COMPOSITE_CHARS
98 Lisp_Object Vcharset_composite;
100 /* Hash tables for composite chars. One maps string representing
101 composed chars to their equivalent chars; one goes the
103 Lisp_Object Vcomposite_char_char2string_hash_table;
104 Lisp_Object Vcomposite_char_string2char_hash_table;
106 static int composite_char_row_next;
107 static int composite_char_col_next;
109 #endif /* ENABLE_COMPOSITE_CHARS */
111 struct charset_lookup *chlook;
113 static const struct lrecord_description charset_lookup_description_1[] = {
114 { XD_LISP_OBJECT_ARRAY, offsetof (struct charset_lookup, charset_by_leading_byte),
123 static const struct struct_description charset_lookup_description = {
124 sizeof (struct charset_lookup),
125 charset_lookup_description_1
129 /* Table of number of bytes in the string representation of a character
130 indexed by the first byte of that representation.
132 rep_bytes_by_first_byte(c) is more efficient than the equivalent
133 canonical computation:
135 XCHARSET_REP_BYTES (CHARSET_BY_LEADING_BYTE (c)) */
137 const Bytecount rep_bytes_by_first_byte[0xA0] =
138 { /* 0x00 - 0x7f are for straight ASCII */
139 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
140 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
141 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
142 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
143 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
144 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
145 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
146 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
147 /* 0x80 - 0x8f are for Dimension-1 official charsets */
149 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
151 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
153 /* 0x90 - 0x9d are for Dimension-2 official charsets */
154 /* 0x9e is for Dimension-1 private charsets */
155 /* 0x9f is for Dimension-2 private charsets */
156 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4
163 mark_byte_table (Lisp_Object obj)
165 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
168 for (i = 0; i < 256; i++)
170 mark_object (cte->property[i]);
176 byte_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
178 Lisp_Byte_Table *cte1 = XBYTE_TABLE (obj1);
179 Lisp_Byte_Table *cte2 = XBYTE_TABLE (obj2);
182 for (i = 0; i < 256; i++)
183 if (BYTE_TABLE_P (cte1->property[i]))
185 if (BYTE_TABLE_P (cte2->property[i]))
187 if (!byte_table_equal (cte1->property[i],
188 cte2->property[i], depth + 1))
195 if (!internal_equal (cte1->property[i], cte2->property[i], depth + 1))
201 byte_table_hash (Lisp_Object obj, int depth)
203 Lisp_Byte_Table *cte = XBYTE_TABLE (obj);
205 return internal_array_hash (cte->property, 256, depth);
208 static const struct lrecord_description byte_table_description[] = {
209 { XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Byte_Table, property), 256 },
213 DEFINE_LRECORD_IMPLEMENTATION ("byte-table", byte_table,
215 internal_object_printer,
218 byte_table_description,
222 make_byte_table (Lisp_Object initval, int older)
226 Lisp_Byte_Table *cte;
229 cte = alloc_older_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
231 cte = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
233 for (i = 0; i < 256; i++)
234 cte->property[i] = initval;
236 XSETBYTE_TABLE (obj, cte);
241 copy_byte_table (Lisp_Object entry)
243 Lisp_Byte_Table *cte = XBYTE_TABLE (entry);
246 Lisp_Byte_Table *ctenew
247 = alloc_lcrecord_type (Lisp_Byte_Table, &lrecord_byte_table);
249 for (i = 0; i < 256; i++)
251 Lisp_Object new = cte->property[i];
252 if (BYTE_TABLE_P (new))
253 ctenew->property[i] = copy_byte_table (new);
255 ctenew->property[i] = new;
258 XSETBYTE_TABLE (obj, ctenew);
264 mark_char_id_table (Lisp_Object obj)
266 Lisp_Char_ID_Table *cte = XCHAR_ID_TABLE (obj);
272 char_id_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
274 Lisp_Char_ID_Table *cte1 = XCHAR_ID_TABLE (obj1);
275 Lisp_Char_ID_Table *cte2 = XCHAR_ID_TABLE (obj2);
277 return byte_table_equal (cte1->table, cte2->table, depth + 1);
281 char_id_table_hash (Lisp_Object obj, int depth)
283 Lisp_Char_ID_Table *cte = XCHAR_ID_TABLE (obj);
285 return char_id_table_hash (cte->table, depth + 1);
288 static const struct lrecord_description char_id_table_description[] = {
289 { XD_LISP_OBJECT, offsetof(Lisp_Char_ID_Table, table) },
293 DEFINE_LRECORD_IMPLEMENTATION ("char-id-table", char_id_table,
295 internal_object_printer,
296 0, char_id_table_equal,
298 char_id_table_description,
302 make_char_id_table (Lisp_Object initval, int older)
305 Lisp_Char_ID_Table *cte;
308 cte = alloc_older_lcrecord_type (Lisp_Char_ID_Table,
309 &lrecord_char_id_table);
311 cte = alloc_lcrecord_type (Lisp_Char_ID_Table, &lrecord_char_id_table);
313 cte->table = make_byte_table (initval, older);
315 XSETCHAR_ID_TABLE (obj, cte);
322 copy_char_id_table (Lisp_Object entry)
324 Lisp_Char_ID_Table *cte = XCHAR_ID_TABLE (entry);
326 Lisp_Char_ID_Table *ctenew
327 = alloc_lcrecord_type (Lisp_Char_ID_Table, &lrecord_char_id_table);
329 ctenew->table = copy_byte_table (cte->table);
330 XSETCHAR_ID_TABLE (obj, ctenew);
337 get_char_id_table (Emchar ch, Lisp_Object table)
339 unsigned int code = ch;
341 = XBYTE_TABLE (XCHAR_ID_TABLE (table)->table);
342 Lisp_Object ret = cpt->property [(unsigned char)(code >> 24)];
344 if (BYTE_TABLE_P (ret))
345 cpt = XBYTE_TABLE (ret);
349 ret = cpt->property [(unsigned char) (code >> 16)];
350 if (BYTE_TABLE_P (ret))
351 cpt = XBYTE_TABLE (ret);
355 ret = cpt->property [(unsigned char) (code >> 8)];
356 if (BYTE_TABLE_P (ret))
357 cpt = XBYTE_TABLE (ret);
361 return cpt->property [(unsigned char) code];
364 void put_char_id_table (Emchar ch, Lisp_Object value, Lisp_Object table);
366 put_char_id_table (Emchar ch, Lisp_Object value, Lisp_Object table)
368 unsigned int code = ch;
369 Lisp_Byte_Table* cpt1 = XBYTE_TABLE (XCHAR_ID_TABLE (table)->table);
370 Lisp_Object ret = cpt1->property[(unsigned char)(code >> 24)];
372 if (BYTE_TABLE_P (ret))
374 Lisp_Byte_Table* cpt2 = XBYTE_TABLE (ret);
376 ret = cpt2->property[(unsigned char)(code >> 16)];
377 if (BYTE_TABLE_P (ret))
379 Lisp_Byte_Table* cpt3 = XBYTE_TABLE (ret);
381 ret = cpt3->property[(unsigned char)(code >> 8)];
382 if (BYTE_TABLE_P (ret))
384 Lisp_Byte_Table* cpt4 = XBYTE_TABLE (ret);
386 cpt4->property[(unsigned char)code] = value;
388 else if (!EQ (ret, value))
391 = make_byte_table (ret, OLDER_RECORD_P (table));
393 XBYTE_TABLE(cpt4)->property[(unsigned char)code] = value;
394 cpt3->property[(unsigned char)(code >> 8)] = cpt4;
397 else if (!EQ (ret, value))
399 int older = OLDER_RECORD_P (table);
400 Lisp_Object cpt3 = make_byte_table (ret, older);
401 Lisp_Object cpt4 = make_byte_table (ret, older);
403 XBYTE_TABLE(cpt4)->property[(unsigned char)code] = value;
404 XBYTE_TABLE(cpt3)->property[(unsigned char)(code >> 8)]
406 cpt2->property[(unsigned char)(code >> 16)] = cpt3;
409 else if (!EQ (ret, value))
411 int older = OLDER_RECORD_P (table);
412 Lisp_Object cpt2 = make_byte_table (ret, older);
413 Lisp_Object cpt3 = make_byte_table (ret, older);
414 Lisp_Object cpt4 = make_byte_table (ret, older);
416 XBYTE_TABLE(cpt4)->property[(unsigned char)code] = value;
417 XBYTE_TABLE(cpt3)->property[(unsigned char)(code >> 8)] = cpt4;
418 XBYTE_TABLE(cpt2)->property[(unsigned char)(code >> 16)] = cpt3;
419 cpt1->property[(unsigned char)(code >> 24)] = cpt2;
424 Lisp_Object Vcharacter_attribute_table;
425 Lisp_Object Vcharacter_name_table;
426 Lisp_Object Vcharacter_decomposition_table;
427 Lisp_Object Vcharacter_composition_table;
428 Lisp_Object Vcharacter_variant_table;
431 Lisp_Object Q_decomposition;
435 Lisp_Object Qisolated;
436 Lisp_Object Qinitial;
439 Lisp_Object Qvertical;
440 Lisp_Object QnoBreak;
441 Lisp_Object Qfraction;
451 Emchar to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg);
453 Lisp_Object put_char_ccs_code_point (Lisp_Object character,
454 Lisp_Object ccs, Lisp_Object value);
455 Lisp_Object remove_char_ccs (Lisp_Object character, Lisp_Object ccs);
457 Lisp_Object put_char_attribute (Lisp_Object character,
458 Lisp_Object attribute, Lisp_Object value);
459 Lisp_Object remove_char_attribute (Lisp_Object character,
460 Lisp_Object attribute);
464 to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg)
470 else if (EQ (v, Qcompat))
472 else if (EQ (v, Qisolated))
474 else if (EQ (v, Qinitial))
476 else if (EQ (v, Qmedial))
478 else if (EQ (v, Qfinal))
480 else if (EQ (v, Qvertical))
482 else if (EQ (v, QnoBreak))
484 else if (EQ (v, Qfraction))
486 else if (EQ (v, Qsuper))
488 else if (EQ (v, Qsub))
490 else if (EQ (v, Qcircle))
492 else if (EQ (v, Qsquare))
494 else if (EQ (v, Qwide))
496 else if (EQ (v, Qnarrow))
498 else if (EQ (v, Qsmall))
500 else if (EQ (v, Qfont))
503 signal_simple_error (err_msg, err_arg);
506 DEFUN ("get-composite-char", Fget_composite_char, 1, 1, 0, /*
507 Return character corresponding with list.
511 Lisp_Object table = Vcharacter_composition_table;
512 Lisp_Object rest = list;
516 Lisp_Object v = Fcar (rest);
518 Emchar c = to_char_id (v, "Invalid value for composition", list);
520 ret = get_char_id_table (c, table);
525 if (!CHAR_ID_TABLE_P (ret))
530 else if (!CONSP (rest))
532 else if (CHAR_ID_TABLE_P (ret))
535 signal_simple_error ("Invalid table is found with", list);
537 signal_simple_error ("Invalid value for composition", list);
540 DEFUN ("char-variants", Fchar_variants, 1, 1, 0, /*
541 Return variants of CHARACTER.
545 CHECK_CHAR (character);
546 return Fcopy_list (get_char_id_table (XCHAR (character),
547 Vcharacter_variant_table));
550 DEFUN ("char-attribute-alist", Fchar_attribute_alist, 1, 1, 0, /*
551 Return the alist of attributes of CHARACTER.
555 Lisp_Object alist, ret;
557 CHECK_CHAR (character);
558 alist = Fcopy_alist (get_char_id_table (XCHAR (character),
559 Vcharacter_attribute_table));
561 ret = get_char_id_table (XCHAR (character), Vcharacter_name_table);
563 alist = Fcons (Fcons (Qname, ret), alist);
565 ret = get_char_id_table (XCHAR (character),
566 Vcharacter_decomposition_table);
568 alist = Fcons (Fcons (Q_decomposition, ret), alist);
573 DEFUN ("get-char-attribute", Fget_char_attribute, 2, 2, 0, /*
574 Return the value of CHARACTER's ATTRIBUTE.
576 (character, attribute))
580 CHECK_CHAR (character);
581 if (!NILP (ccs = Ffind_charset (attribute)))
583 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
585 if (CHAR_ID_TABLE_P (encoding_table))
586 return get_char_id_table (XCHAR (character), encoding_table);
590 else if (EQ (attribute, Qname))
592 return get_char_id_table (XCHAR (character), Vcharacter_name_table);
594 else if (EQ (attribute, Q_decomposition))
596 return get_char_id_table (XCHAR (character),
597 Vcharacter_decomposition_table);
602 = get_char_id_table (XCHAR (character), Vcharacter_attribute_table);
607 return Fcdr (Fassq (attribute, ret));
611 DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /*
612 Store CHARACTER's ATTRIBUTE with VALUE.
614 (character, attribute, value))
618 CHECK_CHAR (character);
619 ccs = Ffind_charset (attribute);
622 return put_char_ccs_code_point (character, ccs, value);
624 else if (EQ (attribute, Qname))
626 CHECK_STRING (value);
627 put_char_id_table (XCHAR (character), value, Vcharacter_name_table);
630 else if (EQ (attribute, Q_decomposition))
635 signal_simple_error ("Invalid value for ->decomposition",
638 if (CONSP (Fcdr (value)))
640 Lisp_Object rest = value;
641 Lisp_Object table = Vcharacter_composition_table;
645 GET_EXTERNAL_LIST_LENGTH (rest, len);
646 seq = make_older_vector (len, Qnil);
650 Lisp_Object v = Fcar (rest);
653 = to_char_id (v, "Invalid value for ->decomposition", value);
656 XVECTOR_DATA(seq)[i++] = v;
658 XVECTOR_DATA(seq)[i++] = make_char (c);
662 put_char_id_table (c, character, table);
667 ntable = get_char_id_table (c, table);
668 if (!CHAR_ID_TABLE_P (ntable))
671 = make_char_id_table (Qnil, OLDER_RECORD_P (table));
672 put_char_id_table (c, ntable, table);
680 Lisp_Object v = Fcar (value);
686 = get_char_id_table (c, Vcharacter_variant_table);
688 if (NILP (Fmemq (v, ret)))
690 put_char_id_table (c, Fcons (character, ret),
691 Vcharacter_variant_table);
694 seq = make_older_vector (1, v);
696 put_char_id_table (XCHAR (character), seq,
697 Vcharacter_decomposition_table);
700 else if (EQ (attribute, Q_ucs))
706 signal_simple_error ("Invalid value for ->ucs", value);
710 ret = get_char_id_table (c, Vcharacter_variant_table);
711 if (NILP (Fmemq (character, ret)))
713 put_char_id_table (c, Fcons (character, ret),
714 Vcharacter_variant_table);
717 return put_char_attribute (character, attribute, value);
720 DEFUN ("remove-char-attribute", Fremove_char_attribute, 2, 2, 0, /*
721 Remove CHARACTER's ATTRIBUTE.
723 (character, attribute))
727 CHECK_CHAR (character);
728 ccs = Ffind_charset (attribute);
731 return remove_char_ccs (character, ccs);
733 return remove_char_attribute (character, attribute);
736 INLINE_HEADER int CHARSET_BYTE_SIZE (Lisp_Charset* cs);
738 CHARSET_BYTE_SIZE (Lisp_Charset* cs)
740 /* ad-hoc method for `ascii' */
741 if ((CHARSET_CHARS (cs) == 94) &&
742 (CHARSET_BYTE_OFFSET (cs) != 33))
743 return 128 - CHARSET_BYTE_OFFSET (cs);
745 return CHARSET_CHARS (cs);
748 #define XCHARSET_BYTE_SIZE(ccs) CHARSET_BYTE_SIZE (XCHARSET (ccs))
750 int decoding_table_check_elements (Lisp_Object v, int dim, int ccs_len);
752 decoding_table_check_elements (Lisp_Object v, int dim, int ccs_len)
756 if (XVECTOR_LENGTH (v) > ccs_len)
759 for (i = 0; i < XVECTOR_LENGTH (v); i++)
761 Lisp_Object c = XVECTOR_DATA(v)[i];
763 if (!NILP (c) && !CHARP (c))
767 int ret = decoding_table_check_elements (c, dim - 1, ccs_len);
779 decoding_table_remove_char (Lisp_Object v, int dim, int byte_offset,
782 decoding_table_remove_char (Lisp_Object v, int dim, int byte_offset,
792 i = ((code_point >> (8 * dim)) & 255) - byte_offset;
793 nv = XVECTOR_DATA(v)[i];
799 XVECTOR_DATA(v)[i] = Qnil;
803 decoding_table_put_char (Lisp_Object v, int dim, int byte_offset,
804 int code_point, Lisp_Object character);
806 decoding_table_put_char (Lisp_Object v, int dim, int byte_offset,
807 int code_point, Lisp_Object character)
811 int ccs_len = XVECTOR_LENGTH (v);
816 i = ((code_point >> (8 * dim)) & 255) - byte_offset;
817 nv = XVECTOR_DATA(v)[i];
821 nv = (XVECTOR_DATA(v)[i] = make_older_vector (ccs_len, Qnil));
827 XVECTOR_DATA(v)[i] = character;
831 put_char_ccs_code_point (Lisp_Object character,
832 Lisp_Object ccs, Lisp_Object value)
834 Lisp_Object encoding_table;
836 if (!EQ (XCHARSET_NAME (ccs), Qucs)
837 || (XCHAR (character) != XINT (value)))
839 Lisp_Object v = XCHARSET_DECODING_TABLE (ccs);
840 int dim = XCHARSET_DIMENSION (ccs);
841 int ccs_len = XCHARSET_BYTE_SIZE (ccs);
842 int byte_offset = XCHARSET_BYTE_OFFSET (ccs);
846 { /* obsolete representation: value must be a list of bytes */
847 Lisp_Object ret = Fcar (value);
851 signal_simple_error ("Invalid value for coded-charset", value);
852 code_point = XINT (ret);
853 if (XCHARSET_GRAPHIC (ccs) == 1)
861 signal_simple_error ("Invalid value for coded-charset",
865 signal_simple_error ("Invalid value for coded-charset",
868 if (XCHARSET_GRAPHIC (ccs) == 1)
870 code_point = (code_point << 8) | j;
873 value = make_int (code_point);
875 else if (INTP (value))
877 code_point = XINT (value);
878 if (XCHARSET_GRAPHIC (ccs) == 1)
880 code_point &= 0x7F7F7F7F;
881 value = make_int (code_point);
885 signal_simple_error ("Invalid value for coded-charset", value);
889 Lisp_Object cpos = Fget_char_attribute (character, ccs);
892 decoding_table_remove_char (v, dim, byte_offset, XINT (cpos));
897 XCHARSET_DECODING_TABLE (ccs)
898 = v = make_older_vector (ccs_len, Qnil);
901 decoding_table_put_char (v, dim, byte_offset, code_point, character);
903 if (NILP (encoding_table = XCHARSET_ENCODING_TABLE (ccs)))
905 XCHARSET_ENCODING_TABLE (ccs)
906 = encoding_table = make_char_id_table (Qnil, -1);
908 put_char_id_table (XCHAR (character), value, encoding_table);
913 remove_char_ccs (Lisp_Object character, Lisp_Object ccs)
915 Lisp_Object decoding_table = XCHARSET_DECODING_TABLE (ccs);
916 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
918 if (VECTORP (decoding_table))
920 Lisp_Object cpos = Fget_char_attribute (character, ccs);
924 decoding_table_remove_char (decoding_table,
925 XCHARSET_DIMENSION (ccs),
926 XCHARSET_BYTE_OFFSET (ccs),
930 if (CHAR_ID_TABLE_P (encoding_table))
932 put_char_id_table (XCHAR (character), Qnil, encoding_table);
938 put_char_attribute (Lisp_Object character, Lisp_Object attribute,
941 Emchar char_id = XCHAR (character);
942 Lisp_Object ret = get_char_id_table (char_id, Vcharacter_attribute_table);
945 cell = Fassq (attribute, ret);
949 ret = Fcons (Fcons (attribute, value), ret);
951 else if (!EQ (Fcdr (cell), value))
953 Fsetcdr (cell, value);
955 put_char_id_table (char_id, ret, Vcharacter_attribute_table);
960 remove_char_attribute (Lisp_Object character, Lisp_Object attribute)
962 Emchar char_id = XCHAR (character);
963 Lisp_Object alist = get_char_id_table (char_id, Vcharacter_attribute_table);
965 if (EQ (attribute, Fcar (Fcar (alist))))
967 alist = Fcdr (alist);
971 Lisp_Object pr = alist;
972 Lisp_Object r = Fcdr (alist);
976 if (EQ (attribute, Fcar (Fcar (r))))
978 XCDR (pr) = Fcdr (r);
985 put_char_id_table (char_id, alist, Vcharacter_attribute_table);
989 EXFUN (Fmake_char, 3);
990 EXFUN (Fdecode_char, 2);
992 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
993 Store character's ATTRIBUTES.
997 Lisp_Object rest = attributes;
998 Lisp_Object code = Fcdr (Fassq (Qucs, attributes));
999 Lisp_Object character;
1003 while (CONSP (rest))
1005 Lisp_Object cell = Fcar (rest);
1009 signal_simple_error ("Invalid argument", attributes);
1010 if (!NILP (ccs = Ffind_charset (Fcar (cell)))
1011 && ((XCHARSET_FINAL (ccs) != 0) ||
1012 (XCHARSET_UCS_MAX (ccs) > 0)) )
1016 character = Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
1018 character = Fdecode_char (ccs, cell);
1019 goto setup_attributes;
1023 if (!NILP (code = Fcdr (Fassq (Q_ucs, attributes))))
1026 signal_simple_error ("Invalid argument", attributes);
1028 character = make_char (XINT (code) + 0x100000);
1029 goto setup_attributes;
1033 else if (!INTP (code))
1034 signal_simple_error ("Invalid argument", attributes);
1036 character = make_char (XINT (code));
1040 while (CONSP (rest))
1042 Lisp_Object cell = Fcar (rest);
1045 signal_simple_error ("Invalid argument", attributes);
1046 Fput_char_attribute (character, Fcar (cell), Fcdr (cell));
1050 get_char_id_table (XCHAR (character), Vcharacter_attribute_table);
1053 Lisp_Object Vutf_2000_version;
1057 int leading_code_private_11;
1060 Lisp_Object Qcharsetp;
1062 /* Qdoc_string, Qdimension, Qchars defined in general.c */
1063 Lisp_Object Qregistry, Qfinal, Qgraphic;
1064 Lisp_Object Qdirection;
1065 Lisp_Object Qreverse_direction_charset;
1066 Lisp_Object Qleading_byte;
1067 Lisp_Object Qshort_name, Qlong_name;
1081 Qcyrillic_iso8859_5,
1083 Qjapanese_jisx0208_1978,
1086 Qjapanese_jisx0208_1990,
1089 Qchinese_cns11643_1,
1090 Qchinese_cns11643_2,
1095 Qlatin_viscii_lower,
1096 Qlatin_viscii_upper,
1097 Qvietnamese_viscii_lower,
1098 Qvietnamese_viscii_upper,
1099 Qideograph_daikanwa,
1128 Lisp_Object Ql2r, Qr2l;
1130 Lisp_Object Vcharset_hash_table;
1132 /* Composite characters are characters constructed by overstriking two
1133 or more regular characters.
1135 1) The old Mule implementation involves storing composite characters
1136 in a buffer as a tag followed by all of the actual characters
1137 used to make up the composite character. I think this is a bad
1138 idea; it greatly complicates code that wants to handle strings
1139 one character at a time because it has to deal with the possibility
1140 of great big ungainly characters. It's much more reasonable to
1141 simply store an index into a table of composite characters.
1143 2) The current implementation only allows for 16,384 separate
1144 composite characters over the lifetime of the XEmacs process.
1145 This could become a potential problem if the user
1146 edited lots of different files that use composite characters.
1147 Due to FSF bogosity, increasing the number of allowable
1148 composite characters under Mule would decrease the number
1149 of possible faces that can exist. Mule already has shrunk
1150 this to 2048, and further shrinkage would become uncomfortable.
1151 No such problems exist in XEmacs.
1153 Composite characters could be represented as 0x80 C1 C2 C3,
1154 where each C[1-3] is in the range 0xA0 - 0xFF. This allows
1155 for slightly under 2^20 (one million) composite characters
1156 over the XEmacs process lifetime, and you only need to
1157 increase the size of a Mule character from 19 to 21 bits.
1158 Or you could use 0x80 C1 C2 C3 C4, allowing for about
1159 85 million (slightly over 2^26) composite characters. */
1162 /************************************************************************/
1163 /* Basic Emchar functions */
1164 /************************************************************************/
1166 /* Convert a non-ASCII Mule character C into a one-character Mule-encoded
1167 string in STR. Returns the number of bytes stored.
1168 Do not call this directly. Use the macro set_charptr_emchar() instead.
1172 non_ascii_set_charptr_emchar (Bufbyte *str, Emchar c)
1178 Lisp_Object charset;
1187 else if ( c <= 0x7ff )
1189 *p++ = (c >> 6) | 0xc0;
1190 *p++ = (c & 0x3f) | 0x80;
1192 else if ( c <= 0xffff )
1194 *p++ = (c >> 12) | 0xe0;
1195 *p++ = ((c >> 6) & 0x3f) | 0x80;
1196 *p++ = (c & 0x3f) | 0x80;
1198 else if ( c <= 0x1fffff )
1200 *p++ = (c >> 18) | 0xf0;
1201 *p++ = ((c >> 12) & 0x3f) | 0x80;
1202 *p++ = ((c >> 6) & 0x3f) | 0x80;
1203 *p++ = (c & 0x3f) | 0x80;
1205 else if ( c <= 0x3ffffff )
1207 *p++ = (c >> 24) | 0xf8;
1208 *p++ = ((c >> 18) & 0x3f) | 0x80;
1209 *p++ = ((c >> 12) & 0x3f) | 0x80;
1210 *p++ = ((c >> 6) & 0x3f) | 0x80;
1211 *p++ = (c & 0x3f) | 0x80;
1215 *p++ = (c >> 30) | 0xfc;
1216 *p++ = ((c >> 24) & 0x3f) | 0x80;
1217 *p++ = ((c >> 18) & 0x3f) | 0x80;
1218 *p++ = ((c >> 12) & 0x3f) | 0x80;
1219 *p++ = ((c >> 6) & 0x3f) | 0x80;
1220 *p++ = (c & 0x3f) | 0x80;
1223 BREAKUP_CHAR (c, charset, c1, c2);
1224 lb = CHAR_LEADING_BYTE (c);
1225 if (LEADING_BYTE_PRIVATE_P (lb))
1226 *p++ = PRIVATE_LEADING_BYTE_PREFIX (lb);
1228 if (EQ (charset, Vcharset_control_1))
1237 /* Return the first character from a Mule-encoded string in STR,
1238 assuming it's non-ASCII. Do not call this directly.
1239 Use the macro charptr_emchar() instead. */
1242 non_ascii_charptr_emchar (const Bufbyte *str)
1255 else if ( b >= 0xf8 )
1260 else if ( b >= 0xf0 )
1265 else if ( b >= 0xe0 )
1270 else if ( b >= 0xc0 )
1280 for( ; len > 0; len-- )
1283 ch = ( ch << 6 ) | ( b & 0x3f );
1287 Bufbyte i0 = *str, i1, i2 = 0;
1288 Lisp_Object charset;
1290 if (i0 == LEADING_BYTE_CONTROL_1)
1291 return (Emchar) (*++str - 0x20);
1293 if (LEADING_BYTE_PREFIX_P (i0))
1298 charset = CHARSET_BY_LEADING_BYTE (i0);
1299 if (XCHARSET_DIMENSION (charset) == 2)
1302 return MAKE_CHAR (charset, i1, i2);
1306 /* Return whether CH is a valid Emchar, assuming it's non-ASCII.
1307 Do not call this directly. Use the macro valid_char_p() instead. */
1311 non_ascii_valid_char_p (Emchar ch)
1315 /* Must have only lowest 19 bits set */
1319 f1 = CHAR_FIELD1 (ch);
1320 f2 = CHAR_FIELD2 (ch);
1321 f3 = CHAR_FIELD3 (ch);
1325 Lisp_Object charset;
1327 if (f2 < MIN_CHAR_FIELD2_OFFICIAL ||
1328 (f2 > MAX_CHAR_FIELD2_OFFICIAL && f2 < MIN_CHAR_FIELD2_PRIVATE) ||
1329 f2 > MAX_CHAR_FIELD2_PRIVATE)
1334 if (f3 != 0x20 && f3 != 0x7F && !(f2 >= MIN_CHAR_FIELD2_PRIVATE &&
1335 f2 <= MAX_CHAR_FIELD2_PRIVATE))
1339 NOTE: This takes advantage of the fact that
1340 FIELD2_TO_OFFICIAL_LEADING_BYTE and
1341 FIELD2_TO_PRIVATE_LEADING_BYTE are the same.
1343 charset = CHARSET_BY_LEADING_BYTE (f2 + FIELD2_TO_OFFICIAL_LEADING_BYTE);
1344 if (EQ (charset, Qnil))
1346 return (XCHARSET_CHARS (charset) == 96);
1350 Lisp_Object charset;
1352 if (f1 < MIN_CHAR_FIELD1_OFFICIAL ||
1353 (f1 > MAX_CHAR_FIELD1_OFFICIAL && f1 < MIN_CHAR_FIELD1_PRIVATE) ||
1354 f1 > MAX_CHAR_FIELD1_PRIVATE)
1356 if (f2 < 0x20 || f3 < 0x20)
1359 #ifdef ENABLE_COMPOSITE_CHARS
1360 if (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE == LEADING_BYTE_COMPOSITE)
1362 if (UNBOUNDP (Fgethash (make_int (ch),
1363 Vcomposite_char_char2string_hash_table,
1368 #endif /* ENABLE_COMPOSITE_CHARS */
1370 if (f2 != 0x20 && f2 != 0x7F && f3 != 0x20 && f3 != 0x7F
1371 && !(f1 >= MIN_CHAR_FIELD1_PRIVATE && f1 <= MAX_CHAR_FIELD1_PRIVATE))
1374 if (f1 <= MAX_CHAR_FIELD1_OFFICIAL)
1376 CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE);
1379 CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_PRIVATE_LEADING_BYTE);
1381 if (EQ (charset, Qnil))
1383 return (XCHARSET_CHARS (charset) == 96);
1389 /************************************************************************/
1390 /* Basic string functions */
1391 /************************************************************************/
1393 /* Copy the character pointed to by PTR into STR, assuming it's
1394 non-ASCII. Do not call this directly. Use the macro
1395 charptr_copy_char() instead. */
1398 non_ascii_charptr_copy_char (const Bufbyte *ptr, Bufbyte *str)
1400 Bufbyte *strptr = str;
1402 switch (REP_BYTES_BY_FIRST_BYTE (*strptr))
1404 /* Notice fallthrough. */
1406 case 6: *++strptr = *ptr++;
1407 case 5: *++strptr = *ptr++;
1409 case 4: *++strptr = *ptr++;
1410 case 3: *++strptr = *ptr++;
1411 case 2: *++strptr = *ptr;
1416 return strptr + 1 - str;
1420 /************************************************************************/
1421 /* streams of Emchars */
1422 /************************************************************************/
1424 /* Treat a stream as a stream of Emchar's rather than a stream of bytes.
1425 The functions below are not meant to be called directly; use
1426 the macros in insdel.h. */
1429 Lstream_get_emchar_1 (Lstream *stream, int ch)
1431 Bufbyte str[MAX_EMCHAR_LEN];
1432 Bufbyte *strptr = str;
1434 str[0] = (Bufbyte) ch;
1435 switch (REP_BYTES_BY_FIRST_BYTE (ch))
1437 /* Notice fallthrough. */
1440 ch = Lstream_getc (stream);
1442 *++strptr = (Bufbyte) ch;
1444 ch = Lstream_getc (stream);
1446 *++strptr = (Bufbyte) ch;
1449 ch = Lstream_getc (stream);
1451 *++strptr = (Bufbyte) ch;
1453 ch = Lstream_getc (stream);
1455 *++strptr = (Bufbyte) ch;
1457 ch = Lstream_getc (stream);
1459 *++strptr = (Bufbyte) ch;
1464 return charptr_emchar (str);
1468 Lstream_fput_emchar (Lstream *stream, Emchar ch)
1470 Bufbyte str[MAX_EMCHAR_LEN];
1471 Bytecount len = set_charptr_emchar (str, ch);
1472 return Lstream_write (stream, str, len);
1476 Lstream_funget_emchar (Lstream *stream, Emchar ch)
1478 Bufbyte str[MAX_EMCHAR_LEN];
1479 Bytecount len = set_charptr_emchar (str, ch);
1480 Lstream_unread (stream, str, len);
1484 /************************************************************************/
1485 /* charset object */
1486 /************************************************************************/
1489 mark_charset (Lisp_Object obj)
1491 Lisp_Charset *cs = XCHARSET (obj);
1493 mark_object (cs->short_name);
1494 mark_object (cs->long_name);
1495 mark_object (cs->doc_string);
1496 mark_object (cs->registry);
1497 mark_object (cs->ccl_program);
1499 /* mark_object (cs->encoding_table); */
1500 /* mark_object (cs->decoding_table); */
1506 print_charset (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1508 Lisp_Charset *cs = XCHARSET (obj);
1512 error ("printing unreadable object #<charset %s 0x%x>",
1513 string_data (XSYMBOL (CHARSET_NAME (cs))->name),
1516 write_c_string ("#<charset ", printcharfun);
1517 print_internal (CHARSET_NAME (cs), printcharfun, 0);
1518 write_c_string (" ", printcharfun);
1519 print_internal (CHARSET_SHORT_NAME (cs), printcharfun, 1);
1520 write_c_string (" ", printcharfun);
1521 print_internal (CHARSET_LONG_NAME (cs), printcharfun, 1);
1522 write_c_string (" ", printcharfun);
1523 print_internal (CHARSET_DOC_STRING (cs), printcharfun, 1);
1524 sprintf (buf, " %d^%d %s cols=%d g%d final='%c' reg=",
1526 CHARSET_DIMENSION (cs),
1527 CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? "l2r" : "r2l",
1528 CHARSET_COLUMNS (cs),
1529 CHARSET_GRAPHIC (cs),
1530 CHARSET_FINAL (cs));
1531 write_c_string (buf, printcharfun);
1532 print_internal (CHARSET_REGISTRY (cs), printcharfun, 0);
1533 sprintf (buf, " 0x%x>", cs->header.uid);
1534 write_c_string (buf, printcharfun);
1537 static const struct lrecord_description charset_description[] = {
1538 { XD_LISP_OBJECT, offsetof (Lisp_Charset, name) },
1539 { XD_LISP_OBJECT, offsetof (Lisp_Charset, doc_string) },
1540 { XD_LISP_OBJECT, offsetof (Lisp_Charset, registry) },
1541 { XD_LISP_OBJECT, offsetof (Lisp_Charset, short_name) },
1542 { XD_LISP_OBJECT, offsetof (Lisp_Charset, long_name) },
1543 { XD_LISP_OBJECT, offsetof (Lisp_Charset, reverse_direction_charset) },
1544 { XD_LISP_OBJECT, offsetof (Lisp_Charset, ccl_program) },
1546 { XD_LISP_OBJECT, offsetof (Lisp_Charset, decoding_table) },
1547 { XD_LISP_OBJECT, offsetof (Lisp_Charset, encoding_table) },
1552 DEFINE_LRECORD_IMPLEMENTATION ("charset", charset,
1553 mark_charset, print_charset, 0, 0, 0,
1554 charset_description,
1556 /* Make a new charset. */
1559 make_charset (Charset_ID id, Lisp_Object name,
1560 unsigned short chars, unsigned char dimension,
1561 unsigned char columns, unsigned char graphic,
1562 Bufbyte final, unsigned char direction, Lisp_Object short_name,
1563 Lisp_Object long_name, Lisp_Object doc,
1565 Lisp_Object decoding_table,
1566 Emchar ucs_min, Emchar ucs_max,
1567 Emchar code_offset, unsigned char byte_offset)
1569 unsigned char type = 0;
1571 Lisp_Charset *cs = alloc_lcrecord_type (Lisp_Charset, &lrecord_charset);
1575 XSETCHARSET (obj, cs);
1577 CHARSET_ID (cs) = id;
1578 CHARSET_NAME (cs) = name;
1579 CHARSET_SHORT_NAME (cs) = short_name;
1580 CHARSET_LONG_NAME (cs) = long_name;
1581 CHARSET_CHARS (cs) = chars;
1582 CHARSET_DIMENSION (cs) = dimension;
1583 CHARSET_DIRECTION (cs) = direction;
1584 CHARSET_COLUMNS (cs) = columns;
1585 CHARSET_GRAPHIC (cs) = graphic;
1586 CHARSET_FINAL (cs) = final;
1587 CHARSET_DOC_STRING (cs) = doc;
1588 CHARSET_REGISTRY (cs) = reg;
1589 CHARSET_CCL_PROGRAM (cs) = Qnil;
1590 CHARSET_REVERSE_DIRECTION_CHARSET (cs) = Qnil;
1592 CHARSET_DECODING_TABLE(cs) = Qnil;
1593 CHARSET_ENCODING_TABLE(cs) = Qnil;
1594 CHARSET_UCS_MIN(cs) = ucs_min;
1595 CHARSET_UCS_MAX(cs) = ucs_max;
1596 CHARSET_CODE_OFFSET(cs) = code_offset;
1597 CHARSET_BYTE_OFFSET(cs) = byte_offset;
1600 switch (CHARSET_CHARS (cs))
1603 switch (CHARSET_DIMENSION (cs))
1606 type = CHARSET_TYPE_94;
1609 type = CHARSET_TYPE_94X94;
1614 switch (CHARSET_DIMENSION (cs))
1617 type = CHARSET_TYPE_96;
1620 type = CHARSET_TYPE_96X96;
1626 switch (CHARSET_DIMENSION (cs))
1629 type = CHARSET_TYPE_128;
1632 type = CHARSET_TYPE_128X128;
1637 switch (CHARSET_DIMENSION (cs))
1640 type = CHARSET_TYPE_256;
1643 type = CHARSET_TYPE_256X256;
1650 CHARSET_TYPE (cs) = type;
1654 if (id == LEADING_BYTE_ASCII)
1655 CHARSET_REP_BYTES (cs) = 1;
1657 CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 1;
1659 CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 2;
1664 /* some charsets do not have final characters. This includes
1665 ASCII, Control-1, Composite, and the two faux private
1668 if (code_offset == 0)
1670 assert (NILP (chlook->charset_by_attributes[type][final]));
1671 chlook->charset_by_attributes[type][final] = obj;
1674 assert (NILP (chlook->charset_by_attributes[type][final][direction]));
1675 chlook->charset_by_attributes[type][final][direction] = obj;
1679 assert (NILP (chlook->charset_by_leading_byte[id - MIN_LEADING_BYTE]));
1680 chlook->charset_by_leading_byte[id - MIN_LEADING_BYTE] = obj;
1682 /* Some charsets are "faux" and don't have names or really exist at
1683 all except in the leading-byte table. */
1685 Fputhash (name, obj, Vcharset_hash_table);
1690 get_unallocated_leading_byte (int dimension)
1695 if (chlook->next_allocated_leading_byte > MAX_LEADING_BYTE_PRIVATE)
1698 lb = chlook->next_allocated_leading_byte++;
1702 if (chlook->next_allocated_1_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_1)
1705 lb = chlook->next_allocated_1_byte_leading_byte++;
1709 if (chlook->next_allocated_2_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_2)
1712 lb = chlook->next_allocated_2_byte_leading_byte++;
1718 ("No more character sets free for this dimension",
1719 make_int (dimension));
1726 make_builtin_char (Lisp_Object charset, int c1, int c2)
1728 if (XCHARSET_UCS_MAX (charset))
1731 = (XCHARSET_DIMENSION (charset) == 1
1733 c1 - XCHARSET_BYTE_OFFSET (charset)
1735 (c1 - XCHARSET_BYTE_OFFSET (charset)) * XCHARSET_CHARS (charset)
1736 + c2 - XCHARSET_BYTE_OFFSET (charset))
1737 - XCHARSET_CODE_OFFSET (charset) + XCHARSET_UCS_MIN (charset);
1738 if ((code < XCHARSET_UCS_MIN (charset))
1739 || (XCHARSET_UCS_MAX (charset) < code))
1740 signal_simple_error ("Arguments makes invalid character",
1744 else if (XCHARSET_DIMENSION (charset) == 1)
1746 switch (XCHARSET_CHARS (charset))
1750 + (XCHARSET_FINAL (charset) - '0') * 94 + (c1 - 33);
1753 + (XCHARSET_FINAL (charset) - '0') * 96 + (c1 - 32);
1760 switch (XCHARSET_CHARS (charset))
1763 return MIN_CHAR_94x94
1764 + (XCHARSET_FINAL (charset) - '0') * 94 * 94
1765 + (c1 - 33) * 94 + (c2 - 33);
1767 return MIN_CHAR_96x96
1768 + (XCHARSET_FINAL (charset) - '0') * 96 * 96
1769 + (c1 - 32) * 96 + (c2 - 32);
1777 range_charset_code_point (Lisp_Object charset, Emchar ch)
1781 if ((XCHARSET_UCS_MIN (charset) <= ch)
1782 && (ch <= XCHARSET_UCS_MAX (charset)))
1784 d = ch - XCHARSET_UCS_MIN (charset) + XCHARSET_CODE_OFFSET (charset);
1786 if (XCHARSET_CHARS (charset) == 256)
1788 else if (XCHARSET_DIMENSION (charset) == 1)
1789 return d + XCHARSET_BYTE_OFFSET (charset);
1790 else if (XCHARSET_DIMENSION (charset) == 2)
1792 ((d / XCHARSET_CHARS (charset)
1793 + XCHARSET_BYTE_OFFSET (charset)) << 8)
1794 | (d % XCHARSET_CHARS (charset) + XCHARSET_BYTE_OFFSET (charset));
1795 else if (XCHARSET_DIMENSION (charset) == 3)
1797 ((d / (XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset))
1798 + XCHARSET_BYTE_OFFSET (charset)) << 16)
1799 | ((d / XCHARSET_CHARS (charset)
1800 % XCHARSET_CHARS (charset)
1801 + XCHARSET_BYTE_OFFSET (charset)) << 8)
1802 | (d % XCHARSET_CHARS (charset) + XCHARSET_BYTE_OFFSET (charset));
1803 else /* if (XCHARSET_DIMENSION (charset) == 4) */
1805 ((d / (XCHARSET_CHARS (charset)
1806 * XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset))
1807 + XCHARSET_BYTE_OFFSET (charset)) << 24)
1808 | ((d / (XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset))
1809 % XCHARSET_CHARS (charset)
1810 + XCHARSET_BYTE_OFFSET (charset)) << 16)
1811 | ((d / XCHARSET_CHARS (charset) % XCHARSET_CHARS (charset)
1812 + XCHARSET_BYTE_OFFSET (charset)) << 8)
1813 | (d % XCHARSET_CHARS (charset) + XCHARSET_BYTE_OFFSET (charset));
1815 else if (XCHARSET_CODE_OFFSET (charset) == 0)
1817 if (XCHARSET_DIMENSION (charset) == 1)
1819 if (XCHARSET_CHARS (charset) == 94)
1821 if (((d = ch - (MIN_CHAR_94
1822 + (XCHARSET_FINAL (charset) - '0') * 94)) >= 0)
1826 else if (XCHARSET_CHARS (charset) == 96)
1828 if (((d = ch - (MIN_CHAR_96
1829 + (XCHARSET_FINAL (charset) - '0') * 96)) >= 0)
1836 else if (XCHARSET_DIMENSION (charset) == 2)
1838 if (XCHARSET_CHARS (charset) == 94)
1840 if (((d = ch - (MIN_CHAR_94x94
1841 + (XCHARSET_FINAL (charset) - '0') * 94 * 94))
1844 return (((d / 94) + 33) << 8) | (d % 94 + 33);
1846 else if (XCHARSET_CHARS (charset) == 96)
1848 if (((d = ch - (MIN_CHAR_96x96
1849 + (XCHARSET_FINAL (charset) - '0') * 96 * 96))
1852 return (((d / 96) + 32) << 8) | (d % 96 + 32);
1862 encode_builtin_char_1 (Emchar c, Lisp_Object* charset)
1864 if (c <= MAX_CHAR_BASIC_LATIN)
1866 *charset = Vcharset_ascii;
1871 *charset = Vcharset_control_1;
1876 *charset = Vcharset_latin_iso8859_1;
1880 else if ((MIN_CHAR_GREEK <= c) && (c <= MAX_CHAR_GREEK))
1882 *charset = Vcharset_greek_iso8859_7;
1883 return c - MIN_CHAR_GREEK + 0x20;
1885 else if ((MIN_CHAR_CYRILLIC <= c) && (c <= MAX_CHAR_CYRILLIC))
1887 *charset = Vcharset_cyrillic_iso8859_5;
1888 return c - MIN_CHAR_CYRILLIC + 0x20;
1891 else if ((MIN_CHAR_HEBREW <= c) && (c <= MAX_CHAR_HEBREW))
1893 *charset = Vcharset_hebrew_iso8859_8;
1894 return c - MIN_CHAR_HEBREW + 0x20;
1896 else if ((MIN_CHAR_THAI <= c) && (c <= MAX_CHAR_THAI))
1898 *charset = Vcharset_thai_tis620;
1899 return c - MIN_CHAR_THAI + 0x20;
1902 else if ((MIN_CHAR_HALFWIDTH_KATAKANA <= c)
1903 && (c <= MAX_CHAR_HALFWIDTH_KATAKANA))
1905 return list2 (Vcharset_katakana_jisx0201,
1906 make_int (c - MIN_CHAR_HALFWIDTH_KATAKANA + 33));
1909 else if (c <= MAX_CHAR_BMP)
1911 *charset = Vcharset_ucs_bmp;
1914 else if (c < MIN_CHAR_DAIKANWA)
1916 *charset = Vcharset_ucs;
1920 else if (c <= MAX_CHAR_DAIKANWA)
1922 *charset = Vcharset_ideograph_daikanwa;
1923 return c - MIN_CHAR_DAIKANWA;
1926 else if (c <= MAX_CHAR_MOJIKYO)
1928 *charset = Vcharset_mojikyo;
1929 return c - MIN_CHAR_MOJIKYO;
1931 else if (c < MIN_CHAR_94)
1933 *charset = Vcharset_ucs;
1936 else if (c <= MAX_CHAR_94)
1938 *charset = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_94,
1939 ((c - MIN_CHAR_94) / 94) + '0',
1940 CHARSET_LEFT_TO_RIGHT);
1941 if (!NILP (*charset))
1942 return ((c - MIN_CHAR_94) % 94) + 33;
1945 *charset = Vcharset_ucs;
1949 else if (c <= MAX_CHAR_96)
1951 *charset = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_96,
1952 ((c - MIN_CHAR_96) / 96) + '0',
1953 CHARSET_LEFT_TO_RIGHT);
1954 if (!NILP (*charset))
1955 return ((c - MIN_CHAR_96) % 96) + 32;
1958 *charset = Vcharset_ucs;
1962 else if (c <= MAX_CHAR_94x94)
1965 = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_94X94,
1966 ((c - MIN_CHAR_94x94) / (94 * 94)) + '0',
1967 CHARSET_LEFT_TO_RIGHT);
1968 if (!NILP (*charset))
1969 return (((((c - MIN_CHAR_94x94) / 94) % 94) + 33) << 8)
1970 | (((c - MIN_CHAR_94x94) % 94) + 33);
1973 *charset = Vcharset_ucs;
1977 else if (c <= MAX_CHAR_96x96)
1980 = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_96X96,
1981 ((c - MIN_CHAR_96x96) / (96 * 96)) + '0',
1982 CHARSET_LEFT_TO_RIGHT);
1983 if (!NILP (*charset))
1984 return ((((c - MIN_CHAR_96x96) / 96) % 96) + 32) << 8
1985 | (((c - MIN_CHAR_96x96) % 96) + 32);
1988 *charset = Vcharset_ucs;
1994 *charset = Vcharset_ucs;
1999 Lisp_Object Vdefault_coded_charset_priority_list;
2003 /************************************************************************/
2004 /* Basic charset Lisp functions */
2005 /************************************************************************/
2007 DEFUN ("charsetp", Fcharsetp, 1, 1, 0, /*
2008 Return non-nil if OBJECT is a charset.
2012 return CHARSETP (object) ? Qt : Qnil;
2015 DEFUN ("find-charset", Ffind_charset, 1, 1, 0, /*
2016 Retrieve the charset of the given name.
2017 If CHARSET-OR-NAME is a charset object, it is simply returned.
2018 Otherwise, CHARSET-OR-NAME should be a symbol. If there is no such charset,
2019 nil is returned. Otherwise the associated charset object is returned.
2023 if (CHARSETP (charset_or_name))
2024 return charset_or_name;
2026 CHECK_SYMBOL (charset_or_name);
2027 return Fgethash (charset_or_name, Vcharset_hash_table, Qnil);
2030 DEFUN ("get-charset", Fget_charset, 1, 1, 0, /*
2031 Retrieve the charset of the given name.
2032 Same as `find-charset' except an error is signalled if there is no such
2033 charset instead of returning nil.
2037 Lisp_Object charset = Ffind_charset (name);
2040 signal_simple_error ("No such charset", name);
2044 /* We store the charsets in hash tables with the names as the key and the
2045 actual charset object as the value. Occasionally we need to use them
2046 in a list format. These routines provide us with that. */
2047 struct charset_list_closure
2049 Lisp_Object *charset_list;
2053 add_charset_to_list_mapper (Lisp_Object key, Lisp_Object value,
2054 void *charset_list_closure)
2056 /* This function can GC */
2057 struct charset_list_closure *chcl =
2058 (struct charset_list_closure*) charset_list_closure;
2059 Lisp_Object *charset_list = chcl->charset_list;
2061 *charset_list = Fcons (XCHARSET_NAME (value), *charset_list);
2065 DEFUN ("charset-list", Fcharset_list, 0, 0, 0, /*
2066 Return a list of the names of all defined charsets.
2070 Lisp_Object charset_list = Qnil;
2071 struct gcpro gcpro1;
2072 struct charset_list_closure charset_list_closure;
2074 GCPRO1 (charset_list);
2075 charset_list_closure.charset_list = &charset_list;
2076 elisp_maphash (add_charset_to_list_mapper, Vcharset_hash_table,
2077 &charset_list_closure);
2080 return charset_list;
2083 DEFUN ("charset-name", Fcharset_name, 1, 1, 0, /*
2084 Return the name of the given charset.
2088 return XCHARSET_NAME (Fget_charset (charset));
2091 DEFUN ("make-charset", Fmake_charset, 3, 3, 0, /*
2092 Define a new character set.
2093 This function is for use with Mule support.
2094 NAME is a symbol, the name by which the character set is normally referred.
2095 DOC-STRING is a string describing the character set.
2096 PROPS is a property list, describing the specific nature of the
2097 character set. Recognized properties are:
2099 'short-name Short version of the charset name (ex: Latin-1)
2100 'long-name Long version of the charset name (ex: ISO8859-1 (Latin-1))
2101 'registry A regular expression matching the font registry field for
2103 'dimension Number of octets used to index a character in this charset.
2104 Either 1 or 2. Defaults to 1.
2105 'columns Number of columns used to display a character in this charset.
2106 Only used in TTY mode. (Under X, the actual width of a
2107 character can be derived from the font used to display the
2108 characters.) If unspecified, defaults to the dimension
2109 (this is almost always the correct value).
2110 'chars Number of characters in each dimension (94 or 96).
2111 Defaults to 94. Note that if the dimension is 2, the
2112 character set thus described is 94x94 or 96x96.
2113 'final Final byte of ISO 2022 escape sequence. Must be
2114 supplied. Each combination of (DIMENSION, CHARS) defines a
2115 separate namespace for final bytes. Note that ISO
2116 2022 restricts the final byte to the range
2117 0x30 - 0x7E if dimension == 1, and 0x30 - 0x5F if
2118 dimension == 2. Note also that final bytes in the range
2119 0x30 - 0x3F are reserved for user-defined (not official)
2121 'graphic 0 (use left half of font on output) or 1 (use right half
2122 of font on output). Defaults to 0. For example, for
2123 a font whose registry is ISO8859-1, the left half
2124 (octets 0x20 - 0x7F) is the `ascii' character set, while
2125 the right half (octets 0xA0 - 0xFF) is the `latin-1'
2126 character set. With 'graphic set to 0, the octets
2127 will have their high bit cleared; with it set to 1,
2128 the octets will have their high bit set.
2129 'direction 'l2r (left-to-right) or 'r2l (right-to-left).
2131 'ccl-program A compiled CCL program used to convert a character in
2132 this charset into an index into the font. This is in
2133 addition to the 'graphic property. The CCL program
2134 is passed the octets of the character, with the high
2135 bit cleared and set depending upon whether the value
2136 of the 'graphic property is 0 or 1.
2138 (name, doc_string, props))
2140 int id, dimension = 1, chars = 94, graphic = 0, final = 0, columns = -1;
2141 int direction = CHARSET_LEFT_TO_RIGHT;
2143 Lisp_Object registry = Qnil;
2144 Lisp_Object charset;
2145 Lisp_Object rest, keyword, value;
2146 Lisp_Object ccl_program = Qnil;
2147 Lisp_Object short_name = Qnil, long_name = Qnil;
2148 int byte_offset = -1;
2150 CHECK_SYMBOL (name);
2151 if (!NILP (doc_string))
2152 CHECK_STRING (doc_string);
2154 charset = Ffind_charset (name);
2155 if (!NILP (charset))
2156 signal_simple_error ("Cannot redefine existing charset", name);
2158 EXTERNAL_PROPERTY_LIST_LOOP (rest, keyword, value, props)
2160 if (EQ (keyword, Qshort_name))
2162 CHECK_STRING (value);
2166 if (EQ (keyword, Qlong_name))
2168 CHECK_STRING (value);
2172 else if (EQ (keyword, Qdimension))
2175 dimension = XINT (value);
2176 if (dimension < 1 || dimension > 2)
2177 signal_simple_error ("Invalid value for 'dimension", value);
2180 else if (EQ (keyword, Qchars))
2183 chars = XINT (value);
2184 if (chars != 94 && chars != 96)
2185 signal_simple_error ("Invalid value for 'chars", value);
2188 else if (EQ (keyword, Qcolumns))
2191 columns = XINT (value);
2192 if (columns != 1 && columns != 2)
2193 signal_simple_error ("Invalid value for 'columns", value);
2196 else if (EQ (keyword, Qgraphic))
2199 graphic = XINT (value);
2201 if (graphic < 0 || graphic > 2)
2203 if (graphic < 0 || graphic > 1)
2205 signal_simple_error ("Invalid value for 'graphic", value);
2208 else if (EQ (keyword, Qregistry))
2210 CHECK_STRING (value);
2214 else if (EQ (keyword, Qdirection))
2216 if (EQ (value, Ql2r))
2217 direction = CHARSET_LEFT_TO_RIGHT;
2218 else if (EQ (value, Qr2l))
2219 direction = CHARSET_RIGHT_TO_LEFT;
2221 signal_simple_error ("Invalid value for 'direction", value);
2224 else if (EQ (keyword, Qfinal))
2226 CHECK_CHAR_COERCE_INT (value);
2227 final = XCHAR (value);
2228 if (final < '0' || final > '~')
2229 signal_simple_error ("Invalid value for 'final", value);
2232 else if (EQ (keyword, Qccl_program))
2234 CHECK_VECTOR (value);
2235 ccl_program = value;
2239 signal_simple_error ("Unrecognized property", keyword);
2243 error ("'final must be specified");
2244 if (dimension == 2 && final > 0x5F)
2246 ("Final must be in the range 0x30 - 0x5F for dimension == 2",
2250 type = (chars == 94) ? CHARSET_TYPE_94 : CHARSET_TYPE_96;
2252 type = (chars == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96;
2254 if (!NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_LEFT_TO_RIGHT)) ||
2255 !NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_RIGHT_TO_LEFT)))
2257 ("Character set already defined for this DIMENSION/CHARS/FINAL combo");
2259 id = get_unallocated_leading_byte (dimension);
2261 if (NILP (doc_string))
2262 doc_string = build_string ("");
2264 if (NILP (registry))
2265 registry = build_string ("");
2267 if (NILP (short_name))
2268 XSETSTRING (short_name, XSYMBOL (name)->name);
2270 if (NILP (long_name))
2271 long_name = doc_string;
2274 columns = dimension;
2276 if (byte_offset < 0)
2280 else if (chars == 96)
2286 charset = make_charset (id, name, chars, dimension, columns, graphic,
2287 final, direction, short_name, long_name,
2288 doc_string, registry,
2289 Qnil, 0, 0, 0, byte_offset);
2290 if (!NILP (ccl_program))
2291 XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2295 DEFUN ("make-reverse-direction-charset", Fmake_reverse_direction_charset,
2297 Make a charset equivalent to CHARSET but which goes in the opposite direction.
2298 NEW-NAME is the name of the new charset. Return the new charset.
2300 (charset, new_name))
2302 Lisp_Object new_charset = Qnil;
2303 int id, chars, dimension, columns, graphic, final;
2305 Lisp_Object registry, doc_string, short_name, long_name;
2308 charset = Fget_charset (charset);
2309 if (!NILP (XCHARSET_REVERSE_DIRECTION_CHARSET (charset)))
2310 signal_simple_error ("Charset already has reverse-direction charset",
2313 CHECK_SYMBOL (new_name);
2314 if (!NILP (Ffind_charset (new_name)))
2315 signal_simple_error ("Cannot redefine existing charset", new_name);
2317 cs = XCHARSET (charset);
2319 chars = CHARSET_CHARS (cs);
2320 dimension = CHARSET_DIMENSION (cs);
2321 columns = CHARSET_COLUMNS (cs);
2322 id = get_unallocated_leading_byte (dimension);
2324 graphic = CHARSET_GRAPHIC (cs);
2325 final = CHARSET_FINAL (cs);
2326 direction = CHARSET_RIGHT_TO_LEFT;
2327 if (CHARSET_DIRECTION (cs) == CHARSET_RIGHT_TO_LEFT)
2328 direction = CHARSET_LEFT_TO_RIGHT;
2329 doc_string = CHARSET_DOC_STRING (cs);
2330 short_name = CHARSET_SHORT_NAME (cs);
2331 long_name = CHARSET_LONG_NAME (cs);
2332 registry = CHARSET_REGISTRY (cs);
2334 new_charset = make_charset (id, new_name, chars, dimension, columns,
2335 graphic, final, direction, short_name, long_name,
2336 doc_string, registry,
2338 CHARSET_DECODING_TABLE(cs),
2339 CHARSET_UCS_MIN(cs),
2340 CHARSET_UCS_MAX(cs),
2341 CHARSET_CODE_OFFSET(cs),
2342 CHARSET_BYTE_OFFSET(cs)
2348 CHARSET_REVERSE_DIRECTION_CHARSET (cs) = new_charset;
2349 XCHARSET_REVERSE_DIRECTION_CHARSET (new_charset) = charset;
2354 DEFUN ("define-charset-alias", Fdefine_charset_alias, 2, 2, 0, /*
2355 Define symbol ALIAS as an alias for CHARSET.
2359 CHECK_SYMBOL (alias);
2360 charset = Fget_charset (charset);
2361 return Fputhash (alias, charset, Vcharset_hash_table);
2364 /* #### Reverse direction charsets not yet implemented. */
2366 DEFUN ("charset-reverse-direction-charset", Fcharset_reverse_direction_charset,
2368 Return the reverse-direction charset parallel to CHARSET, if any.
2369 This is the charset with the same properties (in particular, the same
2370 dimension, number of characters per dimension, and final byte) as
2371 CHARSET but whose characters are displayed in the opposite direction.
2375 charset = Fget_charset (charset);
2376 return XCHARSET_REVERSE_DIRECTION_CHARSET (charset);
2380 DEFUN ("charset-from-attributes", Fcharset_from_attributes, 3, 4, 0, /*
2381 Return a charset with the given DIMENSION, CHARS, FINAL, and DIRECTION.
2382 If DIRECTION is omitted, both directions will be checked (left-to-right
2383 will be returned if character sets exist for both directions).
2385 (dimension, chars, final, direction))
2387 int dm, ch, fi, di = -1;
2389 Lisp_Object obj = Qnil;
2391 CHECK_INT (dimension);
2392 dm = XINT (dimension);
2393 if (dm < 1 || dm > 2)
2394 signal_simple_error ("Invalid value for DIMENSION", dimension);
2398 if (ch != 94 && ch != 96)
2399 signal_simple_error ("Invalid value for CHARS", chars);
2401 CHECK_CHAR_COERCE_INT (final);
2403 if (fi < '0' || fi > '~')
2404 signal_simple_error ("Invalid value for FINAL", final);
2406 if (EQ (direction, Ql2r))
2407 di = CHARSET_LEFT_TO_RIGHT;
2408 else if (EQ (direction, Qr2l))
2409 di = CHARSET_RIGHT_TO_LEFT;
2410 else if (!NILP (direction))
2411 signal_simple_error ("Invalid value for DIRECTION", direction);
2413 if (dm == 2 && fi > 0x5F)
2415 ("Final must be in the range 0x30 - 0x5F for dimension == 2", final);
2418 type = (ch == 94) ? CHARSET_TYPE_94 : CHARSET_TYPE_96;
2420 type = (ch == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96;
2424 obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_LEFT_TO_RIGHT);
2426 obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_RIGHT_TO_LEFT);
2429 obj = CHARSET_BY_ATTRIBUTES (type, fi, di);
2432 return XCHARSET_NAME (obj);
2436 DEFUN ("charset-short-name", Fcharset_short_name, 1, 1, 0, /*
2437 Return short name of CHARSET.
2441 return XCHARSET_SHORT_NAME (Fget_charset (charset));
2444 DEFUN ("charset-long-name", Fcharset_long_name, 1, 1, 0, /*
2445 Return long name of CHARSET.
2449 return XCHARSET_LONG_NAME (Fget_charset (charset));
2452 DEFUN ("charset-description", Fcharset_description, 1, 1, 0, /*
2453 Return description of CHARSET.
2457 return XCHARSET_DOC_STRING (Fget_charset (charset));
2460 DEFUN ("charset-dimension", Fcharset_dimension, 1, 1, 0, /*
2461 Return dimension of CHARSET.
2465 return make_int (XCHARSET_DIMENSION (Fget_charset (charset)));
2468 DEFUN ("charset-property", Fcharset_property, 2, 2, 0, /*
2469 Return property PROP of CHARSET.
2470 Recognized properties are those listed in `make-charset', as well as
2471 'name and 'doc-string.
2477 charset = Fget_charset (charset);
2478 cs = XCHARSET (charset);
2480 CHECK_SYMBOL (prop);
2481 if (EQ (prop, Qname)) return CHARSET_NAME (cs);
2482 if (EQ (prop, Qshort_name)) return CHARSET_SHORT_NAME (cs);
2483 if (EQ (prop, Qlong_name)) return CHARSET_LONG_NAME (cs);
2484 if (EQ (prop, Qdoc_string)) return CHARSET_DOC_STRING (cs);
2485 if (EQ (prop, Qdimension)) return make_int (CHARSET_DIMENSION (cs));
2486 if (EQ (prop, Qcolumns)) return make_int (CHARSET_COLUMNS (cs));
2487 if (EQ (prop, Qgraphic)) return make_int (CHARSET_GRAPHIC (cs));
2488 if (EQ (prop, Qfinal)) return make_char (CHARSET_FINAL (cs));
2489 if (EQ (prop, Qchars)) return make_int (CHARSET_CHARS (cs));
2490 if (EQ (prop, Qregistry)) return CHARSET_REGISTRY (cs);
2491 if (EQ (prop, Qccl_program)) return CHARSET_CCL_PROGRAM (cs);
2492 if (EQ (prop, Qdirection))
2493 return CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? Ql2r : Qr2l;
2494 if (EQ (prop, Qreverse_direction_charset))
2496 Lisp_Object obj = CHARSET_REVERSE_DIRECTION_CHARSET (cs);
2500 return XCHARSET_NAME (obj);
2502 signal_simple_error ("Unrecognized charset property name", prop);
2503 return Qnil; /* not reached */
2506 DEFUN ("charset-id", Fcharset_id, 1, 1, 0, /*
2507 Return charset identification number of CHARSET.
2511 return make_int(XCHARSET_LEADING_BYTE (Fget_charset (charset)));
2514 /* #### We need to figure out which properties we really want to
2517 DEFUN ("set-charset-ccl-program", Fset_charset_ccl_program, 2, 2, 0, /*
2518 Set the 'ccl-program property of CHARSET to CCL-PROGRAM.
2520 (charset, ccl_program))
2522 charset = Fget_charset (charset);
2523 CHECK_VECTOR (ccl_program);
2524 XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2529 invalidate_charset_font_caches (Lisp_Object charset)
2531 /* Invalidate font cache entries for charset on all devices. */
2532 Lisp_Object devcons, concons, hash_table;
2533 DEVICE_LOOP_NO_BREAK (devcons, concons)
2535 struct device *d = XDEVICE (XCAR (devcons));
2536 hash_table = Fgethash (charset, d->charset_font_cache, Qunbound);
2537 if (!UNBOUNDP (hash_table))
2538 Fclrhash (hash_table);
2542 DEFUN ("set-charset-registry", Fset_charset_registry, 2, 2, 0, /*
2543 Set the 'registry property of CHARSET to REGISTRY.
2545 (charset, registry))
2547 charset = Fget_charset (charset);
2548 CHECK_STRING (registry);
2549 XCHARSET_REGISTRY (charset) = registry;
2550 invalidate_charset_font_caches (charset);
2551 face_property_was_changed (Vdefault_face, Qfont, Qglobal);
2556 DEFUN ("charset-mapping-table", Fcharset_mapping_table, 1, 1, 0, /*
2557 Return mapping-table of CHARSET.
2561 return XCHARSET_DECODING_TABLE (Fget_charset (charset));
2564 DEFUN ("set-charset-mapping-table", Fset_charset_mapping_table, 2, 2, 0, /*
2565 Set mapping-table of CHARSET to TABLE.
2569 struct Lisp_Charset *cs;
2573 charset = Fget_charset (charset);
2574 cs = XCHARSET (charset);
2578 CHARSET_DECODING_TABLE(cs) = Qnil;
2581 else if (VECTORP (table))
2583 int ccs_len = CHARSET_BYTE_SIZE (cs);
2584 int ret = decoding_table_check_elements (table,
2585 CHARSET_DIMENSION (cs),
2590 signal_simple_error ("Too big table", table);
2592 signal_simple_error ("Invalid element is found", table);
2594 signal_simple_error ("Something wrong", table);
2596 CHARSET_DECODING_TABLE(cs) = Qnil;
2599 signal_error (Qwrong_type_argument,
2600 list2 (build_translated_string ("vector-or-nil-p"),
2603 byte_offset = CHARSET_BYTE_OFFSET (cs);
2604 switch (CHARSET_DIMENSION (cs))
2607 for (i = 0; i < XVECTOR_LENGTH (table); i++)
2609 Lisp_Object c = XVECTOR_DATA(table)[i];
2612 put_char_ccs_code_point (c, charset,
2613 make_int (i + byte_offset));
2617 for (i = 0; i < XVECTOR_LENGTH (table); i++)
2619 Lisp_Object v = XVECTOR_DATA(table)[i];
2625 for (j = 0; j < XVECTOR_LENGTH (v); j++)
2627 Lisp_Object c = XVECTOR_DATA(v)[j];
2630 put_char_ccs_code_point
2632 make_int ( ( (i + byte_offset) << 8 )
2638 put_char_ccs_code_point (v, charset,
2639 make_int (i + byte_offset));
2648 /************************************************************************/
2649 /* Lisp primitives for working with characters */
2650 /************************************************************************/
2653 DEFUN ("decode-char", Fdecode_char, 2, 2, 0, /*
2654 Make a character from CHARSET and code-point CODE.
2660 charset = Fget_charset (charset);
2663 if (XCHARSET_GRAPHIC (charset) == 1)
2665 return make_char (DECODE_CHAR (charset, c));
2669 DEFUN ("make-char", Fmake_char, 2, 3, 0, /*
2670 Make a character from CHARSET and octets ARG1 and ARG2.
2671 ARG2 is required only for characters from two-dimensional charsets.
2672 For example, (make-char 'latin-iso8859-2 185) will return the Latin 2
2673 character s with caron.
2675 (charset, arg1, arg2))
2679 int lowlim, highlim;
2681 charset = Fget_charset (charset);
2682 cs = XCHARSET (charset);
2684 if (EQ (charset, Vcharset_ascii)) lowlim = 0, highlim = 127;
2685 else if (EQ (charset, Vcharset_control_1)) lowlim = 0, highlim = 31;
2687 else if (CHARSET_CHARS (cs) == 256) lowlim = 0, highlim = 255;
2689 else if (CHARSET_CHARS (cs) == 94) lowlim = 33, highlim = 126;
2690 else /* CHARSET_CHARS (cs) == 96) */ lowlim = 32, highlim = 127;
2693 /* It is useful (and safe, according to Olivier Galibert) to strip
2694 the 8th bit off ARG1 and ARG2 becaue it allows programmers to
2695 write (make-char 'latin-iso8859-2 CODE) where code is the actual
2696 Latin 2 code of the character. */
2704 if (a1 < lowlim || a1 > highlim)
2705 args_out_of_range_3 (arg1, make_int (lowlim), make_int (highlim));
2707 if (CHARSET_DIMENSION (cs) == 1)
2711 ("Charset is of dimension one; second octet must be nil", arg2);
2712 return make_char (MAKE_CHAR (charset, a1, 0));
2721 a2 = XINT (arg2) & 0x7f;
2723 if (a2 < lowlim || a2 > highlim)
2724 args_out_of_range_3 (arg2, make_int (lowlim), make_int (highlim));
2726 return make_char (MAKE_CHAR (charset, a1, a2));
2729 DEFUN ("char-charset", Fchar_charset, 1, 1, 0, /*
2730 Return the character set of char CH.
2734 CHECK_CHAR_COERCE_INT (ch);
2736 return XCHARSET_NAME (CHAR_CHARSET (XCHAR (ch)));
2739 DEFUN ("char-octet", Fchar_octet, 1, 2, 0, /*
2740 Return the octet numbered N (should be 0 or 1) of char CH.
2741 N defaults to 0 if omitted.
2745 Lisp_Object charset;
2748 CHECK_CHAR_COERCE_INT (ch);
2750 BREAKUP_CHAR (XCHAR (ch), charset, octet0, octet1);
2752 if (NILP (n) || EQ (n, Qzero))
2753 return make_int (octet0);
2754 else if (EQ (n, make_int (1)))
2755 return make_int (octet1);
2757 signal_simple_error ("Octet number must be 0 or 1", n);
2760 DEFUN ("split-char", Fsplit_char, 1, 1, 0, /*
2761 Return list of charset and one or two position-codes of CHAR.
2765 /* This function can GC */
2766 struct gcpro gcpro1, gcpro2;
2767 Lisp_Object charset = Qnil;
2768 Lisp_Object rc = Qnil;
2776 GCPRO2 (charset, rc);
2777 CHECK_CHAR_COERCE_INT (character);
2780 code_point = ENCODE_CHAR (XCHAR (character), charset);
2781 dimension = XCHARSET_DIMENSION (charset);
2782 while (dimension > 0)
2784 rc = Fcons (make_int (code_point & 255), rc);
2788 rc = Fcons (XCHARSET_NAME (charset), rc);
2790 BREAKUP_CHAR (XCHAR (character), charset, c1, c2);
2792 if (XCHARSET_DIMENSION (Fget_charset (charset)) == 2)
2794 rc = list3 (XCHARSET_NAME (charset), make_int (c1), make_int (c2));
2798 rc = list2 (XCHARSET_NAME (charset), make_int (c1));
2807 #ifdef ENABLE_COMPOSITE_CHARS
2808 /************************************************************************/
2809 /* composite character functions */
2810 /************************************************************************/
2813 lookup_composite_char (Bufbyte *str, int len)
2815 Lisp_Object lispstr = make_string (str, len);
2816 Lisp_Object ch = Fgethash (lispstr,
2817 Vcomposite_char_string2char_hash_table,
2823 if (composite_char_row_next >= 128)
2824 signal_simple_error ("No more composite chars available", lispstr);
2825 emch = MAKE_CHAR (Vcharset_composite, composite_char_row_next,
2826 composite_char_col_next);
2827 Fputhash (make_char (emch), lispstr,
2828 Vcomposite_char_char2string_hash_table);
2829 Fputhash (lispstr, make_char (emch),
2830 Vcomposite_char_string2char_hash_table);
2831 composite_char_col_next++;
2832 if (composite_char_col_next >= 128)
2834 composite_char_col_next = 32;
2835 composite_char_row_next++;
2844 composite_char_string (Emchar ch)
2846 Lisp_Object str = Fgethash (make_char (ch),
2847 Vcomposite_char_char2string_hash_table,
2849 assert (!UNBOUNDP (str));
2853 xxDEFUN ("make-composite-char", Fmake_composite_char, 1, 1, 0, /*
2854 Convert a string into a single composite character.
2855 The character is the result of overstriking all the characters in
2860 CHECK_STRING (string);
2861 return make_char (lookup_composite_char (XSTRING_DATA (string),
2862 XSTRING_LENGTH (string)));
2865 xxDEFUN ("composite-char-string", Fcomposite_char_string, 1, 1, 0, /*
2866 Return a string of the characters comprising a composite character.
2874 if (CHAR_LEADING_BYTE (emch) != LEADING_BYTE_COMPOSITE)
2875 signal_simple_error ("Must be composite char", ch);
2876 return composite_char_string (emch);
2878 #endif /* ENABLE_COMPOSITE_CHARS */
2881 /************************************************************************/
2882 /* initialization */
2883 /************************************************************************/
2886 syms_of_mule_charset (void)
2889 INIT_LRECORD_IMPLEMENTATION (byte_table);
2890 INIT_LRECORD_IMPLEMENTATION (char_id_table);
2892 INIT_LRECORD_IMPLEMENTATION (charset);
2894 DEFSUBR (Fcharsetp);
2895 DEFSUBR (Ffind_charset);
2896 DEFSUBR (Fget_charset);
2897 DEFSUBR (Fcharset_list);
2898 DEFSUBR (Fcharset_name);
2899 DEFSUBR (Fmake_charset);
2900 DEFSUBR (Fmake_reverse_direction_charset);
2901 /* DEFSUBR (Freverse_direction_charset); */
2902 DEFSUBR (Fdefine_charset_alias);
2903 DEFSUBR (Fcharset_from_attributes);
2904 DEFSUBR (Fcharset_short_name);
2905 DEFSUBR (Fcharset_long_name);
2906 DEFSUBR (Fcharset_description);
2907 DEFSUBR (Fcharset_dimension);
2908 DEFSUBR (Fcharset_property);
2909 DEFSUBR (Fcharset_id);
2910 DEFSUBR (Fset_charset_ccl_program);
2911 DEFSUBR (Fset_charset_registry);
2913 DEFSUBR (Fchar_attribute_alist);
2914 DEFSUBR (Fget_char_attribute);
2915 DEFSUBR (Fput_char_attribute);
2916 DEFSUBR (Fremove_char_attribute);
2917 DEFSUBR (Fdefine_char);
2918 DEFSUBR (Fchar_variants);
2919 DEFSUBR (Fget_composite_char);
2920 DEFSUBR (Fcharset_mapping_table);
2921 DEFSUBR (Fset_charset_mapping_table);
2925 DEFSUBR (Fdecode_char);
2927 DEFSUBR (Fmake_char);
2928 DEFSUBR (Fchar_charset);
2929 DEFSUBR (Fchar_octet);
2930 DEFSUBR (Fsplit_char);
2932 #ifdef ENABLE_COMPOSITE_CHARS
2933 DEFSUBR (Fmake_composite_char);
2934 DEFSUBR (Fcomposite_char_string);
2937 defsymbol (&Qcharsetp, "charsetp");
2938 defsymbol (&Qregistry, "registry");
2939 defsymbol (&Qfinal, "final");
2940 defsymbol (&Qgraphic, "graphic");
2941 defsymbol (&Qdirection, "direction");
2942 defsymbol (&Qreverse_direction_charset, "reverse-direction-charset");
2943 defsymbol (&Qshort_name, "short-name");
2944 defsymbol (&Qlong_name, "long-name");
2946 defsymbol (&Ql2r, "l2r");
2947 defsymbol (&Qr2l, "r2l");
2949 /* Charsets, compatible with FSF 20.3
2950 Naming convention is Script-Charset[-Edition] */
2951 defsymbol (&Qascii, "ascii");
2952 defsymbol (&Qcontrol_1, "control-1");
2953 defsymbol (&Qlatin_iso8859_1, "latin-iso8859-1");
2954 defsymbol (&Qlatin_iso8859_2, "latin-iso8859-2");
2955 defsymbol (&Qlatin_iso8859_3, "latin-iso8859-3");
2956 defsymbol (&Qlatin_iso8859_4, "latin-iso8859-4");
2957 defsymbol (&Qthai_tis620, "thai-tis620");
2958 defsymbol (&Qgreek_iso8859_7, "greek-iso8859-7");
2959 defsymbol (&Qarabic_iso8859_6, "arabic-iso8859-6");
2960 defsymbol (&Qhebrew_iso8859_8, "hebrew-iso8859-8");
2961 defsymbol (&Qkatakana_jisx0201, "katakana-jisx0201");
2962 defsymbol (&Qlatin_jisx0201, "latin-jisx0201");
2963 defsymbol (&Qcyrillic_iso8859_5, "cyrillic-iso8859-5");
2964 defsymbol (&Qlatin_iso8859_9, "latin-iso8859-9");
2965 defsymbol (&Qjapanese_jisx0208_1978, "japanese-jisx0208-1978");
2966 defsymbol (&Qchinese_gb2312, "chinese-gb2312");
2967 defsymbol (&Qjapanese_jisx0208, "japanese-jisx0208");
2968 defsymbol (&Qjapanese_jisx0208_1990, "japanese-jisx0208-1990");
2969 defsymbol (&Qkorean_ksc5601, "korean-ksc5601");
2970 defsymbol (&Qjapanese_jisx0212, "japanese-jisx0212");
2971 defsymbol (&Qchinese_cns11643_1, "chinese-cns11643-1");
2972 defsymbol (&Qchinese_cns11643_2, "chinese-cns11643-2");
2974 defsymbol (&Qname, "name");
2975 defsymbol (&Q_ucs, "->ucs");
2976 defsymbol (&Q_decomposition, "->decomposition");
2977 defsymbol (&Qcompat, "compat");
2978 defsymbol (&Qisolated, "isolated");
2979 defsymbol (&Qinitial, "initial");
2980 defsymbol (&Qmedial, "medial");
2981 defsymbol (&Qfinal, "final");
2982 defsymbol (&Qvertical, "vertical");
2983 defsymbol (&QnoBreak, "noBreak");
2984 defsymbol (&Qfraction, "fraction");
2985 defsymbol (&Qsuper, "super");
2986 defsymbol (&Qsub, "sub");
2987 defsymbol (&Qcircle, "circle");
2988 defsymbol (&Qsquare, "square");
2989 defsymbol (&Qwide, "wide");
2990 defsymbol (&Qnarrow, "narrow");
2991 defsymbol (&Qsmall, "small");
2992 defsymbol (&Qfont, "font");
2993 defsymbol (&Qucs, "ucs");
2994 defsymbol (&Qucs_bmp, "ucs-bmp");
2995 defsymbol (&Qlatin_viscii, "latin-viscii");
2996 defsymbol (&Qlatin_tcvn5712, "latin-tcvn5712");
2997 defsymbol (&Qlatin_viscii_lower, "latin-viscii-lower");
2998 defsymbol (&Qlatin_viscii_upper, "latin-viscii-upper");
2999 defsymbol (&Qvietnamese_viscii_lower, "vietnamese-viscii-lower");
3000 defsymbol (&Qvietnamese_viscii_upper, "vietnamese-viscii-upper");
3001 defsymbol (&Qideograph_daikanwa, "ideograph-daikanwa");
3002 defsymbol (&Qmojikyo, "mojikyo");
3003 defsymbol (&Qmojikyo_pj_1, "mojikyo-pj-1");
3004 defsymbol (&Qmojikyo_pj_2, "mojikyo-pj-2");
3005 defsymbol (&Qmojikyo_pj_3, "mojikyo-pj-3");
3006 defsymbol (&Qmojikyo_pj_4, "mojikyo-pj-4");
3007 defsymbol (&Qmojikyo_pj_5, "mojikyo-pj-5");
3008 defsymbol (&Qmojikyo_pj_6, "mojikyo-pj-6");
3009 defsymbol (&Qmojikyo_pj_7, "mojikyo-pj-7");
3010 defsymbol (&Qmojikyo_pj_8, "mojikyo-pj-8");
3011 defsymbol (&Qmojikyo_pj_9, "mojikyo-pj-9");
3012 defsymbol (&Qmojikyo_pj_10, "mojikyo-pj-10");
3013 defsymbol (&Qmojikyo_pj_11, "mojikyo-pj-11");
3014 defsymbol (&Qmojikyo_pj_12, "mojikyo-pj-12");
3015 defsymbol (&Qmojikyo_pj_13, "mojikyo-pj-13");
3016 defsymbol (&Qmojikyo_pj_14, "mojikyo-pj-14");
3017 defsymbol (&Qmojikyo_pj_15, "mojikyo-pj-15");
3018 defsymbol (&Qmojikyo_pj_16, "mojikyo-pj-16");
3019 defsymbol (&Qmojikyo_pj_17, "mojikyo-pj-17");
3020 defsymbol (&Qmojikyo_pj_18, "mojikyo-pj-18");
3021 defsymbol (&Qmojikyo_pj_19, "mojikyo-pj-19");
3022 defsymbol (&Qmojikyo_pj_20, "mojikyo-pj-20");
3023 defsymbol (&Qmojikyo_pj_21, "mojikyo-pj-21");
3024 defsymbol (&Qethiopic_ucs, "ethiopic-ucs");
3026 defsymbol (&Qchinese_big5_1, "chinese-big5-1");
3027 defsymbol (&Qchinese_big5_2, "chinese-big5-2");
3029 defsymbol (&Qcomposite, "composite");
3033 vars_of_mule_charset (void)
3040 chlook = xnew (struct charset_lookup);
3041 dumpstruct (&chlook, &charset_lookup_description);
3043 /* Table of charsets indexed by leading byte. */
3044 for (i = 0; i < countof (chlook->charset_by_leading_byte); i++)
3045 chlook->charset_by_leading_byte[i] = Qnil;
3048 /* Table of charsets indexed by type/final-byte. */
3049 for (i = 0; i < countof (chlook->charset_by_attributes); i++)
3050 for (j = 0; j < countof (chlook->charset_by_attributes[0]); j++)
3051 chlook->charset_by_attributes[i][j] = Qnil;
3053 /* Table of charsets indexed by type/final-byte/direction. */
3054 for (i = 0; i < countof (chlook->charset_by_attributes); i++)
3055 for (j = 0; j < countof (chlook->charset_by_attributes[0]); j++)
3056 for (k = 0; k < countof (chlook->charset_by_attributes[0][0]); k++)
3057 chlook->charset_by_attributes[i][j][k] = Qnil;
3061 chlook->next_allocated_leading_byte = MIN_LEADING_BYTE_PRIVATE;
3063 chlook->next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1;
3064 chlook->next_allocated_2_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_2;
3068 leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
3069 DEFVAR_INT ("leading-code-private-11", &leading_code_private_11 /*
3070 Leading-code of private TYPE9N charset of column-width 1.
3072 leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
3076 Vutf_2000_version = build_string("0.15 (Sangō)");
3077 DEFVAR_LISP ("utf-2000-version", &Vutf_2000_version /*
3078 Version number of UTF-2000.
3081 staticpro (&Vcharacter_attribute_table);
3082 Vcharacter_attribute_table = make_char_id_table (Qnil, 0);
3084 staticpro (&Vcharacter_name_table);
3085 Vcharacter_name_table = make_char_id_table (Qnil, 0);
3087 /* staticpro (&Vcharacter_decomposition_table); */
3088 Vcharacter_decomposition_table = make_char_id_table (Qnil, -1);
3090 /* staticpro (&Vcharacter_composition_table); */
3091 Vcharacter_composition_table = make_char_id_table (Qnil, -1);
3093 staticpro (&Vcharacter_variant_table);
3094 Vcharacter_variant_table = make_char_id_table (Qnil, 0);
3096 Vdefault_coded_charset_priority_list = Qnil;
3097 DEFVAR_LISP ("default-coded-charset-priority-list",
3098 &Vdefault_coded_charset_priority_list /*
3099 Default order of preferred coded-character-sets.
3105 complex_vars_of_mule_charset (void)
3107 staticpro (&Vcharset_hash_table);
3108 Vcharset_hash_table =
3109 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3111 /* Predefined character sets. We store them into variables for
3115 staticpro (&Vcharset_ucs);
3117 make_charset (LEADING_BYTE_UCS, Qucs, 256, 4,
3118 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3119 build_string ("UCS"),
3120 build_string ("UCS"),
3121 build_string ("ISO/IEC 10646"),
3123 Qnil, 0, 0xFFFFFFF, 0, 0);
3124 staticpro (&Vcharset_ucs_bmp);
3126 make_charset (LEADING_BYTE_UCS_BMP, Qucs_bmp, 256, 2,
3127 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3128 build_string ("BMP"),
3129 build_string ("BMP"),
3130 build_string ("ISO/IEC 10646 Group 0 Plane 0 (BMP)"),
3131 build_string ("\\(ISO10646.*-1\\|UNICODE[23]?-0\\)"),
3132 Qnil, 0, 0xFFFF, 0, 0);
3134 # define MIN_CHAR_THAI 0
3135 # define MAX_CHAR_THAI 0
3136 # define MIN_CHAR_HEBREW 0
3137 # define MAX_CHAR_HEBREW 0
3138 # define MIN_CHAR_HALFWIDTH_KATAKANA 0
3139 # define MAX_CHAR_HALFWIDTH_KATAKANA 0
3141 staticpro (&Vcharset_ascii);
3143 make_charset (LEADING_BYTE_ASCII, Qascii, 94, 1,
3144 1, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3145 build_string ("ASCII"),
3146 build_string ("ASCII)"),
3147 build_string ("ASCII (ISO646 IRV)"),
3148 build_string ("\\(iso8859-[0-9]*\\|-ascii\\)"),
3149 Qnil, 0, 0x7F, 0, 0);
3150 staticpro (&Vcharset_control_1);
3151 Vcharset_control_1 =
3152 make_charset (LEADING_BYTE_CONTROL_1, Qcontrol_1, 94, 1,
3153 1, 1, 0, CHARSET_LEFT_TO_RIGHT,
3154 build_string ("C1"),
3155 build_string ("Control characters"),
3156 build_string ("Control characters 128-191"),
3158 Qnil, 0x80, 0x9F, 0, 0);
3159 staticpro (&Vcharset_latin_iso8859_1);
3160 Vcharset_latin_iso8859_1 =
3161 make_charset (LEADING_BYTE_LATIN_ISO8859_1, Qlatin_iso8859_1, 96, 1,
3162 1, 1, 'A', CHARSET_LEFT_TO_RIGHT,
3163 build_string ("Latin-1"),
3164 build_string ("ISO8859-1 (Latin-1)"),
3165 build_string ("ISO8859-1 (Latin-1)"),
3166 build_string ("iso8859-1"),
3167 Qnil, 0xA0, 0xFF, 0, 32);
3168 staticpro (&Vcharset_latin_iso8859_2);
3169 Vcharset_latin_iso8859_2 =
3170 make_charset (LEADING_BYTE_LATIN_ISO8859_2, Qlatin_iso8859_2, 96, 1,
3171 1, 1, 'B', CHARSET_LEFT_TO_RIGHT,
3172 build_string ("Latin-2"),
3173 build_string ("ISO8859-2 (Latin-2)"),
3174 build_string ("ISO8859-2 (Latin-2)"),
3175 build_string ("iso8859-2"),
3177 staticpro (&Vcharset_latin_iso8859_3);
3178 Vcharset_latin_iso8859_3 =
3179 make_charset (LEADING_BYTE_LATIN_ISO8859_3, Qlatin_iso8859_3, 96, 1,
3180 1, 1, 'C', CHARSET_LEFT_TO_RIGHT,
3181 build_string ("Latin-3"),
3182 build_string ("ISO8859-3 (Latin-3)"),
3183 build_string ("ISO8859-3 (Latin-3)"),
3184 build_string ("iso8859-3"),
3186 staticpro (&Vcharset_latin_iso8859_4);
3187 Vcharset_latin_iso8859_4 =
3188 make_charset (LEADING_BYTE_LATIN_ISO8859_4, Qlatin_iso8859_4, 96, 1,
3189 1, 1, 'D', CHARSET_LEFT_TO_RIGHT,
3190 build_string ("Latin-4"),
3191 build_string ("ISO8859-4 (Latin-4)"),
3192 build_string ("ISO8859-4 (Latin-4)"),
3193 build_string ("iso8859-4"),
3195 staticpro (&Vcharset_thai_tis620);
3196 Vcharset_thai_tis620 =
3197 make_charset (LEADING_BYTE_THAI_TIS620, Qthai_tis620, 96, 1,
3198 1, 1, 'T', CHARSET_LEFT_TO_RIGHT,
3199 build_string ("TIS620"),
3200 build_string ("TIS620 (Thai)"),
3201 build_string ("TIS620.2529 (Thai)"),
3202 build_string ("tis620"),
3203 Qnil, MIN_CHAR_THAI, MAX_CHAR_THAI, 0, 32);
3204 staticpro (&Vcharset_greek_iso8859_7);
3205 Vcharset_greek_iso8859_7 =
3206 make_charset (LEADING_BYTE_GREEK_ISO8859_7, Qgreek_iso8859_7, 96, 1,
3207 1, 1, 'F', CHARSET_LEFT_TO_RIGHT,
3208 build_string ("ISO8859-7"),
3209 build_string ("ISO8859-7 (Greek)"),
3210 build_string ("ISO8859-7 (Greek)"),
3211 build_string ("iso8859-7"),
3213 0 /* MIN_CHAR_GREEK */,
3214 0 /* MAX_CHAR_GREEK */, 0, 32);
3215 staticpro (&Vcharset_arabic_iso8859_6);
3216 Vcharset_arabic_iso8859_6 =
3217 make_charset (LEADING_BYTE_ARABIC_ISO8859_6, Qarabic_iso8859_6, 96, 1,
3218 1, 1, 'G', CHARSET_RIGHT_TO_LEFT,
3219 build_string ("ISO8859-6"),
3220 build_string ("ISO8859-6 (Arabic)"),
3221 build_string ("ISO8859-6 (Arabic)"),
3222 build_string ("iso8859-6"),
3224 staticpro (&Vcharset_hebrew_iso8859_8);
3225 Vcharset_hebrew_iso8859_8 =
3226 make_charset (LEADING_BYTE_HEBREW_ISO8859_8, Qhebrew_iso8859_8, 96, 1,
3227 1, 1, 'H', CHARSET_RIGHT_TO_LEFT,
3228 build_string ("ISO8859-8"),
3229 build_string ("ISO8859-8 (Hebrew)"),
3230 build_string ("ISO8859-8 (Hebrew)"),
3231 build_string ("iso8859-8"),
3232 Qnil, MIN_CHAR_HEBREW, MAX_CHAR_HEBREW, 0, 32);
3233 staticpro (&Vcharset_katakana_jisx0201);
3234 Vcharset_katakana_jisx0201 =
3235 make_charset (LEADING_BYTE_KATAKANA_JISX0201, Qkatakana_jisx0201, 94, 1,
3236 1, 1, 'I', CHARSET_LEFT_TO_RIGHT,
3237 build_string ("JISX0201 Kana"),
3238 build_string ("JISX0201.1976 (Japanese Kana)"),
3239 build_string ("JISX0201.1976 Japanese Kana"),
3240 build_string ("jisx0201\\.1976"),
3242 staticpro (&Vcharset_latin_jisx0201);
3243 Vcharset_latin_jisx0201 =
3244 make_charset (LEADING_BYTE_LATIN_JISX0201, Qlatin_jisx0201, 94, 1,
3245 1, 0, 'J', CHARSET_LEFT_TO_RIGHT,
3246 build_string ("JISX0201 Roman"),
3247 build_string ("JISX0201.1976 (Japanese Roman)"),
3248 build_string ("JISX0201.1976 Japanese Roman"),
3249 build_string ("jisx0201\\.1976"),
3251 staticpro (&Vcharset_cyrillic_iso8859_5);
3252 Vcharset_cyrillic_iso8859_5 =
3253 make_charset (LEADING_BYTE_CYRILLIC_ISO8859_5, Qcyrillic_iso8859_5, 96, 1,
3254 1, 1, 'L', CHARSET_LEFT_TO_RIGHT,
3255 build_string ("ISO8859-5"),
3256 build_string ("ISO8859-5 (Cyrillic)"),
3257 build_string ("ISO8859-5 (Cyrillic)"),
3258 build_string ("iso8859-5"),
3260 0 /* MIN_CHAR_CYRILLIC */,
3261 0 /* MAX_CHAR_CYRILLIC */, 0, 32);
3262 staticpro (&Vcharset_latin_iso8859_9);
3263 Vcharset_latin_iso8859_9 =
3264 make_charset (LEADING_BYTE_LATIN_ISO8859_9, Qlatin_iso8859_9, 96, 1,
3265 1, 1, 'M', CHARSET_LEFT_TO_RIGHT,
3266 build_string ("Latin-5"),
3267 build_string ("ISO8859-9 (Latin-5)"),
3268 build_string ("ISO8859-9 (Latin-5)"),
3269 build_string ("iso8859-9"),
3271 staticpro (&Vcharset_japanese_jisx0208_1978);
3272 Vcharset_japanese_jisx0208_1978 =
3273 make_charset (LEADING_BYTE_JAPANESE_JISX0208_1978,
3274 Qjapanese_jisx0208_1978, 94, 2,
3275 2, 0, '@', CHARSET_LEFT_TO_RIGHT,
3276 build_string ("JIS X0208:1978"),
3277 build_string ("JIS X0208:1978 (Japanese)"),
3279 ("JIS X0208:1978 Japanese Kanji (so called \"old JIS\")"),
3280 build_string ("\\(jisx0208\\|jisc6226\\)\\.1978"),
3282 staticpro (&Vcharset_chinese_gb2312);
3283 Vcharset_chinese_gb2312 =
3284 make_charset (LEADING_BYTE_CHINESE_GB2312, Qchinese_gb2312, 94, 2,
3285 2, 0, 'A', CHARSET_LEFT_TO_RIGHT,
3286 build_string ("GB2312"),
3287 build_string ("GB2312)"),
3288 build_string ("GB2312 Chinese simplified"),
3289 build_string ("gb2312"),
3291 staticpro (&Vcharset_japanese_jisx0208);
3292 Vcharset_japanese_jisx0208 =
3293 make_charset (LEADING_BYTE_JAPANESE_JISX0208, Qjapanese_jisx0208, 94, 2,
3294 2, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3295 build_string ("JISX0208"),
3296 build_string ("JIS X0208:1983 (Japanese)"),
3297 build_string ("JIS X0208:1983 Japanese Kanji"),
3298 build_string ("jisx0208\\.1983"),
3301 staticpro (&Vcharset_japanese_jisx0208_1990);
3302 Vcharset_japanese_jisx0208_1990 =
3303 make_charset (LEADING_BYTE_JAPANESE_JISX0208_1990,
3304 Qjapanese_jisx0208_1990, 94, 2,
3305 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3306 build_string ("JISX0208-1990"),
3307 build_string ("JIS X0208:1990 (Japanese)"),
3308 build_string ("JIS X0208:1990 Japanese Kanji"),
3309 build_string ("jisx0208\\.1990"),
3311 MIN_CHAR_JIS_X0208_1990,
3312 MAX_CHAR_JIS_X0208_1990, 0, 33);
3314 staticpro (&Vcharset_korean_ksc5601);
3315 Vcharset_korean_ksc5601 =
3316 make_charset (LEADING_BYTE_KOREAN_KSC5601, Qkorean_ksc5601, 94, 2,
3317 2, 0, 'C', CHARSET_LEFT_TO_RIGHT,
3318 build_string ("KSC5601"),
3319 build_string ("KSC5601 (Korean"),
3320 build_string ("KSC5601 Korean Hangul and Hanja"),
3321 build_string ("ksc5601"),
3323 staticpro (&Vcharset_japanese_jisx0212);
3324 Vcharset_japanese_jisx0212 =
3325 make_charset (LEADING_BYTE_JAPANESE_JISX0212, Qjapanese_jisx0212, 94, 2,
3326 2, 0, 'D', CHARSET_LEFT_TO_RIGHT,
3327 build_string ("JISX0212"),
3328 build_string ("JISX0212 (Japanese)"),
3329 build_string ("JISX0212 Japanese Supplement"),
3330 build_string ("jisx0212"),
3333 #define CHINESE_CNS_PLANE_RE(n) "cns11643[.-]\\(.*[.-]\\)?" n "$"
3334 staticpro (&Vcharset_chinese_cns11643_1);
3335 Vcharset_chinese_cns11643_1 =
3336 make_charset (LEADING_BYTE_CHINESE_CNS11643_1, Qchinese_cns11643_1, 94, 2,
3337 2, 0, 'G', CHARSET_LEFT_TO_RIGHT,
3338 build_string ("CNS11643-1"),
3339 build_string ("CNS11643-1 (Chinese traditional)"),
3341 ("CNS 11643 Plane 1 Chinese traditional"),
3342 build_string (CHINESE_CNS_PLANE_RE("1")),
3344 staticpro (&Vcharset_chinese_cns11643_2);
3345 Vcharset_chinese_cns11643_2 =
3346 make_charset (LEADING_BYTE_CHINESE_CNS11643_2, Qchinese_cns11643_2, 94, 2,
3347 2, 0, 'H', CHARSET_LEFT_TO_RIGHT,
3348 build_string ("CNS11643-2"),
3349 build_string ("CNS11643-2 (Chinese traditional)"),
3351 ("CNS 11643 Plane 2 Chinese traditional"),
3352 build_string (CHINESE_CNS_PLANE_RE("2")),
3355 staticpro (&Vcharset_latin_tcvn5712);
3356 Vcharset_latin_tcvn5712 =
3357 make_charset (LEADING_BYTE_LATIN_TCVN5712, Qlatin_tcvn5712, 96, 1,
3358 1, 1, 'Z', CHARSET_LEFT_TO_RIGHT,
3359 build_string ("TCVN 5712"),
3360 build_string ("TCVN 5712 (VSCII-2)"),
3361 build_string ("Vietnamese TCVN 5712:1983 (VSCII-2)"),
3362 build_string ("tcvn5712-1"),
3364 staticpro (&Vcharset_latin_viscii_lower);
3365 Vcharset_latin_viscii_lower =
3366 make_charset (LEADING_BYTE_LATIN_VISCII_LOWER, Qlatin_viscii_lower, 96, 1,
3367 1, 1, '1', CHARSET_LEFT_TO_RIGHT,
3368 build_string ("VISCII lower"),
3369 build_string ("VISCII lower (Vietnamese)"),
3370 build_string ("VISCII lower (Vietnamese)"),
3371 build_string ("MULEVISCII-LOWER"),
3373 staticpro (&Vcharset_latin_viscii_upper);
3374 Vcharset_latin_viscii_upper =
3375 make_charset (LEADING_BYTE_LATIN_VISCII_UPPER, Qlatin_viscii_upper, 96, 1,
3376 1, 1, '2', CHARSET_LEFT_TO_RIGHT,
3377 build_string ("VISCII upper"),
3378 build_string ("VISCII upper (Vietnamese)"),
3379 build_string ("VISCII upper (Vietnamese)"),
3380 build_string ("MULEVISCII-UPPER"),
3382 staticpro (&Vcharset_latin_viscii);
3383 Vcharset_latin_viscii =
3384 make_charset (LEADING_BYTE_LATIN_VISCII, Qlatin_viscii, 256, 1,
3385 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3386 build_string ("VISCII"),
3387 build_string ("VISCII 1.1 (Vietnamese)"),
3388 build_string ("VISCII 1.1 (Vietnamese)"),
3389 build_string ("VISCII1\\.1"),
3391 staticpro (&Vcharset_ideograph_daikanwa);
3392 Vcharset_ideograph_daikanwa =
3393 make_charset (LEADING_BYTE_DAIKANWA, Qideograph_daikanwa, 256, 2,
3394 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3395 build_string ("Daikanwa"),
3396 build_string ("Morohashi's Daikanwa"),
3397 build_string ("Daikanwa dictionary by MOROHASHI Tetsuji"),
3398 build_string ("Daikanwa"),
3399 Qnil, MIN_CHAR_DAIKANWA, MAX_CHAR_DAIKANWA, 0, 0);
3400 staticpro (&Vcharset_mojikyo);
3402 make_charset (LEADING_BYTE_MOJIKYO, Qmojikyo, 256, 3,
3403 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3404 build_string ("Mojikyo"),
3405 build_string ("Mojikyo"),
3406 build_string ("Konjaku-Mojikyo"),
3408 Qnil, MIN_CHAR_MOJIKYO, MAX_CHAR_MOJIKYO, 0, 0);
3409 staticpro (&Vcharset_mojikyo_pj_1);
3410 Vcharset_mojikyo_pj_1 =
3411 make_charset (LEADING_BYTE_MOJIKYO_PJ_1, Qmojikyo_pj_1, 94, 2,
3412 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3413 build_string ("Mojikyo-PJ-1"),
3414 build_string ("Mojikyo (pseudo JIS encoding) part 1"),
3416 ("Konjaku-Mojikyo (pseudo JIS encoding) part 1"),
3417 build_string ("jisx0208\\.Mojikyo-1$"),
3419 staticpro (&Vcharset_mojikyo_pj_2);
3420 Vcharset_mojikyo_pj_2 =
3421 make_charset (LEADING_BYTE_MOJIKYO_PJ_2, Qmojikyo_pj_2, 94, 2,
3422 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3423 build_string ("Mojikyo-PJ-2"),
3424 build_string ("Mojikyo (pseudo JIS encoding) part 2"),
3426 ("Konjaku-Mojikyo (pseudo JIS encoding) part 2"),
3427 build_string ("jisx0208\\.Mojikyo-2$"),
3429 staticpro (&Vcharset_mojikyo_pj_3);
3430 Vcharset_mojikyo_pj_3 =
3431 make_charset (LEADING_BYTE_MOJIKYO_PJ_3, Qmojikyo_pj_3, 94, 2,
3432 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3433 build_string ("Mojikyo-PJ-3"),
3434 build_string ("Mojikyo (pseudo JIS encoding) part 3"),
3436 ("Konjaku-Mojikyo (pseudo JIS encoding) part 3"),
3437 build_string ("jisx0208\\.Mojikyo-3$"),
3439 staticpro (&Vcharset_mojikyo_pj_4);
3440 Vcharset_mojikyo_pj_4 =
3441 make_charset (LEADING_BYTE_MOJIKYO_PJ_4, Qmojikyo_pj_4, 94, 2,
3442 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3443 build_string ("Mojikyo-PJ-4"),
3444 build_string ("Mojikyo (pseudo JIS encoding) part 4"),
3446 ("Konjaku-Mojikyo (pseudo JIS encoding) part 4"),
3447 build_string ("jisx0208\\.Mojikyo-4$"),
3449 staticpro (&Vcharset_mojikyo_pj_5);
3450 Vcharset_mojikyo_pj_5 =
3451 make_charset (LEADING_BYTE_MOJIKYO_PJ_5, Qmojikyo_pj_5, 94, 2,
3452 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3453 build_string ("Mojikyo-PJ-5"),
3454 build_string ("Mojikyo (pseudo JIS encoding) part 5"),
3456 ("Konjaku-Mojikyo (pseudo JIS encoding) part 5"),
3457 build_string ("jisx0208\\.Mojikyo-5$"),
3459 staticpro (&Vcharset_mojikyo_pj_6);
3460 Vcharset_mojikyo_pj_6 =
3461 make_charset (LEADING_BYTE_MOJIKYO_PJ_6, Qmojikyo_pj_6, 94, 2,
3462 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3463 build_string ("Mojikyo-PJ-6"),
3464 build_string ("Mojikyo (pseudo JIS encoding) part 6"),
3466 ("Konjaku-Mojikyo (pseudo JIS encoding) part 6"),
3467 build_string ("jisx0208\\.Mojikyo-6$"),
3469 staticpro (&Vcharset_mojikyo_pj_7);
3470 Vcharset_mojikyo_pj_7 =
3471 make_charset (LEADING_BYTE_MOJIKYO_PJ_7, Qmojikyo_pj_7, 94, 2,
3472 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3473 build_string ("Mojikyo-PJ-7"),
3474 build_string ("Mojikyo (pseudo JIS encoding) part 7"),
3476 ("Konjaku-Mojikyo (pseudo JIS encoding) part 7"),
3477 build_string ("jisx0208\\.Mojikyo-7$"),
3479 staticpro (&Vcharset_mojikyo_pj_8);
3480 Vcharset_mojikyo_pj_8 =
3481 make_charset (LEADING_BYTE_MOJIKYO_PJ_8, Qmojikyo_pj_8, 94, 2,
3482 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3483 build_string ("Mojikyo-PJ-8"),
3484 build_string ("Mojikyo (pseudo JIS encoding) part 8"),
3486 ("Konjaku-Mojikyo (pseudo JIS encoding) part 8"),
3487 build_string ("jisx0208\\.Mojikyo-8$"),
3489 staticpro (&Vcharset_mojikyo_pj_9);
3490 Vcharset_mojikyo_pj_9 =
3491 make_charset (LEADING_BYTE_MOJIKYO_PJ_9, Qmojikyo_pj_9, 94, 2,
3492 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3493 build_string ("Mojikyo-PJ-9"),
3494 build_string ("Mojikyo (pseudo JIS encoding) part 9"),
3496 ("Konjaku-Mojikyo (pseudo JIS encoding) part 9"),
3497 build_string ("jisx0208\\.Mojikyo-9$"),
3499 staticpro (&Vcharset_mojikyo_pj_10);
3500 Vcharset_mojikyo_pj_10 =
3501 make_charset (LEADING_BYTE_MOJIKYO_PJ_10, Qmojikyo_pj_10, 94, 2,
3502 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3503 build_string ("Mojikyo-PJ-10"),
3504 build_string ("Mojikyo (pseudo JIS encoding) part 10"),
3506 ("Konjaku-Mojikyo (pseudo JIS encoding) part 10"),
3507 build_string ("jisx0208\\.Mojikyo-10$"),
3509 staticpro (&Vcharset_mojikyo_pj_11);
3510 Vcharset_mojikyo_pj_11 =
3511 make_charset (LEADING_BYTE_MOJIKYO_PJ_11, Qmojikyo_pj_11, 94, 2,
3512 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3513 build_string ("Mojikyo-PJ-11"),
3514 build_string ("Mojikyo (pseudo JIS encoding) part 11"),
3516 ("Konjaku-Mojikyo (pseudo JIS encoding) part 11"),
3517 build_string ("jisx0208\\.Mojikyo-11$"),
3519 staticpro (&Vcharset_mojikyo_pj_12);
3520 Vcharset_mojikyo_pj_12 =
3521 make_charset (LEADING_BYTE_MOJIKYO_PJ_12, Qmojikyo_pj_12, 94, 2,
3522 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3523 build_string ("Mojikyo-PJ-12"),
3524 build_string ("Mojikyo (pseudo JIS encoding) part 12"),
3526 ("Konjaku-Mojikyo (pseudo JIS encoding) part 12"),
3527 build_string ("jisx0208\\.Mojikyo-12$"),
3529 staticpro (&Vcharset_mojikyo_pj_13);
3530 Vcharset_mojikyo_pj_13 =
3531 make_charset (LEADING_BYTE_MOJIKYO_PJ_13, Qmojikyo_pj_13, 94, 2,
3532 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3533 build_string ("Mojikyo-PJ-13"),
3534 build_string ("Mojikyo (pseudo JIS encoding) part 13"),
3536 ("Konjaku-Mojikyo (pseudo JIS encoding) part 13"),
3537 build_string ("jisx0208\\.Mojikyo-13$"),
3539 staticpro (&Vcharset_mojikyo_pj_14);
3540 Vcharset_mojikyo_pj_14 =
3541 make_charset (LEADING_BYTE_MOJIKYO_PJ_14, Qmojikyo_pj_14, 94, 2,
3542 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3543 build_string ("Mojikyo-PJ-14"),
3544 build_string ("Mojikyo (pseudo JIS encoding) part 14"),
3546 ("Konjaku-Mojikyo (pseudo JIS encoding) part 14"),
3547 build_string ("jisx0208\\.Mojikyo-14$"),
3549 staticpro (&Vcharset_mojikyo_pj_15);
3550 Vcharset_mojikyo_pj_15 =
3551 make_charset (LEADING_BYTE_MOJIKYO_PJ_15, Qmojikyo_pj_15, 94, 2,
3552 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3553 build_string ("Mojikyo-PJ-15"),
3554 build_string ("Mojikyo (pseudo JIS encoding) part 15"),
3556 ("Konjaku-Mojikyo (pseudo JIS encoding) part 15"),
3557 build_string ("jisx0208\\.Mojikyo-15$"),
3559 staticpro (&Vcharset_mojikyo_pj_16);
3560 Vcharset_mojikyo_pj_16 =
3561 make_charset (LEADING_BYTE_MOJIKYO_PJ_16, Qmojikyo_pj_16, 94, 2,
3562 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3563 build_string ("Mojikyo-PJ-16"),
3564 build_string ("Mojikyo (pseudo JIS encoding) part 16"),
3566 ("Konjaku-Mojikyo (pseudo JIS encoding) part 16"),
3567 build_string ("jisx0208\\.Mojikyo-16$"),
3569 staticpro (&Vcharset_mojikyo_pj_17);
3570 Vcharset_mojikyo_pj_17 =
3571 make_charset (LEADING_BYTE_MOJIKYO_PJ_17, Qmojikyo_pj_17, 94, 2,
3572 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3573 build_string ("Mojikyo-PJ-17"),
3574 build_string ("Mojikyo (pseudo JIS encoding) part 17"),
3576 ("Konjaku-Mojikyo (pseudo JIS encoding) part 17"),
3577 build_string ("jisx0208\\.Mojikyo-17$"),
3579 staticpro (&Vcharset_mojikyo_pj_18);
3580 Vcharset_mojikyo_pj_18 =
3581 make_charset (LEADING_BYTE_MOJIKYO_PJ_18, Qmojikyo_pj_18, 94, 2,
3582 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3583 build_string ("Mojikyo-PJ-18"),
3584 build_string ("Mojikyo (pseudo JIS encoding) part 18"),
3586 ("Konjaku-Mojikyo (pseudo JIS encoding) part 18"),
3587 build_string ("jisx0208\\.Mojikyo-18$"),
3589 staticpro (&Vcharset_mojikyo_pj_19);
3590 Vcharset_mojikyo_pj_19 =
3591 make_charset (LEADING_BYTE_MOJIKYO_PJ_19, Qmojikyo_pj_19, 94, 2,
3592 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3593 build_string ("Mojikyo-PJ-19"),
3594 build_string ("Mojikyo (pseudo JIS encoding) part 19"),
3596 ("Konjaku-Mojikyo (pseudo JIS encoding) part 19"),
3597 build_string ("jisx0208\\.Mojikyo-19$"),
3599 staticpro (&Vcharset_mojikyo_pj_20);
3600 Vcharset_mojikyo_pj_20 =
3601 make_charset (LEADING_BYTE_MOJIKYO_PJ_20, Qmojikyo_pj_20, 94, 2,
3602 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3603 build_string ("Mojikyo-PJ-20"),
3604 build_string ("Mojikyo (pseudo JIS encoding) part 20"),
3606 ("Konjaku-Mojikyo (pseudo JIS encoding) part 20"),
3607 build_string ("jisx0208\\.Mojikyo-20$"),
3609 staticpro (&Vcharset_mojikyo_pj_21);
3610 Vcharset_mojikyo_pj_21 =
3611 make_charset (LEADING_BYTE_MOJIKYO_PJ_21, Qmojikyo_pj_21, 94, 2,
3612 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3613 build_string ("Mojikyo-PJ-21"),
3614 build_string ("Mojikyo (pseudo JIS encoding) part 21"),
3616 ("Konjaku-Mojikyo (pseudo JIS encoding) part 21"),
3617 build_string ("jisx0208\\.Mojikyo-21$"),
3619 staticpro (&Vcharset_ethiopic_ucs);
3620 Vcharset_ethiopic_ucs =
3621 make_charset (LEADING_BYTE_ETHIOPIC_UCS, Qethiopic_ucs, 256, 2,
3622 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3623 build_string ("Ethiopic (UCS)"),
3624 build_string ("Ethiopic (UCS)"),
3625 build_string ("Ethiopic of UCS"),
3626 build_string ("Ethiopic-Unicode"),
3627 Qnil, 0x1200, 0x137F, 0x1200, 0);
3629 staticpro (&Vcharset_chinese_big5_1);
3630 Vcharset_chinese_big5_1 =
3631 make_charset (LEADING_BYTE_CHINESE_BIG5_1, Qchinese_big5_1, 94, 2,
3632 2, 0, '0', CHARSET_LEFT_TO_RIGHT,
3633 build_string ("Big5"),
3634 build_string ("Big5 (Level-1)"),
3636 ("Big5 Level-1 Chinese traditional"),
3637 build_string ("big5"),
3639 staticpro (&Vcharset_chinese_big5_2);
3640 Vcharset_chinese_big5_2 =
3641 make_charset (LEADING_BYTE_CHINESE_BIG5_2, Qchinese_big5_2, 94, 2,
3642 2, 0, '1', CHARSET_LEFT_TO_RIGHT,
3643 build_string ("Big5"),
3644 build_string ("Big5 (Level-2)"),
3646 ("Big5 Level-2 Chinese traditional"),
3647 build_string ("big5"),
3650 #ifdef ENABLE_COMPOSITE_CHARS
3651 /* #### For simplicity, we put composite chars into a 96x96 charset.
3652 This is going to lead to problems because you can run out of
3653 room, esp. as we don't yet recycle numbers. */
3654 staticpro (&Vcharset_composite);
3655 Vcharset_composite =
3656 make_charset (LEADING_BYTE_COMPOSITE, Qcomposite, 96, 2,
3657 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3658 build_string ("Composite"),
3659 build_string ("Composite characters"),
3660 build_string ("Composite characters"),
3663 /* #### not dumped properly */
3664 composite_char_row_next = 32;
3665 composite_char_col_next = 32;
3667 Vcomposite_char_string2char_hash_table =
3668 make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
3669 Vcomposite_char_char2string_hash_table =
3670 make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3671 staticpro (&Vcomposite_char_string2char_hash_table);
3672 staticpro (&Vcomposite_char_char2string_hash_table);
3673 #endif /* ENABLE_COMPOSITE_CHARS */