View Javadoc

1   // Copyright 2000-2007, FreeHEP.
2   package org.freehep.graphics2d;
3   
4   import java.awt.AlphaComposite;
5   import java.awt.Color;
6   import java.awt.Composite;
7   import java.awt.Dimension;
8   import java.awt.Font;
9   import java.awt.FontMetrics;
10  import java.awt.Graphics;
11  import java.awt.Graphics2D;
12  import java.awt.GraphicsConfiguration;
13  import java.awt.Image;
14  import java.awt.Paint;
15  import java.awt.Rectangle;
16  import java.awt.RenderingHints;
17  import java.awt.Shape;
18  import java.awt.Stroke;
19  import java.awt.font.FontRenderContext;
20  import java.awt.font.GlyphVector;
21  import java.awt.geom.AffineTransform;
22  import java.awt.geom.Rectangle2D;
23  import java.awt.image.BufferedImage;
24  import java.awt.image.BufferedImageOp;
25  import java.awt.image.ImageObserver;
26  import java.awt.image.RenderedImage;
27  import java.awt.image.renderable.RenderableImage;
28  import java.text.AttributedCharacterIterator;
29  import java.util.Hashtable;
30  import java.util.Map;
31  import java.util.Properties;
32  
33  /**
34   * The drawing methods which are guaranteed to work for the various output
35   * formats of the VectorGraphics system on the Java 2 platform. All methods are
36   * re-declared abstract, since this class inherits from Graphics2D and we would
37   * not want to actually or accidentally use any of those methods, except for the
38   * ones noted.
39   * 
40   * Some int methods need to call their super.methods otherwise the compiler
41   * cannot make a distinction if it needs to convert int to doubles or call the
42   * super int method.
43   * 
44   * Note that many of these routines modify the current transformation matrix. To
45   * guard against unintended side effects the following method should be used:
46   * 
47   * <pre><code>
48   *  Graphics2D tempGraphics = (Graphics2D) originalGraphics.create();
49   *  tempGraphics.setStroke(originalGraphics.getStroke());
50   *  tempGraphics.rotate(...);
51   *  tempGraphics.translate(...);
52   *  ...drawing methods on tempGraphics...
53   *  tempGraphics.dispose();
54   * </code></pre>
55   * 
56   * where <code>originalGraphics</code> is the original <code>Graphics2D</code>
57   * object. Note that <code>dispose</code> must be called when the drawing
58   * finishes on <code>tempGraphics</code> and that no drawing should be done on
59   * <code>originalGraphics</code> until <code>dispose</code> has been called.
60   * 
61   * @author Charles Loomis
62   * @author Mark Donszelmann
63   * @version $Id: VectorGraphics.java 10258 2007-01-05 22:51:59Z duns $
64   */
65  public abstract class VectorGraphics extends Graphics2D implements
66          VectorGraphicsConstants {
67  
68      public abstract void setProperties(Properties newProperties);
69  
70      protected abstract void initProperties(Properties defaults);
71  
72      protected abstract Properties getProperties();
73  
74      public abstract String getProperty(String key);
75  
76      public abstract Color getPropertyColor(String key);
77  
78      public abstract Rectangle getPropertyRectangle(String key);
79  
80      public abstract Dimension getPropertyDimension(String key);
81  
82      public abstract int getPropertyInt(String key);
83  
84      public abstract double getPropertyDouble(String key);
85  
86      public abstract boolean isProperty(String key);
87  
88      // //
89      // Methods defined in java.awt.Graphics (alphabetical)
90      // //
91  
92      public abstract void clearRect(int x, int y, int width, int height);
93  
94      public abstract void clipRect(int x, int y, int width, int height);
95  
96      public abstract void copyArea(int x, int y, int width, int height, int dx,
97              int dy);
98  
99      public abstract Graphics create();
100 
101     // NOTE: implemented in Graphics, must be implemented here otherwise the
102     // compiler
103     // cannot choose between converting ints to doubles or calling the
104     // superclass.
105     public Graphics create(int x, int y, int width, int height) {
106         return super.create(x, y, width, height);
107     }
108 
109     public abstract void dispose();
110 
111     // NOTE: implemented in Graphics
112     // public abstract void draw3DRect(int x, int y,
113     // int width, int height,
114     // boolean raised);
115     public abstract void drawArc(int x, int y, int width, int height,
116             int startAngle, int arcAngle);
117 
118     // NOTE: implemented in Graphics
119     // public abstract void drawBytes(byte[] data, int offset,
120     // int length,
121     // int x, int y);
122     // NOTE: implemented in Graphics
123     // public abstract void drawChars(char[] data, int offset,
124     // int length,
125     // int x, int y);
126     public abstract boolean drawImage(Image image, int x, int y,
127             ImageObserver observer);
128 
129     public abstract boolean drawImage(Image image, int x, int y, int width,
130             int height, ImageObserver observer);
131 
132     public abstract boolean drawImage(Image image, int x, int y, Color bgColor,
133             ImageObserver observer);
134 
135     public abstract boolean drawImage(Image image, int x, int y, int width,
136             int height, Color bgColor, ImageObserver observer);
137 
138     public abstract boolean drawImage(Image image, int dx1, int dy1, int dx2,
139             int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer);
140 
141     public abstract boolean drawImage(Image image, int dx1, int dy1, int dx2,
142             int dy2, int sx1, int sy1, int sx2, int sy2, Color bgColor,
143             ImageObserver observer);
144 
145     public abstract void drawLine(int x1, int y1, int x2, int y2);
146 
147     public abstract void drawOval(int x, int y, int width, int height);
148 
149     public abstract void drawPolygon(int[] xPoints, int[] yPoints, int nPoints);
150 
151     // NOTE implemented in Graphics
152     // public abstract void drawPolygon(Polygon p);
153     public abstract void drawPolyline(int[] xPoints, int[] yPoints, int nPoints);
154 
155     public abstract void drawRect(int x, int y, int width, int height);
156 
157     public abstract void drawRoundRect(int x, int y, int width, int height,
158             int arcWidth, int arcHeight);
159 
160     public abstract void drawString(AttributedCharacterIterator iterator,
161             int x, int y);
162 
163     public abstract void drawString(String str, int x, int y);
164 
165     // NOTE: implemented in Graphics
166     // public abstract void fill3DRect(int x, int y,
167     // int width, int height,
168     // boolean raised);
169     public abstract void fillArc(int x, int y, int width, int height,
170             int startAngle, int arcAngle);
171 
172     public abstract void fillOval(int x, int y, int width, int height);
173 
174     public abstract void fillPolygon(int[] xPoints, int[] yPoints, int nPoints);
175 
176     // NOTE: implemented in Graphics
177     // public abstract void fillPolygon(Polygon p);
178     public abstract void fillRect(int x, int y, int width, int height);
179 
180     public abstract void fillRoundRect(int x, int y, int width, int height,
181             int arcWidth, int arcHeight);
182 
183     // NOTE: implemented in Graphics
184     // public abstract void finalize();
185     public abstract Shape getClip();
186 
187     public abstract Rectangle getClipBounds();
188 
189     public abstract Rectangle getClipBounds(Rectangle r);
190 
191     // NOTE: implemented in Graphics
192     // public abstract Rectangle getClipRect();
193     public abstract Color getColor();
194 
195     public abstract Font getFont();
196 
197     // NOTE: implemented in Graphics
198     // public abstract FontMetrics getFontMetrics();
199     public abstract FontMetrics getFontMetrics(Font font);
200 
201     // NOTE: implemented in Graphics
202     // public abstract boolean hitClip(int x, int y, int width, int height);
203     public abstract void setClip(int x, int y, int width, int height);
204 
205     public abstract void setClip(Shape clip);
206 
207     public abstract void setColor(Color c);
208 
209     public abstract void setFont(Font font);
210 
211     public abstract void setPaintMode();
212 
213     public abstract void setXORMode(Color c1);
214 
215     public abstract String toString();
216 
217     public abstract void translate(int x, int y);
218 
219     // //
220     // Methods from java.awt.Graphics2D (alphabetical)
221     // //
222     public abstract void addRenderingHints(Map hints);
223 
224     public abstract void clip(Shape s);
225 
226     public abstract void draw(Shape s);
227 
228     // NOTE: overridden in Graphics2D
229     // public abstract void draw3DRect(int x, int y, int width, int height,
230     // boolean raised);
231     public abstract void drawGlyphVector(GlyphVector g, float x, float y);
232 
233     public abstract void drawImage(BufferedImage img, BufferedImageOp op,
234             int x, int y);
235 
236     public abstract boolean drawImage(Image img, AffineTransform xform,
237             ImageObserver obs);
238 
239     public abstract void drawRenderableImage(RenderableImage img,
240             AffineTransform xform);
241 
242     public abstract void drawRenderedImage(RenderedImage img,
243             AffineTransform xform);
244 
245     public abstract void drawString(AttributedCharacterIterator iterator,
246             float x, float y);
247 
248     // NOTE: overridden in Graphics2D
249     // public abstract void drawString(AttributedCharacterIterator iterator, int
250     // x, int y);
251     // NOTE: redefined in Graphics2D
252     // public abstract void drawString(String str, int x, int y);
253     public abstract void drawString(String str, float x, float y);
254 
255     public abstract void fill(Shape s);
256 
257     /**
258      * Fills an are with the given paint using in offscreen BufferedImage.
259      * Used for drawing GradientPaint or image
260      * @param shape Shape usede as clipping area
261      * @param paint Paint used
262      */
263     protected void fill(Shape shape, Paint paint) {
264         Rectangle2D bounds = shape.getBounds2D();
265 
266         // create image
267         BufferedImage image = new BufferedImage(
268             (int)Math.ceil(bounds.getWidth()) + 1,
269             (int)Math.ceil(bounds.getHeight()) + 1,
270             BufferedImage.TYPE_INT_ARGB);
271 
272         // fill background
273         Graphics2D graphics = image.createGraphics();
274         graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
275         graphics.fill(graphics.getDeviceConfiguration().getBounds());
276         graphics.setComposite(AlphaComposite.SrcOver);
277 
278         // draw paint
279         graphics.setPaint(paint);
280         graphics.translate(- bounds.getMinX(), - bounds.getMinY());
281         graphics.fill(shape);
282         graphics.dispose();
283 
284         // draw image
285         Shape clip = getClip();
286         clip(shape);
287         drawImage(image, (int)bounds.getX(), (int)bounds.getY(), null);
288         setClip(clip);
289     }
290 
291     // NOTE: overridden in Graphics2D
292     // public abstract void fill3DRect(int x, int y,
293     // int width, int height,
294     // boolean raised);
295     public abstract Color getBackground();
296 
297     public abstract Composite getComposite();
298 
299     public abstract GraphicsConfiguration getDeviceConfiguration();
300 
301     public abstract FontRenderContext getFontRenderContext();
302 
303     public abstract Paint getPaint();
304 
305     public abstract Object getRenderingHint(RenderingHints.Key inteKey);
306 
307     public abstract RenderingHints getRenderingHints();
308 
309     public abstract Stroke getStroke();
310 
311     public abstract AffineTransform getTransform();
312 
313     public abstract boolean hit(Rectangle rect, Shape s, boolean onStroke);
314 
315     public abstract void rotate(double theta);
316 
317     public abstract void rotate(double theta, double x, double y);
318 
319     public abstract void scale(double sx, double sy);
320 
321     public abstract void setBackground(Color color);
322 
323     public abstract void setComposite(Composite comp);
324 
325     public abstract void setPaint(Paint paint);
326 
327     public abstract void setRenderingHint(RenderingHints.Key hintKey,
328             Object hintValue);
329 
330     public abstract void setRenderingHints(Map hints);
331 
332     public abstract void setStroke(Stroke s);
333 
334     public abstract void setTransform(AffineTransform xform);
335 
336     public abstract void shear(double shx, double shy);
337 
338     public abstract void transform(AffineTransform xform);
339 
340     public abstract void translate(double tx, double ty);
341 
342     // NOTE: redefines in Graphics2D
343     // public abstract void translate(int x, int y);
344 
345     /*
346      * =====================================================================================
347      * 
348      * Methods added to VectorGraphics (alphabetical)
349      * 
350      * =====================================================================================
351      */
352 
353     public abstract void clearRect(double x, double y, double width,
354             double height);
355 
356     public abstract void clipRect(double x, double y, double width,
357             double height);
358 
359     public abstract Graphics create(double x, double y, double width,
360             double height);
361 
362     /**
363      * Draws an arc. Uses Arc2D to call draw(Shape).
364      * 
365      */
366     public abstract void drawArc(double x, double y, double width,
367             double height, double startAngle, double arcAngle);
368 
369     /**
370      * Draws a straight line. Uses Line2D to call draw(Shape).
371      * 
372      */
373     public abstract void drawLine(double x1, double y1, double x2, double y2);
374 
375     /**
376      * Draws an oval. Uses Ellipse2D to call draw(Shape).
377      * 
378      */
379     public abstract void drawOval(double x, double y, double width,
380             double height);
381 
382     /**
383      * Draws a polygon. Uses createShape(...) to call draw(Shape).
384      * 
385      */
386     public abstract void drawPolygon(double[] xPoints, double[] yPoints,
387             int nPoints);
388 
389     /**
390      * Draws a polyline. Uses createShape(...) to call draw(Shape).
391      * 
392      */
393     public abstract void drawPolyline(double[] xPoints, double[] yPoints,
394             int nPoints);
395 
396     /**
397      * Draws a rectangle. Uses Rectangle2D to call draw(Shape).
398      * 
399      */
400     public abstract void drawRect(double x, double y, double width,
401             double height);
402 
403     /**
404      * Draws a rounded rectangle. Uses RoundRectangle2D to call draw(Shape).
405      * 
406      */
407     public abstract void drawRoundRect(double x, double y, double width,
408             double height, double arcWidth, double arcHeight);
409 
410     public abstract void drawSymbol(int x, int y, int size, int symbol);
411 
412     public abstract void drawSymbol(double x, double y, double size, int symbol);
413 
414     public abstract void fillSymbol(int x, int y, int size, int symbol);
415 
416     public abstract void fillSymbol(double x, double y, double size, int symbol);
417 
418     public abstract void fillAndDrawSymbol(int x, int y, int size, int symbol,
419             Color fillColor);
420 
421     public abstract void fillAndDrawSymbol(double x, double y, double size,
422             int symbol, Color fillColor);
423 
424     /**
425      * Draws a string.
426      * 
427      */
428     public abstract void drawString(String str, double x, double y);
429 
430     public abstract void drawString(TagString str, double x, double y);
431 
432     public abstract void drawString(String str, double x, double y,
433             int horizontal, int vertical);
434 
435     public abstract void drawString(TagString str, double x, double y,
436             int horizontal, int vertical);
437 
438     /**
439      * Draws a string with a lot of parameters.
440      * 
441      * @param str text to be drawn
442      * @param x coordinate to draw string
443      * @param y coordinate to draw string
444      * @param horizontal alignment of the text
445      * @param vertical alignment of the text
446      * @param framed true if text is surrounded by a frame
447      * @param frameColor color of the frame
448      * @param frameWidth witdh of the frame
449      * @param banner true if the frame is filled by a banner
450      * @param bannerColor color of the banner
451      */
452     public abstract void drawString(String str, double x, double y,
453             int horizontal, int vertical, boolean framed, Color frameColor,
454             double frameWidth, boolean banner, Color bannerColor);
455 
456     /**
457      * Draws a TagString with a lot of parameters.
458      * 
459      * @param str Tagged text to be drawn
460      * @param x coordinate to draw string
461      * @param y coordinate to draw string
462      * @param horizontal alignment of the text
463      * @param vertical alignment of the text
464      * @param framed true if text is surrounded by a frame
465      * @param frameColor color of the frame
466      * @param frameWidth witdh of the frame
467      * @param banner true if the frame is filled by a banner
468      * @param bannerColor color of the banner
469      */
470     public abstract void drawString(TagString str, double x, double y,
471             int horizontal, int vertical, boolean framed, Color frameColor,
472             double frameWidth, boolean banner, Color bannerColor);
473 
474     public abstract void endExport();
475 
476     public abstract void fillAndDraw(Shape s, Color fillColor);
477 
478     /**
479      * Fills an arc. Uses Arc2D to call fill(Shape).
480      * 
481      */
482     public abstract void fillArc(double x, double y, double width,
483             double height, double startAngle, double arcAngle);
484 
485     /**
486      * Fills an oval. Uses Ellipse2D to call fill(Shape).
487      * 
488      */
489     public abstract void fillOval(double x, double y, double width,
490             double height);
491 
492     /**
493      * Fills a polygon. Uses createShape(...) to call fill(Shape).
494      * 
495      */
496     public abstract void fillPolygon(double[] xPoints, double[] yPoints,
497             int nPoints);
498 
499     /**
500      * Fills a rectangle. Uses Rectangle2D to call fill(Shape).
501      * 
502      */
503     public abstract void fillRect(double x, double y, double width,
504             double height);
505 
506     /**
507      * Fills a rounded rectangle. Uses RoundRectangle2D to call fill(Shape).
508      * 
509      */
510     public abstract void fillRoundRect(double x, double y, double width,
511             double height, double arcWidth, double arcHeight);
512 
513     public abstract int getColorMode();
514 
515     public abstract String getCreator();
516 
517     public abstract boolean isDeviceIndependent();
518 
519     public abstract void printComment(String comment);
520 
521     public abstract void setClip(double x, double y, double width, double height);
522 
523     public abstract void setColorMode(int colorMode);
524 
525     public abstract void setCreator(String creator);
526 
527     public abstract void setDeviceIndependent(boolean isDeviceIndependent);
528 
529     public abstract void setLineWidth(int width);
530 
531     public abstract void setLineWidth(double width);
532 
533     public abstract void startExport();
534 
535     // STATIC stuff below
536     public static VectorGraphics create(Graphics g) {
537         if ((g != null) && !(g instanceof VectorGraphics)) {
538             return new PixelGraphics2D(g);
539         }
540         return (VectorGraphics) g;
541     }
542 
543     // STATIC stuff below
544     private static Hashtable symbols = new Hashtable(15);
545 
546     static {
547         symbols.put("vline", new Integer(SYMBOL_VLINE));
548         symbols.put("hline", new Integer(SYMBOL_HLINE));
549         symbols.put("plus", new Integer(SYMBOL_PLUS));
550         symbols.put("cross", new Integer(SYMBOL_CROSS));
551         symbols.put("star", new Integer(SYMBOL_STAR));
552         symbols.put("circle", new Integer(SYMBOL_CIRCLE));
553         symbols.put("box", new Integer(SYMBOL_BOX));
554         symbols.put("up_triangle", new Integer(SYMBOL_UP_TRIANGLE));
555         symbols.put("dn_triangle", new Integer(SYMBOL_DN_TRIANGLE));
556         symbols.put("diamond", new Integer(SYMBOL_DIAMOND));
557     }
558 
559     private static Hashtable alignments = new Hashtable(6);
560 
561     static {
562         alignments.put("baseline", new Integer(TEXT_BASELINE));
563         alignments.put("left", new Integer(TEXT_LEFT));
564         alignments.put("top", new Integer(TEXT_TOP));
565         alignments.put("middle", new Integer(TEXT_CENTER));
566         alignments.put("center", new Integer(TEXT_CENTER));
567         alignments.put("right", new Integer(TEXT_RIGHT));
568         alignments.put("bottom", new Integer(TEXT_BOTTOM));
569     }
570 
571     public static int getTextAlignment(String name) {
572         Integer i = (Integer) alignments.get(name.toLowerCase());
573         return (i != null) ? i.intValue() : TEXT_CENTER;
574     }
575 
576     public static int getSymbol(String name) {
577         Integer i = (Integer) symbols.get(name.toLowerCase());
578         return (i != null) ? i.intValue() : SYMBOL_PLUS;
579     }
580 
581     public static double getYalignment(double y, double ascent, double descent,
582             int alignment) {
583         // vertical alignment
584         switch (alignment) {
585         case TEXT_TOP:
586             y = y + ascent - descent;
587             break;
588         case TEXT_CENTER:
589             y = y + ((ascent + descent) / 2) - descent;
590             break;
591         case TEXT_BOTTOM:
592             y = y - descent;
593             break;
594         case TEXT_BASELINE:
595         default:
596             break;
597         }
598         return y;
599     }
600 
601     public static double getXalignment(double x, double width, int alignment) {
602         // horizontal alignment
603         switch (alignment) {
604         case TEXT_CENTER:
605             x = x - (width / 2);
606             break;
607         case TEXT_RIGHT:
608             x = x - width;
609             break;
610         case TEXT_LEFT:
611         default:
612             break;
613         }
614         return x;
615     }
616 }