|
|
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.