|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.