1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.cms.taglibs.util;
35
36 import java.awt.Color;
37 import java.awt.Font;
38 import java.awt.FontFormatException;
39 import java.awt.FontMetrics;
40 import java.awt.Graphics2D;
41 import java.awt.RenderingHints;
42 import java.awt.font.FontRenderContext;
43 import java.awt.font.TextLayout;
44 import java.awt.geom.Rectangle2D;
45 import java.awt.image.BufferedImage;
46 import java.awt.image.RenderedImage;
47 import java.io.File;
48 import java.io.FileInputStream;
49 import java.io.IOException;
50 import java.io.InputStream;
51
52 import javax.imageio.ImageIO;
53
54
55
56
57
58
59
60
61 public class Text2PngFactory {
62
63
64 private String fontname;
65
66
67 private int fontsize;
68
69
70 private String text = "";
71
72
73 private int r = 0;
74
75 private int g = 0;
76
77 private int b = 0;
78
79
80 private int br = 0xff;
81
82 private int bg = 0xff;
83
84 private int bb = 0xff;
85
86
87 private Graphics2D g2;
88
89
90 private Font cachedFont;
91
92
93
94
95 public Text2PngFactory() {
96
97 this.g2 = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR).createGraphics();
98
99 setOptimalRenderQuality(this.g2);
100 }
101
102
103
104
105
106
107
108
109 public Text2PngFactory(String fontname, int fontsize) throws IOException, FontFormatException {
110 this(fontname, fontsize, "");
111 }
112
113
114
115
116
117
118
119
120
121 public Text2PngFactory(String fontname, int fontsize, String text) throws IOException, FontFormatException {
122
123
124 this.g2 = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR).createGraphics();
125
126 setOptimalRenderQuality(this.g2);
127 this.setFontFace(fontname);
128 this.setFontSize(fontsize);
129 this.setText(text);
130 }
131
132
133
134
135
136
137 public void createPngFile(String location) throws IOException {
138 createPngFile(new File(location));
139 }
140
141
142
143
144
145
146 public void createPngFile(File location) throws IOException {
147 ImageIO.write(createImage(), "png", location);
148 }
149
150
151
152
153
154
155 public RenderedImage createImage() throws IOException {
156
157 if (this.fontname == null) {
158 throw new IOException("No font name given!");
159 }
160
161
162 FontRenderContext frc = this.g2.getFontRenderContext();
163 TextLayout layout = new TextLayout(this.text, this.cachedFont, frc);
164 Rectangle2D bounds = layout.getBounds();
165
166
167
168 int stringWidth = (int) (Math.ceil(bounds.getWidth())) + 2;
169
170
171
172
173 FontMetrics fm = this.g2.getFontMetrics();
174 int stringHeight = fm.getHeight();
175
176
177 BufferedImage im = new BufferedImage(stringWidth, stringHeight, BufferedImage.TYPE_3BYTE_BGR);
178
179
180 Graphics2D graphics = im.createGraphics();
181
182
183 setOptimalRenderQuality(graphics);
184
185
186 graphics.setBackground(new Color(this.br, this.bg, this.bb));
187 graphics.setColor(new Color(this.r, this.g, this.b));
188 graphics.clearRect(0, 0, stringWidth, stringHeight);
189
190
191 graphics.setFont(getFont());
192
193
194
195 layout.draw(graphics, -(float) Math.floor(bounds.getX()), fm.getMaxAscent());
196
197
198 return im;
199 }
200
201
202
203
204
205 public void setText(String text) {
206 this.text = text;
207 }
208
209
210
211
212
213
214
215 public void setTextRGB(int r, int g, int b) {
216 this.r = r;
217 this.g = g;
218 this.b = b;
219 }
220
221
222
223
224
225
226
227 public void setBackgroundRGB(int r, int g, int b) {
228 this.br = r;
229 this.bg = g;
230 this.bb = b;
231 }
232
233
234
235
236
237 public void setFontFace(String fontname) throws IOException, FontFormatException {
238
239 if (!fontname.equals(this.fontname)) {
240 this.fontname = fontname;
241 updateFace();
242 }
243 }
244
245
246
247
248
249 public void setFontSize(int fontsize) {
250 if (fontsize != this.fontsize) {
251 this.fontsize = fontsize;
252 updateSize();
253 }
254 }
255
256
257
258
259
260
261 private void updateFace() throws IOException, FontFormatException {
262 Font createdFont = null;
263
264
265 String fontpath = "fonts/" + this.fontname + ".ttf";
266
267 InputStream fontStream = this.getClass().getClassLoader().getResourceAsStream(fontpath);
268 if (fontStream != null) {
269 createdFont = Font.createFont(Font.TRUETYPE_FONT, fontStream);
270 fontStream.close();
271 }
272
273 if (createdFont == null) {
274 Font tempFont = new Font(this.fontname, Font.PLAIN, 1);
275
276
277 if (tempFont.getFamily().equals(this.fontname)) {
278
279 createdFont = tempFont;
280 }
281 }
282
283 if (createdFont == null) {
284 fontStream = new FileInputStream(this.fontname);
285
286 if (fontStream != null) {
287 createdFont = Font.createFont(Font.TRUETYPE_FONT, fontStream);
288 fontStream.close();
289 }
290 }
291
292 if (createdFont == null) {
293 throw new IOException("Can't locate font: " + this.fontname);
294 }
295
296
297 this.cachedFont = createdFont.deriveFont((float) this.fontsize);
298
299
300 this.g2.setFont(this.cachedFont);
301 }
302
303
304
305
306 private void updateSize() {
307
308 if (this.cachedFont == null) {
309 return;
310 }
311
312
313 this.cachedFont = this.cachedFont.deriveFont((float) this.fontsize);
314
315
316 this.g2.setFont(this.cachedFont);
317 }
318
319
320
321
322
323 private FontMetrics getFontMetrics() {
324
325 return this.g2.getFontMetrics();
326 }
327
328
329
330
331
332 private Font getFont() {
333
334 return this.cachedFont;
335 }
336
337
338
339
340
341 private void setOptimalRenderQuality(Graphics2D graphics) {
342
343 graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
344 graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
345 graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
346 graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
347 }
348
349 public String toString() {
350 return this.fontname + ", " + this.fontsize + "pt: " + this.text;
351 }
352 }