Annotation of researchv9/X11/src/X.V11R1/server/ddx/mi/mipoly.h, revision 1.1.1.1

1.1       root        1: /* $Header: mipoly.h,v 1.1 87/09/11 07:20:03 toddb Exp $ */
                      2: /*
                      3:  *     fill.h
                      4:  *
                      5:  *     Created by Brian Kelleher; Oct 1985
                      6:  *
                      7:  *     Include file for filled polygon routines.
                      8:  *
                      9:  *     These are the data structures needed to scan
                     10:  *     convert regions.  Two different scan conversion
                     11:  *     methods are available -- the even-odd method, and
                     12:  *     the winding number method.
                     13:  *     The even-odd rule states that a point is inside
                     14:  *     the polygon if a ray drawn from that point in any
                     15:  *     direction will pass through an odd number of
                     16:  *     path segments.
                     17:  *     By the winding number rule, a point is decided
                     18:  *     to be inside the polygon if a ray drawn from that
                     19:  *     point in any direction passes through a different
                     20:  *     number of clockwise and counter-clockwise path
                     21:  *     segments.
                     22:  *
                     23:  *     These data structures are adapted somewhat from
                     24:  *     the algorithm in (Foley/Van Dam) for scan converting
                     25:  *     polygons.
                     26:  *     The basic algorithm is to start at the top (smallest y)
                     27:  *     of the polygon, stepping down to the bottom of
                     28:  *     the polygon by incrementing the y coordinate.  We
                     29:  *     keep a list of edges which the current scanline crosses,
                     30:  *     sorted by x.  This list is called the Active Edge Table (AET)
                     31:  *     As we change the y-coordinate, we update each entry in 
                     32:  *     in the active edge table to reflect the edges new xcoord.
                     33:  *     This list must be sorted at each scanline in case
                     34:  *     two edges intersect.
                     35:  *     We also keep a data structure known as the Edge Table (ET),
                     36:  *     which keeps track of all the edges which the current
                     37:  *     scanline has not yet reached.  The ET is basically a
                     38:  *     list of ScanLineList structures containing a list of
                     39:  *     edges which are entered at a given scanline.  There is one
                     40:  *     ScanLineList per scanline at which an edge is entered.
                     41:  *     When we enter a new edge, we move it from the ET to the AET.
                     42:  *
                     43:  *     From the AET, we can implement the even-odd rule as in
                     44:  *     (Foley/Van Dam).
                     45:  *     The winding number rule is a little trickier.  We also
                     46:  *     keep the EdgeTableEntries in the AET linked by the
                     47:  *     nextWETE (winding EdgeTableEntry) link.  This allows
                     48:  *     the edges to be linked just as before for updating
                     49:  *     purposes, but only uses the edges linked by the nextWETE
                     50:  *     link as edges representing spans of the polygon to
                     51:  *     drawn (as with the even-odd rule).
                     52:  */
                     53: 
                     54: /*
                     55:  * for the winding number rule
                     56:  */
                     57: #define CLOCKWISE          1
                     58: #define COUNTERCLOCKWISE  -1 
                     59: 
                     60: typedef struct _EdgeTableEntry {
                     61:      int ymax;             /* ycoord at which we exit this edge. */
                     62:      BRESINFO bres;        /* Bresenham info to run the edge     */
                     63:      struct _EdgeTableEntry *next;       /* next in the list     */
                     64:      struct _EdgeTableEntry *back;       /* for insertion sort   */
                     65:      struct _EdgeTableEntry *nextWETE;   /* for winding num rule */
                     66:      int ClockWise;        /* flag for winding number rule       */
                     67: } EdgeTableEntry;
                     68: 
                     69: 
                     70: typedef struct _ScanLineList{
                     71:      int scanline;              /* the scanline represented */
                     72:      EdgeTableEntry *edgelist;  /* header node              */
                     73:      struct _ScanLineList *next;  /* next in the list       */
                     74: } ScanLineList;
                     75: 
                     76: 
                     77: typedef struct {
                     78:      int ymax;                 /* ymax for the polygon     */
                     79:      int ymin;                 /* ymin for the polygon     */
                     80:      ScanLineList scanlines;   /* header node              */
                     81: } EdgeTable;
                     82: 
                     83: 
                     84: /*
                     85:  * Here is a struct to help with storage allocation
                     86:  * so we can allocate a big chunk at a time, and then take
                     87:  * pieces from this heap when we need to.
                     88:  */
                     89: #define SLLSPERBLOCK 25
                     90: 
                     91: typedef struct _ScanLineListBlock {
                     92:      ScanLineList SLLs[SLLSPERBLOCK];
                     93:      struct _ScanLineListBlock *next;
                     94: } ScanLineListBlock;
                     95: 
                     96: /*
                     97:  * number of points to buffer before sending them off
                     98:  * to scanlines() :  Must be an even number
                     99:  */
                    100: #define NUMPTSTOBUFFER 200
                    101: 
                    102: 
                    103: /*
                    104:  *
                    105:  *     a few macros for the inner loops of the fill code where
                    106:  *     performance considerations don't allow a procedure call.
                    107:  *
                    108:  *     Evaluate the given edge at the given scanline.
                    109:  *     If the edge has expired, then we leave it and fix up
                    110:  *     the active edge table; otherwise, we increment the
                    111:  *     x value to be ready for the next scanline.
                    112:  *     The winding number rule is in effect, so we must notify
                    113:  *     the caller when the edge has been removed so he
                    114:  *     can reorder the Winding Active Edge Table.
                    115:  */
                    116: #define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
                    117:    if (pAET->ymax == y) {          /* leaving this edge */ \
                    118:       pPrevAET->next = pAET->next; \
                    119:       pAET = pPrevAET->next; \
                    120:       fixWAET = 1; \
                    121:       if (pAET) \
                    122:          pAET->back = pPrevAET; \
                    123:    } \
                    124:    else { \
                    125:       BRESINCRPGONSTRUCT(pAET->bres); \
                    126:       pPrevAET = pAET; \
                    127:       pAET = pAET->next; \
                    128:    } \
                    129: }
                    130: 
                    131: 
                    132: /*
                    133:  *     Evaluate the given edge at the given scanline.
                    134:  *     If the edge has expired, then we leave it and fix up
                    135:  *     the active edge table; otherwise, we increment the
                    136:  *     x value to be ready for the next scanline.
                    137:  *     The even-odd rule is in effect.
                    138:  */
                    139: #define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
                    140:    if (pAET->ymax == y) {          /* leaving this edge */ \
                    141:       pPrevAET->next = pAET->next; \
                    142:       pAET = pPrevAET->next; \
                    143:       if (pAET) \
                    144:          pAET->back = pPrevAET; \
                    145:    } \
                    146:    else { \
                    147:       BRESINCRPGONSTRUCT(pAET->bres); \
                    148:       pPrevAET = pAET; \
                    149:       pAET = pAET->next; \
                    150:    } \
                    151: }

unix.superglobalmegacorp.com

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