09年春节

再过两天就要放假,今年春节可能要在青岛度过了。阿拉伯的事业终于告一个段落,这两天总结一下阿位伯输入法的东西,希望对你有所启发。历时差不多两个月,阿位伯输入法的实现历经曲折。从代码上看,至少也能学到点东西,至少是经验吧:) 

阿拉伯输入法的实现-概述

 
最近在做的项目要实现阿拉伯输入法,它的实现涉及到了VIA的editctrol控件,EZI的输入法,arphic的排版引擎及其阿拉伯字库。他们的关系,打个比方,要画出阿拉伯语:ezi是画画的铅笔(用什么画),文鼎是画画的方法(画成什么样子),VIA是画画所用到的画纸(画在哪里)

分解开每一步的实现:
首先,输入控件Editctrol接受Onkeypress的按键消息,判断当前是Arbaic输入法,则会把按键消息传递到HandleEziKeypress_Arabic(),这个函数会记录按键消息,并按照EZI对应的键值,赋于一个全局变量中,如:
        mEziArabicInfo.pElements[mEziArabicInfo.ElementCount++] =
ZI8_CODE_LATIN_KEY4;
然后会调用EZI的API,其参数为此变量mEziArabicInfo,调用API后,对应的候选就己经赋值到此变量中。
       Zi8GetCandidates(&mEziArabicInfo);
接下来就是处理在Editctrol中显示候选。
其次,如当有四个候选时,选择其中一个的序号,此时会把该候选输出到控件Editctrol中。输出的过程是找到该序号对应的候选,调用AddChar把候选中的每个阿位伯字符一位一位的输出,由于阿位伯是Unicode所以要进行相应的转换。AddChar中会把字符插在当前光标所在位置并重新计算插入后光标的位置,这个工作就是文鼎做的。
        
AddChar
中首先会调用AddEditChar
把字符加在光标当前位置,然后会根据整个Editctrol中的输入内容来重新AllocateLineInfo()接着调用OnSetCursorRight设置插入后光标的逻辑位置。最关键的是SetCursPos()这个函数,负责处理当前的显示坐标的像素位置,阿位伯,英文,数字混和时光标位置是否定位准确就是在这里决定的,具体是由下面函数决定的:
 int16
CaretPos = ValDispOemArabicGetCaretPosition(dc, (uint8 *)LinString->String,
LinString->StringLen, CursPtr->Col);
     CursPtr->Pos->x
= EditPtr->TextRect.x + CaretPos+EDIT_TEXT_WIDTH ;
得出的CursPtr->Pos->x
即为光标显示的像素位置。
以上只是一个实现步骤的简单思路,真正的做起来要复杂很多,如要处理左右对齐的情况,以英文,还是数字开头的情况,添加,删除,移动光标的情况等等。

 

如果你有兴趣进一步了解这种忽左忽右的输入法,咱们再单独讨论:)

 

Iditu 开源

Iditu到现在己经历经了三次更新(不够快:),解决了地图的拖动,与多线程的加入.现在还有一个问题是拖动地图时可能会出现白屏(刷屏慢的问题),最近会把它解决.

Iditu最终会开源的,我想,但现在还不是时候,一个原因是自己的代码还有待完善,其次大环境还不具备.但我会把Iditu中遇到的问题在这里更新,并有尽可能详细的代码说明:)
 

从杭州归来

在杭州呆了20天,解决阿拉伯输入法光标定位的相关问题,开始在改很老的一套定位算法,后来发现这是个无底洞,项目紧急只好找了第三方,用的是文鼎的方案,经过艰难的移植,现在终于算是比较稳定了,这个项目应该在这个月的上旬就结束了,阿拉伯输入法比预想的还要麻烦些。前段时间Iditu参加了首届软件创新大赛,闯进了入围奖,没能到决赛,总结我想可能是用户群的问题,毕竟不是每个人都有一部带GPS导航的手机,但这会是趋势,所以我会继续把Iditu做的更完善些。