001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.bpel.design.geometry;
021:
022: import java.awt.Graphics2D;
023: import java.awt.Rectangle;
024: import java.awt.Shape;
025: import java.awt.geom.AffineTransform;
026: import java.awt.geom.Area;
027: import java.awt.geom.FlatteningPathIterator;
028: import java.awt.geom.NoninvertibleTransformException;
029: import java.awt.geom.PathIterator;
030: import java.awt.geom.Point2D;
031: import java.awt.geom.Rectangle2D;
032:
033: public abstract class FShape extends FBounds implements Shape {
034:
035: public FShape(double width, double height) {
036: super (width, height);
037: }
038:
039: public FShape(double x, double y, double width, double height) {
040: super (x, y, width, height);
041: }
042:
043: public FShape rebound(double x, double y, double w, double h) {
044: return reshape(x, y, w, h);
045: }
046:
047: public abstract FShape enlarge(double v);
048:
049: public abstract FShape reshape(double x, double y, double w,
050: double h);
051:
052: public FShape reshapeCentered(double cx, double cy, double w,
053: double h) {
054: return reshape(cx - w / 2.0, cy - h / 2.0, w, h);
055: }
056:
057: public FShape move(double x, double y) {
058: return reshape(x, y, width, height);
059: }
060:
061: public FShape moveCenter(double cx, double cy) {
062: return reshape(cx - width / 2.0, cy - height / 2.0, width,
063: height);
064: }
065:
066: public FShape resize(double w, double h) {
067: return reshape(x, y, w, h);
068: }
069:
070: public FShape resizeCentered(double w, double h) {
071: return reshapeCentered(getCenterX(), getCenterY(), w, h);
072: }
073:
074: public FShape translate(double tx, double ty) {
075: return reshape(x + tx, y + ty, width, height);
076: }
077:
078: public abstract boolean intersect(FIntersector intersector);
079:
080: public Area createArea() {
081: return new Area(this );
082: }
083:
084: public abstract PathIterator getPathIterator(AffineTransform at);
085:
086: public PathIterator getPathIterator(AffineTransform at,
087: double flatness) {
088: return new FlatteningPathIterator(getPathIterator(at), flatness);
089: }
090:
091: public boolean contains(Point2D p) {
092: return contains(p.getX(), p.getY());
093: }
094:
095: public boolean intersects(Rectangle2D r) {
096: return intersects(r.getX(), r.getY(), r.getWidth(), r
097: .getHeight());
098: }
099:
100: public boolean contains(Rectangle2D r) {
101: return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
102: }
103:
104: public Rectangle2D getBounds2D() {
105: return new Rectangle2D.Float(x, y, width, height);
106: }
107:
108: public Rectangle getBounds() {
109: int x1 = (int) Math.floor(x);
110: int y1 = (int) Math.floor(y);
111:
112: int x2 = (int) Math.ceil(x + width);
113: int y2 = (int) Math.ceil(y + height);
114:
115: return new Rectangle(x1, y1, x2 - x1, y2 - y1);
116: }
117:
118: public boolean intersects(double x, double y, double w, double h) {
119: double x1, x2, y1, y2;
120:
121: if (w < 0.0) {
122: x1 = x + w;
123: x2 = x;
124: } else {
125: x1 = x;
126: x2 = x + w;
127: }
128:
129: if (h < 0.0) {
130: y1 = y + h;
131: y2 = y;
132: } else {
133: y1 = y;
134: y2 = y + h;
135: }
136:
137: if (this .x + this .width < x1)
138: return false;
139: if (this .y + this .height < y1)
140: return false;
141: if (x2 < this .x)
142: return false;
143: if (y2 < this .y)
144: return false;
145:
146: return true;
147: }
148:
149: public boolean contains(double x, double y, double w, double h) {
150: return contains(x, y) && contains(x + w, y)
151: && contains(x, y + h) && contains(x + w, y + h);
152: }
153:
154: public FPoint getNormalizedCenter(Graphics2D g2) {
155: return getNormalizedCenter(g2.getTransform());
156: }
157:
158: public FPoint getNormalizedCenter(AffineTransform at) {
159: if (at == null) {
160: return new FPoint(0.5 * ((int) x + (int) (x + width)),
161: 0.5 * ((int) y + (int) (y + height)));
162: }
163:
164: float[] coords = { x, y, x + width, y + height };
165:
166: at.transform(coords, 0, coords, 0, 2);
167:
168: double[] center = {
169: 0.5 * ((int) coords[0] + (int) coords[2]) + 0.5,
170: 0.5 * ((int) coords[1] + (int) coords[3]) + 0.5 };
171:
172: try {
173: at.inverseTransform(center, 0, center, 0, 1);
174: } catch (NoninvertibleTransformException exception) {
175: return getCenter();
176: }
177:
178: return new FPoint(center[0], center[1]);
179: }
180:
181: protected class LinePathIterator implements PathIterator {
182:
183: private AffineTransform at;
184: private int index = 0;
185:
186: public LinePathIterator(AffineTransform at) {
187: this .at = at;
188: }
189:
190: public int currentSegment(double[] coords) {
191: int type = 0;
192:
193: if (index == 0) {
194: coords[0] = x;
195: coords[1] = y;
196: type = PathIterator.SEG_MOVETO;
197: } else {
198: coords[0] = x + width;
199: coords[1] = y + height;
200: type = PathIterator.SEG_LINETO;
201: }
202:
203: if (at != null) {
204: at.transform(coords, 0, coords, 0, 1);
205: }
206:
207: return type;
208: }
209:
210: public int currentSegment(float[] coords) {
211: int type = 0;
212:
213: if (index == 0) {
214: coords[0] = x;
215: coords[1] = y;
216: type = PathIterator.SEG_MOVETO;
217: } else {
218: coords[0] = x + width;
219: coords[1] = y + height;
220: type = PathIterator.SEG_LINETO;
221: }
222:
223: if (at != null) {
224: at.transform(coords, 0, coords, 0, 1);
225: }
226:
227: return type;
228: }
229:
230: public void next() {
231: index++;
232: }
233:
234: public boolean isDone() {
235: return index > 1;
236: }
237:
238: public int getWindingRule() {
239: return PathIterator.WIND_NON_ZERO;
240: }
241: }
242:
243: protected class EmptyPathIterator implements PathIterator {
244: public int currentSegment(double[] coords) {
245: return PathIterator.SEG_CLOSE;
246: }
247:
248: public int currentSegment(float[] coords) {
249: return PathIterator.SEG_CLOSE;
250: }
251:
252: public void next() {
253: }
254:
255: public boolean isDone() {
256: return true;
257: }
258:
259: public int getWindingRule() {
260: return PathIterator.WIND_NON_ZERO;
261: }
262: }
263: }
|