KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jcckit > renderer > Graphics2DRenderer


1 /*
2  * Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
3  *
4  * This library is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; either version 2.1 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details
13  * (http://www.gnu.org/copyleft/lesser.html).
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19 package jcckit.renderer;
20
21 import java.awt.BasicStroke JavaDoc;
22 import java.awt.Color JavaDoc;
23 import java.awt.Graphics2D JavaDoc;
24 import java.awt.Shape JavaDoc;
25 import java.awt.font.TextLayout JavaDoc;
26 import java.awt.geom.AffineTransform JavaDoc;
27 import java.awt.geom.Ellipse2D JavaDoc;
28 import java.awt.geom.GeneralPath JavaDoc;
29 import java.awt.geom.Rectangle2D JavaDoc;
30
31 import jcckit.graphic.BasicGraphicalElement;
32 import jcckit.graphic.ClippingRectangle;
33 import jcckit.graphic.ClippingShape;
34 import jcckit.graphic.FillAttributes;
35 import jcckit.graphic.FontStyle;
36 import jcckit.graphic.GraphPoint;
37 import jcckit.graphic.GraphicAttributes;
38 import jcckit.graphic.GraphicalComposite;
39 import jcckit.graphic.GraphicalCompositeRenderer;
40 import jcckit.graphic.LineAttributes;
41 import jcckit.graphic.Oval;
42 import jcckit.graphic.OvalRenderer;
43 import jcckit.graphic.Polygon;
44 import jcckit.graphic.PolygonRenderer;
45 import jcckit.graphic.Rectangle;
46 import jcckit.graphic.RectangleRenderer;
47 import jcckit.graphic.Text;
48 import jcckit.graphic.TextAttributes;
49 import jcckit.graphic.TextRenderer;
50
51 /**
52  * Renderer who draws the {@link jcckit.graphic.GraphicalElement
53  * GraphicalElements} into a <tt>java.awt.Graphics2D</tt> context.
54  * <p>
55  * The default color for lines and texts is determined by the
56  * current color of the <tt>Graphics2D</tt> context when a new
57  * instance of <tt>Graphics2DRenderer</tt> is created.
58  * <p>
59  * The default font is <tt>SansSerif-12</tt>.
60  *
61  * @author Franz-Josef Elmer
62  */

63 public class Graphics2DRenderer implements GraphicalCompositeRenderer,
64                                            PolygonRenderer, OvalRenderer,
65                                            TextRenderer, RectangleRenderer {
66   private static final int FS = 1;
67   private static final String JavaDoc DEFAULT_FONT_NAME = "SansSerif";
68   private static final FontStyle DEFAULT_FONT_STYLE = FontStyle.NORMAL;
69   private static final int DEFAULT_FONT_SIZE = 12;
70
71   private Color JavaDoc _defaultColor;
72   private Graphics2D JavaDoc _graphics;
73
74   /**
75    * Initializes this instance. During renderering the current transformation
76    * will be leaved unchanged. But the current Clip may be cleared.
77    * @param graphics Graphics2D context into which the
78    * {@link BasicGraphicalElement BaiscGraphicalElements} are painted.
79    * @return this instance.
80    */

81   public Graphics2DRenderer init(Graphics2D JavaDoc graphics) {
82     _graphics = graphics;
83     _defaultColor = graphics.getColor(); // the foreground color
84
return this;
85   }
86
87   /**
88    * Starts rendering of the specified composite. Does nothing except if
89    * <tt>composite</tt> has a {@link ClippingShape}. In this case the
90    * Clip of the <tt>Graphics2D</tt> context becomes the clipping
91    * rectangle determined by the bounding box of the <tt>ClippingShape</tt>.
92    */

93   public void startRendering(GraphicalComposite composite) {
94     ClippingShape shape = composite.getClippingShape();
95     if (shape != null) {
96       ClippingRectangle rect = shape.getBoundingBox();
97       _graphics.clip(new Rectangle2D.Double JavaDoc(rect.getMinX(), rect.getMinY(),
98           rect.getMaxX() - rect.getMinX(), rect.getMaxY() - rect.getMinY()));
99     }
100   }
101
102   /**
103    * Finishes rendering of the specified composite. Does nothing except if
104    * <tt>composite</tt> has a {@link ClippingShape}. In this case the
105    * Clip of the <tt>Graphics2D</tt> context will be cleared.
106    */

107   public void finishRendering(GraphicalComposite composite) {
108     _graphics.setClip(null);
109   }
110   
111   /** Paints the specified polygon into the <tt>Graphics2D</tt> context. */
112   public void render(Polygon polygon) {
113     int numberOfPoints = polygon.getNumberOfPoints();
114     if (numberOfPoints > 0) {
115       Color JavaDoc currentColor = _graphics.getColor();
116       GeneralPath JavaDoc p
117           = new GeneralPath JavaDoc(GeneralPath.WIND_EVEN_ODD, numberOfPoints);
118       p.moveTo((float) polygon.getPoint(0).getX(),
119                (float) polygon.getPoint(0).getY());
120       for (int i = 1; i < numberOfPoints; i++) {
121         p.lineTo((float) polygon.getPoint(i).getX(),
122                  (float) polygon.getPoint(i).getY());
123       }
124       if (polygon.isClosed()) {
125         p.closePath();
126       }
127       drawShape(p, polygon, currentColor);
128     }
129   }
130    
131   /**
132    * Paints the specified rectangle into the current <tt>Graphics</tt> context.
133    */

134   public void render(Rectangle rectangle) {
135     Color JavaDoc currentColor = _graphics.getColor();
136     GraphPoint center = rectangle.getCenter();
137     double width = rectangle.getWidth();
138     double height = rectangle.getHeight();
139     Rectangle2D JavaDoc rect = new Rectangle2D.Double JavaDoc(center.getX() - 0.5 * width,
140                                               center.getY() - 0.5 * height,
141                                               width, height);
142     drawShape(rect, rectangle, currentColor);
143   }
144
145   /**
146    * Paints the specified oval into the current <tt>Graphics</tt> context.
147    */

148   public void render(Oval oval) {
149     Color JavaDoc currentColor = _graphics.getColor();
150     GraphPoint center = oval.getCenter();
151     double width = oval.getWidth();
152     double height = oval.getHeight();
153     Ellipse2D JavaDoc ellipse = new Ellipse2D.Double JavaDoc(center.getX() - 0.5 * width,
154                                           center.getY() - 0.5 * height,
155                                           width, height);
156     drawShape(ellipse, oval, currentColor);
157   }
158
159   private void drawShape(Shape JavaDoc shape, BasicGraphicalElement element,
160                          Color JavaDoc backupColor) {
161     GraphicAttributes attributes = element.getGraphicAttributes();
162     Color JavaDoc fillColor = null;
163     if (element.isClosed() && attributes instanceof FillAttributes) {
164       fillColor = ((FillAttributes) attributes).getFillColor();
165     }
166     if (fillColor != null) {
167       _graphics.setColor(fillColor);
168       _graphics.fill(shape);
169     }
170     Color JavaDoc lineColor = _defaultColor;
171     if (attributes instanceof LineAttributes) {
172       LineAttributes la = (LineAttributes) attributes;
173       BasicStroke JavaDoc stroke = new BasicStroke JavaDoc((float) la.getLineThickness());
174       double[] linePattern = la.getLinePattern();
175       if (linePattern != null) {
176         float[] dash = new float[linePattern.length];
177         for (int i = 0; i < dash.length; i++) {
178           dash[i] = (float) la.getLinePattern()[i];
179         }
180         stroke = new BasicStroke JavaDoc(stroke.getLineWidth(), BasicStroke.CAP_BUTT,
181                                  BasicStroke.JOIN_MITER, 10f, dash, 0f);
182       }
183       _graphics.setStroke(stroke);
184       if (la.getLineColor() != null || fillColor != null) {
185         lineColor = la.getLineColor();
186       }
187     }
188     if (lineColor != null) {
189       _graphics.setColor(lineColor);
190       _graphics.draw(shape);
191     }
192     _graphics.setColor(backupColor);
193   }
194
195   /**
196    * Paints the specified text into the current <tt>Graphics</tt> context.
197    * <p>
198    * If the font size is zero the default font size will be used.
199    * <p>
200    * If the orientation angle is unequal zero the text will first be painted
201    * into an off-screen image and rotated. Finally, it will be drawn into the
202    * current <tt>Graphics</tt> context. Note, that only integer multiples of
203    * 90 degree rotation are performed. Other orientation angles will be
204    * adjusted to the nearest integer multiple of 90 degree.
205    */

206   public void render(Text text) {
207     final GraphicAttributes ga = text.getGraphicAttributes();
208     if (ga instanceof TextAttributes) {
209       final TextAttributes ta = (TextAttributes) ga;
210       final Color JavaDoc currentColor = _graphics.getColor();
211       Color JavaDoc fontColor = ta.getTextColor();
212       if (fontColor == null) {
213         fontColor = _defaultColor;
214       }
215       _graphics.setColor(fontColor);
216       
217       final double scale = _graphics.getTransform().getScaleX();
218       final String JavaDoc str = text.getText();
219       final TextLayout JavaDoc layout
220           = new TextLayout JavaDoc(str.length() == 0 ? " " : str, // error if str==""
221
GraphicsRenderer.createFont(ta, 0),
222                            _graphics.getFontRenderContext());
223       double fs = ta.getFontSize();
224       fs = fs == 0 ? 1 / scale : fs / DEFAULT_FONT_SIZE;
225       final Shape JavaDoc ts
226             = layout.getOutline(new AffineTransform JavaDoc(fs, 0, 0, -fs, 0, 0));
227       final double x = -0.5 * ta.getHorizontalAnchor().getFactor()
228                             * ts.getBounds2D().getWidth();
229       final double y = -0.5 * ta.getVerticalAnchor().getFactor()
230                             * ts.getBounds2D().getHeight();
231       final AffineTransform JavaDoc transformation
232              = AffineTransform.getTranslateInstance(text.getPosition().getX(),
233                                                     text.getPosition().getY());
234       transformation.rotate(ta.getOrientationAngle() * Math.PI / 180);
235       transformation.translate(x, y);
236       _graphics.fill(transformation.createTransformedShape(ts));
237       _graphics.setColor(currentColor);
238     }
239   }
240 }
241
Popular Tags