首页 > 其他 > 详细

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

时间:2015-03-24 21:20:47      阅读:163      评论:0      收藏:0      [点我收藏+]

本系统是对中文字库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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!