KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > jpdf > PDFDocument


1 /*
2  * $Id: PDFDocument.java,v 1.2 2001/11/15 20:18:11 ezb Exp $
3  *
4  * $Date: 2001/11/15 20:18:11 $
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */

21 package gnu.jpdf;
22
23 import java.awt.*;
24 import java.io.*;
25 import java.util.*;
26
27 /**
28  * <p>This class is the base of the PDF generator. A PDFDocument class is
29  * created for a document, and each page, object, annotation,
30  * etc is added to the document.
31  * Once complete, the document can be written to an OutputStream, and the PDF
32  * document's internal structures are kept in sync.</p>
33  *
34  * <p>Note that most programmers using this package will NEVER access
35  * one of these objects directly. Most everything can be done using
36  * <code>PDFJob</code> and <code>PDFGraphics</code>, so you don't need
37  * to directly instantiate a <code>PDFDocument</code></p>
38  *
39  * <p>ezb - 20011115 - Wondering if the constructors should even be public.
40  * When would someone want to make one of these and manipulate it outside
41  * the context of a job and graphics object?</p>
42  *
43  * @author Peter T Mount, http://www.retep.org.uk/pdf/
44  * @author Eric Z. Beard, ericzbeard@hotmail.com
45  * @author $Author: ezb $
46  * @version $Revision: 1.2 $, $Date: 2001/11/15 20:18:11 $
47  */

48 public class PDFDocument implements Serializable
49 {
50   
51   /*
52    * NOTE: This class originated in uk.org.retep.pdf, by Peter T. Mount, and it
53    * has been modified by Eric Z. Beard, ericzbeard@hotmail.com. The
54    * package name was changed to gnu.jpdf and several inner classes were
55    * moved out into their own files.
56    */

57
58   /**
59    * This is used to allocate objects a unique serial number in the document.
60    */

61   protected int objser;
62     
63   /**
64    * This vector contains each indirect object within the document.
65    */

66   protected Vector objects;
67     
68   /**
69    * This is the Catalog object, which is required by each PDF Document
70    */

71   private PDFCatalog catalog;
72     
73   /**
74    * This is the info object. Although this is an optional object, we
75    * include it.
76    */

77   private PDFInfo info;
78     
79   /**
80    * This is the Pages object, which is required by each PDF Document
81    */

82   private PDFPageList pdfPageList;
83     
84   /**
85    * This is the Outline object, which is optional
86    */

87   private PDFOutline outline;
88     
89   /**
90    * This holds a PDFObject describing the default border for annotations.
91    * It's only used when the document is being written.
92    */

93   protected PDFObject defaultOutlineBorder;
94     
95   /**
96    * <p>This page mode indicates that the document
97    * should be opened just with the page visible. This is the default</p>
98    */

99   public static final int USENONE = 0;
100     
101   /**
102    * <p>This page mode indicates that the Outlines
103    * should also be displayed when the document is opened.</p>
104    */

105   public static final int USEOUTLINES = 1;
106     
107   /**
108    * <p>This page mode indicates that the Thumbnails should be visible when the
109    * document first opens.</p>
110    */

111   public static final int USETHUMBS = 2;
112     
113   /**
114    * <p>
115    * This page mode indicates that when the document is opened, it is displayed
116    * in full-screen-mode. There is no menu bar, window controls nor any other
117    * window present.</p>
118    */

119   public static final int FULLSCREEN = 3;
120     
121   /**
122    * <p>
123    * These map the page modes just defined to the pagemodes setting of PDF.
124    * </p>
125    */

126   public static final String JavaDoc PDF_PAGE_MODES[] = {
127     "/UseNone",
128     "/UseOutlines",
129     "/UseThumbs",
130     "/FullScreen"
131   };
132     
133   /**
134    * This is used to provide a unique name for a font
135    */

136   private int fontid = 0;
137     
138   /**
139    * <p>This is used to provide a unique name for an image</p>
140    */

141   private int imageid = 0;
142     
143   /**
144    * This holds the current fonts
145    */

146   private Vector fonts;
147     
148       
149   /**
150    * <p>This creates a PDF document with the default pagemode</p>
151    */

152   public PDFDocument() {
153     this(USENONE);
154   }
155     
156   /**
157    * <p>This creates a PDF document</p>
158    * @param pagemode an int, determines how the document will present itself to
159    * the viewer when it first opens.
160    */

161   public PDFDocument(int pagemode) {
162     objser = 1;
163     objects = new Vector();
164     fonts = new Vector();
165         
166     // Now create some standard objects
167
add(pdfPageList = new PDFPageList());
168     add(catalog = new PDFCatalog(pdfPageList,pagemode));
169     add(info = new PDFInfo());
170         
171     // Acroread on linux seems to die if there is no root outline
172
add(getOutline());
173   }
174     
175
176
177   /**
178    * This adds a top level object to the document.
179    *
180    * <p>Once added, it is allocated a unique serial number.
181    *
182    * <p><b>Note:</b> Not all object are added directly using this method.
183    * Some objects which have Kids (in PDF sub-objects or children are
184    * called Kids) will have their own add() method, which will call this
185    * one internally.
186    *
187    * @param obj The PDFObject to add to the document
188    * @return the unique serial number for this object.
189    */

190   public synchronized int add(PDFObject obj)
191   {
192     objects.addElement(obj);
193     obj.objser=objser++; // create a new serial number
194
obj.pdfDocument = this; // so they can find the document they belong to
195

196     // If its a page, then add it to the pages collection
197
if(obj instanceof PDFPage)
198       pdfPageList.add((PDFPage)obj);
199         
200     return obj.objser;
201   }
202     
203   /**
204    * <p>This returns a specific page. It's used mainly when using a
205    * Serialized template file.</p>
206    *
207    * ?? How does a serialized template file work ???
208    *
209    * @param page page number to return
210    * @return PDFPage at that position
211    */

212   public PDFPage getPage(int page) {
213     return pdfPageList.getPage(page);
214   }
215     
216
217   /**
218    * @return the root outline
219    */

220   public PDFOutline getOutline()
221   {
222     if(outline==null) {
223       outline = new PDFOutline();
224       catalog.setOutline(outline);
225     }
226     return outline;
227   }
228     
229   /**
230    * This returns a font of the specified type and font. If the font has
231    * not been defined, it creates a new font in the PDF document, and
232    * returns it.
233    *
234    * @param type PDF Font Type - usually "/Type1"
235    * @param font Java font name
236    * @param style java.awt.Font style (NORMAL, BOLD etc)
237    * @return PDFFont defining this font
238    */

239   public PDFFont getFont(String JavaDoc type,String JavaDoc font,int style) {
240     for(Enumeration en = fonts.elements(); en.hasMoreElements(); ) {
241       PDFFont ft = (PDFFont) en.nextElement();
242       if(ft.equals(type,font,style))
243         return ft;
244     }
245         
246     // the font wasn't found, so create it
247
fontid++;
248     PDFFont ft = new PDFFont("/F"+fontid,type,font,style);
249     add(ft);
250     fonts.addElement(ft);
251     return ft;
252   }
253     
254   /**
255    * Sets a unique name to a PDFImage
256    * @param img PDFImage to set the name of
257    * @return the name given to the image
258    */

259   public String JavaDoc setImageName(PDFImage img) {
260     imageid++;
261     img.setName("/Image"+imageid);
262     return img.getName();
263   }
264
265
266   /**
267    * <p>Set the PDFInfo object, which contains author, title,
268    * keywords, etc</p>
269    */

270   public void setPDFInfo(PDFInfo info) {
271     this.info = info;
272   }
273     
274
275   /**
276    * <p>Get the PDFInfo object, which contains author, title, keywords,
277    * etc</p>
278    */

279   public PDFInfo getPDFInfo() {
280     return this.info;
281   }
282
283
284   /**
285    * This writes the document to an OutputStream.
286    *
287    * <p><b>Note:</b> You can call this as many times as you wish, as long as
288    * the calls are not running at the same time.
289    *
290    * <p>Also, objects can be added or amended between these calls.
291    *
292    * <p>Also, the OutputStream is not closed, but will be flushed on
293    * completion. It is up to the caller to close the stream.
294    *
295    * @param os OutputStream to write the document to
296    * @exception IOException on error
297    */

298   public void write(OutputStream os) throws IOException
299   {
300     PDFOutput pos = new PDFOutput(os);
301         
302     // Write each object to the OutputStream. We call via the output
303
// as that builds the xref table
304
for(Enumeration en = objects.elements(); en.hasMoreElements(); )
305       pos.write((PDFObject)en.nextElement());
306         
307     // Finally close the output, which writes the xref table.
308
pos.close();
309         
310     // and flush the output stream to ensure everything is written.
311
os.flush();
312   }
313           
314 } // end class PDFDocument
315
Popular Tags