Annotation of researchv9/X11/src/X.V11R1/server/ddx/mi/mipolygen.c, revision 1.1.1.1

1.1       root        1: /***********************************************************
                      2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
                      3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
                      4: 
                      5:                         All Rights Reserved
                      6: 
                      7: Permission to use, copy, modify, and distribute this software and its 
                      8: documentation for any purpose and without fee is hereby granted, 
                      9: provided that the above copyright notice appear in all copies and that
                     10: both that copyright notice and this permission notice appear in 
                     11: supporting documentation, and that the names of Digital or MIT not be
                     12: used in advertising or publicity pertaining to distribution of the
                     13: software without specific, written prior permission.  
                     14: 
                     15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     21: SOFTWARE.
                     22: 
                     23: ******************************************************************/
                     24: /* $Header: mipolygen.c,v 1.17 87/09/11 07:19:05 toddb Exp $ */
                     25: #include "X.h"
                     26: #include "gcstruct.h"
                     27: #include "miscanfill.h"
                     28: #include "mipoly.h"
                     29: #include "pixmap.h"
                     30: 
                     31: /*
                     32:  *
                     33:  *     Written by Brian Kelleher;  Oct. 1985
                     34:  *
                     35:  *     Routine to fill a polygon.  Two fill rules are
                     36:  *     supported: frWINDING and frEVENODD.
                     37:  *
                     38:  *     See fillpoly.h for a complete description of the algorithm.
                     39:  */
                     40: 
                     41: int
                     42: miFillGeneralPoly(dst, pgc, count, ptsIn)
                     43:     DrawablePtr dst;
                     44:     GCPtr      pgc;
                     45:     int                count;              /* number of points        */
                     46:     DDXPointPtr ptsIn;              /* the points              */
                     47: {
                     48:     register EdgeTableEntry *pAET;  /* the Active Edge Table   */
                     49:     register int y;                 /* the current scanline    */
                     50:     register int nPts = 0;          /* number of pts in buffer */
                     51:     register EdgeTableEntry *pWETE; /* Winding Edge Table      */
                     52:     register ScanLineList *pSLL;    /* Current ScanLineList    */
                     53:     register DDXPointPtr ptsOut;      /* ptr to output buffers   */
                     54:     int *width;
                     55:     DDXPointRec FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
                     56:     int FirstWidth[NUMPTSTOBUFFER];
                     57:     EdgeTableEntry *pPrevAET;       /* previous AET entry      */
                     58:     EdgeTable ET;                   /* Edge Table header node  */
                     59:     EdgeTableEntry AET;             /* Active ET header node   */
                     60:     EdgeTableEntry *pETEs;          /* Edge Table Entries buff */
                     61:     ScanLineListBlock SLLBlock;     /* header for ScanLineList */
                     62:     int fixWAET = 0;
                     63: 
                     64:     if (count < 3)
                     65:        return;
                     66: 
                     67:     if(!(pETEs = (EdgeTableEntry *)
                     68:         ALLOCATE_LOCAL(sizeof(EdgeTableEntry) * count)))
                     69:        return;
                     70:     ptsOut = FirstPoint;
                     71:     width = FirstWidth;
                     72:     miCreateETandAET(count, ptsIn, &ET, &AET, pETEs, &SLLBlock);
                     73:     pSLL = ET.scanlines.next;
                     74: 
                     75:     if (pgc->fillRule == EvenOddRule) 
                     76:     {
                     77:         /*
                     78:         /*  for each scanline
                     79:         */
                     80:         for (y = ET.ymin; y < ET.ymax; y++) 
                     81:         {
                     82:             /*
                     83:              *  Add a new edge to the active edge table when we
                     84:              *  get to the next edge.
                     85:              */
                     86:             if (pSLL && y == pSLL->scanline) 
                     87:             {
                     88:                 miloadAET(&AET, pSLL->edgelist);
                     89:                 pSLL = pSLL->next;
                     90:             }
                     91:             pPrevAET = &AET;
                     92:             pAET = AET.next;
                     93: 
                     94:             /*
                     95:              *  for each active edge
                     96:              */
                     97:             while (pAET) 
                     98:             {
                     99:                 ptsOut->x = pAET->bres.minor;
                    100:                ptsOut++->y = y;
                    101:                 *width++ = pAET->next->bres.minor - pAET->bres.minor;
                    102:                 nPts++;
                    103: 
                    104:                 /*
                    105:                  *  send out the buffer when its full
                    106:                  */
                    107:                 if (nPts == NUMPTSTOBUFFER) 
                    108:                {
                    109:                    (*pgc->FillSpans)(dst, pgc,
                    110:                                      nPts, FirstPoint, FirstWidth,
                    111:                                      1);
                    112:                     ptsOut = FirstPoint;
                    113:                     width = FirstWidth;
                    114:                     nPts = 0;
                    115:                 }
                    116:                 EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
                    117:                 EVALUATEEDGEEVENODD(pAET, pPrevAET, y);
                    118:             }
                    119:             miInsertionSort(&AET);
                    120:         }
                    121:     }
                    122:     else      /* default to WindingNumber */
                    123:     {
                    124:         /*
                    125:          *  for each scanline
                    126:          */
                    127:         for (y = ET.ymin; y < ET.ymax; y++) 
                    128:         {
                    129:             /*
                    130:              *  Add a new edge to the active edge table when we
                    131:              *  get to the next edge.
                    132:              */
                    133:             if (pSLL && y == pSLL->scanline) 
                    134:             {
                    135:                 miloadAET(&AET, pSLL->edgelist);
                    136:                 micomputeWAET(&AET);
                    137:                 pSLL = pSLL->next;
                    138:             }
                    139:             pPrevAET = &AET;
                    140:             pAET = AET.next;
                    141:             pWETE = pAET;
                    142: 
                    143:             /*
                    144:              *  for each active edge
                    145:              */
                    146:             while (pAET) 
                    147:             {
                    148:                 /*
                    149:                  *  if the next edge in the active edge table is
                    150:                  *  also the next edge in the winding active edge
                    151:                  *  table.
                    152:                  */
                    153:                 if (pWETE == pAET) 
                    154:                 {
                    155:                     ptsOut->x = pAET->bres.minor;
                    156:                    ptsOut++->y = y;
                    157:                     *width++ = pAET->nextWETE->bres.minor - pAET->bres.minor;
                    158:                     nPts++;
                    159: 
                    160:                     /*
                    161:                      *  send out the buffer
                    162:                      */
                    163:                     if (nPts == NUMPTSTOBUFFER) 
                    164:                     {
                    165:                        (*pgc->FillSpans)(dst, pgc, nPts, FirstPoint,
                    166:                                          FirstWidth, 1);
                    167:                         ptsOut = FirstPoint;
                    168:                         width  = FirstWidth;
                    169:                         nPts = 0;
                    170:                     }
                    171: 
                    172:                     pWETE = pWETE->nextWETE;
                    173:                     while (pWETE != pAET)
                    174:                         EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
                    175:                     pWETE = pWETE->nextWETE;
                    176:                 }
                    177:                 EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
                    178:             }
                    179: 
                    180:             /*
                    181:              *  reevaluate the Winding active edge table if we
                    182:              *  just had to resort it or if we just exited an edge.
                    183:              */
                    184:             if (miInsertionSort(&AET) || fixWAET) 
                    185:             {
                    186:                 micomputeWAET(&AET);
                    187:                 fixWAET = 0;
                    188:             }
                    189:         }
                    190:     }
                    191: 
                    192:     /*
                    193:      *     Get any spans that we missed by buffering
                    194:      */
                    195:     (*pgc->FillSpans)(dst, pgc, nPts, FirstPoint, FirstWidth, 1);
                    196:     DEALLOCATE_LOCAL(pETEs);
                    197:     miFreeStorage(SLLBlock.next);
                    198: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.