KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > text > rtf > RtfWriter


1 /*
2  * $Id: RtfWriter.java 2752 2007-05-15 14:58:33Z blowagie $
3  * $Name$
4  *
5  * Copyright 2001, 2002 by Mark Hall
6  *
7  * The contents of this file are subject to the Mozilla Public License Version 1.1
8  * (the "License"); you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the License.
14  *
15  * The Original Code is 'iText, a free JAVA-PDF library'.
16  *
17  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
18  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
19  * All Rights Reserved.
20  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
21  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
22  *
23  * Contributor(s): all the names of the contributors are added in the source code
24  * where applicable.
25  *
26  * Alternatively, the contents of this file may be used under the terms of the
27  * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
28  * provisions of LGPL are applicable instead of those above. If you wish to
29  * allow use of your version of this file only under the terms of the LGPL
30  * License and not to allow others to use your version of this file under
31  * the MPL, indicate your decision by deleting the provisions above and
32  * replace them with the notice and other provisions required by the LGPL.
33  * If you do not delete the provisions above, a recipient may use your version
34  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
35  *
36  * This library is free software; you can redistribute it and/or modify it
37  * under the terms of the MPL as stated above or under the terms of the GNU
38  * Library General Public License as published by the Free Software Foundation;
39  * either version 2 of the License, or any later version.
40  *
41  * This library is distributed in the hope that it will be useful, but WITHOUT
42  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
43  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
44  * details.
45  *
46  * If you didn't download this code from the following link, you should check if
47  * you aren't using an obsolete version:
48  * http://www.lowagie.com/iText/
49  */

50
51 package com.lowagie.text.rtf;
52
53 import java.awt.Color JavaDoc;
54 import java.io.ByteArrayInputStream JavaDoc;
55 import java.io.ByteArrayOutputStream JavaDoc;
56 import java.io.IOException JavaDoc;
57 import java.io.InputStream JavaDoc;
58 import java.io.OutputStream JavaDoc;
59 import java.text.ParsePosition JavaDoc;
60 import java.text.SimpleDateFormat JavaDoc;
61 import java.util.ArrayList JavaDoc;
62 import java.util.Calendar JavaDoc;
63 import java.util.Date JavaDoc;
64 import java.util.Iterator JavaDoc;
65 import java.util.ListIterator JavaDoc;
66
67 import com.lowagie.text.Anchor;
68 import com.lowagie.text.Annotation;
69 import com.lowagie.text.Chunk;
70 import com.lowagie.text.DocWriter;
71 import com.lowagie.text.Document;
72 import com.lowagie.text.DocumentException;
73 import com.lowagie.text.Element;
74 import com.lowagie.text.ExceptionConverter;
75 import com.lowagie.text.Font;
76 import com.lowagie.text.HeaderFooter;
77 import com.lowagie.text.Image;
78 import com.lowagie.text.ListItem;
79 import com.lowagie.text.Meta;
80 import com.lowagie.text.PageSize;
81 import com.lowagie.text.Paragraph;
82 import com.lowagie.text.Phrase;
83 import com.lowagie.text.Rectangle;
84 import com.lowagie.text.Section;
85 import com.lowagie.text.SimpleTable;
86 import com.lowagie.text.Table;
87 import com.lowagie.text.pdf.codec.wmf.MetaDo;
88
89 /**
90  * If you are creating a new project using the rtf part of iText, please
91  * consider using the new RtfWriter2. The RtfWriter is in bug-fix-only mode,
92  * will be deprecated end of 2005 and removed end of 2007.
93  *
94  * A <CODE>DocWriter</CODE> class for Rich Text Files (RTF).
95  * <P>
96  * A <CODE>RtfWriter</CODE> can be added as a <CODE>DocListener</CODE>
97  * to a certain <CODE>Document</CODE> by getting an instance.
98  * Every <CODE>Element</CODE> added to the original <CODE>Document</CODE>
99  * will be written to the <CODE>OutputStream</CODE> of this <CODE>RtfWriter</CODE>.
100  * <P>
101  * Example:
102  * <BLOCKQUOTE><PRE>
103  * // creation of the document with a certain size and certain margins
104  * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
105  * try {
106  * // this will write RTF to the Standard OutputStream
107  * <STRONG>RtfWriter.getInstance(document, System.out);</STRONG>
108  * // this will write Rtf to a file called text.rtf
109  * <STRONG>RtfWriter.getInstance(document, new FileOutputStream("text.rtf"));</STRONG>
110  * // this will write Rtf to for instance the OutputStream of a HttpServletResponse-object
111  * <STRONG>RtfWriter.getInstance(document, response.getOutputStream());</STRONG>
112  * }
113  * catch(DocumentException de) {
114  * System.err.println(de.getMessage());
115  * }
116  * // this will close the document and all the OutputStreams listening to it
117  * <STRONG>document.close();</CODE>
118  * </PRE></BLOCKQUOTE>
119  * <P>
120  * <STRONG>LIMITATIONS</STRONG><BR>
121  * There are currently still a few limitations on what the RTF Writer can do:
122  * <ul>
123  * <li>Watermarks</li>
124  * <li>Viewer preferences</li>
125  * <li>Encryption</li>
126  * <li>Embedded fonts</li>
127  * <li>Phrases with a leading</li>
128  * <li>Lists with non-bullet symbols</li>
129  * <li>Nested tables</li>
130  * <li>Images other than JPEG and PNG</li>
131  * <li>Rotated images</li>
132  * </ul>
133  * <br />
134  *
135  * @author Mark Hall (mhall@edu.uni-klu.ac.at)
136  * @author Steffen Stundzig (Steffen.Stundzig@smb-tec.com)
137  * @author Eric Mattes (ericmattes@yahoo.com)
138  * @author Raul Wegmann (raul.wegmann@uam.es)
139  * @deprecated The RtfWriter is deprecated and will be removed from the iText library end of 2007
140  */

141 public class RtfWriter extends DocWriter {
142     /**
143      * Static Constants
144      */

145
146     /**
147      * General
148      */

149
150     /** This is the escape character which introduces RTF tags. */
151     public static final byte escape = (byte) '\\';
152
153     /** This is another escape character which introduces RTF tags. */
154     private static final byte[] extendedEscape = "\\*\\".getBytes();
155
156     /** This is the delimiter between RTF tags and normal text. */
157     protected static final byte delimiter = (byte) ' ';
158
159     /** This is another delimiter between RTF tags and normal text. */
160     private static final byte commaDelimiter = (byte) ';';
161
162     /** This is the character for beginning a new group. */
163     public static final byte openGroup = (byte) '{';
164
165     /** This is the character for closing a group. */
166     public static final byte closeGroup = (byte) '}';
167
168     /**
169      * RTF Information
170      */

171
172     /** RTF begin and version. */
173     private static final byte[] docBegin = "rtf1".getBytes();
174
175     /** RTF encoding. */
176     private static final byte[] ansi = "ansi".getBytes();
177
178     /** RTF encoding codepage. */
179     private static final byte[] ansiCodepage = "ansicpg".getBytes();
180
181     /**
182      *Font Data
183      */

184
185     /** Begin the font table tag. */
186     private static final byte[] fontTable = "fonttbl".getBytes();
187
188     /** Font number tag. */
189     protected static final byte fontNumber = (byte) 'f';
190
191     /** Font size tag. */
192     protected static final byte[] fontSize = "fs".getBytes();
193
194     /** Font color tag. */
195     protected static final byte[] fontColor = "cf".getBytes();
196
197     /** Modern font tag. */
198     private static final byte[] fontModern = "fmodern".getBytes();
199
200     /** Swiss font tag. */
201     private static final byte[] fontSwiss = "fswiss".getBytes();
202
203     /** Roman font tag. */
204     private static final byte[] fontRoman = "froman".getBytes();
205
206     /** Tech font tag. */
207     private static final byte[] fontTech = "ftech".getBytes();
208
209     /** Font charset tag. */
210     private static final byte[] fontCharset = "fcharset".getBytes();
211
212     /** Font Courier tag. */
213     private static final byte[] fontCourier = "Courier".getBytes();
214
215     /** Font Arial tag. */
216     private static final byte[] fontArial = "Arial".getBytes();
217
218     /** Font Symbol tag. */
219     private static final byte[] fontSymbol = "Symbol".getBytes();
220
221     /** Font Times New Roman tag. */
222     private static final byte[] fontTimesNewRoman = "Times New Roman".getBytes();
223
224     /** Font Windings tag. */
225     private static final byte[] fontWindings = "Windings".getBytes();
226
227     /** Default Font. */
228     private static final byte[] defaultFont = "deff".getBytes();
229
230     /** First indent tag. */
231     private static final byte[] firstIndent = "fi".getBytes();
232
233     /** Left indent tag. */
234     private static final byte[] listIndent = "li".getBytes();
235
236     /** Right indent tag. */
237     private static final byte[] rightIndent = "ri".getBytes();
238
239     /**
240      * Sections / Paragraphs
241      */

242
243     /** Reset section defaults tag. */
244     private static final byte[] sectionDefaults = "sectd".getBytes();
245
246     /** Begin new section tag. */
247     private static final byte[] section = "sect".getBytes();
248
249     /** Reset paragraph defaults tag. */
250     public static final byte[] paragraphDefaults = "pard".getBytes();
251
252     /** Begin new paragraph tag. */
253     public static final byte[] paragraph = "par".getBytes();
254
255     /** Page width of a section. */
256     public static final byte[] sectionPageWidth = "pgwsxn".getBytes();
257
258     /** Page height of a section. */
259     public static final byte[] sectionPageHeight = "pghsxn".getBytes();
260
261     /**
262      * Lists
263      */

264
265     /** Begin the List Table */
266     private static final byte[] listtableGroup = "listtable".getBytes();
267
268     /** Begin the List Override Table */
269     private static final byte[] listoverridetableGroup = "listoverridetable".getBytes();
270
271     /** Begin a List definition */
272     private static final byte[] listDefinition = "list".getBytes();
273
274     /** List Template ID */
275     private static final byte[] listTemplateID = "listtemplateid".getBytes();
276
277     /** RTF Writer outputs hybrid lists */
278     private static final byte[] hybridList = "hybrid".getBytes();
279
280     /** Current List level */
281     private static final byte[] listLevelDefinition = "listlevel".getBytes();
282
283     /** Level numbering (old) */
284     private static final byte[] listLevelTypeOld = "levelnfc".getBytes();
285
286     /** Level numbering (new) */
287     private static final byte[] listLevelTypeNew = "levelnfcn".getBytes();
288
289     /** Level alignment (old) */
290     private static final byte[] listLevelAlignOld = "leveljc".getBytes();
291
292     /** Level alignment (new) */
293     private static final byte[] listLevelAlignNew = "leveljcn".getBytes();
294
295     /** Level starting number */
296     private static final byte[] listLevelStartAt = "levelstartat".getBytes();
297
298     /** Level text group */
299     private static final byte[] listLevelTextDefinition = "leveltext".getBytes();
300
301     /** Filler for Level Text Length */
302     private static final byte[] listLevelTextLength = "\'0".getBytes();
303
304     /** Level Text Numbering Style */
305     private static final byte[] listLevelTextStyleNumbers = "\'00.".getBytes();
306
307     /** Level Text Bullet Style */
308     private static final byte[] listLevelTextStyleBullet = "u-3913 ?".getBytes();
309
310     /** Level Numbers Definition */
311     private static final byte[] listLevelNumbersDefinition = "levelnumbers".getBytes();
312
313     /** Filler for Level Numbers */
314     private static final byte[] listLevelNumbers = "\\'0".getBytes();
315
316     /** Tab Stop */
317     private static final byte[] tabStop = "tx".getBytes();
318
319     /** Actual list begin */
320     private static final byte[] listBegin = "ls".getBytes();
321
322     /** Current list level */
323     private static final byte[] listCurrentLevel = "ilvl".getBytes();
324
325     /** List text group for older browsers */
326     private static final byte[] listTextOld = "listtext".getBytes();
327
328     /** Tab */
329     private static final byte[] tab = "tab".getBytes();
330
331     /** Old Bullet Style */
332     private static final byte[] listBulletOld = "\'b7".getBytes();
333
334     /** Current List ID */
335     private static final byte[] listID = "listid".getBytes();
336
337     /** List override */
338     private static final byte[] listOverride = "listoverride".getBytes();
339
340     /** Number of overrides */
341     private static final byte[] listOverrideCount = "listoverridecount".getBytes();
342
343     /**
344      * Text Style
345      */

346
347     /** Bold tag. */
348     protected static final byte bold = (byte) 'b';
349
350     /** Italic tag. */
351     protected static final byte italic = (byte) 'i';
352
353     /** Underline tag. */
354     protected static final byte[] underline = "ul".getBytes();
355
356     /** Strikethrough tag. */
357     protected static final byte[] strikethrough = "strike".getBytes();
358
359     /** Text alignment left tag. */
360     public static final byte[] alignLeft = "ql".getBytes();
361
362     /** Text alignment center tag. */
363     public static final byte[] alignCenter = "qc".getBytes();
364
365     /** Text alignment right tag. */
366     public static final byte[] alignRight = "qr".getBytes();
367
368     /** Text alignment justify tag. */
369     public static final byte[] alignJustify = "qj".getBytes();
370
371     /**
372      * Colors
373      */

374
375     /** Begin colour table tag. */
376     private static final byte[] colorTable = "colortbl".getBytes();
377
378     /** Red value tag. */
379     private static final byte[] colorRed = "red".getBytes();
380
381     /** Green value tag. */
382     private static final byte[] colorGreen = "green".getBytes();
383
384     /** Blue value tag. */
385     private static final byte[] colorBlue = "blue".getBytes();
386
387     /**
388      * Information Group
389      */

390
391     /** Begin the info group tag.*/
392     private static final byte[] infoBegin = "info".getBytes();
393
394     /** Author tag. */
395     private static final byte[] metaAuthor = "author".getBytes();
396
397     /** Subject tag. */
398     private static final byte[] metaSubject = "subject".getBytes();
399
400     /** Keywords tag. */
401     private static final byte[] metaKeywords = "keywords".getBytes();
402
403     /** Title tag. */
404     private static final byte[] metaTitle = "title".getBytes();
405
406     /** Producer tag. */
407     private static final byte[] metaProducer = "operator".getBytes();
408
409     /** Creation Date tag. */
410     private static final byte[] metaCreationDate = "creationdate".getBytes();
411
412     /** Year tag. */
413     private static final byte[] year = "yr".getBytes();
414
415     /** Month tag. */
416     private static final byte[] month = "mo".getBytes();
417
418     /** Day tag. */
419     private static final byte[] day = "dy".getBytes();
420
421     /** Hour tag. */
422     private static final byte[] hour = "hr".getBytes();
423
424     /** Minute tag. */
425     private static final byte[] minute = "min".getBytes();
426
427     /** Second tag. */
428     private static final byte[] second = "sec".getBytes();
429
430     /** Start superscript. */
431     private static final byte[] startSuper = "super".getBytes();
432
433     /** Start subscript. */
434     private static final byte[] startSub = "sub".getBytes();
435
436     /** End super/sub script. */
437     private static final byte[] endSuperSub = "nosupersub".getBytes();
438
439     /**
440      * Header / Footer
441      */

442
443     /** Title Page tag */
444     private static final byte[] titlePage = "titlepg".getBytes();
445
446     /** Facing pages tag */
447     private static final byte[] facingPages = "facingp".getBytes();
448
449     /** Begin header group tag. */
450     private static final byte[] headerBegin = "header".getBytes();
451
452     /** Begin footer group tag. */
453     private static final byte[] footerBegin = "footer".getBytes();
454
455     // header footer 'left', 'right', 'first'
456
private static final byte[] headerlBegin = "headerl".getBytes();
457
458     private static final byte[] footerlBegin = "footerl".getBytes();
459
460     private static final byte[] headerrBegin = "headerr".getBytes();
461
462     private static final byte[] footerrBegin = "footerr".getBytes();
463
464     private static final byte[] headerfBegin = "headerf".getBytes();
465
466     private static final byte[] footerfBegin = "footerf".getBytes();
467
468     /**
469      * Paper Properties
470      */

471
472     /** Paper width tag. */
473     private static final byte[] rtfPaperWidth = "paperw".getBytes();
474
475     /** Paper height tag. */
476     private static final byte[] rtfPaperHeight = "paperh".getBytes();
477
478     /** Margin left tag. */
479     private static final byte[] rtfMarginLeft = "margl".getBytes();
480
481     /** Margin right tag. */
482     private static final byte[] rtfMarginRight = "margr".getBytes();
483
484     /** Margin top tag. */
485     private static final byte[] rtfMarginTop = "margt".getBytes();
486
487     /** Margin bottom tag. */
488     private static final byte[] rtfMarginBottom = "margb".getBytes();
489
490     /** New Page tag. */
491     private static final byte[] newPage = "page".getBytes();
492
493     /** Document Landscape tag 1. */
494     private static final byte[] landscapeTag1 = "landscape".getBytes();
495
496     /** Document Landscape tag 2. */
497     private static final byte[] landscapeTag2 = "lndscpsxn".getBytes();
498
499     /**
500      * Annotations
501      */

502
503     /** Annotation ID tag. */
504     private static final byte[] annotationID = "atnid".getBytes();
505
506     /** Annotation Author tag. */
507     private static final byte[] annotationAuthor = "atnauthor".getBytes();
508
509     /** Annotation text tag. */
510     private static final byte[] annotation = "annotation".getBytes();
511
512     /**
513      * Images
514      */

515
516     /** Begin the main Picture group tag */
517     private static final byte[] pictureGroup = "shppict".getBytes();
518
519     /** Begin the picture tag */
520     private static final byte[] picture = "pict".getBytes();
521
522     /** PNG Image */
523     private static final byte[] picturePNG = "pngblip".getBytes();
524
525     /** JPEG Image */
526     private static final byte[] pictureJPEG = "jpegblip".getBytes();
527
528     /** BMP Image */
529     private static final byte[] pictureBMP = "dibitmap0".getBytes();
530
531     /** WMF Image */
532     private static final byte[] pictureWMF = "wmetafile8".getBytes();
533
534     /** Picture width */
535     private static final byte[] pictureWidth = "picw".getBytes();
536
537     /** Picture height */
538     private static final byte[] pictureHeight = "pich".getBytes();
539
540     /** Picture scale horizontal percent */
541     private static final byte[] pictureScaleX = "picscalex".getBytes();
542
543     /** Picture scale vertical percent */
544     private static final byte[] pictureScaleY = "picscaley".getBytes();
545
546     /**
547      * Fields (for page numbering)
548      */

549
550     /** Begin field tag */
551     protected static final byte[] field = "field".getBytes();
552
553     /** Content fo the field */
554     protected static final byte[] fieldContent = "fldinst".getBytes();
555
556     /** PAGE numbers */
557     protected static final byte[] fieldPage = "PAGE".getBytes();
558
559     /** HYPERLINK field */
560     protected static final byte[] fieldHyperlink = "HYPERLINK".getBytes();
561
562     /** Last page number (not used) */
563     protected static final byte[] fieldDisplay = "fldrslt".getBytes();
564
565
566     /** Class variables */
567
568     /**
569      * Because of the way RTF works and the way itext works, the text has to be
570      * stored and is only written to the actual OutputStream at the end.
571      */

572
573     /** This <code>ArrayList</code> contains all fonts used in the document. */
574     private ArrayList JavaDoc fontList = new ArrayList JavaDoc();
575
576     /** This <code>ArrayList</code> contains all colours used in the document. */
577     private ArrayList JavaDoc colorList = new ArrayList JavaDoc();
578
579     /** This <code>ByteArrayOutputStream</code> contains the main body of the document. */
580     private ByteArrayOutputStream JavaDoc content = null;
581
582     /** This <code>ByteArrayOutputStream</code> contains the information group. */
583     private ByteArrayOutputStream JavaDoc info = null;
584
585     /** This <code>ByteArrayOutputStream</code> contains the list table. */
586     private ByteArrayOutputStream JavaDoc listtable = null;
587
588     /** This <code>ByteArrayOutputStream</code> contains the list override table. */
589     private ByteArrayOutputStream JavaDoc listoverride = null;
590
591     /** Document header. */
592     private HeaderFooter header = null;
593
594     /** Document footer. */
595     private HeaderFooter footer = null;
596
597     /** Left margin. */
598     private int marginLeft = 1800;
599
600     /** Right margin. */
601     private int marginRight = 1800;
602
603     /** Top margin. */
604     private int marginTop = 1440;
605
606     /** Bottom margin. */
607     private int marginBottom = 1440;
608
609     /** Page width. */
610     private int pageWidth = 11906;
611
612     /** Page height. */
613     private int pageHeight = 16838;
614
615     /** Factor to use when converting. */
616     public final static double TWIPSFACTOR = 20;//20.57140;
617

618     /** Current list ID. */
619     private int currentListID = 1;
620
621     /** List of current Lists. */
622     private ArrayList JavaDoc listIds = null;
623
624     /** Current List Level. */
625     private int listLevel = 0;
626
627     /** Current maximum List Level. */
628     private int maxListLevel = 0;
629
630     /** Write a TOC */
631     private boolean writeTOC = false;
632
633     /** Special title page */
634     private boolean hasTitlePage = false;
635
636     /** Currently writing either Header or Footer */
637     private boolean inHeaderFooter = false;
638
639     /** Currently writing a Table */
640     private boolean inTable = false;
641
642     /** Landscape or Portrait Document */
643     private boolean landscape = false;
644
645     /** Protected Constructor */
646
647     /**
648      * Constructs a <CODE>RtfWriter</CODE>.
649      *
650      * @param doc The <CODE>Document</CODE> that is to be written as RTF
651      * @param os The <CODE>OutputStream</CODE> the writer has to write to.
652      */

653
654     protected RtfWriter(Document doc, OutputStream JavaDoc os) {
655         super(doc, os);
656         document.addDocListener(this);
657         initDefaults();
658     }
659
660     /** Public functions special to the RtfWriter */
661
662     /**
663      * This method controls whether TOC entries are automatically generated
664      *
665      * @param writeTOC boolean value indicating whether a TOC is to be generated
666      */

667     public void setGenerateTOCEntries(boolean writeTOC) {
668         this.writeTOC = writeTOC;
669     }
670
671     /**
672      * Gets the current setting of writeTOC
673      *
674      * @return boolean value indicating whether a TOC is being generated
675      */

676     public boolean getGeneratingTOCEntries() {
677         return writeTOC;
678     }
679
680     /**
681      * This method controls whether the first page is a title page
682      *
683      * @param hasTitlePage boolean value indicating whether the first page is a title page
684      */

685     public void setHasTitlePage(boolean hasTitlePage) {
686         this.hasTitlePage = hasTitlePage;
687     }
688
689     /**
690      * Gets the current setting of hasTitlePage
691      *
692      * @return boolean value indicating whether the first page is a title page
693      */

694     public boolean getHasTitlePage() {
695         return hasTitlePage;
696     }
697
698     /**
699      * Explicitly sets the page format to use.
700      * Otherwise the RtfWriter will try to guess the format by comparing pagewidth and pageheight
701      *
702      * @param landscape boolean value indicating whether we are using landscape format or not
703      */

704     public void setLandscape(boolean landscape) {
705         this.landscape = landscape;
706     }
707
708     /**
709      * Returns the current landscape setting
710      *
711      * @return boolean value indicating the current page format
712      */

713     public boolean getLandscape() {
714         return landscape;
715     }
716
717     /** Public functions from the DocWriter Interface */
718
719     /**
720      * Gets an instance of the <CODE>RtfWriter</CODE>.
721      *
722      * @param document The <CODE>Document</CODE> that has to be written
723      * @param os The <CODE>OutputStream</CODE> the writer has to write to.
724      * @return a new <CODE>RtfWriter</CODE>
725      */

726     public static RtfWriter getInstance(Document document, OutputStream JavaDoc os) {
727         return new RtfWriter(document, os);
728     }
729
730     /**
731      * Signals that the <CODE>Document</CODE> has been opened and that
732      * <CODE>Elements</CODE> can be added.
733      */

734     public void open() {
735         super.open();
736     }
737
738     /**
739      * Signals that the <CODE>Document</CODE> was closed and that no other
740      * <CODE>Elements</CODE> will be added.
741      * <p>
742      * The content of the font table, color table, information group, content, header, footer are merged into the final
743      * <code>OutputStream</code>
744      */

745     public void close() {
746         if (open) {
747             writeDocument();
748             super.close();
749         }
750     }
751
752     /**
753      * Adds the footer to the bottom of the <CODE>Document</CODE>.
754      * @param footer
755      */

756     public void setFooter(HeaderFooter footer) {
757         this.footer = footer;
758         processHeaderFooter(this.footer);
759     }
760
761     /**
762      * Adds the header to the top of the <CODE>Document</CODE>.
763      * @param header
764      */

765     public void setHeader(HeaderFooter header) {
766         this.header = header;
767         processHeaderFooter(this.header);
768     }
769
770     /**
771      * Resets the footer.
772      */

773     public void resetFooter() {
774         setFooter(null);
775     }
776
777     /**
778      * Resets the header.
779      */

780     public void resetHeader() {
781         setHeader(null);
782     }
783
784     /**
785      * Tells the <code>RtfWriter</code> that a new page is to be begun.
786      *
787      * @return <code>true</code> if a new Page was begun.
788      * @throws DocumentException if the Document was not open or had been closed.
789      */

790     public boolean newPage() {
791         try {
792             content.write(escape);
793             content.write(newPage);
794             content.write(escape);
795             content.write(paragraph);
796         } catch (IOException JavaDoc e) {
797             throw new ExceptionConverter(e);
798         }
799         return true;
800     }
801
802     /**
803      * Sets the page margins
804      *
805      * @param marginLeft The left margin
806      * @param marginRight The right margin
807      * @param marginTop The top margin
808      * @param marginBottom The bottom margin
809      *
810      * @return <code>true</code> if the page margins were set.
811      */

812     public boolean setMargins(float marginLeft, float marginRight, float marginTop, float marginBottom) {
813         this.marginLeft = (int) (marginLeft * TWIPSFACTOR);
814         this.marginRight = (int) (marginRight * TWIPSFACTOR);
815         this.marginTop = (int) (marginTop * TWIPSFACTOR);
816         this.marginBottom = (int) (marginBottom * TWIPSFACTOR);
817         return true;
818     }
819
820     /**
821      * Sets the page size
822      *
823      * @param pageSize A <code>Rectangle</code> specifying the page size
824      *
825      * @return <code>true</code> if the page size was set
826      */

827     public boolean setPageSize(Rectangle pageSize) {
828         if (!parseFormat(pageSize, false)) {
829             pageWidth = (int) (pageSize.getWidth() * TWIPSFACTOR);
830             pageHeight = (int) (pageSize.getHeight() * TWIPSFACTOR);
831             landscape = pageWidth > pageHeight;
832         }
833         return true;
834     }
835
836     /**
837      * Write the table of contents.
838      *
839      * @param tocTitle The title that will be displayed above the TOC
840      * @param titleFont The <code>Font</code> that will be used for the tocTitle
841      * @param showTOCasEntry Set this to true if you want the TOC to appear as an entry in the TOC
842      * @param showTOCEntryFont Use this <code>Font</code> to specify what Font to use when showTOCasEntry is true
843      *
844      * @return <code>true</code> if the TOC was added.
845      */

846     public boolean writeTOC(String JavaDoc tocTitle, Font titleFont, boolean showTOCasEntry, Font showTOCEntryFont) {
847         try {
848             RtfTOC toc = new RtfTOC(tocTitle, titleFont);
849             if (showTOCasEntry) {
850                 toc.addTOCAsTOCEntry(tocTitle, showTOCEntryFont);
851             }
852             add(new Paragraph(toc));
853         } catch (DocumentException de) {
854             return false;
855         }
856         return true;
857     }
858
859     /**
860      * Signals that an <CODE>Element</CODE> was added to the <CODE>Document</CODE>.
861      *
862      * @param element A high level object to add
863      * @return <CODE>true</CODE> if the element was added, <CODE>false</CODE> if not.
864      * @throws DocumentException if a document isn't open yet, or has been closed
865      */

866     public boolean add(Element element) throws DocumentException {
867         if (pause) {
868             return false;
869         }
870         return addElement(element, content);
871     }
872
873
874     /** Private functions */
875
876     /**
877      * Adds an <CODE>Element</CODE> to the <CODE>Document</CODE>.
878      * @param element the high level element to add
879      * @param out the outputstream to which the RTF data is sent
880      * @return <CODE>true</CODE> if the element was added, <CODE>false</CODE> if not.
881      * @throws DocumentException if a document isn't open yet, or has been closed
882      */

883     protected boolean addElement(Element element, ByteArrayOutputStream JavaDoc out) throws DocumentException {
884         try {
885             switch (element.type()) {
886                 case Element.CHUNK:
887                     writeChunk((Chunk) element, out);
888                     break;
889                 case Element.PARAGRAPH:
890                     writeParagraph((Paragraph) element, out);
891                     break;
892                 case Element.ANCHOR:
893                     writeAnchor((Anchor) element, out);
894                     break;
895                 case Element.PHRASE:
896                     writePhrase((Phrase) element, out);
897                     break;
898                 case Element.CHAPTER:
899                 case Element.SECTION:
900                     writeSection((Section) element, out);
901                     break;
902                 case Element.LIST:
903                     writeList((com.lowagie.text.List) element, out);
904                     break;
905                 case Element.TABLE:
906                     try {
907                         writeTable((Table) element, out);
908                     }
909                     catch(ClassCastException JavaDoc cce) {
910                         writeTable(((SimpleTable)element).createTable(), out);
911                     }
912                     break;
913                 case Element.ANNOTATION:
914                     writeAnnotation((Annotation) element, out);
915                     break;
916                 case Element.IMGRAW:
917                 case Element.IMGTEMPLATE:
918                 case Element.JPEG:
919                     Image img = (Image)element;
920                     writeImage(img, out);
921                     break;
922
923                 case Element.AUTHOR:
924                     writeMeta(metaAuthor, (Meta) element);
925                     break;
926