This adds some infrastructure to the rasterizer, this is needed for the
upcoming quality improvements, but does not improve the rendering for
itself.

2007-05-24  Roman Kennke  <[EMAIL PROTECTED]>

        * gnu/java/awt/java2d/ScanlineCoverage.java
        (Iterator): New class.
        (Range): New class.
        (Coverage.covDelta): Made field package private.
        (Coverage.xPos): Made field package private.
        (iterator): New field. Stores the iterator that is reused.
        (ScanlineCoverage): Initialize iterator.
        (assertion): Removed.
        (isEmpty): Refined conditions.
        (iterate): Return Iterator instance.
        (next): Removed. This is done by the Iterator class now.
        (test): Removed.
        * gnu/java/awt/java2d/ScanlineConverter.java
        (main): Removed.
        * gnu/java/awt/peer/x/XGraphics2D.java
        (renderScanline): Adjust to new coverage iterator stuff.
        * gnu/java/awt/java2d/AbstractGraphics2D.java
        (renderScanline): Adjust to new coverage iterator stuff.

/Roman

-- 
Dipl.-Inf. Roman Kennke, Software Engineer, http://kennke.org
aicas Allerton Interworks Computer Automated Systems GmbH
Haid-und-Neu-Straße 18 * D-76131 Karlsruhe * Germany
http://www.aicas.com   * Tel: +49-721-663 968-0
USt-Id: DE216375633, Handelsregister HRB 109481, AG Karlsruhe
Geschäftsführer: Dr. James J. Hunt
Index: gnu/java/awt/peer/x/XGraphics2D.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/x/XGraphics2D.java,v
retrieving revision 1.3
diff -u -1 -5 -r1.3 XGraphics2D.java
--- gnu/java/awt/peer/x/XGraphics2D.java	22 May 2007 13:12:56 -0000	1.3
+++ gnu/java/awt/peer/x/XGraphics2D.java	24 May 2007 16:26:25 -0000
@@ -207,64 +207,60 @@
                 //System.err.println("tx: " + tx + ", ty: " + ty + ", pixel: " + pixel[0] + ", " + pixel[1] + ", " + pixel[2]);
 //              System.err.print("r: " + pixel[0]);
 //              System.err.print(", g: " + pixel[1]);
 //              System.err.println(", b: " + pixel[2]);
                 zPixmap.set_red(tx - x, ty - y, pixel[0]);
                 zPixmap.set_green(tx - x, ty - y, pixel[1]);
                 zPixmap.set_blue(tx - x, ty - y, pixel[2]);
               }
           }
         xdrawable.put_image(xgc, zPixmap, x, y);
       }
   }
 
   public void renderScanline(int y, ScanlineCoverage c)
   {
-    ScanlineCoverage.Coverage start = c.iterate();
-    ScanlineCoverage.Coverage end = c.next();
-    assert (start != null);
-    assert (end != null);
-    int coverageAlpha = 0;
+    ScanlineCoverage.Iterator iter = c.iterate();
+    float coverageAlpha = 0;
     int maxCoverage = c.getMaxCoverage();
     Color old = getColor();
     Color col = getColor();
     if (col == null)
       col = Color.BLACK;
-    do
+    while (iter.hasNext())
       {
+        ScanlineCoverage.Range range = iter.next();
         // TODO: Dumb implementation for testing.
-        coverageAlpha = coverageAlpha + start.getCoverageDelta();
+        coverageAlpha = range.getCoverage();
         if (coverageAlpha > 0)
           {
             int red = col.getRed();
             int green = col.getGreen();
             int blue = col.getBlue();
             if (coverageAlpha < c.getMaxCoverage())
               {
                 float alpha = coverageAlpha / maxCoverage;
                 red = 255 - (int) ((255 - red) * alpha);
                 green = 255 - (int) ((255 - green) * alpha);
                 blue = 255 - (int) ((255 - blue) * alpha);
               }
             xgc.set_foreground(red << 16 | green << 8 | blue);
-            int x0 = start.getXPos();
-            int x1 = end.getXPos();
-            xdrawable.fill_rectangle(xgc, x0, y, x1 - x0, 1);
+            int x0 = range.getXPos();
+            int l = range.getLength();
+            xdrawable.fill_rectangle(xgc, x0, y, l, 1);
           }
-        start = end;
-        end = c.next();
-      } while (end != null);
+      }
     xgc.set_foreground(old.getRGB());
   }
 
   protected void fillScanline(int x0, int x1, int y)
   {
     xdrawable.segment(xgc, x0, y, x1, y);
   }
 
   protected void fillScanlineAA(int x0, int x1, int y, int alpha)
   {
     //System.err.println("fillScanlineAA: " + x0 + ", " + x1 + ", " + y + ", " + alpha);
     // FIXME: This is for testing only.
     Color c = getColor();
     setColor(new Color(255-alpha, 255-alpha, 255-alpha));
     xdrawable.segment(xgc, x0, y, x1, y);
Index: gnu/java/awt/java2d/AbstractGraphics2D.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java,v
retrieving revision 1.16
diff -u -1 -5 -r1.16 AbstractGraphics2D.java
--- gnu/java/awt/java2d/AbstractGraphics2D.java	18 May 2007 16:22:40 -0000	1.16
+++ gnu/java/awt/java2d/AbstractGraphics2D.java	24 May 2007 16:26:26 -0000
@@ -1549,31 +1549,30 @@
   {
     // Determine if we need to antialias stuff.
     boolean antialias = false;
     if (isFont)
       {
         Object v = renderingHints.get(RenderingHints.KEY_TEXT_ANTIALIASING);
         // We default to antialiasing for text rendering.
         antialias = (v == RenderingHints.VALUE_TEXT_ANTIALIAS_ON
                      || v == RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
       }
     else
       {
         Object v = renderingHints.get(RenderingHints.KEY_ANTIALIASING);
         antialias = (v == RenderingHints.VALUE_ANTIALIAS_ON);
       }
-
     ScanlineConverter sc = getScanlineConverter();
     int resolution = 0;
     if (antialias)
       {
         // Adjust resolution according to rendering hints.
         resolution = 2;
       }
     sc.renderShape(this, s, clip, transform, resolution);
   }
 
   /**
    * Returns the color model of this Graphics object.
    *
    * @return the color model of this Graphics object
    */
@@ -1727,49 +1726,45 @@
     PaintContext pCtx = paintContext;
     int x0 = c.getMinX();
     int x1 = c.getMaxX();
     Raster paintRaster = pCtx.getRaster(x0, y, x1 - x0, 1);
 
     // Do the anti aliasing thing.
     float coverageAlpha = 0;
     float maxCoverage = c.getMaxCoverage();
     ColorModel cm = pCtx.getColorModel();
     DataBuffer db = paintRaster.getDataBuffer();
     Point loc = new Point(paintRaster.getMinX(), paintRaster.getMinY());
     SampleModel sm = paintRaster.getSampleModel();
     WritableRaster writeRaster = Raster.createWritableRaster(sm, db, loc);
     WritableRaster alphaRaster = cm.getAlphaRaster(writeRaster);
     int pixel;
-    ScanlineCoverage.Coverage start = c.iterate();
-    ScanlineCoverage.Coverage end = c.next();
-    assert (start != null);
-    assert (end != null);
-    do
+    ScanlineCoverage.Iterator iter = c.iterate();
+    while (iter.hasNext())
       {
-        coverageAlpha = coverageAlpha + (start.getCoverageDelta() / maxCoverage);
+        ScanlineCoverage.Range range = iter.next();
+        coverageAlpha = range.getCoverage() / maxCoverage;
         if (coverageAlpha < 1.0)
           {
-            for (int x = start.getXPos(); x < end.getXPos(); x++)
+            for (int x = range.getXPos(); x < range.getXPosEnd(); x++)
               {
                 pixel = alphaRaster.getSample(x, y, 0);
                 pixel = (int) (pixel * coverageAlpha);
                 alphaRaster.setSample(x, y, 0, pixel);
               }
           }
-        start = end;
-        end = c.next();
-      } while (end != null);
+      }
     ColorModel paintColorModel = pCtx.getColorModel();
     CompositeContext cCtx = composite.createContext(paintColorModel,
                                                     getColorModel(),
                                                     renderingHints);
     WritableRaster targetChild = destinationRaster.createWritableTranslatedChild(-x0,- y);
     cCtx.compose(paintRaster, targetChild, targetChild);
     updateRaster(destinationRaster, x0, y, x1 - x0, 1);
     cCtx.dispose();
   }
 
 
   /**
    * Initializes this graphics object. This must be called by subclasses in
    * order to correctly initialize the state of this object.
    */
Index: gnu/java/awt/java2d/ScanlineConverter.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/java2d/ScanlineConverter.java,v
retrieving revision 1.3
diff -u -1 -5 -r1.3 ScanlineConverter.java
--- gnu/java/awt/java2d/ScanlineConverter.java	18 May 2007 16:22:40 -0000	1.3
+++ gnu/java/awt/java2d/ScanlineConverter.java	24 May 2007 16:26:26 -0000
@@ -412,26 +412,16 @@
   }
 
   private void edgePoolAdd(int x0, int y0, int x1, int y1, boolean clip)
   {
     // Don't need no horizontal edges.
     if (y0 != y1)
       {
         edgePoolLast.init(FIXED_DIGITS, x0, y0, x1, y1, clip);
         if (edgePoolLast.poolNext == null)
           {
             edgePoolLast.poolNext = new PolyEdge();
           }
         edgePoolLast = edgePoolLast.poolNext;
       }
   }
-
-  /**
-   * Performs some tests.
-   *
-   * @param args
-   */
-  public static void main(String[] args)
-  {
-    ScanlineCoverage.test();
-  }
 }
Index: gnu/java/awt/java2d/ScanlineCoverage.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/java2d/ScanlineCoverage.java,v
retrieving revision 1.1
diff -u -1 -5 -r1.1 ScanlineCoverage.java
--- gnu/java/awt/java2d/ScanlineCoverage.java	18 May 2007 16:22:40 -0000	1.1
+++ gnu/java/awt/java2d/ScanlineCoverage.java	24 May 2007 16:26:26 -0000
@@ -36,43 +36,224 @@
 exception statement from your version. */
 
 package gnu.java.awt.java2d;
 
 /**
  * Stores and handles the pixel converage for a scanline. The pixel coverage
  * is stored as sorted list of [EMAIL PROTECTED] Covergage} entries, each of which holds
  * information about the coverage for the X and Y axis. This is utilized to
  * compute the actual coverage for each pixel on the scanline and finding
  * chunks of pixels with equal coverage quickly.
  */
 public final class ScanlineCoverage
 {
 
   /**
+   * Iterates over the coverage list and calculates the actual coverage
+   * ranges on a scanline.
+   */
+  public final class Iterator
+  {
+    /**
+     * This instance is reused in the iteration.
+     */
+    private Range range;
+
+    /**
+     * The pointer to the current item in the iteration.
+     */
+    private Coverage currentItem;
+
+    /**
+     * The current coverage value.
+     */
+    private int currentCoverage;
+
+    /**
+     * Creates a new CoverageIterator.
+     */
+    Iterator()
+    {
+      range = new Range();
+    }
+
+    /**
+     * Returns the next coverage range on the scanline. The returned object
+     * will always be the same object, but with different values. Keep that
+     * in mind when dealing with this object.
+     *
+     * @return the next coverage range on the scanline
+     */
+    public Range next()
+    {
+      currentCoverage += currentItem.covDelta;
+      range.setCoverage(currentCoverage);
+      range.setXPos(currentItem.xPos);
+      currentItem = currentItem.next;
+      range.setLength(currentItem.xPos - range.xPos);
+      return range;
+    }
+
+    /**
+     * Returns {@ true} when there are more coverage ranges to iterate,
+     * {@ false} otherwise.
+     *
+     * @return {@ true} when there are more coverage ranges to iterate,
+     *         {@ false} otherwise
+     */
+    public boolean hasNext()
+    {
+      boolean hasNext;
+      if (currentItem == null || currentItem.next == null
+          || currentItem.next == last)
+        hasNext = false;
+      else
+        hasNext = true;
+      return hasNext;
+    }
+
+    /**
+     * Resets this iterator to the start of the list.
+     */
+    void reset()
+    {
+      currentItem = head;
+      currentCoverage = 0;
+    }
+  }
+
+  /**
+   * A data object that carries information about pixel coverage on a scanline.
+   * The data consists of a starting X position on the scanline, the
+   * length of the range in pixels and the actual coverage value.
+´  */
+  public static final class Range
+  {
+    /**
+     * The X position on the scanline, in pixels.
+     */
+    private int xPos;
+
+    /**
+     * The length of the range, in pixels.
+     */
+    private int length;
+
+    /**
+     * The actual coverage. The relation depends on
+     * [EMAIL PROTECTED] ScanlineCoverage#maxCoverage}.
+     */
+    private int coverage;
+
+    /**
+     * Creates a new CoverageRange object.
+     */
+    Range()
+    {
+      // Nothing to do. The values get initialized in the corresponding
+      // setters.
+    }
+
+    /**
+     * Sets the X start position (left) on the scanline. This value is
+     * considered to be in pixels and device space.
+     *
+     * @param x the x position
+     */
+    void setXPos(int x)
+    {
+      xPos = x;
+    }
+
+    /**
+     * Returns the X start position (left) on the scanline. This value
+     * is considered to be in pixels and device space.
+     * 
+     * @return the X position on the scanline
+     */
+    public int getXPos()
+    {
+      return xPos;
+    }
+
+    /**
+     * Sets the length of the pixel range. This is in pixel units.
+     *
+     * @param l the length of the range
+     */
+    void setLength(int l)
+    {
+      length = l;
+    }
+
+    /**
+     * Returns the length of the range in pixel units.
+     *
+     * @return the length of the range in pixel units
+     */
+    public int getLength()
+    {
+      return length;
+    }
+
+    /**
+     * Returns the first X position after the range.
+     *
+     * @return the first X position after the range
+     */
+    public int getXPosEnd()
+    {
+      return xPos + length;
+    }
+
+    /**
+     * Sets the coverage of the pixel range. The relation of that value
+     * depends on [EMAIL PROTECTED] ScanlineCoverage#maxCoverage}.
+     *
+     * @param cov the coverage value for the pixel range
+     */
+    void setCoverage(int cov)
+    {
+      coverage = cov;
+    }
+
+    /**
+     * Returns the coverage of the pixel range. The relation of this value
+     * depends on [EMAIL PROTECTED] ScanlineCoverage#getMaxCoverage()}.
+     *
+     * @return the coverage of the pixel range
+     */
+    public int getCoverage()
+    {
+      return coverage;
+    }
+  }
+
+  /**
    * One bucket in the list.
    */
-  public static final class Coverage
+  private static final class Coverage
   {
     /**
      * The X coordinate on the scanline to which this bucket belongs.
      */
-    private int xPos;
+    int xPos;
 
     /**
      * The X coverage delta.
      */
-    private int covDelta;
+    int covDelta;
 
     /**
      * Implements a linked list. This points to the next element of the list.
      */
     Coverage next;
 
     /**
      * Returns the X coordinate for this entry.
      *
      * @return the X coordinate for this entry
      */
     public int getXPos()
     {
       return xPos;
     }
@@ -146,30 +327,43 @@
    * The minimum X coordinate of this scanline.
    */
   private int minX;
 
   /**
    * The maximum X coordinate of this scanline.
    */
   private int maxX;
 
   /**
    * The maximum coverage value.
    */
   private int maxCoverage;
 
   /**
+   * The iterator over the ranges of this scanline.
+   */
+  private Iterator iterator;
+
+  /**
+   * Creates a new ScanlineCoverage instance.
+   */
+  public ScanlineCoverage()
+  {
+    iterator = new Iterator();
+  }
+
+  /**
    * Indicates the the next scan of the scanline begins and that the next
    * request will be at the beginning of this list. This makes searching and
    * sorting of this list very quick.
    */
   public void rewind()
   {
     current = head;
     currentPrev = null;
   }
 
   /**
    * Clears the list. This does not throw away the old buckets but only
    * resets the end-pointer of the list to the first element. All buckets are
    * then unused and are reused when the list is filled again.
    */
@@ -347,168 +541,40 @@
         else
           {
             // Testpoint 7.
             assert (match == head);
             // Insert at head.
             head = cov;
             head.next = match;
             current = head;
             currentPrev = null;
           }
         return cov;
       }
   }
 
   /**
-   * (Re-)Starts iterating the coverage entries by returning the first Coverage
-   * item in the list. Pixels left to that entry have a zero coverage.
-   *
-   * @return the first coverage item
-   */
-  public Coverage iterate()
-  {
-    if (head == last)
-      current = null;
-    else
-      current = head;
-    currentPrev = null;
-    return current;
-  }
-
-  /**
-   * Returns the next coverage item in the list, according to the current
-   * iteration state.
+   * (Re-)Starts iterating the coverage values for the scanline.
+   * Use the returned iterator to get the consecutive coverage ranges.
    *
-   * @return the next coverage item in the list or {@ null} if the end has
-   *         been reached
+   * @return the iterator
    */
-  public Coverage next()
+  public Iterator iterate()
   {
-    currentPrev = current;
-    if (current == null || current.next == last)
-      current = null;
-    else
-      current = current.next;
-    return current;
+    iterator.reset();
+    return iterator;
   }
 
   /**
    * Returns {@ true} if this object has no entries for the current scanline,
    * {@ false} otherwise.
    *
    * @return {@ true} if this object has no entries for the current scanline,
    *         {@ false} otherwise
    */
   public boolean isEmpty()
   {
-    return head == null || head == last;
-  }
-
-  /**
-   * Performs some tests to check if this class is working correctly.
-   * There are comments about a bunch of test points in this method, which
-   * correspond to other points in this class as commented.
-   */
-  static void test()
-  {
-    System.out.println("ScanlineCoverage test 1");
-    // Test testpoint 1 & 2.
-    ScanlineCoverage c = new ScanlineCoverage();
-    c.add(2, 3);
-    c.add(3, 4);
-    c.add(4, 5);
-
-    Coverage cov = c.iterate();
-    assertion(cov.xPos == 2);
-    assertion(cov.covDelta == 3);
-    cov = c.next();
-    assertion(cov.xPos == 3);
-    assertion(cov.covDelta == 4);
-    cov = c.next();
-    assertion(cov.xPos == 4);
-    assertion(cov.covDelta == 5);
-    assertion(c.next() == null);
-    
-    System.out.println("ScanlineCoverage test 2");
-    // Test testpoint 3 and 4.
-    c.clear();
-    c.add(5, 4);
-    c.add(7, 5);
-    c.add(7, 10);
-    cov = c.iterate();
-    assertion(cov.xPos == 5);
-    assertion(cov.covDelta == 4);
-    cov = c.next();
-    assertion(cov.xPos == 7);
-    assertion(cov.covDelta == 15);
-    assertion(c.next() == null);
-
-    System.out.println("ScanlineCoverage test 3");
-    // Test testpoint 5.
-    c.rewind();
-    c.add(6, 20);
-    cov = c.iterate();
-    assertion(cov.xPos == 5);
-    assertion(cov.covDelta == 4);
-    cov = c.next();
-    assertion(cov.xPos == 6);
-    assertion(cov.covDelta == 20);
-    cov = c.next();
-    assertion(cov.xPos == 7);
-    assertion(cov.covDelta == 15);
-    assertion(c.next() == null);
-    
-    System.out.println("ScanlineCoverage test 4");
-    // Test testpoint 6.
-    c.rewind();
-    c.add(8, 21);
-    cov = c.iterate();
-    assertion(cov.xPos == 5);
-    assertion(cov.covDelta == 4);
-    cov = c.next();
-    assertion(cov.xPos == 6);
-    assertion(cov.covDelta == 20);
-    cov = c.next();
-    assertion(cov.xPos == 7);
-    assertion(cov.covDelta == 15);
-    cov = c.next();
-    assertion(cov.xPos == 8);
-    assertion(cov.covDelta == 21);
-    assertion(c.next() == null);
-    
-    System.out.println("ScanlineCoverage test 5");
-    // Test testpoint 6.
-    c.rewind();
-    c.add(2, 100);
-    cov = c.iterate();
-    assertion(cov.xPos == 2);
-    assertion(cov.covDelta == 100);
-    cov = c.next();
-    assertion(cov.xPos == 5);
-    assertion(cov.covDelta == 4);
-    cov = c.next();
-    assertion(cov.xPos == 6);
-    assertion(cov.covDelta == 20);
-    cov = c.next();
-    assertion(cov.xPos == 7);
-    assertion(cov.covDelta == 15);
-    cov = c.next();
-    assertion(cov.xPos == 8);
-    assertion(cov.covDelta == 21);
-    assertion(c.next() == null);
-    
+    return head == null || head == last
+           || head.next == null || head.next == last;
   }
 
-  /**
-   * Checks a condition and throws and AssertionError if this condition
-   * fails.
-   *
-   * @param b the condition
-   */
-  private static void assertion(boolean b)
-  {
-    if (! b)
-      {
-        throw new AssertionError();
-      }
-  }
 }

Reply via email to