仅当作学习笔记。
步骤:
1.制作字库
首先制作汉字的图片字库,可使用bitmap font generator软件制作,然后用利用GIMP图片编辑器把图片字库转换为C源文件,最后利用得到的C文件与minui/mkfont.c文件一起编译,执行后就会得到字库头文件。注意修改结构体名以及相应cwidth和cheight(字符长宽)。
2.修改代码
用刚才制作的字库头文件替换原有的字库头文件,然后修改graphics.c文件, 添加两个函数,并修改gr_text函数,所有修改如下:
int getGBCharID(unsigned c1, unsigned c2) { if (c1 >= 0xB0 && c1 <=0xF7 && c2>=0xA1 && c2<=0xFE) { return (c1-0xB0)*94+c2-0xA1; } return -1; } int getUNICharID(unsigned short unicode) { int i; for (i = 0; i < UNICODE_NUM; i++) { if (unicode == unicodemap[i]) return i; } return -1; } int gr_text(int x, int y, const char *s) { GGLContext *gl = gr_context; GRFont *font = gr_font; unsigned off; unsigned off2; unsigned off3; int id; unsigned short unicode; y -= font->ascent; gl->bindTexture(gl, &font->texture); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); while((off = *s++)) { if (off < 0x80) { off -= 32; if (off < 96) { if ((x + cw_en) >= gr_fb_width()) return x; gl->texCoord2i(gl, (off * font->cwidth) - x, 0 - y); gl->recti(gl, x, y, x + cw_en, y + font->cheight); } x += cw_en; } else { if ((off & 0xF0) == 0xE0) { off2 = *s++; off3 = *s++; unicode = (off & 0x1F) << 12; unicode |= (off2 & 0x3F) << 6; unicode |= (off3 & 0x3F); id = getUNICharID(unicode); //LOGI("%X %X %X %X %d", off, off2, off3, unicode, id); if (id >= 0) { if ((x + font->cwidth) >= gr_fb_width()) return x; gl->texCoord2i(gl, ((id % 96) * font->cwidth) - x, (id / 96 + 1) * font->cheight - y); gl->recti(gl, x, y, x + font->cwidth, y + font->cheight); x += font->cwidth; } else { x += font->cwidth; } } else { x += cw_en; } } } return x; }
至此,汉化完成。
一个注意点,含有汉字显示的文件要保存为GB2312格式,保存为UTF-8会显示异常。
其实已经有人实现了汉化并上传到了github,上述代码修改也是参考github上的代码完成的。
github地址为:https://github.com/xiaolu/cmw_recovery_cn.git
开源万岁!
另外,补充一些基础知识。
ASCII、GB2312、Unicode、UTF8
ASCII
ASCII(美国信息互换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。
ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符。其中:
0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符),如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(振铃)等;通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;ASCII值为8、9、10 和13 分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响。
32~126(共95个)是字符(32sp是空格),其中48~57为0到9十个阿拉伯数字
65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。
同时还要注意,在标准ASCII中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。
后128个称为扩展ASCII码,目前许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展ASCII 码允许将每个字符的第8 位用于确定附加的128 个特殊符号字符、外来语字母和图形符号。
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-16626.png
图 1 ASCII表
GB2312
GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集——基本集》,由国家标准总局发布,1981年5月1日实施,通行于大陆。新加坡等地也使用此编码。
它是计算机可以识别的编码,适用于汉字处理、汉字通信等系统之间的信息交换。基本集共收入汉字6763个和非汉字图形字符682个。整个字符集分成94个区,每区有94个位。每个区位上只有一个字符,因此可用所在的区和位来对汉字进行编码,称为区位码。
每个汉字也都有在GB2312中的区位码,用两个字节表示。
汉字编码范围,区码:B0 ~ F7,位码:A1 ~ FE
汉字编码后续标准如,GB18030, 对GB2312完全兼容。
code +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
B0A0 啊 阿 埃 挨 哎 唉 哀 皑 癌 蔼 矮 艾 碍 爱 隘
B0B0 鞍 氨 安 俺 按 暗 岸 胺 案 肮 昂 盎 凹 敖 熬 翱
B0C0 袄 傲 奥 懊 澳 芭 捌 扒 叭 吧 笆 八 疤 巴 拔 跋
B0D0 靶 把 耙 坝 霸 罢 爸 白 柏 百 摆 佰 败 拜 稗 斑
B0E0 班 搬 扳 般 颁 板 版 扮 拌 伴 瓣 半 办 绊 邦 帮
B0F0 梆 榜 膀 绑 棒 磅 蚌 镑 傍 谤 苞 胞 包 褒 剥
...
...
...
code +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
F7A0 鳌 鳍 鳎 鳏 鳐 鳓 鳔 鳕 鳗 鳘 鳙 鳜 鳝 鳟 鳢
F7B0 靼 鞅 鞑 鞒 鞔 鞯 鞫 鞣 鞲 鞴 骱 骰 骷 鹘 骶 骺
F7C0 骼 髁 髀 髅 髂 髋 髌 髑 魅 魃 魇 魉 魈 魍 魑 飨
F7D0 餍 餮 饕 饔 髟 髡 髦 髯 髫 髻 髭 髹 鬈 鬏 鬓 鬟
F7E0 鬣 麽 麾 縻 麂 麇 麈 麋 麒 鏖 麝 麟 黛 黜 黝 黠
F7F0 黟 黢 黩 黧 黥 黪 黯 鼢 鼬 鼯 鼹 鼷 鼽 鼾 齄
unicode
通用字符集
UTF8
可变长编码,汉字3字节表示。具体可参考RFC3629。
D2BB 4E00 E4 B8 80 一
B6A1 4E01 E4 B8 81 丁
C6DF 4E03 E4 B8 83 七
CDF2 4E07 E4 B8 87 万
D5C9 4E08 E4 B8 88 丈
C8FD 4E09 E4 B8 89 三
C9CF 4E0A E4 B8 8A 上
CFC2 4E0B E4 B8 8B 下
D8A2 4E0C E4 B8 8C 丌
...
...
...
F6B8 9F88 E9 BE 88 龈
F6B9 9F89 E9 BE 89 龉
F6BA 9F8A E9 BE 8A 龊
C8A3 9F8B E9 BE 8B 龋
F6BB 9F8C E9 BE 8C 龌
C1FA 9F99 E9 BE 99 龙
B9A8 9F9A E9 BE 9A 龚
EDE8 9F9B E9 BE 9B 龛
B9EA 9F9F E9 BE 9F 龟
D9DF 9FA0 E9 BE A0 龠