2007-05-16

figlet 中文支持

figlet的帮助里说它支持多字节字符,如CJK字符。

不过这肯定需要字体文件,我查到它叫figfonts-CJK,但是不大容易下到,后来发现Debian里虽然package下不来,但是src可以,解开以后赫然发现了gb16fs.flf,呵呵,把里面所有的flf和flc文件放到/usr/share/figlet里就好了,注意要去掉目录,只把文件拷过来。

本以为现在就行了,可是“figlet -f gb16fs 王璐”是乱码,又查了查帮助,说是需要control file, figfonts-CJK自带了一些,叫unshift, iso2022, big5等,但是都试了一遍还是不行。

仔细看了figfont.txt, 它描述了figlet的字体文件和控制文件的格式,我发现控制文件中应当用b命令,但是后来发现用了也不行。

再看一眼figfont.txt中关于command的说明,发现h命令类似,只不过是针对HZ编码的,是以"~{"为开始符,然后把以后每两个字节都当成一个汉字处理,直到遇到"~}"为止。我写个CPP看“王”的GB编码,是0xcdf5, 在gb16fs 对应于0x4d75, 我又看了下unshift.flc,这不就是我想要的么,unshift里定义的编码转换就是把每个字节的首二进制位清零,那么0xcdf5就应该变成0x4d75,但是仔细一看又不对了,每个t命令接的两个区间应该等大,而它里面第一个区间都是以\0x??7E结尾的,显然不对,应该改为\0x??FE,于是我另存了个wl.flc,修正了这个bug

现在试“figlet -f wl 王璐” 仍然不行,直觉告诉了我,它仍没有按多字节处理,又查了下gb16fs.flf,果然乱码的第一个符号就是202,即0xcd,“王”的第一个字节!

于是改用h命令强制处理双字节,并把输入改为"~{王璐~}",字体仍用gb16fs,控制文件用wl(已加入wl.flc),于是, 出现了!!!

这就是成功的一大步了,说明了h命令是好的,字体文件也是好的,figlet也确实具有处理多字节字符的能力,于是目标锁定在b命令上

文档上说b命令每次读一个字符,如果小于0x80则当单字节字符输出,否则再读入一个字符,一起当作双字节字符输出。看似这应当正常工作,但是就是不行。

然后我怒了,下了个源码看(是到官方地址下的,源里只有2.2.1,没有2.2.2,但是差别应该不大),在figlet.c中,742行附近为判断输入命令的,可见b命令使得multibyte值为1.而getinchr中对
multibyte不同值对应的模式都有说明,看似multibyte=1对应的DBCS模式也是正常的。

但是,具体一看getinchr()函数,赫然发现multibyte==1时执行的竟然是只把0x80~0x94和0xE0~0xEF区间的字节当作双字节起始字节!!多么大的bug啊。这个应该是和
SHIFT-JIS相同(如果它对SHIFT-JIS的描述是正确的),不过也难怪,毕竟老外不了解CJK,另外它们也不会去测试这个,因此这个bug一直没发现(至少主页上没说)。

那当然改掉它了,改成0x80~0xFF区间就行了,另外我还在wl.flc上加了一行t \0xFFA1-\0xFFFE \0x7F21-\0x7F7E

编译时要设一下font目录,然后编译安装,然后还要把/usr/share/figlet里的字体和控制文件拷出来一份。

然后。。。哇哈哈哈。。。终于出现了!!!
发表评论