/*
 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.java2d.pisces;

public class Renderer extends LineSink {
    public static final int WIND_EVEN_ODD = 0;
    public static final int WIND_NON_ZERO = 1;

    // Initial edge list size
    // IMPL_NOTE - restore size after growth
    public static final int INITIAL_EDGES = 1000;

    // Recommended maximum scratchpad sizes.  The arrays will grow
    // larger if needed, but when finished() is called they will be released
    // if they have grown larger than these sizes.
    public static final int DEFAULT_INDICES_SIZE = 8192;
    public static final int DEFAULT_CROSSINGS_SIZE = 32*1024;

    // Antialiasing
    private int SUBPIXEL_LG_POSITIONS_X;
    private int SUBPIXEL_LG_POSITIONS_Y;
    private int SUBPIXEL_MASK_X;
    private int SUBPIXEL_MASK_Y;
    private int SUBPIXEL_POSITIONS_X;
    private int SUBPIXEL_POSITIONS_Y;
    int MAX_AA_ALPHA;
    private int MAX_AA_ALPHA_DENOM;
    private int HALF_MAX_AA_ALPHA_DENOM;
    private int XSHIFT;
    private int YSHIFT;
    private int YSTEP;
    private int HYSTEP;
    private int YMASK;

    private static final int MIN_QUAD_OPT_WIDTH = 100 << 16;

    // Cache to store RLE-encoded coverage mask of the current primitive
    PiscesCache cache;

    // Bounds of the drawing region, at S15.16 precsion
    private int boundsMinX, boundsMinY, boundsMaxX, boundsMaxY;

    // Bounds of the current primitive, at subsample precision
    private int rasterMinX, rasterMaxX, rasterMinY, rasterMaxY;

    // Pixel bounding box for current primitive
    private int bboxX0, bboxY0, bboxX1, bboxY1;

    // Current winding rule
    private int windingRule;

    // Current drawing position, i.e., final point of last segment
    private int x0, y0;

    // Position of most recent 'moveTo' command
    private int sx0, sy0;

    // Buffer to be filled with one row's worth of alpha values
    private byte[] rowAA; // needs to be short if 16x16 subsampling

    // Track the number of vertical extrema of the incoming edge list
    // in order to determine the maximum number of crossings of a
    // scanline
    private int firstOrientation;
    private int lastOrientation;
    private int flips;

    // Parameters for emitRow
    private int alphaWidth;

    public Renderer() {
    }

    public void setAntialiasing(int subpixelLgPositionsX,
                                int subpixelLgPositionsY) {
        this.SUBPIXEL_LG_POSITIONS_X = subpixelLgPositionsX;
        this.SUBPIXEL_LG_POSITIONS_Y = subpixelLgPositionsY;

        this.SUBPIXEL_MASK_X =
            (1 << (SUBPIXEL_LG_POSITIONS_X)) - 1;
        this.SUBPIXEL_MASK_Y =
            (1 << (SUBPIXEL_LG_POSITIONS_Y)) - 1;
        this.SUBPIXEL_POSITIONS_X =
            1 << (SUBPIXEL_LG_POSITIONS_X);
        this.SUBPIXEL_POSITIONS_Y =
            1 << (SUBPIXEL_LG_POSITIONS_Y);
        this.MAX_AA_ALPHA =
            (SUBPIXEL_POSITIONS_X*SUBPIXEL_POSITIONS_Y);
        this.MAX_AA_ALPHA_DENOM = 255*MAX_AA_ALPHA;
        this.HALF_MAX_AA_ALPHA_DENOM = MAX_AA_ALPHA_DENOM/2;
        this.XSHIFT = 16 - SUBPIXEL_LG_POSITIONS_X;
        this.YSHIFT = 16 - SUBPIXEL_LG_POSITIONS_Y;
        this.YSTEP = 1 << YSHIFT;
        this.HYSTEP = 1 << (YSHIFT - 1);
        this.YMASK = ~(YSTEP - 1);
    }

    public int getSubpixelLgPositionsX() {
        return SUBPIXEL_LG_POSITIONS_X;
    }

    public int getSubpixelLgPositionsY() {
        return SUBPIXEL_LG_POSITIONS_Y;
    }

    public void setWindingRule(int windingRule) {
        this.windingRule = windingRule;
    }

    public int getWindingRule() {
        return windingRule;
    }

    public void beginRendering(int boundsX, int boundsY,
                               int boundsWidth, int boundsHeight) {
        lastOrientation = 0;
        flips = 0;

        resetEdges();

        this.boundsMinX = boundsX << 16;
        this.boundsMinY = boundsY << 16;
        this.boundsMaxX = (boundsX + boundsWidth) << 16;
        this.boundsMaxY = (boundsY + boundsHeight) << 16;

        this.bboxX0 = boundsX;
        this.bboxY0 = boundsY;
        this.bboxX1 = boundsX + boundsWidth;
        this.bboxY1 = boundsY + boundsHeight;
    }

    public void moveTo(int x0, int y0) {
        // System.out.println("Renderer: moveTo " + x0/65536.0 + " " + y0/65536.0);
        close();
        this.sx0 = this.x0 = x0;
        this.sy0 = this.y0 = y0;
        this.lastOrientation = 0;
    }

    public void lineJoin() {
        // System.out.println("Renderer: lineJoin");
        // do nothing
    }

    public void lineTo(int x1, int y1) {
        // System.out.println("Renderer: lineTo " + x1/65536.0 + " " + y1/65536.0);

        // Ignore horizontal lines
        // Next line will count flip
        if (y0 == y1) {
            this.x0 = x1;
            return;
        }

        int orientation = (y0 < y1) ? 1 : -1;
        if (lastOrientation == 0) {
            firstOrientation = orientation;
        } else if (orientation != lastOrientation) {
            ++flips;
        }
        lastOrientation = orientation;

        // Bias Y by 1 ULP so endpoints never lie on a scanline
        addEdge(x0, y0 | 0x1, x1, y1 | 0x1);

        this.x0 = x1;
        this.y0 = y1;
    }

    public void close() {
        // System.out.println("Renderer: close");

        int orientation = lastOrientation;
        if (y0 != sy0) {
            orientation = (y0 < sy0) ? 1 : -1;
        }
        if (orientation != firstOrientation) {
            ++flips;
        }
        lineTo(sx0, sy0);
    }

    public void end() {
        close();
        // System.out.println("Renderer: end");
        // do nothing
    }

    // Scan convert a single edge
    private void computeCrossingsForEdge(int index,
                                         int boundsMinY, int boundsMaxY) {
        int iy0 = edges[index + 1];
        int iy1 = edges[index + 3];

        // Clip to valid Y range
        int clipy0 = (iy0 > boundsMinY) ? iy0 : boundsMinY;
        int clipy1 = (iy1 < boundsMaxY) ? iy1 : boundsMaxY;

        int minY = ((clipy0 + HYSTEP) & YMASK) + HYSTEP;
        int maxY = ((clipy1 - HYSTEP) & YMASK) + HYSTEP;

        // IMPL_NOTE - If line falls outside the valid X range, could
        // draw a vertical line instead

        // Exit if no scanlines are crossed
        if (minY > maxY) {
            return;
        }

        // Scan convert line using a DDA approach

        int ix0 = edges[index];
        int ix1 = edges[index + 2];
        long dx = ((long) ix1) - ix0;
        long dy = ((long) iy1) - iy0;

        // Compute first crossing point at y = minY
        int orientation = edges[index + 4];
        int y = minY;
        long lx = (((long) y) - iy0)*dx/dy + ix0;
        addCrossing(y >> YSHIFT, (int)(lx >> XSHIFT), orientation);

        // Advance y to next scanline, exit if past endpoint
        y += YSTEP;
        if (y > maxY) {
            return;
        }

        // Compute xstep only if additional scanlines are crossed
        // For each scanline, add xstep to lx and YSTEP to y and
        // emit the new crossing
        long xstep = ((long)YSTEP*dx)/dy;
        for (; y <= maxY; y += YSTEP) {
            lx += xstep;
            addCrossing(y >> YSHIFT, (int)(lx >> XSHIFT), orientation);
        }
    }

    private void computeBounds() {
        rasterMinX = crossingMinX & ~SUBPIXEL_MASK_X;
        rasterMaxX = crossingMaxX | SUBPIXEL_MASK_X;
        rasterMinY = crossingMinY & ~SUBPIXEL_MASK_Y;
        rasterMaxY = crossingMaxY | SUBPIXEL_MASK_Y;

        // If nothing was drawn, we have:
        // minX = Integer.MAX_VALUE and maxX = Integer.MIN_VALUE
        // so nothing to render
        if (rasterMinX > rasterMaxX || rasterMinY > rasterMaxY) {
            rasterMinX = 0;
            rasterMaxX = -1;
            rasterMinY = 0;
            rasterMaxY = -1;
            return;
        }

        if (rasterMinX < boundsMinX >> XSHIFT) {
            rasterMinX = boundsMinX >> XSHIFT;
        }
        if (rasterMinY < boundsMinY >> YSHIFT) {
            rasterMinY = boundsMinY >> YSHIFT;
        }
        if (rasterMaxX > boundsMaxX >> XSHIFT) {
            rasterMaxX = boundsMaxX >> XSHIFT;
        }
        if (rasterMaxY > boundsMaxY >> YSHIFT) {
            rasterMaxY = boundsMaxY >> YSHIFT;
        }
    }

    private int clamp(int x, int min, int max) {
        if (x < min) {
            return min;
        } else if (x > max) {
            return max;
        }
        return x;
    }

    private void _endRendering() {
        if (flips == 0) {
            bboxX0 = bboxY0 = 0;
            bboxX1 = bboxY1 = -1;
            return;
        }

        // Special case for filling a single rect with a flat, opaque color
        // REMIND: This special case was not originally written to fill a
        // cache object and called directly to a Blit - it needs some code
        // to fill the cache instead to be useful for this usage...
        if (false /* Does not work with cache (yet?) */ &&
            edgeIdx == 10 &&
            edges[0] == edges[2] &&
            edges[1] == edges[6] &&
            edges[3] == edges[8] &&
            edges[5] == edges[7] &&
            Math.abs(edges[0] - edges[5]) > MIN_QUAD_OPT_WIDTH)
        {

            int x0 = edges[0] >> XSHIFT;
            int y0 = edges[1] >> YSHIFT;
            int x1 = edges[5] >> XSHIFT;
            int y1 = edges[3] >> YSHIFT;

            if (x0 > x1) {
                int tmp = x0;
                x0 = x1;
                x1 = tmp;
            }
            if (y0 > y1) {
                int tmp = y0;
                y0 = y1;
                y1 = tmp;
            }

            int bMinX = this.boundsMinX >> XSHIFT;
            int bMinY = this.boundsMinY >> YSHIFT;
            int bMaxX = this.boundsMaxX >> XSHIFT;
            int bMaxY = this.boundsMaxY >> YSHIFT;

            // Clip to image bounds in supersampled coordinates
            x0 = clamp(x0, bMinX, bMaxX);
            x1 = clamp(x1, bMinX, bMaxX);
            y0 = clamp(y0, bMinY, bMaxY);
            y1 = clamp(y1, bMinY, bMaxY);

            /*
             * REMIND: Need to fill the cache here instead...
            Blit.fillRectSrcOver(this,
                                 imageData, imageType,
                                 imageOffset,
                                 imageScanlineStride, imagePixelStride,
                                 width, height,
                                 x0, y0, x1, y1,
                                 cred, cgreen, cblue);
            */

            bboxX0 = x0 >> SUBPIXEL_LG_POSITIONS_X;
            bboxY0 = y0 >> SUBPIXEL_LG_POSITIONS_Y;
            bboxX1 = (x1 + SUBPIXEL_POSITIONS_X - 1)
                >> SUBPIXEL_LG_POSITIONS_X;
            bboxY1 = (y1 + SUBPIXEL_POSITIONS_Y - 1)
                >> SUBPIXEL_LG_POSITIONS_Y;

            return;
        }

        int minY = (edgeMinY > boundsMinY) ? edgeMinY : boundsMinY;
        int maxY = (edgeMaxY < boundsMaxY) ? edgeMaxY : boundsMaxY;

        // Check for empty intersection of primitive with the drawing area
        if (minY > maxY) {
            bboxX0 = bboxY0 = 0;
            bboxX1 = bboxY1 = -1;
            return;
        }

        // Compute Y extent in subpixel coordinates
        int iminY = (minY >> YSHIFT) & ~SUBPIXEL_MASK_Y;
        int imaxY = (maxY >> YSHIFT) | SUBPIXEL_MASK_Y;
        int yextent = (imaxY - iminY) + 1;

        // Maximum number of crossings
        int size = flips*yextent;

        int bmax = (boundsMaxY >> YSHIFT) - 1;
        if (imaxY > bmax) {
            imaxY = bmax;
        }

        // Initialize X bounds, will be refined for each strip
        bboxX0 = Integer.MAX_VALUE;
        bboxX1 = Integer.MIN_VALUE;

        // Set Y bounds
        bboxY0 = iminY >> SUBPIXEL_LG_POSITIONS_Y;
        bboxY1 = (imaxY + SUBPIXEL_POSITIONS_Y - 1) >> SUBPIXEL_LG_POSITIONS_Y;

        // Compute number of rows that can be processing using
        // a crossings table no larger than DEFAULT_CROSSINGS_SIZE.
        // However, we must process at least one row, so we grow the table
        // temporarily if needed.  This would require an object with a
        // huge number of flips.
        int rows = DEFAULT_CROSSINGS_SIZE/(flips*SUBPIXEL_POSITIONS_Y);
        rows = Math.min(rows, yextent);
        rows = Math.max(rows, 1);
        for (int i = iminY; i <= imaxY; i += rows*SUBPIXEL_POSITIONS_Y) {
            // Compute index of last scanline to be processed in this pass
            int last = Math.min(i + rows*SUBPIXEL_POSITIONS_Y - 1, imaxY);
            setCrossingsExtents(i, last, flips);

            int bminY = i << YSHIFT;
            int bmaxY = (last << YSHIFT) | ~YMASK;

            // Process edges from the edge list
            int maxIdx = edgeIdx;
            for (int index = 0; index < maxIdx; index += 5) {
                // Test y1 < min:
                //
                // If edge lies entirely above current strip,
                // discard it
                if (edges[index + 3] < bminY) {
                    // Overwrite the edge with the last edge
                    edgeIdx -= 5;
                    int fidx = edgeIdx;
                    int tidx = index;
                    edges[tidx++] = edges[fidx++];
                    edges[tidx++] = edges[fidx++];
                    edges[tidx++] = edges[fidx++];
                    edges[tidx++] = edges[fidx++];
                    edges[tidx  ] = edges[fidx  ];

                    maxIdx -= 5;
                    index -= 5;
                    continue;
                }

                // Test y0 > max:
                //
                // If edge lies entirely below current strip,
                // skip it for now
                if (edges[index + 1] > bmaxY) {
                    continue;
                }

                computeCrossingsForEdge(index, bminY, bmaxY);
            }

            computeBounds();
            if (rasterMaxX < rasterMinX) {
                continue;
            }

            bboxX0 = Math.min(bboxX0,
                              rasterMinX >> SUBPIXEL_LG_POSITIONS_X);
            bboxX1 = Math.max(bboxX1,
                              (rasterMaxX + SUBPIXEL_POSITIONS_X - 1)
                              >> SUBPIXEL_LG_POSITIONS_X);
            renderStrip();
        }

        // Free up any unusually large scratchpad memory used by the
        // preceding primitive
        crossingListFinished();
    }

    public void endRendering() {
        // Set up the cache to accumulate the bounding box
        if (cache != null) {
            cache.bboxX0 = Integer.MAX_VALUE;
            cache.bboxY0 = Integer.MAX_VALUE;
            cache.bboxX1 = Integer.MIN_VALUE;
            cache.bboxY1 = Integer.MIN_VALUE;
        }

        _endRendering();
    }

    public void getBoundingBox(int[] bbox) {
        bbox[0] = bboxX0;
        bbox[1] = bboxY0;
        bbox[2] = bboxX1 - bboxX0;
        bbox[3] = bboxY1 - bboxY0;
    }

    private void renderStrip() {
        // Grow rowAA according to the raster width
        int width = (rasterMaxX - rasterMinX + 1) >> SUBPIXEL_LG_POSITIONS_X;
        alphaWidth = width;

        // Allocate one extra entry in rowAA to avoid a conditional in
        // the rendering loop
        int bufLen = width + 1;
        if (this.rowAA == null || this.rowAA.length < bufLen) {
            this.rowAA = new byte[bufLen];
        }

        // Mask to determine the relevant bit of the crossing sum
        // 0x1 if EVEN_ODD, all bits if NON_ZERO
        int mask = (windingRule == WIND_EVEN_ODD) ? 0x1 : ~0x0;

        int y = 0;
        int prevY = rasterMinY - 1;

        int minX = Integer.MAX_VALUE;
        int maxX = Integer.MIN_VALUE;

        iterateCrossings();
        while (hasMoreCrossingRows()) {
            y = crossingY;

            // Emit any skipped rows
            for (int j = prevY + 1; j < y; j++) {
                if (((j & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) ||
                    (j == rasterMaxY)) {
                    emitRow(j >> SUBPIXEL_LG_POSITIONS_Y, 0, -1);
                }
            }
            prevY = y;

            if (crossingRowIndex < crossingRowCount) {
                int lx = crossings[crossingRowOffset + crossingRowIndex];
                lx >>= 1;
                int hx = crossings[crossingRowOffset + crossingRowCount - 1];
                hx >>= 1;
                int x0 = lx > rasterMinX ? lx : rasterMinX;
                int x1 = hx < rasterMaxX ? hx : rasterMaxX;
                x0 -= rasterMinX;
                x1 -= rasterMinX;

                minX = Math.min(minX, x0 >> SUBPIXEL_LG_POSITIONS_X);
                maxX = Math.max(maxX, x1 >> SUBPIXEL_LG_POSITIONS_X);
            }

            int sum = 0;
            int prev = rasterMinX;
            while (crossingRowIndex < crossingRowCount) {
                int crxo = crossings[crossingRowOffset + crossingRowIndex];
                crossingRowIndex++;

                int crx = crxo >> 1;
                int crorientation = ((crxo & 0x1) == 0x1) ? 1 : -1;

                if ((sum & mask) != 0) {
                    // Clip to active X range, if x1 < x0 loop will
                    // have no effect
                    int x0 = prev > rasterMinX ? prev : rasterMinX;
                    int x1 =  crx < rasterMaxX ?  crx : rasterMaxX;

                    // Empty spans
                    if (x1 > x0) {
                        x0 -= rasterMinX;
                        x1 -= rasterMinX;

                        // Accumulate alpha, equivalent to:
                        //   for (int x = x0; x < x1; x++) {
                        //       ++rowAA[x >> SUBPIXEL_LG_POSITIONS_X];
                        //   }
                        //
                        // In the middle of the span, we can update a full
                        // pixel at a time (i.e., SUBPIXEL_POSITIONS_X
                        // subpixels)

                        int x = x0 >> SUBPIXEL_LG_POSITIONS_X;
                        int xmaxm1 = (x1 - 1) >> SUBPIXEL_LG_POSITIONS_X;
                        if (x == xmaxm1) {
                            // Start and end in same pixel
                            rowAA[x] += x1 - x0;
                        } else {
                            // Start and end in different pixels
                            rowAA[x++] += SUBPIXEL_POSITIONS_X -
                                (x0 & SUBPIXEL_MASK_X);
                            int xmax = x1 >> SUBPIXEL_LG_POSITIONS_X;
                            while (x < xmax) {
                                rowAA[x++] += SUBPIXEL_POSITIONS_X;
                            }
                            // Note - at this point it is possible that
                            // x == width, which implies that
                            // x1 & SUBPIXEL_MASK_X == 0.  We allocate
                            // one extra entry in rowAA so this
                            // assignment will be harmless.  The alternative
                            // is an extra conditional here, or some other
                            // scheme to deal with the last pixel better.
                            rowAA[x] += x1 & SUBPIXEL_MASK_X;
                        }
                    }
                }
                sum += crorientation;
                prev = crx;
            }

            // Every SUBPIXEL_POSITIONS rows, output an antialiased row
            if (((y & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) ||
                (y == rasterMaxY)) {
                emitRow(y >> SUBPIXEL_LG_POSITIONS_Y, minX, maxX);
                minX = Integer.MAX_VALUE;
                maxX = Integer.MIN_VALUE;
            }
        }

        // Emit final row
        for (int j = prevY + 1; j <= rasterMaxY; j++) {
            if (((j & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) ||
                (j == rasterMaxY)) {
                emitRow(j >> SUBPIXEL_LG_POSITIONS_Y, minX, maxX);
                minX = Integer.MAX_VALUE;
                maxX = Integer.MIN_VALUE;
            }
        }
    }

    private void clearAlpha(byte[] alpha,
                            int width,
                            int minX, int maxX) {
        if (maxX >= minX) {
            int w = maxX - minX + 1;
            if (w + minX > width) {
                w = width - minX;
            }

            int aidx = minX;
            for (int i = 0; i < w; i++, aidx++) {
                alpha[aidx] = (byte)0;
            }
        }
    }

    private void emitRow(int y, int minX, int maxX) {
        // Copy rowAA data into the cache if one is present
        if (cache != null) {
            if (maxX >= minX) {
                int x0 = minX + (rasterMinX >> SUBPIXEL_LG_POSITIONS_X);
                int x1 = maxX + (rasterMinX >> SUBPIXEL_LG_POSITIONS_X);

                cache.startRow(y, x0, x1);
                int srcIdx = minX;

                // Perform run-length encoding
                // and store results in the cache
                byte startVal = rowAA[srcIdx++];
                int runLen = 1;
                while (srcIdx <= maxX) {
                    byte nextVal = rowAA[srcIdx++];
                    if (nextVal == startVal && runLen < 255) {
                        ++runLen;
                    } else {
                        cache.addRLERun(startVal, runLen);

                        runLen = 1;
                        startVal = nextVal;
                    }
                }
                cache.addRLERun(startVal, runLen);
                cache.addRLERun((byte)0, 0);
            }
        }

        clearAlpha(rowAA,
                   alphaWidth,
                   minX, maxX);
    }

    public void setCache(PiscesCache cache) {
        this.cache = cache;
    }

    // Edge list data

    private int[] edges = new int[5*INITIAL_EDGES];
    private int edgeIdx = 0;
    private int edgeMinY = Integer.MAX_VALUE;
    private int edgeMaxY = Integer.MIN_VALUE;

    private void addEdge(int x0, int y0, int x1, int y1) {
        int newLen = edgeIdx + 5;
        if (edges.length < newLen) {
            int[] tmp = new int[Math.max(11*edges.length/10, newLen)];
            System.arraycopy(edges, 0, tmp, 0, edgeIdx);
            this.edges = tmp;
        }

        int orientation = 1;
        if (y0 > y1) {
            int tmp = y0;
            y0 = y1;
            y1 = tmp;

            orientation = -1;
        }

        // Skip edges that don't cross a subsampled scanline
        int eminY = ((y0 + HYSTEP) & YMASK);
        int emaxY = ((y1 - HYSTEP) & YMASK);
        if (eminY > emaxY) {
            return;
        }

        if (orientation == -1) {
            int tmp = x0;
            x0 = x1;
            x1 = tmp;
        }

        edges[edgeIdx++] = x0;
        edges[edgeIdx++] = y0;
        edges[edgeIdx++] = x1;
        edges[edgeIdx++] = y1;
        edges[edgeIdx++] = orientation;

        // Update Y bounds of primitive
        if (y0 < edgeMinY) {
            edgeMinY = y0;
        }
        if (y1 > edgeMaxY) {
            edgeMaxY = y1;
        }
    }

    private void resetEdges() {
        this.edgeIdx = 0;
        this.edgeMinY = Integer.MAX_VALUE;
        this.edgeMaxY = Integer.MIN_VALUE;
    }

    // Crossing list data

    private int[] crossingIndices;
    private int[] crossings;
    private int crossingMinY;
    private int crossingMaxY;
    private int crossingMinX = Integer.MAX_VALUE;
    private int crossingMaxX = Integer.MIN_VALUE;
    private int crossingMaxXEntries;
    private int numCrossings = 0;
    private boolean crossingsSorted = false;

    private int crossingY;
    private int crossingRowCount;
    private int crossingRowOffset;
    private int crossingRowIndex;

    private void setCrossingsExtents(int minY, int maxY, int maxXEntries) {
        int yextent = maxY - minY + 1;

        // Grow indices array as needed
        if (crossingIndices == null || crossingIndices.length < yextent) {
            this.crossingIndices =
                new int[Math.max(yextent, DEFAULT_INDICES_SIZE)];
        }
        // Grow crossings array as needed
        if (crossings == null || crossings.length < yextent*maxXEntries) {
            this.crossings = new int[Math.max(yextent*maxXEntries,
                                              DEFAULT_CROSSINGS_SIZE)];
        }
        this.crossingMinY = minY;
        this.crossingMaxY = maxY;
        this.crossingMaxXEntries = maxXEntries;
        resetCrossings();
    }

    private void resetCrossings() {
        int yextent = crossingMaxY - crossingMinY + 1;
        int start = 0;
        for (int i = 0; i < yextent; i++) {
            crossingIndices[i] = start;
            start += crossingMaxXEntries;
        }
        crossingMinX = Integer.MAX_VALUE;
        crossingMaxX = Integer.MIN_VALUE;
        numCrossings = 0;
        crossingsSorted = false;
    }

    // Free sorting arrays if larger than maximum size
    private void crossingListFinished() {
        if (crossings != null && crossings.length > DEFAULT_CROSSINGS_SIZE) {
            crossings = new int[DEFAULT_CROSSINGS_SIZE];
        }
        if (crossingIndices != null &&
            crossingIndices.length > DEFAULT_INDICES_SIZE)
        {
            crossingIndices = new int[DEFAULT_INDICES_SIZE];
        }
    }

    private void sortCrossings(int[] x, int off, int len) {
        for (int i = off + 1; i < off + len; i++) {
            int j = i;
            int xj = x[j];
            int xjm1;

            while (j > off && (xjm1 = x[j - 1]) > xj) {
                x[j] = xjm1;
                x[j - 1] = xj;
                j--;
            }
        }
    }

    private void sortCrossings() {
        int start = 0;
        for (int i = 0; i <= crossingMaxY - crossingMinY; i++) {
            sortCrossings(crossings, start, crossingIndices[i] - start);
            start += crossingMaxXEntries;
        }
    }

    private void addCrossing(int y, int x, int orientation) {
        if (x < crossingMinX) {
            crossingMinX = x;
        }
        if (x > crossingMaxX) {
            crossingMaxX = x;
        }

        int index = crossingIndices[y - crossingMinY]++;
        x <<= 1;
        crossings[index] = (orientation == 1) ? (x | 0x1) : x;

        ++numCrossings;
    }

    private void iterateCrossings() {
        if (!crossingsSorted) {
            sortCrossings();
            crossingsSorted = true;
        }
        crossingY = crossingMinY - 1;
        crossingRowOffset = -crossingMaxXEntries;
    }

    private boolean hasMoreCrossingRows() {
        if (++crossingY <= crossingMaxY) {
            crossingRowOffset += crossingMaxXEntries;
            int y = crossingY - crossingMinY;
            crossingRowCount = crossingIndices[y] - y*crossingMaxXEntries;
            crossingRowIndex = 0;
            return true;
        } else {
            return false;
        }
    }
}
