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_composition_table;
427 Lisp_Object Vcharacter_variant_table;
430 Lisp_Object Q_decomposition;
434 Lisp_Object Qisolated;
435 Lisp_Object Qinitial;
438 Lisp_Object Qvertical;
439 Lisp_Object QnoBreak;
440 Lisp_Object Qfraction;
450 Emchar to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg);
452 Lisp_Object put_char_ccs_code_point (Lisp_Object character,
453 Lisp_Object ccs, Lisp_Object value);
454 Lisp_Object remove_char_ccs (Lisp_Object character, Lisp_Object ccs);
456 Lisp_Object put_char_attribute (Lisp_Object character,
457 Lisp_Object attribute, Lisp_Object value);
458 Lisp_Object remove_char_attribute (Lisp_Object character,
459 Lisp_Object attribute);
463 to_char_id (Lisp_Object v, char* err_msg, Lisp_Object err_arg)
469 else if (EQ (v, Qcompat))
471 else if (EQ (v, Qisolated))
473 else if (EQ (v, Qinitial))
475 else if (EQ (v, Qmedial))
477 else if (EQ (v, Qfinal))
479 else if (EQ (v, Qvertical))
481 else if (EQ (v, QnoBreak))
483 else if (EQ (v, Qfraction))
485 else if (EQ (v, Qsuper))
487 else if (EQ (v, Qsub))
489 else if (EQ (v, Qcircle))
491 else if (EQ (v, Qsquare))
493 else if (EQ (v, Qwide))
495 else if (EQ (v, Qnarrow))
497 else if (EQ (v, Qsmall))
499 else if (EQ (v, Qfont))
502 signal_simple_error (err_msg, err_arg);
505 DEFUN ("get-composite-char", Fget_composite_char, 1, 1, 0, /*
506 Return character corresponding with list.
510 Lisp_Object table = Vcharacter_composition_table;
511 Lisp_Object rest = list;
515 Lisp_Object v = Fcar (rest);
517 Emchar c = to_char_id (v, "Invalid value for composition", list);
519 ret = get_char_id_table (c, table);
524 if (!CHAR_ID_TABLE_P (ret))
529 else if (!CONSP (rest))
531 else if (CHAR_ID_TABLE_P (ret))
534 signal_simple_error ("Invalid table is found with", list);
536 signal_simple_error ("Invalid value for composition", list);
539 DEFUN ("char-variants", Fchar_variants, 1, 1, 0, /*
540 Return variants of CHARACTER.
544 CHECK_CHAR (character);
545 return Fcopy_list (get_char_id_table (XCHAR (character),
546 Vcharacter_variant_table));
549 DEFUN ("char-attribute-alist", Fchar_attribute_alist, 1, 1, 0, /*
550 Return the alist of attributes of CHARACTER.
554 CHECK_CHAR (character);
555 return Fcopy_alist (get_char_id_table (XCHAR (character),
556 Vcharacter_attribute_table));
559 DEFUN ("get-char-attribute", Fget_char_attribute, 2, 2, 0, /*
560 Return the value of CHARACTER's ATTRIBUTE.
562 (character, attribute))
566 CHECK_CHAR (character);
567 if (!NILP (ccs = Ffind_charset (attribute)))
569 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
571 if (CHAR_ID_TABLE_P (encoding_table))
572 return get_char_id_table (XCHAR (character), encoding_table);
576 else if (EQ (attribute, Qname))
578 return get_char_id_table (XCHAR (character), Vcharacter_name_table);
583 = get_char_id_table (XCHAR (character), Vcharacter_attribute_table);
588 return Fcdr (Fassq (attribute, ret));
592 DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /*
593 Store CHARACTER's ATTRIBUTE with VALUE.
595 (character, attribute, value))
599 CHECK_CHAR (character);
600 ccs = Ffind_charset (attribute);
603 return put_char_ccs_code_point (character, ccs, value);
605 else if (EQ (attribute, Qname))
607 CHECK_STRING (value);
608 put_char_id_table (XCHAR (character), value, Vcharacter_name_table);
611 else if (EQ (attribute, Q_decomposition))
614 signal_simple_error ("Invalid value for ->decomposition",
617 if (CONSP (Fcdr (value)))
619 Lisp_Object rest = value;
620 Lisp_Object table = Vcharacter_composition_table;
624 Lisp_Object v = Fcar (rest);
627 = to_char_id (v, "Invalid value for ->decomposition", value);
632 put_char_id_table (c, character, table);
637 ntable = get_char_id_table (c, table);
638 if (!CHAR_ID_TABLE_P (ntable))
641 = make_char_id_table (Qnil, OLDER_RECORD_P (table));
642 put_char_id_table (c, ntable, table);
650 Lisp_Object v = Fcar (value);
656 = get_char_id_table (c, Vcharacter_variant_table);
658 if (NILP (Fmemq (v, ret)))
660 put_char_id_table (c, Fcons (character, ret),
661 Vcharacter_variant_table);
666 else if (EQ (attribute, Q_ucs))
672 signal_simple_error ("Invalid value for ->ucs", value);
676 ret = get_char_id_table (c, Vcharacter_variant_table);
677 if (NILP (Fmemq (character, ret)))
679 put_char_id_table (c, Fcons (character, ret),
680 Vcharacter_variant_table);
683 return put_char_attribute (character, attribute, value);
686 DEFUN ("remove-char-attribute", Fremove_char_attribute, 2, 2, 0, /*
687 Remove CHARACTER's ATTRIBUTE.
689 (character, attribute))
693 CHECK_CHAR (character);
694 ccs = Ffind_charset (attribute);
697 return remove_char_ccs (character, ccs);
699 return remove_char_attribute (character, attribute);
702 INLINE_HEADER int CHARSET_BYTE_SIZE (Lisp_Charset* cs);
704 CHARSET_BYTE_SIZE (Lisp_Charset* cs)
706 /* ad-hoc method for `ascii' */
707 if ((CHARSET_CHARS (cs) == 94) &&
708 (CHARSET_BYTE_OFFSET (cs) != 33))
709 return 128 - CHARSET_BYTE_OFFSET (cs);
711 return CHARSET_CHARS (cs);
714 #define XCHARSET_BYTE_SIZE(ccs) CHARSET_BYTE_SIZE (XCHARSET (ccs))
716 int decoding_table_check_elements (Lisp_Object v, int dim, int ccs_len);
718 decoding_table_check_elements (Lisp_Object v, int dim, int ccs_len)
722 if (XVECTOR_LENGTH (v) > ccs_len)
725 for (i = 0; i < XVECTOR_LENGTH (v); i++)
727 Lisp_Object c = XVECTOR_DATA(v)[i];
729 if (!NILP (c) && !CHARP (c))
733 int ret = decoding_table_check_elements (c, dim - 1, ccs_len);
745 decoding_table_remove_char (Lisp_Object v, int dim, int byte_offset,
748 decoding_table_remove_char (Lisp_Object v, int dim, int byte_offset,
758 i = ((code_point >> (8 * dim)) & 255) - byte_offset;
759 nv = XVECTOR_DATA(v)[i];
765 XVECTOR_DATA(v)[i] = Qnil;
769 decoding_table_put_char (Lisp_Object v, int dim, int byte_offset,
770 int code_point, Lisp_Object character);
772 decoding_table_put_char (Lisp_Object v, int dim, int byte_offset,
773 int code_point, Lisp_Object character)
777 int ccs_len = XVECTOR_LENGTH (v);
782 i = ((code_point >> (8 * dim)) & 255) - byte_offset;
783 nv = XVECTOR_DATA(v)[i];
787 nv = (XVECTOR_DATA(v)[i] = make_older_vector (ccs_len, Qnil));
793 XVECTOR_DATA(v)[i] = character;
797 put_char_ccs_code_point (Lisp_Object character,
798 Lisp_Object ccs, Lisp_Object value)
800 Lisp_Object encoding_table;
802 if (!EQ (XCHARSET_NAME (ccs), Qucs)
803 || (XCHAR (character) != XINT (value)))
805 Lisp_Object v = XCHARSET_DECODING_TABLE (ccs);
806 int dim = XCHARSET_DIMENSION (ccs);
807 int ccs_len = XCHARSET_BYTE_SIZE (ccs);
808 int byte_offset = XCHARSET_BYTE_OFFSET (ccs);
812 { /* obsolete representation: value must be a list of bytes */
813 Lisp_Object ret = Fcar (value);
817 signal_simple_error ("Invalid value for coded-charset", value);
818 code_point = XINT (ret);
819 if (XCHARSET_GRAPHIC (ccs) == 1)
827 signal_simple_error ("Invalid value for coded-charset",
831 signal_simple_error ("Invalid value for coded-charset",
834 if (XCHARSET_GRAPHIC (ccs) == 1)
836 code_point = (code_point << 8) | j;
839 value = make_int (code_point);
841 else if (INTP (value))
843 code_point = XINT (value);
844 if (XCHARSET_GRAPHIC (ccs) == 1)
846 code_point &= 0x7F7F7F7F;
847 value = make_int (code_point);
851 signal_simple_error ("Invalid value for coded-charset", value);
855 Lisp_Object cpos = Fget_char_attribute (character, ccs);
858 decoding_table_remove_char (v, dim, byte_offset, XINT (cpos));
863 XCHARSET_DECODING_TABLE (ccs)
864 = v = make_older_vector (ccs_len, Qnil);
867 decoding_table_put_char (v, dim, byte_offset, code_point, character);
869 if (NILP (encoding_table = XCHARSET_ENCODING_TABLE (ccs)))
871 XCHARSET_ENCODING_TABLE (ccs)
872 = encoding_table = make_char_id_table (Qnil, -1);
874 put_char_id_table (XCHAR (character), value, encoding_table);
879 remove_char_ccs (Lisp_Object character, Lisp_Object ccs)
881 Lisp_Object decoding_table = XCHARSET_DECODING_TABLE (ccs);
882 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
884 if (VECTORP (decoding_table))
886 Lisp_Object cpos = Fget_char_attribute (character, ccs);
890 decoding_table_remove_char (decoding_table,
891 XCHARSET_DIMENSION (ccs),
892 XCHARSET_BYTE_OFFSET (ccs),
896 if (CHAR_ID_TABLE_P (encoding_table))
898 put_char_id_table (XCHAR (character), Qnil, encoding_table);
904 put_char_attribute (Lisp_Object character, Lisp_Object attribute,
907 Emchar char_id = XCHAR (character);
908 Lisp_Object ret = get_char_id_table (char_id, Vcharacter_attribute_table);
911 cell = Fassq (attribute, ret);
915 ret = Fcons (Fcons (attribute, value), ret);
917 else if (!EQ (Fcdr (cell), value))
919 Fsetcdr (cell, value);
921 put_char_id_table (char_id, ret, Vcharacter_attribute_table);
926 remove_char_attribute (Lisp_Object character, Lisp_Object attribute)
928 Emchar char_id = XCHAR (character);
929 Lisp_Object alist = get_char_id_table (char_id, Vcharacter_attribute_table);
931 if (EQ (attribute, Fcar (Fcar (alist))))
933 alist = Fcdr (alist);
937 Lisp_Object pr = alist;
938 Lisp_Object r = Fcdr (alist);
942 if (EQ (attribute, Fcar (Fcar (r))))
944 XCDR (pr) = Fcdr (r);
951 put_char_id_table (char_id, alist, Vcharacter_attribute_table);
955 EXFUN (Fmake_char, 3);
956 EXFUN (Fdecode_char, 2);
958 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
959 Store character's ATTRIBUTES.
963 Lisp_Object rest = attributes;
964 Lisp_Object code = Fcdr (Fassq (Qucs, attributes));
965 Lisp_Object character;
971 Lisp_Object cell = Fcar (rest);
975 signal_simple_error ("Invalid argument", attributes);
976 if (!NILP (ccs = Ffind_charset (Fcar (cell)))
977 && ((XCHARSET_FINAL (ccs) != 0) ||
978 (XCHARSET_UCS_MAX (ccs) > 0)) )
982 character = Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
984 character = Fdecode_char (ccs, cell);
985 goto setup_attributes;
989 if (!NILP (code = Fcdr (Fassq (Q_ucs, attributes))))
992 signal_simple_error ("Invalid argument", attributes);
994 character = make_char (XINT (code) + 0x100000);
995 goto setup_attributes;
999 else if (!INTP (code))
1000 signal_simple_error ("Invalid argument", attributes);
1002 character = make_char (XINT (code));
1006 while (CONSP (rest))
1008 Lisp_Object cell = Fcar (rest);
1011 signal_simple_error ("Invalid argument", attributes);
1012 Fput_char_attribute (character, Fcar (cell), Fcdr (cell));
1016 get_char_id_table (XCHAR (character), Vcharacter_attribute_table);
1019 Lisp_Object Vutf_2000_version;
1023 int leading_code_private_11;
1026 Lisp_Object Qcharsetp;
1028 /* Qdoc_string, Qdimension, Qchars defined in general.c */
1029 Lisp_Object Qregistry, Qfinal, Qgraphic;
1030 Lisp_Object Qdirection;
1031 Lisp_Object Qreverse_direction_charset;
1032 Lisp_Object Qleading_byte;
1033 Lisp_Object Qshort_name, Qlong_name;
1047 Qcyrillic_iso8859_5,
1049 Qjapanese_jisx0208_1978,
1052 Qjapanese_jisx0208_1990,
1055 Qchinese_cns11643_1,
1056 Qchinese_cns11643_2,
1061 Qlatin_viscii_lower,
1062 Qlatin_viscii_upper,
1063 Qvietnamese_viscii_lower,
1064 Qvietnamese_viscii_upper,
1065 Qideograph_daikanwa,
1094 Lisp_Object Ql2r, Qr2l;
1096 Lisp_Object Vcharset_hash_table;
1098 /* Composite characters are characters constructed by overstriking two
1099 or more regular characters.
1101 1) The old Mule implementation involves storing composite characters
1102 in a buffer as a tag followed by all of the actual characters
1103 used to make up the composite character. I think this is a bad
1104 idea; it greatly complicates code that wants to handle strings
1105 one character at a time because it has to deal with the possibility
1106 of great big ungainly characters. It's much more reasonable to
1107 simply store an index into a table of composite characters.
1109 2) The current implementation only allows for 16,384 separate
1110 composite characters over the lifetime of the XEmacs process.
1111 This could become a potential problem if the user
1112 edited lots of different files that use composite characters.
1113 Due to FSF bogosity, increasing the number of allowable
1114 composite characters under Mule would decrease the number
1115 of possible faces that can exist. Mule already has shrunk
1116 this to 2048, and further shrinkage would become uncomfortable.
1117 No such problems exist in XEmacs.
1119 Composite characters could be represented as 0x80 C1 C2 C3,
1120 where each C[1-3] is in the range 0xA0 - 0xFF. This allows
1121 for slightly under 2^20 (one million) composite characters
1122 over the XEmacs process lifetime, and you only need to
1123 increase the size of a Mule character from 19 to 21 bits.
1124 Or you could use 0x80 C1 C2 C3 C4, allowing for about
1125 85 million (slightly over 2^26) composite characters. */
1128 /************************************************************************/
1129 /* Basic Emchar functions */
1130 /************************************************************************/
1132 /* Convert a non-ASCII Mule character C into a one-character Mule-encoded
1133 string in STR. Returns the number of bytes stored.
1134 Do not call this directly. Use the macro set_charptr_emchar() instead.
1138 non_ascii_set_charptr_emchar (Bufbyte *str, Emchar c)
1144 Lisp_Object charset;
1153 else if ( c <= 0x7ff )
1155 *p++ = (c >> 6) | 0xc0;
1156 *p++ = (c & 0x3f) | 0x80;
1158 else if ( c <= 0xffff )
1160 *p++ = (c >> 12) | 0xe0;
1161 *p++ = ((c >> 6) & 0x3f) | 0x80;
1162 *p++ = (c & 0x3f) | 0x80;
1164 else if ( c <= 0x1fffff )
1166 *p++ = (c >> 18) | 0xf0;
1167 *p++ = ((c >> 12) & 0x3f) | 0x80;
1168 *p++ = ((c >> 6) & 0x3f) | 0x80;
1169 *p++ = (c & 0x3f) | 0x80;
1171 else if ( c <= 0x3ffffff )
1173 *p++ = (c >> 24) | 0xf8;
1174 *p++ = ((c >> 18) & 0x3f) | 0x80;
1175 *p++ = ((c >> 12) & 0x3f) | 0x80;
1176 *p++ = ((c >> 6) & 0x3f) | 0x80;
1177 *p++ = (c & 0x3f) | 0x80;
1181 *p++ = (c >> 30) | 0xfc;
1182 *p++ = ((c >> 24) & 0x3f) | 0x80;
1183 *p++ = ((c >> 18) & 0x3f) | 0x80;
1184 *p++ = ((c >> 12) & 0x3f) | 0x80;
1185 *p++ = ((c >> 6) & 0x3f) | 0x80;
1186 *p++ = (c & 0x3f) | 0x80;
1189 BREAKUP_CHAR (c, charset, c1, c2);
1190 lb = CHAR_LEADING_BYTE (c);
1191 if (LEADING_BYTE_PRIVATE_P (lb))
1192 *p++ = PRIVATE_LEADING_BYTE_PREFIX (lb);
1194 if (EQ (charset, Vcharset_control_1))
1203 /* Return the first character from a Mule-encoded string in STR,
1204 assuming it's non-ASCII. Do not call this directly.
1205 Use the macro charptr_emchar() instead. */
1208 non_ascii_charptr_emchar (const Bufbyte *str)
1221 else if ( b >= 0xf8 )
1226 else if ( b >= 0xf0 )
1231 else if ( b >= 0xe0 )
1236 else if ( b >= 0xc0 )
1246 for( ; len > 0; len-- )
1249 ch = ( ch << 6 ) | ( b & 0x3f );
1253 Bufbyte i0 = *str, i1, i2 = 0;
1254 Lisp_Object charset;
1256 if (i0 == LEADING_BYTE_CONTROL_1)
1257 return (Emchar) (*++str - 0x20);
1259 if (LEADING_BYTE_PREFIX_P (i0))
1264 charset = CHARSET_BY_LEADING_BYTE (i0);
1265 if (XCHARSET_DIMENSION (charset) == 2)
1268 return MAKE_CHAR (charset, i1, i2);
1272 /* Return whether CH is a valid Emchar, assuming it's non-ASCII.
1273 Do not call this directly. Use the macro valid_char_p() instead. */
1277 non_ascii_valid_char_p (Emchar ch)
1281 /* Must have only lowest 19 bits set */
1285 f1 = CHAR_FIELD1 (ch);
1286 f2 = CHAR_FIELD2 (ch);
1287 f3 = CHAR_FIELD3 (ch);
1291 Lisp_Object charset;
1293 if (f2 < MIN_CHAR_FIELD2_OFFICIAL ||
1294 (f2 > MAX_CHAR_FIELD2_OFFICIAL && f2 < MIN_CHAR_FIELD2_PRIVATE) ||
1295 f2 > MAX_CHAR_FIELD2_PRIVATE)
1300 if (f3 != 0x20 && f3 != 0x7F && !(f2 >= MIN_CHAR_FIELD2_PRIVATE &&
1301 f2 <= MAX_CHAR_FIELD2_PRIVATE))
1305 NOTE: This takes advantage of the fact that
1306 FIELD2_TO_OFFICIAL_LEADING_BYTE and
1307 FIELD2_TO_PRIVATE_LEADING_BYTE are the same.
1309 charset = CHARSET_BY_LEADING_BYTE (f2 + FIELD2_TO_OFFICIAL_LEADING_BYTE);
1310 if (EQ (charset, Qnil))
1312 return (XCHARSET_CHARS (charset) == 96);
1316 Lisp_Object charset;
1318 if (f1 < MIN_CHAR_FIELD1_OFFICIAL ||
1319 (f1 > MAX_CHAR_FIELD1_OFFICIAL && f1 < MIN_CHAR_FIELD1_PRIVATE) ||
1320 f1 > MAX_CHAR_FIELD1_PRIVATE)
1322 if (f2 < 0x20 || f3 < 0x20)
1325 #ifdef ENABLE_COMPOSITE_CHARS
1326 if (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE == LEADING_BYTE_COMPOSITE)
1328 if (UNBOUNDP (Fgethash (make_int (ch),
1329 Vcomposite_char_char2string_hash_table,
1334 #endif /* ENABLE_COMPOSITE_CHARS */
1336 if (f2 != 0x20 && f2 != 0x7F && f3 != 0x20 && f3 != 0x7F
1337 && !(f1 >= MIN_CHAR_FIELD1_PRIVATE && f1 <= MAX_CHAR_FIELD1_PRIVATE))
1340 if (f1 <= MAX_CHAR_FIELD1_OFFICIAL)
1342 CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE);
1345 CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_PRIVATE_LEADING_BYTE);
1347 if (EQ (charset, Qnil))
1349 return (XCHARSET_CHARS (charset) == 96);
1355 /************************************************************************/
1356 /* Basic string functions */
1357 /************************************************************************/
1359 /* Copy the character pointed to by PTR into STR, assuming it's
1360 non-ASCII. Do not call this directly. Use the macro
1361 charptr_copy_char() instead. */
1364 non_ascii_charptr_copy_char (const Bufbyte *ptr, Bufbyte *str)
1366 Bufbyte *strptr = str;
1368 switch (REP_BYTES_BY_FIRST_BYTE (*strptr))
1370 /* Notice fallthrough. */
1372 case 6: *++strptr = *ptr++;
1373 case 5: *++strptr = *ptr++;
1375 case 4: *++strptr = *ptr++;
1376 case 3: *++strptr = *ptr++;
1377 case 2: *++strptr = *ptr;
1382 return strptr + 1 - str;
1386 /************************************************************************/
1387 /* streams of Emchars */
1388 /************************************************************************/
1390 /* Treat a stream as a stream of Emchar's rather than a stream of bytes.
1391 The functions below are not meant to be called directly; use
1392 the macros in insdel.h. */
1395 Lstream_get_emchar_1 (Lstream *stream, int ch)
1397 Bufbyte str[MAX_EMCHAR_LEN];
1398 Bufbyte *strptr = str;
1400 str[0] = (Bufbyte) ch;
1401 switch (REP_BYTES_BY_FIRST_BYTE (ch))
1403 /* Notice fallthrough. */
1406 ch = Lstream_getc (stream);
1408 *++strptr = (Bufbyte) ch;
1410 ch = Lstream_getc (stream);
1412 *++strptr = (Bufbyte) ch;
1415 ch = Lstream_getc (stream);
1417 *++strptr = (Bufbyte) ch;
1419 ch = Lstream_getc (stream);
1421 *++strptr = (Bufbyte) ch;
1423 ch = Lstream_getc (stream);
1425 *++strptr = (Bufbyte) ch;
1430 return charptr_emchar (str);
1434 Lstream_fput_emchar (Lstream *stream, Emchar ch)
1436 Bufbyte str[MAX_EMCHAR_LEN];
1437 Bytecount len = set_charptr_emchar (str, ch);
1438 return Lstream_write (stream, str, len);
1442 Lstream_funget_emchar (Lstream *stream, Emchar ch)
1444 Bufbyte str[MAX_EMCHAR_LEN];
1445 Bytecount len = set_charptr_emchar (str, ch);
1446 Lstream_unread (stream, str, len);
1450 /************************************************************************/
1451 /* charset object */
1452 /************************************************************************/
1455 mark_charset (Lisp_Object obj)
1457 Lisp_Charset *cs = XCHARSET (obj);
1459 mark_object (cs->short_name);
1460 mark_object (cs->long_name);
1461 mark_object (cs->doc_string);
1462 mark_object (cs->registry);
1463 mark_object (cs->ccl_program);
1465 /* mark_object (cs->encoding_table); */
1466 /* mark_object (cs->decoding_table); */
1472 print_charset (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1474 Lisp_Charset *cs = XCHARSET (obj);
1478 error ("printing unreadable object #<charset %s 0x%x>",
1479 string_data (XSYMBOL (CHARSET_NAME (cs))->name),
1482 write_c_string ("#<charset ", printcharfun);
1483 print_internal (CHARSET_NAME (cs), printcharfun, 0);
1484 write_c_string (" ", printcharfun);
1485 print_internal (CHARSET_SHORT_NAME (cs), printcharfun, 1);
1486 write_c_string (" ", printcharfun);
1487 print_internal (CHARSET_LONG_NAME (cs), printcharfun, 1);
1488 write_c_string (" ", printcharfun);
1489 print_internal (CHARSET_DOC_STRING (cs), printcharfun, 1);
1490 sprintf (buf, " %d^%d %s cols=%d g%d final='%c' reg=",
1492 CHARSET_DIMENSION (cs),
1493 CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? "l2r" : "r2l",
1494 CHARSET_COLUMNS (cs),
1495 CHARSET_GRAPHIC (cs),
1496 CHARSET_FINAL (cs));
1497 write_c_string (buf, printcharfun);
1498 print_internal (CHARSET_REGISTRY (cs), printcharfun, 0);
1499 sprintf (buf, " 0x%x>", cs->header.uid);
1500 write_c_string (buf, printcharfun);
1503 static const struct lrecord_description charset_description[] = {
1504 { XD_LISP_OBJECT, offsetof (Lisp_Charset, name) },
1505 { XD_LISP_OBJECT, offsetof (Lisp_Charset, doc_string) },
1506 { XD_LISP_OBJECT, offsetof (Lisp_Charset, registry) },
1507 { XD_LISP_OBJECT, offsetof (Lisp_Charset, short_name) },
1508 { XD_LISP_OBJECT, offsetof (Lisp_Charset, long_name) },
1509 { XD_LISP_OBJECT, offsetof (Lisp_Charset, reverse_direction_charset) },
1510 { XD_LISP_OBJECT, offsetof (Lisp_Charset, ccl_program) },
1512 { XD_LISP_OBJECT, offsetof (Lisp_Charset, decoding_table) },
1513 { XD_LISP_OBJECT, offsetof (Lisp_Charset, encoding_table) },
1518 DEFINE_LRECORD_IMPLEMENTATION ("charset", charset,
1519 mark_charset, print_charset, 0, 0, 0,
1520 charset_description,
1522 /* Make a new charset. */
1525 make_charset (Charset_ID id, Lisp_Object name,
1526 unsigned short chars, unsigned char dimension,
1527 unsigned char columns, unsigned char graphic,
1528 Bufbyte final, unsigned char direction, Lisp_Object short_name,
1529 Lisp_Object long_name, Lisp_Object doc,
1531 Lisp_Object decoding_table,
1532 Emchar ucs_min, Emchar ucs_max,
1533 Emchar code_offset, unsigned char byte_offset)
1535 unsigned char type = 0;
1537 Lisp_Charset *cs = alloc_lcrecord_type (Lisp_Charset, &lrecord_charset);
1541 XSETCHARSET (obj, cs);
1543 CHARSET_ID (cs) = id;
1544 CHARSET_NAME (cs) = name;
1545 CHARSET_SHORT_NAME (cs) = short_name;
1546 CHARSET_LONG_NAME (cs) = long_name;
1547 CHARSET_CHARS (cs) = chars;
1548 CHARSET_DIMENSION (cs) = dimension;
1549 CHARSET_DIRECTION (cs) = direction;
1550 CHARSET_COLUMNS (cs) = columns;
1551 CHARSET_GRAPHIC (cs) = graphic;
1552 CHARSET_FINAL (cs) = final;
1553 CHARSET_DOC_STRING (cs) = doc;
1554 CHARSET_REGISTRY (cs) = reg;
1555 CHARSET_CCL_PROGRAM (cs) = Qnil;
1556 CHARSET_REVERSE_DIRECTION_CHARSET (cs) = Qnil;
1558 CHARSET_DECODING_TABLE(cs) = Qnil;
1559 CHARSET_ENCODING_TABLE(cs) = Qnil;
1560 CHARSET_UCS_MIN(cs) = ucs_min;
1561 CHARSET_UCS_MAX(cs) = ucs_max;
1562 CHARSET_CODE_OFFSET(cs) = code_offset;
1563 CHARSET_BYTE_OFFSET(cs) = byte_offset;
1566 switch (CHARSET_CHARS (cs))
1569 switch (CHARSET_DIMENSION (cs))
1572 type = CHARSET_TYPE_94;
1575 type = CHARSET_TYPE_94X94;
1580 switch (CHARSET_DIMENSION (cs))
1583 type = CHARSET_TYPE_96;
1586 type = CHARSET_TYPE_96X96;
1592 switch (CHARSET_DIMENSION (cs))
1595 type = CHARSET_TYPE_128;
1598 type = CHARSET_TYPE_128X128;
1603 switch (CHARSET_DIMENSION (cs))
1606 type = CHARSET_TYPE_256;
1609 type = CHARSET_TYPE_256X256;
1616 CHARSET_TYPE (cs) = type;
1620 if (id == LEADING_BYTE_ASCII)
1621 CHARSET_REP_BYTES (cs) = 1;
1623 CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 1;
1625 CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 2;
1630 /* some charsets do not have final characters. This includes
1631 ASCII, Control-1, Composite, and the two faux private
1634 if (code_offset == 0)
1636 assert (NILP (chlook->charset_by_attributes[type][final]));
1637 chlook->charset_by_attributes[type][final] = obj;
1640 assert (NILP (chlook->charset_by_attributes[type][final][direction]));
1641 chlook->charset_by_attributes[type][final][direction] = obj;
1645 assert (NILP (chlook->charset_by_leading_byte[id - MIN_LEADING_BYTE]));
1646 chlook->charset_by_leading_byte[id - MIN_LEADING_BYTE] = obj;
1648 /* Some charsets are "faux" and don't have names or really exist at
1649 all except in the leading-byte table. */
1651 Fputhash (name, obj, Vcharset_hash_table);
1656 get_unallocated_leading_byte (int dimension)
1661 if (chlook->next_allocated_leading_byte > MAX_LEADING_BYTE_PRIVATE)
1664 lb = chlook->next_allocated_leading_byte++;
1668 if (chlook->next_allocated_1_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_1)
1671 lb = chlook->next_allocated_1_byte_leading_byte++;
1675 if (chlook->next_allocated_2_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_2)
1678 lb = chlook->next_allocated_2_byte_leading_byte++;
1684 ("No more character sets free for this dimension",
1685 make_int (dimension));
1692 make_builtin_char (Lisp_Object charset, int c1, int c2)
1694 if (XCHARSET_UCS_MAX (charset))
1697 = (XCHARSET_DIMENSION (charset) == 1
1699 c1 - XCHARSET_BYTE_OFFSET (charset)
1701 (c1 - XCHARSET_BYTE_OFFSET (charset)) * XCHARSET_CHARS (charset)
1702 + c2 - XCHARSET_BYTE_OFFSET (charset))
1703 - XCHARSET_CODE_OFFSET (charset) + XCHARSET_UCS_MIN (charset);
1704 if ((code < XCHARSET_UCS_MIN (charset))
1705 || (XCHARSET_UCS_MAX (charset) < code))
1706 signal_simple_error ("Arguments makes invalid character",
1710 else if (XCHARSET_DIMENSION (charset) == 1)
1712 switch (XCHARSET_CHARS (charset))
1716 + (XCHARSET_FINAL (charset) - '0') * 94 + (c1 - 33);
1719 + (XCHARSET_FINAL (charset) - '0') * 96 + (c1 - 32);
1726 switch (XCHARSET_CHARS (charset))
1729 return MIN_CHAR_94x94
1730 + (XCHARSET_FINAL (charset) - '0') * 94 * 94
1731 + (c1 - 33) * 94 + (c2 - 33);
1733 return MIN_CHAR_96x96
1734 + (XCHARSET_FINAL (charset) - '0') * 96 * 96
1735 + (c1 - 32) * 96 + (c2 - 32);
1743 range_charset_code_point (Lisp_Object charset, Emchar ch)
1747 if ((XCHARSET_UCS_MIN (charset) <= ch)
1748 && (ch <= XCHARSET_UCS_MAX (charset)))
1750 d = ch - XCHARSET_UCS_MIN (charset) + XCHARSET_CODE_OFFSET (charset);
1752 if (XCHARSET_CHARS (charset) == 256)
1754 else if (XCHARSET_DIMENSION (charset) == 1)
1755 return d + XCHARSET_BYTE_OFFSET (charset);
1756 else if (XCHARSET_DIMENSION (charset) == 2)
1758 ((d / XCHARSET_CHARS (charset)
1759 + XCHARSET_BYTE_OFFSET (charset)) << 8)
1760 | (d % XCHARSET_CHARS (charset) + XCHARSET_BYTE_OFFSET (charset));
1761 else if (XCHARSET_DIMENSION (charset) == 3)
1763 ((d / (XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset))
1764 + XCHARSET_BYTE_OFFSET (charset)) << 16)
1765 | ((d / XCHARSET_CHARS (charset)
1766 % XCHARSET_CHARS (charset)
1767 + XCHARSET_BYTE_OFFSET (charset)) << 8)
1768 | (d % XCHARSET_CHARS (charset) + XCHARSET_BYTE_OFFSET (charset));
1769 else /* if (XCHARSET_DIMENSION (charset) == 4) */
1771 ((d / (XCHARSET_CHARS (charset)
1772 * XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset))
1773 + XCHARSET_BYTE_OFFSET (charset)) << 24)
1774 | ((d / (XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset))
1775 % XCHARSET_CHARS (charset)
1776 + XCHARSET_BYTE_OFFSET (charset)) << 16)
1777 | ((d / XCHARSET_CHARS (charset) % XCHARSET_CHARS (charset)
1778 + XCHARSET_BYTE_OFFSET (charset)) << 8)
1779 | (d % XCHARSET_CHARS (charset) + XCHARSET_BYTE_OFFSET (charset));
1781 else if (XCHARSET_CODE_OFFSET (charset) == 0)
1783 if (XCHARSET_DIMENSION (charset) == 1)
1785 if (XCHARSET_CHARS (charset) == 94)
1787 if (((d = ch - (MIN_CHAR_94
1788 + (XCHARSET_FINAL (charset) - '0') * 94)) >= 0)
1792 else if (XCHARSET_CHARS (charset) == 96)
1794 if (((d = ch - (MIN_CHAR_96
1795 + (XCHARSET_FINAL (charset) - '0') * 96)) >= 0)
1802 else if (XCHARSET_DIMENSION (charset) == 2)
1804 if (XCHARSET_CHARS (charset) == 94)
1806 if (((d = ch - (MIN_CHAR_94x94
1807 + (XCHARSET_FINAL (charset) - '0') * 94 * 94))
1810 return (((d / 94) + 33) << 8) | (d % 94 + 33);
1812 else if (XCHARSET_CHARS (charset) == 96)
1814 if (((d = ch - (MIN_CHAR_96x96
1815 + (XCHARSET_FINAL (charset) - '0') * 96 * 96))
1818 return (((d / 96) + 32) << 8) | (d % 96 + 32);
1828 encode_builtin_char_1 (Emchar c, Lisp_Object* charset)
1830 if (c <= MAX_CHAR_BASIC_LATIN)
1832 *charset = Vcharset_ascii;
1837 *charset = Vcharset_control_1;
1842 *charset = Vcharset_latin_iso8859_1;
1846 else if ((MIN_CHAR_GREEK <= c) && (c <= MAX_CHAR_GREEK))
1848 *charset = Vcharset_greek_iso8859_7;
1849 return c - MIN_CHAR_GREEK + 0x20;
1851 else if ((MIN_CHAR_CYRILLIC <= c) && (c <= MAX_CHAR_CYRILLIC))
1853 *charset = Vcharset_cyrillic_iso8859_5;
1854 return c - MIN_CHAR_CYRILLIC + 0x20;
1857 else if ((MIN_CHAR_HEBREW <= c) && (c <= MAX_CHAR_HEBREW))
1859 *charset = Vcharset_hebrew_iso8859_8;
1860 return c - MIN_CHAR_HEBREW + 0x20;
1862 else if ((MIN_CHAR_THAI <= c) && (c <= MAX_CHAR_THAI))
1864 *charset = Vcharset_thai_tis620;
1865 return c - MIN_CHAR_THAI + 0x20;
1868 else if ((MIN_CHAR_HALFWIDTH_KATAKANA <= c)
1869 && (c <= MAX_CHAR_HALFWIDTH_KATAKANA))
1871 return list2 (Vcharset_katakana_jisx0201,
1872 make_int (c - MIN_CHAR_HALFWIDTH_KATAKANA + 33));
1875 else if (c <= MAX_CHAR_BMP)
1877 *charset = Vcharset_ucs_bmp;
1880 else if (c < MIN_CHAR_DAIKANWA)
1882 *charset = Vcharset_ucs;
1886 else if (c <= MAX_CHAR_DAIKANWA)
1888 *charset = Vcharset_ideograph_daikanwa;
1889 return c - MIN_CHAR_DAIKANWA;
1892 else if (c <= MAX_CHAR_MOJIKYO)
1894 *charset = Vcharset_mojikyo;
1895 return c - MIN_CHAR_MOJIKYO;
1897 else if (c < MIN_CHAR_94)
1899 *charset = Vcharset_ucs;
1902 else if (c <= MAX_CHAR_94)
1904 *charset = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_94,
1905 ((c - MIN_CHAR_94) / 94) + '0',
1906 CHARSET_LEFT_TO_RIGHT);
1907 if (!NILP (*charset))
1908 return ((c - MIN_CHAR_94) % 94) + 33;
1911 *charset = Vcharset_ucs;
1915 else if (c <= MAX_CHAR_96)
1917 *charset = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_96,
1918 ((c - MIN_CHAR_96) / 96) + '0',
1919 CHARSET_LEFT_TO_RIGHT);
1920 if (!NILP (*charset))
1921 return ((c - MIN_CHAR_96) % 96) + 32;
1924 *charset = Vcharset_ucs;
1928 else if (c <= MAX_CHAR_94x94)
1931 = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_94X94,
1932 ((c - MIN_CHAR_94x94) / (94 * 94)) + '0',
1933 CHARSET_LEFT_TO_RIGHT);
1934 if (!NILP (*charset))
1935 return (((((c - MIN_CHAR_94x94) / 94) % 94) + 33) << 8)
1936 | (((c - MIN_CHAR_94x94) % 94) + 33);
1939 *charset = Vcharset_ucs;
1943 else if (c <= MAX_CHAR_96x96)
1946 = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_96X96,
1947 ((c - MIN_CHAR_96x96) / (96 * 96)) + '0',
1948 CHARSET_LEFT_TO_RIGHT);
1949 if (!NILP (*charset))
1950 return ((((c - MIN_CHAR_96x96) / 96) % 96) + 32) << 8
1951 | (((c - MIN_CHAR_96x96) % 96) + 32);
1954 *charset = Vcharset_ucs;
1960 *charset = Vcharset_ucs;
1965 Lisp_Object Vdefault_coded_charset_priority_list;
1969 /************************************************************************/
1970 /* Basic charset Lisp functions */
1971 /************************************************************************/
1973 DEFUN ("charsetp", Fcharsetp, 1, 1, 0, /*
1974 Return non-nil if OBJECT is a charset.
1978 return CHARSETP (object) ? Qt : Qnil;
1981 DEFUN ("find-charset", Ffind_charset, 1, 1, 0, /*
1982 Retrieve the charset of the given name.
1983 If CHARSET-OR-NAME is a charset object, it is simply returned.
1984 Otherwise, CHARSET-OR-NAME should be a symbol. If there is no such charset,
1985 nil is returned. Otherwise the associated charset object is returned.
1989 if (CHARSETP (charset_or_name))
1990 return charset_or_name;
1992 CHECK_SYMBOL (charset_or_name);
1993 return Fgethash (charset_or_name, Vcharset_hash_table, Qnil);
1996 DEFUN ("get-charset", Fget_charset, 1, 1, 0, /*
1997 Retrieve the charset of the given name.
1998 Same as `find-charset' except an error is signalled if there is no such
1999 charset instead of returning nil.
2003 Lisp_Object charset = Ffind_charset (name);
2006 signal_simple_error ("No such charset", name);
2010 /* We store the charsets in hash tables with the names as the key and the
2011 actual charset object as the value. Occasionally we need to use them
2012 in a list format. These routines provide us with that. */
2013 struct charset_list_closure
2015 Lisp_Object *charset_list;
2019 add_charset_to_list_mapper (Lisp_Object key, Lisp_Object value,
2020 void *charset_list_closure)
2022 /* This function can GC */
2023 struct charset_list_closure *chcl =
2024 (struct charset_list_closure*) charset_list_closure;
2025 Lisp_Object *charset_list = chcl->charset_list;
2027 *charset_list = Fcons (XCHARSET_NAME (value), *charset_list);
2031 DEFUN ("charset-list", Fcharset_list, 0, 0, 0, /*
2032 Return a list of the names of all defined charsets.
2036 Lisp_Object charset_list = Qnil;
2037 struct gcpro gcpro1;
2038 struct charset_list_closure charset_list_closure;
2040 GCPRO1 (charset_list);
2041 charset_list_closure.charset_list = &charset_list;
2042 elisp_maphash (add_charset_to_list_mapper, Vcharset_hash_table,
2043 &charset_list_closure);
2046 return charset_list;
2049 DEFUN ("charset-name", Fcharset_name, 1, 1, 0, /*
2050 Return the name of the given charset.
2054 return XCHARSET_NAME (Fget_charset (charset));
2057 DEFUN ("make-charset", Fmake_charset, 3, 3, 0, /*
2058 Define a new character set.
2059 This function is for use with Mule support.
2060 NAME is a symbol, the name by which the character set is normally referred.
2061 DOC-STRING is a string describing the character set.
2062 PROPS is a property list, describing the specific nature of the
2063 character set. Recognized properties are:
2065 'short-name Short version of the charset name (ex: Latin-1)
2066 'long-name Long version of the charset name (ex: ISO8859-1 (Latin-1))
2067 'registry A regular expression matching the font registry field for
2069 'dimension Number of octets used to index a character in this charset.
2070 Either 1 or 2. Defaults to 1.
2071 'columns Number of columns used to display a character in this charset.
2072 Only used in TTY mode. (Under X, the actual width of a
2073 character can be derived from the font used to display the
2074 characters.) If unspecified, defaults to the dimension
2075 (this is almost always the correct value).
2076 'chars Number of characters in each dimension (94 or 96).
2077 Defaults to 94. Note that if the dimension is 2, the
2078 character set thus described is 94x94 or 96x96.
2079 'final Final byte of ISO 2022 escape sequence. Must be
2080 supplied. Each combination of (DIMENSION, CHARS) defines a
2081 separate namespace for final bytes. Note that ISO
2082 2022 restricts the final byte to the range
2083 0x30 - 0x7E if dimension == 1, and 0x30 - 0x5F if
2084 dimension == 2. Note also that final bytes in the range
2085 0x30 - 0x3F are reserved for user-defined (not official)
2087 'graphic 0 (use left half of font on output) or 1 (use right half
2088 of font on output). Defaults to 0. For example, for
2089 a font whose registry is ISO8859-1, the left half
2090 (octets 0x20 - 0x7F) is the `ascii' character set, while
2091 the right half (octets 0xA0 - 0xFF) is the `latin-1'
2092 character set. With 'graphic set to 0, the octets
2093 will have their high bit cleared; with it set to 1,
2094 the octets will have their high bit set.
2095 'direction 'l2r (left-to-right) or 'r2l (right-to-left).
2097 'ccl-program A compiled CCL program used to convert a character in
2098 this charset into an index into the font. This is in
2099 addition to the 'graphic property. The CCL program
2100 is passed the octets of the character, with the high
2101 bit cleared and set depending upon whether the value
2102 of the 'graphic property is 0 or 1.
2104 (name, doc_string, props))
2106 int id, dimension = 1, chars = 94, graphic = 0, final = 0, columns = -1;
2107 int direction = CHARSET_LEFT_TO_RIGHT;
2109 Lisp_Object registry = Qnil;
2110 Lisp_Object charset;
2111 Lisp_Object rest, keyword, value;
2112 Lisp_Object ccl_program = Qnil;
2113 Lisp_Object short_name = Qnil, long_name = Qnil;
2114 int byte_offset = -1;
2116 CHECK_SYMBOL (name);
2117 if (!NILP (doc_string))
2118 CHECK_STRING (doc_string);
2120 charset = Ffind_charset (name);
2121 if (!NILP (charset))
2122 signal_simple_error ("Cannot redefine existing charset", name);
2124 EXTERNAL_PROPERTY_LIST_LOOP (rest, keyword, value, props)
2126 if (EQ (keyword, Qshort_name))
2128 CHECK_STRING (value);
2132 if (EQ (keyword, Qlong_name))
2134 CHECK_STRING (value);
2138 else if (EQ (keyword, Qdimension))
2141 dimension = XINT (value);
2142 if (dimension < 1 || dimension > 2)
2143 signal_simple_error ("Invalid value for 'dimension", value);
2146 else if (EQ (keyword, Qchars))
2149 chars = XINT (value);
2150 if (chars != 94 && chars != 96)
2151 signal_simple_error ("Invalid value for 'chars", value);
2154 else if (EQ (keyword, Qcolumns))
2157 columns = XINT (value);
2158 if (columns != 1 && columns != 2)
2159 signal_simple_error ("Invalid value for 'columns", value);
2162 else if (EQ (keyword, Qgraphic))
2165 graphic = XINT (value);
2167 if (graphic < 0 || graphic > 2)
2169 if (graphic < 0 || graphic > 1)
2171 signal_simple_error ("Invalid value for 'graphic", value);
2174 else if (EQ (keyword, Qregistry))
2176 CHECK_STRING (value);
2180 else if (EQ (keyword, Qdirection))
2182 if (EQ (value, Ql2r))
2183 direction = CHARSET_LEFT_TO_RIGHT;
2184 else if (EQ (value, Qr2l))
2185 direction = CHARSET_RIGHT_TO_LEFT;
2187 signal_simple_error ("Invalid value for 'direction", value);
2190 else if (EQ (keyword, Qfinal))
2192 CHECK_CHAR_COERCE_INT (value);
2193 final = XCHAR (value);
2194 if (final < '0' || final > '~')
2195 signal_simple_error ("Invalid value for 'final", value);
2198 else if (EQ (keyword, Qccl_program))
2200 CHECK_VECTOR (value);
2201 ccl_program = value;
2205 signal_simple_error ("Unrecognized property", keyword);
2209 error ("'final must be specified");
2210 if (dimension == 2 && final > 0x5F)
2212 ("Final must be in the range 0x30 - 0x5F for dimension == 2",
2216 type = (chars == 94) ? CHARSET_TYPE_94 : CHARSET_TYPE_96;
2218 type = (chars == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96;
2220 if (!NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_LEFT_TO_RIGHT)) ||
2221 !NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_RIGHT_TO_LEFT)))
2223 ("Character set already defined for this DIMENSION/CHARS/FINAL combo");
2225 id = get_unallocated_leading_byte (dimension);
2227 if (NILP (doc_string))
2228 doc_string = build_string ("");
2230 if (NILP (registry))
2231 registry = build_string ("");
2233 if (NILP (short_name))
2234 XSETSTRING (short_name, XSYMBOL (name)->name);
2236 if (NILP (long_name))
2237 long_name = doc_string;
2240 columns = dimension;
2242 if (byte_offset < 0)
2246 else if (chars == 96)
2252 charset = make_charset (id, name, chars, dimension, columns, graphic,
2253 final, direction, short_name, long_name,
2254 doc_string, registry,
2255 Qnil, 0, 0, 0, byte_offset);
2256 if (!NILP (ccl_program))
2257 XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2261 DEFUN ("make-reverse-direction-charset", Fmake_reverse_direction_charset,
2263 Make a charset equivalent to CHARSET but which goes in the opposite direction.
2264 NEW-NAME is the name of the new charset. Return the new charset.
2266 (charset, new_name))
2268 Lisp_Object new_charset = Qnil;
2269 int id, chars, dimension, columns, graphic, final;
2271 Lisp_Object registry, doc_string, short_name, long_name;
2274 charset = Fget_charset (charset);
2275 if (!NILP (XCHARSET_REVERSE_DIRECTION_CHARSET (charset)))
2276 signal_simple_error ("Charset already has reverse-direction charset",
2279 CHECK_SYMBOL (new_name);
2280 if (!NILP (Ffind_charset (new_name)))
2281 signal_simple_error ("Cannot redefine existing charset", new_name);
2283 cs = XCHARSET (charset);
2285 chars = CHARSET_CHARS (cs);
2286 dimension = CHARSET_DIMENSION (cs);
2287 columns = CHARSET_COLUMNS (cs);
2288 id = get_unallocated_leading_byte (dimension);
2290 graphic = CHARSET_GRAPHIC (cs);
2291 final = CHARSET_FINAL (cs);
2292 direction = CHARSET_RIGHT_TO_LEFT;
2293 if (CHARSET_DIRECTION (cs) == CHARSET_RIGHT_TO_LEFT)
2294 direction = CHARSET_LEFT_TO_RIGHT;
2295 doc_string = CHARSET_DOC_STRING (cs);
2296 short_name = CHARSET_SHORT_NAME (cs);
2297 long_name = CHARSET_LONG_NAME (cs);
2298 registry = CHARSET_REGISTRY (cs);
2300 new_charset = make_charset (id, new_name, chars, dimension, columns,
2301 graphic, final, direction, short_name, long_name,
2302 doc_string, registry,
2304 CHARSET_DECODING_TABLE(cs),
2305 CHARSET_UCS_MIN(cs),
2306 CHARSET_UCS_MAX(cs),
2307 CHARSET_CODE_OFFSET(cs),
2308 CHARSET_BYTE_OFFSET(cs)
2314 CHARSET_REVERSE_DIRECTION_CHARSET (cs) = new_charset;
2315 XCHARSET_REVERSE_DIRECTION_CHARSET (new_charset) = charset;
2320 DEFUN ("define-charset-alias", Fdefine_charset_alias, 2, 2, 0, /*
2321 Define symbol ALIAS as an alias for CHARSET.
2325 CHECK_SYMBOL (alias);
2326 charset = Fget_charset (charset);
2327 return Fputhash (alias, charset, Vcharset_hash_table);
2330 /* #### Reverse direction charsets not yet implemented. */
2332 DEFUN ("charset-reverse-direction-charset", Fcharset_reverse_direction_charset,
2334 Return the reverse-direction charset parallel to CHARSET, if any.
2335 This is the charset with the same properties (in particular, the same
2336 dimension, number of characters per dimension, and final byte) as
2337 CHARSET but whose characters are displayed in the opposite direction.
2341 charset = Fget_charset (charset);
2342 return XCHARSET_REVERSE_DIRECTION_CHARSET (charset);
2346 DEFUN ("charset-from-attributes", Fcharset_from_attributes, 3, 4, 0, /*
2347 Return a charset with the given DIMENSION, CHARS, FINAL, and DIRECTION.
2348 If DIRECTION is omitted, both directions will be checked (left-to-right
2349 will be returned if character sets exist for both directions).
2351 (dimension, chars, final, direction))
2353 int dm, ch, fi, di = -1;
2355 Lisp_Object obj = Qnil;
2357 CHECK_INT (dimension);
2358 dm = XINT (dimension);
2359 if (dm < 1 || dm > 2)
2360 signal_simple_error ("Invalid value for DIMENSION", dimension);
2364 if (ch != 94 && ch != 96)
2365 signal_simple_error ("Invalid value for CHARS", chars);
2367 CHECK_CHAR_COERCE_INT (final);
2369 if (fi < '0' || fi > '~')
2370 signal_simple_error ("Invalid value for FINAL", final);
2372 if (EQ (direction, Ql2r))
2373 di = CHARSET_LEFT_TO_RIGHT;
2374 else if (EQ (direction, Qr2l))
2375 di = CHARSET_RIGHT_TO_LEFT;
2376 else if (!NILP (direction))
2377 signal_simple_error ("Invalid value for DIRECTION", direction);
2379 if (dm == 2 && fi > 0x5F)
2381 ("Final must be in the range 0x30 - 0x5F for dimension == 2", final);
2384 type = (ch == 94) ? CHARSET_TYPE_94 : CHARSET_TYPE_96;
2386 type = (ch == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96;
2390 obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_LEFT_TO_RIGHT);
2392 obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_RIGHT_TO_LEFT);
2395 obj = CHARSET_BY_ATTRIBUTES (type, fi, di);
2398 return XCHARSET_NAME (obj);
2402 DEFUN ("charset-short-name", Fcharset_short_name, 1, 1, 0, /*
2403 Return short name of CHARSET.
2407 return XCHARSET_SHORT_NAME (Fget_charset (charset));
2410 DEFUN ("charset-long-name", Fcharset_long_name, 1, 1, 0, /*
2411 Return long name of CHARSET.
2415 return XCHARSET_LONG_NAME (Fget_charset (charset));
2418 DEFUN ("charset-description", Fcharset_description, 1, 1, 0, /*
2419 Return description of CHARSET.
2423 return XCHARSET_DOC_STRING (Fget_charset (charset));
2426 DEFUN ("charset-dimension", Fcharset_dimension, 1, 1, 0, /*
2427 Return dimension of CHARSET.
2431 return make_int (XCHARSET_DIMENSION (Fget_charset (charset)));
2434 DEFUN ("charset-property", Fcharset_property, 2, 2, 0, /*
2435 Return property PROP of CHARSET.
2436 Recognized properties are those listed in `make-charset', as well as
2437 'name and 'doc-string.
2443 charset = Fget_charset (charset);
2444 cs = XCHARSET (charset);
2446 CHECK_SYMBOL (prop);
2447 if (EQ (prop, Qname)) return CHARSET_NAME (cs);
2448 if (EQ (prop, Qshort_name)) return CHARSET_SHORT_NAME (cs);
2449 if (EQ (prop, Qlong_name)) return CHARSET_LONG_NAME (cs);
2450 if (EQ (prop, Qdoc_string)) return CHARSET_DOC_STRING (cs);
2451 if (EQ (prop, Qdimension)) return make_int (CHARSET_DIMENSION (cs));
2452 if (EQ (prop, Qcolumns)) return make_int (CHARSET_COLUMNS (cs));
2453 if (EQ (prop, Qgraphic)) return make_int (CHARSET_GRAPHIC (cs));
2454 if (EQ (prop, Qfinal)) return make_char (CHARSET_FINAL (cs));
2455 if (EQ (prop, Qchars)) return make_int (CHARSET_CHARS (cs));
2456 if (EQ (prop, Qregistry)) return CHARSET_REGISTRY (cs);
2457 if (EQ (prop, Qccl_program)) return CHARSET_CCL_PROGRAM (cs);
2458 if (EQ (prop, Qdirection))
2459 return CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? Ql2r : Qr2l;
2460 if (EQ (prop, Qreverse_direction_charset))
2462 Lisp_Object obj = CHARSET_REVERSE_DIRECTION_CHARSET (cs);
2466 return XCHARSET_NAME (obj);
2468 signal_simple_error ("Unrecognized charset property name", prop);
2469 return Qnil; /* not reached */
2472 DEFUN ("charset-id", Fcharset_id, 1, 1, 0, /*
2473 Return charset identification number of CHARSET.
2477 return make_int(XCHARSET_LEADING_BYTE (Fget_charset (charset)));
2480 /* #### We need to figure out which properties we really want to
2483 DEFUN ("set-charset-ccl-program", Fset_charset_ccl_program, 2, 2, 0, /*
2484 Set the 'ccl-program property of CHARSET to CCL-PROGRAM.
2486 (charset, ccl_program))
2488 charset = Fget_charset (charset);
2489 CHECK_VECTOR (ccl_program);
2490 XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2495 invalidate_charset_font_caches (Lisp_Object charset)
2497 /* Invalidate font cache entries for charset on all devices. */
2498 Lisp_Object devcons, concons, hash_table;
2499 DEVICE_LOOP_NO_BREAK (devcons, concons)
2501 struct device *d = XDEVICE (XCAR (devcons));
2502 hash_table = Fgethash (charset, d->charset_font_cache, Qunbound);
2503 if (!UNBOUNDP (hash_table))
2504 Fclrhash (hash_table);
2508 DEFUN ("set-charset-registry", Fset_charset_registry, 2, 2, 0, /*
2509 Set the 'registry property of CHARSET to REGISTRY.
2511 (charset, registry))
2513 charset = Fget_charset (charset);
2514 CHECK_STRING (registry);
2515 XCHARSET_REGISTRY (charset) = registry;
2516 invalidate_charset_font_caches (charset);
2517 face_property_was_changed (Vdefault_face, Qfont, Qglobal);
2522 DEFUN ("charset-mapping-table", Fcharset_mapping_table, 1, 1, 0, /*
2523 Return mapping-table of CHARSET.
2527 return XCHARSET_DECODING_TABLE (Fget_charset (charset));
2530 DEFUN ("set-charset-mapping-table", Fset_charset_mapping_table, 2, 2, 0, /*
2531 Set mapping-table of CHARSET to TABLE.
2535 struct Lisp_Charset *cs;
2539 charset = Fget_charset (charset);
2540 cs = XCHARSET (charset);
2544 CHARSET_DECODING_TABLE(cs) = Qnil;
2547 else if (VECTORP (table))
2549 int ccs_len = CHARSET_BYTE_SIZE (cs);
2550 int ret = decoding_table_check_elements (table,
2551 CHARSET_DIMENSION (cs),
2556 signal_simple_error ("Too big table", table);
2558 signal_simple_error ("Invalid element is found", table);
2560 signal_simple_error ("Something wrong", table);
2562 CHARSET_DECODING_TABLE(cs) = Qnil;
2565 signal_error (Qwrong_type_argument,
2566 list2 (build_translated_string ("vector-or-nil-p"),
2569 byte_offset = CHARSET_BYTE_OFFSET (cs);
2570 switch (CHARSET_DIMENSION (cs))
2573 for (i = 0; i < XVECTOR_LENGTH (table); i++)
2575 Lisp_Object c = XVECTOR_DATA(table)[i];
2578 put_char_ccs_code_point (c, charset,
2579 make_int (i + byte_offset));
2583 for (i = 0; i < XVECTOR_LENGTH (table); i++)
2585 Lisp_Object v = XVECTOR_DATA(table)[i];
2591 for (j = 0; j < XVECTOR_LENGTH (v); j++)
2593 Lisp_Object c = XVECTOR_DATA(v)[j];
2596 put_char_ccs_code_point
2598 make_int ( ( (i + byte_offset) << 8 )
2604 put_char_ccs_code_point (v, charset,
2605 make_int (i + byte_offset));
2614 /************************************************************************/
2615 /* Lisp primitives for working with characters */
2616 /************************************************************************/
2619 DEFUN ("decode-char", Fdecode_char, 2, 2, 0, /*
2620 Make a character from CHARSET and code-point CODE.
2626 charset = Fget_charset (charset);
2629 if (XCHARSET_GRAPHIC (charset) == 1)
2631 return make_char (DECODE_CHAR (charset, c));
2635 DEFUN ("make-char", Fmake_char, 2, 3, 0, /*
2636 Make a character from CHARSET and octets ARG1 and ARG2.
2637 ARG2 is required only for characters from two-dimensional charsets.
2638 For example, (make-char 'latin-iso8859-2 185) will return the Latin 2
2639 character s with caron.
2641 (charset, arg1, arg2))
2645 int lowlim, highlim;
2647 charset = Fget_charset (charset);
2648 cs = XCHARSET (charset);
2650 if (EQ (charset, Vcharset_ascii)) lowlim = 0, highlim = 127;
2651 else if (EQ (charset, Vcharset_control_1)) lowlim = 0, highlim = 31;
2653 else if (CHARSET_CHARS (cs) == 256) lowlim = 0, highlim = 255;
2655 else if (CHARSET_CHARS (cs) == 94) lowlim = 33, highlim = 126;
2656 else /* CHARSET_CHARS (cs) == 96) */ lowlim = 32, highlim = 127;
2659 /* It is useful (and safe, according to Olivier Galibert) to strip
2660 the 8th bit off ARG1 and ARG2 becaue it allows programmers to
2661 write (make-char 'latin-iso8859-2 CODE) where code is the actual
2662 Latin 2 code of the character. */
2670 if (a1 < lowlim || a1 > highlim)
2671 args_out_of_range_3 (arg1, make_int (lowlim), make_int (highlim));
2673 if (CHARSET_DIMENSION (cs) == 1)
2677 ("Charset is of dimension one; second octet must be nil", arg2);
2678 return make_char (MAKE_CHAR (charset, a1, 0));
2687 a2 = XINT (arg2) & 0x7f;
2689 if (a2 < lowlim || a2 > highlim)
2690 args_out_of_range_3 (arg2, make_int (lowlim), make_int (highlim));
2692 return make_char (MAKE_CHAR (charset, a1, a2));
2695 DEFUN ("char-charset", Fchar_charset, 1, 1, 0, /*
2696 Return the character set of char CH.
2700 CHECK_CHAR_COERCE_INT (ch);
2702 return XCHARSET_NAME (CHAR_CHARSET (XCHAR (ch)));
2705 DEFUN ("char-octet", Fchar_octet, 1, 2, 0, /*
2706 Return the octet numbered N (should be 0 or 1) of char CH.
2707 N defaults to 0 if omitted.
2711 Lisp_Object charset;
2714 CHECK_CHAR_COERCE_INT (ch);
2716 BREAKUP_CHAR (XCHAR (ch), charset, octet0, octet1);
2718 if (NILP (n) || EQ (n, Qzero))
2719 return make_int (octet0);
2720 else if (EQ (n, make_int (1)))
2721 return make_int (octet1);
2723 signal_simple_error ("Octet number must be 0 or 1", n);
2726 DEFUN ("split-char", Fsplit_char, 1, 1, 0, /*
2727 Return list of charset and one or two position-codes of CHAR.
2731 /* This function can GC */
2732 struct gcpro gcpro1, gcpro2;
2733 Lisp_Object charset = Qnil;
2734 Lisp_Object rc = Qnil;
2742 GCPRO2 (charset, rc);
2743 CHECK_CHAR_COERCE_INT (character);
2746 code_point = ENCODE_CHAR (XCHAR (character), charset);
2747 dimension = XCHARSET_DIMENSION (charset);
2748 while (dimension > 0)
2750 rc = Fcons (make_int (code_point & 255), rc);
2754 rc = Fcons (XCHARSET_NAME (charset), rc);
2756 BREAKUP_CHAR (XCHAR (character), charset, c1, c2);
2758 if (XCHARSET_DIMENSION (Fget_charset (charset)) == 2)
2760 rc = list3 (XCHARSET_NAME (charset), make_int (c1), make_int (c2));
2764 rc = list2 (XCHARSET_NAME (charset), make_int (c1));
2773 #ifdef ENABLE_COMPOSITE_CHARS
2774 /************************************************************************/
2775 /* composite character functions */
2776 /************************************************************************/
2779 lookup_composite_char (Bufbyte *str, int len)
2781 Lisp_Object lispstr = make_string (str, len);
2782 Lisp_Object ch = Fgethash (lispstr,
2783 Vcomposite_char_string2char_hash_table,
2789 if (composite_char_row_next >= 128)
2790 signal_simple_error ("No more composite chars available", lispstr);
2791 emch = MAKE_CHAR (Vcharset_composite, composite_char_row_next,
2792 composite_char_col_next);
2793 Fputhash (make_char (emch), lispstr,
2794 Vcomposite_char_char2string_hash_table);
2795 Fputhash (lispstr, make_char (emch),
2796 Vcomposite_char_string2char_hash_table);
2797 composite_char_col_next++;
2798 if (composite_char_col_next >= 128)
2800 composite_char_col_next = 32;
2801 composite_char_row_next++;
2810 composite_char_string (Emchar ch)
2812 Lisp_Object str = Fgethash (make_char (ch),
2813 Vcomposite_char_char2string_hash_table,
2815 assert (!UNBOUNDP (str));
2819 xxDEFUN ("make-composite-char", Fmake_composite_char, 1, 1, 0, /*
2820 Convert a string into a single composite character.
2821 The character is the result of overstriking all the characters in
2826 CHECK_STRING (string);
2827 return make_char (lookup_composite_char (XSTRING_DATA (string),
2828 XSTRING_LENGTH (string)));
2831 xxDEFUN ("composite-char-string", Fcomposite_char_string, 1, 1, 0, /*
2832 Return a string of the characters comprising a composite character.
2840 if (CHAR_LEADING_BYTE (emch) != LEADING_BYTE_COMPOSITE)
2841 signal_simple_error ("Must be composite char", ch);
2842 return composite_char_string (emch);
2844 #endif /* ENABLE_COMPOSITE_CHARS */
2847 /************************************************************************/
2848 /* initialization */
2849 /************************************************************************/
2852 syms_of_mule_charset (void)
2855 INIT_LRECORD_IMPLEMENTATION (byte_table);
2856 INIT_LRECORD_IMPLEMENTATION (char_id_table);
2858 INIT_LRECORD_IMPLEMENTATION (charset);
2860 DEFSUBR (Fcharsetp);
2861 DEFSUBR (Ffind_charset);
2862 DEFSUBR (Fget_charset);
2863 DEFSUBR (Fcharset_list);
2864 DEFSUBR (Fcharset_name);
2865 DEFSUBR (Fmake_charset);
2866 DEFSUBR (Fmake_reverse_direction_charset);
2867 /* DEFSUBR (Freverse_direction_charset); */
2868 DEFSUBR (Fdefine_charset_alias);
2869 DEFSUBR (Fcharset_from_attributes);
2870 DEFSUBR (Fcharset_short_name);
2871 DEFSUBR (Fcharset_long_name);
2872 DEFSUBR (Fcharset_description);
2873 DEFSUBR (Fcharset_dimension);
2874 DEFSUBR (Fcharset_property);
2875 DEFSUBR (Fcharset_id);
2876 DEFSUBR (Fset_charset_ccl_program);
2877 DEFSUBR (Fset_charset_registry);
2879 DEFSUBR (Fchar_attribute_alist);
2880 DEFSUBR (Fget_char_attribute);
2881 DEFSUBR (Fput_char_attribute);
2882 DEFSUBR (Fremove_char_attribute);
2883 DEFSUBR (Fdefine_char);
2884 DEFSUBR (Fchar_variants);
2885 DEFSUBR (Fget_composite_char);
2886 DEFSUBR (Fcharset_mapping_table);
2887 DEFSUBR (Fset_charset_mapping_table);
2891 DEFSUBR (Fdecode_char);
2893 DEFSUBR (Fmake_char);
2894 DEFSUBR (Fchar_charset);
2895 DEFSUBR (Fchar_octet);
2896 DEFSUBR (Fsplit_char);
2898 #ifdef ENABLE_COMPOSITE_CHARS
2899 DEFSUBR (Fmake_composite_char);
2900 DEFSUBR (Fcomposite_char_string);
2903 defsymbol (&Qcharsetp, "charsetp");
2904 defsymbol (&Qregistry, "registry");
2905 defsymbol (&Qfinal, "final");
2906 defsymbol (&Qgraphic, "graphic");
2907 defsymbol (&Qdirection, "direction");
2908 defsymbol (&Qreverse_direction_charset, "reverse-direction-charset");
2909 defsymbol (&Qshort_name, "short-name");
2910 defsymbol (&Qlong_name, "long-name");
2912 defsymbol (&Ql2r, "l2r");
2913 defsymbol (&Qr2l, "r2l");
2915 /* Charsets, compatible with FSF 20.3
2916 Naming convention is Script-Charset[-Edition] */
2917 defsymbol (&Qascii, "ascii");
2918 defsymbol (&Qcontrol_1, "control-1");
2919 defsymbol (&Qlatin_iso8859_1, "latin-iso8859-1");
2920 defsymbol (&Qlatin_iso8859_2, "latin-iso8859-2");
2921 defsymbol (&Qlatin_iso8859_3, "latin-iso8859-3");
2922 defsymbol (&Qlatin_iso8859_4, "latin-iso8859-4");
2923 defsymbol (&Qthai_tis620, "thai-tis620");
2924 defsymbol (&Qgreek_iso8859_7, "greek-iso8859-7");
2925 defsymbol (&Qarabic_iso8859_6, "arabic-iso8859-6");
2926 defsymbol (&Qhebrew_iso8859_8, "hebrew-iso8859-8");
2927 defsymbol (&Qkatakana_jisx0201, "katakana-jisx0201");
2928 defsymbol (&Qlatin_jisx0201, "latin-jisx0201");
2929 defsymbol (&Qcyrillic_iso8859_5, "cyrillic-iso8859-5");
2930 defsymbol (&Qlatin_iso8859_9, "latin-iso8859-9");
2931 defsymbol (&Qjapanese_jisx0208_1978, "japanese-jisx0208-1978");
2932 defsymbol (&Qchinese_gb2312, "chinese-gb2312");
2933 defsymbol (&Qjapanese_jisx0208, "japanese-jisx0208");
2934 defsymbol (&Qjapanese_jisx0208_1990, "japanese-jisx0208-1990");
2935 defsymbol (&Qkorean_ksc5601, "korean-ksc5601");
2936 defsymbol (&Qjapanese_jisx0212, "japanese-jisx0212");
2937 defsymbol (&Qchinese_cns11643_1, "chinese-cns11643-1");
2938 defsymbol (&Qchinese_cns11643_2, "chinese-cns11643-2");
2940 defsymbol (&Qname, "name");
2941 defsymbol (&Q_ucs, "->ucs");
2942 defsymbol (&Q_decomposition, "->decomposition");
2943 defsymbol (&Qcompat, "compat");
2944 defsymbol (&Qisolated, "isolated");
2945 defsymbol (&Qinitial, "initial");
2946 defsymbol (&Qmedial, "medial");
2947 defsymbol (&Qfinal, "final");
2948 defsymbol (&Qvertical, "vertical");
2949 defsymbol (&QnoBreak, "noBreak");
2950 defsymbol (&Qfraction, "fraction");
2951 defsymbol (&Qsuper, "super");
2952 defsymbol (&Qsub, "sub");
2953 defsymbol (&Qcircle, "circle");
2954 defsymbol (&Qsquare, "square");
2955 defsymbol (&Qwide, "wide");
2956 defsymbol (&Qnarrow, "narrow");
2957 defsymbol (&Qsmall, "small");
2958 defsymbol (&Qfont, "font");
2959 defsymbol (&Qucs, "ucs");
2960 defsymbol (&Qucs_bmp, "ucs-bmp");
2961 defsymbol (&Qlatin_viscii, "latin-viscii");
2962 defsymbol (&Qlatin_tcvn5712, "latin-tcvn5712");
2963 defsymbol (&Qlatin_viscii_lower, "latin-viscii-lower");
2964 defsymbol (&Qlatin_viscii_upper, "latin-viscii-upper");
2965 defsymbol (&Qvietnamese_viscii_lower, "vietnamese-viscii-lower");
2966 defsymbol (&Qvietnamese_viscii_upper, "vietnamese-viscii-upper");
2967 defsymbol (&Qideograph_daikanwa, "ideograph-daikanwa");
2968 defsymbol (&Qmojikyo, "mojikyo");
2969 defsymbol (&Qmojikyo_pj_1, "mojikyo-pj-1");
2970 defsymbol (&Qmojikyo_pj_2, "mojikyo-pj-2");
2971 defsymbol (&Qmojikyo_pj_3, "mojikyo-pj-3");
2972 defsymbol (&Qmojikyo_pj_4, "mojikyo-pj-4");
2973 defsymbol (&Qmojikyo_pj_5, "mojikyo-pj-5");
2974 defsymbol (&Qmojikyo_pj_6, "mojikyo-pj-6");
2975 defsymbol (&Qmojikyo_pj_7, "mojikyo-pj-7");
2976 defsymbol (&Qmojikyo_pj_8, "mojikyo-pj-8");
2977 defsymbol (&Qmojikyo_pj_9, "mojikyo-pj-9");
2978 defsymbol (&Qmojikyo_pj_10, "mojikyo-pj-10");
2979 defsymbol (&Qmojikyo_pj_11, "mojikyo-pj-11");
2980 defsymbol (&Qmojikyo_pj_12, "mojikyo-pj-12");
2981 defsymbol (&Qmojikyo_pj_13, "mojikyo-pj-13");
2982 defsymbol (&Qmojikyo_pj_14, "mojikyo-pj-14");
2983 defsymbol (&Qmojikyo_pj_15, "mojikyo-pj-15");
2984 defsymbol (&Qmojikyo_pj_16, "mojikyo-pj-16");
2985 defsymbol (&Qmojikyo_pj_17, "mojikyo-pj-17");
2986 defsymbol (&Qmojikyo_pj_18, "mojikyo-pj-18");
2987 defsymbol (&Qmojikyo_pj_19, "mojikyo-pj-19");
2988 defsymbol (&Qmojikyo_pj_20, "mojikyo-pj-20");
2989 defsymbol (&Qmojikyo_pj_21, "mojikyo-pj-21");
2990 defsymbol (&Qethiopic_ucs, "ethiopic-ucs");
2992 defsymbol (&Qchinese_big5_1, "chinese-big5-1");
2993 defsymbol (&Qchinese_big5_2, "chinese-big5-2");
2995 defsymbol (&Qcomposite, "composite");
2999 vars_of_mule_charset (void)
3006 chlook = xnew (struct charset_lookup);
3007 dumpstruct (&chlook, &charset_lookup_description);
3009 /* Table of charsets indexed by leading byte. */
3010 for (i = 0; i < countof (chlook->charset_by_leading_byte); i++)
3011 chlook->charset_by_leading_byte[i] = Qnil;
3014 /* Table of charsets indexed by type/final-byte. */
3015 for (i = 0; i < countof (chlook->charset_by_attributes); i++)
3016 for (j = 0; j < countof (chlook->charset_by_attributes[0]); j++)
3017 chlook->charset_by_attributes[i][j] = Qnil;
3019 /* Table of charsets indexed by type/final-byte/direction. */
3020 for (i = 0; i < countof (chlook->charset_by_attributes); i++)
3021 for (j = 0; j < countof (chlook->charset_by_attributes[0]); j++)
3022 for (k = 0; k < countof (chlook->charset_by_attributes[0][0]); k++)
3023 chlook->charset_by_attributes[i][j][k] = Qnil;
3027 chlook->next_allocated_leading_byte = MIN_LEADING_BYTE_PRIVATE;
3029 chlook->next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1;
3030 chlook->next_allocated_2_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_2;
3034 leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
3035 DEFVAR_INT ("leading-code-private-11", &leading_code_private_11 /*
3036 Leading-code of private TYPE9N charset of column-width 1.
3038 leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
3042 Vutf_2000_version = build_string("0.15 (Sangō)");
3043 DEFVAR_LISP ("utf-2000-version", &Vutf_2000_version /*
3044 Version number of UTF-2000.
3047 staticpro (&Vcharacter_attribute_table);
3048 Vcharacter_attribute_table = make_char_id_table (Qnil, 0);
3050 staticpro (&Vcharacter_name_table);
3051 Vcharacter_name_table = make_char_id_table (Qnil, 0);
3053 /* staticpro (&Vcharacter_composition_table); */
3054 Vcharacter_composition_table = make_char_id_table (Qnil, -1);
3056 staticpro (&Vcharacter_variant_table);
3057 Vcharacter_variant_table = make_char_id_table (Qnil, 0);
3059 Vdefault_coded_charset_priority_list = Qnil;
3060 DEFVAR_LISP ("default-coded-charset-priority-list",
3061 &Vdefault_coded_charset_priority_list /*
3062 Default order of preferred coded-character-sets.
3068 complex_vars_of_mule_charset (void)
3070 staticpro (&Vcharset_hash_table);
3071 Vcharset_hash_table =
3072 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3074 /* Predefined character sets. We store them into variables for
3078 staticpro (&Vcharset_ucs);
3080 make_charset (LEADING_BYTE_UCS, Qucs, 256, 4,
3081 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3082 build_string ("UCS"),
3083 build_string ("UCS"),
3084 build_string ("ISO/IEC 10646"),
3086 Qnil, 0, 0xFFFFFFF, 0, 0);
3087 staticpro (&Vcharset_ucs_bmp);
3089 make_charset (LEADING_BYTE_UCS_BMP, Qucs_bmp, 256, 2,
3090 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3091 build_string ("BMP"),
3092 build_string ("BMP"),
3093 build_string ("ISO/IEC 10646 Group 0 Plane 0 (BMP)"),
3094 build_string ("\\(ISO10646.*-1\\|UNICODE[23]?-0\\)"),
3095 Qnil, 0, 0xFFFF, 0, 0);
3097 # define MIN_CHAR_THAI 0
3098 # define MAX_CHAR_THAI 0
3099 # define MIN_CHAR_HEBREW 0
3100 # define MAX_CHAR_HEBREW 0
3101 # define MIN_CHAR_HALFWIDTH_KATAKANA 0
3102 # define MAX_CHAR_HALFWIDTH_KATAKANA 0
3104 staticpro (&Vcharset_ascii);
3106 make_charset (LEADING_BYTE_ASCII, Qascii, 94, 1,
3107 1, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3108 build_string ("ASCII"),
3109 build_string ("ASCII)"),
3110 build_string ("ASCII (ISO646 IRV)"),
3111 build_string ("\\(iso8859-[0-9]*\\|-ascii\\)"),
3112 Qnil, 0, 0x7F, 0, 0);
3113 staticpro (&Vcharset_control_1);
3114 Vcharset_control_1 =
3115 make_charset (LEADING_BYTE_CONTROL_1, Qcontrol_1, 94, 1,
3116 1, 1, 0, CHARSET_LEFT_TO_RIGHT,
3117 build_string ("C1"),
3118 build_string ("Control characters"),
3119 build_string ("Control characters 128-191"),
3121 Qnil, 0x80, 0x9F, 0, 0);
3122 staticpro (&Vcharset_latin_iso8859_1);
3123 Vcharset_latin_iso8859_1 =
3124 make_charset (LEADING_BYTE_LATIN_ISO8859_1, Qlatin_iso8859_1, 96, 1,
3125 1, 1, 'A', CHARSET_LEFT_TO_RIGHT,
3126 build_string ("Latin-1"),
3127 build_string ("ISO8859-1 (Latin-1)"),
3128 build_string ("ISO8859-1 (Latin-1)"),
3129 build_string ("iso8859-1"),
3130 Qnil, 0xA0, 0xFF, 0, 32);
3131 staticpro (&Vcharset_latin_iso8859_2);
3132 Vcharset_latin_iso8859_2 =
3133 make_charset (LEADING_BYTE_LATIN_ISO8859_2, Qlatin_iso8859_2, 96, 1,
3134 1, 1, 'B', CHARSET_LEFT_TO_RIGHT,
3135 build_string ("Latin-2"),
3136 build_string ("ISO8859-2 (Latin-2)"),
3137 build_string ("ISO8859-2 (Latin-2)"),
3138 build_string ("iso8859-2"),
3140 staticpro (&Vcharset_latin_iso8859_3);
3141 Vcharset_latin_iso8859_3 =
3142 make_charset (LEADING_BYTE_LATIN_ISO8859_3, Qlatin_iso8859_3, 96, 1,
3143 1, 1, 'C', CHARSET_LEFT_TO_RIGHT,
3144 build_string ("Latin-3"),
3145 build_string ("ISO8859-3 (Latin-3)"),
3146 build_string ("ISO8859-3 (Latin-3)"),
3147 build_string ("iso8859-3"),
3149 staticpro (&Vcharset_latin_iso8859_4);
3150 Vcharset_latin_iso8859_4 =
3151 make_charset (LEADING_BYTE_LATIN_ISO8859_4, Qlatin_iso8859_4, 96, 1,
3152 1, 1, 'D', CHARSET_LEFT_TO_RIGHT,
3153 build_string ("Latin-4"),
3154 build_string ("ISO8859-4 (Latin-4)"),
3155 build_string ("ISO8859-4 (Latin-4)"),
3156 build_string ("iso8859-4"),
3158 staticpro (&Vcharset_thai_tis620);
3159 Vcharset_thai_tis620 =
3160 make_charset (LEADING_BYTE_THAI_TIS620, Qthai_tis620, 96, 1,
3161 1, 1, 'T', CHARSET_LEFT_TO_RIGHT,
3162 build_string ("TIS620"),
3163 build_string ("TIS620 (Thai)"),
3164 build_string ("TIS620.2529 (Thai)"),
3165 build_string ("tis620"),
3166 Qnil, MIN_CHAR_THAI, MAX_CHAR_THAI, 0, 32);
3167 staticpro (&Vcharset_greek_iso8859_7);
3168 Vcharset_greek_iso8859_7 =
3169 make_charset (LEADING_BYTE_GREEK_ISO8859_7, Qgreek_iso8859_7, 96, 1,
3170 1, 1, 'F', CHARSET_LEFT_TO_RIGHT,
3171 build_string ("ISO8859-7"),
3172 build_string ("ISO8859-7 (Greek)"),
3173 build_string ("ISO8859-7 (Greek)"),
3174 build_string ("iso8859-7"),
3176 0 /* MIN_CHAR_GREEK */,
3177 0 /* MAX_CHAR_GREEK */, 0, 32);
3178 staticpro (&Vcharset_arabic_iso8859_6);
3179 Vcharset_arabic_iso8859_6 =
3180 make_charset (LEADING_BYTE_ARABIC_ISO8859_6, Qarabic_iso8859_6, 96, 1,
3181 1, 1, 'G', CHARSET_RIGHT_TO_LEFT,
3182 build_string ("ISO8859-6"),
3183 build_string ("ISO8859-6 (Arabic)"),
3184 build_string ("ISO8859-6 (Arabic)"),
3185 build_string ("iso8859-6"),
3187 staticpro (&Vcharset_hebrew_iso8859_8);
3188 Vcharset_hebrew_iso8859_8 =
3189 make_charset (LEADING_BYTE_HEBREW_ISO8859_8, Qhebrew_iso8859_8, 96, 1,
3190 1, 1, 'H', CHARSET_RIGHT_TO_LEFT,
3191 build_string ("ISO8859-8"),
3192 build_string ("ISO8859-8 (Hebrew)"),
3193 build_string ("ISO8859-8 (Hebrew)"),
3194 build_string ("iso8859-8"),
3195 Qnil, MIN_CHAR_HEBREW, MAX_CHAR_HEBREW, 0, 32);
3196 staticpro (&Vcharset_katakana_jisx0201);
3197 Vcharset_katakana_jisx0201 =
3198 make_charset (LEADING_BYTE_KATAKANA_JISX0201, Qkatakana_jisx0201, 94, 1,
3199 1, 1, 'I', CHARSET_LEFT_TO_RIGHT,
3200 build_string ("JISX0201 Kana"),
3201 build_string ("JISX0201.1976 (Japanese Kana)"),
3202 build_string ("JISX0201.1976 Japanese Kana"),
3203 build_string ("jisx0201\\.1976"),
3205 staticpro (&Vcharset_latin_jisx0201);
3206 Vcharset_latin_jisx0201 =
3207 make_charset (LEADING_BYTE_LATIN_JISX0201, Qlatin_jisx0201, 94, 1,
3208 1, 0, 'J', CHARSET_LEFT_TO_RIGHT,
3209 build_string ("JISX0201 Roman"),
3210 build_string ("JISX0201.1976 (Japanese Roman)"),
3211 build_string ("JISX0201.1976 Japanese Roman"),
3212 build_string ("jisx0201\\.1976"),
3214 staticpro (&Vcharset_cyrillic_iso8859_5);
3215 Vcharset_cyrillic_iso8859_5 =
3216 make_charset (LEADING_BYTE_CYRILLIC_ISO8859_5, Qcyrillic_iso8859_5, 96, 1,
3217 1, 1, 'L', CHARSET_LEFT_TO_RIGHT,
3218 build_string ("ISO8859-5"),
3219 build_string ("ISO8859-5 (Cyrillic)"),
3220 build_string ("ISO8859-5 (Cyrillic)"),
3221 build_string ("iso8859-5"),
3223 0 /* MIN_CHAR_CYRILLIC */,
3224 0 /* MAX_CHAR_CYRILLIC */, 0, 32);
3225 staticpro (&Vcharset_latin_iso8859_9);
3226 Vcharset_latin_iso8859_9 =
3227 make_charset (LEADING_BYTE_LATIN_ISO8859_9, Qlatin_iso8859_9, 96, 1,
3228 1, 1, 'M', CHARSET_LEFT_TO_RIGHT,
3229 build_string ("Latin-5"),
3230 build_string ("ISO8859-9 (Latin-5)"),
3231 build_string ("ISO8859-9 (Latin-5)"),
3232 build_string ("iso8859-9"),
3234 staticpro (&Vcharset_japanese_jisx0208_1978);
3235 Vcharset_japanese_jisx0208_1978 =
3236 make_charset (LEADING_BYTE_JAPANESE_JISX0208_1978,
3237 Qjapanese_jisx0208_1978, 94, 2,
3238 2, 0, '@', CHARSET_LEFT_TO_RIGHT,
3239 build_string ("JIS X0208:1978"),
3240 build_string ("JIS X0208:1978 (Japanese)"),
3242 ("JIS X0208:1978 Japanese Kanji (so called \"old JIS\")"),
3243 build_string ("\\(jisx0208\\|jisc6226\\)\\.1978"),
3245 staticpro (&Vcharset_chinese_gb2312);
3246 Vcharset_chinese_gb2312 =
3247 make_charset (LEADING_BYTE_CHINESE_GB2312, Qchinese_gb2312, 94, 2,
3248 2, 0, 'A', CHARSET_LEFT_TO_RIGHT,
3249 build_string ("GB2312"),
3250 build_string ("GB2312)"),
3251 build_string ("GB2312 Chinese simplified"),
3252 build_string ("gb2312"),
3254 staticpro (&Vcharset_japanese_jisx0208);
3255 Vcharset_japanese_jisx0208 =
3256 make_charset (LEADING_BYTE_JAPANESE_JISX0208, Qjapanese_jisx0208, 94, 2,
3257 2, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3258 build_string ("JISX0208"),
3259 build_string ("JIS X0208:1983 (Japanese)"),
3260 build_string ("JIS X0208:1983 Japanese Kanji"),
3261 build_string ("jisx0208\\.1983"),
3264 staticpro (&Vcharset_japanese_jisx0208_1990);
3265 Vcharset_japanese_jisx0208_1990 =
3266 make_charset (LEADING_BYTE_JAPANESE_JISX0208_1990,
3267 Qjapanese_jisx0208_1990, 94, 2,
3268 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3269 build_string ("JISX0208-1990"),
3270 build_string ("JIS X0208:1990 (Japanese)"),
3271 build_string ("JIS X0208:1990 Japanese Kanji"),
3272 build_string ("jisx0208\\.1990"),
3274 MIN_CHAR_JIS_X0208_1990,
3275 MAX_CHAR_JIS_X0208_1990, 0, 33);
3277 staticpro (&Vcharset_korean_ksc5601);
3278 Vcharset_korean_ksc5601 =
3279 make_charset (LEADING_BYTE_KOREAN_KSC5601, Qkorean_ksc5601, 94, 2,
3280 2, 0, 'C', CHARSET_LEFT_TO_RIGHT,
3281 build_string ("KSC5601"),
3282 build_string ("KSC5601 (Korean"),
3283 build_string ("KSC5601 Korean Hangul and Hanja"),
3284 build_string ("ksc5601"),
3286 staticpro (&Vcharset_japanese_jisx0212);
3287 Vcharset_japanese_jisx0212 =
3288 make_charset (LEADING_BYTE_JAPANESE_JISX0212, Qjapanese_jisx0212, 94, 2,
3289 2, 0, 'D', CHARSET_LEFT_TO_RIGHT,
3290 build_string ("JISX0212"),
3291 build_string ("JISX0212 (Japanese)"),
3292 build_string ("JISX0212 Japanese Supplement"),
3293 build_string ("jisx0212"),
3296 #define CHINESE_CNS_PLANE_RE(n) "cns11643[.-]\\(.*[.-]\\)?" n "$"
3297 staticpro (&Vcharset_chinese_cns11643_1);
3298 Vcharset_chinese_cns11643_1 =
3299 make_charset (LEADING_BYTE_CHINESE_CNS11643_1, Qchinese_cns11643_1, 94, 2,
3300 2, 0, 'G', CHARSET_LEFT_TO_RIGHT,
3301 build_string ("CNS11643-1"),
3302 build_string ("CNS11643-1 (Chinese traditional)"),
3304 ("CNS 11643 Plane 1 Chinese traditional"),
3305 build_string (CHINESE_CNS_PLANE_RE("1")),
3307 staticpro (&Vcharset_chinese_cns11643_2);
3308 Vcharset_chinese_cns11643_2 =
3309 make_charset (LEADING_BYTE_CHINESE_CNS11643_2, Qchinese_cns11643_2, 94, 2,
3310 2, 0, 'H', CHARSET_LEFT_TO_RIGHT,
3311 build_string ("CNS11643-2"),
3312 build_string ("CNS11643-2 (Chinese traditional)"),
3314 ("CNS 11643 Plane 2 Chinese traditional"),
3315 build_string (CHINESE_CNS_PLANE_RE("2")),
3318 staticpro (&Vcharset_latin_tcvn5712);
3319 Vcharset_latin_tcvn5712 =
3320 make_charset (LEADING_BYTE_LATIN_TCVN5712, Qlatin_tcvn5712, 96, 1,
3321 1, 1, 'Z', CHARSET_LEFT_TO_RIGHT,
3322 build_string ("TCVN 5712"),
3323 build_string ("TCVN 5712 (VSCII-2)"),
3324 build_string ("Vietnamese TCVN 5712:1983 (VSCII-2)"),
3325 build_string ("tcvn5712-1"),
3327 staticpro (&Vcharset_latin_viscii_lower);
3328 Vcharset_latin_viscii_lower =
3329 make_charset (LEADING_BYTE_LATIN_VISCII_LOWER, Qlatin_viscii_lower, 96, 1,
3330 1, 1, '1', CHARSET_LEFT_TO_RIGHT,
3331 build_string ("VISCII lower"),
3332 build_string ("VISCII lower (Vietnamese)"),
3333 build_string ("VISCII lower (Vietnamese)"),
3334 build_string ("MULEVISCII-LOWER"),
3336 staticpro (&Vcharset_latin_viscii_upper);
3337 Vcharset_latin_viscii_upper =
3338 make_charset (LEADING_BYTE_LATIN_VISCII_UPPER, Qlatin_viscii_upper, 96, 1,
3339 1, 1, '2', CHARSET_LEFT_TO_RIGHT,
3340 build_string ("VISCII upper"),
3341 build_string ("VISCII upper (Vietnamese)"),
3342 build_string ("VISCII upper (Vietnamese)"),
3343 build_string ("MULEVISCII-UPPER"),
3345 staticpro (&Vcharset_latin_viscii);
3346 Vcharset_latin_viscii =
3347 make_charset (LEADING_BYTE_LATIN_VISCII, Qlatin_viscii, 256, 1,
3348 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3349 build_string ("VISCII"),
3350 build_string ("VISCII 1.1 (Vietnamese)"),
3351 build_string ("VISCII 1.1 (Vietnamese)"),
3352 build_string ("VISCII1\\.1"),
3354 staticpro (&Vcharset_ideograph_daikanwa);
3355 Vcharset_ideograph_daikanwa =
3356 make_charset (LEADING_BYTE_DAIKANWA, Qideograph_daikanwa, 256, 2,
3357 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3358 build_string ("Daikanwa"),
3359 build_string ("Morohashi's Daikanwa"),
3360 build_string ("Daikanwa dictionary by MOROHASHI Tetsuji"),
3361 build_string ("Daikanwa"),
3362 Qnil, MIN_CHAR_DAIKANWA, MAX_CHAR_DAIKANWA, 0, 0);
3363 staticpro (&Vcharset_mojikyo);
3365 make_charset (LEADING_BYTE_MOJIKYO, Qmojikyo, 256, 3,
3366 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3367 build_string ("Mojikyo"),
3368 build_string ("Mojikyo"),
3369 build_string ("Konjaku-Mojikyo"),
3371 Qnil, MIN_CHAR_MOJIKYO, MAX_CHAR_MOJIKYO, 0, 0);
3372 staticpro (&Vcharset_mojikyo_pj_1);
3373 Vcharset_mojikyo_pj_1 =
3374 make_charset (LEADING_BYTE_MOJIKYO_PJ_1, Qmojikyo_pj_1, 94, 2,
3375 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3376 build_string ("Mojikyo-PJ-1"),
3377 build_string ("Mojikyo (pseudo JIS encoding) part 1"),
3379 ("Konjaku-Mojikyo (pseudo JIS encoding) part 1"),
3380 build_string ("jisx0208\\.Mojikyo-1$"),
3382 staticpro (&Vcharset_mojikyo_pj_2);
3383 Vcharset_mojikyo_pj_2 =
3384 make_charset (LEADING_BYTE_MOJIKYO_PJ_2, Qmojikyo_pj_2, 94, 2,
3385 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3386 build_string ("Mojikyo-PJ-2"),
3387 build_string ("Mojikyo (pseudo JIS encoding) part 2"),
3389 ("Konjaku-Mojikyo (pseudo JIS encoding) part 2"),
3390 build_string ("jisx0208\\.Mojikyo-2$"),
3392 staticpro (&Vcharset_mojikyo_pj_3);
3393 Vcharset_mojikyo_pj_3 =
3394 make_charset (LEADING_BYTE_MOJIKYO_PJ_3, Qmojikyo_pj_3, 94, 2,
3395 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3396 build_string ("Mojikyo-PJ-3"),
3397 build_string ("Mojikyo (pseudo JIS encoding) part 3"),
3399 ("Konjaku-Mojikyo (pseudo JIS encoding) part 3"),
3400 build_string ("jisx0208\\.Mojikyo-3$"),
3402 staticpro (&Vcharset_mojikyo_pj_4);
3403 Vcharset_mojikyo_pj_4 =
3404 make_charset (LEADING_BYTE_MOJIKYO_PJ_4, Qmojikyo_pj_4, 94, 2,
3405 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3406 build_string ("Mojikyo-PJ-4"),
3407 build_string ("Mojikyo (pseudo JIS encoding) part 4"),
3409 ("Konjaku-Mojikyo (pseudo JIS encoding) part 4"),
3410 build_string ("jisx0208\\.Mojikyo-4$"),
3412 staticpro (&Vcharset_mojikyo_pj_5);
3413 Vcharset_mojikyo_pj_5 =
3414 make_charset (LEADING_BYTE_MOJIKYO_PJ_5, Qmojikyo_pj_5, 94, 2,
3415 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3416 build_string ("Mojikyo-PJ-5"),
3417 build_string ("Mojikyo (pseudo JIS encoding) part 5"),
3419 ("Konjaku-Mojikyo (pseudo JIS encoding) part 5"),
3420 build_string ("jisx0208\\.Mojikyo-5$"),
3422 staticpro (&Vcharset_mojikyo_pj_6);
3423 Vcharset_mojikyo_pj_6 =
3424 make_charset (LEADING_BYTE_MOJIKYO_PJ_6, Qmojikyo_pj_6, 94, 2,
3425 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3426 build_string ("Mojikyo-PJ-6"),
3427 build_string ("Mojikyo (pseudo JIS encoding) part 6"),
3429 ("Konjaku-Mojikyo (pseudo JIS encoding) part 6"),
3430 build_string ("jisx0208\\.Mojikyo-6$"),
3432 staticpro (&Vcharset_mojikyo_pj_7);
3433 Vcharset_mojikyo_pj_7 =
3434 make_charset (LEADING_BYTE_MOJIKYO_PJ_7, Qmojikyo_pj_7, 94, 2,
3435 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3436 build_string ("Mojikyo-PJ-7"),
3437 build_string ("Mojikyo (pseudo JIS encoding) part 7"),
3439 ("Konjaku-Mojikyo (pseudo JIS encoding) part 7"),
3440 build_string ("jisx0208\\.Mojikyo-7$"),
3442 staticpro (&Vcharset_mojikyo_pj_8);
3443 Vcharset_mojikyo_pj_8 =
3444 make_charset (LEADING_BYTE_MOJIKYO_PJ_8, Qmojikyo_pj_8, 94, 2,
3445 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3446 build_string ("Mojikyo-PJ-8"),
3447 build_string ("Mojikyo (pseudo JIS encoding) part 8"),
3449 ("Konjaku-Mojikyo (pseudo JIS encoding) part 8"),
3450 build_string ("jisx0208\\.Mojikyo-8$"),
3452 staticpro (&Vcharset_mojikyo_pj_9);
3453 Vcharset_mojikyo_pj_9 =
3454 make_charset (LEADING_BYTE_MOJIKYO_PJ_9, Qmojikyo_pj_9, 94, 2,
3455 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3456 build_string ("Mojikyo-PJ-9"),
3457 build_string ("Mojikyo (pseudo JIS encoding) part 9"),
3459 ("Konjaku-Mojikyo (pseudo JIS encoding) part 9"),
3460 build_string ("jisx0208\\.Mojikyo-9$"),
3462 staticpro (&Vcharset_mojikyo_pj_10);
3463 Vcharset_mojikyo_pj_10 =
3464 make_charset (LEADING_BYTE_MOJIKYO_PJ_10, Qmojikyo_pj_10, 94, 2,
3465 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3466 build_string ("Mojikyo-PJ-10"),
3467 build_string ("Mojikyo (pseudo JIS encoding) part 10"),
3469 ("Konjaku-Mojikyo (pseudo JIS encoding) part 10"),
3470 build_string ("jisx0208\\.Mojikyo-10$"),
3472 staticpro (&Vcharset_mojikyo_pj_11);
3473 Vcharset_mojikyo_pj_11 =
3474 make_charset (LEADING_BYTE_MOJIKYO_PJ_11, Qmojikyo_pj_11, 94, 2,
3475 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3476 build_string ("Mojikyo-PJ-11"),
3477 build_string ("Mojikyo (pseudo JIS encoding) part 11"),
3479 ("Konjaku-Mojikyo (pseudo JIS encoding) part 11"),
3480 build_string ("jisx0208\\.Mojikyo-11$"),
3482 staticpro (&Vcharset_mojikyo_pj_12);
3483 Vcharset_mojikyo_pj_12 =
3484 make_charset (LEADING_BYTE_MOJIKYO_PJ_12, Qmojikyo_pj_12, 94, 2,
3485 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3486 build_string ("Mojikyo-PJ-12"),
3487 build_string ("Mojikyo (pseudo JIS encoding) part 12"),
3489 ("Konjaku-Mojikyo (pseudo JIS encoding) part 12"),
3490 build_string ("jisx0208\\.Mojikyo-12$"),
3492 staticpro (&Vcharset_mojikyo_pj_13);
3493 Vcharset_mojikyo_pj_13 =
3494 make_charset (LEADING_BYTE_MOJIKYO_PJ_13, Qmojikyo_pj_13, 94, 2,
3495 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3496 build_string ("Mojikyo-PJ-13"),
3497 build_string ("Mojikyo (pseudo JIS encoding) part 13"),
3499 ("Konjaku-Mojikyo (pseudo JIS encoding) part 13"),
3500 build_string ("jisx0208\\.Mojikyo-13$"),
3502 staticpro (&Vcharset_mojikyo_pj_14);
3503 Vcharset_mojikyo_pj_14 =
3504 make_charset (LEADING_BYTE_MOJIKYO_PJ_14, Qmojikyo_pj_14, 94, 2,
3505 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3506 build_string ("Mojikyo-PJ-14"),
3507 build_string ("Mojikyo (pseudo JIS encoding) part 14"),
3509 ("Konjaku-Mojikyo (pseudo JIS encoding) part 14"),
3510 build_string ("jisx0208\\.Mojikyo-14$"),
3512 staticpro (&Vcharset_mojikyo_pj_15);
3513 Vcharset_mojikyo_pj_15 =
3514 make_charset (LEADING_BYTE_MOJIKYO_PJ_15, Qmojikyo_pj_15, 94, 2,
3515 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3516 build_string ("Mojikyo-PJ-15"),
3517 build_string ("Mojikyo (pseudo JIS encoding) part 15"),
3519 ("Konjaku-Mojikyo (pseudo JIS encoding) part 15"),
3520 build_string ("jisx0208\\.Mojikyo-15$"),
3522 staticpro (&Vcharset_mojikyo_pj_16);
3523 Vcharset_mojikyo_pj_16 =
3524 make_charset (LEADING_BYTE_MOJIKYO_PJ_16, Qmojikyo_pj_16, 94, 2,
3525 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3526 build_string ("Mojikyo-PJ-16"),
3527 build_string ("Mojikyo (pseudo JIS encoding) part 16"),
3529 ("Konjaku-Mojikyo (pseudo JIS encoding) part 16"),
3530 build_string ("jisx0208\\.Mojikyo-16$"),
3532 staticpro (&Vcharset_mojikyo_pj_17);
3533 Vcharset_mojikyo_pj_17 =
3534 make_charset (LEADING_BYTE_MOJIKYO_PJ_17, Qmojikyo_pj_17, 94, 2,
3535 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3536 build_string ("Mojikyo-PJ-17"),
3537 build_string ("Mojikyo (pseudo JIS encoding) part 17"),
3539 ("Konjaku-Mojikyo (pseudo JIS encoding) part 17"),
3540 build_string ("jisx0208\\.Mojikyo-17$"),
3542 staticpro (&Vcharset_mojikyo_pj_18);
3543 Vcharset_mojikyo_pj_18 =
3544 make_charset (LEADING_BYTE_MOJIKYO_PJ_18, Qmojikyo_pj_18, 94, 2,
3545 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3546 build_string ("Mojikyo-PJ-18"),
3547 build_string ("Mojikyo (pseudo JIS encoding) part 18"),
3549 ("Konjaku-Mojikyo (pseudo JIS encoding) part 18"),
3550 build_string ("jisx0208\\.Mojikyo-18$"),
3552 staticpro (&Vcharset_mojikyo_pj_19);
3553 Vcharset_mojikyo_pj_19 =
3554 make_charset (LEADING_BYTE_MOJIKYO_PJ_19, Qmojikyo_pj_19, 94, 2,
3555 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3556 build_string ("Mojikyo-PJ-19"),
3557 build_string ("Mojikyo (pseudo JIS encoding) part 19"),
3559 ("Konjaku-Mojikyo (pseudo JIS encoding) part 19"),
3560 build_string ("jisx0208\\.Mojikyo-19$"),
3562 staticpro (&Vcharset_mojikyo_pj_20);
3563 Vcharset_mojikyo_pj_20 =
3564 make_charset (LEADING_BYTE_MOJIKYO_PJ_20, Qmojikyo_pj_20, 94, 2,
3565 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3566 build_string ("Mojikyo-PJ-20"),
3567 build_string ("Mojikyo (pseudo JIS encoding) part 20"),
3569 ("Konjaku-Mojikyo (pseudo JIS encoding) part 20"),
3570 build_string ("jisx0208\\.Mojikyo-20$"),
3572 staticpro (&Vcharset_mojikyo_pj_21);
3573 Vcharset_mojikyo_pj_21 =
3574 make_charset (LEADING_BYTE_MOJIKYO_PJ_21, Qmojikyo_pj_21, 94, 2,
3575 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3576 build_string ("Mojikyo-PJ-21"),
3577 build_string ("Mojikyo (pseudo JIS encoding) part 21"),
3579 ("Konjaku-Mojikyo (pseudo JIS encoding) part 21"),
3580 build_string ("jisx0208\\.Mojikyo-21$"),
3582 staticpro (&Vcharset_ethiopic_ucs);
3583 Vcharset_ethiopic_ucs =
3584 make_charset (LEADING_BYTE_ETHIOPIC_UCS, Qethiopic_ucs, 256, 2,
3585 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3586 build_string ("Ethiopic (UCS)"),
3587 build_string ("Ethiopic (UCS)"),
3588 build_string ("Ethiopic of UCS"),
3589 build_string ("Ethiopic-Unicode"),
3590 Qnil, 0x1200, 0x137F, 0x1200, 0);
3592 staticpro (&Vcharset_chinese_big5_1);
3593 Vcharset_chinese_big5_1 =
3594 make_charset (LEADING_BYTE_CHINESE_BIG5_1, Qchinese_big5_1, 94, 2,
3595 2, 0, '0', CHARSET_LEFT_TO_RIGHT,
3596 build_string ("Big5"),
3597 build_string ("Big5 (Level-1)"),
3599 ("Big5 Level-1 Chinese traditional"),
3600 build_string ("big5"),
3602 staticpro (&Vcharset_chinese_big5_2);
3603 Vcharset_chinese_big5_2 =
3604 make_charset (LEADING_BYTE_CHINESE_BIG5_2, Qchinese_big5_2, 94, 2,
3605 2, 0, '1', CHARSET_LEFT_TO_RIGHT,
3606 build_string ("Big5"),
3607 build_string ("Big5 (Level-2)"),
3609 ("Big5 Level-2 Chinese traditional"),
3610 build_string ("big5"),
3613 #ifdef ENABLE_COMPOSITE_CHARS
3614 /* #### For simplicity, we put composite chars into a 96x96 charset.
3615 This is going to lead to problems because you can run out of
3616 room, esp. as we don't yet recycle numbers. */
3617 staticpro (&Vcharset_composite);
3618 Vcharset_composite =
3619 make_charset (LEADING_BYTE_COMPOSITE, Qcomposite, 96, 2,
3620 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3621 build_string ("Composite"),
3622 build_string ("Composite characters"),
3623 build_string ("Composite characters"),
3626 /* #### not dumped properly */
3627 composite_char_row_next = 32;
3628 composite_char_col_next = 32;
3630 Vcomposite_char_string2char_hash_table =
3631 make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
3632 Vcomposite_char_char2string_hash_table =
3633 make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3634 staticpro (&Vcomposite_char_string2char_hash_table);
3635 staticpro (&Vcomposite_char_char2string_hash_table);
3636 #endif /* ENABLE_COMPOSITE_CHARS */