转载:谨慎使用setviewport()

Posted on 2007-09-08 01:07 IanZhu 阅读(6355) 评论(0)  编辑 收藏 引用
 

在讲解之前,我得介绍一下setviewport()函数的用途.
它功能就设置视区.视区分两种:一,不可视视区,使用方法setviewport(left,top,right,bottom,1);
       二,可视视区,使用方法setviewport(left,top,right,bottom,0).
这两种视区有没有什么区别.
不可视区: 当作图超出了视区图形被剪切,
如下一段程序:
...
setviewport(50,50,100,100,1);
setfillstyle(1,4);
bar(20,20,300,300);/*这里的(20,20)是相对于(50,50)为(0,0).
也就是说(50,50)为视区的原点,所以(20,20)
相当于setviewport(0,0,getmaxx(),getmaxy(),1)下的点(70,70)*/
setviewport(0,0,getmaxx(),getmaxy(),1);/*恢复视区为全屏*/
...
从运行结果,可以看出超出视区的所有作图都会被剪切.

可视视区:当作图超出了视区图形不会被剪切
如下一段程序:
...
setviewport(50,50,100,100,0);
setfillstyle(1,4);
bar(20,20,300,300);
setviewport(0,0,getmaxx(),getmaxy(),1);/*恢复视区为全屏*/
...
从运行结果,可以看出超出视区的所有作图没有被剪切.

大家从视区的概念也隐约地感觉到视区带来的风险.
虽然视区有风险,但它的功能所带的诱惑力是不可阻挡的.换句话说,有一些功能模块不用视区,
就无法实现或实现起来非常困难.
但是我需要怎样来规避风险呢.有人可能会提出这样的方法:每使用一次视区结束后,都要还原视区.
setviewport(left,top,right,bottom,1);
...
setviewport(0,0,getmaxx(),getmaxy(),1);
这样做,看上去挺有道理的,没有什么问题.

大家可以看一下下面的一个程序:
#i nclude<conio.h>
#i nclude<graphics.h>
void DrawFrame(int,int,int,int);/*画一个框架*/
int main(void)
{
  int gdriver=VGA,gmode=VGAHI;
  initgraph(&gdriver,&gmode,"");/*图形方式驱动*/
  cleardevice();/*清屏*/
  setfillstyle(1,15);/*用白色填充全屏*/
  bar(0,0,getmaxx(),getmaxy());

  setviewport(150,150,500,400,1);

  DrawFrame(50,50,300,150);/*相对(150,150)为原点的(50,50)的位置画一个框架*/
  setcolor(15);
  moveto(53,54);/*相对(150,150)为原点的(53,54)画一些字符*/
  settextstyle(2,0,5);
  outtext("ForeGroundColor");
 
  setviewport(0,0,getmaxx(),getmaxy(),1);
  getch();
  closegraph();
  return 0;
}
void DrawFrame(int left,int top,int right,int bottom)/*画一个框架*/
{
  int i;

  setviewport(left,top,right,bottom,1);/*设置框架视区*/

  setfillstyle(1,7);
  bar(0,0,right-left,bottom-top);/*相对视区画填充区域*/
  /*相对视区画线*/ 
  setcolor(15);
    line(1,1,right-left,1);
    line(1,1,1,bottom-top);
  setcolor(8);
    line(1,bottom-1-top,right-left,bottom-1-top);
    line(right-1-left,1,right-1-left,bottom-top);
  setcolor(0);
    line(0,bottom-top,right-left,bottom-top);
    line(right-left,0,right-left,bottom-top);    
  setfillstyle(1,1);
    bar(3,2,right-3-left,top+17-top);/*相对视区画填充区域*/

  setviewport(0,0,getmaxx(),getmaxy(),1);/*恢复全屏为视区*/
}
大家可运行一下,从结果可以看出框加的输出位置为(50,50).而原本希望输出位置在(200,200)
而原本希望在相对(150,150)为原点的(53,54)画一些字符,却在全屏的(53,54)位置出字符.
为什么会出现这样的问题呢.大家可以仔细分析代码,可以看出.
出现第一个问题的时侯是因为DrawFrame()中重新设置了setviewport(left,top,right,bottom,1);
而不是以setveiwport(150,150,500,400,1);为视区.
出现第二个问题的时侯是因为DrawFrame()最后一行又设置setviewport(0,0,getmaxx(),getmaxy(),1);
所以,输出字符不是以setveiwport(150,150,500,400,1);为视区,而是以
setviewport(0,0,getmaxx(),getmaxy(),1);为视区.

总而言之:
在setviewport(left,top,right,bottom,1);
  ...  /*这中间的代码中不能再出现改变视区的语句.否则,可能会出现意料之外的情况.*/
  setviewport(0,0,getamxx(),getmaxy(),1);


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


posts - 10, comments - 10, trackbacks - 0, articles - 4

Copyright © IanZhu