
 if(j==1){                    //若为汉字,调整地址偏移值
      hz.offset-=0x10000000;
  }
#include "d:\borland\user\src\graphics.h"
#include "d:\borland\user\src\graphics.c"
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <mem.h>
#include <alloc.h>
#include <dir.h>
#include <dos.h>
#include <stdlib.h>
#define  baseSize 250    //此值越大,字体越小,原值为168
#define  portion  100     //100
FILE *fpfh,*fphz,*fpe,*fp;
int X0,Y0,xRange,yRange,curX,curY;
int newX0,newY0,newxRange,newyRange;
unsigned char *wordCont_0=NULL,*wordCont_8=NULL;
unsigned bytesNum_0,bytesNum_8;
unsigned char myread(void);
void control(int *xx,int *yy,unsigned char controlWord,int nowxRange,
             int nowyRange,int nowX0,int nowY0,int call_8_0);
void showhz(char *fontfileName,unsigned long col);
void b3_4(int *x,int *y,unsigned long col);
void b3_3(int *x,int *y,unsigned long col);
int readbyte(void);
int readcount;
static unsigned char next;    //用于读取字节高四位、低四位的标志,1读高位,0读低位
typedef struct _hz{
	    unsigned long offset;    //4字节
	    unsigned int length;     //2字节
	 }hz_;
hz_ hz;
unsigned char hzdata;  //用于读取字型数据
void main(void)
{ 
	
  unsigned char *hzstring="然字Mm骤啊H骤g9酆8G字,汉,然。!!戆";//戆您原回骤然燃";//"共有汉字个骤";原骤戆啊汉字
 
  long color;
 
  initgraph(VBE480_16M);
 
  X0=Y0=1;xRange=yRange=152;//原值为152 
  showhz(hzstring,rgbcolor(255,0,0));
     
  getch();
  cleardevice();
  closegraph();
}
void showhz(char *hzstring,unsigned long col)
{ 
  unsigned long oldcolor;
  unsigned long wordOffset;
  unsigned char qm,wm;
  int bx,by;    //用于记录笔画的起始点坐标
  int xx,yy,controlWord,i,j,m=0;
  char ch,cha,chx,chy,chxx,chyy;
  char mark1_x,mark1_y,mark2_x,mark2_y,mark3_x,mark3_y;
  char *fontFileName="HZKPSKTJ";//HZKPSXKJ";//HZKPSST.GBK";//"HZKPSHTJ";//"HZKPSFSJ";//"HZKPSXBJ";HZKPSKTJ;HZKPSY3J;ASCPS;HZKPST;HZKPSDHJ,HZKPSYTJ
    oldcolor=getcolor();
    setcolor(col);
    if((fpfh=fopen("HZKPST","rb"))==NULL) { //打开中文符号曲线字库
    printf("Cannot open %s file\n","HZKPST");
    exit(0);
       }
    if((fphz=fopen(fontFileName,"rb"))==NULL) { //打开中文曲线字库,若为GBK字库,则打开的是GBK字库
    printf("Cannot open %s file\n",fontFileName);
    exit(0);
      }
    if((fpe=fopen("ASCPS","rb"))==NULL) {    //打开英文曲线字库
    printf("Cannot open %s file\n","ASCPS");
    exit(0);
       }
   i=0; 
 while(i<strlen(hzstring))
 {
  readcount=0;
  next=0;
  if((hzstring&0x80)==0x80){          //判断是否为汉字,相等,即最高位是1,则为汉字
        qm=hzstring-0xa0;       //区码
        wm=hzstring-0xa0;     //位码
        j=1;                //作为汉字的标志,用于调整地址偏移
	      if(strcmp(strrchr(fontFileName, '.')+1,"GBK")==0){     //首先找到最后一个'.'的位置,加1使指针指向'.'后的第一个字符,然后进行比较,判断是否是GBK字库
               fp=fphz;                                  //GBK字库仍有部分汉字缺失,如“镕”字,在字库中不存在
  	           wordOffset=(((long)qm-1)*94+(wm-1))*6;    //GBK字库已包含了16区以前的汉字符号字库,计算地址时,区码应减去1,而不是减去6   
           }
        else {   //不是GBK字库
            if(qm>=16){            //16区以后的汉字 
        	      fp=fphz;
  	            wordOffset=(((long)qm-16)*94+(wm-1))*6;    //16区以后的汉字偏移   
  	          }
  	        else{                //16区以前的汉字符号
  	    	      fp=fpfh;
  		          wordOffset=(((long)qm-1)*94+(wm-1))*6;       //16区以前的汉字符号偏移 
  		       }
  		  }
        i+=2;             //汉字为两字节
      }
    else{          //是英文字符
    	  fp=fpe;
  	    wordOffset=(0*94+(hzstring-32)-1)*6;         //英文字体共有十种0~9,设字体号为N,字符ASCII码为CC,则英文字符偏移为(N*94+(CC-32)-1)*6,空格的ASCII码值为32,但在字库中不存在,字库的起始字符是'!'号,值为33,实际应减33,字库中每种字体字符数为94个
        i+=1;
  	}
  	
  fseek(fp,wordOffset,SEEK_SET);
  fread(&hz,sizeof(hz_),1,fp);
  if(j==1){                    //若为汉字,调整地址偏移值
      hz.offset-=0x10000000;
      j=0;
  }
  fseek(fp,hz.offset,SEEK_SET);
  fread(hzdata,1,hz.length,fp);
  while(readcount<hz.length) {
   	          ch=myread();      //取控制码
   	          switch(ch){ 
   	                  case 0:                //新起点          0000
   	                  	if(readcount>0)lineto(bx,by);     //整个字的第一个起点时不连接,将笔画的最后一个点与起始点相连,将笔画封闭
                             xx=readbyte();
                             yy=readbyte();
                             xx=xRange*xx/baseSize+0.5;
                             yy=yRange*yy/baseSize+0.5;
                             xx+=X0;yy+=Y0;
                             moveto(xx,yy);         //笔画起点
                             curX=xx;curY=yy;
                             bx=xx;by=yy;          //记录笔画的起始点坐标
                             break;
   	                  	
   	                  case 1:
   	                  	     xx=readbyte();
                             xx=xRange*xx/baseSize+0.5;
                             xx+=X0;
                             lineto(xx,curY);
                             curX=xx;
                             break;
   	                  	     
   	                  case 2:	
   	                         yy=readbyte();
   	                         yy=yRange*yy/baseSize+0.5;
                             yy+=Y0;
   	                         lineto(curX,yy);
                             curY=yy;
                             break;
   	                         
   	                  case 3:
   	                  	     xx=readbyte();
                             yy=readbyte();
                             xx=xRange*xx/baseSize+0.5;
                             yy=yRange*yy/baseSize+0.5;
                             xx+=X0;yy+=Y0;
                             lineto(xx,yy);
                             curX=xx;curY=yy;
                             break;
   	                  	     
   	                  case 4:	
   	                         xx=curX;yy=curY;
                             xx=readbyte();
                             yy=readbyte();
                             xx=readbyte();
                             yy=readbyte();
                             xx=xRange*xx/baseSize+0.5;
                             yy=yRange*yy/baseSize+0.5;
                             xx=xRange*xx/baseSize+0.5;
                             yy=yRange*yy/baseSize+0.5;
                             xx+=X0;yy+=Y0;
                             xx+=X0;yy+=Y0;
                             b3_3(xx,yy,COLOR);
                             curX=xx;curY=yy;
                             moveto(curX,curY);
                             break;
   	                        
   	                  case 5:
   	                  	     xx=curX;yy=curY;
                             xx=readbyte();
                             yy=readbyte();
                             xx=readbyte();
                             yy=readbyte();
                             xx=readbyte();
                             yy=readbyte();
                             xx=xRange*xx/baseSize+0.5;
                             yy=yRange*yy/baseSize+0.5;
                             xx=xRange*xx/baseSize+0.5;
                             yy=yRange*yy/baseSize+0.5;
                             xx=xRange*xx/baseSize+0.5;
                             yy=yRange*yy/baseSize+0.5;
                             for(m=1;m<4;m++) {
                                  xx+=X0;yy+=Y0;
                                }
                             b3_4(xx,yy,COLOR);
                             curX=xx;curY=yy;
                             moveto(curX,curY);
                             break;
   	                  	    
   	                  case 6:	
   	                         xx=readbyte();
                             yy=readbyte();
                             xx=readbyte();
                             yy=readbyte();
                             xx=xRange*xx/baseSize+0.5;
                             yy=yRange*yy/baseSize+0.5;
                             xx=xRange*xx/baseSize+0.5;
                             yy=yRange*yy/baseSize+0.5;
                             for(m=0;m<2;m++) {
                                  xx+=X0;yy+=Y0;
                              }
                             rectangle(xx,yy,xx,yy);
                             break;
   	                    
   	                  case 7:
   	                  	     mark1_x=1;
   	                  	     ch=myread();
   	                  	     if(ch&8)mark1_x=-1;
   	                  	     ch&=7;
   	                  	     xx=curX+ch*mark1_x*xRange/baseSize+0.5;
   	                  	     yy=readbyte();
   	                  	     yy=yRange*yy/baseSize+0.5;
   	                  	     yy+=Y0;
   	                  	     lineto(xx,yy);
   	                  	     curX=xx;curY=yy;
                             break;
   	                  	     
   	                  case 8:	
   	                  	     mark1_y=1;
   	                         xx=readbyte();
   	                         xx=xRange*xx/baseSize+0.5;
   	                         xx+=X0;
   	                         ch=myread();
   	                         if(ch&8)mark1_y=-1;
   	                  	     ch&=7;
   	                  	 	   yy=curY+ch*mark1_y*yRange/baseSize+0.5;
                             lineto(xx,yy);
   	                  	     curX=xx;curY=yy;
                             break;
   	                  
   	                  case 9:
   	                  	     mark1_x=1;
   	                  	     mark1_y=1;
   	                  	     ch=myread();
   	                  	     if(ch&8)mark1_x=-1;
   	                  	     ch&=7;
   	                  	     xx=curX+ch*mark1_x*xRange/baseSize+0.5;
   	                  	     ch=myread();
   	                         if(ch&8)mark1_y=-1;
   	                  	     ch&=7;
   	                  	     yy=curY+ch*mark1_y*yRange/baseSize+0.5; 
                      	     lineto(xx,yy);
   	                  	     curX=xx;curY=yy;
                             break;
   	                  	     
   	                  case 10:	
   	                  	     mark1_x=1;
   	                  	     mark1_y=1;
   	                  	     ch=myread();          //第一次读取的四位作为六位数据的高四位
   	                  	     cha=myread();         //第二次读取的四位的高两位作为六位数据的低两位,低两位作为第二个六位数的高两位
   	                  	     ch=(ch<<2)+(cha>>2);
   	                  	     if(ch&0x20)mark1_x=-1;
   	                  	     ch&=0x1f;
   	                  	     xx=curX+ch*mark1_x*xRange/baseSize+0.5;
  	                  	     ch=myread();          //第三次读取的四位作为第二个六位数的低四位
   	                  	     ch=((cha&0x03)<<4)+ch;
   	                         if(ch&0x20)mark1_y=-1;
   	                  	     ch&=0x1f;
   	                  	     yy=curY+ch*mark1_y*yRange/baseSize+0.5;
                      	     lineto(xx,yy);
   	                  	     curX=xx;curY=yy;
                             break;
   	                  	     
   	                  case 11:
   	                  	     mark1_x=1;
   	                  	     mark1_y=1;
   	                  	     mark2_x=1;
   	                  	     mark2_y=1;
   	                  	     xx=curX;yy=curY;
   	                  	     ch=myread();
   	                  	     if(ch&8)mark1_x=-1;
   	                  	     chx=ch=(ch&7)*mark1_x;
   	                  	     xx=curX+ch*xRange/baseSize+0.5;
   	                  	     
   	                  	     ch=myread();
   	                  	     if(ch&8)mark1_y=-1;
   	                  	     chy=ch=(ch&7)*mark1_y;
   	                    	   yy=curY+ch*yRange/baseSize+0.5;
   	                    	   
    	                  	   ch=myread();
   	                         if(ch&8)mark2_x=-1;
   	                         ch=(ch&7)*mark2_x;	
   	                         xx=curX+(chx+ch)*xRange/baseSize+0.5;   
   	                  	        
    	                  	   ch=myread();  
                             if(ch&8)mark2_y=-1;
                             ch=(ch&7)*mark2_y;
                             yy=curY+(chy+ch)*yRange/baseSize+0.5;
                            
                             b3_3(xx,yy,COLOR);
                             curX=xx;curY=yy;
                             moveto(curX,curY);
                             break;
   	                  	     
   	                  case 12:	
   	                  	     mark1_x=1;
   	                  	     mark1_y=1;
   	                  	     mark2_x=1;
   	                  	     mark2_y=1;
   	                  	     
   	                         xx=curX;yy=curY;
                             ch=myread();            //1
                             cha=myread();           //2
   	                  	     ch=(ch<<2)+(cha>>2);
   	                  	     if(ch&0x20)mark1_x=-1;
                 	     	     chx=ch=(ch&0x1f)*mark1_x;
   	                  	     xx=curX+ch*xRange/baseSize+0.5;
   	                  	        	                  	           
   	                  	     ch=myread();           //3
   	                  	     ch=((cha&0x03)<<4)+ch;
   	                  	      
   	                         if(ch&0x20)mark1_y=-1;
   	                  	     chy=ch=(ch&0x1f)*mark1_y;
               	             yy=curY+ch*yRange/baseSize+0.5;
    	                
                             ch=myread();      //1
                             cha=myread();     //2
                             ch=(ch<<2)+(cha>>2);
   	                  	     if(ch&0x20)mark2_x=-1;
                 	     	     ch=(ch&0x1f)*mark2_x;
   	                  	     xx=curX+(chx+ch)*xRange/baseSize+0.5;   	                  	      	           
   	                  	            
   	                  	     ch=myread();         //3
   	                  	     ch=((cha&0x3)<<4)+ch;
   	                         if(ch&0x20)mark2_y=-1;
   	                         ch=(ch&0x1f)*mark2_y;
   	                  	     yy=curY+(chy+ch)*yRange/baseSize+0.5;
                             b3_3(xx,yy,COLOR);
                             curX=xx;curY=yy;
                             moveto(curX,curY);
                             break;
   	                         
   	                  case 13:
   	                  	     mark1_x=1;
   	                  	     mark1_y=1;
   	                  	     mark2_x=1;
   	                  	     mark2_y=1;
   	                  	     mark3_x=1;
   	                  	     mark3_y=1;
   	                  	     xx=curX;yy=curY;
   	                  	     ch=myread();
                             if(ch&8)mark1_x=-1;
                             chx=ch=(ch&7)*mark1_x;
                             xx=curX+ch*xRange/baseSize+0.5;
   	                  	            
   	                  	     ch=myread();
   	                         if(ch&8)mark1_y=-1;
   	                  	     chy=ch=(ch&7)*mark1_y;
   	                  	     yy=curY+ch*yRange/baseSize+0.5;
    	                  	          
    	                  	   ch=myread();
                             if((ch)&8)mark2_x=-1;
                             chxx=ch=(ch&7)*mark2_x;
   	                  	     xx=curX+(chx+ch)*xRange/baseSize+0.5; 
   	                  	          
   	                  	     ch=myread();
   	                         if((ch)&8)mark2_y=-1;
   	                         chyy=ch=(ch&7)*mark2_y;
   	                  	     yy=curY+(chy+ch)*yRange/baseSize+0.5;
    	                  	                          
                             ch=myread();
                             if((ch)&8)mark3_x=-1;
                             ch=(ch&7)*mark3_x;
   	                  	     xx=curX+(chx+chxx+ch)*xRange/baseSize+0.5;
                             
                             ch=myread();
   	                         if((ch)&8)mark3_y=-1;
   	                         ch=(ch&7)*mark3_y;
   	                  	     yy=curY+(chy+chyy+ch)*yRange/baseSize+0.5;
                             b3_4(xx,yy,COLOR);
                             curX=xx;curY=yy;
                             moveto(curX,curY);
                             break;
   	                  	     
   	                  case 14:	
   	                  	     mark1_x=1;
   	                  	     mark1_y=1;
   	                  	     mark2_x=1;
   	                  	     mark2_y=1;
   	                  	     mark3_x=1;
   	                  	     mark3_y=1;
   	                  	     xx=curX;yy=curY;
   	                  	     ch=myread();                         //1
   	                  	     cha=myread();                        //2
   	                  	     ch=(ch<<2)+(cha>>2);
   	                  	     if(ch&0x20)mark1_x=-1;
  	                  	     chx=ch=(ch&0x1f)*mark1_x;
   	                  	     xx=curX+ch*xRange/baseSize+0.5;
   	                  	      	       
   	                  	     ch=myread();                          //3
   	                  	     ch=((cha&0x03)<<4)+ch;
   	                         if(ch&0x20)mark1_y=-1;
   	                         chy=ch=(ch&0x1f)*mark1_y;
   	                  	     yy=curY+ch*yRange/baseSize+0.5;
    	                  	          
                             ch=myread();                       //1
                             cha=myread();                      //2
                             ch=(ch<<2)+(cha>>2);
   	                  	     if(ch&0x20)mark2_x=-1;
   	                  	     chxx=ch=(ch&0x1f)*mark2_x;
   	                  	     xx=curX+(chx+ch)*xRange/baseSize+0.5;
   	                  	     
   	                  	     ch=myread();                         //3
   	                  	     ch=((cha&0x03)<<4)+ch;
   	                         if(ch&0x20)mark2_y=-1;
   	                         chyy=ch=(ch&0x1f)*mark2_y;
   	                  	     yy=curY+(chy+ch)*yRange/baseSize+0.5;
   	                  	     
                             ch=myread();             //1
                             cha=myread();            //2
                             ch=(ch<<2)+(cha>>2);
   	                  	     if(ch&0x20)mark3_x=-1;
   	                  	     ch=(ch&0x1f)*mark3_x;
   	                  	     xx=curX+(chx+chxx+ch)*xRange/baseSize+0.5;
   	                  	        
   	                  	     ch=myread();                //3
   	                  	     ch=((cha&0x03)<<4)+ch;
   	                         if(ch&0x20)mark3_y=-1;
   	                         ch=(ch&0x1f)*mark3_y;
   	                  	     yy=curY+(chy+chyy+ch)*yRange/baseSize+0.5;
   	                  	     b3_4(xx,yy,COLOR);
                             curX=xx;curY=yy;
                             moveto(curX,curY);
                             break;
   	                  	     
   	                  case 15:    //仅读取两个字节,不作处理
   	                  	     readbyte();
   	                  	     readbyte();
   	                  	     break;
       	     
   	        }
         }
         
         if((readcount<hz.length))lineto(bx,by);     //将最后一个笔画的最后一个点与起始点相连,将笔画封闭
         getch();
         X0+=xRange*168/baseSize+0.5;    //此处为168较合适,但未找到原因
	       if(getmaxx()-X0<xRange*168/baseSize){
	       X0=0;
	       Y0+=yRange*168/baseSize+0.5;
	    }
	  if(getmaxy()-Y0<yRange*168/baseSize){
               Y0=0;
               X0=0;
               getch();
               cleardevice();
            } 
     }
  setcolor(oldcolor);
  fp=0;
  fclose(fpe);
  fclose(fpfh);
  fclose(fphz);
  return;
}
unsigned char myread(void)   //每调用一次,读出一个字节的四位数,先读低四位,后读高四位
{
	unsigned char a;
	if(!next){                    //next等于0时读取低四位,为1时读取高四位
		      a=hzdata&0x0f;
		      next=1;
		}
	 else{
		      a=(hzdata&0xf0)>>4;
		      readcount++;
	 	      next=0;
	 	}	
	return a; 
}
	
int readbyte(void)
{
	int kk=0;
	unsigned char a,b;
	a=myread()<<4;
	b=myread();
	kk=(int)(b+a);
	return kk;
	}
void b3_4(int *x,int *y,unsigned long col)      //三次B样条曲线,n可以指定常数
{ int n,*bx,*by,sign=1,j=0,k,i;
  double a,b,c,d,dt,xx,f0_3,f_0,f_1,f_2;
  n=xx=sqrt(((double)(x-x))*((double)(x-x))+
       ((double)(y-y))*((double)(y-y)))+
       sqrt(((double)(x-x))*((double)(x-x))+
       ((double)(y-y))*((double)(y-y)))+
       sqrt(((double)(x-x))*((double)(x-x))+
       ((double)(y-y))*((double)(y-y)));
   
  if(xx>n) n++;
  n*=2;
  if(n==0) n=20;
  do {
    bx=(int *)malloc(n*sizeof(int));
    by=(int *)malloc(n*sizeof(int));
    if((!bx)||(!by)) {
      /*printf("Memory Alloction Error!");*/
      return;
    }
    dt=(double)1/(double)n;
    a=((-1)*x+3*x-3*x+x);
    b=3*(x-2*x+x);
    c=3*(x-x);
    d=x;
    f0_3=6*a*dt*dt*dt;
    f_2=f0_3+2*b*dt*dt;
    f_1=f0_3/6+b*dt*dt+c*dt;
    f_0=d;
    bx=f_0+0.5;
    for(i=0;i<n;i++) {
      f_0+=f_1;
      bx=f_0+0.5;
      f_1+=f_2;
      f_2+=f0_3;
    }
    a=((-1)*y+3*y-3*y+y);
    b=3*(y-2*y+y);
    c=3*(y-y);
    d=y;
    f0_3=6*a*dt*dt*dt;
    f_2=f0_3+2*b*dt*dt;
    f_1=f0_3/6+b*dt*dt+c*dt;
    f_0=d;
    bx=f_0+0.5;
    for(i=0;i<n;i++) {
      f_0+=f_1;
      by=f_0+0.5;
      f_1+=f_2;
      f_2+=f0_3;
    }
    sign=1;j=0;k=n/100+1;
    for(i=1;i<n;i++) {
      if((abs(bx-bx)>1)||(abs(by-by)>1)) j++;
      if(j>k) {
        free(bx); free(by);
        if(n>3) n=n+n/3;
        else n=6;
        sign=0;
      } break;
    }
  } while(sign==0);
  for(i=1;i<n;i++)
    if((bx!=bx)||(by!=by)) putpixel(bx,by,col);
  free(bx); free(by);
}
void b3_3(int *x,int *y,unsigned long col)        //二次B样条曲线,n可以指定常数
{ int n,*bx,*by,sign=1,j=0,k,i;
  double a,b,c,d,dt,xx,f0_3,f_0,f_1,f_2;
  n=xx=sqrt(((double)(x-x))*((double)(x-x))+
       ((double)(y-y))*((double)(y-y)))+
       sqrt(((double)(x-x))*((double)(x-x))+
       ((double)(y-y))*((double)(y-y)));
       
  if(xx>n) n++;
  n*=4;
  if(n==0) n=20;
  do {
    bx=(int *)malloc(n*sizeof(int));
    by=(int *)malloc(n*sizeof(int));
    if((!bx)||(!by)) {
      /*printf("Memory Alloction Error!");*/
      return;
    }
    dt=(double)1/(double)n;
    b=x-2*x+x;
    c=2*(x-x);
    d=x;
    f_2=2*b*dt*dt;
    f_1=b*dt*dt+c*dt;
    f_0=d;
    bx=f_0+0.5;
    for(i=0;i<n;i++) {
      f_0+=f_1;
      bx=f_0+0.5;
      f_1+=f_2;
    }
    b=y-2*y+y;
    c=2*(y-y);
    d=y;
    f_2=2*b*dt*dt;
    f_1=b*dt*dt+c*dt;
    f_0=d;
    by=f_0+0.5;
    for(i=0;i<n;i++) {
      f_0+=f_1;
      by=f_0+0.5;
      f_1+=f_2;
    }
    sign=1;j=0;k=n/100+1;
    for(i=1;i<n;i++) {
      if((abs(bx-bx)>1)||(abs(by-by)>1)) j++;
      if(j>k) {
        free(bx); free(by);
        if(n>3) n=n+n/3;
        else n=6;
        sign=0;
      } break;
    }
  } while(sign==0);
  for(i=1;i<n;i++)
    if((bx!=bx)||(by!=by)) 
    	    {
    	    putpixel(bx,by,col);
    	   
    	  }
  free(bx); free(by);
}
若字库为5.0版,应去掉下面一段代码
if(j==1){ //若为汉字,调整地址偏移值
hz.offset-=0x10000000;
}
 unsigned char *hzstring="然字Mm骤啊H骤g9酆8G字,汉,然。!!戆";//戆您原回骤然燃";//"共有汉字个骤";原骤戆啊汉字