本系统是对中文字库HZK16和ASC16字库进行操作
HZK16字库中每一个中文字符使用的是32字节的点阵信息,ASC16字库是16字节的点阵信息打印
本文实现了中文汉字的点阵信息打印和字符的操作,包括插入未知字符(囧)(需要借助软件PCtoLCD.exe实现点阵信息的提取)
/**************************************************************************
** this C source code is made for HZK16 and ASC16 characters system ***
** ***
** newplan 2013.9 in UESTC ***
**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//typedef unsigned int WORD;
//typedef unsigned char BYTE;
/**********************************************************************************************/
int Get_Asc_Code(unsigned char *Get_Input_Char,char buff[]);
int Get_HzK_Code(unsigned char *Get_Input_Char,char buff[]);
void Print_Asc_Char(char *mat,char *Out_Put_1,char *Out_Put_2);
void Print_HzK_Char(char *mat,char *Out_Put_1,char *Out_Put_2);
unsigned long Judge_type_char(unsigned char *Get_Input_Char,unsigned long *offset,int *length);
int Delete_Char_From_Lib(char *character,unsigned long offset,char *Lib_Name);
int Get_Char_Model(unsigned char buff_input[32]);
int Not_In_Lib(char buff[32]);
int transpose(char chaned[16][16]);
void distranspose(char mat[][2],char **array);
int asistant_insert(unsigned char *mat);
void change(char mat[][2],char **array);
/**********************************************************************************************/
int output_system(void);
int insert_system(void);
int delete_system(void);
//*******************************************************************
// Method: Get_Asc_Code
// FullName: Get_Asc_Code
// Access: public
// Returns: int
// Qualifier: 得到英文字符的字模信息,存入数组
// Parameter: unsigned char * Get_Input_Char 要得到字模信息的字符指针
// Parameter: char buff[] 存储得到字模信息的数组
//********************************************************************
int Get_Asc_Code(unsigned char *Get_Input_Char,char buff[])
{
unsigned long offset;
FILE *ASC;
/*打开字库文件asc16*/
if((ASC=fopen("C:\\experience\\ASC16","rb+"))==NULL)
{
printf("Can't open asc,Please add it?");
system("pause");
exit(0);
}
offset = *(Get_Input_Char)*16+1; /*通过ascii码算出偏移量*/
fseek(ASC,offset,SEEK_SET); /*将文件指针移动到偏移量的位置*/
fread(buff, 16, 1, ASC); /*从偏移量的位置读取32个字节*/
printf("ASCII:%d,offset:%d \n\r",*Get_Input_Char,offset);
fclose(ASC);
return 1;
}
//*****************************************************************************
// Method: Print_Asc_Char
// FullName: Print_Asc_Char
// Access: public
// Returns: void
// Qualifier: 根据字模信息输出英文字符
// Parameter: char * mat 字模指针
// Parameter: char * Out_Put_1 字模中为1的点显示的字符,也就是前景字符
// Parameter: char * Out_Put_2 字模中为0的点显示的字符,也就是背景字符
//***************************************************************
void Print_Asc_Char(char *mat,char *Out_Put_1,char *Out_Put_2)
{
int i,j;
for(i=0; i<16; i++) /* 8x16的点阵,一共有16行*/
{
for(j=0; j<8; j++) /*横向一个字节8位,依次判断每位是否为0*/
if(mat[i]&(0x80>>j)) /*测试当前位是否为1*/
printf("%s",Out_Put_1); /*为1的显示为字符c1*/
else printf("%s",Out_Put_2); /*为0的显示为字符c2*/
printf("\n"); /*输完一行以后,进行换行*/
}
}
/***************************************************************************/
// Method: Get_HzK_Code ***
// FullName: Get_HzK_Code ***
// Access: public ***
// Returns: int ***
// Qualifier: 得到汉字字符的字模信息,存入数组 ***
// Parameter: unsigned char * Get_Input_Char 要得到字模信息的字符指针 ***
// Parameter: char buff[] 存储字模信息的数组 ***
/***************************************************************************/
int Get_HzK_Code(unsigned char *Get_Input_Char,char buff[])
{
int not_find=0;
unsigned char qh,wh;
unsigned long offset;
FILE *HZK;
char file_name[]="C:\\experience\\HZK16";
if((HZK=fopen(file_name,"rb+"))==NULL)/*打开字库文件hzk16*/
{
printf("Can't open haz16,Please add it?");
system("pause");
exit(0);
}
/*区码=内码(高字节)-160 位码=内码(低字节)-160*/
qh = *(Get_Input_Char) -0xa0; /*10进制的160等于16进制的A0*/
wh = *(Get_Input_Char+1) -0xa0; /*获得区码与位码*/
offset = (94*(qh-1)+(wh-1))*32L; /*计算该汉字在字库中偏移量*/
not_find=fseek(HZK,offset,SEEK_SET); /*将文件指针移动到偏移量的位置*/
if (not_find)
{
printf("未查到该区!error!!!\n");
fclose(HZK);
return 0;
}
fread(buff,32,1,HZK); /*从偏移量的位置读取32个字节*/
if (Not_In_Lib(buff))
{
fclose(HZK);
printf("有未识别字符!\n");
system("pause");
return 0;
}
printf("qh:%d,wh:%d,offset:%ld\n\r",qh,wh,offset);
fclose(HZK);
return 1;
}
//**************************************************************************
// Method: Print_HzK_Char ***
// FullName: Print_HzK_Char ***
// Access: public ***
// Returns: void ***
// Qualifier: 根据字模信息输汉字字符 ***
// Parameter: char * mat 字模指针 ***
// Parameter: char * Out_Put_1 字模中为1的点显示的字符,也就是前景字符 ***
// Parameter: char * Out_Put_2 字模中为0的点显示的字符,也就是背景字符 ***
//**************************************************************************
void Print_HzK_Char(char *mat,char *Out_Put_1,char *Out_Put_2)
{
int i, j, k;
for(i=0; i<16; i++) /*16x16点阵汉字,一共有16行*/
{
for(j=0; j<2; j++) /*横向有2个字节,循环判断每个字节的*/
for(k=0; k<8; k++) /*每个字节有8位,循环判断每位是否为1*/
if(mat[i*2+j]&(0x80>>k)) /*测试当前位是否为1*/
printf("%s",Out_Put_1); /*为1的显示为字符c1*/
else printf("%s",Out_Put_2); /*为0的显示为字符c2*/
printf("\n"); /*输完一行以后,进行换行*/
}
}
//*****************************************
// Method: Not_In_Lib ***
// FullName: Not_In_Lib ***
// Access: public ***
// Returns: int ***
// Qualifier: /*判断字符是不是在字库里 ***
// Parameter: char buff[] ***
//*****************************************
int Not_In_Lib(char buff[32])
{
for (int i=0; i<32; i++)
{
if (buff[i]) //如果有一个不为0,表明buff【】已经被修改过,字库存在此字退出此函数
return 0;
}
return 1;
}
//******************************************************************
// Method: Select_type_char ***
// FullName: Select_type_char ***
// Access: public ***
// Returns: int 0 表示成功; ***
// Qualifier: 判断是中文字符还是英文单字节字符,并算出偏移量 ***
// Parameter: unsigned char * Get_Input_Char ***
// Parameter: int * offset 偏移量 ***
// Parameter: int * length 缓冲区的长度 ***
//******************************************************************
unsigned long Judge_type_char(char *Get_Input_Char,unsigned long *offset,int *length)
{
if (Get_Input_Char[2]==0 && Get_Input_Char[1]==0)//asc16
{
*offset = *(Get_Input_Char)*16+1;
*length = 16;
}
else //HZK16
{
unsigned char qh = (unsigned char)Get_Input_Char[0] -0xa0; /*10进制的160等于16进制的A0*/
unsigned char wh = (unsigned char)Get_Input_Char[1] -0xa0; /*获得区码与位码*/
*offset = (94*(qh-1)+(wh-1))*32L; /*计算该汉字在字库中偏移量*/
*length = 32;
}
return *offset;
}
//**************************************************************
// Method: Get_Char_Model ***
// FullName: Get_Char_Model ***
// Access: public ***
// Returns: int 0 表示字模读取失败 1表示读取成功 ***
// Qualifier: 区汉字字模 ***
// Parameter: unsigned char * character 指向一个要加入字库的字符
// Parameter: char buff_input 指向字模的指针 ***
//**************************************************************
int Get_Char_Model( unsigned char buff_input[32])
{
char st[]="C:/experience/PCtoLCD/PCtoLCD.exe"; // 已给定命令内容的字符变量
char file_read_buffer[200];
FILE * model_read_stream;
int number=0,current=0,decade=0,bits=0;
memset(file_read_buffer,0,sizeof(file_read_buffer));
printf("保存的字模文件请务必以:model.TXT文件名保存\n");
printf("读取汉字字模应用程序即将打开!\n");
system("pause");
system(st); // 运行文件PCtoLCD.exe
model_read_stream=fopen("C:/experience/PCtoLCD/lib/model.TXT","r");
if (!model_read_stream)
{
printf("文件打开失败!\n");
return 0;
}
fread(file_read_buffer,sizeof(file_read_buffer),sizeof(char),model_read_stream);
system("pause");
printf("\n%s\n",file_read_buffer);
fclose(model_read_stream);
// system("del C:/experience/PCtoLCD/lib/model.TXT");
// system("del C:/experience/PCtoLCD/lib/model.TXT_index.TXT");
printf("wait for a minute!\n");
system("pause");
for (current=0; current<sizeof(file_read_buffer); current++)
{
if(file_read_buffer[current]=='H')
{
decade=file_read_buffer[current-2]<'A' ?
file_read_buffer[current-2]-'0' : file_read_buffer[current-2]-'A'+10;
bits=file_read_buffer[current-1]<'A' ?
file_read_buffer[current-1]-'0' : file_read_buffer[current-1]-'A'+10;
buff_input[number]=(unsigned char)(decade*16+bits);
number++;
}
if(number>=32)
return 1;
}
return 0;
}
//***********************************************************
// Method: Delete_Char_From_Lib ***
// FullName: Delete_Char_From_Lib ***
// Access: public ***
// Returns: int ***
// Qualifier: 删除字库中的某个文字 ***
// Parameter: unsigned char * character 要删除的字符 ***
// Parameter: int offset 删除字符的偏移量 ***
// Parameter: char * Lib_Name 删除字符的库 ***
//***********************************************************
int Delete_Char_From_Lib(char *character,unsigned long offset,char *Lib_Name)
{
char buff_clear_chinese[32],buff_clear_english[16];
memset(buff_clear_chinese,0,sizeof(buff_clear_chinese));
memset(buff_clear_english,0,sizeof(buff_clear_english));
FILE *open_file=fopen(Lib_Name,"rb+");
fseek(open_file,offset,SEEK_SET);
if (!open_file)
{
printf("can`t open file: %s\n",Lib_Name);
exit(0);
}
if (character[2]==0 && character[1]==0)
{
fwrite(buff_clear_english,16,1,open_file);
}
else
{
system("pause");
fwrite(buff_clear_chinese,32,1,open_file);
}
printf("delete successfully!\n");
fclose(open_file);
system("pause");
return 0;
}
//*****************************************************************
// Method: transpose ***
// FullName: transpose ***
// Access: public ***
// Returns: int ***
// Qualifier: 转置函数 ***
//因为字模软件读取的汉字按照正常运算是被转置的 ***
// Parameter: char changed[16][16] ***
//*****************************************************************
int transpose(char changed[16][16])
{
char temp;
int i=0,j=0;
for (i; i<16; i++)
{
for(j=i; j<16; j++)
{
temp=changed[i][j];
changed[i][j]=changed[j][i];
changed[j][i]=temp;
}
}
return 1;
}
//************************************
// Method: distranspose
// FullName: distranspose
// Access: public
// Returns: void
// Qualifier: /*把二进制的mat数组转变成字符change数组*/
// Parameter: char mat[][2]
// Parameter: char * * array
// Parameter: int m
// Parameter: int n
//************************************
void distranspose(char mat[][2],char **array)
{
int i,j,k,l=0,n=16;
for(i=0; i<16; i++)
{
for(j=0; j<2; j++)
{
for(k=0; k<8; k++)
{
if (*((char*)array+n*i+l) =='#') //根据每个字节的0和1的状态计算出可用的字模
{
mat[i][j]|=(0x80>>k);
}
else
{
mat[i][j]&=(~(0x80>>k));
}
l++;
}
}
l=0;
}
return ;
}
//************************************
// Method: change
// FullName: change
// Access: public
// Returns: void
// Qualifier: /*把二进制的mat数组转变成字符change数组*/
// Parameter: char mat[][2]
// Parameter: char * * array
// Parameter: int m
// Parameter: int n
//************************************
void change(char mat[][2],char **array)
{
int i,j,k,l=0,n=16;
for(i=0; i<16; i++)
{
for(j=0; j<2; j++)
{
for(k=0; k<8; k++)
{
if(mat[i][j]&(0x80>>k)) //提出每个字节的0和1的状态
{
*((char*)array+n*i+l) ='#';
l++;
}
else
{
*((char*)array+n*i+l) ='-';
l++;
}
}
}
l=0;
}
return ;
}
//************************************
// Method: asistant_insert
// FullName: asistant_insert
// Access: public
// Returns: int
// Qualifier: 辅助插入字符函数
// Parameter: unsigned char * mat
//************************************
int asistant_insert(unsigned char *mat)
{
int j=0,i=0;
char array[16][16],mat_temp[16][2];
memset(array,0,sizeof(array));
memset(mat_temp,0,sizeof(mat_temp));
for(j=0,i=0;j<16;j++)
{
mat_temp[j][0]=mat[i];
mat_temp[j][1]=mat[i+1];
i=i+2;
}
change(mat_temp,(char **)array);
transpose(array);
distranspose(mat_temp,(char **)array);
for(j=0,i=0;j<16;j++)
{
mat[i]=mat_temp[j][0];
mat[i+1]=mat_temp[j][1];
i=i+2;
}
return 0;
}
//************************************
// Method: out_put_system
// FullName: out_put_system
// Access: public
// Returns: int
// Qualifier: 显示输出系统(包括中英文字符)
// Parameter: void
//************************************
int output_system(void)
{
int count=0;
char Buffer_English[16],Buffer_Chinese[32];
unsigned char word[3]={0};
char *Output_String1 = (char *)"●",*Output_String2=(char *)"○";
while(1)
{
memset(Buffer_Chinese,0,sizeof(Buffer_Chinese));
memset(Buffer_English,0,sizeof(Buffer_English));
printf("输入要生成字模的汉字(可以多个输入)[Q表示退出]:");
for(;;)
{
word[2]=getchar();
/*************************************************************************
**根据汉字编码的规定,汉字字符使用双字节表示,而且第一个字节的表示成数字是 **
**大于128,根据getchar()是否大于128可以判断出是单字节字符还是双字节字符 **
**另外根据计数变量count计算出当前操作的字符是双字节字符还是单字节字符。。 **
*************************************************************************/
if(((unsigned char)word[2] < 128)&&(count%2==0))
{
if(word[2] =='\n')
{
break;
}
else if (word[2]=='Q')
{
getchar();
fflush(stdin);
return 1;
}
if (Get_Asc_Code(&word[2],Buffer_English))
{
Print_Asc_Char(Buffer_English,Output_String1,Output_String2);
memset(Buffer_English,0,sizeof(Buffer_English));
}
continue ;
}
if ((count%2)==0)
{
word[0]=word[2];
count++;
continue;
}
word[1]=word[2];
word[2]=0;
count++;
if (Get_HzK_Code(word,Buffer_Chinese))
{
Print_HzK_Char(Buffer_Chinese,Output_String1,Output_String2);
memset(Buffer_Chinese,0,sizeof(Buffer_Chinese));
}
else continue;
}
}
return 0;
}
//************************************
// Method: insert_system
// FullName: insert_system
// Access: public
// Returns: int
// Qualifier: 插入字符
// Parameter: void
//************************************
int insert_system(void)
{
//变量申明部分
char get_char[3];
FILE *fp=NULL;
int not_find=0;
unsigned char qh,wh;
unsigned long offset;
char buff[32];
char file_name[]="C:\\experience\\HZK16";
memset(get_char,0,sizeof(get_char));
printf("请输入您想加入字库的字:");
gets(get_char);
if (strcmp(get_char,"ZZ")<=0)
{
printf("您输入了非法字符!\n");
system("pause");
return 0;
}
if((fp=fopen(file_name,"rb+"))==NULL) /*打开字库文件hzk16*/
{
printf("Can't open haz16,Please add it?");
system("pause");
exit(0);
}
/*区码=内码(高字节)-160 位码=内码(低字节)-160*/
qh = (unsigned char)get_char[0] -0xa0; /*10进制的160等于16进制的A0*/
wh = (unsigned char)get_char[1] -0xa0; /*获得区码与位码*/
offset = (94*(qh-1)+(wh-1))*32L; /*计算该汉字在字库中偏移量*/
not_find=fseek(fp,offset,SEEK_SET); /*将文件指针移动到偏移量的位置*/
if (not_find)
{
printf("未查到该区!error!!!\n");
fclose(fp);
return 0;
}
memset(buff,0,sizeof(buff));
fread(buff,32,1,fp); /*从偏移量的位置读取32个字节*/
if (!Not_In_Lib(buff))
{
printf("字库HZK16存在此字!!!\n");
system("pause");
fclose(fp);
return 0;
}
fseek(fp,offset,SEEK_SET); //重置字库中的偏移量
unsigned char buff_time[32];
memset(buff_time,0,sizeof(buff_time));
if (!Get_Char_Model(buff_time))
{
printf("字模读取失败\n");
fclose(fp);
return 0;
}
asistant_insert(buff_time);
fwrite(buff_time,32,1,fp)? printf("字符加入成功!\n") : printf("字符加入失败!\n");
printf("qh:%d,wh:%d,offset:%ld\n\r",qh,wh,offset);
system("pause");
fclose(fp);
return 0;
}
//************************************
// Method: delete_system
// FullName: delete_system
// Access: public
// Returns: int
// Qualifier: 删除字符部分
// Parameter: void
//************************************
int delete_system(void)
{
char character[3],*lib_name;
int length=0;
unsigned long offset=0;
memset(character,0,sizeof(character));
lib_name=(char *)malloc(30*sizeof(char));
memset(lib_name,0,sizeof(lib_name));
printf("输入您要删除的字符:");
gets(character);
offset=Judge_type_char(character,&offset,&length);
if(length==16)
{
strcat(lib_name,"C:\\experience\\ASC16");
}
else
{
strcat(lib_name,"C:\\experience\\HZK16");
}
Delete_Char_From_Lib(character,offset,lib_name);
return 0;
}
//************************************
// Method: main
// FullName: main
// Access: public
// Returns: int
// Qualifier: 函数入口
// Parameter: void
//************************************
int main(void)
{
char choice[2]= {0,0};
int number=-1;
for (;;)
{
printf("\n\tEmbedded Characters Processing Program\n");
printf("\t\t\tmade by NEWPLAN\n");
printf("\t\t\t2013.9 in UESTC\n");
printf("\t MENU\n\n");
printf("\t0:退出程序\n");
printf("\t1:字符显示\n");
printf("\t2:字符删除\n");
printf("\t3:添加字符\n");
printf("\t4:清理屏幕\n");
printf("your choice=");
gets(choice);
number=atoi(choice);
fflush(stdin);
switch (number)
{
case 0 :
printf("退出程序!\n");
system("pause");
return 0;
case 1 :
output_system();
break;
case 2 :
delete_system();
break;
case 3 :
insert_system();
break;
case 4 :
system("cls");
break;
default :
printf("错误输入!\n\n");
break;
}
number=-1;
}
return 0;
}
中文字符点阵信息的显示和插入新字符(基于HZK16 ASC16软字库)
原文:http://blog.csdn.net/u011889952/article/details/44597723