KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > faceless > pdf > PDF


1 // $Id: PDF.java,v 1.9 2003/12/02 10:37:53 mike Exp $
2
package org.faceless.pdf;
3
4 import java.io.*;
5 import java.util.*;
6
7 /**
8  * <p>A <code>PDF</code> describes a single document in Adobe's Portable
9  * Document Format. It is the highest-level object in the package.</p>
10  *
11  * <p>
12  * The life-cycle of a PDF generally consists of being created, adding
13  * new pages, optionally adding information about the document structure
14  * (like bookmarks), and finally rendering to an <code>OutputStream</code>.
15  * </p><p>
16  * This class only deals with the structure of the document. To actually
17  * create some content see the {@link PDFPage} class.
18  * </p>
19  *
20  * Here's the ubiquitous example:
21  * <pre>
22  * import org.faceless.pdf.*;
23  *
24  * // Create a new PDF
25  * PDF p = new PDF();
26  *
27  * // Create a new page
28  * PDFPage page = p.newPage(PDF.PAGESIZE_A4);
29  *
30  * // Create a new "style" to write in - Black 24pt Times Roman.
31  * PDFStyle mystyle = new PDFStyle();
32  * mystyle.setFont(new StandardFont(StandardFont.TIMES), 24);
33  * mystyle.setFillColor(java.awt.Color.black);
34  *
35  * // Put something on the page
36  * page.setStyle(mystyle);
37  * page.drawText("Hello, PDF-viewing World!", 100, 100);
38  *
39  * // Automatically go to this page when the document is opened.
40  * p.setOpenAction(PDFAction.goTo(page));
41  *
42  * // Add some document info
43  * p.setInfo("Author", "Joe Bloggs");
44  * p.setInfo("Title", "My Document");
45  *
46  * // Add a bookmark
47  * java.util.List bookmarks = p.getBookmarks();
48  * bookmarks.add(new PDFBookmark("Hello World page", PDFAction.goTo(page)));
49  *
50  * // Allow the user to print the document, but nothing else
51  * p.setAccessLevel(PDF.ACCESS_PRINT);
52  *
53  * // Write the document to a file
54  * p.render(new FileOutputStream("test.pdf"));
55  * </pre>
56  *
57  * @see PDFPage
58  * @see PDFReader
59  * @see PDFBookmark
60  * @see PDFStyle
61  * @version $Revision: 1.9 $
62  *
63  */

64 public class PDF
65 {
66     private org.faceless.pdf2.PDF pdf;
67
68     /**
69      * The package version number
70      */

71     public static final String JavaDoc VERSION="BFOPDF $Revision: 1.9 $";
72
73      /**
74      * Argument to <code>setLayout</code> to display each page separately (the default)
75      */

76     public static final String JavaDoc SINGLEPAGE = "SinglePage";
77
78     /**
79      * Argument to <code>setLayout</code> to display the pages in a single column.
80      */

81     public static final String JavaDoc ONECOLUMN = "OneColumn";
82
83     /**
84      * Argument to <code>setLayout</code> to display the pages in two columns, with
85      * odd numbered pages to the left.
86      */

87     public static final String JavaDoc TWOCOLUMNLEFT = "TwoColumnLeft";
88
89     /**
90      * Argument to <code>setLayout</code> to display the pages in two columns, with
91      * odd numbered pages to the right.
92      */

93     public static final String JavaDoc TWOCOLUMNRIGHT = "TwoColumnRight";
94
95     /**
96      * Argument to <code>newPage</code> to create a new A3 portrait page
97      */

98     public static final String JavaDoc PAGESIZE_A3 = "842x1190";
99
100     /**
101      * Argument to <code>newPage</code> to create a new A3 landscape page
102      */

103     public static final String JavaDoc PAGESIZE_A3_LANDSCAPE = "1190x842";
104
105     /**
106      * Argument to <code>newPage</code> to create a new A4 portrait page
107      */

108     public static final String JavaDoc PAGESIZE_A4 = "595x842";
109
110     /**
111      * Argument to <code>newPage</code> to create a new A4 landscape page
112      */

113     public static final String JavaDoc PAGESIZE_A4_LANDSCAPE = "842x595";
114
115     /**
116      * Argument to <code>newPage</code> to create a new A5 portrait page
117      */

118     public static final String JavaDoc PAGESIZE_A5 = "421x595";
119
120     /**
121      * Argument to <code>newPage</code> to create a new A5 landscape page
122      */

123     public static final String JavaDoc PAGESIZE_A5_LANDSCAPE = "595x421";
124
125     /**
126      * Argument to <code>newPage</code> to create a new A6 portrait page
127      */

128     public static final String JavaDoc PAGESIZE_A6 = "297x421";
129
130     /**
131      * Argument to <code>newPage</code> to create a new A6 landscape page
132      */

133     public static final String JavaDoc PAGESIZE_A6_LANDSCAPE = "421x297";
134
135     /**
136      * Argument to <code>newPage</code> to create a new "letter" portrait page
137      */

138     public static final String JavaDoc PAGESIZE_LETTER = "612x792";
139
140     /**
141      * Argument to <code>newPage</code> to create a new "letter" landscape page
142      */

143     public static final String JavaDoc PAGESIZE_LETTER_LANDSCAPE = "792x612";
144
145     /**
146      * Argument to <code>newPage</code> to create a new "legal" portrait page
147      */

148     public static final String JavaDoc PAGESIZE_LEGAL = "612x1008";
149
150     /**
151      * Argument to <code>newPage</code> to create a new "legal" landscape page
152      */

153     public static final String JavaDoc PAGESIZE_LEGAL_LANDSCAPE = "1008x612";
154
155     /**
156      * Argument to <code>setAccessLevel</code> to allow the user full access
157      * to the document.
158      * @since 1.1.12
159      */

160     public static final int ACCESS_ALL = 0xFFFFFFFF;
161
162     /**
163      * Argument to <code>setAccessLevel</code> to allow the user to print
164      * the document. If 128-bit encryption is used, this flag on it's own
165      * will only allow low-quality printing - you should set the
166      * {@link #ACCESS_HQPRINT} flag too for high quality printing. If
167      * 40-bit encryption is used, printing is always high-quality.
168      */

169     public static final int ACCESS_PRINT = 4;
170
171     /**
172      * Argument to <code>setAccessLevel</code> to allow the user to edit
173      * the document with software like Adobe Acrobat&trade;
174      */

175     public static final int ACCESS_EDIT = 8;
176
177     /**
178      * Argument to <code>setAccessLevel</code> to allow the user to copy
179      * and paste text and images from the document
180      */

181     public static final int ACCESS_COPY = 16;
182
183     /**
184      * Argument to <code>setAccessLevel</code> to allow the user to add
185      * annotations to the document and create or edit interactive form
186      * fields (including signature fields).
187      */

188     public static final int ACCESS_ANNOTATE = 32;
189
190     /**
191      * Argument to <code>setAccessLevel</code> to allow the user to fill
192      * in existing interactive form fields (including signature fields),
193      * even if ACCESS_ANNOTATE is not set. (128 bit encryption only)
194      * @since 1.1.12
195      */

196     public static final int ACCESS_FORMS = 256;
197
198     /**
199      * Argument to <code>setAccessLevel</code> to allow the user to
200      * extract text and graphics (in support of accessibility for disabled
201      * users or for other purposes). (128 bit encryption only)
202      * @since 1.1.12
203      */

204     public static final int ACCESS_EXTRACT = 512;
205
206     /**
207      * Argument to <code>setAccessLevel</code> to allow the user to
208      * assemble the document (insert, rotate or delete pages and create
209      * bookmarks or thumbnail images), even if ACCESS_EDIT is not set.
210      * (128 bit encryption only)
211      * @since 1.1.12
212      */

213     public static final int ACCESS_ASSEMBLE = 1024;
214
215     /**
216      * Argument to <code>setAccessLevel</code> to allow the user to
217      * print the document to a representation from which a faithful digital
218      * copy of the PDF content could be generated. When this option is not set
219      * and ACCESS_PRINT is set, printing is limited to a low-level
220      * representation of the appearance, possibly of degraded quality.
221      * (128 bit encryption only)
222      * @since 1.1.12
223      */

224     public static final int ACCESS_HQPRINT = 2048;
225
226     /**
227      * Argument to <code>setEncryptionAlgorithm</code> to
228      * turn off encryption for the document. This is
229      * the default.
230      * @since 1.1.12
231      */

232     public static final int ENCRYPT_NONE = 0;
233
234     /**
235      * Argument to <code>setEncryptionAlgorithm</code> to
236      * set the encryption to the standard 40 bit encryption
237      * algorithm used by Acrobat 3.x and later.
238      * @since 1.1.12
239      */

240     public static final int ENCRYPT_40BIT = 40;
241
242     /**
243      * Argument to <code>setEncryptionAlgorithm</code> to
244      * set the encryption to the 128 bit encryption
245      * algorithm added in Acrobat 5.x. Documents encrypted
246      * with this algorithm cannot be opened by earlier
247      * versions of Acrobat.
248      * @since 1.1.12
249      */

250     public static final int ENCRYPT_128BIT = 128;
251
252
253     public PDF(org.faceless.pdf2.PDF pdf)
254     {
255         this.pdf=pdf;
256     }
257
258     /**
259      * Create a new PDF document.
260      */

261     public PDF()
262     {
263     pdf = new org.faceless.pdf2.PDF();
264     }
265
266     /**
267      * Create a PDF from the specified PDFReader. The <tt>PDFReader</tt> class
268      * is available as part of the "Extended Edition" of the PDF library, and is
269      * included with this package. If the document contains multiple revisions,
270      * the latest revision is loaded.
271      * @since 1.1.12
272      */

273     public PDF(PDFReader reader)
274     {
275     pdf = new org.faceless.pdf2.PDF(reader.reader);
276     }
277
278     /**
279      * Create a PDF from the specified PDFReader, using the specified revision of
280      * the document. The <tt>PDFReader</tt> class is available as part of the
281      * "Extended Edition" of the PDF library, and is included with this package.
282      * The revision number must be between 0 and
283      * {@link PDFReader#getNumberOfRevisions}, otherwise an
284      * <code>IllegalArgumentException</code> is thrown.
285      * @param reader the <code>PDFReader</code> to load the document from
286      * @param revision the revision of the document to load - betwween
287      * <code>reader.getNumberOfRevisions()-1</code> to load the latest revision, or
288      * <code>0</code> to load the first.
289      * @since 1.2.1
290      */

291     public PDF(PDFReader reader, int revision)
292     {
293     pdf = new org.faceless.pdf2.PDF(reader.reader, revision);
294     }
295
296     /**
297      * Create a new page with the specified pagesize. This version is
298      * usually called to set the page to a standard size, like
299      * {@link #PAGESIZE_A4}
300      * @param pagesize The size of the page as a String of the format "WxH",
301      * showing width and height in points.
302      */

303     public PDFPage newPage(String JavaDoc pagesize)
304     {
305     return (PDFPage)PeeredObject.getPeer(pdf.newPage(pagesize));
306     }
307
308     /**
309      * Create a new page in the specified size.
310      * @param width The width of the page, in points
311      * @param height The height of the page, in points
312      */

313     public PDFPage newPage(float width, float height)
314     {
315     return (PDFPage)PeeredObject.getPeer(pdf.newPage((int)width,(int)height));
316     }
317
318     /**
319      * Return the page returned from the last call to <code>newPage</code>
320      * @return the last page returned from the {@link #newPage} method, or
321      * <tt>null</tt> if that method hasn't been called yet.
322      */

323     public PDFPage getLastPage()
324     {
325     return getPage(getNumberOfPages()-1);
326     }
327
328     /**
329      * Return the specified page, where <code>0 &lt;= page &lt; numpages</code>.
330      * If the page is outside this range, throw an <code>ArrayIndexOutOfBoundsException</code>
331      * @return the specified page
332      * @throws ArrayIndexOutOfBoundsException if the page is out of range
333      * @since 1.1
334      */

335     public PDFPage getPage(int pagenum)
336         throws ArrayIndexOutOfBoundsException JavaDoc
337     {
338     return (PDFPage)PeeredObject.getPeer(pdf.getPage(pagenum));
339     }
340
341     /**
342      * Return the number of pages currently defined in the PDF document
343      * @since 1.1
344      */

345     public int getNumberOfPages()
346     {
347     return pdf.getNumberOfPages();
348     }
349
350     /**
351      * Return the number of revisions made to the document. This will only be
352      * useful for documents read in using a <code>PDFReader</code> - all
353      * other PDFs (and many of these too) will return zero. See the
354      * {@link PDFReader} class for more information on revisions.
355      * @since 1.2.1
356      */

357     public int getNumberOfRevisions()
358     {
359     return pdf.getNumberOfRevisions();
360     }
361
362     /**
363      * Return the list of pages in the PDF document. This list can be manipulated
364      * to reorder, delete or append pages as necessary using the standard
365      * <tt>java.util.List</tt> methods.
366      * @since 1.1.12
367      */

368     public List getPages()
369     {
370     /*
371      * We need to override these methods because in version 1, moving pages
372      * between documents also moved any form fields associated with those
373      * pages. This is a bit crude - what happens if a field has annotations
374      * on two pages, for instance - but that's what it did, so that's what
375      * we do here too.
376      */

377
378     return new ListPeer(pdf.getPages())
379     {
380         public void add(int i, Object JavaDoc o)
381         {
382             super.add(i,o);
383         List l = ((PDFPage)o).page.getAnnotations();
384         for (i=0;i<l.size();i++) {
385             if (l.get(i) instanceof org.faceless.pdf2.WidgetAnnotation) {
386                 org.faceless.pdf2.WidgetAnnotation annot = (org.faceless.pdf2.WidgetAnnotation)l.get(i);
387                 pdf.getForm().getElements().put(annot.getField().getForm().getName(annot.getField()), annot.getField());
388             }
389         }
390         }
391
392         public Object JavaDoc set(int i, Object JavaDoc o)
393         {
394             Object JavaDoc old = super.set(i,o);
395         List l = ((PDFPage)o).page.getAnnotations();
396         for (i=0;i<l.size();i++) {
397             if (l.get(i) instanceof org.faceless.pdf2.WidgetAnnotation) {
398                 org.faceless.pdf2.WidgetAnnotation annot = (org.faceless.pdf2.WidgetAnnotation)l.get(i);
399                 pdf.getForm().getElements().put(annot.getField().getForm().getName(annot.getField()), annot.getField());
400             }
401         }
402         return old;
403         }
404     };
405     }
406
407     /**
408      * <p>
409      * Set the current Locale of the document. The locale language alters how the document
410      * processes text internally - for example, setting the locale to
411      * <code>Locale.ARABIC</code> sets the default justification to right-aligned.
412      * </p><p>
413      * The locale may be set many times throughout the document as required. However,
414      * changing the locale in the middle of a paragraph should be avoided.
415      * </p><p>
416      * The default PDF locale is the value of <code>Locale.getDefault()</code>
417      * </p>
418      * @since 1.1
419      */

420     public void setLocale(Locale locale)
421     {
422     pdf.setLocale(locale);
423     }
424
425     /**
426      * Return the PDF's locale, as set by {@link #setLocale}
427      * @since 1.1
428      */

429     public Locale getLocale()
430     {
431     return pdf.getLocale();
432     }
433
434     /**
435      * Controls how the document is initially laid out in the PDF viewer.
436      *
437      * @param layout How to display the document if there is more than one page.
438      * Can be {@link #SINGLEPAGE} (the default), {@link #ONECOLUMN},
439      * {@link #TWOCOLUMNLEFT} or {@link #TWOCOLUMNRIGHT}
440      * @param bookmarks whether to show bookmarks when the document is first
441      * opened. The default is <i>false</i>.
442      */

443     public void setLayout(String JavaDoc layout, boolean bookmarks)
444     {
445     pdf.setLayout(layout, bookmarks ? "UseOutlines" : "UseNone");
446     }
447
448     /**
449      * <p>
450      * Add some meta-information on the document, like the subject or title.
451      * Although any key or value is valid (except <code>Producer</code>,
452      * <code>CreationDate</code> and <code>ModDate</code>, which are set
453      * by the library internally), the following fields are recognised
454      * by Acrobat:
455      * </p><table>
456      * <tr><th align=left valign=top>Title</th><td>The document's title</td></tr>
457      * <tr><th align=left valign=top>Author</th><td>The name of the person who created the document.</td></tr>
458      * <tr><th align=left valign=top>Subject</th><td>The subject of the document.</td></tr>
459      * <tr><th align=left valign=top>Keywords</th><td>Keywords associated with the document.</td></tr>
460      * <tr><th align=left valign=top>Creator</th><td>If the document was converted to PDF from another format, the
461      * name of the application that created the original document from which it was converted.</td></tr>
462      * </table>
463      * <p>
464      * Although both key and value can use Unicode characters outside the
465      * ASCII range, whether the viewer can display them correctly is another
466      * matter.
467      * </p>
468      * <p>
469      * Note that this meta-information can be set independently of any XML
470      * meta information as set by {@link #setMetaData}.
471      * </p>
472      * @param key the field to set
473      * @param val the value to set.
474      */

475     public void setInfo(String JavaDoc key, String JavaDoc val)
476     {
477     pdf.setInfo(key,val);
478     }
479
480     /**
481      * <p>
482      * Return document meta information, as set by {@link #setInfo}.
483      * </p>
484      * <p>
485      * Note that this meta-information can be used independently of any XML
486      * meta information as returned by {@link #getMetaData}.
487      * </p>
488      * @param key the field to get
489      * @return the value of the specified field, or <tt>null</tt> if the field is not set
490      */

491     public String JavaDoc getInfo(String JavaDoc key)
492     {
493     return pdf.getInfo(key);
494     }
495
496     /**
497      * <p>
498      * Return document meta information, as set by {@link #setInfo}. This
499      * method returns a map containing all the meta information. If no
500      * meta information is available, returns an empty Map.
501      * </p><p>
502      * Note that this meta-information can be used independently of any XML
503      * meta information as returned by {@link #getMetaData}.
504      * </p>
505      * @return a Map containing any meta information specified in the document.
506      * The keys in the Map are Strings, and the values are always Strings or
507      * Dates.
508      * @since 1.1.12
509      */

510     public Map getInfo()
511     {
512     // We have to filter out anything that's not a String or a Date,
513
// as that's all v1 functions were expecting back.
514
//
515
Map m = pdf.getInfo();
516     Map out = new HashMap();
517     for (Iterator i = m.entrySet().iterator();i.hasNext();) {
518         Map.Entry entry = (Map.Entry)i.next();
519         if (entry.getValue() instanceof String JavaDoc || entry.getValue() instanceof Date) {
520             out.put(entry.getKey(), entry.getValue());
521         }
522     }
523     return Collections.unmodifiableMap(out);
524     }
525
526     /**
527      * <p>
528      * Set the page to open Full Screen or not. This is off by default, and will
529      * probably be ignored by any PDF viewer other than Adobe's own Acrobat.
530      * </p>
531      * @since 1.1.2
532      */

533     public void setOpenFullScreen(boolean fullscreen)
534     {
535     pdf.setViewerPreference("FullScreen", fullscreen);
536     }
537
538     /**
539      * <p>
540      * Set the XML Metadata associated with this document. This is a PDF
541      * 1.4 feature, so it will only be used by Acrobat 5.0 or later - although
542      * it <i>should</i> be ignored by earlier viewers.
543      * </p><p>
544      * The value is specified as a String, but as it's XML it will probably be
545      * created as a <tt>java.io.Writer</tt>. Here's an example showing how
546      * to use this with SAX and the <tt>org.apache.xml.serialize</tt>
547      * classes. The lines marked in bold could apply to any method of
548      * serializing the XML.
549      * </p>
550      * <pre>
551      * void addMetaData(PDF pdf, InputSource source)
552      * {
553      * <i>// Create a java.io.Writer</i>
554      * <b>StringWriter meta = new StringWriter();</b>
555      *
556      * <i>// Create a SAX XML serializer using the apache classes</i>
557      * <i>// We must not include the XML Declaration in the output.</i>
558      * OutputFormat outformat = new OutputFormat();
559      * outformat.setOmitXMLDeclaration(true);
560      * Serializer serial = new XMLSerializer(out, outformat);
561      *
562      * <i>// Create the XML parser and parse the input source</i>
563      * XMLReader parser = XMLReaderFactory.createXMLReader();
564      * parser.setContentHandler(serial.asContentHandler());
565      * parser.parse(inputsource);
566      *
567      * <b>pdf.setMetaData(meta.toString());</b>
568      * }
569      * </pre>
570      * <p>
571      * For more information on XML metadata in PDF documents, see
572      * <a HREF="http://www.adobe.com/products/xmp">http://www.adobe.com/products/xmp</a>
573      * </p>
574      * @param xmldata the XML data to embed into the document. No validation is performed
575      * on this input.
576      * @since 1.1.12
577      */

578     public void setMetaData(String JavaDoc xmldata)
579     {
580         pdf.setMetaData(xmldata);
581     }
582
583     /**
584      * <p>
585      * Return any XML Metadata associated with the document. XML Metadata
586      * is a PDF 1.4 (Acrobat 5.x) feature, so this method will return
587      * <tt>null</tt> for all documents matching earlier specifications or
588      * if no metadata is specified.
589      * </p><p>
590      * Here's an example of how to extract the MetaData into a DOM tree.
591      * Lines in bold could apply to any parsing method.
592      * </p>
593      * <pre>
594      * <b>InputSource source = new InputSource(pdf.getMetaData());</b>
595      * DOMParser parser = new DOMParser();
596      * parser.parse(source);
597      * Document doc = parser.getDocument();
598      * </pre>
599      * <p>
600      * For more information on XML metadata in PDF documents, see
601      * <a HREF="http://www.adobe.com/products/xmp">http://www.adobe.com/products/xmp</a>
602      * </p>
603      * @since 1.1.12
604      * @returns a {@link java.io.Reader} containing the source of the XML
605      */

606     public Reader getMetaData()
607         throws IOException
608     {
609         return pdf.getMetaData();
610     }
611
612     /**
613      * <p>
614      * Set some preferences as to how the document is displayed on screen. Along with the
615      * <code>setLayout</code> function (which set some of the
616      * more conventional viewer preferences), this function allow you to turn on or off some
617      * of the more obscure features of the users PDF viewer application. By default, all
618      * these options are set to <i>false</i>. Valid options are:
619      * </p>
620      * <table>
621      * <tr><th align=left valign=top>HideToolbar</th><td>A flag specifying whether to hide the viewer application's tool bars when the document is active.</td></tr>
622      * <tr><th align=left valign=top>HideMenubar</th><td>A flag specifying whether to hide the viewer application's menu bar when the document is active.</td></tr>
623      * <tr><th align=left valign=top>HideWindowUI</th><td>A flag specifying whether to hide user interface elements in the document' window (such as scroll bars and navigation controls), leaving only the document's contents displayed.</td></tr>
624      * <tr><th align=left valign=top>FitWindow</th><td>A flag specifying whether to resize the document's window to fit the size of the first displayed page. Note this resizes the window to fit the document, not the other way round.</td></tr>
625      * <tr><th align=left valign=top>CenterWindow</th><td>A flag specifying whether to position the document's window in the center of the screen. Note this moves the whole viewer to the center of the screen, not the document to the center of the viewer.</td></tr>
626      * </table>
627      * <p>Viewers other than Adobes own Acrobat reader will probably ignore these options.</p>
628      * @param key the option to set, from the list above
629      * @param val whether to turn that option on or off
630      */

631     public void setViewerPreference(String JavaDoc key, boolean val)
632     {
633     pdf.setViewerPreference(key, val);
634     }
635
636     /**
637      * Return the value of the specified viewer preference, as set by {@link #setViewerPreference}.
638      * @param key the option to query
639      * @return <tt>true</tt> if the option is set to "on", or <tt>false</tt> if the option is set to "off" or not set.
640      * @since 1.1.12
641      */

642     public boolean getViewerPreference(String JavaDoc key)
643     {
644     return pdf.getViewerPreference(key);
645     }
646
647     /**
648      * <p>
649      * Set the action to perform when the document is first opened. Use
650      * this method to open the PDF at a specific page, or set the initial
651      * zoom level.
652      * </p><p>
653      * To run an action when a specific <i>page</i> is opened, see the
654      * method with the same name in the {@link PDFPage} object.
655      * </p>
656      * @param action The action to perform on opening. Since 1.1, set to
657      * <code>null</code> to remove the action.
658      */

659     public void setOpenAction(PDFAction action)
660     {
661     pdf.setAction(org.faceless.pdf2.Event.OPEN, action==null ? null : action.action);
662     }
663
664     /**
665      * Return the action that is performed when the document is first
666      * opened.
667      * @return the action that is performed when the document is first
668      * opened, or <tt>null</tt> if no action is performed
669      * @since 1.1.12
670      */

671     public PDFAction getOpenAction()
672     {
673     return (PDFAction)PeeredObject.getPeer(pdf.getAction(org.faceless.pdf2.Event.OPEN));
674     }
675
676     /**
677      * <p>
678      * Create a "named" action, which can be referenced from outside the
679      * current PDF, useful to (for example) open the generated PDF at a
680      * specific position from an HTML link. Here's how to do this:
681      * </p>
682      * In the PDF, add the following code:
683      * <pre>
684      * pdf.setNamedAction("Myaction", PDFAction.goTo(somepage))
685      * </pre>
686      * Then in your HTML document, add the following code:
687      * <pre>
688      * &lt;a HREF="http://www.mycompany.com/mypdf.pdf#Myaction"&gt;
689      * </pre>
690      * <p>
691      * The action name is case sensitive. Adding a <tt>null</tt> action
692      * causes the specified named action to be deleted. The action <i>must</i>
693      * be a standard "goTo" action, jumping to a page in the document.
694      * </p>
695      * @param name The name to give this action.
696      * @param action The action to perform on opening, or <tt>null</tt> to
697      * delete the action
698      * @since 1.1.5
699      */

700     public void setNamedAction(String JavaDoc name, PDFAction action)
701     {
702     if (action==null) {
703         pdf.getNamedActions().remove(name);
704     } else {
705         pdf.getNamedActions().put(name, action.action);
706     }
707     }
708
709     /**
710      * Return a Map of all the "named actions" in the document,
711      * as set by {@link #setNamedAction}.
712      * @return A Map of all the named actions in the document. The key is
713      * the {@link java.lang.String} which is the name of the action, the
714      * value is the {@link PDFAction} to be performed. If no named actions
715      * are specified, an empty map is returned.
716      * @since 1.1.12
717      */

718     public Map getNamedActions()
719     {
720     // Return a copy, because in v1 changing the returned map has no effect.
721
TreeMap map = new TreeMap();
722     for (Iterator i = pdf.getNamedActions().entrySet().iterator();i.hasNext();) {
723         Map.Entry entry = (Map.Entry)i.next();
724         map.put(entry.getKey(), PeeredObject.getPeer(entry.getValue()));
725     }
726     return map;
727     }
728
729     /**
730      * Return the list of Bookmarks at the top level of the document. The List
731      * contains zero or more elements of type {@link PDFBookmark}. The List can
732      * be altered using any of the standard {@link java.util.List} methods to
733      * order the documents bookmarks in any way you see fit. By default, all
734      * documents start with an empty List.
735      * @see PDFBookmark
736      * @return The List of bookmarks at the top level of the document
737      */

738     public List getBookmarks()
739     {
740     return new ListPeer(pdf.getBookmarks());
741     }
742
743     // ---------------------------------------------------------------------------------
744

745     /**
746      * <p>
747      * Set the "security" password for the PDF document - the password
748      * required to change the security settings of the document (the access
749      * level and the open password). If you don't anticipate changing
750      * the security settings at a later date, you can leave this blank.
751      * </p><p>
752      * If no encryption type has been set by calling {@link #setEncryptionAlgorithm},
753      * the algorithm is set to the standard 40 bit encryption.
754      * </p>
755      * @since 1.1
756      */

757     public void setSecurityPassword(String JavaDoc s)
758     {
759     org.faceless.pdf2.StandardEncryptionHandler handler = (org.faceless.pdf2.StandardEncryptionHandler)pdf.getEncryptionHandler();
760     if (s==null) s="";
761     if (handler==null) {
762         handler = new org.faceless.pdf2.StandardEncryptionHandler();
763         pdf.setEncryptionHandler(handler);
764     }
765     handler.setOwnerPassword(s);
766     }
767
768     /**
769      * <p>
770      * Set the password required to open the PDF document.
771      * (also called the "User" password). It can be left blank,
772      * in which case the document can be opened by anyone.
773      * </p><p>
774      * If no encryption type has been set by calling {@link #setEncryptionAlgorithm},
775      * the algorithm is set to the standard 40 bit encryption.
776      * </p>
777      * @since 1.1
778      */

779     public void setPassword(String JavaDoc s)
780     {
781     org.faceless.pdf2.StandardEncryptionHandler handler = (org.faceless.pdf2.StandardEncryptionHandler)pdf.getEncryptionHandler();
782     if (s==null) s="";
783     if (handler==null) {
784         handler = new org.faceless.pdf2.StandardEncryptionHandler();
785         pdf.setEncryptionHandler(handler);
786     }
787     handler.setUserPassword(s);
788     }
789
790     /**
791      * <p>
792      * Set the encryption algorithm used to encrypt the document.
793      * Currently limited to either {@link #ENCRYPT_NONE} to disable
794      * encryption, {@link #ENCRYPT_40BIT} to use the standard 40-bit
795      * algorithm accepted by most modern versions of Acrobat, or
796      * {@link #ENCRYPT_128BIT} to use the expanded 128-bit algorithm
797      * introduced in PDF1.4 (Acrobat 5).
798      * </p>
799      * @since 1.1.12
800      */

801     public void setEncryptionAlgorithm(int type)
802     {
803     if (type==ENCRYPT_NONE) {
804         pdf.setEncryptionHandler(null);
805     } else {
806         org.faceless.pdf2.StandardEncryptionHandler handler = (org.faceless.pdf2.StandardEncryptionHandler)pdf.getEncryptionHandler();
807         if (handler==null) {
808         handler = new org.faceless.pdf2.StandardEncryptionHandler();
809         pdf.setEncryptionHandler(handler);
810         }
811         if (type==ENCRYPT_128BIT) {
812         handler.setAcrobat5Level(handler.PRINT_HIGHRES, handler.EXTRACT_ALL, handler.CHANGE_ALL);
813         } else {
814         handler.setAcrobat3Level(true, true, true, true);
815         }
816     }
817     }
818
819     /**
820      * <p>
821      * Set the level of access available to the user. The user can be granted any
822      * of the {@link #ACCESS_PRINT}, {@link #ACCESS_EDIT}, {@link #ACCESS_COPY}
823      * or {@link #ACCESS_ANNOTATE} rights. Additionally, if 128 bit encryption
824      * is used the {@link #ACCESS_FORMS}, {@link #ACCESS_ASSEMBLE}, {@link #ACCESS_EXTRACT}
825      * and {@link #ACCESS_HQPRINT} options can be used.
826      * </p><p>
827      * Please remember it is <i>up to the PDF viewer software</i> to enforce this, and
828      * that there are plenty of applications available on the 'net to allow full access
829      * to a PDF document. Consequently this setting should be considered a <b>recommendation
830      * only</b>.
831      * </p><p>
832      * Setting this value involves encrypting the document, even if no password has been
833      * set. If no encryption type has been set by calling {@link #setEncryptionAlgorithm},
834      * the algorithm is set to the standard 40 bit encryption.
835      * </p><p>
836      * The default is that the user has full access to the document.
837      * </p>
838      * @param level a logical-OR of any of the above flags
839      * @since 1.1
840      */

841     public void setAccessLevel(int level)
842     {
843     org.faceless.pdf2.StandardEncryptionHandler handler = (org.faceless.pdf2.StandardEncryptionHandler)pdf.getEncryptionHandler();
844     if (handler==null) {
845         handler = new org.faceless.pdf2.StandardEncryptionHandler();
846         pdf.setEncryptionHandler(handler);
847     }
848
849     if (handler.getVersion()==2) {
850         boolean print = (level&ACCESS_PRINT)!=0;
851         boolean annotate = (level&ACCESS_ANNOTATE)!=0;
852         boolean edit = (level&ACCESS_EDIT)!=0;
853         boolean copy = (level&ACCESS_COPY)!=0;
854         boolean forms = (level&ACCESS_FORMS)!=0;
855         boolean extract = (level&ACCESS_EXTRACT)!=0;
856         boolean assemble = (level&ACCESS_ASSEMBLE)!=0;
857         boolean hqprint = (level&ACCESS_HQPRINT)!=0;
858
859         int newchange=handler.CHANGE_NONE, newprint=handler.PRINT_NONE, newextract=handler.EXTRACT_NONE;
860
861         if (print && hqprint) {
862             newprint=handler.PRINT_HIGHRES;
863         } else if (print) {
864             newprint=handler.PRINT_LOWRES;
865         } else {
866             newprint=handler.PRINT_NONE;
867         }
868
869         if (extract && copy) {
870             newprint=handler.EXTRACT_ALL;
871         } else if (extract) {
872             newprint=handler.EXTRACT_ACCESSIBILITY;
873         } else {
874             newprint=handler.EXTRACT_NONE;
875         }
876
877         if (assemble && annotate && edit) {
878             newchange = handler.CHANGE_ALL;
879         } else if (assemble && annotate) {
880             newchange = handler.CHANGE_ANNOTATIONS;
881         } else if (forms) {
882             newchange = handler.CHANGE_FORMS;
883         } else if (assemble) {
884             newchange = handler.CHANGE_LAYOUT;
885         } else {
886             newchange = handler.CHANGE_NONE;
887         }
888
889         handler.setAcrobat5Level(newprint, newextract, newchange);
890     }
891     else
892     {
893         boolean print = (level&ACCESS_PRINT)!=0;
894         boolean annotate = (level&ACCESS_ANNOTATE)!=0;
895         boolean edit = (level&ACCESS_EDIT)!=0;
896         boolean copy = (level&ACCESS_COPY)!=0;
897         handler.setAcrobat3Level(print, annotate, copy, edit);
898     }
899     }
900
901
902     //--------------------------------------------------------------------
903

904
905     /**
906      * Return the Interactive {@link Form} or "AcroForm" object which is part
907      * of each PDF document.
908      * <b>Note that using interactive forms requires the "Extended Edition"
909      * of the library</b> - although the classes are supplied with the package an "Extended
910      * Edition" license must be purchased to activate this functionality.
911      * @since 1.1.13
912      */

913     public Form getForm()
914     {
915     return (Form)PeeredObject.getPeer(pdf.getForm());
916     }
917
918     /**
919      * Set the document-wide JavaScript. This JavaScript is executed when
920      * the document is first loaded - this is normally used to define
921      * functions and the like, in the same way as JavaScript defined in the
922      * &lt;HEAD&gt; of an HTML document.
923      * @param javascript the JavaScript to use for the entire document
924      * @since 1.1.23
925      * @see #getJavaScript
926      * @see PDFAction#formJavaScript
927      */

928     public void setJavaScript(String JavaDoc javascript)
929     {
930     pdf.setJavaScript(javascript);
931     }
932
933     /**
934      * Return the document-wide JavaScript, as set by {@link #setJavaScript},
935      * or <code>null</code> if no JavaScript is defined for this document.
936      * @since 1.1.23
937      * @see #setJavaScript
938      * @see PDFAction#formJavaScript
939      */

940     public String JavaDoc getJavaScript()
941     {
942     return pdf.getJavaScript();
943     }
944
945     /**
946      * <p>
947      * This method renders the completed PDF to an OutputStream. The
948      * stream is left open on completion. A document may be rendered
949      * more than once. Rendering the document merges all the revisions
950      * of a document, so after rendering the {@link #getNumberOfRevisions}
951      * method will always return zero.
952      * </p>
953      * @param out the output stream to write the PDF to.
954      * @throws IOException if the rendering process could not be completed
955      */

956     public synchronized void render(OutputStream out)
957     throws IOException
958     {
959     pdf.render(out);
960     }
961
962     /**
963      * Set the license key for the library. When the library is purchased,
964      * the Big Faceless Organization supplies a key which removes the "DEMO"
965      * stamp on each of the documents
966      * @param key the license key
967      */

968     public static void setLicenseKey(String JavaDoc key)
969     {
970         org.faceless.pdf2.PDF.setLicenseKey(key);
971     }
972
973     /**
974      * Import the contents of the specified {@link FDF} into the PDF document.
975      * Although the FDF file may contain a wide variety of information, the
976      * only part of it actually used by this method are the form values, which
977      * are used to set the corresponding form fields in the PDF. If a field
978      * doesn't exist, a warning is printed and the field is ignored
979      * @since 1.2.1
980      */

981     public void importFDF(FDF fdf)
982     {
983     pdf.importFDF((org.faceless.pdf2.FDF)fdf.fdf);
984     }
985 }
986
Popular Tags