#include <stdio.h>
#include "zm_liangbiao.h"
#include "juzheng.h"
//取字模时应该选择全角输入字符否则不能正确取字模
class quzimo
{
int ZKBJ;//字库标记:8=8*8,16=16*16,32=32*32,48=48*48
int ZMCD;//字模长度根据字库标记计算
int QMFX;//取字模方向
void qumo_1616(char zf[2],char zm[32]);//取字符的16*16点阵字模
void qumo(char zf[2],char zm[300]);//根据字库类型标记取一个字符的点阵字模并添加到缓存链表
public:
zm_liangbiao *zmlb,*zmlb_xz;//创建一个字模数据链表
quzimo(int zk,int fx){zmlb=new zm_liangbiao;zmlb_xz=new zm_liangbiao;ZKBJ=zk;QMFX=fx;ZMCD=ZKBJ*ZKBJ/8;}//初始化
void zmlb_add(char zf[2]);//添加一个字符的字模到字模链表
void zmlb_add_shougong(char zm[300]);//手工添加一个字模数据到链表
void zmlb_print_c51(int x,int jzs,char qz[],int qzcd,char hz[],int hzcd,char hcq[]);//将字模链表组合成C51格式输出到一个缓存区
void zmlb_print_asm(int h,int jzs,char qz[],int qzcd,char hz[],int hzcd,char hcq[]);//将字模链表组合成asm格式输出到一个缓存区
void qmfx(int QMFX);//根据取模方向重新组合字模数据
void print_zm(char hcq[300]);//输出链表尾部的一个没有格式化的字模数据
void print_lb();//调试用输出链表数据
};
void quzimo::qumo_1616(char zf[2],char zm[32])
{
//取字符的16*16点阵字模
FILE *fp_hzk;
char ZM[32];
unsigned long offset;//字模在16*16字库中的偏移地址
offset=(((unsigned char)zf[0]-0xa1)*94+((unsigned char)zf[1]-0xa1))*32; //根据内码找出汉字在HZK16中的偏移位置,第一个字节是区码第二个字节是位码
if((fp_hzk=fopen("c:\\vc\\HZK16","rb"))==NULL) return; //打开字库文件
fseek(fp_hzk,offset,SEEK_SET); //文件指针偏移到要找的汉字处
fread(ZM,32,1,fp_hzk);//读取该汉字的字模
memcpy(zm,ZM,sizeof(char)*32);//返回获取的字模数据
}
void quzimo::qmfx(int QMFX)
{
//根据取模方向重新组合字模数据
int xz[48][48];
int xz1[48][48];
char zm[300];
Node *q;
q=zmlb->head;
int y,x,k;
//遍历链表根据取模方向重组字模数据
while(q){
////////////////////
//读字模数据到数组
k=0;
for(y=0;y<ZKBJ;y++)
for(x=0;x<ZKBJ;x+=8)
{
zjtodz_z(q->zm[k],&xz[y][x]);
k++;
}
/////////////////////
//数组向右旋转90度
for(y=0;y<ZKBJ;y++)
{
for(x=0;x<ZKBJ;x++)
{
xz1[x][y]=xz[ZKBJ-1-y][x];//直接顺时针旋转90度
}
}
/////////////////////
switch(QMFX)
{
case 2:
{
///////////////////////
//纵向ACBD方式重组字模
k=0;
for(y=0;y<ZKBJ;y++)
{
for(x=ZKBJ-8;x>=0;x-=8)
{
zm[k]=dztozj_y(&xz1[y][x]); //读8位显存数据合成为一个字节
k++;
}
}
///////////////////////////
break;
}
case 3:
{
///////////////////////
//纵向BDAC方式重组字模
k=0;
for(y=ZKBJ-1;y>=0;y--)
{
for(x=ZKBJ-8;x>=0;x-=8)
{
zm[k]=dztozj_y(&xz1[y][x]); //读8位显存数据合成为一个字节
k++;
}
}
///////////////////////////
break;
}
case 0:
{
//横向ABCD方式重组字模
k=0;
for(y=0;y<ZKBJ;y++)
{
for(x=0;x<ZKBJ;x+=8)
{
zm[k]=dztozj_z(&xz[y][x]); //读8位显存数据合成为一个字节
k++;
}
}
/////////////////////////
break;
}
case 1:
{
///////////////////////////
//横向BADC方式重组字模
k=0;
for(y=0;y<ZKBJ;y++)
{
for(x=ZKBJ-8;x>=0;x-=8)
{
zm[k]=dztozj_y(&xz[y][x]); //读8位显存数据合成为一个字节
k++;
}
}
/////////////////////////
break;
}
}
zmlb_xz->add(q->ZKBJ,q->zf,zm);//重组后的字模数据链表
q=q->next;
}
}
void quzimo::qumo(char zf[2],char zm[300])
{
//根据字库类型标记取一个字符的点阵字模
switch(ZKBJ)
{
case 8:
//暂不支持待扩展
break;
case 16:
qumo_1616(zf,zm);//取字符的16*16点阵字模
break;
case 32:
//暂不支持待扩展
break;
case 48:
//暂不支持待扩展
break;
}
}
void quzimo::zmlb_add(char zf[2])
{
//添加一个字符的字模到字模链表
char ZM[300];//字模数据缓存区
qumo(zf,ZM);//取字模
zmlb->add(ZKBJ,zf,ZM);//添加一个字符数据
}
void quzimo::zmlb_add_shougong(char zm[300])
{
//添加一个手工绘制的字模到字模链表
char *zf="000";//手工绘制标记
zmlb->add(ZKBJ,zf,zm);//添加一个字符数据
}
void quzimo::zmlb_print_c51(int x,int jzs,char qz[],int qzcd,char hz[],int hzcd,char hcq[])
{
qmfx(QMFX);//根据取模方向重组字模数据
//将字模链表组合成C51格式输出到一个缓存区 x=1格式为0xaa否则格式为0XAA;
char QZ[20];//前缀不能超过19字节
char HZ[20];//后缀不能超过19字节
char ZM[1500];//字模数据1字节格式化后需要5字节存储空间
char ZS[]="//字符: 的点阵字模\r\n"; //字符注释信息
char ZS_0[]=" \r\n";//注释信息为空
//char zm_c51[1100];//一条c51格式的完整字模信息
char zfcend[]=" ";//字符串结束向缓存区输出一个0x00的字符串结尾标记避免缓存区输出后面没有准确数据的乱码
int i=0;//输出缓存区位置标记
int k=0;//字模格式化缓存区位置标记
////////////////////////////
//避免缓存区区溢出所以必须限定前后缀字符串输入的长度
int QZCD,HZCD;
if(qzcd<20)
{
QZCD=qzcd;
}else
{
QZCD=19;
}
if(hzcd<20)
{
HZCD=hzcd;
}else
{
HZCD=19;
}
memcpy(QZ,qz,QZCD);
memcpy(HZ,hz,HZCD);
////////////////////////////
Node *q;
q=zmlb_xz->head;//输出重组后的字模数据
/////////////////////////////////////////
//遍历字模数据链表并向缓存区输出格式化后的链表数据
while(q){
//////////////////////////////////////////
//格式化字模数据
k=0;//字模缓存区指针清零
for(int j=0;j<ZMCD;j++)
{
if(x==1)
{
sprintf(ZM+k,"0X%02X,",(unsigned char)q->zm[j]);
k+=5;
//大写X
}else
{
sprintf(ZM+k,"0x%02x,",(unsigned char)q->zm[j]);
k+=5;
//小写x
}
}
memcpy(ZS+7,q->zf,sizeof(char)*2);//格式化注释信息+7的偏移是为了将原字符信息添加到注释里面
///////////////////////////////////////////
//向缓存区输出格式化的字符串 -1是为了消除没个单独字符串的结尾标记,否则格式后的字符串将不能完全显示或乱码
memcpy(hcq+i,QZ,QZCD-1);i+=QZCD-1;//输出前缀字符串
memcpy(hcq+i,ZM,sizeof(char)*(ZMCD*5));i+=(ZMCD*5)-1;//输出字模数据字符串,这里的指针偏移-1是为了消除数组尾部一个多余的','号
memcpy(hcq+i,HZ,HZCD-1);i+=HZCD-1;//输出后缀字符串
if(jzs==1)
{
memcpy(hcq+i,ZS,sizeof(ZS)-1);i+=sizeof(ZS)-1;//输出注释信息字符串
}else{
memcpy(hcq+i,ZS_0,sizeof(ZS_0)-1);i+=sizeof(ZS_0)-1;//输出空注释信息字符串
}
///////////////////////////////////////////
q=q->next;
}
memcpy(hcq+i,zfcend,sizeof(zfcend));i+=sizeof(zfcend);//添加一个字符串结尾标记
///////////////////////////////////////////
}
void quzimo::zmlb_print_asm(int h,int jzs,char qz[],int qzcd,char hz[],int hzcd,char hcq[])
{
qmfx(QMFX);//根据取模方向重组字模数据
//将字模链表组合成ASM格式输出到一个缓存区 x=1格式为0xaa否则格式为0XAA;
char QZ[20];//前缀不能超过19字节
char HZ[20];//后缀不能超过19字节
char ZM[1500];//字模数据1字节格式化后需要5字节存储空间
char ZS[]=";字符: 的点阵字模\r\n"; //字符注释信息
char ZS_0[]=" \r\n";//注释信息为空
//char zm_c51[1100];//一条c51格式的完整字模信息
char zfcend[]=" ";//字符串结束向缓存区输出一个0x00的字符串结尾标记避免缓存区输出后面没有准确数据的乱码
int i=0;//输出缓存区位置标记
int k=0;//字模格式化缓存区位置标记
////////////////////////////
//避免缓存区区溢出所以必须限定前后缀字符串输入的长度
int QZCD,HZCD;
if(qzcd<20)
{
QZCD=qzcd;
}else
{
QZCD=19;
}
if(hzcd<20)
{
HZCD=hzcd;
}else
{
HZCD=19;
}
memcpy(QZ,qz,QZCD);
memcpy(HZ,hz,HZCD);
////////////////////////////
Node *q;
q=zmlb_xz->head;
/////////////////////////////////////////
//遍历字模数据链表并向缓存区输出格式化后的链表数据
while(q){
//////////////////////////////////////////
//格式化字模数据
k=0;//字模缓存区指针清零
for(int j=0;j<ZMCD;j++)
{
if(h==1)
{
sprintf(ZM+k,"%02XH,",(unsigned char)q->zm[j]);
k+=4;
//大写X
}else
{
sprintf(ZM+k,"%02xh,",(unsigned char)q->zm[j]);
k+=4;
//小写x
}
}
memcpy(ZS+6,q->zf,sizeof(char)*2);//格式化注释信息+7的偏移是为了将原字符信息添加到注释里面
///////////////////////////////////////////
//向缓存区输出格式化的字符串 -1是为了消除没个单独字符串的结尾标记,否则格式后的字符串将不能完全显示或乱码
memcpy(hcq+i,QZ,QZCD-1);i+=QZCD-1;//输出前缀字符串
memcpy(hcq+i,ZM,sizeof(char)*(ZMCD*4));i+=(ZMCD*4)-1;//输出字模数据字符串,这里的指针偏移-1是为了消除数组尾部一个多余的','号
memcpy(hcq+i,HZ,HZCD-1);i+=HZCD-1;//输出后缀字符串
if(jzs==1)
{
memcpy(hcq+i,ZS,sizeof(ZS)-1);i+=sizeof(ZS)-1;//输出注释信息字符串
}else{
memcpy(hcq+i,ZS_0,sizeof(ZS_0)-1);i+=sizeof(ZS_0)-1;//输出空注释信息字符串
}
///////////////////////////////////////////
q=q->next;
}
memcpy(hcq+i,zfcend,sizeof(zfcend));i+=sizeof(zfcend);//添加一个字符串结尾标记
///////////////////////////////////////////
}
void quzimo::print_zm(char hcq[300])
{
//输出原始字模数据链表里的最后一个字符的字模信
char HC[300];
zmlb->print_zm(HC);
memcpy(hcq,HC,sizeof(char)*ZMCD);
}
void quzimo::print_lb()
{
//调试用输出链表数据
Node *q;
q=zmlb->head;
do{
for(int x=0;x<32;x++)
{
printf("%02X ",(unsigned char)q->zm[x]);//(unsigned char)强制转换后才能输出2位的16进制数
}
q=q->next;
printf("\n");
}while(q);
}
|