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