中文字符点阵信息的显示和插入新字符(基于HZK16 ASC16软字库)

本系统是对中文字库HZK16和ASC16字库进行操作

HZK16字库中每一个中文字符使用的是32字节的点阵信息,ASC16字库是16字节的点阵信息打印

本文实现了中文汉字的点阵信息打印和字符的操作,包括插入未知字符(囧)(需要借助软件PCtoLCD.exe实现点阵信息的提取)

/****************************************************************************this C source code is made for HZK16 and ASC16 characters system**********newplan 2013.9in 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++)/* 8×16的点阵,一共有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++)/*16×16点阵汉字,一共有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.exemodel_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软字库)

相关文章:

你感兴趣的文章:

标签云: