< prev index next >

src/java.desktop/share/classes/java/awt/geom/FlatteningPathIterator.java

Print this page




  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt.geom;
  27 
  28 import java.util.*;
  29 
  30 /**
  31  * The <code>FlatteningPathIterator</code> class returns a flattened view of
  32  * another {@link PathIterator} object.  Other {@link java.awt.Shape Shape}
  33  * classes can use this class to provide flattening behavior for their paths
  34  * without having to perform the interpolation calculations themselves.
  35  *
  36  * @author Jim Graham
  37  */
  38 public class FlatteningPathIterator implements PathIterator {
  39     static final int GROW_SIZE = 24;    // Multiple of cubic & quad curve size
  40 
  41     PathIterator src;                   // The source iterator
  42 
  43     double squareflat;                  // Square of the flatness parameter
  44                                         // for testing against squared lengths
  45 
  46     int limit;                          // Maximum number of recursion levels
  47 
  48     double hold[] = new double[14];     // The cache of interpolated coords
  49                                         // Note that this must be long enough
  50                                         // to store a full cubic segment and
  51                                         // a relative cubic segment to avoid


  65     int holdEnd;                        // The index of the last curve segment
  66                                         // being held for interpolation
  67 
  68     int holdIndex;                      // The index of the curve segment
  69                                         // that was last interpolated.  This
  70                                         // is the curve segment ready to be
  71                                         // returned in the next call to
  72                                         // currentSegment().
  73 
  74     int levels[];                       // The recursion level at which
  75                                         // each curve being held in storage
  76                                         // was generated.
  77 
  78     int levelIndex;                     // The index of the entry in the
  79                                         // levels array of the curve segment
  80                                         // at the holdIndex
  81 
  82     boolean done;                       // True when iteration is done
  83 
  84     /**
  85      * Constructs a new <code>FlatteningPathIterator</code> object that
  86      * flattens a path as it iterates over it.  The iterator does not
  87      * subdivide any curve read from the source iterator to more than
  88      * 10 levels of subdivision which yields a maximum of 1024 line
  89      * segments per curve.
  90      * @param src the original unflattened path being iterated over
  91      * @param flatness the maximum allowable distance between the
  92      * control points and the flattened curve
  93      */
  94     public FlatteningPathIterator(PathIterator src, double flatness) {
  95         this(src, flatness, 10);
  96     }
  97 
  98     /**
  99      * Constructs a new <code>FlatteningPathIterator</code> object
 100      * that flattens a path as it iterates over it.
 101      * The <code>limit</code> parameter allows you to control the
 102      * maximum number of recursive subdivisions that the iterator
 103      * can make before it assumes that the curve is flat enough
 104      * without measuring against the <code>flatness</code> parameter.
 105      * The flattened iteration therefore never generates more than
 106      * a maximum of <code>(2^limit)</code> line segments per curve.
 107      * @param src the original unflattened path being iterated over
 108      * @param flatness the maximum allowable distance between the
 109      * control points and the flattened curve
 110      * @param limit the maximum number of recursive subdivisions
 111      * allowed for any curved segment
 112      * @exception IllegalArgumentException if
 113      *          <code>flatness</code> or <code>limit</code>
 114      *          is less than zero
 115      */
 116     public FlatteningPathIterator(PathIterator src, double flatness,
 117                                   int limit) {
 118         if (flatness < 0.0) {
 119             throw new IllegalArgumentException("flatness must be >= 0");
 120         }
 121         if (limit < 0) {
 122             throw new IllegalArgumentException("limit must be >= 0");
 123         }
 124         this.src = src;
 125         this.squareflat = flatness * flatness;
 126         this.limit = limit;
 127         this.levels = new int[limit + 1];
 128         // prime the first path segment
 129         next(false);
 130     }
 131 
 132     /**
 133      * Returns the flatness of this iterator.
 134      * @return the flatness of this <code>FlatteningPathIterator</code>.
 135      */
 136     public double getFlatness() {
 137         return Math.sqrt(squareflat);
 138     }
 139 
 140     /**
 141      * Returns the recursion limit of this iterator.
 142      * @return the recursion limit of this
 143      * <code>FlatteningPathIterator</code>.
 144      */
 145     public int getRecursionLimit() {
 146         return limit;
 147     }
 148 
 149     /**
 150      * Returns the winding rule for determining the interior of the
 151      * path.
 152      * @return the winding rule of the original unflattened path being
 153      * iterated over.
 154      * @see PathIterator#WIND_EVEN_ODD
 155      * @see PathIterator#WIND_NON_ZERO
 156      */
 157     public int getWindingRule() {
 158         return src.getWindingRule();
 159     }
 160 
 161     /**
 162      * Tests if the iteration is complete.
 163      * @return <code>true</code> if all the segments have
 164      * been read; <code>false</code> otherwise.
 165      */
 166     public boolean isDone() {
 167         return done;
 168     }
 169 
 170     /*
 171      * Ensures that the hold array can hold up to (want) more values.
 172      * It is currently holding (hold.length - holdIndex) values.
 173      */
 174     void ensureHoldCapacity(int want) {
 175         if (holdIndex - want < 0) {
 176             int have = hold.length - holdIndex;
 177             int newsize = hold.length + GROW_SIZE;
 178             double newhold[] = new double[newsize];
 179             System.arraycopy(hold, holdIndex,
 180                              newhold, holdIndex + GROW_SIZE,
 181                              have);
 182             hold = newhold;
 183             holdIndex += GROW_SIZE;
 184             holdEnd += GROW_SIZE;




  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt.geom;
  27 
  28 import java.util.*;
  29 
  30 /**
  31  * The {@code FlatteningPathIterator} class returns a flattened view of
  32  * another {@link PathIterator} object.  Other {@link java.awt.Shape Shape}
  33  * classes can use this class to provide flattening behavior for their paths
  34  * without having to perform the interpolation calculations themselves.
  35  *
  36  * @author Jim Graham
  37  */
  38 public class FlatteningPathIterator implements PathIterator {
  39     static final int GROW_SIZE = 24;    // Multiple of cubic & quad curve size
  40 
  41     PathIterator src;                   // The source iterator
  42 
  43     double squareflat;                  // Square of the flatness parameter
  44                                         // for testing against squared lengths
  45 
  46     int limit;                          // Maximum number of recursion levels
  47 
  48     double hold[] = new double[14];     // The cache of interpolated coords
  49                                         // Note that this must be long enough
  50                                         // to store a full cubic segment and
  51                                         // a relative cubic segment to avoid


  65     int holdEnd;                        // The index of the last curve segment
  66                                         // being held for interpolation
  67 
  68     int holdIndex;                      // The index of the curve segment
  69                                         // that was last interpolated.  This
  70                                         // is the curve segment ready to be
  71                                         // returned in the next call to
  72                                         // currentSegment().
  73 
  74     int levels[];                       // The recursion level at which
  75                                         // each curve being held in storage
  76                                         // was generated.
  77 
  78     int levelIndex;                     // The index of the entry in the
  79                                         // levels array of the curve segment
  80                                         // at the holdIndex
  81 
  82     boolean done;                       // True when iteration is done
  83 
  84     /**
  85      * Constructs a new {@code FlatteningPathIterator} object that
  86      * flattens a path as it iterates over it.  The iterator does not
  87      * subdivide any curve read from the source iterator to more than
  88      * 10 levels of subdivision which yields a maximum of 1024 line
  89      * segments per curve.
  90      * @param src the original unflattened path being iterated over
  91      * @param flatness the maximum allowable distance between the
  92      * control points and the flattened curve
  93      */
  94     public FlatteningPathIterator(PathIterator src, double flatness) {
  95         this(src, flatness, 10);
  96     }
  97 
  98     /**
  99      * Constructs a new {@code FlatteningPathIterator} object
 100      * that flattens a path as it iterates over it.
 101      * The {@code limit} parameter allows you to control the
 102      * maximum number of recursive subdivisions that the iterator
 103      * can make before it assumes that the curve is flat enough
 104      * without measuring against the {@code flatness} parameter.
 105      * The flattened iteration therefore never generates more than
 106      * a maximum of {@code (2^limit)} line segments per curve.
 107      * @param src the original unflattened path being iterated over
 108      * @param flatness the maximum allowable distance between the
 109      * control points and the flattened curve
 110      * @param limit the maximum number of recursive subdivisions
 111      * allowed for any curved segment
 112      * @exception IllegalArgumentException if
 113      *          {@code flatness} or {@code limit}
 114      *          is less than zero
 115      */
 116     public FlatteningPathIterator(PathIterator src, double flatness,
 117                                   int limit) {
 118         if (flatness < 0.0) {
 119             throw new IllegalArgumentException("flatness must be >= 0");
 120         }
 121         if (limit < 0) {
 122             throw new IllegalArgumentException("limit must be >= 0");
 123         }
 124         this.src = src;
 125         this.squareflat = flatness * flatness;
 126         this.limit = limit;
 127         this.levels = new int[limit + 1];
 128         // prime the first path segment
 129         next(false);
 130     }
 131 
 132     /**
 133      * Returns the flatness of this iterator.
 134      * @return the flatness of this {@code FlatteningPathIterator}.
 135      */
 136     public double getFlatness() {
 137         return Math.sqrt(squareflat);
 138     }
 139 
 140     /**
 141      * Returns the recursion limit of this iterator.
 142      * @return the recursion limit of this
 143      * {@code FlatteningPathIterator}.
 144      */
 145     public int getRecursionLimit() {
 146         return limit;
 147     }
 148 
 149     /**
 150      * Returns the winding rule for determining the interior of the
 151      * path.
 152      * @return the winding rule of the original unflattened path being
 153      * iterated over.
 154      * @see PathIterator#WIND_EVEN_ODD
 155      * @see PathIterator#WIND_NON_ZERO
 156      */
 157     public int getWindingRule() {
 158         return src.getWindingRule();
 159     }
 160 
 161     /**
 162      * Tests if the iteration is complete.
 163      * @return {@code true} if all the segments have
 164      * been read; {@code false} otherwise.
 165      */
 166     public boolean isDone() {
 167         return done;
 168     }
 169 
 170     /*
 171      * Ensures that the hold array can hold up to (want) more values.
 172      * It is currently holding (hold.length - holdIndex) values.
 173      */
 174     void ensureHoldCapacity(int want) {
 175         if (holdIndex - want < 0) {
 176             int have = hold.length - holdIndex;
 177             int newsize = hold.length + GROW_SIZE;
 178             double newhold[] = new double[newsize];
 179             System.arraycopy(hold, holdIndex,
 180                              newhold, holdIndex + GROW_SIZE,
 181                              have);
 182             hold = newhold;
 183             holdIndex += GROW_SIZE;
 184             holdEnd += GROW_SIZE;


< prev index next >