关于矢量字库的读取及其算法...
关于矢量字库的读取及其算法...
你的问题使我想起我的高中时代。
我读高一时(那时是1999年),在校图书馆借了一本C语言应用的程序(书名和出版社已记不请了,只记得书名有个“应用”一词),这本书非常棒!虽然书不大也不厚,但有读取 UCDOS 的各种矢量字体并作字体变形、旋转、填充、空心字等效果的源程序,还有读取并显示BMP图片实例程序以及扫雷游戏程序!这些程序都是在 Turbo C 2.0 下开发的源程序!




这本书我只借了一次,也在电脑上输入几个珍贵的源程序,后来就把书还了。谁知一年后我的电脑染上了可恶的病毒,硬盘分区表破坏了,硬盘内部的资料也受病毒改写,不得不忍痛割爱、重新分区、格式化,宝贵的源程序都灰飞烟灭

……还书以后,就再也找不到这本书了。那图书馆比较小,藏书不多,用电脑查找该书,结果显示仅有一本。每次去图书馆我都经常去寻找这本宝典,还与图书管理员联系、帮忙,直至高三毕业了,仍寻而无果,我猜该书以丢失了,而市面上也没有一本C语言应用的书籍能与之媲美,这给我的高中时代留下一大遗憾

。
上了大学,开始接触互联网,感受到现在已经是VB、VC等Windows编程统领的时代,DOS 下的QB 和 C 编程已是明日黄花,研究和利用的价值已经贬得很低了,况且,受我选的专业的限制,我再也没花心机去研究编程。
好了,说了这么多,虽然书很难找,但我想这些程序应该可以在ProgramFan、QB 等论坛上找的到,楼主加油吧!
/*****来自http://www.moon-soft.com/program/doc/docelite1257.htm****/
/* 请问ucdos矢量字库算法 */
/* 矢量汉字的读取和显示 */
#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; /* 汉字索引 */
unsigned char buf;
unsigned char dotbuf;
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.size, HZ_Index.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;
}
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 = dotbuf;
BH.str = dotbuf;
if (BH.size == 0)
break; /* 每个汉字以0结束 */
x0 = START_X + (dotbuf * VIEW_W) / HZKSIZE;
y0 = START_Y + (dotbuf * VIEW_H) / HZKSIZE;
//x0 = START_X + dotbuf;
//y0 = START_Y + dotbuf;
moveto(x0, y0);
for (j = 0; j < BH.size - 1; j++) {
x1 = START_X + (dotbuf * VIEW_W) / HZKSIZE;
y1 = START_Y + (dotbuf * VIEW_W) / HZKSIZE;
//x1 = START_X + dotbuf;
//y1 = START_Y + dotbuf;
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 = (k - lposi - 2) / 2;
dotbuf = 0;
lposi = k++;
k++;
}
x0 = ( * p & 0x3f) << 1;
dx = ( * (p + 1) >> 7) & 0x01;
dx = dx + x0;
p++;
dy = * p++ & 0x7f;
dotbuf = xsum = dx;
dotbuf = 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 = xsum;
dotbuf = 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 = xsum;
dotbuf = 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 = xsum;
dotbuf = ysum;
p++;
}
}
}
dotbuf = 0;
dotbuf = 0;
dotbuf = (k - lposi - 2 - 2) / 2;
dotbuf = 0;
return k;
}
-- edit by AlexZhang: code formatting
UCDOS下的例程用的是他自己的特显功能来完成的.这样的话就无法掌控这一技术.所以要求自己能掌握这一技术.以免受制于人啊.
谢谢Firstsail提供的算法.COPY下来后等会儿再试试.