home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frostbyte's 1980s DOS Shareware Collection
/
floppyshareware.zip
/
floppyshareware
/
GLEN
/
KALEIDS.ZIP
/
FILL.C
next >
Wrap
C/C++ Source or Header
|
1987-05-06
|
2KB
|
83 lines
/*
* fill.c : one page seed fill program, 1 channel frame buffer version
*
* doesn't read each pixel twice like the BASICFILL algorithm in
* Alvy Ray Smith, "Tint Fill", SIGGRAPH '79
*
* Paul Heckbert
* PIXAR 415-499-3600
* P.O. Box 13719 UUCP: {sun,ucbvax}!pixar!ph
* San Rafael, CA 94913 ARPA: ph%pixar.uucp@ucbvax.berkeley.edu
* 13 Sept 1982, 28 Jan 1987
*/
typedef int pixel;
struct seg {
short y;
short xl;
short xr;
short dy;
};
#define MAX 100 /* max depth of stack */
extern unsigned int xmax;
extern unsigned int ymax;
extern unsigned int (*get_dot)(); /* the current read pixel routine */
extern int (*dot)(); /* the current pixel output routine */
int wx1, wx2, wy1, wy2; /* screen window */
/*
* segment of scan line y for xl<=x<=xr was filled,
* now explore adjacent pixels in scan line y+dy
*/
#define PUSH(Y, XL, XR, DY) \
if (sp<stack+MAX && Y+(DY)>=wy1 && Y+(DY)<=wy2) \
{sp->y = Y; sp->xl = XL; sp->xr = XR; sp->dy = DY; sp++;}
#define POP(Y, XL, XR, DY) \
{sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;}
fill(x, y, nv)
int x, y; /* seed point */
pixel nv; /* new pixel value */
{
int l, x1, x2, dy;
pixel ov; /* old pixel value */
struct seg stack[MAX];
struct seg *sp = stack;
wx1 = 0;
wy1 = 0;
wx2 = xmax-1;
wy2 = ymax-1;
ov = (*get_dot)(x, y); /* read pv at seed point */
if (ov==nv || x<wx1 || x>wx2 || y<wy1 || y>wy2) return;
PUSH(y, x, x, 1); /* needed in some cases */
PUSH(y+1, x, x, -1); /* seed segment (popped 1st) */
while (sp>stack) {
/* pop segment off stack and fill a neighboring scan line */
POP(y, x1, x2, dy);
for (x=x1; x>=wx1 && (*get_dot)(x, y)==ov; x--)
(*dot)(x, y);
if (x >= x1)
goto skip;
l = x+1;
if (l<x1)
PUSH(y, l, x1-1, -dy); /* leak on left? */
x = x1+1;
do {
while (x<=wx2 && (*get_dot)(x, y)==ov)
(*dot)(x++, y);
PUSH(y, l, x-1, dy);
if (x>x2+1)
PUSH(y, x2+1, x-1, -dy); /* leak on right? */
skip: for (x++; x<=x2 && (*get_dot)(x, y)!=ov; x++)
;
l = x;
} while (x <= x2);
}
}