Author: [EMAIL PROTECTED]
Date: Tue Nov  4 16:09:55 2008
New Revision: 404

Modified:
     
piccolo2d.java/trunk/extras/src/test/java/edu/umd/cs/piccolox/util/PFixedWidthStrokeMRO.java

Log:
issue#49 issue#48 - much more elegant plus delegates but also less robust  
(sic\!). Maybe we'll keep the previous version...

Modified:  
piccolo2d.java/trunk/extras/src/test/java/edu/umd/cs/piccolox/util/PFixedWidthStrokeMRO.java
==============================================================================
---  
piccolo2d.java/trunk/extras/src/test/java/edu/umd/cs/piccolox/util/PFixedWidthStrokeMRO.java
     
(original)
+++  
piccolo2d.java/trunk/extras/src/test/java/edu/umd/cs/piccolox/util/PFixedWidthStrokeMRO.java
     
Tue Nov  4 16:09:55 2008
@@ -32,7 +32,6 @@
  import java.awt.Stroke;
  import java.io.ObjectStreamException;
  import java.io.Serializable;
-import java.util.Arrays;

  import edu.umd.cs.piccolo.util.PDebug;
  import edu.umd.cs.piccolo.util.PPaintContext;
@@ -55,6 +54,10 @@
   * [EMAIL PROTECTED] BasicStroke} and therefore limited to a minimal 1.0 by 
this
   * implementation. A more sophisticated implementation might use the  
approach
   * mentioned at http://code.google.com/p/piccolo2d/issues/detail?id=49
+ * <p>
+ * <b>CAUTION!</b> after extreme scaling this implementation seems to  
change to
+ * internal state of the base stroke. Try PathExample with extreme zoom in  
and
+ * zoom back to the original scale. The pickable circles disappear.  
Strange!
   *
   * @see edu.umd.cs.piccolo.nodes.PPath
   * @see BasicStroke
@@ -74,32 +77,30 @@
      private static final long serialVersionUID = -2503357070350473610L;
      private static final double THRESHOLD = 1e-6;

-    private static int hashCode(final float[] array) {
-        final int prime = 31;
-        if (array == null) {
-            return 0;
-        }
-        int result = 1;
-        for (int index = 0; index < array.length; index++) {
-            result = prime * result + Float.floatToIntBits(array[index]);
-        }
-        return result;
-    }
-
-    private final int cap;
-    private final float dash[];
-    private final float dash_phase;
-    private final int join;
-    private final float miterlimit;
+    // avoid repeated cloning:
+    private transient final float dash[];
      private transient float recentScale;
-    private transient Stroke recentStroke;
+    // this could very well just be a mere Stroke in an abstract base class
+    // "PSemanticStroke":
+    private transient BasicStroke recentStroke;
+    // this could very well just be a mere Stroke in an abstract base class
+    // "PSemanticStroke":
+    private final BasicStroke stroke;
+    // avoid repeated instantiations:
      private transient final float tmpDash[];
-    private final float width;

      public PFixedWidthStrokeMRO() {
          this(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f,  
null, 0.0f);
      }

+    /** This should be "public" and the "main" constructor. */
+    private PFixedWidthStrokeMRO(final BasicStroke stroke) {
+        this.stroke = recentStroke = stroke;
+        recentScale = 1.0F;
+        dash = this.stroke.getDashArray();
+        tmpDash = dash == null ? null : new float[dash.length];
+    }
+
      public PFixedWidthStrokeMRO(final float width) {
          this(width, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f,  
null, 0.0f);
      }
@@ -114,16 +115,7 @@

      public PFixedWidthStrokeMRO(final float width, final int cap, final  
int join, final float miterlimit,
              final float dash[], final float dash_phase) {
-        this.width = width;
-        this.cap = cap;
-        this.join = join;
-        this.miterlimit = miterlimit;
-        this.dash = dash;
-        this.dash_phase = dash_phase;
-        // avoid instantiations at the cost of some bytes of memory:
-        tmpDash = this.dash == null ? null : new float[this.dash.length];
-        // Instantiate eagerly to benefit from ctor's argument checks.
-        recentStroke = newStroke(recentScale = 1.0F);
+        this(new BasicStroke(width, cap, join, miterlimit, dash,  
dash_phase));
      }

      public Object clone() {
@@ -174,55 +166,72 @@
              return false;
          }
          final PFixedWidthStrokeMRO other = (PFixedWidthStrokeMRO) obj;
-        if (cap != other.cap) {
-            return false;
-        }
-        if (!Arrays.equals(dash, other.dash)) {
-            return false;
-        }
-        if (Float.floatToIntBits(dash_phase) !=  
Float.floatToIntBits(other.dash_phase)) {
-            return false;
-        }
-        if (join != other.join) {
-            return false;
-        }
-        if (Float.floatToIntBits(miterlimit) !=  
Float.floatToIntBits(other.miterlimit)) {
-            return false;
+        if (stroke == null) {
+            if (other.stroke != null) {
+                return false;
+            }
          }
-        if (Float.floatToIntBits(width) !=  
Float.floatToIntBits(other.width)) {
+        else if (!stroke.equals(other.stroke)) {
              return false;
          }
          return true;
      }

+    public float[] getDashArray() {
+        return stroke.getDashArray();
+    }
+
+    public float getDashPhase() {
+        return stroke.getDashPhase();
+    }
+
+    public int getEndCap() {
+        return stroke.getEndCap();
+    }
+
+    public int getLineJoin() {
+        return stroke.getLineJoin();
+    }
+
+    public float getLineWidth() {
+        return stroke.getLineWidth();
+    }
+
+    public float getMiterLimit() {
+        return stroke.getMiterLimit();
+    }
+
      public int hashCode() {
          final int prime = 31;
          int result = 1;
-        result = prime * result + cap;
-        result = prime * result + PFixedWidthStrokeMRO.hashCode(dash);
-        result = prime * result + Float.floatToIntBits(dash_phase);
-        result = prime * result + join;
-        result = prime * result + Float.floatToIntBits(miterlimit);
-        result = prime * result + Float.floatToIntBits(width);
+        result = prime * result + (stroke == null ? 0 : stroke.hashCode());
          return result;
      }

      /**
       * Factory to create a new internal stroke delegate. Made protected to
       * enable custom re-implementations.
+     *
+     * @return could return a [EMAIL PROTECTED] Stroke} when defined in an 
abstract  
base
+     *         class.
       */
-    protected Stroke newStroke(final float scale) {
+    protected BasicStroke newStroke(final float scale) {
          if (tmpDash != null) {
              for (int i = dash.length - 1; i >= 0; i--) {
                  tmpDash[i] = dash[i] * scale;
              }
          }
-        final float ml = miterlimit * scale;
-        return new BasicStroke(width * scale, cap, join, ml < 1.0f ?  
1.0f : ml, tmpDash, dash_phase * scale);
+        final float ml = stroke.getMiterLimit() * scale;
+        return new BasicStroke(stroke.getLineWidth() * scale,  
stroke.getEndCap(), stroke.getLineJoin(),
+                ml < 1.0f ? 1.0f : ml, tmpDash, stroke.getDashPhase() *  
scale);
      }

      /** Is it really necessary to implement [EMAIL PROTECTED] Serializable}? 
*/
      protected Object readResolve() throws ObjectStreamException {
-        return new PFixedWidthStrokeMRO(width, cap, join, miterlimit,  
dash, dash_phase);
+        return new PFixedWidthStrokeMRO(stroke);
+    }
+
+    public String toString() {
+        return stroke.toString();
      }
  }

--~--~---------~--~----~------------~-------~--~----~
Piccolo2D Developers Group: http://groups.google.com/group/piccolo2d-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to