Hi,

This patch implements better support for negative extents in the Arc2D
iterator.  Before, we simply reversed the arc so that the extent would
always be positive; however this causes problems when the arc is apart
of a larger shape.  Now, the iterator handles negative extents without
the reversing trick.

Cheers,
Francis


2006-12-05  Francis Kung  <[EMAIL PROTECTED]>

        * java/awt/BasicStroke.java
        (capEnd): Prevent division by zero.
        * java/awt/geom/Arc2D.java
        (ArcIterator.ArcIterator): Do not shift the arc to make the extent
positive.
        (ArcIterator.currentSegment): Handle a negative extent.

Index: java/awt/BasicStroke.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/BasicStroke.java,v
retrieving revision 1.17
diff -u -r1.17 BasicStroke.java
--- java/awt/BasicStroke.java	4 Aug 2006 22:03:24 -0000	1.17
+++ java/awt/BasicStroke.java	5 Dec 2006 20:36:49 -0000
@@ -761,9 +761,13 @@
         p1 = new double[]{a.last.P2.getX(), a.last.P2.getY()};
         dx = p1[0] - p0[0];
         dy = p1[1] - p0[1];
-        l = Math.sqrt(dx * dx + dy * dy);
-        dx = (2.0/3.0)*width*dx/l;
-        dy = (2.0/3.0)*width*dy/l;
+        if (dx != 0 && dy != 0)
+          {
+            l = Math.sqrt(dx * dx + dy * dy);
+            dx = (2.0/3.0)*width*dx/l;
+            dy = (2.0/3.0)*width*dy/l;
+          }
+        
         c1 = new Point2D.Double(p1[0] + dx, p1[1] + dy);
         c2 = new Point2D.Double(b.P1.getX() + dx, b.P1.getY() + dy);
         a.add(new CubicSegment(a.last.P2, c1, c2, b.P1));
Index: java/awt/geom/Arc2D.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/geom/Arc2D.java,v
retrieving revision 1.12
diff -u -r1.12 Arc2D.java
--- java/awt/geom/Arc2D.java	2 Jul 2005 20:32:29 -0000	1.12
+++ java/awt/geom/Arc2D.java	5 Dec 2006 20:36:49 -0000
@@ -774,14 +774,9 @@
       y = a.getY();
       w = a.getWidth();
       h = a.getHeight();
-      double start = a.getAngleStart() * (Math.PI / 180);
-      double extent = a.getAngleExtent() * (Math.PI / 180);
+      double start = Math.toRadians(a.getAngleStart());
+      double extent = Math.toRadians(a.getAngleExtent());
 
-      if (extent < 0)
-        {
-	  extent = -extent;
-	  start = 2 * Math.PI - extent + start;
-        }
       this.start = start;
       this.extent = extent;
 
@@ -790,11 +785,11 @@
 	limit = -1;
       else if (extent == 0)
 	limit = type;
-      else if (extent <= Math.PI / 2.0)
+      else if (Math.abs(extent) <= Math.PI / 2.0)
 	limit = type + 1;
-      else if (extent <= Math.PI)
+      else if (Math.abs(extent) <= Math.PI)
 	limit = type + 2;
-      else if (extent <= 3.0 * (Math.PI / 2.0))
+      else if (Math.abs(extent) <= 3.0 * (Math.PI / 2.0))
 	limit = type + 3;
       else
 	limit = type + 4;
@@ -909,9 +904,20 @@
       double kappa = (Math.sqrt(2.0) - 1.0) * (4.0 / 3.0);
       double quad = (Math.PI / 2.0);
 
-      double curr_begin = start + (current - 1) * quad;
-      double curr_extent = Math.min((start + extent) - curr_begin, quad);
-      double portion_of_a_quadrant = curr_extent / quad;
+      double curr_begin;
+      double curr_extent;
+      if (extent > 0)
+        {
+          curr_begin = start + (current - 1) * quad;
+          curr_extent = Math.min((start + extent) - curr_begin, quad);
+        }
+      else
+        {
+          curr_begin = start - (current - 1) * quad;
+          curr_extent = Math.max((start + extent) - curr_begin, -quad);
+        }
+      
+      double portion_of_a_quadrant = Math.abs(curr_extent / quad);
 
       double x0 = xmid + rx * Math.cos(curr_begin);
       double y0 = ymid - ry * Math.sin(curr_begin);
@@ -932,7 +938,11 @@
       // will *subtract* the y value of this control vector from our first
       // point.
       cvec[0] = 0;
-      cvec[1] = len;
+      if (extent > 0)
+        cvec[1] = len;
+      else
+        cvec[1] = -len;
+      
       trans.scale(rx, ry);
       trans.rotate(angle);
       trans.transform(cvec, 0, cvec, 0, 1);
@@ -942,7 +952,11 @@
       // control vector #2 would, ideally, be sticking out and to the
       // right, in a first quadrant arc segment. again, subtraction of y.
       cvec[0] = 0;
-      cvec[1] = -len;
+      if (extent > 0)
+        cvec[1] = -len;
+      else
+        cvec[1] = len;
+      
       trans.rotate(curr_extent);
       trans.transform(cvec, 0, cvec, 0, 1);
       coords[2] = x1 + cvec[0];

Reply via email to