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, 2001, 2002, 2003, 2004, 2008, 2009, 2011
7 This file is part of XEmacs.
9 XEmacs is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with XEmacs; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
24 /* Rewritten by Ben Wing <ben@xemacs.org>. */
26 /* Rewritten by MORIOKA Tomohiko <tomo@m17n.org> for XEmacs CHISE. */
45 /* The various pre-defined charsets. */
47 Lisp_Object Vcharset_ascii;
48 Lisp_Object Vcharset_control_1;
49 Lisp_Object Vcharset_latin_iso8859_1;
50 Lisp_Object Vcharset_latin_iso8859_2;
51 Lisp_Object Vcharset_latin_iso8859_3;
52 Lisp_Object Vcharset_latin_iso8859_4;
53 Lisp_Object Vcharset_thai_tis620;
54 Lisp_Object Vcharset_greek_iso8859_7;
55 Lisp_Object Vcharset_arabic_iso8859_6;
56 Lisp_Object Vcharset_hebrew_iso8859_8;
57 Lisp_Object Vcharset_katakana_jisx0201;
58 Lisp_Object Vcharset_latin_jisx0201;
59 Lisp_Object Vcharset_cyrillic_iso8859_5;
60 Lisp_Object Vcharset_latin_iso8859_9;
61 /* Lisp_Object Vcharset_japanese_jisx0208_1978; */
62 Lisp_Object Vcharset_chinese_gb2312;
63 Lisp_Object Vcharset_chinese_gb12345;
64 Lisp_Object Vcharset_japanese_jisx0208;
65 Lisp_Object Vcharset_japanese_jisx0208_1990;
66 Lisp_Object Vcharset_korean_ksc5601;
67 Lisp_Object Vcharset_japanese_jisx0212;
68 Lisp_Object Vcharset_chinese_cns11643_1;
69 Lisp_Object Vcharset_chinese_cns11643_2;
71 Lisp_Object Vcharset_system_char_id;
72 Lisp_Object Vcharset_ucs;
73 Lisp_Object Vcharset_ucs_bmp;
74 Lisp_Object Vcharset_ucs_smp;
75 Lisp_Object Vcharset_ucs_sip;
76 Lisp_Object Vcharset_latin_viscii;
77 Lisp_Object Vcharset_latin_tcvn5712;
78 Lisp_Object Vcharset_latin_viscii_lower;
79 Lisp_Object Vcharset_latin_viscii_upper;
80 Lisp_Object Vcharset_jis_x0208;
81 Lisp_Object Vcharset_chinese_big5;
82 Lisp_Object Vcharset_ethiopic_ucs;
84 Lisp_Object Vcharset_chinese_big5_1;
85 Lisp_Object Vcharset_chinese_big5_2;
87 #ifdef ENABLE_COMPOSITE_CHARS
88 Lisp_Object Vcharset_composite;
90 /* Hash tables for composite chars. One maps string representing
91 composed chars to their equivalent chars; one goes the
93 Lisp_Object Vcomposite_char_char2string_hash_table;
94 Lisp_Object Vcomposite_char_string2char_hash_table;
96 static int composite_char_row_next;
97 static int composite_char_col_next;
99 #endif /* ENABLE_COMPOSITE_CHARS */
101 struct charset_lookup *chlook;
103 static const struct lrecord_description charset_lookup_description_1[] = {
104 { XD_LISP_OBJECT_ARRAY, offsetof (struct charset_lookup, charset_by_leading_byte),
106 NUM_LEADING_BYTES+4*128
113 static const struct struct_description charset_lookup_description = {
114 sizeof (struct charset_lookup),
115 charset_lookup_description_1
119 /* Table of number of bytes in the string representation of a character
120 indexed by the first byte of that representation.
122 rep_bytes_by_first_byte(c) is more efficient than the equivalent
123 canonical computation:
125 XCHARSET_REP_BYTES (CHARSET_BY_LEADING_BYTE (c)) */
127 const Bytecount rep_bytes_by_first_byte[0xA0] =
128 { /* 0x00 - 0x7f are for straight ASCII */
129 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
130 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
131 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
132 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
133 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
134 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
135 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
136 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
137 /* 0x80 - 0x8f are for Dimension-1 official charsets */
139 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
141 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
143 /* 0x90 - 0x9d are for Dimension-2 official charsets */
144 /* 0x9e is for Dimension-1 private charsets */
145 /* 0x9f is for Dimension-2 private charsets */
146 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4
152 int decoding_table_check_elements (Lisp_Object v, int dim, int ccs_len);
154 decoding_table_check_elements (Lisp_Object v, int dim, int ccs_len)
158 if (XVECTOR_LENGTH (v) > ccs_len)
161 for (i = 0; i < XVECTOR_LENGTH (v); i++)
163 Lisp_Object c = XVECTOR_DATA(v)[i];
165 if (!NILP (c) && !CHARP (c))
169 int ret = decoding_table_check_elements (c, dim - 1, ccs_len);
181 decoding_table_put_char (Lisp_Object ccs,
182 int code_point, Lisp_Object character)
185 Lisp_Object table1 = XCHARSET_DECODING_TABLE (ccs);
186 int dim = XCHARSET_DIMENSION (ccs);
189 XCHARSET_DECODING_TABLE (ccs)
190 = put_ccs_octet_table (table1, ccs, code_point, character);
194 = get_ccs_octet_table (table1, ccs, (unsigned char)(code_point >> 8));
196 table2 = put_ccs_octet_table (table2, ccs,
197 (unsigned char)code_point, character);
198 XCHARSET_DECODING_TABLE (ccs)
199 = put_ccs_octet_table (table1, ccs,
200 (unsigned char)(code_point >> 8), table2);
205 = get_ccs_octet_table (table1, ccs, (unsigned char)(code_point >> 16));
207 = get_ccs_octet_table (table2, ccs, (unsigned char)(code_point >> 8));
209 table3 = put_ccs_octet_table (table3, ccs,
210 (unsigned char)code_point, character);
211 table2 = put_ccs_octet_table (table2, ccs,
212 (unsigned char)(code_point >> 8), table3);
213 XCHARSET_DECODING_TABLE (ccs)
214 = put_ccs_octet_table (table1, ccs,
215 (unsigned char)(code_point >> 16), table2);
217 else /* if (dim == 4) */
220 = get_ccs_octet_table (table1, ccs, (unsigned char)(code_point >> 24));
222 = get_ccs_octet_table (table2, ccs, (unsigned char)(code_point >> 16));
224 = get_ccs_octet_table (table3, ccs, (unsigned char)(code_point >> 8));
226 table4 = put_ccs_octet_table (table4, ccs,
227 (unsigned char)code_point, character);
228 table3 = put_ccs_octet_table (table3, ccs,
229 (unsigned char)(code_point >> 8), table4);
230 table2 = put_ccs_octet_table (table2, ccs,
231 (unsigned char)(code_point >> 16), table3);
232 XCHARSET_DECODING_TABLE (ccs)
233 = put_ccs_octet_table (table1, ccs,
234 (unsigned char)(code_point >> 24), table2);
237 Lisp_Object v = XCHARSET_DECODING_TABLE (ccs);
238 int dim = XCHARSET_DIMENSION (ccs);
239 int byte_offset = XCHARSET_BYTE_OFFSET (ccs);
242 int ccs_len = XVECTOR_LENGTH (v);
247 i = ((code_point >> (8 * dim)) & 255) - byte_offset;
248 nv = XVECTOR_DATA(v)[i];
253 if (EQ (nv, character))
256 nv = (XVECTOR_DATA(v)[i] = make_vector (ccs_len, Qnil));
263 XVECTOR_DATA(v)[i] = character;
268 put_char_ccs_code_point (Lisp_Object character,
269 Lisp_Object ccs, Lisp_Object value)
271 if ( !( EQ (XCHARSET_NAME (ccs), Qrep_ucs)
272 && INTP (value) && (XINT (value) < 0xF0000)
273 && XCHAR (character) == XINT (value) )
276 Lisp_Object v = XCHARSET_DECODING_TABLE (ccs);
280 { /* obsolete representation: value must be a list of bytes */
281 Lisp_Object ret = Fcar (value);
285 signal_simple_error ("Invalid value for coded-charset", value);
286 code_point = XINT (ret);
287 if (XCHARSET_GRAPHIC (ccs) == 1)
295 signal_simple_error ("Invalid value for coded-charset",
299 signal_simple_error ("Invalid value for coded-charset",
302 if (XCHARSET_GRAPHIC (ccs) == 1)
304 code_point = (code_point << 8) | j;
307 value = make_int (code_point);
309 else if (INTP (value))
311 code_point = XINT (value);
312 if (XCHARSET_GRAPHIC (ccs) == 1)
314 code_point &= 0x7F7F7F7F;
315 value = make_int (code_point);
319 signal_simple_error ("Invalid value for coded-charset", value);
323 Lisp_Object cpos = Fget_char_attribute (character, ccs, Qnil);
326 decoding_table_remove_char (ccs, XINT (cpos));
329 decoding_table_put_char (ccs, code_point, character);
335 remove_char_ccs (Lisp_Object character, Lisp_Object ccs)
337 Lisp_Object decoding_table = XCHARSET_DECODING_TABLE (ccs);
338 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
340 if (VECTORP (decoding_table))
342 Lisp_Object cpos = Fget_char_attribute (character, ccs, Qnil);
346 decoding_table_remove_char (ccs, XINT (cpos));
349 if (CHAR_TABLEP (encoding_table))
351 put_char_id_table (XCHAR_TABLE(encoding_table), character, Qunbound);
359 int leading_code_private_11;
362 Lisp_Object Qcharsetp;
364 /* Qdoc_string, Qdimension, Qchars defined in general.c */
365 Lisp_Object Qregistry, Qfinal, Qgraphic;
366 Lisp_Object Qdirection;
367 Lisp_Object Qreverse_direction_charset;
368 Lisp_Object Qleading_byte;
369 Lisp_Object Qshort_name, Qlong_name;
372 Lisp_Object Qto_iso_ir;
373 Lisp_Object Qpartial;
374 Lisp_Object Qmin_code, Qmax_code, Qcode_offset;
375 Lisp_Object Qmother, Qconversion, Q94x60, Q94x94x60, Qbig5_1, Qbig5_2;
392 /* Qrep_jis_x0208_1978, */
410 Qvietnamese_viscii_lower,
411 Qvietnamese_viscii_upper,
421 Lisp_Object Ql2r, Qr2l;
423 Lisp_Object Vcharset_hash_table;
425 /* Composite characters are characters constructed by overstriking two
426 or more regular characters.
428 1) The old Mule implementation involves storing composite characters
429 in a buffer as a tag followed by all of the actual characters
430 used to make up the composite character. I think this is a bad
431 idea; it greatly complicates code that wants to handle strings
432 one character at a time because it has to deal with the possibility
433 of great big ungainly characters. It's much more reasonable to
434 simply store an index into a table of composite characters.
436 2) The current implementation only allows for 16,384 separate
437 composite characters over the lifetime of the XEmacs process.
438 This could become a potential problem if the user
439 edited lots of different files that use composite characters.
440 Due to FSF bogosity, increasing the number of allowable
441 composite characters under Mule would decrease the number
442 of possible faces that can exist. Mule already has shrunk
443 this to 2048, and further shrinkage would become uncomfortable.
444 No such problems exist in XEmacs.
446 Composite characters could be represented as 0x80 C1 C2 C3,
447 where each C[1-3] is in the range 0xA0 - 0xFF. This allows
448 for slightly under 2^20 (one million) composite characters
449 over the XEmacs process lifetime, and you only need to
450 increase the size of a Mule character from 19 to 21 bits.
451 Or you could use 0x80 C1 C2 C3 C4, allowing for about
452 85 million (slightly over 2^26) composite characters. */
455 /************************************************************************/
456 /* Basic Emchar functions */
457 /************************************************************************/
459 /* Convert a non-ASCII Mule character C into a one-character Mule-encoded
460 string in STR. Returns the number of bytes stored.
461 Do not call this directly. Use the macro set_charptr_emchar() instead.
465 non_ascii_set_charptr_emchar (Bufbyte *str, Emchar c)
480 else if ( c <= 0x7ff )
482 *p++ = (c >> 6) | 0xc0;
483 *p++ = (c & 0x3f) | 0x80;
485 else if ( c <= 0xffff )
487 *p++ = (c >> 12) | 0xe0;
488 *p++ = ((c >> 6) & 0x3f) | 0x80;
489 *p++ = (c & 0x3f) | 0x80;
491 else if ( c <= 0x1fffff )
493 *p++ = (c >> 18) | 0xf0;
494 *p++ = ((c >> 12) & 0x3f) | 0x80;
495 *p++ = ((c >> 6) & 0x3f) | 0x80;
496 *p++ = (c & 0x3f) | 0x80;
498 else if ( c <= 0x3ffffff )
500 *p++ = (c >> 24) | 0xf8;
501 *p++ = ((c >> 18) & 0x3f) | 0x80;
502 *p++ = ((c >> 12) & 0x3f) | 0x80;
503 *p++ = ((c >> 6) & 0x3f) | 0x80;
504 *p++ = (c & 0x3f) | 0x80;
508 *p++ = (c >> 30) | 0xfc;
509 *p++ = ((c >> 24) & 0x3f) | 0x80;
510 *p++ = ((c >> 18) & 0x3f) | 0x80;
511 *p++ = ((c >> 12) & 0x3f) | 0x80;
512 *p++ = ((c >> 6) & 0x3f) | 0x80;
513 *p++ = (c & 0x3f) | 0x80;
516 BREAKUP_CHAR (c, charset, c1, c2);
517 lb = CHAR_LEADING_BYTE (c);
518 if (LEADING_BYTE_PRIVATE_P (lb))
519 *p++ = PRIVATE_LEADING_BYTE_PREFIX (lb);
521 if (EQ (charset, Vcharset_control_1))
530 /* Return the first character from a Mule-encoded string in STR,
531 assuming it's non-ASCII. Do not call this directly.
532 Use the macro charptr_emchar() instead. */
535 non_ascii_charptr_emchar (const Bufbyte *str)
548 else if ( b >= 0xf8 )
553 else if ( b >= 0xf0 )
558 else if ( b >= 0xe0 )
563 else if ( b >= 0xc0 )
573 for( ; len > 0; len-- )
576 ch = ( ch << 6 ) | ( b & 0x3f );
580 Bufbyte i0 = *str, i1, i2 = 0;
583 if (i0 == LEADING_BYTE_CONTROL_1)
584 return (Emchar) (*++str - 0x20);
586 if (LEADING_BYTE_PREFIX_P (i0))
591 charset = CHARSET_BY_LEADING_BYTE (i0);
592 if (XCHARSET_DIMENSION (charset) == 2)
595 return MAKE_CHAR (charset, i1, i2);
599 /* Return whether CH is a valid Emchar, assuming it's non-ASCII.
600 Do not call this directly. Use the macro valid_char_p() instead. */
604 non_ascii_valid_char_p (Emchar ch)
608 /* Must have only lowest 19 bits set */
612 f1 = CHAR_FIELD1 (ch);
613 f2 = CHAR_FIELD2 (ch);
614 f3 = CHAR_FIELD3 (ch);
620 if (f2 < MIN_CHAR_FIELD2_OFFICIAL ||
621 (f2 > MAX_CHAR_FIELD2_OFFICIAL && f2 < MIN_CHAR_FIELD2_PRIVATE) ||
622 f2 > MAX_CHAR_FIELD2_PRIVATE)
627 if (f3 != 0x20 && f3 != 0x7F && !(f2 >= MIN_CHAR_FIELD2_PRIVATE &&
628 f2 <= MAX_CHAR_FIELD2_PRIVATE))
632 NOTE: This takes advantage of the fact that
633 FIELD2_TO_OFFICIAL_LEADING_BYTE and
634 FIELD2_TO_PRIVATE_LEADING_BYTE are the same.
636 charset = CHARSET_BY_LEADING_BYTE (f2 + FIELD2_TO_OFFICIAL_LEADING_BYTE);
637 if (EQ (charset, Qnil))
639 return (XCHARSET_CHARS (charset) == 96);
645 if (f1 < MIN_CHAR_FIELD1_OFFICIAL ||
646 (f1 > MAX_CHAR_FIELD1_OFFICIAL && f1 < MIN_CHAR_FIELD1_PRIVATE) ||
647 f1 > MAX_CHAR_FIELD1_PRIVATE)
649 if (f2 < 0x20 || f3 < 0x20)
652 #ifdef ENABLE_COMPOSITE_CHARS
653 if (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE == LEADING_BYTE_COMPOSITE)
655 if (UNBOUNDP (Fgethash (make_int (ch),
656 Vcomposite_char_char2string_hash_table,
661 #endif /* ENABLE_COMPOSITE_CHARS */
663 if (f2 != 0x20 && f2 != 0x7F && f3 != 0x20 && f3 != 0x7F
664 && !(f1 >= MIN_CHAR_FIELD1_PRIVATE && f1 <= MAX_CHAR_FIELD1_PRIVATE))
667 if (f1 <= MAX_CHAR_FIELD1_OFFICIAL)
669 CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE);
672 CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_PRIVATE_LEADING_BYTE);
674 if (EQ (charset, Qnil))
676 return (XCHARSET_CHARS (charset) == 96);
682 /************************************************************************/
683 /* Basic string functions */
684 /************************************************************************/
686 /* Copy the character pointed to by SRC into DST. Do not call this
687 directly. Use the macro charptr_copy_char() instead.
688 Return the number of bytes copied. */
691 non_ascii_charptr_copy_char (const Bufbyte *src, Bufbyte *dst)
693 unsigned int bytes = REP_BYTES_BY_FIRST_BYTE (*src);
695 for (i = bytes; i; i--, dst++, src++)
701 /************************************************************************/
702 /* streams of Emchars */
703 /************************************************************************/
705 /* Treat a stream as a stream of Emchar's rather than a stream of bytes.
706 The functions below are not meant to be called directly; use
707 the macros in insdel.h. */
710 Lstream_get_emchar_1 (Lstream *stream, int ch)
712 Bufbyte str[MAX_EMCHAR_LEN];
713 Bufbyte *strptr = str;
716 str[0] = (Bufbyte) ch;
718 for (bytes = REP_BYTES_BY_FIRST_BYTE (ch) - 1; bytes; bytes--)
720 int c = Lstream_getc (stream);
721 bufpos_checking_assert (c >= 0);
722 *++strptr = (Bufbyte) c;
724 return charptr_emchar (str);
728 Lstream_fput_emchar (Lstream *stream, Emchar ch)
730 Bufbyte str[MAX_EMCHAR_LEN];
731 Bytecount len = set_charptr_emchar (str, ch);
732 return Lstream_write (stream, str, len);
736 Lstream_funget_emchar (Lstream *stream, Emchar ch)
738 Bufbyte str[MAX_EMCHAR_LEN];
739 Bytecount len = set_charptr_emchar (str, ch);
740 Lstream_unread (stream, str, len);
744 /************************************************************************/
746 /************************************************************************/
749 mark_charset (Lisp_Object obj)
751 Lisp_Charset *cs = XCHARSET (obj);
753 mark_object (cs->short_name);
754 mark_object (cs->long_name);
755 mark_object (cs->doc_string);
756 mark_object (cs->registry);
757 mark_object (cs->ccl_program);
759 mark_object (cs->decoding_table);
760 mark_object (cs->mother);
766 print_charset (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
768 Lisp_Charset *cs = XCHARSET (obj);
772 error ("printing unreadable object #<charset %s 0x%x>",
773 string_data (XSYMBOL (CHARSET_NAME (cs))->name),
776 write_c_string ("#<charset ", printcharfun);
777 print_internal (CHARSET_NAME (cs), printcharfun, 0);
778 write_c_string (" ", printcharfun);
779 print_internal (CHARSET_SHORT_NAME (cs), printcharfun, 1);
780 write_c_string (" ", printcharfun);
781 print_internal (CHARSET_LONG_NAME (cs), printcharfun, 1);
782 write_c_string (" ", printcharfun);
783 print_internal (CHARSET_DOC_STRING (cs), printcharfun, 1);
784 sprintf (buf, " %d^%d %s cols=%d g%d final='%c' reg=",
786 CHARSET_DIMENSION (cs),
787 CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? "l2r" : "r2l",
788 CHARSET_COLUMNS (cs),
789 CHARSET_GRAPHIC (cs),
791 write_c_string (buf, printcharfun);
792 print_internal (CHARSET_REGISTRY (cs), printcharfun, 0);
793 sprintf (buf, " 0x%x>", cs->header.uid);
794 write_c_string (buf, printcharfun);
797 static const struct lrecord_description charset_description[] = {
798 { XD_LISP_OBJECT, offsetof (Lisp_Charset, name) },
799 { XD_LISP_OBJECT, offsetof (Lisp_Charset, doc_string) },
800 { XD_LISP_OBJECT, offsetof (Lisp_Charset, registry) },
801 { XD_LISP_OBJECT, offsetof (Lisp_Charset, short_name) },
802 { XD_LISP_OBJECT, offsetof (Lisp_Charset, long_name) },
803 { XD_LISP_OBJECT, offsetof (Lisp_Charset, reverse_direction_charset) },
804 { XD_LISP_OBJECT, offsetof (Lisp_Charset, ccl_program) },
806 { XD_LISP_OBJECT, offsetof (Lisp_Charset, decoding_table) },
807 { XD_LISP_OBJECT, offsetof (Lisp_Charset, mother) },
812 DEFINE_LRECORD_IMPLEMENTATION ("charset", charset,
813 mark_charset, print_charset, 0, 0, 0,
817 /* Make a new charset. */
818 /* #### SJT Should generic properties be allowed? */
820 make_charset (Charset_ID id, Lisp_Object name,
821 unsigned short chars, unsigned char dimension,
822 unsigned char columns, unsigned char graphic,
823 Bufbyte final, unsigned char direction, Lisp_Object short_name,
824 Lisp_Object long_name, Lisp_Object doc,
827 Lisp_Object decoding_table,
828 Emchar min_code, Emchar max_code,
829 Emchar code_offset, unsigned char byte_offset,
830 Lisp_Object mother, unsigned char conversion,
834 Lisp_Charset *cs = alloc_lcrecord_type (Lisp_Charset, &lrecord_charset);
838 XSETCHARSET (obj, cs);
840 CHARSET_ID (cs) = id;
841 CHARSET_NAME (cs) = name;
842 CHARSET_SHORT_NAME (cs) = short_name;
843 CHARSET_LONG_NAME (cs) = long_name;
844 CHARSET_CHARS (cs) = chars;
845 CHARSET_DIMENSION (cs) = dimension;
846 CHARSET_DIRECTION (cs) = direction;
847 CHARSET_COLUMNS (cs) = columns;
848 CHARSET_GRAPHIC (cs) = graphic;
849 CHARSET_FINAL (cs) = final;
850 CHARSET_DOC_STRING (cs) = doc;
851 CHARSET_REGISTRY (cs) = reg;
852 CHARSET_CCL_PROGRAM (cs) = Qnil;
853 CHARSET_REVERSE_DIRECTION_CHARSET (cs) = Qnil;
855 CHARSET_ISO_IR (cs) = iso_ir;
856 CHARSET_DECODING_TABLE(cs) = Qunbound;
857 CHARSET_MIN_CODE (cs) = min_code;
858 CHARSET_MAX_CODE (cs) = max_code;
859 CHARSET_CODE_OFFSET (cs) = code_offset;
860 CHARSET_BYTE_OFFSET (cs) = byte_offset;
861 CHARSET_MOTHER (cs) = mother;
862 CHARSET_CONVERSION (cs) = conversion;
866 if (id == LEADING_BYTE_ASCII)
867 CHARSET_REP_BYTES (cs) = 1;
869 CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 1;
871 CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 2;
876 /* some charsets do not have final characters. This includes
877 ASCII, Control-1, Composite, and the two faux private
879 unsigned char iso2022_type
880 = (dimension == 1 ? 0 : 2) + (chars == 94 ? 0 : 1);
882 if ( ( !partial ) && ( code_offset == 0 ) )
884 assert (NILP (chlook->charset_by_attributes[iso2022_type][final]));
885 chlook->charset_by_attributes[iso2022_type][final] = obj;
889 (chlook->charset_by_attributes[iso2022_type][final][direction]));
890 chlook->charset_by_attributes[iso2022_type][final][direction] = obj;
894 assert (NILP (chlook->charset_by_leading_byte[id - MIN_LEADING_BYTE]));
895 chlook->charset_by_leading_byte[id - MIN_LEADING_BYTE] = obj;
897 /* Some charsets are "faux" and don't have names or really exist at
898 all except in the leading-byte table. */
900 Fputhash (name, obj, Vcharset_hash_table);
905 get_unallocated_leading_byte (int dimension)
910 if (chlook->next_allocated_leading_byte > MAX_LEADING_BYTE_PRIVATE)
913 lb = chlook->next_allocated_leading_byte++;
917 if (chlook->next_allocated_1_byte_leading_byte >
918 MAX_LEADING_BYTE_PRIVATE_1)
921 lb = chlook->next_allocated_1_byte_leading_byte++;
925 /* awfully fragile, but correct */
926 #if MAX_LEADING_BYTE_PRIVATE_2 == 255
927 if (chlook->next_allocated_2_byte_leading_byte == 0)
929 if (chlook->next_allocated_2_byte_leading_byte >
930 MAX_LEADING_BYTE_PRIVATE_2)
934 lb = chlook->next_allocated_2_byte_leading_byte++;
940 ("No more character sets free for this dimension",
941 make_int (dimension));
947 /* Number of Big5 characters which have the same code in 1st byte. */
949 #define BIG5_SAME_ROW (0xFF - 0xA1 + 0x7F - 0x40)
952 decode_ccs_conversion (int conv_type, int code_point)
954 if ( conv_type == CONVERSION_IDENTICAL )
958 if ( conv_type == CONVERSION_94x60 )
960 int row = code_point >> 8;
961 int cell = code_point & 255;
965 else if (row < 16 + 32 + 30)
966 return (row - (16 + 32)) * 94 + cell - 33;
967 else if (row < 18 + 32 + 30)
969 else if (row < 18 + 32 + 60)
970 return (row - (18 + 32)) * 94 + cell - 33;
972 else if ( conv_type == CONVERSION_94x94x60 )
974 int plane = code_point >> 16;
975 int row = (code_point >> 8) & 255;
976 int cell = code_point & 255;
980 else if (row < 16 + 32 + 30)
982 (plane - 33) * 94 * 60
983 + (row - (16 + 32)) * 94
985 else if (row < 18 + 32 + 30)
987 else if (row < 18 + 32 + 60)
989 (plane - 33) * 94 * 60
990 + (row - (18 + 32)) * 94
993 else if ( conv_type == CONVERSION_BIG5_1 )
996 = (((code_point >> 8) & 0x7F) - 33) * 94
997 + (( code_point & 0x7F) - 33);
998 unsigned char b1 = I / (0xFF - 0xA1 + 0x7F - 0x40) + 0xA1;
999 unsigned char b2 = I % (0xFF - 0xA1 + 0x7F - 0x40);
1001 b2 += b2 < 0x3F ? 0x40 : 0x62;
1002 return (b1 << 8) | b2;
1004 else if ( conv_type == CONVERSION_BIG5_2 )
1007 = (((code_point >> 8) & 0x7F) - 33) * 94
1008 + (( code_point & 0x7F) - 33)
1009 + BIG5_SAME_ROW * (0xC9 - 0xA1);
1010 unsigned char b1 = I / (0xFF - 0xA1 + 0x7F - 0x40) + 0xA1;
1011 unsigned char b2 = I % (0xFF - 0xA1 + 0x7F - 0x40);
1013 b2 += b2 < 0x3F ? 0x40 : 0x62;
1014 return (b1 << 8) | b2;
1020 decode_defined_char (Lisp_Object ccs, int code_point, int without_inheritance)
1022 int dim = XCHARSET_DIMENSION (ccs);
1023 Lisp_Object decoding_table = XCHARSET_DECODING_TABLE (ccs);
1024 Emchar char_id = -1;
1031 = get_ccs_octet_table (decoding_table, ccs,
1032 (code_point >> (dim * 8)) & 255);
1034 if (CHARP (decoding_table))
1035 return XCHAR (decoding_table);
1037 if (EQ (decoding_table, Qunloaded))
1039 char_id = load_char_decoding_entry_maybe (ccs, code_point);
1041 #endif /* HAVE_CHISE */
1044 else if ( !without_inheritance
1045 && CHARSETP (mother = XCHARSET_MOTHER (ccs)) )
1048 = decode_ccs_conversion (XCHARSET_CONVERSION (ccs), code_point);
1052 code += XCHARSET_CODE_OFFSET(ccs);
1053 if ( EQ (mother, Vcharset_ucs) )
1054 return DECODE_CHAR (mother, code, without_inheritance);
1056 return decode_defined_char (mother, code,
1057 without_inheritance);
1064 decode_builtin_char (Lisp_Object charset, int code_point)
1066 Lisp_Object mother = XCHARSET_MOTHER (charset);
1069 if ( XCHARSET_MAX_CODE (charset) > 0 )
1071 if ( CHARSETP (mother) )
1074 = decode_ccs_conversion (XCHARSET_CONVERSION (charset),
1079 decode_builtin_char (mother,
1080 code + XCHARSET_CODE_OFFSET(charset));
1087 = (XCHARSET_DIMENSION (charset) == 1
1089 code_point - XCHARSET_BYTE_OFFSET (charset)
1091 ((code_point >> 8) - XCHARSET_BYTE_OFFSET (charset))
1092 * XCHARSET_CHARS (charset)
1093 + (code_point & 0xFF) - XCHARSET_BYTE_OFFSET (charset))
1094 + XCHARSET_CODE_OFFSET (charset);
1095 if ((cid < XCHARSET_MIN_CODE (charset))
1096 || (XCHARSET_MAX_CODE (charset) < cid))
1101 else if ((final = XCHARSET_FINAL (charset)) >= '0')
1103 if (XCHARSET_DIMENSION (charset) == 1)
1105 switch (XCHARSET_CHARS (charset))
1109 + (final - '0') * 94 + ((code_point & 0x7F) - 33);
1112 + (final - '0') * 96 + ((code_point & 0x7F) - 32);
1120 switch (XCHARSET_CHARS (charset))
1123 return MIN_CHAR_94x94
1124 + (final - '0') * 94 * 94
1125 + (((code_point >> 8) & 0x7F) - 33) * 94
1126 + ((code_point & 0x7F) - 33);
1128 return MIN_CHAR_96x96
1129 + (final - '0') * 96 * 96
1130 + (((code_point >> 8) & 0x7F) - 32) * 96
1131 + ((code_point & 0x7F) - 32);
1143 charset_code_point (Lisp_Object charset, Emchar ch, int defined_only)
1145 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (charset);
1148 if ( CHAR_TABLEP (encoding_table)
1149 && INTP (ret = get_char_id_table (XCHAR_TABLE(encoding_table),
1154 Lisp_Object mother = XCHARSET_MOTHER (charset);
1155 int min = XCHARSET_MIN_CODE (charset);
1156 int max = XCHARSET_MAX_CODE (charset);
1159 if ( CHARSETP (mother) )
1161 if (XCHARSET_FINAL (charset) >= '0')
1162 code = charset_code_point (mother, ch, 1);
1164 code = charset_code_point (mother, ch, defined_only);
1166 else if (defined_only)
1168 else if ( ((max == 0) && CHARSETP (mother)
1169 && (XCHARSET_FINAL (charset) == 0))
1170 || ((min <= ch) && (ch <= max)) )
1172 if ( ((max == 0) && CHARSETP (mother) && (code >= 0))
1173 || ((min <= code) && (code <= max)) )
1175 int d = code - XCHARSET_CODE_OFFSET (charset);
1177 if ( XCHARSET_CONVERSION (charset) == CONVERSION_IDENTICAL )
1179 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94 )
1181 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_96 )
1183 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94x60 )
1186 int cell = d % 94 + 33;
1192 return (row << 8) | cell;
1194 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_BIG5_1 )
1196 int B1 = d >> 8, B2 = d & 0xFF;
1198 = (B1 - 0xA1) * BIG5_SAME_ROW + B2
1199 - (B2 < 0x7F ? 0x40 : 0x62);
1203 return ((I / 94 + 33) << 8) | (I % 94 + 33);
1206 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_BIG5_2 )
1208 int B1 = d >> 8, B2 = d & 0xFF;
1210 = (B1 - 0xA1) * BIG5_SAME_ROW + B2
1211 - (B2 < 0x7F ? 0x40 : 0x62);
1215 I -= (BIG5_SAME_ROW) * (0xC9 - 0xA1);
1216 return ((I / 94 + 33) << 8) | (I % 94 + 33);
1219 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94x94 )
1220 return ((d / 94 + 33) << 8) | (d % 94 + 33);
1221 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_96x96 )
1222 return ((d / 96 + 32) << 8) | (d % 96 + 32);
1223 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94x94x60 )
1225 int plane = d / (94 * 60) + 33;
1226 int row = (d % (94 * 60)) / 94;
1227 int cell = d % 94 + 33;
1233 return (plane << 16) | (row << 8) | cell;
1235 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94x94x94 )
1237 ( (d / (94 * 94) + 33) << 16)
1238 | ((d / 94 % 94 + 33) << 8)
1240 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_96x96x96 )
1242 ( (d / (96 * 96) + 32) << 16)
1243 | ((d / 96 % 96 + 32) << 8)
1245 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94x94x94x94 )
1247 ( (d / (94 * 94 * 94) + 33) << 24)
1248 | ((d / (94 * 94) % 94 + 33) << 16)
1249 | ((d / 94 % 94 + 33) << 8)
1251 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_96x96x96x96 )
1253 ( (d / (96 * 96 * 96) + 32) << 24)
1254 | ((d / (96 * 96) % 96 + 32) << 16)
1255 | ((d / 96 % 96 + 32) << 8)
1259 printf ("Unknown CCS-conversion %d is specified!",
1260 XCHARSET_CONVERSION (charset));
1264 else if (defined_only)
1266 else if ( ( XCHARSET_FINAL (charset) >= '0' ) &&
1267 ( XCHARSET_MIN_CODE (charset) == 0 )
1269 (XCHARSET_CODE_OFFSET (charset) == 0) ||
1270 (XCHARSET_CODE_OFFSET (charset)
1271 == XCHARSET_MIN_CODE (charset))
1276 if (XCHARSET_DIMENSION (charset) == 1)
1278 if (XCHARSET_CHARS (charset) == 94)
1280 if (((d = ch - (MIN_CHAR_94
1281 + (XCHARSET_FINAL (charset) - '0') * 94))
1286 else if (XCHARSET_CHARS (charset) == 96)
1288 if (((d = ch - (MIN_CHAR_96
1289 + (XCHARSET_FINAL (charset) - '0') * 96))
1297 else if (XCHARSET_DIMENSION (charset) == 2)
1299 if (XCHARSET_CHARS (charset) == 94)
1301 if (((d = ch - (MIN_CHAR_94x94
1303 (XCHARSET_FINAL (charset) - '0') * 94 * 94))
1306 return (((d / 94) + 33) << 8) | (d % 94 + 33);
1308 else if (XCHARSET_CHARS (charset) == 96)
1310 if (((d = ch - (MIN_CHAR_96x96
1312 (XCHARSET_FINAL (charset) - '0') * 96 * 96))
1315 return (((d / 96) + 32) << 8) | (d % 96 + 32);
1326 encode_char_2 (Emchar ch, Lisp_Object* charset)
1328 Lisp_Object charsets = Vdefault_coded_charset_priority_list;
1331 while (!NILP (charsets))
1333 *charset = Ffind_charset (Fcar (charsets));
1334 if ( !NILP (*charset)
1335 && (XCHARSET_DIMENSION (*charset) <= 2) )
1337 code_point = charset_code_point (*charset, ch, 0);
1338 if (code_point >= 0)
1341 if ( !NILP (Vdisplay_coded_charset_priority_use_inheritance) &&
1342 NILP (Vdisplay_coded_charset_priority_use_hierarchy_order) )
1344 code_point = encode_char_2_search_children (ch, charset);
1345 if (code_point >= 0)
1349 charsets = Fcdr (charsets);
1352 if ( !NILP (Vdisplay_coded_charset_priority_use_inheritance) &&
1353 !NILP (Vdisplay_coded_charset_priority_use_hierarchy_order) )
1355 charsets = Vdefault_coded_charset_priority_list;
1356 while (!NILP (charsets))
1358 *charset = Ffind_charset (Fcar (charsets));
1359 if ( !NILP (*charset)
1360 && (XCHARSET_DIMENSION (*charset) <= 2) )
1362 code_point = encode_char_2_search_children (ch, charset);
1363 if (code_point >= 0)
1366 charsets = Fcdr (charsets);
1370 /* otherwise --- maybe for bootstrap */
1371 return encode_builtin_char_1 (ch, charset);
1375 encode_builtin_char_1 (Emchar c, Lisp_Object* charset)
1377 if (c <= MAX_CHAR_BASIC_LATIN)
1379 *charset = Vcharset_ascii;
1384 *charset = Vcharset_control_1;
1389 *charset = Vcharset_latin_iso8859_1;
1393 else if ((MIN_CHAR_HEBREW <= c) && (c <= MAX_CHAR_HEBREW))
1395 *charset = Vcharset_hebrew_iso8859_8;
1396 return c - MIN_CHAR_HEBREW + 0x20;
1399 else if ((MIN_CHAR_THAI <= c) && (c <= MAX_CHAR_THAI))
1401 *charset = Vcharset_thai_tis620;
1402 return c - MIN_CHAR_THAI + 0x20;
1405 else if ((MIN_CHAR_HALFWIDTH_KATAKANA <= c)
1406 && (c <= MAX_CHAR_HALFWIDTH_KATAKANA))
1408 return list2 (Vcharset_katakana_jisx0201,
1409 make_int (c - MIN_CHAR_HALFWIDTH_KATAKANA + 33));
1412 else if (c <= MAX_CHAR_BMP)
1414 *charset = Vcharset_ucs_bmp;
1417 else if (c <= MAX_CHAR_SMP)
1419 *charset = Vcharset_ucs_smp;
1420 return c - MIN_CHAR_SMP;
1422 else if (c <= MAX_CHAR_SIP)
1424 *charset = Vcharset_ucs_sip;
1425 return c - MIN_CHAR_SIP;
1427 else if (c < MIN_CHAR_94)
1429 *charset = Vcharset_ucs;
1432 else if (c <= MAX_CHAR_94)
1434 *charset = CHARSET_BY_ATTRIBUTES (94, 1,
1435 ((c - MIN_CHAR_94) / 94) + '0',
1436 CHARSET_LEFT_TO_RIGHT);
1437 if (!NILP (*charset))
1438 return ((c - MIN_CHAR_94) % 94) + 33;
1441 *charset = Vcharset_ucs;
1445 else if (c <= MAX_CHAR_96)
1447 *charset = CHARSET_BY_ATTRIBUTES (96, 1,
1448 ((c - MIN_CHAR_96) / 96) + '0',
1449 CHARSET_LEFT_TO_RIGHT);
1450 if (!NILP (*charset))
1451 return ((c - MIN_CHAR_96) % 96) + 32;
1454 *charset = Vcharset_ucs;
1458 else if (c <= MAX_CHAR_94x94)
1461 = CHARSET_BY_ATTRIBUTES (94, 2,
1462 ((c - MIN_CHAR_94x94) / (94 * 94)) + '0',
1463 CHARSET_LEFT_TO_RIGHT);
1464 if (!NILP (*charset))
1465 return (((((c - MIN_CHAR_94x94) / 94) % 94) + 33) << 8)
1466 | (((c - MIN_CHAR_94x94) % 94) + 33);
1469 *charset = Vcharset_ucs;
1473 else if (c <= MAX_CHAR_96x96)
1476 = CHARSET_BY_ATTRIBUTES (96, 2,
1477 ((c - MIN_CHAR_96x96) / (96 * 96)) + '0',
1478 CHARSET_LEFT_TO_RIGHT);
1479 if (!NILP (*charset))
1480 return ((((c - MIN_CHAR_96x96) / 96) % 96) + 32) << 8
1481 | (((c - MIN_CHAR_96x96) % 96) + 32);
1484 *charset = Vcharset_ucs;
1490 *charset = Vcharset_ucs;
1495 Lisp_Object Vdefault_coded_charset_priority_list;
1496 Lisp_Object Vdisplay_coded_charset_priority_use_inheritance;
1497 Lisp_Object Vdisplay_coded_charset_priority_use_hierarchy_order;
1501 /************************************************************************/
1502 /* Basic charset Lisp functions */
1503 /************************************************************************/
1505 DEFUN ("charsetp", Fcharsetp, 1, 1, 0, /*
1506 Return non-nil if OBJECT is a charset.
1510 return CHARSETP (object) ? Qt : Qnil;
1513 DEFUN ("find-charset", Ffind_charset, 1, 1, 0, /*
1514 Retrieve the charset of the given name.
1515 If CHARSET-OR-NAME is a charset object, it is simply returned.
1516 Otherwise, CHARSET-OR-NAME should be a symbol. If there is no such charset,
1517 nil is returned. Otherwise the associated charset object is returned.
1521 if (CHARSETP (charset_or_name))
1522 return charset_or_name;
1524 CHECK_SYMBOL (charset_or_name);
1525 return Fgethash (charset_or_name, Vcharset_hash_table, Qnil);
1528 DEFUN ("get-charset", Fget_charset, 1, 1, 0, /*
1529 Retrieve the charset of the given name.
1530 Same as `find-charset' except an error is signalled if there is no such
1531 charset instead of returning nil.
1535 Lisp_Object charset = Ffind_charset (name);
1538 signal_simple_error ("No such charset", name);
1542 /* We store the charsets in hash tables with the names as the key and the
1543 actual charset object as the value. Occasionally we need to use them
1544 in a list format. These routines provide us with that. */
1545 struct charset_list_closure
1547 Lisp_Object *charset_list;
1551 add_charset_to_list_mapper (Lisp_Object key, Lisp_Object value,
1552 void *charset_list_closure)
1554 /* This function can GC */
1555 struct charset_list_closure *chcl =
1556 (struct charset_list_closure*) charset_list_closure;
1557 Lisp_Object *charset_list = chcl->charset_list;
1559 *charset_list = Fcons (key /* XCHARSET_NAME (value) */, *charset_list);
1563 DEFUN ("charset-list", Fcharset_list, 0, 0, 0, /*
1564 Return a list of the names of all defined charsets.
1568 Lisp_Object charset_list = Qnil;
1569 struct gcpro gcpro1;
1570 struct charset_list_closure charset_list_closure;
1572 GCPRO1 (charset_list);
1573 charset_list_closure.charset_list = &charset_list;
1574 elisp_maphash (add_charset_to_list_mapper, Vcharset_hash_table,
1575 &charset_list_closure);
1578 return charset_list;
1581 DEFUN ("charset-name", Fcharset_name, 1, 1, 0, /*
1582 Return the name of charset CHARSET.
1586 return XCHARSET_NAME (Fget_charset (charset));
1589 /* #### SJT Should generic properties be allowed? */
1590 DEFUN ("make-charset", Fmake_charset, 3, 3, 0, /*
1591 Define a new character set.
1592 This function is for use with Mule support.
1593 NAME is a symbol, the name by which the character set is normally referred.
1594 DOC-STRING is a string describing the character set.
1595 PROPS is a property list, describing the specific nature of the
1596 character set. Recognized properties are:
1598 'short-name Short version of the charset name (ex: Latin-1)
1599 'long-name Long version of the charset name (ex: ISO8859-1 (Latin-1))
1600 'registry A regular expression matching the font registry field for
1602 'dimension Number of octets used to index a character in this charset.
1603 Either 1 or 2. Defaults to 1.
1604 If UTF-2000 feature is enabled, 3 or 4 are also available.
1605 'columns Number of columns used to display a character in this charset.
1606 Only used in TTY mode. (Under X, the actual width of a
1607 character can be derived from the font used to display the
1608 characters.) If unspecified, defaults to the dimension
1609 (this is almost always the correct value).
1610 'chars Number of characters in each dimension (94 or 96).
1611 Defaults to 94. Note that if the dimension is 2, the
1612 character set thus described is 94x94 or 96x96.
1613 If UTF-2000 feature is enabled, 128 or 256 are also available.
1614 'final Final byte of ISO 2022 escape sequence. Must be
1615 supplied. Each combination of (DIMENSION, CHARS) defines a
1616 separate namespace for final bytes. Note that ISO
1617 2022 restricts the final byte to the range
1618 0x30 - 0x7E if dimension == 1, and 0x30 - 0x5F if
1619 dimension == 2. Note also that final bytes in the range
1620 0x30 - 0x3F are reserved for user-defined (not official)
1622 'graphic 0 (use left half of font on output) or 1 (use right half
1623 of font on output). Defaults to 0. For example, for
1624 a font whose registry is ISO8859-1, the left half
1625 (octets 0x20 - 0x7F) is the `ascii' character set, while
1626 the right half (octets 0xA0 - 0xFF) is the `latin-1'
1627 character set. With 'graphic set to 0, the octets
1628 will have their high bit cleared; with it set to 1,
1629 the octets will have their high bit set.
1630 'direction 'l2r (left-to-right) or 'r2l (right-to-left).
1632 'ccl-program A compiled CCL program used to convert a character in
1633 this charset into an index into the font. This is in
1634 addition to the 'graphic property. The CCL program
1635 is passed the octets of the character, with the high
1636 bit cleared and set depending upon whether the value
1637 of the 'graphic property is 0 or 1.
1638 'iso-ir ISO-IR number (for representative coded-charset).
1639 '=>iso-ir [UTF-2000 only] Corresponding ISO-IR number.
1640 'mother [UTF-2000 only] Base coded-charset.
1641 'code-min [UTF-2000 only] Minimum code-point of a base coded-charset.
1642 'code-max [UTF-2000 only] Maximum code-point of a base coded-charset.
1643 'code-offset [UTF-2000 only] Offset for a code-point of a base
1645 'conversion [UTF-2000 only] Conversion for a code-point of a base
1646 coded-charset (94x60, 94x94x60, big5-1 or big5-2).
1647 'partial [UTF-2000 only] If t, specify as a partial coded-charset.
1649 (name, doc_string, props))
1651 int id = 0, dimension = 1, chars = 94, graphic = 0, final = 0, columns = -1;
1653 int direction = CHARSET_LEFT_TO_RIGHT;
1654 Lisp_Object registry = Qnil;
1655 Lisp_Object charset;
1656 Lisp_Object ccl_program = Qnil;
1657 Lisp_Object short_name = Qnil, long_name = Qnil;
1658 Lisp_Object mother = Qnil;
1660 int min_code = 0, max_code = 0, code_offset = 0;
1661 int byte_offset = -1;
1664 CHECK_SYMBOL (name);
1665 if (!NILP (doc_string))
1666 CHECK_STRING (doc_string);
1668 charset = Ffind_charset (name);
1669 if (!NILP (charset))
1670 signal_simple_error ("Cannot redefine existing charset", name);
1673 EXTERNAL_PROPERTY_LIST_LOOP_3 (keyword, value, props)
1675 if (EQ (keyword, Qshort_name))
1677 CHECK_STRING (value);
1681 else if (EQ (keyword, Qlong_name))
1683 CHECK_STRING (value);
1687 else if (EQ (keyword, Qiso_ir))
1691 iso_ir = XINT (value);
1697 else if (EQ (keyword, Qto_iso_ir))
1700 iso_ir = XINT (value);
1704 else if (EQ (keyword, Qdimension))
1707 dimension = XINT (value);
1708 if (dimension < 1 ||
1715 signal_simple_error ("Invalid value for 'dimension", value);
1718 else if (EQ (keyword, Qchars))
1721 chars = XINT (value);
1722 if (chars != 94 && chars != 96
1724 && chars != 128 && chars != 256
1727 signal_simple_error ("Invalid value for 'chars", value);
1730 else if (EQ (keyword, Qcolumns))
1733 columns = XINT (value);
1734 if (columns != 1 && columns != 2)
1735 signal_simple_error ("Invalid value for 'columns", value);
1738 else if (EQ (keyword, Qgraphic))
1741 graphic = XINT (value);
1749 signal_simple_error ("Invalid value for 'graphic", value);
1752 else if (EQ (keyword, Qregistry))
1754 CHECK_STRING (value);
1758 else if (EQ (keyword, Qdirection))
1760 if (EQ (value, Ql2r))
1761 direction = CHARSET_LEFT_TO_RIGHT;
1762 else if (EQ (value, Qr2l))
1763 direction = CHARSET_RIGHT_TO_LEFT;
1765 signal_simple_error ("Invalid value for 'direction", value);
1768 else if (EQ (keyword, Qfinal))
1770 CHECK_CHAR_COERCE_INT (value);
1771 final = XCHAR (value);
1772 if (final < '0' || final > '~')
1773 signal_simple_error ("Invalid value for 'final", value);
1777 else if (EQ (keyword, Qpartial))
1779 partial = !NILP (value);
1782 else if (EQ (keyword, Qmother))
1784 mother = Fget_charset (value);
1787 else if (EQ (keyword, Qmin_code))
1790 min_code = XUINT (value);
1793 else if (EQ (keyword, Qmax_code))
1796 max_code = XUINT (value);
1799 else if (EQ (keyword, Qcode_offset))
1802 code_offset = XUINT (value);
1805 else if (EQ (keyword, Qconversion))
1807 if (EQ (value, Q94x60))
1808 conversion = CONVERSION_94x60;
1809 else if (EQ (value, Q94x94x60))
1810 conversion = CONVERSION_94x94x60;
1811 else if (EQ (value, Qbig5_1))
1812 conversion = CONVERSION_BIG5_1;
1813 else if (EQ (value, Qbig5_2))
1814 conversion = CONVERSION_BIG5_2;
1816 signal_simple_error ("Unrecognized conversion", value);
1820 else if (EQ (keyword, Qccl_program))
1822 struct ccl_program test_ccl;
1824 if (setup_ccl_program (&test_ccl, value) < 0)
1825 signal_simple_error ("Invalid value for 'ccl-program", value);
1826 ccl_program = value;
1830 signal_simple_error ("Unrecognized property", keyword);
1836 error ("'final must be specified");
1838 if (dimension == 2 && final > 0x5F)
1840 ("Final must be in the range 0x30 - 0x5F for dimension == 2",
1843 if (!NILP (CHARSET_BY_ATTRIBUTES (chars, dimension, final,
1844 CHARSET_LEFT_TO_RIGHT)) ||
1845 !NILP (CHARSET_BY_ATTRIBUTES (chars, dimension, final,
1846 CHARSET_RIGHT_TO_LEFT)))
1848 ("Character set already defined for this DIMENSION/CHARS/FINAL combo");
1851 id = get_unallocated_leading_byte (dimension);
1853 if (NILP (doc_string))
1854 doc_string = build_string ("");
1856 if (NILP (registry))
1857 registry = build_string ("");
1859 if (NILP (short_name))
1860 XSETSTRING (short_name, XSYMBOL (name)->name);
1862 if (NILP (long_name))
1863 long_name = doc_string;
1866 columns = dimension;
1868 if (byte_offset < 0)
1872 else if (chars == 96)
1878 if ( (conversion == 0) && NILP (mother) && (min_code > 0) )
1886 conversion = CONVERSION_94;
1889 conversion = CONVERSION_94x94;
1892 conversion = CONVERSION_94x94x94;
1895 conversion = CONVERSION_94x94x94x94;
1903 conversion = CONVERSION_96;
1906 conversion = CONVERSION_96x96;
1909 conversion = CONVERSION_96x96x96;
1912 conversion = CONVERSION_96x96x96x96;
1919 charset = make_charset (id, name, chars, dimension, columns, graphic,
1920 final, direction, short_name, long_name,
1921 doc_string, registry, iso_ir,
1922 Qnil, min_code, max_code, code_offset, byte_offset,
1923 mother, conversion, partial);
1924 if (!NILP (ccl_program))
1925 XCHARSET_CCL_PROGRAM (charset) = ccl_program;
1929 DEFUN ("make-reverse-direction-charset", Fmake_reverse_direction_charset,
1931 Make a charset equivalent to CHARSET but which goes in the opposite direction.
1932 NEW-NAME is the name of the new charset. Return the new charset.
1934 (charset, new_name))
1936 Lisp_Object new_charset = Qnil;
1937 int id, chars, dimension, columns, graphic, final;
1939 Lisp_Object registry, doc_string, short_name, long_name;
1942 charset = Fget_charset (charset);
1943 if (!NILP (XCHARSET_REVERSE_DIRECTION_CHARSET (charset)))
1944 signal_simple_error ("Charset already has reverse-direction charset",
1947 CHECK_SYMBOL (new_name);
1948 if (!NILP (Ffind_charset (new_name)))
1949 signal_simple_error ("Cannot redefine existing charset", new_name);
1951 cs = XCHARSET (charset);
1953 chars = CHARSET_CHARS (cs);
1954 dimension = CHARSET_DIMENSION (cs);
1955 columns = CHARSET_COLUMNS (cs);
1956 id = get_unallocated_leading_byte (dimension);
1958 graphic = CHARSET_GRAPHIC (cs);
1959 final = CHARSET_FINAL (cs);
1960 direction = CHARSET_RIGHT_TO_LEFT;
1961 if (CHARSET_DIRECTION (cs) == CHARSET_RIGHT_TO_LEFT)
1962 direction = CHARSET_LEFT_TO_RIGHT;
1963 doc_string = CHARSET_DOC_STRING (cs);
1964 short_name = CHARSET_SHORT_NAME (cs);
1965 long_name = CHARSET_LONG_NAME (cs);
1966 registry = CHARSET_REGISTRY (cs);
1968 new_charset = make_charset (id, new_name, chars, dimension, columns,
1969 graphic, final, direction, short_name, long_name,
1970 doc_string, registry,
1973 CHARSET_DECODING_TABLE(cs),
1974 CHARSET_MIN_CODE(cs),
1975 CHARSET_MAX_CODE(cs),
1976 CHARSET_CODE_OFFSET(cs),
1977 CHARSET_BYTE_OFFSET(cs),
1979 CHARSET_CONVERSION (cs)
1981 Qnil, 0, 0, 0, 0, Qnil, 0
1985 CHARSET_REVERSE_DIRECTION_CHARSET (cs) = new_charset;
1986 XCHARSET_REVERSE_DIRECTION_CHARSET (new_charset) = charset;
1991 DEFUN ("define-charset-alias", Fdefine_charset_alias, 2, 2, 0, /*
1992 Define symbol ALIAS as an alias for CHARSET.
1996 CHECK_SYMBOL (alias);
1997 charset = Fget_charset (charset);
1998 return Fputhash (alias, charset, Vcharset_hash_table);
2001 /* #### Reverse direction charsets not yet implemented. */
2003 DEFUN ("charset-reverse-direction-charset", Fcharset_reverse_direction_charset,
2005 Return the reverse-direction charset parallel to CHARSET, if any.
2006 This is the charset with the same properties (in particular, the same
2007 dimension, number of characters per dimension, and final byte) as
2008 CHARSET but whose characters are displayed in the opposite direction.
2012 charset = Fget_charset (charset);
2013 return XCHARSET_REVERSE_DIRECTION_CHARSET (charset);
2017 DEFUN ("charset-from-attributes", Fcharset_from_attributes, 3, 4, 0, /*
2018 Return a charset with the given DIMENSION, CHARS, FINAL, and DIRECTION.
2019 If DIRECTION is omitted, both directions will be checked (left-to-right
2020 will be returned if character sets exist for both directions).
2022 (dimension, chars, final, direction))
2024 int dm, ch, fi, di = -1;
2025 Lisp_Object obj = Qnil;
2027 CHECK_INT (dimension);
2028 dm = XINT (dimension);
2029 if (dm < 1 || dm > 2)
2030 signal_simple_error ("Invalid value for DIMENSION", dimension);
2034 if (ch != 94 && ch != 96)
2035 signal_simple_error ("Invalid value for CHARS", chars);
2037 CHECK_CHAR_COERCE_INT (final);
2039 if (fi < '0' || fi > '~')
2040 signal_simple_error ("Invalid value for FINAL", final);
2042 if (EQ (direction, Ql2r))
2043 di = CHARSET_LEFT_TO_RIGHT;
2044 else if (EQ (direction, Qr2l))
2045 di = CHARSET_RIGHT_TO_LEFT;
2046 else if (!NILP (direction))
2047 signal_simple_error ("Invalid value for DIRECTION", direction);
2049 if (dm == 2 && fi > 0x5F)
2051 ("Final must be in the range 0x30 - 0x5F for dimension == 2", final);
2055 obj = CHARSET_BY_ATTRIBUTES (ch, dm, fi, CHARSET_LEFT_TO_RIGHT);
2057 obj = CHARSET_BY_ATTRIBUTES (ch, dm, fi, CHARSET_RIGHT_TO_LEFT);
2060 obj = CHARSET_BY_ATTRIBUTES (ch, dm, fi, di);
2063 return XCHARSET_NAME (obj);
2067 DEFUN ("charset-short-name", Fcharset_short_name, 1, 1, 0, /*
2068 Return short name of CHARSET.
2072 return XCHARSET_SHORT_NAME (Fget_charset (charset));
2075 DEFUN ("charset-long-name", Fcharset_long_name, 1, 1, 0, /*
2076 Return long name of CHARSET.
2080 return XCHARSET_LONG_NAME (Fget_charset (charset));
2083 DEFUN ("charset-description", Fcharset_description, 1, 1, 0, /*
2084 Return description of CHARSET.
2088 return XCHARSET_DOC_STRING (Fget_charset (charset));
2091 DEFUN ("charset-dimension", Fcharset_dimension, 1, 1, 0, /*
2092 Return dimension of CHARSET.
2096 return make_int (XCHARSET_DIMENSION (Fget_charset (charset)));
2099 DEFUN ("charset-property", Fcharset_property, 2, 2, 0, /*
2100 Return property PROP of CHARSET, a charset object or symbol naming a charset.
2101 Recognized properties are those listed in `make-charset', as well as
2102 'name and 'doc-string.
2108 charset = Fget_charset (charset);
2109 cs = XCHARSET (charset);
2111 CHECK_SYMBOL (prop);
2112 if (EQ (prop, Qname)) return CHARSET_NAME (cs);
2113 if (EQ (prop, Qshort_name)) return CHARSET_SHORT_NAME (cs);
2114 if (EQ (prop, Qlong_name)) return CHARSET_LONG_NAME (cs);
2115 if (EQ (prop, Qdoc_string)) return CHARSET_DOC_STRING (cs);
2116 if (EQ (prop, Qdimension)) return make_int (CHARSET_DIMENSION (cs));
2117 if (EQ (prop, Qcolumns)) return make_int (CHARSET_COLUMNS (cs));
2118 if (EQ (prop, Qgraphic)) return make_int (CHARSET_GRAPHIC (cs));
2119 if (EQ (prop, Qfinal)) return CHARSET_FINAL (cs) == 0 ?
2120 Qnil : make_char (CHARSET_FINAL (cs));
2121 if (EQ (prop, Qchars)) return make_int (CHARSET_CHARS (cs));
2122 if (EQ (prop, Qregistry)) return CHARSET_REGISTRY (cs);
2123 if (EQ (prop, Qccl_program)) return CHARSET_CCL_PROGRAM (cs);
2124 if (EQ (prop, Qdirection))
2125 return CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? Ql2r : Qr2l;
2126 if (EQ (prop, Qreverse_direction_charset))
2128 Lisp_Object obj = CHARSET_REVERSE_DIRECTION_CHARSET (cs);
2129 /* #### Is this translation OK? If so, error checking sufficient? */
2130 return CHARSETP (obj) ? XCHARSET_NAME (obj) : obj;
2133 if (EQ (prop, Qiso_ir)||
2134 EQ (prop, Qto_iso_ir))
2136 if ( CHARSET_ISO_IR (cs) > 0 )
2137 return make_int (CHARSET_ISO_IR (cs));
2141 if (EQ (prop, Qmother))
2142 return CHARSET_MOTHER (cs);
2143 if (EQ (prop, Qmin_code))
2144 return make_int (CHARSET_MIN_CODE (cs));
2145 if (EQ (prop, Qmax_code))
2146 return make_int (CHARSET_MAX_CODE (cs));
2148 signal_simple_error ("Unrecognized charset property name", prop);
2149 return Qnil; /* not reached */
2152 DEFUN ("charset-id", Fcharset_id, 1, 1, 0, /*
2153 Return charset identification number of CHARSET.
2157 return make_int(XCHARSET_LEADING_BYTE (Fget_charset (charset)));
2160 /* #### We need to figure out which properties we really want to
2163 DEFUN ("set-charset-ccl-program", Fset_charset_ccl_program, 2, 2, 0, /*
2164 Set the 'ccl-program property of CHARSET to CCL-PROGRAM.
2166 (charset, ccl_program))
2168 struct ccl_program test_ccl;
2170 charset = Fget_charset (charset);
2171 if (setup_ccl_program (&test_ccl, ccl_program) < 0)
2172 signal_simple_error ("Invalid ccl-program", ccl_program);
2173 XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2178 invalidate_charset_font_caches (Lisp_Object charset)
2180 /* Invalidate font cache entries for charset on all devices. */
2181 Lisp_Object devcons, concons, hash_table;
2182 DEVICE_LOOP_NO_BREAK (devcons, concons)
2184 struct device *d = XDEVICE (XCAR (devcons));
2185 hash_table = Fgethash (charset, d->charset_font_cache, Qunbound);
2186 if (!UNBOUNDP (hash_table))
2187 Fclrhash (hash_table);
2191 DEFUN ("set-charset-registry", Fset_charset_registry, 2, 2, 0, /*
2192 Set the 'registry property of CHARSET to REGISTRY.
2194 (charset, registry))
2196 charset = Fget_charset (charset);
2197 CHECK_STRING (registry);
2198 XCHARSET_REGISTRY (charset) = registry;
2199 invalidate_charset_font_caches (charset);
2200 face_property_was_changed (Vdefault_face, Qfont, Qglobal);
2205 DEFUN ("charset-mapping-table", Fcharset_mapping_table, 1, 1, 0, /*
2206 Return mapping-table of CHARSET.
2210 return XCHARSET_DECODING_TABLE (Fget_charset (charset));
2213 DEFUN ("set-charset-mapping-table", Fset_charset_mapping_table, 2, 2, 0, /*
2214 Set mapping-table of CHARSET to TABLE.
2218 struct Lisp_Charset *cs;
2222 charset = Fget_charset (charset);
2223 cs = XCHARSET (charset);
2227 CHARSET_DECODING_TABLE(cs) = Qnil;
2230 else if (VECTORP (table))
2232 int ccs_len = CHARSET_BYTE_SIZE (cs);
2233 int ret = decoding_table_check_elements (table,
2234 CHARSET_DIMENSION (cs),
2239 signal_simple_error ("Too big table", table);
2241 signal_simple_error ("Invalid element is found", table);
2243 signal_simple_error ("Something wrong", table);
2245 CHARSET_DECODING_TABLE(cs) = Qnil;
2248 signal_error (Qwrong_type_argument,
2249 list2 (build_translated_string ("vector-or-nil-p"),
2252 byte_offset = CHARSET_BYTE_OFFSET (cs);
2253 switch (CHARSET_DIMENSION (cs))
2256 for (i = 0; i < XVECTOR_LENGTH (table); i++)
2258 Lisp_Object c = XVECTOR_DATA(table)[i];
2261 Fput_char_attribute (c, XCHARSET_NAME (charset),
2262 make_int (i + byte_offset));
2266 for (i = 0; i < XVECTOR_LENGTH (table); i++)
2268 Lisp_Object v = XVECTOR_DATA(table)[i];
2274 for (j = 0; j < XVECTOR_LENGTH (v); j++)
2276 Lisp_Object c = XVECTOR_DATA(v)[j];
2280 (c, XCHARSET_NAME (charset),
2281 make_int ( ( (i + byte_offset) << 8 )
2287 Fput_char_attribute (v, XCHARSET_NAME (charset),
2288 make_int (i + byte_offset));
2296 DEFUN ("save-charset-mapping-table", Fsave_charset_mapping_table, 1, 1, 0, /*
2297 Save mapping-table of CHARSET.
2301 struct Lisp_Charset *cs;
2302 int byte_min, byte_max;
2303 #ifdef HAVE_LIBCHISE
2305 #else /* HAVE_LIBCHISE */
2307 Lisp_Object db_file;
2308 #endif /* not HAVE_LIBCHISE */
2310 charset = Fget_charset (charset);
2311 cs = XCHARSET (charset);
2313 #ifdef HAVE_LIBCHISE
2314 if ( open_chise_data_source_maybe () )
2318 = chise_ds_get_ccs (default_chise_data_source,
2319 XSTRING_DATA (Fsymbol_name (XCHARSET_NAME(charset))));
2322 printf ("Can't open decoding-table %s\n",
2323 XSTRING_DATA (Fsymbol_name (XCHARSET_NAME(charset))));
2326 #else /* HAVE_LIBCHISE */
2327 db_file = char_attribute_system_db_file (CHARSET_NAME (cs),
2328 Qsystem_char_id, 1);
2329 db = Fopen_database (db_file, Qnil, Qnil, build_string ("w+"), Qnil);
2330 #endif /* not HAVE_LIBCHISE */
2332 byte_min = CHARSET_BYTE_OFFSET (cs);
2333 byte_max = byte_min + CHARSET_BYTE_SIZE (cs);
2334 switch (CHARSET_DIMENSION (cs))
2338 Lisp_Object table_c = XCHARSET_DECODING_TABLE (charset);
2341 for (cell = byte_min; cell < byte_max; cell++)
2343 Lisp_Object c = get_ccs_octet_table (table_c, charset, cell);
2347 #ifdef HAVE_LIBCHISE
2348 chise_ccs_set_decoded_char (dt_ccs, cell, XCHAR (c));
2349 #else /* HAVE_LIBCHISE */
2350 Fput_database (Fprin1_to_string (make_int (cell), Qnil),
2351 Fprin1_to_string (c, Qnil),
2353 #endif /* not HAVE_LIBCHISE */
2360 Lisp_Object table_r = XCHARSET_DECODING_TABLE (charset);
2363 for (row = byte_min; row < byte_max; row++)
2365 Lisp_Object table_c = get_ccs_octet_table (table_r, charset, row);
2368 for (cell = byte_min; cell < byte_max; cell++)
2370 Lisp_Object c = get_ccs_octet_table (table_c, charset, cell);
2374 #ifdef HAVE_LIBCHISE
2375 chise_ccs_set_decoded_char
2377 (row << 8) | cell, XCHAR (c));
2378 #else /* HAVE_LIBCHISE */
2379 Fput_database (Fprin1_to_string (make_int ((row << 8)
2382 Fprin1_to_string (c, Qnil),
2384 #endif /* not HAVE_LIBCHISE */
2392 Lisp_Object table_p = XCHARSET_DECODING_TABLE (charset);
2395 for (plane = byte_min; plane < byte_max; plane++)
2398 = get_ccs_octet_table (table_p, charset, plane);
2401 for (row = byte_min; row < byte_max; row++)
2404 = get_ccs_octet_table (table_r, charset, row);
2407 for (cell = byte_min; cell < byte_max; cell++)
2409 Lisp_Object c = get_ccs_octet_table (table_c, charset,
2414 #ifdef HAVE_LIBCHISE
2415 chise_ccs_set_decoded_char
2420 #else /* HAVE_LIBCHISE */
2421 Fput_database (Fprin1_to_string
2422 (make_int ((plane << 16)
2426 Fprin1_to_string (c, Qnil),
2428 #endif /* not HAVE_LIBCHISE */
2437 Lisp_Object table_g = XCHARSET_DECODING_TABLE (charset);
2440 for (group = byte_min; group < byte_max; group++)
2443 = get_ccs_octet_table (table_g, charset, group);
2446 for (plane = byte_min; plane < byte_max; plane++)
2449 = get_ccs_octet_table (table_p, charset, plane);
2452 for (row = byte_min; row < byte_max; row++)
2455 = get_ccs_octet_table (table_r, charset, row);
2458 for (cell = byte_min; cell < byte_max; cell++)
2461 = get_ccs_octet_table (table_c, charset, cell);
2465 #ifdef HAVE_LIBCHISE
2466 chise_ccs_set_decoded_char
2472 #else /* HAVE_LIBCHISE */
2473 Fput_database (Fprin1_to_string
2474 (make_int (( group << 24)
2479 Fprin1_to_string (c, Qnil),
2481 #endif /* not HAVE_LIBCHISE */
2489 #ifdef HAVE_LIBCHISE
2490 chise_ccs_sync (dt_ccs);
2492 #else /* HAVE_LIBCHISE */
2493 return Fclose_database (db);
2494 #endif /* not HAVE_LIBCHISE */
2497 DEFUN ("reset-charset-mapping-table", Freset_charset_mapping_table, 1, 1, 0, /*
2498 Reset mapping-table of CCS with database file.
2502 #ifdef HAVE_LIBCHISE
2503 CHISE_CCS chise_ccs;
2505 Lisp_Object db_file;
2508 ccs = Fget_charset (ccs);
2510 #ifdef HAVE_LIBCHISE
2511 if ( open_chise_data_source_maybe () )
2514 chise_ccs = chise_ds_get_ccs (default_chise_data_source,
2515 XSTRING_DATA (Fsymbol_name
2516 (XCHARSET_NAME(ccs))));
2517 if (chise_ccs == NULL)
2520 db_file = char_attribute_system_db_file (XCHARSET_NAME(ccs),
2521 Qsystem_char_id, 0);
2525 #ifdef HAVE_LIBCHISE
2526 chise_ccs_setup_db (chise_ccs, 0) == 0
2528 !NILP (Ffile_exists_p (db_file))
2532 XCHARSET_DECODING_TABLE(ccs) = Qunloaded;
2539 load_char_decoding_entry_maybe (Lisp_Object ccs, int code_point)
2541 #ifdef HAVE_LIBCHISE
2542 CHISE_Char_ID char_id;
2544 if ( open_chise_data_source_maybe () )
2548 = chise_ds_decode_char (default_chise_data_source,
2549 XSTRING_DATA(Fsymbol_name (XCHARSET_NAME(ccs))),
2552 decoding_table_put_char (ccs, code_point, make_char (char_id));
2554 decoding_table_put_char (ccs, code_point, Qnil);
2556 /* chise_ccst_close (dt_ccs); */
2558 #else /* HAVE_LIBCHISE */
2561 = char_attribute_system_db_file (XCHARSET_NAME(ccs), Qsystem_char_id,
2564 db = Fopen_database (db_file, Qnil, Qnil, build_string ("r"), Qnil);
2568 = Fget_database (Fprin1_to_string (make_int (code_point), Qnil),
2575 decoding_table_put_char (ccs, code_point, ret);
2576 Fclose_database (db);
2580 decoding_table_put_char (ccs, code_point, Qnil);
2581 Fclose_database (db);
2584 #endif /* not HAVE_LIBCHISE */
2587 #ifdef HAVE_LIBCHISE
2588 DEFUN ("save-charset-properties", Fsave_charset_properties, 1, 1, 0, /*
2589 Save properties of CHARSET.
2593 struct Lisp_Charset *cs;
2594 CHISE_Property property;
2596 unsigned char* feature_name;
2598 ccs = Fget_charset (charset);
2599 cs = XCHARSET (ccs);
2601 if ( open_chise_data_source_maybe () )
2604 if ( SYMBOLP (charset) && !EQ (charset, XCHARSET_NAME (ccs)) )
2606 property = chise_ds_get_property (default_chise_data_source,
2608 feature_name = XSTRING_DATA (Fsymbol_name (charset));
2609 chise_feature_set_property_value
2610 (chise_ds_get_feature (default_chise_data_source, feature_name),
2611 property, XSTRING_DATA (Fprin1_to_string (CHARSET_NAME (cs),
2613 chise_property_sync (property);
2615 charset = XCHARSET_NAME (ccs);
2616 feature_name = XSTRING_DATA (Fsymbol_name (charset));
2618 property = chise_ds_get_property (default_chise_data_source,
2620 chise_feature_set_property_value
2621 (chise_ds_get_feature (default_chise_data_source, feature_name),
2622 property, XSTRING_DATA (Fprin1_to_string
2623 (CHARSET_DOC_STRING (cs), Qnil)));
2624 chise_property_sync (property);
2626 property = chise_ds_get_property (default_chise_data_source, "type");
2627 chise_feature_set_property_value
2628 (chise_ds_get_feature (default_chise_data_source, feature_name),
2630 chise_property_sync (property);
2632 property = chise_ds_get_property (default_chise_data_source, "chars");
2633 chise_feature_set_property_value
2634 (chise_ds_get_feature (default_chise_data_source, feature_name),
2635 property, XSTRING_DATA (Fprin1_to_string (make_int
2636 (CHARSET_CHARS (cs)),
2638 chise_property_sync (property);
2640 property = chise_ds_get_property (default_chise_data_source, "dimension");
2641 chise_feature_set_property_value
2642 (chise_ds_get_feature (default_chise_data_source, feature_name),
2643 property, XSTRING_DATA (Fprin1_to_string (make_int
2644 (CHARSET_DIMENSION (cs)),
2646 chise_property_sync (property);
2648 if ( CHARSET_FINAL (cs) != 0 )
2650 property = chise_ds_get_property (default_chise_data_source,
2652 chise_feature_set_property_value
2653 (chise_ds_get_feature (default_chise_data_source, feature_name),
2654 property, XSTRING_DATA (Fprin1_to_string (make_int
2655 (CHARSET_FINAL (cs)),
2657 chise_property_sync (property);
2660 if ( !NILP (CHARSET_MOTHER (cs)) )
2662 Lisp_Object mother = CHARSET_MOTHER (cs);
2664 if ( CHARSETP (mother) )
2665 mother = XCHARSET_NAME (mother);
2667 property = chise_ds_get_property (default_chise_data_source,
2669 chise_feature_set_property_value
2670 (chise_ds_get_feature (default_chise_data_source, feature_name),
2671 property, XSTRING_DATA (Fprin1_to_string (mother, Qnil)));
2672 chise_property_sync (property);
2675 if ( CHARSET_MAX_CODE (cs) != 0 )
2679 property = chise_ds_get_property (default_chise_data_source,
2681 if ( CHARSET_MIN_CODE (cs) == 0 )
2682 chise_feature_set_property_value
2683 (chise_ds_get_feature (default_chise_data_source, feature_name),
2687 sprintf (str, "#x%X", CHARSET_MIN_CODE (cs));
2688 chise_feature_set_property_value
2689 (chise_ds_get_feature (default_chise_data_source, feature_name),
2692 chise_property_sync (property);
2694 property = chise_ds_get_property (default_chise_data_source,
2696 sprintf (str, "#x%X", CHARSET_MAX_CODE (cs));
2697 chise_feature_set_property_value
2698 (chise_ds_get_feature (default_chise_data_source, feature_name),
2700 chise_property_sync (property);
2702 property = chise_ds_get_property (default_chise_data_source,
2703 "mother-code-offset");
2704 if ( CHARSET_CODE_OFFSET (cs) == 0 )
2705 chise_feature_set_property_value
2706 (chise_ds_get_feature (default_chise_data_source, feature_name),
2710 sprintf (str, "#x%X", CHARSET_CODE_OFFSET (cs));
2711 chise_feature_set_property_value
2712 (chise_ds_get_feature (default_chise_data_source, feature_name),
2715 chise_property_sync (property);
2717 property = chise_ds_get_property (default_chise_data_source,
2718 "mother-code-conversion");
2719 if ( CHARSET_CONVERSION (cs) == CONVERSION_IDENTICAL )
2720 chise_feature_set_property_value
2721 (chise_ds_get_feature (default_chise_data_source, feature_name),
2722 property, "identical");
2725 Lisp_Object sym = Qnil;
2727 if ( CHARSET_CONVERSION (cs) == CONVERSION_94x60 )
2729 else if ( CHARSET_CONVERSION (cs) == CONVERSION_94x94x60 )
2731 else if ( CHARSET_CONVERSION (cs) == CONVERSION_BIG5_1 )
2733 else if ( CHARSET_CONVERSION (cs) == CONVERSION_BIG5_2 )
2736 chise_feature_set_property_value
2737 (chise_ds_get_feature (default_chise_data_source, feature_name),
2738 property, XSTRING_DATA (Fprin1_to_string (sym, Qnil)));
2740 chise_feature_set_property_value
2741 (chise_ds_get_feature (default_chise_data_source, feature_name),
2742 property, "unknown");
2744 chise_property_sync (property);
2748 #endif /* HAVE_LIBCHISE */
2750 #endif /* HAVE_CHISE */
2751 #endif /* UTF2000 */
2754 /************************************************************************/
2755 /* Lisp primitives for working with characters */
2756 /************************************************************************/
2759 DEFUN ("decode-char", Fdecode_char, 2, 4, 0, /*
2760 Make a character from CHARSET and code-point CODE.
2761 If DEFINED_ONLY is non-nil, builtin character is not returned.
2762 If WITHOUT_INHERITANCE is non-nil, inherited character is not returned.
2763 If corresponding character is not found, nil is returned.
2765 (charset, code, defined_only, without_inheritance))
2769 charset = Fget_charset (charset);
2772 if ( (XCHARSET_GRAPHIC (charset) == 0) ||
2773 (XCHARSET_GRAPHIC (charset) == 1) )
2775 if (NILP (defined_only))
2776 c = DECODE_CHAR (charset, c, !NILP (without_inheritance));
2778 c = decode_defined_char (charset, c, !NILP (without_inheritance));
2779 return c >= 0 ? make_char (c) : Qnil;
2782 DEFUN ("decode-builtin-char", Fdecode_builtin_char, 2, 2, 0, /*
2783 Make a builtin character from CHARSET and code-point CODE.
2790 charset = Fget_charset (charset);
2792 if (EQ (charset, Vcharset_latin_viscii))
2794 Lisp_Object chr = Fdecode_char (charset, code, Qnil, Qnil);
2800 (ret = Fget_char_attribute (chr,
2801 Vcharset_latin_viscii_lower,
2804 charset = Vcharset_latin_viscii_lower;
2808 (ret = Fget_char_attribute (chr,
2809 Vcharset_latin_viscii_upper,
2812 charset = Vcharset_latin_viscii_upper;
2819 if (XCHARSET_GRAPHIC (charset) == 1)
2822 ch = decode_builtin_char (charset, c);
2824 ch >= 0 ? make_char (ch) : Fdecode_char (charset, code, Qnil, Qnil);
2828 DEFUN ("make-char", Fmake_char, 2, 3, 0, /*
2829 Make a character from CHARSET and octets ARG1 and ARG2.
2830 ARG2 is required only for characters from two-dimensional charsets.
2831 For example, (make-char 'latin-iso8859-2 185) will return the Latin 2
2832 character s with caron.
2834 (charset, arg1, arg2))
2838 int lowlim, highlim;
2840 charset = Fget_charset (charset);
2841 cs = XCHARSET (charset);
2843 if (EQ (charset, Vcharset_ascii)) lowlim = 0, highlim = 127;
2844 else if (EQ (charset, Vcharset_control_1)) lowlim = 0, highlim = 31;
2846 else if (CHARSET_CHARS (cs) == 256) lowlim = 0, highlim = 255;
2848 else if (CHARSET_CHARS (cs) == 94) lowlim = 33, highlim = 126;
2849 else /* CHARSET_CHARS (cs) == 96) */ lowlim = 32, highlim = 127;
2852 /* It is useful (and safe, according to Olivier Galibert) to strip
2853 the 8th bit off ARG1 and ARG2 because it allows programmers to
2854 write (make-char 'latin-iso8859-2 CODE) where code is the actual
2855 Latin 2 code of the character. */
2863 if (a1 < lowlim || a1 > highlim)
2864 args_out_of_range_3 (arg1, make_int (lowlim), make_int (highlim));
2866 if (CHARSET_DIMENSION (cs) == 1)
2870 ("Charset is of dimension one; second octet must be nil", arg2);
2871 return make_char (MAKE_CHAR (charset, a1, 0));
2880 a2 = XINT (arg2) & 0x7f;
2882 if (a2 < lowlim || a2 > highlim)
2883 args_out_of_range_3 (arg2, make_int (lowlim), make_int (highlim));
2885 return make_char (MAKE_CHAR (charset, a1, a2));
2888 DEFUN ("char-charset", Fchar_charset, 1, 1, 0, /*
2889 Return the character set of CHARACTER.
2893 CHECK_CHAR_COERCE_INT (character);
2895 return XCHARSET_NAME (CHAR_CHARSET (XCHAR (character)));
2898 DEFUN ("char-octet", Fchar_octet, 1, 2, 0, /*
2899 Return the octet numbered N (should be 0 or 1) of CHARACTER.
2900 N defaults to 0 if omitted.
2904 Lisp_Object charset;
2907 CHECK_CHAR_COERCE_INT (character);
2909 BREAKUP_CHAR (XCHAR (character), charset, octet0, octet1);
2911 if (NILP (n) || EQ (n, Qzero))
2912 return make_int (octet0);
2913 else if (EQ (n, make_int (1)))
2914 return make_int (octet1);
2916 signal_simple_error ("Octet number must be 0 or 1", n);
2920 DEFUN ("encode-char", Fencode_char, 2, 3, 0, /*
2921 Return code-point of CHARACTER in specified CHARSET.
2923 (character, charset, defined_only))
2927 CHECK_CHAR_COERCE_INT (character);
2928 charset = Fget_charset (charset);
2929 code_point = charset_code_point (charset, XCHAR (character),
2930 !NILP (defined_only));
2931 if (code_point >= 0)
2932 return make_int (code_point);
2938 DEFUN ("split-char", Fsplit_char, 1, 1, 0, /*
2939 Return list of charset and one or two position-codes of CHARACTER.
2943 /* This function can GC */
2944 struct gcpro gcpro1, gcpro2;
2945 Lisp_Object charset = Qnil;
2946 Lisp_Object rc = Qnil;
2954 GCPRO2 (charset, rc);
2955 CHECK_CHAR_COERCE_INT (character);
2958 code_point = ENCODE_CHAR (XCHAR (character), charset);
2959 dimension = XCHARSET_DIMENSION (charset);
2960 while (dimension > 0)
2962 rc = Fcons (make_int (code_point & 255), rc);
2966 rc = Fcons (XCHARSET_NAME (charset), rc);
2968 BREAKUP_CHAR (XCHAR (character), charset, c1, c2);
2970 if (XCHARSET_DIMENSION (Fget_charset (charset)) == 2)
2972 rc = list3 (XCHARSET_NAME (charset), make_int (c1), make_int (c2));
2976 rc = list2 (XCHARSET_NAME (charset), make_int (c1));
2985 #ifdef ENABLE_COMPOSITE_CHARS
2986 /************************************************************************/
2987 /* composite character functions */
2988 /************************************************************************/
2991 lookup_composite_char (Bufbyte *str, int len)
2993 Lisp_Object lispstr = make_string (str, len);
2994 Lisp_Object ch = Fgethash (lispstr,
2995 Vcomposite_char_string2char_hash_table,
3001 if (composite_char_row_next >= 128)
3002 signal_simple_error ("No more composite chars available", lispstr);
3003 emch = MAKE_CHAR (Vcharset_composite, composite_char_row_next,
3004 composite_char_col_next);
3005 Fputhash (make_char (emch), lispstr,
3006 Vcomposite_char_char2string_hash_table);
3007 Fputhash (lispstr, make_char (emch),
3008 Vcomposite_char_string2char_hash_table);
3009 composite_char_col_next++;
3010 if (composite_char_col_next >= 128)
3012 composite_char_col_next = 32;
3013 composite_char_row_next++;
3022 composite_char_string (Emchar ch)
3024 Lisp_Object str = Fgethash (make_char (ch),
3025 Vcomposite_char_char2string_hash_table,
3027 assert (!UNBOUNDP (str));
3031 xxDEFUN ("make-composite-char", Fmake_composite_char, 1, 1, 0, /*
3032 Convert a string into a single composite character.
3033 The character is the result of overstriking all the characters in
3038 CHECK_STRING (string);
3039 return make_char (lookup_composite_char (XSTRING_DATA (string),
3040 XSTRING_LENGTH (string)));
3043 xxDEFUN ("composite-char-string", Fcomposite_char_string, 1, 1, 0, /*
3044 Return a string of the characters comprising a composite character.
3052 if (CHAR_LEADING_BYTE (emch) != LEADING_BYTE_COMPOSITE)
3053 signal_simple_error ("Must be composite char", ch);
3054 return composite_char_string (emch);
3056 #endif /* ENABLE_COMPOSITE_CHARS */
3059 /************************************************************************/
3060 /* initialization */
3061 /************************************************************************/
3064 syms_of_mule_charset (void)
3066 INIT_LRECORD_IMPLEMENTATION (charset);
3068 DEFSUBR (Fcharsetp);
3069 DEFSUBR (Ffind_charset);
3070 DEFSUBR (Fget_charset);
3071 DEFSUBR (Fcharset_list);
3072 DEFSUBR (Fcharset_name);
3073 DEFSUBR (Fmake_charset);
3074 DEFSUBR (Fmake_reverse_direction_charset);
3075 /* DEFSUBR (Freverse_direction_charset); */
3076 DEFSUBR (Fdefine_charset_alias);
3077 DEFSUBR (Fcharset_from_attributes);
3078 DEFSUBR (Fcharset_short_name);
3079 DEFSUBR (Fcharset_long_name);
3080 DEFSUBR (Fcharset_description);
3081 DEFSUBR (Fcharset_dimension);
3082 DEFSUBR (Fcharset_property);
3083 DEFSUBR (Fcharset_id);
3084 DEFSUBR (Fset_charset_ccl_program);
3085 DEFSUBR (Fset_charset_registry);
3088 DEFSUBR (Fcharset_mapping_table);
3089 DEFSUBR (Fset_charset_mapping_table);
3091 DEFSUBR (Fsave_charset_mapping_table);
3092 DEFSUBR (Freset_charset_mapping_table);
3093 #ifdef HAVE_LIBCHISE
3094 DEFSUBR (Fsave_charset_properties);
3095 #endif /* HAVE_LIBCHISE */
3096 #endif /* HAVE_CHISE */
3097 DEFSUBR (Fdecode_char);
3098 DEFSUBR (Fdecode_builtin_char);
3099 DEFSUBR (Fencode_char);
3102 DEFSUBR (Fmake_char);
3103 DEFSUBR (Fchar_charset);
3104 DEFSUBR (Fchar_octet);
3105 DEFSUBR (Fsplit_char);
3107 #ifdef ENABLE_COMPOSITE_CHARS
3108 DEFSUBR (Fmake_composite_char);
3109 DEFSUBR (Fcomposite_char_string);
3112 defsymbol (&Qcharsetp, "charsetp");
3113 defsymbol (&Qregistry, "registry");
3114 defsymbol (&Qfinal, "final");
3115 defsymbol (&Qgraphic, "graphic");
3116 defsymbol (&Qdirection, "direction");
3117 defsymbol (&Qreverse_direction_charset, "reverse-direction-charset");
3118 defsymbol (&Qshort_name, "short-name");
3119 defsymbol (&Qlong_name, "long-name");
3120 defsymbol (&Qiso_ir, "iso-ir");
3122 defsymbol (&Qto_iso_ir, "=>iso-ir");
3123 defsymbol (&Qpartial, "partial");
3124 defsymbol (&Qmother, "mother");
3125 defsymbol (&Qmin_code, "min-code");
3126 defsymbol (&Qmax_code, "max-code");
3127 defsymbol (&Qcode_offset, "code-offset");
3128 defsymbol (&Qconversion, "conversion");
3129 defsymbol (&Q94x60, "94x60");
3130 defsymbol (&Q94x94x60, "94x94x60");
3131 defsymbol (&Qbig5_1, "big5-1");
3132 defsymbol (&Qbig5_2, "big5-2");
3135 defsymbol (&Ql2r, "l2r");
3136 defsymbol (&Qr2l, "r2l");
3138 /* Charsets, compatible with FSF 20.3
3139 Naming convention is Script-Charset[-Edition] */
3140 defsymbol (&Qascii, "ascii");
3141 defsymbol (&Qcontrol_1, "control-1");
3142 defsymbol (&Qlatin_iso8859_1, "latin-iso8859-1");
3143 defsymbol (&Qlatin_iso8859_2, "latin-iso8859-2");
3144 defsymbol (&Qlatin_iso8859_3, "latin-iso8859-3");
3145 defsymbol (&Qlatin_iso8859_4, "latin-iso8859-4");
3146 defsymbol (&Qthai_tis620, "thai-tis620");
3147 defsymbol (&Qgreek_iso8859_7, "greek-iso8859-7");
3148 defsymbol (&Qarabic_iso8859_6, "arabic-iso8859-6");
3149 defsymbol (&Qhebrew_iso8859_8, "hebrew-iso8859-8");
3150 defsymbol (&Qkatakana_jisx0201, "katakana-jisx0201");
3151 defsymbol (&Qlatin_jisx0201, "latin-jisx0201");
3152 defsymbol (&Qcyrillic_iso8859_5, "cyrillic-iso8859-5");
3153 defsymbol (&Qlatin_iso8859_9, "latin-iso8859-9");
3154 /* defsymbol (&Qrep_jis_x0208_1978, "=jis-x0208@1978"); */
3155 defsymbol (&Qrep_gb2312, "=gb2312");
3156 defsymbol (&Qrep_gb12345, "=gb12345");
3157 defsymbol (&Qrep_jis_x0208_1983, "=jis-x0208@1983");
3158 defsymbol (&Qrep_ks_x1001, "=ks-x1001");
3159 defsymbol (&Qrep_jis_x0212, "=jis-x0212");
3160 defsymbol (&Qrep_cns11643_1, "=cns11643-1");
3161 defsymbol (&Qrep_cns11643_2, "=cns11643-2");
3163 defsymbol (&Qsystem_char_id, "system-char-id");
3164 defsymbol (&Qrep_ucs, "=ucs");
3165 defsymbol (&Qucs, "ucs");
3166 defsymbol (&Qucs_bmp, "ucs-bmp");
3167 defsymbol (&Qucs_smp, "ucs-smp");
3168 defsymbol (&Qucs_sip, "ucs-sip");
3169 defsymbol (&Qlatin_viscii, "latin-viscii");
3170 defsymbol (&Qlatin_tcvn5712, "latin-tcvn5712");
3171 defsymbol (&Qlatin_viscii_lower, "latin-viscii-lower");
3172 defsymbol (&Qlatin_viscii_upper, "latin-viscii-upper");
3173 defsymbol (&Qvietnamese_viscii_lower, "vietnamese-viscii-lower");
3174 defsymbol (&Qvietnamese_viscii_upper, "vietnamese-viscii-upper");
3175 defsymbol (&Qrep_jis_x0208, "=jis-x0208");
3176 defsymbol (&Qrep_jis_x0208_1990, "=jis-x0208@1990");
3177 defsymbol (&Qrep_big5, "=big5");
3178 defsymbol (&Qethiopic_ucs, "ethiopic-ucs");
3180 defsymbol (&Qchinese_big5_1, "chinese-big5-1");
3181 defsymbol (&Qchinese_big5_2, "chinese-big5-2");
3183 defsymbol (&Qcomposite, "composite");
3187 vars_of_mule_charset (void)
3194 chlook = xnew_and_zero (struct charset_lookup); /* zero for Purify. */
3195 dump_add_root_struct_ptr (&chlook, &charset_lookup_description);
3197 /* Table of charsets indexed by leading byte. */
3198 for (i = 0; i < countof (chlook->charset_by_leading_byte); i++)
3199 chlook->charset_by_leading_byte[i] = Qnil;
3202 /* Table of charsets indexed by type/final-byte. */
3203 for (i = 0; i < countof (chlook->charset_by_attributes); i++)
3204 for (j = 0; j < countof (chlook->charset_by_attributes[0]); j++)
3205 chlook->charset_by_attributes[i][j] = Qnil;
3207 /* Table of charsets indexed by type/final-byte/direction. */
3208 for (i = 0; i < countof (chlook->charset_by_attributes); i++)
3209 for (j = 0; j < countof (chlook->charset_by_attributes[0]); j++)
3210 for (k = 0; k < countof (chlook->charset_by_attributes[0][0]); k++)
3211 chlook->charset_by_attributes[i][j][k] = Qnil;
3215 chlook->next_allocated_leading_byte = MIN_LEADING_BYTE_PRIVATE;
3217 chlook->next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1;
3218 chlook->next_allocated_2_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_2;
3222 leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
3223 DEFVAR_INT ("leading-code-private-11", &leading_code_private_11 /*
3224 Leading-code of private TYPE9N charset of column-width 1.
3226 leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
3230 Vdefault_coded_charset_priority_list = Qnil;
3231 DEFVAR_LISP ("default-coded-charset-priority-list",
3232 &Vdefault_coded_charset_priority_list /*
3233 Default order of preferred coded-character-sets.
3235 Vdisplay_coded_charset_priority_use_inheritance = Qt;
3236 DEFVAR_LISP ("display-coded-charset-priority-use-inheritance",
3237 &Vdisplay_coded_charset_priority_use_inheritance /*
3238 If non-nil, use character inheritance.
3240 Vdisplay_coded_charset_priority_use_hierarchy_order = Qt;
3241 DEFVAR_LISP ("display-coded-charset-priority-use-hierarchy-order",
3242 &Vdisplay_coded_charset_priority_use_hierarchy_order /*
3243 If non-nil, prefer nearest character in hierarchy order.
3249 complex_vars_of_mule_charset (void)
3251 staticpro (&Vcharset_hash_table);
3252 Vcharset_hash_table =
3253 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3255 /* Predefined character sets. We store them into variables for
3259 staticpro (&Vcharset_system_char_id);
3260 Vcharset_system_char_id =
3261 make_charset (LEADING_BYTE_SYSTEM_CHAR_ID, Qsystem_char_id, 256, 4,
3262 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3263 build_string ("SCID"),
3264 build_string ("CHAR-ID"),
3265 build_string ("System char-id"),
3268 Qnil, 0, 0x7FFFFFFF, 0, 0, Qnil, CONVERSION_IDENTICAL,
3270 staticpro (&Vcharset_ucs);
3272 make_charset (LEADING_BYTE_UCS, Qrep_ucs, 256, 4,
3273 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3274 build_string ("UCS"),
3275 build_string ("UCS"),
3276 build_string ("ISO/IEC 10646"),
3279 Qnil, 0, 0xEFFFF, 0, 0, Qnil, CONVERSION_IDENTICAL,
3281 staticpro (&Vcharset_ucs_bmp);
3283 make_charset (LEADING_BYTE_UCS_BMP, Qucs_bmp, 256, 2,
3284 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3285 build_string ("BMP"),
3286 build_string ("UCS-BMP"),
3287 build_string ("ISO/IEC 10646 Group 0 Plane 0 (BMP)"),
3289 ("\\(ISO10646\\(\\.[0-9]+\\)?-[01]\\|UCS00-0\\|UNICODE[23]?-0\\)"),
3290 - LEADING_BYTE_UCS_BMP,
3291 Qnil, 0, 0xFFFF, 0, 0, Qnil, CONVERSION_IDENTICAL,
3293 staticpro (&Vcharset_ucs_smp);
3295 make_charset (LEADING_BYTE_UCS_SMP, Qucs_smp, 256, 2,
3296 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3297 build_string ("SMP"),
3298 build_string ("UCS-SMP"),
3299 build_string ("ISO/IEC 10646 Group 0 Plane 1 (SMP)"),
3300 build_string ("UCS00-1"),
3302 Qnil, MIN_CHAR_SMP, MAX_CHAR_SMP,
3303 MIN_CHAR_SMP, 0, Qnil, CONVERSION_IDENTICAL,
3305 staticpro (&Vcharset_ucs_sip);
3307 make_charset (LEADING_BYTE_UCS_SIP, Qucs_sip, 256, 2,
3308 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3309 build_string ("SIP"),
3310 build_string ("UCS-SIP"),
3311 build_string ("ISO/IEC 10646 Group 0 Plane 2 (SIP)"),
3312 build_string ("\\(ISO10646.*-2\\|UCS00-2\\)"),
3314 Qnil, MIN_CHAR_SIP, MAX_CHAR_SIP,
3315 MIN_CHAR_SIP, 0, Qnil, CONVERSION_IDENTICAL,
3318 # define MIN_CHAR_THAI 0
3319 # define MAX_CHAR_THAI 0
3320 /* # define MIN_CHAR_HEBREW 0 */
3321 /* # define MAX_CHAR_HEBREW 0 */
3322 # define MIN_CHAR_HALFWIDTH_KATAKANA 0
3323 # define MAX_CHAR_HALFWIDTH_KATAKANA 0
3325 staticpro (&Vcharset_ascii);
3327 make_charset (LEADING_BYTE_ASCII, Qascii, 94, 1,
3328 1, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3329 build_string ("ASCII"),
3330 build_string ("ASCII)"),
3331 build_string ("ASCII (ISO646 IRV)"),
3332 build_string ("\\(iso8859-[0-9]*\\|-ascii\\)"),
3333 - LEADING_BYTE_ASCII,
3334 Qnil, 0, 0x7F, 0, 0, Qnil, CONVERSION_IDENTICAL,
3336 staticpro (&Vcharset_control_1);
3337 Vcharset_control_1 =
3338 make_charset (LEADING_BYTE_CONTROL_1, Qcontrol_1, 94, 1,
3339 1, 1, 0, CHARSET_LEFT_TO_RIGHT,
3340 build_string ("C1"),
3341 build_string ("Control characters"),
3342 build_string ("Control characters 128-191"),
3344 - LEADING_BYTE_CONTROL_1,
3345 Qnil, 0x80, 0x9F, 0x80, 0, Qnil, CONVERSION_IDENTICAL,
3347 staticpro (&Vcharset_latin_iso8859_1);
3348 Vcharset_latin_iso8859_1 =
3349 make_charset (LEADING_BYTE_LATIN_ISO8859_1, Qlatin_iso8859_1, 96, 1,
3350 1, 1, 'A', CHARSET_LEFT_TO_RIGHT,
3351 build_string ("Latin-1"),
3352 build_string ("ISO8859-1 (Latin-1)"),
3353 build_string ("ISO8859-1 (Latin-1)"),
3354 build_string ("iso8859-1"),
3355 - LEADING_BYTE_LATIN_ISO8859_1,
3356 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3358 staticpro (&Vcharset_latin_iso8859_2);
3359 Vcharset_latin_iso8859_2 =
3360 make_charset (LEADING_BYTE_LATIN_ISO8859_2, Qlatin_iso8859_2, 96, 1,
3361 1, 1, 'B', CHARSET_LEFT_TO_RIGHT,
3362 build_string ("Latin-2"),
3363 build_string ("ISO8859-2 (Latin-2)"),
3364 build_string ("ISO8859-2 (Latin-2)"),
3365 build_string ("iso8859-2"),
3366 - LEADING_BYTE_LATIN_ISO8859_2,
3367 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3369 staticpro (&Vcharset_latin_iso8859_3);
3370 Vcharset_latin_iso8859_3 =
3371 make_charset (LEADING_BYTE_LATIN_ISO8859_3, Qlatin_iso8859_3, 96, 1,
3372 1, 1, 'C', CHARSET_LEFT_TO_RIGHT,
3373 build_string ("Latin-3"),
3374 build_string ("ISO8859-3 (Latin-3)"),
3375 build_string ("ISO8859-3 (Latin-3)"),
3376 build_string ("iso8859-3"),
3377 - LEADING_BYTE_LATIN_ISO8859_3,
3378 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3380 staticpro (&Vcharset_latin_iso8859_4);
3381 Vcharset_latin_iso8859_4 =
3382 make_charset (LEADING_BYTE_LATIN_ISO8859_4, Qlatin_iso8859_4, 96, 1,
3383 1, 1, 'D', CHARSET_LEFT_TO_RIGHT,
3384 build_string ("Latin-4"),
3385 build_string ("ISO8859-4 (Latin-4)"),
3386 build_string ("ISO8859-4 (Latin-4)"),
3387 build_string ("iso8859-4"),
3388 - LEADING_BYTE_LATIN_ISO8859_4,
3389 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3391 staticpro (&Vcharset_thai_tis620);
3392 Vcharset_thai_tis620 =
3393 make_charset (LEADING_BYTE_THAI_TIS620, Qthai_tis620, 96, 1,
3394 1, 1, 'T', CHARSET_LEFT_TO_RIGHT,
3395 build_string ("TIS620"),
3396 build_string ("TIS620 (Thai)"),
3397 build_string ("TIS620.2529 (Thai)"),
3398 build_string ("tis620"),
3399 - LEADING_BYTE_THAI_TIS620,
3400 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3402 staticpro (&Vcharset_greek_iso8859_7);
3403 Vcharset_greek_iso8859_7 =
3404 make_charset (LEADING_BYTE_GREEK_ISO8859_7, Qgreek_iso8859_7, 96, 1,
3405 1, 1, 'F', CHARSET_LEFT_TO_RIGHT,
3406 build_string ("ISO8859-7"),
3407 build_string ("ISO8859-7 (Greek)"),
3408 build_string ("ISO8859-7 (Greek)"),
3409 build_string ("iso8859-7"),
3410 - LEADING_BYTE_GREEK_ISO8859_7,
3411 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3413 staticpro (&Vcharset_arabic_iso8859_6);
3414 Vcharset_arabic_iso8859_6 =
3415 make_charset (LEADING_BYTE_ARABIC_ISO8859_6, Qarabic_iso8859_6, 96, 1,
3416 1, 1, 'G', CHARSET_RIGHT_TO_LEFT,
3417 build_string ("ISO8859-6"),
3418 build_string ("ISO8859-6 (Arabic)"),
3419 build_string ("ISO8859-6 (Arabic)"),
3420 build_string ("iso8859-6"),
3421 - LEADING_BYTE_ARABIC_ISO8859_6,
3422 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3424 staticpro (&Vcharset_hebrew_iso8859_8);
3425 Vcharset_hebrew_iso8859_8 =
3426 make_charset (LEADING_BYTE_HEBREW_ISO8859_8, Qhebrew_iso8859_8, 96, 1,
3427 1, 1, 'H', CHARSET_RIGHT_TO_LEFT,
3428 build_string ("ISO8859-8"),
3429 build_string ("ISO8859-8 (Hebrew)"),
3430 build_string ("ISO8859-8 (Hebrew)"),
3431 build_string ("iso8859-8"),
3432 - LEADING_BYTE_HEBREW_ISO8859_8,
3434 0 /* MIN_CHAR_HEBREW */,
3435 0 /* MAX_CHAR_HEBREW */, 0, 32,
3436 Qnil, CONVERSION_IDENTICAL,
3438 staticpro (&Vcharset_katakana_jisx0201);
3439 Vcharset_katakana_jisx0201 =
3440 make_charset (LEADING_BYTE_KATAKANA_JISX0201, Qkatakana_jisx0201, 94, 1,
3441 1, 1, 'I', CHARSET_LEFT_TO_RIGHT,
3442 build_string ("JISX0201 Kana"),
3443 build_string ("JISX0201.1976 (Japanese Kana)"),
3444 build_string ("JISX0201.1976 Japanese Kana"),
3445 build_string ("jisx0201\\.1976"),
3446 - LEADING_BYTE_KATAKANA_JISX0201,
3447 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3449 staticpro (&Vcharset_latin_jisx0201);
3450 Vcharset_latin_jisx0201 =
3451 make_charset (LEADING_BYTE_LATIN_JISX0201, Qlatin_jisx0201, 94, 1,
3452 1, 0, 'J', CHARSET_LEFT_TO_RIGHT,
3453 build_string ("JISX0201 Roman"),
3454 build_string ("JISX0201.1976 (Japanese Roman)"),
3455 build_string ("JISX0201.1976 Japanese Roman"),
3456 build_string ("jisx0201\\.1976"),
3457 - LEADING_BYTE_LATIN_JISX0201,
3458 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3460 staticpro (&Vcharset_cyrillic_iso8859_5);
3461 Vcharset_cyrillic_iso8859_5 =
3462 make_charset (LEADING_BYTE_CYRILLIC_ISO8859_5, Qcyrillic_iso8859_5, 96, 1,
3463 1, 1, 'L', CHARSET_LEFT_TO_RIGHT,
3464 build_string ("ISO8859-5"),
3465 build_string ("ISO8859-5 (Cyrillic)"),
3466 build_string ("ISO8859-5 (Cyrillic)"),
3467 build_string ("iso8859-5"),
3468 - LEADING_BYTE_CYRILLIC_ISO8859_5,
3469 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3471 staticpro (&Vcharset_latin_iso8859_9);
3472 Vcharset_latin_iso8859_9 =
3473 make_charset (LEADING_BYTE_LATIN_ISO8859_9, Qlatin_iso8859_9, 96, 1,
3474 1, 1, 'M', CHARSET_LEFT_TO_RIGHT,
3475 build_string ("Latin-5"),
3476 build_string ("ISO8859-9 (Latin-5)"),
3477 build_string ("ISO8859-9 (Latin-5)"),
3478 build_string ("iso8859-9"),
3479 - LEADING_BYTE_LATIN_ISO8859_9,
3480 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3483 staticpro (&Vcharset_jis_x0208);
3484 Vcharset_jis_x0208 =
3485 make_charset (LEADING_BYTE_JIS_X0208,
3486 Qrep_jis_x0208, 94, 2,
3487 2, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3488 build_string ("JIS X0208"),
3489 build_string ("JIS X0208 Common"),
3490 build_string ("JIS X0208 Common part"),
3491 build_string ("jisx0208\\.1990"),
3492 - LEADING_BYTE_JAPANESE_JISX0208_1978,
3494 MIN_CHAR_JIS_X0208_1990,
3495 MAX_CHAR_JIS_X0208_1990, MIN_CHAR_JIS_X0208_1990, 33,
3496 Qnil, CONVERSION_94x94,
3500 staticpro (&Vcharset_japanese_jisx0208_1978);
3501 Vcharset_japanese_jisx0208_1978 =
3502 make_charset (LEADING_BYTE_JAPANESE_JISX0208_1978,
3503 Qrep_jis_x0208_1978, 94, 2,
3504 2, 0, '@', CHARSET_LEFT_TO_RIGHT,
3505 build_string ("JIS X0208:1978"),
3506 build_string ("JIS X0208:1978 (Japanese)"),
3508 ("JIS X0208:1978 Japanese Kanji (so called \"old JIS\")"),
3509 build_string ("\\(jisx0208\\|jisc6226\\)\\.1978"),
3510 - LEADING_BYTE_JAPANESE_JISX0208_1978,
3517 CONVERSION_IDENTICAL,
3520 staticpro (&Vcharset_chinese_gb2312);
3521 Vcharset_chinese_gb2312 =
3522 make_charset (LEADING_BYTE_CHINESE_GB2312, Qrep_gb2312, 94, 2,
3523 2, 0, 'A', CHARSET_LEFT_TO_RIGHT,
3524 build_string ("GB2312"),
3525 build_string ("GB2312)"),
3526 build_string ("GB2312 Chinese simplified"),
3527 build_string ("gb2312"),
3528 - LEADING_BYTE_CHINESE_GB2312,
3529 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3531 staticpro (&Vcharset_chinese_gb12345);
3532 Vcharset_chinese_gb12345 =
3533 make_charset (LEADING_BYTE_CHINESE_GB12345, Qrep_gb12345, 94, 2,
3534 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3535 build_string ("G1"),
3536 build_string ("GB 12345)"),
3537 build_string ("GB 12345-1990"),
3538 build_string ("GB12345\\(\\.1990\\)?-0"),
3540 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3542 staticpro (&Vcharset_japanese_jisx0208);
3543 Vcharset_japanese_jisx0208 =
3544 make_charset (LEADING_BYTE_JAPANESE_JISX0208, Qrep_jis_x0208_1983, 94, 2,
3545 2, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3546 build_string ("JISX0208"),
3547 build_string ("JIS X0208:1983 (Japanese)"),
3548 build_string ("JIS X0208:1983 Japanese Kanji"),
3549 build_string ("jisx0208\\.1983"),
3550 - LEADING_BYTE_JAPANESE_JISX0208,
3557 CONVERSION_IDENTICAL,
3560 staticpro (&Vcharset_japanese_jisx0208_1990);
3561 Vcharset_japanese_jisx0208_1990 =
3562 make_charset (LEADING_BYTE_JAPANESE_JISX0208_1990,
3563 Qrep_jis_x0208_1990, 94, 2,
3564 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3565 build_string ("JISX0208-1990"),
3566 build_string ("JIS X0208:1990 (Japanese)"),
3567 build_string ("JIS X0208:1990 Japanese Kanji"),
3568 build_string ("jisx0208\\.1990"),
3569 - LEADING_BYTE_JAPANESE_JISX0208_1990,
3571 0x2121 /* MIN_CHAR_JIS_X0208_1990 */,
3572 0x7426 /* MAX_CHAR_JIS_X0208_1990 */,
3573 0 /* MIN_CHAR_JIS_X0208_1990 */, 33,
3574 Vcharset_jis_x0208 /* Qnil */,
3575 CONVERSION_IDENTICAL /* CONVERSION_94x94 */,
3578 staticpro (&Vcharset_korean_ksc5601);
3579 Vcharset_korean_ksc5601 =
3580 make_charset (LEADING_BYTE_KOREAN_KSC5601, Qrep_ks_x1001, 94, 2,
3581 2, 0, 'C', CHARSET_LEFT_TO_RIGHT,
3582 build_string ("KSC5601"),
3583 build_string ("KSC5601 (Korean"),
3584 build_string ("KSC5601 Korean Hangul and Hanja"),
3585 build_string ("ksc5601"),
3586 - LEADING_BYTE_KOREAN_KSC5601,
3587 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3589 staticpro (&Vcharset_japanese_jisx0212);
3590 Vcharset_japanese_jisx0212 =
3591 make_charset (LEADING_BYTE_JAPANESE_JISX0212, Qrep_jis_x0212, 94, 2,
3592 2, 0, 'D', CHARSET_LEFT_TO_RIGHT,
3593 build_string ("JISX0212"),
3594 build_string ("JISX0212 (Japanese)"),
3595 build_string ("JISX0212 Japanese Supplement"),
3596 build_string ("jisx0212"),
3597 - LEADING_BYTE_JAPANESE_JISX0212,
3598 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3601 #define CHINESE_CNS_PLANE_RE(n) "cns11643[.-]\\(.*[.-]\\)?" n "$"
3602 staticpro (&Vcharset_chinese_cns11643_1);
3603 Vcharset_chinese_cns11643_1 =
3604 make_charset (LEADING_BYTE_CHINESE_CNS11643_1, Qrep_cns11643_1, 94, 2,
3605 2, 0, 'G', CHARSET_LEFT_TO_RIGHT,
3606 build_string ("CNS11643-1"),
3607 build_string ("CNS11643-1 (Chinese traditional)"),
3609 ("CNS 11643 Plane 1 Chinese traditional"),
3610 build_string (CHINESE_CNS_PLANE_RE("1")),
3611 - LEADING_BYTE_CHINESE_CNS11643_1,
3612 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3614 staticpro (&Vcharset_chinese_cns11643_2);
3615 Vcharset_chinese_cns11643_2 =
3616 make_charset (LEADING_BYTE_CHINESE_CNS11643_2, Qrep_cns11643_2, 94, 2,
3617 2, 0, 'H', CHARSET_LEFT_TO_RIGHT,
3618 build_string ("CNS11643-2"),
3619 build_string ("CNS11643-2 (Chinese traditional)"),
3621 ("CNS 11643 Plane 2 Chinese traditional"),
3622 build_string (CHINESE_CNS_PLANE_RE("2")),
3623 - LEADING_BYTE_CHINESE_CNS11643_2,
3624 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3627 staticpro (&Vcharset_latin_tcvn5712);
3628 Vcharset_latin_tcvn5712 =
3629 make_charset (LEADING_BYTE_LATIN_TCVN5712, Qlatin_tcvn5712, 96, 1,
3630 1, 1, 'Z', CHARSET_LEFT_TO_RIGHT,
3631 build_string ("TCVN 5712"),
3632 build_string ("TCVN 5712 (VSCII-2)"),
3633 build_string ("Vietnamese TCVN 5712:1983 (VSCII-2)"),
3634 build_string ("tcvn5712\\(\\.1993\\)?-1"),
3635 - LEADING_BYTE_LATIN_TCVN5712,
3636 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3638 staticpro (&Vcharset_latin_viscii_lower);
3639 Vcharset_latin_viscii_lower =
3640 make_charset (LEADING_BYTE_LATIN_VISCII_LOWER, Qlatin_viscii_lower, 96, 1,
3641 1, 1, '1', CHARSET_LEFT_TO_RIGHT,
3642 build_string ("VISCII lower"),
3643 build_string ("VISCII lower (Vietnamese)"),
3644 build_string ("VISCII lower (Vietnamese)"),
3645 build_string ("MULEVISCII-LOWER"),
3647 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3649 staticpro (&Vcharset_latin_viscii_upper);
3650 Vcharset_latin_viscii_upper =
3651 make_charset (LEADING_BYTE_LATIN_VISCII_UPPER, Qlatin_viscii_upper, 96, 1,
3652 1, 1, '2', CHARSET_LEFT_TO_RIGHT,
3653 build_string ("VISCII upper"),
3654 build_string ("VISCII upper (Vietnamese)"),
3655 build_string ("VISCII upper (Vietnamese)"),
3656 build_string ("MULEVISCII-UPPER"),
3658 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3660 staticpro (&Vcharset_latin_viscii);
3661 Vcharset_latin_viscii =
3662 make_charset (LEADING_BYTE_LATIN_VISCII, Qlatin_viscii, 256, 1,
3663 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3664 build_string ("VISCII"),
3665 build_string ("VISCII 1.1 (Vietnamese)"),
3666 build_string ("VISCII 1.1 (Vietnamese)"),
3667 build_string ("VISCII1\\.1"),
3669 Qnil, 0, 0, 0, 0, Qnil, CONVERSION_IDENTICAL,
3671 staticpro (&Vcharset_chinese_big5);
3672 Vcharset_chinese_big5 =
3673 make_charset (LEADING_BYTE_CHINESE_BIG5, Qrep_big5, 256, 2,
3674 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3675 build_string ("Big5"),
3676 build_string ("Big5"),
3677 build_string ("Big5 Chinese traditional"),
3678 build_string ("big5-0"),
3681 MIN_CHAR_BIG5_CDP, MAX_CHAR_BIG5_CDP,
3682 MIN_CHAR_BIG5_CDP, 0, Qnil, CONVERSION_IDENTICAL,
3685 staticpro (&Vcharset_ethiopic_ucs);
3686 Vcharset_ethiopic_ucs =
3687 make_charset (LEADING_BYTE_ETHIOPIC_UCS, Qethiopic_ucs, 256, 2,
3688 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3689 build_string ("Ethiopic (UCS)"),
3690 build_string ("Ethiopic (UCS)"),
3691 build_string ("Ethiopic of UCS"),
3692 build_string ("Ethiopic-Unicode"),
3694 Qnil, 0x1200, 0x137F, 0, 0,
3695 Qnil, CONVERSION_IDENTICAL,
3698 staticpro (&Vcharset_chinese_big5_1);
3699 Vcharset_chinese_big5_1 =
3700 make_charset (LEADING_BYTE_CHINESE_BIG5_1, Qchinese_big5_1, 94, 2,
3701 2, 0, '0', CHARSET_LEFT_TO_RIGHT,
3702 build_string ("Big5"),
3703 build_string ("Big5 (Level-1)"),
3705 ("Big5 Level-1 Chinese traditional"),
3706 build_string ("big5"),
3708 Qnil, 0, 0, 0, 33, /* Qnil, CONVERSION_IDENTICAL */
3709 Vcharset_chinese_big5, CONVERSION_BIG5_1,
3711 staticpro (&Vcharset_chinese_big5_2);
3712 Vcharset_chinese_big5_2 =
3713 make_charset (LEADING_BYTE_CHINESE_BIG5_2, Qchinese_big5_2, 94, 2,
3714 2, 0, '1', CHARSET_LEFT_TO_RIGHT,
3715 build_string ("Big5"),
3716 build_string ("Big5 (Level-2)"),
3718 ("Big5 Level-2 Chinese traditional"),
3719 build_string ("big5"),
3721 Qnil, 0, 0, 0, 33, /* Qnil, CONVERSION_IDENTICAL */
3722 Vcharset_chinese_big5, CONVERSION_BIG5_2,
3725 #ifdef ENABLE_COMPOSITE_CHARS
3726 /* #### For simplicity, we put composite chars into a 96x96 charset.
3727 This is going to lead to problems because you can run out of
3728 room, esp. as we don't yet recycle numbers. */
3729 staticpro (&Vcharset_composite);
3730 Vcharset_composite =
3731 make_charset (LEADING_BYTE_COMPOSITE, Qcomposite, 96, 2,
3732 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3733 build_string ("Composite"),
3734 build_string ("Composite characters"),
3735 build_string ("Composite characters"),
3738 /* #### not dumped properly */
3739 composite_char_row_next = 32;
3740 composite_char_col_next = 32;
3742 Vcomposite_char_string2char_hash_table =
3743 make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
3744 Vcomposite_char_char2string_hash_table =
3745 make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3746 staticpro (&Vcomposite_char_string2char_hash_table);
3747 staticpro (&Vcomposite_char_char2string_hash_table);
3748 #endif /* ENABLE_COMPOSITE_CHARS */