KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > magnolia > cms > taglibs > util > Text2PngFactory


1 /**
2  *
3  * Magnolia and its source-code is licensed under the LGPL.
4  * You may copy, adapt, and redistribute this file for commercial or non-commercial use.
5  * When copying, adapting, or redistributing this document in keeping with the guidelines above,
6  * you are required to provide proper attribution to obinary.
7  * If you reproduce or distribute the document without making any substantive modifications to its content,
8  * please use the following attribution line:
9  *
10  * Copyright 1993-2006 obinary Ltd. (http://www.obinary.com) All rights reserved.
11  *
12  */

13 package info.magnolia.cms.taglibs.util;
14
15 import java.awt.Color JavaDoc;
16 import java.awt.Font JavaDoc;
17 import java.awt.FontFormatException JavaDoc;
18 import java.awt.FontMetrics JavaDoc;
19 import java.awt.Graphics2D JavaDoc;
20 import java.awt.RenderingHints JavaDoc;
21 import java.awt.font.FontRenderContext JavaDoc;
22 import java.awt.font.TextLayout JavaDoc;
23 import java.awt.geom.Rectangle2D JavaDoc;
24 import java.awt.image.BufferedImage JavaDoc;
25 import java.awt.image.RenderedImage JavaDoc;
26 import java.io.File JavaDoc;
27 import java.io.FileInputStream JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30
31 import javax.imageio.ImageIO JavaDoc;
32
33
34 /**
35  * Class to generate PNG images from TrueType font strings. Originally by Philip McCarthy - http://chimpen.com
36  * http://chimpen.com/things/archives/001139.php
37  * @author Philip McCarthy
38  * @author Patrick Janssen
39  */

40 public class Text2PngFactory {
41
42     /** Font name */
43     private String JavaDoc fontname;
44
45     /** Font size */
46     private int fontsize;
47
48     /** Text to render */
49     private String JavaDoc text = "";
50
51     /** Text color */
52     private int r = 0;
53
54     private int g = 0;
55
56     private int b = 0;
57
58     /** Background colour */
59     private int br = 0xff;
60
61     private int bg = 0xff;
62
63     private int bb = 0xff;
64
65     /** Used to obtain fontmetrics for given fontname */
66     private Graphics2D JavaDoc g2;
67
68     /** Cached Font object */
69     private Font JavaDoc cachedFont;
70
71     /**
72      * Construct factory without setting font
73      */

74     public Text2PngFactory() {
75         // Create a single-pixel buffered image to do font stuff with
76
this.g2 = new BufferedImage JavaDoc(1, 1, BufferedImage.TYPE_3BYTE_BGR).createGraphics();
77         // Set same hints as used for final render
78
setOptimalRenderQuality(this.g2);
79     }
80
81     /**
82      * Construct factory with given font face and size
83      * @param fontname Name of TrueType font
84      * @param fontsize Point size of font
85      * @throws IOException if font can't be loaded
86      * @throws FontFormatException if font is not a valid TTF
87      */

88     public Text2PngFactory(String JavaDoc fontname, int fontsize) throws IOException JavaDoc, FontFormatException JavaDoc {
89         this(fontname, fontsize, "");
90     }
91
92     /**
93      * Construct factory with given font face and size
94      * @param fontname Name of TrueType font
95      * @param fontsize Point size of font
96      * @param text The text to render
97      * @throws IOException if font can't be loaded
98      * @throws FontFormatException if font is not a valid TTF
99      */

100     public Text2PngFactory(String JavaDoc fontname, int fontsize, String JavaDoc text) throws IOException JavaDoc, FontFormatException JavaDoc {
101
102         // Create a single-pixel buffered image to get font sizes etc from.
103
this.g2 = new BufferedImage JavaDoc(1, 1, BufferedImage.TYPE_3BYTE_BGR).createGraphics();
104         // Set same hints as used for final render
105
setOptimalRenderQuality(this.g2);
106         this.setFontFace(fontname);
107         this.setFontSize(fontsize);
108         this.setText(text);
109     }
110
111     /**
112      * Renders the current text to a .png file
113      * @param location Location to write the file out to
114      * @throws IOException if file cannot be created
115      */

116     public void createPngFile(String JavaDoc location) throws IOException JavaDoc {
117         createPngFile(new File JavaDoc(location));
118     }
119
120     /**
121      * Renders the current text to a .png file
122      * @param location Location to write the file out to
123      * @throws IOException if file cannot be created
124      */

125     public void createPngFile(File JavaDoc location) throws IOException JavaDoc {
126         ImageIO.write(createImage(), "png", location);
127     }
128
129     /**
130      * Renders the current text in the current font fontname, fontsize and color
131      * @return Image containing rendered text
132      * @throws IOException if no font name has been specified yet
133      */

134     public RenderedImage JavaDoc createImage() throws IOException JavaDoc {
135
136         if (this.fontname == null) {
137             throw new IOException JavaDoc("No font name given!");
138         }
139
140         // Get the bounds needed to render the text
141
FontRenderContext JavaDoc frc = this.g2.getFontRenderContext();
142         TextLayout JavaDoc layout = new TextLayout JavaDoc(this.text, this.cachedFont, frc);
143         Rectangle2D JavaDoc bounds = layout.getBounds();
144
145         // Get the width needed to render this piece of text
146
// 2 pixels were added here due to problem with cutting of end of text
147
int stringWidth = (int) (Math.ceil(bounds.getWidth())) + 2;
148
149         // Get the height from generic font info
150
// This way, all strings in this font will have same height
151
// and vertical alignment
152
FontMetrics JavaDoc fm = this.g2.getFontMetrics();
153         int stringHeight = fm.getHeight();
154
155         // Make an image to contain string
156
BufferedImage JavaDoc im = new BufferedImage JavaDoc(stringWidth, stringHeight, BufferedImage.TYPE_3BYTE_BGR);
157
158         // Set the font and colours on the image
159
Graphics2D JavaDoc graphics = im.createGraphics();
160
161         // Setup best-quality rendering
162
setOptimalRenderQuality(graphics);
163
164         // Set colours and clear rectangle
165
graphics.setBackground(new Color JavaDoc(this.br, this.bg, this.bb));
166         graphics.setColor(new Color JavaDoc(this.r, this.g, this.b));
167         graphics.clearRect(0, 0, stringWidth, stringHeight);
168
169         // Set the font to use
170
graphics.setFont(getFont());
171
172         // Position text on baseline, with first character exactly against
173
// left margin
174
layout.draw(graphics, -(float) Math.floor(bounds.getX()), fm.getMaxAscent());
175
176         // Return the image
177
return im;
178     }
179
180     /**
181      * Set the text to be rendered by the Txt2PngFactory
182      * @param text The text to render
183      */

184     public void setText(String JavaDoc text) {
185         this.text = text;
186     }
187
188     /**
189      * Set 8-bit RGB values for text colour
190      * @param r Red component (0-255)
191      * @param g Green component (0-255)
192      * @param b Blue component (0-255)
193      */

194     public void setTextRGB(int r, int g, int b) {
195         this.r = r;
196         this.g = g;
197         this.b = b;
198     }
199
200     /**
201      * Set 8-bit RGB values for background colour
202      * @param r Red component (0-255)
203      * @param g Green component (0-255)
204      * @param b Blue component (0-255)
205      */

206     public void setBackgroundRGB(int r, int g, int b) {
207         this.br = r;
208         this.bg = g;
209         this.bb = b;
210     }
211
212     /**
213      * Set the TrueType font to render with
214      * @param fontname The name of the font to use
215      */

216     public void setFontFace(String JavaDoc fontname) throws IOException JavaDoc, FontFormatException JavaDoc {
217
218         if (!fontname.equals(this.fontname)) {
219             this.fontname = fontname;
220             updateFace();
221         }
222     }
223
224     /**
225      * Set the point size of the font
226      * @param fontsize The point size of the font
227      */

228     public void setFontSize(int fontsize) {
229         if (fontsize != this.fontsize) {
230             this.fontsize = fontsize;
231             updateSize();
232         }
233     }
234
235     /**
236      * Updates the cached font object
237      * @throws IOException if the font can't be loaded
238      * @throws FontFormatException if font is not a valid TTF
239      */

240     private void updateFace() throws IOException JavaDoc, FontFormatException JavaDoc {
241         Font JavaDoc createdFont = null;
242
243         // Attempt to load font from /fonts under classloader
244
String JavaDoc fontpath = "fonts/" + this.fontname + ".ttf";
245
246         InputStream JavaDoc fontStream = this.getClass().getClassLoader().getResourceAsStream(fontpath);
247         if (fontStream != null) {
248             createdFont = Font.createFont(Font.TRUETYPE_FONT, fontStream);
249             fontStream.close();
250         }
251         // Next try to get it from fontpath
252
if (createdFont == null) {
253             Font JavaDoc tempFont = new Font JavaDoc(this.fontname, Font.PLAIN, 1);
254
255             // Check we got correct font, not a fallback
256
if (tempFont.getFamily().equals(this.fontname)) {
257                 // It's the correct font, set it
258
createdFont = tempFont;
259             }
260         }
261         // Last resort, treat as a path to font
262
if (createdFont == null) {
263             fontStream = new FileInputStream JavaDoc(this.fontname);
264
265             if (fontStream != null) {
266                 createdFont = Font.createFont(Font.TRUETYPE_FONT, fontStream);
267                 fontStream.close();
268             }
269         }
270         // If we still don't have a font, throw exception
271
if (createdFont == null) {
272             throw new IOException JavaDoc("Can't locate font: " + this.fontname);
273         }
274
275         // Derive font of correct fontsize
276
this.cachedFont = createdFont.deriveFont((float) this.fontsize);
277
278         // Set on prototype image
279
this.g2.setFont(this.cachedFont);
280     }
281
282     /**
283      * Updates the cached font to new font derived with new size
284      */

285     private void updateSize() {
286
287         if (this.cachedFont == null) {
288             return;
289         }
290
291         // Derive font of correct fontsize
292
this.cachedFont = this.cachedFont.deriveFont((float) this.fontsize);
293
294         // Set on Graphics object so we can get FontMetrics
295
this.g2.setFont(this.cachedFont);
296     }
297
298     /**
299      * Get the FontMetrics object for the current font
300      * @return FontMetrics object for current font
301      */

302     private FontMetrics JavaDoc getFontMetrics() {
303
304         return this.g2.getFontMetrics();
305     }
306
307     /**
308      * Get a Font object for the current fontname and fontsize
309      * @return Font object for current name and size
310      */

311     private Font JavaDoc getFont() {
312
313         return this.cachedFont;
314     }
315
316     /**
317      * Sets rendering hints for optimal rendering quality
318      * @param graphics Graphics2D object to set rendering options on
319      */

320     private void setOptimalRenderQuality(Graphics2D JavaDoc graphics) {
321
322         graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
323         graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
324         graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
325         graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
326     }
327
328     public String JavaDoc toString() {
329         return this.fontname + ", " + this.fontsize + "pt: " + this.text;
330     }
331 }
Popular Tags