漢字庫種類非常多,但是都是按照順序排列的。前一個字節爲該漢字的區號,後一個字節爲該字的位號。每一個區記錄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;
}
結果如下: