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_ */