JAL-2872 Undid inference disabling (done in Jalview instead)
[jalview.git] / forester / java / src / org / forester / archaeopteryx / PdfExporter.java
1 // $Id:
2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
4 //
5 // Copyright (C) 2008-2009 Christian M. Zmasek
6 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
7 // Copyright (C) 2000-2001 Washington University School of Medicine
8 // and Howard Hughes Medical Institute
9 // Copyright (C) 2003-2007 Ethalinda K.S. Cannon
10 // All rights reserved
11 //
12 // This library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation; either
15 // version 2.1 of the License, or (at your option) any later version.
16 //
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 //
26 // Contact: phylosoft @ gmail . com
27 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
28
29 package org.forester.archaeopteryx;
30
31 import java.awt.Graphics2D;
32 import java.io.File;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.util.Iterator;
36 import java.util.Map;
37
38 import org.forester.phylogeny.Phylogeny;
39 import org.forester.util.ForesterUtil;
40
41 import com.itextpdf.awt.DefaultFontMapper;
42 import com.itextpdf.awt.DefaultFontMapper.BaseFontParameters;
43 import com.itextpdf.awt.PdfGraphics2D;
44 import com.itextpdf.text.Document;
45 import com.itextpdf.text.DocumentException;
46 import com.itextpdf.text.FontFactory;
47 import com.itextpdf.text.Rectangle;
48 import com.itextpdf.text.pdf.BaseFont;
49 import com.itextpdf.text.pdf.PdfContentByte;
50 import com.itextpdf.text.pdf.PdfWriter;
51
52 /*
53  * 
54  * This uses iText.
55  * 
56  * See: http://www.lowagie.com/iText/
57  * 
58  * Current version: iText-5.5.9
59  */
60 final class PdfExporter {
61
62     private static final int HEIGHT_LIMIT = 100;
63     private static final int WIDTH_LIMIT  = 60;
64     private static final int MARGIN_X = 20;
65     private static final int MARGIN_Y = 10;
66     
67     private PdfExporter() {
68         // Empty constructor.
69     }
70
71     static String writePhylogenyToPdf( final String file_name, final TreePanel tree_panel, final int width, final int height )
72             throws IOException {
73         final int my_height;
74         final int my_width;
75         if ( height < HEIGHT_LIMIT ) {
76             my_height = HEIGHT_LIMIT + 2 * MARGIN_Y;
77         }
78         else {
79             my_height = height + 2 * MARGIN_Y;
80         }
81         if ( width < WIDTH_LIMIT ) {
82             my_width = WIDTH_LIMIT +  2 * MARGIN_X;
83         }
84         else {
85             my_width = width +  2 * MARGIN_X;
86         }
87         final Phylogeny phylogeny = tree_panel.getPhylogeny();
88         if ( ( phylogeny == null ) || phylogeny.isEmpty() ) {
89             return "";
90         }
91         if ( tree_panel.getMainPanel().getTreeFontSet().getSmallFont().getSize() < 1 ) {
92             throw new IOException( "fonts are too small for PDF export" );
93         }
94         if ( tree_panel.getMainPanel().getTreeFontSet().getLargeFont().getSize() < 1 ) {
95             throw new IOException( "fonts are too small for PDF export" );
96         }
97         final File file = new File( file_name );
98         if ( file.isDirectory() ) {
99             throw new IOException( "[" + file_name + "] is a directory" );
100         }
101         final Document document = new Document();
102         document.setPageSize( new Rectangle( my_width, my_height ) );
103         document.setMargins( MARGIN_X, MARGIN_X, MARGIN_Y, MARGIN_Y );
104         PdfWriter writer = null;
105         try {
106             writer = PdfWriter.getInstance( document, new FileOutputStream( file_name ) );
107            
108         }
109         catch ( final DocumentException e ) {
110             throw new IOException( e );
111         }
112         document.open();
113         final DefaultFontMapper mapper = new DefaultFontMapper();
114         FontFactory.registerDirectories();
115         if ( ForesterUtil.isWindows() ) {
116             mapper.insertDirectory( "c:/windows/fonts" );
117         }
118         else if ( ForesterUtil.isMac() ) {
119             mapper.insertDirectory( "/Library/Fonts/" );
120             mapper.insertDirectory( "/System/Library/Fonts/" );
121         }
122         else {
123             mapper.insertDirectory( "/usr/X/lib/X11/fonts/TrueType/" );
124             mapper.insertDirectory( "/usr/X/lib/X11/fonts/Type1/" );
125             mapper.insertDirectory( "/usr/share/fonts/default/TrueType/" );
126             mapper.insertDirectory( "/usr/share/fonts/default/Type1/" );
127         }
128         enableUnicode( mapper );
129         final PdfContentByte cb = writer.getDirectContent();
130         
131         final Graphics2D g2 = new PdfGraphics2D(cb, my_width, my_height, mapper); 
132     
133         try {
134             tree_panel.paintPhylogeny( g2, true, false, my_width, my_height, 0, 0 );
135         }
136         catch ( final Exception e ) {
137             AptxUtil.unexpectedException( e );
138         }
139         finally {
140             try {
141                 g2.dispose();
142                 document.close();
143             }
144             catch ( final Exception e ) {
145                 //Do nothing.
146             }
147         }
148         final String msg = file.toString() +  " [size: " + my_width + ", " + my_height + "]";
149         return msg;
150     }
151
152     private final static void enableUnicode( final DefaultFontMapper mapper ) {
153         final Map<String, DefaultFontMapper.BaseFontParameters> map = mapper.getMapper();
154         for (final Iterator<String> i = map.keySet().iterator(); i.hasNext();) {
155             final String name = i.next();
156             final String name_lc = name.toLowerCase();
157             if ( name_lc.contains( "unicode" ) || name_lc.equals( "dialog" ) ) {
158                 final BaseFontParameters pfps = map.get(name);
159                 try {
160                     pfps.encoding = BaseFont.IDENTITY_H;
161                     pfps.embedded = true;
162                 }
163                 catch ( Exception e )  {
164                     //Ignore.
165                 }
166             }
167         }
168     }
169     
170     /* not used currently 
171     static FontMapper arial_uni = new FontMapper() {
172         public BaseFont awtToPdf(Font font) {
173             System.out.println( font.toString() );
174             try {
175                 return BaseFont.createFont(
176                         "c:/windows/fonts/arialuni.ttf",
177                         BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
178             }
179             catch (DocumentException e) {
180                 e.printStackTrace();
181             }
182             catch (IOException e) {
183                 e.printStackTrace();
184             }
185             return null;
186         }
187        
188         @Override
189         public Font pdfToAwt( BaseFont arg0, int arg1 ) {
190             return null;
191         }
192     };
193     */
194 }