xref: /OK3568_Linux_fs/external/xserver/mi/mipoly.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun 
3*4882a593Smuzhiyun Copyright 1987, 1998  The Open Group
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its
6*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that
7*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that
8*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting
9*4882a593Smuzhiyun documentation.
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included
12*4882a593Smuzhiyun in all copies or substantial portions of the Software.
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15*4882a593Smuzhiyun OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16*4882a593Smuzhiyun MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17*4882a593Smuzhiyun IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*4882a593Smuzhiyun OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*4882a593Smuzhiyun ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*4882a593Smuzhiyun OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall
23*4882a593Smuzhiyun not be used in advertising or otherwise to promote the sale, use or
24*4882a593Smuzhiyun other dealings in this Software without prior written authorization
25*4882a593Smuzhiyun from The Open Group.
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /*
30*4882a593Smuzhiyun  *     fill.h
31*4882a593Smuzhiyun  *
32*4882a593Smuzhiyun  *     Created by Brian Kelleher; Oct 1985
33*4882a593Smuzhiyun  *
34*4882a593Smuzhiyun  *     Include file for filled polygon routines.
35*4882a593Smuzhiyun  *
36*4882a593Smuzhiyun  *     These are the data structures needed to scan
37*4882a593Smuzhiyun  *     convert regions.  Two different scan conversion
38*4882a593Smuzhiyun  *     methods are available -- the even-odd method, and
39*4882a593Smuzhiyun  *     the winding number method.
40*4882a593Smuzhiyun  *     The even-odd rule states that a point is inside
41*4882a593Smuzhiyun  *     the polygon if a ray drawn from that point in any
42*4882a593Smuzhiyun  *     direction will pass through an odd number of
43*4882a593Smuzhiyun  *     path segments.
44*4882a593Smuzhiyun  *     By the winding number rule, a point is decided
45*4882a593Smuzhiyun  *     to be inside the polygon if a ray drawn from that
46*4882a593Smuzhiyun  *     point in any direction passes through a different
47*4882a593Smuzhiyun  *     number of clockwise and counter-clockwise path
48*4882a593Smuzhiyun  *     segments.
49*4882a593Smuzhiyun  *
50*4882a593Smuzhiyun  *     These data structures are adapted somewhat from
51*4882a593Smuzhiyun  *     the algorithm in (Foley/Van Dam) for scan converting
52*4882a593Smuzhiyun  *     polygons.
53*4882a593Smuzhiyun  *     The basic algorithm is to start at the top (smallest y)
54*4882a593Smuzhiyun  *     of the polygon, stepping down to the bottom of
55*4882a593Smuzhiyun  *     the polygon by incrementing the y coordinate.  We
56*4882a593Smuzhiyun  *     keep a list of edges which the current scanline crosses,
57*4882a593Smuzhiyun  *     sorted by x.  This list is called the Active Edge Table (AET)
58*4882a593Smuzhiyun  *     As we change the y-coordinate, we update each entry in
59*4882a593Smuzhiyun  *     in the active edge table to reflect the edges new xcoord.
60*4882a593Smuzhiyun  *     This list must be sorted at each scanline in case
61*4882a593Smuzhiyun  *     two edges intersect.
62*4882a593Smuzhiyun  *     We also keep a data structure known as the Edge Table (ET),
63*4882a593Smuzhiyun  *     which keeps track of all the edges which the current
64*4882a593Smuzhiyun  *     scanline has not yet reached.  The ET is basically a
65*4882a593Smuzhiyun  *     list of ScanLineList structures containing a list of
66*4882a593Smuzhiyun  *     edges which are entered at a given scanline.  There is one
67*4882a593Smuzhiyun  *     ScanLineList per scanline at which an edge is entered.
68*4882a593Smuzhiyun  *     When we enter a new edge, we move it from the ET to the AET.
69*4882a593Smuzhiyun  *
70*4882a593Smuzhiyun  *     From the AET, we can implement the even-odd rule as in
71*4882a593Smuzhiyun  *     (Foley/Van Dam).
72*4882a593Smuzhiyun  *     The winding number rule is a little trickier.  We also
73*4882a593Smuzhiyun  *     keep the EdgeTableEntries in the AET linked by the
74*4882a593Smuzhiyun  *     nextWETE (winding EdgeTableEntry) link.  This allows
75*4882a593Smuzhiyun  *     the edges to be linked just as before for updating
76*4882a593Smuzhiyun  *     purposes, but only uses the edges linked by the nextWETE
77*4882a593Smuzhiyun  *     link as edges representing spans of the polygon to
78*4882a593Smuzhiyun  *     drawn (as with the even-odd rule).
79*4882a593Smuzhiyun  */
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun /*
82*4882a593Smuzhiyun  * for the winding number rule
83*4882a593Smuzhiyun  */
84*4882a593Smuzhiyun #define CLOCKWISE          1
85*4882a593Smuzhiyun #define COUNTERCLOCKWISE  -1
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun typedef struct _EdgeTableEntry {
88*4882a593Smuzhiyun     int ymax;                   /* ycoord at which we exit this edge. */
89*4882a593Smuzhiyun     BRESINFO bres;              /* Bresenham info to run the edge     */
90*4882a593Smuzhiyun     struct _EdgeTableEntry *next;       /* next in the list     */
91*4882a593Smuzhiyun     struct _EdgeTableEntry *back;       /* for insertion sort   */
92*4882a593Smuzhiyun     struct _EdgeTableEntry *nextWETE;   /* for winding num rule */
93*4882a593Smuzhiyun     int ClockWise;              /* flag for winding number rule       */
94*4882a593Smuzhiyun } EdgeTableEntry;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun typedef struct _ScanLineList {
97*4882a593Smuzhiyun     int scanline;               /* the scanline represented */
98*4882a593Smuzhiyun     EdgeTableEntry *edgelist;   /* header node              */
99*4882a593Smuzhiyun     struct _ScanLineList *next; /* next in the list       */
100*4882a593Smuzhiyun } ScanLineList;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun typedef struct {
103*4882a593Smuzhiyun     int ymax;                   /* ymax for the polygon     */
104*4882a593Smuzhiyun     int ymin;                   /* ymin for the polygon     */
105*4882a593Smuzhiyun     ScanLineList scanlines;     /* header node              */
106*4882a593Smuzhiyun } EdgeTable;
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun /*
109*4882a593Smuzhiyun  * Here is a struct to help with storage allocation
110*4882a593Smuzhiyun  * so we can allocate a big chunk at a time, and then take
111*4882a593Smuzhiyun  * pieces from this heap when we need to.
112*4882a593Smuzhiyun  */
113*4882a593Smuzhiyun #define SLLSPERBLOCK 25
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun typedef struct _ScanLineListBlock {
116*4882a593Smuzhiyun     ScanLineList SLLs[SLLSPERBLOCK];
117*4882a593Smuzhiyun     struct _ScanLineListBlock *next;
118*4882a593Smuzhiyun } ScanLineListBlock;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun /*
121*4882a593Smuzhiyun  * number of points to buffer before sending them off
122*4882a593Smuzhiyun  * to scanlines() :  Must be an even number
123*4882a593Smuzhiyun  */
124*4882a593Smuzhiyun #define NUMPTSTOBUFFER 200
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun /*
127*4882a593Smuzhiyun  *
128*4882a593Smuzhiyun  *     a few macros for the inner loops of the fill code where
129*4882a593Smuzhiyun  *     performance considerations don't allow a procedure call.
130*4882a593Smuzhiyun  *
131*4882a593Smuzhiyun  *     Evaluate the given edge at the given scanline.
132*4882a593Smuzhiyun  *     If the edge has expired, then we leave it and fix up
133*4882a593Smuzhiyun  *     the active edge table; otherwise, we increment the
134*4882a593Smuzhiyun  *     x value to be ready for the next scanline.
135*4882a593Smuzhiyun  *     The winding number rule is in effect, so we must notify
136*4882a593Smuzhiyun  *     the caller when the edge has been removed so he
137*4882a593Smuzhiyun  *     can reorder the Winding Active Edge Table.
138*4882a593Smuzhiyun  */
139*4882a593Smuzhiyun #define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
140*4882a593Smuzhiyun    if (pAET->ymax == y) {          /* leaving this edge */ \
141*4882a593Smuzhiyun       pPrevAET->next = pAET->next; \
142*4882a593Smuzhiyun       pAET = pPrevAET->next; \
143*4882a593Smuzhiyun       fixWAET = 1; \
144*4882a593Smuzhiyun       if (pAET) \
145*4882a593Smuzhiyun          pAET->back = pPrevAET; \
146*4882a593Smuzhiyun    } \
147*4882a593Smuzhiyun    else { \
148*4882a593Smuzhiyun       BRESINCRPGONSTRUCT(pAET->bres); \
149*4882a593Smuzhiyun       pPrevAET = pAET; \
150*4882a593Smuzhiyun       pAET = pAET->next; \
151*4882a593Smuzhiyun    } \
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun /*
155*4882a593Smuzhiyun  *     Evaluate the given edge at the given scanline.
156*4882a593Smuzhiyun  *     If the edge has expired, then we leave it and fix up
157*4882a593Smuzhiyun  *     the active edge table; otherwise, we increment the
158*4882a593Smuzhiyun  *     x value to be ready for the next scanline.
159*4882a593Smuzhiyun  *     The even-odd rule is in effect.
160*4882a593Smuzhiyun  */
161*4882a593Smuzhiyun #define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
162*4882a593Smuzhiyun    if (pAET->ymax == y) {          /* leaving this edge */ \
163*4882a593Smuzhiyun       pPrevAET->next = pAET->next; \
164*4882a593Smuzhiyun       pAET = pPrevAET->next; \
165*4882a593Smuzhiyun       if (pAET) \
166*4882a593Smuzhiyun          pAET->back = pPrevAET; \
167*4882a593Smuzhiyun    } \
168*4882a593Smuzhiyun    else { \
169*4882a593Smuzhiyun       BRESINCRPGONSTRUCT(pAET->bres); \
170*4882a593Smuzhiyun       pPrevAET = pAET; \
171*4882a593Smuzhiyun       pAET = pAET->next; \
172*4882a593Smuzhiyun    } \
173*4882a593Smuzhiyun }
174