88363
|
1 /* Basic character support.
|
|
2 Copyright (C) 1995, 1997, 1998, 2001 Electrotechnical Laboratory, JAPAN.
|
89483
|
3 Licensed to the Free Software Foundation.
|
91443
|
4 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
|
5 Free Software Foundation, Inc.
|
|
6 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
|
88363
|
7 National Institute of Advanced Industrial Science and Technology (AIST)
|
|
8 Registration Number H13PRO009
|
|
9
|
|
10 This file is part of GNU Emacs.
|
|
11
|
|
12 GNU Emacs is free software; you can redistribute it and/or modify
|
|
13 it under the terms of the GNU General Public License as published by
|
91443
|
14 the Free Software Foundation; either version 3, or (at your option)
|
88363
|
15 any later version.
|
|
16
|
|
17 GNU Emacs is distributed in the hope that it will be useful,
|
|
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20 GNU General Public License for more details.
|
|
21
|
|
22 You should have received a copy of the GNU General Public License
|
91443
|
23 along with GNU Emacs; see the file COPYING. If not, write to the
|
|
24 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
25 Boston, MA 02110-1301, USA. */
|
88363
|
26
|
|
27 /* At first, see the document in `character.h' to understand the code
|
|
28 in this file. */
|
|
29
|
|
30 #ifdef emacs
|
|
31 #include <config.h>
|
|
32 #endif
|
|
33
|
|
34 #include <stdio.h>
|
|
35
|
|
36 #ifdef emacs
|
|
37
|
|
38 #include <sys/types.h>
|
|
39 #include "lisp.h"
|
|
40 #include "character.h"
|
|
41 #include "buffer.h"
|
|
42 #include "charset.h"
|
|
43 #include "composite.h"
|
|
44 #include "disptab.h"
|
|
45
|
|
46 #else /* not emacs */
|
|
47
|
|
48 #include "mulelib.h"
|
|
49
|
|
50 #endif /* emacs */
|
|
51
|
|
52 Lisp_Object Qcharacterp;
|
|
53
|
|
54 /* Vector of translation table ever defined.
|
|
55 ID of a translation table is used to index this vector. */
|
|
56 Lisp_Object Vtranslation_table_vector;
|
|
57
|
|
58 /* A char-table for characters which may invoke auto-filling. */
|
|
59 Lisp_Object Vauto_fill_chars;
|
|
60
|
|
61 Lisp_Object Qauto_fill_chars;
|
|
62
|
89888
|
63 /* Char-table of information about which character to unify to which
|
|
64 Unicode character. */
|
88363
|
65 Lisp_Object Vchar_unify_table;
|
|
66
|
|
67 /* A char-table. An element is non-nil iff the corresponding
|
|
68 character has a printable glyph. */
|
|
69 Lisp_Object Vprintable_chars;
|
|
70
|
|
71 /* A char-table. An elemnent is a column-width of the corresponding
|
|
72 character. */
|
|
73 Lisp_Object Vchar_width_table;
|
|
74
|
|
75 /* A char-table. An element is a symbol indicating the direction
|
|
76 property of corresponding character. */
|
|
77 Lisp_Object Vchar_direction_table;
|
|
78
|
89020
|
79 /* Variable used locally in the macro FETCH_MULTIBYTE_CHAR. */
|
88363
|
80 unsigned char *_fetch_multibyte_char_p;
|
|
81
|
88913
|
82 /* Char table of scripts. */
|
|
83 Lisp_Object Vchar_script_table;
|
|
84
|
90403
|
85 /* Alist of scripts vs representative characters. */
|
|
86 Lisp_Object Vscript_representative_chars;
|
|
87
|
88913
|
88 static Lisp_Object Qchar_script_table;
|
|
89
|
89054
|
90 /* Mapping table from unibyte chars to multibyte chars. */
|
|
91 int unibyte_to_multibyte_table[256];
|
88878
|
92
|
90020
|
93 /* Nth element is 1 iff unibyte char N can be mapped to a multibyte
|
|
94 char. */
|
|
95 char unibyte_has_multibyte_table[256];
|
|
96
|
88363
|
97
|
|
98
|
92483
|
99 /* If character code C has modifier masks, reflect them to the
|
|
100 character code if possible. Return the resulting code. */
|
|
101
|
|
102 int
|
|
103 char_resolve_modifier_mask (c)
|
|
104 int c;
|
|
105 {
|
92494
|
106 /* A non-ASCII character can't reflect modifier bits to the code. */
|
92483
|
107 if (! ASCII_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
|
|
108 return c;
|
|
109
|
|
110 /* For Meta, Shift, and Control modifiers, we need special care. */
|
|
111 if (c & CHAR_SHIFT)
|
|
112 {
|
|
113 /* Shift modifier is valid only with [A-Za-z]. */
|
|
114 if ((c & 0377) >= 'A' && (c & 0377) <= 'Z')
|
|
115 c &= ~CHAR_SHIFT;
|
|
116 else if ((c & 0377) >= 'a' && (c & 0377) <= 'z')
|
|
117 c = (c & ~CHAR_SHIFT) - ('a' - 'A');
|
92499
|
118 /* Shift modifier for control characters and SPC is ignored. */
|
|
119 else if ((c & ~CHAR_MODIFIER_MASK) <= 0x20)
|
92494
|
120 c &= ~CHAR_SHIFT;
|
|
121 }
|
92483
|
122 if (c & CHAR_CTL)
|
|
123 {
|
|
124 /* Simulate the code in lread.c. */
|
|
125 /* Allow `\C- ' and `\C-?'. */
|
92499
|
126 if ((c & 0377) == ' ')
|
|
127 c &= ~0177 & ~ CHAR_CTL;
|
|
128 else if ((c & 0377) == '?')
|
|
129 c = 0177 | (c & ~0177 & ~CHAR_CTL);
|
92483
|
130 /* ASCII control chars are made from letters (both cases),
|
|
131 as well as the non-letters within 0100...0137. */
|
|
132 else if ((c & 0137) >= 0101 && (c & 0137) <= 0132)
|
|
133 c &= (037 | (~0177 & ~CHAR_CTL));
|
|
134 else if ((c & 0177) >= 0100 && (c & 0177) <= 0137)
|
|
135 c &= (037 | (~0177 & ~CHAR_CTL));
|
|
136 }
|
92499
|
137 if (c & CHAR_META)
|
|
138 {
|
|
139 /* Move the meta bit to the right place for a string. */
|
|
140 c = (c & ~CHAR_META) | 0x80;
|
|
141 }
|
92483
|
142
|
|
143 return c;
|
|
144 }
|
|
145
|
|
146
|
89888
|
147 /* Store multibyte form of character C at P. If C has modifier bits,
|
|
148 handle them appropriately. */
|
|
149
|
88363
|
150 int
|
89181
|
151 char_string (c, p)
|
90797
|
152 unsigned c;
|
88427
|
153 unsigned char *p;
|
88363
|
154 {
|
|
155 int bytes;
|
|
156
|
89181
|
157 if (c & CHAR_MODIFIER_MASK)
|
|
158 {
|
92483
|
159 c = (unsigned) char_resolve_modifier_mask ((int) c);
|
89181
|
160 /* If C still has any modifier bits, just ignore it. */
|
|
161 c &= ~CHAR_MODIFIER_MASK;
|
|
162 }
|
|
163
|
88363
|
164 MAYBE_UNIFY_CHAR (c);
|
|
165
|
89181
|
166 if (c <= MAX_3_BYTE_CHAR)
|
88363
|
167 {
|
|
168 bytes = CHAR_STRING (c, p);
|
|
169 }
|
|
170 else if (c <= MAX_4_BYTE_CHAR)
|
|
171 {
|
|
172 p[0] = (0xF0 | (c >> 18));
|
|
173 p[1] = (0x80 | ((c >> 12) & 0x3F));
|
|
174 p[2] = (0x80 | ((c >> 6) & 0x3F));
|
|
175 p[3] = (0x80 | (c & 0x3F));
|
|
176 bytes = 4;
|
|
177 }
|
89181
|
178 else if (c <= MAX_5_BYTE_CHAR)
|
88363
|
179 {
|
|
180 p[0] = 0xF8;
|
|
181 p[1] = (0x80 | ((c >> 18) & 0x0F));
|
|
182 p[2] = (0x80 | ((c >> 12) & 0x3F));
|
|
183 p[3] = (0x80 | ((c >> 6) & 0x3F));
|
|
184 p[4] = (0x80 | (c & 0x3F));
|
|
185 bytes = 5;
|
|
186 }
|
90797
|
187 else if (c <= MAX_CHAR)
|
89181
|
188 {
|
|
189 c = CHAR_TO_BYTE8 (c);
|
|
190 bytes = BYTE8_STRING (c, p);
|
|
191 }
|
90797
|
192 else
|
|
193 error ("Invalid character: %d", c);
|
88427
|
194
|
88363
|
195 return bytes;
|
|
196 }
|
|
197
|
|
198
|
89888
|
199 /* Return a character whose multibyte form is at P. Set LEN is not
|
|
200 NULL, it must be a pointer to integer. In that case, set *LEN to
|
|
201 the byte length of the multibyte form. If ADVANCED is not NULL, is
|
|
202 must be a pointer to unsigned char. In that case, set *ADVANCED to
|
|
203 the ending address (i.e. the starting address of the next
|
|
204 character) of the multibyte form. */
|
|
205
|
88363
|
206 int
|
89181
|
207 string_char (p, advanced, len)
|
88878
|
208 const unsigned char *p;
|
|
209 const unsigned char **advanced;
|
88363
|
210 int *len;
|
|
211 {
|
88427
|
212 int c;
|
88878
|
213 const unsigned char *saved_p = p;
|
88363
|
214
|
|
215 if (*p < 0x80 || ! (*p & 0x20) || ! (*p & 0x10))
|
|
216 {
|
|
217 c = STRING_CHAR_ADVANCE (p);
|
|
218 }
|
|
219 else if (! (*p & 0x08))
|
|
220 {
|
|
221 c = ((((p)[0] & 0xF) << 18)
|
|
222 | (((p)[1] & 0x3F) << 12)
|
|
223 | (((p)[2] & 0x3F) << 6)
|
|
224 | ((p)[3] & 0x3F));
|
|
225 p += 4;
|
|
226 }
|
|
227 else
|
|
228 {
|
|
229 c = ((((p)[1] & 0x3F) << 18)
|
|
230 | (((p)[2] & 0x3F) << 12)
|
|
231 | (((p)[3] & 0x3F) << 6)
|
|
232 | ((p)[4] & 0x3F));
|
|
233 p += 5;
|
|
234 }
|
|
235
|
|
236 MAYBE_UNIFY_CHAR (c);
|
|
237
|
|
238 if (len)
|
|
239 *len = p - saved_p;
|
|
240 if (advanced)
|
|
241 *advanced = p;
|
|
242 return c;
|
|
243 }
|
|
244
|
|
245
|
|
246 /* Translate character C by translation table TABLE. If C is
|
|
247 negative, translate a character specified by CHARSET and CODE. If
|
|
248 no translation is found in TABLE, return the untranslated
|
89757
|
249 character. If TABLE is a list, elements are char tables. In this
|
|
250 case, translace C by all tables. */
|
88363
|
251
|
|
252 int
|
|
253 translate_char (table, c)
|
|
254 Lisp_Object table;
|
|
255 int c;
|
|
256 {
|
89757
|
257 if (CHAR_TABLE_P (table))
|
|
258 {
|
|
259 Lisp_Object ch;
|
88363
|
260
|
89757
|
261 ch = CHAR_TABLE_REF (table, c);
|
|
262 if (CHARACTERP (ch))
|
|
263 c = XINT (ch);
|
|
264 }
|
|
265 else
|
|
266 {
|
|
267 for (; CONSP (table); table = XCDR (table))
|
|
268 c = translate_char (XCAR (table), c);
|
|
269 }
|
|
270 return c;
|
88363
|
271 }
|
|
272
|
|
273 /* Convert the multibyte character C to unibyte 8-bit character based
|
88983
|
274 on the current value of charset_unibyte. If dimension of
|
|
275 charset_unibyte is more than one, return (C & 0xFF).
|
88363
|
276
|
|
277 The argument REV_TBL is now ignored. It will be removed in the
|
|
278 future. */
|
|
279
|
|
280 int
|
|
281 multibyte_char_to_unibyte (c, rev_tbl)
|
|
282 int c;
|
|
283 Lisp_Object rev_tbl;
|
|
284 {
|
89054
|
285 struct charset *charset;
|
|
286 unsigned c1;
|
88363
|
287
|
89054
|
288 if (CHAR_BYTE8_P (c))
|
|
289 return CHAR_TO_BYTE8 (c);
|
|
290 charset = CHARSET_FROM_ID (charset_unibyte);
|
|
291 c1 = ENCODE_CHAR (charset, c);
|
88363
|
292 return ((c1 != CHARSET_INVALID_CODE (charset)) ? c1 : c & 0xFF);
|
|
293 }
|
|
294
|
90761
|
295 /* Like multibyte_char_to_unibyte, but return -1 if C is not supported
|
|
296 by charset_unibyte. */
|
|
297
|
|
298 int
|
|
299 multibyte_char_to_unibyte_safe (c)
|
|
300 int c;
|
|
301 {
|
|
302 struct charset *charset;
|
|
303 unsigned c1;
|
|
304
|
|
305 if (CHAR_BYTE8_P (c))
|
|
306 return CHAR_TO_BYTE8 (c);
|
|
307 charset = CHARSET_FROM_ID (charset_unibyte);
|
|
308 c1 = ENCODE_CHAR (charset, c);
|
|
309 return ((c1 != CHARSET_INVALID_CODE (charset)) ? c1 : -1);
|
|
310 }
|
88363
|
311
|
|
312 DEFUN ("characterp", Fcharacterp, Scharacterp, 1, 2, 0,
|
|
313 doc: /* Return non-nil if OBJECT is a character. */)
|
|
314 (object, ignore)
|
|
315 Lisp_Object object, ignore;
|
|
316 {
|
|
317 return (CHARACTERP (object) ? Qt : Qnil);
|
|
318 }
|
|
319
|
|
320 DEFUN ("max-char", Fmax_char, Smax_char, 0, 0, 0,
|
|
321 doc: /* Return the character of the maximum code. */)
|
|
322 ()
|
|
323 {
|
|
324 return make_number (MAX_CHAR);
|
|
325 }
|
|
326
|
|
327 DEFUN ("unibyte-char-to-multibyte", Funibyte_char_to_multibyte,
|
|
328 Sunibyte_char_to_multibyte, 1, 1, 0,
|
94146
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
329 doc: /* Convert the byte CH to multibyte character. */)
|
88363
|
330 (ch)
|
|
331 Lisp_Object ch;
|
|
332 {
|
|
333 int c;
|
|
334 struct charset *charset;
|
|
335
|
|
336 CHECK_CHARACTER (ch);
|
|
337 c = XFASTINT (ch);
|
|
338 if (c >= 0400)
|
|
339 error ("Invalid unibyte character: %d", c);
|
88983
|
340 charset = CHARSET_FROM_ID (charset_unibyte);
|
88363
|
341 c = DECODE_CHAR (charset, c);
|
|
342 if (c < 0)
|
88947
|
343 c = BYTE8_TO_CHAR (XFASTINT (ch));
|
88363
|
344 return make_number (c);
|
|
345 }
|
|
346
|
|
347 DEFUN ("multibyte-char-to-unibyte", Fmultibyte_char_to_unibyte,
|
|
348 Smultibyte_char_to_unibyte, 1, 1, 0,
|
94146
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
349 doc: /* Convert the multibyte character CH to a byte.
|
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
350 If the multibyte character does not represent a byte, return -1. */)
|
88363
|
351 (ch)
|
|
352 Lisp_Object ch;
|
|
353 {
|
94146
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
354 int cm;
|
88363
|
355
|
|
356 CHECK_CHARACTER (ch);
|
94146
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
357 cm = XFASTINT (ch);
|
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
358 if (cm < 256)
|
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
359 /* Can't distinguish a byte read from a unibyte buffer from
|
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
360 a latin1 char, so let's let it slide. */
|
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
361 return ch;
|
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
362 else
|
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
363 {
|
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
364 int cu = CHAR_TO_BYTE8 (cm);
|
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
365 return make_number (cu);
|
096ad76b9ccf
(Fmultibyte_char_to_unibyte): Return latin1 chars unchanged.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
366 }
|
88363
|
367 }
|
|
368
|
|
369 DEFUN ("char-bytes", Fchar_bytes, Schar_bytes, 1, 1, 0,
|
|
370 doc: /* Return 1 regardless of the argument CHAR.
|
94114
327f7207ff7e
(Fchar_bytes, Fchar_width, Fstring_width, Fchar_direction):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
371 This is now an obsolete function. We keep it just for backward compatibility.
|
327f7207ff7e
(Fchar_bytes, Fchar_width, Fstring_width, Fchar_direction):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
372 usage: (char-bytes CHAR) */)
|
88363
|
373 (ch)
|
|
374 Lisp_Object ch;
|
|
375 {
|
|
376 CHECK_CHARACTER (ch);
|
|
377 return make_number (1);
|
|
378 }
|
|
379
|
|
380 DEFUN ("char-width", Fchar_width, Schar_width, 1, 1, 0,
|
|
381 doc: /* Return width of CHAR when displayed in the current buffer.
|
|
382 The width is measured by how many columns it occupies on the screen.
|
94114
327f7207ff7e
(Fchar_bytes, Fchar_width, Fstring_width, Fchar_direction):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
383 Tab is taken to occupy `tab-width' columns.
|
327f7207ff7e
(Fchar_bytes, Fchar_width, Fstring_width, Fchar_direction):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
384 usage: (char-width CHAR) */)
|
88363
|
385 (ch)
|
|
386 Lisp_Object ch;
|
|
387 {
|
|
388 Lisp_Object disp;
|
|
389 int c, width;
|
|
390 struct Lisp_Char_Table *dp = buffer_display_table ();
|
|
391
|
|
392 CHECK_CHARACTER (ch);
|
|
393 c = XINT (ch);
|
|
394
|
|
395 /* Get the way the display table would display it. */
|
|
396 disp = dp ? DISP_CHAR_VECTOR (dp, c) : Qnil;
|
|
397
|
|
398 if (VECTORP (disp))
|
|
399 width = ASIZE (disp);
|
|
400 else
|
|
401 width = CHAR_WIDTH (c);
|
|
402
|
|
403 return make_number (width);
|
|
404 }
|
|
405
|
|
406 /* Return width of string STR of length LEN when displayed in the
|
|
407 current buffer. The width is measured by how many columns it
|
|
408 occupies on the screen. If PRECISION > 0, return the width of
|
|
409 longest substring that doesn't exceed PRECISION, and set number of
|
|
410 characters and bytes of the substring in *NCHARS and *NBYTES
|
|
411 respectively. */
|
|
412
|
88427
|
413 int
|
88363
|
414 c_string_width (str, len, precision, nchars, nbytes)
|
89483
|
415 const unsigned char *str;
|
88363
|
416 int precision, *nchars, *nbytes;
|
|
417 {
|
|
418 int i = 0, i_byte = 0;
|
|
419 int width = 0;
|
|
420 struct Lisp_Char_Table *dp = buffer_display_table ();
|
|
421
|
|
422 while (i_byte < len)
|
|
423 {
|
|
424 int bytes, thiswidth;
|
|
425 Lisp_Object val;
|
|
426 int c = STRING_CHAR_AND_LENGTH (str + i_byte, len - i_byte, bytes);
|
|
427
|
|
428 if (dp)
|
|
429 {
|
|
430 val = DISP_CHAR_VECTOR (dp, c);
|
|
431 if (VECTORP (val))
|
|
432 thiswidth = XVECTOR (val)->size;
|
|
433 else
|
|
434 thiswidth = CHAR_WIDTH (c);
|
|
435 }
|
|
436 else
|
|
437 {
|
|
438 thiswidth = CHAR_WIDTH (c);
|
|
439 }
|
|
440
|
|
441 if (precision > 0
|
|
442 && (width + thiswidth > precision))
|
|
443 {
|
|
444 *nchars = i;
|
|
445 *nbytes = i_byte;
|
|
446 return width;
|
|
447 }
|
|
448 i++;
|
|
449 i_byte += bytes;
|
|
450 width += thiswidth;
|
|
451 }
|
|
452
|
|
453 if (precision > 0)
|
|
454 {
|
|
455 *nchars = i;
|
|
456 *nbytes = i_byte;
|
|
457 }
|
|
458
|
|
459 return width;
|
|
460 }
|
|
461
|
88427
|
462 /* Return width of string STR of length LEN when displayed in the
|
|
463 current buffer. The width is measured by how many columns it
|
|
464 occupies on the screen. */
|
|
465
|
|
466 int
|
|
467 strwidth (str, len)
|
|
468 unsigned char *str;
|
|
469 int len;
|
|
470 {
|
|
471 return c_string_width (str, len, -1, NULL, NULL);
|
|
472 }
|
|
473
|
88363
|
474 /* Return width of Lisp string STRING when displayed in the current
|
|
475 buffer. The width is measured by how many columns it occupies on
|
|
476 the screen while paying attention to compositions. If PRECISION >
|
|
477 0, return the width of longest substring that doesn't exceed
|
|
478 PRECISION, and set number of characters and bytes of the substring
|
|
479 in *NCHARS and *NBYTES respectively. */
|
|
480
|
|
481 int
|
|
482 lisp_string_width (string, precision, nchars, nbytes)
|
|
483 Lisp_Object string;
|
|
484 int precision, *nchars, *nbytes;
|
|
485 {
|
89483
|
486 int len = SCHARS (string);
|
90256
|
487 /* This set multibyte to 0 even if STRING is multibyte when it
|
|
488 contains only ascii and eight-bit-graphic, but that's
|
|
489 intentional. */
|
|
490 int multibyte = len < SBYTES (string);
|
89483
|
491 unsigned char *str = SDATA (string);
|
88363
|
492 int i = 0, i_byte = 0;
|
|
493 int width = 0;
|
|
494 struct Lisp_Char_Table *dp = buffer_display_table ();
|
|
495
|
|
496 while (i < len)
|
|
497 {
|
|
498 int chars, bytes, thiswidth;
|
|
499 Lisp_Object val;
|
|
500 int cmp_id;
|
89511
|
501 EMACS_INT ignore, end;
|
88363
|
502
|
|
503 if (find_composition (i, -1, &ignore, &end, &val, string)
|
|
504 && ((cmp_id = get_composition_id (i, i_byte, end - i, val, string))
|
|
505 >= 0))
|
|
506 {
|
|
507 thiswidth = composition_table[cmp_id]->width;
|
|
508 chars = end - i;
|
|
509 bytes = string_char_to_byte (string, end) - i_byte;
|
|
510 }
|
|
511 else
|
|
512 {
|
90256
|
513 int c;
|
88363
|
514
|
90256
|
515 if (multibyte)
|
|
516 c = STRING_CHAR_AND_LENGTH (str + i_byte, len - i_byte, bytes);
|
|
517 else
|
|
518 c = str[i_byte], bytes = 1;
|
88363
|
519 chars = 1;
|
90256
|
520 if (dp)
|
|
521 {
|
|
522 val = DISP_CHAR_VECTOR (dp, c);
|
|
523 if (VECTORP (val))
|
|
524 thiswidth = XVECTOR (val)->size;
|
|
525 else
|
|
526 thiswidth = CHAR_WIDTH (c);
|
|
527 }
|
|
528 else
|
|
529 {
|
|
530 thiswidth = CHAR_WIDTH (c);
|
|
531 }
|
88363
|
532 }
|
|
533
|
|
534 if (precision > 0
|
|
535 && (width + thiswidth > precision))
|
|
536 {
|
|
537 *nchars = i;
|
|
538 *nbytes = i_byte;
|
|
539 return width;
|
|
540 }
|
|
541 i += chars;
|
|
542 i_byte += bytes;
|
|
543 width += thiswidth;
|
|
544 }
|
|
545
|
|
546 if (precision > 0)
|
|
547 {
|
|
548 *nchars = i;
|
|
549 *nbytes = i_byte;
|
|
550 }
|
|
551
|
|
552 return width;
|
|
553 }
|
|
554
|
|
555 DEFUN ("string-width", Fstring_width, Sstring_width, 1, 1, 0,
|
|
556 doc: /* Return width of STRING when displayed in the current buffer.
|
|
557 Width is measured by how many columns it occupies on the screen.
|
|
558 When calculating width of a multibyte character in STRING,
|
|
559 only the base leading-code is considered; the validity of
|
|
560 the following bytes is not checked. Tabs in STRING are always
|
94114
327f7207ff7e
(Fchar_bytes, Fchar_width, Fstring_width, Fchar_direction):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
561 taken to occupy `tab-width' columns.
|
327f7207ff7e
(Fchar_bytes, Fchar_width, Fstring_width, Fchar_direction):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
562 usage: (string-width STRING) */)
|
88363
|
563 (str)
|
|
564 Lisp_Object str;
|
|
565 {
|
|
566 Lisp_Object val;
|
|
567
|
|
568 CHECK_STRING (str);
|
|
569 XSETFASTINT (val, lisp_string_width (str, -1, NULL, NULL));
|
|
570 return val;
|
|
571 }
|
|
572
|
|
573 DEFUN ("char-direction", Fchar_direction, Schar_direction, 1, 1, 0,
|
|
574 doc: /* Return the direction of CHAR.
|
94114
327f7207ff7e
(Fchar_bytes, Fchar_width, Fstring_width, Fchar_direction):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
575 The returned value is 0 for left-to-right and 1 for right-to-left.
|
327f7207ff7e
(Fchar_bytes, Fchar_width, Fstring_width, Fchar_direction):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
576 usage: (char-direction CHAR) */)
|
88363
|
577 (ch)
|
|
578 Lisp_Object ch;
|
|
579 {
|
|
580 int c;
|
|
581
|
|
582 CHECK_CHARACTER (ch);
|
|
583 c = XINT (ch);
|
|
584 return CHAR_TABLE_REF (Vchar_direction_table, c);
|
|
585 }
|
|
586
|
|
587 /* Return the number of characters in the NBYTES bytes at PTR.
|
|
588 This works by looking at the contents and checking for multibyte
|
|
589 sequences while assuming that there's no invalid sequence.
|
|
590 However, if the current buffer has enable-multibyte-characters =
|
|
591 nil, we treat each byte as a character. */
|
|
592
|
91807
507bcfb4342c
* coding.c (coding_set_destination): Use BEG_BYTE rather than hardcoding 1.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
593 EMACS_INT
|
88363
|
594 chars_in_text (ptr, nbytes)
|
89483
|
595 const unsigned char *ptr;
|
91807
507bcfb4342c
* coding.c (coding_set_destination): Use BEG_BYTE rather than hardcoding 1.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
596 EMACS_INT nbytes;
|
88363
|
597 {
|
|
598 /* current_buffer is null at early stages of Emacs initialization. */
|
|
599 if (current_buffer == 0
|
|
600 || NILP (current_buffer->enable_multibyte_characters))
|
|
601 return nbytes;
|
|
602
|
|
603 return multibyte_chars_in_text (ptr, nbytes);
|
|
604 }
|
|
605
|
|
606 /* Return the number of characters in the NBYTES bytes at PTR.
|
|
607 This works by looking at the contents and checking for multibyte
|
|
608 sequences while assuming that there's no invalid sequence. It
|
|
609 ignores enable-multibyte-characters. */
|
|
610
|
91807
507bcfb4342c
* coding.c (coding_set_destination): Use BEG_BYTE rather than hardcoding 1.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
611 EMACS_INT
|
88363
|
612 multibyte_chars_in_text (ptr, nbytes)
|
89483
|
613 const unsigned char *ptr;
|
91807
507bcfb4342c
* coding.c (coding_set_destination): Use BEG_BYTE rather than hardcoding 1.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
614 EMACS_INT nbytes;
|
88363
|
615 {
|
89483
|
616 const unsigned char *endp = ptr + nbytes;
|
88363
|
617 int chars = 0;
|
|
618
|
|
619 while (ptr < endp)
|
|
620 {
|
|
621 int len = MULTIBYTE_LENGTH (ptr, endp);
|
|
622
|
|
623 if (len == 0)
|
|
624 abort ();
|
|
625 ptr += len;
|
|
626 chars++;
|
|
627 }
|
|
628
|
|
629 return chars;
|
|
630 }
|
|
631
|
|
632 /* Parse unibyte text at STR of LEN bytes as a multibyte text, count
|
|
633 characters and bytes in it, and store them in *NCHARS and *NBYTES
|
|
634 respectively. On counting bytes, pay attention to that 8-bit
|
|
635 characters not constructing a valid multibyte sequence are
|
|
636 represented by 2-byte in a multibyte text. */
|
|
637
|
|
638 void
|
|
639 parse_str_as_multibyte (str, len, nchars, nbytes)
|
89483
|
640 const unsigned char *str;
|
88363
|
641 int len, *nchars, *nbytes;
|
|
642 {
|
89483
|
643 const unsigned char *endp = str + len;
|
88363
|
644 int n, chars = 0, bytes = 0;
|
|
645
|
|
646 if (len >= MAX_MULTIBYTE_LENGTH)
|
|
647 {
|
89483
|
648 const unsigned char *adjusted_endp = endp - MAX_MULTIBYTE_LENGTH;
|
88363
|
649 while (str < adjusted_endp)
|
|
650 {
|
|
651 if ((n = MULTIBYTE_LENGTH_NO_CHECK (str)) > 0)
|
|
652 str += n, bytes += n;
|
|
653 else
|
|
654 str++, bytes += 2;
|
|
655 chars++;
|
|
656 }
|
|
657 }
|
|
658 while (str < endp)
|
|
659 {
|
|
660 if ((n = MULTIBYTE_LENGTH (str, endp)) > 0)
|
|
661 str += n, bytes += n;
|
|
662 else
|
|
663 str++, bytes += 2;
|
|
664 chars++;
|
|
665 }
|
|
666
|
|
667 *nchars = chars;
|
|
668 *nbytes = bytes;
|
|
669 return;
|
|
670 }
|
|
671
|
|
672 /* Arrange unibyte text at STR of NBYTES bytes as a multibyte text.
|
|
673 It actually converts only such 8-bit characters that don't contruct
|
|
674 a multibyte sequence to multibyte forms of Latin-1 characters. If
|
|
675 NCHARS is nonzero, set *NCHARS to the number of characters in the
|
|
676 text. It is assured that we can use LEN bytes at STR as a work
|
|
677 area and that is enough. Return the number of bytes of the
|
|
678 resulting text. */
|
|
679
|
|
680 int
|
|
681 str_as_multibyte (str, len, nbytes, nchars)
|
|
682 unsigned char *str;
|
|
683 int len, nbytes, *nchars;
|
|
684 {
|
|
685 unsigned char *p = str, *endp = str + nbytes;
|
|
686 unsigned char *to;
|
|
687 int chars = 0;
|
|
688 int n;
|
|
689
|
|
690 if (nbytes >= MAX_MULTIBYTE_LENGTH)
|
|
691 {
|
|
692 unsigned char *adjusted_endp = endp - MAX_MULTIBYTE_LENGTH;
|
|
693 while (p < adjusted_endp
|
|
694 && (n = MULTIBYTE_LENGTH_NO_CHECK (p)) > 0)
|
|
695 p += n, chars++;
|
|
696 }
|
|
697 while ((n = MULTIBYTE_LENGTH (p, endp)) > 0)
|
|
698 p += n, chars++;
|
|
699 if (nchars)
|
|
700 *nchars = chars;
|
|
701 if (p == endp)
|
|
702 return nbytes;
|
|
703
|
|
704 to = p;
|
|
705 nbytes = endp - p;
|
|
706 endp = str + len;
|
|
707 safe_bcopy ((char *) p, (char *) (endp - nbytes), nbytes);
|
|
708 p = endp - nbytes;
|
|
709
|
|
710 if (nbytes >= MAX_MULTIBYTE_LENGTH)
|
|
711 {
|
|
712 unsigned char *adjusted_endp = endp - MAX_MULTIBYTE_LENGTH;
|
|
713 while (p < adjusted_endp)
|
|
714 {
|
|
715 if ((n = MULTIBYTE_LENGTH_NO_CHECK (p)) > 0)
|
|
716 {
|
|
717 while (n--)
|
|
718 *to++ = *p++;
|
|
719 }
|
|
720 else
|
|
721 {
|
|
722 int c = *p++;
|
|
723 c = BYTE8_TO_CHAR (c);
|
|
724 to += CHAR_STRING (c, to);
|
|
725 }
|
|
726 }
|
|
727 chars++;
|
|
728 }
|
|
729 while (p < endp)
|
|
730 {
|
|
731 if ((n = MULTIBYTE_LENGTH (p, endp)) > 0)
|
|
732 {
|
|
733 while (n--)
|
|
734 *to++ = *p++;
|
89483
|
735 }
|
88363
|
736 else
|
|
737 {
|
|
738 int c = *p++;
|
|
739 c = BYTE8_TO_CHAR (c);
|
|
740 to += CHAR_STRING (c, to);
|
|
741 }
|
|
742 chars++;
|
|
743 }
|
|
744 if (nchars)
|
|
745 *nchars = chars;
|
|
746 return (to - str);
|
|
747 }
|
|
748
|
|
749 /* Parse unibyte string at STR of LEN bytes, and return the number of
|
|
750 bytes it may ocupy when converted to multibyte string by
|
|
751 `str_to_multibyte'. */
|
|
752
|
|
753 int
|
|
754 parse_str_to_multibyte (str, len)
|
|
755 unsigned char *str;
|
|
756 int len;
|
|
757 {
|
|
758 unsigned char *endp = str + len;
|
|
759 int bytes;
|
|
760
|
|
761 for (bytes = 0; str < endp; str++)
|
|
762 bytes += (*str < 0x80) ? 1 : 2;
|
|
763 return bytes;
|
|
764 }
|
|
765
|
|
766
|
|
767 /* Convert unibyte text at STR of NBYTES bytes to a multibyte text
|
|
768 that contains the same single-byte characters. It actually
|
|
769 converts all 8-bit characters to multibyte forms. It is assured
|
|
770 that we can use LEN bytes at STR as a work area and that is
|
|
771 enough. */
|
|
772
|
|
773 int
|
|
774 str_to_multibyte (str, len, bytes)
|
|
775 unsigned char *str;
|
|
776 int len, bytes;
|
|
777 {
|
|
778 unsigned char *p = str, *endp = str + bytes;
|
|
779 unsigned char *to;
|
|
780
|
|
781 while (p < endp && *p < 0x80) p++;
|
|
782 if (p == endp)
|
|
783 return bytes;
|
|
784 to = p;
|
|
785 bytes = endp - p;
|
|
786 endp = str + len;
|
|
787 safe_bcopy ((char *) p, (char *) (endp - bytes), bytes);
|
|
788 p = endp - bytes;
|
89483
|
789 while (p < endp)
|
88363
|
790 {
|
|
791 int c = *p++;
|
|
792
|
|
793 if (c >= 0x80)
|
|
794 c = BYTE8_TO_CHAR (c);
|
|
795 to += CHAR_STRING (c, to);
|
|
796 }
|
|
797 return (to - str);
|
|
798 }
|
|
799
|
|
800 /* Arrange multibyte text at STR of LEN bytes as a unibyte text. It
|
|
801 actually converts characters in the range 0x80..0xFF to
|
|
802 unibyte. */
|
|
803
|
|
804 int
|
|
805 str_as_unibyte (str, bytes)
|
|
806 unsigned char *str;
|
|
807 int bytes;
|
|
808 {
|
88878
|
809 const unsigned char *p = str, *endp = str + bytes;
|
|
810 unsigned char *to;
|
88363
|
811 int c, len;
|
|
812
|
|
813 while (p < endp)
|
|
814 {
|
|
815 c = *p;
|
|
816 len = BYTES_BY_CHAR_HEAD (c);
|
|
817 if (CHAR_BYTE8_HEAD_P (c))
|
|
818 break;
|
|
819 p += len;
|
|
820 }
|
88878
|
821 to = str + (p - str);
|
89483
|
822 while (p < endp)
|
88363
|
823 {
|
|
824 c = *p;
|
|
825 len = BYTES_BY_CHAR_HEAD (c);
|
|
826 if (CHAR_BYTE8_HEAD_P (c))
|
|
827 {
|
|
828 c = STRING_CHAR_ADVANCE (p);
|
|
829 *to++ = CHAR_TO_BYTE8 (c);
|
|
830 }
|
|
831 else
|
|
832 {
|
|
833 while (len--) *to++ = *p++;
|
|
834 }
|
|
835 }
|
|
836 return (to - str);
|
|
837 }
|
|
838
|
|
839 int
|
|
840 string_count_byte8 (string)
|
|
841 Lisp_Object string;
|
|
842 {
|
|
843 int multibyte = STRING_MULTIBYTE (string);
|
89483
|
844 int nbytes = SBYTES (string);
|
|
845 unsigned char *p = SDATA (string);
|
88363
|
846 unsigned char *pend = p + nbytes;
|
|
847 int count = 0;
|
|
848 int c, len;
|
|
849
|
|
850 if (multibyte)
|
|
851 while (p < pend)
|
|
852 {
|
|
853 c = *p;
|
|
854 len = BYTES_BY_CHAR_HEAD (c);
|
|
855
|
|
856 if (CHAR_BYTE8_HEAD_P (c))
|
|
857 count++;
|
|
858 p += len;
|
|
859 }
|
|
860 else
|
|
861 while (p < pend)
|
|
862 {
|
|
863 if (*p++ >= 0x80)
|
|
864 count++;
|
|
865 }
|
|
866 return count;
|
|
867 }
|
|
868
|
|
869
|
|
870 Lisp_Object
|
|
871 string_escape_byte8 (string)
|
|
872 Lisp_Object string;
|
|
873 {
|
89483
|
874 int nchars = SCHARS (string);
|
|
875 int nbytes = SBYTES (string);
|
88363
|
876 int multibyte = STRING_MULTIBYTE (string);
|
|
877 int byte8_count;
|
88878
|
878 const unsigned char *src, *src_end;
|
|
879 unsigned char *dst;
|
88363
|
880 Lisp_Object val;
|
|
881 int c, len;
|
|
882
|
|
883 if (multibyte && nchars == nbytes)
|
|
884 return string;
|
|
885
|
|
886 byte8_count = string_count_byte8 (string);
|
|
887
|
|
888 if (byte8_count == 0)
|
|
889 return string;
|
|
890
|
|
891 if (multibyte)
|
|
892 /* Convert 2-byte sequence of byte8 chars to 4-byte octal. */
|
88526
|
893 val = make_uninit_multibyte_string (nchars + byte8_count * 3,
|
88363
|
894 nbytes + byte8_count * 2);
|
|
895 else
|
|
896 /* Convert 1-byte sequence of byte8 chars to 4-byte octal. */
|
|
897 val = make_uninit_string (nbytes + byte8_count * 3);
|
|
898
|
89483
|
899 src = SDATA (string);
|
88363
|
900 src_end = src + nbytes;
|
89483
|
901 dst = SDATA (val);
|
88363
|
902 if (multibyte)
|
|
903 while (src < src_end)
|
|
904 {
|
|
905 c = *src;
|
|
906 len = BYTES_BY_CHAR_HEAD (c);
|
|
907
|
|
908 if (CHAR_BYTE8_HEAD_P (c))
|
|
909 {
|
|
910 c = STRING_CHAR_ADVANCE (src);
|
|
911 c = CHAR_TO_BYTE8 (c);
|
88427
|
912 sprintf ((char *) dst, "\\%03o", c);
|
88363
|
913 dst += 4;
|
|
914 }
|
|
915 else
|
|
916 while (len--) *dst++ = *src++;
|
|
917 }
|
|
918 else
|
|
919 while (src < src_end)
|
|
920 {
|
|
921 c = *src++;
|
|
922 if (c >= 0x80)
|
|
923 {
|
88427
|
924 sprintf ((char *) dst, "\\%03o", c);
|
88363
|
925 dst += 4;
|
|
926 }
|
|
927 else
|
|
928 *dst++ = c;
|
|
929 }
|
|
930 return val;
|
|
931 }
|
|
932
|
|
933
|
89483
|
934 DEFUN ("string", Fstring, Sstring, 0, MANY, 0,
|
88363
|
935 doc: /*
|
88640
|
936 Concatenate all the argument characters and make the result a string.
|
|
937 usage: (string &rest CHARACTERS) */)
|
88363
|
938 (n, args)
|
|
939 int n;
|
|
940 Lisp_Object *args;
|
|
941 {
|
|
942 int i;
|
|
943 unsigned char *buf = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH * n);
|
|
944 unsigned char *p = buf;
|
|
945 int c;
|
|
946
|
|
947 for (i = 0; i < n; i++)
|
|
948 {
|
|
949 CHECK_CHARACTER (args[i]);
|
|
950 c = XINT (args[i]);
|
|
951 p += CHAR_STRING (c, p);
|
|
952 }
|
|
953
|
|
954 return make_string_from_bytes ((char *) buf, n, p - buf);
|
|
955 }
|
|
956
|
90841
|
957 DEFUN ("unibyte-string", Funibyte_string, Sunibyte_string, 0, MANY, 0,
|
90942
|
958 doc: /* Concatenate all the argument bytes and make the result a unibyte string.
|
|
959 usage: (unibyte-string &rest BYTES) */)
|
90841
|
960 (n, args)
|
|
961 int n;
|
|
962 Lisp_Object *args;
|
|
963 {
|
|
964 int i;
|
|
965 unsigned char *buf = (unsigned char *) alloca (n);
|
|
966 unsigned char *p = buf;
|
|
967 unsigned c;
|
|
968
|
|
969 for (i = 0; i < n; i++)
|
|
970 {
|
|
971 CHECK_NATNUM (args[i]);
|
|
972 c = XFASTINT (args[i]);
|
|
973 if (c >= 256)
|
|
974 args_out_of_range_3 (args[i], make_number (0), make_number (255));
|
|
975 *p++ = c;
|
|
976 }
|
|
977
|
|
978 return make_string_from_bytes ((char *) buf, n, p - buf);
|
|
979 }
|
|
980
|
92494
|
981 DEFUN ("char-resolve-modifers", Fchar_resolve_modifiers,
|
|
982 Schar_resolve_modifiers, 1, 1, 0,
|
|
983 doc: /* Resolve modifiers in the character CHAR.
|
|
984 The value is a character with modifiers resolved into the character
|
|
985 code. Unresolved modifiers are kept in the value.
|
|
986 usage: (char-resolve-modifers CHAR) */)
|
|
987 (character)
|
|
988 Lisp_Object character;
|
|
989 {
|
|
990 int c;
|
|
991
|
|
992 CHECK_NUMBER (character);
|
|
993 c = XINT (character);
|
|
994 return make_number (char_resolve_modifier_mask (c));
|
|
995 }
|
|
996
|
88363
|
997 void
|
|
998 init_character_once ()
|
|
999 {
|
|
1000 }
|
|
1001
|
|
1002 #ifdef emacs
|
|
1003
|
|
1004 void
|
|
1005 syms_of_character ()
|
|
1006 {
|
|
1007 DEFSYM (Qcharacterp, "characterp");
|
|
1008 DEFSYM (Qauto_fill_chars, "auto-fill-chars");
|
|
1009
|
|
1010 staticpro (&Vchar_unify_table);
|
|
1011 Vchar_unify_table = Qnil;
|
|
1012
|
|
1013 defsubr (&Smax_char);
|
|
1014 defsubr (&Scharacterp);
|
|
1015 defsubr (&Sunibyte_char_to_multibyte);
|
|
1016 defsubr (&Smultibyte_char_to_unibyte);
|
|
1017 defsubr (&Schar_bytes);
|
|
1018 defsubr (&Schar_width);
|
|
1019 defsubr (&Sstring_width);
|
|
1020 defsubr (&Schar_direction);
|
|
1021 defsubr (&Sstring);
|
90841
|
1022 defsubr (&Sunibyte_string);
|
92494
|
1023 defsubr (&Schar_resolve_modifiers);
|
88363
|
1024
|
|
1025 DEFVAR_LISP ("translation-table-vector", &Vtranslation_table_vector,
|
|
1026 doc: /*
|
88926
|
1027 Vector recording all translation tables ever defined.
|
|
1028 Each element is a pair (SYMBOL . TABLE) relating the table to the
|
|
1029 symbol naming it. The ID of a translation table is an index into this vector. */);
|
88363
|
1030 Vtranslation_table_vector = Fmake_vector (make_number (16), Qnil);
|
|
1031
|
|
1032 DEFVAR_LISP ("auto-fill-chars", &Vauto_fill_chars,
|
|
1033 doc: /*
|
|
1034 A char-table for characters which invoke auto-filling.
|
|
1035 Such characters have value t in this table. */);
|
|
1036 Vauto_fill_chars = Fmake_char_table (Qauto_fill_chars, Qnil);
|
88853
|
1037 CHAR_TABLE_SET (Vauto_fill_chars, ' ', Qt);
|
|
1038 CHAR_TABLE_SET (Vauto_fill_chars, '\n', Qt);
|
88363
|
1039
|
|
1040 DEFVAR_LISP ("char-width-table", &Vchar_width_table,
|
|
1041 doc: /*
|
|
1042 A char-table for width (columns) of each character. */);
|
|
1043 Vchar_width_table = Fmake_char_table (Qnil, make_number (1));
|
88743
|
1044 char_table_set_range (Vchar_width_table, 0x80, 0x9F, make_number (4));
|
|
1045 char_table_set_range (Vchar_width_table, MAX_5_BYTE_CHAR + 1, MAX_CHAR,
|
|
1046 make_number (4));
|
88363
|
1047
|
|
1048 DEFVAR_LISP ("char-direction-table", &Vchar_direction_table,
|
|
1049 doc: /* A char-table for direction of each character. */);
|
|
1050 Vchar_direction_table = Fmake_char_table (Qnil, make_number (1));
|
|
1051
|
|
1052 DEFVAR_LISP ("printable-chars", &Vprintable_chars,
|
|
1053 doc: /* A char-table for each printable character. */);
|
88716
|
1054 Vprintable_chars = Fmake_char_table (Qnil, Qnil);
|
89029
|
1055 Fset_char_table_range (Vprintable_chars,
|
|
1056 Fcons (make_number (32), make_number (126)), Qt);
|
|
1057 Fset_char_table_range (Vprintable_chars,
|
|
1058 Fcons (make_number (160),
|
|
1059 make_number (MAX_5_BYTE_CHAR)), Qt);
|
88878
|
1060
|
88913
|
1061 DEFVAR_LISP ("char-script-table", &Vchar_script_table,
|
|
1062 doc: /* Char table of script symbols.
|
|
1063 It has one extra slot whose value is a list of script symbols. */);
|
|
1064
|
|
1065 /* Intern this now in case it isn't already done.
|
|
1066 Setting this variable twice is harmless.
|
|
1067 But don't staticpro it here--that is done in alloc.c. */
|
|
1068 Qchar_table_extra_slots = intern ("char-table-extra-slots");
|
|
1069 DEFSYM (Qchar_script_table, "char-script-table");
|
|
1070 Fput (Qchar_script_table, Qchar_table_extra_slots, make_number (1));
|
|
1071 Vchar_script_table = Fmake_char_table (Qchar_script_table, Qnil);
|
90403
|
1072
|
|
1073 DEFVAR_LISP ("script-representative-chars", &Vscript_representative_chars,
|
|
1074 doc: /* Alist of scripts vs the representative characters. */);
|
|
1075 Vscript_representative_chars = Qnil;
|
88363
|
1076 }
|
|
1077
|
|
1078 #endif /* emacs */
|
89911
|
1079
|
|
1080 /* arch-tag: b6665960-3c3d-4184-85cd-af4318197999
|
|
1081 (do not change this comment) */
|