`
hzy3774
  • 浏览: 996917 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

HZK16.dat解析及其在字符显示中应用

 
阅读更多

    在嵌入式显示设备中如果有足够大的flash,我们就可以用数百KB空间来存储一个HZK16字库文件用于显示16*16汉字,免得还要自己提取字模。

    HZK16字库是符合GB2312标准的16×16点阵字库,HZK16的GB2312-80支持的汉字有6763个,符号682个. 

其中一级汉字有 3755个,按声序排列,二级汉字有3008个,按偏旁部首排列. 

我们在一些应用场合根本用不到这么多汉字字模, 所以在应用时就可以只提取部分字体作为己用.

HZK16字库里的16×16汉字一共需要256个点来显示, 也就是说需要32个字节才能达到显示一个普通汉字的目的.

我们知道一个GB2312汉字是由两个字节编码的,范围为0xA1A1~0xFEFE. 

A1-A9为符号区, B0到F7为汉字区. 每一个区有94个字符(注意:这只是编码的许可范围,不一定都有字型对应,比如符号区就有很多编码空白区域).

    一个汉字占两个字节,这两个中前一个字节为该汉字的区号,后一个字节为该字的位号.

其中, 每个区记录94个汉字, 位号为该字在该区中的位置. 所以要找到"我"在hzk16库中的位置就必须得到它的区码和位码.

区码:汉字的第一个字节-0xA0 (因为汉字编码是从0xA0区开始的, 所以文件最前面就是从0xA0区开始, 要算出相对区码)

位码:汉字的第二个字节-0xA0

这样我们就可以得到汉字在HZK16中的绝对偏移位置:

    offset=(94*(区码-0xa1)+(位码-0xa1))*32

如何知道一个汉字的区码和位码呢,可以用一个小程序来计算:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
	unsigned char code[2] = {0};
	puts("请输入一个汉字:");
	gets((char*)code);
	printf("区码:%d 位码:%d",code[0],code[1]);
	return EXIT_SUCCESS;
}

 

 知道区位码就可以计算出字模数据在字库文件中的绝对偏移地址:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
	int posi;
	unsigned char code[2] = {0};
	puts("请输入一个汉字:");
	gets((char*)code);
	printf("区码:%d 位码:%d\n",code[0],code[1]);
	posi = ((code[0] - 0xa1) * 94 + code[1] - 0xa1)*32;
	printf("偏移值为: %d\n", posi);
	return EXIT_SUCCESS;
}

 

 

有了文件,又有了偏移量,我们就可以对文件进行读取,取出一个汉字所需要的32字节字模数据,并将该字模显示出来了:

 

 

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	long int offset;
	unsigned char code[2] = {0};
	unsigned char buffer[32];		//存储一个汉字所用的32个字节
	unsigned char i,j;
	FILE *fp = NULL;

	puts("请输入一个汉字:");
	gets((char*)code);
	printf("区码:%d 位码:%d\n", code[0], code[1]);		//显示区位码
	offset = ((code[0] - 0xa1) * 94 + code[1] - 0xa1) * 32;		//计算绝对偏移地址
	printf("偏移值为: %ld\n", offset);

	fp = fopen("hzk16.dat", "rb");	//二进制只读方式打开,261KB
	if (fp == NULL )				//如果打开失败
	{
		printf("打开字库失败\n");
		return 0;
	}

	fseek(fp,offset,0);				//根据偏移寻找到该字字模的第一个字节
	for (i = 0; i < 32; ++i) {		//连续读取32个字节
		buffer[i] = fgetc(fp);
	}

	for (i = 0; i < 32; ++i) {		//将32个字节顺序打印
		for (j = 0; j < 8; ++j) {
			if (buffer[i] & 0x80) {
				printf("@@");
			}else{
				printf("  ");
			}
			buffer[i] <<= 1;
		}
		if (i % 2) {
			printf("\n");			//如果i%2==1说明该字节是靠后的那个字节,显示完后要换行
		}
	}

	return EXIT_SUCCESS;
}

 

 

 

此时,HZK16通过C代码解析出来了。但是采用这种字库毕竟有局限,如“囧”字,是无法显示出来的,很多没有收录的新字在显示时还是不得不采用字模方式:



 值

 

  • 大小: 8 KB
  • 大小: 11 KB
  • 大小: 34 KB
  • 大小: 14.4 KB
分享到:
评论

相关推荐

    hzk16-uicode点整字库文件内含3k多中文简体字符点整码

    在处理HZK16.dat这类字库文件时,开发者可能需要编写特定的程序来解析和显示其中的字符。这涉及到读取文件,解码点阵数据,并将其转化为屏幕上的像素。为了提高效率,一些优化技术可能会被采用,比如使用位图操作来...

    16x16字模.zip

    2. 字模.exe - 这是一个可执行文件,很可能是一个程序,用于处理或显示HZK16.dat中的字模。.exe文件是Windows操作系统中的可执行程序格式,用户可以通过运行这个程序来查看、编辑或转换16x16字模。 使用这样的工具...

    字模提取软件(用来提取点阵的16进制数,功能同PICKHZB)

    HZK16.dat很可能是包含16x16点阵汉字的字库,这种大小的点阵能提供相对较高的清晰度,适合在有限的显示空间内展示汉字。 在编程中,特别是在汇编语言(ASM)环境下,直接使用这些16进制值可以节省内存和计算资源。...

    电脑模拟LED跑马灯的程序

    5. **ASCII编码**:ASC16.dat可能包含ASCII编码的数据,ASCII码是用于表示文本的一种标准,程序可能通过解析这些编码来显示特定的字符序列。 6. **执行文件**:LED.exe是可执行文件,意味着它是已经编译好的程序,...

    LED显示屏详解文档内包含了LED显示屏详细介绍和选型分析

    例如,`点阵提取.CAB`可能涉及到点阵显示技术,`Hzk16f.dat`和`Hzk16.dat`可能是汉字字库文件,用于显示中文字符。`www.hd-xt网站介绍.doc`可能提供了更多关于LED显示屏厂商的信息,`setup.exe`和`SETUP.LST`可能与...

    高级语言程序设计(SIST000812)第3次实验报告-2020疫情版.docx

    此任务涉及从16×16点阵汉字库文件"HZK16.dat"中读取并显示汉字。关键步骤如下: - 获取输入:从用户处接收一个汉字的输入。 - 汉字内码计算:根据GB2312-80编码规则,计算输入汉字的区位码,然后转换为内码。 - 从...

    C语言参考试题

    数码管显示在实际应用中非常常见,尤其在电子设备的状态显示中,如电梯楼层显示、时钟、家电控制面板等。通过7段LED或LCD构成的数字形状,可以显示0至9的数字。 #### 错误分析与修正: 1. **退出机制问题**:原程序...

Global site tag (gtag.js) - Google Analytics