JAL-3085 spike - will need to cherrypick from this 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.awt.print.PageFormat;
35 import java.awt.print.Paper;
36 import java.io.File;
37 import java.io.FileOutputStream;
38
39 import javax.imageio.ImageIO;
40
41 import org.jfree.graphics2d.svg.SVGGraphics2D;
42 import org.jfree.graphics2d.svg.SVGHints;
43 import org.jibble.epsgraphics.EpsGraphics2D;
44
45 import gnu.jpdf.PDFJob;
46
47 public class ImageMaker
48 {
49   public static final String SVG_DESCRIPTION = "Scalable Vector Graphics";
50
51   public static final String SVG_EXTENSION = "svg";
52
53   public static final String EPS_DESCRIPTION = "Encapsulated Postscript";
54
55   public static final String EPS_EXTENSION = "eps";
56
57   public static final String PNG_EXTENSION = "png";
58
59   public static final String PNG_DESCRIPTION = "Portable  network graphics";
60
61   public static final String PDF_EXTENSION = "pdf";
62
63   public static final String PDF_DESCRIPTION = "Portable  Document Format";
64
65   public static final String HTML_EXTENSION = "html";
66
67   public static final String HTML_DESCRIPTION = "Hypertext Markup Language";
68
69   EpsGraphics2D pg;
70
71   SVGGraphics2D g2;
72
73
74   Graphics graphics;
75
76   FileOutputStream out;
77
78   BufferedImage bi;
79
80   TYPE type;
81
82   private IProgressIndicator pIndicator;
83
84   private long pSessionId;
85
86   private boolean headless;
87
88   private PDFJob pdfjob;
89
90   public enum TYPE
91   {
92     EPS("EPS", MessageManager.getString("label.eps_file"), getEPSChooser()),
93     PNG("PNG", MessageManager.getString("label.png_image"),
94             getPNGChooser()),
95     SVG("SVG", "SVG", getSVGChooser()),
96     PDF("PDF","PDF",getPDFChooser());
97
98     private JalviewFileChooser chooser;
99
100     private String name;
101
102     private String label;
103
104     TYPE(String name, String label, JalviewFileChooser chooser)
105     {
106       this.name = name;
107       this.label = label;
108       this.chooser = chooser;
109     }
110
111     public String getName()
112     {
113       return name;
114     }
115
116     public JalviewFileChooser getChooser()
117     {
118       return chooser;
119     }
120
121     public String getLabel()
122     {
123       return label;
124     }
125
126   }
127
128   public ImageMaker(Component parent, TYPE type, String title, int width,
129           int height, File file, String fileTitle,
130           IProgressIndicator pIndicator, long pSessionId, boolean headless)
131   {
132     this.pIndicator = pIndicator;
133     this.type = type;
134     this.pSessionId = pSessionId;
135     this.headless = headless;
136     if (file == null)
137     {
138       setProgressMessage(MessageManager.formatMessage(
139               "status.waiting_for_user_to_select_output_file", type.name));
140       JalviewFileChooser chooser;
141       chooser = type.getChooser();
142       chooser.setFileView(new jalview.io.JalviewFileView());
143       chooser.setDialogTitle(title);
144       chooser.setToolTipText(MessageManager.getString("action.save"));
145       int value = chooser.showSaveDialog(parent);
146
147       if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
148       {
149         jalview.bin.Cache.setProperty("LAST_DIRECTORY",
150                 chooser.getSelectedFile().getParent());
151         file = chooser.getSelectedFile();
152       }
153       else
154       {
155         setProgressMessage(MessageManager.formatMessage(
156                 "status.cancelled_image_export_operation", type.name));
157       }
158     }
159
160     if (file != null)
161     {
162       try
163       {
164         out = new FileOutputStream(file);
165         setProgressMessage(null);
166         setProgressMessage(MessageManager.formatMessage(
167                 "status.exporting_alignment_as_x_file", type.getName()));
168         if (type == TYPE.SVG)
169         {
170           setupSVG(width, height, fileTitle);
171         }
172         else if (type == TYPE.EPS)
173         {
174           setupEPS(width, height, fileTitle);
175         }
176         else if (type == TYPE.PNG)
177         {
178           setupPNG(width, height);
179         }
180         else if (type == TYPE.PDF)
181         {
182           setupPDF(width, height, fileTitle);
183         }
184
185       } catch (Exception ex)
186       {
187         System.out.println("Error creating " + type.getName() + " file.");
188
189         setProgressMessage(MessageManager
190                 .formatMessage("info.error_creating_file", type.getName()));
191       }
192     }
193   }
194
195   public Graphics getGraphics()
196   {
197     return graphics;
198   }
199
200   public void writeImage()
201   {
202     try
203     {
204       switch (type)
205       {
206       case EPS:
207         pg.flush();
208         pg.close();
209         break;
210       case SVG:
211         String svgData = ((SVGGraphics2D) getGraphics()).getSVGDocument();
212         out.write(svgData.getBytes());
213         out.flush();
214         out.close();
215         break;
216       case PNG:
217         ImageIO.write(bi, PNG_EXTENSION, out);
218         out.flush();
219         out.close();
220         break;
221       case PDF:
222         graphics = null;
223         pdfjob.end();
224         pdfjob = null;
225       }
226     } catch (Exception ex)
227     {
228       ex.printStackTrace();
229     }
230   }
231
232   void setupEPS(int width, int height, String title)
233   {
234     boolean accurateText = true;
235
236     String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",
237             "Prompt each time");
238
239     // If we need to prompt, and if the GUI is visible then
240     // Prompt for EPS rendering style
241     if (renderStyle.equalsIgnoreCase("Prompt each time")
242             && !(System.getProperty("java.awt.headless") != null && System
243                     .getProperty("java.awt.headless").equals("true")))
244     {
245       EPSOptions eps = new EPSOptions();
246       renderStyle = eps.getValue();
247
248       if (renderStyle == null || eps.cancelled)
249       {
250         setProgressMessage(MessageManager.formatMessage(
251                 "status.cancelled_image_export_operation", "EPS"));
252         return;
253       }
254     }
255
256     if (renderStyle.equalsIgnoreCase("text"))
257     {
258       accurateText = false;
259     }
260
261     try
262     {
263       pg = new EpsGraphics2D(title, out, 0, 0, width, height);
264       Graphics2D ig2 = pg;
265       ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
266               RenderingHints.VALUE_ANTIALIAS_ON);
267
268       pg.setAccurateTextMode(accurateText);
269
270       graphics = pg;
271       setProgressMessage(MessageManager
272               .formatMessage("status.export_complete", type.getName()));
273     } catch (Exception ex)
274     {
275     }
276   }
277
278   void setupPDF(int width, int height, String title)
279   {
280     boolean accurateText = true;
281
282     // String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",
283     // "Prompt each time");
284     //
285     // // If we need to prompt, and if the GUI is visible then
286     // // Prompt for EPS rendering style
287     // if (renderStyle.equalsIgnoreCase("Prompt each time")
288     // && !(System.getProperty("java.awt.headless") != null && System
289     // .getProperty("java.awt.headless").equals("true")))
290     // {
291     // EPSOptions eps = new EPSOptions();
292     // renderStyle = eps.getValue();
293     //
294     // if (renderStyle == null || eps.cancelled)
295     // {
296     // setProgressMessage(MessageManager.formatMessage(
297     // "status.cancelled_image_export_operation", "EPS"));
298     // return;
299     // }
300     // }
301     //
302     // if (renderStyle.equalsIgnoreCase("text"))
303     // {
304     // accurateText = false;
305     // }
306
307     try
308     {
309       pdfjob = new PDFJob(out, title);
310       
311       Paper paper = new Paper();
312       paper.setSize(width, height);
313       PageFormat pf = new PageFormat();
314       pf.setPaper(paper);
315       graphics = pdfjob.getGraphics(pf);
316       setProgressMessage(MessageManager
317               .formatMessage("status.export_complete", type.getName()));
318     } catch (Exception ex)
319     {
320     }
321   }
322   void setupPNG(int width, int height)
323   {
324     bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
325     graphics = bi.getGraphics();
326     Graphics2D ig2 = (Graphics2D) graphics;
327     ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
328             RenderingHints.VALUE_ANTIALIAS_ON);
329     setProgressMessage(MessageManager
330             .formatMessage("status.export_complete", type.getName()));
331
332   }
333
334   void setupSVG(int width, int height, String title)
335   {
336
337     g2 = new SVGGraphics2D(width, height);
338     Graphics2D ig2 = g2;
339
340     String renderStyle = jalview.bin.Cache.getDefault("SVG_RENDERING",
341             "Prompt each time");
342
343     // If we need to prompt, and if the GUI is visible then
344     // Prompt for EPS rendering style
345     if (renderStyle.equalsIgnoreCase("Prompt each time")
346             && !(System.getProperty("java.awt.headless") != null && System
347                     .getProperty("java.awt.headless").equals("true")))
348     {
349       SVGOptions svgOption = new SVGOptions();
350       renderStyle = svgOption.getValue();
351
352       if (renderStyle == null || svgOption.cancelled)
353       {
354         setProgressMessage(MessageManager.formatMessage(
355                 "status.cancelled_image_export_operation", "SVG"));
356         return;
357       }
358     }
359
360     if (renderStyle.equalsIgnoreCase("Lineart"))
361     {
362       ig2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
363               SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
364     }
365
366     setProgressMessage(MessageManager
367             .formatMessage("status.export_complete", type.getName()));
368     graphics = g2;
369   }
370
371   static JalviewFileChooser getPNGChooser()
372   {
373     if (Jalview.isHeadlessMode())
374     {
375       return null;
376     }
377     return new JalviewFileChooser(PNG_EXTENSION, PNG_DESCRIPTION);
378   }
379
380   static JalviewFileChooser getPDFChooser()
381   {
382     if (Jalview.isHeadlessMode())
383     {
384       return null;
385     }
386     return new JalviewFileChooser(PDF_EXTENSION, PDF_DESCRIPTION);
387   }
388
389   static JalviewFileChooser getEPSChooser()
390   {
391     if (Jalview.isHeadlessMode())
392     {
393       return null;
394     }
395     return new JalviewFileChooser(EPS_EXTENSION, EPS_DESCRIPTION);
396   }
397
398   private void setProgressMessage(String message)
399   {
400     if (pIndicator != null && !headless)
401     {
402       pIndicator.setProgressBar(message, pSessionId);
403     }
404   }
405
406   static JalviewFileChooser getSVGChooser()
407   {
408     if (Jalview.isHeadlessMode())
409     {
410       return null;
411     }
412     return new JalviewFileChooser(SVG_EXTENSION, SVG_DESCRIPTION);
413   }
414 }