284b7becc010298f981b3d41653b7789b2451b0d
[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.IProgressIndicator;
25 import jalview.gui.LineartOptions;
26 import jalview.io.JalviewFileChooser;
27
28 import java.awt.Component;
29 import java.awt.Graphics;
30 import java.awt.Graphics2D;
31 import java.awt.RenderingHints;
32 import java.awt.image.BufferedImage;
33 import java.io.File;
34 import java.io.FileOutputStream;
35
36 import javax.imageio.ImageIO;
37
38 import org.jfree.graphics2d.svg.SVGGraphics2D;
39 import org.jfree.graphics2d.svg.SVGHints;
40 import org.jibble.epsgraphics.EpsGraphics2D;
41
42 public class ImageMaker
43 {
44   public static final String SVG_DESCRIPTION = "Scalable Vector Graphics";
45
46   public static final String SVG_EXTENSION = "svg";
47
48   public static final String EPS_DESCRIPTION = "Encapsulated Postscript";
49
50   public static final String EPS_EXTENSION = "eps";
51
52   public static final String PNG_EXTENSION = "png";
53
54   public static final String PNG_DESCRIPTION = "Portable  network graphics";
55
56   public static final String HTML_EXTENSION = "html";
57
58   public static final String HTML_DESCRIPTION = "Hypertext Markup Language";
59
60   EpsGraphics2D pg;
61
62   SVGGraphics2D g2;
63
64   Graphics graphics;
65
66   FileOutputStream out;
67
68   BufferedImage bi;
69
70   TYPE type;
71
72   private IProgressIndicator pIndicator;
73
74   private long pSessionId;
75
76   private boolean headless;
77
78   public enum TYPE
79   {
80     EPS("EPS", MessageManager.getString("label.eps_file"), getEPSChooser()),
81     PNG("PNG", MessageManager.getString("label.png_image"),
82             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       // TODO: JAL-3048 export SVG/EPS/PNG- not required for Jalview-JS
126
127       setProgressMessage(MessageManager.formatMessage(
128               "status.waiting_for_user_to_select_output_file", type.name));
129       JalviewFileChooser chooser;
130       chooser = type.getChooser();
131       chooser.setFileView(new jalview.io.JalviewFileView());
132       chooser.setDialogTitle(title);
133       chooser.setToolTipText(MessageManager.getString("action.save"));
134       int value = chooser.showSaveDialog(parent);
135
136       if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
137       {
138         jalview.bin.Cache.setProperty("LAST_DIRECTORY",
139                 chooser.getSelectedFile().getParent());
140         file = chooser.getSelectedFile();
141       }
142       else
143       {
144         setProgressMessage(MessageManager.formatMessage(
145                 "status.cancelled_image_export_operation", type.name));
146       }
147     }
148     // TODO JAL-3048 refactor to method called by constructor or callback
149     if (file != null)
150     {
151       try
152       {
153         out = new FileOutputStream(file);
154         setProgressMessage(null);
155         setProgressMessage(MessageManager.formatMessage(
156                 "status.exporting_alignment_as_x_file", type.getName()));
157         if (type == TYPE.SVG)
158         {
159           setupSVG(width, height, fileTitle);
160         }
161         else if (type == TYPE.EPS)
162         {
163           setupEPS(width, height, fileTitle);
164         }
165         else if (type == TYPE.PNG)
166         {
167           setupPNG(width, height);
168         }
169
170       } catch (Exception ex)
171       {
172         System.out.println("Error creating " + type.getName() + " file.");
173
174         setProgressMessage(MessageManager
175                 .formatMessage("info.error_creating_file", type.getName()));
176       }
177     }
178   }
179
180   public Graphics getGraphics()
181   {
182     return graphics;
183   }
184
185   public void writeImage()
186   {
187     try
188     {
189       switch (type)
190       {
191       case EPS:
192         pg.flush();
193         pg.close();
194         break;
195       case SVG:
196         String svgData = ((SVGGraphics2D) getGraphics()).getSVGDocument();
197         out.write(svgData.getBytes());
198         out.flush();
199         out.close();
200         break;
201       case PNG:
202         ImageIO.write(bi, PNG_EXTENSION, out);
203         out.flush();
204         out.close();
205         break;
206       }
207     } catch (Exception ex)
208     {
209       ex.printStackTrace();
210     }
211   }
212
213   void setupEPS(int width, int height, String title)
214   {
215     boolean accurateText = true;
216
217     String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",
218             "Prompt each time");
219
220     // If we need to prompt, and if the GUI is visible then
221     // Prompt for EPS rendering style
222     if (renderStyle.equalsIgnoreCase("Prompt each time")
223             && !(System.getProperty("java.awt.headless") != null && System
224                     .getProperty("java.awt.headless").equals("true")))
225     {
226       LineartOptions eps = new LineartOptions("EPS_RENDERING", "EPS");
227       renderStyle = eps.getValue();
228
229       if (renderStyle == null || eps.cancelled)
230       {
231         setProgressMessage(MessageManager.formatMessage(
232                 "status.cancelled_image_export_operation", "EPS"));
233         return;
234       }
235     }
236
237     if (renderStyle.equalsIgnoreCase("text"))
238     {
239       accurateText = false;
240     }
241
242     try
243     {
244       pg = new EpsGraphics2D(title, out, 0, 0, width, height);
245       Graphics2D ig2 = pg;
246       ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
247               RenderingHints.VALUE_ANTIALIAS_ON);
248
249       pg.setAccurateTextMode(accurateText);
250
251       graphics = pg;
252       setProgressMessage(MessageManager
253               .formatMessage("status.export_complete", type.getName()));
254     } catch (Exception ex)
255     {
256     }
257   }
258
259   void setupPNG(int width, int height)
260   {
261     bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
262     graphics = bi.getGraphics();
263     Graphics2D ig2 = (Graphics2D) graphics;
264     ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
265             RenderingHints.VALUE_ANTIALIAS_ON);
266     setProgressMessage(MessageManager
267             .formatMessage("status.export_complete", type.getName()));
268
269   }
270
271   void setupSVG(int width, int height, String title)
272   {
273
274     g2 = new SVGGraphics2D(width, height);
275     Graphics2D ig2 = g2;
276
277     String renderStyle = jalview.bin.Cache.getDefault("SVG_RENDERING",
278             "Prompt each time");
279
280     // If we need to prompt, and if the GUI is visible then
281     // Prompt for EPS rendering style
282     if (renderStyle.equalsIgnoreCase("Prompt each time")
283             && !(System.getProperty("java.awt.headless") != null && System
284                     .getProperty("java.awt.headless").equals("true")))
285     {
286       LineartOptions svgOption = new LineartOptions("SVG_RENDERING", "SVG");
287       renderStyle = svgOption.getValue();
288
289       if (renderStyle == null || svgOption.cancelled)
290       {
291         setProgressMessage(MessageManager.formatMessage(
292                 "status.cancelled_image_export_operation", "SVG"));
293         return;
294       }
295     }
296
297     if (renderStyle.equalsIgnoreCase("Lineart"))
298     {
299       ig2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
300               SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
301     }
302
303     setProgressMessage(MessageManager
304             .formatMessage("status.export_complete", type.getName()));
305     graphics = g2;
306   }
307
308   static JalviewFileChooser getPNGChooser()
309   {
310     if (Jalview.isHeadlessMode())
311     {
312       return null;
313     }
314     return new JalviewFileChooser(PNG_EXTENSION, PNG_DESCRIPTION);
315   }
316
317   static JalviewFileChooser getEPSChooser()
318   {
319     if (Jalview.isHeadlessMode())
320     {
321       return null;
322     }
323     return new JalviewFileChooser(EPS_EXTENSION, EPS_DESCRIPTION);
324   }
325
326   private void setProgressMessage(String message)
327   {
328     if (pIndicator != null && !headless)
329     {
330       pIndicator.setProgressBar(message, pSessionId);
331     }
332   }
333
334   static JalviewFileChooser getSVGChooser()
335   {
336     if (Jalview.isHeadlessMode())
337     {
338       return null;
339     }
340     return new JalviewFileChooser(SVG_EXTENSION, SVG_DESCRIPTION);
341   }
342 }