home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / GLEN / KALEIDS.ZIP / FILL.C next >
C/C++ Source or Header  |  1987-05-06  |  2KB  |  83 lines

  1. /*
  2.  * fill.c : one page seed fill program, 1 channel frame buffer version
  3.  *
  4.  * doesn't read each pixel twice like the BASICFILL algorithm in
  5.  *      Alvy Ray Smith, "Tint Fill", SIGGRAPH '79
  6.  *
  7.  * Paul Heckbert
  8.  * PIXAR                           415-499-3600
  9.  * P.O. Box 13719                  UUCP: {sun,ucbvax}!pixar!ph
  10.  * San Rafael, CA 94913            ARPA: ph%pixar.uucp@ucbvax.berkeley.edu
  11.  *                                 13 Sept 1982, 28 Jan 1987
  12.  */
  13.  
  14. typedef int pixel;
  15. struct seg {
  16.    short y;
  17.    short xl;
  18.    short xr;
  19.    short dy;
  20.    };
  21.  
  22. #define MAX 100            /* max depth of stack */
  23.  
  24. extern unsigned int xmax;
  25. extern unsigned int ymax;
  26. extern unsigned int (*get_dot)();   /* the current read  pixel routine */
  27. extern int (*dot)();        /* the current pixel output routine */
  28.  
  29. int wx1, wx2, wy1, wy2;        /* screen window */
  30.  
  31. /*
  32.  * segment of scan line y for xl<=x<=xr was filled,
  33.  * now explore adjacent pixels in scan line y+dy
  34.  */
  35. #define PUSH(Y, XL, XR, DY) \
  36.     if (sp<stack+MAX && Y+(DY)>=wy1 && Y+(DY)<=wy2) \
  37.     {sp->y = Y; sp->xl = XL; sp->xr = XR; sp->dy = DY; sp++;}
  38. #define POP(Y, XL, XR, DY) \
  39.     {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;}
  40.  
  41. fill(x, y, nv)
  42.    int x, y;            /* seed point */
  43.    pixel nv;            /* new pixel value */
  44.    {
  45.    int l, x1, x2, dy;
  46.    pixel ov;            /* old pixel value */
  47.    struct seg stack[MAX];
  48.    struct seg *sp = stack;
  49.  
  50.    wx1 = 0;
  51.    wy1 = 0;
  52.    wx2 = xmax-1;
  53.    wy2 = ymax-1;
  54.  
  55.    ov = (*get_dot)(x, y);    /* read pv at seed point */
  56.    if (ov==nv || x<wx1 || x>wx2 || y<wy1 || y>wy2) return;
  57.    PUSH(y, x, x, 1);        /* needed in some cases */
  58.    PUSH(y+1, x, x, -1);        /* seed segment (popped 1st) */
  59.  
  60.    while (sp>stack) {
  61.       /* pop segment off stack and fill a neighboring scan line */
  62.       POP(y, x1, x2, dy);
  63.       for (x=x1; x>=wx1 && (*get_dot)(x, y)==ov; x--)
  64.          (*dot)(x, y);
  65.       if (x >= x1)
  66.          goto skip;
  67.       l = x+1;
  68.       if (l<x1)
  69.          PUSH(y, l, x1-1, -dy);        /* leak on left? */
  70.       x = x1+1;
  71.       do {
  72.          while (x<=wx2 && (*get_dot)(x, y)==ov)
  73.             (*dot)(x++, y);
  74.          PUSH(y, l, x-1, dy);
  75.          if (x>x2+1)
  76.             PUSH(y, x2+1, x-1, -dy);    /* leak on right? */
  77. skip:    for (x++; x<=x2 && (*get_dot)(x, y)!=ov; x++)
  78.             ;
  79.          l = x;
  80.          } while (x <= x2);
  81.       }
  82.    }
  83.