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