汉字库种类非常多,但是都是按照顺序排列的。前一个字节为该汉字的区号,后一个字节为该字的位号。每一个区记录94个汉字,位号则为该字在该区中的位置。因此,汉字在汉字库中的具体位置计算公式为:(94*(区号-1)+位号-1)*字节数(一个汉字字模占用的字节数)。以32*32点阵字库为例,计算公式则为:(94*(区号-1)+(位号-1))*32*32/8。32*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;
}
结果如下: