给他们国内做PDA,手机输入法的同行们参考(呵,写的比较粗糙):
1。字符分类:
1.1子音Cons(consonants),44个子音0xa1-0xce
这类字符比较简单,可独立对应于键盘的1-9
1( ก ข ฃ ค ฅ)2(ฆ ง จ ฉ) 3 (ช ซ ฌ ญ)
4(ฎ ฏ ฐ ฑ ฒ ณ)5(ด ต ถ ท ธ)6(น บ ป ผ ฝ)
7(พ ฟ ภ ม ย)8(ร ล ว ศ ษ)9(ส ห ฬ อ ฮ)
其中有两个0xc4,0xc6为特殊音,不在此类
1.2元音Vowels
1.3音调Tone 4个音调0xe8,0xe9.0xea,0xeb
1.4变音符Diacritics,分为上变音符,下变音符。
1.5非构成音,如数字或特殊音,一般都不提供泰文数字输入,而用阿拉伯数字替换。
具体的分类可查看<<Thai Input and output Methods>>
这个文档必须仔细阅读,要不你就没法进行输入法的编写。至少要知道LV,FV1.,FV2,FV3,BV1,.....是个什么概念
2.字符显示的属性
泰文的一个显示单位可由组成:1.top,2.above,3.base 4.below.
就是分为四层,如กี่ 就有top,above,base三部分.base一般为子音
因泰文可由以上几部分组成,因此这里就会在输入一些字符后, 光标往前走,还是和前一字符全成的问题。
这里有个字义,死字符(Dead characters):
在输入死字符后,后面再输入的字符,不能与死字符合成,必须得移动光标的字符称为死字符。如上面的音调就是死字符
3.字符显示
我们可以定义泰文字符为Cn和Cn-1,Cn-1为主导字符(base),Cn为随从字符
如果Cn为一个独立字符,就显示下个显示单位
如果Cn为一个死字符,
1.Cn-1是合成字符,则两个字符组合后,显示到下个显示单位
2.Cn-1不是合成字符,则把Cn显示到下一个显示单位上。
3.Cn-1与Cn组成为非法字符,则不显示
4.输入法规则
每个显示单位必须是以base字符为基本(base字符的意思为单个字符能独立构成一个意义,如子音)
这里不写很复杂,对于手机或PDA来说,输入法不同与PC键盘。
上面提到1-9对应的泰文字符,全部是子音。这里我们把除子音外的字符都放到一个键中,就如在英文输入法中的标点符号输入一样。
“*”号键包括的内容:
分为三类(8,5,14,共27个)
(一) ั ิ ี ึ ื ็ ุ ู
(二)่ ้ ๊ ๋
(三)เ แ โ ใ ไ ะ า ำ ๅ ฯ ๆ ฤ ฦ ฿
在输入框输入泰文时,在“*”中的字符根据前一字符Cn-1进行调整。
1. 在子音后选择第一类后不能再选择一类符号,可选择二、三类符号
2. 在子音后选择第二类后不能再选择一、二类符号,可选择三类符号
3. 在子音后选择第三类后,不能再选择一、二类符号,但可以继续选择第三类符号
4. 无子音情况下能输入第三类符号,以独立的字符存在,不能在和“*”中的叠加组合成新符。
5. 第三类中“ฤ”,“ฦ”比较特殊,和子音操作一样,可在后面选择第一、二类字符。
当然以上5点规则并不完善,你可通过<<Thai Input and output Methods>>得出标准的规则:
5。
1. 代码分析:
1-9对应的泰文数组
/* 数字键与泰文字母的对应表 *///added by yrui 20050810 for thai input
ImeEnTBL ThaiTbl[IME_THAI_CONS_COUNT + 11] = {
{'0', '0'},
{'1', 0xa1},
{'1', 0xa2},
{'1', 0xa3},
{'1', 0xa4},
{'1', 0xa5},
{'1', '1'},
{'2', 0xa6},
{'2', 0xa7},
{'2', 0xa8},
{'2', 0xa9},
{'2', '2'},
{'3', 0xaa},
{'3', 0xab},
{'3', 0xac},
{'3', 0xad},
{'3', '3'},
{'4', 0xae},
{'4', 0xaf},
{'4', 0xb0},
{'4', 0xb1},
{'4', 0xb2},
{'4', 0xb3},
{'4', '4'},
{'5', 0xb4},
{'5', 0xb5},
{'5', 0xb6},
{'5', 0xb7},
{'5', 0xb8},
{'5', '5'},
{'6', 0xb9},
{'6', 0xba},
{'6', 0xbb},
{'6', 0xbc},
{'6', 0xbd},
{'6', '6'},
{'7', 0xbe},
{'7', 0xbf},
{'7', 0xc0},
{'7', 0xc1},
{'7', 0xc2},
{'7', '7'},
{'8', 0xc3},
{'8', 0xc5},
{'8', 0xc7},
{'8', 0xc8},
{'8', 0xc9},
{'8', '8'},
{'9', 0xca},
{'9', 0xcb},
{'9', 0xcc},
{'9', 0xcd},
{'9', 0xce},
{'9', '9'},
{'/0', '/0'}
};
ImeEnTBL * ThaiTblIdx[IME_NUMBER_COUNT] = {//added by yrui 20050810 for thai input
NULL,
&ThaiTbl[1],
&ThaiTbl[2],
&ThaiTbl[3],
&ThaiTbl[4],
&ThaiTbl[5],
&ThaiTbl[6],
&ThaiTbl[7],
&ThaiTbl[8],
&ThaiTbl[9]
};
//“*”号键对应的字符
//added by yrui 20050817 for thai input
char ThaiSymbolTbl[IME_SYMBOL_ROWS][IME_THAI_SYMBOL_COLS][IME_SYMBOL_SIZE] =
{
{
{(char)0xd1, 0, 0,0},
{(char)0xd4, 0, 0,0},
{(char)0xd5, 0,0,0},
{(char)0xd6, 0, 0,0},
{(char)0xd7, 0, 0,0},
{(char)0xe7, 0, 0,0},
{(char)0xd8, 0, 0,0},
{(char)0xd9, 0, 0,0},
{(char)0xda, 0,0,0}, //第一批
{(char)0xe8, 0, 0,0},
//
// {(char)0xed, 0, 0,0},
// {(char)0xda, 0,0,0},
},
{
{(char)0xe9, 0, 0,0},
{(char)0xea, 0,0,0},
{(char)0xeb, 0, 0,0},
{(char)0xec, 0, 0,0},
{(char)0xed, 0, 0,0}, //第二批
{(char)0xe0, 0, 0,0},
{(char)0xe1, 0, 0,0},
{(char)0xe2, 0, 0,0},
{(char)0xe3, 0, 0,0},
{(char)0xe4, 0,0,0},
//
// {(char)0xed, 0, 0,0},
// {(char)0xda, 0,0,0},
},
{
{(char)0xd0, 0, 0,0},
{(char)0xd2, 0, 0,0},
{(char)0xd3, 0,0,0},
{(char)0xe5, 0, 0,0},
{(char)0xcf, 0, 0,0},
{(char)0xe6, 0, 0,0},
{(char)0xc4, 0, 0,0},
{(char)0xc6, 0, 0,0},
{(char)0xdf, 0, 0,0},
{(char)0xef, 0,0,0},
//
// {(char)0xed, 0, 0,0},
// {(char)0xda, 0,0,0},
}
};
TACchtype数组为ascii码对应的泰文字符分类
char TACchtype_[256] = {
CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 0 - 7 */
CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 8 - 15 */
CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 16 - 23 */
CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 24 - 31 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 32 - 39 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 40 - 47 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 48 - 55 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 56 - 63 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 64 - 71 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 72 - 79 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 80 - 87 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 88 - 95 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 96 - 103 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 104 - 111 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 112 - 119 */
NON, NON, NON, NON, NON, NON, NON, CTRL, /* 120 - 127 */
CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 128 - 135 */
CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 136 - 143 */
CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 144 - 151 */
CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, CTRL, /* 152 - 159 */
NON, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 160 - 167 */
CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 168 - 175 */
CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 176 - 183 */
CONS, CONS, CONS, CONS, CONS, CONS, CONS, CONS, /* 184 - 191 */
CONS, CONS, CONS, CONS, FV3, CONS, FV3, CONS, /* 192 - 199 */
CONS, CONS, CONS, CONS, CONS, CONS, CONS, NON, /* 200 - 207 */
FV1, AV2, FV1, FV1, AV1, AV3, AV2, AV3, /* 208 - 215 */
BV1, BV2, BD, NON, NON, NON, NON, NON, /* 216 - 223 */
LV, LV, LV, LV, LV, FV2, NON, AD2, /* 224 - 231 */
TONE, TONE, TONE, TONE, AD1, AD1, AD3, NON, /* 232 - 239 */
NON, NON, NON, NON, NON, NON, NON, NON, /* 240 - 247 */
NON, NON, NON, NON, NON, NON, NON, CTRL /* 248 - 255 */
};
TACio_op数组为Cn-1和Cn的组合规则
AC表示可接受
CP表示合成接受
SR表示严格规则下拒绝
RJ表示拒绝
XC表示接受,不显示
/* Table for Thai Cell Manipulation */
char TACio_op_[17][17] = {
/* Table 2: WTT I/O sequence check rules */
/* row: leading char, column: following char */
/* CTRL NON CONS LV FV1 FV2 FV3 BV1 BV2 BD TONE AD1 AD2 AD3 AV1 AV2 AV3 */
{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*CTRL*/
,{XC, AC, AC, AC, SR, SR, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*NON*/
,{XC, AC, AC, AC, AC, SR, AC, CP, CP, CP, CP, CP, CP, CP, CP, CP, CP}/*CONS*/
,{XC, SR, AC, SR, SR, SR, SR, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*LV*/
,{XC, AC, AC, AC, AC, SR, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV1*/
,{XC, AC, AC, AC, AC, SR, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV2*/
,{XC, AC, AC, AC, SR, AC, SR, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*FV3*/
,{XC, AC, AC, AC, AC, SR, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*BV1*/
,{XC, AC, AC, AC, SR, SR, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*BV2*/
,{XC, AC, AC, AC, SR, SR, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*BD*/
,{XC, AC, AC, AC, AC, AC, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*TONE*/
,{XC, AC, AC, AC, SR, SR, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD1*/
,{XC, AC, AC, AC, SR, SR, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD2*/
,{XC, AC, AC, AC, SR, SR, AC, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ, RJ}/*AD3*/
,{XC, AC, AC, AC, SR, SR, AC, RJ, RJ, RJ, CP, CP, RJ, RJ, RJ, RJ, RJ}/*AV1*/
,{XC, AC, AC, AC, SR, SR, AC, RJ, RJ, RJ, CP, RJ, RJ, RJ, RJ, RJ, RJ}/*AV2*/
,{XC, AC, AC, AC, SR, SR, AC, RJ, RJ, RJ, CP, RJ, CP, RJ, RJ, RJ, RJ}/*AV3*/
};
int TACchtype(char c)
{
return TACchtype_[c];
}
int TACio_op(char c1, char c2)
{
return TACio_op_[TACchtype_[c1]][TACchtype_[c2]];
}
以上代码可从libthai开源代码中下载
有了这个规则代码,你的输入法基本就可以成型了
你只需得到输入框中的前一个字符Cn-1,然后与ThaiSymbolTbl数组的每个字符运算一下
For(ThaiSymbolTbl)
{
Re=TACio_op(Cn-1, ThaiSymbolTbl[i])
if(re!=SR&&re!=RJ)
在“*”键中显示此字符
}
6。编辑移动
1.子音与上下标元音或声调组成后,编辑时以整体处理。
2.但删除一个合成音时,按反过来的顺序删除合成的子字符。