harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From apetre...@apache.org
Subject svn commit: r566713 - in /harmony/enhanced/classlib/trunk/modules/awt/src: main/java/common/java/awt/geom/ main/java/common/org/apache/harmony/awt/geom/ main/java/common/org/apache/harmony/awt/gl/ test/api/java/common/java/awt/geom/
Date Thu, 16 Aug 2007 13:44:20 GMT
Author: apetrenko
Date: Thu Aug 16 06:44:19 2007
New Revision: 566713

URL: http://svn.apache.org/viewvc?view=rev&rev=566713
Log:
Patch for HARMONY-4110 "[classlib][awt] The method java.awt.geom.Area.subtract() returns no
correct result when the first figure lies inside the second one"

Modified:
    harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/java/awt/geom/Area.java
    harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/geom/CrossingHelper.java
    harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/geom/GeometryUtil.java
    harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/gl/Crossing.java
    harmony/enhanced/classlib/trunk/modules/awt/src/test/api/java/common/java/awt/geom/AreaTest.java

Modified: harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/java/awt/geom/Area.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/java/awt/geom/Area.java?view=diff&rev=566713&r1=566712&r2=566713
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/java/awt/geom/Area.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/java/awt/geom/Area.java
Thu Aug 16 06:44:19 2007
@@ -241,27 +241,57 @@
 	}
 
 	public void add(Area area) {
+    	if (area == null || area.isEmpty()) {
+    	    return;
+    	} else if (isEmpty()) {
+    	    copy(area, this);
+    		return;
+    	}
+
 		if (isPolygonal() && area.isPolygonal()) {
 			addPolygon(area);
 		} else {
 			addCurvePolygon(area);
 		}
+		
+		if (getAreaBoundsSquare() < GeometryUtil.EPSILON) {
+		    reset();
+		}
 	}
 	   
 	public void intersect(Area area) {
+		if (area == null) {
+		    return;
+		} else if (isEmpty() || area.isEmpty()) {
+		    reset();
+			return;		
+		}
+		
 		if (isPolygonal() && area.isPolygonal()) {
 			intersectPolygon(area);
 		} else {
 			intersectCurvePolygon(area);
 		}
+		
+		if (getAreaBoundsSquare() < GeometryUtil.EPSILON) {
+		    reset();
+		}
 	}
 	
 	public void subtract(Area area) {
+		if (area == null || isEmpty() || area.isEmpty()) {
+		    return;
+		}
+
 		if (isPolygonal() && area.isPolygonal()) {
 			subtractPolygon(area);
 		} else {
 			subtractCurvePolygon(area);
 		}
+		
+		if (getAreaBoundsSquare() < GeometryUtil.EPSILON) {
+		    reset();
+		}
 	}
 	
  	public void exclusiveOr(Area area) {
@@ -441,8 +471,9 @@
             double[] coords = (isCurrentArea) ? this.coords : area.coords;
             int offset = 2 * point.getEndIndex(isCurrentArea);
  
-            if (nextPoint.getBegIndex(isCurrentArea) < 
-            		point.getEndIndex(isCurrentArea)) {
+            if ((offset >= 0) && 
+            	    (nextPoint.getBegIndex(isCurrentArea) < 
+            		    point.getEndIndex(isCurrentArea))) {
                 int coordSize = (isCurrentArea) ? this.coordsSize : 
                 	                              area.coordsSize;
                 int length = coordSize - offset;
@@ -458,14 +489,16 @@
                 offset = 0;
             }
             
-            int length = 2 * nextPoint.getBegIndex(isCurrentArea) - offset + 2;
-            System.arraycopy(coords, offset, 
-            		         resultCoords, resultCoordPos, length);
-            
-            for (int i = 0; i < length / 2; i++) {
-            	resultRules[resultRulesPos] = PathIterator.SEG_LINETO;
-            	resultOffsets[resultRulesPos++] = resultCoordPos;
-            	resultCoordPos += 2;
+            if (offset >= 0) {
+                int length = 2 * nextPoint.getBegIndex(isCurrentArea) - offset + 2;
+                System.arraycopy(coords, offset, 
+            		             resultCoords, resultCoordPos, length);
+            
+                for (int i = 0; i < length / 2; i++) {
+            	    resultRules[resultRulesPos] = PathIterator.SEG_LINETO;
+            	    resultOffsets[resultRulesPos++] = resultCoordPos;
+            	    resultCoordPos += 2;
+                }
             }
 
             point = nextPoint;
@@ -814,21 +847,26 @@
 				                                        area.coordsSize });
 		IntersectPoint[] intersectPoints = crossHelper.findCrossing();
 
-		if ((intersectPoints.length == 0) && (contains(area.getBounds2D()))) {
-			copy(area, this);
-			return;
-		} 
+		if (intersectPoints.length == 0) {
+		    if (contains(area.getBounds2D())) {
+		        copy(area, this);
+		        return;
+			} 
+		    return;
+		}
 
-        double[] resultCoords = new double[coordsSize + area.coordsSize + 
-                                                       intersectPoints.length];
-        int[] resultRules = new int[rulesSize + area.rulesSize + 
-                                                       intersectPoints.length];
-        int[] resultOffsets = new int[rulesSize + area.rulesSize + 
-                                                       intersectPoints.length];
+        double[] resultCoords = new double[2 * (coordsSize + area.coordsSize + 
+                                                       intersectPoints.length)];
+        int[] resultRules = new int[2 * (rulesSize + area.rulesSize + 
+                                                       intersectPoints.length)];
+        int[] resultOffsets = new int[2 * (rulesSize + area.rulesSize + 
+                                                       intersectPoints.length)];
         int resultCoordPos = 0;
         int resultRulesPos = 0;
         boolean isCurrentArea = true;
-        int count = 0;
+        int countPoints = 0;
+        boolean curArea = false;
+        boolean addArea = false;
 
         IntersectPoint point = intersectPoints[0];
         resultRules[resultRulesPos] = PathIterator.SEG_MOVETO;
@@ -842,8 +880,11 @@
             int curIndex = point.getEndIndex(true);
             
             if ((curIndex < 0) || 
-            	(area.containsExact(coords[2 * curIndex], 
-            			            coords[2 * curIndex + 1]) > 0)) {
+            		(area.isVertex(coords[2 * curIndex], coords[2 * curIndex + 1]) && 
+            		     crossHelper.containsPoint(new double[] {coords[2 * curIndex], 
+            				                       coords[2 * curIndex + 1]}) && 
+            		(coords[2 * curIndex] != point.getX() || 
+            			 coords[2 * curIndex + 1] != point.getY()))) {
             	isCurrentArea = !isCurrentArea;
             } else if (area.containsExact(coords[2 * curIndex], 
             		                      coords[2 * curIndex + 1]) > 0) { 
@@ -851,6 +892,16 @@
             } else {
             	isCurrentArea = true;
             }
+            
+            if (countPoints >= intersectPoints.length) {
+                isCurrentArea = !isCurrentArea;
+            }
+            	 
+            if (isCurrentArea) {
+                curArea = true;
+            } else {
+                addArea = true;
+            }
 
             IntersectPoint nextPoint = (isCurrentArea) ? 
             		getNextIntersectPoint(intersectPoints, point, isCurrentArea):
@@ -916,27 +967,22 @@
             }
 
             point = nextPoint;
-            count++;
-        } while (point != intersectPoints[0] && count <= intersectPoints.length);
+            countPoints++;
+        } while (point != intersectPoints[0] || !(curArea && addArea));
         
-        if (count > intersectPoints.length) {
-        	reset();
-        } else {
-            resultRules[resultRulesPos - 1] = PathIterator.SEG_CLOSE;
-            resultOffsets[resultRulesPos - 1] = resultCoordPos;
-		    coords = resultCoords;
-		    rules = resultRules;
-		    offsets = resultOffsets;
-		    coordsSize = resultCoordPos;
-		    rulesSize = resultRulesPos;
-        }
+        resultRules[resultRulesPos - 1] = PathIterator.SEG_CLOSE;
+        resultOffsets[resultRulesPos - 1] = resultCoordPos;
+	    coords = resultCoords;
+	    rules = resultRules;
+	    offsets = resultOffsets;
+	    coordsSize = resultCoordPos;
+	    rulesSize = resultRulesPos;
 	}
 	
-	   private IntersectPoint getNextIntersectPoint(IntersectPoint[] iPoints,
+	private IntersectPoint getNextIntersectPoint(IntersectPoint[] iPoints,
 			                                        IntersectPoint isectPoint, 
 			                                        boolean isCurrentArea) {
-		   
-		int endIndex = isectPoint.getEndIndex(isCurrentArea);
+	    int endIndex = isectPoint.getEndIndex(isCurrentArea);
 		if (endIndex < 0) {
 			return iPoints[Math.abs(endIndex) - 1];
 		}
@@ -1227,6 +1273,20 @@
     	}
     }
     
+    private double getAreaBoundsSquare() {
+        Rectangle2D bounds = getBounds2D();
+        return bounds.getHeight() * bounds.getWidth();
+    }
+
+    private boolean isVertex(double x, double y) {
+        for (int i = 0; i < coordsSize;) {
+    	    if (x == coords[i++] && y == coords[i++]) {
+    		    return true;
+    		}
+    	}
+    	return false;
+    }
+
     // the internal class implements PathIterator
 	private class AreaPathIterator implements PathIterator {
 

Modified: harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/geom/CrossingHelper.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/geom/CrossingHelper.java?view=diff&rev=566713&r1=566712&r2=566713
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/geom/CrossingHelper.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/geom/CrossingHelper.java
Thu Aug 16 06:44:19 2007
@@ -284,7 +284,7 @@
         }
     }
     
-    private boolean containsPoint(double[] point) {
+    public boolean containsPoint(double[] point) {
     	IntersectPoint ipoint;
     	
     	for (Iterator i = isectPoints.iterator(); i.hasNext(); ) {

Modified: harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/geom/GeometryUtil.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/geom/GeometryUtil.java?view=diff&rev=566713&r1=566712&r2=566713
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/geom/GeometryUtil.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/geom/GeometryUtil.java
Thu Aug 16 06:44:19 2007
@@ -19,7 +19,7 @@
 import org.apache.harmony.awt.gl.Crossing;
 
 public class GeometryUtil {
-    static final double EPSILON = Math.pow(10, -15);
+    public static final double EPSILON = Math.pow(10, -14);
 
     public static int intersectLinesWithParams(double x1, double y1, double x2, double y2,
                                                double x3, double y3, double x4, double y4,

Modified: harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/gl/Crossing.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/gl/Crossing.java?view=diff&rev=566713&r1=566712&r2=566713
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/gl/Crossing.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/awt/src/main/java/common/org/apache/harmony/awt/gl/Crossing.java
Thu Aug 16 06:44:19 2007
@@ -382,9 +382,14 @@
             }
         }
 
-        // START or END
-        if (x == x1 || x == x2) {
-            return 0;
+        // START
+        if (x == x1) {
+        	return x1 < x2 ? 0 : -1;        
+        }
+        
+        // END
+        if (x == x2) {
+        	return x1 < x2 ? 1 : 0;        
         }
 
         // INSIDE-DOWN
@@ -486,6 +491,13 @@
                     cross += crossLine(cx, cy, cx = mx, cy = my, x, y);
                 }
                 break;
+            }
+            
+            // checks if the point (x,y) is the vertex of shape with PathIterator p     
     
+            if (x == cx && y == cy) {
+            	cross = 0;
+            	cy = my;
+            	break;
             }
             p.next();
         }

Modified: harmony/enhanced/classlib/trunk/modules/awt/src/test/api/java/common/java/awt/geom/AreaTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/awt/src/test/api/java/common/java/awt/geom/AreaTest.java?view=diff&rev=566713&r1=566712&r2=566713
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/awt/src/test/api/java/common/java/awt/geom/AreaTest.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/awt/src/test/api/java/common/java/awt/geom/AreaTest.java
Thu Aug 16 06:44:19 2007
@@ -174,6 +174,24 @@
          checkPathRule(path, PathIterator.WIND_EVEN_ODD);
          checkPathDone(path, true);
      }
+     
+     public void testSubtract() {
+         // Regression test HARMONY-4410
+ 		Rectangle2D rect1 = new Rectangle2D.Double(300, 300, 200, 150);
+		Rectangle2D rect2 = new Rectangle2D.Double(350, 200, 300, 150);
+
+		Area area1 = new Area(rect1);
+		Area area2 = new Area(rect2);
+
+		Area a = (Area) area1.clone();
+		a.intersect(area2);
+		area1.add(area2);
+		area1.subtract(a);
+		
+		assertFalse(area1.contains(375, 325));
+		assertTrue(area1.contains(600, 300));
+		assertTrue(area1.contains(325, 325));
+     }
 
     public static void main(String[] args) {
         junit.textui.TestRunner.run(AreaTest.class);



Mime
View raw message