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