KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > riotfamily > website > txt2img > ImageGenerator


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1
3  * The contents of this file are subject to the Mozilla Public License Version
4  * 1.1 (the "License"); you may not use this file except in compliance with
5  * the License. You may obtain a copy of the License at
6  * http://www.mozilla.org/MPL/
7  *
8  * Software distributed under the License is distributed on an "AS IS" basis,
9  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10  * for the specific language governing rights and limitations under the
11  * License.
12  *
13  * The Original Code is Riot.
14  *
15  * The Initial Developer of the Original Code is
16  * Neteye GmbH.
17  * Portions created by the Initial Developer are Copyright (C) 2007
18  * the Initial Developer. All Rights Reserved.
19  *
20  * Contributor(s):
21  * flx
22  *
23  * ***** END LICENSE BLOCK ***** */

24 package org.riotfamily.website.txt2img;
25
26 import java.awt.Color JavaDoc;
27 import java.awt.Dimension JavaDoc;
28 import java.awt.Font JavaDoc;
29 import java.awt.FontFormatException JavaDoc;
30 import java.awt.Graphics JavaDoc;
31 import java.awt.Graphics2D JavaDoc;
32 import java.awt.Image JavaDoc;
33 import java.awt.RenderingHints JavaDoc;
34 import java.awt.font.FontRenderContext JavaDoc;
35 import java.awt.font.LineBreakMeasurer JavaDoc;
36 import java.awt.font.TextAttribute JavaDoc;
37 import java.awt.font.TextLayout JavaDoc;
38 import java.awt.image.BufferedImage JavaDoc;
39 import java.io.IOException JavaDoc;
40 import java.io.OutputStream JavaDoc;
41 import java.text.AttributedCharacterIterator JavaDoc;
42 import java.text.AttributedString JavaDoc;
43
44 import javax.imageio.ImageIO JavaDoc;
45
46 import org.riotfamily.common.collection.FlatMap;
47 import org.riotfamily.common.util.ColorUtils;
48 import org.riotfamily.common.util.FormatUtils;
49 import org.springframework.beans.factory.InitializingBean;
50 import org.springframework.core.io.Resource;
51
52 /**
53  * @author Felix Gnass [fgnass at neteye dot de]
54  * @since 6.5
55  */

56 public class ImageGenerator implements InitializingBean {
57
58     private Font JavaDoc font = Font.getFont("Serif");
59     
60     private float size = 22;
61     
62     private int paddingTop = 0;
63     
64     private int paddingRight = 0;
65     
66     private int paddingBottom = 0;
67     
68     private int paddingLeft = 0;
69     
70     private int lineSpacing = 0;
71     
72     private Integer JavaDoc maxWidth;
73     
74     private Color JavaDoc color = Color.BLACK;
75     
76     private boolean antiAlias = true;
77     
78     private boolean resample = false;
79     
80     private int internalFontSize = 120;
81     
82     private int scale = 1;
83     
84     private FlatMap attributes = new FlatMap();
85     
86     /**
87      * Sets the font file to use. The resource must either point to a Type 1
88      * or TrueType font. The type is determined by the extension of the
89      * resource's filename (the check is case insensitive). If the extension
90      * is <i>.pfa</i> or <i>.pfb</i> {@link Font#TYPE1_FONT} is used,
91      * otherwise {@link Font#TRUETYPE_FONT}.
92      */

93     public void setFont(Resource res) throws FontFormatException JavaDoc, IOException JavaDoc {
94         String JavaDoc ext = FormatUtils.getExtension(res.getFilename()).toLowerCase();
95         int format = Font.TRUETYPE_FONT;
96         if (ext.equals("pfa") || ext.equals("pfb")) {
97             format = Font.TYPE1_FONT;
98         }
99         this.font = Font.createFont(format, res.getInputStream());
100     }
101     
102     /**
103      * Sets the text foreground color. Examples of supported formats:
104      * <pre>
105      * #fff
106      * #fffff
107      * rgb(255,255,255)
108      * rgb(100%, 100%, 100%)
109      * </pre>
110      */

111     public void setColor(String JavaDoc color) {
112         this.color = ColorUtils.parseColor(color);
113     }
114     
115     /**
116      * Sets the font size.
117      */

118     public void setSize(float size) {
119         this.size = size;
120     }
121
122     /**
123      * Turns anti-aliasing off or on (default).
124      */

125     public void setAntiAlias(boolean antiAlias) {
126         this.antiAlias = antiAlias;
127     }
128     
129     /**
130      * Sets the interline spacing in pixels. If not set,
131      * {@link TextLayout#getLeading()} is used.
132      */

133     public void setLineSpacing(int lineSpacing) {
134         this.lineSpacing = lineSpacing;
135     }
136     
137     /**
138      * Sets the maximum image width.
139      */

140     public void setMaxWidth(Integer JavaDoc maxWidth) {
141         this.maxWidth = maxWidth;
142     }
143     
144     /**
145      * Sets the padding at the top of the image in pixels.
146      * The default value is <code>0</code>.
147      */

148     public void setPaddingTop(int paddingTop) {
149         this.paddingTop = paddingTop;
150     }
151     
152     /**
153      * Sets the padding at the right side of the image in pixels.
154      * The default value is <code>0</code>.
155      */

156     public void setPaddingRight(int paddingRight) {
157         this.paddingRight = paddingRight;
158     }
159     
160     /**
161      * Sets the padding at the bottom of the image in pixels.
162      * The default value is <code>0</code>.
163      */

164     public void setPaddingBottom(int paddingBottom) {
165         this.paddingBottom = paddingBottom;
166     }
167     
168     /**
169      * Sets the padding at the left side of the image in pixels.
170      * The default value is <code>0</code>.
171      */

172     public void setPaddingLeft(int paddingLeft) {
173         this.paddingLeft = paddingLeft;
174     }
175     
176     /**
177      * If set to true, the text will be rendered at a larger size internally
178      * and scaled down to the requested size.
179      */

180     public void setResample(boolean resample) {
181         this.resample = resample;
182     }
183     
184     /**
185      * Sets the font size at which the text is rendered internally when
186      * resampling is enabled.
187      */

188     public void setInternalFontSize(int internalFontSize) {
189         this.internalFontSize = internalFontSize;
190     }
191     
192     public void afterPropertiesSet() {
193         if (resample) {
194             scale = Math.round(internalFontSize / size);
195             size *= scale;
196             paddingTop *= scale;
197             paddingRight *= scale;
198             paddingBottom *= scale;
199             paddingLeft *= scale;
200             lineSpacing *= scale;
201             if (maxWidth != null) {
202                 maxWidth = new Integer JavaDoc(maxWidth.intValue() * scale);
203             }
204         }
205         attributes.put(TextAttribute.FONT, font.deriveFont(size));
206         attributes.put(TextAttribute.FOREGROUND, color);
207     }
208     
209     public void generate(String JavaDoc text, int maxWidth, String JavaDoc color, OutputStream JavaDoc os)
210             throws IOException JavaDoc {
211         
212         if (this.maxWidth != null) {
213             maxWidth = this.maxWidth.intValue();
214         }
215         else if (resample && maxWidth < Integer.MAX_VALUE) {
216             maxWidth *= scale;
217         }
218         Dimension JavaDoc size = getSize(text, maxWidth);
219         BufferedImage JavaDoc image = createImage(size);
220         drawText(text, maxWidth, color, image);
221         if (resample) {
222             int w = (int) (size.getWidth() / scale);
223             int h = (int) (size.getHeight() / scale);
224             Image JavaDoc scaledImage = image.getScaledInstance(w, h, Image.SCALE_SMOOTH);
225             image = new BufferedImage JavaDoc(w, h, BufferedImage.TYPE_INT_ARGB);
226             Graphics JavaDoc g = image.getGraphics();
227             g.drawImage(scaledImage, 0, 0, w, h, null);
228             g.dispose();
229         }
230         
231         ImageIO.write(image, "png", os);
232         image.flush();
233     }
234     
235     protected Dimension JavaDoc getSize(String JavaDoc text, float maxWidth) {
236         return layout(text, maxWidth, null, createImage(new Dimension JavaDoc(1, 1)), false);
237     }
238     
239     protected void drawText(String JavaDoc text, float maxWidth, String JavaDoc color,
240             BufferedImage JavaDoc image) {
241         
242         layout(text, maxWidth, color, image, true);
243     }
244     
245     protected Dimension JavaDoc layout(String JavaDoc text, float maxWidth, String JavaDoc color,
246             BufferedImage JavaDoc image, boolean draw) {
247         
248         FlatMap attrs = attributes;
249         if (draw && color != null) {
250             attrs = new FlatMap(attributes);
251             attrs.put(TextAttribute.FOREGROUND, ColorUtils.parseColor(color));
252         }
253         AttributedString JavaDoc as = new AttributedString JavaDoc(text, attrs);
254         Graphics2D JavaDoc graphics = createGraphics(image);
255         FontRenderContext JavaDoc fc = graphics.getFontRenderContext();
256         AttributedCharacterIterator JavaDoc it = as.getIterator();
257         LineBreakMeasurer JavaDoc measurer = new LineBreakMeasurer JavaDoc(it, fc);
258         int y = paddingTop;
259         int maxX = 0;
260         while (measurer.getPosition() < it.getEndIndex()) {
261             TextLayout JavaDoc layout;
262             int nextBreak = text.indexOf('\n', measurer.getPosition() + 1);
263             if (nextBreak != -1) {
264                 layout = measurer.nextLayout(maxWidth, nextBreak, false);
265             }
266             else {
267                 layout = measurer.nextLayout(maxWidth);
268             }
269             y += layout.getAscent();
270             if (draw) {
271                 layout.draw(graphics, paddingLeft, y);
272             }
273             y += layout.getDescent();
274             maxX = Math.max(maxX, paddingLeft + (int) layout.getVisibleAdvance() + paddingRight);
275             y += layout.getLeading();
276             if (measurer.getPosition() < it.getEndIndex()) {
277                 y += lineSpacing;
278             }
279         }
280         y += paddingBottom;
281         graphics.dispose();
282         return new Dimension JavaDoc(maxX, y);
283     }
284     
285     protected Graphics2D JavaDoc createGraphics(BufferedImage JavaDoc image) {
286         Graphics2D JavaDoc graphics = image.createGraphics();
287         graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias
288                 ? RenderingHints.VALUE_ANTIALIAS_ON
289                 : RenderingHints.VALUE_ANTIALIAS_OFF);
290         
291         graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, antiAlias
292                 ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON
293                 : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
294         
295         graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, antiAlias
296                 ? RenderingHints.VALUE_FRACTIONALMETRICS_ON
297                 : RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
298         
299         return graphics;
300     }
301     
302     protected BufferedImage JavaDoc createImage(Dimension JavaDoc size) {
303         return new BufferedImage JavaDoc((int) size.getWidth(), (int) size.getHeight(),
304                 BufferedImage.TYPE_INT_ARGB);
305     }
306     
307 }
308
Popular Tags