KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > hssf > usermodel > EscherGraphics


1 /* ====================================================================
2    Copyright 2004 Apache Software Foundation
3
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7
8        http://www.apache.org/licenses/LICENSE-2.0
9
10    Unless required by applicable law or agreed to in writing, software
11    distributed under the License is distributed on an "AS IS" BASIS,
12    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    See the License for the specific language governing permissions and
14    limitations under the License.
15 ==================================================================== */

16
17 package org.apache.poi.hssf.usermodel;
18
19 import org.apache.poi.util.POILogFactory;
20 import org.apache.poi.util.POILogger;
21 import org.apache.poi.hssf.util.HSSFColor;
22
23 import java.awt.*;
24 import java.awt.image.ImageObserver JavaDoc;
25 import java.text.AttributedCharacterIterator JavaDoc;
26
27 /**
28  * Translates Graphics calls into escher calls. The translation is lossy so
29  * many features are not supported and some just aren't implemented yet. If
30  * in doubt test the specific calls you wish to make. Graphics calls are
31  * always performed into an EscherGroup so one will need to be created.
32  * <p>
33  * <b>Important:</b>
34  * <blockquote>
35  * One important concept worth considering is that of font size. One of the
36  * difficulties in converting Graphics calls into escher drawing calls is that
37  * Excel does not have the concept of absolute pixel positions. It measures
38  * it's cell widths in 'characters' and the cell heights in points.
39  * Unfortunately it's not defined exactly what a type of character it's
40  * measuring. Presumably this is due to the fact that the Excel will be
41  * using different fonts on different platforms or even within the same
42  * platform.
43  * <p>
44  * Because of this constraint we've had to calculate the
45  * verticalPointsPerPixel. This the amount the font should be scaled by when
46  * you issue commands such as drawString(). A good way to calculate this
47  * is to use the follow formula:
48  * <p>
49  * <pre>
50  * multipler = groupHeightInPoints / heightOfGroup
51  * </pre>
52  * <p>
53  * The height of the group is calculated fairly simply by calculating the
54  * difference between the y coordinates of the bounding box of the shape. The
55  * height of the group can be calculated by using a convenience called
56  * <code>HSSFClientAnchor.getAnchorHeightInPoints()</code>.
57  * </blockquote>
58  *
59  * @author Glen Stampoultzis (glens at apache.org)
60  */

61 public class EscherGraphics
62         extends Graphics
63 {
64     private HSSFShapeGroup escherGroup;
65     private HSSFWorkbook workbook;
66     private float verticalPointsPerPixel = 1.0f;
67     private float verticalPixelsPerPoint;
68     private Color foreground;
69     private Color background = Color.white;
70     private Font font;
71     private static POILogger logger = POILogFactory.getLogger(EscherGraphics.class);
72
73     /**
74      * Construct an escher graphics object.
75      *
76      * @param escherGroup The escher group to write the graphics calls into.
77      * @param workbook The workbook we are using.
78      * @param forecolor The foreground color to use as default.
79      * @param verticalPointsPerPixel The font multiplier. (See class description for information on how this works.).
80      */

81     public EscherGraphics(HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color forecolor, float verticalPointsPerPixel )
82     {
83         this.escherGroup = escherGroup;
84         this.workbook = workbook;
85         this.verticalPointsPerPixel = verticalPointsPerPixel;
86         this.verticalPixelsPerPoint = 1 / verticalPointsPerPixel;
87         this.font = new Font("Arial", 0, 10);
88         this.foreground = forecolor;
89 // background = backcolor;
90
}
91
92     /**
93      * Constructs an escher graphics object.
94      *
95      * @param escherGroup The escher group to write the graphics calls into.
96      * @param workbook The workbook we are using.
97      * @param foreground The foreground color to use as default.
98      * @param verticalPointsPerPixel The font multiplier. (See class description for information on how this works.).
99      * @param font The font to use.
100      */

101     EscherGraphics( HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color foreground, Font font, float verticalPointsPerPixel )
102     {
103         this.escherGroup = escherGroup;
104         this.workbook = workbook;
105         this.foreground = foreground;
106 // this.background = background;
107
this.font = font;
108         this.verticalPointsPerPixel = verticalPointsPerPixel;
109         this.verticalPixelsPerPoint = 1 / verticalPointsPerPixel;
110     }
111
112 // /**
113
// * Constructs an escher graphics object.
114
// *
115
// * @param escherGroup The escher group to write the graphics calls into.
116
// * @param workbook The workbook we are using.
117
// * @param forecolor The default foreground color.
118
// */
119
// public EscherGraphics( HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color forecolor)
120
// {
121
// this(escherGroup, workbook, forecolor, 1.0f);
122
// }
123

124
125     public void clearRect(int x, int y, int width, int height)
126     {
127         Color color = foreground;
128         setColor(background);
129         fillRect(x,y,width,height);
130         setColor(color);
131     }
132
133     public void clipRect(int x, int y, int width, int height)
134     {
135         if (logger.check( POILogger.WARN ))
136             logger.log(POILogger.WARN,"clipRect not supported");
137     }
138
139     public void copyArea(int x, int y, int width, int height, int dx, int dy)
140     {
141         if (logger.check( POILogger.WARN ))
142             logger.log(POILogger.WARN,"copyArea not supported");
143     }
144
145     public Graphics create()
146     {
147         EscherGraphics g = new EscherGraphics(escherGroup, workbook,
148                 foreground, font, verticalPointsPerPixel );
149         return g;
150     }
151
152     public void dispose()
153     {
154     }
155
156     public void drawArc(int x, int y, int width, int height,
157                  int startAngle, int arcAngle)
158     {
159         if (logger.check( POILogger.WARN ))
160             logger.log(POILogger.WARN,"drawArc not supported");
161     }
162
163     public boolean drawImage(Image img,
164                       int dx1, int dy1, int dx2, int dy2,
165                       int sx1, int sy1, int sx2, int sy2,
166                       Color bgcolor,
167                       ImageObserver JavaDoc observer)
168     {
169         if (logger.check( POILogger.WARN ))
170             logger.log(POILogger.WARN,"drawImage not supported");
171
172         return true;
173     }
174
175     public boolean drawImage(Image img,
176                       int dx1, int dy1, int dx2, int dy2,
177                       int sx1, int sy1, int sx2, int sy2,
178                       ImageObserver JavaDoc observer)
179     {
180         if (logger.check( POILogger.WARN ))
181             logger.log(POILogger.WARN,"drawImage not supported");
182         return true;
183     }
184
185     public boolean drawImage(Image image, int i, int j, int k, int l, Color color, ImageObserver JavaDoc imageobserver)
186     {
187         return drawImage(image, i, j, i + k, j + l, 0, 0, image.getWidth(imageobserver), image.getHeight(imageobserver), color, imageobserver);
188     }
189
190     public boolean drawImage(Image image, int i, int j, int k, int l, ImageObserver JavaDoc imageobserver)
191     {
192         return drawImage(image, i, j, i + k, j + l, 0, 0, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver);
193     }
194
195     public boolean drawImage(Image image, int i, int j, Color color, ImageObserver JavaDoc imageobserver)
196     {
197         return drawImage(image, i, j, image.getWidth(imageobserver), image.getHeight(imageobserver), color, imageobserver);
198     }
199
200     public boolean drawImage(Image image, int i, int j, ImageObserver JavaDoc imageobserver)
201     {
202         return drawImage(image, i, j, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver);
203     }
204
205     public void drawLine(int x1, int y1, int x2, int y2)
206     {
207         HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor(x1, y1, x2, y2) );
208         shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
209         shape.setLineWidth(0);
210         shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
211     }
212
213     public void drawOval(int x, int y, int width, int height)
214     {
215         HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor(x,y,x+width,y+height) );
216         shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);
217         shape.setLineWidth(0);
218         shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
219         shape.setNoFill(true);
220     }
221
222     public void drawPolygon(int xPoints[], int yPoints[],
223                      int nPoints)
224     {
225         int right = findBiggest(xPoints);
226         int bottom = findBiggest(yPoints);
227         int left = findSmallest(xPoints);
228         int top = findSmallest(yPoints);
229         HSSFPolygon shape = escherGroup.createPolygon(new HSSFChildAnchor(left,top,right,bottom) );
230         shape.setPolygonDrawArea(right - left, bottom - top);
231         shape.setPoints(addToAll(xPoints, -left), addToAll(yPoints, -top));
232         shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
233         shape.setLineWidth(0);
234         shape.setNoFill(true);
235     }
236
237     private int[] addToAll( int[] values, int amount )
238     {
239         int[] result = new int[values.length];
240         for ( int i = 0; i < values.length; i++ )
241             result[i] = values[i] + amount;
242         return result;
243     }
244
245     public void drawPolyline(int xPoints[], int yPoints[],
246                       int nPoints)
247     {
248         if (logger.check( POILogger.WARN ))
249             logger.log(POILogger.WARN,"drawPolyline not supported");
250     }
251
252     public void drawRect(int x, int y, int width, int height)
253     {
254         if (logger.check( POILogger.WARN ))
255             logger.log(POILogger.WARN,"drawRect not supported");
256     }
257
258     public void drawRoundRect(int x, int y, int width, int height,
259                        int arcWidth, int arcHeight)
260     {
261         if (logger.check( POILogger.WARN ))
262             logger.log(POILogger.WARN,"drawRoundRect not supported");
263     }
264
265     public void drawString(String JavaDoc str, int x, int y)
266     {
267         if (str == null || str.equals(""))
268             return;
269
270         Font excelFont = font;
271         if ( font.getName().equals( "SansSerif" ) )
272         {
273             excelFont = new Font( "Arial", font.getStyle(), (int) ( font.getSize() / verticalPixelsPerPoint ) );
274         }
275         else
276         {
277             excelFont = new Font( font.getName(), font.getStyle(), (int) ( font.getSize() / verticalPixelsPerPoint ));
278         }
279         FontDetails d = StaticFontMetrics.getFontDetails( excelFont );
280         int width = (int) ( (d.getStringWidth( str ) * 8) + 12 );
281         int height = (int) ( ( font.getSize() / verticalPixelsPerPoint ) + 6 ) * 2;
282         y -= ( font.getSize() / verticalPixelsPerPoint ) + 2 * verticalPixelsPerPoint; // we want to draw the shape from the top-left
283
HSSFTextbox textbox = escherGroup.createTextbox( new HSSFChildAnchor( x, y, x + width, y + height ) );
284         textbox.setNoFill( true );
285         textbox.setLineStyle( HSSFShape.LINESTYLE_NONE );
286         HSSFRichTextString s = new HSSFRichTextString( str );
287         HSSFFont hssfFont = matchFont( excelFont );
288         s.applyFont( hssfFont );
289         textbox.setString( s );
290     }
291
292     private HSSFFont matchFont( Font font )
293     {
294         HSSFColor hssfColor = workbook.getCustomPalette()
295                 .findColor((byte)foreground.getRed(), (byte)foreground.getGreen(), (byte)foreground.getBlue());
296         if (hssfColor == null)
297             hssfColor = workbook.getCustomPalette().findSimilarColor((byte)foreground.getRed(), (byte)foreground.getGreen(), (byte)foreground.getBlue());
298         boolean bold = (font.getStyle() & Font.BOLD) != 0;
299         boolean italic = (font.getStyle() & Font.ITALIC) != 0;
300         HSSFFont hssfFont = workbook.findFont(bold ? HSSFFont.BOLDWEIGHT_BOLD : 0,
301                     hssfColor.getIndex(),
302                     (short)(font.getSize() * 20),
303                     font.getName(),
304                     italic,
305                     false,
306                     (short)0,
307                     (byte)0);
308         if (hssfFont == null)
309         {
310             hssfFont = workbook.createFont();
311             hssfFont.setBoldweight(bold ? HSSFFont.BOLDWEIGHT_BOLD : 0);
312             hssfFont.setColor(hssfColor.getIndex());
313             hssfFont.setFontHeight((short)(font.getSize() * 20));
314             hssfFont.setFontName(font.getName());
315             hssfFont.setItalic(italic);
316             hssfFont.setStrikeout(false);
317             hssfFont.setTypeOffset((short) 0);
318             hssfFont.setUnderline((byte) 0);
319         }
320
321         return hssfFont;
322     }
323
324
325     public void drawString(AttributedCharacterIterator JavaDoc iterator,
326                                     int x, int y)
327     {
328         if (logger.check( POILogger.WARN ))
329             logger.log(POILogger.WARN,"drawString not supported");
330     }
331
332     public void fillArc(int x, int y, int width, int height,
333                  int startAngle, int arcAngle)
334     {
335         if (logger.check( POILogger.WARN ))
336             logger.log(POILogger.WARN,"fillArc not supported");
337     }
338
339     public void fillOval(int x, int y, int width, int height)
340     {
341         HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor( x, y, x + width, y + height ) );
342         shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);
343         shape.setLineStyle(HSSFShape.LINESTYLE_NONE);
344         shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
345         shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
346     }
347
348     public void fillPolygon(int xPoints[], int yPoints[],
349                      int nPoints)
350     {
351         int right = findBiggest(xPoints);
352         int bottom = findBiggest(yPoints);
353         int left = findSmallest(xPoints);
354         int top = findSmallest(yPoints);
355         HSSFPolygon shape = escherGroup.createPolygon(new HSSFChildAnchor(left,top,right,bottom) );
356         shape.setPolygonDrawArea(right - left, bottom - top);
357         shape.setPoints(addToAll(xPoints, -left), addToAll(yPoints, -top));
358         shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
359         shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
360     }
361
362     private int findBiggest( int[] values )
363     {
364         int result = Integer.MIN_VALUE;
365         for ( int i = 0; i < values.length; i++ )
366         {
367             if (values[i] > result)
368                 result = values[i];
369         }
370         return result;
371     }
372
373     private int findSmallest( int[] values )
374     {
375         int result = Integer.MAX_VALUE;
376         for ( int i = 0; i < values.length; i++ )
377         {
378             if (values[i] < result)
379                 result = values[i];
380         }
381         return result;
382     }
383
384     public void fillRect(int x, int y, int width, int height)
385     {
386         HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor( x, y, x + width, y + height ) );
387         shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
388         shape.setLineStyle(HSSFShape.LINESTYLE_NONE);
389         shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
390         shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
391     }
392
393     public void fillRoundRect(int x, int y, int width, int height,
394                        int arcWidth, int arcHeight)
395     {
396         if (logger.check( POILogger.WARN ))
397             logger.log(POILogger.WARN,"fillRoundRect not supported");
398     }
399
400     public Shape getClip()
401     {
402         return getClipBounds();
403     }
404
405     public Rectangle getClipBounds()
406     {
407         return null;
408     }
409
410     public Rectangle getClipRect()
411     {
412         return getClipBounds();
413     }
414
415     public Color getColor()
416     {
417         return foreground;
418     }
419
420     public Font getFont()
421     {
422         return font;
423     }
424
425     public FontMetrics getFontMetrics(Font f)
426     {
427         return Toolkit.getDefaultToolkit().getFontMetrics(f);
428     }
429
430     public void setClip(int x, int y, int width, int height)
431     {
432         setClip(((Shape) (new Rectangle(x,y,width,height))));
433     }
434
435     public void setClip(Shape shape)
436     {
437         // ignore... not implemented
438
}
439
440     public void setColor(Color color)
441     {
442         foreground = color;
443     }
444
445     public void setFont(Font f)
446     {
447         font = f;
448     }
449
450     public void setPaintMode()
451     {
452         if (logger.check( POILogger.WARN ))
453             logger.log(POILogger.WARN,"setPaintMode not supported");
454     }
455
456     public void setXORMode(Color color)
457     {
458         if (logger.check( POILogger.WARN ))
459             logger.log(POILogger.WARN,"setXORMode not supported");
460     }
461
462     public void translate(int x, int y)
463     {
464         if (logger.check( POILogger.WARN ))
465             logger.log(POILogger.WARN,"translate not supported");
466     }
467
468     public Color getBackground()
469     {
470         return background;
471     }
472
473     public void setBackground( Color background )
474     {
475         this.background = background;
476     }
477
478
479 }
480
481
Popular Tags