目前位置: VCer资源中心 >>> VCer文章 >>> 软件工程

[本帖已阅读5807次 分值85 回复2次] 张贴资源 发回信箱 控制面板

白乔原创:DOS时代-汉字的处理技术(三)

提供者:bluejoe 张贴时间:2004-05-24 21:21:05.0 出处:vcer.net 作者:不祥

白乔原创:DOS时代-汉字的处理技术(三)(2004-05-24 21:21:05.0)


白乔


 
级别: VCer师长
头衔: VCer创始人

经验: 21107
作品: 514
分会: 华北分会
注册: 2003-12-01 09:20:32.0
登录: 2009-01-02 17:21:44.0

2.使用点阵字库来写字

读者看到上一节的内容,恐怕会产生一种担忧:如果要写出十几个,甚至上百个字,那该需要花多少时间来拼写点阵字模呢?

我们应该感谢那些致力于UCDOS等中文操作系统的开发人员,他们在为我们提供了完美的操作系统的同时还为用户和他们的软件本身提供了属于不同字体而又庞大的汉字库(分别取名为HZK16, HZK16K,HZK16F等等),他们一笔一划地为我们创造了一个又一个行业标准,避免了用户的大量劳动。

这些字库已成为标准字库,只要熟悉其中的结构特点,就不难写出不同的汉字来。首先,标准字库是二进制文件,那些好奇的读者是无法通过文本编辑器来直接观看它是否包含有那么多的0还是1的。利用C语言的fopen()函数时,必须指明打开方式为"rb",这是非常重要的。

其次,标准字库的数据内容是按位存放的,一个字节只存一个0或1是相当浪费的,这样一个16 * 16汉字就会占用265字节!实际上一个字节的每个位都可以用来标志1和0,这样一个16 * 16汉字只占用16*16/8=32个字节。很多初学者朋友在练习中总得莫名其妙地填上一个16点阵字模信息占用32Bytes,就是这个原因。

最后,这些汉字堆砌在一起到底是按什么顺序的呢?这就有必要了解区位码的含义。人们将汉字与一些字符分成94个区(区码1-94),每个区内含有94位(位码1-94),这正如我们开辟了一个word[94][94]的二维数组。显然,第1区第1位的汉字的区位码为0101,如此类推……

区位码与前面谈到的机内码的区别在于,机内码是从161开始排列的值,而区位码是从1开始排列的,即:

高字节内码=区码+ 160(0xa0)

低字节内码=位码+160(0xa0)

作为例子,“呸”字的区位码则为3762,机内码为0xc5de。现在我们可以推想出写点阵字的基本步骤:

①获取该汉字机内码;

②由机内码推算出区位码;

③由区位码计算出记录号rec =(区码-1) *94(位码-1);

④由记录号rec计算汉字在字库中的位置offset = rec * 32L或offset= rec * 72L (24点阵字模占用24*24/8=72个字节);

⑤读取相关字模信息,画点写字。

我们谈到过字模信息是按位存放的,如何获取字节ch中的第n位的数值,许多程序以下面的GetBit ( )函数来实现:

这个程序用来测试GetBit的功能,它输出0xal的进制表示:10100001

讨论到现在,自然可以写出使用点阵字库来写字的程序:

如果你使用其它的汉字系统,或者所使用的汉字库是24点阵的,那么以上的代码就必须修改。

3.汉字的放大

很多时候确实需要汉字的放大,例如要制作一个非常漂亮的封面,或者在“圣诞节彩蛋”中突出自己的名字等等。当然,还有些时候需要缩小汉字,例如要制作一串精致的按钮菜单的时候。

诚然,利用点阵法也是可以写出一些字的,基本原理是将点放大成长zoom_x、宽zoom_y的方块,其中zoom_x和zoom_y分别为在x y方向的放大倍数。例程:

结果表明,当放大倍数大于3时,出现的字就比较难看,有的程序用“光滑处理”来改进,但既然中文操作系统提供了完整的矢量字库,我们为什么不用它呢?

汉字矢量字库大致可分为单线体、笔划轮廓体和纯轮廓体字库三种类型。不同于点阵字库,矢量字库中每个字模所占的空间长度是不确定的,因此不能简单地获取字模偏移量来显示汉字。一般矢量字库文件的开头处均有一个索引表,其中每个表项对应一个汉字的数据长度及在字库文件中的位置,即偏移量。找到汉字的位置后,即可由数据信息来写字,一般来说,不同的汉字系统提供不同的字库数据,内容格式也不同,读者应查阅相关手册才能实现对其操作,在此不再详述。

4.小汉字库的建立

实际上,程序的编制人员应该充分考虑到用户的硬盘上是否具有指定路径下的标准字库,如果没有,就必须携带一个个的字库。如果每位编程者都是这样热心的话,那用户的硬盘容量恐怕就所剩无几了。

这就引出了“小汉字库技术”,一个程序用到的汉字也许只有几十个,我们完全可以将这些所需的字存放在一个小汉字库里,当需要时就调用它。小汉字库是从大汉字库中裁剪下来的,字模的内容完全一样。小汉字库的建立有许多方法,基本上有静态、动态之分。

将预生成小汉字库的汉字存于一个文本文件中,然后用程序来访问它。从大字库的相应位置裁剪下来,这样的过程属于静态建库过程。假设原文本文件名为test.txt,观察下面的程序:

生成的汉字库放在文件testl.hzk里,以.hzk作为扩展名系笔者的杜撰,为的是将它与常见的其它类型库文件区分开。所有的建库动作一次性完成,当需要修改其中的内容时,就必须修改test.txt,之后再运行以上的程序一遍,这就是所谓“静态”的来源。如果把打开testl.hzk的操作力一式置为"ab",允许用户每次输入新的内容来增补它的建库力一式则称为“动态”过程。

以下是实现的程序清单:

本文曾经发表于《电脑爱好者》期刊杂志98年6期,版权CFan所有。

注:转载文章需注明来源:VCer.net 文章地址:http://vcer.net/2280.html

  如果你觉得VCer.net不错,而且你愿意为VCer.net捐赠一元钱,那么点击后面的捐赠按钮吧:) vcer.net捐赠

1082687209616[385,308字节]

得意,我用他的代码;

自豪,他用我的代码!

[回复该贴] [加入个人书签]
[连载系列]

[1] 白乔原创:DOS时代-汉字的处理技术(一)
[2] 白乔原创:DOS时代-汉字的处理技术(二)
[3] 白乔原创:DOS时代-汉字的处理技术(三)
[4] 白乔原创:DOS时代-汉字的处理技术(四)

[投票结果]

A: 评分 10 0% (0 票)
B: 评分 5 50% (1 票)
C: 评分 0 50% (1 票)
D: 评分 -5 0% (0 票)
E: 评分 -10 0% (0 票)

 


re:白乔原创:DOS时代-汉字的处理技术(三)
非常 感谢你的代码! 想斗胆问一句,你有TRUETYPE字体文件的相关文档,或源代码吗?

dam_chang 于 2004-11-17 11:05:12.0 编辑 [回复该贴]

re:re:白乔原创:DOS时代-汉字的处理技术(三)

...

你的代码似乎不是很完整的

sgl870927 于 2008-01-14 21:37:02.0 编辑 [回复该贴]