1
2 package org.freehep.graphicsio.java;
3
4 import java.awt.Rectangle;
5 import java.awt.Shape;
6 import java.awt.geom.AffineTransform;
7 import java.awt.geom.FlatteningPathIterator;
8 import java.awt.geom.PathIterator;
9 import java.awt.geom.Point2D;
10 import java.awt.geom.Rectangle2D;
11
12
13
14
15
16 public class JAVAGeneralPath implements Shape {
17 private int rule;
18
19 private PathElement[] path;
20
21 private float minX, minY = Float.MAX_VALUE;
22
23 private float maxX, maxY = Float.MIN_VALUE;
24
25 public JAVAGeneralPath(int rule, PathElement[] path) {
26 this.rule = rule;
27 this.path = path;
28 for (int i = 0; i < path.length; i++) {
29 minX = Math.min(minX, path[i].getMinX());
30 maxX = Math.max(maxX, path[i].getMaxX());
31 minY = Math.min(minY, path[i].getMinY());
32 maxY = Math.max(maxY, path[i].getMaxY());
33 }
34 }
35
36 public static abstract class PathElement {
37 public abstract float getMinX();
38
39 public abstract float getMaxX();
40
41 public abstract float getMinY();
42
43 public abstract float getMaxY();
44
45 public abstract int currentSegment(float[] coords);
46
47 public abstract int currentSegment(double[] coords);
48 }
49
50 public static abstract class Point extends PathElement {
51 private float x, y;
52
53 public Point(float x, float y) {
54 this.x = x;
55 this.y = y;
56 }
57
58 public float getMinX() {
59 return x;
60 }
61
62 public float getMaxX() {
63 return x;
64 }
65
66 public float getMinY() {
67 return y;
68 }
69
70 public float getMaxY() {
71 return y;
72 }
73
74 protected void fill(float[] coords) {
75 coords[0] = x;
76 coords[1] = y;
77 }
78
79 protected void fill(double[] coords) {
80 coords[0] = x;
81 coords[1] = y;
82 }
83 }
84
85 public static class MoveTo extends Point {
86 public MoveTo(float x, float y) {
87 super(x, y);
88 }
89
90 public int currentSegment(float[] coords) {
91 fill(coords);
92 return PathIterator.SEG_MOVETO;
93 }
94
95 public int currentSegment(double[] coords) {
96 fill(coords);
97 return PathIterator.SEG_MOVETO;
98 }
99 }
100
101 public static class LineTo extends Point {
102 public LineTo(float x, float y) {
103 super(x, y);
104 }
105
106 public int currentSegment(float[] coords) {
107 fill(coords);
108 return PathIterator.SEG_LINETO;
109 }
110
111 public int currentSegment(double[] coords) {
112 fill(coords);
113 return PathIterator.SEG_LINETO;
114 }
115 }
116
117 public static class QuadTo extends PathElement {
118 private float x1, y1, x2, y2;
119
120 public QuadTo(float x1, float y1, float x2, float y2) {
121 super();
122 this.x1 = x1;
123 this.y1 = y1;
124 this.x2 = x2;
125 this.y2 = y2;
126 }
127
128 public float getMinX() {
129 return Math.min(x1, x2);
130 }
131
132 public float getMaxX() {
133 return Math.max(x1, x2);
134 }
135
136 public float getMinY() {
137 return Math.min(y1, y2);
138 }
139
140 public float getMaxY() {
141 return Math.max(y1, y2);
142 }
143
144 public int currentSegment(float[] coords) {
145 coords[0] = x1;
146 coords[1] = y1;
147 coords[2] = x2;
148 coords[3] = y2;
149 return PathIterator.SEG_QUADTO;
150 }
151
152 public int currentSegment(double[] coords) {
153 coords[0] = x1;
154 coords[1] = y1;
155 coords[2] = x2;
156 coords[3] = y2;
157 return PathIterator.SEG_QUADTO;
158 }
159 }
160
161 public static class CurveTo extends PathElement {
162 private float x1, y1, x2, y2, x3, y3;
163
164 public CurveTo(float x1, float y1, float x2, float y2, float x3,
165 float y3) {
166 super();
167 this.x1 = x1;
168 this.y1 = y1;
169 this.x2 = x2;
170 this.y2 = y2;
171 this.x3 = x3;
172 this.y3 = y3;
173 }
174
175 public float getMinX() {
176 return Math.min(x1, Math.min(x2, x3));
177 }
178
179 public float getMaxX() {
180 return Math.max(x1, Math.max(x2, x3));
181 }
182
183 public float getMinY() {
184 return Math.min(y1, Math.min(y2, y3));
185 }
186
187 public float getMaxY() {
188 return Math.max(y1, Math.max(y2, y3));
189 }
190
191 public int currentSegment(float[] coords) {
192 coords[0] = x1;
193 coords[1] = y1;
194 coords[2] = x2;
195 coords[3] = y2;
196 coords[4] = x3;
197 coords[5] = y3;
198 return PathIterator.SEG_CUBICTO;
199 }
200
201 public int currentSegment(double[] coords) {
202 coords[0] = x1;
203 coords[1] = y1;
204 coords[2] = x2;
205 coords[3] = y2;
206 coords[4] = x3;
207 coords[5] = y3;
208 return PathIterator.SEG_CUBICTO;
209 }
210 }
211
212 public static class ClosePath extends PathElement {
213 public ClosePath() {
214 super();
215 }
216
217 public float getMinX() {
218 return Float.MAX_VALUE;
219 }
220
221 public float getMaxX() {
222 return Float.MIN_VALUE;
223 }
224
225 public float getMinY() {
226 return Float.MAX_VALUE;
227 }
228
229 public float getMaxY() {
230 return Float.MIN_VALUE;
231 }
232
233 public int currentSegment(float[] coords) {
234 return PathIterator.SEG_CLOSE;
235 }
236
237 public int currentSegment(double[] coords) {
238 return PathIterator.SEG_CLOSE;
239 }
240 }
241
242 public Rectangle getBounds() {
243 return getBounds2D().getBounds();
244 }
245
246 public Rectangle2D getBounds2D() {
247 return new Rectangle2D.Float(minX, minY, maxX - minX, maxY - minY);
248 }
249
250
251 public boolean contains(double x, double y) {
252 return getBounds2D().contains(x, y);
253 }
254
255 public boolean contains(Point2D p) {
256 return contains(p.getX(), p.getY());
257 }
258
259
260 public boolean intersects(double x, double y, double w, double h) {
261 return getBounds2D().intersects(x, y, w, h);
262 }
263
264 public boolean intersects(Rectangle2D r) {
265 return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
266 }
267
268
269 public boolean contains(double x, double y, double w, double h) {
270 return getBounds2D().contains(x, y, w, h);
271 }
272
273 public boolean contains(Rectangle2D r) {
274 return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
275 }
276
277 public PathIterator getPathIterator(final AffineTransform at) {
278
279 return new PathIterator() {
280 private int index = 0;
281
282 private AffineTransform transform = at;
283
284 public int getWindingRule() {
285 return rule;
286 }
287
288 public boolean isDone() {
289 return index >= path.length;
290 }
291
292 public void next() {
293 if (!isDone())
294 index++;
295 }
296
297 public int currentSegment(float[] coords) {
298 int type = path[index].currentSegment(coords);
299 if (transform != null) transform.transform(coords, 0, coords, 0, coords.length / 2);
300 return type;
301 }
302
303 public int currentSegment(double[] coords) {
304 int type = path[index].currentSegment(coords);
305 if (transform != null) transform.transform(coords, 0, coords, 0, coords.length / 2);
306 return type;
307 }
308 };
309 }
310
311 public PathIterator getPathIterator(AffineTransform at, double flatness) {
312 return new FlatteningPathIterator(getPathIterator(at), flatness);
313 }
314 }