KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > nightlabs > editor2d > util > J2DUtil


1 /* *****************************************************************************
2  * NightLabs Editor2D - Graphical editor framework *
3  * Copyright (C) 2004-2005 NightLabs - http://NightLabs.org *
4  * Project author: Daniel Mazurek <Daniel.Mazurek [at] nightlabs [dot] org> *
5  * *
6  * This library is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin St, Fifth Floor, *
20  * Boston, MA 02110-1301 USA *
21  * *
22  * Or get it online : *
23  * http://www.gnu.org/copyleft/lesser.html *
24  * *
25  * *
26  ******************************************************************************/

27
28 package org.nightlabs.editor2d.util;
29
30 import java.awt.geom.AffineTransform JavaDoc;
31 import java.awt.geom.PathIterator JavaDoc;
32 import java.awt.geom.Point2D JavaDoc;
33 import java.awt.geom.Rectangle2D JavaDoc;
34
35 import org.apache.log4j.Logger;
36 import org.eclipse.draw2d.Polyline;
37 import org.eclipse.draw2d.geometry.PointList;
38 import org.eclipse.swt.graphics.Rectangle;
39
40 import org.nightlabs.base.util.ColorUtil;
41 import org.nightlabs.editor2d.j2d.GeneralShape;
42
43
44 public class J2DUtil
45 extends ColorUtil
46 {
47
48   public static final Logger LOGGER = Logger.getLogger(J2DUtil.class);
49   
50     public static org.eclipse.draw2d.geometry.Point toDraw2D(Point2D JavaDoc p) {
51       return new org.eclipse.draw2d.geometry.Point(p.getX(), p.getY());
52     }
53     
54     public static Point2D JavaDoc toPoint2D(org.eclipse.draw2d.geometry.Point p) {
55       return new Point2D.Double JavaDoc(p.x, p.y);
56     }
57     
58   public static Rectangle toSWTRectangle(org.eclipse.draw2d.geometry.Rectangle rect) {
59     return new Rectangle(rect.x, rect.y, rect.width, rect.height);
60   }
61   
62   public static org.eclipse.draw2d.geometry.Rectangle toDraw2D(Rectangle rect) {
63     return new org.eclipse.draw2d.geometry.Rectangle(rect.x, rect.y, rect.width, rect.height);
64   }
65   
66     public static java.awt.Rectangle JavaDoc toAWTRectangle(org.eclipse.draw2d.geometry.Rectangle rectangle) {
67       return new java.awt.Rectangle JavaDoc(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
68     }
69     
70     public static org.eclipse.draw2d.geometry.Rectangle toDraw2D(Rectangle2D JavaDoc r2d) {
71       java.awt.Rectangle JavaDoc r = r2d.getBounds();
72       return new org.eclipse.draw2d.geometry.Rectangle(r.x, r.y, r.width, r.height);
73     }
74
75     public static Rectangle2D JavaDoc toRectangle2D(org.eclipse.draw2d.geometry.Rectangle r) {
76       return new Rectangle2D.Double JavaDoc(r.x, r.y, r.width, r.height);
77     }
78     
79     public static void transformAWTGeneralShape(GeneralShape gs,
80              java.awt.Rectangle JavaDoc oldBounds,
81              java.awt.Rectangle JavaDoc newBounds,
82              boolean cloneGS)
83     {
84       transformGeneralShape(gs, oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height,
85           newBounds.x, newBounds.y, newBounds.width, newBounds.height, cloneGS);
86     }
87     
88     public static void transformAWTGeneralShape(GeneralShape gs,
89              java.awt.Rectangle JavaDoc oldBounds,
90              java.awt.Rectangle JavaDoc newBounds)
91     {
92       transformGeneralShape(gs, oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height,
93           newBounds.x, newBounds.y, newBounds.width, newBounds.height, false);
94     }
95     
96     public static void transformGeneralShape(GeneralShape gs,
97                                                                                  org.eclipse.draw2d.geometry.Rectangle oldBounds,
98                                                                                  org.eclipse.draw2d.geometry.Rectangle newBounds,
99                                                                                  boolean cloneGS)
100     {
101       transformGeneralShape(gs, oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height,
102           newBounds.x, newBounds.y, newBounds.width, newBounds.height, false);
103     }
104         
105     public static void transformGeneralShape(GeneralShape gs,
106              org.eclipse.draw2d.geometry.Rectangle oldBounds,
107              org.eclipse.draw2d.geometry.Rectangle newBounds)
108     {
109         transformGeneralShape(gs, oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height,
110         newBounds.x, newBounds.y, newBounds.width, newBounds.height, false);
111     }
112     
113     protected static AffineTransform JavaDoc at = new AffineTransform JavaDoc();
114     
115     public static void transformGeneralShape(GeneralShape generalShape, int x1, int y1, int w1, int h1,
116         int x2, int y2, int w2, int h2, boolean cloneGS)
117     {
118       // TODO: if cloneGS is true return the cloned GeneralShape in a seperate Method
119
// else return the transformed generalShape for convience
120
GeneralShape gs;
121       if (cloneGS) {
122         gs = (GeneralShape) generalShape.clone();
123       } else {
124         gs = generalShape;
125       }
126                 
127       // if both Rectangles are equal do nothing
128
if (x1 == x2 && y1 == y2 && w1 == w2 && h1 == h2) {
129 // LOGGER.debug("Both Rectangles are Equal!");
130
return;
131       }
132               
133       // if only a Translation is performed, just translate
134
if (w1 == w2 && h1 == h2)
135       {
136         at.setToIdentity();
137         at.translate(x2 - x1, y2 - y1);
138         gs.transform(at);
139       }
140       // translate to origin and scale
141
else
142       {
143           double ratioX = ((double)w2) / ((double)w1);
144           double ratioY = ((double)h2) / ((double)h1);
145         double x = (double)x1;
146         double y = (double)y1;
147         double distanceX = x - (x*ratioX);
148         double distanceY = y - (y*ratioY);
149         at.setToIdentity();
150         at.translate(distanceX, distanceY);
151         at.scale(ratioX, ratioY);
152         gs.transform(at);
153           
154         // translate back
155
distanceX = x2 - x1;
156         distanceY = y2 - y1;
157         at.setToIdentity();
158         at.translate(distanceX, distanceY);
159         gs.transform(at);
160       }
161     }
162      
163 // public static AffineTransform getAffineTransform(int x1, int y1, int w1, int h1,
164
// int x2, int y2, int w2, int h2)
165
// {
166
// // if both Rectangles are equal do nothing
167
// if (x1 == x2 && y1 == y2 && w1 == w2 && h1 == h2)
168
// {
169
//// LOGGER.debug("Both Rectangles are Equal!");
170
// at.setToIdentity();
171
// return at;
172
// }
173
//
174
// // if only a Translation is performed, just translate
175
// if (w1 == w2 && h1 == h2)
176
// {
177
//// LOGGER.debug("Only Translation!");
178
// at.setToIdentity();
179
// at.translate(x2 - x1, y2 - y1);
180
// return at;
181
// }
182
// else if (x1 == x2 && y1 == y2)
183
// {
184
//// LOGGER.debug("Only Scale");
185
// at.setToIdentity();
186
// float ratioY = (float)h2 / (float)h1;
187
// float ratioX = (float)w2 / (float)w1;
188
// float distanceX = (float)x1 - ((float)x1*ratioX);
189
// float distanceY = (float)y1 - ((float)y1*ratioY);
190
// at.translate(distanceX, distanceY);
191
// at.scale(ratioX, ratioY);
192
// return at;
193
// }
194
// else
195
// {
196
//// LOGGER.debug("Scale + Translation");
197
// // translate to origin and scale
198
// double ratioX = ((double)w2) / ((double)w1);
199
// double ratioY = ((double)h2) / ((double)h1);
200
// double x = (double)x1;
201
// double y = (double)y1;
202
// double distanceX = x - (x*ratioX);
203
// double distanceY = y - (y*ratioY);
204
// at.setToIdentity();
205
// at.translate(distanceX, distanceY);
206
// at.scale(ratioX, ratioY);
207
//
208
// // translate back
209
// AffineTransform at2 = new AffineTransform();
210
// distanceX = x2 - x1;
211
// distanceY = y2 - y1;
212
// at2.translate(distanceX, distanceY);
213
//
214
// at.preConcatenate(at2);
215
// }
216
// return at;
217
// }
218

219   public static AffineTransform JavaDoc getTranslateAffineTransform(java.awt.Rectangle JavaDoc oldBounds,
220       java.awt.Rectangle JavaDoc newBounds)
221   {
222     return getTranslateAffineTransform(oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height,
223         newBounds.x, newBounds.y, newBounds.width, newBounds.height);
224   }
225   
226   /*
227    * Should only be used in Combination with getScaledAffineTransform() by calling it afterwards
228    */

229   public static AffineTransform JavaDoc getTranslateAffineTransform(int x1, int y1, int w1, int h1,
230       int x2, int y2, int w2, int h2)
231   {
232     // if both Rectangles are equal do nothing
233
if (x1 == x2 && y1 == y2 && w1 == w2 && h1 == h2) {
234 // LOGGER.debug("Both Rectangles are Equal!");
235
at.setToIdentity();
236       return at;
237     }
238           
239     // if only a Translation is performed, just translate
240
if (w1 == w2 && h1 == h2)
241     {
242       at.setToIdentity();
243     }
244     // translate to origin and scale
245
else
246     {
247       at.setToIdentity();
248       int distanceX = x2 - x1;
249       int distanceY = y2 - y1;
250       at.translate(distanceX, distanceY);
251     }
252     return at;
253   }
254
255   public static AffineTransform JavaDoc getScaleAffineTransform(java.awt.Rectangle JavaDoc oldBounds,
256       java.awt.Rectangle JavaDoc newBounds)
257   {
258     return getScaleAffineTransform(oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height,
259         newBounds.x, newBounds.y, newBounds.width, newBounds.height);
260   }
261   
262   /*
263    * Should only be used in Combination with getTranslateAffineTransform() by calling it first
264    */

265   public static AffineTransform JavaDoc getScaleAffineTransform(int x1, int y1, int w1, int h1,
266       int x2, int y2, int w2, int h2)
267   {
268     // if both Rectangles are equal do nothing
269
if (x1 == x2 && y1 == y2 && w1 == w2 && h1 == h2) {
270       at.setToIdentity();
271       return at;
272     }
273     
274     // if only a Translation is performed, just translate
275
if (w1 == w2 && h1 == h2)
276     {
277       at.setToIdentity();
278       at.translate(x2 - x1, y2 - y1);
279     }
280     // translate to origin and scale
281
else
282     {
283       double ratioX = ((double)w2) / ((double)w1);
284       double ratioY = ((double)h2) / ((double)h1);
285       double x = (double)x1;
286       double y = (double)y1;
287       double distanceX = x - (x*ratioX);
288       double distanceY = y - (y*ratioY);
289       at.setToIdentity();
290       at.translate(distanceX, distanceY);
291       at.scale(ratioX, ratioY);
292     }
293     return at;
294   }
295   
296   /**
297    * @see GeomUtil#getAffineTransform(java.awt.Rectangle, java.awt.Rectangle)
298    */

299   public static AffineTransform JavaDoc getAffineTransform(org.eclipse.draw2d.geometry.Rectangle oldBounds,
300       org.eclipse.draw2d.geometry.Rectangle newBounds)
301   {
302     return GeomUtil.getAffineTransform(oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height,
303         newBounds.x, newBounds.y, newBounds.width, newBounds.height);
304   }
305   
306   /**
307    * @see GeomUtil#getAffineTransform(java.awt.Rectangle, java.awt.Rectangle)
308    */

309   public static AffineTransform JavaDoc getAffineTransform(java.awt.Rectangle JavaDoc oldBounds,
310       java.awt.Rectangle JavaDoc newBounds)
311   {
312     return GeomUtil.getAffineTransform(oldBounds, newBounds);
313   }
314   
315   /**
316    * converts the roattion from degrees to radians
317    *
318    * @param _degrees the rotation given in degrees
319    * @return the rotation given in radians
320    */

321   public static double calcRotationInRadians(double _degrees)
322   {
323     double degreesToRotate = 0;
324         
325     if (_degrees > 360 || _degrees < -360)
326       degreesToRotate = _degrees%360;
327             
328     return Math.toRadians(degreesToRotate);
329   }
330     
331   public static PointList getPathSegments(GeneralShape gs)
332   {
333     PointList points = new PointList();
334     if (gs != null)
335     {
336       double[] coords = new double[6];
337       org.eclipse.draw2d.geometry.Point p, p2, p3;
338       for (PathIterator JavaDoc pi = gs.getPathIterator(null); !pi.isDone(); pi.next())
339       {
340         int segType = pi.currentSegment(coords);
341         switch (segType)
342         {
343             case (PathIterator.SEG_MOVETO):
344                 p = new org.eclipse.draw2d.geometry.Point(coords[0], coords[1]);
345                 points.addPoint(p);
346               break;
347             case (PathIterator.SEG_LINETO):
348                 p = new org.eclipse.draw2d.geometry.Point(coords[0], coords[1]);
349                 points.addPoint(p);
350               break;
351             case (PathIterator.SEG_QUADTO):
352                 p = new org.eclipse.draw2d.geometry.Point(coords[0], coords[1]);
353                 p2 = new org.eclipse.draw2d.geometry.Point(coords[2], coords[3]);
354                 points.addPoint(p);
355                 points.addPoint(p2);
356               break;
357             case (PathIterator.SEG_CUBICTO):
358                 p = new org.eclipse.draw2d.geometry.Point(coords[0], coords[1]);
359                     p2 = new org.eclipse.draw2d.geometry.Point(coords[2], coords[3]);
360                     p3 = new org.eclipse.draw2d.geometry.Point(coords[4], coords[5]);
361                 points.addPoint(p);
362                 points.addPoint(p2);
363                 points.addPoint(p3);
364               break;
365             case (PathIterator.SEG_CLOSE):
366     
367               break;
368         }
369       }
370     }
371     return points;
372   }
373   
374   public static Polyline toPolyline(GeneralShape gs, org.eclipse.draw2d.geometry.Rectangle newBounds)
375   {
376     at.setToIdentity();
377     org.eclipse.draw2d.geometry.Rectangle oldBounds = toDraw2D(gs.getBounds());
378     transformGeneralShape(gs, oldBounds, newBounds, true);
379     return toPolyline(gs);
380   }
381   
382   public static Polyline toPolyline(GeneralShape gs)
383   {
384     Polyline polyline = new Polyline();
385     double[] coords = new double[6];
386     
387     for (PathIterator JavaDoc pi = gs.getPathIterator(new AffineTransform JavaDoc());
388                 !pi.isDone(); pi.next())
389     {
390       int segType = pi.currentSegment(coords);
391       switch (segType) {
392       case (PathIterator.SEG_MOVETO):
393         pi.currentSegment(coords);
394         polyline.addPoint(new org.eclipse.draw2d.geometry.Point(coords[0], coords[1]));
395         break;
396       case (PathIterator.SEG_LINETO):
397         pi.currentSegment(coords);
398         polyline.addPoint(new org.eclipse.draw2d.geometry.Point(coords[0], coords[1]));
399         break;
400       case (PathIterator.SEG_QUADTO):
401         pi.currentSegment(coords);
402         polyline.addPoint(new org.eclipse.draw2d.geometry.Point(coords[0], coords[1]));
403         break;
404       case (PathIterator.SEG_CUBICTO):
405         pi.currentSegment(coords);
406             polyline.addPoint(new org.eclipse.draw2d.geometry.Point(coords[0], coords[1]));
407         break;
408       case (PathIterator.SEG_CLOSE):
409 // pi.currentSegment(coords);
410
// polyline.addPoint(new org.eclipse.draw2d.geometry.Point(coords[0], coords[1]));
411
break;
412       }
413     }
414     return polyline;
415   }
416   
417   public static GeneralShape toGeneralShape(Polyline polyline)
418   {
419     PointList points = polyline.getPoints();
420     GeneralShape gs = new GeneralShape();
421     for (int i=0; i<points.size(); i++)
422     {
423       org.eclipse.draw2d.geometry.Point p = points.getPoint(i);
424       if (i==0)
425         gs.moveTo(p.x, p.y);
426       else
427         gs.lineTo(p.x, p.y);
428     }
429     return gs;
430   }
431     
432   public static GeneralShape removePathSegment(GeneralShape generalShape, int index)
433   {
434     if (generalShape == null)
435       throw new IllegalArgumentException JavaDoc("Param generalShape MUST not be null!");
436       
437     if (index > generalShape.getNumTypes())
438       throw new IndexOutOfBoundsException JavaDoc("Param index is out of GeneralShape PathSegment Bounds!");
439
440     if (index == 0)
441       removeFirstPathSegment(generalShape);
442     
443     float[] coords = new float[6];
444     int pathIndex = 0;
445     GeneralShape gs = new GeneralShape();
446     boolean indexSet = false;
447     for (PathIterator JavaDoc pi = generalShape.getPathIterator(new AffineTransform JavaDoc()); !pi.isDone(); pi.next())
448     {
449       if (pathIndex == index)
450       {
451         pathIndex = -1;
452         indexSet = true;
453         continue;
454       }
455                 
456       int segType = pi.currentSegment(coords);
457       switch (segType)
458       {
459           case (PathIterator.SEG_MOVETO):
460             gs.moveTo(coords[0], coords[1]);
461             if (!indexSet)
462               pathIndex++;
463             break;
464           case (PathIterator.SEG_LINETO):
465             gs.lineTo(coords[0], coords[1]);
466             if (!indexSet)
467               pathIndex++;
468             break;
469           case (PathIterator.SEG_QUADTO):
470             gs.quadTo(coords[0], coords[1], coords[2], coords[3]);
471             if (!indexSet)
472               pathIndex++;
473             break;
474           case (PathIterator.SEG_CUBICTO):
475             gs.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
476             if (!indexSet)
477               pathIndex++;
478             break;
479           case (PathIterator.SEG_CLOSE):
480             gs.closePath();
481             if (!indexSet)
482               pathIndex++;
483             break;
484       }
485     }
486     return gs;
487   }
488   
489   public static GeneralShape removeFirstPathSegment(GeneralShape generalShape)
490   {
491     float[] coords = new float[6];
492     int pathIndex = 0;
493     GeneralShape gs = new GeneralShape();
494     for (PathIterator JavaDoc pi = generalShape.getPathIterator(null); !pi.isDone(); pi.next())
495     {
496       int segType = pi.currentSegment(coords);
497       switch (segType)
498       {
499           case (PathIterator.SEG_MOVETO):
500             pathIndex++;
501             break;
502           case (PathIterator.SEG_LINETO):
503             if (pathIndex == 1)
504               gs.moveTo(coords[0], coords[1]);
505             else
506               gs.lineTo(coords[0], coords[1]);
507             pathIndex++;
508             break;
509           case (PathIterator.SEG_QUADTO):
510             gs.quadTo(coords[0], coords[1], coords[2], coords[3]);
511             pathIndex++;
512             break;
513           case (PathIterator.SEG_CUBICTO):
514             gs.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
515             pathIndex++;
516             break;
517           case (PathIterator.SEG_CLOSE):
518             pathIndex++;
519             break;
520       }
521     }
522     return gs;
523   }
524   
525   public static GeneralShape addPathSegment(GeneralShape generalShape, int type, int index, float[] newCoords)
526   {
527     float[] coords = new float[6];
528     GeneralShape gs = new GeneralShape();
529     int pathIndex = 0;
530     boolean indexSet = false;
531     for (PathIterator JavaDoc pi = generalShape.getPathIterator(null); !pi.isDone(); pi.next())
532     {
533       if (pathIndex == index)
534       {
535         switch (type)
536         {
537             case (PathIterator.SEG_MOVETO):
538               gs.moveTo(newCoords[0], newCoords[1]);
539               break;
540             case (PathIterator.SEG_LINETO):
541               gs.lineTo(newCoords[0], newCoords[1]);
542               break;
543               case (PathIterator.SEG_QUADTO):
544                 gs.quadTo(newCoords[0], newCoords[1], newCoords[2], newCoords[3]);
545                 break;
546               case (PathIterator.SEG_CUBICTO):
547                 gs.curveTo(newCoords[0], newCoords[1], newCoords[2], newCoords[3], newCoords[4], newCoords[5]);
548                 break;
549         }
550         pathIndex = -1;
551         indexSet = true;
552       }
553       
554       int segType = pi.currentSegment(coords);
555       switch (segType)
556       {
557           case (PathIterator.SEG_MOVETO):
558             gs.moveTo(coords[0], coords[1]);
559             if (!indexSet)
560               pathIndex++;
561             break;
562           case (PathIterator.SEG_LINETO):
563             gs.lineTo(coords[0], coords[1]);
564             if (!indexSet)
565               pathIndex++;
566             break;
567           case (PathIterator.SEG_QUADTO):
568             gs.quadTo(coords[0], coords[1], coords[2], coords[3]);
569             if (!indexSet)
570               pathIndex++;
571             break;
572           case (PathIterator.SEG_CUBICTO):
573             gs.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
574             if (!indexSet)
575               pathIndex++;
576             break;
577           case (PathIterator.SEG_CLOSE):
578             gs.closePath();
579             if (!indexSet)
580               pathIndex++;
581             break;
582       }
583     }
584     return gs;
585   }
586     
587 }
588
589
Popular Tags