< prev index next >

openjfx9/modules/javafx.graphics/src/main/java/com/sun/javafx/geom/Path2D.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -24,10 +24,11 @@
  */
 
 package com.sun.javafx.geom;
 
 import com.sun.javafx.geom.transform.BaseTransform;
+import java.util.Arrays;
 
 /**
  * The {@code Path2D} class provides a simple, yet flexible
  * shape which represents an arbitrary geometric path.
  * It can fully represent any path which can be iterated by the

@@ -99,10 +100,11 @@
     int numCoords;
     int windingRule;
 
     static final int INIT_SIZE = 20;
     static final int EXPAND_MAX = 500;
+    static final int EXPAND_MAX_COORDS = EXPAND_MAX * 2;
 
     float floatCoords[];
     float moveX, moveY;
     float prevX, prevY;
     float currX, currY;

@@ -174,17 +176,14 @@
     public Path2D(Shape s, BaseTransform tx) {
         if (s instanceof Path2D) {
             Path2D p2d = (Path2D) s;
             setWindingRule(p2d.windingRule);
             this.numTypes = p2d.numTypes;
-            //this.pointTypes = Arrays.copyOf(p2d.pointTypes,
-            //                                p2d.pointTypes.length); // jk16 dependency
-            this.pointTypes = copyOf(p2d.pointTypes,
-                                            p2d.pointTypes.length);
+            this.pointTypes = Arrays.copyOf(p2d.pointTypes, numTypes);
             this.numCoords = p2d.numCoords;
             if (tx == null || tx.isIdentity()) {
-                this.floatCoords = copyOf(p2d.floatCoords, numCoords);
+                this.floatCoords = Arrays.copyOf(p2d.floatCoords, numCoords);
                 this.moveX = p2d.moveX;
                 this.moveY = p2d.moveY;
                 this.prevX = p2d.prevX;
                 this.prevY = p2d.prevY;
                 this.currX = p2d.currX;

@@ -334,36 +333,96 @@
         }
         return false;
     }
 
     void needRoom(boolean needMove, int newCoords) {
-        if (needMove && numTypes == 0) {
+        if (needMove && (numTypes == 0)) {
             throw new IllegalPathStateException("missing initial moveto "+
                                                 "in path definition");
         }
         int size = pointTypes.length;
         if (size == 0) {
             pointTypes = new byte[2];
         } else if (numTypes >= size) {
-            int grow = size;
-            if (grow > EXPAND_MAX) {
-                grow = EXPAND_MAX;
-            }
-            //pointTypes = Arrays.copyOf(pointTypes, size+grow); // jk16 dependency
-            pointTypes = copyOf(pointTypes, size+grow);
+            pointTypes = expandPointTypes(pointTypes, 1);
         }
         size = floatCoords.length;
-        if (numCoords + newCoords > size) {
-            int grow = size;
-            if (grow > EXPAND_MAX * 2) {
-                grow = EXPAND_MAX * 2;
+        if (numCoords > (floatCoords.length - newCoords)) {
+            floatCoords = expandCoords(floatCoords, newCoords);
+        }
+    }
+
+    static byte[] expandPointTypes(byte[] oldPointTypes, int needed) {
+        final int oldSize = oldPointTypes.length;
+        final int newSizeMin = oldSize + needed;
+        if (newSizeMin < oldSize) {
+            // hard overflow failure - we can't even accommodate
+            // new items without overflowing
+            throw new ArrayIndexOutOfBoundsException(
+                          "pointTypes exceeds maximum capacity !");
+        }
+        // growth algorithm computation
+        int grow = oldSize;
+        if (grow > EXPAND_MAX) {
+            grow = Math.max(EXPAND_MAX, oldSize >> 3); // 1/8th min
+        } else if (grow < INIT_SIZE) {
+            grow = INIT_SIZE; // ensure > 6 (cubics)
+        }
+        assert grow > 0;
+
+        int newSize = oldSize + grow;
+        if (newSize < newSizeMin) {
+            // overflow in growth algorithm computation
+            newSize = Integer.MAX_VALUE;
+        }
+
+        while (true) {
+            try {
+                // try allocating the larger array
+                return Arrays.copyOf(oldPointTypes, newSize);
+            } catch (OutOfMemoryError oome) {
+                if (newSize == newSizeMin) {
+                    throw oome;
+                }
             }
-            if (grow < newCoords) {
-                grow = newCoords;
+            newSize = newSizeMin + (newSize - newSizeMin) / 2;
+        }
+    }
+
+    static float[] expandCoords(float[] oldCoords, int needed) {
+        final int oldSize = oldCoords.length;
+        final int newSizeMin = oldSize + needed;
+        if (newSizeMin < oldSize) {
+            // hard overflow failure - we can't even accommodate
+            // new items without overflowing
+            throw new ArrayIndexOutOfBoundsException(
+                          "coords exceeds maximum capacity !");
+        }
+        // growth algorithm computation
+        int grow = oldSize;
+        if (grow > EXPAND_MAX_COORDS) {
+            grow = Math.max(EXPAND_MAX_COORDS, oldSize >> 3); // 1/8th min
+        } else if (grow < INIT_SIZE) {
+            grow = INIT_SIZE; // ensure > 6 (cubics)
+        }
+        assert grow > needed;
+
+        int newSize = oldSize + grow;
+        if (newSize < newSizeMin) {
+            // overflow in growth algorithm computation
+            newSize = Integer.MAX_VALUE;
+        }
+        while (true) {
+            try {
+                // try allocating the larger array
+                return Arrays.copyOf(oldCoords, newSize);
+            } catch (OutOfMemoryError oome) {
+                if (newSize == newSizeMin) {
+                    throw oome;
+                }
             }
-            //floatCoords = Arrays.copyOf(floatCoords, size+grow); // jk16 dependency
-            floatCoords = copyOf(floatCoords, size+grow);
+            newSize = newSizeMin + (newSize - newSizeMin) / 2;
         }
     }
 
     /**
      * Adds a point to the path by moving to the specified

@@ -2288,24 +2347,10 @@
             int type = path.pointTypes[typeIdx++];
             pointIdx += curvecoords[type];
         }
     }
 
-    // jk16 dependency methods
-    static byte[] copyOf(byte[] original, int newLength) {
-        byte[] copy = new byte[newLength];
-        System.arraycopy(original, 0, copy, 0,
-                         Math.min(original.length, newLength));
-        return copy;
-    }
-    static float[] copyOf(float[] original, int newLength) {
-        float[] copy = new float[newLength];
-        System.arraycopy(original, 0, copy, 0,
-                         Math.min(original.length, newLength));
-        return copy;
-    }
-
     public void setTo(Path2D otherPath) {
         numTypes = otherPath.numTypes;
         numCoords = otherPath.numCoords;
         if (numTypes > pointTypes.length) {
             pointTypes = new byte[numTypes];
< prev index next >