📄 graphic.c
字号:
/*** <计算机图形学>课程设计 ***/
/* 文 件 名: Graphic.c
* 附加文件: Hzk12 (12X12点阵汉字字模库文件)
* 开发模式: MS-DOS程序
* 开发环境: Turbo C 2.0
* 作 者: 毛建忠
* E - Mail: Mao_jzh@163.com
* 完成时间: 2001年4月底
* 完成地点: 华东地质学院综合楼507机房
*/
/* 备注:
* 程序主要实现的功能: MS-DOS状态下跟随鼠标轨迹显示“欢迎
* 联系:Mao_jzh@163.net”,并且可以改变字体颜色和轨迹颜色。
* 由于Windows 2000将一些底层中断调用屏蔽,程序在Win2000的
* 命令状态下运行时看不到鼠标光标,其他功能仍可实现。
*/
/*******************************************************/
#include "graphics.h"
#include "dos.h"
#include "stdio.h"
#include "io.h"
#include "fcntl.h"
#include "conio.h"
#include "math.h"
/* 预定义in和out, 详见函数box的注解 */
#define in 1 /* flag of box inside */
#define out 0 /* flag of box outside link an button */
#define DRAW 100
#define EXIT 200
int file;
union REGS regs; /* 寄存器 */
void initmouse() /* 初始化鼠标 */
{
int flag;
regs.x.ax=0;
int86(0x33,®s,®s); /* 0x33为鼠标中断 */
flag=regs.x.ax;
if(flag!=-1) /** 鼠标初始化失败 **/
{ printf("\n\n\tNO MOUSE!"); exit(0); }
}
void noico() /* hide mouse curser 隐藏鼠标光标 */
{
regs.x.ax=2;
int86(0x33,®s,®s);
}
void ico() /* show mouse curser 显示鼠标光标*/
{
regs.x.ax=1;
int86(0x33,®s,®s);
}
/* 控制鼠标活动的范围并显示鼠标光标 */
void showmouse() /* set the range of the mouse curser */
{
regs.x.ax=7;
regs.x.cx=25;
regs.x.dx=620;
int86(0x33,®s,®s); /* 鼠标X方向活动范围(25~620) */
regs.x.ax=8;
regs.x.cx=25;
regs.x.dx=455;
int86(0x33,®s,®s); /* 鼠标Y方向活动范围(25~455) */
ico();
}
/* 功能:获取鼠标坐标及鼠标按钮按下的状态 */
/* 参数:指向存储鼠标当前坐标的变量的指针 */
int mouseimg(int *x,int *y) /* mouse position and button down */
{
regs.x.ax=3;
int86(0x33,®s,®s);
*x=regs.x.cx;
*y=regs.x.dx;
return regs.x.bx; /* 返回按钮按下的状态 */
}
/**** draw box inside or outside(like a button) ****/
/* 功能:绘制界面中的按钮或窗口,由内外两个框组成,突出立体感 */
/* 参数:边框的四角坐标,窗体类型(in或out),内外两个框间的间距 */
/* type参数为in时,绘制窗口,为out时绘制按钮 */
void box(int left,int top,int right,int bottom,int type,int w)
{
register int i,c1,c2;
/* if语句选择窗体类型 */
if(type) { c1=DARKGRAY; c2=WHITE; }
else { c1=WHITE; c2=DARKGRAY; }
/* 以下绘制窗体边框 */
for(i=left;i<=right;i++)
{ putpixel(i,top,c1); putpixel(i,bottom,c2); }
for(i=top;i<=bottom;i++)
{ putpixel(left,i,c1); putpixel(right,i,c2); }
left+=w; top+=w; right-=w; bottom-=w;
for(i=left;i<=right;i++)
{ putpixel(i,top,c1); putpixel(i,bottom,c2); }
for(i=top;i<=bottom;i++)
{ putpixel(left,i,c1); putpixel(right,i,c2); }
}
/**** print/draw hz 12*12 ****/
/* 功能:窗体上的汉字文本输出 */
/* 参数:汉字输出位置,颜色和汉字字符串 */
void text(int x,int y,int color,char *str)
{
register i,j,k;
unsigned char qm,wm;
unsigned char flag[8]={128,64,32,16,8,4,2,1};
long offset;
unsigned char code[24];
while(*str!=0)
{
qm=*(str++)-0xa1; wm=*(str++)-0xa1;
offset=(qm*94+wm)*24L; /* 确定汉字字模在文件中的位置 */
lseek(file,offset,SEEK_SET);
read(file,code,24); /* 读取字模阵列到内存 */
/* 以下输出汉字象素阵列,先输出前面8列,再输出后面4列 */
for(i=0;i<8;i++) /* first of the 8 point of 12 */
for(j=0;j<12;j++)
if(code[2*j]&flag[i]) putpixel(x+i,y+j,color);
for(i=0;i<4;i++) /* the last 4 point */
for(j=0;j<12;j++)
if(code[2*j+1]&flag[i]) putpixel(x+8+i,y+j,color);
x+=13; /* 汉字列之间间隔一个象素 1 point between two hz */
}
}
/* 绘制程序界面 */
void face()
{
register int i,j;
char *label[6]={"蓝","绿","红","灰","紫","黄"};
int col[6]={1,2,4,7,13,14};
box(5,5,635,475,out,3); /* 界面的外框架(主窗口) */
box(15,15,550,465,in,2); /* 绘图(即显示字符串)区间 */
text(555,25,DARKGRAY,"轨迹颜色");
box(557,40,625,200,in,2); /* 轨迹颜色选择区间 */
text(555,225,DARKGRAY,"字体颜色");
box(557,240,625,400,in,2); /* 字体颜色选择区间 */
/* 颜色选择项 */
for(i=0;i<6;i++)
{
for(j=0;j<2;j++)
{
circle(580,55+25*i+200*j,7);
text(600,50+25*i+200*j,col[i],label[i]);
}
}
/* 绘制退出按钮 */
box(560,430,620,455,out,2);
text(575,437,DARKGRAY,"退出");
}
void quit()
{
closegraph();
close(file);
exit(0);
}
/* 功能:检测鼠标状态和鼠标事件 */
/* 参数:鼠标当前位置(已经按下) */
/* 返回:鼠标点击的按钮(或者是在绘图区按下)*/
int which(int x,int y) /* return the button which the mouse selected */
{
register int i; /*** mouse in the workspace ? ***/
if(x>25&&x<550&&y>25&&y<465) return DRAW;
if(x>560&&x<620&&y>430&&y<455) return EXIT;
if(x>570&&x<620)
{ /* 选择了轨迹颜色或字体颜色 select line color OR font color */
for(i=0;i<6;i++) if((y>50+25*i)&&(y<70+i*25)) return i+1;
for(i=0;i<6;i++) if((y>250+25*i)&&(y<270+i*25)) return 11+i;
}
return 0;
}
/* 功能:跟随鼠标显示字符串 */
/* 参数:字符串显示的起始位置和字体颜色 */
void show(int x,int y,int fontcol)
{
int record,i,j,k,x0=x,y0=y;
long pointer;
float l,SQ,CQ;
char ch,Bit[24];
unsigned char flag[8]={128,64,32,16,8,4,2,1};
unsigned char far *Char=(char far *)0xf000fa6eL; /* ASCII字符阵列其始地址 */
unsigned char num,qm,wm;
char *str="欢迎联系:Mao_jzh@163.com";
char *str0=str;
while(mouseimg(&x,&y))
{
if(x>540) return;
l=(float)sqrt((float)(x0-x)*(x0-x)+(float)(y0-y)*(y0-y));
/* l为输出前一字符后鼠标移动的距离 */
/* 当当前字符为汉字时,必须l>=24,为ASCII时必须l>=16才输出字符 */
if(*str0==0) str0=str;
num=*str0;
if(num>0xa0&&l>=24) /* 当前字符为汉字 Is HZ ? */
{
noico();
qm=(num-0xa1)&0x07f;
num=*(str0+1);
wm=(num-0xa1)&0x07f;
record=qm*94+wm;
pointer=record*24L;
lseek(file,pointer,SEEK_SET);
read(file,Bit,24);
for(i=0;i<12;i++)
for(j=0;j<2;j++)
for(k=0;k<8;k++)
if(Bit[i*2+j]&flag[k])
{ SQ=(y-y0)/l; CQ=(x-x0)/l; /* 计算轨迹斜率 */
putpixel(x0+(j*8+k)*2*CQ+i*2*SQ,y0+i*2*CQ-(j*8+k)*2*SQ,fontcol);
}
str0+=2;
line(x,y,x0,y0); /* 输出轨迹 */
x0=x; y0=y;
ico();
}
else if(num<0x7e&&num>0x00&&l>=16) /* ASCII字符输出 draw E char */
{
noico();
for(i=0;i<8;i++)
{
ch=*(Char+num*8L+i);
for(j=0;j<8;j++)
if(ch&flag[j])
{ SQ=(y-y0)/l; CQ=(x-x0)/l; /* 计算轨迹斜率 */
putpixel(x0+j*2*CQ+i*2*SQ,y0-j*2*SQ+i*2*CQ,fontcol);
}
}
str0++;
line(x,y,x0,y0); /* 输出轨迹 */
x0=x; y0=y;
ico();
}
}
}
void dowork()
{
int x,y,select,linecol=DARKGRAY,fontcol=DARKGRAY;
int mousefree=0;
while(1) /* 消息循环 ^0^ */
{ /*** 检测鼠标状态和鼠标事件 mouse button down ? *****/
while(!mousefree) mousefree=mouseimg(&x,&y);
select=which(x,y);
switch(select)
{
case 1: linecol=1; break;
case 2: linecol=2; break;
case 3: linecol=4; break;
case 4: linecol=7; break;
case 5: linecol=13; break;
case 6: linecol=14; break;
case 11: fontcol=1; break;
case 12: fontcol=2; break;
case 13: fontcol=4; break;
case 14: fontcol=7; break;
case 15: fontcol=13; break;
case 16: fontcol=14; break;
case DRAW: /* 鼠标在绘图区按下 */
show(x,y,fontcol);
break;
case EXIT: quit(); break; /* 点击了退出按钮 */
}
setcolor(linecol);
mousefree=0;
}
}
main()
{
int driver=DETECT,mode;
if((file=open("hzk12",O_RDONLY|O_BINARY))==-1) /* 打开字模库文件 */
{ printf("\n\n\tCAN'T OPEN HZK FILES!"); exit(0); }
initgraph(&driver,&mode,""); /* 初始化图形设备环境 */
directvideo=0;
face();
initmouse();
showmouse();
setcolor(DARKGRAY);
dowork();
}
/****************************************************/
/*
* 注释修改:
* 于:佛山市三水区建设银行职工宿舍
* 2003-2-20
*
* Turbo C虽失去了其商业价值,却能成为编程爱好者们工作之余
* 的消谴和编程初学者的入门导师。我将继续完成大学里《图形学》教
* 程中各个章节的实验程序。
*/
/***************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -