汉字是方块字,宽高相等的汉字库在嵌入式领域有着广泛的应用,且其解析也相对来说是比较简单的。
汉字在汉字库中的索引一般会遵循GB2312/GBK编码规则,GB2312/GBK规定汉字编码由2个字节组成,其中低字节区码,高字节为位码。本文以最常见的UCDOS中16x16的宋体字库HZK16来演示汉字的显示方法,HZK16中汉字的存放基于GB2312编码的顺序,每个汉字的点阵数据占32个字节,每个字节表征8个点的状态,每行从左至右的点的状态分别对应字节从高到低的位值。
汉字在汉字库中的索引一般会遵循GB2312/GBK编码规则,GB2312/GBK规定汉字编码由2个字节组成,其中低字节区码,高字节为位码。本文以最常见的UCDOS中16x16的宋体字库HZK16来演示汉字的显示方法,HZK16中汉字的存放基于GB2312编码的顺序,每个汉字的点阵数据占32个字节,每个字节表征8个点的状态,每行从左至右的点的状态分别对应字节从高到低的位值。
下面提供完整的演示程序以供参考,
#include <stdio.h>
#define FONT_SIZE (16) /* 字体大小 */
/*
获取汉字在汉字库中的索引位置
根据GB2312/GBK编码规则,汉字的低字节hz[0]是区码,高字节hz[1]是位码,汉字库从区位码0xa1a1开始存放汉字
*/
#define HZ_INDEX(hz) ((hz[0] - 0xa1) * 94 + (hz[1] - 0xa1))
#define DOTS_BYTES (FONT_SIZE * FONT_SIZE / 8) /* 汉字点阵数据所占的字节数 */
int main(int argc, char* argv[])
{
FILE* hzk;
unsigned char song[2] = "\xcb\xce"; /* “宋”字的区位码为0xcbce */
unsigned char dots[DOTS_BYTES];
unsigned char b;
int i, j, k;
/* 打开汉字库hzk16,并从中提取“宋”字的点阵数据 */
if((hzk = fopen("hzk16", "rb")) == NULL)
{
return -1;
}
fseek(hzk, HZ_INDEX(song) * DOTS_BYTES, SEEK_SET);
fread(dots, sizeof(unsigned char), DOTS_BYTES, hzk);
fclose(hzk);
/* 用“*”号根据点阵数据显示“宋”字 */
for(i = 0; i < FONT_SIZE; i++)
{
/* 每行共FONT_SIZE / 8个字节 */
for(j = 0; j < FONT_SIZE / 8; j++)
{
b = dots[i * 2 + j];
/* 从左至右的点分别对应字节从高到低的位值 */
for(k = 0; k < 8; k++)
{
if(b & 0x80)
printf("%c ", '*');
else
printf(" ");
b <<= 1;
}
}
printf("\n");
}
return 0;
}
程序编译运行后会出现如下的显示效果,
*
*
* * * * * * * * * * * * * *
* *
* * *
*
* *
* * * * * * * * * * * * * * *
* * *
* * *
* * * *
* * * * *
* * *
* *
*
*