new itext version, plus minor changes
[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
65     private PdfExporter() {
66         // Empty constructor.
67     }
68
69     static String writePhylogenyToPdf( final String file_name, final TreePanel tree_panel, int width, int height )
70             throws IOException {
71         if ( height < HEIGHT_LIMIT ) {
72             height = HEIGHT_LIMIT;
73         }
74         if ( width < WIDTH_LIMIT ) {
75             width = WIDTH_LIMIT;
76         }
77         final Phylogeny phylogeny = tree_panel.getPhylogeny();
78         if ( ( phylogeny == null ) || phylogeny.isEmpty() ) {
79             return "";
80         }
81         if ( tree_panel.getMainPanel().getTreeFontSet().getSmallFont().getSize() < 1 ) {
82             throw new IOException( "fonts are too small for PDF export" );
83         }
84         final File file = new File( file_name );
85         if ( file.isDirectory() ) {
86             throw new IOException( "[" + file_name + "] is a directory" );
87         }
88         final Document document = new Document();
89         document.setPageSize( new Rectangle( width, height ) );
90         document.setMargins( WIDTH_LIMIT / 2, WIDTH_LIMIT / 2, HEIGHT_LIMIT / 2, HEIGHT_LIMIT / 2 );
91         PdfWriter writer = null;
92         try {
93             writer = PdfWriter.getInstance( document, new FileOutputStream( file_name ) );
94            
95         }
96         catch ( final DocumentException e ) {
97             throw new IOException( e );
98         }
99         document.open();
100         final DefaultFontMapper mapper = new DefaultFontMapper();
101         FontFactory.registerDirectories();
102         if ( ForesterUtil.isWindows() ) {
103             mapper.insertDirectory( "c:/windows/fonts" );
104         }
105         else if ( ForesterUtil.isMac() ) {
106             mapper.insertDirectory( "/Library/Fonts/" );
107             mapper.insertDirectory( "/System/Library/Fonts/" );
108         }
109         else {
110             mapper.insertDirectory( "/usr/X/lib/X11/fonts/TrueType/" );
111             mapper.insertDirectory( "/usr/X/lib/X11/fonts/Type1/" );
112             mapper.insertDirectory( "/usr/share/fonts/default/TrueType/" );
113             mapper.insertDirectory( "/usr/share/fonts/default/Type1/" );
114         }
115         enableUnicode( mapper );
116         final PdfContentByte cb = writer.getDirectContent();
117         
118         final Graphics2D g2 = new PdfGraphics2D(cb, width, height, mapper); 
119     
120         try {
121             tree_panel.paintPhylogeny( g2, true, false, width, height, 0, 0 );
122         }
123         catch ( final Exception e ) {
124             AptxUtil.unexpectedException( e );
125         }
126         finally {
127             try {
128                 g2.dispose();
129                 document.close();
130             }
131             catch ( final Exception e ) {
132                 //Do nothing.
133             }
134         }
135         String msg = file.toString();
136         if ( ( width > 0 ) && ( height > 0 ) ) {
137             msg += " [size: " + width + ", " + height + "]";
138         }
139         return msg;
140     }
141
142     private final static void enableUnicode( final DefaultFontMapper mapper ) {
143         final Map<String, DefaultFontMapper.BaseFontParameters> map = mapper.getMapper();
144         for (final Iterator<String> i = map.keySet().iterator(); i.hasNext();) {
145             final String name = i.next();
146             final String name_lc = name.toLowerCase();
147             if ( name_lc.contains( "unicode" ) || name_lc.equals( "dialog" ) ) {
148                 final BaseFontParameters pfps = map.get(name);
149                 try {
150                     pfps.encoding = BaseFont.IDENTITY_H;
151                     pfps.embedded = true;
152                 }
153                 catch ( Exception e )  {
154                     //Ignore.
155                 }
156             }
157         }
158     }
159     
160     /* not used currently 
161     static FontMapper arial_uni = new FontMapper() {
162         public BaseFont awtToPdf(Font font) {
163             System.out.println( font.toString() );
164             try {
165                 return BaseFont.createFont(
166                         "c:/windows/fonts/arialuni.ttf",
167                         BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
168             }
169             catch (DocumentException e) {
170                 e.printStackTrace();
171             }
172             catch (IOException e) {
173                 e.printStackTrace();
174             }
175             return null;
176         }
177        
178         @Override
179         public Font pdfToAwt( BaseFont arg0, int arg1 ) {
180             return null;
181         }
182     };
183     */
184 }