KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > jpdf > PDFOutline


1 /*
2  * $Id: PDFOutline.java,v 1.1.1.1 2001/10/29 19:51:08 ezb Exp $
3  *
4  * $Date: 2001/10/29 19:51:08 $
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 package gnu.jpdf;
21
22 import java.io.*;
23 import java.util.*;
24
25 /**
26  * This class manages the documents outlines (also known as bookmarks).
27  *
28  * @author Peter T Mount http://www.retep.org.uk/pdf/
29  * @author Eric Z. Beard, ericzbeard@hotmail.com
30  * @author $Author: ezb $
31  * @version $Revision: 1.1.1.1 $, $Date: 2001/10/29 19:51:08 $
32  */

33 public class PDFOutline extends PDFObject implements Serializable
34 {
35
36   /*
37    * NOTE: The original class is the work of Peter T. Mount, who released it
38    * in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as
39    * follows:
40    * The package name was changed to gnu.pdf.
41    * The formatting was changed a little bit.
42    * It is still licensed under the LGPL.
43    */

44
45     /**
46      * This holds any outlines below us
47      */

48     private Vector outlines;
49     
50     /**
51      * For subentries, this points to it's parent outline
52      */

53     protected PDFOutline parent;
54     
55     /**
56      * This is this outlines Title
57      */

58     private String JavaDoc title;
59     
60     /**
61      * The destination page
62      */

63     PDFPage dest;
64     
65     /**
66      * The region on the destination page
67      */

68     int l,b,r,t;
69     
70     /**
71      * How the destination is handled
72      */

73     boolean destMode;
74     
75     /**
76      * When jumping to the destination, display the whole page
77      */

78     static final boolean FITPAGE = false;
79     
80     /**
81      * When jumping to the destination, display the specified region
82      */

83     static final boolean FITRECT = true;
84     
85     /**
86      * Constructs a PDF Outline object. This method is used internally only.
87      */

88     protected PDFOutline()
89     {
90         super("/Outlines");
91         outlines = new Vector();
92         title = null;
93         dest = null;
94         destMode = FITPAGE;
95     }
96     
97     /**
98      * Constructs a PDF Outline object. When selected, the whole page is
99      * displayed.
100      *
101      * @param title Title of the outline
102      * @param dest The destination page
103      */

104     public PDFOutline(String JavaDoc title,PDFPage dest)
105     {
106         this();
107         this.title = title;
108         this.dest = dest;
109     }
110     
111     /**
112      * Constructs a PDF Outline object. When selected, the specified region
113      * is displayed.
114      *
115      * @param title Title of the outline
116      * @param dest The destination page
117      * @param l left coordinate
118      * @param b bottom coordinate
119      * @param r right coordinate
120      * @param t top coordinate
121      */

122     public PDFOutline(String JavaDoc title,PDFPage dest,int l,int b,int r,int t)
123     {
124         this(title,dest);
125         this.destMode = FITRECT;
126         this.l = l;
127         this.b = b;
128         this.r = r;
129         this.t = t;
130     }
131     
132     /**
133      * This method creates an outline, and attaches it to this one.
134      * When the outline is selected, the entire page is displayed.
135      *
136      * <p>This allows you to have an outline for say a Chapter,
137      * then under the chapter, one for each section. You are not really
138      * limited on how deep you go, but it's best not to go below say 6 levels,
139      * for the reader's sake.
140      *
141      * @param title Title of the outline
142      * @param dest The destination page
143      * @return PDFOutline object created, for creating sub-outlines
144      */

145     public PDFOutline add(String JavaDoc title,PDFPage dest) {
146         PDFOutline outline = new PDFOutline(title,dest);
147         pdfDocument.add(outline); // add to the pdf first!
148
add(outline);
149         return outline;
150     }
151     
152     /**
153      * This method creates an outline, and attaches it to this one.
154      * When the outline is selected, the supplied region is displayed.
155      *
156      * <p>Note: the coordiates are in Java space. They are converted to User
157      * space.
158      *
159      * <p>This allows you to have an outline for say a Chapter,
160      * then under the chapter, one for each section. You are not really
161      * limited on how deep you go, but it's best not to go below say 6 levels,
162      * for the reader's sake.
163      *
164      * @param title Title of the outline
165      * @param dest The destination page
166      * @param x coordinate of region in Java space
167      * @param y coordinate of region in Java space
168      * @param w width of region in Java space
169      * @param h height of region in Java space
170      * @return PDFOutline object created, for creating sub-outlines
171      */

172     public PDFOutline add(String JavaDoc title,PDFPage dest,
173                           int x,int y,int w,int h) {
174         int xy1[] = dest.cxy(x,y+h);
175         int xy2[] = dest.cxy(x+w,y);
176         PDFOutline outline = new PDFOutline(title,dest,
177                                             xy1[0],xy1[1],
178                                             xy2[0],xy2[1]);
179         pdfDocument.add(outline); // add to the pdf first!
180
add(outline);
181         return outline;
182     }
183     
184     /**
185      * This adds an already existing outline to this one.
186      *
187      * <p>Note: the outline must have been added to the PDF document before
188      * calling this method. Normally the other add methods are used.
189      *
190      * @param page PDFOutline to add
191      */

192     public void add(PDFOutline outline)
193     {
194         outlines.addElement(outline);
195         
196         // Tell the outline of ourselves
197
outline.parent = this;
198     }
199     
200     /**
201      * @param os OutputStream to send the object to
202      * @exception IOException on error
203      */

204     public void write(OutputStream os) throws IOException
205     {
206         // Write the object header
207
writeStart(os);
208         
209         // now the objects body
210

211         // These are for kids only
212
if(parent!=null) {
213             os.write("/Title ".getBytes());
214             os.write(PDFStringHelper.makePDFString(title).getBytes());
215             os.write("\n/Dest [".getBytes());
216             os.write(dest.toString().getBytes());
217             
218             if(destMode==FITPAGE) {
219                 //os.write(" null null null]\n/Parent ".getBytes());
220
os.write(" /Fit]\n/Parent ".getBytes());
221             } else {
222                 os.write(" /FitR ".getBytes());
223                 os.write(Integer.toString(l).getBytes());
224                 os.write(" ".getBytes());
225                 os.write(Integer.toString(b).getBytes());
226                 os.write(" ".getBytes());
227                 os.write(Integer.toString(r).getBytes());
228                 os.write(" ".getBytes());
229                 os.write(Integer.toString(t).getBytes());
230                 os.write("]\n/Parent ".getBytes());
231             }
232             os.write(parent.toString().getBytes());
233             os.write("\n".getBytes());
234         }
235         
236         // the number of outlines in this document
237
if(parent==null) {
238             // were the top level node, so all are open by default
239
os.write("/Count ".getBytes());
240             os.write(Integer.toString(outlines.size()).getBytes());
241             os.write("\n".getBytes());
242         } else {
243             // were a decendent, so by default we are closed. Find out how many
244
// entries are below us
245
int c = descendants();
246             if(c>0) {
247                 os.write("/Count ".getBytes());
248                 os.write(Integer.toString(-c).getBytes());
249                 os.write("\n".getBytes());
250             }
251         }
252         
253         // These only valid if we have children
254
if(outlines.size()>0) {
255             // the number of the first outline in list
256
os.write("/First ".getBytes());
257             os.write(outlines.elementAt(0).toString().getBytes());
258             os.write("\n".getBytes());
259             
260             // the number of the last outline in list
261
os.write("/Last ".getBytes());
262             os.write(outlines.elementAt(outlines.size()-1).toString().getBytes());
263             os.write("\n".getBytes());
264         }
265         
266         if(parent!=null) {
267             int index = parent.getIndex(this);
268             if(index>0) {
269                 // Now if were not the first, then we have a /Prev node
270
os.write("/Prev ".getBytes());
271                 os.write(parent.getNode(index-1).toString().getBytes());
272                 os.write("\n".getBytes());
273             }
274             if(index<parent.getLast()) {
275                 // We have a /Next node
276
os.write("/Next ".getBytes());
277                 os.write(parent.getNode(index+1).toString().getBytes());
278                 os.write("\n".getBytes());
279             }
280         }
281         
282         // finish off with its footer
283
writeEnd(os);
284     }
285     
286     /**
287      * This is called by children to find their position in this outlines
288      * tree.
289      *
290      * @param outline PDFOutline to search for
291      * @return index within Vector
292      */

293     protected int getIndex(PDFOutline outline)
294     {
295         return outlines.indexOf(outline);
296     }
297     
298     /**
299      * Returns the last index in this outline
300      * @return last index in outline
301      */

302     protected int getLast()
303     {
304         return outlines.size()-1;
305     }
306     
307     /**
308      * Returns the outline at a specified position.
309      * @param i index
310      * @return the node at index i
311      */

312     protected PDFOutline getNode(int i)
313     {
314         return (PDFOutline)(outlines.elementAt(i));
315     }
316     
317     /**
318      * Returns all outlines directly below this one.
319      * @return Enumeration of child elements
320      */

321     public Enumeration elements()
322     {
323         return outlines.elements();
324     }
325     
326     /**
327      * Returns the total number of descendants below this one.
328      * @return the number of descendants below this one
329      */

330     protected int descendants()
331     {
332         int c = outlines.size(); // initially the number of kids
333

334         // now call each one for their descendants
335
for(Enumeration en = outlines.elements(); en.hasMoreElements(); ) {
336             c += ((PDFOutline)en.nextElement()).descendants();
337         }
338         
339         return c;
340     }
341 } // end class PDFOutline
342
Popular Tags