FLTK 1.3.0
big5_emacs.h
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 }