1 /* 2 * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 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 * A utility class to iterate over the path segments of a rectangle 32 * through the PathIterator interface. 33 * 34 * @author Jim Graham 35 */ 36 class RectIterator implements PathIterator { 37 double x, y, w, h; 38 AffineTransform affine; 39 int index; 40 RectIterator(Rectangle2D r, AffineTransform at)41 RectIterator(Rectangle2D r, AffineTransform at) { 42 this.x = r.getX(); 43 this.y = r.getY(); 44 this.w = r.getWidth(); 45 this.h = r.getHeight(); 46 this.affine = at; 47 if (w < 0 || h < 0) { 48 index = 6; 49 } 50 } 51 52 /** 53 * Return the winding rule for determining the insideness of the 54 * path. 55 * @see #WIND_EVEN_ODD 56 * @see #WIND_NON_ZERO 57 */ getWindingRule()58 public int getWindingRule() { 59 return WIND_NON_ZERO; 60 } 61 62 /** 63 * Tests if there are more points to read. 64 * @return true if there are more points to read 65 */ isDone()66 public boolean isDone() { 67 return index > 5; 68 } 69 70 /** 71 * Moves the iterator to the next segment of the path forwards 72 * along the primary direction of traversal as long as there are 73 * more points in that direction. 74 */ next()75 public void next() { 76 index++; 77 } 78 79 /** 80 * Returns the coordinates and type of the current path segment in 81 * the iteration. 82 * The return value is the path segment type: 83 * SEG_MOVETO, SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE. 84 * A float array of length 6 must be passed in and may be used to 85 * store the coordinates of the point(s). 86 * Each point is stored as a pair of float x,y coordinates. 87 * SEG_MOVETO and SEG_LINETO types will return one point, 88 * SEG_QUADTO will return two points, 89 * SEG_CUBICTO will return 3 points 90 * and SEG_CLOSE will not return any points. 91 * @see #SEG_MOVETO 92 * @see #SEG_LINETO 93 * @see #SEG_QUADTO 94 * @see #SEG_CUBICTO 95 * @see #SEG_CLOSE 96 */ currentSegment(float[] coords)97 public int currentSegment(float[] coords) { 98 if (isDone()) { 99 throw new NoSuchElementException("rect iterator out of bounds"); 100 } 101 if (index == 5) { 102 return SEG_CLOSE; 103 } 104 coords[0] = (float) x; 105 coords[1] = (float) y; 106 if (index == 1 || index == 2) { 107 coords[0] += (float) w; 108 } 109 if (index == 2 || index == 3) { 110 coords[1] += (float) h; 111 } 112 if (affine != null) { 113 affine.transform(coords, 0, coords, 0, 1); 114 } 115 return (index == 0 ? SEG_MOVETO : SEG_LINETO); 116 } 117 118 /** 119 * Returns the coordinates and type of the current path segment in 120 * the iteration. 121 * The return value is the path segment type: 122 * SEG_MOVETO, SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE. 123 * A double array of length 6 must be passed in and may be used to 124 * store the coordinates of the point(s). 125 * Each point is stored as a pair of double x,y coordinates. 126 * SEG_MOVETO and SEG_LINETO types will return one point, 127 * SEG_QUADTO will return two points, 128 * SEG_CUBICTO will return 3 points 129 * and SEG_CLOSE will not return any points. 130 * @see #SEG_MOVETO 131 * @see #SEG_LINETO 132 * @see #SEG_QUADTO 133 * @see #SEG_CUBICTO 134 * @see #SEG_CLOSE 135 */ currentSegment(double[] coords)136 public int currentSegment(double[] coords) { 137 if (isDone()) { 138 throw new NoSuchElementException("rect iterator out of bounds"); 139 } 140 if (index == 5) { 141 return SEG_CLOSE; 142 } 143 coords[0] = x; 144 coords[1] = y; 145 if (index == 1 || index == 2) { 146 coords[0] += w; 147 } 148 if (index == 2 || index == 3) { 149 coords[1] += h; 150 } 151 if (affine != null) { 152 affine.transform(coords, 0, coords, 0, 1); 153 } 154 return (index == 0 ? SEG_MOVETO : SEG_LINETO); 155 } 156 } 157