001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Denis M. Kishenko
019: * @version $Revision$
020: */package java.awt;
021:
022: import java.awt.Point;
023: import java.awt.Rectangle;
024: import java.awt.Shape;
025: import java.awt.geom.AffineTransform;
026: import java.awt.geom.PathIterator;
027: import java.awt.geom.Point2D;
028: import java.awt.geom.Rectangle2D;
029: import java.io.Serializable;
030: import java.util.NoSuchElementException;
031:
032: import org.apache.harmony.awt.gl.*;
033: import org.apache.harmony.awt.internal.nls.Messages;
034:
035: public class Polygon implements Shape, Serializable {
036:
037: private static final long serialVersionUID = -6460061437900069969L;
038:
039: /**
040: * The points buffer capacity
041: */
042: private static final int BUFFER_CAPACITY = 4;
043:
044: public int npoints;
045: public int[] xpoints;
046: public int[] ypoints;
047: protected Rectangle bounds;
048:
049: /*
050: * Polygon path iterator
051: */
052: class Iterator implements PathIterator {
053:
054: /**
055: * The source Polygon object
056: */
057: public Polygon p;
058:
059: /**
060: * The path iterator transformation
061: */
062: public AffineTransform t;
063:
064: /**
065: * The current segmenet index
066: */
067: public int index;
068:
069: /**
070: * Constructs a new Polygon.Iterator for given polygon and transformation
071: * @param l - the source Line2D object
072: * @param at - the AffineTransform object to apply rectangle path
073: */
074: public Iterator(AffineTransform at, Polygon p) {
075: this .p = p;
076: this .t = at;
077: if (p.npoints == 0) {
078: index = 1;
079: }
080: }
081:
082: public int getWindingRule() {
083: return WIND_EVEN_ODD;
084: }
085:
086: public boolean isDone() {
087: return index > p.npoints;
088: }
089:
090: public void next() {
091: index++;
092: }
093:
094: public int currentSegment(double[] coords) {
095: if (isDone()) {
096: // awt.110=Iterator out of bounds
097: throw new NoSuchElementException(Messages
098: .getString("awt.110")); //$NON-NLS-1$
099: }
100: if (index == p.npoints) {
101: return SEG_CLOSE;
102: }
103: coords[0] = p.xpoints[index];
104: coords[1] = p.ypoints[index];
105: if (t != null) {
106: t.transform(coords, 0, coords, 0, 1);
107: }
108: return index == 0 ? SEG_MOVETO : SEG_LINETO;
109: }
110:
111: public int currentSegment(float[] coords) {
112: if (isDone()) {
113: // awt.110=Iterator out of bounds
114: throw new NoSuchElementException(Messages
115: .getString("awt.110")); //$NON-NLS-1$
116: }
117: if (index == p.npoints) {
118: return SEG_CLOSE;
119: }
120: coords[0] = p.xpoints[index];
121: coords[1] = p.ypoints[index];
122: if (t != null) {
123: t.transform(coords, 0, coords, 0, 1);
124: }
125: return index == 0 ? SEG_MOVETO : SEG_LINETO;
126: }
127: }
128:
129: public Polygon() {
130: xpoints = new int[BUFFER_CAPACITY];
131: ypoints = new int[BUFFER_CAPACITY];
132: }
133:
134: public Polygon(int[] xpoints, int[] ypoints, int npoints) {
135: if (npoints > xpoints.length || npoints > ypoints.length) {
136: // awt.111=Parameter npoints is greater than array length
137: throw new IndexOutOfBoundsException(Messages
138: .getString("awt.111")); //$NON-NLS-1$
139: }
140: if (npoints < 0) {
141: // awt.112=Negative number of points
142: throw new NegativeArraySizeException(Messages
143: .getString("awt.112")); //$NON-NLS-1$
144: }
145: this .npoints = npoints;
146: this .xpoints = new int[npoints];
147: this .ypoints = new int[npoints];
148: System.arraycopy(xpoints, 0, this .xpoints, 0, npoints);
149: System.arraycopy(ypoints, 0, this .ypoints, 0, npoints);
150: }
151:
152: public void reset() {
153: npoints = 0;
154: bounds = null;
155: }
156:
157: public void invalidate() {
158: bounds = null;
159: }
160:
161: public void addPoint(int px, int py) {
162: if (npoints == xpoints.length) {
163: int[] tmp;
164:
165: tmp = new int[xpoints.length + BUFFER_CAPACITY];
166: System.arraycopy(xpoints, 0, tmp, 0, xpoints.length);
167: xpoints = tmp;
168:
169: tmp = new int[ypoints.length + BUFFER_CAPACITY];
170: System.arraycopy(ypoints, 0, tmp, 0, ypoints.length);
171: ypoints = tmp;
172: }
173:
174: xpoints[npoints] = px;
175: ypoints[npoints] = py;
176: npoints++;
177:
178: if (bounds != null) {
179: bounds.setFrameFromDiagonal(Math.min(bounds.getMinX(), px),
180: Math.min(bounds.getMinY(), py), Math.max(bounds
181: .getMaxX(), px), Math.max(bounds.getMaxY(),
182: py));
183: }
184: }
185:
186: public Rectangle getBounds() {
187: if (bounds != null) {
188: return bounds;
189: }
190: if (npoints == 0) {
191: return new Rectangle();
192: }
193:
194: int bx1 = xpoints[0];
195: int by1 = ypoints[0];
196: int bx2 = bx1;
197: int by2 = by1;
198:
199: for (int i = 1; i < npoints; i++) {
200: int x = xpoints[i];
201: int y = ypoints[i];
202: if (x < bx1) {
203: bx1 = x;
204: } else if (x > bx2) {
205: bx2 = x;
206: }
207: if (y < by1) {
208: by1 = y;
209: } else if (y > by2) {
210: by2 = y;
211: }
212: }
213:
214: return bounds = new Rectangle(bx1, by1, bx2 - bx1, by2 - by1);
215: }
216:
217: /**
218: * @deprecated
219: */
220: @Deprecated
221: public Rectangle getBoundingBox() {
222: return getBounds();
223: }
224:
225: public Rectangle2D getBounds2D() {
226: return getBounds().getBounds2D();
227: }
228:
229: public void translate(int mx, int my) {
230: for (int i = 0; i < npoints; i++) {
231: xpoints[i] += mx;
232: ypoints[i] += my;
233: }
234: if (bounds != null) {
235: bounds.translate(mx, my);
236: }
237: }
238:
239: /**
240: * @deprecated
241: */
242: @Deprecated
243: public boolean inside(int x, int y) {
244: return contains((double) x, (double) y);
245: }
246:
247: public boolean contains(int x, int y) {
248: return contains((double) x, (double) y);
249: }
250:
251: public boolean contains(double x, double y) {
252: return Crossing
253: .isInsideEvenOdd(Crossing.crossShape(this , x, y));
254: }
255:
256: public boolean contains(double x, double y, double width,
257: double height) {
258: int cross = Crossing.intersectShape(this , x, y, width, height);
259: return cross != Crossing.CROSSING
260: && Crossing.isInsideEvenOdd(cross);
261: }
262:
263: public boolean intersects(double x, double y, double width,
264: double height) {
265: int cross = Crossing.intersectShape(this , x, y, width, height);
266: return cross == Crossing.CROSSING
267: || Crossing.isInsideEvenOdd(cross);
268: }
269:
270: public boolean contains(Rectangle2D rect) {
271: return contains(rect.getX(), rect.getY(), rect.getWidth(), rect
272: .getHeight());
273: }
274:
275: public boolean contains(Point point) {
276: return contains(point.getX(), point.getY());
277: }
278:
279: public boolean contains(Point2D point) {
280: return contains(point.getX(), point.getY());
281: }
282:
283: public boolean intersects(Rectangle2D rect) {
284: return intersects(rect.getX(), rect.getY(), rect.getWidth(),
285: rect.getHeight());
286: }
287:
288: public PathIterator getPathIterator(AffineTransform t) {
289: return new Iterator(t, this );
290: }
291:
292: public PathIterator getPathIterator(AffineTransform t,
293: double flatness) {
294: return new Iterator(t, this);
295: }
296:
297: }
|