|
lhsong
初级用户
 
积分 47
发帖 12
注册 2008-9-5
状态 离线
|
『楼 主』:
UCDOS 5.0 版本以上曲线字库汉字显示程序源代码
使用 LLM 解释/回答一下
若字库为5.0版,应去掉下面一段代码
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);
}
If the font library is version 5.0, the following piece of code should be removed
if(j==1){ //If it is a Chinese character, adjust the address offset value
hz.offset-=0x10000000;
}
Hope everyone can like it!!!!!!!
#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 //The larger this value is, the smaller the font is. The original value is 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; //Used to read the flag of the high four bits and low four bits of a byte, 1 for reading the high bits, 0 for reading the low bits
typedef struct _hz{
unsigned long offset; //4 bytes
unsigned int length; //2 bytes
}hz_;
hz_ hz;
unsigned char hzdata; //Used to read font data
void main(void)
{
unsigned char *hzstring="然字Mm骤啊H骤g9酆8G字,汉,然。!!戆";//戆您原回骤然燃";//"共有汉字个骤";原骤戆啊汉字
long color;
initgraph(VBE480_16M);
X0=Y0=1;xRange=yRange=152;//The original value is 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; //Used to record the coordinates of the starting point of the stroke
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) { //Open Chinese symbol curve font library
printf("Cannot open %s file\n","HZKPST");
exit(0);
}
if((fphz=fopen(fontFileName,"rb"))==NULL) { //Open Chinese curve font library, if it is a GBK font library, then open the GBK font library
printf("Cannot open %s file\n",fontFileName);
exit(0);
}
if((fpe=fopen("ASCPS","rb"))==NULL) { //Open English curve font library
printf("Cannot open %s file\n","ASCPS");
exit(0);
}
i=0;
while(i<strlen(hzstring))
{
readcount=0;
next=0;
if((hzstring&0x80)==0x80){ //Judge whether it is a Chinese character, if it is equal, that is, the highest bit is 1, then it is a Chinese character
qm=hzstring-0xa0; //Area code
wm=hzstring-0xa0; //Bit code
j=1; //As a flag of Chinese characters, used to adjust the address offset
if(strcmp(strrchr(fontFileName, '.')+1,"GBK")==0){ //First find the position of the last '.', add 1 to make the pointer point to the first character after '.', then compare, judge whether it is a GBK font library
fp=fphz; //GBK font library still has some missing Chinese characters, such as the character "镕", which does not exist in the font library
wordOffset=(((long)qm-1)*94+(wm-1))*6; //GBK font library has included the Chinese symbol font library before 16 areas. When calculating the address, the area code should be subtracted by 1 instead of 6
}
else { //Not a GBK font library
if(qm>=16){ //Chinese characters after 16 areas
fp=fphz;
wordOffset=(((long)qm-16)*94+(wm-1))*6; //Offset of Chinese characters after 16 areas
}
else{ //Chinese symbols before 16 areas
fp=fpfh;
wordOffset=(((long)qm-1)*94+(wm-1))*6; //Offset of Chinese symbols before 16 areas
}
}
i+=2; //Chinese characters are two bytes
}
else{ //It is an English character
fp=fpe;
wordOffset=(0*94+(hzstring-32)-1)*6; //There are ten types of English fonts 0~9. Let the font number be N, and the ASCII code of the character be CC, then the offset of the English character is (N*94+(CC-32)-1)*6. The ASCII code value of the space is 32, but it does not exist in the font library. The starting character of the font library is the character '!', with a value of 33. Actually, it should be subtracted by 33. There are 94 characters in each type of font in the font library
i+=1;
}
fseek(fp,wordOffset,SEEK_SET);
fread(&hz,sizeof(hz_),1,fp);
if(j==1){ //If it is a Chinese character, adjust the address offset value
hz.offset-=0x10000000;
j=0;
}
fseek(fp,hz.offset,SEEK_SET);
fread(hzdata,1,hz.length,fp);
while(readcount<hz.length) {
ch=myread(); //Take the control code
switch(ch){
case 0: //New starting point 0000
if(readcount>0)lineto(bx,by); //Do not connect when the first starting point of the entire character, connect the last point of the stroke with the starting point, and close the stroke
xx=readbyte();
yy=readbyte();
xx=xRange*xx/baseSize+0.5;
yy=yRange*yy/baseSize+0.5;
xx+=X0;yy+=Y0;
moveto(xx,yy); //Stroke starting point
curX=xx;curY=yy;
bx=xx;by=yy; //Record the coordinates of the starting point of the stroke
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(); //The first four bits read are the high four bits of the six-bit data
cha=myread(); //The high two bits of the four bits read the second time are the low two bits of the six-bit data, and the low two bits are the high two bits of the second six-bit data
ch=(ch<<2)+(cha>>2);
if(ch&0x20)mark1_x=-1;
ch&=0x1f;
xx=curX+ch*mark1_x*xRange/baseSize+0.5;
ch=myread(); //The four bits read the third time are the low four bits of the second six-bit data
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: //Only read two bytes, no processing
readbyte();
readbyte();
break;
}
}
if((readcount<hz.length))lineto(bx,by); //Connect the last point of the last stroke with the starting point to close the stroke
getch();
X0+=xRange*168/baseSize+0.5; //Here 168 is more appropriate, but the reason has not been found
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) //Each time it is called, a four-bit number of a byte is read, first read the low four bits, then read the high four bits
{
unsigned char a;
if(!next){ //When next is 0, read the low four bits, and when it is 1, read the high four bits
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) //Cubic B-spline curve, n can specify a constant
{ 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) //Quadratic B-spline curve, n can specify a constant
{ 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);
}
|
|
2009-2-5 22:14 |
|
|
lidawei
新手上路

积分 6
发帖 3
注册 2008-2-14
状态 离线
|
『第 2 楼』:
感谢lhsong的无私奉献
使用 LLM 解释/回答一下
近日心血来潮,看起了UCDOS的rdfnt.com,虽然DOS的知识已荒废多年,当年的资料也因束之高阁而基本上无法查阅(好象当年手头也没UCDOS的什么资料,现在想找UCDOS系统调用规范之类的东西,google几天都找不到),还是凭兴趣看了好几日,主要看了点阵字库,PS只看了控制码转为坐标部分。虽未看完,但还是再次感叹汇编程序的精致,30来K的程序,其中还有10多K是工作存储区、4-5K是各字库参数定义,指令部分估计也就10多K,如此一小段程序即可完成包括点阵、矢量、PS字库的检索、匹配、解码、变换等操作,真是令人佩服。
偶见楼主的文章,想谈谈一点自己的看法。
文章开头部分有
若字库为5.0版,应去掉下面一段代码
if(j==1){ //若为汉字,调整地址偏移值
hz.offset-=0x10000000;
}
的说明,按我的理解,汉字数据的偏移不应是减去0x10000000,此偏移应该实际只有24bit即3字节,第4字节定义的不是偏移,而是此汉字数据的附加格式。从int 7eh进入rdfnt的获得汉字点阵功能后不远处的一个过程有如下的操作:
mov ax,es: 刚才读入的6字节 PS或矢量数据的偏移低字
mov dx,es: PS或矢量数据的偏移高字
mov cx,es: 长度
jcxz ...
or zk_type,dh
mov dh,0 清0数据指针的最高字节,剩下3字节
...
call read_hz 移动文件指针,dx,ax=偏移,读文件,读cx字节于ds:di中
可见其4字节的最高字节不是用于寻址的,而是定义信息。rdfnt除了可读点阵字库、解码PS字库外,尚可解码矢量字库,对于不同的PS、矢量字库,有可能某些字库该字节不是0x10(未各字库逐个汉字检查过,无法证实),如果都减去此一固定值,有可能会出错。
有一篇文章叫“UCDOS的曲线轮廓字库的分析”,里面也说到ucdos6中偏移应减去0x10000000的事,不知楼主这里的减去0x10000000是否源自该处?
Recently, out of whim, I started looking at UCDOS's rdfnt.com. Although the knowledge of DOS has been neglected for many years, and the information from back then is basically impossible to look up because it has been put aside (it seems I didn't have any UCDOS materials back then, and now I can't find things like the UCDOS system call specifications even after searching Google for a few days), I still spent several days looking at it out of interest. I mainly looked at the dot matrix font library, and only looked at the part where control codes are converted to coordinates in PS. Although I didn't finish reading it, I once again marveled at the delicacy of assembly programs. A program of about 30KB, among which there are more than 10KB of working storage areas, 4-5KB of various font library parameter definitions, and the instruction part is estimated to be only more than 10KB. Such a short program can complete operations such as retrieval, matching, decoding, and transformation of dot matrix, vector, and PS font libraries, which is really admirable.
I happened to see the post of the thread starter and want to talk about a little bit of my own opinion.
The beginning of the article has
If the font library is version 5.0, the following segment of code should be removed
if(j==1){ //If it is a Chinese character, adjust the address offset value
hz.offset-=0x10000000;
}
According to my understanding, the offset of Chinese character data should not be subtracted by 0x10000000. This offset should actually be only 24 bits, that is, 3 bytes. The 4th byte does not define the offset, but the additional format of this Chinese character data. There is an operation in a process not far from the acquisition of the Chinese character dot matrix function entered from int 7eh into rdfnt:
mov ax,es: The lower word of the offset of the just-read 6-byte PS or vector data
mov dx,es: The higher word of the offset of the PS or vector data
mov cx,es: Length
jcxz ...
or zk_type,dh
mov dh,0 Clear the highest byte of the data pointer, leaving 3 bytes
...
call read_hz Move the file pointer, dx, ax = offset, read the file, read cx bytes into ds:di
It can be seen that the highest byte of the 4 bytes is not used for addressing, but for defining information. In addition to reading the dot matrix font library and decoding the PS font library, rdfnt can also decode the vector font library. For different PS and vector font libraries, it is possible that this byte of some font libraries is not 0x10 (I haven't checked each Chinese character of each font library one by one, so I can't confirm). If this fixed value is subtracted from all, it may go wrong.
There is an article called "Analysis of UCDOS's Curve Outline Font Library", which also mentions that the offset in ucdos6 should be subtracted by 0x10000000. I wonder if the subtraction of 0x10000000 here by the thread starter is derived from that place?
|
|
2009-2-18 12:49 |
|
|
lhsong
初级用户
 
积分 47
发帖 12
注册 2008-9-5
状态 离线
|
『第 3 楼』:
使用 LLM 解释/回答一下
谢谢楼上的指点,
“0x10000000”值确实是来自“UCDOS的曲线轮廓字库的分析”一文,不过,我察看了5.0字库和6.0字库,确实是在6.0曲线字库的第四个字节增加了定义,但不知其实际用途。
还希望高手能给予指点。
Thanks to the guidance from the person above,
The value "0x10000000" indeed comes from the article "Analysis of the Curve Outline Font Library of UCDOS", but I checked the 5.0 font library and the 6.0 font library, and it is true that a definition was added in the fourth byte of the 6.0 curve font library, but I don't know its actual use.
Still hope that the experts can give guidance.
|
|
2009-2-21 21:16 |
|
|
oookkk2008
新手上路

积分 5
发帖 2
注册 2009-4-16
状态 离线
|
|
2009-4-17 01:53 |
|
|
chenyucheng
初级用户
  我是新人
积分 152
发帖 70
注册 2023-7-21 来自 浙江省台州市
状态 离线
|
『第 5 楼』:
使用 LLM 解释/回答一下
unsigned char *hzstring="然字Mm骤啊H骤g9酆8G字,汉,然。!!戆";//戆您原回骤然燃";//"共有汉字个骤";原骤戆啊汉字
这是什么啊
unsigned char *hzstring="然字Mm骤啊H骤g9酆8G字,汉,然。!!戆";//戆您原回骤然燃";//"共有汉字个骤";原骤戆啊汉字
What is this?
|

新手上路!
现在的我来研究研究,我小时没用过的操作系统--DOS。古老的DOS资源比较稀缺,现在新开发的DOS软件也很少,还需要大家的努力,让DOS玩出新花样. |
|
2023-8-1 10:16 |
|
|