无辜的“联通”:
在windows下打开一个记事本,输入“联通”保存后,再次打开却发现“联通”不见了
首先了解,不同编码文本的存储,开头字节:
UTF-8: EF BB BF
UTF-16/UCS-2,little endian: FF FE
UTF-16/UCS-2,big endian: FE FF
UTF-32/UCS-4,little endian: FF FE 00 00
UTF-32/UCS-4,big endian: 00 00 FE FF
“连通”的几种编码:
GBK: C1 AA CD A8
UTF-16(big endian):DE 8F 1A 90
UTF-8: E8 BF 9E E9 80 9A
打开一个文本要确定它的编码格式有三种途径:
第一:检测文本开头字节(最理想的方法)
第二:猜测,通过读取几个字符测试出可能的编码类型(防止未加格式头)
第三:提示,当打开一个不确定编码类型的文本时可以弹出对话框,让用户来选择(如mail)
其实软件开发中可能三种方法都会用到
Microsoft在采用第二种方法进行打时出错
“联通”的错误出在TXT文件在保存时默认采用ANSI,而当打开时自动猜测成UTF-8打开
所以显示乱码,是猜错引起的。而只要我们以保存的编码方式打开就不会出问题。而“联通”这个编码是个意外
从字符编码角度分析原因:
这应该就是Microsoft程序上的bug了,且至今未找到更好的解决方案(做了优化,即可能是随机多取几字符进行测试 ,所以在“联通”后面如果再多输入几个字符就不会出现乱码了)
先看“联通”的内码(GBK):0xC1AACDA8
C1- 1100 0001
AA- 1010 1010
CD- 1100 1101
A8- 1010 1000
其中一二字节和三四字节中开头都是“110”和“10”,正好与UTF8规则里的双字节模板一致,所以就猜成按UTF-8编码方式打开了
所以只要出现类似“110”和“10”的字符编码,且以ANSI存储,自动打开都会出现乱码的情况,如“联系”和“this app can break” 等等
根据规则统计,一切字符的高字节在C0≤AA≤DF且低字节在80≤BB≤BF这个范围时,notepad都无法确认文档的格式,没有自动依照ANSI格式来显示
而“联通”就是0xC1AACDA8,刚好在上面地范围内,所以不能正常显示,像这样的字符有近二千个
所以说“联通”是无辜的
字库:
是外文字体、中文字体以及相关字符形状的电子文字字体集合,被广泛用于计算机、网络及相关电子产品上
字库分类:
按语种不同可分为:外文字库、中文字库、图形符号库;外文字库又可分为:英文字库、俄文字库、日文字库等等
按不同公司划分为:微软字库、方正字库、汉仪字库、文鼎字库、汉鼎字库、长城字库、金梅字库等等
按历史版本划分,如汉字库:GB字库、GBK字库、GB18030字库等等
按字符字形划分如:宋体、楷体、方正舒体、黑体、MingLiU、Gulim等
按字模存在形式划分为,常见的有:点阵字库、矢量字库、PostScript字库、图形字库等
以GB2312字库举例说明:
为了便于管理GB2312字库,通常采用的是区位码(内码– 0xA0A0)进行检索
假设:有一字符串str,当前字号占s_size字节,求当前字符在字库中的偏移地址offset_addr
s_row = *(str)-0xA0;
s_col = *(str+1)-0xA0;
offset_addr=(94*(s_row-1)+(s_col-1))*s_size;
读取点阵信息到buffer:
fseek(fp,offset_addr,SEEK_SET);
fread(buffer,s_size,1,fp);
6、矢量字体的应用移植:
FreeType 2被设计为一种占用空间小、高效、高度可定制的、并且可以产生可移植的高品质输出(符号图像)。可以被用在诸如图像库、展出服务器、字体转换工具、图像文字产生工具等多种其它产品上
FreeType 2的发行遵循两个开源许可:BSD样式的FreeType License和GPL
它提供一个简单的、易用的并且统一的接口实现对多种字体文件的访问
尽管点阵字体在时间和空间性能上都有较佳的表现,但是由于缺乏灵活性,不便于改变字体的大小和风格
矢量字体不像点阵字体那样直接记录字符的字模数据,而是记录字体描述信息,其中最重要的两部分是outline和hint
outline(轮廓):这是用来描述字体的基本手段,它一般由直线和贝塞尔曲线组成。贝塞尔曲线是一条由三个点确定的曲线,假设这三点的坐标是(Ax,Ay)、(Bx, By) 和(Cx, Cy),那么曲线方程为:
px = (1-t)2.Ax + 2t(1-t).Bx + t2.Cx
py = (1-t)2.Ay + 2t(1-t).By + t2.Cy
hint(精调):Outline已经描述字体的表现形式,但是数学上的正确对人眼来说并不见得合适,特别是缩放到特定的大小和分辨率的时候,字体可能变得不好看,或者不清析。hint指的是一系列的技术,用来微调字体,让字体变得更美观,更清析
字符影射表(charmap):字符对应的字体数据称为glyph,字体文件中通常带有一个字符映射表,用来把字符映射到对应glyph的索引值
矢量字体有多种不同的格式,其中TrueType用得最为广泛,它的扩展名通常为OTF或者TTF
它的文件内容由几部分组成,文件头、表目录和表。文件头描述了版本号和表的数目等信息,表目录记录了表的偏移量和大小,表则是文件的实际数据
矢量字体的处理比较麻烦,即要进行矢量计算,又要进行精调处理,相对于点阵字体处理要慢
freetype2应用移植:
freetype-2.1.10下载地址:
http://iask.sina.com.cn/u/2487717952/ish
或http://savannah.nongnu.org/download/freetype/
编译配置:
./configure --host=arm-linux --prefix=/xxx/xxx
make
make install
应用程序的编写:
常用头文件包含:
#include <ft2build.h>
#include <freetype/freetype.h>
#include <freetype/fttrigon.h>
#include <freetype/ftstroke.h>
应用程序编译:
export C_INCLUDE_PATH=/home/xiuhai/Desktop/libfree/include/:/home/xiuhai/Desktop/libfree/include/freetype2/
arm-linux-gcc -L/home/xiuhai/Desktop/libfree/lib/ -lfreetype -o t freetype_test.c
运行时要拷贝动态库到开发板lib下,TTY字体库可以拷贝到应用程序指定的位置
当新建一个face对象时,freetype2默认选择Unicode字符表
初始化freetype:
FT_Library library;
FT_Init_FreeType( &library );
加载字体创建face:
FT_Face face;
FT_New_Face(library,"simfang.ttf",0, &face)
设置字体大小(宽/高):
FT_Set_Pixel_Sizes(face, 16,0)
根据目标编码获取字符在字库中的索引:
FT_UInt glyph_index;
glyph_index = FT_Get_Char_Index(face,unicode);
按指定的大小加载字符的glyph:
FT_Load_Glyph(face,glyph_index,FT_LOAD_DEFAULT)
将指定的glyph转换成bitmap:
FT_Render_Glyph(face->glyph,FT_RENDER_MODE_MONO)
FT_GlyphSlot结构体部分成员信息:
bitmap_left:距离左边的空余像素
bitmap_top: 用于描述顶部空白区 (bitmap.rows - bitmap_top)
bitmap.rows:字符所占的行数
bitmap.width:字符所占的列数
bitmap.pitch:绝对值表示一行所占字节数
bitmap.pixel_mode:像素模式,1指单色的,8表示反走样灰度值
bitmap.buffer:glyph的点阵位图内存绶冲区
源码实例(用到的字库可以到C:\WINDOWS\Fonts去拷贝)
Freetype2其他应用:
指定字符编码集:
FT_Select_Charmap(face, FT_ENCODING_GB2312);
字形变换:
仿射、旋转、文字渲染、缩放、自居调整等
7、多国语言开发:
对于一个嵌入式产品多语言支持,一般分两部分:
一是终端本地显示界面,如菜单、图标等
二是来自外部的文件,需要在终端上进行显示
针对上面两点,都离不开Codepage与Unicode,同时还要有支持各国语言的内码表及各国语言内码所对应的字库或Unicode字库
开发工作主要集中在编码转换和字库索引这块,编码转换方式多样,效率也会不同
对于字符显示的方案:
对于本地字符串显示,由于内容比较少,可以将字符串定义在头文件中,为了便于随时修改,也可以做成XML文件
字符串可以是文本也可以是内码(字符串内码数组)
可以采用各国内码字库,不过得熟悉其编码规则,所以不怎么采用
一般采用Unicode字库,或TTY字库
Freetype2为多国语显示提供了很大方便,我们只需要佣用相应语言的TTY字库就可以方便的显示字符了
转自: http://blog.sina.com.cn/s/blog_94479040010159sq.html