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))
717 decoding_table_remove_char (Lisp_Object v, int dim, int byte_offset,
720 decoding_table_remove_char (Lisp_Object v, int dim, int byte_offset,
730 i = ((code_point >> (8 * dim)) & 255) - byte_offset;
731 nv = XVECTOR_DATA(v)[i];
737 XVECTOR_DATA(v)[i] = Qnil;
741 put_char_ccs_code_point (Lisp_Object character,
742 Lisp_Object ccs, Lisp_Object value)
744 Lisp_Object encoding_table;
746 if (!EQ (XCHARSET_NAME (ccs), Qucs)
747 || (XCHAR (character) != XINT (value)))
749 Lisp_Object cpos, rest;
750 Lisp_Object v = XCHARSET_DECODING_TABLE (ccs);
753 int dim = XCHARSET_DIMENSION (ccs);
754 int ccs_len = XCHARSET_BYTE_SIZE (ccs);
755 int byte_offset = XCHARSET_BYTE_OFFSET (ccs);
759 { /* obsolete representation: value must be a list of bytes */
760 Lisp_Object ret = Fcar (value);
763 signal_simple_error ("Invalid value for coded-charset", value);
764 code_point = XINT (ret);
765 if (XCHARSET_GRAPHIC (ccs) == 1)
773 signal_simple_error ("Invalid value for coded-charset",
777 signal_simple_error ("Invalid value for coded-charset",
780 if (XCHARSET_GRAPHIC (ccs) == 1)
782 code_point = (code_point << 8) | j;
785 value = make_int (code_point);
787 else if (INTP (value))
789 if (XCHARSET_GRAPHIC (ccs) == 1)
790 value = make_int (XINT (value) & 0x7F7F7F7F);
793 signal_simple_error ("Invalid value for coded-charset", value);
795 cpos = Fget_char_attribute (character, ccs);
800 decoding_table_remove_char (v, dim, byte_offset, XINT (cpos));
805 XCHARSET_DECODING_TABLE (ccs) = v
806 = make_older_vector (ccs_len, Qnil);
809 code_point = XINT (value);
814 i = ((code_point >> (8 * dim)) & 255) - byte_offset;
815 nv = XVECTOR_DATA(v)[i];
819 nv = (XVECTOR_DATA(v)[i]
820 = make_older_vector (ccs_len, Qnil));
826 XVECTOR_DATA(v)[i] = character;
828 if (NILP (encoding_table = XCHARSET_ENCODING_TABLE (ccs)))
830 XCHARSET_ENCODING_TABLE (ccs) = encoding_table
831 = make_char_id_table (Qnil, -1);
833 put_char_id_table (XCHAR (character), value, encoding_table);
838 remove_char_ccs (Lisp_Object character, Lisp_Object ccs)
840 Lisp_Object decoding_table = XCHARSET_DECODING_TABLE (ccs);
841 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
843 if (VECTORP (decoding_table))
845 Lisp_Object cpos = Fget_char_attribute (character, ccs);
849 decoding_table_remove_char (decoding_table,
850 XCHARSET_DIMENSION (ccs),
851 XCHARSET_BYTE_OFFSET (ccs),
855 if (CHAR_ID_TABLE_P (encoding_table))
857 put_char_id_table (XCHAR (character), Qnil, encoding_table);
863 put_char_attribute (Lisp_Object character, Lisp_Object attribute,
866 Emchar char_id = XCHAR (character);
867 Lisp_Object ret = get_char_id_table (char_id, Vcharacter_attribute_table);
870 cell = Fassq (attribute, ret);
874 ret = Fcons (Fcons (attribute, value), ret);
876 else if (!EQ (Fcdr (cell), value))
878 Fsetcdr (cell, value);
880 put_char_id_table (char_id, ret, Vcharacter_attribute_table);
885 remove_char_attribute (Lisp_Object character, Lisp_Object attribute)
887 Emchar char_id = XCHAR (character);
888 Lisp_Object alist = get_char_id_table (char_id, Vcharacter_attribute_table);
890 if (EQ (attribute, Fcar (Fcar (alist))))
892 alist = Fcdr (alist);
896 Lisp_Object pr = alist;
897 Lisp_Object r = Fcdr (alist);
901 if (EQ (attribute, Fcar (Fcar (r))))
903 XCDR (pr) = Fcdr (r);
910 put_char_id_table (char_id, alist, Vcharacter_attribute_table);
914 EXFUN (Fmake_char, 3);
915 EXFUN (Fdecode_char, 2);
917 DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
918 Store character's ATTRIBUTES.
922 Lisp_Object rest = attributes;
923 Lisp_Object code = Fcdr (Fassq (Qucs, attributes));
924 Lisp_Object character;
930 Lisp_Object cell = Fcar (rest);
934 signal_simple_error ("Invalid argument", attributes);
935 if (!NILP (ccs = Ffind_charset (Fcar (cell)))
936 && ((XCHARSET_FINAL (ccs) != 0) ||
937 (XCHARSET_UCS_MAX (ccs) > 0)) )
941 character = Fmake_char (ccs, Fcar (cell), Fcar (Fcdr (cell)));
943 character = Fdecode_char (ccs, cell);
944 goto setup_attributes;
948 if (!NILP (code = Fcdr (Fassq (Q_ucs, attributes))))
951 signal_simple_error ("Invalid argument", attributes);
953 character = make_char (XINT (code) + 0x100000);
954 goto setup_attributes;
958 else if (!INTP (code))
959 signal_simple_error ("Invalid argument", attributes);
961 character = make_char (XINT (code));
967 Lisp_Object cell = Fcar (rest);
970 signal_simple_error ("Invalid argument", attributes);
971 Fput_char_attribute (character, Fcar (cell), Fcdr (cell));
975 get_char_id_table (XCHAR (character), Vcharacter_attribute_table);
978 Lisp_Object Vutf_2000_version;
982 int leading_code_private_11;
985 Lisp_Object Qcharsetp;
987 /* Qdoc_string, Qdimension, Qchars defined in general.c */
988 Lisp_Object Qregistry, Qfinal, Qgraphic;
989 Lisp_Object Qdirection;
990 Lisp_Object Qreverse_direction_charset;
991 Lisp_Object Qleading_byte;
992 Lisp_Object Qshort_name, Qlong_name;
1006 Qcyrillic_iso8859_5,
1008 Qjapanese_jisx0208_1978,
1011 Qjapanese_jisx0208_1990,
1014 Qchinese_cns11643_1,
1015 Qchinese_cns11643_2,
1020 Qlatin_viscii_lower,
1021 Qlatin_viscii_upper,
1022 Qvietnamese_viscii_lower,
1023 Qvietnamese_viscii_upper,
1024 Qideograph_daikanwa,
1053 Lisp_Object Ql2r, Qr2l;
1055 Lisp_Object Vcharset_hash_table;
1057 /* Composite characters are characters constructed by overstriking two
1058 or more regular characters.
1060 1) The old Mule implementation involves storing composite characters
1061 in a buffer as a tag followed by all of the actual characters
1062 used to make up the composite character. I think this is a bad
1063 idea; it greatly complicates code that wants to handle strings
1064 one character at a time because it has to deal with the possibility
1065 of great big ungainly characters. It's much more reasonable to
1066 simply store an index into a table of composite characters.
1068 2) The current implementation only allows for 16,384 separate
1069 composite characters over the lifetime of the XEmacs process.
1070 This could become a potential problem if the user
1071 edited lots of different files that use composite characters.
1072 Due to FSF bogosity, increasing the number of allowable
1073 composite characters under Mule would decrease the number
1074 of possible faces that can exist. Mule already has shrunk
1075 this to 2048, and further shrinkage would become uncomfortable.
1076 No such problems exist in XEmacs.
1078 Composite characters could be represented as 0x80 C1 C2 C3,
1079 where each C[1-3] is in the range 0xA0 - 0xFF. This allows
1080 for slightly under 2^20 (one million) composite characters
1081 over the XEmacs process lifetime, and you only need to
1082 increase the size of a Mule character from 19 to 21 bits.
1083 Or you could use 0x80 C1 C2 C3 C4, allowing for about
1084 85 million (slightly over 2^26) composite characters. */
1087 /************************************************************************/
1088 /* Basic Emchar functions */
1089 /************************************************************************/
1091 /* Convert a non-ASCII Mule character C into a one-character Mule-encoded
1092 string in STR. Returns the number of bytes stored.
1093 Do not call this directly. Use the macro set_charptr_emchar() instead.
1097 non_ascii_set_charptr_emchar (Bufbyte *str, Emchar c)
1103 Lisp_Object charset;
1112 else if ( c <= 0x7ff )
1114 *p++ = (c >> 6) | 0xc0;
1115 *p++ = (c & 0x3f) | 0x80;
1117 else if ( c <= 0xffff )
1119 *p++ = (c >> 12) | 0xe0;
1120 *p++ = ((c >> 6) & 0x3f) | 0x80;
1121 *p++ = (c & 0x3f) | 0x80;
1123 else if ( c <= 0x1fffff )
1125 *p++ = (c >> 18) | 0xf0;
1126 *p++ = ((c >> 12) & 0x3f) | 0x80;
1127 *p++ = ((c >> 6) & 0x3f) | 0x80;
1128 *p++ = (c & 0x3f) | 0x80;
1130 else if ( c <= 0x3ffffff )
1132 *p++ = (c >> 24) | 0xf8;
1133 *p++ = ((c >> 18) & 0x3f) | 0x80;
1134 *p++ = ((c >> 12) & 0x3f) | 0x80;
1135 *p++ = ((c >> 6) & 0x3f) | 0x80;
1136 *p++ = (c & 0x3f) | 0x80;
1140 *p++ = (c >> 30) | 0xfc;
1141 *p++ = ((c >> 24) & 0x3f) | 0x80;
1142 *p++ = ((c >> 18) & 0x3f) | 0x80;
1143 *p++ = ((c >> 12) & 0x3f) | 0x80;
1144 *p++ = ((c >> 6) & 0x3f) | 0x80;
1145 *p++ = (c & 0x3f) | 0x80;
1148 BREAKUP_CHAR (c, charset, c1, c2);
1149 lb = CHAR_LEADING_BYTE (c);
1150 if (LEADING_BYTE_PRIVATE_P (lb))
1151 *p++ = PRIVATE_LEADING_BYTE_PREFIX (lb);
1153 if (EQ (charset, Vcharset_control_1))
1162 /* Return the first character from a Mule-encoded string in STR,
1163 assuming it's non-ASCII. Do not call this directly.
1164 Use the macro charptr_emchar() instead. */
1167 non_ascii_charptr_emchar (const Bufbyte *str)
1180 else if ( b >= 0xf8 )
1185 else if ( b >= 0xf0 )
1190 else if ( b >= 0xe0 )
1195 else if ( b >= 0xc0 )
1205 for( ; len > 0; len-- )
1208 ch = ( ch << 6 ) | ( b & 0x3f );
1212 Bufbyte i0 = *str, i1, i2 = 0;
1213 Lisp_Object charset;
1215 if (i0 == LEADING_BYTE_CONTROL_1)
1216 return (Emchar) (*++str - 0x20);
1218 if (LEADING_BYTE_PREFIX_P (i0))
1223 charset = CHARSET_BY_LEADING_BYTE (i0);
1224 if (XCHARSET_DIMENSION (charset) == 2)
1227 return MAKE_CHAR (charset, i1, i2);
1231 /* Return whether CH is a valid Emchar, assuming it's non-ASCII.
1232 Do not call this directly. Use the macro valid_char_p() instead. */
1236 non_ascii_valid_char_p (Emchar ch)
1240 /* Must have only lowest 19 bits set */
1244 f1 = CHAR_FIELD1 (ch);
1245 f2 = CHAR_FIELD2 (ch);
1246 f3 = CHAR_FIELD3 (ch);
1250 Lisp_Object charset;
1252 if (f2 < MIN_CHAR_FIELD2_OFFICIAL ||
1253 (f2 > MAX_CHAR_FIELD2_OFFICIAL && f2 < MIN_CHAR_FIELD2_PRIVATE) ||
1254 f2 > MAX_CHAR_FIELD2_PRIVATE)
1259 if (f3 != 0x20 && f3 != 0x7F && !(f2 >= MIN_CHAR_FIELD2_PRIVATE &&
1260 f2 <= MAX_CHAR_FIELD2_PRIVATE))
1264 NOTE: This takes advantage of the fact that
1265 FIELD2_TO_OFFICIAL_LEADING_BYTE and
1266 FIELD2_TO_PRIVATE_LEADING_BYTE are the same.
1268 charset = CHARSET_BY_LEADING_BYTE (f2 + FIELD2_TO_OFFICIAL_LEADING_BYTE);
1269 if (EQ (charset, Qnil))
1271 return (XCHARSET_CHARS (charset) == 96);
1275 Lisp_Object charset;
1277 if (f1 < MIN_CHAR_FIELD1_OFFICIAL ||
1278 (f1 > MAX_CHAR_FIELD1_OFFICIAL && f1 < MIN_CHAR_FIELD1_PRIVATE) ||
1279 f1 > MAX_CHAR_FIELD1_PRIVATE)
1281 if (f2 < 0x20 || f3 < 0x20)
1284 #ifdef ENABLE_COMPOSITE_CHARS
1285 if (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE == LEADING_BYTE_COMPOSITE)
1287 if (UNBOUNDP (Fgethash (make_int (ch),
1288 Vcomposite_char_char2string_hash_table,
1293 #endif /* ENABLE_COMPOSITE_CHARS */
1295 if (f2 != 0x20 && f2 != 0x7F && f3 != 0x20 && f3 != 0x7F
1296 && !(f1 >= MIN_CHAR_FIELD1_PRIVATE && f1 <= MAX_CHAR_FIELD1_PRIVATE))
1299 if (f1 <= MAX_CHAR_FIELD1_OFFICIAL)
1301 CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE);
1304 CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_PRIVATE_LEADING_BYTE);
1306 if (EQ (charset, Qnil))
1308 return (XCHARSET_CHARS (charset) == 96);
1314 /************************************************************************/
1315 /* Basic string functions */
1316 /************************************************************************/
1318 /* Copy the character pointed to by PTR into STR, assuming it's
1319 non-ASCII. Do not call this directly. Use the macro
1320 charptr_copy_char() instead. */
1323 non_ascii_charptr_copy_char (const Bufbyte *ptr, Bufbyte *str)
1325 Bufbyte *strptr = str;
1327 switch (REP_BYTES_BY_FIRST_BYTE (*strptr))
1329 /* Notice fallthrough. */
1331 case 6: *++strptr = *ptr++;
1332 case 5: *++strptr = *ptr++;
1334 case 4: *++strptr = *ptr++;
1335 case 3: *++strptr = *ptr++;
1336 case 2: *++strptr = *ptr;
1341 return strptr + 1 - str;
1345 /************************************************************************/
1346 /* streams of Emchars */
1347 /************************************************************************/
1349 /* Treat a stream as a stream of Emchar's rather than a stream of bytes.
1350 The functions below are not meant to be called directly; use
1351 the macros in insdel.h. */
1354 Lstream_get_emchar_1 (Lstream *stream, int ch)
1356 Bufbyte str[MAX_EMCHAR_LEN];
1357 Bufbyte *strptr = str;
1359 str[0] = (Bufbyte) ch;
1360 switch (REP_BYTES_BY_FIRST_BYTE (ch))
1362 /* Notice fallthrough. */
1365 ch = Lstream_getc (stream);
1367 *++strptr = (Bufbyte) ch;
1369 ch = Lstream_getc (stream);
1371 *++strptr = (Bufbyte) ch;
1374 ch = Lstream_getc (stream);
1376 *++strptr = (Bufbyte) ch;
1378 ch = Lstream_getc (stream);
1380 *++strptr = (Bufbyte) ch;
1382 ch = Lstream_getc (stream);
1384 *++strptr = (Bufbyte) ch;
1389 return charptr_emchar (str);
1393 Lstream_fput_emchar (Lstream *stream, Emchar ch)
1395 Bufbyte str[MAX_EMCHAR_LEN];
1396 Bytecount len = set_charptr_emchar (str, ch);
1397 return Lstream_write (stream, str, len);
1401 Lstream_funget_emchar (Lstream *stream, Emchar ch)
1403 Bufbyte str[MAX_EMCHAR_LEN];
1404 Bytecount len = set_charptr_emchar (str, ch);
1405 Lstream_unread (stream, str, len);
1409 /************************************************************************/
1410 /* charset object */
1411 /************************************************************************/
1414 mark_charset (Lisp_Object obj)
1416 Lisp_Charset *cs = XCHARSET (obj);
1418 mark_object (cs->short_name);
1419 mark_object (cs->long_name);
1420 mark_object (cs->doc_string);
1421 mark_object (cs->registry);
1422 mark_object (cs->ccl_program);
1424 /* mark_object (cs->encoding_table); */
1425 /* mark_object (cs->decoding_table); */
1431 print_charset (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1433 Lisp_Charset *cs = XCHARSET (obj);
1437 error ("printing unreadable object #<charset %s 0x%x>",
1438 string_data (XSYMBOL (CHARSET_NAME (cs))->name),
1441 write_c_string ("#<charset ", printcharfun);
1442 print_internal (CHARSET_NAME (cs), printcharfun, 0);
1443 write_c_string (" ", printcharfun);
1444 print_internal (CHARSET_SHORT_NAME (cs), printcharfun, 1);
1445 write_c_string (" ", printcharfun);
1446 print_internal (CHARSET_LONG_NAME (cs), printcharfun, 1);
1447 write_c_string (" ", printcharfun);
1448 print_internal (CHARSET_DOC_STRING (cs), printcharfun, 1);
1449 sprintf (buf, " %d^%d %s cols=%d g%d final='%c' reg=",
1451 CHARSET_DIMENSION (cs),
1452 CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? "l2r" : "r2l",
1453 CHARSET_COLUMNS (cs),
1454 CHARSET_GRAPHIC (cs),
1455 CHARSET_FINAL (cs));
1456 write_c_string (buf, printcharfun);
1457 print_internal (CHARSET_REGISTRY (cs), printcharfun, 0);
1458 sprintf (buf, " 0x%x>", cs->header.uid);
1459 write_c_string (buf, printcharfun);
1462 static const struct lrecord_description charset_description[] = {
1463 { XD_LISP_OBJECT, offsetof (Lisp_Charset, name) },
1464 { XD_LISP_OBJECT, offsetof (Lisp_Charset, doc_string) },
1465 { XD_LISP_OBJECT, offsetof (Lisp_Charset, registry) },
1466 { XD_LISP_OBJECT, offsetof (Lisp_Charset, short_name) },
1467 { XD_LISP_OBJECT, offsetof (Lisp_Charset, long_name) },
1468 { XD_LISP_OBJECT, offsetof (Lisp_Charset, reverse_direction_charset) },
1469 { XD_LISP_OBJECT, offsetof (Lisp_Charset, ccl_program) },
1471 { XD_LISP_OBJECT, offsetof (Lisp_Charset, decoding_table) },
1472 { XD_LISP_OBJECT, offsetof (Lisp_Charset, encoding_table) },
1477 DEFINE_LRECORD_IMPLEMENTATION ("charset", charset,
1478 mark_charset, print_charset, 0, 0, 0,
1479 charset_description,
1481 /* Make a new charset. */
1484 make_charset (Charset_ID id, Lisp_Object name,
1485 unsigned short chars, unsigned char dimension,
1486 unsigned char columns, unsigned char graphic,
1487 Bufbyte final, unsigned char direction, Lisp_Object short_name,
1488 Lisp_Object long_name, Lisp_Object doc,
1490 Lisp_Object decoding_table,
1491 Emchar ucs_min, Emchar ucs_max,
1492 Emchar code_offset, unsigned char byte_offset)
1494 unsigned char type = 0;
1496 Lisp_Charset *cs = alloc_lcrecord_type (Lisp_Charset, &lrecord_charset);
1500 XSETCHARSET (obj, cs);
1502 CHARSET_ID (cs) = id;
1503 CHARSET_NAME (cs) = name;
1504 CHARSET_SHORT_NAME (cs) = short_name;
1505 CHARSET_LONG_NAME (cs) = long_name;
1506 CHARSET_CHARS (cs) = chars;
1507 CHARSET_DIMENSION (cs) = dimension;
1508 CHARSET_DIRECTION (cs) = direction;
1509 CHARSET_COLUMNS (cs) = columns;
1510 CHARSET_GRAPHIC (cs) = graphic;
1511 CHARSET_FINAL (cs) = final;
1512 CHARSET_DOC_STRING (cs) = doc;
1513 CHARSET_REGISTRY (cs) = reg;
1514 CHARSET_CCL_PROGRAM (cs) = Qnil;
1515 CHARSET_REVERSE_DIRECTION_CHARSET (cs) = Qnil;
1517 CHARSET_DECODING_TABLE(cs) = Qnil;
1518 CHARSET_ENCODING_TABLE(cs) = Qnil;
1519 CHARSET_UCS_MIN(cs) = ucs_min;
1520 CHARSET_UCS_MAX(cs) = ucs_max;
1521 CHARSET_CODE_OFFSET(cs) = code_offset;
1522 CHARSET_BYTE_OFFSET(cs) = byte_offset;
1525 switch (CHARSET_CHARS (cs))
1528 switch (CHARSET_DIMENSION (cs))
1531 type = CHARSET_TYPE_94;
1534 type = CHARSET_TYPE_94X94;
1539 switch (CHARSET_DIMENSION (cs))
1542 type = CHARSET_TYPE_96;
1545 type = CHARSET_TYPE_96X96;
1551 switch (CHARSET_DIMENSION (cs))
1554 type = CHARSET_TYPE_128;
1557 type = CHARSET_TYPE_128X128;
1562 switch (CHARSET_DIMENSION (cs))
1565 type = CHARSET_TYPE_256;
1568 type = CHARSET_TYPE_256X256;
1575 CHARSET_TYPE (cs) = type;
1579 if (id == LEADING_BYTE_ASCII)
1580 CHARSET_REP_BYTES (cs) = 1;
1582 CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 1;
1584 CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 2;
1589 /* some charsets do not have final characters. This includes
1590 ASCII, Control-1, Composite, and the two faux private
1593 if (code_offset == 0)
1595 assert (NILP (chlook->charset_by_attributes[type][final]));
1596 chlook->charset_by_attributes[type][final] = obj;
1599 assert (NILP (chlook->charset_by_attributes[type][final][direction]));
1600 chlook->charset_by_attributes[type][final][direction] = obj;
1604 assert (NILP (chlook->charset_by_leading_byte[id - MIN_LEADING_BYTE]));
1605 chlook->charset_by_leading_byte[id - MIN_LEADING_BYTE] = obj;
1607 /* Some charsets are "faux" and don't have names or really exist at
1608 all except in the leading-byte table. */
1610 Fputhash (name, obj, Vcharset_hash_table);
1615 get_unallocated_leading_byte (int dimension)
1620 if (chlook->next_allocated_leading_byte > MAX_LEADING_BYTE_PRIVATE)
1623 lb = chlook->next_allocated_leading_byte++;
1627 if (chlook->next_allocated_1_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_1)
1630 lb = chlook->next_allocated_1_byte_leading_byte++;
1634 if (chlook->next_allocated_2_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_2)
1637 lb = chlook->next_allocated_2_byte_leading_byte++;
1643 ("No more character sets free for this dimension",
1644 make_int (dimension));
1651 make_builtin_char (Lisp_Object charset, int c1, int c2)
1653 if (XCHARSET_UCS_MAX (charset))
1656 = (XCHARSET_DIMENSION (charset) == 1
1658 c1 - XCHARSET_BYTE_OFFSET (charset)
1660 (c1 - XCHARSET_BYTE_OFFSET (charset)) * XCHARSET_CHARS (charset)
1661 + c2 - XCHARSET_BYTE_OFFSET (charset))
1662 - XCHARSET_CODE_OFFSET (charset) + XCHARSET_UCS_MIN (charset);
1663 if ((code < XCHARSET_UCS_MIN (charset))
1664 || (XCHARSET_UCS_MAX (charset) < code))
1665 signal_simple_error ("Arguments makes invalid character",
1669 else if (XCHARSET_DIMENSION (charset) == 1)
1671 switch (XCHARSET_CHARS (charset))
1675 + (XCHARSET_FINAL (charset) - '0') * 94 + (c1 - 33);
1678 + (XCHARSET_FINAL (charset) - '0') * 96 + (c1 - 32);
1685 switch (XCHARSET_CHARS (charset))
1688 return MIN_CHAR_94x94
1689 + (XCHARSET_FINAL (charset) - '0') * 94 * 94
1690 + (c1 - 33) * 94 + (c2 - 33);
1692 return MIN_CHAR_96x96
1693 + (XCHARSET_FINAL (charset) - '0') * 96 * 96
1694 + (c1 - 32) * 96 + (c2 - 32);
1702 range_charset_code_point (Lisp_Object charset, Emchar ch)
1706 if ((XCHARSET_UCS_MIN (charset) <= ch)
1707 && (ch <= XCHARSET_UCS_MAX (charset)))
1709 d = ch - XCHARSET_UCS_MIN (charset) + XCHARSET_CODE_OFFSET (charset);
1711 if (XCHARSET_CHARS (charset) == 256)
1713 else if (XCHARSET_DIMENSION (charset) == 1)
1714 return d + XCHARSET_BYTE_OFFSET (charset);
1715 else if (XCHARSET_DIMENSION (charset) == 2)
1717 ((d / XCHARSET_CHARS (charset)
1718 + XCHARSET_BYTE_OFFSET (charset)) << 8)
1719 | (d % XCHARSET_CHARS (charset) + XCHARSET_BYTE_OFFSET (charset));
1720 else if (XCHARSET_DIMENSION (charset) == 3)
1722 ((d / (XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset))
1723 + XCHARSET_BYTE_OFFSET (charset)) << 16)
1724 | ((d / XCHARSET_CHARS (charset)
1725 % XCHARSET_CHARS (charset)
1726 + XCHARSET_BYTE_OFFSET (charset)) << 8)
1727 | (d % XCHARSET_CHARS (charset) + XCHARSET_BYTE_OFFSET (charset));
1728 else /* if (XCHARSET_DIMENSION (charset) == 4) */
1730 ((d / (XCHARSET_CHARS (charset)
1731 * XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset))
1732 + XCHARSET_BYTE_OFFSET (charset)) << 24)
1733 | ((d / (XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset))
1734 % XCHARSET_CHARS (charset)
1735 + XCHARSET_BYTE_OFFSET (charset)) << 16)
1736 | ((d / XCHARSET_CHARS (charset) % XCHARSET_CHARS (charset)
1737 + XCHARSET_BYTE_OFFSET (charset)) << 8)
1738 | (d % XCHARSET_CHARS (charset) + XCHARSET_BYTE_OFFSET (charset));
1740 else if (XCHARSET_CODE_OFFSET (charset) == 0)
1742 if (XCHARSET_DIMENSION (charset) == 1)
1744 if (XCHARSET_CHARS (charset) == 94)
1746 if (((d = ch - (MIN_CHAR_94
1747 + (XCHARSET_FINAL (charset) - '0') * 94)) >= 0)
1751 else if (XCHARSET_CHARS (charset) == 96)
1753 if (((d = ch - (MIN_CHAR_96
1754 + (XCHARSET_FINAL (charset) - '0') * 96)) >= 0)
1761 else if (XCHARSET_DIMENSION (charset) == 2)
1763 if (XCHARSET_CHARS (charset) == 94)
1765 if (((d = ch - (MIN_CHAR_94x94
1766 + (XCHARSET_FINAL (charset) - '0') * 94 * 94))
1769 return (((d / 94) + 33) << 8) | (d % 94 + 33);
1771 else if (XCHARSET_CHARS (charset) == 96)
1773 if (((d = ch - (MIN_CHAR_96x96
1774 + (XCHARSET_FINAL (charset) - '0') * 96 * 96))
1777 return (((d / 96) + 32) << 8) | (d % 96 + 32);
1787 encode_builtin_char_1 (Emchar c, Lisp_Object* charset)
1789 if (c <= MAX_CHAR_BASIC_LATIN)
1791 *charset = Vcharset_ascii;
1796 *charset = Vcharset_control_1;
1801 *charset = Vcharset_latin_iso8859_1;
1805 else if ((MIN_CHAR_GREEK <= c) && (c <= MAX_CHAR_GREEK))
1807 *charset = Vcharset_greek_iso8859_7;
1808 return c - MIN_CHAR_GREEK + 0x20;
1810 else if ((MIN_CHAR_CYRILLIC <= c) && (c <= MAX_CHAR_CYRILLIC))
1812 *charset = Vcharset_cyrillic_iso8859_5;
1813 return c - MIN_CHAR_CYRILLIC + 0x20;
1816 else if ((MIN_CHAR_HEBREW <= c) && (c <= MAX_CHAR_HEBREW))
1818 *charset = Vcharset_hebrew_iso8859_8;
1819 return c - MIN_CHAR_HEBREW + 0x20;
1821 else if ((MIN_CHAR_THAI <= c) && (c <= MAX_CHAR_THAI))
1823 *charset = Vcharset_thai_tis620;
1824 return c - MIN_CHAR_THAI + 0x20;
1827 else if ((MIN_CHAR_HALFWIDTH_KATAKANA <= c)
1828 && (c <= MAX_CHAR_HALFWIDTH_KATAKANA))
1830 return list2 (Vcharset_katakana_jisx0201,
1831 make_int (c - MIN_CHAR_HALFWIDTH_KATAKANA + 33));
1834 else if (c <= MAX_CHAR_BMP)
1836 *charset = Vcharset_ucs_bmp;
1839 else if (c < MIN_CHAR_DAIKANWA)
1841 *charset = Vcharset_ucs;
1845 else if (c <= MAX_CHAR_DAIKANWA)
1847 *charset = Vcharset_ideograph_daikanwa;
1848 return c - MIN_CHAR_DAIKANWA;
1851 else if (c <= MAX_CHAR_MOJIKYO)
1853 *charset = Vcharset_mojikyo;
1854 return c - MIN_CHAR_MOJIKYO;
1856 else if (c < MIN_CHAR_94)
1858 *charset = Vcharset_ucs;
1861 else if (c <= MAX_CHAR_94)
1863 *charset = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_94,
1864 ((c - MIN_CHAR_94) / 94) + '0',
1865 CHARSET_LEFT_TO_RIGHT);
1866 if (!NILP (*charset))
1867 return ((c - MIN_CHAR_94) % 94) + 33;
1870 *charset = Vcharset_ucs;
1874 else if (c <= MAX_CHAR_96)
1876 *charset = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_96,
1877 ((c - MIN_CHAR_96) / 96) + '0',
1878 CHARSET_LEFT_TO_RIGHT);
1879 if (!NILP (*charset))
1880 return ((c - MIN_CHAR_96) % 96) + 32;
1883 *charset = Vcharset_ucs;
1887 else if (c <= MAX_CHAR_94x94)
1890 = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_94X94,
1891 ((c - MIN_CHAR_94x94) / (94 * 94)) + '0',
1892 CHARSET_LEFT_TO_RIGHT);
1893 if (!NILP (*charset))
1894 return (((((c - MIN_CHAR_94x94) / 94) % 94) + 33) << 8)
1895 | (((c - MIN_CHAR_94x94) % 94) + 33);
1898 *charset = Vcharset_ucs;
1902 else if (c <= MAX_CHAR_96x96)
1905 = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_96X96,
1906 ((c - MIN_CHAR_96x96) / (96 * 96)) + '0',
1907 CHARSET_LEFT_TO_RIGHT);
1908 if (!NILP (*charset))
1909 return ((((c - MIN_CHAR_96x96) / 96) % 96) + 32) << 8
1910 | (((c - MIN_CHAR_96x96) % 96) + 32);
1913 *charset = Vcharset_ucs;
1919 *charset = Vcharset_ucs;
1924 Lisp_Object Vdefault_coded_charset_priority_list;
1928 /************************************************************************/
1929 /* Basic charset Lisp functions */
1930 /************************************************************************/
1932 DEFUN ("charsetp", Fcharsetp, 1, 1, 0, /*
1933 Return non-nil if OBJECT is a charset.
1937 return CHARSETP (object) ? Qt : Qnil;
1940 DEFUN ("find-charset", Ffind_charset, 1, 1, 0, /*
1941 Retrieve the charset of the given name.
1942 If CHARSET-OR-NAME is a charset object, it is simply returned.
1943 Otherwise, CHARSET-OR-NAME should be a symbol. If there is no such charset,
1944 nil is returned. Otherwise the associated charset object is returned.
1948 if (CHARSETP (charset_or_name))
1949 return charset_or_name;
1951 CHECK_SYMBOL (charset_or_name);
1952 return Fgethash (charset_or_name, Vcharset_hash_table, Qnil);
1955 DEFUN ("get-charset", Fget_charset, 1, 1, 0, /*
1956 Retrieve the charset of the given name.
1957 Same as `find-charset' except an error is signalled if there is no such
1958 charset instead of returning nil.
1962 Lisp_Object charset = Ffind_charset (name);
1965 signal_simple_error ("No such charset", name);
1969 /* We store the charsets in hash tables with the names as the key and the
1970 actual charset object as the value. Occasionally we need to use them
1971 in a list format. These routines provide us with that. */
1972 struct charset_list_closure
1974 Lisp_Object *charset_list;
1978 add_charset_to_list_mapper (Lisp_Object key, Lisp_Object value,
1979 void *charset_list_closure)
1981 /* This function can GC */
1982 struct charset_list_closure *chcl =
1983 (struct charset_list_closure*) charset_list_closure;
1984 Lisp_Object *charset_list = chcl->charset_list;
1986 *charset_list = Fcons (XCHARSET_NAME (value), *charset_list);
1990 DEFUN ("charset-list", Fcharset_list, 0, 0, 0, /*
1991 Return a list of the names of all defined charsets.
1995 Lisp_Object charset_list = Qnil;
1996 struct gcpro gcpro1;
1997 struct charset_list_closure charset_list_closure;
1999 GCPRO1 (charset_list);
2000 charset_list_closure.charset_list = &charset_list;
2001 elisp_maphash (add_charset_to_list_mapper, Vcharset_hash_table,
2002 &charset_list_closure);
2005 return charset_list;
2008 DEFUN ("charset-name", Fcharset_name, 1, 1, 0, /*
2009 Return the name of the given charset.
2013 return XCHARSET_NAME (Fget_charset (charset));
2016 DEFUN ("make-charset", Fmake_charset, 3, 3, 0, /*
2017 Define a new character set.
2018 This function is for use with Mule support.
2019 NAME is a symbol, the name by which the character set is normally referred.
2020 DOC-STRING is a string describing the character set.
2021 PROPS is a property list, describing the specific nature of the
2022 character set. Recognized properties are:
2024 'short-name Short version of the charset name (ex: Latin-1)
2025 'long-name Long version of the charset name (ex: ISO8859-1 (Latin-1))
2026 'registry A regular expression matching the font registry field for
2028 'dimension Number of octets used to index a character in this charset.
2029 Either 1 or 2. Defaults to 1.
2030 'columns Number of columns used to display a character in this charset.
2031 Only used in TTY mode. (Under X, the actual width of a
2032 character can be derived from the font used to display the
2033 characters.) If unspecified, defaults to the dimension
2034 (this is almost always the correct value).
2035 'chars Number of characters in each dimension (94 or 96).
2036 Defaults to 94. Note that if the dimension is 2, the
2037 character set thus described is 94x94 or 96x96.
2038 'final Final byte of ISO 2022 escape sequence. Must be
2039 supplied. Each combination of (DIMENSION, CHARS) defines a
2040 separate namespace for final bytes. Note that ISO
2041 2022 restricts the final byte to the range
2042 0x30 - 0x7E if dimension == 1, and 0x30 - 0x5F if
2043 dimension == 2. Note also that final bytes in the range
2044 0x30 - 0x3F are reserved for user-defined (not official)
2046 'graphic 0 (use left half of font on output) or 1 (use right half
2047 of font on output). Defaults to 0. For example, for
2048 a font whose registry is ISO8859-1, the left half
2049 (octets 0x20 - 0x7F) is the `ascii' character set, while
2050 the right half (octets 0xA0 - 0xFF) is the `latin-1'
2051 character set. With 'graphic set to 0, the octets
2052 will have their high bit cleared; with it set to 1,
2053 the octets will have their high bit set.
2054 'direction 'l2r (left-to-right) or 'r2l (right-to-left).
2056 'ccl-program A compiled CCL program used to convert a character in
2057 this charset into an index into the font. This is in
2058 addition to the 'graphic property. The CCL program
2059 is passed the octets of the character, with the high
2060 bit cleared and set depending upon whether the value
2061 of the 'graphic property is 0 or 1.
2063 (name, doc_string, props))
2065 int id, dimension = 1, chars = 94, graphic = 0, final = 0, columns = -1;
2066 int direction = CHARSET_LEFT_TO_RIGHT;
2068 Lisp_Object registry = Qnil;
2069 Lisp_Object charset;
2070 Lisp_Object rest, keyword, value;
2071 Lisp_Object ccl_program = Qnil;
2072 Lisp_Object short_name = Qnil, long_name = Qnil;
2073 int byte_offset = -1;
2075 CHECK_SYMBOL (name);
2076 if (!NILP (doc_string))
2077 CHECK_STRING (doc_string);
2079 charset = Ffind_charset (name);
2080 if (!NILP (charset))
2081 signal_simple_error ("Cannot redefine existing charset", name);
2083 EXTERNAL_PROPERTY_LIST_LOOP (rest, keyword, value, props)
2085 if (EQ (keyword, Qshort_name))
2087 CHECK_STRING (value);
2091 if (EQ (keyword, Qlong_name))
2093 CHECK_STRING (value);
2097 else if (EQ (keyword, Qdimension))
2100 dimension = XINT (value);
2101 if (dimension < 1 || dimension > 2)
2102 signal_simple_error ("Invalid value for 'dimension", value);
2105 else if (EQ (keyword, Qchars))
2108 chars = XINT (value);
2109 if (chars != 94 && chars != 96)
2110 signal_simple_error ("Invalid value for 'chars", value);
2113 else if (EQ (keyword, Qcolumns))
2116 columns = XINT (value);
2117 if (columns != 1 && columns != 2)
2118 signal_simple_error ("Invalid value for 'columns", value);
2121 else if (EQ (keyword, Qgraphic))
2124 graphic = XINT (value);
2126 if (graphic < 0 || graphic > 2)
2128 if (graphic < 0 || graphic > 1)
2130 signal_simple_error ("Invalid value for 'graphic", value);
2133 else if (EQ (keyword, Qregistry))
2135 CHECK_STRING (value);
2139 else if (EQ (keyword, Qdirection))
2141 if (EQ (value, Ql2r))
2142 direction = CHARSET_LEFT_TO_RIGHT;
2143 else if (EQ (value, Qr2l))
2144 direction = CHARSET_RIGHT_TO_LEFT;
2146 signal_simple_error ("Invalid value for 'direction", value);
2149 else if (EQ (keyword, Qfinal))
2151 CHECK_CHAR_COERCE_INT (value);
2152 final = XCHAR (value);
2153 if (final < '0' || final > '~')
2154 signal_simple_error ("Invalid value for 'final", value);
2157 else if (EQ (keyword, Qccl_program))
2159 CHECK_VECTOR (value);
2160 ccl_program = value;
2164 signal_simple_error ("Unrecognized property", keyword);
2168 error ("'final must be specified");
2169 if (dimension == 2 && final > 0x5F)
2171 ("Final must be in the range 0x30 - 0x5F for dimension == 2",
2175 type = (chars == 94) ? CHARSET_TYPE_94 : CHARSET_TYPE_96;
2177 type = (chars == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96;
2179 if (!NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_LEFT_TO_RIGHT)) ||
2180 !NILP (CHARSET_BY_ATTRIBUTES (type, final, CHARSET_RIGHT_TO_LEFT)))
2182 ("Character set already defined for this DIMENSION/CHARS/FINAL combo");
2184 id = get_unallocated_leading_byte (dimension);
2186 if (NILP (doc_string))
2187 doc_string = build_string ("");
2189 if (NILP (registry))
2190 registry = build_string ("");
2192 if (NILP (short_name))
2193 XSETSTRING (short_name, XSYMBOL (name)->name);
2195 if (NILP (long_name))
2196 long_name = doc_string;
2199 columns = dimension;
2201 if (byte_offset < 0)
2205 else if (chars == 96)
2211 charset = make_charset (id, name, chars, dimension, columns, graphic,
2212 final, direction, short_name, long_name,
2213 doc_string, registry,
2214 Qnil, 0, 0, 0, byte_offset);
2215 if (!NILP (ccl_program))
2216 XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2220 DEFUN ("make-reverse-direction-charset", Fmake_reverse_direction_charset,
2222 Make a charset equivalent to CHARSET but which goes in the opposite direction.
2223 NEW-NAME is the name of the new charset. Return the new charset.
2225 (charset, new_name))
2227 Lisp_Object new_charset = Qnil;
2228 int id, chars, dimension, columns, graphic, final;
2230 Lisp_Object registry, doc_string, short_name, long_name;
2233 charset = Fget_charset (charset);
2234 if (!NILP (XCHARSET_REVERSE_DIRECTION_CHARSET (charset)))
2235 signal_simple_error ("Charset already has reverse-direction charset",
2238 CHECK_SYMBOL (new_name);
2239 if (!NILP (Ffind_charset (new_name)))
2240 signal_simple_error ("Cannot redefine existing charset", new_name);
2242 cs = XCHARSET (charset);
2244 chars = CHARSET_CHARS (cs);
2245 dimension = CHARSET_DIMENSION (cs);
2246 columns = CHARSET_COLUMNS (cs);
2247 id = get_unallocated_leading_byte (dimension);
2249 graphic = CHARSET_GRAPHIC (cs);
2250 final = CHARSET_FINAL (cs);
2251 direction = CHARSET_RIGHT_TO_LEFT;
2252 if (CHARSET_DIRECTION (cs) == CHARSET_RIGHT_TO_LEFT)
2253 direction = CHARSET_LEFT_TO_RIGHT;
2254 doc_string = CHARSET_DOC_STRING (cs);
2255 short_name = CHARSET_SHORT_NAME (cs);
2256 long_name = CHARSET_LONG_NAME (cs);
2257 registry = CHARSET_REGISTRY (cs);
2259 new_charset = make_charset (id, new_name, chars, dimension, columns,
2260 graphic, final, direction, short_name, long_name,
2261 doc_string, registry,
2263 CHARSET_DECODING_TABLE(cs),
2264 CHARSET_UCS_MIN(cs),
2265 CHARSET_UCS_MAX(cs),
2266 CHARSET_CODE_OFFSET(cs),
2267 CHARSET_BYTE_OFFSET(cs)
2273 CHARSET_REVERSE_DIRECTION_CHARSET (cs) = new_charset;
2274 XCHARSET_REVERSE_DIRECTION_CHARSET (new_charset) = charset;
2279 DEFUN ("define-charset-alias", Fdefine_charset_alias, 2, 2, 0, /*
2280 Define symbol ALIAS as an alias for CHARSET.
2284 CHECK_SYMBOL (alias);
2285 charset = Fget_charset (charset);
2286 return Fputhash (alias, charset, Vcharset_hash_table);
2289 /* #### Reverse direction charsets not yet implemented. */
2291 DEFUN ("charset-reverse-direction-charset", Fcharset_reverse_direction_charset,
2293 Return the reverse-direction charset parallel to CHARSET, if any.
2294 This is the charset with the same properties (in particular, the same
2295 dimension, number of characters per dimension, and final byte) as
2296 CHARSET but whose characters are displayed in the opposite direction.
2300 charset = Fget_charset (charset);
2301 return XCHARSET_REVERSE_DIRECTION_CHARSET (charset);
2305 DEFUN ("charset-from-attributes", Fcharset_from_attributes, 3, 4, 0, /*
2306 Return a charset with the given DIMENSION, CHARS, FINAL, and DIRECTION.
2307 If DIRECTION is omitted, both directions will be checked (left-to-right
2308 will be returned if character sets exist for both directions).
2310 (dimension, chars, final, direction))
2312 int dm, ch, fi, di = -1;
2314 Lisp_Object obj = Qnil;
2316 CHECK_INT (dimension);
2317 dm = XINT (dimension);
2318 if (dm < 1 || dm > 2)
2319 signal_simple_error ("Invalid value for DIMENSION", dimension);
2323 if (ch != 94 && ch != 96)
2324 signal_simple_error ("Invalid value for CHARS", chars);
2326 CHECK_CHAR_COERCE_INT (final);
2328 if (fi < '0' || fi > '~')
2329 signal_simple_error ("Invalid value for FINAL", final);
2331 if (EQ (direction, Ql2r))
2332 di = CHARSET_LEFT_TO_RIGHT;
2333 else if (EQ (direction, Qr2l))
2334 di = CHARSET_RIGHT_TO_LEFT;
2335 else if (!NILP (direction))
2336 signal_simple_error ("Invalid value for DIRECTION", direction);
2338 if (dm == 2 && fi > 0x5F)
2340 ("Final must be in the range 0x30 - 0x5F for dimension == 2", final);
2343 type = (ch == 94) ? CHARSET_TYPE_94 : CHARSET_TYPE_96;
2345 type = (ch == 94) ? CHARSET_TYPE_94X94 : CHARSET_TYPE_96X96;
2349 obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_LEFT_TO_RIGHT);
2351 obj = CHARSET_BY_ATTRIBUTES (type, fi, CHARSET_RIGHT_TO_LEFT);
2354 obj = CHARSET_BY_ATTRIBUTES (type, fi, di);
2357 return XCHARSET_NAME (obj);
2361 DEFUN ("charset-short-name", Fcharset_short_name, 1, 1, 0, /*
2362 Return short name of CHARSET.
2366 return XCHARSET_SHORT_NAME (Fget_charset (charset));
2369 DEFUN ("charset-long-name", Fcharset_long_name, 1, 1, 0, /*
2370 Return long name of CHARSET.
2374 return XCHARSET_LONG_NAME (Fget_charset (charset));
2377 DEFUN ("charset-description", Fcharset_description, 1, 1, 0, /*
2378 Return description of CHARSET.
2382 return XCHARSET_DOC_STRING (Fget_charset (charset));
2385 DEFUN ("charset-dimension", Fcharset_dimension, 1, 1, 0, /*
2386 Return dimension of CHARSET.
2390 return make_int (XCHARSET_DIMENSION (Fget_charset (charset)));
2393 DEFUN ("charset-property", Fcharset_property, 2, 2, 0, /*
2394 Return property PROP of CHARSET.
2395 Recognized properties are those listed in `make-charset', as well as
2396 'name and 'doc-string.
2402 charset = Fget_charset (charset);
2403 cs = XCHARSET (charset);
2405 CHECK_SYMBOL (prop);
2406 if (EQ (prop, Qname)) return CHARSET_NAME (cs);
2407 if (EQ (prop, Qshort_name)) return CHARSET_SHORT_NAME (cs);
2408 if (EQ (prop, Qlong_name)) return CHARSET_LONG_NAME (cs);
2409 if (EQ (prop, Qdoc_string)) return CHARSET_DOC_STRING (cs);
2410 if (EQ (prop, Qdimension)) return make_int (CHARSET_DIMENSION (cs));
2411 if (EQ (prop, Qcolumns)) return make_int (CHARSET_COLUMNS (cs));
2412 if (EQ (prop, Qgraphic)) return make_int (CHARSET_GRAPHIC (cs));
2413 if (EQ (prop, Qfinal)) return make_char (CHARSET_FINAL (cs));
2414 if (EQ (prop, Qchars)) return make_int (CHARSET_CHARS (cs));
2415 if (EQ (prop, Qregistry)) return CHARSET_REGISTRY (cs);
2416 if (EQ (prop, Qccl_program)) return CHARSET_CCL_PROGRAM (cs);
2417 if (EQ (prop, Qdirection))
2418 return CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? Ql2r : Qr2l;
2419 if (EQ (prop, Qreverse_direction_charset))
2421 Lisp_Object obj = CHARSET_REVERSE_DIRECTION_CHARSET (cs);
2425 return XCHARSET_NAME (obj);
2427 signal_simple_error ("Unrecognized charset property name", prop);
2428 return Qnil; /* not reached */
2431 DEFUN ("charset-id", Fcharset_id, 1, 1, 0, /*
2432 Return charset identification number of CHARSET.
2436 return make_int(XCHARSET_LEADING_BYTE (Fget_charset (charset)));
2439 /* #### We need to figure out which properties we really want to
2442 DEFUN ("set-charset-ccl-program", Fset_charset_ccl_program, 2, 2, 0, /*
2443 Set the 'ccl-program property of CHARSET to CCL-PROGRAM.
2445 (charset, ccl_program))
2447 charset = Fget_charset (charset);
2448 CHECK_VECTOR (ccl_program);
2449 XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2454 invalidate_charset_font_caches (Lisp_Object charset)
2456 /* Invalidate font cache entries for charset on all devices. */
2457 Lisp_Object devcons, concons, hash_table;
2458 DEVICE_LOOP_NO_BREAK (devcons, concons)
2460 struct device *d = XDEVICE (XCAR (devcons));
2461 hash_table = Fgethash (charset, d->charset_font_cache, Qunbound);
2462 if (!UNBOUNDP (hash_table))
2463 Fclrhash (hash_table);
2467 DEFUN ("set-charset-registry", Fset_charset_registry, 2, 2, 0, /*
2468 Set the 'registry property of CHARSET to REGISTRY.
2470 (charset, registry))
2472 charset = Fget_charset (charset);
2473 CHECK_STRING (registry);
2474 XCHARSET_REGISTRY (charset) = registry;
2475 invalidate_charset_font_caches (charset);
2476 face_property_was_changed (Vdefault_face, Qfont, Qglobal);
2481 DEFUN ("charset-mapping-table", Fcharset_mapping_table, 1, 1, 0, /*
2482 Return mapping-table of CHARSET.
2486 return XCHARSET_DECODING_TABLE (Fget_charset (charset));
2489 DEFUN ("set-charset-mapping-table", Fset_charset_mapping_table, 2, 2, 0, /*
2490 Set mapping-table of CHARSET to TABLE.
2494 struct Lisp_Charset *cs;
2495 Lisp_Object old_table;
2498 charset = Fget_charset (charset);
2499 cs = XCHARSET (charset);
2501 if (EQ (table, Qnil))
2503 CHARSET_DECODING_TABLE(cs) = table;
2506 else if (VECTORP (table))
2508 int ccs_len = CHARSET_BYTE_SIZE (cs);
2510 if (XVECTOR_LENGTH (table) > ccs_len)
2511 args_out_of_range (table, make_int (CHARSET_CHARS (cs)));
2512 old_table = CHARSET_DECODING_TABLE(cs);
2513 CHARSET_DECODING_TABLE(cs) = table;
2516 signal_error (Qwrong_type_argument,
2517 list2 (build_translated_string ("vector-or-nil-p"),
2519 /* signal_simple_error ("Wrong type argument: vector-or-nil-p", table); */
2521 switch (CHARSET_DIMENSION (cs))
2524 for (i = 0; i < XVECTOR_LENGTH (table); i++)
2526 Lisp_Object c = XVECTOR_DATA(table)[i];
2531 make_int (i + CHARSET_BYTE_OFFSET (cs)));
2535 for (i = 0; i < XVECTOR_LENGTH (table); i++)
2537 Lisp_Object v = XVECTOR_DATA(table)[i];
2543 if (XVECTOR_LENGTH (v) > CHARSET_CHARS (cs))
2545 CHARSET_DECODING_TABLE(cs) = old_table;
2546 args_out_of_range (v, make_int (CHARSET_CHARS (cs)));
2548 for (j = 0; j < XVECTOR_LENGTH (v); j++)
2550 Lisp_Object c = XVECTOR_DATA(v)[j];
2555 make_int ( ((i + CHARSET_BYTE_OFFSET (cs)) << 8)
2556 | (j + CHARSET_BYTE_OFFSET (cs)) ));
2560 put_char_attribute (v, charset,
2561 make_int (i + CHARSET_BYTE_OFFSET (cs)));
2570 /************************************************************************/
2571 /* Lisp primitives for working with characters */
2572 /************************************************************************/
2575 DEFUN ("decode-char", Fdecode_char, 2, 2, 0, /*
2576 Make a character from CHARSET and code-point CODE.
2582 charset = Fget_charset (charset);
2585 if (XCHARSET_GRAPHIC (charset) == 1)
2587 return make_char (DECODE_CHAR (charset, c));
2591 DEFUN ("make-char", Fmake_char, 2, 3, 0, /*
2592 Make a character from CHARSET and octets ARG1 and ARG2.
2593 ARG2 is required only for characters from two-dimensional charsets.
2594 For example, (make-char 'latin-iso8859-2 185) will return the Latin 2
2595 character s with caron.
2597 (charset, arg1, arg2))
2601 int lowlim, highlim;
2603 charset = Fget_charset (charset);
2604 cs = XCHARSET (charset);
2606 if (EQ (charset, Vcharset_ascii)) lowlim = 0, highlim = 127;
2607 else if (EQ (charset, Vcharset_control_1)) lowlim = 0, highlim = 31;
2609 else if (CHARSET_CHARS (cs) == 256) lowlim = 0, highlim = 255;
2611 else if (CHARSET_CHARS (cs) == 94) lowlim = 33, highlim = 126;
2612 else /* CHARSET_CHARS (cs) == 96) */ lowlim = 32, highlim = 127;
2615 /* It is useful (and safe, according to Olivier Galibert) to strip
2616 the 8th bit off ARG1 and ARG2 becaue it allows programmers to
2617 write (make-char 'latin-iso8859-2 CODE) where code is the actual
2618 Latin 2 code of the character. */
2626 if (a1 < lowlim || a1 > highlim)
2627 args_out_of_range_3 (arg1, make_int (lowlim), make_int (highlim));
2629 if (CHARSET_DIMENSION (cs) == 1)
2633 ("Charset is of dimension one; second octet must be nil", arg2);
2634 return make_char (MAKE_CHAR (charset, a1, 0));
2643 a2 = XINT (arg2) & 0x7f;
2645 if (a2 < lowlim || a2 > highlim)
2646 args_out_of_range_3 (arg2, make_int (lowlim), make_int (highlim));
2648 return make_char (MAKE_CHAR (charset, a1, a2));
2651 DEFUN ("char-charset", Fchar_charset, 1, 1, 0, /*
2652 Return the character set of char CH.
2656 CHECK_CHAR_COERCE_INT (ch);
2658 return XCHARSET_NAME (CHAR_CHARSET (XCHAR (ch)));
2661 DEFUN ("char-octet", Fchar_octet, 1, 2, 0, /*
2662 Return the octet numbered N (should be 0 or 1) of char CH.
2663 N defaults to 0 if omitted.
2667 Lisp_Object charset;
2670 CHECK_CHAR_COERCE_INT (ch);
2672 BREAKUP_CHAR (XCHAR (ch), charset, octet0, octet1);
2674 if (NILP (n) || EQ (n, Qzero))
2675 return make_int (octet0);
2676 else if (EQ (n, make_int (1)))
2677 return make_int (octet1);
2679 signal_simple_error ("Octet number must be 0 or 1", n);
2682 DEFUN ("split-char", Fsplit_char, 1, 1, 0, /*
2683 Return list of charset and one or two position-codes of CHAR.
2687 /* This function can GC */
2688 struct gcpro gcpro1, gcpro2;
2689 Lisp_Object charset = Qnil;
2690 Lisp_Object rc = Qnil;
2698 GCPRO2 (charset, rc);
2699 CHECK_CHAR_COERCE_INT (character);
2702 code_point = ENCODE_CHAR (XCHAR (character), charset);
2703 dimension = XCHARSET_DIMENSION (charset);
2704 while (dimension > 0)
2706 rc = Fcons (make_int (code_point & 255), rc);
2710 rc = Fcons (XCHARSET_NAME (charset), rc);
2712 BREAKUP_CHAR (XCHAR (character), charset, c1, c2);
2714 if (XCHARSET_DIMENSION (Fget_charset (charset)) == 2)
2716 rc = list3 (XCHARSET_NAME (charset), make_int (c1), make_int (c2));
2720 rc = list2 (XCHARSET_NAME (charset), make_int (c1));
2729 #ifdef ENABLE_COMPOSITE_CHARS
2730 /************************************************************************/
2731 /* composite character functions */
2732 /************************************************************************/
2735 lookup_composite_char (Bufbyte *str, int len)
2737 Lisp_Object lispstr = make_string (str, len);
2738 Lisp_Object ch = Fgethash (lispstr,
2739 Vcomposite_char_string2char_hash_table,
2745 if (composite_char_row_next >= 128)
2746 signal_simple_error ("No more composite chars available", lispstr);
2747 emch = MAKE_CHAR (Vcharset_composite, composite_char_row_next,
2748 composite_char_col_next);
2749 Fputhash (make_char (emch), lispstr,
2750 Vcomposite_char_char2string_hash_table);
2751 Fputhash (lispstr, make_char (emch),
2752 Vcomposite_char_string2char_hash_table);
2753 composite_char_col_next++;
2754 if (composite_char_col_next >= 128)
2756 composite_char_col_next = 32;
2757 composite_char_row_next++;
2766 composite_char_string (Emchar ch)
2768 Lisp_Object str = Fgethash (make_char (ch),
2769 Vcomposite_char_char2string_hash_table,
2771 assert (!UNBOUNDP (str));
2775 xxDEFUN ("make-composite-char", Fmake_composite_char, 1, 1, 0, /*
2776 Convert a string into a single composite character.
2777 The character is the result of overstriking all the characters in
2782 CHECK_STRING (string);
2783 return make_char (lookup_composite_char (XSTRING_DATA (string),
2784 XSTRING_LENGTH (string)));
2787 xxDEFUN ("composite-char-string", Fcomposite_char_string, 1, 1, 0, /*
2788 Return a string of the characters comprising a composite character.
2796 if (CHAR_LEADING_BYTE (emch) != LEADING_BYTE_COMPOSITE)
2797 signal_simple_error ("Must be composite char", ch);
2798 return composite_char_string (emch);
2800 #endif /* ENABLE_COMPOSITE_CHARS */
2803 /************************************************************************/
2804 /* initialization */
2805 /************************************************************************/
2808 syms_of_mule_charset (void)
2811 INIT_LRECORD_IMPLEMENTATION (byte_table);
2812 INIT_LRECORD_IMPLEMENTATION (char_id_table);
2814 INIT_LRECORD_IMPLEMENTATION (charset);
2816 DEFSUBR (Fcharsetp);
2817 DEFSUBR (Ffind_charset);
2818 DEFSUBR (Fget_charset);
2819 DEFSUBR (Fcharset_list);
2820 DEFSUBR (Fcharset_name);
2821 DEFSUBR (Fmake_charset);
2822 DEFSUBR (Fmake_reverse_direction_charset);
2823 /* DEFSUBR (Freverse_direction_charset); */
2824 DEFSUBR (Fdefine_charset_alias);
2825 DEFSUBR (Fcharset_from_attributes);
2826 DEFSUBR (Fcharset_short_name);
2827 DEFSUBR (Fcharset_long_name);
2828 DEFSUBR (Fcharset_description);
2829 DEFSUBR (Fcharset_dimension);
2830 DEFSUBR (Fcharset_property);
2831 DEFSUBR (Fcharset_id);
2832 DEFSUBR (Fset_charset_ccl_program);
2833 DEFSUBR (Fset_charset_registry);
2835 DEFSUBR (Fchar_attribute_alist);
2836 DEFSUBR (Fget_char_attribute);
2837 DEFSUBR (Fput_char_attribute);
2838 DEFSUBR (Fremove_char_attribute);
2839 DEFSUBR (Fdefine_char);
2840 DEFSUBR (Fchar_variants);
2841 DEFSUBR (Fget_composite_char);
2842 DEFSUBR (Fcharset_mapping_table);
2843 DEFSUBR (Fset_charset_mapping_table);
2847 DEFSUBR (Fdecode_char);
2849 DEFSUBR (Fmake_char);
2850 DEFSUBR (Fchar_charset);
2851 DEFSUBR (Fchar_octet);
2852 DEFSUBR (Fsplit_char);
2854 #ifdef ENABLE_COMPOSITE_CHARS
2855 DEFSUBR (Fmake_composite_char);
2856 DEFSUBR (Fcomposite_char_string);
2859 defsymbol (&Qcharsetp, "charsetp");
2860 defsymbol (&Qregistry, "registry");
2861 defsymbol (&Qfinal, "final");
2862 defsymbol (&Qgraphic, "graphic");
2863 defsymbol (&Qdirection, "direction");
2864 defsymbol (&Qreverse_direction_charset, "reverse-direction-charset");
2865 defsymbol (&Qshort_name, "short-name");
2866 defsymbol (&Qlong_name, "long-name");
2868 defsymbol (&Ql2r, "l2r");
2869 defsymbol (&Qr2l, "r2l");
2871 /* Charsets, compatible with FSF 20.3
2872 Naming convention is Script-Charset[-Edition] */
2873 defsymbol (&Qascii, "ascii");
2874 defsymbol (&Qcontrol_1, "control-1");
2875 defsymbol (&Qlatin_iso8859_1, "latin-iso8859-1");
2876 defsymbol (&Qlatin_iso8859_2, "latin-iso8859-2");
2877 defsymbol (&Qlatin_iso8859_3, "latin-iso8859-3");
2878 defsymbol (&Qlatin_iso8859_4, "latin-iso8859-4");
2879 defsymbol (&Qthai_tis620, "thai-tis620");
2880 defsymbol (&Qgreek_iso8859_7, "greek-iso8859-7");
2881 defsymbol (&Qarabic_iso8859_6, "arabic-iso8859-6");
2882 defsymbol (&Qhebrew_iso8859_8, "hebrew-iso8859-8");
2883 defsymbol (&Qkatakana_jisx0201, "katakana-jisx0201");
2884 defsymbol (&Qlatin_jisx0201, "latin-jisx0201");
2885 defsymbol (&Qcyrillic_iso8859_5, "cyrillic-iso8859-5");
2886 defsymbol (&Qlatin_iso8859_9, "latin-iso8859-9");
2887 defsymbol (&Qjapanese_jisx0208_1978, "japanese-jisx0208-1978");
2888 defsymbol (&Qchinese_gb2312, "chinese-gb2312");
2889 defsymbol (&Qjapanese_jisx0208, "japanese-jisx0208");
2890 defsymbol (&Qjapanese_jisx0208_1990, "japanese-jisx0208-1990");
2891 defsymbol (&Qkorean_ksc5601, "korean-ksc5601");
2892 defsymbol (&Qjapanese_jisx0212, "japanese-jisx0212");
2893 defsymbol (&Qchinese_cns11643_1, "chinese-cns11643-1");
2894 defsymbol (&Qchinese_cns11643_2, "chinese-cns11643-2");
2896 defsymbol (&Qname, "name");
2897 defsymbol (&Q_ucs, "->ucs");
2898 defsymbol (&Q_decomposition, "->decomposition");
2899 defsymbol (&Qcompat, "compat");
2900 defsymbol (&Qisolated, "isolated");
2901 defsymbol (&Qinitial, "initial");
2902 defsymbol (&Qmedial, "medial");
2903 defsymbol (&Qfinal, "final");
2904 defsymbol (&Qvertical, "vertical");
2905 defsymbol (&QnoBreak, "noBreak");
2906 defsymbol (&Qfraction, "fraction");
2907 defsymbol (&Qsuper, "super");
2908 defsymbol (&Qsub, "sub");
2909 defsymbol (&Qcircle, "circle");
2910 defsymbol (&Qsquare, "square");
2911 defsymbol (&Qwide, "wide");
2912 defsymbol (&Qnarrow, "narrow");
2913 defsymbol (&Qsmall, "small");
2914 defsymbol (&Qfont, "font");
2915 defsymbol (&Qucs, "ucs");
2916 defsymbol (&Qucs_bmp, "ucs-bmp");
2917 defsymbol (&Qlatin_viscii, "latin-viscii");
2918 defsymbol (&Qlatin_tcvn5712, "latin-tcvn5712");
2919 defsymbol (&Qlatin_viscii_lower, "latin-viscii-lower");
2920 defsymbol (&Qlatin_viscii_upper, "latin-viscii-upper");
2921 defsymbol (&Qvietnamese_viscii_lower, "vietnamese-viscii-lower");
2922 defsymbol (&Qvietnamese_viscii_upper, "vietnamese-viscii-upper");
2923 defsymbol (&Qideograph_daikanwa, "ideograph-daikanwa");
2924 defsymbol (&Qmojikyo, "mojikyo");
2925 defsymbol (&Qmojikyo_pj_1, "mojikyo-pj-1");
2926 defsymbol (&Qmojikyo_pj_2, "mojikyo-pj-2");
2927 defsymbol (&Qmojikyo_pj_3, "mojikyo-pj-3");
2928 defsymbol (&Qmojikyo_pj_4, "mojikyo-pj-4");
2929 defsymbol (&Qmojikyo_pj_5, "mojikyo-pj-5");
2930 defsymbol (&Qmojikyo_pj_6, "mojikyo-pj-6");
2931 defsymbol (&Qmojikyo_pj_7, "mojikyo-pj-7");
2932 defsymbol (&Qmojikyo_pj_8, "mojikyo-pj-8");
2933 defsymbol (&Qmojikyo_pj_9, "mojikyo-pj-9");
2934 defsymbol (&Qmojikyo_pj_10, "mojikyo-pj-10");
2935 defsymbol (&Qmojikyo_pj_11, "mojikyo-pj-11");
2936 defsymbol (&Qmojikyo_pj_12, "mojikyo-pj-12");
2937 defsymbol (&Qmojikyo_pj_13, "mojikyo-pj-13");
2938 defsymbol (&Qmojikyo_pj_14, "mojikyo-pj-14");
2939 defsymbol (&Qmojikyo_pj_15, "mojikyo-pj-15");
2940 defsymbol (&Qmojikyo_pj_16, "mojikyo-pj-16");
2941 defsymbol (&Qmojikyo_pj_17, "mojikyo-pj-17");
2942 defsymbol (&Qmojikyo_pj_18, "mojikyo-pj-18");
2943 defsymbol (&Qmojikyo_pj_19, "mojikyo-pj-19");
2944 defsymbol (&Qmojikyo_pj_20, "mojikyo-pj-20");
2945 defsymbol (&Qmojikyo_pj_21, "mojikyo-pj-21");
2946 defsymbol (&Qethiopic_ucs, "ethiopic-ucs");
2948 defsymbol (&Qchinese_big5_1, "chinese-big5-1");
2949 defsymbol (&Qchinese_big5_2, "chinese-big5-2");
2951 defsymbol (&Qcomposite, "composite");
2955 vars_of_mule_charset (void)
2962 chlook = xnew (struct charset_lookup);
2963 dumpstruct (&chlook, &charset_lookup_description);
2965 /* Table of charsets indexed by leading byte. */
2966 for (i = 0; i < countof (chlook->charset_by_leading_byte); i++)
2967 chlook->charset_by_leading_byte[i] = Qnil;
2970 /* Table of charsets indexed by type/final-byte. */
2971 for (i = 0; i < countof (chlook->charset_by_attributes); i++)
2972 for (j = 0; j < countof (chlook->charset_by_attributes[0]); j++)
2973 chlook->charset_by_attributes[i][j] = Qnil;
2975 /* Table of charsets indexed by type/final-byte/direction. */
2976 for (i = 0; i < countof (chlook->charset_by_attributes); i++)
2977 for (j = 0; j < countof (chlook->charset_by_attributes[0]); j++)
2978 for (k = 0; k < countof (chlook->charset_by_attributes[0][0]); k++)
2979 chlook->charset_by_attributes[i][j][k] = Qnil;
2983 chlook->next_allocated_leading_byte = MIN_LEADING_BYTE_PRIVATE;
2985 chlook->next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1;
2986 chlook->next_allocated_2_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_2;
2990 leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
2991 DEFVAR_INT ("leading-code-private-11", &leading_code_private_11 /*
2992 Leading-code of private TYPE9N charset of column-width 1.
2994 leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
2998 Vutf_2000_version = build_string("0.15 (Sangō)");
2999 DEFVAR_LISP ("utf-2000-version", &Vutf_2000_version /*
3000 Version number of UTF-2000.
3003 staticpro (&Vcharacter_attribute_table);
3004 Vcharacter_attribute_table = make_char_id_table (Qnil, 0);
3006 staticpro (&Vcharacter_name_table);
3007 Vcharacter_name_table = make_char_id_table (Qnil, 0);
3009 /* staticpro (&Vcharacter_composition_table); */
3010 Vcharacter_composition_table = make_char_id_table (Qnil, -1);
3012 staticpro (&Vcharacter_variant_table);
3013 Vcharacter_variant_table = make_char_id_table (Qnil, 0);
3015 Vdefault_coded_charset_priority_list = Qnil;
3016 DEFVAR_LISP ("default-coded-charset-priority-list",
3017 &Vdefault_coded_charset_priority_list /*
3018 Default order of preferred coded-character-sets.
3024 complex_vars_of_mule_charset (void)
3026 staticpro (&Vcharset_hash_table);
3027 Vcharset_hash_table =
3028 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3030 /* Predefined character sets. We store them into variables for
3034 staticpro (&Vcharset_ucs);
3036 make_charset (LEADING_BYTE_UCS, Qucs, 256, 4,
3037 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3038 build_string ("UCS"),
3039 build_string ("UCS"),
3040 build_string ("ISO/IEC 10646"),
3042 Qnil, 0, 0xFFFFFFF, 0, 0);
3043 staticpro (&Vcharset_ucs_bmp);
3045 make_charset (LEADING_BYTE_UCS_BMP, Qucs_bmp, 256, 2,
3046 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3047 build_string ("BMP"),
3048 build_string ("BMP"),
3049 build_string ("ISO/IEC 10646 Group 0 Plane 0 (BMP)"),
3050 build_string ("\\(ISO10646.*-1\\|UNICODE[23]?-0\\)"),
3051 Qnil, 0, 0xFFFF, 0, 0);
3053 # define MIN_CHAR_THAI 0
3054 # define MAX_CHAR_THAI 0
3055 # define MIN_CHAR_HEBREW 0
3056 # define MAX_CHAR_HEBREW 0
3057 # define MIN_CHAR_HALFWIDTH_KATAKANA 0
3058 # define MAX_CHAR_HALFWIDTH_KATAKANA 0
3060 staticpro (&Vcharset_ascii);
3062 make_charset (LEADING_BYTE_ASCII, Qascii, 94, 1,
3063 1, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3064 build_string ("ASCII"),
3065 build_string ("ASCII)"),
3066 build_string ("ASCII (ISO646 IRV)"),
3067 build_string ("\\(iso8859-[0-9]*\\|-ascii\\)"),
3068 Qnil, 0, 0x7F, 0, 0);
3069 staticpro (&Vcharset_control_1);
3070 Vcharset_control_1 =
3071 make_charset (LEADING_BYTE_CONTROL_1, Qcontrol_1, 94, 1,
3072 1, 1, 0, CHARSET_LEFT_TO_RIGHT,
3073 build_string ("C1"),
3074 build_string ("Control characters"),
3075 build_string ("Control characters 128-191"),
3077 Qnil, 0x80, 0x9F, 0, 0);
3078 staticpro (&Vcharset_latin_iso8859_1);
3079 Vcharset_latin_iso8859_1 =
3080 make_charset (LEADING_BYTE_LATIN_ISO8859_1, Qlatin_iso8859_1, 96, 1,
3081 1, 1, 'A', CHARSET_LEFT_TO_RIGHT,
3082 build_string ("Latin-1"),
3083 build_string ("ISO8859-1 (Latin-1)"),
3084 build_string ("ISO8859-1 (Latin-1)"),
3085 build_string ("iso8859-1"),
3086 Qnil, 0xA0, 0xFF, 0, 32);
3087 staticpro (&Vcharset_latin_iso8859_2);
3088 Vcharset_latin_iso8859_2 =
3089 make_charset (LEADING_BYTE_LATIN_ISO8859_2, Qlatin_iso8859_2, 96, 1,
3090 1, 1, 'B', CHARSET_LEFT_TO_RIGHT,
3091 build_string ("Latin-2"),
3092 build_string ("ISO8859-2 (Latin-2)"),
3093 build_string ("ISO8859-2 (Latin-2)"),
3094 build_string ("iso8859-2"),
3096 staticpro (&Vcharset_latin_iso8859_3);
3097 Vcharset_latin_iso8859_3 =
3098 make_charset (LEADING_BYTE_LATIN_ISO8859_3, Qlatin_iso8859_3, 96, 1,
3099 1, 1, 'C', CHARSET_LEFT_TO_RIGHT,
3100 build_string ("Latin-3"),
3101 build_string ("ISO8859-3 (Latin-3)"),
3102 build_string ("ISO8859-3 (Latin-3)"),
3103 build_string ("iso8859-3"),
3105 staticpro (&Vcharset_latin_iso8859_4);
3106 Vcharset_latin_iso8859_4 =
3107 make_charset (LEADING_BYTE_LATIN_ISO8859_4, Qlatin_iso8859_4, 96, 1,
3108 1, 1, 'D', CHARSET_LEFT_TO_RIGHT,
3109 build_string ("Latin-4"),
3110 build_string ("ISO8859-4 (Latin-4)"),
3111 build_string ("ISO8859-4 (Latin-4)"),
3112 build_string ("iso8859-4"),
3114 staticpro (&Vcharset_thai_tis620);
3115 Vcharset_thai_tis620 =
3116 make_charset (LEADING_BYTE_THAI_TIS620, Qthai_tis620, 96, 1,
3117 1, 1, 'T', CHARSET_LEFT_TO_RIGHT,
3118 build_string ("TIS620"),
3119 build_string ("TIS620 (Thai)"),
3120 build_string ("TIS620.2529 (Thai)"),
3121 build_string ("tis620"),
3122 Qnil, MIN_CHAR_THAI, MAX_CHAR_THAI, 0, 32);
3123 staticpro (&Vcharset_greek_iso8859_7);
3124 Vcharset_greek_iso8859_7 =
3125 make_charset (LEADING_BYTE_GREEK_ISO8859_7, Qgreek_iso8859_7, 96, 1,
3126 1, 1, 'F', CHARSET_LEFT_TO_RIGHT,
3127 build_string ("ISO8859-7"),
3128 build_string ("ISO8859-7 (Greek)"),
3129 build_string ("ISO8859-7 (Greek)"),
3130 build_string ("iso8859-7"),
3132 0 /* MIN_CHAR_GREEK */,
3133 0 /* MAX_CHAR_GREEK */, 0, 32);
3134 staticpro (&Vcharset_arabic_iso8859_6);
3135 Vcharset_arabic_iso8859_6 =
3136 make_charset (LEADING_BYTE_ARABIC_ISO8859_6, Qarabic_iso8859_6, 96, 1,
3137 1, 1, 'G', CHARSET_RIGHT_TO_LEFT,
3138 build_string ("ISO8859-6"),
3139 build_string ("ISO8859-6 (Arabic)"),
3140 build_string ("ISO8859-6 (Arabic)"),
3141 build_string ("iso8859-6"),
3143 staticpro (&Vcharset_hebrew_iso8859_8);
3144 Vcharset_hebrew_iso8859_8 =
3145 make_charset (LEADING_BYTE_HEBREW_ISO8859_8, Qhebrew_iso8859_8, 96, 1,
3146 1, 1, 'H', CHARSET_RIGHT_TO_LEFT,
3147 build_string ("ISO8859-8"),
3148 build_string ("ISO8859-8 (Hebrew)"),
3149 build_string ("ISO8859-8 (Hebrew)"),
3150 build_string ("iso8859-8"),
3151 Qnil, MIN_CHAR_HEBREW, MAX_CHAR_HEBREW, 0, 32);
3152 staticpro (&Vcharset_katakana_jisx0201);
3153 Vcharset_katakana_jisx0201 =
3154 make_charset (LEADING_BYTE_KATAKANA_JISX0201, Qkatakana_jisx0201, 94, 1,
3155 1, 1, 'I', CHARSET_LEFT_TO_RIGHT,
3156 build_string ("JISX0201 Kana"),
3157 build_string ("JISX0201.1976 (Japanese Kana)"),
3158 build_string ("JISX0201.1976 Japanese Kana"),
3159 build_string ("jisx0201\\.1976"),
3161 staticpro (&Vcharset_latin_jisx0201);
3162 Vcharset_latin_jisx0201 =
3163 make_charset (LEADING_BYTE_LATIN_JISX0201, Qlatin_jisx0201, 94, 1,
3164 1, 0, 'J', CHARSET_LEFT_TO_RIGHT,
3165 build_string ("JISX0201 Roman"),
3166 build_string ("JISX0201.1976 (Japanese Roman)"),
3167 build_string ("JISX0201.1976 Japanese Roman"),
3168 build_string ("jisx0201\\.1976"),
3170 staticpro (&Vcharset_cyrillic_iso8859_5);
3171 Vcharset_cyrillic_iso8859_5 =
3172 make_charset (LEADING_BYTE_CYRILLIC_ISO8859_5, Qcyrillic_iso8859_5, 96, 1,
3173 1, 1, 'L', CHARSET_LEFT_TO_RIGHT,
3174 build_string ("ISO8859-5"),
3175 build_string ("ISO8859-5 (Cyrillic)"),
3176 build_string ("ISO8859-5 (Cyrillic)"),
3177 build_string ("iso8859-5"),
3179 0 /* MIN_CHAR_CYRILLIC */,
3180 0 /* MAX_CHAR_CYRILLIC */, 0, 32);
3181 staticpro (&Vcharset_latin_iso8859_9);
3182 Vcharset_latin_iso8859_9 =
3183 make_charset (LEADING_BYTE_LATIN_ISO8859_9, Qlatin_iso8859_9, 96, 1,
3184 1, 1, 'M', CHARSET_LEFT_TO_RIGHT,
3185 build_string ("Latin-5"),
3186 build_string ("ISO8859-9 (Latin-5)"),
3187 build_string ("ISO8859-9 (Latin-5)"),
3188 build_string ("iso8859-9"),
3190 staticpro (&Vcharset_japanese_jisx0208_1978);
3191 Vcharset_japanese_jisx0208_1978 =
3192 make_charset (LEADING_BYTE_JAPANESE_JISX0208_1978,
3193 Qjapanese_jisx0208_1978, 94, 2,
3194 2, 0, '@', CHARSET_LEFT_TO_RIGHT,
3195 build_string ("JIS X0208:1978"),
3196 build_string ("JIS X0208:1978 (Japanese)"),
3198 ("JIS X0208:1978 Japanese Kanji (so called \"old JIS\")"),
3199 build_string ("\\(jisx0208\\|jisc6226\\)\\.1978"),
3201 staticpro (&Vcharset_chinese_gb2312);
3202 Vcharset_chinese_gb2312 =
3203 make_charset (LEADING_BYTE_CHINESE_GB2312, Qchinese_gb2312, 94, 2,
3204 2, 0, 'A', CHARSET_LEFT_TO_RIGHT,
3205 build_string ("GB2312"),
3206 build_string ("GB2312)"),
3207 build_string ("GB2312 Chinese simplified"),
3208 build_string ("gb2312"),
3210 staticpro (&Vcharset_japanese_jisx0208);
3211 Vcharset_japanese_jisx0208 =
3212 make_charset (LEADING_BYTE_JAPANESE_JISX0208, Qjapanese_jisx0208, 94, 2,
3213 2, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3214 build_string ("JISX0208"),
3215 build_string ("JIS X0208:1983 (Japanese)"),
3216 build_string ("JIS X0208:1983 Japanese Kanji"),
3217 build_string ("jisx0208\\.1983"),
3220 staticpro (&Vcharset_japanese_jisx0208_1990);
3221 Vcharset_japanese_jisx0208_1990 =
3222 make_charset (LEADING_BYTE_JAPANESE_JISX0208_1990,
3223 Qjapanese_jisx0208_1990, 94, 2,
3224 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3225 build_string ("JISX0208-1990"),
3226 build_string ("JIS X0208:1990 (Japanese)"),
3227 build_string ("JIS X0208:1990 Japanese Kanji"),
3228 build_string ("jisx0208\\.1990"),
3230 MIN_CHAR_JIS_X0208_1990,
3231 MAX_CHAR_JIS_X0208_1990, 0, 33);
3233 staticpro (&Vcharset_korean_ksc5601);
3234 Vcharset_korean_ksc5601 =
3235 make_charset (LEADING_BYTE_KOREAN_KSC5601, Qkorean_ksc5601, 94, 2,
3236 2, 0, 'C', CHARSET_LEFT_TO_RIGHT,
3237 build_string ("KSC5601"),
3238 build_string ("KSC5601 (Korean"),
3239 build_string ("KSC5601 Korean Hangul and Hanja"),
3240 build_string ("ksc5601"),
3242 staticpro (&Vcharset_japanese_jisx0212);
3243 Vcharset_japanese_jisx0212 =
3244 make_charset (LEADING_BYTE_JAPANESE_JISX0212, Qjapanese_jisx0212, 94, 2,
3245 2, 0, 'D', CHARSET_LEFT_TO_RIGHT,
3246 build_string ("JISX0212"),
3247 build_string ("JISX0212 (Japanese)"),
3248 build_string ("JISX0212 Japanese Supplement"),
3249 build_string ("jisx0212"),
3252 #define CHINESE_CNS_PLANE_RE(n) "cns11643[.-]\\(.*[.-]\\)?" n "$"
3253 staticpro (&Vcharset_chinese_cns11643_1);
3254 Vcharset_chinese_cns11643_1 =
3255 make_charset (LEADING_BYTE_CHINESE_CNS11643_1, Qchinese_cns11643_1, 94, 2,
3256 2, 0, 'G', CHARSET_LEFT_TO_RIGHT,
3257 build_string ("CNS11643-1"),
3258 build_string ("CNS11643-1 (Chinese traditional)"),
3260 ("CNS 11643 Plane 1 Chinese traditional"),
3261 build_string (CHINESE_CNS_PLANE_RE("1")),
3263 staticpro (&Vcharset_chinese_cns11643_2);
3264 Vcharset_chinese_cns11643_2 =
3265 make_charset (LEADING_BYTE_CHINESE_CNS11643_2, Qchinese_cns11643_2, 94, 2,
3266 2, 0, 'H', CHARSET_LEFT_TO_RIGHT,
3267 build_string ("CNS11643-2"),
3268 build_string ("CNS11643-2 (Chinese traditional)"),
3270 ("CNS 11643 Plane 2 Chinese traditional"),
3271 build_string (CHINESE_CNS_PLANE_RE("2")),
3274 staticpro (&Vcharset_latin_tcvn5712);
3275 Vcharset_latin_tcvn5712 =
3276 make_charset (LEADING_BYTE_LATIN_TCVN5712, Qlatin_tcvn5712, 96, 1,
3277 1, 1, 'Z', CHARSET_LEFT_TO_RIGHT,
3278 build_string ("TCVN 5712"),
3279 build_string ("TCVN 5712 (VSCII-2)"),
3280 build_string ("Vietnamese TCVN 5712:1983 (VSCII-2)"),
3281 build_string ("tcvn5712-1"),
3283 staticpro (&Vcharset_latin_viscii_lower);
3284 Vcharset_latin_viscii_lower =
3285 make_charset (LEADING_BYTE_LATIN_VISCII_LOWER, Qlatin_viscii_lower, 96, 1,
3286 1, 1, '1', CHARSET_LEFT_TO_RIGHT,
3287 build_string ("VISCII lower"),
3288 build_string ("VISCII lower (Vietnamese)"),
3289 build_string ("VISCII lower (Vietnamese)"),
3290 build_string ("MULEVISCII-LOWER"),
3292 staticpro (&Vcharset_latin_viscii_upper);
3293 Vcharset_latin_viscii_upper =
3294 make_charset (LEADING_BYTE_LATIN_VISCII_UPPER, Qlatin_viscii_upper, 96, 1,
3295 1, 1, '2', CHARSET_LEFT_TO_RIGHT,
3296 build_string ("VISCII upper"),
3297 build_string ("VISCII upper (Vietnamese)"),
3298 build_string ("VISCII upper (Vietnamese)"),
3299 build_string ("MULEVISCII-UPPER"),
3301 staticpro (&Vcharset_latin_viscii);
3302 Vcharset_latin_viscii =
3303 make_charset (LEADING_BYTE_LATIN_VISCII, Qlatin_viscii, 256, 1,
3304 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3305 build_string ("VISCII"),
3306 build_string ("VISCII 1.1 (Vietnamese)"),
3307 build_string ("VISCII 1.1 (Vietnamese)"),
3308 build_string ("VISCII1\\.1"),
3310 staticpro (&Vcharset_ideograph_daikanwa);
3311 Vcharset_ideograph_daikanwa =
3312 make_charset (LEADING_BYTE_DAIKANWA, Qideograph_daikanwa, 256, 2,
3313 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3314 build_string ("Daikanwa"),
3315 build_string ("Morohashi's Daikanwa"),
3316 build_string ("Daikanwa dictionary by MOROHASHI Tetsuji"),
3317 build_string ("Daikanwa"),
3318 Qnil, MIN_CHAR_DAIKANWA, MAX_CHAR_DAIKANWA, 0, 0);
3319 staticpro (&Vcharset_mojikyo);
3321 make_charset (LEADING_BYTE_MOJIKYO, Qmojikyo, 256, 3,
3322 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3323 build_string ("Mojikyo"),
3324 build_string ("Mojikyo"),
3325 build_string ("Konjaku-Mojikyo"),
3327 Qnil, MIN_CHAR_MOJIKYO, MAX_CHAR_MOJIKYO, 0, 0);
3328 staticpro (&Vcharset_mojikyo_pj_1);
3329 Vcharset_mojikyo_pj_1 =
3330 make_charset (LEADING_BYTE_MOJIKYO_PJ_1, Qmojikyo_pj_1, 94, 2,
3331 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3332 build_string ("Mojikyo-PJ-1"),
3333 build_string ("Mojikyo (pseudo JIS encoding) part 1"),
3335 ("Konjaku-Mojikyo (pseudo JIS encoding) part 1"),
3336 build_string ("jisx0208\\.Mojikyo-1$"),
3338 staticpro (&Vcharset_mojikyo_pj_2);
3339 Vcharset_mojikyo_pj_2 =
3340 make_charset (LEADING_BYTE_MOJIKYO_PJ_2, Qmojikyo_pj_2, 94, 2,
3341 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3342 build_string ("Mojikyo-PJ-2"),
3343 build_string ("Mojikyo (pseudo JIS encoding) part 2"),
3345 ("Konjaku-Mojikyo (pseudo JIS encoding) part 2"),
3346 build_string ("jisx0208\\.Mojikyo-2$"),
3348 staticpro (&Vcharset_mojikyo_pj_3);
3349 Vcharset_mojikyo_pj_3 =
3350 make_charset (LEADING_BYTE_MOJIKYO_PJ_3, Qmojikyo_pj_3, 94, 2,
3351 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3352 build_string ("Mojikyo-PJ-3"),
3353 build_string ("Mojikyo (pseudo JIS encoding) part 3"),
3355 ("Konjaku-Mojikyo (pseudo JIS encoding) part 3"),
3356 build_string ("jisx0208\\.Mojikyo-3$"),
3358 staticpro (&Vcharset_mojikyo_pj_4);
3359 Vcharset_mojikyo_pj_4 =
3360 make_charset (LEADING_BYTE_MOJIKYO_PJ_4, Qmojikyo_pj_4, 94, 2,
3361 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3362 build_string ("Mojikyo-PJ-4"),
3363 build_string ("Mojikyo (pseudo JIS encoding) part 4"),
3365 ("Konjaku-Mojikyo (pseudo JIS encoding) part 4"),
3366 build_string ("jisx0208\\.Mojikyo-4$"),
3368 staticpro (&Vcharset_mojikyo_pj_5);
3369 Vcharset_mojikyo_pj_5 =
3370 make_charset (LEADING_BYTE_MOJIKYO_PJ_5, Qmojikyo_pj_5, 94, 2,
3371 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3372 build_string ("Mojikyo-PJ-5"),
3373 build_string ("Mojikyo (pseudo JIS encoding) part 5"),
3375 ("Konjaku-Mojikyo (pseudo JIS encoding) part 5"),
3376 build_string ("jisx0208\\.Mojikyo-5$"),
3378 staticpro (&Vcharset_mojikyo_pj_6);
3379 Vcharset_mojikyo_pj_6 =
3380 make_charset (LEADING_BYTE_MOJIKYO_PJ_6, Qmojikyo_pj_6, 94, 2,
3381 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3382 build_string ("Mojikyo-PJ-6"),
3383 build_string ("Mojikyo (pseudo JIS encoding) part 6"),
3385 ("Konjaku-Mojikyo (pseudo JIS encoding) part 6"),
3386 build_string ("jisx0208\\.Mojikyo-6$"),
3388 staticpro (&Vcharset_mojikyo_pj_7);
3389 Vcharset_mojikyo_pj_7 =
3390 make_charset (LEADING_BYTE_MOJIKYO_PJ_7, Qmojikyo_pj_7, 94, 2,
3391 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3392 build_string ("Mojikyo-PJ-7"),
3393 build_string ("Mojikyo (pseudo JIS encoding) part 7"),
3395 ("Konjaku-Mojikyo (pseudo JIS encoding) part 7"),
3396 build_string ("jisx0208\\.Mojikyo-7$"),
3398 staticpro (&Vcharset_mojikyo_pj_8);
3399 Vcharset_mojikyo_pj_8 =
3400 make_charset (LEADING_BYTE_MOJIKYO_PJ_8, Qmojikyo_pj_8, 94, 2,
3401 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3402 build_string ("Mojikyo-PJ-8"),
3403 build_string ("Mojikyo (pseudo JIS encoding) part 8"),
3405 ("Konjaku-Mojikyo (pseudo JIS encoding) part 8"),
3406 build_string ("jisx0208\\.Mojikyo-8$"),
3408 staticpro (&Vcharset_mojikyo_pj_9);
3409 Vcharset_mojikyo_pj_9 =
3410 make_charset (LEADING_BYTE_MOJIKYO_PJ_9, Qmojikyo_pj_9, 94, 2,
3411 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3412 build_string ("Mojikyo-PJ-9"),
3413 build_string ("Mojikyo (pseudo JIS encoding) part 9"),
3415 ("Konjaku-Mojikyo (pseudo JIS encoding) part 9"),
3416 build_string ("jisx0208\\.Mojikyo-9$"),
3418 staticpro (&Vcharset_mojikyo_pj_10);
3419 Vcharset_mojikyo_pj_10 =
3420 make_charset (LEADING_BYTE_MOJIKYO_PJ_10, Qmojikyo_pj_10, 94, 2,
3421 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3422 build_string ("Mojikyo-PJ-10"),
3423 build_string ("Mojikyo (pseudo JIS encoding) part 10"),
3425 ("Konjaku-Mojikyo (pseudo JIS encoding) part 10"),
3426 build_string ("jisx0208\\.Mojikyo-10$"),
3428 staticpro (&Vcharset_mojikyo_pj_11);
3429 Vcharset_mojikyo_pj_11 =
3430 make_charset (LEADING_BYTE_MOJIKYO_PJ_11, Qmojikyo_pj_11, 94, 2,
3431 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3432 build_string ("Mojikyo-PJ-11"),
3433 build_string ("Mojikyo (pseudo JIS encoding) part 11"),
3435 ("Konjaku-Mojikyo (pseudo JIS encoding) part 11"),
3436 build_string ("jisx0208\\.Mojikyo-11$"),
3438 staticpro (&Vcharset_mojikyo_pj_12);
3439 Vcharset_mojikyo_pj_12 =
3440 make_charset (LEADING_BYTE_MOJIKYO_PJ_12, Qmojikyo_pj_12, 94, 2,
3441 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3442 build_string ("Mojikyo-PJ-12"),
3443 build_string ("Mojikyo (pseudo JIS encoding) part 12"),
3445 ("Konjaku-Mojikyo (pseudo JIS encoding) part 12"),
3446 build_string ("jisx0208\\.Mojikyo-12$"),
3448 staticpro (&Vcharset_mojikyo_pj_13);
3449 Vcharset_mojikyo_pj_13 =
3450 make_charset (LEADING_BYTE_MOJIKYO_PJ_13, Qmojikyo_pj_13, 94, 2,
3451 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3452 build_string ("Mojikyo-PJ-13"),
3453 build_string ("Mojikyo (pseudo JIS encoding) part 13"),
3455 ("Konjaku-Mojikyo (pseudo JIS encoding) part 13"),
3456 build_string ("jisx0208\\.Mojikyo-13$"),
3458 staticpro (&Vcharset_mojikyo_pj_14);
3459 Vcharset_mojikyo_pj_14 =
3460 make_charset (LEADING_BYTE_MOJIKYO_PJ_14, Qmojikyo_pj_14, 94, 2,
3461 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3462 build_string ("Mojikyo-PJ-14"),
3463 build_string ("Mojikyo (pseudo JIS encoding) part 14"),
3465 ("Konjaku-Mojikyo (pseudo JIS encoding) part 14"),
3466 build_string ("jisx0208\\.Mojikyo-14$"),
3468 staticpro (&Vcharset_mojikyo_pj_15);
3469 Vcharset_mojikyo_pj_15 =
3470 make_charset (LEADING_BYTE_MOJIKYO_PJ_15, Qmojikyo_pj_15, 94, 2,
3471 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3472 build_string ("Mojikyo-PJ-15"),
3473 build_string ("Mojikyo (pseudo JIS encoding) part 15"),
3475 ("Konjaku-Mojikyo (pseudo JIS encoding) part 15"),
3476 build_string ("jisx0208\\.Mojikyo-15$"),
3478 staticpro (&Vcharset_mojikyo_pj_16);
3479 Vcharset_mojikyo_pj_16 =
3480 make_charset (LEADING_BYTE_MOJIKYO_PJ_16, Qmojikyo_pj_16, 94, 2,
3481 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3482 build_string ("Mojikyo-PJ-16"),
3483 build_string ("Mojikyo (pseudo JIS encoding) part 16"),
3485 ("Konjaku-Mojikyo (pseudo JIS encoding) part 16"),
3486 build_string ("jisx0208\\.Mojikyo-16$"),
3488 staticpro (&Vcharset_mojikyo_pj_17);
3489 Vcharset_mojikyo_pj_17 =
3490 make_charset (LEADING_BYTE_MOJIKYO_PJ_17, Qmojikyo_pj_17, 94, 2,
3491 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3492 build_string ("Mojikyo-PJ-17"),
3493 build_string ("Mojikyo (pseudo JIS encoding) part 17"),
3495 ("Konjaku-Mojikyo (pseudo JIS encoding) part 17"),
3496 build_string ("jisx0208\\.Mojikyo-17$"),
3498 staticpro (&Vcharset_mojikyo_pj_18);
3499 Vcharset_mojikyo_pj_18 =
3500 make_charset (LEADING_BYTE_MOJIKYO_PJ_18, Qmojikyo_pj_18, 94, 2,
3501 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3502 build_string ("Mojikyo-PJ-18"),
3503 build_string ("Mojikyo (pseudo JIS encoding) part 18"),
3505 ("Konjaku-Mojikyo (pseudo JIS encoding) part 18"),
3506 build_string ("jisx0208\\.Mojikyo-18$"),
3508 staticpro (&Vcharset_mojikyo_pj_19);
3509 Vcharset_mojikyo_pj_19 =
3510 make_charset (LEADING_BYTE_MOJIKYO_PJ_19, Qmojikyo_pj_19, 94, 2,
3511 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3512 build_string ("Mojikyo-PJ-19"),
3513 build_string ("Mojikyo (pseudo JIS encoding) part 19"),
3515 ("Konjaku-Mojikyo (pseudo JIS encoding) part 19"),
3516 build_string ("jisx0208\\.Mojikyo-19$"),
3518 staticpro (&Vcharset_mojikyo_pj_20);
3519 Vcharset_mojikyo_pj_20 =
3520 make_charset (LEADING_BYTE_MOJIKYO_PJ_20, Qmojikyo_pj_20, 94, 2,
3521 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3522 build_string ("Mojikyo-PJ-20"),
3523 build_string ("Mojikyo (pseudo JIS encoding) part 20"),
3525 ("Konjaku-Mojikyo (pseudo JIS encoding) part 20"),
3526 build_string ("jisx0208\\.Mojikyo-20$"),
3528 staticpro (&Vcharset_mojikyo_pj_21);
3529 Vcharset_mojikyo_pj_21 =
3530 make_charset (LEADING_BYTE_MOJIKYO_PJ_21, Qmojikyo_pj_21, 94, 2,
3531 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3532 build_string ("Mojikyo-PJ-21"),
3533 build_string ("Mojikyo (pseudo JIS encoding) part 21"),
3535 ("Konjaku-Mojikyo (pseudo JIS encoding) part 21"),
3536 build_string ("jisx0208\\.Mojikyo-21$"),
3538 staticpro (&Vcharset_ethiopic_ucs);
3539 Vcharset_ethiopic_ucs =
3540 make_charset (LEADING_BYTE_ETHIOPIC_UCS, Qethiopic_ucs, 256, 2,
3541 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3542 build_string ("Ethiopic (UCS)"),
3543 build_string ("Ethiopic (UCS)"),
3544 build_string ("Ethiopic of UCS"),
3545 build_string ("Ethiopic-Unicode"),
3546 Qnil, 0x1200, 0x137F, 0x1200, 0);
3548 staticpro (&Vcharset_chinese_big5_1);
3549 Vcharset_chinese_big5_1 =
3550 make_charset (LEADING_BYTE_CHINESE_BIG5_1, Qchinese_big5_1, 94, 2,
3551 2, 0, '0', CHARSET_LEFT_TO_RIGHT,
3552 build_string ("Big5"),
3553 build_string ("Big5 (Level-1)"),
3555 ("Big5 Level-1 Chinese traditional"),
3556 build_string ("big5"),
3558 staticpro (&Vcharset_chinese_big5_2);
3559 Vcharset_chinese_big5_2 =
3560 make_charset (LEADING_BYTE_CHINESE_BIG5_2, Qchinese_big5_2, 94, 2,
3561 2, 0, '1', CHARSET_LEFT_TO_RIGHT,
3562 build_string ("Big5"),
3563 build_string ("Big5 (Level-2)"),
3565 ("Big5 Level-2 Chinese traditional"),
3566 build_string ("big5"),
3569 #ifdef ENABLE_COMPOSITE_CHARS
3570 /* #### For simplicity, we put composite chars into a 96x96 charset.
3571 This is going to lead to problems because you can run out of
3572 room, esp. as we don't yet recycle numbers. */
3573 staticpro (&Vcharset_composite);
3574 Vcharset_composite =
3575 make_charset (LEADING_BYTE_COMPOSITE, Qcomposite, 96, 2,
3576 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3577 build_string ("Composite"),
3578 build_string ("Composite characters"),
3579 build_string ("Composite characters"),
3582 /* #### not dumped properly */
3583 composite_char_row_next = 32;
3584 composite_char_col_next = 32;
3586 Vcomposite_char_string2char_hash_table =
3587 make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
3588 Vcomposite_char_char2string_hash_table =
3589 make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3590 staticpro (&Vcomposite_char_string2char_hash_table);
3591 staticpro (&Vcomposite_char_char2string_hash_table);
3592 #endif /* ENABLE_COMPOSITE_CHARS */