Merge branch 'bug/JAL-3141_backupfiles_prefs_widget_disable_bug' into merge/develop_b...
[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"), EPS_EXTENSION,
82             EPS_DESCRIPTION),
83     PNG("PNG", MessageManager.getString("label.png_image"),
84             PNG_EXTENSION, PNG_DESCRIPTION),
85     SVG("SVG", "SVG", SVG_EXTENSION, SVG_DESCRIPTION);
86
87     private String name;
88
89     private String label;
90
91     private String extension;
92
93     private String description;
94
95     TYPE(String name, String label, String ext, String desc)
96     {
97       this.name = name;
98       this.label = label;
99       this.extension = ext;
100       this.description = desc;
101     }
102
103     public String getName()
104     {
105       return name;
106     }
107
108     public JalviewFileChooser getFileChooser()
109     {
110       return new JalviewFileChooser(extension, description);
111     }
112
113     public String getLabel()
114     {
115       return label;
116     }
117
118   }
119
120   public ImageMaker(Component parent, TYPE type, String title, int width,
121           int height, File file, String fileTitle,
122           IProgressIndicator pIndicator, long pSessionId, boolean headless)
123   {
124     this.pIndicator = pIndicator;
125     this.type = type;
126     this.pSessionId = pSessionId;
127     this.headless = headless;
128     if (file == null)
129     {
130       setProgressMessage(MessageManager.formatMessage(
131               "status.waiting_for_user_to_select_output_file", type.name));
132       JalviewFileChooser chooser;
133       chooser = type.getFileChooser();
134       chooser.setFileView(new jalview.io.JalviewFileView());
135       chooser.setDialogTitle(title);
136       chooser.setToolTipText(MessageManager.getString("action.save"));
137       int value = chooser.showSaveDialog(parent);
138
139       if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
140       {
141         jalview.bin.Cache.setProperty("LAST_DIRECTORY",
142                 chooser.getSelectedFile().getParent());
143         file = chooser.getSelectedFile();
144       }
145       else
146       {
147         setProgressMessage(MessageManager.formatMessage(
148                 "status.cancelled_image_export_operation", type.name));
149       }
150     }
151
152     if (file != null)
153     {
154       try
155       {
156         out = new FileOutputStream(file);
157         setProgressMessage(null);
158         setProgressMessage(MessageManager.formatMessage(
159                 "status.exporting_alignment_as_x_file", type.getName()));
160         if (type == TYPE.SVG)
161         {
162           setupSVG(width, height, fileTitle);
163         }
164         else if (type == TYPE.EPS)
165         {
166           setupEPS(width, height, fileTitle);
167         }
168         else if (type == TYPE.PNG)
169         {
170           setupPNG(width, height);
171         }
172
173       } catch (Exception ex)
174       {
175         System.out.println("Error creating " + type.getName() + " file.");
176
177         setProgressMessage(MessageManager
178                 .formatMessage("info.error_creating_file", type.getName()));
179       }
180     }
181   }
182
183   public Graphics getGraphics()
184   {
185     return graphics;
186   }
187
188   public void writeImage()
189   {
190     try
191     {
192       switch (type)
193       {
194       case EPS:
195         pg.flush();
196         pg.close();
197         break;
198       case SVG:
199         String svgData = ((SVGGraphics2D) getGraphics()).getSVGDocument();
200         out.write(svgData.getBytes());
201         out.flush();
202         out.close();
203         break;
204       case PNG:
205         ImageIO.write(bi, PNG_EXTENSION, out);
206         out.flush();
207         out.close();
208         break;
209       }
210     } catch (Exception ex)
211     {
212       ex.printStackTrace();
213     }
214   }
215
216   void setupEPS(int width, int height, String title)
217   {
218     boolean accurateText = true;
219
220     String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",
221             "Prompt each time");
222
223     // If we need to prompt, and if the GUI is visible then
224     // Prompt for EPS rendering style
225     if (renderStyle.equalsIgnoreCase("Prompt each time")
226             && !(System.getProperty("java.awt.headless") != null && System
227                     .getProperty("java.awt.headless").equals("true")))
228     {
229       EPSOptions eps = new EPSOptions();
230       renderStyle = eps.getValue();
231
232       if (renderStyle == null || eps.cancelled)
233       {
234         setProgressMessage(MessageManager.formatMessage(
235                 "status.cancelled_image_export_operation", "EPS"));
236         return;
237       }
238     }
239
240     if (renderStyle.equalsIgnoreCase("text"))
241     {
242       accurateText = false;
243     }
244
245     try
246     {
247       pg = new EpsGraphics2D(title, out, 0, 0, width, height);
248       Graphics2D ig2 = pg;
249       ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
250               RenderingHints.VALUE_ANTIALIAS_ON);
251
252       pg.setAccurateTextMode(accurateText);
253
254       graphics = pg;
255       setProgressMessage(MessageManager
256               .formatMessage("status.export_complete", type.getName()));
257     } catch (Exception ex)
258     {
259     }
260   }
261
262   void setupPNG(int width, int height)
263   {
264     bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
265     graphics = bi.getGraphics();
266     Graphics2D ig2 = (Graphics2D) graphics;
267     ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
268             RenderingHints.VALUE_ANTIALIAS_ON);
269     setProgressMessage(MessageManager
270             .formatMessage("status.export_complete", type.getName()));
271
272   }
273
274   void setupSVG(int width, int height, String title)
275   {
276
277     g2 = new SVGGraphics2D(width, height);
278     Graphics2D ig2 = g2;
279
280     String renderStyle = jalview.bin.Cache.getDefault("SVG_RENDERING",
281             "Prompt each time");
282
283     // If we need to prompt, and if the GUI is visible then
284     // Prompt for EPS rendering style
285     if (renderStyle.equalsIgnoreCase("Prompt each time")
286             && !(System.getProperty("java.awt.headless") != null && System
287                     .getProperty("java.awt.headless").equals("true")))
288     {
289       SVGOptions svgOption = new SVGOptions();
290       renderStyle = svgOption.getValue();
291
292       if (renderStyle == null || svgOption.cancelled)
293       {
294         setProgressMessage(MessageManager.formatMessage(
295                 "status.cancelled_image_export_operation", "SVG"));
296         return;
297       }
298     }
299
300     if (renderStyle.equalsIgnoreCase("Lineart"))
301     {
302       ig2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
303               SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
304     }
305
306     setProgressMessage(MessageManager
307             .formatMessage("status.export_complete", type.getName()));
308     graphics = g2;
309   }
310
311   static JalviewFileChooser getPNGChooser()
312   {
313     if (Jalview.isHeadlessMode())
314     {
315       return null;
316     }
317     return new JalviewFileChooser(PNG_EXTENSION, PNG_DESCRIPTION);
318   }
319
320   static JalviewFileChooser getEPSChooser()
321   {
322     if (Jalview.isHeadlessMode())
323     {
324       return null;
325     }
326     return new JalviewFileChooser(EPS_EXTENSION, EPS_DESCRIPTION);
327   }
328
329   private void setProgressMessage(String message)
330   {
331     if (pIndicator != null && !headless)
332     {
333       pIndicator.setProgressBar(message, pSessionId);
334     }
335   }
336
337   static JalviewFileChooser getSVGChooser()
338   {
339     if (Jalview.isHeadlessMode())
340     {
341       return null;
342     }
343     return new JalviewFileChooser(SVG_EXTENSION, SVG_DESCRIPTION);
344   }
345 }