home *** CD-ROM | disk | FTP | other *** search
/ Shareware 1 2 the Maxx / sw_1.zip / sw_1 / PROGRAM / CBGRX100.ZIP / CONTRIB / LIBGRX / SRC / FILLPOLY.C < prev    next >
Text File  |  1992-04-10  |  5KB  |  152 lines

  1. /** 
  2.  ** FILLPOLY.C 
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #include "grx.h"
  25. #include "libgrx.h"
  26. #include "clipping.h"
  27. #include "scale.h"
  28.  
  29. void _GrScanConvexPoly(int n,int pt[][2],_GrScanLineProc lnproc,void *lnarg)
  30. {
  31.     int  lx1,ly1,lx2,ly2,ldx,ldy;
  32.     int  rx1,ry1,rx2,ry2,rdx,rdy;
  33.     int  lslope,lerror,lcalc;
  34.     int  rslope,rerror,rcalc;
  35.     int  bottom,left,right;
  36.     int  x1,x2,yy,next,dir;
  37.     MOUSE_FLAG;
  38.  
  39.     lx1 = ly1 = 32000;
  40.     lx2 = ly2 = (-32000);
  41.     for(yy = 0; yy < n; yy++) {
  42.         if(lx1 > pt[yy][0]) lx1 = pt[yy][0];
  43.         if(lx2 < pt[yy][0]) lx2 = pt[yy][0];
  44.         if(ly1 > pt[yy][1]) ly1 = pt[yy][1],left = yy;
  45.         if(ly2 < pt[yy][1]) ly2 = pt[yy][1];
  46.     }
  47.     if(ly1 == ly2) {
  48.         CLIPHLINE(CURC,lx1,lx2,ly1);
  49.         MOUSE_BLOCK(CURC,lx1,ly1,lx2,ly1);
  50.         (*lnproc)(lx1,lx2,ly1,lnarg);
  51.         MOUSE_UNBLOCK();
  52.         return;
  53.     }
  54.     CLIPSORTEDBOX(CURC,lx1,ly1,lx2,ly2);
  55.     MOUSE_BLOCK(CURC,lx1,ly1,lx2,ly2);
  56.     bottom = ly2;
  57.     lx1 = rx1 = pt[left][0];
  58.     ly1 = ry1 = pt[left][1];
  59.     if((right = left + 1) == n) right = 0;
  60.     if(--left < 0) left = n - 1;
  61.     dir = 0;
  62.     if(pt[left][0] > pt[right][0]) {
  63.         dir = 1;
  64.         EXCHG(left,right);
  65.     }
  66.     for( ; ; ) {
  67.         lx2 = pt[left][0];
  68.         if(((ly2 = pt[left][1]) >= _GrLoY) && (ly2 != ly1)) break;
  69.         lx1 = lx2; ly1 = ly2;
  70.         if(dir) { if(++left == n) left = 0; }
  71.         else    { if(--left <  0) left = n - 1; }
  72.     }
  73.     for( ; ; ) {
  74.         rx2 = pt[right][0];
  75.         if(((ry2 = pt[right][1]) >= _GrLoY) && (ry2 != ry1)) break;
  76.         rx1 = rx2; ry1 = ry2;
  77.         if(dir) { if(--right <  0) right = n - 1; }
  78.         else    { if(++right == n) right = 0; }
  79.     }
  80.     if(ly1 < _GrLoY) {
  81.         SCALE(lcalc,(lx1 - lx2),(ly2 - _GrLoY),(ly2 - ly1));
  82.         lx1 = lx2 + lcalc;
  83.         ly1 = _GrLoY;
  84.     }
  85.     if(ry1 < _GrLoY) {
  86.         SCALE(rcalc,(rx1 - rx2),(ry2 - _GrLoY),(ry2 - ry1));
  87.         rx1 = rx2 + rcalc;
  88.         ry1 = _GrLoY;
  89.     }
  90.     yy = ly1; lcalc = rcalc = TRUE;
  91.     for( ; ; ) {
  92.         if(lcalc && ((ldy = ly2 - ly1) > 0)) {
  93.         lslope = (ldx = lx2 - lx1) / ldy;
  94.         if((ldx %= ldy) < 0) { lslope--; ldx += ldy; }
  95.         lerror = (ldy >> 1);
  96.         }
  97.         if(rcalc && ((rdy = ry2 - ry1) > 0)) {
  98.         rslope = (rdx = rx2 - rx1) / rdy;
  99.         if((rdx %= rdy) < 0) { rslope--; rdx += rdy; }
  100.         rerror = (rdy >> 1);
  101.         }
  102.         if((next = MIN(ly2,ry2)) > bottom) next = bottom;
  103.         while(yy < next) {
  104.         if((lx1 <= _GrHiX) && (rx1 >= _GrLoX)) {
  105.             if((x1 = lx1) < _GrLoX) x1 = _GrLoX;
  106.             if((x2 = rx1) > _GrHiX) x2 = _GrHiX;
  107.             (*lnproc)(x1,x2,yy,lnarg);
  108.         }
  109.         lx1 += lslope;
  110.         if((lerror -= ldx) < 0) { lx1++; lerror += ldy; }
  111.         rx1 += rslope;
  112.         if((rerror -= rdx) < 0) { rx1++; rerror += rdy; }
  113.         yy++;
  114.         }
  115.         if(next == bottom) break;
  116.         lcalc = rcalc = FALSE;
  117.         while(next == ly2) {
  118.         lx1 = lx2; ly1 = ly2;
  119.         if(dir) { if(++left == n) left = 0; }
  120.         else    { if(--left <  0) left = n - 1; }
  121.         lx2 = pt[left][0];
  122.         ly2 = pt[left][1];
  123.         lcalc = TRUE;
  124.         }
  125.         while(next == ry2) {
  126.         rx1 = rx2; ry1 = ry2;
  127.         if(dir) { if(--right <  0) right = n - 1; }
  128.         else    { if(++right == n) right = 0; }
  129.         rx2 = pt[right][0];
  130.         ry2 = pt[right][1];
  131.         rcalc = TRUE;
  132.         }
  133.     }
  134.     if((lx1 <= _GrHiX) && (rx1 >= _GrLoX)) {
  135.         if((x1 = lx1) < _GrLoX) x1 = _GrLoX;
  136.         if((x2 = rx1) > _GrHiX) x2 = _GrHiX;
  137.         (*lnproc)(x1,x2,yy,lnarg);
  138.     }
  139.     MOUSE_UNBLOCK();
  140. }
  141.  
  142. static void default_lineproc(int x1,int x2,int y,void *arg)
  143. {
  144.     _GrSetPixRow(PIXEL_ADDR(x1,y),(int)arg,(x2 - x1 + 1));
  145. }
  146.  
  147. void GrFilledPolygon(int numpts,int points[][2],int c)
  148. {
  149.     _GrScanConvexPoly(numpts,points,default_lineproc,(void *)c);
  150. }
  151.  
  152.