点阵字库HZK32的使用方法和显示

       汉字库种类非常多,但是都是按照顺序排列的。前一个字节为该汉字的区号,后一个字节为该字的位号。每一个区记录94个汉字,位号则为该字在该区中的位置。因此,汉字在汉字库中的具体位置计算公式为:94*(区号-1)+位号-1*字节数(一个汉字字模占用的字节数。以32*32点阵字库为例,计算公式则为:(94*(区号-1)+(位号-1))*32*32/832*32字模为长和宽都是32位的数据,而一个字节为8位,所以32*32的字节数为32*32/8,下面以32*32字库为例,给出了正常显示和左转和右转的程序

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

#define FONTSIZE 32

int Not_In_Lib(char buff[FONTSIZE * FONTSIZE / 8])
{
    int i = 0;
	for (i = 0; i < FONTSIZE * FONTSIZE / 8; i++)
	{
		if (buff[i])   //如果有一个不为0,表明buff已经被修改过,字库存在此字退出此函数
			return 0;
	}
	return 1;
}

void Print_HzK_Char(char *mat, char *Out_Put_1, char *Out_Put_2)
{
	int i, j, k;
	for (j = 0; j < FONTSIZE; j++)               /*横向有4个字节,循环判断每个字节的*/
    {
		for (k = 0; k < FONTSIZE/8; k++)         /*每个字节有8位,循环判断每位是否为1*/
		{
			for (i = 0; i < 8; i++)              /*32x32点阵汉字,一共有32行*/
			{
				if (mat[j*4+k] & (0x80 >> i))   /*测试当前位是否为1*/
					printf("%s", Out_Put_1);    /*为1的显示为字符c1*/
				else
    				printf("%s", Out_Put_2);    /*为0的显示为字符c2*/
			}
		}
        printf("\n");                           /*输完一行以后,进行换行*/
    }
}

void Print_HzK_Char_Left_Rotate_90(char *mat, char *Out_Put_1, char *Out_Put_2)
{
	int i, j, k;
	for (j = 0; j < FONTSIZE / 8; j++)          /*横向有4个字节,循环判断每个字节的*/
    {
		for (k = 0; k < 8; k++)                 /*每个字节有8位,循环判断每位是否为1*/
		{
			for (i = 0; i < FONTSIZE; i++)      /*32x32点阵汉字,一共有32行*/
			{
				if (mat[i * FONTSIZE / 8 - j - 1] & (0x01 << k)) /*测试当前位是否为1*/
					printf("%s", Out_Put_1);    /*为1的显示为字符c1*/
				else
    				printf("%s", Out_Put_2);    /*为0的显示为字符c2*/
			}
			printf("\n");                       /*输完一行以后,进行换行*/
		}
	}

}

void Print_HzK_Char_Right_Rotate_90(char *mat, char *Out_Put_1, char *Out_Put_2)
{
	int i, j, k;
	for (j = 0; j < FONTSIZE / 8; j++)          /*横向有4个字节,循环判断每个字节的*/
    {
		for (k = 0; k < 8; k++)                 /*每个字节有8位,循环判断每位是否为1*/
		{
			for (i = 0; i < FONTSIZE; i++)      /*32x32点阵汉字,一共有32行*/
			{
				if (mat[(31 - i) * FONTSIZE / 8 + j] & (0x80 >> k)) /*测试当前位是否为1*/
					printf("%s", Out_Put_1);    /*为1的显示为字符c1*/
				else
    				printf("%s", Out_Put_2);    /*为0的显示为字符c2*/
			}
			printf("\n");                       /*输完一行以后,进行换行*/
		}
	}
}

int Get_HzK_Code(unsigned char *Input_Char, char buff[])
{
	int ret = 0;
	unsigned char q, w;
	unsigned long offset;
	FILE *HZK;
	char file_name[] = "HZK32";

	if ((HZK = fopen(file_name, "rb+")) == NULL) /*打开字库文件HZK32*/
	{
		printf("Can't open %s,Please add it?\n", file_name);
		system("pause");
		exit(0);
	}

	/*区码=内码(高字节)-160  位码=内码(低字节)-160*/
	q     = *(Input_Char) - 0xa0;           /*10进制的160等于16进制的A0*/
	w     = *(Input_Char + 1) - 0xa0;       /*获得区码与位码*/
	offset = (94 * (q - 1) + (w - 1)) * FONTSIZE * FONTSIZE / 8; /*计算该汉字在字库中偏移量*/

	ret = fseek(HZK, offset, SEEK_SET); /*将文件指针移动到偏移量的位置*/
	if (ret)
	{
		printf("find error!!!\n");
		fclose(HZK);
		return 0;
	}
	fread(buff, FONTSIZE * FONTSIZE / 8, 1, HZK);    /*从偏移量的位置读取32个字节*/
	if (Not_In_Lib(buff))
	{
		fclose(HZK);
		printf("Unrecognized char\n");
		return 0;
	}

	fclose(HZK);
	return 1;
}

int main(void)
{
    int count = 0;
    char English[16], Chinese[FONTSIZE * FONTSIZE / 8];
    unsigned char word[3] = "天";
    char *String1 = (char *)"*";
    char *String2 = (char *)" ";

    memset(Chinese, 0, sizeof(Chinese));
    memset(English, 0, sizeof(English));

    if (Get_HzK_Code(word, Chinese))
    {
        Print_HzK_Char(Chinese, String1,String2);
        Print_HzK_Char_Left_Rotate_90(Chinese, String1,String2);
        Print_HzK_Char_Right_Rotate_90(Chinese, String1,String2);
    }

	return 0;
}

结果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章