FLTK 1.3.4
big5_emacs.h
1 /* $XFree86: xc/lib/X11/lcUniConv/big5_emacs.h,v 1.1 2000/11/28 18:50:06 dawes Exp $ */
2 
3 /*
4  * BIG5-0 and BIG5-1
5  */
6 
7 /*
8  BIG5 with its 13494 characters doesn't fit in a single 94x94 or 96x96
9  block. Therefore Emacs/Mule developers, in a typically Japanese way of
10  thinking, have developed an alternative encoding of BIG5 in two 94x94
11  planes, very similar to the SHIFT_JIS encoding for JISX0208.
12 
13  Conversion between BIG5 codes (s1,s2) and BIG5-0 codes (c1,c2):
14  Example. (s1,s2) = 0xA140, (c1,c2) = 0x2121.
15  0xA1 <= s1 <= 0xC7, 0x40 <= s2 <= 0x7E || 0xA1 <= s2 <= 0xFE,
16  0x21 <= c1 <= 0x62, 0x21 <= c2 <= 0x7E.
17  Invariant:
18  157*(s1-0xA1) + (s2 < 0x80 ? s2-0x40 : s2-0x62)
19  = 94*(c1-0x21)+(c2-0x21)
20  Conversion (s1,s2) -> (c1,c2):
21  t := 157*(s1-0xA1) + (s2 < 0x80 ? s2-0x40 : s2-0x62)
22  c1 := (t div 94) + 0x21
23  c2 := (t mod 94) + 0x21
24  Conversion (c1,c2) -> (s1,s2):
25  t := 94*(c1-0x21)+(c2-0x21)
26  t2 := t mod 157
27  s1 := (t div 157) + 0xA1
28  s2 := (t2 < 0x3F ? t2+0x40 : t2+0x62)
29 
30  Conversion between BIG5 codes (s1,s2) and BIG5-1 codes (c1,c2):
31  Example. (s1,s2) = 0xC940, (c1,c2) = 0x2121.
32  0xC9 <= s1 <= 0xF9, 0x40 <= s2 <= 0x7E || 0xA1 <= s2 <= 0xFE,
33  0x21 <= c1 <= 0x72, 0x21 <= c2 <= 0x7E.
34  Invariant:
35  157*(s1-0xC9) + (s2 < 0x80 ? s2-0x40 : s2-0x62)
36  = 94*(c1-0x21)+(c2-0x21)
37  Conversion (s1,s2) -> (c1,c2):
38  t := 157*(s1-0xC9) + (s2 < 0x80 ? s2-0x40 : s2-0x62)
39  c1 := (t div 94) + 0x21
40  c2 := (t mod 94) + 0x21
41  Conversion (c1,c2) -> (s1,s2):
42  t := 94*(c1-0x21)+(c2-0x21)
43  t2 := t mod 157
44  s1 := (t div 157) + 0xC9
45  s2 := (t2 < 0x3F ? t2+0x40 : t2+0x62)
46  */
47 
48 static int
49 big5_0_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n)
50 {
51  unsigned char c1 = s[0];
52  if (c1 >= 0x21 && c1 <= 0x62) {
53  if (n >= 2) {
54  unsigned char c2 = s[1];
55  if (c2 >= 0x21 && c2 <= 0x7e) {
56  unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21);
57  if (0) {
58  /* Unoptimized. */
59  unsigned char buf[2];
60  buf[0] = (i / 157) + 0xa1;
61  i = i % 157;
62  buf[1] = i + (i < 0x3f ? 0x40 : 0x62);
63  return big5_mbtowc(conv,pwc,buf,2);
64  } else {
65  /* Inline the implementation of big5_mbtowc. */
66  if (i < 6121) {
67  unsigned short wc = big5_2uni_pagea1[i];
68  if (wc != 0xfffd) {
69  *pwc = (ucs4_t) wc;
70  return 2;
71  }
72  }
73  }
74  }
75  return RET_ILSEQ;
76  }
77  return RET_TOOFEW(0);
78  }
79  return RET_ILSEQ;
80 }
81 
82 static int
83 big5_1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n)
84 {
85  unsigned char c1 = s[0];
86  if (c1 >= 0x21 && c1 <= 0x72) {
87  if (n >= 2) {
88  unsigned char c2 = s[1];
89  if (c2 >= 0x21 && c2 <= 0x7e) {
90  unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21);
91  if (0) {
92  /* Unoptimized. */
93  unsigned char buf[2];
94  buf[0] = (i / 157) + 0xc9;
95  i = i % 157;
96  buf[1] = i + (i < 0x3f ? 0x40 : 0x62);
97  return big5_mbtowc(conv,pwc,buf,2);
98  } else {
99  /* Inline the implementation of big5_mbtowc. */
100  if (i < 7652) {
101  unsigned short wc = big5_2uni_pagec9[i];
102  if (wc != 0xfffd) {
103  *pwc = (ucs4_t) wc;
104  return 2;
105  }
106  }
107  }
108  }
109  return RET_ILSEQ;
110  }
111  return RET_TOOFEW(0);
112  }
113  return RET_ILSEQ;
114 }
115 
116 static int
117 big5_0_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)
118 {
119  if (n >= 2) {
120  unsigned char buf[2];
121  int ret = big5_wctomb(conv,buf,wc,2);
122  if (ret != RET_ILSEQ) {
123  unsigned char s1, s2;
124  if (ret != 2) abort();
125  s1 = buf[0];
126  s2 = buf[1];
127  if (!(s1 >= 0xa1)) abort();
128  if (!((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0xa1 && s2 <= 0xfe))) abort();
129  if (s1 < 0xc9) {
130  unsigned int t = 157 * (s1 - 0xa1) + s2 - (s2 < 0x80 ? 0x40 : 0x62);
131  r[0] = (t / 94) + 0x21;
132  r[1] = (t % 94) + 0x21;
133  return 2;
134  }
135  }
136  return RET_ILSEQ;
137  }
138  return RET_TOOSMALL;
139 }
140 
141 static int
142 big5_1_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)
143 {
144  if (n >= 2) {
145  unsigned char buf[2];
146  int ret = big5_wctomb(conv,buf,wc,2);
147  if (ret != RET_ILSEQ) {
148  unsigned char s1, s2;
149  if (ret != 2) abort();
150  s1 = buf[0];
151  s2 = buf[1];
152  if (!(s1 <= 0xf9)) abort();
153  if (!((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0xa1 && s2 <= 0xfe))) abort();
154  if (s1 >= 0xc9) {
155  unsigned int t = 157 * (s1 - 0xc9) + s2 - (s2 < 0x80 ? 0x40 : 0x62);
156  r[0] = (t / 94) + 0x21;
157  r[1] = (t % 94) + 0x21;
158  return 2;
159  }
160  }
161  return RET_ILSEQ;
162  }
163  return RET_TOOSMALL;
164 }