去年年初的时候,我在用PPC,Jarod推荐了我一款开源的BookReader - Vade Mecum。下回来一用确实还蛮不错的,因为它可以看Plucker的电子书(格式效果比HandStory好),而且还可以做note,不过问题是不显示中文!
那个时候Jarod一直在修改Vade Mecum的源码,于是我给他说了希望能加上中文显示,不过Jarod却一直钟情于加强note,他又只看英文书,所以对我的建议没时间来理睬…… 于是我开始自己研究,终于找到了修改方法。
首先找到pagination.c,它是负责格式化要显示的文字的,其中的static_process_item函数功能是从pdb的字节编码转换成UNICODE。就从这里开始做起吧: (cvs 0.6.2的代码)
if( state->buffer[*position] != '\0' )
{
item->item_type = IT_CHAR; // 这里表示类型是显示字符
item->c = state->buffer[*position]; // 这个c的类型是TCHAR,而buffer是unsigned char
*position += 1;
首先需要说明一下的是Plucker是Palm上的软件,不是UNICODE的,所以buffer是char。
对于英文这种1char的字符集来说,这段代码没有问题,DrawText能一个字母一个字母的显示,但是对中文这类2chars的字符集就不行了。DrawText会半个汉字半个汉字的显示,当然就是大家看到的乱码了。
知道了以上这些原理修改起来就很简单了,在后面增加:
if ((item->c>=0x81) && (item->c<0xff) && (state->buffer[*position]!=0x7F)) {
char tmp[2];
TCHAR totmp;
int ret;
tmp[0] = item->c & 0xff;
tmp[1] = state->buffer[*position];
ret = MultiByteToWideChar(936, 0, tmp, 2, &totmp, 1);
if (ret == 1) {
item->c = totmp;
*position += 1;
}
} else if (item->c == 0x09) { // tab => ' '
item->c = 32;
}
上面的代码说明了把2chars的一个汉字转换成UNICODE,如果遇到TAB转换成空格。注意的是GB汉字的判断: 0x8140-0xFEFE(除去xx7F);CodePage 936表示GB,具体可以查MSDN。
现在已经可以很好的显示GB码的文档了,不过默认字体下的显示效果很不好,因为默认的字体显示效果不好。修改这个不难,在library.c中修改为一下这个即可:)
void Library_initializeDefaults( FormattingDefaults *options )
{
wcscpy( options->normal_face, L\"宋体\" );
wcscpy( options->monotype_face, L\"宋体\" );
options->font_size = 12;
来张效果图看看吧:

PS:如果你要转换成其他编码格式,比如BIG5,找到相应的编码规范和CodePage就可以了:)
那个时候Jarod一直在修改Vade Mecum的源码,于是我给他说了希望能加上中文显示,不过Jarod却一直钟情于加强note,他又只看英文书,所以对我的建议没时间来理睬…… 于是我开始自己研究,终于找到了修改方法。
首先找到pagination.c,它是负责格式化要显示的文字的,其中的static_process_item函数功能是从pdb的字节编码转换成UNICODE。就从这里开始做起吧: (cvs 0.6.2的代码)
if( state->buffer[*position] != '\0' )
{
item->item_type = IT_CHAR; // 这里表示类型是显示字符
item->c = state->buffer[*position]; // 这个c的类型是TCHAR,而buffer是unsigned char
*position += 1;
首先需要说明一下的是Plucker是Palm上的软件,不是UNICODE的,所以buffer是char。
对于英文这种1char的字符集来说,这段代码没有问题,DrawText能一个字母一个字母的显示,但是对中文这类2chars的字符集就不行了。DrawText会半个汉字半个汉字的显示,当然就是大家看到的乱码了。
知道了以上这些原理修改起来就很简单了,在后面增加:
if ((item->c>=0x81) && (item->c<0xff) && (state->buffer[*position]!=0x7F)) {
char tmp[2];
TCHAR totmp;
int ret;
tmp[0] = item->c & 0xff;
tmp[1] = state->buffer[*position];
ret = MultiByteToWideChar(936, 0, tmp, 2, &totmp, 1);
if (ret == 1) {
item->c = totmp;
*position += 1;
}
} else if (item->c == 0x09) { // tab => ' '
item->c = 32;
}
上面的代码说明了把2chars的一个汉字转换成UNICODE,如果遇到TAB转换成空格。注意的是GB汉字的判断: 0x8140-0xFEFE(除去xx7F);CodePage 936表示GB,具体可以查MSDN。
现在已经可以很好的显示GB码的文档了,不过默认字体下的显示效果很不好,因为默认的字体显示效果不好。修改这个不难,在library.c中修改为一下这个即可:)
void Library_initializeDefaults( FormattingDefaults *options )
{
wcscpy( options->normal_face, L\"宋体\" );
wcscpy( options->monotype_face, L\"宋体\" );
options->font_size = 12;
来张效果图看看吧:

PS:如果你要转换成其他编码格式,比如BIG5,找到相应的编码规范和CodePage就可以了:)
开源项目--GSPlay



2005/03/05 14:10 

插件的皮肤一定要放在这样的路径里面吗?
在存储卡里面建一个这样的文件夹可以吗?还是非要跟主程序放在一起?我都试过了,还是不行!前一版本的我都能正常使用。请指教!