利用WPS中的曲线字体生成优美汉字-Auto CAD
·当前位置: 学海荡舟-论文 >> 电脑技术 >> 图形图象 >> Auto CAD
利用WPS中的曲线字体生成优美汉字



 摘要 该文根据WPS中曲线字体的结构,利用AutoCAD本身的功能

和其ADS接口,提供了在AutoCAD中生成曲线汉字的方法,并给出了相应

的C语言源程序清单。

关键字 曲线字体 ADS 拟合 Bezier曲线

一、引言

AutoCAD是目前微机上广泛使用的绘图平台,其上使用的汉字常常

是通过形文件(.shx)来实现的,虽然采用的是矢量字体,但放大后总不

够满意,而且也不便于对笔划进行编辑或对空心字进行填充。现在的W

PS中提供了多种优美的中文曲线字体(.ps文件),这些字体文件中存放

的是相应字体的轮廓描述信息。如果按其中的信息来绘制图案,自然

可获得优美的轮廓汉字,并可填充或编辑。关于中文曲线字体的结构,

《微电脑世界》1996.1中袁国强等撰写的《揭开PostScript字体的奥

秘》一文中已经作了详细介绍,本人参照其内容要点,结合AutoCAD的

功能特点,利用其ADS开发系统作了绘制曲线汉字的尝试。

二、AutoCAD处理曲线字体的有效性

曲线字体中所使用的曲线有两种,一种是由3点控制的二次Bezier

曲线,另一种是由4点控制的3次Bezier曲线。通过数学推导可证明,只

要把控制点作适当变换,可用3次Bezier曲线精确地代替二次Bezier曲

线,这样,实质上可统一为由4点控制的3次Bezier曲线。而在AutoCAD

中恰好有拟合曲线的功能,当系统变量"SplieType"的值设置成6时,笔

者经过精确测试,当控制点为4时,系统是按3次Bezier曲线来以分段拟

合曲线的(尽管书上声称为3次B-Spline),且分段数是由系统变量"Spl

ineSegs"决定的,当该值取为负值时还能在分段的基础上用圆弧拟合,

达到了非常光滑的程度。关于曲线字体中的直接处理,则更为容易。

因此,用AutoCAD来处理曲线汉字将有独到之处。另外,AutoCAD从R11

版开始提供了ADS接口,即支持C语言编程。这样,根据曲线字体的结构

,用C语言来处理二进制数据,而用AutoCAD来处理相应的轮廓绘制,就

能有效地展示曲线汉字的风彩。

三、程序清单

为了减少篇幅,程序中只考虑了用区位码输入单个汉字的方法,读

者可对程序作适当修改以便使程序能处理汉字串等。关于ADS程序的

编译和链接,可参考有关文献。笔者所编程序分别用Watcom C9.01和T

urbo C++3.1编译和链接,并在AutoCAD R12 for DOS和for Windows中

调试通过。

/*文件名:PSHZ.C

使用方法:

在AutoCAD下,先用SETVAR命令把有关系统变量设置如下:

"SplineType"=6(样条类型)

"SplineSegs"=-8(用圆弧分段代替样条)

"SnapMode"=0(关掉目录捕捉)

"SplFrame"=0(不显示控制边框)

再通过xload函数装入pshz.exp或pshz.exe,在命令状态下打入PS

HZ,并根据提示陆续输入曲线字体文件名、区位码、左上角定位点及

文字高度。

*/

#include

#include

#include"abslib"

#define COPY-POINT(Dp,Sp){(Dp)[0]=(Sp)[0];(Dp)[1]=(Sp)[1

];

}

#define INDEX(Arr) ((long(Arr)[2]*65536+(long)(Arr)[1]*2

56+(long)(Arr)[0])

unsigned int mainCount,mainBlockSize,subCount,subBlockSi

ze;

unsigned char *mainBlock,*subBlock;

ads-real scaleX,scaleY;

void main(int,char **);

int dofun(void);

int funcload(void);

int pshz(struct resbuf *rb);

unsigned char readBlock(int);

int drawHandle(int,unsigned char,ads real, ads real, ads

point, ads point);

int partHandle(FLIE *,unsigned char *,long,ads-point);

void main(argc,argv) int argc;

char *argv[];

{

short scode=RSRSLT;

int stat;

char errmsg[80];

ads-int(argc,argv);

for(;;)

{

if((stat=ads-link(scode))<0)

{

sprinft(errmsg,"PSHZ:bad status from ads-link()=%d\n",st

at);

exit(1);

}

scode=RSRSLT;

switch(stat)

{

case RQXLOAD: scode=funcload()==RTNORM?RSRSLT:RSERR;

break;

case RQSUBR: scode=dofun()==RTNORM?RSRSLT:RSERR;

break;

default;

break;

}}}

static int funcload(){if(!ads-defun("c:pshz",0)) return

RTERROR;

return RTNORM;

}

static int dofun(){struct resbuf *rb;

if(!ads-getfuncode()==0{

ads-fail("Received nonexistent function code.");

return RTERROR;

}

rb=ads getargs();

return pshz(rb);

}

static int pshz(rb)struct resbuf *rb;

{

int qw,qm,wm;

ads-point refP,curP;

char fileName[128];

long firstIndex,secondIndex,wordOffset;

unsigned char indexValue[2][3],partData[11];

FILE *fp;

int i,j;

char controlWord;

ads-getstring(0,"\npsFontFileName(eg.KTDOT.PS):",fileNam

e);

ads-getint("\nQuWeiMa:",&qw);

ads-getpoint(NULL,"\nupperleft point:",refp);

ads getreal("\nText height:",&scaleY);

scaleY/=160.0;

scaleX=scaleY;

scaleY=-scaleY;

mainCount=0;

if(!(fp=fopen(fileName,"rb"))){

ads-printf("Cannot open %s file\n",fileName);

return RTERROR;

}

wordOffset=72*94*3;

fseek(fp,wordOffset,SEEK-SET);

fread(indexValue[0],3,1,fp);

secondIndex=INDEX(indexValue[0]);

qm=qw/100;

wm=qw%100;

wordOffset=(((long)qm-16)*94+wm-1)*3;

fseek(fp,wordOffset,SEEK-SET);

fread(indexValue[0],3,1,fp);

fread(indexValue[1],3,1,fp);

firstIndex=INDEX(indexValue[0]);

mainBlockSize=INDEX(indexValue[1])-firstIndex;

mainBlock=(unsigned char *)malloc(mainBlockSize);

if(!mainBlock){

ads-printf("Out of memory!\n");

goto err2;

}

fseek(fp,firstIndex,SEEK SET);

fread(mainBlock,1,mainBlockSize,fp);

while(mainCount<2*mianBlockSize)

{

controlWord=readBlock(0);

if(controlWord<=7)

{

if(drawHandle(0,controlWord,1.0,1.0,refP,curP)!=RTNORM)

goto err1;

}

else

{

partData[0]=controlWord;

for(i=1;i<11;i++)

partData=readBlock(0);

if(partII andle(fp,partData,secondIndex,refP)!=RTNORM)

goto err1;

}}

free(mainBlock);

fclose(fp);

return RTNORM;

err1: free(mainBlock);

err2: fclose(fp);

return RTERROR;

}

unsigned char readBlock(int SubOrMain)

{

if(subOrMain==0)

return (0x0f & (mainBlock[mainCount/2]>>((1-((mainCount+

+)%2))*4)));

return (0x0f & (subBlock[subCount/2]>>((1-((subCount++)%

2))*4)));

}

int drawHandle(blkNo,controlWord,facX,facY,refP,curP)

int blkNo;

unsigned char controlWord;

ads-real facX,facY;

ads-point refP,curP;

{

int i,j;

ads-point p[4],scaleP;

scaleP[0]=scaleX*facX;

scaleP[1]=scaleY*facY;

switch(controlWord)

{

case 0:

for(i=0;i<2;i++)

{

p[0]=(int)readBlock(blkNo)*16+readBlock(blkNo);

p[0]*=scaleP;

p[0]+=refP;

}

COPY POINT (curP,p[0]);

break;

case 1:

case 2: i=controlWord-1;

j=(i+1)%2;

p[0]=(int)readBlock(blkNo)*16+readBlock(blkNo);

p[0]*=scaleP;

p[0]+=refPp[0][j]=curP[j];

goto line;

case 3: for(i=0;i<2;i++)

{

p[0]=(int)readBlock(blkNo)*16+readBlock(blkNo);

p[0]*=scaleP;

p[0]+=refP;

}

line;

ads-command(RTSTR,"pline",RTPOINT,curP,RTPOINT,p[0],RTST

R,"",0);

COPY POINT(curP,p[0]);

break;

case 4:

case 5: COPY-POINT(p[0],curP);

for(i=1;i

  • 上一篇教程:
  • 下一篇教程:
  • :查看相关:
  • 解决R14打开R12文件的汉字乱码问题
  • 怎样在AutoCAD2004中自定义字体
  • CAD2000-CAD2004中的两个技巧
  • CAD2000-CAD2004中的两个技巧
  • 怎样在AutoCAD2004中自定义字体