Back to index

im-sdk  12.3.91
wtt_isc.c
Go to the documentation of this file.
00001 
00009 #include <stdio.h>
00010 #include "wtt_isc.h"
00011 
00012 /* character classification table */
00013 #define TACTIS_CHARS 256
00014 
00015 char const tactis_chtype[TACTIS_CHARS] = {
00016     CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL,  /*  0 -  7 */
00017     CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL,  /*  8 - 15 */
00018     CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL,  /* 16 - 23 */
00019     CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL,  /* 24 - 31 */
00020     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 32 - 39 */
00021     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 40 - 47 */
00022     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 48 - 55 */
00023     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 56 - 63 */
00024     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 64 - 71 */
00025     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 72 - 79 */
00026     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 80 - 87 */
00027     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 88 - 95 */
00028     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 96 - 103 */
00029     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 104 - 111 */
00030     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 112 - 119 */
00031     NON,  NON,  NON,  NON,  NON,  NON,  NON,  CTRL,  /* 120 - 127 */
00032     CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL,  /* 128 - 135 */
00033     CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL,  /* 136 - 143 */
00034     CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL,  /* 144 - 151 */
00035     CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL,  /* 152 - 159 */
00036     NON,  CONS, CONS, CONS, CONS, CONS, CONS, CONS,  /* 160 - 167 */
00037     CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS,  /* 168 - 175 */
00038     CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS,  /* 176 - 183 */
00039     CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS,  /* 184 - 191 */
00040     CONS, CONS, CONS, CONS,  FV3, CONS,  FV3, CONS,  /* 192 - 199 */
00041     CONS, CONS, CONS, CONS, CONS, CONS, CONS, NON,   /* 200 - 207 */
00042     FV1,  AV2,  FV1,  FV1,  AV1,  AV3,  AV2,  AV3,   /* 208 - 215 */
00043     BV1,  BV2,  BD,   NON,  NON,  NON,  NON,  NON,   /* 216 - 223 */
00044     LV,   LV,   LV,   LV,   LV,   FV2,  NON,  AD2,   /* 224 - 231 */
00045     TONE, TONE, TONE, TONE, AD1,  AD1,  AD3,  NON,   /* 232 - 239 */
00046     NON,  NON,  NON,  NON,  NON,  NON,  NON,  NON,   /* 240 - 247 */
00047     NON,  NON,  NON,  NON,  NON,  NON,  NON,  CTRL   /* 248 - 255 */
00048 };
00049 
00050 /* Composibility checking tables */
00051 #define NC  0   /* NOT COMPOSIBLE - following char displays in next cell */
00052 #define CP  1   /* COMPOSIBLE - following char is displayed in the same cell
00053                                 as leading char, also implies ACCEPT */
00054 #define XC  3   /* Non-display */
00055 #define AC  4   /* ACCEPT - display the following char in the next cell */
00056 #define RJ  5   /* REJECT - discard that following char, ignore it */
00057 
00058 #define CH_CLASSES      17  /* 17 classes of chars */
00059 
00060 char const write_rules_lookup[CH_CLASSES][CH_CLASSES] = {
00061         /* Table 0: writing/outputing rules */
00062         /* row: leading char,  column: following char */
00063 /* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
00064    {XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*CTRL*/
00065   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*NON*/
00066   ,{XC, NC, NC, NC, NC, NC, NC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
00067   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*LV*/
00068   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*FV1*/
00069   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*FV2*/
00070   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*FV3*/
00071   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, CP, NC, NC, NC, NC, NC}/*BV1*/
00072   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, NC, NC, NC, NC, NC, NC}/*BV2*/
00073   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*BD*/
00074   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*TONE*/
00075   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*AD1*/
00076   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*AD2*/
00077   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC, NC}/*AD3*/
00078   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, CP, NC, NC, NC, NC, NC}/*AV1*/
00079   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, NC, NC, NC, NC, NC, NC}/*AV2*/
00080   ,{XC, NC, NC, NC, NC, NC, NC, NC, NC, NC, CP, NC, CP, NC, NC, NC, NC}/*AV3*/
00081 };
00082 
00083 char const wtt_isc1_lookup[CH_CLASSES][CH_CLASSES] = {
00084       /* Table 1: WTT default input sequence check rules */
00085       /* row: leading char,  column: following char */
00086 /* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
00087    {XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*CTRL*/
00088   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*NON*/
00089   ,{XC, AC, AC, AC, AC, AC, AC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
00090   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*LV*/
00091   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV1*/
00092   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV2*/
00093   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV3*/
00094   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*BV1*/
00095   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*BV2*/
00096   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*BD*/
00097   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*TONE*/
00098   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD1*/
00099   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD2*/
00100   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD3*/
00101   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*AV1*/
00102   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*AV2*/
00103   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, CP, RJ, RJ, RJ, RJ}/*AV3*/
00104 };
00105 
00106 /* This is copied from XFree86, but seems not follow WTT 2.0 */
00107 char const wtt_isc2_lookup[CH_CLASSES][CH_CLASSES] = {
00108       /* Table 2: WTT strict input sequence check rules */
00109       /* row: leading char,  column: following char */
00110 /* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
00111    {XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*CTRL*/
00112   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*NON*/
00113   ,{XC, AC, AC, AC, AC, RJ, AC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
00114   ,{XC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*LV*/
00115   ,{XC, AC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV1*/
00116   ,{XC, AC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV2*/
00117   ,{XC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV3*/
00118   ,{XC, AC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*BV1*/
00119   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*BV2*/
00120   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*BD*/
00121   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*TONE*/
00122   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD1*/
00123   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD2*/
00124   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD3*/
00125   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*AV1*/
00126   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*AV2*/
00127   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, CP, RJ, RJ, RJ, RJ}/*AV3*/
00128 };
00129 
00130 #if 0
00131 /* This is follow WTT 2.0 */
00132 char const wtt_isc2_lookup[CH_CLASSES][CH_CLASSES] = {
00133       /* Table 2: WTT strict input sequence check rules */
00134       /* row: leading char,  column: following char */
00135 /* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
00136    {XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*CTRL*/
00137   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*NON*/
00138   ,{XC, AC, AC, AC, AC, RJ, AC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
00139   ,{XC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*LV*/
00140   ,{XC, RJ, AC, RJ, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV1*/
00141   ,{XC, AC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV2*/
00142   ,{XC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV3*/
00143   ,{XC, AC, AC, AC, AC, RJ, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*BV1*/
00144   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*BV2*/
00145   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*BD*/
00146   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*TONE*/
00147   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD1*/
00148   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD2*/
00149   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD3*/
00150   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*AV1*/
00151   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*AV2*/
00152   ,{XC, AC, AC, AC, RJ, RJ, AC, RJ, RJ, RJ, CP, RJ, CP, RJ, RJ, RJ, RJ}/*AV3*/
00153 };
00154 #endif
00155 
00156 char const thaicat_isc_lookup[CH_CLASSES][CH_CLASSES] = {
00157       /* Table 3: Thaicat input sequence check rules */
00158       /* row: leading char,  column: following char */
00159 /* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
00160    {XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*CTRL*/
00161   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*NON*/
00162   ,{XC, AC, AC, AC, AC, AC, AC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
00163   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*LV*/
00164   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV1*/
00165   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV2*/
00166   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ} /*FV3*/
00167   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*BV1*/
00168   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*BV2*/
00169   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*BD*/
00170   ,{XC, AC, AC, AC, AC, AC, AC, CP, CP, RJ, RJ, RJ, RJ, RJ, CP, CP, CP}/*TONE*/
00171   ,{XC, AC, AC, AC, AC, AC, AC, CP, RJ, RJ, RJ, RJ, RJ, RJ, CP, RJ, RJ}/*AD1*/
00172   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, CP}/*AD2*/
00173   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD3*/
00174   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*AV1*/
00175   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*AV2*/
00176   ,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, CP, RJ, CP, RJ, RJ, RJ, RJ}/*AV3*/
00177 };
00178 
00179 char *wtt_isc_mode_names[WTT_ISC_MODES_NUM + 1] = {
00180        WTT_ISC0_NAME,
00181        WTT_ISC1_NAME,
00182        WTT_ISC2_NAME,
00183        THAICAT_ISC_NAME,
00184 };
00185 
00186 /* returns classification of a char */
00187 int THAI_chtype (unsigned char ch)
00188 {
00189     return tactis_chtype[ch];
00190 }
00191 
00192 
00193 /* returns the display level */
00194 int THAI_chlevel (unsigned char ch)
00195 {
00196     int     chlevel;
00197 
00198     switch (tactis_chtype[ch])
00199     {
00200         case CTRL:
00201             chlevel = NON;
00202             break;
00203         case BV1:
00204         case BV2:
00205         case BD:
00206             chlevel = BELOW;
00207             break;
00208         case TONE:
00209         case AD1:
00210         case AD2:
00211             chlevel = TOP;
00212             break;
00213         case AV1:
00214         case AV2:
00215         case AV3:
00216         case AD3:
00217             chlevel = ABOVE;
00218             break;
00219         case NON:
00220         case CONS:
00221         case LV:
00222         case FV1:
00223         case FV2:
00224         case FV3:
00225         default: /* if tactis_chtype is invalid */
00226             chlevel = BASE;
00227             break;
00228     }
00229     return chlevel;
00230 }
00231 
00232 
00233 /* return True if char is non-spacing */
00234 Bool THAI_isdead (unsigned char ch)
00235 {
00236     return ((tactis_chtype[ch] == CTRL) || (tactis_chtype[ch] == BV1) ||
00237             (tactis_chtype[ch] == BV2)  || (tactis_chtype[ch] == BD)  ||
00238             (tactis_chtype[ch] == TONE) || (tactis_chtype[ch] == AD1) ||
00239             (tactis_chtype[ch] == AD2)  || (tactis_chtype[ch] == AD3) ||
00240             (tactis_chtype[ch] == AV1)  || (tactis_chtype[ch] == AV2) ||
00241             (tactis_chtype[ch] == AV3));
00242 }
00243 
00244 
00245 /* return True if char is consonant */
00246 Bool THAI_iscons (unsigned char ch)
00247 {
00248     return (tactis_chtype[ch] == CONS);
00249 }
00250 
00251 
00252 /* return True if char is vowel */
00253 Bool THAI_isvowel (unsigned char ch)
00254 {
00255     return ((tactis_chtype[ch] == LV)  || (tactis_chtype[ch] == FV1) ||
00256             (tactis_chtype[ch] == FV2) || (tactis_chtype[ch] == FV3) ||
00257             (tactis_chtype[ch] == BV1) || (tactis_chtype[ch] == BV2) ||
00258             (tactis_chtype[ch] == AV1) || (tactis_chtype[ch] == AV2) ||
00259             (tactis_chtype[ch] == AV3));
00260 }
00261 
00262 
00263 /* return True if char is tonemark */
00264 Bool THAI_istone (unsigned char ch)
00265 {
00266     return (tactis_chtype[ch] == TONE);
00267 }
00268 
00269 
00270 Bool THAI_iscomposible (
00271     unsigned char    follow_ch, 
00272     unsigned char    lead_ch)
00273 {/* "Can follow_ch be put in the same display cell as lead_ch?" */
00274 
00275     return (write_rules_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)] 
00276             == CP);
00277 }
00278 
00279 Bool THAI_isaccepted (
00280     unsigned char    follow_ch, 
00281     unsigned char    lead_ch,
00282     unsigned char    mode)
00283 {
00284     Bool iskeyvalid; /*  means "Can follow_ch be keyed in after lead_ch?" */
00285 
00286 /*
00287     printf("lead_ch_class:%d, follow_ch_class: %d\n", THAI_chtype(lead_ch), THAI_chtype(follow_ch));
00288 */
00289     switch (mode)
00290     {
00291         case WTT_ISC1:
00292             iskeyvalid = 
00293           (wtt_isc1_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)] != RJ);
00294             break;
00295         case WTT_ISC2:
00296             iskeyvalid = 
00297           (wtt_isc2_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)] != RJ);
00298             break;
00299         case THAICAT_ISC:
00300             iskeyvalid =
00301        (thaicat_isc_lookup[THAI_chtype(lead_ch)][THAI_chtype(follow_ch)] != RJ);
00302             break;
00303         default:
00304             iskeyvalid = True;
00305             break;
00306     }
00307 
00308     return iskeyvalid;
00309 }
00310 
00311 int THAI_find_chtype (
00312     unsigned char    *instr, 
00313     int              chtype)
00314 {
00315 /*
00316 Input parameters:
00317     instr - input string
00318     chtype - type of character to look for
00319 Output parameters:
00320     function returns first position of character with matched chtype
00321     function returns -1 if it does not find.
00322 */
00323     int i = 0, position = -1;
00324 
00325     switch (chtype)
00326     {
00327         case DEAD:
00328             for (i = 0; *instr != '\0' && THAI_isdead(*instr); i++, instr++)
00329               ;
00330             if (*instr != '\0') position = i; 
00331             break;
00332         default:
00333             break;
00334     }
00335     return position;
00336 }
00337 
00338 int THAI_apply_scm(
00339     unsigned char    *instr, 
00340     unsigned char    *outstr, 
00341     unsigned char    spec_ch, 
00342     int              num_sp, 
00343     unsigned char    insert_ch)
00344 {
00345     unsigned char   *scan, *outch;
00346     int             i, dead_count, found_count;
00347     Bool            isconsecutive;
00348 
00349     scan = instr;
00350     outch = outstr;
00351     dead_count = found_count = 0;
00352     isconsecutive = False;
00353     while (*scan != '\0') {
00354         if (THAI_isdead(*scan))
00355             dead_count++;       /* count number of non-spacing char */
00356         if (*scan == spec_ch)
00357             if (!isconsecutive) 
00358                 found_count++;      /* count number consecutive spec char found */
00359         *outch++ = *scan++;
00360         if (found_count == num_sp) {
00361             for (i = 0; i < dead_count; i++)
00362                 *outch++ = insert_ch;
00363             dead_count = found_count = 0;
00364         }
00365     }
00366     /* what to return? */
00367     return 0; /* probably not right but better than returning garbage */
00368 }
00369