123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- /*
- Copyright 1987, 1998 The Open Group
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of The Open Group shall
- not be used in advertising or otherwise to promote the sale, use or
- other dealings in this Software without prior written authorization
- from The Open Group.
- */
- /*
- * fill.h
- *
- * Created by Brian Kelleher; Oct 1985
- *
- * Include file for filled polygon routines.
- *
- * These are the data structures needed to scan
- * convert regions. Two different scan conversion
- * methods are available -- the even-odd method, and
- * the winding number method.
- * The even-odd rule states that a point is inside
- * the polygon if a ray drawn from that point in any
- * direction will pass through an odd number of
- * path segments.
- * By the winding number rule, a point is decided
- * to be inside the polygon if a ray drawn from that
- * point in any direction passes through a different
- * number of clockwise and counter-clockwise path
- * segments.
- *
- * These data structures are adapted somewhat from
- * the algorithm in (Foley/Van Dam) for scan converting
- * polygons.
- * The basic algorithm is to start at the top (smallest y)
- * of the polygon, stepping down to the bottom of
- * the polygon by incrementing the y coordinate. We
- * keep a list of edges which the current scanline crosses,
- * sorted by x. This list is called the Active Edge Table (AET)
- * As we change the y-coordinate, we update each entry in
- * in the active edge table to reflect the edges new xcoord.
- * This list must be sorted at each scanline in case
- * two edges intersect.
- * We also keep a data structure known as the Edge Table (ET),
- * which keeps track of all the edges which the current
- * scanline has not yet reached. The ET is basically a
- * list of ScanLineList structures containing a list of
- * edges which are entered at a given scanline. There is one
- * ScanLineList per scanline at which an edge is entered.
- * When we enter a new edge, we move it from the ET to the AET.
- *
- * From the AET, we can implement the even-odd rule as in
- * (Foley/Van Dam).
- * The winding number rule is a little trickier. We also
- * keep the EdgeTableEntries in the AET linked by the
- * nextWETE (winding EdgeTableEntry) link. This allows
- * the edges to be linked just as before for updating
- * purposes, but only uses the edges linked by the nextWETE
- * link as edges representing spans of the polygon to
- * drawn (as with the even-odd rule).
- */
- /*
- * for the winding number rule
- */
- #define CLOCKWISE 1
- #define COUNTERCLOCKWISE -1
- typedef struct _EdgeTableEntry {
- int ymax; /* ycoord at which we exit this edge. */
- BRESINFO bres; /* Bresenham info to run the edge */
- struct _EdgeTableEntry *next; /* next in the list */
- struct _EdgeTableEntry *back; /* for insertion sort */
- struct _EdgeTableEntry *nextWETE; /* for winding num rule */
- int ClockWise; /* flag for winding number rule */
- } EdgeTableEntry;
- typedef struct _ScanLineList{
- int scanline; /* the scanline represented */
- EdgeTableEntry *edgelist; /* header node */
- struct _ScanLineList *next; /* next in the list */
- } ScanLineList;
- typedef struct {
- int ymax; /* ymax for the polygon */
- int ymin; /* ymin for the polygon */
- ScanLineList scanlines; /* header node */
- } EdgeTable;
- /*
- * Here is a struct to help with storage allocation
- * so we can allocate a big chunk at a time, and then take
- * pieces from this heap when we need to.
- */
- #define SLLSPERBLOCK 25
- typedef struct _ScanLineListBlock {
- ScanLineList SLLs[SLLSPERBLOCK];
- struct _ScanLineListBlock *next;
- } ScanLineListBlock;
- /*
- * number of points to buffer before sending them off
- * to scanlines() : Must be an even number
- */
- #define NUMPTSTOBUFFER 200
- /*
- *
- * a few macros for the inner loops of the fill code where
- * performance considerations don't allow a procedure call.
- *
- * Evaluate the given edge at the given scanline.
- * If the edge has expired, then we leave it and fix up
- * the active edge table; otherwise, we increment the
- * x value to be ready for the next scanline.
- * The winding number rule is in effect, so we must notify
- * the caller when the edge has been removed so he
- * can reorder the Winding Active Edge Table.
- */
- #define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
- if (pAET->ymax == y) { /* leaving this edge */ \
- pPrevAET->next = pAET->next; \
- pAET = pPrevAET->next; \
- fixWAET = 1; \
- if (pAET) \
- pAET->back = pPrevAET; \
- } \
- else { \
- BRESINCRPGONSTRUCT(pAET->bres); \
- pPrevAET = pAET; \
- pAET = pAET->next; \
- } \
- }
- /*
- * Evaluate the given edge at the given scanline.
- * If the edge has expired, then we leave it and fix up
- * the active edge table; otherwise, we increment the
- * x value to be ready for the next scanline.
- * The even-odd rule is in effect.
- */
- #define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
- if (pAET->ymax == y) { /* leaving this edge */ \
- pPrevAET->next = pAET->next; \
- pAET = pPrevAET->next; \
- if (pAET) \
- pAET->back = pPrevAET; \
- } \
- else { \
- BRESINCRPGONSTRUCT(pAET->bres); \
- pPrevAET = pAET; \
- pAET = pAET->next; \
- } \
- }
- /* mipolyutil.c */
- extern Bool miInsertEdgeInET(
- EdgeTable * /*ET*/,
- EdgeTableEntry * /*ETE*/,
- int /*scanline*/,
- ScanLineListBlock ** /*SLLBlock*/,
- int * /*iSLLBlock*/
- );
- extern Bool miCreateETandAET(
- int /*count*/,
- DDXPointPtr /*pts*/,
- EdgeTable * /*ET*/,
- EdgeTableEntry * /*AET*/,
- EdgeTableEntry * /*pETEs*/,
- ScanLineListBlock * /*pSLLBlock*/
- );
- extern void miloadAET(
- EdgeTableEntry * /*AET*/,
- EdgeTableEntry * /*ETEs*/
- );
- extern void micomputeWAET(
- EdgeTableEntry * /*AET*/
- );
- extern int miInsertionSort(
- EdgeTableEntry * /*AET*/
- );
- extern void miFreeStorage(
- ScanLineListBlock * /*pSLLBlock*/
- );
|