db0e132988a71f741d1669eea83ed16e409ec2af
[scilab.git] / scilab / modules / helptools / src / java / org / scilab / modules / helptools / image / ImageConverter.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - Calixte DENIZET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.helptools.image;
14
15 import java.awt.Graphics2D;
16 import java.awt.Color;
17 import java.awt.image.BufferedImage;
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.FileOutputStream;
21 import java.io.IOException;
22 import java.io.OutputStream;
23 import java.io.StringReader;
24 import java.net.URI;
25 import java.net.URISyntaxException;
26 import java.nio.channels.FileChannel;
27 import java.util.HashMap;
28 import java.util.Map;
29
30 import javax.activation.MimetypesFileTypeMap;
31 import javax.imageio.ImageIO;
32 import javax.swing.Icon;
33 import javax.swing.ImageIcon;
34 import javax.swing.JLabel;
35
36 /**
37  * Class to handle the image conversion
38  * @author Calixte DENIZET
39  */
40 public final class ImageConverter {
41
42     private static Map<String, ExternalImageConverter> externalConverters = new HashMap<String, ExternalImageConverter>();
43     private static MimetypesFileTypeMap mimeMap = new MimetypesFileTypeMap();
44
45     static {
46         mimeMap.addMimeTypes("type=image/latex exts=tex,latex");
47         mimeMap.addMimeTypes("type=image/mathml exts=mml,mathml");
48         mimeMap.addMimeTypes("type=image/svg exts=svg");
49         mimeMap.addMimeTypes("type=image/scilab exts=sce");
50         mimeMap.addMimeTypes("type=image/scilab-xcos exts=xcos,zcos");
51     }
52
53     /**
54      * Register a new ExternalImageConverter
55      * @param c the converter to register
56      */
57     public static void registerExternalImageConverter(ExternalImageConverter c) {
58         if (c != null) {
59             externalConverters.put(c.getMimeType(), c);
60         }
61     }
62
63     /**
64      * @param attrs the attribute of the image
65      * @param path the current XML file which is parsed
66      * @param image the filename
67      * @param destDir the destination directory
68      * @return the HTML code to insert the image
69      */
70     public static String getImageByFile(Map<String, String> attrs, String path, String image, String outputDir, String destDir) {
71         File f = new File(image);
72         if (!f.isAbsolute()) {
73             f = new File(path + File.separator + image);
74         }
75
76         String destFile = outputDir + File.separator + destDir + File.separator + f.getName();
77
78         ExternalImageConverter conv = externalConverters.get(mimeMap.getContentType(f));
79         if (conv != null) {
80             destFile += ".png";
81         }
82         File imageFile = new File(destFile);
83         String imageName = destDir + "/" + imageFile.getName();
84
85         if (f.lastModified() > imageFile.lastModified()) {
86             if (conv != null) {
87                 return conv.convertToImage(f, attrs, imageFile, imageName);
88             }
89             copyImageFile(f, destDir);
90         }
91
92         return "<img src=\'" + imageName + "\'/>";
93     }
94
95
96     /**
97      * @param code the code to translate
98      * @param attrs the attribute of the image
99      * @param mime type
100      * @param imageFile the filename
101      * @return the HTML code to insert the image
102      */
103     public static String getImageByCode(String currentFile, String code, Map<String, String> attrs, String mime, File imageFile, String imageName) {
104         File current = null;
105         try {
106             current = new File(new URI(currentFile));
107         } catch (URISyntaxException e) { }
108
109         ExternalImageConverter conv = externalConverters.get(mime);
110         if (conv == null) {
111             System.err.println("In file " + currentFile + "invalid code:\n" + code);
112             return null;
113         }
114
115         if (conv.mustRegenerate() || current == null || current.lastModified() > imageFile.lastModified()) {
116             return conv.convertToImage(currentFile, code, attrs, imageFile, imageName);
117         }
118
119         return "<img src=\'" + imageName + "\'/>";
120     }
121
122     /**
123      * @param code the code to translate
124      * @param img image informations
125      * @param fileName the filename
126      * @param attrs the attribute of the image
127      * @return the HTML code to insert the image
128      */
129     public static String generateCode(Image img, String fileName, Map<String, String> attrs) {
130         String style = attrs.get("style");
131         String top = "";
132         boolean display = style != null && style.equals("display");
133
134         if (!display) {
135             top = "top:" + img.descent + "px;";
136         }
137
138         String alignAttr = attrs.get("align");
139         String align = "";
140         String div = "div";
141         if (alignAttr != null) {
142             align = " style=\'text-align:" + alignAttr + "\'";
143         } else if (display) {
144             align = " style=\'text-align:center\'";
145         } else {
146             div = "span";
147         }
148
149         return "<" + div + align + "><img src=\'" + fileName + "\' style=\'position:relative;" + top  + "width:" + img.width + "px;height:" + img.height + "px\'/></" + div + ">";
150     }
151
152     /**
153      * Test if an image file exists.
154      * @param path of the parsed file
155      * @param image the image name
156      * @return true if the image exists
157      */
158     public static boolean imageExists(String path, String image) {
159         File f = new File(image);
160         if (!f.isAbsolute()) {
161             f = new File(path + File.separator + image);
162         }
163
164         return f.exists();
165     }
166
167     /**
168      * @param f the file to copy
169      * @param destDir the destination directory
170      */
171     public static void copyImageFile(File f, String destDir) {
172         FileChannel src = null;
173         FileChannel dest = null;
174         try {
175             File destFile = new File(destDir + File.separator + f.getName());
176             if (!destFile.exists()) {
177                 destFile.createNewFile();
178             } else if (f.lastModified() <= destFile.lastModified()) {
179                 return;
180             }
181
182             src = new FileInputStream(f).getChannel();
183             dest = new FileOutputStream(destFile).getChannel();
184             dest.transferFrom(src, 0, src.size());
185         } catch (IOException e) {
186             System.err.println(e);
187         } finally {
188             try {
189                 if (src != null) {
190                     src.close();
191                 }
192                 if (dest != null) {
193                     dest.close();
194                 }
195             } catch (IOException e) {
196                 System.err.println(e);
197             }
198         }
199     }
200
201     /**
202      * @param icon the icon to convert into PNG
203      * @param imageFile the destination file
204      * @return true if all is ok
205      */
206     public static boolean convertIconToPNG(Icon icon, File imageFile) {
207         BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
208         Graphics2D g2d = image.createGraphics();
209         icon.paintIcon(null, g2d, 0, 0);
210
211         try {
212             ImageIO.write(image, "png", imageFile.getAbsoluteFile());
213         } catch (IOException ex) {
214             return false;
215         }
216
217         g2d.dispose();
218
219         return true;
220     }
221 }