1 /*
2 * $Id: Document.java 4007 2009-07-07 09:43:40Z blowagie $
3 *
4 * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * (the "License"); you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the License.
13 *
14 * The Original Code is 'iText, a free JAVA-PDF library'.
15 *
16 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
18 * All Rights Reserved.
19 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
21 *
22 * Contributor(s): all the names of the contributors are added in the source code
23 * where applicable.
24 *
25 * Alternatively, the contents of this file may be used under the terms of the
26 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
27 * provisions of LGPL are applicable instead of those above. If you wish to
28 * allow use of your version of this file only under the terms of the LGPL
29 * License and not to allow others to use your version of this file under
30 * the MPL, indicate your decision by deleting the provisions above and
31 * replace them with the notice and other provisions required by the LGPL.
32 * If you do not delete the provisions above, a recipient may use your version
33 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34 *
35 * This library is free software; you can redistribute it and/or modify it
36 * under the terms of the MPL as stated above or under the terms of the GNU
37 * Library General Public License as published by the Free Software Foundation;
38 * either version 2 of the License, or any later version.
39 *
40 * This library is distributed in the hope that it will be useful, but WITHOUT
41 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43 * details.
44 *
45 * If you didn't download this code from the following link, you should check if
46 * you aren't using an obsolete version:
47 * http://www.lowagie.com/iText/
48 */
49
50 package com.lowagie.text;
51
52 import java.text.SimpleDateFormat;
53 import java.util.ArrayList;
54 import java.util.Date;
55 import java.util.Iterator;
56
57 /**
58 * A generic Document class.
59 * <P>
60 * All kinds of Text-elements can be added to a <CODE>HTMLDocument</CODE>.
61 * The <CODE>Document</CODE> signals all the listeners when an element has
62 * been added.
63 * <P>
64 * Remark:
65 * <OL>
66 * <LI>Once a document is created you can add some meta information.
67 * <LI>You can also set the headers/footers.
68 * <LI>You have to open the document before you can write content.
69 * <LI>You can only write content (no more meta-formation!) once a document is
70 * opened.
71 * <LI>When you change the header/footer on a certain page, this will be
72 * effective starting on the next page.
73 * <LI>After closing the document, every listener (as well as its <CODE>
74 * OutputStream</CODE>) is closed too.
75 * </OL>
76 * Example: <BLOCKQUOTE>
77 *
78 * <PRE>// creation of the document with a certain size and certain margins
79 * <STRONG>Document document = new Document(PageSize.A4, 50, 50, 50, 50);
80 * </STRONG> try {
81 * // creation of the different writers
82 * HtmlWriter.getInstance(<STRONG>document </STRONG>, System.out);
83 * PdfWriter.getInstance(<STRONG>document </STRONG>, new FileOutputStream("text.pdf"));
84 * // we add some meta information to the document
85 * <STRONG>document.addAuthor("Bruno Lowagie"); </STRONG>
86 * <STRONG>document.addSubject("This is the result of a Test."); </STRONG>
87 * // we open the document for writing
88 * <STRONG>document.open(); </STRONG>
89 * <STRONG>document.add(new Paragraph("Hello world"));</STRONG>
90 * } catch(DocumentException de) {
91 * System.err.println(de.getMessage());
92 * }
93 * <STRONG>document.close();</STRONG>
94 * </PRE>
95 *
96 * </BLOCKQUOTE>
97 */
98
99 public class Document implements DocListener {
100
101 // membervariables
102 /**
103 * This constant may only be changed by Paulo Soares and/or Bruno Lowagie.
104 * @since 2.1.6
105 */
106 private static final String ITEXT = "iText";
107 /**
108 * This constant may only be changed by Paulo Soares and/or Bruno Lowagie.
109 * @since 2.1.6
110 */
111 private static final String RELEASE = "2.1.7";
112 /** This constant may only be changed by Paulo Soares and/or Bruno Lowagie. */
113 private static final String ITEXT_VERSION = ITEXT + " " + RELEASE + " by 1T3XT";
114
115 /**
116 * Allows the pdf documents to be produced without compression for debugging
117 * purposes.
118 */
119 public static boolean compress = true;
120
121 /**
122 * When true the file access is not done through a memory mapped file. Use it if the file
123 * is too big to be mapped in your address space.
124 */
125 public static boolean plainRandomAccess = false;
126
127 /** Scales the WMF font size. The default value is 0.86. */
128 public static float wmfFontCorrection = 0.86f;
129
130 /** The DocListener. */
131 private ArrayList listeners = new ArrayList();
132
133 /** Is the document open or not? */
134 protected boolean open;
135
136 /** Has the document already been closed? */
137 protected boolean close;
138
139 // membervariables concerning the layout
140
141 /** The size of the page. */
142 protected Rectangle pageSize;
143
144 /** margin in x direction starting from the left */
145 protected float marginLeft = 0;
146
147 /** margin in x direction starting from the right */
148 protected float marginRight = 0;
149
150 /** margin in y direction starting from the top */
151 protected float marginTop = 0;
152
153 /** margin in y direction starting from the bottom */
154 protected float marginBottom = 0;
155
156 /** mirroring of the left/right margins */
157 protected boolean marginMirroring = false;
158
159 /**
160 * mirroring of the top/bottom margins
161 * @since 2.1.6
162 */
163 protected boolean marginMirroringTopBottom = false;
164
165 /** Content of JavaScript onLoad function */
166 protected String javaScript_onLoad = null;
167
168 /** Content of JavaScript onUnLoad function */
169 protected String javaScript_onUnLoad = null;
170
171 /** Style class in HTML body tag */
172 protected String htmlStyleClass = null;
173
174 // headers, footers
175
176 /** Current pagenumber */
177 protected int pageN = 0;
178
179 /** This is the textual part of a Page; it can contain a header */
180 protected HeaderFooter header = null;
181
182 /** This is the textual part of the footer */
183 protected HeaderFooter footer = null;
184
185 /** This is a chapter number in case ChapterAutoNumber is used. */
186 protected int chapternumber = 0;
187
188 // constructor
189
190 /**
191 * Constructs a new <CODE>Document</CODE> -object.
192 */
193
194 public Document() {
195 this(PageSize.A4);
196 }
197
198 /**
199 * Constructs a new <CODE>Document</CODE> -object.
200 *
201 * @param pageSize
202 * the pageSize
203 */
204
205 public Document(Rectangle pageSize) {
206 this(pageSize, 36, 36, 36, 36);
207 }
208
209 /**
210 * Constructs a new <CODE>Document</CODE> -object.
211 *
212 * @param pageSize
213 * the pageSize
214 * @param marginLeft
215 * the margin on the left
216 * @param marginRight
217 * the margin on the right
218 * @param marginTop
219 * the margin on the top
220 * @param marginBottom
221 * the margin on the bottom
222 */
223
224 public Document(Rectangle pageSize, float marginLeft, float marginRight,
225 float marginTop, float marginBottom) {
226 this.pageSize = pageSize;
227 this.marginLeft = marginLeft;
228 this.marginRight = marginRight;
229 this.marginTop = marginTop;
230 this.marginBottom = marginBottom;
231 }
232
233 // listener methods
234
235 /**
236 * Adds a <CODE>DocListener</CODE> to the <CODE>Document</CODE>.
237 *
238 * @param listener
239 * the new DocListener.
240 */
241
242 public void addDocListener(DocListener listener) {
243 listeners.add(listener);
244 }
245
246 /**
247 * Removes a <CODE>DocListener</CODE> from the <CODE>Document</CODE>.
248 *
249 * @param listener
250 * the DocListener that has to be removed.
251 */
252
253 public void removeDocListener(DocListener listener) {
254 listeners.remove(listener);
255 }
256
257 // methods implementing the DocListener interface
258
259 /**
260 * Adds an <CODE>Element</CODE> to the <CODE>Document</CODE>.
261 *
262 * @param element
263 * the <CODE>Element</CODE> to add
264 * @return <CODE>true</CODE> if the element was added, <CODE>false
265 * </CODE> if not
266 * @throws DocumentException
267 * when a document isn't open yet, or has been closed
268 */
269
270 public boolean add(Element element) throws DocumentException {
271 if (close) {
272 throw new DocumentException(
273 "The document has been closed. You can't add any Elements.");
274 }
275 if (!open && element.isContent()) {
276 throw new DocumentException(
277 "The document is not open yet; you can only add Meta information.");
278 }
279 boolean success = false;
280 DocListener listener;
281 if (element instanceof ChapterAutoNumber) {
282 chapternumber = ((ChapterAutoNumber)element).setAutomaticNumber(chapternumber);
283 }
284 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
285 listener = (DocListener) iterator.next();
286 success |= listener.add(element);
287 }
288 if (element instanceof LargeElement) {
289 LargeElement e = (LargeElement)element;
290 if (!e.isComplete())
291 e.flushContent();
292 }
293 return success;
294 }
295
296 /**
297 * Opens the document.
298 * <P>
299 * Once the document is opened, you can't write any Header- or
300 * Meta-information anymore. You have to open the document before you can
301 * begin to add content to the body of the document.
302 */
303
304 public void open() {
305 if (!close) {
306 open = true;
307 }
308 DocListener listener;
309 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
310 listener = (DocListener) iterator.next();
311 listener.setPageSize(pageSize);
312 listener.setMargins(marginLeft, marginRight, marginTop,
313 marginBottom);
314 listener.open();
315 }
316 }
317
318 /**
319 * Sets the pagesize.
320 *
321 * @param pageSize
322 * the new pagesize
323 * @return a <CODE>boolean</CODE>
324 */
325
326 public boolean setPageSize(Rectangle pageSize) {
327 this.pageSize = pageSize;
328 DocListener listener;
329 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
330 listener = (DocListener) iterator.next();
331 listener.setPageSize(pageSize);
332 }
333 return true;
334 }
335
336 /**
337 * Sets the margins.
338 *
339 * @param marginLeft
340 * the margin on the left
341 * @param marginRight
342 * the margin on the right
343 * @param marginTop
344 * the margin on the top
345 * @param marginBottom
346 * the margin on the bottom
347 * @return a <CODE>boolean</CODE>
348 */
349
350 public boolean setMargins(float marginLeft, float marginRight,
351 float marginTop, float marginBottom) {
352 this.marginLeft = marginLeft;
353 this.marginRight = marginRight;
354 this.marginTop = marginTop;
355 this.marginBottom = marginBottom;
356 DocListener listener;
357 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
358 listener = (DocListener) iterator.next();
359 listener.setMargins(marginLeft, marginRight, marginTop,
360 marginBottom);
361 }
362 return true;
363 }
364
365 /**
366 * Signals that an new page has to be started.
367 *
368 * @return <CODE>true</CODE> if the page was added, <CODE>false</CODE>
369 * if not.
370 */
371
372 public boolean newPage() {
373 if (!open || close) {
374 return false;
375 }
376 DocListener listener;
377 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
378 listener = (DocListener) iterator.next();
379 listener.newPage();
380 }
381 return true;
382 }
383
384 /**
385 * Changes the header of this document.
386 *
387 * @param header
388 * the new header
389 */
390
391 public void setHeader(HeaderFooter header) {
392 this.header = header;
393 DocListener listener;
394 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
395 listener = (DocListener) iterator.next();
396 listener.setHeader(header);
397 }
398 }
399
400 /**
401 * Resets the header of this document.
402 */
403
404 public void resetHeader() {
405 this.header = null;
406 DocListener listener;
407 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
408 listener = (DocListener) iterator.next();
409 listener.resetHeader();
410 }
411 }
412
413 /**
414 * Changes the footer of this document.
415 *
416 * @param footer
417 * the new footer
418 */
419
420 public void setFooter(HeaderFooter footer) {
421 this.footer = footer;
422 DocListener listener;
423 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
424 listener = (DocListener) iterator.next();
425 listener.setFooter(footer);
426 }
427 }
428
429 /**
430 * Resets the footer of this document.
431 */
432
433 public void resetFooter() {
434 this.footer = null;
435 DocListener listener;
436 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
437 listener = (DocListener) iterator.next();
438 listener.resetFooter();
439 }
440 }
441
442 /**
443 * Sets the page number to 0.
444 */
445
446 public void resetPageCount() {
447 pageN = 0;
448 DocListener listener;
449 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
450 listener = (DocListener) iterator.next();
451 listener.resetPageCount();
452 }
453 }
454
455 /**
456 * Sets the page number.
457 *
458 * @param pageN
459 * the new page number
460 */
461
462 public void setPageCount(int pageN) {
463 this.pageN = pageN;
464 DocListener listener;
465 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
466 listener = (DocListener) iterator.next();
467 listener.setPageCount(pageN);
468 }
469 }
470
471 /**
472 * Returns the current page number.
473 *
474 * @return the current page number
475 */
476
477 public int getPageNumber() {
478 return this.pageN;
479 }
480
481 /**
482 * Closes the document.
483 * <P>
484 * Once all the content has been written in the body, you have to close the
485 * body. After that nothing can be written to the body anymore.
486 */
487
488 public void close() {
489 if (!close) {
490 open = false;
491 close = true;
492 }
493 DocListener listener;
494 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
495 listener = (DocListener) iterator.next();
496 listener.close();
497 }
498 }
499
500 // methods concerning the header or some meta information
501
502 /**
503 * Adds a user defined header to the document.
504 *
505 * @param name
506 * the name of the header
507 * @param content
508 * the content of the header
509 * @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
510 */
511
512 public boolean addHeader(String name, String content) {
513 try {
514 return add(new Header(name, content));
515 } catch (DocumentException de) {
516 throw new ExceptionConverter(de);
517 }
518 }
519
520 /**
521 * Adds the title to a Document.
522 *
523 * @param title
524 * the title
525 * @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
526 */
527
528 public boolean addTitle(String title) {
529 try {
530 return add(new Meta(Element.TITLE, title));
531 } catch (DocumentException de) {
532 throw new ExceptionConverter(de);
533 }
534 }
535
536 /**
537 * Adds the subject to a Document.
538 *
539 * @param subject
540 * the subject
541 * @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
542 */
543
544 public boolean addSubject(String subject) {
545 try {
546 return add(new Meta(Element.SUBJECT, subject));
547 } catch (DocumentException de) {
548 throw new ExceptionConverter(de);
549 }
550 }
551
552 /**
553 * Adds the keywords to a Document.
554 *
555 * @param keywords
556 * adds the keywords to the document
557 * @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
558 */
559
560 public boolean addKeywords(String keywords) {
561 try {
562 return add(new Meta(Element.KEYWORDS, keywords));
563 } catch (DocumentException de) {
564 throw new ExceptionConverter(de);
565 }
566 }
567
568 /**
569 * Adds the author to a Document.
570 *
571 * @param author
572 * the name of the author
573 * @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
574 */
575
576 public boolean addAuthor(String author) {
577 try {
578 return add(new Meta(Element.AUTHOR, author));
579 } catch (DocumentException de) {
580 throw new ExceptionConverter(de);
581 }
582 }
583
584 /**
585 * Adds the creator to a Document.
586 *
587 * @param creator
588 * the name of the creator
589 * @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
590 */
591
592 public boolean addCreator(String creator) {
593 try {
594 return add(new Meta(Element.CREATOR, creator));
595 } catch (DocumentException de) {
596 throw new ExceptionConverter(de);
597 }
598 }
599
600 /**
601 * Adds the producer to a Document.
602 *
603 * @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
604 */
605
606 public boolean addProducer() {
607 try {
608 return add(new Meta(Element.PRODUCER, getVersion()));
609 } catch (DocumentException de) {
610 throw new ExceptionConverter(de);
611 }
612 }
613
614 /**
615 * Adds the current date and time to a Document.
616 *
617 * @return <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise
618 */
619
620 public boolean addCreationDate() {
621 try {
622 /* bugfix by 'taqua' (Thomas) */
623 final SimpleDateFormat sdf = new SimpleDateFormat(
624 "EEE MMM dd HH:mm:ss zzz yyyy");
625 return add(new Meta(Element.CREATIONDATE, sdf.format(new Date())));
626 } catch (DocumentException de) {
627 throw new ExceptionConverter(de);
628 }
629 }
630
631 // methods to get the layout of the document.
632
633 /**
634 * Returns the left margin.
635 *
636 * @return the left margin
637 */
638
639 public float leftMargin() {
640 return marginLeft;
641 }
642
643 /**
644 * Return the right margin.
645 *
646 * @return the right margin
647 */
648
649 public float rightMargin() {
650 return marginRight;
651 }
652
653 /**
654 * Returns the top margin.
655 *
656 * @return the top margin
657 */
658
659 public float topMargin() {
660 return marginTop;
661 }
662
663 /**
664 * Returns the bottom margin.
665 *
666 * @return the bottom margin
667 */
668
669 public float bottomMargin() {
670 return marginBottom;
671 }
672
673 /**
674 * Returns the lower left x-coordinate.
675 *
676 * @return the lower left x-coordinate
677 */
678
679 public float left() {
680 return pageSize.getLeft(marginLeft);
681 }
682
683 /**
684 * Returns the upper right x-coordinate.
685 *
686 * @return the upper right x-coordinate
687 */
688
689 public float right() {
690 return pageSize.getRight(marginRight);
691 }
692
693 /**
694 * Returns the upper right y-coordinate.
695 *
696 * @return the upper right y-coordinate
697 */
698
699 public float top() {
700 return pageSize.getTop(marginTop);
701 }
702
703 /**
704 * Returns the lower left y-coordinate.
705 *
706 * @return the lower left y-coordinate
707 */
708
709 public float bottom() {
710 return pageSize.getBottom(marginBottom);
711 }
712
713 /**
714 * Returns the lower left x-coordinate considering a given margin.
715 *
716 * @param margin
717 * a margin
718 * @return the lower left x-coordinate
719 */
720
721 public float left(float margin) {
722 return pageSize.getLeft(marginLeft + margin);
723 }
724
725 /**
726 * Returns the upper right x-coordinate, considering a given margin.
727 *
728 * @param margin
729 * a margin
730 * @return the upper right x-coordinate
731 */
732
733 public float right(float margin) {
734 return pageSize.getRight(marginRight + margin);
735 }
736
737 /**
738 * Returns the upper right y-coordinate, considering a given margin.
739 *
740 * @param margin
741 * a margin
742 * @return the upper right y-coordinate
743 */
744
745 public float top(float margin) {
746 return pageSize.getTop(marginTop + margin);
747 }
748
749 /**
750 * Returns the lower left y-coordinate, considering a given margin.
751 *
752 * @param margin
753 * a margin
754 * @return the lower left y-coordinate
755 */
756
757 public float bottom(float margin) {
758 return pageSize.getBottom(marginBottom + margin);
759 }
760
761 /**
762 * Gets the pagesize.
763 *
764 * @return the page size
765 */
766
767 public Rectangle getPageSize() {
768 return this.pageSize;
769 }
770
771 /**
772 * Checks if the document is open.
773 *
774 * @return <CODE>true</CODE> if the document is open
775 */
776 public boolean isOpen() {
777 return open;
778 }
779
780 /**
781 * Gets the product name.
782 * This method may only be changed by Paulo Soares and/or Bruno Lowagie.
783 * @return the product name
784 * @since 2.1.6
785 */
786 public static final String getProduct() {
787 return ITEXT;
788 }
789
790 /**
791 * Gets the release number.
792 * This method may only be changed by Paulo Soares and/or Bruno Lowagie.
793 * @return the product name
794 * @since 2.1.6
795 */
796 public static final String getRelease() {
797 return RELEASE;
798 }
799
800 /**
801 * Gets the iText version.
802 * This method may only be changed by Paulo Soares and/or Bruno Lowagie.
803 * @return iText version
804 */
805 public static final String getVersion() {
806 return ITEXT_VERSION;
807 }
808
809 /**
810 * Adds a JavaScript onLoad function to the HTML body tag
811 *
812 * @param code
813 * the JavaScript code to be executed on load of the HTML page
814 */
815
816 public void setJavaScript_onLoad(String code) {
817 this.javaScript_onLoad = code;
818 }
819
820 /**
821 * Gets the JavaScript onLoad command.
822 *
823 * @return the JavaScript onLoad command
824 */
825
826 public String getJavaScript_onLoad() {
827 return this.javaScript_onLoad;
828 }
829
830 /**
831 * Adds a JavaScript onUnLoad function to the HTML body tag
832 *
833 * @param code
834 * the JavaScript code to be executed on unload of the HTML page
835 */
836
837 public void setJavaScript_onUnLoad(String code) {
838 this.javaScript_onUnLoad = code;
839 }
840
841 /**
842 * Gets the JavaScript onUnLoad command.
843 *
844 * @return the JavaScript onUnLoad command
845 */
846
847 public String getJavaScript_onUnLoad() {
848 return this.javaScript_onUnLoad;
849 }
850
851 /**
852 * Adds a style class to the HTML body tag
853 *
854 * @param htmlStyleClass
855 * the style class for the HTML body tag
856 */
857
858 public void setHtmlStyleClass(String htmlStyleClass) {
859 this.htmlStyleClass = htmlStyleClass;
860 }
861
862 /**
863 * Gets the style class of the HTML body tag
864 *
865 * @return the style class of the HTML body tag
866 */
867
868 public String getHtmlStyleClass() {
869 return this.htmlStyleClass;
870 }
871
872 /**
873 * Set the margin mirroring. It will mirror right/left margins for odd/even pages.
874 * <p>
875 * Note: it will not work with {@link Table}.
876 *
877 * @param marginMirroring
878 * <CODE>true</CODE> to mirror the margins
879 * @return always <CODE>true</CODE>
880 */
881 public boolean setMarginMirroring(boolean marginMirroring) {
882 this.marginMirroring = marginMirroring;
883 DocListener listener;
884 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
885 listener = (DocListener) iterator.next();
886 listener.setMarginMirroring(marginMirroring);
887 }
888 return true;
889 }
890
891 /**
892 * Set the margin mirroring. It will mirror top/bottom margins for odd/even pages.
893 * <p>
894 * Note: it will not work with {@link Table}.
895 *
896 * @param marginMirroringTopBottom
897 * <CODE>true</CODE> to mirror the margins
898 * @return always <CODE>true</CODE>
899 * @since 2.1.6
900 */
901 public boolean setMarginMirroringTopBottom(boolean marginMirroringTopBottom) {
902 this.marginMirroringTopBottom = marginMirroringTopBottom;
903 DocListener listener;
904 for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
905 listener = (DocListener) iterator.next();
906 listener.setMarginMirroringTopBottom(marginMirroringTopBottom);
907 }
908 return true;
909 }
910
911 /**
912 * Gets the margin mirroring flag.
913 *
914 * @return the margin mirroring flag
915 */
916 public boolean isMarginMirroring() {
917 return marginMirroring;
918 }
919 }
920