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 info.magnolia.cms.core.Content;
37 import info.magnolia.cms.core.ItemType;
38
39 import java.awt.FontFormatException;
40 import java.awt.Graphics2D;
41 import java.awt.Image;
42 import java.awt.image.BufferedImage;
43 import java.io.File;
44 import java.io.FileNotFoundException;
45 import java.io.IOException;
46 import java.util.StringTokenizer;
47
48 import javax.imageio.ImageIO;
49 import javax.jcr.AccessDeniedException;
50 import javax.jcr.PathNotFoundException;
51 import javax.jcr.RepositoryException;
52 import javax.servlet.http.HttpServletRequest;
53 import javax.servlet.jsp.JspException;
54 import javax.servlet.jsp.JspWriter;
55 import javax.servlet.jsp.PageContext;
56
57 import org.apache.commons.lang.SystemUtils;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 public class TextToImageTag extends BaseImageTag {
97
98
99
100
101
102
103 private static final double SCALE_FACTOR = SystemUtils.IS_OS_WINDOWS ? 4 : 1;
104
105
106
107
108 private static final String CSS_CHARACTER_IMAGE = "character-image";
109
110
111
112
113 private static final String CSS_WORD_IMAGE = "word-image";
114
115
116
117
118 private static final String CSS_TEXT_IMAGE = "text-image";
119
120
121
122
123 private static final String TEXT_SPLIT_NONE = "none";
124
125
126
127
128 private static final String TEXT_SPLIT_WORDS = "words";
129
130
131
132
133 private static final String TEXT_SPLIT_CHARACTERS = "characters";
134
135 private static final Logger log = LoggerFactory.getLogger(BaseImageTag.class);
136
137 private String text;
138 private String textFontFace;
139 private int textFontSize;
140 private String textFontColor;
141 private String textBackColor;
142 private String textSplit;
143 private String divCSS;
144
145
146
147
148
149 public void setText(String text) {
150 this.text = text;
151 }
152
153
154
155
156
157 public void setImageContentNodeName(String imageContentNodeName) {
158 this.imageContentNodeName = imageContentNodeName;
159 }
160
161
162
163
164
165 public void setParentContentNodeName(String parentContentNodeName) {
166 this.parentContentNodeName = parentContentNodeName;
167 }
168
169
170
171
172
173 public void setTextFontFace(String textFontFace) {
174 this.textFontFace = textFontFace;
175 }
176
177
178
179
180
181 public void setTextFontSize(int textFontSize) {
182 this.textFontSize = textFontSize;
183 }
184
185
186
187
188
189 public void setTextFontColor(String textFontColor) {
190 this.textFontColor = textFontColor;
191 }
192
193
194
195
196
197 public void setTextBackColor(String textBackColor) {
198 this.textBackColor = textBackColor;
199 }
200
201
202
203
204
205 public void setTextSplit(String textSplit) {
206 this.textSplit = textSplit;
207 }
208
209
210
211
212
213
214 public void setDivCSS(String divCSS) {
215 this.divCSS = divCSS;
216 }
217
218
219
220
221 protected String getFilename() {
222 return "textImage";
223 }
224
225
226
227
228 public void setUp() {
229
230
231 if (this.text == null) {
232 this.text = "Test Test Test";
233 }
234 if (this.textFontFace == null) {
235 this.textFontFace = SystemUtils.IS_OS_WINDOWS ? "Arial" : "Helvetica";
236 }
237 if (this.textFontSize == 0) {
238 this.textFontSize = 12;
239 }
240 if (this.textFontColor == null) {
241 this.textFontColor = "000000";
242 }
243 if (this.textBackColor == null) {
244 this.textBackColor = "ffffff";
245 }
246 if (this.textSplit == null) {
247 this.textSplit = TEXT_SPLIT_NONE;
248 }
249 else if (!((this.textSplit.equals(TEXT_SPLIT_WORDS)) || (this.textSplit.equals(TEXT_SPLIT_CHARACTERS)))) {
250 this.textSplit = TEXT_SPLIT_NONE;
251 }
252 if (this.divCSS == null) {
253 this.divCSS = "text-box";
254 }
255 }
256
257
258
259
260 public void doTag() throws JspException {
261
262 this.setUp();
263
264 try {
265 Content imageContentNode = getImageContentNode();
266
267 String[] subStrings = this.getTextSubStrings(this.text);
268 String[] imageURIs = this.getImageURIs(
269 subStrings,
270 (HttpServletRequest) ((PageContext) this.getJspContext()).getRequest(),
271 imageContentNode);
272 this.drawTextImages(imageURIs, subStrings);
273 }
274 catch (PathNotFoundException e) {
275 log.error("PathNotFoundException occured during text-to-image conversion: " + e.getMessage(), e);
276 }
277 catch (AccessDeniedException e) {
278 log.error("AccessDeniedException occured during text-to-image conversion: " + e.getMessage(), e);
279 }
280 catch (RepositoryException e) {
281 log.error("RepositoryException occured during text-to-image conversion: " + e.getMessage(), e);
282 }
283 catch (FileNotFoundException e) {
284 log.error("FileNotFoundException occured during text-to-image conversion: " + e.getMessage(), e);
285 }
286 catch (IOException e) {
287 log.error("IOException occured during text-to-image conversion: " + e.getMessage(), e);
288 }
289 catch (FontFormatException e) {
290 log.error("FontFormatException occured during text-to-image conversion: " + e.getMessage(), e);
291 }
292 this.cleanUp();
293 }
294
295
296
297
298 public void cleanUp() {
299 this.parentContentNodeName = null;
300 this.imageContentNodeName = null;
301 this.text = null;
302 this.textFontFace = null;
303 this.textFontSize = 0;
304 this.textFontColor = null;
305 this.textBackColor = null;
306 this.textSplit = null;
307 this.divCSS = null;
308 }
309
310
311
312
313
314
315
316 private void drawTextImages(String[] imageURIs, String[] subStrings) throws IOException {
317 JspWriter out = this.getJspContext().getOut();
318
319 if (this.divCSS != null) {
320 out.print("<div class=\"");
321 out.print(this.divCSS);
322 out.print("\">");
323 }
324
325 for (int i = 0; i < imageURIs.length; i++) {
326 out.print("<img class=\"");
327 if (this.textSplit.equals(TEXT_SPLIT_CHARACTERS)) {
328 out.print(CSS_CHARACTER_IMAGE);
329 }
330 else if (this.textSplit.equals(TEXT_SPLIT_WORDS)) {
331 out.print(CSS_WORD_IMAGE);
332 }
333 else {
334 out.print(CSS_TEXT_IMAGE);
335 }
336 out.print("\" src=\"");
337 out.print(imageURIs[i]);
338 out.print("\" alt=\"");
339 out.print(subStrings[i]);
340 out.print("\" />");
341 }
342
343 if (this.divCSS != null) {
344 out.print("</div>");
345 }
346 }
347
348
349
350
351
352
353
354 private String[] getTextSubStrings(String text) {
355 String[] subStrings = null;
356 if (this.textSplit.equals(TEXT_SPLIT_CHARACTERS)) {
357 subStrings = new String[text.length()];
358 for (int i = 0; i < text.length(); i++) {
359 subStrings[i] = text.substring(i, i + 1);
360 }
361 }
362 else if (this.textSplit.equals(TEXT_SPLIT_WORDS)) {
363 StringTokenizer st = new StringTokenizer(text, " ");
364 subStrings = new String[st.countTokens()];
365 for (int i = 0; st.hasMoreTokens(); i++) {
366 subStrings[i] = st.nextToken().trim();
367 }
368 }
369 else {
370 subStrings = new String[]{text};
371 }
372 return subStrings;
373 }
374
375
376
377
378
379
380 private String[] getImageURIs(String[] subStrings, HttpServletRequest req, Content imageContentNode)
381 throws PathNotFoundException, AccessDeniedException, RepositoryException, FileNotFoundException, IOException,
382 FontFormatException {
383
384 String[] imageURIs = new String[subStrings.length];
385 for (int i = 0; i < subStrings.length; i++) {
386
387 String tmpImgNodeName = subStrings[i]
388 + this.textBackColor
389 + this.textFontColor
390 + this.textFontFace
391 + this.textFontSize;
392 String imageNodeName = this.convertToSimpleString(tmpImgNodeName);
393
394 if (!imageContentNode.hasContent(imageNodeName)) {
395 File image = createImage(subStrings[i]);
396
397
398 Content imageNode = imageContentNode.createContent(imageNodeName, ItemType.CONTENTNODE);
399
400 this.createImageNode(image, imageNode);
401 }
402
403 String contextPath = req.getContextPath();
404 String handle = imageContentNode.getHandle();
405 String imageURI = contextPath
406 + handle
407 + "/"
408 + imageNodeName
409 + "/"
410 + getFilename()
411 + "."
412 + PROPERTIES_EXTENSION_VALUE;
413 imageURIs[i] = imageURI;
414 }
415 return imageURIs;
416 }
417
418
419
420
421
422
423 private File createImage(String subString) throws FileNotFoundException, IOException, FontFormatException {
424
425
426 File imageFile = File.createTempFile(getClass().getName(), "png");
427 imageFile.createNewFile();
428
429
430
431
432 Text2PngFactory tpf = new Text2PngFactory();
433 tpf.setFontFace(this.textFontFace);
434 tpf.setFontSize((int) (this.textFontSize * SCALE_FACTOR));
435 int[] textRGB = this.convertHexToRGB(this.textFontColor);
436 int[] backRGB = this.convertHexToRGB(this.textBackColor);
437 tpf.setTextRGB(textRGB[0], textRGB[1], textRGB[2]);
438 tpf.setBackgroundRGB(backRGB[0], backRGB[1], backRGB[2]);
439 tpf.setText(subString);
440
441 BufferedImage bigImgBuff = (BufferedImage) tpf.createImage();
442 if (SCALE_FACTOR != 1) {
443 BufferedImage smallImgBuff = this.scaleImage(bigImgBuff, (1.0 / SCALE_FACTOR));
444 ImageIO.write(smallImgBuff, "png", imageFile);
445 smallImgBuff = null;
446 }
447 else {
448 ImageIO.write(bigImgBuff, "png", imageFile);
449 }
450 bigImgBuff = null;
451 return imageFile;
452 }
453
454
455
456
457
458
459
460 private BufferedImage scaleImage(BufferedImage oriImgBuff, double scaleFactor) {
461
462
463 int oriWidth = oriImgBuff.getWidth();
464 int oriHeight = oriImgBuff.getHeight();
465
466 int newWidth = new Double(oriWidth * scaleFactor).intValue();
467 int newHeight = new Double(oriHeight * scaleFactor).intValue();
468
469 Image newImg = oriImgBuff.getScaledInstance(newWidth, newHeight, Image.SCALE_AREA_AVERAGING);
470 BufferedImage newImgBuff = new BufferedImage(
471 newImg.getWidth(null),
472 newImg.getHeight(null),
473 BufferedImage.TYPE_INT_RGB);
474 Graphics2D g = newImgBuff.createGraphics();
475 g.drawImage(newImg, 0, 0, null);
476 g.dispose();
477
478 return newImgBuff;
479 }
480
481 }