alpha[x0 - (int) minX]++; alpha[x1 - (int) minX + 1]--; previous = edge; active = false;
int left = x0 - (int) minX; int right = x1 - (int) minX + 1; alpha[left]++; alpha[right]--; leftX = Math.min(x0, leftX); rightX = Math.max(x1+2, rightX); emptyScanline = false;
  private void fillShapeAntialias(ArrayList segs, double minX, double minY,                                  double maxX, double maxY,                                  Rectangle2D userBounds)  {    // This is an implementation of a polygon scanline conversion algorithm    // described here:    // http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/scan/    // The antialiasing is implemented using a sampling technique, we do    // not scan whole lines but fractions of the line.    Rectangle deviceBounds = new Rectangle((int) minX, (int) minY,                                           (int) Math.ceil(maxX) - (int) minX,                                           (int) Math.ceil(maxY) - (int) minY);    PaintContext pCtx = paint.createContext(getColorModel(), deviceBounds,                                            userBounds, transform,                                            renderingHints);    // This array will contain the oversampled transparency values for    // each pixel in the scanline.    int numScanlines = (int) Math.ceil(maxY) - (int) minY;    int numScanlinePixels = (int) Math.ceil(maxX) - (int) minX + 1;    if (alpha == null || alpha.length < (numScanlinePixels + 1))      alpha = new int[numScanlinePixels + 1];        int firstLine = (int) minY;    //System.err.println("minY: " + minY);    int firstSubline = (int) (Math.ceil((minY - Math.floor(minY)) * AA_SAMPLING));    double firstLineDouble = firstLine + firstSubline / (double) AA_SAMPLING;    //System.err.println("firstSubline: " + firstSubline);    // Create table of all edges.    // The edge buckets, sorted and indexed by their Y values.    //System.err.println("numScanlines: " + numScanlines);    if (edgeTable == null        || edgeTable.length < numScanlines * AA_SAMPLING + AA_SAMPLING)      edgeTable = new ArrayList[numScanlines * AA_SAMPLING + AA_SAMPLING];    //System.err.println("firstLineDouble: " + firstLineDouble);        for (Iterator i = segs.iterator(); i.hasNext();)      {        PolyEdge edge = (PolyEdge) i.next();        int yindex = (int) (Math.ceil((edge.y0 - firstLineDouble) * AA_SAMPLING));        //System.err.println("yindex: " + yindex + " for y0: " + edge.y0);        // Initialize edge's slope and initial xIntersection.        edge.slope = ((edge.x1 - edge.x0) / (edge.y1 - edge.y0)) / AA_SAMPLING;        if (edge.y0 == edge.y1) // Horizontal edge.          edge.xIntersection = Math.min(edge.x0, edge.x1);        else          {            double alignedFirst = Math.ceil(edge.y0 * AA_SAMPLING) / AA_SAMPLING;            edge.xIntersection = edge.x0 + (edge.slope * AA_SAMPLING) * (alignedFirst - edge.y0);          }        //System.err.println(edge);        // FIXME: Sanity check should not be needed when clipping works.        if (yindex >= 0 && yindex < edgeTable.length)          {            if (edgeTable[yindex] == null) // Create bucket when needed.              edgeTable[yindex] = new ArrayList();            edgeTable[yindex].add(edge); // Add edge to the bucket of its line.          }      }        // The activeEdges list contains all the edges of the current scanline    // ordered by their intersection points with this scanline.    ArrayList activeEdges = new ArrayList();    PolyEdgeComparator comparator = new PolyEdgeComparator();        // Scan all lines.    int yindex = 0;    //System.err.println("firstLine: " + firstLine + ", maxY: " + maxY + ", firstSubline: " + firstSubline);    for (int y = firstLine; y <= maxY; y++)      {        for (int subY = firstSubline; subY < AA_SAMPLING; subY++)          {            //System.err.println("scanline: " + y + ", subScanline: " + subY);            ArrayList bucket = edgeTable[yindex];            // Update all the x intersections in the current activeEdges table            // and remove entries that are no longer in the scanline.            for (Iterator i = activeEdges.iterator(); i.hasNext();)              {                PolyEdge edge = (PolyEdge) i.next();                // TODO: Do the following using integer arithmetics.                if ((y + ((double) subY / (double) AA_SAMPLING)) > edge.y1)                  i.remove();                else                  {                    edge.xIntersection += edge.slope;                    //System.err.println("edge: " + edge);                    //edge.xIntersection = edge.x0 + edge.slope * (y - edge.y0);                    //System.err.println("edge.xIntersection: " + edge.xIntersection);                  }              }            if (bucket != null)              {                activeEdges.addAll(bucket);                edgeTable[yindex].clear();              }            // Sort current edges. We are using a bubble sort, because the order            // of the intersections will not change in most situations. They            // will only change, when edges intersect each other.            int size = activeEdges.size();            if (size > 1)              {                for (int i = 1; i < size; i++)                  {                    PolyEdge e1 = (PolyEdge) activeEdges.get(i - 1);                    PolyEdge e2 = (PolyEdge) activeEdges.get(i);                    if (comparator.compare(e1, e2) > 0)                      {                        // Swap e2 with its left neighbor until it 'fits'.                        int j = i;                        do                          {                            activeEdges.set(j, e1);                            activeEdges.set(j - 1, e2);                            j--;                            if (j >= 1)                              e1 = (PolyEdge) activeEdges.get(j - 1);                          } while (j >= 1 && comparator.compare(e1, e2) > 0);                      }                  }              }                    // Now draw all pixels inside the polygon.            // This is the last edge that intersected the scanline.            PolyEdge previous = null; // Gets initialized below.            boolean active = false;            //System.err.println("scanline: " + y + ", subscanline: " + subY);            for (Iterator i = activeEdges.iterator(); i.hasNext();)              {                PolyEdge edge = (PolyEdge) i.next();                // Only fill scanline, if the current edge actually intersects                // the scanline. There may be edges that lie completely                // within the current scanline.                //System.err.println("previous: " + previous);                //System.err.println("edge: " + edge);                if (active)                  {                    // TODO: Use integer arithmetics here.                    if (edge.y1 > (y + (subY / (double) AA_SAMPLING)))                      {                        //System.err.println(edge);                        // TODO: Eliminate the aligments.                        int x0 = (int) Math.min(Math.max(previous.xIntersection, minX), maxX);                        int x1 = (int) Math.min(Math.max(edge.xIntersection, minX), maxX);                        //System.err.println("minX: " + minX + ", x0: " + x0 + ", x1: " + x1 + ", maxX: " + maxX);                        // TODO: Pull out cast.                        alpha[x0 - (int) minX]++;                        alpha[x1 - (int) minX + 1]--;                        previous = edge;                        active = false;                      }                  }                else                  {                    // TODO: Use integer arithmetics here.                    if (edge.y1 > (y + (subY / (double) AA_SAMPLING)))                      {                        //System.err.println(edge);                        previous = edge;                        active = true;                      }                  }              }            yindex++;          }        firstSubline = 0;        // Render full scanline.        //System.err.println("scanline: " + y);        fillScanlineAA(alpha, (int) minX, (int) y, numScanlinePixels, pCtx);      }    if (paint instanceof Color && composite == AlphaComposite.SrcOver)      rawSetForeground((Color) paint);    pCtx.dispose();  }