直接写屏显示文字

类别:编程语言 点击:0 评论:0 推荐:

看到有前(钱)人发表了DOS下的东西,咱也凑凑热闹,把毕业设计时用过的一个小东西也拿出来晾晾,别霉了!

这是一个DOS下直接写屏显示16点阵汉字的演示程序
功能由函数OutText()完成,该函数区别于大多数此类函数的特点如下
.支持视区剪裁输出
.支持屏幕任意位置输出(不局限于一般直接写屏方法640X480分辩率下的输出位置必须为8的整数倍)
.支持英文字母及数字的8X16点阵输出
.支持直接写屏下的彩色汉字输出

演示起见,未加入将字库读入XMS内存,并从XMS内存读取字模的代码,因此纯DOS下运行可能会频繁的读硬盘。
要得到有XMS支持的直接写屏功能,可查看EGL程序源代码。
(2001.10.13日注:这个EGL是学校时做的一个DOS下仿Window3.1的界面库(Easy Graphics Library)。很完整,菜单,对话框,鼠标,键盘,图形下闪烁光标,可移动窗口,XMS,动画,位图,编辑控制,检查框,单选钮,push按钮等等,都支持,现在看看那时真是狂热,没有配套磁盘的书中的例子,就用手硬敲。刚才我又大略看了一遍,真是TMD破腚百出,哎,都是过去的事了)
废话说了一大堆,又发了点小感慨,说正题吧,下面是代码,格式为了对齐,把tab全换成了空格,多见谅吧,可执行文件目录下需要hzk16与asc16两个字库文件(ucdos自带)及EGAVGA.BGI这个老东西,如果你硬盘上无这些东西,那请到http://www.csdn.net/filebbs/read_topic.asp?id=677下载打包后文档

补充一句吧,CSDN上卧虎藏龙,小人这点小代码牛人就见怪不怪吧,如果实在不痛快,以后在街上看到我就狗血喷头的骂一顿吧,在这先谢罪了

                                                                                                                       MSVCer(家宝)

/*
OutText.C,Turbo C 2.0
WangJiaBao Create
ShenYang Electric Power Institute,1997.09.19
*/
/*
WangJiaBao Modify for friend
ShenYang Thermo Power Plant,2001.04.20
*/
/*
WangJiaBao Modify for CSDN
ShenYang Thermo Power Plant,2001.10.13
*/

#include "dos.h"
#include "stdio.h"
#include "stdlib.h"
#include "graphics.h"

FILE *fp_hzk,*fp_asc;
/*
OutText()各参数意义:
x 字符串x轴坐标
y 字符串y轴坐标
color 字符串颜色
hz 字符串地址
*/
void OutText(int x,int y,unsigned char color,unsigned char *hz);

main()
{
    int gd=VGA,gm=VGAHI;
    int x,y,len,color,y8X8=2,y8X16=16,bottom=447;
    int wl=120,wt=100,wr=520,wb=315; /* 视区坐标 */
    unsigned long times=1,time1=0,time2=0;
    unsigned char tmpstr[100],\
        *errorhzk="\nError open hzk16\a",\
        *errorasc="\nError open asc16\a",\
        *goon="任意键继续演示",\
        *viewport="演示OutText()函数的视区显示能力",\
        *demoviewstr="在视区(%d,%d,%d,%d)内显示汉字,起点坐标为X=%d Y=%d",\
        *fonts="比较8x8与8x16两种点阵ASCII码字符的输出效果",\
        *hello="小人向各位CSDN的朋友问好",\
        *report="%lu秒输出句子%lu次.",\
        *enddemo="演示OutText()函数的高速写屏能力,任意键结束演示";
   
    if( (fp_hzk=fopen("hzk16","rb"))==NULL ){ /* 打开16*16点阵汉字库文件 */
        printf(errorhzk);
        exit(1);
    }
    if( (fp_asc=fopen("asc16","rb"))==NULL ){ /* 打开ASCII码8*16点阵文件 */
        printf(errorasc);
        fclose(fp_hzk);
        exit(1);
    }
    initgraph(&gd,&gm,"");
   
    /* 1.演示OutText()函数的全屏输出及视区显示能力 */
    setfillstyle(WIDE_DOT_FILL,BLUE);
    bar(0,0,639,479);
    setfillstyle(SOLID_FILL,WHITE);
    bar(wl,wt,wr,wb);
    setviewport(wl,wt,wr,wb,1); /* 定义视区 */
    for(x=y=0;x<=15;x++,y+=16){
        sprintf(tmpstr,demoviewstr,wl,wt,wr,wb,x,y);
        OutText(x,y,BLUE,tmpstr);
    }
    setviewport(0,0,639,479,1); /* 重置视区 */
    OutText(320-strlen(viewport)*4,60,YELLOW,viewport);
    OutText(320-strlen(goon)*4,80,LIGHTCYAN,goon);
    getch();
    /* 2.演示图形模式下的ASCII码字符,以8X8点阵和8X16点阵输出之间的对比 */
    setfillstyle(SOLID_FILL,BLACK);
    bar(0,0,639,479);
    x=0;
    tmpstr[0]=tmpstr[1]='\0';
    textcolor(WHITE);
    do{
        if( x>630 ){ y8X8+=48; y8X16+=48; x=0; }
        outtextxy(x,y8X8,tmpstr);
        OutText(x,y8X16,LIGHTCYAN,tmpstr);
        x+=10;
    }while( ++tmpstr[0]<255 );
    OutText(320-strlen(fonts)*4,200,YELLOW,fonts);
    OutText(320-strlen(goon)*4,220,LIGHTCYAN,goon);
    getch();
    /* 3.演示OutText()函数的高速输出能力 */
    bar(0,0,639,479);
    OutText(639-strlen(enddemo)*8,463,LIGHTCYAN,enddemo);
    y=bottom;
    randomize();
    len=strlen(hello)*8;
    time1=time(); /* 开始时刻 */
    while( !kbhit() ){ /* 当无按键时执行 */
        if( y>=bottom ){
            y=0;
            x=random(639-len);
            color=random(15)+1;
            bottom=bottom<=0?447:bottom-16;
        }
        bar(x-1,y-1,x+len,y+16);
        OutText(x,y++,color,hello);
        sprintf(tmpstr,"%lu",times++);
        bar(0,463,strlen(tmpstr)*8,479);
        OutText(0,463,WHITE,tmpstr); /* 计数 */
    }
    time2=time(); /* 结束时刻 */
    getch();
    bar(0,463,639,479);
    sprintf(tmpstr,report,time2-time1,times);
    OutText(0,463,LIGHTGREEN,tmpstr);
    getch();
    fclose(fp_hzk);
    fclose(fp_asc);
    closegraph();
}

void OutText(int x,int y,unsigned char color,unsigned char *hz)
{
    long i;
    char far *ptr;
    int movebit,ybit;
    struct viewporttype v;
    unsigned char by[32],by1,by2,byte1,byte2,tmp,*byptr;
    getviewsettings(&v);
    x+=v.left; y+=v.top; /* 在视区内显示 */
    if( x<0 || y<0 || x>=639 || y>=479 || x>=v.right || y>=v.bottom ) return;
    ybit= y+15>=v.bottom?v.bottom-y:16; /* Y方向不超过视区的下边界 */
    ybit= ybit<=0?0:ybit;
    /* 采用写方式2 */
    outportb(0x3ce,5);   outportb(0x3cf,2);
    /* 一次写4个位平面 */
    outportb(0x3c4,2);   outportb(0x3c5,255);
    outportb(0x3ce,8);
    while(*hz){
        byte1=(unsigned char)*hz;  byte2=(unsigned char)*(hz+1);
        if( (byte1>=0xa1 && byte1<=0xfe)&&(byte2>=0xa1 && byte2<=0xfe) ){ /* 汉字 */
            byptr=by;
            if(x+15>v.right) break; /* 超出视区不显示 */
            i=(byte1-0xa1)*94+byte2-0xa1;
            i<<=5;
            fseek(fp_hzk,i,SEEK_SET);
            fread(by,32,1,fp_hzk); /* 读汉字点阵 */
            /* 因为一个字节含有8个像素点,必须考虑到起始位置未处于x%8==0时的情况 */
            /* 为此设置一个只从有效的x位置写起的偏移量movebit */
            movebit=x%8; /* 起始位置在缓冲区中字节内相对偏移 */
            for(i=0;i<ybit;i++){
                ptr=MK_FP( 0xA000,(y+i)*80+x/8 );
                by1=*byptr++; by2=*byptr++;
                /* 将汉字点阵的两个字节写入缓冲区 */
                /* 要写8个像点的掩码,此掩码即为汉字的点阵信息,第一个字节 */
                outportb( 0x3cf,by1>>movebit );
                tmp=*ptr;  *ptr++=color; /* 将颜色值写入缓冲区 */
                /* 要写8个像点的掩码,第二个字节 */
                outportb( 0x3cf,(by1<<(8-movebit))|(by2>>movebit) );
                tmp=*ptr;  *ptr++=color;
                /* 当汉字点阵正好充满两个字节,不对第三个字节操作 */
                if( movebit!=0 ){
                    /* 要写8个像点的掩码 */
                    outportb( 0x3cf,by2<<(8-movebit) );
                    tmp=*ptr;  *ptr=color;
                }
            } /* for end */
            x+=16;  hz+=2;
        } /* if HZ end */
        else{ /* 显示ASCII */
            if(x+7>v.right) break; /* 超出视区不显示 */
            fseek(fp_asc,byte1*16,SEEK_SET);
            fread(by,16,1,fp_asc); /* 读ASCII码点阵 */
            movebit=x%8; /* 起始位置在缓冲区字节内相对偏移 */
            for(i=0;i<ybit;i++){
                ptr=MK_FP( 0xA000,(y+i)*80+x/8 );
                by1=*(by+i);
                outportb( 0x3cf,by1>>movebit );
                tmp=*ptr;  *ptr++=color;
                if( movebit!=0 ){
                    outportb( 0x3cf,by1<<(8-movebit) );
                    tmp=*ptr;  *ptr++=color;
                }
            } /* for end */
            x+=8;   hz++;
        } /* if ASCII end */
    } /* while end */
    tmp=tmp;
    outportb(0x3ce,8);   outportb(0x3cf,255);
    outportb(0x3ce,5);   outportb(0x3cf,0);
} /* OutText() end */

本文地址:http://com.8s8s.com/it/it29928.htm