发信人: yudehai.163(爱血男孩)
整理人: skybird(2001-09-13 09:06:08), 站内信件
|
出 处: bbs.sjtu.edu.cn
【 在 gwh (天元) 的大作中提到: 】
: 我想直接读取ucdos下的矢量字库,请问有谁知道算法?
: 急!急!急?/font>
: ?/font>
/* 矢量汉字的读取和显示 */
#include <stdio.h>
#include <graphics.h>
#define HZNUM (0xf7-0xaf)*(0xfe-0xa0) /* 除前16区外的所有汉字 */
#define HZKSIZE 128 /* 汉字的大小 */
#define START_X 0
#define START_Y 0
#define VIEW_H 256 /* 显示汉字的高度 */
#define VIEW_W 256 /* 显示汉字的宽度 */
FILE *fp;
struct hz_struct {
unsigned long shift; /* 偏移量 */
unsigned int size; /* 大小 */
}HZ_Index[HZNUM]; /* 汉字索引 */
unsigned char buf[1024];
unsigned char dotbuf[1024];
main()
{
long ioffset;
int i,j;
char ch;
int gdriver=DETECT;
int gmode;
if((fp=fopen("hzksly1j","rb"))==NULL){
printf("cano't open the HZlib!");
exit(1);
}
fread(HZ_Index,sizeof(struct hz_struct),HZNUM,fp);
//if(registerbgidriver(EGAVGA_driver)<0) exit(1);
initgraph(&gdriver,&gmode,"");
cleardevice();
setcolor(LIGHTGRAY);
for(i=0; i<HZNUM;i++){
Disp_HZ(HZ_Index[i].size,HZ_Index[i].shift);
rectangle(START_X,START_Y,START_X+256,START_Y+256);
ch=getch();
cleardevice();
if(ch=='q') break;
}
closegraph();
fclose(fp);
}
/* 显示汉字 */
Disp_HZ(int length,long posi)
{
int i,j,k;
int x0,y0,x1,y1;
int hzsize;
union utype{
unsigned short size;
unsigned char str[2];
}BH;
if((fseek(fp,posi,0))!=0){
printf("seek\"clib\"error!\n");
exit(0);
}
memset(buf,0,1024);
fread(buf,length,1,fp);
hzsize=decode(buf,length);
k=0;
for(i=0;i<hzsize;i++){
BH.str[0]=dotbuf[k++];
BH.str[1]=dotbuf[k++];
if(BH.size==0)break;/* 每个汉字以0结束 */
x0=START_X+(dotbuf[k++]*VIEW_W)/HZKSIZE;
y0=START_Y+(dotbuf[k++]*VIEW_H)/HZKSIZE;
// x0=START_X+dotbuf[k++];
// y0=START_Y+dotbuf[k++];
moveto(x0,y0);
for(j=0;j<BH.size-1;j++){
x1=START_X+(dotbuf[k++]*VIEW_W)/HZKSIZE;
y1=START_Y+(dotbuf[k++]*VIEW_W)/HZKSIZE;
// x1=START_X+dotbuf[k++];
// y1=START_Y+dotbuf[k++];
lineto(x1,y1);
}
lineto(x0,y0);
}
}
/* 汉字字形还原
*/
decode(p,length)
unsigned char *p;
int length;
{
int k;
int i,count,lposi,xsum,ysum;
unsigned char b60;
char dxfh,dyfh;
char x0,dx,dy;
lposi=0;
k=2;
while((p-buf)<=length){
b60=*p&0xc0;
switch(b60){
case 0xc0:
if(k!=2){
dotbuf[lposi]=(k-lposi-2)/2;
dotbuf[lposi+1]=0;
lposi=k++;
k++;
}
x0=(*p&0x3f)<<1;
dx=(*(p+1)>>7)&0x01;
dx=dx+x0;
p++;
dy=*p++&0x7f;
dotbuf[k++]=xsum=dx;
dotbuf[k++]=ysum=dy;
break;
case 0x80:
dxfh=dyfh=1;
switch(*p&0x30){
case 0x00:
if(*p&0x08)dxfh=-1;
dx=*p&0x07;
p++;
if(*p&0x80)dyfh=-1;
dy=*p&0x7f;
break;
case 0x10:
if(*p&0x08)dyfh=-1;
dy=*p&0x07;
p++;
if(*p&0x80)dxfh=-1;
dx=*p&0x7f;
break;
case 0x20:
case 0x30:
p++;
if(*p&0x80)dxfh=-1;
dx=*p&0x7f;
p++;
if(*p&0x80)dyfh=-1;
dy=*p&0x7f;
break;
}
p++;
xsum+=dx*dxfh;
ysum+=dy*dyfh;
dotbuf[k++]=xsum;
dotbuf[k++]=ysum;
break;
case 0x40:
dxfh=*p&0x30;
if(dxfh==0){
dxfh=1;
dyfh=1;
}
else if(dxfh==0x10){
dxfh=-1;
dyfh=1;
}
else if(dxfh==0x20){
dxfh=-1;
dyfh=-1;
}
else if(dxfh==0x30){
dxfh=1;
dyfh=-1;
}
count=*p++&0x0f;
for(i=0;i<count;i++){
dx=*p>>4;
dy=*p&0x0f;
xsum+=dxfh*dx;
ysum+=dyfh*dy;
dotbuf[k++]=xsum;
dotbuf[k++]=ysum;
p++;
}
break;
case 00:
count=*p++&0x3f;
for(i=0;i<count;i++){
if(*p&0x80) dxfh=-1;
else dxfh=1;
if(*p&0x08)dyfh=-1;
else dyfh=1;
dx=(*p&0x70)>>4;
dy=(*p&0x07);
xsum+=dx*dxfh;
ysum+=dy*dyfh;
dotbuf[k++]=xsum;
dotbuf[k++]=ysum;
p++;
}
}
}
dotbuf[k++]=0;
dotbuf[k++]=0;
dotbuf[lposi]=(k-lposi-2-2)/2;
dotbuf[lposi+1]=0;
return k;
}
---- 本贴标题由版主修改过。
请大家在发贴的时候一定记住写清楚标题,不要是“请教高手……”“请帮忙……”“一个问题……”之类的。写清楚以后会有更多的人帮助你的,谢谢合作! |
|