JAL-2446 merged to spike branch
[jalview.git] / src / jalview / util / ImageMaker.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.util;
22
23 import jalview.bin.Jalview;
24 import jalview.gui.EPSOptions;
25 import jalview.gui.IProgressIndicator;
26 import jalview.gui.SVGOptions;
27 import jalview.io.JalviewFileChooser;
28
29 import java.awt.Component;
30 import java.awt.Graphics;
31 import java.awt.Graphics2D;
32 import java.awt.RenderingHints;
33 import java.awt.image.BufferedImage;
34 import java.io.File;
35 import java.io.FileOutputStream;
36
37 import javax.imageio.ImageIO;
38
39 import org.jfree.graphics2d.svg.SVGGraphics2D;
40 import org.jfree.graphics2d.svg.SVGHints;
41 import org.jibble.epsgraphics.EpsGraphics2D;
42
43 public class ImageMaker
44 {
45   public static final String SVG_DESCRIPTION = "Scalable Vector Graphics";
46
47   public static final String SVG_EXTENSION = "svg";
48
49   public static final String EPS_DESCRIPTION = "Encapsulated Postscript";
50
51   public static final String EPS_EXTENSION = "eps";
52
53   public static final String PNG_EXTENSION = "png";
54
55   public static final String PNG_DESCRIPTION = "Portable  network graphics";
56
57   public static final String HTML_EXTENSION = "html";
58
59   public static final String HTML_DESCRIPTION = "Hypertext Markup Language";
60
61   EpsGraphics2D pg;
62
63   SVGGraphics2D g2;
64
65   Graphics graphics;
66
67   FileOutputStream out;
68
69   BufferedImage bi;
70
71   TYPE type;
72
73   private IProgressIndicator pIndicator;
74
75   private long pSessionId;
76
77   private boolean headless;
78
79   public enum TYPE
80   {
81     EPS("EPS", MessageManager.getString("label.eps_file"), getEPSChooser()),
82     PNG("PNG", MessageManager.getString("label.png_image"), getPNGChooser()),
83     SVG("SVG", "SVG", getSVGChooser());
84
85     private JalviewFileChooser chooser;
86
87     private String name;
88
89     private String label;
90
91     TYPE(String name, String label, JalviewFileChooser chooser)
92     {
93       this.name = name;
94       this.label = label;
95       this.chooser = chooser;
96     }
97
98     public String getName()
99     {
100       return name;
101     }
102
103     public JalviewFileChooser getChooser()
104     {
105       return chooser;
106     }
107
108     public String getLabel()
109     {
110       return label;
111     }
112
113   }
114
115   public ImageMaker(Component parent, TYPE type, String title, int width,
116           int height, File file, String fileTitle,
117           IProgressIndicator pIndicator, long pSessionId, boolean headless)
118   {
119     this.pIndicator = pIndicator;
120     this.type = type;
121     this.pSessionId = pSessionId;
122     this.headless = headless;
123     if (file == null)
124     {
125       setProgressMessage(MessageManager.formatMessage(
126               "status.waiting_for_user_to_select_output_file", type.name));
127       JalviewFileChooser chooser;
128       chooser = type.getChooser();
129       chooser.setFileView(new jalview.io.JalviewFileView());
130       chooser.setDialogTitle(title);
131       chooser.setToolTipText(MessageManager.getString("action.save"));
132       int value = chooser.showSaveDialog(parent);
133
134       if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
135       {
136         jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
137                 .getSelectedFile().getParent());
138         file = chooser.getSelectedFile();
139       }
140       else
141       {
142         setProgressMessage(MessageManager.formatMessage(
143                 "status.cancelled_image_export_operation", type.name));
144       }
145     }
146
147     if (file != null)
148     {
149       try
150       {
151         out = new FileOutputStream(file);
152         setProgressMessage(null);
153         setProgressMessage(MessageManager.formatMessage(
154                 "status.exporting_alignment_as_x_file", type.getName()));
155         if (type == TYPE.SVG)
156         {
157           setupSVG(width, height, fileTitle);
158         }
159         else if (type == TYPE.EPS)
160         {
161           setupEPS(width, height, fileTitle);
162         }
163         else if (type == TYPE.PNG)
164         {
165           setupPNG(width, height);
166         }
167
168       } catch (Exception ex)
169       {
170         System.out.println("Error creating " + type.getName() + " file.");
171
172         setProgressMessage(MessageManager.formatMessage(
173                 "info.error_creating_file", type.getName()));
174       }
175     }
176   }
177
178   public Graphics getGraphics()
179   {
180     return graphics;
181   }
182
183   public void writeImage()
184   {
185     try
186     {
187       switch (type)
188       {
189       case EPS:
190         pg.flush();
191         pg.close();
192         break;
193       case SVG:
194         String svgData = ((SVGGraphics2D) getGraphics()).getSVGDocument();
195         out.write(svgData.getBytes());
196         out.flush();
197         out.close();
198         break;
199       case PNG:
200         ImageIO.write(bi, PNG_EXTENSION, out);
201         out.flush();
202         out.close();
203         break;
204       }
205     } catch (Exception ex)
206     {
207       ex.printStackTrace();
208     }
209   }
210
211   void setupEPS(int width, int height, String title)
212   {
213     boolean accurateText = true;
214
215     String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",
216             "Prompt each time");
217
218     // If we need to prompt, and if the GUI is visible then
219     // Prompt for EPS rendering style
220     if (renderStyle.equalsIgnoreCase("Prompt each time")
221             && !(System.getProperty("java.awt.headless") != null && System
222                     .getProperty("java.awt.headless").equals("true")))
223     {
224       EPSOptions eps = new EPSOptions();
225       renderStyle = eps.getValue();
226
227       if (renderStyle == null || eps.cancelled)
228       {
229         setProgressMessage(MessageManager.formatMessage(
230                 "status.cancelled_image_export_operation", "EPS"));
231         return;
232       }
233     }
234
235     if (renderStyle.equalsIgnoreCase("text"))
236     {
237       accurateText = false;
238     }
239
240     try
241     {
242       pg = new EpsGraphics2D(title, out, 0, 0, width, height);
243       Graphics2D ig2 = pg;
244       ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
245               RenderingHints.VALUE_ANTIALIAS_ON);
246
247       pg.setAccurateTextMode(accurateText);
248
249       graphics = pg;
250       setProgressMessage(MessageManager.formatMessage(
251               "status.export_complete", type.getName()));
252     } catch (Exception ex)
253     {
254     }
255   }
256
257   void setupPNG(int width, int height)
258   {
259     bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
260     graphics = bi.getGraphics();
261     Graphics2D ig2 = (Graphics2D) graphics;
262     ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
263             RenderingHints.VALUE_ANTIALIAS_ON);
264     setProgressMessage(MessageManager.formatMessage(
265             "status.export_complete", type.getName()));
266
267   }
268
269   void setupSVG(int width, int height, String title)
270   {
271
272     g2 = new SVGGraphics2D(width, height);
273     Graphics2D ig2 = g2;
274
275     String renderStyle = jalview.bin.Cache.getDefault("SVG_RENDERING",
276             "Prompt each time");
277
278     // If we need to prompt, and if the GUI is visible then
279     // Prompt for EPS rendering style
280     if (renderStyle.equalsIgnoreCase("Prompt each time")
281             && !(System.getProperty("java.awt.headless") != null && System
282                     .getProperty("java.awt.headless").equals("true")))
283     {
284       SVGOptions svgOption = new SVGOptions();
285       renderStyle = svgOption.getValue();
286
287       if (renderStyle == null || svgOption.cancelled)
288       {
289         setProgressMessage(MessageManager.formatMessage(
290                 "status.cancelled_image_export_operation", "SVG"));
291         return;
292       }
293     }
294
295     if (renderStyle.equalsIgnoreCase("Lineart"))
296     {
297       ig2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
298               SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
299     }
300
301     setProgressMessage(MessageManager.formatMessage(
302             "status.export_complete", type.getName()));
303     graphics = g2;
304   }
305
306   static JalviewFileChooser getPNGChooser()
307   {
308     if (Jalview.isHeadlessMode())
309     {
310       return null;
311     }
312     return new JalviewFileChooser(PNG_EXTENSION, PNG_DESCRIPTION);
313   }
314
315   static JalviewFileChooser getEPSChooser()
316   {
317     if (Jalview.isHeadlessMode())
318     {
319       return null;
320     }
321     return new JalviewFileChooser(EPS_EXTENSION, EPS_DESCRIPTION);
322   }
323
324   private void setProgressMessage(String message)
325   {
326     if (pIndicator != null && !headless)
327     {
328       pIndicator.setProgressBar(message, pSessionId);
329     }
330   }
331
332   static JalviewFileChooser getSVGChooser()
333   {
334     if (Jalview.isHeadlessMode())
335     {
336       return null;
337     }
338     return new JalviewFileChooser(SVG_EXTENSION, SVG_DESCRIPTION);
339   }
340 }