⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphic.c

📁 在dos环境下的汉子点阵信息输出和更改
💻 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,&regs,&regs);   /* 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,&regs,&regs);
}

void ico()                /* show mouse curser 显示鼠标光标*/
{
	regs.x.ax=1;
	int86(0x33,&regs,&regs);
}

/* 控制鼠标活动的范围并显示鼠标光标 */
void showmouse()         /* set the range of the mouse curser */
{
	regs.x.ax=7;
	regs.x.cx=25;
	regs.x.dx=620;
	int86(0x33,&regs,&regs); /* 鼠标X方向活动范围(25~620) */
	regs.x.ax=8;
	regs.x.cx=25;
	regs.x.dx=455;
	int86(0x33,&regs,&regs); /* 鼠标Y方向活动范围(25~455) */
	ico();
}

/* 功能:获取鼠标坐标及鼠标按钮按下的状态 */
/* 参数:指向存储鼠标当前坐标的变量的指针 */
int mouseimg(int *x,int *y)                /* mouse position and button down */
{
	regs.x.ax=3;
	int86(0x33,&regs,&regs);
	*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 + -