汉字显示技术交流讲义.doc
6页汉字显示技术交流1. 字库文件基本知识 什么是字库?字库一般来说需要包含两个要素:字符的图像信息和字符编码到这些图像信息的映射字库的主要功能是将字符的编码转换为一个图片用以显示在屏幕或者用户界面上从编码到字符的映射有很多中情况,一个编码映射到多个图像,但最常见的还是一个编码一个图像 字库文件常见有哪几种?常见的字体有两大类,一类称为位图字体,或称点阵字体,这类字库用一个二值(0-1)矩阵来表示一个符号,0-1矩阵信息将在屏幕上转换为黑白图像,这样的字体包括bdf,pcf,fnt,hbf等格式;第二类称为矢量字体(outline font),这类字库中每一个符号是通过数学曲线来描述的,字体中包含了符号边界上的关键点,连线的导数信息等,字体的渲染引擎通过读取这些数学区域,然后进行一定的数学运算来进行渲染这类字体的好处是字体可以无限放大而不产生字体,使用于高质量的打印和屏幕显示矢量字体主要包括Type1和True-Type等几类, True-Type使用了二次B样条(quadratic Bézier spline)而Type1使用了三次B样条曲线(cubic Bézier spline)来描述符号边界。
2. 点阵字库和矢量字库 点阵字库 下面是16*16点阵字库的汉字字型排列0x20-0x80的ASCII码则是左边一半) 每个字型的点阵数据为16×16(横行点数×纵列点数),共256个二进制位,32个字节汉字16点阵字型数据的32个字节排列次序是以0字节开始到31字节结束,均用十六进制表示,其记录格式如下:765432107654321000字节1字节1::2::::::: 1530字节31字节 下面是24*24点阵字库的汉字字型排列 每个字型的点阵数据为24×24(横行点数×纵列点数),72个字节汉字72点阵字型数据的72个字节排列次序是以0字节开始到71字节结束,均用十六进制表示,其记录格式如下: 76543210765432107654321000字节1字节2字节1::2::::::: 2369字节70字节71字节 注:12*24的ASCII码字型占2*24=48字节,其中每行第二个字节低4Bit无意义 矢量字库 最常见的矢量字库就是TTF,即TrueType Font字库 如上图中的点即是矢量字库中需要记录的信息,这个过程就是数字化拟合过程这一步是利用专门的程序进行纯粹的数学计算,即根据字体的不同风格,按照一定的数学算法,自动地将扫描后的点阵图形抽成尽可能接近原稿的数字化信息。
字库的制作 字库的制作是一个非常复杂,工作量非常大的过程依次要经过字稿、扫描、数字 化拟合、修字、质检、整合成、测试、商品化这些步骤,这其中大部分的过程都是经过 人工逐字来完成的3. 字符编码基本知识 字符编码就是指字符的计算机内码早期的计算机使用7位的ASCII编码,为了处理汉字,设计了用于简体中文的GB2312和用于繁体中文的BIG5GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768其中有5个空位是D7FA-D7FE GB2312支持的汉字太少1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区汉字区包括21003个字符2000年的GB18030是取代GBK1.0的正式国家标准该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字注: GB2312和GBK经常提到区位码,从区位码到内码,需要在高字节和低字节上分别加上A0) 随着国际互联网的迅速发展,要求进行数据交换的需求越来越大,不同的编码体系越来越成为信息交换的障碍,而且多种语言共存的文档不断增多,单靠代码页已很难解决这些问题,于是UNICODE应运而生。
UNICODE是两字节的全编码,对于ASCII字符它也使用两字节表示代码页是通过高字节的取值范围来确定是ASCII字符,还是汉字的高字节如果发生数据损坏,某处内容破坏,则会引起其后汉字的混乱UNICODE则一律使用两个字节表示一个字符,最明显的好处是它简化了汉字的处理过程目前Unicode是采用16位编码体系,Unicode目前版本V2.0于1996公布,内容包含符号6811个,汉字20902个,韩文拼音11172个,造字区6400个,保留20249个,共计65534个 前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的而Unicode只与ASCII兼容,与GB码不兼容例如“汉”字的Unicode编码是6C49,而GB码是BABAGB18030/GBK中的汉字到Unicode中的CJK汉字有一一对应的关系,需要一个映射表来描述这种关系4. GB18030和Unicode GB18030/GBK 3区8140|A0FE(6080/6080)A140E3|A7A0(0/672)5区A840|A9A0(166/192)4区AA40-FEA0 (8160/8160)1区E1A1A1|A9FE(717/846)AAA1|AFFE(0/564)2区B0A1|F7FE(6763/6768)E2F8A1|FEFE(0/658) 通常意义上讲的GB18030其实就是GBK,因为目前为止没有一个系统完全支持所谓GB18030。
GB18030的编码是变长的,其二字节部分与GBK兼容;四字节部分是扩充的字形、字位,其编码范围是首字节0x81-0xfe、二字节0x30-0x39、三字节0x81-0xfe、四字节0x30-0x39以下讲到的GBK可等价于GB18030GB18030是国家强制性编码规范,所有PC软件都要支持的,嵌入式软件可以只支持GB2312 GBK 亦采用双字节表示(双字节字符集DBCS),总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个 GBK字库分布图如下:灰色区域是已使用区域、绿色是空白区(也叫自定义区) GB2312和GBK字库大小计算:GB2312是GBK的一个子集,即GBK的第2区,占用6768个汉字区域,所以对于16点阵GB2312来说,需要空间为:6768*32 = 216,576字节;24点阵的GB2312点阵字库则是6768*72 = 487,296字节GBK的16点阵字库需要空间:126*190 * 32 = 766,080字节;当然还可以省了些空间,因为里面有一些小的空白区域(即绿色的自定义区)。
Unicode Linux下的字符编码主要是Unicode编码UNICODE使用平面来描述编码空间,每个平面分为256行,256列,相对于两字节编码的高低两个字节 UCS 包含了用于表达所有已知语言的字符. 不仅包括拉丁语,希腊语, 斯拉夫语,希伯来语,阿拉伯语,亚美尼亚语和乔治亚语的描述, 还包括中文, 日文和韩文这样的象形文字, 以及 平假名, 片假名, 孟加拉语, 旁遮普语果鲁穆奇字符(Gurmukhi), 泰米尔语, 印.埃纳德语(Kannada), Malayalam, 泰国语, 老挝语, 汉语拼音(Bopomofo), Hangul, Devangari, Gujarati, Oriya, Telugu 以及其他数也数不清的语 UNICODE的第一个平面,称为BasicMultilingualPlane(基本多文种平面),简称BMP,目前所有语言字符几乎都在BMP中UCS 不仅给每个字符分配一个代码, 而且赋予了一个正式的名字. 表示一个 UCS 或 Unicode 值的十六进制数, 通常在前面加上 "U+", 就象 U+0041 代表字符"拉丁大写字母A". UCS 字符 U+0000 到 U+007F 与 US-ASCII(ISO 646) 是一致的, U+0000 到 U+00FF 与 ISO 8859-1(Latin-1) 也是一致的. 从 U+E000 到 U+F8FF, 已经 BMP 以外的大范围的编码是为私用保留的。
5. UTF-8和UTF-16 首先Unicode 只是分配整数给字符的编码表. 现在存在好几种将一串字符表示为一串字节的方法. 最显而易见的两种方法是将 Unicode 文本存储为2个或4个字节序列的串这两种方法的正式名称分别为 UCS-2 和 UCS-4. 除非另外指定, 否则大多数的字节都是这样的(Big endian),将一个 ASCII 或 Latin-1 的文件转换成 UCS-2 只需简单地在每个ASCII字节前插入0x00. 如果要转换成UCS-4, 则必须在每个 ASCII 字节前插入三个0x00 在 Unix 下使用 UCS-2 (或 UCS-4) 会导致非常严重的问题. 用这些编码的字符串会包含一些特殊的字符, 比如 '\0' 或 '/', 它们在 文件名和其他 C 库函数参数里都有特别的含义. 另外, 大多数使用 ASCII 文件的 UNIX 下的工具, 如果不进行重大修改是无法读取 16 位的字符的. 基于这些原因, 在文件名, 文本文件, 环境变量等地方, UCS-2 不适合作为 Unicode 的外部编码 UTF-8就是以8位为单元对UCS进行编码从UCS-2到UTF-8的编码方式如下:UCS-2编码(16进制)UTF-8 字节流(二进制)U-00000000 - U-0000007F: 0xxxxxxx U-00000080 - U-000007FF: 110xxxxx 10xxxxxx U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 例如“汉”字的Unicode编码是6C49。
6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx将6C49写成二进制是:0110 110001 0010。





