Helptools error reports: print out the expected file path on fileref error
[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 null if the image exists, the expected file path otherwise.
157      */
158     public static File 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         if (f.exists()) {
165             return null;
166         } else {
167             return f;
168         }
169     }
170
171     /**
172      * @param f the file to copy
173      * @param destDir the destination directory
174      */
175     public static void copyImageFile(File f, String destDir) {
176         FileChannel src = null;
177         FileChannel dest = null;
178         try {
179             File destFile = new File(destDir + File.separator + f.getName());
180             if (!destFile.exists()) {
181                 destFile.createNewFile();
182             } else if (f.lastModified() <= destFile.lastModified()) {
183                 return;
184             }
185
186             src = new FileInputStream(f).getChannel();
187             dest = new FileOutputStream(destFile).getChannel();
188             dest.transferFrom(src, 0, src.size());
189         } catch (IOException e) {
190             System.err.println(e);
191         } finally {
192             try {
193                 if (src != null) {
194                     src.close();
195                 }
196                 if (dest != null) {
197                     dest.close();
198                 }
199             } catch (IOException e) {
200                 System.err.println(e);
201             }
202         }
203     }
204
205     /**
206      * @param icon the icon to convert into PNG
207      * @param imageFile the destination file
208      * @return true if all is ok
209      */
210     public static boolean convertIconToPNG(Icon icon, File imageFile) {
211         BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
212         Graphics2D g2d = image.createGraphics();
213         icon.paintIcon(null, g2d, 0, 0);
214
215         try {
216             ImageIO.write(image, "png", imageFile.getAbsoluteFile());
217         } catch (IOException ex) {
218             return false;
219         }
220
221         g2d.dispose();
222
223         return true;
224     }
225 }