OSDN Git Service

2003-10-21 Sascha Brawer <brawer@dandelis.ch>
authormkoch <mkoch@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Oct 2003 13:18:22 +0000 (13:18 +0000)
committermkoch <mkoch@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Oct 2003 13:18:22 +0000 (13:18 +0000)
Fix for Classpath bug #6076.
* java/awt/geom/GeneralPath.java (append): Re-written.

2003-10-21  Sascha Brawer  <brawer@dandelis.ch>

Fix for Classpath bug #6089.
* java/awt/geom/GeneralPath.java (curveTo): Set correct segment type.
(getPathIterator, GeneralPathIterator): Re-written from scratch.

2003-10-21  Sascha Brawer  <brawer@dandelis.ch>

* java/awt/geom/GeneralPath.java (getCurrentPoint): Return last
point, not start of subpath.  Fixes Classpath bug #6075.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72748 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/java/awt/geom/GeneralPath.java

index f5bf330..4946230 100644 (file)
@@ -1,3 +1,19 @@
+2003-10-21  Sascha Brawer  <brawer@dandelis.ch>
+
+       Fix for Classpath bug #6076.
+       * java/awt/geom/GeneralPath.java (append): Re-written.
+
+2003-10-21  Sascha Brawer  <brawer@dandelis.ch>
+
+       Fix for Classpath bug #6089.
+       * java/awt/geom/GeneralPath.java (curveTo): Set correct segment type.
+       (getPathIterator, GeneralPathIterator): Re-written from scratch.
+
+2003-10-21  Sascha Brawer  <brawer@dandelis.ch>
+
+       * java/awt/geom/GeneralPath.java (getCurrentPoint): Return last
+       point, not start of subpath.  Fixes Classpath bug #6075.
+
 2003-10-21  Michael Koch  <konqueror@gmx.de>
 
        * java/nio/ByteOrder.java,
index 6c1b578..05d98c7 100644 (file)
@@ -1,5 +1,5 @@
 /* GeneralPath.java -- represents a shape built from subpaths
-   Copyright (C) 2002 Free Software Foundation
+   Copyright (C) 2002, 2003 Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -128,7 +128,7 @@ public final class GeneralPath implements Shape, Cloneable
                       float x3, float y3)
   {
     ensureSize(index + 6);
-    types[index >> 1] = PathIterator.SEG_QUADTO;
+    types[index >> 1] = PathIterator.SEG_CUBICTO;
     points[index++] = x1;
     points[index++] = y1;
     points[index++] = x2;
@@ -148,40 +148,69 @@ public final class GeneralPath implements Shape, Cloneable
   {
     append(s.getPathIterator(null), connect);
   }
-  public void append(PathIterator i, boolean connect)
+
+
+  /**
+   * Appends the segments of a PathIterator to this GeneralPath.
+   * Optionally, the initial {@link PathIterator#SEG_MOVETO} segment
+   * of the appended path is changed into a {@link
+   * PathIterator#SEG_LINETO} segment.
+   *
+   * @param iter the PathIterator specifying which segments shall be
+   * appended.
+   * 
+   * @param connect <code>true</code> for substituting the initial
+   * {@link PathIterator#SEG_MOVETO} segment by a {@link
+   * PathIterator#SEG_LINETO}, or <code>false</code> for not
+   * performing any substitution. If this GeneralPath is currently
+   * empty, <code>connect</code> is assumed to be <code>false</code>,
+   * thus leaving the initial {@link PathIterator#SEG_MOVETO}
+   * unchanged.
+   */
+  public void append(PathIterator iter, boolean connect)
   {
+    // A bad implementation of this method had caused Classpath bug #6076.
     float[] f = new float[6];
-    while (! i.isDone())
+    while (!iter.isDone())
+    {
+      switch (iter.currentSegment(f))
       {
-        int result = i.currentSegment(f);
-        switch (result)
-          {
-          case PathIterator.SEG_MOVETO:
-            if (! connect)
-              {
-                moveTo(f[0], f[1]);
-                break;
-              }
-            if (subpath >= 0 && f[0] == points[subpath]
-                && f[1] == points[subpath + 1])
-              break;
-            // Fallthrough.
-          case PathIterator.SEG_LINETO:
-            lineTo(f[0], f[1]);
-            break;
-          case PathIterator.SEG_QUADTO:
-            quadTo(f[0], f[1], f[2], f[3]);
-            break;
-          case PathIterator.SEG_CUBICTO:
-            curveTo(f[0], f[1], f[2], f[3], f[4], f[5]);
-            break;
-          default:
-            closePath();
-          }
-        connect = false;
+      case PathIterator.SEG_MOVETO:
+        if (!connect || (index == 0))
+        {
+          moveTo(f[0], f[1]);
+          break;
+        }
+
+        if ((index >= 2) && (types[(index - 2) >> 2] == PathIterator.SEG_CLOSE)
+            && (f[0] == points[index - 2]) && (f[1] == points[index - 1]))
+          break;
+        
+        // Fall through.
+
+      case PathIterator.SEG_LINETO:
+        lineTo(f[0], f[1]);
+        break;
+
+      case PathIterator.SEG_QUADTO:
+        quadTo(f[0], f[1], f[2], f[3]);
+        break;
+
+      case PathIterator.SEG_CUBICTO:
+        curveTo(f[0], f[1], f[2], f[3], f[4], f[5]);
+        break;
+
+      case PathIterator.SEG_CLOSE:
+        closePath();
+        break;
       }
+
+      connect = false;
+      iter.next();
+    }
   }
 
+
   public int getWindingRule()
   {
     return rule;
@@ -197,7 +226,7 @@ public final class GeneralPath implements Shape, Cloneable
   {
     if (subpath < 0)
       return null;
-    return new Point2D.Float(points[subpath], points[subpath + 1]);
+    return new Point2D.Float(points[index - 2], points[index - 1]);
   }
   public void reset()
   {
@@ -254,80 +283,163 @@ public final class GeneralPath implements Shape, Cloneable
   {
     return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
   }
-  public PathIterator getPathIterator(final AffineTransform at)
+
+
+  /**
+   * A PathIterator that iterates over the segments of a GeneralPath.
+   *
+   * @author Sascha Brawer (brawer@dandelis.ch)
+   */
+  private static class GeneralPathIterator
+    implements PathIterator
   {
-    return new PathIterator()
+    /**
+     * The number of coordinate values for each segment type.
+     */
+    private static final int[] NUM_COORDS =
     {
-      int current = 0;
+      /* 0: SEG_MOVETO */ 2,
+      /* 1: SEG_LINETO */ 2,
+      /* 2: SEG_QUADTO */ 4,
+      /* 3: SEG_CUBICTO */ 6,
+      /* 4: SEG_CLOSE */ 0
+    };
 
-      public int getWindingRule()
-      {
-        return rule;
-      }
 
-      public boolean isDone()
-      {
-        return current >= index;
-      }
+    /**
+     * The GeneralPath whose segments are being iterated.
+     */
+    private final GeneralPath path;
 
-      public void next()
-      {
-        current++;
-      }
 
-      public int currentSegment(float[] coords)
+    /**
+     * The affine transformation used to transform coordinates.
+     */
+    private final AffineTransform transform;
+
+
+    /**
+     * The current position of the iterator.
+     */
+    private int pos;
+
+
+    /**
+     * Constructs a new iterator for enumerating the segments of a
+     * GeneralPath.
+     *
+     * @param at an affine transformation for projecting the returned
+     * points, or <code>null</code> to return the original points
+     * without any mapping.
+     */
+    GeneralPathIterator(GeneralPath path, AffineTransform transform)
+    {
+      this.path = path;
+      this.transform = transform;
+    }
+
+
+    /**
+     * Returns the current winding rule of the GeneralPath.
+     */
+    public int getWindingRule()
+    {
+      return path.rule;
+    }
+
+
+    /**
+     * Determines whether the iterator has reached the last segment in
+     * the path.
+     */
+    public boolean isDone()
+    {
+      return pos >= path.index;
+    }
+
+
+    /**
+     * Advances the iterator position by one segment.
+     */
+    public void next()
+    {
+      int seg;
+
+      /* Increment pos by the number of coordinate values. Note that
+       * we store two values even for a SEG_CLOSE segment, which is
+       * why we increment pos at least by 2. 
+       */
+      seg = path.types[pos >> 1];
+      if (seg == SEG_CLOSE)
+        pos += 2;
+      else
+        pos += NUM_COORDS[seg];
+    }
+
+
+    /**
+     * Returns the current segment in float coordinates.
+     */
+    public int currentSegment(float[] coords)
+    {
+      int seg, numCoords;
+
+      seg = path.types[pos >> 1];
+      numCoords = NUM_COORDS[seg];
+      if (numCoords > 0)
       {
-        if (current >= index)
-          return SEG_CLOSE;
-        int result = types[current >> 1];
-        int i = 0;
-        if (result == 3)
-          {
-            coords[i++] = points[current++];
-            coords[i++] = points[current++];
-          }
-        if (result == 2)
-          {
-            coords[i++] = points[current++];
-            coords[i++] = points[current++];
-          }
-        if (result < 2)
-          {
-            coords[i++] = points[current++];
-            coords[i++] = points[current++];
-            if (at != null)
-              at.transform(coords, 0, coords, 0, result == 0 ? 1 : result);
-          }
-        return result;
+        if (transform == null)
+          System.arraycopy(path.points, pos, coords, 0, numCoords);
+        else
+          transform.transform(/* src */ path.points, /* srcOffset */ pos,
+                              /* dest */ coords, /* destOffset */ 0,
+                              /* numPoints */ numCoords >> 1);
       }
+      return seg;
+    }
+
+
+    /**
+     * Returns the current segment in double coordinates.
+     */
+    public int currentSegment(double[] coords)
+    {
+      int seg, numCoords;
 
-      public int currentSegment(double[] coords)
+      seg = path.types[pos >> 1];
+      numCoords = NUM_COORDS[seg];
+      if (numCoords > 0)
       {
-        if (current >= index)
-          return SEG_CLOSE;
-        int result = types[current >> 1];
-        int i = 0;
-        if (result == 3)
-          {
-            coords[i++] = points[current++];
-            coords[i++] = points[current++];
-          }
-        if (result == 2)
-          {
-            coords[i++] = points[current++];
-            coords[i++] = points[current++];
-          }
-        if (result < 2)
-          {
-            coords[i++] = points[current++];
-            coords[i++] = points[current++];
-            if (at != null)
-              at.transform(coords, 0, coords, 0, result == 0 ? 1 : result);
-          }
-        return result;
+        if (transform == null)
+        {
+          // System.arraycopy throws an exception if the source and destination
+          // array are not of the same primitive type.
+          for (int i = 0; i < numCoords; i++)
+            coords[i] = (double) path.points[pos + i];
+        }
+        else
+          transform.transform(/* src */ path.points, /* srcOffset */ pos,
+                              /* dest */ coords, /* destOffset */ 0,
+                              /* numPoints */ numCoords >> 1);
       }
-    };
+      return seg;
+    }
+  }
+
+
+  /**
+   * Creates a PathIterator for iterating along the segments of this path.
+   *
+   * @param at an affine transformation for projecting the returned
+   * points, or <code>null</code> to let the created iterator return
+   * the original points without any mapping.
+   */
+  public PathIterator getPathIterator(AffineTransform at)
+  {
+    return new GeneralPathIterator(this, at);
   }
+
+
   public PathIterator getPathIterator(AffineTransform at, double flatness)
   {
     return new FlatteningPathIterator(getPathIterator(at), flatness);