double maxX, double maxY)
double maxX, double maxY, Rectangle2D userBounds)
  protected void rawFillShape(ArrayList segs, double minX, double minY,                              double maxX, double maxY)  {    // This is an implementation of a polygon scanline conversion algorithm    // described here:    // http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/scan/    // Create table of all edges.    // The edge buckets, sorted and indexed by their Y values.    ArrayList[] edgeTable = new ArrayList[(int) Math.ceil(maxY)                                          - (int) Math.ceil(minY) + 1];    for (Iterator i = segs.iterator(); i.hasNext();)      {        PolyEdge edge = (PolyEdge) i.next();        // Horizontal edges are not needed and make things only more        // complicated. Skip them.        if (Math.ceil(edge.y0) == Math.ceil(edge.y1))          continue;        int yindex = (int) ((int) Math.ceil(edge.y0) - (int) Math.ceil(minY));        if (edgeTable[yindex] == null) // Create bucket when needed.          edgeTable[yindex] = new ArrayList();        edgeTable[yindex].add(edge); // Add edge to the bucket of its line.      }    // TODO: The following could be useful for a future optimization.//    // Sort all the edges in the edge table within their buckets.//    for (int y = 0; y < edgeTable.length; y++)//      {//        if (edgeTable[y] != null)//          Collections.sort(edgeTable[y]);//      }    // 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 relevant lines.    int minYInt = (int) Math.ceil(minY);    for (int y = minYInt; y <= maxY; y++)      {        ArrayList bucket = edgeTable[y - minYInt];        // 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();            if (y >= edge.y0 && y >= edge.y1)              i.remove();            else              {                edge.xIntersection += edge.slope;                //edge.xIntersection = edge.x0 + edge.slope * (y - edge.y0);                //System.err.println("edge.xIntersection: " + edge.xIntersection);              }          }        if (bucket != null)          activeEdges.addAll(bucket);        // 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.        int x0 = 0; // Gets initialized in the first else branch below.        boolean active = false;        //System.err.println("scanline: " + y);        for (Iterator i = activeEdges.iterator(); i.hasNext();)          {            PolyEdge edge = (PolyEdge) i.next();            //System.err.println("edge: " + edge);            int x = (int) edge.xIntersection;            if (active)              {                fillScanline(x0, x, y);                active = false;              }            else              {                x0 = x;                active = true;              }          }      }  }