diff --git a/build.xml b/build.xml index 817ea0c..db297a6 100644 --- a/build.xml +++ b/build.xml @@ -41,6 +41,7 @@ + @@ -63,9 +64,7 @@ - - - + @@ -91,8 +90,9 @@ - + + diff --git a/src/main/java/pythagoras/Pythagoras.gwt.xml b/src/main/java/pythagoras/Pythagoras.gwt.xml index 9ce0b8a..398ee65 100644 --- a/src/main/java/pythagoras/Pythagoras.gwt.xml +++ b/src/main/java/pythagoras/Pythagoras.gwt.xml @@ -3,4 +3,5 @@ + diff --git a/src/main/java/pythagoras/d/AbstractDimension.java b/src/main/java/pythagoras/d/AbstractDimension.java index c0ff06e..3c12e43 100644 --- a/src/main/java/pythagoras/d/AbstractDimension.java +++ b/src/main/java/pythagoras/d/AbstractDimension.java @@ -4,6 +4,8 @@ package pythagoras.d; +import pythagoras.util.Platform; + /** * Provides most of the implementation of {@link IDimension}, obtaining only width and height from * the derived class. @@ -17,8 +19,8 @@ public abstract class AbstractDimension implements IDimension @Override public int hashCode () { - long bits = Double.doubleToLongBits(getWidth()); - bits += Double.doubleToLongBits(getHeight()) * 37; + long bits = Platform.hashCode(getWidth()); + bits += Platform.hashCode(getHeight()) * 37; return (((int) bits) ^ ((int) (bits >> 32))); } diff --git a/src/main/java/pythagoras/d/AbstractPoint.java b/src/main/java/pythagoras/d/AbstractPoint.java index ab7a71c..116be02 100644 --- a/src/main/java/pythagoras/d/AbstractPoint.java +++ b/src/main/java/pythagoras/d/AbstractPoint.java @@ -4,6 +4,8 @@ package pythagoras.d; +import pythagoras.util.Platform; + /** * Provides most of the implementation of {@link IPoint}, obtaining only the location from the * derived class. @@ -49,9 +51,7 @@ public abstract class AbstractPoint implements IPoint @Override public int hashCode () { - long bits = Double.doubleToLongBits(getX()); - bits += Double.doubleToLongBits(getY()) * 37; - return (((int) bits) ^ ((int) (bits >> 32))); + return Platform.hashCode(getX()) ^ Platform.hashCode(getY()); } @Override diff --git a/src/main/java/pythagoras/d/AbstractRectangle.java b/src/main/java/pythagoras/d/AbstractRectangle.java index 6c8a8d8..de38ec9 100644 --- a/src/main/java/pythagoras/d/AbstractRectangle.java +++ b/src/main/java/pythagoras/d/AbstractRectangle.java @@ -6,6 +6,8 @@ package pythagoras.d; import java.util.NoSuchElementException; +import pythagoras.util.Platform; + /** * Provides most of the implementation of {@link IRectangle}, obtaining only the location and * dimensions from the derived class. @@ -151,11 +153,8 @@ public abstract class AbstractRectangle extends RectangularShape implements IRec @Override // from Object public int hashCode () { - long bits = Double.doubleToLongBits(getX()); - bits += Double.doubleToLongBits(getY()) * 37; - bits += Double.doubleToLongBits(getWidth()) * 43; - bits += Double.doubleToLongBits(getHeight()) * 47; - return (((int) bits) ^ ((int) (bits >> 32))); + return Platform.hashCode(getX()) ^ Platform.hashCode(getY()) ^ + Platform.hashCode(getWidth()) ^ Platform.hashCode(getHeight()); } @Override // from Object diff --git a/src/main/java/pythagoras/d/AffineTransform.java b/src/main/java/pythagoras/d/AffineTransform.java index 5f87e49..4e7fccf 100644 --- a/src/main/java/pythagoras/d/AffineTransform.java +++ b/src/main/java/pythagoras/d/AffineTransform.java @@ -6,6 +6,8 @@ package pythagoras.d; import java.io.Serializable; +import pythagoras.util.Platform; + /** * Represents a 2D affine transform, which performs a linear mapping that preserves the * straightness and parallelness of lines. @@ -437,24 +439,17 @@ public class AffineTransform implements Cloneable, Serializable "[[" + m00 + ", " + m01 + ", " + m02 + "], [" + m10 + ", " + m11 + ", " + m12 + "]]"; } - @Override + // @Override // can't declare @Override due to GWT public AffineTransform clone () { - try { - return (AffineTransform)super.clone(); - } catch (CloneNotSupportedException e) { - throw new InternalError(); - } + AffineTransform xform = new AffineTransform(m00, m01, m02, m10, m11, m12); + xform.type = this.type; + return xform; } @Override public int hashCode () { - long bits = Double.doubleToLongBits(m00); - bits += Double.doubleToLongBits(m01) * 37; - bits += Double.doubleToLongBits(m02) * 43; - bits += Double.doubleToLongBits(m10) * 47; - bits += Double.doubleToLongBits(m11) * 53; - bits += Double.doubleToLongBits(m12) * 59; - return (((int) bits) ^ ((int) (bits >> 32))); + return Platform.hashCode(m00) ^ Platform.hashCode(m01) ^ Platform.hashCode(m02) ^ + Platform.hashCode(m10) ^ Platform.hashCode(m11) ^ Platform.hashCode(m12); } @Override diff --git a/src/main/java/pythagoras/d/Area.java b/src/main/java/pythagoras/d/Area.java index 6cf105d..3ad915a 100644 --- a/src/main/java/pythagoras/d/Area.java +++ b/src/main/java/pythagoras/d/Area.java @@ -6,6 +6,8 @@ package pythagoras.d; import java.util.NoSuchElementException; +import pythagoras.util.Platform; + /** * Stores and manipulates an enclosed area of 2D space. * See http://download.oracle.com/javase/6/docs/api/java/awt/geom/Area.html @@ -277,7 +279,7 @@ public class Area implements IShape, Cloneable return area.isEmpty(); } - @Override // from Cloneable + // @Override // can't declare @Override due to GWT public Area clone () { Area area = new Area(); copy(this, area); @@ -1038,11 +1040,11 @@ public class Area implements IShape, Cloneable private void copy (Area src, Area dst) { dst.coordsSize = src.coordsSize; - dst.coords = src.coords.clone(); + dst.coords = Platform.clone(src.coords); dst.rulesSize = src.rulesSize; - dst.rules = src.rules.clone(); + dst.rules = Platform.clone(src.rules); dst.moveToCount = src.moveToCount; - dst.offsets = src.offsets.clone(); + dst.offsets = Platform.clone(src.offsets); } private int containsExact (double x, double y) { diff --git a/src/main/java/pythagoras/d/Path.java b/src/main/java/pythagoras/d/Path.java index b1f5fc9..1b7c910 100644 --- a/src/main/java/pythagoras/d/Path.java +++ b/src/main/java/pythagoras/d/Path.java @@ -6,6 +6,8 @@ package pythagoras.d; import java.util.NoSuchElementException; +import pythagoras.util.Platform; + /** * Represents a path constructed from lines and curves and which can contain subpaths. */ @@ -248,16 +250,9 @@ public final class Path implements IShape, Cloneable return new FlatteningPathIterator(getPathIterator(t), flatness); } - @Override + // @Override // can't declare @Override due to GWT public Path clone () { - try { - Path p = (Path)super.clone(); - p.types = types.clone(); - p.points = points.clone(); - return p; - } catch (CloneNotSupportedException e) { - throw new InternalError(); - } + return new Path(rule, Platform.clone(types), Platform.clone(points), typeSize, pointSize); } /** @@ -293,6 +288,14 @@ public final class Path implements IShape, Cloneable Crossing.isInsideEvenOdd(cross); } + private Path (int rule, byte[] types, double[] points, int typeSize, int pointSize) { + this.types = types; + this.points = points; + this.typeSize = typeSize; + this.pointSize = pointSize; + setWindingRule(rule); + } + /** An iterator over a {@link Path}. */ protected static class Iterator implements PathIterator { diff --git a/src/main/java/pythagoras/f/AbstractDimension.java b/src/main/java/pythagoras/f/AbstractDimension.java index 69b7c08..f089519 100644 --- a/src/main/java/pythagoras/f/AbstractDimension.java +++ b/src/main/java/pythagoras/f/AbstractDimension.java @@ -4,6 +4,8 @@ package pythagoras.f; +import pythagoras.util.Platform; + /** * Provides most of the implementation of {@link IDimension}, obtaining only width and height from * the derived class. @@ -17,7 +19,7 @@ public abstract class AbstractDimension implements IDimension @Override public int hashCode () { - return Float.floatToIntBits(getWidth()) ^ Float.floatToIntBits(getHeight()); + return Platform.hashCode(getWidth()) ^ Platform.hashCode(getHeight()); } @Override diff --git a/src/main/java/pythagoras/f/AbstractPoint.java b/src/main/java/pythagoras/f/AbstractPoint.java index 2ac8ea6..5066483 100644 --- a/src/main/java/pythagoras/f/AbstractPoint.java +++ b/src/main/java/pythagoras/f/AbstractPoint.java @@ -4,6 +4,8 @@ package pythagoras.f; +import pythagoras.util.Platform; + /** * Provides most of the implementation of {@link IPoint}, obtaining only the location from the * derived class. @@ -49,7 +51,7 @@ public abstract class AbstractPoint implements IPoint @Override public int hashCode () { - return Float.floatToIntBits(getX()) ^ Float.floatToIntBits(getY()); + return Platform.hashCode(getX()) ^ Platform.hashCode(getY()); } @Override diff --git a/src/main/java/pythagoras/f/AbstractRectangle.java b/src/main/java/pythagoras/f/AbstractRectangle.java index c0a8884..6234c9b 100644 --- a/src/main/java/pythagoras/f/AbstractRectangle.java +++ b/src/main/java/pythagoras/f/AbstractRectangle.java @@ -6,6 +6,8 @@ package pythagoras.f; import java.util.NoSuchElementException; +import pythagoras.util.Platform; + /** * Provides most of the implementation of {@link IRectangle}, obtaining only the location and * dimensions from the derived class. @@ -151,8 +153,8 @@ public abstract class AbstractRectangle extends RectangularShape implements IRec @Override // from Object public int hashCode () { - return Float.floatToIntBits(getX()) ^ Float.floatToIntBits(getY()) ^ - Float.floatToIntBits(getWidth()) ^ Float.floatToIntBits(getHeight()); + return Platform.hashCode(getX()) ^ Platform.hashCode(getY()) ^ + Platform.hashCode(getWidth()) ^ Platform.hashCode(getHeight()); } @Override // from Object diff --git a/src/main/java/pythagoras/f/AffineTransform.java b/src/main/java/pythagoras/f/AffineTransform.java index 34f8a12..226d93d 100644 --- a/src/main/java/pythagoras/f/AffineTransform.java +++ b/src/main/java/pythagoras/f/AffineTransform.java @@ -6,6 +6,8 @@ package pythagoras.f; import java.io.Serializable; +import pythagoras.util.Platform; + /** * Represents a 2D affine transform, which performs a linear mapping that preserves the * straightness and parallelness of lines. @@ -436,19 +438,17 @@ public class AffineTransform implements Cloneable, Serializable "[[" + m00 + ", " + m01 + ", " + m02 + "], [" + m10 + ", " + m11 + ", " + m12 + "]]"; } - @Override + // @Override // can't declare @Override due to GWT public AffineTransform clone () { - try { - return (AffineTransform)super.clone(); - } catch (CloneNotSupportedException e) { - throw new InternalError(); - } + AffineTransform xform = new AffineTransform(m00, m01, m02, m10, m11, m12); + xform.type = this.type; + return xform; } @Override public int hashCode () { - return Float.floatToIntBits(m00) ^ Float.floatToIntBits(m01) ^ Float.floatToIntBits(m02) ^ - Float.floatToIntBits(m10) ^ Float.floatToIntBits(m11) ^ Float.floatToIntBits(m12); + return Platform.hashCode(m00) ^ Platform.hashCode(m01) ^ Platform.hashCode(m02) ^ + Platform.hashCode(m10) ^ Platform.hashCode(m11) ^ Platform.hashCode(m12); } @Override diff --git a/src/main/java/pythagoras/f/Area.java b/src/main/java/pythagoras/f/Area.java index df1d0a7..b3ec4cd 100644 --- a/src/main/java/pythagoras/f/Area.java +++ b/src/main/java/pythagoras/f/Area.java @@ -6,6 +6,8 @@ package pythagoras.f; import java.util.NoSuchElementException; +import pythagoras.util.Platform; + /** * Stores and manipulates an enclosed area of 2D space. * See http://download.oracle.com/javase/6/docs/api/java/awt/geom/Area.html @@ -277,7 +279,7 @@ public class Area implements IShape, Cloneable return area.isEmpty(); } - @Override // from Cloneable + // @Override // can't declare @Override due to GWT public Area clone () { Area area = new Area(); copy(this, area); @@ -1038,11 +1040,11 @@ public class Area implements IShape, Cloneable private void copy (Area src, Area dst) { dst.coordsSize = src.coordsSize; - dst.coords = src.coords.clone(); + dst.coords = Platform.clone(src.coords); dst.rulesSize = src.rulesSize; - dst.rules = src.rules.clone(); + dst.rules = Platform.clone(src.rules); dst.moveToCount = src.moveToCount; - dst.offsets = src.offsets.clone(); + dst.offsets = Platform.clone(src.offsets); } private int containsExact (float x, float y) { diff --git a/src/main/java/pythagoras/f/Path.java b/src/main/java/pythagoras/f/Path.java index 28ced8c..b8030a2 100644 --- a/src/main/java/pythagoras/f/Path.java +++ b/src/main/java/pythagoras/f/Path.java @@ -6,6 +6,8 @@ package pythagoras.f; import java.util.NoSuchElementException; +import pythagoras.util.Platform; + /** * Represents a path constructed from lines and curves and which can contain subpaths. */ @@ -248,16 +250,9 @@ public final class Path implements IShape, Cloneable return new FlatteningPathIterator(getPathIterator(t), flatness); } - @Override + // @Override // can't declare @Override due to GWT public Path clone () { - try { - Path p = (Path)super.clone(); - p.types = types.clone(); - p.points = points.clone(); - return p; - } catch (CloneNotSupportedException e) { - throw new InternalError(); - } + return new Path(rule, Platform.clone(types), Platform.clone(points), typeSize, pointSize); } /** @@ -293,6 +288,14 @@ public final class Path implements IShape, Cloneable Crossing.isInsideEvenOdd(cross); } + private Path (int rule, byte[] types, float[] points, int typeSize, int pointSize) { + this.types = types; + this.points = points; + this.typeSize = typeSize; + this.pointSize = pointSize; + setWindingRule(rule); + } + /** An iterator over a {@link Path}. */ protected static class Iterator implements PathIterator { diff --git a/src/main/java/pythagoras/util/Platform.java b/src/main/java/pythagoras/util/Platform.java new file mode 100644 index 0000000..9576e7b --- /dev/null +++ b/src/main/java/pythagoras/util/Platform.java @@ -0,0 +1,54 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.util; + +/** + * Handles differences between the JDK and GWT platforms. + */ +public class Platform +{ + /** + * Returns a hash code for the supplied float value. + */ + public static int hashCode (float f1) { + return Float.floatToIntBits(f1); + } + + /** + * Returns a hash code for the supplied double value. + */ + public static int hashCode (double d1) { + long bits = Double.doubleToLongBits(d1); + return (int)(bits ^ (bits >>> 32)); + } + + /** + * Clones the supplied array of bytes. + */ + public static byte[] clone (byte[] values) { + return values.clone(); + } + + /** + * Clones the supplied array of ints. + */ + public static int[] clone (int[] values) { + return values.clone(); + } + + /** + * Clones the supplied array of floats. + */ + public static float[] clone (float[] values) { + return values.clone(); + } + + /** + * Clones the supplied array of doubles. + */ + public static double[] clone (double[] values) { + return values.clone(); + } +} diff --git a/src/main/resources/pythagoras/util/Platform.java b/src/main/resources/pythagoras/util/Platform.java new file mode 100644 index 0000000..e916471 --- /dev/null +++ b/src/main/resources/pythagoras/util/Platform.java @@ -0,0 +1,63 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.util; + +/** + * A platform instance that's used when running in GWT. Note that this is copied over top of the + * JDK implementation in the pythagoras.jar file, so this is never actually compiled to bytecode. + * Thus be careful when making changes to this file. + */ +public class Platform +{ + /** + * Returns a hash code for the supplied float value. + */ + public static int hashCode (float f1) { + return (int)f1; // alas nothing better can be done in JavaScript + } + + /** + * Returns a hash code for the supplied double value. + */ + public static int hashCode (double d1) { + return (int)d1; // alas nothing better can be done in JavaScript + } + + /** + * Clones the supplied array of bytes. + */ + public static byte[] clone (byte[] values) { + byte[] nvalues = new byte[values.length]; + System.arraycopy(values, 0, nvalues, 0, values.length); + return nvalues; + } + + /** + * Clones the supplied array of ints. + */ + public static int[] clone (int[] values) { + int[] nvalues = new int[values.length]; + System.arraycopy(values, 0, nvalues, 0, values.length); + return nvalues; + } + + /** + * Clones the supplied array of floats. + */ + public static float[] clone (float[] values) { + float[] nvalues = new float[values.length]; + System.arraycopy(values, 0, nvalues, 0, values.length); + return nvalues; + } + + /** + * Clones the supplied array of doubles. + */ + public static double[] clone (double[] values) { + double[] nvalues = new double[values.length]; + System.arraycopy(values, 0, nvalues, 0, values.length); + return nvalues; + } +}