www.pudn.com > pcx_c.zip > VGRFILL.C


/*	VGRFILL.c - Routine to fill an outline in a bit map. 
 
DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!  
***************************************************************************** 
*	                     NOTE CAREFULLY:                                * 
***************************************************************************** 
*	           This function uses ***LOTS***                            * 
*	     of stack space!!! ie: count on up to about 10K                 * 
*	     for every 100 levels of call nesting, with a                   * 
*	     possibility of >200 levels being reached!!!                    * 
***************************************************************************** 
DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!  
*/ 
 
 
#include "lib.h" 
#include "vgr.h" 
 
 
#ifdef __STDC__ 
void vgr_fill(int x,int y,int color); 
static void _fill_y(int x,int y,int yinc); 
static void _fill_x(int x,int y); 
static int __fill_x(int x,int y,int xinc); 
#else 
void vgr_fill(); 
static void _fill_y(); 
static void _fill_x(); 
static int __fill_x(); 
#endif 
 
static unsigned char _color, _search; 
static int _set_cnt, _up_cnt, _dn_cnt, _y_ok; 
 
 
void vgr_fill( x, y, color ) 
int x, y, color; 
{ 
	if ( (_search = VGR_GET( x, y )) == (_color = color) ) 
	   return; 
 
	_fill_y( x, y+1,  1 ); 
	_fill_y( x, y  , -1 ); 
} 
 
 
static void _fill_y( x, y, yinc ) 
int x, y, yinc; 
{ 
	for ( ; y >= 0 && y < VGR_VRES; y += yinc ) 
	   if ( _search == VGR_GET( x, y ) ) 
	      _fill_x( x, y ); 
	   else return; 
} 
 
 
static void _fill_x( x, y ) 
int x, y; 
{ 
	int i, l, h, u, d, c; 
	void _fill_y(); 
 
#ifdef DEBUG 
	static int depth; 
	 
	putcur(0,0); 
	printf("%d  ", ++depth ); 
	if ( constat() ) 
	   if ( conin() == 27 ) 
	   {  video_mode(3); 
	      exit(1); 
	   }; 
#endif 
	_set_cnt = _up_cnt = _dn_cnt = 0; 
	_y_ok = ( (y >= 1) && (y < (VGR_VRES-1)) ); 
 
	h = __fill_x( x+1, y,  1 ); 
	l = __fill_x( x  , y, -1 ); 
 
	/* The purpose of the following code is to prevent  
	   excessive call nesting. It can be removed, but  
	   the resulting several thousand useless function  
	   calls slow down processing considerably, as well  
	   as killing the system when SP rolls over... 
	*/ 
 
	if ( !_y_ok ) 
	{ 
#ifdef DEBUG 
	   depth--; 
#endif 
	   return; 
	}; 
 
	c = _set_cnt; 
	u = _up_cnt; 
	d = _dn_cnt; 
 
	if ( c != u ) 
	   for ( i = l+1; i <= h-1; i++ ) 
	      if ( _search == VGR_GET( i, y-1 ) ) 
	         _fill_y( i, y-1, -1 ); 
 
	if ( c != d ) 
	   for ( i = l+1; i <= h-1; i++ ) 
	      if ( _search == VGR_GET( i, y+1 ) ) 
	         _fill_y( i, y+1,  1 ); 
#ifdef DEBUG 
	depth--; 
#endif 
} 
 
 
static int __fill_x( x, y, xinc ) 
int x, y, xinc; 
{ 
	for ( ; x >= 0 && x < VGR_HRES; x += xinc ) 
	   if ( _search == VGR_GET( x, y ) ) 
	   {  VGR_SET( x, y, _color );  
	      _set_cnt++; 
 
	      if ( _y_ok ) 
	      {  if ( _search == VGR_GET(x,y-1) ) 
	            _up_cnt++; 
	         if ( _search == VGR_GET(x,y+1) ) 
	            _dn_cnt++; 
	      }; 
	   } else return x; 
}