FLTK 1.3.0
|
00001 /* $XFree86: xc/lib/X11/lcUniConv/big5_emacs.h,v 1.1 2000/11/28 18:50:06 dawes Exp $ */ 00002 00003 /* 00004 * BIG5-0 and BIG5-1 00005 */ 00006 00007 /* 00008 BIG5 with its 13494 characters doesn't fit in a single 94x94 or 96x96 00009 block. Therefore Emacs/Mule developers, in a typically Japanese way of 00010 thinking, have developed an alternative encoding of BIG5 in two 94x94 00011 planes, very similar to the SHIFT_JIS encoding for JISX0208. 00012 00013 Conversion between BIG5 codes (s1,s2) and BIG5-0 codes (c1,c2): 00014 Example. (s1,s2) = 0xA140, (c1,c2) = 0x2121. 00015 0xA1 <= s1 <= 0xC7, 0x40 <= s2 <= 0x7E || 0xA1 <= s2 <= 0xFE, 00016 0x21 <= c1 <= 0x62, 0x21 <= c2 <= 0x7E. 00017 Invariant: 00018 157*(s1-0xA1) + (s2 < 0x80 ? s2-0x40 : s2-0x62) 00019 = 94*(c1-0x21)+(c2-0x21) 00020 Conversion (s1,s2) -> (c1,c2): 00021 t := 157*(s1-0xA1) + (s2 < 0x80 ? s2-0x40 : s2-0x62) 00022 c1 := (t div 94) + 0x21 00023 c2 := (t mod 94) + 0x21 00024 Conversion (c1,c2) -> (s1,s2): 00025 t := 94*(c1-0x21)+(c2-0x21) 00026 t2 := t mod 157 00027 s1 := (t div 157) + 0xA1 00028 s2 := (t2 < 0x3F ? t2+0x40 : t2+0x62) 00029 00030 Conversion between BIG5 codes (s1,s2) and BIG5-1 codes (c1,c2): 00031 Example. (s1,s2) = 0xC940, (c1,c2) = 0x2121. 00032 0xC9 <= s1 <= 0xF9, 0x40 <= s2 <= 0x7E || 0xA1 <= s2 <= 0xFE, 00033 0x21 <= c1 <= 0x72, 0x21 <= c2 <= 0x7E. 00034 Invariant: 00035 157*(s1-0xC9) + (s2 < 0x80 ? s2-0x40 : s2-0x62) 00036 = 94*(c1-0x21)+(c2-0x21) 00037 Conversion (s1,s2) -> (c1,c2): 00038 t := 157*(s1-0xC9) + (s2 < 0x80 ? s2-0x40 : s2-0x62) 00039 c1 := (t div 94) + 0x21 00040 c2 := (t mod 94) + 0x21 00041 Conversion (c1,c2) -> (s1,s2): 00042 t := 94*(c1-0x21)+(c2-0x21) 00043 t2 := t mod 157 00044 s1 := (t div 157) + 0xC9 00045 s2 := (t2 < 0x3F ? t2+0x40 : t2+0x62) 00046 */ 00047 00048 static int 00049 big5_0_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) 00050 { 00051 unsigned char c1 = s[0]; 00052 if (c1 >= 0x21 && c1 <= 0x62) { 00053 if (n >= 2) { 00054 unsigned char c2 = s[1]; 00055 if (c2 >= 0x21 && c2 <= 0x7e) { 00056 unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); 00057 if (0) { 00058 /* Unoptimized. */ 00059 unsigned char buf[2]; 00060 buf[0] = (i / 157) + 0xa1; 00061 i = i % 157; 00062 buf[1] = i + (i < 0x3f ? 0x40 : 0x62); 00063 return big5_mbtowc(conv,pwc,buf,2); 00064 } else { 00065 /* Inline the implementation of big5_mbtowc. */ 00066 if (i < 6121) { 00067 unsigned short wc = big5_2uni_pagea1[i]; 00068 if (wc != 0xfffd) { 00069 *pwc = (ucs4_t) wc; 00070 return 2; 00071 } 00072 } 00073 } 00074 } 00075 return RET_ILSEQ; 00076 } 00077 return RET_TOOFEW(0); 00078 } 00079 return RET_ILSEQ; 00080 } 00081 00082 static int 00083 big5_1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) 00084 { 00085 unsigned char c1 = s[0]; 00086 if (c1 >= 0x21 && c1 <= 0x72) { 00087 if (n >= 2) { 00088 unsigned char c2 = s[1]; 00089 if (c2 >= 0x21 && c2 <= 0x7e) { 00090 unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); 00091 if (0) { 00092 /* Unoptimized. */ 00093 unsigned char buf[2]; 00094 buf[0] = (i / 157) + 0xc9; 00095 i = i % 157; 00096 buf[1] = i + (i < 0x3f ? 0x40 : 0x62); 00097 return big5_mbtowc(conv,pwc,buf,2); 00098 } else { 00099 /* Inline the implementation of big5_mbtowc. */ 00100 if (i < 7652) { 00101 unsigned short wc = big5_2uni_pagec9[i]; 00102 if (wc != 0xfffd) { 00103 *pwc = (ucs4_t) wc; 00104 return 2; 00105 } 00106 } 00107 } 00108 } 00109 return RET_ILSEQ; 00110 } 00111 return RET_TOOFEW(0); 00112 } 00113 return RET_ILSEQ; 00114 } 00115 00116 static int 00117 big5_0_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) 00118 { 00119 if (n >= 2) { 00120 unsigned char buf[2]; 00121 int ret = big5_wctomb(conv,buf,wc,2); 00122 if (ret != RET_ILSEQ) { 00123 unsigned char s1, s2; 00124 if (ret != 2) abort(); 00125 s1 = buf[0]; 00126 s2 = buf[1]; 00127 if (!(s1 >= 0xa1)) abort(); 00128 if (!((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0xa1 && s2 <= 0xfe))) abort(); 00129 if (s1 < 0xc9) { 00130 unsigned int t = 157 * (s1 - 0xa1) + s2 - (s2 < 0x80 ? 0x40 : 0x62); 00131 r[0] = (t / 94) + 0x21; 00132 r[1] = (t % 94) + 0x21; 00133 return 2; 00134 } 00135 } 00136 return RET_ILSEQ; 00137 } 00138 return RET_TOOSMALL; 00139 } 00140 00141 static int 00142 big5_1_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) 00143 { 00144 if (n >= 2) { 00145 unsigned char buf[2]; 00146 int ret = big5_wctomb(conv,buf,wc,2); 00147 if (ret != RET_ILSEQ) { 00148 unsigned char s1, s2; 00149 if (ret != 2) abort(); 00150 s1 = buf[0]; 00151 s2 = buf[1]; 00152 if (!(s1 <= 0xf9)) abort(); 00153 if (!((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0xa1 && s2 <= 0xfe))) abort(); 00154 if (s1 >= 0xc9) { 00155 unsigned int t = 157 * (s1 - 0xc9) + s2 - (s2 < 0x80 ? 0x40 : 0x62); 00156 r[0] = (t / 94) + 0x21; 00157 r[1] = (t % 94) + 0x21; 00158 return 2; 00159 } 00160 } 00161 return RET_ILSEQ; 00162 } 00163 return RET_TOOSMALL; 00164 }