View Javadoc

1   // Copyright 2000-2003 FreeHEP
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   * @author Mark Donszelmann
14   * @version $Id: JAVAGeneralPath.java 12619 2007-06-07 18:07:57Z duns $
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     // approximation
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     // approximation
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     // approximation
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 }