}
+Lisp_Object Vcharacter_attribute_table;
+
+DEFUN ("char-attribute-alist", Fchar_attribute_alist, 1, 1, 0, /*
+Return the alist of attributes of CHARACTER.
+*/
+ (character))
+{
+ return get_char_code_table (XCHAR (character), Vcharacter_attribute_table);
+}
+
+DEFUN ("get-char-attribute", Fget_char_attribute, 2, 2, 0, /*
+Return the value of CHARACTER's ATTRIBUTE.
+*/
+ (character, attribute))
+{
+ Lisp_Object ret
+ = get_char_code_table (XCHAR (character), Vcharacter_attribute_table);
+ Lisp_Object ccs;
+
+ if (EQ (ret, Qnil))
+ return Qnil;
+
+ if (!NILP (ccs = Ffind_charset (attribute)))
+ attribute = ccs;
+
+ return Fcdr (Fassq (attribute, ret));
+}
+
+Lisp_Object
+put_char_attribute (Lisp_Object character, Lisp_Object attribute,
+ Lisp_Object value)
+{
+ Emchar char_code = XCHAR (character);
+ Lisp_Object ret
+ = get_char_code_table (char_code, Vcharacter_attribute_table);
+ Lisp_Object cell;
+
+ cell = Fassq (attribute, ret);
+
+ if (NILP (cell))
+ {
+ ret = Fcons (Fcons (attribute, value), ret);
+ }
+ else if (!EQ (Fcdr (cell), value))
+ {
+ Fsetcdr (cell, value);
+ }
+ put_char_code_table (char_code, ret, Vcharacter_attribute_table);
+ return ret;
+}
+
+DEFUN ("put-char-attribute", Fput_char_attribute, 3, 3, 0, /*
+Store CHARACTER's ATTRIBUTE with VALUE.
+*/
+ (character, attribute, value))
+{
+ Lisp_Object ccs;
+
+ ccs = Ffind_charset (attribute);
+ if (!NILP (ccs))
+ {
+ Lisp_Object rest;
+ Lisp_Object v = XCHARSET_DECODING_TABLE (ccs);
+ Lisp_Object nv;
+ int i = -1;
+ int ccs_len;
+
+ /* ad-hoc method for `ascii' */
+ if ((XCHARSET_CHARS (ccs) == 94) &&
+ (XCHARSET_BYTE_OFFSET (ccs) != 33))
+ ccs_len = 128 - XCHARSET_BYTE_OFFSET (ccs);
+ else
+ ccs_len = XCHARSET_CHARS (ccs);
+
+ if (!CONSP (value))
+ signal_simple_error ("Invalid value for coded-charset",
+ value);
+
+ attribute = ccs;
+ rest = Fget_char_attribute (character, attribute);
+ if (VECTORP (v))
+ {
+ if (!NILP (rest))
+ {
+ while (!NILP (rest))
+ {
+ Lisp_Object ei = Fcar (rest);
+
+ i = XINT (ei) - XCHARSET_BYTE_OFFSET (ccs);
+ nv = XVECTOR_DATA(v)[i];
+ if (!VECTORP (nv))
+ break;
+ v = nv;
+ rest = Fcdr (rest);
+ }
+ if (i >= 0)
+ XVECTOR_DATA(v)[i] = Qnil;
+ v = XCHARSET_DECODING_TABLE (ccs);
+ }
+ }
+ else
+ {
+ XCHARSET_DECODING_TABLE (ccs) = v = make_vector (ccs_len, Qnil);
+ }
+
+ rest = value;
+ i = -1;
+ while (CONSP (rest))
+ {
+ Lisp_Object ei = Fcar (rest);
+
+ if (!INTP (ei))
+ signal_simple_error ("Invalid value for coded-charset",
+ value);
+ i = XINT (ei) - XCHARSET_BYTE_OFFSET (ccs);
+ nv = XVECTOR_DATA(v)[i];
+ rest = Fcdr (rest);
+ if (CONSP (rest))
+ {
+ if (!VECTORP (nv))
+ {
+ nv = (XVECTOR_DATA(v)[i] = make_vector (ccs_len, Qnil));
+ }
+ v = nv;
+ }
+ else
+ break;
+ }
+ XVECTOR_DATA(v)[i] = character;
+ }
+ return put_char_attribute (character, attribute, value);
+}
+
+Lisp_Object Qucs;
+
+DEFUN ("define-char", Fdefine_char, 1, 1, 0, /*
+Store character's ATTRIBUTES.
+*/
+ (attributes))
+{
+ Lisp_Object rest = attributes;
+ Lisp_Object code = Fcdr (Fassq (Qucs, attributes));
+ Lisp_Object character;
+
+ if (NILP (code))
+ {
+ while (CONSP (rest))
+ {
+ Lisp_Object cell = Fcar (rest);
+ Lisp_Object ccs;
+
+ if (!LISTP (cell))
+ signal_simple_error ("Invalid argument", attributes);
+ if (!NILP (ccs = Ffind_charset (Fcar (cell)))
+ && XCHARSET_FINAL (ccs))
+ {
+ Emchar code;
+
+ if (XCHARSET_DIMENSION (ccs) == 1)
+ {
+ Lisp_Object eb1 = Fcar (Fcdr (cell));
+ int b1;
+
+ if (!INTP (eb1))
+ signal_simple_error ("Invalid argument", attributes);
+ b1 = XINT (eb1);
+ switch (XCHARSET_CHARS (ccs))
+ {
+ case 94:
+ code = MIN_CHAR_94
+ + (XCHARSET_FINAL (ccs) - '0') * 94 + (b1 - 33);
+ break;
+ case 96:
+ code = MIN_CHAR_96
+ + (XCHARSET_FINAL (ccs) - '0') * 96 + (b1 - 32);
+ break;
+ default:
+ abort ();
+ }
+ }
+ else if (XCHARSET_DIMENSION (ccs) == 2)
+ {
+ Lisp_Object eb1 = Fcar (Fcdr (cell));
+ Lisp_Object eb2 = Fcar (Fcdr (Fcdr (cell)));
+ int b1, b2;
+
+ if (!INTP (eb1))
+ signal_simple_error ("Invalid argument", attributes);
+ b1 = XINT (eb1);
+ if (!INTP (eb2))
+ signal_simple_error ("Invalid argument", attributes);
+ b2 = XINT (eb2);
+ switch (XCHARSET_CHARS (ccs))
+ {
+ case 94:
+ code = MIN_CHAR_94x94
+ + (XCHARSET_FINAL (ccs) - '0') * 94 * 94
+ + (b1 - 33) * 94 + (b2 - 33);
+ break;
+ case 96:
+ code = MIN_CHAR_96x96
+ + (XCHARSET_FINAL (ccs) - '0') * 96 * 96
+ + (b1 - 32) * 96 + (b2 - 32);
+ break;
+ default:
+ abort ();
+ }
+ }
+ else
+ {
+ rest = Fcdr (rest);
+ continue;
+ }
+ character = make_char (code);
+ goto setup_attributes;
+ }
+ rest = Fcdr (rest);
+ }
+ return Qnil;
+ }
+ else if (!INTP (code))
+ signal_simple_error ("Invalid argument", attributes);
+ else
+ character = make_char (XINT (code));
+
+ setup_attributes:
+ rest = attributes;
+ while (CONSP (rest))
+ {
+ Lisp_Object cell = Fcar (rest);
+
+ if (!LISTP (cell))
+ signal_simple_error ("Invalid argument", attributes);
+ Fput_char_attribute (character, Fcar (cell), Fcdr (cell));
+ rest = Fcdr (rest);
+ }
+ return
+ get_char_code_table (XCHAR (character), Vcharacter_attribute_table);
+}
+
Lisp_Object Vutf_2000_version;
#endif
Lisp_Object Vcharset_hash_table;
+#ifdef UTF2000
+static Charset_ID next_allocated_leading_byte;
+#else
static Charset_ID next_allocated_1_byte_leading_byte;
static Charset_ID next_allocated_2_byte_leading_byte;
+#endif
/* Composite characters are characters constructed by overstriking two
or more regular characters.
markobj (cs->ccl_program);
#ifdef UTF2000
markobj (cs->decoding_table);
- markobj (cs->encoding_table);
#endif
return cs->name;
}
CHARSET_REVERSE_DIRECTION_CHARSET (cs) = Qnil;
#ifdef UTF2000
CHARSET_DECODING_TABLE(cs) = Qnil;
- CHARSET_ENCODING_TABLE(cs) = Qnil;
CHARSET_UCS_MIN(cs) = ucs_min;
CHARSET_UCS_MAX(cs) = ucs_max;
CHARSET_CODE_OFFSET(cs) = code_offset;
{
Charset_ID lb;
+#ifdef UTF2000
+ if (next_allocated_leading_byte > MAX_LEADING_BYTE_PRIVATE)
+ lb = 0;
+ else
+ lb = next_allocated_leading_byte++;
+#else
if (dimension == 1)
{
if (next_allocated_1_byte_leading_byte > MAX_LEADING_BYTE_PRIVATE_1)
else
lb = next_allocated_2_byte_leading_byte++;
}
+#endif
if (!lb)
signal_simple_error
}
#ifdef UTF2000
-unsigned char
-charset_get_byte1 (Lisp_Object charset, Emchar ch)
+Lisp_Object
+range_charset_code_point (Lisp_Object charset, Emchar ch)
{
- Lisp_Object table;
int d;
- if (!EQ (table = XCHARSET_ENCODING_TABLE (charset), Qnil))
- {
- Lisp_Object value = get_char_code_table (ch, table);
-
- if (INTP (value))
- {
- Emchar code = XINT (value);
-
- if (code < (1 << 8))
- return code;
- else if (code < (1 << 16))
- return code >> 8;
- else if (code < (1 << 24))
- return code >> 16;
- else
- return code >> 24;
- }
- }
if ((XCHARSET_UCS_MIN (charset) <= ch)
&& (ch <= XCHARSET_UCS_MAX (charset)))
- return (ch - XCHARSET_UCS_MIN (charset)
- + XCHARSET_CODE_OFFSET (charset))
- / (XCHARSET_DIMENSION (charset) == 1 ?
- 1
- :
- XCHARSET_DIMENSION (charset) == 2 ?
- XCHARSET_CHARS (charset)
- :
- XCHARSET_DIMENSION (charset) == 3 ?
- XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset)
- :
- XCHARSET_CHARS (charset)
- * XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset))
- + XCHARSET_BYTE_OFFSET (charset);
+ {
+ d = ch - XCHARSET_UCS_MIN (charset) + XCHARSET_CODE_OFFSET (charset);
+
+ if (XCHARSET_DIMENSION (charset) == 1)
+ return list1 (make_int (d + XCHARSET_BYTE_OFFSET (charset)));
+ else if (XCHARSET_DIMENSION (charset) == 2)
+ return list2 (make_int (d / XCHARSET_CHARS (charset)
+ + XCHARSET_BYTE_OFFSET (charset)),
+ make_int (d % XCHARSET_CHARS (charset)
+ + XCHARSET_BYTE_OFFSET (charset)));
+ else if (XCHARSET_DIMENSION (charset) == 3)
+ return list3 (make_int (d / (XCHARSET_CHARS (charset)
+ * XCHARSET_CHARS (charset))
+ + XCHARSET_BYTE_OFFSET (charset)),
+ make_int (d / XCHARSET_CHARS (charset)
+ % XCHARSET_CHARS (charset)
+ + XCHARSET_BYTE_OFFSET (charset)),
+ make_int (d % XCHARSET_CHARS (charset)
+ + XCHARSET_BYTE_OFFSET (charset)));
+ else /* if (XCHARSET_DIMENSION (charset) == 4) */
+ return list4 (make_int (d / (XCHARSET_CHARS (charset)
+ * XCHARSET_CHARS (charset)
+ * XCHARSET_CHARS (charset))
+ + XCHARSET_BYTE_OFFSET (charset)),
+ make_int (d / (XCHARSET_CHARS (charset)
+ * XCHARSET_CHARS (charset))
+ % XCHARSET_CHARS (charset)
+ + XCHARSET_BYTE_OFFSET (charset)),
+ make_int (d / XCHARSET_CHARS (charset)
+ % XCHARSET_CHARS (charset)
+ + XCHARSET_BYTE_OFFSET (charset)),
+ make_int (d % XCHARSET_CHARS (charset)
+ + XCHARSET_BYTE_OFFSET (charset)));
+ }
else if (XCHARSET_CODE_OFFSET (charset) == 0)
{
if (XCHARSET_DIMENSION (charset) == 1)
if (((d = ch - (MIN_CHAR_94
+ (XCHARSET_FINAL (charset) - '0') * 94)) >= 0)
&& (d < 94))
- return d + 33;
+ return list1 (make_int (d + 33));
}
else if (XCHARSET_CHARS (charset) == 96)
{
if (((d = ch - (MIN_CHAR_96
+ (XCHARSET_FINAL (charset) - '0') * 96)) >= 0)
&& (d < 96))
- return d + 32;
+ return list1 (make_int (d + 32));
}
else
- return 0;
+ return Qnil;
}
else if (XCHARSET_DIMENSION (charset) == 2)
{
+ (XCHARSET_FINAL (charset) - '0') * 94 * 94))
>= 0)
&& (d < 94 * 94))
- return (d / 94) + 33;
+ return list2 ((d / 94) + 33, d % 94 + 33);
}
else if (XCHARSET_CHARS (charset) == 96)
{
+ (XCHARSET_FINAL (charset) - '0') * 96 * 96))
>= 0)
&& (d < 96 * 96))
- return (d / 96) + 32;
+ return list2 ((d / 96) + 32, d % 96 + 32);
}
}
}
- return 0;
+ return Qnil;
}
-unsigned char
-charset_get_byte2 (Lisp_Object charset, Emchar ch)
+Lisp_Object
+charset_code_point (Lisp_Object charset, Emchar ch)
{
- if (XCHARSET_DIMENSION (charset) == 1)
- return 0;
- else
- {
- Lisp_Object table;
+ Lisp_Object cdef = get_char_code_table (ch, Vcharacter_attribute_table);
- if (!EQ (table = XCHARSET_ENCODING_TABLE (charset), Qnil))
- {
- Lisp_Object value = get_char_code_table (ch, table);
-
- if (INTP (value))
- {
- Emchar code = XINT (value);
+ if (!EQ (cdef, Qnil))
+ {
+ Lisp_Object field = Fassq (charset, cdef);
- if (code < (1 << 16))
- return (unsigned char)code;
- else if (code < (1 << 24))
- return (unsigned char)(code >> 16);
- else
- return (unsigned char)(code >> 24);
- }
- }
- if ((XCHARSET_UCS_MIN (charset) <= ch)
- && (ch <= XCHARSET_UCS_MAX (charset)))
- return ((ch - XCHARSET_UCS_MIN (charset)
- + XCHARSET_CODE_OFFSET (charset))
- / (XCHARSET_DIMENSION (charset) == 2 ?
- 1
- :
- XCHARSET_DIMENSION (charset) == 3 ?
- XCHARSET_CHARS (charset)
- :
- XCHARSET_CHARS (charset) * XCHARSET_CHARS (charset)))
- % XCHARSET_CHARS (charset)
- + XCHARSET_BYTE_OFFSET (charset);
- else if (XCHARSET_CHARS (charset) == 94)
- return (MIN_CHAR_94x94
- + (XCHARSET_FINAL (charset) - '0') * 94 * 94 <= ch)
- && (ch < MIN_CHAR_94x94
- + (XCHARSET_FINAL (charset) - '0' + 1) * 94 * 94) ?
- ((ch - MIN_CHAR_94x94) % 94) + 33 : 0;
- else /* if (XCHARSET_CHARS (charset) == 96) */
- return (MIN_CHAR_96x96
- + (XCHARSET_FINAL (charset) - '0') * 96 * 96 <= ch)
- && (ch < MIN_CHAR_96x96
- + (XCHARSET_FINAL (charset) - '0' + 1) * 96 * 96) ?
- ((ch - MIN_CHAR_96x96) % 96) + 32 : 0;
+ if (!EQ (field, Qnil))
+ return Fcdr (field);
}
+ return range_charset_code_point (charset, ch);
}
Lisp_Object Vdefault_coded_charset_priority_list;
Lisp_Object rest, keyword, value;
Lisp_Object ccl_program = Qnil;
Lisp_Object short_name = Qnil, long_name = Qnil;
-#ifdef UTF2000
unsigned char byte_offset = 0;
-#endif
CHECK_SYMBOL (name);
if (!NILP (doc_string))
error
("Character set already defined for this DIMENSION/CHARS/FINAL combo");
-#ifdef UTF2000
- if (dimension == 1)
- {
- if (chars == 94)
- {
- /* id = CHARSET_ID_OFFSET_94 + final; */
- id = get_unallocated_leading_byte (dimension);
- }
- else if (chars == 96)
- {
- id = get_unallocated_leading_byte (dimension);
- }
- else
- {
- abort ();
- }
- }
- else if (dimension == 2)
- {
- if (chars == 94)
- {
- id = get_unallocated_leading_byte (dimension);
- }
- else if (chars == 96)
- {
- id = get_unallocated_leading_byte (dimension);
- }
- else
- {
- abort ();
- }
- }
- else
- {
- abort ();
- }
- if (final)
- {
- if (chars == 94)
- byte_offset = 33;
- else if (chars == 96)
- byte_offset = 32;
- }
-#else
id = get_unallocated_leading_byte (dimension);
-#endif
if (NILP (doc_string))
doc_string = build_string ("");
if (EQ (table, Qnil))
{
CHARSET_DECODING_TABLE(cs) = table;
- CHARSET_ENCODING_TABLE(cs) = Qnil;
return table;
}
else if (VECTORP (table))
{
if (XVECTOR_LENGTH (table) > CHARSET_CHARS (cs))
args_out_of_range (table, make_int (CHARSET_CHARS (cs)));
- old_table = CHARSET_ENCODING_TABLE(cs);
+ old_table = CHARSET_DECODING_TABLE(cs);
CHARSET_DECODING_TABLE(cs) = table;
}
else
switch (CHARSET_DIMENSION (cs))
{
case 1:
- CHARSET_ENCODING_TABLE(cs) = make_char_code_table (Qnil);
for (i = 0; i < XVECTOR_LENGTH (table); i++)
{
Lisp_Object c = XVECTOR_DATA(table)[i];
if (CHARP (c))
- put_char_code_table (XCHAR (c),
- make_int (i + CHARSET_BYTE_OFFSET (cs)),
- CHARSET_ENCODING_TABLE(cs));
+ put_char_attribute
+ (c, charset,
+ list1 (make_int (i + CHARSET_BYTE_OFFSET (cs))));
}
break;
case 2:
- CHARSET_ENCODING_TABLE(cs) = make_char_code_table (Qnil);
for (i = 0; i < XVECTOR_LENGTH (table); i++)
{
Lisp_Object v = XVECTOR_DATA(table)[i];
Lisp_Object c = XVECTOR_DATA(v)[j];
if (CHARP (c))
- put_char_code_table
- (XCHAR (c),
- make_int (( (i + CHARSET_BYTE_OFFSET (cs)) << 8)
- | (j + CHARSET_BYTE_OFFSET (cs))),
- CHARSET_ENCODING_TABLE(cs));
+ put_char_attribute (c, charset,
+ list2
+ (make_int
+ (i + CHARSET_BYTE_OFFSET (cs)),
+ make_int
+ (j + CHARSET_BYTE_OFFSET (cs))));
}
}
else if (CHARP (v))
- put_char_code_table (XCHAR (v),
- make_int (i + CHARSET_BYTE_OFFSET (cs)),
- CHARSET_ENCODING_TABLE(cs));
+ put_char_attribute (v, charset,
+ list1
+ (make_int (i + CHARSET_BYTE_OFFSET (cs))));
}
break;
}
DEFSUBR (Fset_charset_ccl_program);
DEFSUBR (Fset_charset_registry);
#ifdef UTF2000
+ DEFSUBR (Fchar_attribute_alist);
+ DEFSUBR (Fget_char_attribute);
+ DEFSUBR (Fput_char_attribute);
+ DEFSUBR (Fdefine_char);
DEFSUBR (Fcharset_mapping_table);
DEFSUBR (Fset_charset_mapping_table);
#endif
defsymbol (&Qchinese_cns11643_1, "chinese-cns11643-1");
defsymbol (&Qchinese_cns11643_2, "chinese-cns11643-2");
#ifdef UTF2000
+ defsymbol (&Qucs, "ucs");
defsymbol (&Qucs_bmp, "ucs-bmp");
defsymbol (&Qlatin_viscii, "latin-viscii");
defsymbol (&Qlatin_viscii_lower, "latin-viscii-lower");
charset_by_attributes[i][j][k] = Qnil;
#endif
- next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1;
#ifdef UTF2000
- next_allocated_2_byte_leading_byte = LEADING_BYTE_CHINESE_BIG5_2 + 1;
+ next_allocated_leading_byte = MIN_LEADING_BYTE_PRIVATE;
#else
+ next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1;
next_allocated_2_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_2;
#endif
#endif
#ifdef UTF2000
- Vutf_2000_version = build_string("0.8 (Kami)");
+ Vutf_2000_version = build_string("0.11 (Shiki)");
DEFVAR_LISP ("utf-2000-version", &Vutf_2000_version /*
Version number of UTF-2000.
*/ );
+ staticpro (&Vcharacter_attribute_table);
+ Vcharacter_attribute_table = make_char_code_table (Qnil);
+
Vdefault_coded_charset_priority_list = Qnil;
DEFVAR_LISP ("default-coded-charset-priority-list",
&Vdefault_coded_charset_priority_list /*
-Default order of preferred coded-character-set.
+Default order of preferred coded-character-sets.
*/ );
#endif
}