?? 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; /* 返回按鈕按下的狀態 */
}
/* 功能:繪制界面中的按鈕或窗口,由內外兩個框組成,突出立體感 */
/* 參數:邊框的四角坐標,窗體類型(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 + -