Mercurial > hg > xemacs-beta
comparison src/charset.h @ 771:943eaba38521
[xemacs-hg @ 2002-03-13 08:51:24 by ben]
The big ben-mule-21-5 check-in!
Various files were added and deleted. See CHANGES-ben-mule.
There are still some test suite failures. No crashes, though.
Many of the failures have to do with problems in the test suite itself
rather than in the actual code. I'll be addressing these in the next
day or so -- none of the test suite failures are at all critical.
Meanwhile I'll be trying to address the biggest issues -- i.e. build
or run failures, which will almost certainly happen on various platforms.
All comments should be sent to ben@xemacs.org -- use a Cc: if necessary
when sending to mailing lists. There will be pre- and post- tags,
something like
pre-ben-mule-21-5-merge-in, and
post-ben-mule-21-5-merge-in.
author | ben |
---|---|
date | Wed, 13 Mar 2002 08:54:06 +0000 |
parents | |
children | 026c5bf9c134 |
comparison
equal
deleted
inserted
replaced
770:336a418893b5 | 771:943eaba38521 |
---|---|
1 /* Header for charsets. | |
2 Copyright (C) 1992, 1995 Free Software Foundation, Inc. | |
3 Copyright (C) 1995 Sun Microsystems, Inc. | |
4 Copyright (C) 2001, 2002 Ben Wing. | |
5 | |
6 This file is part of XEmacs. | |
7 | |
8 XEmacs is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 2, or (at your option) any | |
11 later version. | |
12 | |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with XEmacs; see the file COPYING. If not, write to | |
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
21 Boston, MA 02111-1307, USA. */ | |
22 | |
23 /* Synched up with: Mule 2.3. Not in FSF. */ | |
24 | |
25 /* Rewritten by Ben Wing <ben@xemacs.org>. */ | |
26 | |
27 #ifndef INCLUDED_charset_h_ | |
28 #define INCLUDED_charset_h_ | |
29 | |
30 | |
31 | |
32 #ifndef MULE | |
33 | |
34 /************************************************************************/ | |
35 /* fake charset defs */ | |
36 /************************************************************************/ | |
37 | |
38 /* used when MULE is not defined, so that Charset-type stuff can still | |
39 be done */ | |
40 | |
41 #define Vcharset_ascii Qnil | |
42 | |
43 #define CHAR_CHARSET(ch) Vcharset_ascii | |
44 #define CHAR_LEADING_BYTE(ch) LEADING_BYTE_ASCII | |
45 #define LEADING_BYTE_ASCII 0x80 | |
46 #define NUM_LEADING_BYTES 1 | |
47 #define MIN_LEADING_BYTE 0x80 | |
48 #define CHARSETP(cs) 1 | |
49 #define CHARSET_BY_LEADING_BYTE(lb) Vcharset_ascii | |
50 #define XCHARSET_LEADING_BYTE(cs) LEADING_BYTE_ASCII | |
51 #define XCHARSET_GRAPHIC(cs) -1 | |
52 #define XCHARSET_COLUMNS(cs) 1 | |
53 #define XCHARSET_DIMENSION(cs) 1 | |
54 #define BREAKUP_CHAR(ch, charset, byte1, byte2) do { \ | |
55 (charset) = Vcharset_ascii; \ | |
56 (byte1) = (ch); \ | |
57 (byte2) = 0; \ | |
58 } while (0) | |
59 | |
60 #else /* MULE */ | |
61 | |
62 | |
63 /************************************************************************/ | |
64 /* Definition of leading bytes */ | |
65 /************************************************************************/ | |
66 | |
67 #define MIN_LEADING_BYTE 0x7F | |
68 | |
69 /** The following are for 1-byte characters in an official charset. **/ | |
70 enum LEADING_BYTE_OFFICIAL_1 | |
71 { | |
72 MIN_LEADING_BYTE_OFFICIAL_1 = 0x80, | |
73 /* LEADING_BYTE_LATIN_ISO8859_1 *MUST* be equal to | |
74 MIN_LEADING_BYTE_OFFICIAL_1. */ | |
75 LEADING_BYTE_LATIN_ISO8859_1 = /* 0x80 Right half of ISO 8859-1 */ | |
76 MIN_LEADING_BYTE_OFFICIAL_1, | |
77 LEADING_BYTE_LATIN_ISO8859_2, /* 0x81 Right half of ISO 8859-2 */ | |
78 LEADING_BYTE_LATIN_ISO8859_3, /* 0x82 Right half of ISO 8859-3 */ | |
79 LEADING_BYTE_LATIN_ISO8859_4, /* 0x83 Right half of ISO 8859-4 */ | |
80 LEADING_BYTE_THAI_TIS620, /* 0x84 TIS620-2533 */ | |
81 LEADING_BYTE_GREEK_ISO8859_7, /* 0x85 Right half of ISO 8859-7 */ | |
82 LEADING_BYTE_ARABIC_ISO8859_6, /* 0x86 Right half of ISO 8859-6 */ | |
83 LEADING_BYTE_HEBREW_ISO8859_8, /* 0x87 Right half of ISO 8859-8 */ | |
84 LEADING_BYTE_KATAKANA_JISX0201, /* 0x88 Right half of JIS X0201-1976 */ | |
85 LEADING_BYTE_LATIN_JISX0201, /* 0x89 Left half of JIS X0201-1976 */ | |
86 LEADING_BYTE_CYRILLIC_ISO8859_5,/* 0x8A Right half of ISO 8859-5 */ | |
87 LEADING_BYTE_LATIN_ISO8859_9, /* 0x8B Right half of ISO 8859-9 */ | |
88 LEADING_BYTE_LATIN_ISO8859_15, /* 0x8C Right half of ISO 8859-15 */ | |
89 #ifdef ENABLE_COMPOSITE_CHARS | |
90 LEADING_BYTE_COMPOSITE, /* 0x8D For a composite character */ | |
91 MAX_LEADING_BYTE_OFFICIAL_1 = | |
92 LEADING_BYTE_COMPOSITE - 1, | |
93 #else | |
94 /* Does not need to be the last entry, but simplifies things */ | |
95 LEADING_BYTE_COMPOSITE_REPLACEMENT, /* 0x8D Replaces ESC 0 - ESC 4 in a | |
96 buffer */ | |
97 MAX_LEADING_BYTE_OFFICIAL_1 = | |
98 LEADING_BYTE_COMPOSITE_REPLACEMENT, | |
99 #endif | |
100 /* 0x8E Unused */ | |
101 }; | |
102 | |
103 /* These next 2 + LEADING_BYTE_COMPOSITE need special treatment in a string | |
104 and/or character */ | |
105 | |
106 #define LEADING_BYTE_ASCII 0x7F /* Not used except in arrays | |
107 indexed by leading byte */ | |
108 #define LEADING_BYTE_CONTROL_1 0x8F /* represent normal 80-9F */ | |
109 | |
110 /** The following are for 2-byte characters in an official charset. **/ | |
111 enum LEADING_BYTE_OFFICIAL_2 | |
112 { | |
113 MIN_LEADING_BYTE_OFFICIAL_2 = 0x90, | |
114 LEADING_BYTE_JAPANESE_JISX0208_1978 = | |
115 MIN_LEADING_BYTE_OFFICIAL_2, /* 0x90 Japanese JIS X0208-1978 */ | |
116 LEADING_BYTE_CHINESE_GB2312, /* 0x91 Chinese Hanzi GB2312-1980 */ | |
117 LEADING_BYTE_JAPANESE_JISX0208, /* 0x92 Japanese JIS X0208-1983 */ | |
118 LEADING_BYTE_KOREAN_KSC5601, /* 0x93 Hangul KS C5601-1987 */ | |
119 LEADING_BYTE_JAPANESE_JISX0212, /* 0x94 Japanese JIS X0212-1990 */ | |
120 LEADING_BYTE_CHINESE_CNS11643_1, /* 0x95 Chinese CNS11643 Set 1 */ | |
121 LEADING_BYTE_CHINESE_CNS11643_2, /* 0x96 Chinese CNS11643 Set 2 */ | |
122 LEADING_BYTE_CHINESE_BIG5_1, /* 0x97 Big5 Level 1 */ | |
123 LEADING_BYTE_CHINESE_BIG5_2, /* 0x98 Big5 Level 2 */ | |
124 MAX_LEADING_BYTE_OFFICIAL_2 = | |
125 LEADING_BYTE_CHINESE_BIG5_2, | |
126 | |
127 /* 0x99 unused */ | |
128 /* 0x9A unused */ | |
129 /* 0x9B unused */ | |
130 /* 0x9C unused */ | |
131 /* 0x9D unused */ | |
132 }; | |
133 | |
134 | |
135 /** The following are for 1- and 2-byte characters in a private charset. **/ | |
136 | |
137 #define PRE_LEADING_BYTE_PRIVATE_1 0x9E /* 1-byte char-set */ | |
138 #define PRE_LEADING_BYTE_PRIVATE_2 0x9F /* 2-byte char-set */ | |
139 | |
140 #define MIN_LEADING_BYTE_PRIVATE_1 0xA0 | |
141 #define MAX_LEADING_BYTE_PRIVATE_1 0xEF | |
142 #define MIN_LEADING_BYTE_PRIVATE_2 0xF0 | |
143 #define MAX_LEADING_BYTE_PRIVATE_2 0xFF | |
144 | |
145 #define NUM_LEADING_BYTES 129 | |
146 | |
147 | |
148 /************************************************************************/ | |
149 /* Operations on leading bytes */ | |
150 /************************************************************************/ | |
151 | |
152 /* Is this leading byte for a private charset? */ | |
153 | |
154 #define LEADING_BYTE_PRIVATE_P(lb) ((lb) >= MIN_LEADING_BYTE_PRIVATE_1) | |
155 | |
156 /* Is this a prefix for a private leading byte? */ | |
157 | |
158 INLINE_HEADER int LEADING_BYTE_PREFIX_P (Intbyte lb); | |
159 INLINE_HEADER int | |
160 LEADING_BYTE_PREFIX_P (Intbyte lb) | |
161 { | |
162 return (lb == PRE_LEADING_BYTE_PRIVATE_1 || | |
163 lb == PRE_LEADING_BYTE_PRIVATE_2); | |
164 } | |
165 | |
166 /* Given a private leading byte, return the leading byte prefix stored | |
167 in a string. */ | |
168 | |
169 #define PRIVATE_LEADING_BYTE_PREFIX(lb) \ | |
170 ((unsigned int) (lb) < MIN_LEADING_BYTE_PRIVATE_2 ? \ | |
171 PRE_LEADING_BYTE_PRIVATE_1 : \ | |
172 PRE_LEADING_BYTE_PRIVATE_2) | |
173 | |
174 | |
175 /************************************************************************/ | |
176 /* Information about a particular character set */ | |
177 /************************************************************************/ | |
178 | |
179 struct Lisp_Charset | |
180 { | |
181 struct lcrecord_header header; | |
182 | |
183 int id; | |
184 Lisp_Object name; | |
185 Lisp_Object doc_string; | |
186 Lisp_Object registry; | |
187 Lisp_Object short_name; | |
188 Lisp_Object long_name; | |
189 | |
190 Lisp_Object reverse_direction_charset; | |
191 | |
192 Lisp_Object ccl_program; | |
193 | |
194 /* Unicode translation tables. See unicode.c for the format of these tables. | |
195 | |
196 NOTE ABOUT DUMPING: We don't currently dump these tables. For one | |
197 thing, they're big, and it's very fast to recreate them (a fraction of | |
198 a second on modern processors); for another, there isn't currently | |
199 support in pdump for this. (At one point I started writing it, in the | |
200 form of XD_UNION, but thought better of it.) In order to avoid pdump | |
201 problems (and to make the dump data smaller), we free all the tables | |
202 at dump time (using the disksave finalization method), set them to | |
203 zero, and reinit them to blank when we start up again; they will be | |
204 reloaded when `init-mule-at-startup' is called. | |
205 | |
206 #### This creates a problem w.r.t. user-defined charsets. It would be | |
207 inconvenient to require all dumped user-defined charsets to be | |
208 reloaded at init time, but that's what currently needs to be done. | |
209 The solution is either to go ahead and create pdump support for | |
210 dumping the tables, and use it just for these; or to copy the data in | |
211 them into a compressed format, write it out to pdump as a single | |
212 opaque block, and undo the operation at startup. | |
213 | |
214 #### There's another problem, having to do with starting up in a | |
215 non-ISO-8859-1 directory. We don't load the tables until after we've | |
216 parsed the current directories, and we run into a real bootstrapping | |
217 problem trying to solve this. Either we'll have to dump all the | |
218 tables as-is or make some special provisions for writing extra binary | |
219 data into the pdump data, and do the compressed trick mentioned above | |
220 for all the tables. */ | |
221 void *to_unicode_table; | |
222 void *from_unicode_table; | |
223 int from_unicode_levels; | |
224 | |
225 unsigned char unicode_table_loaded; | |
226 | |
227 /* Final byte of this character set in ISO2022 designating escape sequence */ | |
228 Intbyte final; | |
229 | |
230 /* Number of bytes (1 - 4) required in the internal representation | |
231 for characters in this character set. This is *not* the | |
232 same as the dimension of the character set). */ | |
233 int rep_bytes; | |
234 | |
235 /* Number of columns a character in this charset takes up, on TTY | |
236 devices. Not used for X devices. */ | |
237 int columns; | |
238 | |
239 /* Direction of this character set */ | |
240 int direction; | |
241 | |
242 /* Type of this character set (94, 96, 94x94, 96x96) */ | |
243 int type; | |
244 | |
245 /* Number of bytes used in encoding of this character set (1 or 2) */ | |
246 int dimension; | |
247 | |
248 /* Number of chars in each dimension (usually 94 or 96) */ | |
249 int chars; | |
250 | |
251 /* Which half of font to be used to display this character set */ | |
252 int graphic; | |
253 | |
254 /* If set, this is a "temporary" charset created when we encounter | |
255 an unknown final. This is so that we can successfully compile | |
256 and load such files. We allow a real charset to be created on top | |
257 of this temporary charset. */ | |
258 unsigned int temporary :1; | |
259 }; | |
260 typedef struct Lisp_Charset Lisp_Charset; | |
261 | |
262 DECLARE_LRECORD (charset, Lisp_Charset); | |
263 #define XCHARSET(x) XRECORD (x, charset, Lisp_Charset) | |
264 #define XSETCHARSET(x, p) XSETRECORD (x, p, charset) | |
265 #define wrap_charset(p) wrap_record (p, charset) | |
266 #define CHARSETP(x) RECORDP (x, charset) | |
267 #define CHECK_CHARSET(x) CHECK_RECORD (x, charset) | |
268 #define CONCHECK_CHARSET(x) CONCHECK_RECORD (x, charset) | |
269 | |
270 #define CHARSET_TYPE_94 0 /* This charset includes 94 characters. */ | |
271 #define CHARSET_TYPE_96 1 /* This charset includes 96 characters. */ | |
272 #define CHARSET_TYPE_94X94 2 /* This charset includes 94x94 characters. */ | |
273 #define CHARSET_TYPE_96X96 3 /* This charset includes 96x96 characters. */ | |
274 | |
275 #define CHARSET_LEFT_TO_RIGHT 0 | |
276 #define CHARSET_RIGHT_TO_LEFT 1 | |
277 | |
278 /* Leading byte and id have been regrouped. -- OG */ | |
279 #define CHARSET_ID(cs) ((cs)->id) | |
280 #define CHARSET_LEADING_BYTE(cs) ((Intbyte) CHARSET_ID (cs)) | |
281 #define CHARSET_NAME(cs) ((cs)->name) | |
282 #define CHARSET_SHORT_NAME(cs) ((cs)->short_name) | |
283 #define CHARSET_LONG_NAME(cs) ((cs)->long_name) | |
284 #define CHARSET_REP_BYTES(cs) ((cs)->rep_bytes) | |
285 #define CHARSET_COLUMNS(cs) ((cs)->columns) | |
286 #define CHARSET_GRAPHIC(cs) ((cs)->graphic) | |
287 #define CHARSET_TYPE(cs) ((cs)->type) | |
288 #define CHARSET_DIRECTION(cs) ((cs)->direction) | |
289 #define CHARSET_FINAL(cs) ((cs)->final) | |
290 #define CHARSET_DOC_STRING(cs) ((cs)->doc_string) | |
291 #define CHARSET_REGISTRY(cs) ((cs)->registry) | |
292 #define CHARSET_CCL_PROGRAM(cs) ((cs)->ccl_program) | |
293 #define CHARSET_DIMENSION(cs) ((cs)->dimension) | |
294 #define CHARSET_CHARS(cs) ((cs)->chars) | |
295 #define CHARSET_REVERSE_DIRECTION_CHARSET(cs) ((cs)->reverse_direction_charset) | |
296 #define CHARSET_TO_UNICODE_TABLE(cs) ((cs)->to_unicode_table) | |
297 #define CHARSET_FROM_UNICODE_TABLE(cs) ((cs)->from_unicode_table) | |
298 #define CHARSET_FROM_UNICODE_LEVELS(cs) ((cs)->from_unicode_levels) | |
299 | |
300 | |
301 #define CHARSET_PRIVATE_P(cs) LEADING_BYTE_PRIVATE_P (CHARSET_LEADING_BYTE (cs)) | |
302 | |
303 #define XCHARSET_ID(cs) CHARSET_ID (XCHARSET (cs)) | |
304 #define XCHARSET_NAME(cs) CHARSET_NAME (XCHARSET (cs)) | |
305 #define XCHARSET_SHORT_NAME(cs) CHARSET_SHORT_NAME (XCHARSET (cs)) | |
306 #define XCHARSET_LONG_NAME(cs) CHARSET_LONG_NAME (XCHARSET (cs)) | |
307 #define XCHARSET_REP_BYTES(cs) CHARSET_REP_BYTES (XCHARSET (cs)) | |
308 #define XCHARSET_COLUMNS(cs) CHARSET_COLUMNS (XCHARSET (cs)) | |
309 #define XCHARSET_GRAPHIC(cs) CHARSET_GRAPHIC (XCHARSET (cs)) | |
310 #define XCHARSET_TYPE(cs) CHARSET_TYPE (XCHARSET (cs)) | |
311 #define XCHARSET_DIRECTION(cs) CHARSET_DIRECTION (XCHARSET (cs)) | |
312 #define XCHARSET_FINAL(cs) CHARSET_FINAL (XCHARSET (cs)) | |
313 #define XCHARSET_DOC_STRING(cs) CHARSET_DOC_STRING (XCHARSET (cs)) | |
314 #define XCHARSET_REGISTRY(cs) CHARSET_REGISTRY (XCHARSET (cs)) | |
315 #define XCHARSET_LEADING_BYTE(cs) CHARSET_LEADING_BYTE (XCHARSET (cs)) | |
316 #define XCHARSET_CCL_PROGRAM(cs) CHARSET_CCL_PROGRAM (XCHARSET (cs)) | |
317 #define XCHARSET_DIMENSION(cs) CHARSET_DIMENSION (XCHARSET (cs)) | |
318 #define XCHARSET_CHARS(cs) CHARSET_CHARS (XCHARSET (cs)) | |
319 #define XCHARSET_PRIVATE_P(cs) CHARSET_PRIVATE_P (XCHARSET (cs)) | |
320 #define XCHARSET_REVERSE_DIRECTION_CHARSET(cs) \ | |
321 CHARSET_REVERSE_DIRECTION_CHARSET (XCHARSET (cs)) | |
322 #define XCHARSET_TO_UNICODE_TABLE(cs) \ | |
323 CHARSET_TO_UNICODE_TABLE (XCHARSET (cs)) | |
324 #define XCHARSET_FROM_UNICODE_TABLE(cs) \ | |
325 CHARSET_FROM_UNICODE_TABLE (XCHARSET (cs)) | |
326 #define XCHARSET_FROM_UNICODE_LEVELS(cs) \ | |
327 CHARSET_FROM_UNICODE_LEVELS (XCHARSET (cs)) | |
328 | |
329 struct charset_lookup | |
330 { | |
331 /* Table of charsets indexed by leading byte. */ | |
332 Lisp_Object charset_by_leading_byte[NUM_LEADING_BYTES]; | |
333 | |
334 /* Table of charsets indexed by type/final-byte/direction. */ | |
335 Lisp_Object charset_by_attributes[4][128][2]; | |
336 Intbyte next_allocated_1_byte_leading_byte; | |
337 Intbyte next_allocated_2_byte_leading_byte; | |
338 }; | |
339 | |
340 INLINE_HEADER Lisp_Object CHARSET_BY_LEADING_BYTE (int lb); | |
341 INLINE_HEADER Lisp_Object | |
342 CHARSET_BY_LEADING_BYTE (int lb) | |
343 { | |
344 extern struct charset_lookup *chlook; | |
345 | |
346 #ifdef ERROR_CHECK_TYPECHECK | |
347 /* When error-checking is on, x86 GCC 2.95.2 -O3 miscompiles the | |
348 following unless we introduce `tem'. */ | |
349 int tem = lb; | |
350 type_checking_assert (tem >= MIN_LEADING_BYTE && tem <= 0xFF); | |
351 #endif | |
352 return chlook->charset_by_leading_byte[lb - MIN_LEADING_BYTE]; | |
353 } | |
354 | |
355 INLINE_HEADER Lisp_Object | |
356 CHARSET_BY_ATTRIBUTES (int type, int final, int dir); | |
357 INLINE_HEADER Lisp_Object | |
358 CHARSET_BY_ATTRIBUTES (int type, int final, int dir) | |
359 { | |
360 extern struct charset_lookup *chlook; | |
361 | |
362 type_checking_assert (type < countof (chlook->charset_by_attributes) && | |
363 final < countof (chlook->charset_by_attributes[0]) && | |
364 dir < countof (chlook->charset_by_attributes[0][0])); | |
365 return chlook->charset_by_attributes[type][final][dir]; | |
366 } | |
367 | |
368 | |
369 /************************************************************************/ | |
370 /* Dealing with characters */ | |
371 /************************************************************************/ | |
372 | |
373 /* The bit fields of character are divided into 3 parts: | |
374 FIELD1(5bits):FIELD2(7bits):FIELD3(7bits) */ | |
375 | |
376 #define CHAR_FIELD1_MASK (0x1F << 14) | |
377 #define CHAR_FIELD2_MASK (0x7F << 7) | |
378 #define CHAR_FIELD3_MASK 0x7F | |
379 | |
380 /* Macros to access each field of a character code of C. */ | |
381 | |
382 #define CHAR_FIELD1(c) (((c) & CHAR_FIELD1_MASK) >> 14) | |
383 #define CHAR_FIELD2(c) (((c) & CHAR_FIELD2_MASK) >> 7) | |
384 #define CHAR_FIELD3(c) ((c) & CHAR_FIELD3_MASK) | |
385 | |
386 /* Field 1, if non-zero, usually holds a leading byte for a | |
387 dimension-2 charset. Field 2, if non-zero, usually holds a leading | |
388 byte for a dimension-1 charset. */ | |
389 | |
390 /* Converting between field values and leading bytes. */ | |
391 | |
392 #define FIELD2_TO_OFFICIAL_LEADING_BYTE (MIN_LEADING_BYTE_OFFICIAL_1 - 1) | |
393 #define FIELD2_TO_PRIVATE_LEADING_BYTE 0x80 | |
394 | |
395 #define FIELD1_TO_OFFICIAL_LEADING_BYTE (MIN_LEADING_BYTE_OFFICIAL_2 - 1) | |
396 #define FIELD1_TO_PRIVATE_LEADING_BYTE 0xE1 | |
397 | |
398 /* Minimum and maximum allowed values for the fields. */ | |
399 | |
400 #define MIN_CHAR_FIELD2_OFFICIAL \ | |
401 (MIN_LEADING_BYTE_OFFICIAL_1 - FIELD2_TO_OFFICIAL_LEADING_BYTE) | |
402 #define MAX_CHAR_FIELD2_OFFICIAL \ | |
403 (MAX_LEADING_BYTE_OFFICIAL_1 - FIELD2_TO_OFFICIAL_LEADING_BYTE) | |
404 | |
405 #define MIN_CHAR_FIELD1_OFFICIAL \ | |
406 (MIN_LEADING_BYTE_OFFICIAL_2 - FIELD1_TO_OFFICIAL_LEADING_BYTE) | |
407 #define MAX_CHAR_FIELD1_OFFICIAL \ | |
408 (MAX_LEADING_BYTE_OFFICIAL_2 - FIELD1_TO_OFFICIAL_LEADING_BYTE) | |
409 | |
410 #define MIN_CHAR_FIELD2_PRIVATE \ | |
411 (MIN_LEADING_BYTE_PRIVATE_1 - FIELD2_TO_PRIVATE_LEADING_BYTE) | |
412 #define MAX_CHAR_FIELD2_PRIVATE \ | |
413 (MAX_LEADING_BYTE_PRIVATE_1 - FIELD2_TO_PRIVATE_LEADING_BYTE) | |
414 | |
415 #define MIN_CHAR_FIELD1_PRIVATE \ | |
416 (MIN_LEADING_BYTE_PRIVATE_2 - FIELD1_TO_PRIVATE_LEADING_BYTE) | |
417 #define MAX_CHAR_FIELD1_PRIVATE \ | |
418 (MAX_LEADING_BYTE_PRIVATE_2 - FIELD1_TO_PRIVATE_LEADING_BYTE) | |
419 | |
420 /* Minimum character code of each <type> character. */ | |
421 | |
422 #define MIN_CHAR_OFFICIAL_TYPE9N (MIN_CHAR_FIELD2_OFFICIAL << 7) | |
423 #define MIN_CHAR_PRIVATE_TYPE9N (MIN_CHAR_FIELD2_PRIVATE << 7) | |
424 #define MIN_CHAR_OFFICIAL_TYPE9NX9N (MIN_CHAR_FIELD1_OFFICIAL << 14) | |
425 #define MIN_CHAR_PRIVATE_TYPE9NX9N (MIN_CHAR_FIELD1_PRIVATE << 14) | |
426 #define MIN_CHAR_COMPOSITION (0x1F << 14) | |
427 | |
428 /* Leading byte of a character. | |
429 | |
430 NOTE: This takes advantage of the fact that | |
431 FIELD2_TO_OFFICIAL_LEADING_BYTE and | |
432 FIELD2_TO_PRIVATE_LEADING_BYTE are the same. | |
433 */ | |
434 | |
435 INLINE_HEADER Intbyte CHAR_LEADING_BYTE (Emchar c); | |
436 INLINE_HEADER Intbyte | |
437 CHAR_LEADING_BYTE (Emchar c) | |
438 { | |
439 if (CHAR_ASCII_P (c)) | |
440 return LEADING_BYTE_ASCII; | |
441 else if (c < 0xA0) | |
442 return LEADING_BYTE_CONTROL_1; | |
443 else if (c < MIN_CHAR_OFFICIAL_TYPE9NX9N) | |
444 return CHAR_FIELD2 (c) + FIELD2_TO_OFFICIAL_LEADING_BYTE; | |
445 else if (c < MIN_CHAR_PRIVATE_TYPE9NX9N) | |
446 return CHAR_FIELD1 (c) + FIELD1_TO_OFFICIAL_LEADING_BYTE; | |
447 else if (c < MIN_CHAR_COMPOSITION) | |
448 return CHAR_FIELD1 (c) + FIELD1_TO_PRIVATE_LEADING_BYTE; | |
449 else | |
450 { | |
451 #ifdef ENABLE_COMPOSITE_CHARS | |
452 return LEADING_BYTE_COMPOSITE; | |
453 #else | |
454 abort(); | |
455 return 0; | |
456 #endif /* ENABLE_COMPOSITE_CHARS */ | |
457 } | |
458 } | |
459 | |
460 #define CHAR_CHARSET(c) CHARSET_BY_LEADING_BYTE (CHAR_LEADING_BYTE (c)) | |
461 | |
462 /* Return a character whose charset is CHARSET and position-codes are C1 | |
463 and C2. TYPE9N character ignores C2. (For typical charsets, i.e. not | |
464 ASCII, Control-1 or Composite, C1 and C2 will be in the range of 32 to | |
465 127 or 33 to 126. See `make-char'.) | |
466 | |
467 NOTE: This takes advantage of the fact that | |
468 FIELD2_TO_OFFICIAL_LEADING_BYTE and | |
469 FIELD2_TO_PRIVATE_LEADING_BYTE are the same. | |
470 */ | |
471 | |
472 INLINE_HEADER Emchar MAKE_CHAR_1 (Lisp_Object charset, int c1, int c2); | |
473 INLINE_HEADER Emchar | |
474 MAKE_CHAR_1 (Lisp_Object charset, int c1, int c2) | |
475 { | |
476 if (EQ (charset, Vcharset_ascii)) | |
477 return c1; | |
478 else if (EQ (charset, Vcharset_control_1)) | |
479 return c1 | 0x80; | |
480 #ifdef ENABLE_COMPOSITE_CHARS | |
481 else if (EQ (charset, Vcharset_composite)) | |
482 return (0x1F << 14) | ((c1) << 7) | (c2); | |
483 #endif | |
484 else if (XCHARSET_DIMENSION (charset) == 1) | |
485 return ((XCHARSET_LEADING_BYTE (charset) - | |
486 FIELD2_TO_OFFICIAL_LEADING_BYTE) << 7) | (c1); | |
487 else if (!XCHARSET_PRIVATE_P (charset)) | |
488 return ((XCHARSET_LEADING_BYTE (charset) - | |
489 FIELD1_TO_OFFICIAL_LEADING_BYTE) << 14) | ((c1) << 7) | (c2); | |
490 else | |
491 return ((XCHARSET_LEADING_BYTE (charset) - | |
492 FIELD1_TO_PRIVATE_LEADING_BYTE) << 14) | ((c1) << 7) | (c2); | |
493 } | |
494 | |
495 #ifdef ERROR_CHECK_CHARBPOS | |
496 INLINE_HEADER Emchar MAKE_CHAR (Lisp_Object charset, int c1, int c2); | |
497 INLINE_HEADER Emchar | |
498 MAKE_CHAR (Lisp_Object charset, int c1, int c2) | |
499 { | |
500 Emchar retval = MAKE_CHAR_1 (charset, c1, c2); | |
501 assert (valid_char_p (retval)); | |
502 return retval; | |
503 } | |
504 #else | |
505 #define MAKE_CHAR(charset, c1, c2) MAKE_CHAR_1 (charset, c1, c2) | |
506 #endif | |
507 | |
508 /* BREAKUP_CHAR_1_UNSAFE assumes that the charset has already been | |
509 calculated, and just computes c1 and c2. | |
510 | |
511 BREAKUP_CHAR also computes and stores the charset. */ | |
512 | |
513 #define BREAKUP_CHAR_1_UNSAFE(c, charset, c1, c2) \ | |
514 XCHARSET_DIMENSION (charset) == 1 \ | |
515 ? ((c1) = CHAR_FIELD3 (c), (c2) = 0) \ | |
516 : ((c1) = CHAR_FIELD2 (c), \ | |
517 (c2) = CHAR_FIELD3 (c)) | |
518 | |
519 INLINE_HEADER void breakup_char_1 (Emchar c, Lisp_Object *charset, int *c1, | |
520 int *c2); | |
521 INLINE_HEADER void | |
522 breakup_char_1 (Emchar c, Lisp_Object *charset, int *c1, int *c2) | |
523 { | |
524 charbpos_checking_assert (valid_char_p (c)); | |
525 *charset = CHAR_CHARSET (c); | |
526 BREAKUP_CHAR_1_UNSAFE (c, *charset, *c1, *c2); | |
527 } | |
528 | |
529 /* BREAKUP_CHAR separates an Emchar into its components. The charset of | |
530 character C is set to CHARSET, and the position-codes of C are set to C1 | |
531 and C2. C2 of TYPE9N character is 0. */ | |
532 | |
533 #define BREAKUP_CHAR(c, charset, c1, c2) \ | |
534 breakup_char_1 (c, &(charset), &(c1), &(c2)) | |
535 | |
536 #endif /* MULE */ | |
537 | |
538 #endif /* INCLUDED_charset_h_ */ |