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