From 6025b6016517c6d898d8957d1d7e03ba71431912 Mon Sep 17 00:00:00 2001 From: tknall Date: Fri, 1 Dec 2006 12:20:24 +0000 Subject: Initial import of release 2.2. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@4 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../com/lowagie/text/rtf/AbstractRtfField.java | 358 +++ .../java/com/lowagie/text/rtf/GenericRtfField.java | 139 ++ .../com/lowagie/text/rtf/RtfAddableElement.java | 127 ++ .../java/com/lowagie/text/rtf/RtfBasicElement.java | 110 + src/main/java/com/lowagie/text/rtf/RtfCell.java | 549 +++++ src/main/java/com/lowagie/text/rtf/RtfElement.java | 149 ++ .../com/lowagie/text/rtf/RtfExtendedElement.java | 65 + src/main/java/com/lowagie/text/rtf/RtfField.java | 84 + src/main/java/com/lowagie/text/rtf/RtfFont.java | 162 ++ .../java/com/lowagie/text/rtf/RtfHeaderFooter.java | 114 + .../com/lowagie/text/rtf/RtfHeaderFooters.java | 160 ++ src/main/java/com/lowagie/text/rtf/RtfMapper.java | 182 ++ .../java/com/lowagie/text/rtf/RtfPageNumber.java | 105 + src/main/java/com/lowagie/text/rtf/RtfRow.java | 443 ++++ src/main/java/com/lowagie/text/rtf/RtfTOC.java | 187 ++ .../java/com/lowagie/text/rtf/RtfTOCEntry.java | 174 ++ src/main/java/com/lowagie/text/rtf/RtfTable.java | 201 ++ .../java/com/lowagie/text/rtf/RtfTableCell.java | 392 ++++ src/main/java/com/lowagie/text/rtf/RtfWriter.java | 2299 ++++++++++++++++++++ src/main/java/com/lowagie/text/rtf/RtfWriter2.java | 268 +++ .../com/lowagie/text/rtf/document/RtfCodePage.java | 102 + .../com/lowagie/text/rtf/document/RtfDocument.java | 301 +++ .../text/rtf/document/RtfDocumentHeader.java | 310 +++ .../text/rtf/document/RtfDocumentSettings.java | 182 ++ .../lowagie/text/rtf/document/RtfInfoElement.java | 181 ++ .../lowagie/text/rtf/document/RtfInfoGroup.java | 117 + .../lowagie/text/rtf/document/RtfPageSetting.java | 435 ++++ .../text/rtf/document/output/RtfDataCache.java | 86 + .../text/rtf/document/output/RtfDiskCache.java | 113 + .../text/rtf/document/output/RtfMemoryCache.java | 93 + .../java/com/lowagie/text/rtf/field/RtfAnchor.java | 122 ++ .../java/com/lowagie/text/rtf/field/RtfField.java | 445 ++++ .../com/lowagie/text/rtf/field/RtfPageNumber.java | 83 + .../com/lowagie/text/rtf/field/RtfTOCEntry.java | 163 ++ .../lowagie/text/rtf/field/RtfTableOfContents.java | 109 + .../lowagie/text/rtf/field/RtfTotalPageNumber.java | 128 ++ .../com/lowagie/text/rtf/graphic/RtfImage.java | 306 +++ .../text/rtf/headerfooter/RtfHeaderFooter.java | 326 +++ .../rtf/headerfooter/RtfHeaderFooterGroup.java | 393 ++++ .../java/com/lowagie/text/rtf/list/RtfList.java | 605 ++++++ .../com/lowagie/text/rtf/list/RtfListItem.java | 182 ++ .../com/lowagie/text/rtf/list/RtfListTable.java | 202 ++ .../java/com/lowagie/text/rtf/style/RtfColor.java | 302 +++ .../com/lowagie/text/rtf/style/RtfColorList.java | 137 ++ .../java/com/lowagie/text/rtf/style/RtfFont.java | 681 ++++++ .../com/lowagie/text/rtf/style/RtfFontList.java | 149 ++ .../lowagie/text/rtf/style/RtfParagraphStyle.java | 665 ++++++ .../lowagie/text/rtf/style/RtfStylesheetList.java | 121 ++ .../java/com/lowagie/text/rtf/table/RtfBorder.java | 577 +++++ .../com/lowagie/text/rtf/table/RtfBorderGroup.java | 232 ++ .../java/com/lowagie/text/rtf/table/RtfCell.java | 534 +++++ .../java/com/lowagie/text/rtf/table/RtfRow.java | 377 ++++ .../java/com/lowagie/text/rtf/table/RtfTable.java | 271 +++ .../com/lowagie/text/rtf/text/RtfAnnotation.java | 133 ++ .../java/com/lowagie/text/rtf/text/RtfChapter.java | 105 + .../java/com/lowagie/text/rtf/text/RtfChunk.java | 202 ++ .../java/com/lowagie/text/rtf/text/RtfNewPage.java | 53 + .../com/lowagie/text/rtf/text/RtfParagraph.java | 211 ++ .../java/com/lowagie/text/rtf/text/RtfPhrase.java | 203 ++ .../java/com/lowagie/text/rtf/text/RtfSection.java | 201 ++ .../java/com/lowagie/text/rtf/text/RtfTab.java | 140 ++ .../com/lowagie/text/rtf/text/RtfTabGroup.java | 127 ++ 62 files changed, 16673 insertions(+) create mode 100644 src/main/java/com/lowagie/text/rtf/AbstractRtfField.java create mode 100644 src/main/java/com/lowagie/text/rtf/GenericRtfField.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfAddableElement.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfBasicElement.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfCell.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfElement.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfExtendedElement.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfField.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfFont.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfHeaderFooter.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfHeaderFooters.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfMapper.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfPageNumber.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfRow.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfTOC.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfTOCEntry.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfTable.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfTableCell.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfWriter.java create mode 100644 src/main/java/com/lowagie/text/rtf/RtfWriter2.java create mode 100644 src/main/java/com/lowagie/text/rtf/document/RtfCodePage.java create mode 100644 src/main/java/com/lowagie/text/rtf/document/RtfDocument.java create mode 100644 src/main/java/com/lowagie/text/rtf/document/RtfDocumentHeader.java create mode 100644 src/main/java/com/lowagie/text/rtf/document/RtfDocumentSettings.java create mode 100644 src/main/java/com/lowagie/text/rtf/document/RtfInfoElement.java create mode 100644 src/main/java/com/lowagie/text/rtf/document/RtfInfoGroup.java create mode 100644 src/main/java/com/lowagie/text/rtf/document/RtfPageSetting.java create mode 100644 src/main/java/com/lowagie/text/rtf/document/output/RtfDataCache.java create mode 100644 src/main/java/com/lowagie/text/rtf/document/output/RtfDiskCache.java create mode 100644 src/main/java/com/lowagie/text/rtf/document/output/RtfMemoryCache.java create mode 100644 src/main/java/com/lowagie/text/rtf/field/RtfAnchor.java create mode 100644 src/main/java/com/lowagie/text/rtf/field/RtfField.java create mode 100644 src/main/java/com/lowagie/text/rtf/field/RtfPageNumber.java create mode 100644 src/main/java/com/lowagie/text/rtf/field/RtfTOCEntry.java create mode 100644 src/main/java/com/lowagie/text/rtf/field/RtfTableOfContents.java create mode 100644 src/main/java/com/lowagie/text/rtf/field/RtfTotalPageNumber.java create mode 100644 src/main/java/com/lowagie/text/rtf/graphic/RtfImage.java create mode 100644 src/main/java/com/lowagie/text/rtf/headerfooter/RtfHeaderFooter.java create mode 100644 src/main/java/com/lowagie/text/rtf/headerfooter/RtfHeaderFooterGroup.java create mode 100644 src/main/java/com/lowagie/text/rtf/list/RtfList.java create mode 100644 src/main/java/com/lowagie/text/rtf/list/RtfListItem.java create mode 100644 src/main/java/com/lowagie/text/rtf/list/RtfListTable.java create mode 100644 src/main/java/com/lowagie/text/rtf/style/RtfColor.java create mode 100644 src/main/java/com/lowagie/text/rtf/style/RtfColorList.java create mode 100644 src/main/java/com/lowagie/text/rtf/style/RtfFont.java create mode 100644 src/main/java/com/lowagie/text/rtf/style/RtfFontList.java create mode 100644 src/main/java/com/lowagie/text/rtf/style/RtfParagraphStyle.java create mode 100644 src/main/java/com/lowagie/text/rtf/style/RtfStylesheetList.java create mode 100644 src/main/java/com/lowagie/text/rtf/table/RtfBorder.java create mode 100644 src/main/java/com/lowagie/text/rtf/table/RtfBorderGroup.java create mode 100644 src/main/java/com/lowagie/text/rtf/table/RtfCell.java create mode 100644 src/main/java/com/lowagie/text/rtf/table/RtfRow.java create mode 100644 src/main/java/com/lowagie/text/rtf/table/RtfTable.java create mode 100644 src/main/java/com/lowagie/text/rtf/text/RtfAnnotation.java create mode 100644 src/main/java/com/lowagie/text/rtf/text/RtfChapter.java create mode 100644 src/main/java/com/lowagie/text/rtf/text/RtfChunk.java create mode 100644 src/main/java/com/lowagie/text/rtf/text/RtfNewPage.java create mode 100644 src/main/java/com/lowagie/text/rtf/text/RtfParagraph.java create mode 100644 src/main/java/com/lowagie/text/rtf/text/RtfPhrase.java create mode 100644 src/main/java/com/lowagie/text/rtf/text/RtfSection.java create mode 100644 src/main/java/com/lowagie/text/rtf/text/RtfTab.java create mode 100644 src/main/java/com/lowagie/text/rtf/text/RtfTabGroup.java (limited to 'src/main/java/com/lowagie/text/rtf') diff --git a/src/main/java/com/lowagie/text/rtf/AbstractRtfField.java b/src/main/java/com/lowagie/text/rtf/AbstractRtfField.java new file mode 100644 index 0000000..347784d --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/AbstractRtfField.java @@ -0,0 +1,358 @@ +/** + * $Id: AbstractRtfField.java,v 1.17 2006/02/09 17:25:26 hallm Exp $ + * + * Copyright 2002 by + * SMB + * Dirk.Weigenand@smb-tec.com + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the “GNU LIBRARY GENERAL PUBLIC LICENSE”), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.Chunk; +import com.lowagie.text.Font; +import com.lowagie.text.rtf.RtfWriter; + +import java.io.OutputStream; +import java.io.IOException; + + +/** + * This class implements an abstract RtfField. + * + * This class is based on the RtfWriter-package from Mark Hall. + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * @author Dirk Weigenand + * @version $Id: AbstractRtfField.java,v 1.17 2006/02/09 17:25:26 hallm Exp $ + * @since Mon Aug 19 14:50:39 2002 + * @deprecated Please move to the RtfWriter2 and associated classes. + */ +abstract class AbstractRtfField extends Chunk implements RtfField { + private static final byte[] fldDirty = "\\flddirty".getBytes(); + private static final byte[] fldPriv = "\\fldpriv".getBytes(); + private static final byte[] fldLock = "\\fldlock".getBytes(); + private static final byte[] fldEdit = "\\fldedit".getBytes(); + private static final byte[] fldAlt = "\\fldalt".getBytes(); + + /** + * public constructor + * @param content the content of the field + * @param font the font of the field + */ + public AbstractRtfField(String content, Font font) { + super(content, font); + } + + /** + * Determines whether this RtfField is locked, i.e. it cannot be + * updated. Defaults to false. + */ + private boolean rtfFieldIsLocked = false; + + /** + * Determines whether a formatting change has been made since the + * field was last updated. Defaults to false. + */ + private boolean rtfFieldIsDirty = false; + + /** + * Determines whether text has been added, removed from thre field + * result since the field was last updated. Defaults to + * false. + */ + private boolean rtfFieldWasEdited = false; + + /** + * Determines whether the field is in suitable form for + * display. Defaults to false. + */ + private boolean rtfFieldIsPrivate = false; + + /** + * Determines whether this RtfField shall refer to an end note. + */ + private boolean rtfFieldIsAlt = false; + + /** + * Determines whtether the field is locked, i.e. it cannot be + * updated. + * + * @return true iff the field cannot be updated, + * false otherwise. + */ + public final boolean isLocked() { + return this.rtfFieldIsLocked; + } + + /** + * Set whether the field can be updated. + * + * @param rtfFieldIsLocked true if the field cannot be + * updated, false otherwise. + */ + public final void setLocked(final boolean rtfFieldIsLocked) { + this.rtfFieldIsLocked = rtfFieldIsLocked; + } + + /** + * Set whether a formatting change has been made since the field + * was last updated + * @param rtfFieldIsDirty true if the field was + * changed since the field was last updated, false + * otherwise. + */ + public final void setDirty(final boolean rtfFieldIsDirty) { + this.rtfFieldIsDirty = rtfFieldIsDirty; + } + + /** + * Determines whether the field was changed since the field was + * last updated + * @return true if the field was changed since the field + * was last updated, false otherwise. + */ + public final boolean isDirty() { + return this.rtfFieldIsDirty; + } + + /** + * Set whether text has been added, removed from thre field result + * since the field was last updated. + * @param rtfFieldWasEdited Determines whether text has been + * added, removed from the field result since the field was last + * updated (true, false otherwise.. + */ + public final void setEdited(final boolean rtfFieldWasEdited) { + this.rtfFieldWasEdited = rtfFieldWasEdited; + } + + /** + * Determines whether text has been added, removed from the field + * result since the field was last updated. + * @return rtfFieldWasEdited true if text has been added, + * removed from the field result since the field was last updated, + * false otherwise. + */ + public final boolean wasEdited() { + return this.rtfFieldWasEdited; + } + + /** + * Set whether the field is in suitable form for + * display. I.e. it's not a field with a picture as field result + * @param rtfFieldIsPrivate Determines whether the field is in + * suitable form for display: true it can be displayed, + * false it cannot be displayed. + */ + public final void setPrivate(final boolean rtfFieldIsPrivate) { + this.rtfFieldIsPrivate = rtfFieldIsPrivate; + } + + /** + * Determines whether the field is in suitable form for display. + * @return whether the field is in suitable form for display: + * true yes, false no it cannot be displayed. + */ + public final boolean isPrivate() { + return this.rtfFieldIsPrivate; + } + + /** + * Abstract method for writing custom stuff to the Field + * Initialization Stuff part of an RtfField. + * @param out + * @throws IOException + */ + public abstract void writeRtfFieldInitializationStuff(OutputStream out) throws IOException; + + /** + * Abstract method for writing custom stuff to the Field Result + * part of an RtfField. + * @param out + * @throws IOException + */ + public abstract void writeRtfFieldResultStuff(OutputStream out) throws IOException; + + /** + * Determines whether this RtfField shall refer to an end note. + * @param rtfFieldIsAlt true if this RtfField shall refer + * to an end note, false otherwise + */ + public final void setAlt(final boolean rtfFieldIsAlt) { + this.rtfFieldIsAlt = rtfFieldIsAlt; + } + + /** + * Determines whether this RtfField shall refer to an end + * note. + * @return true if this RtfField shall refer to an end + * note, false otherwise. + */ + public final boolean isAlt() { + return this.rtfFieldIsAlt; + } + + /** + * empty implementation for Chunk. + * @return an empty string + */ + public final String content() { + return ""; + } + + /** + * For Interface RtfField. + * @param writer + * @param out + * @throws IOException + */ + public void write( RtfWriter writer, OutputStream out ) throws IOException { + writeRtfFieldBegin(out); + writeRtfFieldModifiers(out); + writeRtfFieldInstBegin(out); + writer.writeInitialFontSignature( out, this ); + writeRtfFieldInitializationStuff(out); + writeRtfFieldInstEnd(out); + writeRtfFieldResultBegin(out); + writer.writeInitialFontSignature( out, this ); + writeRtfFieldResultStuff(out); + writeRtfFieldResultEnd(out); + writeRtfFieldEnd(out); + } + + /** + * Write the beginning of an RtfField to the OutputStream. + * @param out + * @throws IOException + */ + protected final void writeRtfFieldBegin(OutputStream out) throws IOException { + out.write(RtfWriter.openGroup); + out.write(RtfWriter.escape); + out.write(RtfWriter.field); + } + + /** + * Write the modifiers defined for a RtfField to the OutputStream. + * @param out + * @throws IOException + */ + protected final void writeRtfFieldModifiers(OutputStream out) throws IOException { + if (isDirty()) { + out.write(fldDirty); + } + + if (wasEdited()) { + out.write(fldEdit); + } + + if (isLocked()) { + out.write(fldLock); + } + + if (isPrivate()) { + out.write(fldPriv); + } + } + + /** + * Write RtfField Initialization Stuff to OutputStream. + * @param out + * @throws IOException + */ + protected final void writeRtfFieldInstBegin(OutputStream out) throws IOException { + out.write( RtfWriter.openGroup ); + out.write( RtfWriter.escape ); + out.write( RtfWriter.fieldContent ); + out.write( RtfWriter.delimiter ); + } + + /** + * Write end of RtfField Initialization Stuff to OutputStream. + * @param out + * @throws IOException + */ + protected final void writeRtfFieldInstEnd(OutputStream out) throws IOException { + if (isAlt()) { + out.write( fldAlt ); + out.write( RtfWriter.delimiter ); + } + + out.write( RtfWriter.closeGroup ); + } + + /** + * Write beginning of RtfField Result to OutputStream. + * @param out + * @throws IOException + */ + protected final void writeRtfFieldResultBegin(OutputStream out) throws IOException { + out.write( RtfWriter.openGroup ); + out.write( RtfWriter.escape ); + out.write( RtfWriter.fieldDisplay ); + out.write( RtfWriter.delimiter ); + } + + /** + * Write end of RtfField Result to OutputStream. + * @param out + * @throws IOException + */ + protected final void writeRtfFieldResultEnd(OutputStream out) throws IOException { + out.write( RtfWriter.delimiter ); + out.write( RtfWriter.closeGroup ); + } + + /** + * Close the RtfField. + * @param out + * @throws IOException + */ + protected final void writeRtfFieldEnd(OutputStream out) throws IOException { + out.write( RtfWriter.closeGroup ); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/GenericRtfField.java b/src/main/java/com/lowagie/text/rtf/GenericRtfField.java new file mode 100644 index 0000000..23401e4 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/GenericRtfField.java @@ -0,0 +1,139 @@ +/** + * $Id: GenericRtfField.java,v 1.18 2006/02/09 17:25:25 hallm Exp $ + * + * Copyright 2002 by + * SMB + * Dirk.Weigenand@smb-tec.com + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the “GNU LIBRARY GENERAL PUBLIC LICENSE”), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import java.io.IOException; +import java.io.OutputStream; + +import com.lowagie.text.Font; + + +/** + * This class implements a generic RtfField. + * + * This class is based on the RtfWriter-package from Mark Hall. + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * @author Dirk Weigenand + * @version $Id: GenericRtfField.java,v 1.18 2006/02/09 17:25:25 hallm Exp $ + * @since Mon Aug 19 14:50:39 2002 + * @deprecated Please move to the RtfWriter2 and associated classes. + */ +public class GenericRtfField extends AbstractRtfField implements RtfField { + /** + * Field Initialization Stuff. + */ + protected String fieldInst; + + /** + * Field Result Stuff. + */ + protected String fieldResult; + + /** + * public constructor, set the data that is to be written into the + * Field Initialization Stuff and Field Result parts of the + * RtfField. + * + * @param fieldInst data to be written into the Field + * Initialization Stuff part of the RtfField. + * @param fieldResult data to be written into the Field Result + * part of the RtfField. + */ + public GenericRtfField(final String fieldInst, final String fieldResult) { + super("x", new Font()); + this.fieldInst = fieldInst; + this.fieldResult = fieldResult; + } + + /** + * public constructor, set the data that is to be written into the + * Field Initialization Stuff and Field Result parts of the + * RtfField. + * + * @param fieldInst data to be written into the Field + * Initialization Stuff part of the RtfField. + * @param fieldResult data to be written into the Field Result + * part of the RtfField. + * @param font + */ + public GenericRtfField(final String fieldInst, final String fieldResult, Font font) { + super("x", font); + this.fieldInst = fieldInst; + this.fieldResult = fieldResult; + } + + /** + * method for writing custom stuff to the Field Initialization + * Stuff part of an RtfField. + * @param out + * @throws IOException + */ + public void writeRtfFieldInitializationStuff(OutputStream out) throws IOException { + out.write(fieldInst.trim().getBytes()); + out.write(RtfWriter.delimiter); + } + + /** + * method for writing custom stuff to the Field Result part of an + * RtfField. + * @param out + * @throws IOException + */ + public void writeRtfFieldResultStuff(OutputStream out) throws IOException { + if (null != fieldResult) { + out.write(fieldResult.trim().getBytes()); + } + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfAddableElement.java b/src/main/java/com/lowagie/text/rtf/RtfAddableElement.java new file mode 100644 index 0000000..539b647 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfAddableElement.java @@ -0,0 +1,127 @@ +/* + * $Id: RtfAddableElement.java,v 1.1 2006/06/17 10:02:31 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * Co-Developer of the code is Mark Hall. Portions created by the Co-Developer are + * Copyright (C) 2006 by Mark Hall. All Rights Reserved + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.Chunk; +import com.lowagie.text.Font; +import com.lowagie.text.rtf.document.RtfDocument; + +/** + * The RtfAddableElement is the superclass for all rtf specific elements + * that need to be added to an iText document. It is an extension of Chunk + * and it also implements RtfBasicElement. It is an abstract class thus it + * cannot be instantiated itself and has to be subclassed to be used. + * + * @version $Revision: 1.1 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public abstract class RtfAddableElement extends Chunk implements RtfBasicElement { + + /** + * The RtfDocument this RtfAddableElement belongs to. + */ + protected RtfDocument doc = null; + /** + * Whether this RtfAddableElement is contained in a table. + */ + protected boolean inTable = false; + /** + * Whether this RtfAddableElement is contained in a header. + */ + protected boolean inHeader = false; + + /** + * Constructs a new RtfAddableElement. The Chunk content is + * set to an empty string and the font to the default Font(). + */ + public RtfAddableElement() { + super("", new Font()); + } + + /** + * Subclasses have to implement this method. + */ + public abstract byte[] write(); + + /** + * Sets the RtfDocument this RtfAddableElement belongs to + */ + public void setRtfDocument(RtfDocument doc) { + this.doc = doc; + } + + /** + * Sets whether this RtfAddableElement is contained in a table. + */ + public void setInTable(boolean inTable) { + this.inTable = inTable; + } + + /** + * Sets whether this RtfAddableElement is contained in a header/footer. + */ + public void setInHeader(boolean inHeader) { + this.inHeader = inHeader; + } + + /** + * Transforms an integer into its String representation and then returns the bytes + * of that string. + * + * @param i The integer to convert + * @return A byte array representing the integer + */ + public byte[] intToByteArray(int i) { + return Integer.toString(i).getBytes(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfBasicElement.java b/src/main/java/com/lowagie/text/rtf/RtfBasicElement.java new file mode 100644 index 0000000..8b315ec --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfBasicElement.java @@ -0,0 +1,110 @@ +/* + * $Id: RtfBasicElement.java,v 1.16 2005/05/04 14:33:37 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.rtf.document.RtfDocument; + +/** + * The RtfBasicElement interface defines the interface for elements that can + * be added to the RtfWriter. + * + * Version: $Id: RtfBasicElement.java,v 1.16 2005/05/04 14:33:37 blowagie Exp $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public interface RtfBasicElement { + /** + * Constant for the beginning of a rtf group + */ + public static final byte[] OPEN_GROUP = "{".getBytes(); + /** + * Constant for the end of an rtf group + */ + public static final byte[] CLOSE_GROUP = "}".getBytes(); + /** + * Constant for a delimiter in rtf + */ + public static final byte[] DELIMITER = " ".getBytes(); + /** + * Constant for a comma delimiter in rtf + */ + public static final byte[] COMMA_DELIMITER = ";".getBytes(); + /** + * The factor to use for translating from iText to rtf measurments + */ + public static final double TWIPS_FACTOR = 20; + + /** + * Return the content of the Element in a byte array + * @return The byte array containing the data + */ + public byte[] write(); + + /** + * Sets the RtfDocument this RtfElement belongs to + * + * @param doc The RtfDocument to use + */ + public void setRtfDocument(RtfDocument doc); + + /** + * Sets whether this RtfBasicElement is in a table + * + * @param inTable Whether this RtfBasicElement is in a table + */ + public void setInTable(boolean inTable); + + /** + * Sets whether this RtfBasicElement is in a header + * + * @param inHeader Whether this RtfBasicElement is in a header + */ + public void setInHeader(boolean inHeader); +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfCell.java b/src/main/java/com/lowagie/text/rtf/RtfCell.java new file mode 100644 index 0000000..841c25b --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfCell.java @@ -0,0 +1,549 @@ +/** + * $Id: RtfCell.java,v 1.37 2006/02/09 17:25:26 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.*; + +import java.util.Iterator; +import java.io.*; +import java.awt.Color; + +/** + * A Helper Class for the RtfWriter. + *

+ * Do not use it directly + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * Parts of this Class were contributed by Steffen Stundzig. Many thanks for the + * improvements. + * Updates by Benoit WIART + * @deprecated Please move to the RtfWriter2 and associated classes. + */ +public class RtfCell { + /** Constants for merging Cells */ + + /** A possible value for merging */ + private static final int MERGE_HORIZ_FIRST = 1; + /** A possible value for merging */ + private static final int MERGE_VERT_FIRST = 2; + /** A possible value for merging */ + private static final int MERGE_BOTH_FIRST = 3; + /** A possible value for merging */ + private static final int MERGE_HORIZ_PREV = 4; + /** A possible value for merging */ + private static final int MERGE_VERT_PREV = 5; + /** A possible value for merging */ + private static final int MERGE_BOTH_PREV = 6; + + /** + * RTF Tags + */ + + /** First cell to merge with - Horizontal */ + private static final byte[] cellMergeFirst = "clmgf".getBytes(); + /** First cell to merge with - Vertical */ + private static final byte[] cellVMergeFirst = "clvmgf".getBytes(); + /** Merge cell with previous horizontal cell */ + private static final byte[] cellMergePrev = "clmrg".getBytes(); + /** Merge cell with previous vertical cell */ + private static final byte[] cellVMergePrev = "clvmrg".getBytes(); + /** Cell content vertical alignment bottom */ + private static final byte[] cellVerticalAlignBottom = "clvertalb".getBytes(); + /** Cell content vertical alignment center */ + private static final byte[] cellVerticalAlignCenter = "clvertalc".getBytes(); + /** Cell content vertical alignment top */ + private static final byte[] cellVerticalAlignTop = "clvertalt".getBytes(); + /** Cell border left */ + private static final byte[] cellBorderLeft = "clbrdrl".getBytes(); + /** Cell border right */ + private static final byte[] cellBorderRight = "clbrdrr".getBytes(); + /** Cell border top */ + private static final byte[] cellBorderTop = "clbrdrt".getBytes(); + /** Cell border bottom */ + private static final byte[] cellBorderBottom = "clbrdrb".getBytes(); + /** Cell background color */ + private static final byte[] cellBackgroundColor = "clcbpat".getBytes(); + /** Cell width format */ + private static final byte[] cellWidthStyle = "clftsWidth3".getBytes(); + /** Cell width */ + private static final byte[] cellWidthTag = "clwWidth".getBytes(); + /** Cell right border position */ + private static final byte[] cellRightBorder = "cellx".getBytes(); + /** Cell is part of table */ + protected static final byte[] cellInTable = "intbl".getBytes(); + /** End of cell */ + private static final byte[] cellEnd = "cell".getBytes(); + + /** padding top */ + private static final byte[] cellPaddingTop = "clpadt".getBytes(); + /** padding top unit */ + private static final byte[] cellPaddingTopUnit = "clpadft3".getBytes(); + /** padding bottom */ + private static final byte[] cellPaddingBottom = "clpadb".getBytes(); + /** padding bottom unit */ + private static final byte[] cellPaddingBottomUnit = "clpadfb3".getBytes(); + /** padding left */ + private static final byte[] cellPaddingLeft = "clpadl".getBytes(); + /** padding left unit */ + private static final byte[] cellPaddingLeftUnit = "clpadfl3".getBytes(); + /** padding right */ + private static final byte[] cellPaddingRight = "clpadr".getBytes(); + /** padding right unit */ + private static final byte[] cellPaddingRightUnit = "clpadfr3".getBytes(); + + /** The RtfWriter to which this RtfCell belongs. */ + private RtfWriter writer = null; + /** The RtfTable to which this RtfCell belongs. */ + private RtfTable mainTable = null; + + /** Cell width */ + private int cellWidth = 0; + /** Cell right border position */ + private int cellRight = 0; + /** Cell containing the actual data */ + private Cell store = null; + /** Is this an empty cell */ + private boolean emptyCell = true; + /** Type of merging to do */ + private int mergeType = 0; + /** cell padding, because the table only renders the left and right cell padding + * and not the top and bottom one + */ + private int cellpadding = 0; + + /** + * Create a new RtfCell. + * + * @param writer The RtfWriter that this RtfCell belongs to + * @param mainTable The RtfTable that created the + * RtfRow that created the RtfCell :-) + */ + public RtfCell(RtfWriter writer, RtfTable mainTable) { + super(); + this.writer = writer; + this.mainTable = mainTable; + } + + /** + * Import a Cell. + *

+ * @param cell The Cell containing the data for this + * RtfCell + * @param cellLeft The position of the left border + * @param cellWidth The default width of a cell + * @param x The column index of this RtfCell + * @param y The row index of this RtfCell + * @param cellpadding the cellpadding + * @return the position of the right side of the cell + */ + public int importCell(Cell cell, int cellLeft, int cellWidth, int x, int y, int cellpadding) { + this.cellpadding = cellpadding; + + // set this value in any case + this.cellWidth = cellWidth; + if (cell == null) { + cellRight = cellLeft + cellWidth; + return cellRight; + } + if (cell.cellWidth() != null && !cell.cellWidth().equals("")) { + + this.cellWidth = (int) (Integer.parseInt(cell.cellWidth()) * RtfWriter.TWIPSFACTOR); + } + cellRight = cellLeft + this.cellWidth; + store = cell; + emptyCell = false; + if (cell.colspan() > 1) { + if (cell.rowspan() > 1) { + mergeType = MERGE_BOTH_FIRST; + for (int i = y; i < y + cell.rowspan(); i++) { + if (i > y) mainTable.setMerge(x, i, MERGE_VERT_PREV, this); + for (int j = x + 1; j < x + cell.colspan(); j++) { + mainTable.setMerge(j, i, MERGE_BOTH_PREV, this); + } + } + } else { + mergeType = MERGE_HORIZ_FIRST; + for (int i = x + 1; i < x + cell.colspan(); i++) { + mainTable.setMerge(i, y, MERGE_HORIZ_PREV, this); + } + } + } else if (cell.rowspan() > 1) { + mergeType = MERGE_VERT_FIRST; + for (int i = y + 1; i < y + cell.rowspan(); i++) { + mainTable.setMerge(x, i, MERGE_VERT_PREV, this); + } + } + return cellRight; + } + + /** + * Write the properties of the RtfCell. + * + * @param os The OutputStream to which to write the properties + * of the RtfCell to. + * @return true if writing the cell settings succeeded + * @throws DocumentException + */ + public boolean writeCellSettings(ByteArrayOutputStream os) throws DocumentException { + try { + float lWidth, tWidth, rWidth, bWidth; + byte[] lStyle, tStyle, rStyle, bStyle; + + if (store instanceof RtfTableCell) { + RtfTableCell c = (RtfTableCell) store; + lWidth = c.leftBorderWidth(); + tWidth = c.topBorderWidth(); + rWidth = c.rightBorderWidth(); + bWidth = c.bottomBorderWidth(); + lStyle = RtfTableCell.getStyleControlWord(c.leftBorderStyle()); + tStyle = RtfTableCell.getStyleControlWord(c.topBorderStyle()); + rStyle = RtfTableCell.getStyleControlWord(c.rightBorderStyle()); + bStyle = RtfTableCell.getStyleControlWord(c.bottomBorderStyle()); + } else { + lWidth = tWidth = rWidth = bWidth = store.borderWidth(); + lStyle = tStyle = rStyle = bStyle = RtfRow.tableBorder; + } + + if (mergeType == MERGE_HORIZ_PREV || mergeType == MERGE_BOTH_PREV) { + return true; + } + switch (mergeType) { + case MERGE_VERT_FIRST: + os.write(RtfWriter.escape); + os.write(cellVMergeFirst); + break; + case MERGE_BOTH_FIRST: + os.write(RtfWriter.escape); + os.write(cellVMergeFirst); + break; + case MERGE_HORIZ_PREV: + os.write(RtfWriter.escape); + os.write(cellMergePrev); + break; + case MERGE_VERT_PREV: + os.write(RtfWriter.escape); + os.write(cellVMergePrev); + break; + case MERGE_BOTH_PREV: + os.write(RtfWriter.escape); + os.write(cellMergeFirst); + break; + } + switch (store.verticalAlignment()) { + case Element.ALIGN_BOTTOM: + os.write(RtfWriter.escape); + os.write(cellVerticalAlignBottom); + break; + case Element.ALIGN_CENTER: + case Element.ALIGN_MIDDLE: + os.write(RtfWriter.escape); + os.write(cellVerticalAlignCenter); + break; + case Element.ALIGN_TOP: + os.write(RtfWriter.escape); + os.write(cellVerticalAlignTop); + break; + } + + if (((store.border() & Rectangle.LEFT) == Rectangle.LEFT) && + (lWidth > 0)) { + os.write(RtfWriter.escape); + os.write(cellBorderLeft); + os.write(RtfWriter.escape); + os.write(lStyle); + os.write(RtfWriter.escape); + os.write(RtfRow.tableBorderWidth); + writeInt(os, (int) (lWidth * RtfWriter.TWIPSFACTOR)); + os.write(RtfWriter.escape); + os.write(RtfRow.tableBorderColor); + if (store.borderColor() == null) + writeInt(os, writer.addColor(new + Color(0, 0, 0))); + else + writeInt(os, writer.addColor(store.borderColor())); + os.write((byte) '\n'); + } + if (((store.border() & Rectangle.TOP) == Rectangle.TOP) && (tWidth > 0)) { + os.write(RtfWriter.escape); + os.write(cellBorderTop); + os.write(RtfWriter.escape); + os.write(tStyle); + os.write(RtfWriter.escape); + os.write(RtfRow.tableBorderWidth); + writeInt(os, (int) (tWidth * RtfWriter.TWIPSFACTOR)); + os.write(RtfWriter.escape); + os.write(RtfRow.tableBorderColor); + if (store.borderColor() == null) + writeInt(os, writer.addColor(new + Color(0, 0, 0))); + else + writeInt(os, writer.addColor(store.borderColor())); + os.write((byte) '\n'); + } + if (((store.border() & Rectangle.BOTTOM) == Rectangle.BOTTOM) && + (bWidth > 0)) { + os.write(RtfWriter.escape); + os.write(cellBorderBottom); + os.write(RtfWriter.escape); + os.write(bStyle); + os.write(RtfWriter.escape); + os.write(RtfRow.tableBorderWidth); + writeInt(os, (int) (bWidth * RtfWriter.TWIPSFACTOR)); + os.write(RtfWriter.escape); + os.write(RtfRow.tableBorderColor); + if (store.borderColor() == null) + writeInt(os, writer.addColor(new + Color(0, 0, 0))); + else + writeInt(os, writer.addColor(store.borderColor())); + os.write((byte) '\n'); + } + if (((store.border() & Rectangle.RIGHT) == Rectangle.RIGHT) && + (rWidth > 0)) { + os.write(RtfWriter.escape); + os.write(cellBorderRight); + os.write(RtfWriter.escape); + os.write(rStyle); + os.write(RtfWriter.escape); + os.write(RtfRow.tableBorderWidth); + writeInt(os, (int) (rWidth * RtfWriter.TWIPSFACTOR)); + os.write(RtfWriter.escape); + os.write(RtfRow.tableBorderColor); + if (store.borderColor() == null) + writeInt(os, writer.addColor(new + Color(0, 0, 0))); + else + writeInt(os, writer.addColor(store.borderColor())); + os.write((byte) '\n'); + } + os.write(RtfWriter.escape); + os.write(cellBackgroundColor); + if (store.backgroundColor() == null) { + writeInt(os, writer.addColor(new Color(255, 255, 255))); + } else { + writeInt(os, writer.addColor(store.backgroundColor())); + } + os.write((byte) '\n'); + os.write(RtfWriter.escape); + os.write(cellWidthStyle); + os.write((byte) '\n'); + os.write(RtfWriter.escape); + os.write(cellWidthTag); + writeInt(os, cellWidth); + os.write((byte) '\n'); + if (cellpadding > 0) { + // values + os.write(RtfWriter.escape); + os.write(cellPaddingLeft); + writeInt(os, cellpadding / 2); + os.write(RtfWriter.escape); + os.write(cellPaddingTop); + writeInt(os, cellpadding / 2); + os.write(RtfWriter.escape); + os.write(cellPaddingRight); + writeInt(os, cellpadding / 2); + os.write(RtfWriter.escape); + os.write(cellPaddingBottom); + writeInt(os, cellpadding / 2); + // unit + os.write(RtfWriter.escape); + os.write(cellPaddingLeftUnit); + os.write(RtfWriter.escape); + os.write(cellPaddingTopUnit); + os.write(RtfWriter.escape); + os.write(cellPaddingRightUnit); + os.write(RtfWriter.escape); + os.write(cellPaddingBottomUnit); + } + os.write(RtfWriter.escape); + os.write(cellRightBorder); + writeInt(os, cellRight); + } catch (IOException e) { + return false; + } + return true; + } + + /** + * Write the content of the RtfCell. + * + * @param os The OutputStream to which to write the content of + * the RtfCell to. + * @return true if writing the cell content succeeded + * @throws DocumentException + */ + public boolean writeCellContent(ByteArrayOutputStream os) throws DocumentException { + try { + if (mergeType == MERGE_HORIZ_PREV || mergeType == MERGE_BOTH_PREV) { + return true; + } + + if (!emptyCell) { + Iterator cellIterator = store.getElements(); + Paragraph container = null; + while (cellIterator.hasNext()) { + Element element = (Element) cellIterator.next(); + // should we wrap it in a paragraph + if(!(element instanceof Paragraph)) { + if(container != null) { + container.add(element); + } else { + container = new Paragraph(); + container.setAlignment(store.horizontalAlignment()); + container.add(element); + } + } else { + if(container != null) { + writer.addElement(container, os); + container =null; + container =null; + } + + + // if horizontal alignment is undefined overwrite + // with that of enclosing cell + if (element instanceof Paragraph && ((Paragraph) element).alignment() == Element.ALIGN_UNDEFINED) { + ((Paragraph) element).setAlignment(store.horizontalAlignment()); + } + writer.addElement(element, os); + if (element.type() == Element.PARAGRAPH && cellIterator.hasNext()) { + os.write(RtfWriter.escape); + os.write(RtfWriter.paragraph); + } + } + } + if(container != null) { + writer.addElement(container, os); + container =null; + } + } else { + os.write(RtfWriter.escape); + os.write(RtfWriter.paragraphDefaults); + os.write(RtfWriter.escape); + os.write(cellInTable); + } + os.write(RtfWriter.escape); + os.write(cellEnd); + } catch (IOException e) { + return false; + } + return true; + } + + /** + * Sets the merge type and the RtfCell with which this + * RtfCell is to be merged. + * + * @param mergeType The merge type specifies the kind of merge to be applied + * (MERGE_HORIZ_PREV, MERGE_VERT_PREV, MERGE_BOTH_PREV) + * @param mergeCell The RtfCell that the cell at x and y is to + * be merged with + */ + public void setMerge(int mergeType, RtfCell mergeCell) { + this.mergeType = mergeType; + store = mergeCell.getStore(); + } + + /** + * Get the Cell with the actual content. + * + * @return Cell which is contained in the RtfCell + */ + public Cell getStore() { + return store; + } + + /** + * Get the with of this RtfCell + * + * @return Width of the current RtfCell + */ + public int getCellWidth() { + return cellWidth; + } + + /** + * sets the width of the cell + * @param value a width + */ + public void setCellWidth(int value) { + cellWidth = value; + } + + /** + * Get the position of the right border of this RtfCell. + * @return position of the right border + */ + public int getCellRight() { + return cellRight; + } + + + /** + * Sets the right position of the cell + * @param value a cell position + */ + public void setCellRight(int value) { + cellRight = value; + } + + /** + * Write an Integer to the Outputstream. + * + * @param out The OutputStream to be written to. + * @param i The int to be written. + * @throws IOException + */ + private void writeInt(ByteArrayOutputStream out, int i) throws IOException { + out.write(Integer.toString(i).getBytes()); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfElement.java b/src/main/java/com/lowagie/text/rtf/RtfElement.java new file mode 100644 index 0000000..03d05c0 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfElement.java @@ -0,0 +1,149 @@ +/* + * $Id: RtfElement.java,v 1.8 2004/12/14 15:14:44 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.rtf.document.RtfDocument; + +/** + * RtfElement is the base class for all RTF Element classes + * + * Version: $Id: RtfElement.java,v 1.8 2004/12/14 15:14:44 blowagie Exp $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfElement implements RtfBasicElement { + /** + * Constant for a rtf escape + */ + //public static final byte[] ESCAPE = "\\".getBytes(); + /** + * Constant for a rtf extended escape + */ + //public static final byte[] EXTENDED_ESCAPE = "\\*\\".getBytes(); + + /** + * The RtfDocument this RtfElement belongs to + */ + protected RtfDocument document = null; + /** + * Whether this RtfElement is in a table + */ + protected boolean inTable = false; + /** + * Whether this RtfElement is in a header + */ + protected boolean inHeader = false; + + /** + * Constructs a RtfElement belonging to the specified RtfDocument. + * + * @param doc The RtfDocument this RtfElement belongs to + */ + public RtfElement(RtfDocument doc) { + super(); + this.document = doc; + } + + /** + * Transforms an integer into its String representation and then returns the bytes + * of that string. + * + * @param i The integer to convert + * @return A byte array representing the integer + */ + public byte[] intToByteArray(int i) { + return Integer.toString(i).getBytes(); + } + + /** + * Returns the content of the RtfElement in a byte array. + * + * @return An empty byte array + */ + public byte[] write() { + return new byte[0]; + } + + /** + * Sets the RtfDocument this RtfElement belongs to + * + * @param doc The RtfDocument to use + */ + public void setRtfDocument(RtfDocument doc) { + this.document = doc; + } + + /** + * Gets whether this RtfElement is in a table + * + * @return Whether this RtfElement is in a table + */ + public boolean isInTable() { + return inTable; + } + + /** + * Sets whether this RtfElement is in a table + * + * @param inTable True if this RtfElement is in a table, false otherwise + */ + public void setInTable(boolean inTable) { + this.inTable = inTable; + } + + /** + * Sets whether this RtfElement is in a header + * + * @param inHeader True if this RtfElement is in a header, false otherwise + */ + public void setInHeader(boolean inHeader) { + this.inHeader = inHeader; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfExtendedElement.java b/src/main/java/com/lowagie/text/rtf/RtfExtendedElement.java new file mode 100644 index 0000000..39a6efa --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfExtendedElement.java @@ -0,0 +1,65 @@ +/* + * $Id: RtfExtendedElement.java,v 1.16 2005/05/04 14:33:37 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +/** + * The RtfExtendedElement interface is to be used for elements that also + * write data into the definition part of the rtf document + * Version: $Id: RtfExtendedElement.java,v 1.16 2005/05/04 14:33:37 blowagie Exp $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public interface RtfExtendedElement extends RtfBasicElement { + /** + * Return the definition part of the element in a byte array + * @return A byte array containing the definition data of the Element + */ + public byte[] writeDefinition(); +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfField.java b/src/main/java/com/lowagie/text/rtf/RtfField.java new file mode 100644 index 0000000..a98fb31 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfField.java @@ -0,0 +1,84 @@ +/** + * $Id: RtfField.java,v 1.18 2006/02/09 17:25:25 hallm Exp $ + * + * Copyright 2002 by + * SMB + * Steffen.Stundzig@smb-tec.com + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the “GNU LIBRARY GENERAL PUBLIC LICENSE”), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.rtf.RtfWriter; + +import java.io.OutputStream; +import java.io.IOException; + + +/** + * This interface should mark classes, that can be represented + * as RTF fields, such as pagenumber, toc entries and so on. + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * This class is based on the RtfWriter-package from Mark Hall. + * @author Steffen.Stundzig@smb-tec.com + * @version $Revision: 1.18 $Date: 2006/02/09 17:25:25 $ + * @deprecated Please move to the RtfWriter2 and associated classes. + */ +public interface RtfField { + + + /** + * Writes an RTF field. + * @param writer + * @param out + * @throws IOException + */ + public void write( RtfWriter writer, OutputStream out ) throws IOException; +} + + diff --git a/src/main/java/com/lowagie/text/rtf/RtfFont.java b/src/main/java/com/lowagie/text/rtf/RtfFont.java new file mode 100644 index 0000000..3fd4651 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfFont.java @@ -0,0 +1,162 @@ +/* + * $Id: RtfFont.java,v 1.25 2006/02/09 17:25:26 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.Font; + +import java.awt.*; + +/** + * The RtfFont class enables you to add arbitrary Fonts to a rtf document by specifying + * the font name you want to have. The font has to be installed on the client for this to + * work. + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * @author mhall@myrealbox.com + * @deprecated Please move to the RtfWriter2 and associated classes. com.lowagie.text.rtf.style.RtfFont replaces the functionality of this class. + */ +public class RtfFont extends Font { + /** + * The font family name of this RtfFont + */ + private String familyName = ""; + + /** + * Constructs a RtfFont + * + * @param familyName The family name of this RtfFont + */ + public RtfFont(String familyName) { + super(Font.UNDEFINED); + this.familyName = familyName; + } + + /** + * Constructs a RtfFont + * + * @param familyName The font family name of this RtfFont + * @param size The font size of this RtfFont + */ + public RtfFont(String familyName, float size) { + super(Font.UNDEFINED, size); + this.familyName = familyName; + } + + /** + * Constructs a RtfFont + * + * @param familyName The font family name of this RtfFont + * @param size The font size of this RtfFont + * @param style The font style of this RtfFont + */ + public RtfFont(String familyName, float size, int style) { + super(Font.UNDEFINED, size, style); + this.familyName = familyName; + } + + /** + * Constructs a RtfFont + * + * @param familyName The font family name of this RtfFont + * @param size The font size of this RtfFont + * @param style The font style of this RtfFont + * @param color The font color of this RtfFont + */ + public RtfFont(String familyName, float size, int style, Color color) { + super(Font.UNDEFINED, size, style, color); + this.familyName = familyName; + } + + /** + * Gets the familyname as a String. + * + * @return the familyname + */ + public String getFamilyname() { + return this.familyName; + } + + /** + * Replaces the attributes that are equal to null with + * the attributes of a given font. + * + * @param font the font of a bigger element class + * @return a Font + */ + public Font difference(Font font) { + String dFamilyname = font.getFamilyname(); + if(dFamilyname == null || dFamilyname.trim().equals("")) { + dFamilyname = this.familyName; + } + + float dSize = font.size(); + if(dSize == Font.UNDEFINED) { + dSize = this.size(); + } + + int dStyle = Font.UNDEFINED; + if(this.style() != Font.UNDEFINED && font.style() != Font.UNDEFINED) { + dStyle = this.style() | font.style(); + } else if(this.style() != Font.UNDEFINED) { + dStyle = this.style(); + } else if(font.style() != Font.UNDEFINED) { + dStyle = font.style(); + } + + Color dColor = font.color(); + if(dColor == null) { + dColor = this.color(); + } + + return new RtfFont(dFamilyname, dSize, dStyle, dColor); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfHeaderFooter.java b/src/main/java/com/lowagie/text/rtf/RtfHeaderFooter.java new file mode 100644 index 0000000..d1f59f5 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfHeaderFooter.java @@ -0,0 +1,114 @@ +/** + * $Id: RtfHeaderFooter.java,v 1.20 2006/02/09 17:25:25 hallm Exp $ + * + * Copyright 2002 by + * SMB + * Steffen.Stundzig@smb-tec.com + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without right the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ +package com.lowagie.text.rtf; + +import com.lowagie.text.Element; +import com.lowagie.text.HeaderFooter; +import com.lowagie.text.Phrase; + + +/** + * This HeaderFooter specialization extends the normal HeaderFooter impl. + * by the new ctor with 'Element' param. + * So we have the ability to add a table or some moe sophisticated stuff + * as header or footer content. + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * This class is based on the RtfWriter-package from Mark Hall. + * @author Steffen.Stundzig@smb-tec.com + * @author Mark.Hall@myrealbox.com + * @version $Revision: 1.20 $Date: 2006/02/09 17:25:25 $ + * @deprecated Please move to the RtfWriter2 and associated classes. com.lowagie.text.rtf.headerfooter.RtfHeaderFooter replaces the functionality of this class. + */ +public class RtfHeaderFooter extends HeaderFooter { + + + private Element content = null; + + + /** + * Constructs a new header + * @param before + * @param after + */ + public RtfHeaderFooter( Phrase before, Phrase after ) { + super( before, after ); + } + + + /** + * Constructs a new header + * @param before + * @param numbered + */ + public RtfHeaderFooter( Phrase before, boolean numbered ) { + super( before, numbered ); + } + + + /** + * Constructs a new header + * @param content + */ + public RtfHeaderFooter( Element content ) { + super(new Phrase(content.toString()), false); + this.content = content; + } + + + /** + * @return the element specified in the ctor or null; + */ + public Element content() { + return content; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfHeaderFooters.java b/src/main/java/com/lowagie/text/rtf/RtfHeaderFooters.java new file mode 100644 index 0000000..70d0c83 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfHeaderFooters.java @@ -0,0 +1,160 @@ +/** + * $Id: RtfHeaderFooters.java,v 1.21 2006/02/09 17:25:25 hallm Exp $ + * + * Copyright 2002 by + * SMB + * Steffen.Stundzig@smb-tec.com + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without right the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.HeaderFooter; +import com.lowagie.text.Phrase; + + +/** + * This HeaderFooter specialization contains some headers or footers for several + * pages. Is a list of headerFooters but also a sub class of header footer, to change + * as less as possible of the current API. + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * This class is based on the RtfWriter-package from Mark Hall. + * @author Steffen.Stundzig@smb-tec.com + * @author Mark.Hall@myrealbox.com + * @version $Revision: 1.21 $Date: 2006/02/09 17:25:25 $ + * @deprecated Please move to the RtfWriter2 and associated classes. com.lowagie.text.rtf.headerfooter.RtfHeaderFooterGroup replaces the functionality of this class. + */ +public class RtfHeaderFooters extends HeaderFooter { + /** an attribute value */ + public final static int ALL_PAGES = 0; + /** an attribute value */ + public final static int LEFT_PAGES = 1; + /** an attribute value */ + public final static int RIGHT_PAGES = 2; + /** an attribute value */ + public final static int FIRST_PAGE = 3; + +// public int defaultHeader = ALL_PAGES; + + /** header or footer placeholder */ + private HeaderFooter allPages = null; + /** header or footer placeholder */ + private HeaderFooter leftPages = null; + /** header or footer placeholder */ + private HeaderFooter rightPages = null; + /** header or footer placeholder */ + private HeaderFooter firstPage = null; + + /** + * Contructs a HeaderFooters object + */ + public RtfHeaderFooters() { + super( new Phrase(""), false ); + } + + /** + * Contructs a HeaderFooters object + * @param before + * @param after + */ + public RtfHeaderFooters( Phrase before, Phrase after ) { + super( before, after ); + } + + /** + * Contructs a HeaderFooters object + * @param before + * @param numbered + */ + public RtfHeaderFooters( Phrase before, boolean numbered ) { + super( before, numbered ); + } + + /** + * Adds a HeaderFooter to this HeaderFooters object + * @param type + * @param hf + */ + public void set( int type, HeaderFooter hf ) { + switch (type) { + case ALL_PAGES: + allPages = hf; + break; + case LEFT_PAGES: + leftPages = hf; + break; + case RIGHT_PAGES: + rightPages = hf; + break; + case FIRST_PAGE: + firstPage = hf; + break; + default: + throw new IllegalStateException( "unknown type " + type ); + } + } + + /** + * Returns a type of HeaderFooter object registered in this HeaderFooters object. + * @param type type of the HeaderFooter object + * @return a HeaderFooter object + */ + public HeaderFooter get( int type ) { + switch (type) { + case ALL_PAGES: + return allPages; + case LEFT_PAGES: + return leftPages; + case RIGHT_PAGES: + return rightPages; + case FIRST_PAGE: + return firstPage; + default: + throw new IllegalStateException( "unknown type " + type ); + } + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfMapper.java b/src/main/java/com/lowagie/text/rtf/RtfMapper.java new file mode 100644 index 0000000..1464c81 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfMapper.java @@ -0,0 +1,182 @@ +/* + * $Id: RtfMapper.java,v 1.10 2005/05/04 14:41:15 blowagie Exp $ + * $Name: $ + * + * Copyright 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.Anchor; +import com.lowagie.text.Annotation; +import com.lowagie.text.Chapter; +import com.lowagie.text.Chunk; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.Image; +import com.lowagie.text.List; +import com.lowagie.text.ListItem; +import com.lowagie.text.Meta; +import com.lowagie.text.Paragraph; +import com.lowagie.text.Phrase; +import com.lowagie.text.Section; +import com.lowagie.text.SimpleTable; +import com.lowagie.text.Table; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.document.RtfInfoElement; +import com.lowagie.text.rtf.field.RtfAnchor; +import com.lowagie.text.rtf.graphic.RtfImage; +import com.lowagie.text.rtf.list.RtfList; +import com.lowagie.text.rtf.list.RtfListItem; +import com.lowagie.text.rtf.table.RtfTable; +import com.lowagie.text.rtf.text.RtfAnnotation; +import com.lowagie.text.rtf.text.RtfChapter; +import com.lowagie.text.rtf.text.RtfChunk; +import com.lowagie.text.rtf.text.RtfNewPage; +import com.lowagie.text.rtf.text.RtfParagraph; +import com.lowagie.text.rtf.text.RtfPhrase; +import com.lowagie.text.rtf.text.RtfSection; + + +/** + * The RtfMapper provides mappings between com.lowagie.text.* classes + * and the corresponding com.lowagie.text.rtf.** classes. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfMapper { + + /** + * The RtfDocument this RtfMapper belongs to + */ + RtfDocument rtfDoc; + + /** + * Constructs a RtfMapper for a RtfDocument + * + * @param doc The RtfDocument this RtfMapper belongs to + */ + public RtfMapper(RtfDocument doc) { + this.rtfDoc = doc; + } + + /** + * Takes an Element subclass and returns the correct RtfBasicElement + * subclass, that wraps the Element subclass. + * + * @param element The Element to wrap + * @return A RtfBasicElement wrapping the Element + * @throws DocumentException + */ + public RtfBasicElement mapElement(Element element) throws DocumentException { + RtfBasicElement rtfElement = null; + + if(element instanceof RtfBasicElement) { + rtfElement = (RtfBasicElement) element; + rtfElement.setRtfDocument(this.rtfDoc); + return rtfElement; + } + switch(element.type()) { + case Element.CHUNK: + if(((Chunk) element).getImage() != null) { + rtfElement = new RtfImage(rtfDoc, ((Chunk) element).getImage()); + } else if(((Chunk) element).hasAttributes() && ((Chunk) element).getAttributes().containsKey(Chunk.NEWPAGE)) { + rtfElement = new RtfNewPage(rtfDoc); + } else { + rtfElement = new RtfChunk(rtfDoc, (Chunk) element); + } + break; + case Element.PHRASE: + rtfElement = new RtfPhrase(rtfDoc, (Phrase) element); + break; + case Element.PARAGRAPH: + rtfElement = new RtfParagraph(rtfDoc, (Paragraph) element); + break; + case Element.ANCHOR: + rtfElement = new RtfAnchor(rtfDoc, (Anchor) element); + break; + case Element.ANNOTATION: + rtfElement = new RtfAnnotation(rtfDoc, (Annotation) element); + break; + case Element.IMGRAW: + case Element.IMGTEMPLATE: + case Element.JPEG: + rtfElement = new RtfImage(rtfDoc, (Image) element); + break; + case Element.AUTHOR: + case Element.SUBJECT: + case Element.KEYWORDS: + case Element.TITLE: + case Element.PRODUCER: + case Element.CREATIONDATE: + rtfElement = new RtfInfoElement(rtfDoc, (Meta) element); + break; + case Element.LIST: + rtfElement = new RtfList(rtfDoc, (List) element); + break; + case Element.LISTITEM: + rtfElement = new RtfListItem(rtfDoc, (ListItem) element); + break; + case Element.SECTION: + rtfElement = new RtfSection(rtfDoc, (Section) element); + break; + case Element.CHAPTER: + rtfElement = new RtfChapter(rtfDoc, (Chapter) element); + break; + case Element.TABLE: + try { + rtfElement = new RtfTable(rtfDoc, (Table) element); + } + catch(ClassCastException e) { + rtfElement = new RtfTable(rtfDoc, ((SimpleTable) element).createTable()); + } + break; + } + + return rtfElement; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfPageNumber.java b/src/main/java/com/lowagie/text/rtf/RtfPageNumber.java new file mode 100644 index 0000000..1e966a2 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfPageNumber.java @@ -0,0 +1,105 @@ +/** + * $Id: RtfPageNumber.java,v 1.26 2006/02/09 17:25:25 hallm Exp $ + * + * Copyright 2002 by + * SMB + * Steffen.Stundzig@smb-tec.com + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import java.io.IOException; +import java.io.OutputStream; + +import com.lowagie.text.Font; + +/** + * A rtf page number field. + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * This class is based on the RtfWriter-package from Mark Hall. + * @author Steffen.Stundzig@smb-tec.com + * @author mhall@myrealbox.com + * @version $Revision: 1.26 $Date: 2006/02/09 17:25:25 $ + * @deprecated Please move to the RtfWriter2 and associated classes. com.lowagie.text.rtf.field.RtfPageNumber replaces the functionality of this class. + */ +public class RtfPageNumber extends GenericRtfField implements RtfField { + private String content; + + /** + * construct a RtfPageNumber. The parameter content will be + * displayed in front of the page number using the font given as + * second argument. + * @param content the String that will be displayed in front of the page number + * @param contentFont the font to use to display this page number + */ + public RtfPageNumber( String content, Font contentFont ) { + super("PAGE", "", contentFont); + this.content = content; + } + + /** + * write this RtfField into a stream using the writer given as + * first argument. + * @param writer the RtfWriter to use to write this RtfField + * @param out the Stream to write this RtfField into. + * @throws IOException + */ + public void write( RtfWriter writer, OutputStream out ) throws IOException { + writer.writeInitialFontSignature( out, this ); + out.write(content.getBytes()); + writer.writeFinishingFontSignature( out, this ); + super.write(writer, out); + } + + /** + * @see com.lowagie.text.Element#toString() + */ + public String toString() { + return content; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfRow.java b/src/main/java/com/lowagie/text/rtf/RtfRow.java new file mode 100644 index 0000000..4a68987 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfRow.java @@ -0,0 +1,443 @@ +/** + * $Id: RtfRow.java,v 1.38 2006/02/09 17:25:25 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.*; + +import java.util.ArrayList; +import java.util.Iterator; +import java.io.*; +import java.awt.Color; + +/** + * A Helper Class for the RtfWriter. + *

+ * Do not use it directly + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * Parts of this Class were contributed by Steffen Stundzig. Many thanks for the + * improvements. + * Code added by c + * @deprecated Please move to the RtfWriter2 and associated classes. + */ +public class RtfRow { + /** Table border solid */ + public static final byte[] tableBorder = "brdrs".getBytes(); + /** Table border width */ + public static final byte[] tableBorderWidth = "brdrw".getBytes(); + /** Table border color */ + public static final byte[] tableBorderColor = "brdrcf".getBytes(); + + /** Table row defaults */ + private static final byte[] rowBegin = "trowd".getBytes(); + /** End of table row */ + private static final byte[] rowEnd = "row".getBytes(); + /** Table row autofit */ + private static final byte[] rowAutofit = "trautofit1".getBytes(); + private static final byte[] graphLeft = "trgaph".getBytes(); + /** Row border left */ + private static final byte[] rowBorderLeft = "trbrdrl".getBytes(); + /** Row border right */ + private static final byte[] rowBorderRight = "trbrdrr".getBytes(); + /** Row border top */ + private static final byte[] rowBorderTop = "trbrdrt".getBytes(); + /** Row border bottom */ + private static final byte[] rowBorderBottom = "trbrdrb".getBytes(); + /** Row border horiz inline */ + private static final byte[] rowBorderInlineHorizontal = "trbrdrh".getBytes(); + /** Row border bottom */ + private static final byte[] rowBorderInlineVertical = "trbrdrv".getBytes(); + /** Default cell spacing left */ + private static final byte[] rowSpacingLeft = "trspdl".getBytes(); + /** Default cell spacing right */ + private static final byte[] rowSpacingRight = "trspdr".getBytes(); + /** Default cell spacing top */ + private static final byte[] rowSpacingTop = "trspdt".getBytes(); + /** Default cell spacing bottom */ + private static final byte[] rowSpacingBottom = "trspdb".getBytes(); + /** Default cell spacing format left */ + private static final byte[] rowSpacingLeftStyle = "trspdfl3".getBytes(); + /** Default cell spacing format right */ + private static final byte[] rowSpacingRightStyle = "trspdfr3".getBytes(); + /** Default cell spacing format top */ + private static final byte[] rowSpacingTopStyle = "trspdft3".getBytes(); + /** Default cell spacing format bottom */ + private static final byte[] rowSpacingBottomStyle = "trspdfb3".getBytes(); + /** Default cell padding left */ + private static final byte[] rowPaddingLeft = "trpaddl".getBytes(); + /** Default cell padding right */ + private static final byte[] rowPaddingRight = "trpaddr".getBytes(); + /** Default cell padding format left */ + private static final byte[] rowPaddingLeftStyle = "trpaddfl3".getBytes(); + /** Default cell padding format right */ + private static final byte[] rowPaddingRightStyle = "trpaddfr3".getBytes(); + /** Row width format */ + private static final byte[] rowWidthStyle = "trftsWidth3".getBytes(); + /** Row width */ + private static final byte[] rowWidth = "trwWidth".getBytes(); + /** + * Table row header. This row should appear at the top of every + * page the current table appears on. + */ + private static final byte[] rowHeader = "trhdr".getBytes(); + /** + * Table row keep together. This row cannot be split by a page break. + * This property is assumed to be off unless the control word is + * present. + */ + private static final byte[] rowKeep = "trkeep".getBytes(); + /** Table alignment left */ + private static final byte[] rowAlignLeft = "trql".getBytes(); + /** Table alignment center */ + private static final byte[] rowAlignCenter = "trqc".getBytes(); + /** Table alignment right */ + private static final byte[] rowAlignRight = "trqr".getBytes(); + + /** List of RtfCells in this RtfRow */ + private ArrayList cells = new ArrayList(); + /** The RtfWriter to which this RtfRow belongs */ + private RtfWriter writer = null; + /** The RtfTable to which this RtfRow belongs */ + private RtfTable mainTable = null; + + /** The width of this RtfRow (in percent) */ + private int width = 100; + /** The default cellpadding of RtfCells in this + * RtfRow */ + private int cellpadding = 115; + /** The default cellspacing of RtfCells in this + * RtfRow */ + private int cellspacing = 14; + /** The borders of this RtfRow */ + private int borders = 0; + /** The border color of this RtfRow */ + private java.awt.Color borderColor = null; + /** The border width of this RtfRow */ + private float borderWidth = 0; + + /** Original Row */ + private Row origRow = null; + + /** + * Create a new RtfRow. + * + * @param writer The RtfWriter that this RtfRow belongs to + * @param mainTable The RtfTable that created this + * RtfRow + */ + public RtfRow(RtfWriter writer, RtfTable mainTable) { + super(); + this.writer = writer; + this.mainTable = mainTable; + } + + /** + * Pregenerate the RtfCells in this RtfRow. + * + * @param columns The number of RtfCells to be generated. + */ + public void pregenerateRows(int columns) { + for (int i = 0; i < columns; i++) { + RtfCell rtfCell = new RtfCell(writer, mainTable); + cells.add(rtfCell); + } + } + + /** + * Import a Row. + *

+ * All the parameters are taken from the RtfTable which contains + * this RtfRow and they do exactely what they say + * @param row + * @param propWidths in percent + * @param tableWidth in percent + * @param pageWidth + * @param cellpadding + * @param cellspacing + * @param borders + * @param borderColor + * @param borderWidth + * @param y + * @return true if importing the row succeeded + */ + public boolean importRow(Row row, float[] propWidths, int tableWidth, int pageWidth, int cellpadding, + int cellspacing, int borders, java.awt.Color borderColor, float borderWidth, + int y) { + // the width of this row is the absolute witdh, calculated from the + // proportional with of the table and the total width of the page + this.origRow = row; + this.width = pageWidth / 100 * tableWidth; + this.cellpadding = cellpadding; + this.cellspacing = cellspacing; + this.borders = borders; + this.borderColor = borderColor; + this.borderWidth = borderWidth; + + if (this.borderWidth > 2) this.borderWidth = 2; + + int cellLeft = 0; + for (int i = 0; i < row.columns(); i++) { + Element cell = (Element) row.getCell(i); + + // cellWidth is an absolute argument + // it's based on the absolute of this row and the proportional + // width of this column + int cellWidth = (int) (width / 100 * propWidths[i]); + if (cell != null) { + if (cell.type() == Element.CELL) { + RtfCell rtfCell = (RtfCell) cells.get(i); + cellLeft = rtfCell.importCell((Cell) cell, cellLeft, cellWidth, i, y, cellpadding); + } + } else { + RtfCell rtfCell = (RtfCell) cells.get(i); + cellLeft = rtfCell.importCell(null, cellLeft, cellWidth, i, y, cellpadding); + } + } + + // recalculate the cell right border and the cumulative width + // on col spanning cells. + // col + row spanning cells are also handled by this loop, because the real cell of + // the upper left corner in such an col, row matrix is copied as first cell + // in each row in this matrix + int columns = row.columns(); + for (int i = 0; i < columns; i++) { + RtfCell firstCell = (RtfCell) cells.get(i); + Cell cell = firstCell.getStore(); + int cols = 0; + if(cell != null) { + cols = cell.colspan(); + } + if (cols > 1) { + RtfCell lastCell = (RtfCell) cells.get(i + cols - 1); + firstCell.setCellRight(lastCell.getCellRight()); + int width = firstCell.getCellWidth(); + for (int j = i + 1; j < i + cols; j++) { + RtfCell cCell = (RtfCell) cells.get(j); + width += cCell.getCellWidth(); + } + firstCell.setCellWidth(width); + i += cols - 1; + } + } + return true; + } + + /** + * Write the RtfRow to the specified OutputStream. + * + * @param os The OutputStream to which this RtfRow + * should be written to. + * @param rowNum The index of this row in the containing table. + * @param table The Table which contains the original Row. + * @return true if writing the row succeeded + * @throws DocumentException + * @throws IOException + */ + public boolean writeRow(ByteArrayOutputStream os, int rowNum, Table table) throws DocumentException, + IOException { + os.write(RtfWriter.escape); + os.write(rowBegin); + os.write((byte) '\n'); + os.write(RtfWriter.escape); + os.write(rowWidthStyle); + os.write(RtfWriter.escape); + os.write(rowWidth); + writeInt(os, width); +// os.write(RtfWriter.escape); +// os.write(rowAutofit); + if (mainTable.getOriginalTable().hasToFitPageCells()) { + os.write(RtfWriter.escape); + os.write(rowKeep); + } + // check if this row is a header row + if (rowNum < table.firstDataRow()) { + os.write(RtfWriter.escape); + os.write(rowHeader); + } + os.write(RtfWriter.escape); + switch (this.origRow.horizontalAlignment()) { + case Element.ALIGN_LEFT: + os.write(rowAlignLeft); + break; + case Element.ALIGN_CENTER: + os.write(rowAlignCenter); + break; + case Element.ALIGN_RIGHT: + os.write(rowAlignRight); + break; + default : + os.write(rowAlignLeft); + break; + } + os.write(RtfWriter.escape); + os.write(graphLeft); + writeInt(os, 10); + if (((borders & Rectangle.LEFT) == Rectangle.LEFT) && (borderWidth > 0)) { + writeBorder(os, rowBorderLeft); + } + if (((borders & Rectangle.TOP) == Rectangle.TOP) && (borderWidth > 0)) { + writeBorder(os, rowBorderTop); + } + if (((borders & Rectangle.BOTTOM) == Rectangle.BOTTOM) && (borderWidth > 0)) { + writeBorder(os, rowBorderBottom); + } + if (((borders & Rectangle.RIGHT) == Rectangle.RIGHT) && (borderWidth > 0)) { + writeBorder(os, rowBorderRight); + } + if (((borders & Rectangle.BOX) == Rectangle.BOX) && (borderWidth > 0)) { + writeBorder(os, rowBorderInlineHorizontal); + writeBorder(os, rowBorderInlineVertical); + } + + if (cellspacing > 0) { + os.write(RtfWriter.escape); + os.write(rowSpacingLeft); + writeInt(os, cellspacing / 2); + os.write(RtfWriter.escape); + os.write(rowSpacingLeftStyle); + os.write(RtfWriter.escape); + os.write(rowSpacingTop); + writeInt(os, cellspacing / 2); + os.write(RtfWriter.escape); + os.write(rowSpacingTopStyle); + os.write(RtfWriter.escape); + os.write(rowSpacingBottom); + writeInt(os, cellspacing / 2); + os.write(RtfWriter.escape); + os.write(rowSpacingBottomStyle); + os.write(RtfWriter.escape); + os.write(rowSpacingRight); + writeInt(os, cellspacing / 2); + os.write(RtfWriter.escape); + os.write(rowSpacingRightStyle); + } + os.write(RtfWriter.escape); + os.write(rowPaddingLeft); + writeInt(os, cellpadding / 2); + os.write(RtfWriter.escape); + os.write(rowPaddingRight); + writeInt(os, cellpadding / 2); + os.write(RtfWriter.escape); + os.write(rowPaddingLeftStyle); + os.write(RtfWriter.escape); + os.write(rowPaddingRightStyle); + os.write((byte) '\n'); + + Iterator cellIterator = cells.iterator(); + while (cellIterator.hasNext()) { + RtfCell cell = (RtfCell) cellIterator.next(); + cell.writeCellSettings(os); + } + + os.write(RtfWriter.escape); + os.write("intbl".getBytes()); + + cellIterator = cells.iterator(); + while (cellIterator.hasNext()) { + RtfCell cell = (RtfCell) cellIterator.next(); + cell.writeCellContent(os); + } + os.write(RtfWriter.delimiter); + os.write(RtfWriter.escape); + os.write(rowEnd); + return true; + } + + + private void writeBorder(ByteArrayOutputStream os, byte[] borderType) throws IOException { + // horizontal and vertical, top, left, bottom, right + os.write(RtfWriter.escape); + os.write(borderType); + // line style + os.write(RtfWriter.escape); + os.write(RtfRow.tableBorder); + // borderwidth + os.write(RtfWriter.escape); + os.write(RtfRow.tableBorderWidth); + writeInt(os, (int) (borderWidth * RtfWriter.TWIPSFACTOR)); + // border color + os.write(RtfWriter.escape); + os.write(RtfRow.tableBorderColor); + if (borderColor == null) { + writeInt(os, writer.addColor(new Color(0, 0, 0))); + } else { + writeInt(os, writer.addColor(borderColor)); + } + os.write((byte) '\n'); + } + + + /** + * RtfTables call this method from their own setMerge() to + * specify that a certain other cell is to be merged with it. + * + * @param x The column position of the cell to be merged + * @param mergeType The merge type specifies the kind of merge to be applied + * (MERGE_HORIZ_PREV, MERGE_VERT_PREV, MERGE_BOTH_PREV) + * @param mergeCell The RtfCell that the cell at x and y is to + * be merged with + */ + public void setMerge(int x, int mergeType, RtfCell mergeCell) { + RtfCell cell = (RtfCell) cells.get(x); + cell.setMerge(mergeType, mergeCell); + } + + /* + * Write an Integer to the Outputstream. + * + * @param out The OutputStream to be written to. + * @param i The int to be written. + */ + private void writeInt(ByteArrayOutputStream out, int i) throws IOException { + out.write(Integer.toString(i).getBytes()); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfTOC.java b/src/main/java/com/lowagie/text/rtf/RtfTOC.java new file mode 100644 index 0000000..044a871 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfTOC.java @@ -0,0 +1,187 @@ +/** + * $Id: RtfTOC.java,v 1.23 2006/02/09 17:25:25 hallm Exp $ + * + * Copyright 2002 by + * SMB + * Steffen.Stundzig@smb-tec.com + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the “GNU LIBRARY GENERAL PUBLIC LICENSE”), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import java.io.IOException; +import java.io.OutputStream; + +import com.lowagie.text.Chunk; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Font; +import com.lowagie.text.ExceptionConverter; + +/** + * This class can be used to insert a table of contents into + * the RTF document. + * Therefore the field TOC is used. It works great in Word 2000. + * StarOffice doesn't support such fields. Other word version + * are not tested yet. + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * This class is based on the RtfWriter-package from Mark Hall. + * @author Steffen.Stundzig@smb-tec.com + * @version $Revision: 1.23 $Date: 2006/02/09 17:25:25 $ + * @deprecated Please move to the RtfWriter2 and associated classes. com.lowagie.text.rtf.field.RtfTableOfContents replaces the functionality of this class. + */ +public class RtfTOC extends Chunk implements RtfField { + + + private String defaultText = "Klicken Sie mit der rechten Maustaste auf diesen Text, um das Inhaltsverzeichnis zu aktualisieren!"; + + private boolean addTOCAsTOCEntry = false; + + private Font entryFont = null; + private String entryName = null; + + + /** + * @param tocName the headline of the table of contents + * @param tocFont the font for the headline + */ + public RtfTOC( String tocName, Font tocFont ) { + super( tocName, tocFont ); + } + + /** + * @see com.lowagie.text.rtf.RtfField#write(com.lowagie.text.rtf.RtfWriter, java.io.OutputStream) + */ + public void write( RtfWriter writer, OutputStream out ) throws IOException { + + writer.writeInitialFontSignature( out, this ); + out.write( RtfWriter.filterSpecialChar( content(), true ).getBytes() ); + writer.writeFinishingFontSignature( out, this ); + + if (addTOCAsTOCEntry) { + RtfTOCEntry entry = new RtfTOCEntry( entryName, entryFont ); + entry.hideText(); + try { + writer.add( entry ); + } catch ( DocumentException de ) { + throw new ExceptionConverter(de); + } + } + + // line break after headline + out.write( RtfWriter.escape ); + out.write( RtfWriter.paragraph ); + out.write( RtfWriter.delimiter ); + + // toc field entry + out.write( RtfWriter.openGroup ); + out.write( RtfWriter.escape ); + out.write( RtfWriter.field ); + // field initialization stuff + out.write( RtfWriter.openGroup ); + out.write( RtfWriter.escape ); + out.write( RtfWriter.fieldContent ); + out.write( RtfWriter.delimiter ); + out.write( "TOC".getBytes() ); + // create the TOC based on the 'toc entries' + out.write( RtfWriter.delimiter ); + out.write( RtfWriter.escape ); + out.write( RtfWriter.escape ); + out.write( "f".getBytes() ); + out.write( RtfWriter.delimiter ); + // create Hyperlink TOC Entrie + out.write( RtfWriter.escape ); + out.write( RtfWriter.escape ); + out.write( "h".getBytes() ); + out.write( RtfWriter.delimiter ); + // create the TOC based on the paragraph level + out.write( RtfWriter.delimiter ); + out.write( RtfWriter.escape ); + out.write( RtfWriter.escape ); + out.write( "u".getBytes() ); + out.write( RtfWriter.delimiter ); + // create the TOC based on the paragraph headlines 1-5 + out.write( RtfWriter.delimiter ); + out.write( RtfWriter.escape ); + out.write( RtfWriter.escape ); + out.write( "o".getBytes() ); + out.write( RtfWriter.delimiter ); + out.write( "\"1-5\"".getBytes() ); + out.write( RtfWriter.delimiter ); + out.write( RtfWriter.closeGroup ); + + // field default result stuff + out.write( RtfWriter.openGroup ); + out.write( RtfWriter.escape ); + out.write( RtfWriter.fieldDisplay ); + out.write( RtfWriter.delimiter ); + out.write( defaultText.getBytes() ); + out.write( RtfWriter.delimiter ); + out.write( RtfWriter.closeGroup ); + out.write( RtfWriter.closeGroup ); + } + + + /** + * Add a toc entry + * @param entryName the name of the entry + * @param entryFont the font to be used for the entry + */ + public void addTOCAsTOCEntry( String entryName, Font entryFont ) { + this.addTOCAsTOCEntry = true; + this.entryFont = entryFont; + this.entryName = entryName; + } + + + /** + * Sets the default text of the Table of Contents + * @param text the default text + */ + public void setDefaultText( String text ) { + this.defaultText = text; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfTOCEntry.java b/src/main/java/com/lowagie/text/rtf/RtfTOCEntry.java new file mode 100644 index 0000000..c3ceab1 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfTOCEntry.java @@ -0,0 +1,174 @@ +/** + * $Id: RtfTOCEntry.java,v 1.23 2006/02/09 17:25:26 hallm Exp $ + * + * Copyright 2002 by + * SMB + * Steffen.Stundzig@smb-tec.com + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the “GNU LIBRARY GENERAL PUBLIC LICENSE”), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import java.io.IOException; +import java.io.OutputStream; + +import com.lowagie.text.Chunk; +import com.lowagie.text.Font; + +/** + * This class can be used to insert entries for a table of contents into + * the RTF document. + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * This class is based on the RtfWriter-package from Mark Hall. + * @author Steffen.Stundzig@smb-tec.com + * @version $Revision: 1.23 $Date: 2006/02/09 17:25:26 $ + * @deprecated Please move to the RtfWriter2 and associated classes. com.lowagie.text.rtf.field.RtfTOCEntry replaces the functionality of this class. + */ +public class RtfTOCEntry extends Chunk implements RtfField { + + + private boolean hideText = false; + + private boolean hidePageNumber = false; + + private String entryName; + + private Font entryFont; + + private Font contentFont; + + + /** + * Constructs an entry for the Table of Contents + * @param content the content of the entry + * @param contentFont the font + */ + public RtfTOCEntry( String content, Font contentFont ) { + this( content, contentFont, content, contentFont ); +// super( content, font ); +// this.entryName = content; +// printEntryNameAsText = true; + } + + + /** + * Constructs an entry for the Table of Contents + * @param content the content of the entry + * @param contentFont the font + * @param entryName name of the entry + * @param entryFont font of the entryname + */ + public RtfTOCEntry( String content, Font contentFont, String entryName, Font entryFont ) { + super( content, contentFont ); + // hide the text of the entry, because it is printed + this.entryName = entryName; + this.entryFont = entryFont; + this.contentFont = contentFont; + } + + /** + * @see com.lowagie.text.rtf.RtfField#write(com.lowagie.text.rtf.RtfWriter, java.io.OutputStream) + */ + public void write( RtfWriter writer, OutputStream out ) throws IOException { + + if (!hideText) { + writer.writeInitialFontSignature( out, new Chunk("", contentFont) ); + out.write( RtfWriter.filterSpecialChar( content(), true ).getBytes() ); + writer.writeFinishingFontSignature( out, new Chunk("", contentFont) ); + } + + if (!entryFont.equals( contentFont )) { + writer.writeInitialFontSignature(out, new Chunk("", entryFont) ); + writeField( out ); + writer.writeFinishingFontSignature(out, new Chunk("", entryFont) ); + } else { + writer.writeInitialFontSignature(out, new Chunk("", contentFont) ); + writeField( out ); + writer.writeFinishingFontSignature(out, new Chunk("", contentFont) ); + } + } + + + private void writeField( OutputStream out ) throws IOException { + + // always hide the toc entry + out.write( RtfWriter.openGroup ); + out.write( RtfWriter.escape ); + out.write( "v".getBytes() ); + + // tc field entry + out.write( RtfWriter.openGroup ); + out.write( RtfWriter.escape ); + if (!hidePageNumber) { + out.write( "tc".getBytes() ); + } else { + out.write( "tcn".getBytes() ); + } + out.write( RtfWriter.delimiter ); + out.write( RtfWriter.filterSpecialChar( entryName, true ).getBytes() ); + out.write( RtfWriter.delimiter ); + out.write( RtfWriter.closeGroup ); + + out.write( RtfWriter.closeGroup ); + } + + /** + * sets the hideText value to true + */ + public void hideText() { + hideText = true; + } + + /** + * sets the hidePageNumber value to true + */ + public void hidePageNumber() { + hidePageNumber = true; + } +} + + diff --git a/src/main/java/com/lowagie/text/rtf/RtfTable.java b/src/main/java/com/lowagie/text/rtf/RtfTable.java new file mode 100644 index 0000000..70c403e --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfTable.java @@ -0,0 +1,201 @@ +/** + * $Id: RtfTable.java,v 1.31 2006/02/09 17:25:25 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.*; + +import java.util.ArrayList; +import java.util.Iterator; +import java.io.*; + +/** + * A Helper Class for the RtfWriter. + *

+ * Do not use it directly, except if you want to write a DocumentListener for Rtf + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * + * Parts of this Class were contributed by Steffen Stundzig. Many thanks for the + * improvements. + * Updates Benoit WIART + * @deprecated Please move to the RtfWriter2 and associated classes. + */ +public class RtfTable { + /** Stores the different rows. */ + private ArrayList rowsList = new ArrayList(); + /** Stores the RtfWriter, which created this RtfTable. */ + private RtfWriter writer = null; + /** Stores the Table, which this RtfTable is based on. */ + private Table origTable = null; + + + + /** + * Create a new RtfTable. + * + * @param writer The RtfWriter that created this Table + */ + public RtfTable(RtfWriter writer) { + super(); + this.writer = writer; + } + + /** + * Import a Table into the RtfTable. + *

+ * @param table A Table specifying the Table to be imported + * @param pageWidth An int specifying the page width + * @return true if importing the table succeeded + */ + public boolean importTable(Table table, int pageWidth) { + origTable = table; + // All Cells are pregenerated first, so that cell and rowspanning work + Iterator rows = table.iterator(); + Row row = null; + + int tableWidth = (int) table.widthPercentage(); + int cellpadding = (int) (table.cellpadding() * RtfWriter.TWIPSFACTOR); + int cellspacing = (int) (table.cellspacing() * RtfWriter.TWIPSFACTOR); + float[] propWidths = table.getProportionalWidths(); + + int borders = table.border(); + java.awt.Color borderColor = table.borderColor(); + float borderWidth = table.borderWidth(); + + for (int i = 0; i < table.size(); i++) { + RtfRow rtfRow = new RtfRow(writer, this); + rtfRow.pregenerateRows(table.columns()); + rowsList.add(rtfRow); + } + int i = 0; + while (rows.hasNext()) { + row = (Row) rows.next(); + row.setHorizontalAlignment(table.alignment()); + RtfRow rtfRow = (RtfRow) rowsList.get(i); + rtfRow.importRow(row, propWidths, tableWidth, pageWidth, cellpadding, cellspacing, borders, borderColor, borderWidth, i); + i++; + } + return true; + } + + /** + * Output the content of the RtfTable to an OutputStream. + * + * @param os The OutputStream that the content of the RtfTable is to be written to + * @return true if writing the table succeeded + * @throws DocumentException + * @throws IOException + */ + public boolean writeTable(ByteArrayOutputStream os) throws DocumentException, IOException { + + if(!this.writer.writingHeaderFooter()) { + // Added by Benoit WIART + // Add a new line before each table + os.write(RtfWriter.escape); + os.write(RtfWriter.paragraph); + } + + int size = rowsList.size(); + for (int i = 0; i < size; i++) { + RtfRow row = (RtfRow) rowsList.get(i); + row.writeRow(os, i, origTable); + os.write((byte) '\n'); + } + if (!writer.writingHeaderFooter()) { + os.write(RtfWriter.escape); + os.write(RtfWriter.paragraphDefaults); + os.write(RtfWriter.escape); + os.write(RtfWriter.paragraph); + switch (origTable.alignment()) { + case Element.ALIGN_LEFT: + os.write(RtfWriter.escape); + os.write(RtfWriter.alignLeft); + break; + case Element.ALIGN_RIGHT: + os.write(RtfWriter.escape); + os.write(RtfWriter.alignRight); + break; + case Element.ALIGN_CENTER: + os.write(RtfWriter.escape); + os.write(RtfWriter.alignCenter); + break; + case Element.ALIGN_JUSTIFIED: + case Element.ALIGN_JUSTIFIED_ALL: + os.write(RtfWriter.escape); + os.write(RtfWriter.alignJustify); + break; + } + } + return true; + } + + /** + * RtfCells call this method to specify that a certain other cell is to be merged with it. + * + * @param x The column position of the cell to be merged + * @param y The row position of the cell to be merged + * @param mergeType The merge type specifies the kind of merge to be applied (MERGE_HORIZ_PREV, MERGE_VERT_PREV, MERGE_BOTH_PREV) + * @param mergeCell The RtfCell that the cell at x and y is to be merged with + */ + public void setMerge(int x, int y, int mergeType, RtfCell mergeCell) { + RtfRow row = (RtfRow) rowsList.get(y); + row.setMerge(x, mergeType, mergeCell); + } + + /** + * This method allows access to the original Table that led to this RtfTable. + * + * @return The Table object that is the basis of this RtfTable. + */ + protected Table getOriginalTable() { + return origTable; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfTableCell.java b/src/main/java/com/lowagie/text/rtf/RtfTableCell.java new file mode 100644 index 0000000..1d9b220 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfTableCell.java @@ -0,0 +1,392 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.Cell; +import com.lowagie.text.Element; +import com.lowagie.text.BadElementException; + +import java.util.Properties; + +/** + * A Cell with extended style attributes + * + * ONLY FOR USE WITH THE RtfWriter NOT with the RtfWriter2. + * @deprecated Please move to the RtfWriter2 and associated classes. com.lowagie.text.rtf.table.RtfCell replaces the functionality of this class. + */ +public class RtfTableCell extends Cell +{ + /* Table border styles */ + + /** Table border solid */ + public static final int BORDER_UNDEFINED = 0; + + /** Table border solid */ + public static final int BORDER_SINGLE = 1; + + /** Table border double thickness */ + public static final int BORDER_DOUBLE_THICK = 2; + + /** Table border shadowed */ + public static final int BORDER_SHADOWED = 3; + + /** Table border dotted */ + public static final int BORDER_DOTTED = 4; + + /** Table border dashed */ + public static final int BORDER_DASHED = 5; + + /** Table border hairline */ + public static final int BORDER_HAIRLINE = 6; + + /** Table border double line */ + public static final int BORDER_DOUBLE = 7; + + /** Table border dot dash line */ + public static final int BORDER_DOT_DASH = 8; + + /** Table border dot dot dash line */ + public static final int BORDER_DOT_DOT_DASH = 9; + + /** Table border triple line */ + public static final int BORDER_TRIPLE = 10; + + /** Table border line */ + public static final int BORDER_THICK_THIN = 11; + + /** Table border line */ + public static final int BORDER_THIN_THICK = 12; + + /** Table border line */ + public static final int BORDER_THIN_THICK_THIN = 13; + + /** Table border line */ + public static final int BORDER_THICK_THIN_MED = 14; + + /** Table border line */ + public static final int BORDER_THIN_THICK_MED = 15; + + /** Table border line */ + public static final int BORDER_THIN_THICK_THIN_MED = 16; + + /** Table border line */ + public static final int BORDER_THICK_THIN_LARGE = 17; + + /** Table border line */ + public static final int BORDER_THIN_THICK_LARGE = 18; + + /** Table border line */ + public static final int BORDER_THIN_THICK_THIN_LARGE = 19; + + /** Table border line */ + public static final int BORDER_WAVY = 20; + + /** Table border line */ + public static final int BORDER_DOUBLE_WAVY = 21; + + /** Table border line */ + public static final int BORDER_STRIPED = 22; + + /** Table border line */ + public static final int BORDER_EMBOSS = 23; + + /** Table border line */ + public static final int BORDER_ENGRAVE = 24; + + /* Instance variables */ + private float topBorderWidth; + private float leftBorderWidth; + private float rightBorderWidth; + private float bottomBorderWidth; + private int topBorderStyle = 1; + private int leftBorderStyle = 1; + private int rightBorderStyle = 1; + private int bottomBorderStyle = 1; + +/** + * Constructs an empty Cell (for internal use only). + * + * @param dummy a dummy value + */ + + public RtfTableCell(boolean dummy) { + super(dummy); + } + +/** + * Constructs a Cell with a certain Element. + *

+ * if the element is a ListItem, Row or + * Cell, an exception will be thrown. + * + * @param element the element + * @throws BadElementException when the creator was called with a ListItem, Row or Cell + */ + public RtfTableCell(Element element) throws BadElementException { + super(element); + } + +/** + * Constructs a Cell with a certain content. + *

+ * The String will be converted into a Paragraph. + * + * @param content a String + */ + public RtfTableCell(String content) { + super(content); + } + +/** + * Returns a Cell that has been constructed taking in account + * the value of some attributes. + * + * @param attributes Some attributes + */ + + public RtfTableCell(Properties attributes) { + super(attributes); + } + + /** + * Set all four borders to f width + * + * @param f the desired width + */ + public void setBorderWidth(float f) { + super.setBorderWidth(f); + topBorderWidth = f; + leftBorderWidth = f; + rightBorderWidth = f; + bottomBorderWidth = f; + } + + /** + * Set the top border to f width + * + * @param f the desired width + */ + public void setTopBorderWidth(float f) { + topBorderWidth = f; + } + + /** + * Get the top border width + * @return a width + */ + public float topBorderWidth() { + return topBorderWidth; + } + + /** + * Set the left border to f width + * + * @param f the desired width + */ + public void setLeftBorderWidth(float f) { + leftBorderWidth = f; + } + + /** + * Get the left border width + * @return a width + */ + public float leftBorderWidth() { + return leftBorderWidth; + } + + /** + * Set the right border to f width + * + * @param f the desired width + */ + public void setRightBorderWidth(float f) { + rightBorderWidth = f; + } + + /** + * Get the right border width + * @return a width + */ + public float rightBorderWidth() { + return rightBorderWidth; + } + + /** + * Set the bottom border to f width + * + * @param f the desired width + */ + public void setBottomBorderWidth(float f) { + bottomBorderWidth = f; + } + + /** + * Get the bottom border width + * @return a width + */ + public float bottomBorderWidth() { + return bottomBorderWidth; + } + + /** + * Set all four borders to style defined by style + * + * @param style the desired style + */ + public void setBorderStyle(int style) { + topBorderStyle = style; + leftBorderStyle = style; + rightBorderStyle = style; + bottomBorderStyle = style; + } + + /** + * Set the top border to style defined by style + * + * @param style the desired style + */ + public void setTopBorderStyle(int style) { + topBorderStyle = style; + } + + /** + * Get the top border style + * @return a style value + */ + public int topBorderStyle() { + return topBorderStyle; + } + + /** + * Set the left border to style defined by style + * + * @param style the desired style + */ + public void setLeftBorderStyle(int style) { + leftBorderStyle = style; + } + + /** + * Get the left border style + * @return a style value + */ + public int leftBorderStyle() { + return leftBorderStyle; + } + + /** + * Set the right border to style defined by style + * + * @param style the desired style + */ + public void setRightBorderStyle(int style) { + rightBorderStyle = style; + } + + /** + * Get the right border style + * @return a style value + */ + public int rightBorderStyle() { + return rightBorderStyle; + } + + /** + * Set the bottom border to style defined by style + * + * @param style the desired style + */ + public void setBottomBorderStyle(int style) { + bottomBorderStyle = style; + } + + /** + * Get the bottom border style + * @return a style value + */ + public int bottomBorderStyle() { + return bottomBorderStyle; + } + + /** + * Get the RTF control word for style + * @param style a style value + * @return a byte array corresponding with a style control word + */ + protected static byte[] getStyleControlWord(int style) { + switch(style) + { + case BORDER_UNDEFINED : return "brdrs".getBytes(); + case BORDER_SINGLE : return "brdrs".getBytes(); + case BORDER_DOUBLE_THICK : return "brdrth".getBytes(); + case BORDER_SHADOWED : return "brdrsh".getBytes(); + case BORDER_DOTTED : return "brdrdot".getBytes(); + case BORDER_DASHED : return "brdrdash".getBytes(); + case BORDER_HAIRLINE : return "brdrhair".getBytes(); + case BORDER_DOUBLE : return "brdrdb".getBytes(); + case BORDER_DOT_DASH : return "brdrdashd".getBytes(); + case BORDER_DOT_DOT_DASH : return "brdrdashdd".getBytes(); + case BORDER_TRIPLE : return "brdrtriple".getBytes(); + case BORDER_THICK_THIN : return "brdrtnthsg".getBytes(); + case BORDER_THIN_THICK : return "brdrthtnsg".getBytes(); + case BORDER_THIN_THICK_THIN : return "brdrtnthtnsg".getBytes(); + case BORDER_THICK_THIN_MED : return "brdrtnthmg".getBytes(); + case BORDER_THIN_THICK_MED : return "brdrthtnmg".getBytes(); + case BORDER_THIN_THICK_THIN_MED : return "brdrtnthtnmg".getBytes(); + case BORDER_THICK_THIN_LARGE : return "brdrtnthlg".getBytes(); + case BORDER_THIN_THICK_LARGE : return "brdrthtnlg".getBytes(); + case BORDER_THIN_THICK_THIN_LARGE : return "brdrtnthtnlg".getBytes(); + case BORDER_WAVY : return "brdrwavy".getBytes(); + case BORDER_DOUBLE_WAVY : return "brdrwavydb".getBytes(); + case BORDER_STRIPED : return "brdrdashdotstr".getBytes(); + case BORDER_EMBOSS : return "brdremboss".getBytes(); + case BORDER_ENGRAVE : return "brdrengrave".getBytes(); + } + + return "brdrs".getBytes(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/RtfWriter.java b/src/main/java/com/lowagie/text/rtf/RtfWriter.java new file mode 100644 index 0000000..43b47da --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfWriter.java @@ -0,0 +1,2299 @@ +/* + * $Id: RtfWriter.java,v 1.70 2006/02/09 17:25:25 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.*; + +import java.io.*; +import java.util.ArrayList; +import java.util.ListIterator; +import java.util.Iterator; +import java.util.Calendar; +import java.util.Date; +import java.awt.Color; +import java.text.SimpleDateFormat; +import java.text.ParsePosition; +import com.lowagie.text.pdf.codec.wmf.MetaDo; + +/** + * If you are creating a new project using the rtf part of iText, please + * consider using the new RtfWriter2. The RtfWriter is in bug-fix-only mode, + * will be deprecated end of 2005 and removed end of 2007. + * + * A DocWriter class for Rich Text Files (RTF). + *

+ * A RtfWriter can be added as a DocListener + * to a certain Document by getting an instance. + * Every Element added to the original Document + * will be written to the OutputStream of this RtfWriter. + *

+ * Example: + *

+ * // creation of the document with a certain size and certain margins
+ * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
+ * try {
+ *    // this will write RTF to the Standard OutputStream
+ *    RtfWriter.getInstance(document, System.out);
+ *    // this will write Rtf to a file called text.rtf
+ *    RtfWriter.getInstance(document, new FileOutputStream("text.rtf"));
+ *    // this will write Rtf to for instance the OutputStream of a HttpServletResponse-object
+ *    RtfWriter.getInstance(document, response.getOutputStream());
+ * }
+ * catch(DocumentException de) {
+ *    System.err.println(de.getMessage());
+ * }
+ * // this will close the document and all the OutputStreams listening to it
+ * document.close();
+ * 
+ *

+ * LIMITATIONS
+ * There are currently still a few limitations on what the RTF Writer can do: + *

+ *
+ * + * @author Mark.Hall@myrealbox.com + * @author Steffen Stundzig + * @author Eric Mattes + * @author Raul Wegmann + * @deprecated The RtfWriter is deprecated and will be removed from the iText library end of 2007 + */ +public class RtfWriter extends DocWriter implements DocListener { + /** + * Static Constants + */ + + /** + * General + */ + + /** This is the escape character which introduces RTF tags. */ + public static final byte escape = (byte) '\\'; + + /** This is another escape character which introduces RTF tags. */ + private static final byte[] extendedEscape = "\\*\\".getBytes(); + + /** This is the delimiter between RTF tags and normal text. */ + protected static final byte delimiter = (byte) ' '; + + /** This is another delimiter between RTF tags and normal text. */ + private static final byte commaDelimiter = (byte) ';'; + + /** This is the character for beginning a new group. */ + public static final byte openGroup = (byte) '{'; + + /** This is the character for closing a group. */ + public static final byte closeGroup = (byte) '}'; + + /** + * RTF Information + */ + + /** RTF begin and version. */ + private static final byte[] docBegin = "rtf1".getBytes(); + + /** RTF encoding. */ + private static final byte[] ansi = "ansi".getBytes(); + + /** RTF encoding codepage. */ + private static final byte[] ansiCodepage = "ansicpg".getBytes(); + + /** + *Font Data + */ + + /** Begin the font table tag. */ + private static final byte[] fontTable = "fonttbl".getBytes(); + + /** Font number tag. */ + protected static final byte fontNumber = (byte) 'f'; + + /** Font size tag. */ + protected static final byte[] fontSize = "fs".getBytes(); + + /** Font color tag. */ + protected static final byte[] fontColor = "cf".getBytes(); + + /** Modern font tag. */ + private static final byte[] fontModern = "fmodern".getBytes(); + + /** Swiss font tag. */ + private static final byte[] fontSwiss = "fswiss".getBytes(); + + /** Roman font tag. */ + private static final byte[] fontRoman = "froman".getBytes(); + + /** Tech font tag. */ + private static final byte[] fontTech = "ftech".getBytes(); + + /** Font charset tag. */ + private static final byte[] fontCharset = "fcharset".getBytes(); + + /** Font Courier tag. */ + private static final byte[] fontCourier = "Courier".getBytes(); + + /** Font Arial tag. */ + private static final byte[] fontArial = "Arial".getBytes(); + + /** Font Symbol tag. */ + private static final byte[] fontSymbol = "Symbol".getBytes(); + + /** Font Times New Roman tag. */ + private static final byte[] fontTimesNewRoman = "Times New Roman".getBytes(); + + /** Font Windings tag. */ + private static final byte[] fontWindings = "Windings".getBytes(); + + /** Default Font. */ + private static final byte[] defaultFont = "deff".getBytes(); + + /** First indent tag. */ + private static final byte[] firstIndent = "fi".getBytes(); + + /** Left indent tag. */ + private static final byte[] listIndent = "li".getBytes(); + + /** Right indent tag. */ + private static final byte[] rightIndent = "ri".getBytes(); + + /** + * Sections / Paragraphs + */ + + /** Reset section defaults tag. */ + private static final byte[] sectionDefaults = "sectd".getBytes(); + + /** Begin new section tag. */ + private static final byte[] section = "sect".getBytes(); + + /** Reset paragraph defaults tag. */ + public static final byte[] paragraphDefaults = "pard".getBytes(); + + /** Begin new paragraph tag. */ + public static final byte[] paragraph = "par".getBytes(); + + /** Page width of a section. */ + public static final byte[] sectionPageWidth = "pgwsxn".getBytes(); + + /** Page height of a section. */ + public static final byte[] sectionPageHeight = "pghsxn".getBytes(); + + /** + * Lists + */ + + /** Begin the List Table */ + private static final byte[] listtableGroup = "listtable".getBytes(); + + /** Begin the List Override Table */ + private static final byte[] listoverridetableGroup = "listoverridetable".getBytes(); + + /** Begin a List definition */ + private static final byte[] listDefinition = "list".getBytes(); + + /** List Template ID */ + private static final byte[] listTemplateID = "listtemplateid".getBytes(); + + /** RTF Writer outputs hybrid lists */ + private static final byte[] hybridList = "hybrid".getBytes(); + + /** Current List level */ + private static final byte[] listLevelDefinition = "listlevel".getBytes(); + + /** Level numbering (old) */ + private static final byte[] listLevelTypeOld = "levelnfc".getBytes(); + + /** Level numbering (new) */ + private static final byte[] listLevelTypeNew = "levelnfcn".getBytes(); + + /** Level alignment (old) */ + private static final byte[] listLevelAlignOld = "leveljc".getBytes(); + + /** Level alignment (new) */ + private static final byte[] listLevelAlignNew = "leveljcn".getBytes(); + + /** Level starting number */ + private static final byte[] listLevelStartAt = "levelstartat".getBytes(); + + /** Level text group */ + private static final byte[] listLevelTextDefinition = "leveltext".getBytes(); + + /** Filler for Level Text Length */ + private static final byte[] listLevelTextLength = "\'0".getBytes(); + + /** Level Text Numbering Style */ + private static final byte[] listLevelTextStyleNumbers = "\'00.".getBytes(); + + /** Level Text Bullet Style */ + private static final byte[] listLevelTextStyleBullet = "u-3913 ?".getBytes(); + + /** Level Numbers Definition */ + private static final byte[] listLevelNumbersDefinition = "levelnumbers".getBytes(); + + /** Filler for Level Numbers */ + private static final byte[] listLevelNumbers = "\\'0".getBytes(); + + /** Tab Stop */ + private static final byte[] tabStop = "tx".getBytes(); + + /** Actual list begin */ + private static final byte[] listBegin = "ls".getBytes(); + + /** Current list level */ + private static final byte[] listCurrentLevel = "ilvl".getBytes(); + + /** List text group for older browsers */ + private static final byte[] listTextOld = "listtext".getBytes(); + + /** Tab */ + private static final byte[] tab = "tab".getBytes(); + + /** Old Bullet Style */ + private static final byte[] listBulletOld = "\'b7".getBytes(); + + /** Current List ID */ + private static final byte[] listID = "listid".getBytes(); + + /** List override */ + private static final byte[] listOverride = "listoverride".getBytes(); + + /** Number of overrides */ + private static final byte[] listOverrideCount = "listoverridecount".getBytes(); + + /** + * Text Style + */ + + /** Bold tag. */ + protected static final byte bold = (byte) 'b'; + + /** Italic tag. */ + protected static final byte italic = (byte) 'i'; + + /** Underline tag. */ + protected static final byte[] underline = "ul".getBytes(); + + /** Strikethrough tag. */ + protected static final byte[] strikethrough = "strike".getBytes(); + + /** Text alignment left tag. */ + public static final byte[] alignLeft = "ql".getBytes(); + + /** Text alignment center tag. */ + public static final byte[] alignCenter = "qc".getBytes(); + + /** Text alignment right tag. */ + public static final byte[] alignRight = "qr".getBytes(); + + /** Text alignment justify tag. */ + public static final byte[] alignJustify = "qj".getBytes(); + + /** + * Colors + */ + + /** Begin colour table tag. */ + private static final byte[] colorTable = "colortbl".getBytes(); + + /** Red value tag. */ + private static final byte[] colorRed = "red".getBytes(); + + /** Green value tag. */ + private static final byte[] colorGreen = "green".getBytes(); + + /** Blue value tag. */ + private static final byte[] colorBlue = "blue".getBytes(); + + /** + * Information Group + */ + + /** Begin the info group tag.*/ + private static final byte[] infoBegin = "info".getBytes(); + + /** Author tag. */ + private static final byte[] metaAuthor = "author".getBytes(); + + /** Subject tag. */ + private static final byte[] metaSubject = "subject".getBytes(); + + /** Keywords tag. */ + private static final byte[] metaKeywords = "keywords".getBytes(); + + /** Title tag. */ + private static final byte[] metaTitle = "title".getBytes(); + + /** Producer tag. */ + private static final byte[] metaProducer = "operator".getBytes(); + + /** Creation Date tag. */ + private static final byte[] metaCreationDate = "creationdate".getBytes(); + + /** Year tag. */ + private static final byte[] year = "yr".getBytes(); + + /** Month tag. */ + private static final byte[] month = "mo".getBytes(); + + /** Day tag. */ + private static final byte[] day = "dy".getBytes(); + + /** Hour tag. */ + private static final byte[] hour = "hr".getBytes(); + + /** Minute tag. */ + private static final byte[] minute = "min".getBytes(); + + /** Second tag. */ + private static final byte[] second = "sec".getBytes(); + + /** Start superscript. */ + private static final byte[] startSuper = "super".getBytes(); + + /** Start subscript. */ + private static final byte[] startSub = "sub".getBytes(); + + /** End super/sub script. */ + private static final byte[] endSuperSub = "nosupersub".getBytes(); + + /** + * Header / Footer + */ + + /** Title Page tag */ + private static final byte[] titlePage = "titlepg".getBytes(); + + /** Facing pages tag */ + private static final byte[] facingPages = "facingp".getBytes(); + + /** Begin header group tag. */ + private static final byte[] headerBegin = "header".getBytes(); + + /** Begin footer group tag. */ + private static final byte[] footerBegin = "footer".getBytes(); + + // header footer 'left', 'right', 'first' + private static final byte[] headerlBegin = "headerl".getBytes(); + + private static final byte[] footerlBegin = "footerl".getBytes(); + + private static final byte[] headerrBegin = "headerr".getBytes(); + + private static final byte[] footerrBegin = "footerr".getBytes(); + + private static final byte[] headerfBegin = "headerf".getBytes(); + + private static final byte[] footerfBegin = "footerf".getBytes(); + + /** + * Paper Properties + */ + + /** Paper width tag. */ + private static final byte[] rtfPaperWidth = "paperw".getBytes(); + + /** Paper height tag. */ + private static final byte[] rtfPaperHeight = "paperh".getBytes(); + + /** Margin left tag. */ + private static final byte[] rtfMarginLeft = "margl".getBytes(); + + /** Margin right tag. */ + private static final byte[] rtfMarginRight = "margr".getBytes(); + + /** Margin top tag. */ + private static final byte[] rtfMarginTop = "margt".getBytes(); + + /** Margin bottom tag. */ + private static final byte[] rtfMarginBottom = "margb".getBytes(); + + /** New Page tag. */ + private static final byte[] newPage = "page".getBytes(); + + /** Document Landscape tag 1. */ + private static final byte[] landscapeTag1 = "landscape".getBytes(); + + /** Document Landscape tag 2. */ + private static final byte[] landscapeTag2 = "lndscpsxn".getBytes(); + + /** + * Annotations + */ + + /** Annotation ID tag. */ + private static final byte[] annotationID = "atnid".getBytes(); + + /** Annotation Author tag. */ + private static final byte[] annotationAuthor = "atnauthor".getBytes(); + + /** Annotation text tag. */ + private static final byte[] annotation = "annotation".getBytes(); + + /** + * Images + */ + + /** Begin the main Picture group tag */ + private static final byte[] pictureGroup = "shppict".getBytes(); + + /** Begin the picture tag */ + private static final byte[] picture = "pict".getBytes(); + + /** PNG Image */ + private static final byte[] picturePNG = "pngblip".getBytes(); + + /** JPEG Image */ + private static final byte[] pictureJPEG = "jpegblip".getBytes(); + + /** BMP Image */ + private static final byte[] pictureBMP = "dibitmap0".getBytes(); + + /** WMF Image */ + private static final byte[] pictureWMF = "wmetafile8".getBytes(); + + /** Picture width */ + private static final byte[] pictureWidth = "picw".getBytes(); + + /** Picture height */ + private static final byte[] pictureHeight = "pich".getBytes(); + + /** Picture scale horizontal percent */ + private static final byte[] pictureScaleX = "picscalex".getBytes(); + + /** Picture scale vertical percent */ + private static final byte[] pictureScaleY = "picscaley".getBytes(); + + /** + * Fields (for page numbering) + */ + + /** Begin field tag */ + protected static final byte[] field = "field".getBytes(); + + /** Content fo the field */ + protected static final byte[] fieldContent = "fldinst".getBytes(); + + /** PAGE numbers */ + protected static final byte[] fieldPage = "PAGE".getBytes(); + + /** HYPERLINK field */ + protected static final byte[] fieldHyperlink = "HYPERLINK".getBytes(); + + /** Last page number (not used) */ + protected static final byte[] fieldDisplay = "fldrslt".getBytes(); + + + /** Class variables */ + + /** + * Because of the way RTF works and the way itext works, the text has to be + * stored and is only written to the actual OutputStream at the end. + */ + + /** This ArrayList contains all fonts used in the document. */ + private ArrayList fontList = new ArrayList(); + + /** This ArrayList contains all colours used in the document. */ + private ArrayList colorList = new ArrayList(); + + /** This ByteArrayOutputStream contains the main body of the document. */ + private ByteArrayOutputStream content = null; + + /** This ByteArrayOutputStream contains the information group. */ + private ByteArrayOutputStream info = null; + + /** This ByteArrayOutputStream contains the list table. */ + private ByteArrayOutputStream listtable = null; + + /** This ByteArrayOutputStream contains the list override table. */ + private ByteArrayOutputStream listoverride = null; + + /** Document header. */ + private HeaderFooter header = null; + + /** Document footer. */ + private HeaderFooter footer = null; + + /** Left margin. */ + private int marginLeft = 1800; + + /** Right margin. */ + private int marginRight = 1800; + + /** Top margin. */ + private int marginTop = 1440; + + /** Bottom margin. */ + private int marginBottom = 1440; + + /** Page width. */ + private int pageWidth = 11906; + + /** Page height. */ + private int pageHeight = 16838; + + /** Factor to use when converting. */ + public final static double TWIPSFACTOR = 20;//20.57140; + + /** Current list ID. */ + private int currentListID = 1; + + /** List of current Lists. */ + private ArrayList listIds = null; + + /** Current List Level. */ + private int listLevel = 0; + + /** Current maximum List Level. */ + private int maxListLevel = 0; + + /** Write a TOC */ + private boolean writeTOC = false; + + /** Special title page */ + private boolean hasTitlePage = false; + + /** Currently writing either Header or Footer */ + private boolean inHeaderFooter = false; + + /** Currently writing a Table */ + private boolean inTable = false; + + /** Landscape or Portrait Document */ + private boolean landscape = false; + + /** Protected Constructor */ + + /** + * Constructs a RtfWriter. + * + * @param doc The Document that is to be written as RTF + * @param os The OutputStream the writer has to write to. + */ + + protected RtfWriter(Document doc, OutputStream os) { + super(doc, os); + document.addDocListener(this); + initDefaults(); + } + + /** Public functions special to the RtfWriter */ + + /** + * This method controls whether TOC entries are automatically generated + * + * @param writeTOC boolean value indicating whether a TOC is to be generated + */ + public void setGenerateTOCEntries(boolean writeTOC) { + this.writeTOC = writeTOC; + } + + /** + * Gets the current setting of writeTOC + * + * @return boolean value indicating whether a TOC is being generated + */ + public boolean getGeneratingTOCEntries() { + return writeTOC; + } + + /** + * This method controls whether the first page is a title page + * + * @param hasTitlePage boolean value indicating whether the first page is a title page + */ + public void setHasTitlePage(boolean hasTitlePage) { + this.hasTitlePage = hasTitlePage; + } + + /** + * Gets the current setting of hasTitlePage + * + * @return boolean value indicating whether the first page is a title page + */ + public boolean getHasTitlePage() { + return hasTitlePage; + } + + /** + * Explicitly sets the page format to use. + * Otherwise the RtfWriter will try to guess the format by comparing pagewidth and pageheight + * + * @param landscape boolean value indicating whether we are using landscape format or not + */ + public void setLandscape(boolean landscape) { + this.landscape = landscape; + } + + /** + * Returns the current landscape setting + * + * @return boolean value indicating the current page format + */ + public boolean getLandscape() { + return landscape; + } + + /** Public functions from the DocWriter Interface */ + + /** + * Gets an instance of the RtfWriter. + * + * @param document The Document that has to be written + * @param os The OutputStream the writer has to write to. + * @return a new RtfWriter + */ + public static RtfWriter getInstance(Document document, OutputStream os) { + return (new RtfWriter(document, os)); + } + + /** + * Signals that the Document has been opened and that + * Elements can be added. + */ + public void open() { + super.open(); + } + + /** + * Signals that the Document was closed and that no other + * Elements will be added. + *

+ * The content of the font table, color table, information group, content, header, footer are merged into the final + * OutputStream + */ + public void close() { + writeDocument(); + super.close(); + } + + /** + * Adds the footer to the bottom of the Document. + * @param footer + */ + public void setFooter(HeaderFooter footer) { + this.footer = footer; + processHeaderFooter(this.footer); + } + + /** + * Adds the header to the top of the Document. + * @param header + */ + public void setHeader(HeaderFooter header) { + this.header = header; + processHeaderFooter(this.header); + } + + /** + * Resets the footer. + */ + public void resetFooter() { + setFooter(null); + } + + /** + * Resets the header. + */ + public void resetHeader() { + setHeader(null); + } + + /** + * Tells the RtfWriter that a new page is to be begun. + * + * @return true if a new Page was begun. + * @throws DocumentException if the Document was not open or had been closed. + */ + public boolean newPage() throws DocumentException { + try { + content.write(escape); + content.write(newPage); + content.write(escape); + content.write(paragraph); + } catch (IOException e) { + return false; + } + return true; + } + + /** + * Sets the page margins + * + * @param marginLeft The left margin + * @param marginRight The right margin + * @param marginTop The top margin + * @param marginBottom The bottom margin + * + * @return true if the page margins were set. + */ + public boolean setMargins(float marginLeft, float marginRight, float marginTop, float marginBottom) { + this.marginLeft = (int) (marginLeft * TWIPSFACTOR); + this.marginRight = (int) (marginRight * TWIPSFACTOR); + this.marginTop = (int) (marginTop * TWIPSFACTOR); + this.marginBottom = (int) (marginBottom * TWIPSFACTOR); + return true; + } + + /** + * Sets the page size + * + * @param pageSize A Rectangle specifying the page size + * + * @return true if the page size was set + */ + public boolean setPageSize(Rectangle pageSize) { + if (!parseFormat(pageSize, false)) { + pageWidth = (int) (pageSize.width() * TWIPSFACTOR); + pageHeight = (int) (pageSize.height() * TWIPSFACTOR); + landscape = pageWidth > pageHeight; + } + return true; + } + + /** + * Write the table of contents. + * + * @param tocTitle The title that will be displayed above the TOC + * @param titleFont The Font that will be used for the tocTitle + * @param showTOCasEntry Set this to true if you want the TOC to appear as an entry in the TOC + * @param showTOCEntryFont Use this Font to specify what Font to use when showTOCasEntry is true + * + * @return true if the TOC was added. + */ + public boolean writeTOC(String tocTitle, Font titleFont, boolean showTOCasEntry, Font showTOCEntryFont) { + try { + RtfTOC toc = new RtfTOC(tocTitle, titleFont); + if (showTOCasEntry) { + toc.addTOCAsTOCEntry(tocTitle, showTOCEntryFont); + } + add(new Paragraph(toc)); + } catch (DocumentException de) { + return false; + } + return true; + } + + /** + * Signals that an Element was added to the Document. + * + * @param element A high level object to add + * @return true if the element was added, false if not. + * @throws DocumentException if a document isn't open yet, or has been closed + */ + public boolean add(Element element) throws DocumentException { + if (pause) { + return false; + } + return addElement(element, content); + } + + + /** Private functions */ + + /** + * Adds an Element to the Document. + * @param element the high level element to add + * @param out the outputstream to which the RTF data is sent + * @return true if the element was added, false if not. + * @throws DocumentException if a document isn't open yet, or has been closed + */ + protected boolean addElement(Element element, ByteArrayOutputStream out) throws DocumentException { + try { + switch (element.type()) { + case Element.CHUNK: + writeChunk((Chunk) element, out); + break; + case Element.PARAGRAPH: + writeParagraph((Paragraph) element, out); + break; + case Element.ANCHOR: + writeAnchor((Anchor) element, out); + break; + case Element.PHRASE: + writePhrase((Phrase) element, out); + break; + case Element.CHAPTER: + case Element.SECTION: + writeSection((Section) element, out); + break; + case Element.LIST: + writeList((com.lowagie.text.List) element, out); + break; + case Element.TABLE: + try { + writeTable((Table) element, out); + } + catch(ClassCastException cce) { + writeTable(((SimpleTable)element).createTable(), out); + } + break; + case Element.ANNOTATION: + writeAnnotation((Annotation) element, out); + break; + case Element.IMGRAW: + case Element.IMGTEMPLATE: + case Element.JPEG: + Image img = (Image)element; + writeImage(img, out); + break; + + case Element.AUTHOR: + writeMeta(metaAuthor, (Meta) element); + break; + case Element.SUBJECT: + writeMeta(metaSubject, (Meta) element); + break; + case Element.KEYWORDS: + writeMeta(metaKeywords, (Meta) element); + break; + case Element.TITLE: + writeMeta(metaTitle, (Meta) element); + break; + case Element.PRODUCER: + writeMeta(metaProducer, (Meta) element); + break; + case Element.CREATIONDATE: + writeMeta(metaCreationDate, (Meta) element); + break; + } + } catch (IOException e) { + return false; + } + return true; + } + + /** + * Write the beginning of a new Section + * + * @param sectionElement The Section be written + * @param out The ByteArrayOutputStream to write to + * + * @throws IOException + * @throws DocumentException + */ + private void writeSection(Section sectionElement, ByteArrayOutputStream out) throws IOException, DocumentException { + if (sectionElement.type() == Element.CHAPTER) { + out.write(escape); + out.write(sectionDefaults); + writeSectionDefaults(out); + } + if (sectionElement.title() != null) { + if (writeTOC) { + StringBuffer title = new StringBuffer(""); + for (ListIterator li = sectionElement.title().getChunks().listIterator(); li.hasNext();) { + title.append(((Chunk) li.next()).content()); + } + add(new RtfTOCEntry(title.toString(), sectionElement.title().font())); + } else { + add(sectionElement.title()); + } + out.write(escape); + out.write(paragraph); + } + sectionElement.process(this); + if (sectionElement.type() == Element.CHAPTER) { + out.write(escape); + out.write(section); + } + if (sectionElement.type() == Element.SECTION) { + out.write(escape); + out.write(paragraph); + } + } + + /** + * Write the beginning of a new Paragraph + * + * @param paragraphElement The Paragraph to be written + * @param out The ByteArrayOutputStream to write to + * + * @throws IOException + */ + private void writeParagraph(Paragraph paragraphElement, ByteArrayOutputStream out) throws IOException { + out.write(escape); + out.write(paragraphDefaults); + if (inTable) { + out.write(escape); + out.write(RtfCell.cellInTable); + } + switch (paragraphElement.alignment()) { + case Element.ALIGN_LEFT: + out.write(escape); + out.write(alignLeft); + break; + case Element.ALIGN_RIGHT: + out.write(escape); + out.write(alignRight); + break; + case Element.ALIGN_CENTER: + out.write(escape); + out.write(alignCenter); + break; + case Element.ALIGN_JUSTIFIED: + case Element.ALIGN_JUSTIFIED_ALL: + out.write(escape); + out.write(alignJustify); + break; + } + out.write(escape); + out.write(listIndent); + writeInt(out, (int) (paragraphElement.indentationLeft() * TWIPSFACTOR)); + out.write(escape); + out.write(rightIndent); + writeInt(out, (int) (paragraphElement.indentationRight() * TWIPSFACTOR)); + Iterator chunks = paragraphElement.getChunks().iterator(); + while (chunks.hasNext()) { + Chunk ch = (Chunk) chunks.next(); + ch.setFont(paragraphElement.font().difference(ch.font())); + } + ByteArrayOutputStream save = content; + content = out; + paragraphElement.process(this); + content = save; + if (!inTable) { + out.write(escape); + out.write(paragraph); + } + } + + /** + * Write a Phrase. + * + * @param phrase The Phrase item to be written + * @param out The ByteArrayOutputStream to write to + * + * @throws IOException + */ + private void writePhrase(Phrase phrase, ByteArrayOutputStream out) throws IOException { + out.write(escape); + out.write(paragraphDefaults); + if (inTable) { + out.write(escape); + out.write(RtfCell.cellInTable); + } + Iterator chunks = phrase.getChunks().iterator(); + while (chunks.hasNext()) { + Chunk ch = (Chunk) chunks.next(); + ch.setFont(phrase.font().difference(ch.font())); + } + ByteArrayOutputStream save = content; + content = out; + phrase.process(this); + content = save; + } + + /** + * Write an Anchor. Anchors are treated like Phrases. + * + * @param anchor The Chunk item to be written + * @param out The ByteArrayOutputStream to write to + * + * @throws IOException + */ + private void writeAnchor(Anchor anchor, ByteArrayOutputStream out) throws IOException { + if (anchor.url() != null) { + out.write(openGroup); + out.write(escape); + out.write(field); + out.write(openGroup); + out.write(extendedEscape); + out.write(fieldContent); + out.write(openGroup); + out.write(fieldHyperlink); + out.write(delimiter); + out.write(anchor.url().toString().getBytes()); + out.write(closeGroup); + out.write(closeGroup); + out.write(openGroup); + out.write(escape); + out.write(fieldDisplay); + out.write(delimiter); + writePhrase(anchor, out); + out.write(closeGroup); + out.write(closeGroup); + } else { + writePhrase(anchor, out); + } + } + + /** + * Write a Chunk and all its font properties. + * + * @param chunk The Chunk item to be written + * @param out The ByteArrayOutputStream to write to + * + * @throws IOException + * @throws DocumentException + */ + private void writeChunk(Chunk chunk, ByteArrayOutputStream out) throws IOException, DocumentException { + if (chunk instanceof RtfField) { + ((RtfField) chunk).write(this, out); + } else { + if (chunk.getImage() != null) { + writeImage(chunk.getImage(), out); + } else { + writeInitialFontSignature(out, chunk); + out.write(filterSpecialChar(chunk.content(), false).getBytes()); + writeFinishingFontSignature(out, chunk); + } + } + } + + + protected void writeInitialFontSignature(OutputStream out, Chunk chunk) throws IOException { + Font font = chunk.font(); + + out.write(escape); + out.write(fontNumber); + if (!font.getFamilyname().equalsIgnoreCase("unknown")) { + writeInt(out, addFont(font)); + } else { + writeInt(out, 0); + } + out.write(escape); + out.write(fontSize); + if (font.size() > 0) { + writeInt(out, (int) (font.size() * 2)); + } else { + writeInt(out, 20); + } + out.write(escape); + out.write(fontColor); + writeInt(out, addColor(font.color())); + if (font.isBold()) { + out.write(escape); + out.write(bold); + } + if (font.isItalic()) { + out.write(escape); + out.write(italic); + } + if (font.isUnderlined()) { + out.write(escape); + out.write(underline); + } + if (font.isStrikethru()) { + out.write(escape); + out.write(strikethrough); + } + + /* + * Superscript / Subscript added by Scott Dietrich (sdietrich@emlab.com) + */ + if (chunk.getAttributes() != null) { + Float f = (Float) chunk.getAttributes().get(Chunk.SUBSUPSCRIPT); + if (f != null) + if (f.floatValue() > 0) { + out.write(escape); + out.write(startSuper); + } else if (f.floatValue() < 0) { + out.write(escape); + out.write(startSub); + } + } + + out.write(delimiter); + } + + + protected void writeFinishingFontSignature(OutputStream out, Chunk chunk) throws IOException { + Font font = chunk.font(); + + if (font.isBold()) { + out.write(escape); + out.write(bold); + writeInt(out, 0); + } + if (font.isItalic()) { + out.write(escape); + out.write(italic); + writeInt(out, 0); + } + if (font.isUnderlined()) { + out.write(escape); + out.write(underline); + writeInt(out, 0); + } + if (font.isStrikethru()) { + out.write(escape); + out.write(strikethrough); + writeInt(out, 0); + } + + /* + * Superscript / Subscript added by Scott Dietrich (sdietrich@emlab.com) + */ + if (chunk.getAttributes() != null) { + Float f = (Float) chunk.getAttributes().get(Chunk.SUBSUPSCRIPT); + if (f != null) + if (f.floatValue() != 0) { + out.write(escape); + out.write(endSuperSub); + } + } + } + + /** + * Write a ListItem + * + * @param listItem The ListItem to be written + * @param out The ByteArrayOutputStream to write to + * + * @throws IOException + * @throws DocumentException + */ + private void writeListElement(ListItem listItem, ByteArrayOutputStream out) throws IOException, DocumentException { + Iterator chunks = listItem.getChunks().iterator(); + while (chunks.hasNext()) { + Chunk ch = (Chunk) chunks.next(); + addElement(ch, out); + } + out.write(escape); + out.write(paragraph); + } + + /** + * Write a List + * + * @param list The List to be written + * @param out The ByteArrayOutputStream to write to + * + * @throws IOException + * @throws DocumentException + */ + private void writeList(com.lowagie.text.List list, ByteArrayOutputStream out) throws IOException, DocumentException { + int type = 0; + int align = 0; + int fontNr = addFont(new Font(Font.SYMBOL, 10, Font.NORMAL, new Color(0, 0, 0))); + if (!list.isNumbered()) type = 23; + if (listLevel == 0) { + maxListLevel = 0; + listtable.write(openGroup); + listtable.write(escape); + listtable.write(listDefinition); + int i = getRandomInt(); + listtable.write(escape); + listtable.write(listTemplateID); + writeInt(listtable, i); + listtable.write(escape); + listtable.write(hybridList); + listtable.write((byte) '\n'); + } + if (listLevel >= maxListLevel) { + maxListLevel++; + listtable.write(openGroup); + listtable.write(escape); + listtable.write(listLevelDefinition); + listtable.write(escape); + listtable.write(listLevelTypeOld); + writeInt(listtable, type); + listtable.write(escape); + listtable.write(listLevelTypeNew); + writeInt(listtable, type); + listtable.write(escape); + listtable.write(listLevelAlignOld); + writeInt(listtable, align); + listtable.write(escape); + listtable.write(listLevelAlignNew); + writeInt(listtable, align); + listtable.write(escape); + listtable.write(listLevelStartAt); + writeInt(listtable, 1); + listtable.write(openGroup); + listtable.write(escape); + listtable.write(listLevelTextDefinition); + listtable.write(escape); + listtable.write(listLevelTextLength); + if (list.isNumbered()) { + writeInt(listtable, 2); + } else { + writeInt(listtable, 1); + } + listtable.write(escape); + if (list.isNumbered()) { + listtable.write(listLevelTextStyleNumbers); + } else { + listtable.write(listLevelTextStyleBullet); + } + listtable.write(commaDelimiter); + listtable.write(closeGroup); + listtable.write(openGroup); + listtable.write(escape); + listtable.write(listLevelNumbersDefinition); + if (list.isNumbered()) { + listtable.write(delimiter); + listtable.write(listLevelNumbers); + writeInt(listtable, listLevel + 1); + } + listtable.write(commaDelimiter); + listtable.write(closeGroup); + if (!list.isNumbered()) { + listtable.write(escape); + listtable.write(fontNumber); + writeInt(listtable, fontNr); + } + listtable.write(escape); + listtable.write(firstIndent); + writeInt(listtable, (int) (list.indentationLeft() * TWIPSFACTOR * -1)); + listtable.write(escape); + listtable.write(listIndent); + writeInt(listtable, (int) ((list.indentationLeft() + list.symbolIndent()) * TWIPSFACTOR)); + listtable.write(escape); + listtable.write(rightIndent); + writeInt(listtable, (int) (list.indentationRight() * TWIPSFACTOR)); + listtable.write(escape); + listtable.write(tabStop); + writeInt(listtable, (int) (list.symbolIndent() * TWIPSFACTOR)); + listtable.write(closeGroup); + listtable.write((byte) '\n'); + } + // Actual List Begin in Content + out.write(escape); + out.write(paragraphDefaults); + out.write(escape); + out.write(alignLeft); + out.write(escape); + out.write(firstIndent); + writeInt(out, (int) (list.indentationLeft() * TWIPSFACTOR * -1)); + out.write(escape); + out.write(listIndent); + writeInt(out, (int) ((list.indentationLeft() + list.symbolIndent()) * TWIPSFACTOR)); + out.write(escape); + out.write(rightIndent); + writeInt(out, (int) (list.indentationRight() * TWIPSFACTOR)); + out.write(escape); + out.write(fontSize); + writeInt(out, 20); + out.write(escape); + out.write(listBegin); + writeInt(out, currentListID); + if (listLevel > 0) { + out.write(escape); + out.write(listCurrentLevel); + writeInt(out, listLevel); + } + out.write(openGroup); + ListIterator listItems = list.getItems().listIterator(); + Element listElem; + int count = 1; + while (listItems.hasNext()) { + listElem = (Element) listItems.next(); + if (listElem.type() == Element.CHUNK) { + listElem = new ListItem((Chunk) listElem); + } + if (listElem.type() == Element.LISTITEM) { + out.write(openGroup); + out.write(escape); + out.write(listTextOld); + out.write(escape); + out.write(paragraphDefaults); + out.write(escape); + out.write(fontNumber); + if (list.isNumbered()) { + writeInt(out, addFont(new Font(Font.TIMES_ROMAN, Font.NORMAL, 10, new Color(0, 0, 0)))); + } else { + writeInt(out, fontNr); + } + out.write(escape); + out.write(firstIndent); + writeInt(out, (int) (list.indentationLeft() * TWIPSFACTOR * -1)); + out.write(escape); + out.write(listIndent); + writeInt(out, (int) ((list.indentationLeft() + list.symbolIndent()) * TWIPSFACTOR)); + out.write(escape); + out.write(rightIndent); + writeInt(out, (int) (list.indentationRight() * TWIPSFACTOR)); + out.write(delimiter); + if (list.isNumbered()) { + writeInt(out, count); + out.write(".".getBytes()); + } else { + out.write(escape); + out.write(listBulletOld); + } + out.write(escape); + out.write(tab); + out.write(closeGroup); + writeListElement((ListItem) listElem, out); + count++; + } else if (listElem.type() == Element.LIST) { + listLevel++; + writeList((com.lowagie.text.List) listElem, out); + listLevel--; + out.write(escape); + out.write(paragraphDefaults); + out.write(escape); + out.write(alignLeft); + out.write(escape); + out.write(firstIndent); + writeInt(out, (int) (list.indentationLeft() * TWIPSFACTOR * -1)); + out.write(escape); + out.write(listIndent); + writeInt(out, (int) ((list.indentationLeft() + list.symbolIndent()) * TWIPSFACTOR)); + out.write(escape); + out.write(rightIndent); + writeInt(out, (int) (list.indentationRight() * TWIPSFACTOR)); + out.write(escape); + out.write(fontSize); + writeInt(out, 20); + out.write(escape); + out.write(listBegin); + writeInt(out, currentListID); + if (listLevel > 0) { + out.write(escape); + out.write(listCurrentLevel); + writeInt(out, listLevel); + } + } + out.write((byte) '\n'); + } + out.write(closeGroup); + if (listLevel == 0) { + int i = getRandomInt(); + listtable.write(escape); + listtable.write(listID); + writeInt(listtable, i); + listtable.write(closeGroup); + listtable.write((byte) '\n'); + listoverride.write(openGroup); + listoverride.write(escape); + listoverride.write(listOverride); + listoverride.write(escape); + listoverride.write(listID); + writeInt(listoverride, i); + listoverride.write(escape); + listoverride.write(listOverrideCount); + writeInt(listoverride, 0); + listoverride.write(escape); + listoverride.write(listBegin); + writeInt(listoverride, currentListID); + currentListID++; + listoverride.write(closeGroup); + listoverride.write((byte) '\n'); + } + out.write(escape); + out.write(paragraphDefaults); + } + + /** + * Write a Table. + * + * @param table The table to be written + * @param out The ByteArrayOutputStream to write to + * + * Currently no nesting of tables is supported. If a cell contains anything but a Cell Object it is ignored. + * + * @throws IOException + * @throws DocumentException + */ + private void writeTable(Table table, ByteArrayOutputStream out) throws IOException, DocumentException { + inTable = true; + table.complete(); + RtfTable rtfTable = new RtfTable(this); + rtfTable.importTable(table, pageWidth - marginLeft - marginRight); + rtfTable.writeTable(out); + inTable = false; + } + + + /** + * Write an Image. + * + * @param image The image to be written + * @param out The ByteArrayOutputStream to write to + * + * At the moment only PNG and JPEG Images are supported. + * + * @throws IOException + * @throws DocumentException + */ + private void writeImage(Image image, ByteArrayOutputStream out) throws IOException, DocumentException { + int type = image.getOriginalType(); + if (!(type == Image.ORIGINAL_JPEG || type == Image.ORIGINAL_BMP + || type == Image.ORIGINAL_PNG || type == Image.ORIGINAL_WMF)) + throw new DocumentException("Only BMP, PNG, WMF and JPEG images are supported by the RTF Writer"); + switch (image.alignment()) { + case Element.ALIGN_LEFT: + out.write(escape); + out.write(alignLeft); + break; + case Element.ALIGN_RIGHT: + out.write(escape); + out.write(alignRight); + break; + case Element.ALIGN_CENTER: + out.write(escape); + out.write(alignCenter); + break; + case Element.ALIGN_JUSTIFIED: + out.write(escape); + out.write(alignJustify); + break; + } + out.write(openGroup); + out.write(extendedEscape); + out.write(pictureGroup); + out.write(openGroup); + out.write(escape); + out.write(picture); + out.write(escape); + switch (type) { + case Image.ORIGINAL_JPEG: + out.write(pictureJPEG); + break; + case Image.ORIGINAL_PNG: + out.write(picturePNG); + break; + case Image.ORIGINAL_WMF: + case Image.ORIGINAL_BMP: + out.write(pictureWMF); + break; + } + out.write(escape); + out.write(pictureWidth); + writeInt(out, (int) (image.plainWidth() * TWIPSFACTOR)); + out.write(escape); + out.write(pictureHeight); + writeInt(out, (int) (image.plainHeight() * TWIPSFACTOR)); + + +// For some reason this messes up the intended image size. It makes it too big. Weird +// +// out.write(escape); +// out.write(pictureIntendedWidth); +// writeInt(out, (int) (image.plainWidth() * twipsFactor)); +// out.write(escape); +// out.write(pictureIntendedHeight); +// writeInt(out, (int) (image.plainHeight() * twipsFactor)); + + + if (image.width() > 0) { + out.write(escape); + out.write(pictureScaleX); + writeInt(out, (int) (100 / image.width() * image.plainWidth())); + } + if (image.height() > 0) { + out.write(escape); + out.write(pictureScaleY); + writeInt(out, (int) (100 / image.height() * image.plainHeight())); + } + out.write(delimiter); + InputStream imgIn; + if (type == Image.ORIGINAL_BMP) { + imgIn = new ByteArrayInputStream(MetaDo.wrapBMP(image)); + } + else { + if (image.getOriginalData() == null) { + imgIn = image.url().openStream(); + } else { + imgIn = new ByteArrayInputStream(image.getOriginalData()); + } + if (type == Image.ORIGINAL_WMF) { //remove the placeable header + long skipLength = 22; + while(skipLength > 0) { + skipLength = skipLength - imgIn.skip(skipLength); + } + } + } + int buffer = -1; + int count = 0; + out.write((byte) '\n'); + while ((buffer = imgIn.read()) != -1) { + String helperStr = Integer.toHexString(buffer); + if (helperStr.length() < 2) helperStr = "0" + helperStr; + out.write(helperStr.getBytes()); + count++; + if (count == 64) { + out.write((byte) '\n'); + count = 0; + } + } + imgIn.close(); + out.write(closeGroup); + out.write(closeGroup); + out.write((byte) '\n'); + } + + /** + * Write an Annotation + * + * @param annotationElement The Annotation to be written + * @param out The ByteArrayOutputStream to write to + * + * @throws IOException + */ + private void writeAnnotation(Annotation annotationElement, ByteArrayOutputStream out) throws IOException { + int id = getRandomInt(); + out.write(openGroup); + out.write(extendedEscape); + out.write(annotationID); + out.write(delimiter); + writeInt(out, id); + out.write(closeGroup); + out.write(openGroup); + out.write(extendedEscape); + out.write(annotationAuthor); + out.write(delimiter); + out.write(annotationElement.title().getBytes()); + out.write(closeGroup); + out.write(openGroup); + out.write(extendedEscape); + out.write(annotation); + out.write(escape); + out.write(paragraphDefaults); + out.write(delimiter); + out.write(annotationElement.content().getBytes()); + out.write(closeGroup); + } + + /** + * Add a Meta element. It is written to the Inforamtion Group + * and merged with the main ByteArrayOutputStream when the + * Document is closed. + * + * @param metaName The type of Meta element to be added + * @param meta The Meta element to be added + * + * Currently only the Meta Elements Author, Subject, Keywords, Title, Producer and CreationDate are supported. + * + * @throws IOException + */ + private void writeMeta(byte[] metaName, Meta meta) throws IOException { + info.write(openGroup); + try { + info.write(escape); + info.write(metaName); + info.write(delimiter); + if (meta.type() == Meta.CREATIONDATE) { + writeFormatedDateTime(meta.content()); + } else { + info.write(meta.content().getBytes()); + } + } finally { + info.write(closeGroup); + } + } + + /** + * Writes a date. The date is formated Year, Month, Day, Hour, Minute, Second + * + * @param date The date to be written + * + * @throws IOException + */ + private void writeFormatedDateTime(String date) throws IOException { + Calendar cal = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); + ParsePosition pp = new ParsePosition(0); + Date d = sdf.parse(date, pp); + if (d == null) { + d = new Date(); + } + cal.setTime(d); + info.write(escape); + info.write(year); + writeInt(info, cal.get(Calendar.YEAR)); + info.write(escape); + info.write(month); + writeInt(info, cal.get(Calendar.MONTH)); + info.write(escape); + info.write(day); + writeInt(info, cal.get(Calendar.DAY_OF_MONTH)); + info.write(escape); + info.write(hour); + writeInt(info, cal.get(Calendar.HOUR_OF_DAY)); + info.write(escape); + info.write(minute); + writeInt(info, cal.get(Calendar.MINUTE)); + info.write(escape); + info.write(second); + writeInt(info, cal.get(Calendar.SECOND)); + } + + /** + * Add a new Font to the list of fonts. If the Font + * already exists in the list of fonts, then it is not added again. + * + * @param newFont The Font to be added + * + * @return The index of the Font in the font list + */ + protected int addFont(Font newFont) { + int fn = -1; + + for (int i = 0; i < fontList.size(); i++) { + if (newFont.getFamilyname().equals(((Font) fontList.get(i)).getFamilyname())) { + fn = i; + } + } + if (fn == -1) { + fontList.add(newFont); + return fontList.size() - 1; + } + return fn; + } + + /** + * Add a new Color to the list of colours. If the Color + * already exists in the list of colours, then it is not added again. + * + * @param newColor The Color to be added + * + * @return The index of the color in the colour list + */ + protected int addColor(Color newColor) { + int cn = 0; + if (newColor == null) { + return cn; + } + cn = colorList.indexOf(newColor); + if (cn == -1) { + colorList.add(newColor); + return colorList.size() - 1; + } + return cn; + } + + /** + * Merge all the different ArrayLists and ByteArrayOutputStreams + * to the final ByteArrayOutputStream + * + * @return true if all information was sucessfully written to the ByteArrayOutputStream + */ + private boolean writeDocument() { + try { + writeDocumentIntro(); + writeFontList(); + os.write((byte) '\n'); + writeColorList(); + os.write((byte) '\n'); + writeList(); + os.write((byte) '\n'); + writeInfoGroup(); + os.write((byte) '\n'); + writeDocumentFormat(); + os.write((byte) '\n'); + ByteArrayOutputStream hf = new ByteArrayOutputStream(); + writeSectionDefaults(hf); + hf.writeTo(os); + content.writeTo(os); + os.write(closeGroup); + return true; + } catch (IOException e) { + System.err.println(e.getMessage()); + return false; + } + + } + + /** Write the Rich Text file settings + * @throws IOException + */ + private void writeDocumentIntro() throws IOException { + os.write(openGroup); + os.write(escape); + os.write(docBegin); + os.write(escape); + os.write(ansi); + os.write(escape); + os.write(ansiCodepage); + writeInt(os, 1252); + os.write((byte)'\n'); + os.write(escape); + os.write(defaultFont); + writeInt(os, 0); + } + + /** + * Write the font list to the final ByteArrayOutputStream + * @throws IOException + */ + private void writeFontList() throws IOException { + Font fnt; + + os.write(openGroup); + os.write(escape); + os.write(fontTable); + for (int i = 0; i < fontList.size(); i++) { + fnt = (Font) fontList.get(i); + os.write(openGroup); + os.write(escape); + os.write(fontNumber); + writeInt(os, i); + os.write(escape); + switch (Font.getFamilyIndex(fnt.getFamilyname())) { + case Font.COURIER: + os.write(fontModern); + os.write(escape); + os.write(fontCharset); + writeInt(os, 0); + os.write(delimiter); + os.write(fontCourier); + break; + case Font.HELVETICA: + os.write(fontSwiss); + os.write(escape); + os.write(fontCharset); + writeInt(os, 0); + os.write(delimiter); + os.write(fontArial); + break; + case Font.SYMBOL: + os.write(fontRoman); + os.write(escape); + os.write(fontCharset); + writeInt(os, 2); + os.write(delimiter); + os.write(fontSymbol); + break; + case Font.TIMES_ROMAN: + os.write(fontRoman); + os.write(escape); + os.write(fontCharset); + writeInt(os, 0); + os.write(delimiter); + os.write(fontTimesNewRoman); + break; + case Font.ZAPFDINGBATS: + os.write(fontTech); + os.write(escape); + os.write(fontCharset); + writeInt(os, 0); + os.write(delimiter); + os.write(fontWindings); + break; + default: + os.write(fontRoman); + os.write(escape); + os.write(fontCharset); + writeInt(os, 0); + os.write(delimiter); + os.write(filterSpecialChar(fnt.getFamilyname(), true).getBytes()); + } + os.write(commaDelimiter); + os.write(closeGroup); + } + os.write(closeGroup); + } + + /** + * Write the colour list to the final ByteArrayOutputStream + * @throws IOException + */ + private void writeColorList() throws IOException { + Color color = null; + + os.write(openGroup); + os.write(escape); + os.write(colorTable); + for (int i = 0; i < colorList.size(); i++) { + color = (Color) colorList.get(i); + os.write(escape); + os.write(colorRed); + writeInt(os, color.getRed()); + os.write(escape); + os.write(colorGreen); + writeInt(os, color.getGreen()); + os.write(escape); + os.write(colorBlue); + writeInt(os, color.getBlue()); + os.write(commaDelimiter); + } + os.write(closeGroup); + } + + /** + * Write the Information Group to the final ByteArrayOutputStream + * @throws IOException + */ + private void writeInfoGroup() throws IOException { + os.write(openGroup); + os.write(escape); + os.write(infoBegin); + info.writeTo(os); + os.write(closeGroup); + } + + /** + * Write the listtable and listoverridetable to the final ByteArrayOutputStream + * @throws IOException + */ + private void writeList() throws IOException { + listtable.write(closeGroup); + listoverride.write(closeGroup); + listtable.writeTo(os); + os.write((byte) '\n'); + listoverride.writeTo(os); + } + + /** + * Write an integer + * + * @param out The OuputStream to which the int value is to be written + * @param i The int value to be written + * @throws IOException + */ + public final static void writeInt(OutputStream out, int i) throws IOException { + out.write(Integer.toString(i).getBytes()); + } + + /** + * Get a random integer. + * This returns a unique random integer to be used with listids. + * + * @return Random int value. + */ + private int getRandomInt() { + boolean ok = false; + Integer newInt = null; + Integer oldInt = null; + while (!ok) { + newInt = new Integer((int) (Math.random() * Integer.MAX_VALUE)); + ok = true; + for (int i = 0; i < listIds.size(); i++) { + oldInt = (Integer) listIds.get(i); + if (oldInt.equals(newInt)) { + ok = true; + } + } + } + listIds.add(newInt); + return newInt.intValue(); + } + + /** + * Write the current header and footer to a ByteArrayOutputStream + * + * @param os The ByteArrayOutputStream to which the header and footer will be written. + * @throws IOException + */ + public void writeHeadersFooters(ByteArrayOutputStream os) throws IOException { + if (this.footer instanceof RtfHeaderFooters) { + RtfHeaderFooters rtfHf = (RtfHeaderFooters) this.footer; + HeaderFooter hf = rtfHf.get(RtfHeaderFooters.ALL_PAGES); + if (hf != null) { + writeHeaderFooter(hf, footerBegin, os); + } + hf = rtfHf.get(RtfHeaderFooters.LEFT_PAGES); + if (hf != null) { + writeHeaderFooter(hf, footerlBegin, os); + } + hf = rtfHf.get(RtfHeaderFooters.RIGHT_PAGES); + if (hf != null) { + writeHeaderFooter(hf, footerrBegin, os); + } + hf = rtfHf.get(RtfHeaderFooters.FIRST_PAGE); + if (hf != null) { + writeHeaderFooter(hf, footerfBegin, os); + } + } else { + writeHeaderFooter(this.footer, footerBegin, os); + } + if (this.header instanceof RtfHeaderFooters) { + RtfHeaderFooters rtfHf = (RtfHeaderFooters) this.header; + HeaderFooter hf = rtfHf.get(RtfHeaderFooters.ALL_PAGES); + if (hf != null) { + writeHeaderFooter(hf, headerBegin, os); + } + hf = rtfHf.get(RtfHeaderFooters.LEFT_PAGES); + if (hf != null) { + writeHeaderFooter(hf, headerlBegin, os); + } + hf = rtfHf.get(RtfHeaderFooters.RIGHT_PAGES); + if (hf != null) { + writeHeaderFooter(hf, headerrBegin, os); + } + hf = rtfHf.get(RtfHeaderFooters.FIRST_PAGE); + if (hf != null) { + writeHeaderFooter(hf, headerfBegin, os); + } + } else { + writeHeaderFooter(this.header, headerBegin, os); + } + } + + /** + * Write a HeaderFooter to a ByteArrayOutputStream + * + * @param headerFooter The HeaderFooter object to be written. + * @param hfType The type of header or footer to be added. + * @param target The ByteArrayOutputStream to which the HeaderFooter will be written. + * @throws IOException + */ + private void writeHeaderFooter(HeaderFooter headerFooter, byte[] hfType, ByteArrayOutputStream target) throws IOException { + inHeaderFooter = true; + try { + target.write(openGroup); + target.write(escape); + target.write(hfType); + target.write(delimiter); + if (headerFooter != null) { + if (headerFooter instanceof RtfHeaderFooter && ((RtfHeaderFooter) headerFooter).content() != null) { + this.addElement(((RtfHeaderFooter) headerFooter).content(), target); + } else { + Paragraph par = new Paragraph(); + par.setAlignment(headerFooter.alignment()); + if (headerFooter.getBefore() != null) { + par.add(headerFooter.getBefore()); + } + if (headerFooter.isNumbered()) { + par.add(new RtfPageNumber("", headerFooter.getBefore().font())); + } + if (headerFooter.getAfter() != null) { + par.add(headerFooter.getAfter()); + } + this.addElement(par, target); + } + } + target.write(closeGroup); + } catch (DocumentException e) { + throw new IOException("DocumentException - " + e.getMessage()); + } + inHeaderFooter = false; + } + + /** + * Write the Document's Paper and Margin Size + * to the final ByteArrayOutputStream + * @throws IOException + */ + private void writeDocumentFormat() throws IOException { +// os.write(openGroup); + os.write(escape); + os.write(rtfPaperWidth); + writeInt(os, pageWidth); + os.write(escape); + os.write(rtfPaperHeight); + writeInt(os, pageHeight); + os.write(escape); + os.write(rtfMarginLeft); + writeInt(os, marginLeft); + os.write(escape); + os.write(rtfMarginRight); + writeInt(os, marginRight); + os.write(escape); + os.write(rtfMarginTop); + writeInt(os, marginTop); + os.write(escape); + os.write(rtfMarginBottom); + writeInt(os, marginBottom); +// os.write(closeGroup); + } + + /** + * Initialise all helper classes. + * Clears alls lists, creates new ByteArrayOutputStream's + */ + private void initDefaults() { + fontList.clear(); + colorList.clear(); + info = new ByteArrayOutputStream(); + content = new ByteArrayOutputStream(); + listtable = new ByteArrayOutputStream(); + listoverride = new ByteArrayOutputStream(); + document.addProducer(); + document.addCreationDate(); + addFont(new Font(Font.TIMES_ROMAN, 10, Font.NORMAL)); + addColor(new Color(0, 0, 0)); + addColor(new Color(255, 255, 255)); + listIds = new ArrayList(); + try { + listtable.write(openGroup); + listtable.write(extendedEscape); + listtable.write(listtableGroup); + listtable.write((byte) '\n'); + listoverride.write(openGroup); + listoverride.write(extendedEscape); + listoverride.write(listoverridetableGroup); + listoverride.write((byte) '\n'); + } catch (IOException e) { + System.err.println("InitDefaultsError" + e); + } + } + + /** + * Writes the default values for the current Section + * + * @param out The ByteArrayOutputStream to be written to + * @throws IOException + */ + private void writeSectionDefaults(ByteArrayOutputStream out) throws IOException { + if (header instanceof RtfHeaderFooters || footer instanceof RtfHeaderFooters) { + RtfHeaderFooters rtfHeader = (RtfHeaderFooters) header; + RtfHeaderFooters rtfFooter = (RtfHeaderFooters) footer; + if ((rtfHeader != null && (rtfHeader.get(RtfHeaderFooters.LEFT_PAGES) != null || rtfHeader.get(RtfHeaderFooters.RIGHT_PAGES) != null)) || (rtfFooter != null && (rtfFooter.get(RtfHeaderFooters.LEFT_PAGES) != null || rtfFooter.get(RtfHeaderFooters.RIGHT_PAGES) != null))) { + out.write(escape); + out.write(facingPages); + } + } + if (hasTitlePage) { + out.write(escape); + out.write(titlePage); + } + writeHeadersFooters(out); + if (landscape) { + //out.write(escape); + //out.write(landscapeTag1); + out.write(escape); + out.write(landscapeTag2); + out.write(escape); + out.write(sectionPageWidth); + writeInt(out, pageWidth); + out.write(escape); + out.write(sectionPageHeight); + writeInt(out, pageHeight); + } else { + out.write(escape); + out.write(sectionPageWidth); + writeInt(out, pageWidth); + out.write(escape); + out.write(sectionPageHeight); + writeInt(out, pageHeight); + } + } + + /** + * This method tries to fit the Rectangle pageSize to one of the predefined PageSize rectangles. + * If a match is found the pageWidth and pageHeight will be set according to values determined from files + * generated by MS Word2000 and OpenOffice 641. If no match is found the method will try to match the rotated + * Rectangle by calling itself with the parameter rotate set to true. + * @param pageSize a rectangle defining the size of the page + * @param rotate portrait or lanscape? + * @return true if the format parsing succeeded + */ + private boolean parseFormat(Rectangle pageSize, boolean rotate) { + if (rotate) { + pageSize = pageSize.rotate(); + } + if (rectEquals(pageSize, PageSize.A3)) { + pageWidth = 16837; + pageHeight = 23811; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.A4)) { + pageWidth = 11907; + pageHeight = 16840; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.A5)) { + pageWidth = 8391; + pageHeight = 11907; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.A6)) { + pageWidth = 5959; + pageHeight = 8420; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.B4)) { + pageWidth = 14570; + pageHeight = 20636; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.B5)) { + pageWidth = 10319; + pageHeight = 14572; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.HALFLETTER)) { + pageWidth = 7927; + pageHeight = 12247; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.LETTER)) { + pageWidth = 12242; + pageHeight = 15842; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.LEGAL)) { + pageWidth = 12252; + pageHeight = 20163; + landscape = rotate; + return true; + } + if (!rotate && parseFormat(pageSize, true)) { + int x = pageWidth; + pageWidth = pageHeight; + pageHeight = x; + return true; + } + return false; + } + + /** + * This method compares to Rectangles. They are considered equal if width and height are the same + * @param rect1 + * @param rect2 + * @return true if rect1 and rect2 represent the same rectangle + */ + private boolean rectEquals(Rectangle rect1, Rectangle rect2) { + return (rect1.width() == rect2.width()) && (rect1.height() == rect2.height()); + } + + /** + * Returns whether we are currently writing a header or footer + * + * @return the value of inHeaderFooter + */ + public boolean writingHeaderFooter() { + return inHeaderFooter; + } + + /** + * Replaces special characters with their unicode values + * + * @param str The original String + * @param useHex + * @return The converted String + */ + public final static String filterSpecialChar(String str, boolean useHex) { + int length = str.length(); + int z = (int) 'z'; + StringBuffer ret = new StringBuffer(length); + for (int i = 0; i < length; i++) { + char ch = str.charAt(i); + + if (ch == '\\') { + ret.append("\\\\"); + } else if (ch == '\n') { + ret.append("\\par "); + } else if (((int) ch) > z) { + if(useHex) { + ret.append("\\\'").append(Long.toHexString((long) ch)); + } else { + ret.append("\\u").append((long) ch).append('?'); + } + } else { + ret.append(ch); + } + } + String s = ret.toString(); + if(s.indexOf("$newpage$") >= 0) { + String before = s.substring(0, s.indexOf("$newpage$")); + String after = s.substring(s.indexOf("$newpage$") + 9); + ret = new StringBuffer(before); + ret.append("\\page\\par "); + ret.append(after); + return ret.toString(); + } + return s; + } + + private void addHeaderFooterFontColor(HeaderFooter hf) { + if(hf instanceof RtfHeaderFooter) { + RtfHeaderFooter rhf = (RtfHeaderFooter) hf; + if(rhf.content() instanceof Chunk) { + addFont(((Chunk) rhf.content()).font()); + addColor(((Chunk) rhf.content()).font().color()); + } else if(rhf.content() instanceof Phrase) { + addFont(((Phrase) rhf.content()).font()); + addColor(((Phrase) rhf.content()).font().color()); + } + } + if(hf.getBefore() != null) { + addFont(hf.getBefore().font()); + addColor(hf.getBefore().font().color()); + } + if(hf.getAfter() != null) { + addFont(hf.getAfter().font()); + addColor(hf.getAfter().font().color()); + } + } + + private void processHeaderFooter(HeaderFooter hf) { + if(hf != null) { + if(hf instanceof RtfHeaderFooters) { + RtfHeaderFooters rhf = (RtfHeaderFooters) hf; + if(rhf.get(RtfHeaderFooters.ALL_PAGES) != null) { + addHeaderFooterFontColor(rhf.get(RtfHeaderFooters.ALL_PAGES)); + } + if(rhf.get(RtfHeaderFooters.LEFT_PAGES) != null) { + addHeaderFooterFontColor(rhf.get(RtfHeaderFooters.LEFT_PAGES)); + } + if(rhf.get(RtfHeaderFooters.RIGHT_PAGES) != null) { + addHeaderFooterFontColor(rhf.get(RtfHeaderFooters.RIGHT_PAGES)); + } + if(rhf.get(RtfHeaderFooters.FIRST_PAGE) != null) { + addHeaderFooterFontColor(rhf.get(RtfHeaderFooters.FIRST_PAGE)); + } + } else { + addHeaderFooterFontColor(hf); + } + } + } + + /** + * @see com.lowagie.text.DocListener#setMarginMirroring(boolean) + */ + public boolean setMarginMirroring(boolean MarginMirroring) { + return false; + } + +} + diff --git a/src/main/java/com/lowagie/text/rtf/RtfWriter2.java b/src/main/java/com/lowagie/text/rtf/RtfWriter2.java new file mode 100644 index 0000000..40040df --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/RtfWriter2.java @@ -0,0 +1,268 @@ +/* + * $Id: RtfWriter2.java,v 1.11 2005/09/11 19:09:57 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf; + +import com.lowagie.text.*; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.document.RtfDocumentSettings; +import com.lowagie.text.rtf.text.RtfNewPage; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * The RtfWriter allows the creation of rtf documents via the iText system + * + * Version: $Id: RtfWriter2.java,v 1.11 2005/09/11 19:09:57 hallm Exp $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfWriter2 extends DocWriter implements DocListener { + /** + * The RtfDocument this RtfWriter is creating + */ + RtfDocument rtfDoc = null; + + /** + * Constructs a new RtfWriter that listens to the specified Document and + * writes its output to the OutputStream. + * + * @param doc The Document that this RtfWriter listens to + * @param os The OutputStream to write to + */ + protected RtfWriter2(Document doc, OutputStream os) { + super(doc, os); + doc.addDocListener(this); + rtfDoc = new RtfDocument(); + } + + /** + * Static method to generate RtfWriters + * + * @param doc The Document that this RtfWriter listens to + * @param os The OutputStream to write to + * @return The new RtfWriter + */ + public static RtfWriter2 getInstance(Document doc, OutputStream os) { + return new RtfWriter2(doc, os); + } + + /** + * Sets the header to use + * + * @param hf The HeaderFooter to use + */ + public void setHeader(HeaderFooter hf) { + this.rtfDoc.getDocumentHeader().setHeader(hf); + } + + /** + * Resets the header + */ + public void resetHeader() { + this.rtfDoc.getDocumentHeader().setHeader(null); + } + + /** + * Sets the footer to use + * + * @param hf The HeaderFooter to use + */ + public void setFooter(HeaderFooter hf) { + this.rtfDoc.getDocumentHeader().setFooter(hf); + } + + /** + * Resets the footer + */ + public void resetFooter() { + this.rtfDoc.getDocumentHeader().setFooter(null); + } + + /** + * This method is not supported in the RtfWriter + * @param i Unused + */ + public void setPageCount(int i) {} + + /** + * This method is not supported in the RtfWriter + */ + public void resetPageCount() {} + + /** + * This method is not supported in the RtfWriter + * + * @param wm Unused + * @return false + */ + public boolean add(Watermark wm) { return false; } + + /** + * This method is not supported in the RtfWriter + */ + public void removeWatermark() {} + + /** + * This method is not supported in the RtfWriter + */ + public void clearTextWrap() {} + + /** + * Opens the RtfDocument + */ + public void open() { + } + + /** + * Closes the RtfDocument. This causes the document to be written + * to the specified OutputStream + */ + public void close() { + try { + os.write(rtfDoc.writeDocument()); + if(this.closeStream) { + os.close(); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + this.rtfDoc = new RtfDocument(); + } + + /** + * Adds an Element to the Document + * + * @param element The element to be added + * @return false + * @throws DocumentException + */ + public boolean add(Element element) throws DocumentException { + if (pause) { + return false; + } + RtfBasicElement rtfElement = rtfDoc.getMapper().mapElement(element); + if(rtfElement != null) { + rtfDoc.add(rtfElement); + return true; + } else { + return false; + } + } + + /** + * Adds a page break + * + * @return false + */ + public boolean newPage() { + rtfDoc.add(new RtfNewPage(rtfDoc)); + return true; + } + + /** + * Sets the page margins + * + * @param left The left margin + * @param right The right margin + * @param top The top margin + * @param bottom The bottom margin + * @return false + */ + public boolean setMargins(float left, float right, float top, float bottom) { + rtfDoc.getDocumentHeader().getPageSetting().setMarginLeft((int) (left * RtfElement.TWIPS_FACTOR)); + rtfDoc.getDocumentHeader().getPageSetting().setMarginRight((int) (right * RtfElement.TWIPS_FACTOR)); + rtfDoc.getDocumentHeader().getPageSetting().setMarginTop((int) (top * RtfElement.TWIPS_FACTOR)); + rtfDoc.getDocumentHeader().getPageSetting().setMarginBottom((int) (bottom * RtfElement.TWIPS_FACTOR)); + return true; + } + + /** + * Sets the size of the page + * + * @param rect A Rectangle representing the page + * @return false + */ + public boolean setPageSize(Rectangle rect) { + rtfDoc.getDocumentHeader().getPageSetting().setPageSize(rect); + return true; + } + + /** + * Whether to automagically generate table of contents entries when + * adding Chapters or Sections. + * + * @param autogenerate Whether to automatically generate TOC entries + */ + public void setAutogenerateTOCEntries(boolean autogenerate) { + this.rtfDoc.setAutogenerateTOCEntries(autogenerate); + } + + /** + * Sets the rtf data cache style to use. Valid values are given in the + * RtfDataCache class. + * + * @param dataCacheStyle The style to use. + * @throws DocumentException If data has already been written into the data cache. + * @throws IOException If the disk cache could not be initialised. + */ + public void setDataCacheStyle(int dataCacheStyle) throws DocumentException, IOException { + this.rtfDoc.setDataCacheStyle(dataCacheStyle); + } + + /** + * Gets the RtfDocumentSettings that specify how the rtf document is generated. + * + * @return The current RtfDocumentSettings. + */ + public RtfDocumentSettings getDocumentSettings() { + return this.rtfDoc.getDocumentSettings(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/document/RtfCodePage.java b/src/main/java/com/lowagie/text/rtf/document/RtfCodePage.java new file mode 100644 index 0000000..e88a942 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/document/RtfCodePage.java @@ -0,0 +1,102 @@ +/* + * $Id: RtfCodePage.java,v 1.16 2005/05/04 14:33:53 blowagie Exp $ + * $Name: $ + * + * Copyright 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.document; + +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.RtfExtendedElement; + +import java.io.IOException; +import java.io.ByteArrayOutputStream; + +/** + * The RtfCodePage class allows different code pages to be used in the rtf document. + * Currently always ansi / ansicpg1252 + * + * Version: $Id: RtfCodePage.java,v 1.16 2005/05/04 14:33:53 blowagie Exp $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfCodePage extends RtfElement implements RtfExtendedElement { + /** + * Constant for ansi encoded rtf documents + */ + private static final byte[] ANSI = "\\ansi".getBytes(); + /** + * Constant for the ansi codepage + */ + private static final byte[] ANSI_CODEPAGE = "\\ansicpg".getBytes(); + + /** + * Construct an RtfCodePage + * + * @param doc The RtfDocument this RtfCodePage belongs to + */ + public RtfCodePage(RtfDocument doc) { + super(doc); + } + + /** + * Writes the selected codepage to a byte array + * + * @return Byte array with the current codepage + */ + public byte[] writeDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(ANSI); + result.write(ANSI_CODEPAGE); + result.write(intToByteArray(1252)); + result.write((byte)'\n'); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/document/RtfDocument.java b/src/main/java/com/lowagie/text/rtf/document/RtfDocument.java new file mode 100644 index 0000000..63f0321 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/document/RtfDocument.java @@ -0,0 +1,301 @@ +/* + * $Id: RtfDocument.java,v 1.16 2005/12/24 13:14:59 hallm Exp $ + * $Name: $ + * + * Copyright 2003, 2004, 2005 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.document; + +import com.lowagie.text.DocumentException; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.RtfMapper; +import com.lowagie.text.rtf.document.output.RtfDataCache; +import com.lowagie.text.rtf.document.output.RtfDiskCache; +import com.lowagie.text.rtf.document.output.RtfMemoryCache; +import com.lowagie.text.rtf.graphic.RtfImage; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +/** + * The RtfDocument stores all document related data and also the main data stream. + * INTERNAL CLASS - NOT TO BE USED DIRECTLY + * + * Version: $Id: RtfDocument.java,v 1.16 2005/12/24 13:14:59 hallm Exp $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Todd Bush (Todd.Bush@canopysystems.com) [Tab support] + */ +public class RtfDocument extends RtfElement { + /** + * Stores the actual document data + */ + private RtfDataCache data = null; + /** + * The RtfMapper to use in this RtfDocument + */ + private RtfMapper mapper = null; + /** + * The RtfDocumentHeader that handles all document header methods + */ + private RtfDocumentHeader documentHeader = null; + /** + * Stores integers that have been generated as unique random numbers + */ + private ArrayList previousRandomInts = null; + /** + * Whether to automatically generate TOC entries for Chapters and Sections. Defaults to false + */ + private boolean autogenerateTOCEntries = false; + /** + * Whether data has been written to the RtfDataCache. + */ + private boolean dataWritten = false; + /** + * The RtfDocumentSettings for this RtfDocument. + */ + private RtfDocumentSettings documentSettings = null; + /** + * The last RtfBasicElement that was added directly to the RtfDocument. + */ + private RtfBasicElement lastElementWritten = null; + + /** + * Constant for the Rtf document start + */ + private static final byte[] RTF_DOCUMENT = "\\rtf1".getBytes(); + + /** + * The default constructor for a RtfDocument + */ + public RtfDocument() { + super(null); + data = new RtfMemoryCache(); + mapper = new RtfMapper(this); + documentHeader = new RtfDocumentHeader(this); + documentHeader.init(); + previousRandomInts = new ArrayList(); + this.documentSettings = new RtfDocumentSettings(this); + } + + /** + * Writes the document + * + * @return A byte array containing the complete rtf document + */ + public byte[] writeDocument() { + ByteArrayOutputStream docStream = new ByteArrayOutputStream(); + try { + docStream.write(OPEN_GROUP); + docStream.write(RtfDocument.RTF_DOCUMENT); + docStream.write(documentHeader.write()); + data.writeTo(docStream); + docStream.write(CLOSE_GROUP); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return docStream.toByteArray(); + } + + /** + * Adds an element to the rtf document + * + * @param element The element to add + */ + public void add(RtfBasicElement element) { + try { + if(element instanceof RtfInfoElement) { + this.documentHeader.addInfoElement((RtfInfoElement) element); + } else { + this.dataWritten = true; + if(element instanceof RtfImage) { + ((RtfImage) element).setTopLevelElement(true); + } + data.getOutputStream().write(element.write()); + this.lastElementWritten = element; + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + } + + /** + * Gets the RtfMapper object of this RtfDocument + * + * @return The RtfMapper + */ + public RtfMapper getMapper() { + return mapper; + } + + /** + * Generates a random integer that is unique with respect to the document. + * + * @return A random int + */ + public int getRandomInt() { + Integer newInt = null; + do { + newInt = new Integer((int) (Math.random() * Integer.MAX_VALUE)); + } while(previousRandomInts.contains(newInt)); + previousRandomInts.add(newInt); + return newInt.intValue(); + } + + /** + * Gets the RtfDocumentHeader of this RtfDocument + * + * @return The RtfDocumentHeader of this RtfDocument + */ + public RtfDocumentHeader getDocumentHeader() { + return this.documentHeader; + } + + /** + * Replaces special characters with their unicode values + * @param str The original String + * @param useHex indicated if the hexadecimal value has to be used + * @param softLineBreaks whether to use soft line breaks instead of default hard ones. + * + * @return The converted String + */ + public String filterSpecialChar(String str, boolean useHex, boolean softLineBreaks) { + int length = str.length(); + int z = (int) 'z'; + StringBuffer ret = new StringBuffer(length); + for (int i = 0; i < length; i++) { + char ch = str.charAt(i); + + if (ch == '\\') { + ret.append("\\\\"); + } else if (ch == '\n') { + if(softLineBreaks) { + ret.append("\\line "); + } else { + ret.append("\\par "); + } + } else if (ch == '\t') { + ret.append("\\tab "); + } else if (((int) ch) > z && this.documentSettings.isAlwaysUseUnicode()) { + if(useHex) { + ret.append("\\\'").append(Long.toHexString((long) ch)); + } else { + ret.append("\\u").append((long) ch).append('?'); + } + } else { + ret.append(ch); + } + } + String s = ret.toString(); + if(s.indexOf("$newpage$") >= 0) { + String before = s.substring(0, s.indexOf("$newpage$")); + String after = s.substring(s.indexOf("$newpage$") + 9); + ret = new StringBuffer(before); + ret.append("\\page\\par "); + ret.append(after); + return ret.toString(); + } + return s; + } + + /** + * Whether to automagically generate table of contents entries when + * adding Chapters or Sections. + * + * @param autogenerate Whether to automatically generate TOC entries + */ + public void setAutogenerateTOCEntries(boolean autogenerate) { + this.autogenerateTOCEntries = autogenerate; + } + + /** + * Get whether to autmatically generate table of contents entries + * + * @return Wheter to automatically generate TOC entries + */ + public boolean getAutogenerateTOCEntries() { + return this.autogenerateTOCEntries; + } + + /** + * Sets the rtf data cache style to use. Valid values are given in the + * RtfDataCache class. + * + * @param dataCacheStyle The style to use. + * @throws DocumentException If data has already been written into the data cache. + * @throws IOException If the disk cache could not be initialised. + */ + public void setDataCacheStyle(int dataCacheStyle) throws DocumentException, IOException { + if(dataWritten) { + throw new DocumentException("Data has already been written into the data cache. You can not change the cache style anymore."); + } + switch(dataCacheStyle) { + case RtfDataCache.CACHE_MEMORY : this.data = new RtfMemoryCache(); break; + case RtfDataCache.CACHE_DISK : this.data = new RtfDiskCache(); break; + default : this.data = new RtfMemoryCache(); break; + } + } + + /** + * Gets the RtfDocumentSettings that specify how the rtf document is generated. + * + * @return The current RtfDocumentSettings. + */ + public RtfDocumentSettings getDocumentSettings() { + return this.documentSettings; + } + + /** + * Gets the last RtfBasicElement that was directly added to the RtfDocument. + * + * @return The last RtfBasicElement that was directly added to the RtfDocument. + */ + public RtfBasicElement getLastElementWritten() { + return this.lastElementWritten; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/document/RtfDocumentHeader.java b/src/main/java/com/lowagie/text/rtf/document/RtfDocumentHeader.java new file mode 100644 index 0000000..1ae8027 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/document/RtfDocumentHeader.java @@ -0,0 +1,310 @@ +/* + * $Id: RtfDocumentHeader.java,v 1.16 2005/12/24 13:14:59 hallm Exp $ + * $Name: $ + * + * Copyright 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.document; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.HeaderFooter; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.headerfooter.RtfHeaderFooter; +import com.lowagie.text.rtf.headerfooter.RtfHeaderFooterGroup; +import com.lowagie.text.rtf.list.RtfList; +import com.lowagie.text.rtf.list.RtfListTable; +import com.lowagie.text.rtf.style.RtfColor; +import com.lowagie.text.rtf.style.RtfColorList; +import com.lowagie.text.rtf.style.RtfFont; +import com.lowagie.text.rtf.style.RtfFontList; +import com.lowagie.text.rtf.style.RtfParagraphStyle; +import com.lowagie.text.rtf.style.RtfStylesheetList; + + +/** + * The RtfDocumentHeader contains all classes required for the generation of + * the document header area. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfDocumentHeader extends RtfElement { + /** + * Constant for the title page + */ + private static final byte[] TITLE_PAGE = "\\titlepg".getBytes(); + /** + * Constant for facing pages + */ + private static final byte[] FACING_PAGES = "\\facingp".getBytes(); + + /** + * The code page to use + */ + private RtfCodePage codePage = null; + /** + * Stores all the colors used in the document + */ + private RtfColorList colorList = null; + /** + * Stores all the fonts used in the document + */ + private RtfFontList fontList = null; + /** + * Manages List tables + */ + private RtfListTable listTable = null; + /** + * Stores all paragraph styles used in the document. + */ + private RtfStylesheetList stylesheetList = null; + /** + * The information group with author/subject/keywords/title/producer/creationdate data + */ + private RtfInfoGroup infoGroup = null; + /** + * The page settings + */ + private RtfPageSetting pageSetting = null; + /** + * The current RtfHeaderFooterGroup for the header + */ + private RtfHeaderFooterGroup header = null; + /** + * The current RtfHeaderFooterGroup for the footer + */ + private RtfHeaderFooterGroup footer = null; + + /** + * Constructs a RtfDocumentHeader for a RtfDocument + * + * @param doc The RtfDocument this RtfDocumentHeader belongs to + */ + protected RtfDocumentHeader(RtfDocument doc) { + super(doc); + } + + /** + * Initialises the RtfDocumentHeader. + */ + protected void init() { + this.codePage = new RtfCodePage(this.document); + this.colorList = new RtfColorList(this.document); + this.fontList = new RtfFontList(this.document); + this.listTable = new RtfListTable(this.document); + this.stylesheetList = new RtfStylesheetList(this.document); + this.infoGroup = new RtfInfoGroup(this.document); + this.pageSetting = new RtfPageSetting(this.document); + this.header = new RtfHeaderFooterGroup(this.document, RtfHeaderFooter.TYPE_HEADER); + this.footer = new RtfHeaderFooterGroup(this.document, RtfHeaderFooter.TYPE_FOOTER); + } + + /** + * Write the contents of the document header area. + * + * @return A byte array with the contents of the document header area + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(this.codePage.writeDefinition()); + result.write(this.fontList.writeDefinition()); + result.write(this.colorList.writeDefinition()); + result.write(this.stylesheetList.writeDefinition()); + result.write(this.listTable.writeDefinition()); + result.write(this.infoGroup.write()); + result.write(this.pageSetting.writeDefinition()); + result.write(writeSectionDefinition()); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Writes the section definition data + * + * @return A byte array with the section definition data + */ + public byte[] writeSectionDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(header.hasTitlePage() || footer.hasTitlePage()) { + result.write(TITLE_PAGE); + header.setHasTitlePage(); + footer.setHasTitlePage(); + } + if(header.hasFacingPages() || footer.hasFacingPages()) { + result.write(FACING_PAGES); + header.setHasFacingPages(); + footer.setHasFacingPages(); + } + result.write(footer.write()); + result.write(header.write()); + result.write(pageSetting.writeSectionDefinition()); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Gets the number of the specified RtfFont + * + * @param font The RtfFont for which to get the number + * @return The number of the font + */ + public int getFontNumber(RtfFont font) { + return this.fontList.getFontNumber(font); + } + + /** + * Gets the number of the specified RtfColor + * + * @param color The RtfColor for which to get the number + * @return The number of the color + */ + public int getColorNumber(RtfColor color) { + return this.colorList.getColorNumber(color); + } + + /** + * Gets the number of the specified RtfList + * + * @param list The RtfList for which to get the number + * @return The number of the list + */ + public int getListNumber(RtfList list) { + return this.listTable.getListNumber(list); + } + + /** + * Gets the RtfParagraphStyle with the given style name. + * + * @param styleName The style name of the RtfParagraphStyle to get. + * @return The RtfParagraphStyle with the given style name or null. + */ + public RtfParagraphStyle getRtfParagraphStyle(String styleName) { + return this.stylesheetList.getRtfParagraphStyle(styleName); + } + + /** + * Removes a RtfList from the list table + * + * @param list The RtfList to remove + */ + public void freeListNumber(RtfList list) { + this.listTable.freeListNumber(list); + } + + /** + * Gets the RtfPageSetting object of this RtfDocument + * + * @return The RtfPageSetting object + */ + public RtfPageSetting getPageSetting() { + return this.pageSetting; + } + + /** + * Adds an RtfInfoElement to the list of RtfInfoElements + * + * @param rtfInfoElement The RtfInfoElement to add + */ + public void addInfoElement(RtfInfoElement rtfInfoElement) { + this.infoGroup.add(rtfInfoElement); + } + + /** + * Sets the current header to use + * + * @param header The HeaderFooter to use as header + */ + public void setHeader(HeaderFooter header) { + if(header != null) { + if(header instanceof RtfHeaderFooterGroup) { + this.header = new RtfHeaderFooterGroup(this.document, (RtfHeaderFooterGroup) header, RtfHeaderFooter.TYPE_HEADER); + } else if(header instanceof RtfHeaderFooter) { + this.header = new RtfHeaderFooterGroup(this.document, (RtfHeaderFooter) header, RtfHeaderFooter.TYPE_HEADER); + } else { + this.header = new RtfHeaderFooterGroup(this.document, header, RtfHeaderFooter.TYPE_HEADER); + } + } else { + this.header = new RtfHeaderFooterGroup(this.document, RtfHeaderFooter.TYPE_HEADER); + } + } + + /** + * Sets the current footer to use + * + * @param footer The HeaderFooter to use as footer + */ + public void setFooter(HeaderFooter footer) { + if(footer != null) { + if(footer instanceof RtfHeaderFooterGroup) { + this.footer = new RtfHeaderFooterGroup(this.document, (RtfHeaderFooterGroup) footer, RtfHeaderFooter.TYPE_FOOTER); + } else if(footer instanceof RtfHeaderFooter) { + this.footer = new RtfHeaderFooterGroup(this.document, (RtfHeaderFooter) footer, RtfHeaderFooter.TYPE_FOOTER); + } else { + this.footer = new RtfHeaderFooterGroup(this.document, footer, RtfHeaderFooter.TYPE_FOOTER); + } + } else { + this.footer = new RtfHeaderFooterGroup(this.document, RtfHeaderFooter.TYPE_FOOTER); + } + } + + /** + * Registers the RtfParagraphStyle for further use in the document. + * + * @param rtfParagraphStyle The RtfParagraphStyle to register. + */ + public void registerParagraphStyle(RtfParagraphStyle rtfParagraphStyle) { + this.stylesheetList.registerParagraphStyle(rtfParagraphStyle); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/document/RtfDocumentSettings.java b/src/main/java/com/lowagie/text/rtf/document/RtfDocumentSettings.java new file mode 100644 index 0000000..15b5b92 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/document/RtfDocumentSettings.java @@ -0,0 +1,182 @@ +/* + * $Id: RtfDocumentSettings.java,v 1.4 2005/12/24 13:14:59 hallm Exp $ + * $Name: $ + * + * Copyright 2003, 2004, 2005 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.document; + +import com.lowagie.text.rtf.style.RtfParagraphStyle; + + +/** + * The RtfDocumentSettings contains output specific settings. These settings modify + * how the actual document is then generated and some settings may mean that some + * RTF readers can't read the document or render it wrongly. + * + * @version $Revision: 1.4 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfDocumentSettings { + + /** + * The RtfDocument this RtfDocumentSettings belongs to. + */ + private RtfDocument document = null; + /** + * Whether to also output the table row definition after the cell content. + */ + private boolean outputTableRowDefinitionAfter = true; + /** + * Whether to output the line breaks that make the rtf document source more readable. + */ + private boolean outputDebugLineBreaks = true; + /** + * Whether to always generate soft linebreaks for \n in Chunks. + */ + private boolean alwaysGenerateSoftLinebreaks = false; + /** + * Whether to always translate characters past 'z' into unicode representations. + */ + private boolean alwaysUseUnicode = true; + + + /** + * Constructs a new RtfDocumentSettings object. + * + * @param document The RtfDocument this RtfDocumentSettings belong to. + */ + public RtfDocumentSettings(RtfDocument document) { + this.document = document; + } + + /** + * Gets whether to output the line breaks for increased rtf document readability. + * + * @return Whether to output line breaks. + */ + public boolean isOutputDebugLineBreaks() { + return outputDebugLineBreaks; + } + + /** + * Sets whether to output the line breaks for increased rtf document readability. + * Some line breaks may be added where the rtf specification demands it. + * + * @param outputDebugLineBreaks The outputDebugLineBreaks to set. + */ + public void setOutputDebugLineBreaks(boolean outputDebugLineBreaks) { + this.outputDebugLineBreaks = outputDebugLineBreaks; + } + + /** + * Gets whether the table row definition should also be written after the cell content. + * + * @return Returns the outputTableRowDefinitionAfter. + */ + public boolean isOutputTableRowDefinitionAfter() { + return outputTableRowDefinitionAfter; + } + + /** + * Sets whether the table row definition should also be written after the cell content. + * This is recommended to be set to true if you need Word2000 compatiblity and + * false if the document should be opened in OpenOffice.org Writer. + * + * @param outputTableRowDefinitionAfter The outputTableRowDefinitionAfter to set. + */ + public void setOutputTableRowDefinitionAfter( + boolean outputTableRowDefinitionAfter) { + this.outputTableRowDefinitionAfter = outputTableRowDefinitionAfter; + } + + /** + * Gets whether all linebreaks inside Chunks are generated as soft linebreaks. + * + * @return True if soft linebreaks are generated, false for hard linebreaks. + */ + public boolean isAlwaysGenerateSoftLinebreaks() { + return this.alwaysGenerateSoftLinebreaks; + } + + /** + * Sets whether to always generate soft linebreaks. + * + * @param alwaysGenerateSoftLinebreaks Whether to always generate soft linebreaks. + */ + public void setAlwaysGenerateSoftLinebreaks(boolean alwaysGenerateSoftLinebreaks) { + this.alwaysGenerateSoftLinebreaks = alwaysGenerateSoftLinebreaks; + } + + /** + * Gets whether all characters bigger than 'z' are represented as unicode. + * + * @return True if unicode representation is used, false otherwise. + */ + public boolean isAlwaysUseUnicode() { + return this.alwaysUseUnicode; + } + + /** + * Sets whether to represent all characters bigger than 'z' as unicode. + * + * @param alwaysUseUnicode True to use unicode representation, false otherwise. + */ + public void setAlwaysUseUnicode(boolean alwaysUseUnicode) { + this.alwaysUseUnicode = alwaysUseUnicode; + } + + /** + * Registers the RtfParagraphStyle for further use in the document. This does not need to be + * done for the default styles in the RtfParagraphStyle object. Those are added automatically. + * + * @param rtfParagraphStyle The RtfParagraphStyle to register. + */ + public void registerParagraphStyle(RtfParagraphStyle rtfParagraphStyle) { + this.document.getDocumentHeader().registerParagraphStyle(rtfParagraphStyle); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/document/RtfInfoElement.java b/src/main/java/com/lowagie/text/rtf/document/RtfInfoElement.java new file mode 100644 index 0000000..5549684 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/document/RtfInfoElement.java @@ -0,0 +1,181 @@ +/* + * $Id: RtfInfoElement.java,v 1.16 2005/05/04 14:33:53 blowagie Exp $ + * $Name: $ + * + * Copyright 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.document; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.lowagie.text.Meta; +import com.lowagie.text.rtf.RtfElement; + + +/** + * Stores one information group element. Valid elements are + * author, title, subject, keywords, producer and creationdate. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfInfoElement extends RtfElement { + + /** + * Constant for the author element + */ + private static final byte[] INFO_AUTHOR = "\\author".getBytes(); + /** + * Constant for the subject element + */ + private static final byte[] INFO_SUBJECT = "\\subject".getBytes(); + /** + * Constant for the keywords element + */ + private static final byte[] INFO_KEYWORDS = "\\keywords".getBytes(); + /** + * Constant for the title element + */ + private static final byte[] INFO_TITLE = "\\title".getBytes(); + /** + * Constant for the producer element + */ + private static final byte[] INFO_PRODUCER = "\\operator".getBytes(); + /** + * Constant for the creationdate element + */ + private static final byte[] INFO_CREATION_DATE = "\\creationdate".getBytes(); + + /** + * The type of this RtfInfoElement. The values from Element.INFO_ELEMENT_NAME are used. + */ + private int infoType = -1; + /** + * The content of this RtfInfoElement + */ + private String content = ""; + + /** + * Constructs a RtfInfoElement based on the given Meta object + * + * @param doc The RtfDocument this RtfInfoElement belongs to + * @param meta The Meta object this RtfInfoElement is based on + */ + public RtfInfoElement(RtfDocument doc, Meta meta) { + super(doc); + infoType = meta.type(); + content = meta.content(); + } + + /** + * Writes this RtfInfoElement + * + * @return A byte array containing the RtfInfoElement data + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(OPEN_GROUP); + switch(infoType) { + case Meta.AUTHOR: + result.write(INFO_AUTHOR); + break; + case Meta.SUBJECT: + result.write(INFO_SUBJECT); + break; + case Meta.KEYWORDS: + result.write(INFO_KEYWORDS); + break; + case Meta.TITLE: + result.write(INFO_TITLE); + break; + case Meta.PRODUCER: + result.write(INFO_PRODUCER); + break; + case Meta.CREATIONDATE: + result.write(INFO_CREATION_DATE); + break; + default: + result.write(INFO_AUTHOR); + break; + } + result.write(DELIMITER); + if(infoType == Meta.CREATIONDATE) { + result.write(convertDate(content).getBytes()); + } else { + result.write(content.getBytes()); + } + result.write(CLOSE_GROUP); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Converts a date from the format used by iText to the format required by + * rtf.
iText: EEE MMM dd HH:mm:ss zzz yyyy - rtf: \\'yr'yyyy\\'mo'MM\\'dy'dd\\'hr'HH\\'min'mm\\'sec'ss + * + * @param date The date formated by iText + * @return The date formated for rtf + */ + private String convertDate(String date) { + SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); + try { + Date creationDate = sdf.parse(date); + sdf = new SimpleDateFormat("\\'yr'yyyy\\'mo'MM\\'dy'dd\\'hr'HH\\'min'mm\\'sec'ss"); + return sdf.format(creationDate); + } catch(ParseException pe) { + pe.printStackTrace(); + return ""; + } + } +} diff --git a/src/main/java/com/lowagie/text/rtf/document/RtfInfoGroup.java b/src/main/java/com/lowagie/text/rtf/document/RtfInfoGroup.java new file mode 100644 index 0000000..fc6c46a --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/document/RtfInfoGroup.java @@ -0,0 +1,117 @@ +/* + * $Id: RtfInfoGroup.java,v 1.16 2005/05/04 14:33:52 blowagie Exp $ + * $Name: $ + * + * Copyright 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.document; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +import com.lowagie.text.rtf.RtfElement; + + +/** + * The RtfInfoGroup stores information group elements. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfInfoGroup extends RtfElement { + /** + * Information group starting tag + */ + private static final byte[] INFO_GROUP = "\\info".getBytes(); + + /** + * The RtfInfoElements that belong to this RtfInfoGroup + */ + ArrayList infoElements = null; + + /** + * Constructs a RtfInfoGroup belonging to a RtfDocument + * + * @param doc The RtfDocument this RtfInfoGroup belongs to + */ + public RtfInfoGroup(RtfDocument doc) { + super(doc); + infoElements = new ArrayList(); + } + + /** + * Adds an RtfInfoElement to the RtfInfoGroup + * + * @param infoElement The RtfInfoElement to add + */ + public void add(RtfInfoElement infoElement) { + this.infoElements.add(infoElement); + } + + /** + * Writes the RtfInfoGroup and its RtfInfoElement elements. + * + * @return A byte array containing the group and its elements + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(OPEN_GROUP); + result.write(INFO_GROUP); + for(int i = 0; i < infoElements.size(); i++) { + RtfInfoElement infoElement = (RtfInfoElement) infoElements.get(i); + result.write(infoElement.write()); + } + result.write(CLOSE_GROUP); + result.write((byte)'\n'); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/document/RtfPageSetting.java b/src/main/java/com/lowagie/text/rtf/document/RtfPageSetting.java new file mode 100644 index 0000000..fd456e4 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/document/RtfPageSetting.java @@ -0,0 +1,435 @@ +/* + * $Id: RtfPageSetting.java,v 1.15 2005/02/23 16:57:45 hallm Exp $ + * $Name: $ + * + * Copyright 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.document; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.PageSize; +import com.lowagie.text.Rectangle; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.RtfExtendedElement; + + +/** + * The RtfPageSetting stores the page size / page margins for a RtfDocument. + * INTERNAL CLASS - NOT TO BE USED DIRECTLY + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfPageSetting extends RtfElement implements RtfExtendedElement { + + /** + * Constant for the page height + */ + private static final byte[] PAGE_WIDTH = "\\paperw".getBytes(); + /** + * Constant for the page width + */ + private static final byte[] PAGE_HEIGHT = "\\paperh".getBytes(); + /** + * Constant for the left margin + */ + private static final byte[] MARGIN_LEFT = "\\margl".getBytes(); + /** + * Constant for the right margin + */ + private static final byte[] MARGIN_RIGHT = "\\margr".getBytes(); + /** + * Constant for the top margin + */ + private static final byte[] MARGIN_TOP = "\\margt".getBytes(); + /** + * Constant for the bottom margin + */ + private static final byte[] MARGIN_BOTTOM = "\\margb".getBytes(); + /** + * Constant for landscape + */ + private static final byte[] LANDSCAPE = "\\lndscpsxn".getBytes(); + /** + * Constant for the section page width + */ + private static final byte[] SECTION_PAGE_WIDTH = "\\pgwsxn".getBytes(); + /** + * Constant for the section page height + */ + private static final byte[] SECTION_PAGE_HEIGHT = "\\pghsxn".getBytes(); + /** + * Constant for the section left margin + */ + private static final byte[] SECTION_MARGIN_LEFT = "\\marglsxn".getBytes(); + /** + * Constant for the section right margin + */ + private static final byte[] SECTION_MARGIN_RIGHT = "\\margrsxn".getBytes(); + /** + * Constant for the section top margin + */ + private static final byte[] SECTION_MARGIN_TOP = "\\margtsxn".getBytes(); + /** + * Constant for the section bottom margin + */ + private static final byte[] SECTION_MARGIN_BOTTOM = "\\margbsxn".getBytes(); + + /** + * The page width to use + */ + private int pageWidth = 11906; + /** + * The page height to use + */ + private int pageHeight = 16840; + /** + * The left margin to use + */ + private int marginLeft = 1800; + /** + * The right margin to use + */ + private int marginRight = 1800; + /** + * The top margin to use + */ + private int marginTop = 1440; + /** + * The bottom margin to use + */ + private int marginBottom = 1440; + /** + * Whether the page is portrait or landscape + */ + private boolean landscape = false; + + /** + * Constructs a new RtfPageSetting object belonging to a RtfDocument. + * + * @param doc The RtfDocument this RtfPageSetting belongs to + */ + public RtfPageSetting(RtfDocument doc) { + super(doc); + } + + /** + * Writes the page size / page margin definition + * + * @return A byte array with the page size / page margin definition + */ + public byte[] writeDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(PAGE_WIDTH); + result.write(intToByteArray(pageWidth)); + result.write(PAGE_HEIGHT); + result.write(intToByteArray(pageHeight)); + result.write(MARGIN_LEFT); + result.write(intToByteArray(marginLeft)); + result.write(MARGIN_RIGHT); + result.write(intToByteArray(marginRight)); + result.write(MARGIN_TOP); + result.write(intToByteArray(marginTop)); + result.write(MARGIN_BOTTOM); + result.write(intToByteArray(marginBottom)); + result.write((byte)'\n'); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Writes the definition part for a new section + * + * @return A byte array containing the definition for a new section + */ + public byte[] writeSectionDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(landscape) { + result.write(LANDSCAPE); + result.write(SECTION_PAGE_WIDTH); + result.write(intToByteArray(pageWidth)); + result.write(SECTION_PAGE_HEIGHT); + result.write(intToByteArray(pageHeight)); + result.write((byte)'\n'); + } else { + result.write(SECTION_PAGE_WIDTH); + result.write(intToByteArray(pageWidth)); + result.write(SECTION_PAGE_HEIGHT); + result.write(intToByteArray(pageHeight)); + result.write((byte)'\n'); + } + result.write(SECTION_MARGIN_LEFT); + result.write(intToByteArray(marginLeft)); + result.write(SECTION_MARGIN_RIGHT); + result.write(intToByteArray(marginRight)); + result.write(SECTION_MARGIN_TOP); + result.write(intToByteArray(marginTop)); + result.write(SECTION_MARGIN_BOTTOM); + result.write(intToByteArray(marginBottom)); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Gets the bottom margin + * + * @return Returns the bottom margin + */ + public int getMarginBottom() { + return marginBottom; + } + + /** + * Sets the bottom margin + * + * @param marginBottom The bottom margin to use + */ + public void setMarginBottom(int marginBottom) { + this.marginBottom = marginBottom; + } + + /** + * Gets the left margin + * + * @return Returns the left margin + */ + public int getMarginLeft() { + return marginLeft; + } + + /** + * Sets the left margin to use + * + * @param marginLeft The left margin to use + */ + public void setMarginLeft(int marginLeft) { + this.marginLeft = marginLeft; + } + + /** + * Gets the right margin + * + * @return Returns the right margin + */ + public int getMarginRight() { + return marginRight; + } + + /** + * Sets the right margin to use + * + * @param marginRight The right margin to use + */ + public void setMarginRight(int marginRight) { + this.marginRight = marginRight; + } + + /** + * Gets the top margin + * + * @return Returns the top margin + */ + public int getMarginTop() { + return marginTop; + } + + /** + * Sets the top margin to use + * + * @param marginTop The top margin to use + */ + public void setMarginTop(int marginTop) { + this.marginTop = marginTop; + } + + /** + * Gets the page height + * + * @return Returns the page height + */ + public int getPageHeight() { + return pageHeight; + } + + /** + * Sets the page height to use + * + * @param pageHeight The page height to use + */ + public void setPageHeight(int pageHeight) { + this.pageHeight = pageHeight; + } + + /** + * Gets the page width + * + * @return Returns the page width + */ + public int getPageWidth() { + return pageWidth; + } + + /** + * Sets the page width to use + * + * @param pageWidth The page width to use + */ + public void setPageWidth(int pageWidth) { + this.pageWidth = pageWidth; + } + + /** + * Set the page size to use. This method will use guessFormat to try to guess the correct + * page format. If no format could be guessed, the sizes from the pageSize are used and + * the landscape setting is determined by comparing width and height; + * + * @param pageSize The pageSize to use + */ + public void setPageSize(Rectangle pageSize) { + if(!guessFormat(pageSize, false)) { + this.pageWidth = (int) (pageSize.width() * RtfElement.TWIPS_FACTOR); + this.pageHeight = (int) (pageSize.height() * RtfElement.TWIPS_FACTOR); + this.landscape = pageWidth > pageHeight; + } + } + + /** + * This method tries to fit the Rectangle pageSize to one of the predefined PageSize rectangles. + * If a match is found the pageWidth and pageHeight will be set according to values determined from files + * generated by MS Word2000 and OpenOffice 641. If no match is found the method will try to match the rotated + * Rectangle by calling itself with the parameter rotate set to true. + * + * @param pageSize the page size for which to guess the correct format + * @param rotate Whether we should try to rotate the size befor guessing the format + * @return True if the format was guessed, false/ otherwise + */ + private boolean guessFormat(Rectangle pageSize, boolean rotate) { + if (rotate) { + pageSize = pageSize.rotate(); + } + if (rectEquals(pageSize, PageSize.A3)) { + pageWidth = 16837; + pageHeight = 23811; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.A4)) { + pageWidth = 11907; + pageHeight = 16840; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.A5)) { + pageWidth = 8391; + pageHeight = 11907; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.A6)) { + pageWidth = 5959; + pageHeight = 8420; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.B4)) { + pageWidth = 14570; + pageHeight = 20636; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.B5)) { + pageWidth = 10319; + pageHeight = 14572; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.HALFLETTER)) { + pageWidth = 7927; + pageHeight = 12247; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.LETTER)) { + pageWidth = 12242; + pageHeight = 15842; + landscape = rotate; + return true; + } + if (rectEquals(pageSize, PageSize.LEGAL)) { + pageWidth = 12252; + pageHeight = 20163; + landscape = rotate; + return true; + } + if (!rotate && guessFormat(pageSize, true)) { + int x = pageWidth; + pageWidth = pageHeight; + pageHeight = x; + return true; + } + return false; + } + + /** + * This method compares to Rectangles. They are considered equal if width and height are the same + * + * @param rect1 The first Rectangle to compare + * @param rect2 The second Rectangle to compare + * @return True if the Rectangles equal, false otherwise + */ + private boolean rectEquals(Rectangle rect1, Rectangle rect2) { + return (rect1.width() == rect2.width()) && (rect1.height() == rect2.height()); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/document/output/RtfDataCache.java b/src/main/java/com/lowagie/text/rtf/document/output/RtfDataCache.java new file mode 100644 index 0000000..f9b3e9d --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/document/output/RtfDataCache.java @@ -0,0 +1,86 @@ +/* + * $Id: RtfDataCache.java,v 1.1 2005/02/02 18:09:32 hallm Exp $ + * $Name: $ + * + * Copyright 2005 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.document.output; + +import java.io.IOException; +import java.io.OutputStream; + + +/** + * The RtfDataCache interface must be implemented by classes wishing to + * act as caches for the rtf document data. + * + * @version $Revision: 1.1 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public interface RtfDataCache { + /** + * Constant for caching into memory. + */ + public static final int CACHE_MEMORY = 2; + /** + * Constant for caching to the disk. + */ + public static final int CACHE_DISK = 1; + /** + * Get the OutputStream that the RtfDocument can write to. + * + * @return The OutputStream the RtfDocument can use. + */ + public OutputStream getOutputStream(); + /** + * Write the content of the cache into the OutputStream. + * + * @param target The OutputStream to write the content into. + * @throws IOException If an error occurs reading/writing. + */ + public void writeTo(OutputStream target) throws IOException; +} diff --git a/src/main/java/com/lowagie/text/rtf/document/output/RtfDiskCache.java b/src/main/java/com/lowagie/text/rtf/document/output/RtfDiskCache.java new file mode 100644 index 0000000..77053ac --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/document/output/RtfDiskCache.java @@ -0,0 +1,113 @@ +/* + * $Id: RtfDiskCache.java,v 1.1 2005/02/02 18:09:32 hallm Exp $ + * $Name: $ + * + * Copyright 2005 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.document.output; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + + +/** + * The RtfFileCache is a RtfDataCache that uses a temporary file + * to store the rtf document data. Not so fast, but doesn't use any + * memory (just disk space). + * + * @version $Revision: 1.1 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfDiskCache implements RtfDataCache { + + /** + * The BufferedOutputStream that stores the cache data. + */ + private BufferedOutputStream data = null; + /** + * The temporary file to store the data in. + */ + private File tempFile = null; + + /** + * Constructs a RtfFileCache. Creates the temp file. + * + * @throws IOException If the temporary file could not be created. + */ + public RtfDiskCache() throws IOException { + this.tempFile = File.createTempFile("iText", null); + this.data = new BufferedOutputStream(new FileOutputStream(tempFile)); + } + + /** + * Gets the BufferedOutputStream to write to. + */ + public OutputStream getOutputStream() { + return this.data; + } + + /** + * Writes the content of the temporary file into the OutputStream. + */ + public void writeTo(OutputStream target) throws IOException { + this.data.close(); + BufferedInputStream tempIn = new BufferedInputStream(new FileInputStream(this.tempFile)); + byte[] buffer = new byte[8192]; + int bytesRead = -1; + while((bytesRead = tempIn.read(buffer)) >= 0) { + target.write(buffer, 0, bytesRead); + } + tempIn.close(); + this.tempFile.delete(); + } + +} diff --git a/src/main/java/com/lowagie/text/rtf/document/output/RtfMemoryCache.java b/src/main/java/com/lowagie/text/rtf/document/output/RtfMemoryCache.java new file mode 100644 index 0000000..002355f --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/document/output/RtfMemoryCache.java @@ -0,0 +1,93 @@ +/* + * $Id: RtfMemoryCache.java,v 1.1 2005/02/02 18:09:31 hallm Exp $ + * $Name: $ + * + * Copyright 2005 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.document.output; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + + +/** + * The RtfMemoryCache is an RtfDataCache that keeps the whole rtf document + * data in memory. Fast but memory intensive. + * + * @version $Revision: 1.1 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfMemoryCache implements RtfDataCache { + + /** + * The buffer for the rtf document data. + */ + private ByteArrayOutputStream data = null; + + /** + * Constructs a RtfMemoryCache. + */ + public RtfMemoryCache() { + this.data = new ByteArrayOutputStream(); + } + + /** + * Gets the ByteArrayOutputStream. + */ + public OutputStream getOutputStream() { + return this.data; + } + + /** + * Writes the content of the ByteArrayOutputStream into the OutputStream. + */ + public void writeTo(OutputStream target) throws IOException { + this.data.writeTo(target); + } + +} diff --git a/src/main/java/com/lowagie/text/rtf/field/RtfAnchor.java b/src/main/java/com/lowagie/text/rtf/field/RtfAnchor.java new file mode 100644 index 0000000..3823c3d --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/field/RtfAnchor.java @@ -0,0 +1,122 @@ +/* + * $Id: RtfAnchor.java,v 1.9 2005/07/07 14:44:47 hallm Exp $ + * $Name: $ + * + * Copyright 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.field; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.Anchor; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.text.RtfPhrase; + + +/** + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Werner Daehn (Werner.Daehn@BusinessObjects.com) + */ +public class RtfAnchor extends RtfField { + + /** + * Constant for a hyperlink + */ + private static final byte[] HYPERLINK = "HYPERLINK".getBytes(); + + /** + * The url of this RtfAnchor + */ + private String url = ""; + /** + * The RtfPhrase to display for the url + */ + private RtfPhrase content = null; + + /** + * Constructs a RtfAnchor based on a RtfField + * + * @param doc The RtfDocument this RtfAnchor belongs to + * @param anchor The Anchor this RtfAnchor is based on + */ + public RtfAnchor(RtfDocument doc, Anchor anchor) { + super(doc); + this.url = anchor.reference(); + this.content = new RtfPhrase(doc, anchor); + } + + /** + * Write the field instructions for this RtfAnchor. Sets the field + * type to HYPERLINK and then writes the url. + * + * @return The field instructions for this RtfAnchor + * @throws IOException + */ + protected byte[] writeFieldInstContent() throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + + result.write(HYPERLINK); + result.write(DELIMITER); + result.write(url.getBytes()); + + return result.toByteArray(); + } + + /** + * Write the field result for this RtfAnchor. Writes the content + * of the RtfPhrase. + * + * @return The field result for this RtfAnchor + * @throws IOException + */ + protected byte[] writeFieldResultContent() throws IOException { + return content.write(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/field/RtfField.java b/src/main/java/com/lowagie/text/rtf/field/RtfField.java new file mode 100644 index 0000000..6eaa525 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/field/RtfField.java @@ -0,0 +1,445 @@ +/* + * $Id: RtfField.java,v 1.11 2005/09/05 16:02:40 hallm Exp $ + * $Name: $ + * + * Copyright 2004 by Mark Hall + * Uses code Copyright 2002 + * SMB + * Dirk.Weigenand@smb-tec.com + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.field; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.Chunk; +import com.lowagie.text.Font; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.style.RtfFont; + + +/** + * The RtfField class is an abstract base class for all rtf field functionality. + * Subclasses only need to implement the two abstract methods writeFieldInstContent + * and writeFieldResultContent. All other field functionality is handled by the + * RtfField class. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Dirk Weigenand + */ +public abstract class RtfField extends Chunk implements RtfBasicElement { + + /** + * Constant for a rtf field + */ + private static final byte[] FIELD = "\\field".getBytes(); + /** + * Constant for a dirty field + */ + private static final byte[] FIELD_DIRTY = "\\flddirty".getBytes(); + /** + * Constant for a private field + */ + private static final byte[] FIELD_PRIVATE = "\\fldpriv".getBytes(); + /** + * Constant for a locked field + */ + private static final byte[] FIELD_LOCKED = "\\fldlock".getBytes(); + /** + * Constant for a edited field + */ + private static final byte[] FIELD_EDIT = "\\fldedit".getBytes(); + /** + * Constant for an alt field + */ + private static final byte[] FIELD_ALT = "\\fldalt".getBytes(); + /** + * Constant for the field instructions + */ + private static final byte[] FIELD_INSTRUCTIONS = "\\*\\fldinst".getBytes(); + /** + * Constant for the field result + */ + private static final byte[] FIELD_RESULT = "\\fldrslt".getBytes(); + + /** + * Is the field dirty + */ + private boolean fieldDirty = false; + /** + * Is the field edited + */ + private boolean fieldEdit = false; + /** + * Is the field locked + */ + private boolean fieldLocked = false; + /** + * Is the field private + */ + private boolean fieldPrivate = false; + /** + * Is it an alt field + */ + private boolean fieldAlt = false; + /** + * Whether this RtfField is in a table + */ + private boolean inTable = false; + /** + * Whether this RtfElement is in a header + */ + private boolean inHeader = false; + /** + * The RtfDocument this RtfField belongs to + */ + protected RtfDocument document = null; + /** + * The RtfFont of this RtfField + */ + private RtfFont font = null; + + /** + * Constructs a RtfField for a RtfDocument. This is not very usefull, + * since the RtfField by itself does not do anything. Use one of the + * subclasses instead. + * + * @param doc The RtfDocument this RtfField belongs to. + */ + protected RtfField(RtfDocument doc) { + this(doc, new Font()); + } + + /** + * Constructs a RtfField for a RtfDocument. This is not very usefull, + * since the RtfField by itself does not do anything. Use one of the + * subclasses instead. + * + * @param doc The RtfDocument this RtfField belongs to. + * @param font The Font this RtfField should use + */ + protected RtfField(RtfDocument doc, Font font) { + super("", font); + this.document = doc; + this.font = new RtfFont(this.document, font); + } + + /** + * Sets the RtfDocument this RtfElement belongs to + * + * @param doc The RtfDocument to use + */ + public void setRtfDocument(RtfDocument doc) { + this.document = doc; + this.font.setRtfDocument(this.document); + } + + /** + * Writes the field beginning. Also writes field properties. + * + * @return A byte array with the field beginning. + * @throws IOException + */ + private byte[] writeFieldBegin() throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + + result.write(OPEN_GROUP); + result.write(FIELD); + + if (fieldDirty) { + result.write(FIELD_DIRTY); + } + if (fieldEdit) { + result.write(FIELD_EDIT); + } + if (fieldLocked) { + result.write(FIELD_LOCKED); + } + if (fieldPrivate) { + result.write(FIELD_PRIVATE); + } + + return result.toByteArray(); + } + + /** + * Writes the beginning of the field instruction area. + * + * @return The beginning of the field instruction area + * @throws IOException + */ + private byte[] writeFieldInstBegin() throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + + result.write(OPEN_GROUP); + result.write(FIELD_INSTRUCTIONS); + result.write(DELIMITER); + + return result.toByteArray(); + } + + /** + * Writes the content of the field instruction area. Override this + * method in your subclasses. + * + * @return The content of the field instruction area + * @throws IOException If an error occurs. + */ + protected abstract byte[] writeFieldInstContent() throws IOException; + + /** + * Writes the end of the field instruction area. + * + * @return A byte array containing the end of the field instruction area + * @throws IOException + */ + private byte[] writeFieldInstEnd() throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + + if (fieldAlt) { + result.write(DELIMITER); + result.write(FIELD_ALT); + } + result.write(CLOSE_GROUP); + + return result.toByteArray(); + } + + /** + * Writes the beginning of the field result area + * + * @return A byte array containing the beginning of the field result area + * @throws IOException + */ + private byte[] writeFieldResultBegin() throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + + result.write(OPEN_GROUP); + result.write(FIELD_RESULT); + result.write(DELIMITER); + + return result.toByteArray(); + } + + /** + * Writes the content of the pre-calculated field result. Override this + * method in your subclasses. + * + * @return A byte array containing the field result + * @throws IOException If an error occurs + */ + protected abstract byte[] writeFieldResultContent() throws IOException; + + /** + * Writes the end of the field result area + * + * @return A byte array containing the end of the field result area + * @throws IOException + */ + private byte[] writeFieldResultEnd() throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + + result.write(DELIMITER); + result.write(CLOSE_GROUP); + + return result.toByteArray(); + } + + /** + * Writes the end of the field + * + * @return A byte array containing the end of the field + * @throws IOException + */ + private byte[] writeFieldEnd() throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + + result.write(CLOSE_GROUP); + + return result.toByteArray(); + } + + /** + * Write the content of this RtfField. + * + * @return A byte array containing the content of this RtfField + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(this.font.writeBegin()); + result.write(writeFieldBegin()); + result.write(writeFieldInstBegin()); + result.write(writeFieldInstContent()); + result.write(writeFieldInstEnd()); + result.write(writeFieldResultBegin()); + result.write(writeFieldResultContent()); + result.write(writeFieldResultEnd()); + result.write(writeFieldEnd()); + result.write(this.font.writeEnd()); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Get whether this field is an alt field + * + * @return Returns whether this field is an alt field + */ + public boolean isFieldAlt() { + return fieldAlt; + } + + /** + * Set whether this field is an alt field + * + * @param fieldAlt The value to use + */ + public void setFieldAlt(boolean fieldAlt) { + this.fieldAlt = fieldAlt; + } + + /** + * Get whether this field is dirty + * + * @return Returns whether this field is dirty + */ + public boolean isFieldDirty() { + return fieldDirty; + } + + /** + * Set whether this field is dirty + * + * @param fieldDirty The value to use + */ + public void setFieldDirty(boolean fieldDirty) { + this.fieldDirty = fieldDirty; + } + + /** + * Get whether this field is edited + * + * @return Returns whether this field is edited + */ + public boolean isFieldEdit() { + return fieldEdit; + } + + /** + * Set whether this field is edited. + * + * @param fieldEdit The value to use + */ + public void setFieldEdit(boolean fieldEdit) { + this.fieldEdit = fieldEdit; + } + + /** + * Get whether this field is locked + * + * @return Returns the fieldLocked. + */ + public boolean isFieldLocked() { + return fieldLocked; + } + + /** + * Set whether this field is locked + * @param fieldLocked The value to use + */ + public void setFieldLocked(boolean fieldLocked) { + this.fieldLocked = fieldLocked; + } + + /** + * Get whether this field is private + * + * @return Returns the fieldPrivate. + */ + public boolean isFieldPrivate() { + return fieldPrivate; + } + + /** + * Set whether this field is private + * + * @param fieldPrivate The value to use + */ + public void setFieldPrivate(boolean fieldPrivate) { + this.fieldPrivate = fieldPrivate; + } + + /** + * Sets whether this RtfField is in a table + * + * @param inTable True if this RtfField is in a table, false otherwise + */ + public void setInTable(boolean inTable) { + this.inTable = inTable; + } + + /** + * Sets whether this RtfField is in a header + * + * @param inHeader True if this RtfField is in a header, false otherwise + */ + public void setInHeader(boolean inHeader) { + this.inHeader = inHeader; + } + + /** + * An RtfField is never empty. + */ + public boolean isEmpty() { + return false; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/field/RtfPageNumber.java b/src/main/java/com/lowagie/text/rtf/field/RtfPageNumber.java new file mode 100644 index 0000000..3b69295 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/field/RtfPageNumber.java @@ -0,0 +1,83 @@ +/* + * Created on Aug 10, 2004 + * + * To change the template for this generated file go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ +package com.lowagie.text.rtf.field; + +import java.io.IOException; + +import com.lowagie.text.Font; +import com.lowagie.text.rtf.document.RtfDocument; + + +/** + * The RtfPageNumber provides the page number field in rtf documents. + * + * @version $Revision: 1.7 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Steffen.Stundzig@smb-tec.com + */ +public class RtfPageNumber extends RtfField { + + /** + * Constant for the page number + */ + private static final byte[] PAGE_NUMBER = "PAGE".getBytes(); + + /** + * Constructs a RtfPageNumber. This can be added anywhere to add a page number field. + */ + public RtfPageNumber() { + super(null); + } + + /** + * Constructs a RtfPageNumber with a specified Font. This can be added anywhere to + * add a page number field. + * @param font + */ + public RtfPageNumber(Font font) { + super(null, font); + } + + /** + * Constructs a RtfPageNumber object. + * + * @param doc The RtfDocument this RtfPageNumber belongs to + */ + public RtfPageNumber(RtfDocument doc) { + super(doc); + } + + /** + * Constructs a RtfPageNumber object with a specific font. + * + * @param doc The RtfDocument this RtfPageNumber belongs to + * @param font The Font to use + */ + public RtfPageNumber(RtfDocument doc, Font font) { + super(doc, font); + } + + /** + * Writes the field instruction content + * + * @return A byte array containing "PAGE" + * @throws IOException + */ + protected byte[] writeFieldInstContent() throws IOException { + return PAGE_NUMBER; + } + + /** + * Writes the field result content + * + * @return An empty byte array + * @throws IOException + */ + protected byte[] writeFieldResultContent() throws IOException { + return new byte[0]; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/field/RtfTOCEntry.java b/src/main/java/com/lowagie/text/rtf/field/RtfTOCEntry.java new file mode 100644 index 0000000..f65e424 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/field/RtfTOCEntry.java @@ -0,0 +1,163 @@ +/* + * $Id: RtfTOCEntry.java,v 1.9 2004/12/25 10:18:11 hallm Exp $ + * $Name: $ + * + * Copyright 2004 by Mark Hall + * Uses code Copyright 2002 + * Steffen.Stundzig@smb-tec.com + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.field; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.Font; + + +/** + * The RtfTOCEntry is used together with the RtfTableOfContents to generate a table of + * contents. Add the RtfTOCEntry in those locations in the document where table of + * contents entries should link to + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Steffen.Stundzig@smb-tec.com + */ +public class RtfTOCEntry extends RtfField { + + /** + * Constant for the beginning of hidden text + */ + private static final byte[] TEXT_HIDDEN_ON = "\\v".getBytes(); + /** + * Constant for the end of hidden text + */ + private static final byte[] TEXT_HIDDEN_OFF = "\\v0".getBytes(); + /** + * Constant for a TOC entry with page numbers + */ + private static final byte[] TOC_ENTRY_PAGE_NUMBER = "\\tc".getBytes(); + /** + * Constant for a TOC entry without page numbers + */ + private static final byte[] TOC_ENTRY_NO_PAGE_NUMBER = "\\tcn".getBytes(); + + /** + * The entry text of this RtfTOCEntry + */ + private String entry = ""; + /** + * Whether to show page numbers in the table of contents + */ + private boolean showPageNumber = true; + + /** + * Constructs a RtfTOCEntry with a certain entry text. + * + * @param entry The entry text to display + * @param font The Font to use + */ + public RtfTOCEntry(String entry, Font font) { + super(null, font); + if(entry != null) { + this.entry = entry; + } + } + + /** + * Writes the content of the RtfTOCEntry + * + * @return A byte array with the contents of the RtfTOCEntry + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(TEXT_HIDDEN_ON); + result.write(OPEN_GROUP); + if(this.showPageNumber) { + result.write(TOC_ENTRY_PAGE_NUMBER); + } else { + result.write(TOC_ENTRY_NO_PAGE_NUMBER); + } + result.write(DELIMITER); + result.write(this.document.filterSpecialChar(this.entry, true, false).getBytes()); + result.write(CLOSE_GROUP); + result.write(TEXT_HIDDEN_OFF); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Sets whether to display a page number in the table of contents, or not + * + * @param showPageNumber Whether to display a page number or not + */ + public void setShowPageNumber(boolean showPageNumber) { + this.showPageNumber = showPageNumber; + } + + /** + * UNUSED + * @return null + * @throws IOException never thrown + */ + protected byte[] writeFieldInstContent() throws IOException { + return null; + } + + /** + * UNUSED + * @return null + * @throws IOException never thrown + */ + protected byte[] writeFieldResultContent() throws IOException { + return null; + } + +} diff --git a/src/main/java/com/lowagie/text/rtf/field/RtfTableOfContents.java b/src/main/java/com/lowagie/text/rtf/field/RtfTableOfContents.java new file mode 100644 index 0000000..b6738c1 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/field/RtfTableOfContents.java @@ -0,0 +1,109 @@ +/* + * $Id: RtfTableOfContents.java,v 1.8 2004/12/14 12:51:54 blowagie Exp $ + * $Name: $ + * + * Copyright 2004 by Mark Hall + * Uses code Copyright 2002 + * Steffen.Stundzig@smb-tec.com + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.field; + +import java.io.IOException; + +import com.lowagie.text.Font; + + + +/** + * The RtfTableOfContents together with multiple RtfTOCEntry objects generates a table + * of contents. The table of contents will display no entries in the viewing program + * and the user will have to update it first. A text to inform the user of this is + * displayed instead. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Steffen.Stundzig@smb-tec.com + */ +public class RtfTableOfContents extends RtfField { + + /** + * The default text to display + */ + private String defaultText = "Table of Contents - Click to update"; + + /** + * Constructs a RtfTableOfContents. The default text is the text that is displayed + * before the user updates the table of contents + * + * @param defaultText The default text to display + * @param font The Font to use + */ + public RtfTableOfContents(String defaultText, Font font) { + super(null, font); + this.defaultText = defaultText; + } + + /** + * Writes the field instruction content + * + * @return A byte array containing with the field instructions + * @throws IOException + */ + protected byte[] writeFieldInstContent() throws IOException { + return "TOC \\\\f \\\\h \\\\u \\\\o \"1-5\" ".getBytes(); + } + + /** + * Writes the field result content + * + * @return An byte array containing the default text + * @throws IOException + */ + protected byte[] writeFieldResultContent() throws IOException { + return defaultText.getBytes(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/field/RtfTotalPageNumber.java b/src/main/java/com/lowagie/text/rtf/field/RtfTotalPageNumber.java new file mode 100644 index 0000000..a776fd6 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/field/RtfTotalPageNumber.java @@ -0,0 +1,128 @@ +/* + * $Id: RtfTotalPageNumber.java,v 1.3 2005/05/13 12:09:14 hallm Exp $ + * $Name: $ + * + * Copyright 2005 Jose Hurtado jose.hurtado@gft.com + * Parts Copyright 2005 Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.field; + +import java.io.IOException; + +import com.lowagie.text.Font; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.field.RtfField; + +/** + * The RtfTotalPageNumber provides the total number of pages field in rtf documents. + * + * @version $Version:$ + * @author Jose Hurtado (jose.hurtado@gft.com) + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfTotalPageNumber extends RtfField { + + /** + * Constant for arabic total page numbers. + */ + private static final byte[] ARABIC_TOTAL_PAGES = "NUMPAGES \\\\* Arabic".getBytes(); + + /** + * Constructs a RtfTotalPageNumber. This can be added anywhere to add a total number of pages field. + */ + public RtfTotalPageNumber() { + super(null); + } + + /** + * Constructs a RtfTotalPageNumber with a specified Font. This can be added anywhere + * to add a total number of pages field. + * @param font + */ + public RtfTotalPageNumber(Font font) { + super(null, font); + } + + /** + * Constructs a RtfTotalPageNumber object. + * + * @param doc The RtfDocument this RtfTotalPageNumber belongs to + */ + public RtfTotalPageNumber(RtfDocument doc) { + super(doc); + } + + /** + * Constructs a RtfTotalPageNumber object with a specific font. + * + * @param doc The RtfDocument this RtfTotalPageNumber belongs to + * @param font The Font to use + */ + public RtfTotalPageNumber(RtfDocument doc, Font font) { + super(doc, font); + } + + /** + * Writes the field NUMPAGES instruction with Arabic format + * + * @return A byte array containing "NUMPAGES \\\\* Arabic". + * @throws IOException + */ + protected byte[] writeFieldInstContent() throws IOException { + return ARABIC_TOTAL_PAGES; + } + + /** + * Writes the field result content + * + * @return An byte array containing "1". + * @throws IOException + */ + protected byte[] writeFieldResultContent() throws IOException { + return "1".getBytes(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/graphic/RtfImage.java b/src/main/java/com/lowagie/text/rtf/graphic/RtfImage.java new file mode 100644 index 0000000..c0446f8 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/graphic/RtfImage.java @@ -0,0 +1,306 @@ +/* + * $Id: RtfImage.java,v 1.23 2005/12/24 13:14:28 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.graphic; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.Image; +import com.lowagie.text.pdf.codec.wmf.MetaDo; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.style.RtfParagraphStyle; +import com.lowagie.text.rtf.text.RtfParagraph; + + +/** + * The RtfImage contains one image. Supported image types are jpeg, png, wmf, bmp. + * + * @version $Revision: 1.23 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Paulo Soares + */ +public class RtfImage extends RtfElement { + + /** + * Constant for the shape/picture group + */ + private static final byte[] PICTURE_GROUP = "\\*\\shppict".getBytes(); + /** + * Constant for a picture + */ + private static final byte[] PICTURE = "\\pict".getBytes(); + /** + * Constant for a jpeg image + */ + private static final byte[] PICTURE_JPEG = "\\jpegblip".getBytes(); + /** + * Constant for a png image + */ + private static final byte[] PICTURE_PNG = "\\pngblip".getBytes(); + /** + * Constant for a bmp image + */ + private static final byte[] PICTURE_BMP = "\\dibitmap0".getBytes(); + /** + * Constant for a wmf image + */ + private static final byte[] PICTURE_WMF = "\\wmetafile8".getBytes(); + /** + * Constant for the picture width + */ + private static final byte[] PICTURE_WIDTH = "\\picw".getBytes(); + /** + * Constant for the picture height + */ + private static final byte[] PICTURE_HEIGHT = "\\pich".getBytes(); + /** + * Constant for the picture width scale + */ + private static final byte[] PICTURE_SCALED_WIDTH = "\\picwgoal".getBytes(); + /** + * Constant for the picture height scale + */ + private static final byte[] PICTURE_SCALED_HEIGHT = "\\pichgoal".getBytes(); + + /** + * The type of image this is. + */ + private int imageType = Image.ORIGINAL_NONE; + /** + * The actual image. Already formated for direct inclusion in the rtf document + */ + private byte[] image = new byte[0]; + /** + * The alignment of this picture + */ + private int alignment = Element.ALIGN_LEFT; + /** + * The width of this picture + */ + private float width = 0; + /** + * The height of this picutre + */ + private float height = 0; + /** + * The intended display width of this picture + */ + private float plainWidth = 0; + /** + * The intended display height of this picture + */ + private float plainHeight = 0; + /** + * Whether this RtfImage is a top level element and should + * be an extra paragraph. + */ + private boolean topLevelElement = false; + + /** + * Constructs a RtfImage for an Image. + * + * @param doc The RtfDocument this RtfImage belongs to + * @param image The Image that this RtfImage wraps + * @throws DocumentException If an error occured accessing the image content + */ + public RtfImage(RtfDocument doc, Image image) throws DocumentException { + super(doc); + imageType = image.getOriginalType(); + if (!(imageType == Image.ORIGINAL_JPEG || imageType == Image.ORIGINAL_BMP + || imageType == Image.ORIGINAL_PNG || imageType == Image.ORIGINAL_WMF)) { + throw new DocumentException("Only BMP, PNG, WMF and JPEG images are supported by the RTF Writer"); + } + alignment = image.alignment(); + width = image.width(); + height = image.height(); + plainWidth = image.plainWidth(); + plainHeight = image.plainHeight(); + this.image = getImage(image); + } + + /** + * Extracts the image data from the Image. The data is formated for direct inclusion + * in a rtf document + * + * @param image The Image for which to extract the content + * @return The image data formated for the rtf document + * @throws DocumentException If an error occurs accessing the image content + */ + private byte[] getImage(Image image) throws DocumentException { + ByteArrayOutputStream imageTemp = new ByteArrayOutputStream(); + try { + InputStream imageIn; + if (imageType == Image.ORIGINAL_BMP) { + imageIn = new ByteArrayInputStream(MetaDo.wrapBMP(image)); + } else { + if (image.getOriginalData() == null) { + imageIn = image.url().openStream(); + } else { + imageIn = new ByteArrayInputStream(image.getOriginalData()); + } + if (imageType == Image.ORIGINAL_WMF) { //remove the placeable header + long skipLength = 22; + while(skipLength > 0) { + skipLength = skipLength - imageIn.skip(skipLength); + } + } + } + int buffer = 0; + int count = 0; + while((buffer = imageIn.read()) != -1) { + String helperStr = Integer.toHexString(buffer); + if (helperStr.length() < 2) helperStr = "0" + helperStr; + imageTemp.write(helperStr.getBytes()); + count++; + if (count == 64) { + imageTemp.write((byte) '\n'); + count = 0; + } + } + } catch(IOException ioe) { + throw new DocumentException(ioe.getMessage()); + } + return imageTemp.toByteArray(); + } + + /** + * Writes the RtfImage content + * + * @return the RtfImage content + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(this.topLevelElement) { + result.write(RtfParagraph.PARAGRAPH_DEFAULTS); + } + switch(alignment) { + case Element.ALIGN_LEFT: + result.write(RtfParagraphStyle.ALIGN_LEFT); + break; + case Element.ALIGN_RIGHT: + result.write(RtfParagraphStyle.ALIGN_RIGHT); + break; + case Element.ALIGN_CENTER: + result.write(RtfParagraphStyle.ALIGN_CENTER); + break; + case Element.ALIGN_JUSTIFIED: + result.write(RtfParagraphStyle.ALIGN_JUSTIFY); + break; + } + result.write(OPEN_GROUP); + result.write(PICTURE_GROUP); + result.write(OPEN_GROUP); + result.write(PICTURE); + switch(imageType) { + case Image.ORIGINAL_JPEG: + result.write(PICTURE_JPEG); + break; + case Image.ORIGINAL_PNG: + result.write(PICTURE_PNG); + break; + case Image.ORIGINAL_WMF: + case Image.ORIGINAL_BMP: + result.write(PICTURE_WMF); + break; + } + result.write(PICTURE_WIDTH); + result.write(intToByteArray((int) width)); + result.write(PICTURE_HEIGHT); + result.write(intToByteArray((int) height)); + if(width != plainWidth || this.imageType == Image.ORIGINAL_BMP) { + result.write(PICTURE_SCALED_WIDTH); + result.write(intToByteArray((int) (plainWidth * RtfElement.TWIPS_FACTOR))); + } + if(height != plainHeight || this.imageType == Image.ORIGINAL_BMP) { + result.write(PICTURE_SCALED_HEIGHT); + result.write(intToByteArray((int) (plainHeight * RtfElement.TWIPS_FACTOR))); + } + result.write(DELIMITER); + result.write((byte) '\n'); + result.write(image); + result.write(CLOSE_GROUP); + result.write(CLOSE_GROUP); + if(this.topLevelElement) { + result.write(RtfParagraph.PARAGRAPH); + result.write(RtfParagraph.PARAGRAPH); + } + result.write((byte) '\n'); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Sets the alignment of this RtfImage. Uses the alignments from com.lowagie.text.Element. + * + * @param alignment The alignment to use. + */ + public void setAlignment(int alignment) { + this.alignment = alignment; + } + + /** + * Set whether this RtfImage should behave like a top level element + * and enclose itself in a paragraph. + * + * @param topLevelElement Whether to behave like a top level element. + */ + public void setTopLevelElement(boolean topLevelElement) { + this.topLevelElement = topLevelElement; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/headerfooter/RtfHeaderFooter.java b/src/main/java/com/lowagie/text/rtf/headerfooter/RtfHeaderFooter.java new file mode 100644 index 0000000..d338f71 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/headerfooter/RtfHeaderFooter.java @@ -0,0 +1,326 @@ +/* + * Created on Aug 10, 2004 + * + * To change the template for this generated file go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ +package com.lowagie.text.rtf.headerfooter; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.HeaderFooter; +import com.lowagie.text.Image; +import com.lowagie.text.Paragraph; +import com.lowagie.text.Phrase; +import com.lowagie.text.Table; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.field.RtfPageNumber; + + +/** + * The RtfHeaderFooter represents one header or footer. This class can be used + * directly. + * + * @version $Id: RtfHeaderFooter.java,v 1.9 2005/09/21 15:26:01 hallm Exp $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfHeaderFooter extends HeaderFooter implements RtfBasicElement { + + /** + * Constant for the header type + */ + public static final int TYPE_HEADER = 1; + /** + * Constant for the footer type + */ + public static final int TYPE_FOOTER = 2; + /** + * Constant for displaying the header/footer on the first page + */ + public static final int DISPLAY_FIRST_PAGE = 0; + /** + * Constant for displaying the header/footer on all pages + */ + public static final int DISPLAY_ALL_PAGES = 1; + /** + * Constant for displaying the header/footer on all left hand pages + */ + public static final int DISPLAY_LEFT_PAGES = 2; + /** + * Constant for displaying the header/footer on all right hand pages + */ + public static final int DISPLAY_RIGHT_PAGES = 4; + + /** + * Constant for a header on all pages + */ + private static final byte[] HEADER_ALL = "\\header".getBytes(); + /** + * Constant for a header on the first page + */ + private static final byte[] HEADER_FIRST = "\\headerf".getBytes(); + /** + * Constant for a header on all left hand pages + */ + private static final byte[] HEADER_LEFT = "\\headerl".getBytes(); + /** + * Constant for a header on all right hand pages + */ + private static final byte[] HEADER_RIGHT = "\\headerr".getBytes(); + /** + * Constant for a footer on all pages + */ + private static final byte[] FOOTER_ALL = "\\footer".getBytes(); + /** + * Constant for a footer on the first page + */ + private static final byte[] FOOTER_FIRST = "\\footerf".getBytes(); + /** + * Constnat for a footer on the left hand pages + */ + private static final byte[] FOOTER_LEFT = "\\footerl".getBytes(); + /** + * Constant for a footer on the right hand pages + */ + private static final byte[] FOOTER_RIGHT = "\\footerr".getBytes(); + + /** + * The RtfDocument this RtfHeaderFooter belongs to + */ + private RtfDocument document = null; + /** + * The content of this RtfHeaderFooter + */ + private Object content = null; + /** + * The display type of this RtfHeaderFooter. TYPE_HEADER or TYPE_FOOTER + */ + private int type = TYPE_HEADER; + /** + * The display location of this RtfHeaderFooter. DISPLAY_FIRST_PAGE, + * DISPLAY_LEFT_PAGES, DISPLAY_RIGHT_PAGES or DISPLAY_ALL_PAGES + */ + private int displayAt = DISPLAY_ALL_PAGES; + + /** + * Constructs a RtfHeaderFooter based on a HeaderFooter with a certain type and displayAt + * location. For internal use only. + * + * @param doc The RtfDocument this RtfHeaderFooter belongs to + * @param headerFooter The HeaderFooter to base this RtfHeaderFooter on + * @param type The type of RtfHeaderFooter + * @param displayAt The display location of this RtfHeaderFooter + */ + protected RtfHeaderFooter(RtfDocument doc, HeaderFooter headerFooter, int type, int displayAt) { + super(new Phrase(""), false); + this.document = doc; + this.type = type; + this.displayAt = displayAt; + Paragraph par = new Paragraph(); + par.setAlignment(headerFooter.alignment()); + if (headerFooter.getBefore() != null) { + par.add(headerFooter.getBefore()); + } + if (headerFooter.isNumbered()) { + par.add(new RtfPageNumber(this.document)); + } + if (headerFooter.getAfter() != null) { + par.add(headerFooter.getAfter()); + } + try { + if(this.document != null) { + content = this.document.getMapper().mapElement(par); + ((RtfBasicElement) this.content).setInHeader(true); + } else { + content = par; + } + } catch(DocumentException de) { + de.printStackTrace(); + } + } + + /** + * Constructs a RtfHeaderFooter as a copy of an existing RtfHeaderFooter. + * For internal use only. + * + * @param doc The RtfDocument this RtfHeaderFooter belongs to + * @param headerFooter The RtfHeaderFooter to copy + * @param displayAt The display location of this RtfHeaderFooter + */ + protected RtfHeaderFooter(RtfDocument doc, RtfHeaderFooter headerFooter, int displayAt) { + super(new Phrase(""), false); + this.document = doc; + this.content = headerFooter.getContent(); + this.displayAt = displayAt; + if(this.content instanceof Element) { + try { + this.content = this.document.getMapper().mapElement((Element) this.content); + } catch(DocumentException de) { + de.printStackTrace(); + } + } + ((RtfBasicElement) this.content).setInHeader(true); + } + + /** + * Constructs a RtfHeaderFooter for a HeaderFooter. + * + * @param doc The RtfDocument this RtfHeaderFooter belongs to + * @param headerFooter The HeaderFooter to base this RtfHeaderFooter on + */ + protected RtfHeaderFooter(RtfDocument doc, HeaderFooter headerFooter) { + super(new Phrase(""), false); + this.document = doc; + Paragraph par = new Paragraph(); + par.setAlignment(headerFooter.alignment()); + if (headerFooter.getBefore() != null) { + par.add(headerFooter.getBefore()); + } + if (headerFooter.isNumbered()) { + par.add(new RtfPageNumber(this.document)); + } + if (headerFooter.getAfter() != null) { + par.add(headerFooter.getAfter()); + } + try { + content = doc.getMapper().mapElement(par); + ((RtfBasicElement) this.content).setInHeader(true); + } catch(DocumentException de) { + de.printStackTrace(); + } + } + + /** + * Constructs a RtfHeaderFooter for any Element. + * + * @param element The Element to display as content of this RtfHeaderFooter + */ + public RtfHeaderFooter(Element element) { + super(new Phrase(""), false); + this.content = element; + } + + /** + * Sets the RtfDocument this RtfElement belongs to + * + * @param doc The RtfDocument to use + */ + public void setRtfDocument(RtfDocument doc) { + this.document = doc; + if(this.document != null) { + try { + if(this.content instanceof Element) { + this.content = this.document.getMapper().mapElement((Element) this.content); + ((RtfBasicElement) this.content).setInHeader(true); + } else if(this.content instanceof RtfBasicElement){ + ((RtfBasicElement) this.content).setRtfDocument(this.document); + ((RtfBasicElement) this.content).setInHeader(true); + } + } catch(DocumentException de) { + de.printStackTrace(); + } + } + } + + /** + * Writes the content of this RtfHeaderFooter + * + * @return A byte array with the content of this RtfHeaderFooter + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(OPEN_GROUP); + if(this.type == TYPE_HEADER) { + if(this.displayAt == DISPLAY_ALL_PAGES) { + result.write(HEADER_ALL); + } else if(this.displayAt == DISPLAY_FIRST_PAGE) { + result.write(HEADER_FIRST); + } else if(this.displayAt == DISPLAY_LEFT_PAGES) { + result.write(HEADER_LEFT); + } else if(this.displayAt == DISPLAY_RIGHT_PAGES) { + result.write(HEADER_RIGHT); + } + } else { + if(this.displayAt == DISPLAY_ALL_PAGES) { + result.write(FOOTER_ALL); + } else if(this.displayAt == DISPLAY_FIRST_PAGE) { + result.write(FOOTER_FIRST); + } else if(this.displayAt == DISPLAY_LEFT_PAGES) { + result.write(FOOTER_LEFT); + } else if(this.displayAt == DISPLAY_RIGHT_PAGES) { + result.write(FOOTER_RIGHT); + } + } + result.write(DELIMITER); + if(content instanceof RtfBasicElement) { + result.write(((RtfBasicElement) this.content).write()); + } + result.write(CLOSE_GROUP); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + + /** + * Sets the display location of this RtfHeaderFooter + * + * @param displayAt The display location to use. + */ + public void setDisplayAt(int displayAt) { + this.displayAt = displayAt; + } + + /** + * Sets the type of this RtfHeaderFooter + * + * @param type The type to use. + */ + public void setType(int type) { + this.type = type; + } + + /** + * Gets the content of this RtfHeaderFooter + * + * @return The content of this RtfHeaderFooter + */ + private Object getContent() { + return this.content; + } + + /** + * Unused + * @param inTable + */ + public void setInTable(boolean inTable) { + } + + /** + * Unused + * @param inHeader + */ + public void setInHeader(boolean inHeader) { + } + + /** + * Set the alignment of this RtfHeaderFooter. Passes the setting + * on to the contained element. + */ + public void setAlignment(int alignment) { + super.setAlignment(alignment); + if(this.content instanceof Paragraph) { + ((Paragraph) this.content).setAlignment(alignment); + } else if(this.content instanceof Table) { + ((Table) this.content).setAlignment(alignment); + } else if(this.content instanceof Image) { + ((Image) this.content).setAlignment(alignment); + } + } +} diff --git a/src/main/java/com/lowagie/text/rtf/headerfooter/RtfHeaderFooterGroup.java b/src/main/java/com/lowagie/text/rtf/headerfooter/RtfHeaderFooterGroup.java new file mode 100644 index 0000000..e0934bf --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/headerfooter/RtfHeaderFooterGroup.java @@ -0,0 +1,393 @@ +/* + * Created on Aug 6, 2004 + * + * To change the template for this generated file go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ +package com.lowagie.text.rtf.headerfooter; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.HeaderFooter; +import com.lowagie.text.Phrase; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.document.RtfDocument; + + +/** + * The RtfHeaderFooterGroup holds 0 - 3 RtfHeaderFooters that create a group + * of headers or footers. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfHeaderFooterGroup extends HeaderFooter implements RtfBasicElement { + + /** + * This RtfHeaderFooterGroup contains no RtfHeaderFooter objects + */ + private static final int MODE_NONE = 0; + /** + * This RtfHeaderFooterGroup contains one RtfHeaderFooter object + */ + private static final int MODE_SINGLE = 1; + /** + * This RtfHeaderFooterGroup contains two or three RtfHeaderFooter objects + */ + private static final int MODE_MULTIPLE = 2; + + /** + * The current mode of this RtfHeaderFooterGroup. Defaults to MODE_NONE + */ + private int mode = MODE_NONE; + /** + * The current type of this RtfHeaderFooterGroup. Defaults to RtfHeaderFooter.TYPE_HEADER + */ + private int type = RtfHeaderFooter.TYPE_HEADER; + + /** + * The RtfHeaderFooter for all pages + */ + private RtfHeaderFooter headerAll = null; + /** + * The RtfHeaderFooter for the first page + */ + private RtfHeaderFooter headerFirst = null; + /** + * The RtfHeaderFooter for the left hand pages + */ + private RtfHeaderFooter headerLeft = null; + /** + * The RtfHeaderFooter for the right hand pages + */ + private RtfHeaderFooter headerRight = null; + /** + * The RtfDocument this RtfHeaderFooterGroup belongs to + */ + private RtfDocument document = null; + + /** + * Constructs a RtfHeaderGroup to which you add headers/footers using + * via the setHeaderFooter method. + * + */ + public RtfHeaderFooterGroup() { + super(new Phrase(""), false); + this.mode = MODE_NONE; + } + + /** + * Constructs a certain type of RtfHeaderFooterGroup. RtfHeaderFooter.TYPE_HEADER + * and RtfHeaderFooter.TYPE_FOOTER are valid values for type. + * + * @param doc The RtfDocument this RtfHeaderFooter belongs to + * @param type The type of RtfHeaderFooterGroup to create + */ + public RtfHeaderFooterGroup(RtfDocument doc, int type) { + super(new Phrase(""), false); + this.document = doc; + this.type = type; + } + + /** + * Constructs a RtfHeaderFooterGroup by copying the content of the original + * RtfHeaderFooterGroup + * + * @param doc The RtfDocument this RtfHeaderFooter belongs to + * @param headerFooter The RtfHeaderFooterGroup to copy + * @param type The type of RtfHeaderFooterGroup to create + */ + public RtfHeaderFooterGroup(RtfDocument doc, RtfHeaderFooterGroup headerFooter, int type) { + super(new Phrase(""), false); + this.document = doc; + this.mode = headerFooter.getMode(); + this.type = type; + if(headerFooter.getHeaderAll() != null) { + this.headerAll = new RtfHeaderFooter(this.document, headerFooter.getHeaderAll(), RtfHeaderFooter.DISPLAY_ALL_PAGES); + } + if(headerFooter.getHeaderFirst() != null) { + this.headerFirst = new RtfHeaderFooter(this.document, headerFooter.getHeaderFirst(), RtfHeaderFooter.DISPLAY_FIRST_PAGE); + } + if(headerFooter.getHeaderLeft() != null) { + this.headerLeft = new RtfHeaderFooter(this.document, headerFooter.getHeaderLeft(), RtfHeaderFooter.DISPLAY_LEFT_PAGES); + } + if(headerFooter.getHeaderRight() != null) { + this.headerRight = new RtfHeaderFooter(this.document, headerFooter.getHeaderRight(), RtfHeaderFooter.DISPLAY_RIGHT_PAGES); + } + setType(this.type); + } + + /** + * Constructs a RtfHeaderFooterGroup for a certain RtfHeaderFooter. + * + * @param doc The RtfDocument this RtfHeaderFooter belongs to + * @param headerFooter The RtfHeaderFooter to display + * @param type The typ of RtfHeaderFooterGroup to create + */ + public RtfHeaderFooterGroup(RtfDocument doc, RtfHeaderFooter headerFooter, int type) { + super(new Phrase(""), false); + this.document = doc; + this.type = type; + this.mode = MODE_SINGLE; + headerAll = new RtfHeaderFooter(doc, headerFooter, RtfHeaderFooter.DISPLAY_ALL_PAGES); + headerAll.setType(this.type); + } + + /** + * Constructs a RtfHeaderGroup for a certain HeaderFooter + * + * @param doc The RtfDocument this RtfHeaderFooter belongs to + * @param headerFooter The HeaderFooter to display + * @param type The typ of RtfHeaderFooterGroup to create + */ + public RtfHeaderFooterGroup(RtfDocument doc, HeaderFooter headerFooter, int type) { + super(new Phrase(""), false); + this.document = doc; + this.type = type; + this.mode = MODE_SINGLE; + headerAll = new RtfHeaderFooter(doc, headerFooter, type, RtfHeaderFooter.DISPLAY_ALL_PAGES); + headerAll.setType(this.type); + } + + /** + * Sets the RtfDocument this RtfElement belongs to + * + * @param doc The RtfDocument to use + */ + public void setRtfDocument(RtfDocument doc) { + this.document = doc; + if(headerAll != null) { + headerAll.setRtfDocument(this.document); + } + if(headerFirst != null) { + headerFirst.setRtfDocument(this.document); + } + if(headerLeft != null) { + headerLeft.setRtfDocument(this.document); + } + if(headerRight != null) { + headerRight.setRtfDocument(this.document); + } + } + + /** + * Write the content of this RtfHeaderFooterGroup. + * + * @return A byte array with the content of this RtfHeaderFooterGroup + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(this.mode == MODE_SINGLE) { + result.write(headerAll.write()); + } else if(this.mode == MODE_MULTIPLE) { + if(headerFirst != null) { + result.write(headerFirst.write()); + } + if(headerLeft != null) { + result.write(headerLeft.write()); + } + if(headerRight != null) { + result.write(headerRight.write()); + } + if(headerAll != null) { + result.write(headerAll.write()); + } + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Set a RtfHeaderFooter to be displayed at a certain position + * + * @param headerFooter The RtfHeaderFooter to display + * @param displayAt The display location to use + */ + public void setHeaderFooter(RtfHeaderFooter headerFooter, int displayAt) { + this.mode = MODE_MULTIPLE; + headerFooter.setRtfDocument(this.document); + headerFooter.setType(this.type); + headerFooter.setDisplayAt(displayAt); + switch(displayAt) { + case RtfHeaderFooter.DISPLAY_ALL_PAGES: + headerAll = headerFooter; + break; + case RtfHeaderFooter.DISPLAY_FIRST_PAGE: + headerFirst = headerFooter; + break; + case RtfHeaderFooter.DISPLAY_LEFT_PAGES: + headerLeft = headerFooter; + break; + case RtfHeaderFooter.DISPLAY_RIGHT_PAGES: + headerRight = headerFooter; + break; + } + } + + /** + * Set a HeaderFooter to be displayed at a certain position + * + * @param headerFooter The HeaderFooter to set + * @param displayAt The display location to use + */ + public void setHeaderFooter(HeaderFooter headerFooter, int displayAt) { + this.mode = MODE_MULTIPLE; + switch(displayAt) { + case RtfHeaderFooter.DISPLAY_ALL_PAGES: + headerAll = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt); + break; + case RtfHeaderFooter.DISPLAY_FIRST_PAGE: + headerFirst = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt); + break; + case RtfHeaderFooter.DISPLAY_LEFT_PAGES: + headerLeft = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt); + break; + case RtfHeaderFooter.DISPLAY_RIGHT_PAGES: + headerRight = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt); + break; + } + } + + /** + * Set that this RtfHeaderFooterGroup should have a title page. If only + * a header / footer for all pages exists, then it will be copied to the + * first page aswell. + */ + public void setHasTitlePage() { + if(this.mode == MODE_SINGLE) { + this.mode = MODE_MULTIPLE; + headerFirst = new RtfHeaderFooter(this.document, headerAll, RtfHeaderFooter.DISPLAY_FIRST_PAGE); + headerFirst.setType(this.type); + } + } + + /** + * Set that this RtfHeaderFooterGroup should have facing pages. If only + * a header / footer for all pages exists, then it will be copied to the left + * and right pages aswell. + */ + public void setHasFacingPages() { + if(this.mode == MODE_SINGLE) { + this.mode = MODE_MULTIPLE; + this.headerLeft = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_LEFT_PAGES); + this.headerLeft.setType(this.type); + this.headerRight = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_RIGHT_PAGES); + this.headerRight.setType(this.type); + this.headerAll = null; + } else if(this.mode == MODE_MULTIPLE) { + if(this.headerLeft == null && this.headerAll != null) { + this.headerLeft = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_LEFT_PAGES); + this.headerLeft.setType(this.type); + } + if(this.headerRight == null && this.headerAll != null) { + this.headerRight = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_RIGHT_PAGES); + this.headerRight.setType(this.type); + } + this.headerAll = null; + } + } + + /** + * Get whether this RtfHeaderFooterGroup has a titlepage + * + * @return Whether this RtfHeaderFooterGroup has a titlepage + */ + public boolean hasTitlePage() { + return (headerFirst != null); + } + + /** + * Get whether this RtfHeaderFooterGroup has facing pages + * + * @return Whether this RtfHeaderFooterGroup has facing pages + */ + public boolean hasFacingPages() { + return (headerLeft != null || headerRight != null); + } + + /** + * Unused + * @param inTable + */ + public void setInTable(boolean inTable) { + } + + /** + * Unused + * @param inHeader + */ + public void setInHeader(boolean inHeader) { + } + + /** + * Set the type of this RtfHeaderFooterGroup. RtfHeaderFooter.TYPE_HEADER + * or RtfHeaderFooter.TYPE_FOOTER. Also sets the type for all RtfHeaderFooters + * of this RtfHeaderFooterGroup. + * + * @param type The type to use + */ + public void setType(int type) { + this.type = type; + if(headerAll != null) { + headerAll.setType(this.type); + } + if(headerFirst != null) { + headerFirst.setType(this.type); + } + if(headerLeft != null) { + headerLeft.setType(this.type); + } + if(headerRight != null) { + headerRight.setType(this.type); + } + } + + /** + * Gets the mode of this RtfHeaderFooterGroup + * + * @return The mode of this RtfHeaderFooterGroup + */ + protected int getMode() { + return this.mode; + } + + /** + * Gets the RtfHeaderFooter for all pages + * + * @return The RtfHeaderFooter for all pages + */ + protected RtfHeaderFooter getHeaderAll() { + return headerAll; + } + + /** + * Gets the RtfHeaderFooter for the title page + * + * @return The RtfHeaderFooter for the title page + */ + protected RtfHeaderFooter getHeaderFirst() { + return headerFirst; + } + + /** + * Gets the RtfHeaderFooter for all left hand pages + * + * @return The RtfHeaderFooter for all left hand pages + */ + protected RtfHeaderFooter getHeaderLeft() { + return headerLeft; + } + + /** + * Gets the RtfHeaderFooter for all right hand pages + * + * @return The RtfHeaderFooter for all right hand pages + */ + protected RtfHeaderFooter getHeaderRight() { + return headerRight; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/list/RtfList.java b/src/main/java/com/lowagie/text/rtf/list/RtfList.java new file mode 100644 index 0000000..cfa5c33 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/list/RtfList.java @@ -0,0 +1,605 @@ +/* + * $Id: RtfList.java,v 1.19 2006/04/05 09:30:47 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004, 2005 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.list; + +import java.awt.Color; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +import com.lowagie.text.Chunk; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.Font; +import com.lowagie.text.List; +import com.lowagie.text.ListItem; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.RtfExtendedElement; +import com.lowagie.text.rtf.style.RtfFont; +import com.lowagie.text.rtf.style.RtfFontList; +import com.lowagie.text.rtf.style.RtfParagraphStyle; +import com.lowagie.text.rtf.text.RtfParagraph; +import com.lowagie.text.rtf.document.RtfDocument; + + +/** + * The RtfList stores one List. It also provides the methods to write the + * list declaration and the list data. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfList extends RtfElement implements RtfExtendedElement { + + /** + * Constant for list level + */ + private static final byte[] LIST_LEVEL = "\\listlevel".getBytes(); + /** + * Constant for list level style old + */ + private static final byte[] LIST_LEVEL_TYPE = "\\levelnfc".getBytes(); + /** + * Constant for list level style new + */ + private static final byte[] LIST_LEVEL_TYPE_NEW = "\\levelnfcn".getBytes(); + /** + * Constant for list level alignment old + */ + private static final byte[] LIST_LEVEL_ALIGNMENT = "\\leveljc".getBytes(); + /** + * Constant for list level alignment new + */ + private static final byte[] LIST_LEVEL_ALIGNMENT_NEW = "\\leveljcn".getBytes(); + /** + * Constant for list level start at + */ + private static final byte[] LIST_LEVEL_START_AT = "\\levelstartat".getBytes(); + /** + * Constant for list level text + */ + private static final byte[] LIST_LEVEL_TEXT = "\\leveltext".getBytes(); + /** + * Constant for the beginning of the list level numbered style + */ + private static final byte[] LIST_LEVEL_STYLE_NUMBERED_BEGIN = "\\\'02\\\'".getBytes(); + /** + * Constant for the end of the list level numbered style + */ + private static final byte[] LIST_LEVEL_STYLE_NUMBERED_END = ".;".getBytes(); + /** + * Constant for the list level bulleted style + */ + private static final byte[] LIST_LEVEL_STYLE_BULLETED = "\\\'01\\u-3913 ?;".getBytes(); + /** + * Constant for the beginning of the list level numbers + */ + private static final byte[] LIST_LEVEL_NUMBERS_BEGIN = "\\levelnumbers".getBytes(); + /** + * Constant for the list level numbers + */ + private static final byte[] LIST_LEVEL_NUMBERS_NUMBERED = "\\\'01".getBytes(); + /** + * Constant for the end of the list level numbers + */ + private static final byte[] LIST_LEVEL_NUMBERS_END = ";".getBytes(); + /** + * Constant for the first indentation + */ + private static final byte[] LIST_LEVEL_FIRST_INDENT = "\\fi".getBytes(); + /** + * Constant for the symbol indentation + */ + private static final byte[] LIST_LEVEL_SYMBOL_INDENT = "\\tx".getBytes(); + /** + * Constant for the list level value + */ + private static final byte[] LIST_LEVEL_NUMBER = "\\ilvl".getBytes(); + /** + * Constant for a tab character + */ + private static final byte[] TAB = "\\tab".getBytes(); + /** + * Constant for the old list text + */ + private static final byte[] LIST_TEXT = "\\listtext".getBytes(); + /** + * Constant for the old list number end + */ + private static final byte[] LIST_NUMBER_END = ".".getBytes(); + /** + * Constant for the old bulleted list + */ + private static final byte[] LIST_BULLET = "\\\'b7".getBytes(); + + /** + * The subitems of this RtfList + */ + private ArrayList items; + /** + * The level of this RtfList + */ + private int listLevel = 0; + /** + * The first indentation of this RtfList + */ + private int firstIndent = 0; + /** + * The left indentation of this RtfList + */ + private int leftIndent = 0; + /** + * The right indentation of this RtfList + */ + private int rightIndent = 0; + /** + * The symbol indentation of this RtfList + */ + private int symbolIndent = 0; + /** + * The list number of this RtfList + */ + private int listNumber = 1; + /** + * Whether this RtfList is numbered + */ + private boolean numbered = true; + /** + * The RtfFont for numbered lists + */ + private RtfFont fontNumber; + /** + * The RtfFont for bulleted lists + */ + private RtfFont fontBullet; + /** + * The alignment of this RtfList + */ + private int alignment = Element.ALIGN_LEFT; + /** + * The parent List in multi-level lists. + */ + private RtfList parentList = null; + + /** + * Constructs a new RtfList for the specified List. + * + * @param doc The RtfDocument this RtfList belongs to + * @param list The List this RtfList is based on + */ + public RtfList(RtfDocument doc, List list) { + super(doc); + + this.listNumber = document.getDocumentHeader().getListNumber(this); + + this.items = new ArrayList(); + if(list.symbolIndent() > 0 && list.indentationLeft() > 0) { + this.firstIndent = (int) (list.symbolIndent() * RtfElement.TWIPS_FACTOR * -1); + this.leftIndent = (int) ((list.indentationLeft() + list.symbolIndent()) * RtfElement.TWIPS_FACTOR); + } else if(list.symbolIndent() > 0) { + this.firstIndent = (int) (list.symbolIndent() * RtfElement.TWIPS_FACTOR * -1); + this.leftIndent = (int) (list.symbolIndent() * RtfElement.TWIPS_FACTOR); + } else if(list.indentationLeft() > 0) { + this.firstIndent = 0; + this.leftIndent = (int) (list.indentationLeft() * RtfElement.TWIPS_FACTOR); + } else { + this.firstIndent = 0; + this.leftIndent = 0; + } + this.rightIndent = (int) (list.indentationRight() * RtfElement.TWIPS_FACTOR); + this.symbolIndent = (int) ((list.symbolIndent() + list.indentationLeft()) * RtfElement.TWIPS_FACTOR); + this.numbered = list.isNumbered(); + + for(int i = 0; i < list.getItems().size(); i++) { + try { + Element element = (Element) list.getItems().get(i); + if(element.type() == Element.CHUNK) { + element = new ListItem((Chunk) element); + } + if(element instanceof ListItem) { + this.alignment = ((ListItem) element).alignment(); + } + RtfBasicElement rtfElement = doc.getMapper().mapElement(element); + if(rtfElement instanceof RtfList) { + ((RtfList) rtfElement).setListNumber(listNumber); + ((RtfList) rtfElement).setListLevel(listLevel + 1); + ((RtfList) rtfElement).setParent(this); + } else if(rtfElement instanceof RtfListItem) { + ((RtfListItem) rtfElement).setParent(this); + ((RtfListItem) rtfElement).inheritListSettings(listNumber, listLevel + 1); + } + items.add(rtfElement); + } catch(DocumentException de) { + de.printStackTrace(); + } + } + + if(this.listLevel == 0) { + correctIndentation(); + } + + fontNumber = new RtfFont(document, new Font(Font.TIMES_ROMAN, 10, Font.NORMAL, new Color(0, 0, 0))); + fontBullet = new RtfFont(document, new Font(Font.SYMBOL, 10, Font.NORMAL, new Color(0, 0, 0))); + } + + private byte[] writeIndentations() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(LIST_LEVEL_FIRST_INDENT); + result.write(intToByteArray(firstIndent)); + result.write(RtfParagraphStyle.INDENT_LEFT); + result.write(intToByteArray(leftIndent)); + result.write(RtfParagraphStyle.INDENT_RIGHT); + result.write(intToByteArray(rightIndent)); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Writes the definition part of this list level + * + * @return A byte array containing the definition of this list level + */ + public byte[] writeDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(OPEN_GROUP); + result.write(LIST_LEVEL); + result.write(LIST_LEVEL_TYPE); + if(numbered) { + result.write(intToByteArray(0)); + } else { + result.write(intToByteArray(23)); + } + result.write(LIST_LEVEL_TYPE_NEW); + if(numbered) { + result.write(intToByteArray(0)); + } else { + result.write(intToByteArray(23)); + } + result.write(LIST_LEVEL_ALIGNMENT); + result.write(intToByteArray(0)); + result.write(LIST_LEVEL_ALIGNMENT_NEW); + result.write(intToByteArray(0)); + result.write(LIST_LEVEL_START_AT); + result.write(intToByteArray(1)); + result.write(OPEN_GROUP); + result.write(LIST_LEVEL_TEXT); + if(numbered) { + result.write(LIST_LEVEL_STYLE_NUMBERED_BEGIN); + if(listLevel < 10) { + result.write(intToByteArray(0)); + } + result.write(intToByteArray(listLevel)); + result.write(LIST_LEVEL_STYLE_NUMBERED_END); + } else { + result.write(LIST_LEVEL_STYLE_BULLETED); + } + result.write(CLOSE_GROUP); + result.write(OPEN_GROUP); + result.write(LIST_LEVEL_NUMBERS_BEGIN); + if(numbered) { + result.write(LIST_LEVEL_NUMBERS_NUMBERED); + } + result.write(LIST_LEVEL_NUMBERS_END); + result.write(CLOSE_GROUP); + result.write(RtfFontList.FONT_NUMBER); + if(numbered) { + result.write(intToByteArray(fontNumber.getFontNumber())); + } else { + result.write(intToByteArray(fontBullet.getFontNumber())); + } + result.write(writeIndentations()); + result.write(LIST_LEVEL_SYMBOL_INDENT); + result.write(intToByteArray(this.leftIndent)); + result.write(CLOSE_GROUP); + result.write("\n".getBytes()); + for(int i = 0; i < items.size(); i++) { + RtfElement rtfElement = (RtfElement) items.get(i); + if(rtfElement instanceof RtfList) { + result.write(((RtfList) rtfElement).writeDefinition()); + break; + } else if(rtfElement instanceof RtfListItem) { + byte[] data = ((RtfListItem) rtfElement).writeDefinition(); + if(data.length > 0) { + result.write(data); + break; + } + } + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Writes the initialisation part of the RtfList + * + * @return A byte array containing the initialisation part + */ + protected byte[] writeListBeginning() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(RtfParagraph.PARAGRAPH_DEFAULTS); + if(this.inTable) { + result.write(RtfParagraph.IN_TABLE); + } + switch (this.alignment) { + case Element.ALIGN_LEFT: + result.write(RtfParagraphStyle.ALIGN_LEFT); + break; + case Element.ALIGN_RIGHT: + result.write(RtfParagraphStyle.ALIGN_RIGHT); + break; + case Element.ALIGN_CENTER: + result.write(RtfParagraphStyle.ALIGN_CENTER); + break; + case Element.ALIGN_JUSTIFIED: + case Element.ALIGN_JUSTIFIED_ALL: + result.write(RtfParagraphStyle.ALIGN_JUSTIFY); + break; + } + result.write(writeIndentations()); + result.write(RtfFont.FONT_SIZE); + result.write(intToByteArray(fontNumber.getFontSize() * 2)); + if(this.symbolIndent > 0) { // TODO This is a slight hack. Replace with a call to tab support when implemented. + result.write("\\tx".getBytes()); + result.write(intToByteArray(this.leftIndent)); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Writes only the list number and list level number. + * + * @return The list number and list level number of this RtfList. + */ + protected byte[] writeListNumbers() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(RtfListTable.LIST_NUMBER); + result.write(intToByteArray(listNumber)); + if(listLevel > 0) { + result.write(LIST_LEVEL_NUMBER); + result.write(intToByteArray(listLevel)); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Writes the content of the RtfList + * + * @return A byte array containing the actual content of the RtfList + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(writeListBeginning()); + result.write(writeListNumbers()); + result.write(OPEN_GROUP); + int itemNr = 0; + for(int i = 0; i < items.size(); i++) { + RtfElement rtfElement = (RtfElement) items.get(i); + if(rtfElement instanceof RtfListItem) { + itemNr++; + result.write(OPEN_GROUP); + result.write(LIST_TEXT); + result.write(RtfParagraph.PARAGRAPH_DEFAULTS); + if(this.inTable) { + result.write(RtfParagraph.IN_TABLE); + } + result.write(RtfFontList.FONT_NUMBER); + if(numbered) { + result.write(intToByteArray(fontNumber.getFontNumber())); + } else { + result.write(intToByteArray(fontBullet.getFontNumber())); + } + result.write(writeIndentations()); + result.write(DELIMITER); + if(numbered) { + result.write(this.intToByteArray(itemNr)); + result.write(LIST_NUMBER_END); + } else { + result.write(LIST_BULLET); + } + result.write(TAB); + result.write(CLOSE_GROUP); + result.write(rtfElement.write()); + result.write(RtfParagraph.PARAGRAPH); + if(((RtfListItem) rtfElement).isContainsInnerList()) { + result.write(writeListNumbers()); + } + result.write("\n".getBytes()); + } else if(rtfElement instanceof RtfList) { + result.write(rtfElement.write()); + result.write(writeListBeginning()); + result.write("\n".getBytes()); + } + } + result.write(CLOSE_GROUP); + if(!this.inTable) { + result.write(RtfParagraph.PARAGRAPH_DEFAULTS); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + + /** + * Gets the list level of this RtfList + * + * @return Returns the list level. + */ + public int getListLevel() { + return listLevel; + } + + /** + * Sets the list level of this RtfList. A list level > 0 will + * unregister this RtfList from the RtfListTable + * + * @param listLevel The list level to set. + */ + public void setListLevel(int listLevel) { + this.listLevel = listLevel; + if(this.listLevel != 0) { + document.getDocumentHeader().freeListNumber(this); + for(int i = 0; i < this.items.size(); i++) { + if(this.items.get(i) instanceof RtfList) { + ((RtfList) this.items.get(i)).setListNumber(this.listNumber); + ((RtfList) this.items.get(i)).setListLevel(this.listLevel + 1); + } + } + } else { + this.listNumber = document.getDocumentHeader().getListNumber(this); + } + } + + /** + * Sets the parent RtfList of this RtfList + * + * @param parent The parent RtfList to use. + */ + protected void setParent(RtfList parent) { + this.parentList = parent; + } + + /** + * Gets the id of this list + * + * @return Returns the list number. + */ + public int getListNumber() { + return listNumber; + } + + /** + * Sets the id of this list + * + * @param listNumber The list number to set. + */ + public void setListNumber(int listNumber) { + this.listNumber = listNumber; + } + + /** + * Sets whether this RtfList is in a table. Sets the correct inTable setting for all + * child elements. + * + * @param inTable True if this RtfList is in a table, false otherwise + */ + public void setInTable(boolean inTable) { + super.setInTable(inTable); + for(int i = 0; i < this.items.size(); i++) { + ((RtfBasicElement) this.items.get(i)).setInTable(inTable); + } + } + + /** + * Sets whether this RtfList is in a header. Sets the correct inTable setting for all + * child elements. + * + * @param inHeader True if this RtfList is in a header, false otherwise + */ + public void setInHeader(boolean inHeader) { + super.setInHeader(inHeader); + for(int i = 0; i < this.items.size(); i++) { + ((RtfBasicElement) this.items.get(i)).setInHeader(inHeader); + } + } + + /** + * Correct the indentation of this RtfList by adding left/first line indentation + * from the parent RtfList. Also calls correctIndentation on all child RtfLists. + */ + protected void correctIndentation() { + if(this.parentList != null) { + this.leftIndent = this.leftIndent + this.parentList.getLeftIndent() + this.parentList.getFirstIndent(); + } + for(int i = 0; i < this.items.size(); i++) { + if(this.items.get(i) instanceof RtfList) { + ((RtfList) this.items.get(i)).correctIndentation(); + } else if(this.items.get(i) instanceof RtfListItem) { + ((RtfListItem) this.items.get(i)).correctIndentation(); + } + } + } + + /** + * Get the left indentation of this RtfList. + * + * @return The left indentation. + */ + private int getLeftIndent() { + return this.leftIndent; + } + + /** + * Get the first line indentation of this RtfList. + * + * @return The first line indentation. + */ + private int getFirstIndent() { + return this.firstIndent; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/list/RtfListItem.java b/src/main/java/com/lowagie/text/rtf/list/RtfListItem.java new file mode 100644 index 0000000..9e5b184 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/list/RtfListItem.java @@ -0,0 +1,182 @@ +/* + * $Id: RtfListItem.java,v 1.11 2006/04/05 09:30:47 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004, 2005 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.list; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.ListItem; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.text.RtfChunk; +import com.lowagie.text.rtf.text.RtfParagraph; + + +/** + * The RtfListItem acts as a wrapper for a ListItem. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfListItem extends RtfParagraph { + + /** + * The RtfList this RtfListItem belongs to. + */ + private RtfList parentList = null; + /** + * Whether this RtfListItem contains further RtfLists. + */ + private boolean containsInnerList = false; + + /** + * Constructs a RtfListItem for a ListItem belonging to a RtfDocument. + * + * @param doc The RtfDocument this RtfListItem belongs to. + * @param listItem The ListItem this RtfListItem is based on. + */ + public RtfListItem(RtfDocument doc, ListItem listItem) { + super(doc, listItem); + } + + /** + * Writes the content of this RtfListItem. + * + * @return A byte array with the content of this RtfListItem. + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + for(int i = 0; i < chunks.size(); i++) { + RtfBasicElement rtfElement = (RtfBasicElement) chunks.get(i); + if(rtfElement instanceof RtfChunk) { + ((RtfChunk) rtfElement).setSoftLineBreaks(true); + } else if(rtfElement instanceof RtfList) { + result.write(RtfParagraph.PARAGRAPH); + this.containsInnerList = true; + } + result.write(rtfElement.write()); + if(rtfElement instanceof RtfList) { + result.write(this.parentList.writeListBeginning()); + result.write("\\tab".getBytes()); + } + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Returns the definition of the first list contained in this RtfListItem or + * an empty byte array if no inner RtfLists exist. + * + * @return The definition of the first inner RtfList or an empty byte array. + */ + public byte[] writeDefinition() { + for(int i = 0; i < chunks.size(); i++) { + RtfBasicElement rtfElement = (RtfBasicElement) chunks.get(i); + if(rtfElement instanceof RtfList) { + return ((RtfList) rtfElement).writeDefinition(); + } + } + return new byte[0]; + } + + /** + * Inherit the list settings from the parent list to RtfLists that + * are contained in this RtfListItem. + * + * @param listNumber The list number to inherit. + * @param listLevel The list level to inherit. + */ + public void inheritListSettings(int listNumber, int listLevel) { + for(int i = 0; i < chunks.size(); i++) { + RtfBasicElement rtfElement = (RtfBasicElement) chunks.get(i); + if(rtfElement instanceof RtfList) { + ((RtfList) rtfElement).setListNumber(listNumber); + ((RtfList) rtfElement).setListLevel(listLevel); + ((RtfList) rtfElement).setParent(this.parentList); + } + } + } + + /** + * Correct the indentation of RtfLists in this RtfListItem by adding left/first line indentation + * from the parent RtfList. Also calls correctIndentation on all child RtfLists. + */ + protected void correctIndentation() { + for(int i = 0; i < chunks.size(); i++) { + RtfBasicElement rtfElement = (RtfBasicElement) chunks.get(i); + if(rtfElement instanceof RtfList) { + ((RtfList) rtfElement).correctIndentation(); + } + } + } + + /** + * Set the parent RtfList. + * + * @param parentList The parent RtfList to use. + */ + public void setParent(RtfList parentList) { + this.parentList = parentList; + } + + /** + * Gets whether this RtfListItem contains further RtfLists. + * + * @return Whether this RtfListItem contains further RtfLists. + */ + public boolean isContainsInnerList() { + return this.containsInnerList; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/list/RtfListTable.java b/src/main/java/com/lowagie/text/rtf/list/RtfListTable.java new file mode 100644 index 0000000..ee10c94 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/list/RtfListTable.java @@ -0,0 +1,202 @@ +/* + * $Id: RtfListTable.java,v 1.16 2005/05/04 14:33:45 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.list; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.RtfExtendedElement; +import com.lowagie.text.rtf.document.RtfDocument; + + +/** + * The RtfListTable manages all RtfLists in one RtfDocument. It also generates + * the list and list override tables in the document header. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfListTable extends RtfElement implements RtfExtendedElement { + + /** + * Constant for the list number + */ + protected static final byte[] LIST_NUMBER = "\\ls".getBytes(); + /** + * Constant for the list table + */ + private static final byte[] LIST_TABLE = "\\*\\listtable".getBytes(); + /** + * Constant for the list + */ + private static final byte[] LIST = "\\list".getBytes(); + /** + * Constant for the list template id + */ + private static final byte[] LIST_TEMPLATE_ID = "\\listtemplateid".getBytes(); + /** + * Constant for the hybrid list + */ + private static final byte[] LIST_HYBRID = "\\hybrid".getBytes(); + /** + * Constant for the list id + */ + private static final byte[] LIST_ID = "\\listid".getBytes(); + /** + * Constant for the list override table + */ + private static final byte[] LIST_OVERRIDE_TABLE = "\\*\\listoverridetable".getBytes(); + /** + * Constant for the list override + */ + private static final byte[] LIST_OVERRIDE = "\\listoverride".getBytes(); + /** + * Constant for the list override count + */ + private static final byte[] LIST_OVERRIDE_COUNT = "\\listoverridecount".getBytes(); + + /** + * The RtfLists managed by this RtfListTable + */ + private ArrayList lists; + + /** + * Constructs a RtfListTable for a RtfDocument + * + * @param doc The RtfDocument this RtfListTable belongs to + */ + public RtfListTable(RtfDocument doc) { + super(doc); + + this.lists = new ArrayList(); + } + + /** + * Writes the list and list override tables. + * + * @return A byte array with the list and list override tables. + */ + public byte[] writeDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + int[] listIds = new int[lists.size()]; + try { + result.write(OPEN_GROUP); + result.write(LIST_TABLE); + result.write("\n".getBytes()); + for(int i = 0; i < lists.size(); i++) { + result.write(OPEN_GROUP); + result.write(LIST); + result.write(LIST_TEMPLATE_ID); + result.write(intToByteArray(document.getRandomInt())); + result.write(LIST_HYBRID); + result.write("\n".getBytes()); + result.write(((RtfList) lists.get(i)).writeDefinition()); + result.write(LIST_ID); + listIds[i] = document.getRandomInt(); + result.write(intToByteArray(listIds[i])); + result.write(CLOSE_GROUP); + result.write("\n".getBytes()); + } + result.write(CLOSE_GROUP); + result.write("\n".getBytes()); + result.write(OPEN_GROUP); + result.write(LIST_OVERRIDE_TABLE); + result.write("\n".getBytes()); + for(int i = 0; i < lists.size(); i++) { + result.write(OPEN_GROUP); + result.write(LIST_OVERRIDE); + result.write(LIST_ID); + result.write(intToByteArray(listIds[i])); + result.write(LIST_OVERRIDE_COUNT); + result.write(intToByteArray(0)); + result.write(LIST_NUMBER); + result.write(intToByteArray(((RtfList) lists.get(i)).getListNumber())); + result.write(CLOSE_GROUP); + result.write("\n".getBytes()); + } + result.write(CLOSE_GROUP); + result.write("\n".getBytes()); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Gets the id of the specified RtfList. If the RtfList is not yet in the + * list of RtfLists, then it is added. + * + * @param list The RtfList for which to get the id. + * @return The id of the RtfList. + */ + public int getListNumber(RtfList list) { + if(lists.contains(list)) { + return lists.indexOf(list); + } else { + lists.add(list); + return lists.size(); + } + } + + /** + * Remove a RtfList from the list of RtfLists + * + * @param list The RtfList to remove. + */ + public void freeListNumber(RtfList list) { + int i = lists.indexOf(list); + if(i >= 0) { + lists.remove(i); + } + } +} diff --git a/src/main/java/com/lowagie/text/rtf/style/RtfColor.java b/src/main/java/com/lowagie/text/rtf/style/RtfColor.java new file mode 100644 index 0000000..aca4ea2 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/style/RtfColor.java @@ -0,0 +1,302 @@ +/* + * $Id: RtfColor.java,v 1.7 2004/12/14 12:51:59 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.style; + +import java.awt.Color; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.RtfExtendedElement; +import com.lowagie.text.rtf.document.RtfDocument; + + +/** + * The RtfColor stores one rtf color value for a rtf document + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfColor extends RtfElement implements RtfExtendedElement { + + /** + * Constant for RED value + */ + private static final byte[] COLOR_RED = "\\red".getBytes(); + /** + * Constant for GREEN value + */ + private static final byte[] COLOR_GREEN = "\\green".getBytes(); + /** + * Constant for BLUE value + */ + private static final byte[] COLOR_BLUE = "\\blue".getBytes(); + /** + * Constant for the end of one color entry + */ + private static final byte COLON = (byte) ';'; + /** + * Constant for the number of the colour in the list of colours + */ + private static final byte[] COLOR_NUMBER = "\\cf".getBytes(); + + /** + * The number of the colour in the list of colours + */ + private int colorNumber = 0; + /** + * The red value + */ + private int red = 0; + /** + * The green value + */ + private int green = 0; + /** + * The blue value + */ + private int blue = 0; + + /** + * Constructor only for use when initializing the RtfColorList + * + * @param doc The RtfDocument this RtfColor belongs to + * @param red The red value to use + * @param green The green value to use + * @param blue The blue value to use + * @param colorNumber The number of the colour in the colour list + */ + protected RtfColor(RtfDocument doc, int red, int green, int blue, int colorNumber) { + super(doc); + this.red = red; + this.blue = blue; + this.green = green; + this.colorNumber = colorNumber; + } + + /** + * Constructs a RtfColor as a clone of an existing RtfColor + * + * @param doc The RtfDocument this RtfColor belongs to + * @param col The RtfColor to use as a base + */ + public RtfColor(RtfDocument doc, RtfColor col) { + super(doc); + if(col != null) { + this.red = col.getRed(); + this.green = col.getGreen(); + this.blue = col.getBlue(); + } + if(this.document != null) { + this.colorNumber = this.document.getDocumentHeader().getColorNumber(this); + } + } + + /** + * Constructs a RtfColor based on the Color + * + * @param doc The RtfDocument this RtfColor belongs to + * @param col The Color to base this RtfColor on + */ + public RtfColor(RtfDocument doc, Color col) { + super(doc); + if(col != null) { + this.red = col.getRed(); + this.blue = col.getBlue(); + this.green = col.getGreen(); + } + if(this.document != null) { + this.colorNumber = this.document.getDocumentHeader().getColorNumber(this); + } + } + + /** + * Constructs a RtfColor based on the red/green/blue values + * + * @param doc The RtfDocument this RtfColor belongs to + * @param red The red value to use + * @param green The green value to use + * @param blue The blue value to use + */ + public RtfColor(RtfDocument doc, int red, int green, int blue) { + super(doc); + this.red = red; + this.blue = blue; + this.green = green; + if(this.document != null) { + this.colorNumber = this.document.getDocumentHeader().getColorNumber(this); + } + } + + /** + * Write the definition part of this RtfColor. + * + * @return A byte array with the definition of this colour + */ + public byte[] writeDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(COLOR_RED); + result.write(intToByteArray(red)); + result.write(COLOR_GREEN); + result.write(intToByteArray(green)); + result.write(COLOR_BLUE); + result.write(intToByteArray(blue)); + result.write(COLON); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Writes the beginning of this RtfColor + * + * @return A byte array with the colour start data + */ + public byte[] writeBegin() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(COLOR_NUMBER); + result.write(intToByteArray(colorNumber)); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Unused + * + * @return An empty (byte[0]) byte array + */ + public byte[] writeEnd() { + return new byte[0]; + } + + /** + * Tests if this RtfColor is equal to another RtfColor. + * + * @param obj another RtfColor + * @return True if red, green and blue values of the two colours match, + * false otherwise. + */ + public boolean equals(Object obj) { + if(!(obj instanceof RtfColor)) { + return false; + } + RtfColor color = (RtfColor) obj; + if(this.red == color.getRed() && this.green == color.getGreen() && this.blue == color.getBlue()) { + return true; + } else { + return false; + } + } + + /** + * Returns the hash code of this RtfColor. The hash code is + * an integer with the lowest three bytes containing the values + * of red, green and blue. + * + * @return The hash code of this RtfColor + */ + public int hashCode() { + return (this.red << 16) | (this.green << 8) | this.blue; + } + + /** + * Get the blue value of this RtfColor + * + * @return The blue value + */ + public int getBlue() { + return blue; + } + + /** + * Get the green value of this RtfColor + * + * @return The green value + */ + public int getGreen() { + return green; + } + + /** + * Get the red value of this RtfColor + * + * @return The red value + */ + public int getRed() { + return red; + } + + /** + * Gets the number of this RtfColor in the list of colours + * + * @return Returns the colorNumber. + */ + public int getColorNumber() { + return colorNumber; + } + + /** + * Sets the RtfDocument this RtfColor belongs to + * + * @param doc The RtfDocument to use + */ + public void setRtfDocument(RtfDocument doc) { + super.setRtfDocument(doc); + if(document != null) { + this.colorNumber = document.getDocumentHeader().getColorNumber(this); + } + } +} diff --git a/src/main/java/com/lowagie/text/rtf/style/RtfColorList.java b/src/main/java/com/lowagie/text/rtf/style/RtfColorList.java new file mode 100644 index 0000000..ddb71d1 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/style/RtfColorList.java @@ -0,0 +1,137 @@ +/* + * $Id: RtfColorList.java,v 1.16 2005/05/04 14:33:52 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.style; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.RtfExtendedElement; +import com.lowagie.text.rtf.document.RtfDocument; + + +/** + * The RtfColorList stores all colours that appear in the document. Black + * and White are always added + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfColorList extends RtfElement implements RtfExtendedElement { + + /** + * Constant for the beginning of the colour table + */ + private static final byte[] COLOR_TABLE = "\\colortbl".getBytes(); + + /** + * ArrayList containing all colours of this RtfColorList + */ + ArrayList colorList = new ArrayList(); + + /** + * Constructs a new RtfColorList for the RtfDocument. Will add the default + * black and white colours. + * + * @param doc The RtfDocument this RtfColorList belongs to + */ + public RtfColorList(RtfDocument doc) { + super(doc); + colorList.add(new RtfColor(doc, 0, 0, 0, 0)); + colorList.add(new RtfColor(doc, 255, 255, 255, 1)); + } + + /** + * Returns the index of the given RtfColor in the colour list. If the RtfColor + * is not in the list of colours, then it is added. + * + * @param color The RtfColor for which to get the index + * @return The index of the RtfColor + */ + public int getColorNumber(RtfColor color) { + int colorIndex = -1; + for(int i = 0; i < colorList.size(); i++) { + if(colorList.get(i).equals(color)) { + colorIndex = i; + } + } + if(colorIndex == -1) { + colorIndex = colorList.size(); + colorList.add(color); + } + return colorIndex; + } + + /** + * Write the definition part of the colour list. Calls the writeDefinition + * methods of the RtfColors in the colour list. + * + * @return A byte array with the definition colour list + */ + public byte[] writeDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(OPEN_GROUP); + result.write(COLOR_TABLE); + for(int i = 0; i < colorList.size(); i++) { + RtfColor color = (RtfColor) colorList.get(i); + result.write(color.writeDefinition()); + } + result.write(CLOSE_GROUP); + result.write((byte)'\n'); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + +} diff --git a/src/main/java/com/lowagie/text/rtf/style/RtfFont.java b/src/main/java/com/lowagie/text/rtf/style/RtfFont.java new file mode 100644 index 0000000..150b0b2 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/style/RtfFont.java @@ -0,0 +1,681 @@ +/* + * $Id: RtfFont.java,v 1.23 2006/02/09 17:11:31 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.style; + +import com.lowagie.text.rtf.RtfExtendedElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.Font; + +import java.awt.Color; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * The RtfFont class stores one font for an rtf document. It extends Font, + * so can be set as a font, to allow adding of fonts with arbitrary names. + * BaseFont fontname handling contributed by Craig Fleming. Various fixes + * Renaud Michel, Werner Daehn. + * + * Version: $Id: RtfFont.java,v 1.23 2006/02/09 17:11:31 hallm Exp $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Craig Fleming (rythos@rhana.dhs.org) + * @author Renaud Michel (r.michel@immedia.be) + * @author Werner Daehn (Werner.Daehn@BusinessObjects.com) + */ +public class RtfFont extends Font implements RtfExtendedElement { + /** + * Constant for the font family to use ("froman") + */ + private static final byte[] FONT_FAMILY = "\\froman".getBytes(); + /** + * Constant for the charset + */ + private static final byte[] FONT_CHARSET = "\\fcharset".getBytes(); + /** + * Constant for the font size + */ + public static final byte[] FONT_SIZE = "\\fs".getBytes(); + /** + * Constant for the bold flag + */ + private static final byte[] FONT_BOLD = "\\b".getBytes(); + /** + * Constant for the italic flag + */ + private static final byte[] FONT_ITALIC = "\\i".getBytes(); + /** + * Constant for the underline flag + */ + private static final byte[] FONT_UNDERLINE = "\\ul".getBytes(); + /** + * Constant for the strikethrough flag + */ + private static final byte[] FONT_STRIKETHROUGH = "\\strike".getBytes(); + /** + * Constant for the double strikethrough flag + */ + private static final byte[] FONT_DOUBLE_STRIKETHROUGH = "\\striked".getBytes(); + /** + * Constant for the shadow flag + */ + private static final byte[] FONT_SHADOW = "\\shad".getBytes(); + /** + * Constant for the outline flag + */ + private static final byte[] FONT_OUTLINE = "\\outl".getBytes(); + /** + * Constant for the embossed flag + */ + private static final byte[] FONT_EMBOSSED = "\\embo".getBytes(); + /** + * Constant for the engraved flag + */ + private static final byte[] FONT_ENGRAVED = "\\impr".getBytes(); + /** + * Constant for hidden text flag + */ + private static final byte[] FONT_HIDDEN = "\\v".getBytes(); + + /** + * Constant for a plain font + */ + public static final int STYLE_NONE = 0; + /** + * Constant for a bold font + */ + public static final int STYLE_BOLD = 1; + /** + * Constant for an italic font + */ + public static final int STYLE_ITALIC = 2; + /** + * Constant for an underlined font + */ + public static final int STYLE_UNDERLINE = 4; + /** + * Constant for a strikethrough font + */ + public static final int STYLE_STRIKETHROUGH = 8; + /** + * Constant for a double strikethrough font + */ + public static final int STYLE_DOUBLE_STRIKETHROUGH = 16; + /** + * Constant for a shadowed font + */ + public static final int STYLE_SHADOW = 32; + /** + * Constant for an outlined font + */ + public static final int STYLE_OUTLINE = 64; + /** + * Constant for an embossed font + */ + public static final int STYLE_EMBOSSED = 128; + /** + * Constant for an engraved font + */ + public static final int STYLE_ENGRAVED = 256; + /** + * Constant for a font that hides the actual text. + */ + public static final int STYLE_HIDDEN = 512; + + /** + * The font name. Defaults to "Times New Roman" + */ + private String fontName = "Times New Roman"; + /** + * The font size. Defaults to 10 + */ + private int fontSize = 10; + /** + * The font style. Defaults to STYLE_NONE + */ + private int fontStyle = STYLE_NONE; + /** + * The number of this font + */ + private int fontNumber = 0; + /** + * The colour of this font + */ + private RtfColor color = null; + /** + * The character set to use for this font + */ + private int charset = 0; + /** + * The RtfDocument this RtfFont belongs to. + */ + protected RtfDocument document = null; + + /** + * Constructs a RtfFont with the given font name and all other properties + * at their default values. + * + * @param fontName The font name to use + */ + public RtfFont(String fontName) { + super(Font.UNDEFINED, Font.UNDEFINED, Font.UNDEFINED, null); + this.fontName = fontName; + } + + /** + * Constructs a RtfFont with the given font name and font size and all other + * properties at their default values. + * + * @param fontName The font name to use + * @param size The font size to use + */ + public RtfFont(String fontName, float size) { + super(Font.UNDEFINED, size, Font.UNDEFINED, null); + this.fontName = fontName; + } + + /** + * Constructs a RtfFont with the given font name, font size and font style and the + * default color. + * + * @param fontName The font name to use + * @param size The font size to use + * @param style The font style to use + */ + public RtfFont(String fontName, float size, int style) { + super(Font.UNDEFINED, size, style, null); + this.fontName = fontName; + } + + /** + * Constructs a RtfFont with the given font name, font size, font style and + * color. + * + * @param fontName The font name to use + * @param size the font size to use + * @param style The font style to use + * @param color The font color to use + */ + public RtfFont(String fontName, float size, int style, Color color) { + super(Font.UNDEFINED, size, style, color); + this.fontName = fontName; + } + + /** + * Special constructor for the default font + * + * @param doc The RtfDocument this font appears in + * @param fontNumber The id of this font + */ + protected RtfFont(RtfDocument doc, int fontNumber) { + this.document = doc; + this.fontNumber = fontNumber; + color = new RtfColor(doc, 0, 0, 0); + } + + /** + * Constructs a RtfFont from a com.lowagie.text.Font + * @param doc The RtfDocument this font appears in + * @param font The Font to use as a base + */ + public RtfFont(RtfDocument doc, Font font) { + this.document = doc; + if(font != null) { + if(font instanceof RtfFont) { + this.fontName = ((RtfFont) font).getFontName(); + } else { + setToDefaultFamily(font.getFamilyname()); + } + if(font.getBaseFont() != null) { + String[][] fontNames = font.getBaseFont().getFullFontName(); + for(int i = 0; i < fontNames.length; i++) { + if(fontNames[i][2].equals("0")) { + this.fontName = fontNames[i][3]; + break; + } else if(fontNames[i][2].equals("1033") || fontNames[i][2].equals("")) { + this.fontName = fontNames[i][3]; + } + } + } + + setSize(font.size()); + setStyle(font.style()); + setColor(font.color()); + } + + if(this.fontName.equalsIgnoreCase("unknown")) { + return; + } + + if(document != null) { + setRtfDocument(document); + } + } + + /** + * Writes the font definition + * + * @return A byte array with the font definition + */ + public byte[] writeDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(FONT_FAMILY); + result.write(FONT_CHARSET); + result.write(intToByteArray(charset)); + result.write(DELIMITER); + result.write(document.filterSpecialChar(fontName, true, false).getBytes()); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Writes the font beginning + * + * @return A byte array with the font start data + */ + public byte[] writeBegin() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(this.fontNumber != Font.UNDEFINED) { + result.write(RtfFontList.FONT_NUMBER); + result.write(intToByteArray(fontNumber)); + } + if(this.fontSize != Font.UNDEFINED) { + result.write(FONT_SIZE); + result.write(intToByteArray(fontSize * 2)); + } + if(this.fontStyle != UNDEFINED) { + if((fontStyle & STYLE_BOLD) == STYLE_BOLD) { + result.write(FONT_BOLD); + } + if((fontStyle & STYLE_ITALIC) == STYLE_ITALIC) { + result.write(FONT_ITALIC); + } + if((fontStyle & STYLE_UNDERLINE) == STYLE_UNDERLINE) { + result.write(FONT_UNDERLINE); + } + if((fontStyle & STYLE_STRIKETHROUGH) == STYLE_STRIKETHROUGH) { + result.write(FONT_STRIKETHROUGH); + } + if((fontStyle & STYLE_HIDDEN) == STYLE_HIDDEN) { + result.write(FONT_HIDDEN); + } + if((fontStyle & STYLE_DOUBLE_STRIKETHROUGH) == STYLE_DOUBLE_STRIKETHROUGH) { + result.write(FONT_DOUBLE_STRIKETHROUGH); + result.write(intToByteArray(1)); + } + if((fontStyle & STYLE_SHADOW) == STYLE_SHADOW) { + result.write(FONT_SHADOW); + } + if((fontStyle & STYLE_OUTLINE) == STYLE_OUTLINE) { + result.write(FONT_OUTLINE); + } + if((fontStyle & STYLE_EMBOSSED) == STYLE_EMBOSSED) { + result.write(FONT_EMBOSSED); + } + if((fontStyle & STYLE_ENGRAVED) == STYLE_ENGRAVED) { + result.write(FONT_ENGRAVED); + } + } + if(color != null) { + result.write(color.writeBegin()); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Write the font end + * + * @return A byte array with the end of font data + */ + public byte[] writeEnd() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(this.fontStyle != UNDEFINED) { + if((fontStyle & STYLE_BOLD) == STYLE_BOLD) { + result.write(FONT_BOLD); + result.write(intToByteArray(0)); + } + if((fontStyle & STYLE_ITALIC) == STYLE_ITALIC) { + result.write(FONT_ITALIC); + result.write(intToByteArray(0)); + } + if((fontStyle & STYLE_UNDERLINE) == STYLE_UNDERLINE) { + result.write(FONT_UNDERLINE); + result.write(intToByteArray(0)); + } + if((fontStyle & STYLE_STRIKETHROUGH) == STYLE_STRIKETHROUGH) { + result.write(FONT_STRIKETHROUGH); + result.write(intToByteArray(0)); + } + if((fontStyle & STYLE_HIDDEN) == STYLE_HIDDEN) { + result.write(FONT_HIDDEN); + result.write(intToByteArray(0)); + } + if((fontStyle & STYLE_DOUBLE_STRIKETHROUGH) == STYLE_DOUBLE_STRIKETHROUGH) { + result.write(FONT_DOUBLE_STRIKETHROUGH); + result.write(intToByteArray(0)); + } + if((fontStyle & STYLE_SHADOW) == STYLE_SHADOW) { + result.write(FONT_SHADOW); + result.write(intToByteArray(0)); + } + if((fontStyle & STYLE_OUTLINE) == STYLE_OUTLINE) { + result.write(FONT_OUTLINE); + result.write(intToByteArray(0)); + } + if((fontStyle & STYLE_EMBOSSED) == STYLE_EMBOSSED) { + result.write(FONT_EMBOSSED); + result.write(intToByteArray(0)); + } + if((fontStyle & STYLE_ENGRAVED) == STYLE_ENGRAVED) { + result.write(FONT_ENGRAVED); + result.write(intToByteArray(0)); + } + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Unused + * @return an empty byte array + */ + public byte[] write() { + return new byte[0]; + } + + /** + * Tests for equality of RtfFonts. RtfFonts are equal if their fontName, + * fontSize, fontStyle and fontSuperSubscript are equal + * + * @param obj The RtfFont to compare with this RtfFont + * @return True if the RtfFonts are equal, false otherwise + */ + public boolean equals(Object obj) { + if(!(obj instanceof RtfFont)) { + return false; + } + RtfFont font = (RtfFont) obj; + boolean result = true; + result = result & this.fontName.equals(font.getFontName()); + + return result; + } + + /** + * Returns the hash code of this RtfFont. The hash code is the hash code of the + * string containing the font name + font size + "-" + the font style + "-" + the + * font super/supscript value. + * + * @return The hash code of this RtfFont + */ + public int hashCode() { + return (this.fontName + this.fontSize + "-" + this.fontStyle).hashCode(); + } + + /** + * Gets the font name of this RtfFont + * + * @return The font name + */ + public String getFontName() { + return this.fontName; + } + + /** + * Sets the font name of this RtfFont. + * + * @param fontName The font name to use + */ + protected void setFontName(String fontName) { + this.fontName = fontName; + if(document != null) { + this.fontNumber = document.getDocumentHeader().getFontNumber(this); + } + } + + /** + * @see com.lowagie.text.Font#getFamilyname() + */ + public String getFamilyname() { + return this.fontName; + } + + /** + * @see com.lowagie.text.Font#setFamily(String) + */ + public void setFamily(String family){ + super.setFamily(family); + setToDefaultFamily(family); + } + + /** + * Sets the correct font name from the family name. + * + * @param familyname The family name to set the name to. + */ + private void setToDefaultFamily(String familyname){ + switch (Font.getFamilyIndex(familyname)) { + case Font.COURIER: + this.fontName = "Courier"; + break; + case Font.HELVETICA: + this.fontName = "Arial"; + break; + case Font.SYMBOL: + this.fontName = "Symbol"; + this.charset = 2; + break; + case Font.TIMES_ROMAN: + this.fontName = "Times New Roman"; + break; + case Font.ZAPFDINGBATS: + this.fontName = "Windings"; + break; + default: + this.fontName = familyname; + } + } + + /** + * Gets the font size of this RtfFont + * + * @return The font size + */ + public int getFontSize() { + return this.fontSize; + } + + /** + * @see com.lowagie.text.Font#setSize(float) + */ + public void setSize(float size){ + super.setSize(size); + this.fontSize = (int) size(); + } + + /** + * Gets the font style of this RtfFont + * + * @return The font style + */ + public int getFontStyle() { + return this.fontStyle; + } + + /** + * @see com.lowagie.text.Font#setStyle(int) + */ + public void setStyle(int style){ + super.setStyle(style); + this.fontStyle = style(); + } + + /** + * @see com.lowagie.text.Font#setStyle(String) + */ + public void setStyle(String style) { + super.setStyle(style); + fontStyle = style(); + } + + /** + * Gets the font number of this RtfFont + * + * @return The font number + */ + public int getFontNumber() { + return fontNumber; + } + + /** + * Sets the RtfDocument this RtfFont belongs to + * + * @param doc The RtfDocument to use + */ + public void setRtfDocument(RtfDocument doc) { + this.document = doc; + if(document != null) { + this.fontNumber = document.getDocumentHeader().getFontNumber(this); + } + if(this.color != null) { + this.color.setRtfDocument(this.document); + } + } + + /** + * Unused + * @param inTable + */ + public void setInTable(boolean inTable) { + } + + /** + * Unused + * @param inHeader + */ + public void setInHeader(boolean inHeader) { + } + + /** + * @see com.lowagie.text.Font#setColor(Color) + */ + public void setColor(Color color) { + super.setColor(color); + if(color != null) { + this.color = new RtfColor(document, color); + } else { + this.color = null; + } + } + + /** + * @see com.lowagie.text.Font#setColor(int, int, int) + */ + public void setColor(int red, int green, int blue) { + super.setColor(red,green,blue); + this.color = new RtfColor(document, red, green, blue); + } + + /** + * Transforms an integer into its String representation and then returns the bytes + * of that string. + * + * @param i The integer to convert + * @return A byte array representing the integer + */ + protected byte[] intToByteArray(int i) { + return Integer.toString(i).getBytes(); + } + + /** + * Replaces the attributes that are equal to null with + * the attributes of a given font. + * + * @param font The surrounding font + * @return A RtfFont + */ + public Font difference(Font font) { + String dFamilyname = font.getFamilyname(); + if(dFamilyname == null || dFamilyname.trim().equals("") || dFamilyname.trim().equalsIgnoreCase("unknown")) { + dFamilyname = this.fontName; + } + + float dSize = font.size(); + if(dSize == Font.UNDEFINED) { + dSize = this.size(); + } + + int dStyle = Font.UNDEFINED; + if(this.style() != Font.UNDEFINED && font.style() != Font.UNDEFINED) { + dStyle = this.style() | font.style(); + } else if(this.style() != Font.UNDEFINED) { + dStyle = this.style(); + } else if(font.style() != Font.UNDEFINED) { + dStyle = font.style(); + } + + Color dColor = font.color(); + if(dColor == null) { + dColor = this.color(); + } + + return new RtfFont(dFamilyname, dSize, dStyle, dColor); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/style/RtfFontList.java b/src/main/java/com/lowagie/text/rtf/style/RtfFontList.java new file mode 100644 index 0000000..6e90371 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/style/RtfFontList.java @@ -0,0 +1,149 @@ +/* + * $Id: RtfFontList.java,v 1.17 2005/12/24 13:10:37 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.style; + +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.RtfExtendedElement; +import com.lowagie.text.rtf.document.RtfDocument; + +import java.util.ArrayList; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * The RtfFontList stores the list of fonts used in the rtf document. It also + * has methods for writing this list to the document + * + * Version: $Id: RtfFontList.java,v 1.17 2005/12/24 13:10:37 hallm Exp $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfFontList extends RtfElement implements RtfExtendedElement { + + /** + * Constant for the default font + */ + private static final byte[] DEFAULT_FONT = "\\deff".getBytes(); + /** + * Constant for the font table + */ + private static final byte[] FONT_TABLE = "\\fonttbl".getBytes(); + /** + * Constant for the font number + */ + public static final byte[] FONT_NUMBER = "\\f".getBytes(); + + /** + * The list of fonts + */ + private ArrayList fontList = new ArrayList(); + + /** + * Creates a RtfFontList + * + * @param doc The RtfDocument this RtfFontList belongs to + */ + public RtfFontList(RtfDocument doc) { + super(doc); + fontList.add(new RtfFont(document, 0)); + } + + /** + * Gets the index of the font in the list of fonts. If the font does not + * exist in the list, it is added. + * + * @param font The font to get the id for + * @return The index of the font + */ + public int getFontNumber(RtfFont font) { + if(font instanceof RtfParagraphStyle) { + font = new RtfFont(this.document, (RtfParagraphStyle) font); + } + int fontIndex = -1; + for(int i = 0; i < fontList.size(); i++) { + if(fontList.get(i).equals(font)) { + fontIndex = i; + } + } + if(fontIndex == -1) { + fontIndex = fontList.size(); + fontList.add(font); + } + return fontIndex; + } + + /** + * Writes the definition of the font list + * + * @return A byte array with the definition of the font list + */ + public byte[] writeDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(DEFAULT_FONT); + result.write(intToByteArray(0)); + result.write(OPEN_GROUP); + result.write(FONT_TABLE); + for(int i = 0; i < fontList.size(); i++) { + result.write(OPEN_GROUP); + result.write(FONT_NUMBER); + result.write(intToByteArray(i)); + result.write(((RtfFont) fontList.get(i)).writeDefinition()); + result.write(COMMA_DELIMITER); + result.write(CLOSE_GROUP); + } + result.write(CLOSE_GROUP); + result.write((byte)'\n'); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/style/RtfParagraphStyle.java b/src/main/java/com/lowagie/text/rtf/style/RtfParagraphStyle.java new file mode 100644 index 0000000..d8c582c --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/style/RtfParagraphStyle.java @@ -0,0 +1,665 @@ +package com.lowagie.text.rtf.style; + +import java.awt.Color; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.Element; +import com.lowagie.text.Font; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.text.RtfParagraph; + +/** + * The RtfParagraphStyle stores all style/formatting attributes of a RtfParagraph. + * Additionally it also supports the style name system available in RTF. The RtfParagraphStyle + * is a Font and can thus be used as such. To use the stylesheet functionality + * it needs to be set as the font of a Paragraph. Otherwise it will work like a + * RtfFont. It also supports inheritance of styles. + * + * @version $Revision: 1.4 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfParagraphStyle extends RtfFont { + + /** + * Constant for left alignment + */ + public static final byte[] ALIGN_LEFT = "\\ql".getBytes(); + /** + * Constant for right alignment + */ + public static final byte[] ALIGN_RIGHT = "\\qr".getBytes(); + /** + * Constant for center alignment + */ + public static final byte[] ALIGN_CENTER = "\\qc".getBytes(); + /** + * Constant for justified alignment + */ + public static final byte[] ALIGN_JUSTIFY = "\\qj".getBytes(); + /** + * Constant for left indentation + */ + public static final byte[] INDENT_LEFT = "\\li".getBytes(); + /** + * Constant for right indentation + */ + public static final byte[] INDENT_RIGHT = "\\ri".getBytes(); + /** + * Constant for keeping the paragraph together on one page + */ + public static final byte[] KEEP_TOGETHER = "\\keep".getBytes(); + /** + * Constant for keeping the paragraph toghether with the next one on one page + */ + public static final byte[] KEEP_TOGETHER_WITH_NEXT = "\\keepn".getBytes(); + /** + * Constant for the space after the paragraph. + */ + public static final byte[] SPACING_AFTER = "\\sa".getBytes(); + /** + * Constant for the space before the paragraph. + */ + public static final byte[] SPACING_BEFORE = "\\sb".getBytes(); + + /** + * The NORMAL/STANDARD style. + */ + public static final RtfParagraphStyle STYLE_NORMAL = new RtfParagraphStyle("Normal", "Arial", 12, Font.NORMAL, Color.black); + /** + * The style for level 1 headings. + */ + public static final RtfParagraphStyle STYLE_HEADING_1 = new RtfParagraphStyle("heading 1", "Normal"); + /** + * The style for level 2 headings. + */ + public static final RtfParagraphStyle STYLE_HEADING_2 = new RtfParagraphStyle("heading 2", "Normal"); + /** + * The style for level 3 headings. + */ + public static final RtfParagraphStyle STYLE_HEADING_3 = new RtfParagraphStyle("heading 3", "Normal"); + + /** + * Initialises the properties of the styles. + */ + static { + STYLE_HEADING_1.setSize(16); + STYLE_HEADING_1.setStyle(Font.BOLD); + STYLE_HEADING_2.setSize(14); + STYLE_HEADING_2.setStyle(Font.BOLDITALIC); + STYLE_HEADING_3.setSize(13); + STYLE_HEADING_3.setStyle(Font.BOLD); + } + + /** + * No modification has taken place when compared to the RtfParagraphStyle this RtfParagraphStyle + * is based on. These modification markers are used to determine what needs to be + * inherited and what not from the parent RtfParagraphStyle. + */ + private static final int MODIFIED_NONE = 0; + /** + * The alignment has been modified. + */ + private static final int MODIFIED_ALIGNMENT = 1; + /** + * The left indentation has been modified. + */ + private static final int MODIFIED_INDENT_LEFT = 2; + /** + * The right indentation has been modified. + */ + private static final int MODIFIED_INDENT_RIGHT = 4; + /** + * The spacing before a paragraph has been modified. + */ + private static final int MODIFIED_SPACING_BEFORE = 8; + /** + * The spacing after a paragraph has been modified. + */ + private static final int MODIFIED_SPACING_AFTER = 16; + /** + * The font name has been modified. + */ + private static final int MODIFIED_FONT_NAME = 32; + /** + * The font style has been modified. + */ + private static final int MODIFIED_FONT_SIZE = 64; + /** + * The font size has been modified. + */ + private static final int MODIFIED_FONT_STYLE = 128; + /** + * The font colour has been modified. + */ + private static final int MODIFIED_FONT_COLOR = 256; + /** + * The line leading has been modified. + */ + private static final int MODIFIED_LINE_LEADING = 512; + /** + * The paragraph keep together setting has been modified. + */ + private static final int MODIFIED_KEEP_TOGETHER = 1024; + /** + * The paragraph keep together with next setting has been modified. + */ + private static final int MODIFIED_KEEP_TOGETHER_WITH_NEXT = 2048; + + /** + * The alignment of the paragraph. + */ + private int alignment = Element.ALIGN_LEFT; + /** + * The left indentation of the paragraph. + */ + private int indentLeft = 0; + /** + * The right indentation of the paragraph. + */ + private int indentRight = 0; + /** + * The spacing before a paragraph. + */ + private int spacingBefore = 0; + /** + * The spacing after a paragraph. + */ + private int spacingAfter = 0; + /** + * The line leading of the paragraph. + */ + private int lineLeading = 0; + /** + * Whether this RtfParagraph must stay on one page. + */ + private boolean keepTogether = false; + /** + * Whether this RtfParagraph must stay on the same page as the next paragraph. + */ + private boolean keepTogetherWithNext = false; + /** + * The name of this RtfParagraphStyle. + */ + private String styleName = ""; + /** + * The name of the RtfParagraphStyle this RtfParagraphStyle is based on. + */ + private String basedOnName = null; + /** + * The RtfParagraphStyle this RtfParagraphStyle is based on. + */ + private RtfParagraphStyle baseStyle = null; + /** + * Which properties have been modified when compared to the base style. + */ + private int modified = MODIFIED_NONE; + /** + * The number of this RtfParagraphStyle in the stylesheet list. + */ + private int styleNumber = -1; + + /** + * Constructs a new RtfParagraphStyle with the given attributes. + * + * @param styleName The name of this RtfParagraphStyle. + * @param fontName The name of the font to use for this RtfParagraphStyle. + * @param fontSize The size of the font to use for this RtfParagraphStyle. + * @param fontStyle The style of the font to use for this RtfParagraphStyle. + * @param fontColor The colour of the font to use for this RtfParagraphStyle. + */ + public RtfParagraphStyle(String styleName, String fontName, int fontSize, int fontStyle, Color fontColor) { + super(null, new RtfFont(fontName, fontSize, fontStyle, fontColor)); + this.styleName = styleName; + } + + /** + * Constructs a new RtfParagraphStyle that is based on an existing RtfParagraphStyle. + * + * @param styleName The name of this RtfParagraphStyle. + * @param basedOnName The name of the RtfParagraphStyle this RtfParagraphStyle is based on. + */ + public RtfParagraphStyle(String styleName, String basedOnName) { + super(null, new Font()); + this.styleName = styleName; + this.basedOnName = basedOnName; + } + + /** + * Constructs a RtfParagraphStyle from another RtfParagraphStyle. + * + * INTERNAL USE ONLY + * + * @param doc The RtfDocument this RtfParagraphStyle belongs to. + * @param style The RtfParagraphStyle to copy settings from. + */ + public RtfParagraphStyle(RtfDocument doc, RtfParagraphStyle style) { + super(doc, style); + this.document = doc; + this.styleName = style.getStyleName(); + this.alignment = style.getAlignment(); + this.indentLeft = (int) (style.getIndentLeft() * RtfBasicElement.TWIPS_FACTOR); + this.indentRight = (int) (style.getIndentRight() * RtfBasicElement.TWIPS_FACTOR); + this.spacingBefore = (int) (style.getSpacingBefore() * RtfBasicElement.TWIPS_FACTOR); + this.spacingAfter = (int) (style.getSpacingAfter() * RtfBasicElement.TWIPS_FACTOR); + this.lineLeading = (int) (style.getLineLeading() * RtfBasicElement.TWIPS_FACTOR); + this.keepTogether = style.getKeepTogether(); + this.keepTogetherWithNext = style.getKeepTogetherWithNext(); + this.basedOnName = style.basedOnName; + this.modified = style.modified; + this.styleNumber = style.getStyleNumber(); + + if(this.document != null) { + setRtfDocument(this.document); + } + } + + /** + * Gets the name of this RtfParagraphStyle. + * + * @return The name of this RtfParagraphStyle. + */ + public String getStyleName() { + return this.styleName; + } + + /** + * Gets the name of the RtfParagraphStyle this RtfParagraphStyle is based on. + * + * @return The name of the base RtfParagraphStyle. + */ + public String getBasedOnName() { + return this.basedOnName; + } + + /** + * Gets the alignment of this RtfParagraphStyle. + * + * @return The alignment of this RtfParagraphStyle. + */ + public int getAlignment() { + return this.alignment; + } + + /** + * Sets the alignment of this RtfParagraphStyle. + * + * @param alignment The alignment to use. + */ + public void setAlignment(int alignment) { + this.modified = this.modified | MODIFIED_ALIGNMENT; + this.alignment = alignment; + } + + /** + * Gets the left indentation of this RtfParagraphStyle. + * + * @return The left indentation of this RtfParagraphStyle. + */ + public int getIndentLeft() { + return this.indentLeft; + } + + /** + * Sets the left indentation of this RtfParagraphStyle. + * + * @param indentLeft The left indentation to use. + */ + public void setIndentLeft(int indentLeft) { + this.modified = this.modified | MODIFIED_INDENT_LEFT; + this.indentLeft = indentLeft; + } + + /** + * Gets the right indentation of this RtfParagraphStyle. + * + * @return The right indentation of this RtfParagraphStyle. + */ + public int getIndentRight() { + return this.indentRight; + } + + /** + * Sets the right indentation of this RtfParagraphStyle. + * + * @param indentRight The right indentation to use. + */ + public void setIndentRight(int indentRight) { + this.modified = this.modified | MODIFIED_INDENT_RIGHT; + this.indentRight = indentRight; + } + + /** + * Gets the space before the paragraph of this RtfParagraphStyle.. + * + * @return The space before the paragraph. + */ + public int getSpacingBefore() { + return this.spacingBefore; + } + + /** + * Sets the space before the paragraph of this RtfParagraphStyle. + * + * @param spacingBefore The space before to use. + */ + public void setSpacingBefore(int spacingBefore) { + this.modified = this.modified | MODIFIED_SPACING_BEFORE; + this.spacingBefore = spacingBefore; + } + + /** + * Gets the space after the paragraph of this RtfParagraphStyle. + * + * @return The space after the paragraph. + */ + public int getSpacingAfter() { + return this.spacingAfter; + } + + /** + * Sets the space after the paragraph of this RtfParagraphStyle. + * + * @param spacingAfter The space after to use. + */ + public void setSpacingAfter(int spacingAfter) { + this.modified = this.modified | MODIFIED_SPACING_AFTER; + this.spacingAfter = spacingAfter; + } + + /** + * Sets the font name of this RtfParagraphStyle. + * + * @param fontName The font name to use + */ + public void setFontName(String fontName) { + this.modified = this.modified | MODIFIED_FONT_NAME; + super.setFontName(fontName); + } + + /** + * Sets the font size of this RtfParagraphStyle. + * + * @param fontSize The font size to use. + */ + public void setSize(float fontSize) { + this.modified = this.modified | MODIFIED_FONT_SIZE; + super.setSize(fontSize); + } + + /** + * Sets the font style of this RtfParagraphStyle. + * + * @param fontStyle The font style to use. + */ + public void setStyle(int fontStyle) { + this.modified = this.modified | MODIFIED_FONT_STYLE; + super.setStyle(fontStyle); + } + + /** + * Sets the colour of this RtfParagraphStyle. + * + * @param color The Color to use. + */ + public void setColor(Color color) { + this.modified = this.modified | MODIFIED_FONT_COLOR; + super.setColor(color); + } + + /** + * Gets the line leading of this RtfParagraphStyle. + * + * @return The line leading of this RtfParagraphStyle. + */ + public int getLineLeading() { + return this.lineLeading; + } + + /** + * Sets the line leading of this RtfParagraphStyle. + * + * @param lineLeading The line leading to use. + */ + public void setLineLeading(int lineLeading) { + this.lineLeading = lineLeading; + this.modified = this.modified | MODIFIED_LINE_LEADING; + } + + /** + * Gets whether the lines in the paragraph should be kept together in + * this RtfParagraphStyle. + * + * @return Whether the lines in the paragraph should be kept together. + */ + public boolean getKeepTogether() { + return this.keepTogether; + } + + /** + * Sets whether the lines in the paragraph should be kept together in + * this RtfParagraphStyle. + * + * @param keepTogether Whether the lines in the paragraph should be kept together. + */ + public void setKeepTogether(boolean keepTogether) { + this.keepTogether = keepTogether; + this.modified = this.modified | MODIFIED_KEEP_TOGETHER; + } + + /** + * Gets whether the paragraph should be kept toggether with the next in + * this RtfParagraphStyle. + * + * @return Whether the paragraph should be kept together with the next. + */ + public boolean getKeepTogetherWithNext() { + return this.keepTogetherWithNext; + } + + /** + * Sets whether the paragraph should be kept together with the next in + * this RtfParagraphStyle. + * + * @param keepTogetherWithNext Whether the paragraph should be kept together with the next. + */ + public void setKeepTogetherWithNext(boolean keepTogetherWithNext) { + this.keepTogetherWithNext = keepTogetherWithNext; + this.modified = this.modified | MODIFIED_KEEP_TOGETHER_WITH_NEXT; + } + + /** + * Handles the inheritance of paragraph style settings. All settings that + * have not been modified will be inherited from the base RtfParagraphStyle. + * If this RtfParagraphStyle is not based on another one, then nothing happens. + */ + public void handleInheritance() { + if(this.basedOnName != null && this.document.getDocumentHeader().getRtfParagraphStyle(this.basedOnName) != null) { + this.baseStyle = this.document.getDocumentHeader().getRtfParagraphStyle(this.basedOnName); + this.baseStyle.handleInheritance(); + if(!((this.modified & MODIFIED_ALIGNMENT) == MODIFIED_ALIGNMENT)) { + this.alignment = this.baseStyle.getAlignment(); + } + if(!((this.modified & MODIFIED_INDENT_LEFT) == MODIFIED_INDENT_LEFT)) { + this.indentLeft = this.baseStyle.getIndentLeft(); + } + if(!((this.modified & MODIFIED_INDENT_RIGHT) == MODIFIED_INDENT_RIGHT)) { + this.indentRight = this.baseStyle.getIndentRight(); + } + if(!((this.modified & MODIFIED_SPACING_BEFORE) == MODIFIED_SPACING_BEFORE)) { + this.spacingBefore = this.baseStyle.getSpacingBefore(); + } + if(!((this.modified & MODIFIED_SPACING_AFTER) == MODIFIED_SPACING_AFTER)) { + this.spacingAfter = this.baseStyle.getSpacingAfter(); + } + if(!((this.modified & MODIFIED_FONT_NAME) == MODIFIED_FONT_NAME)) { + setFontName(this.baseStyle.getFontName()); + } + if(!((this.modified & MODIFIED_FONT_SIZE) == MODIFIED_FONT_SIZE)) { + setSize(this.baseStyle.getFontSize()); + } + if(!((this.modified & MODIFIED_FONT_STYLE) == MODIFIED_FONT_STYLE)) { + setStyle(this.baseStyle.getFontStyle()); + } + if(!((this.modified & MODIFIED_FONT_COLOR) == MODIFIED_FONT_COLOR)) { + setColor(this.baseStyle.color()); + } + if(!((this.modified & MODIFIED_LINE_LEADING) == MODIFIED_LINE_LEADING)) { + setLineLeading(this.baseStyle.getLineLeading()); + } + if(!((this.modified & MODIFIED_KEEP_TOGETHER) == MODIFIED_KEEP_TOGETHER)) { + setKeepTogether(this.baseStyle.getKeepTogether()); + } + if(!((this.modified & MODIFIED_KEEP_TOGETHER_WITH_NEXT) == MODIFIED_KEEP_TOGETHER_WITH_NEXT)) { + setKeepTogetherWithNext(this.baseStyle.getKeepTogetherWithNext()); + } + } + } + + /** + * Writes the settings of this RtfParagraphStyle. + * + * @return A byte array with the settings of this RtfParagraphStyle. + */ + private byte[] writeParagraphSettings() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(this.keepTogether) { + result.write(RtfParagraphStyle.KEEP_TOGETHER); + } + if(this.keepTogetherWithNext) { + result.write(RtfParagraphStyle.KEEP_TOGETHER_WITH_NEXT); + } + switch (alignment) { + case Element.ALIGN_LEFT: + result.write(RtfParagraphStyle.ALIGN_LEFT); + break; + case Element.ALIGN_RIGHT: + result.write(RtfParagraphStyle.ALIGN_RIGHT); + break; + case Element.ALIGN_CENTER: + result.write(RtfParagraphStyle.ALIGN_CENTER); + break; + case Element.ALIGN_JUSTIFIED: + case Element.ALIGN_JUSTIFIED_ALL: + result.write(RtfParagraphStyle.ALIGN_JUSTIFY); + break; + } + result.write(RtfParagraphStyle.INDENT_LEFT); + result.write(intToByteArray(indentLeft)); + result.write(RtfParagraphStyle.INDENT_RIGHT); + result.write(intToByteArray(indentRight)); + if(this.spacingBefore > 0) { + result.write(RtfParagraphStyle.SPACING_BEFORE); + result.write(intToByteArray(this.spacingBefore)); + } + if(this.spacingAfter > 0) { + result.write(RtfParagraphStyle.SPACING_AFTER); + result.write(intToByteArray(this.spacingAfter)); + } + if(this.lineLeading > 0) { + result.write(RtfParagraph.LINE_SPACING); + result.write(intToByteArray(this.lineLeading)); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Writes the definition of this RtfParagraphStyle for the stylesheet list. + */ + public byte[] writeDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write("{".getBytes()); + result.write("\\style".getBytes()); + result.write("\\s".getBytes()); + result.write(intToByteArray(this.styleNumber)); + result.write(RtfBasicElement.DELIMITER); + result.write(writeParagraphSettings()); + result.write(super.writeBegin()); + result.write(RtfBasicElement.DELIMITER); + result.write(this.styleName.getBytes()); + result.write(";".getBytes()); + result.write("}".getBytes()); + if(this.document.getDocumentSettings().isOutputDebugLineBreaks()) { + result.write('\n'); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Writes the start information of this RtfParagraphStyle. + */ + public byte[] writeBegin() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write("\\s".getBytes()); + result.write(intToByteArray(this.styleNumber)); + result.write(writeParagraphSettings()); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Unused + * @return An empty byte array. + */ + public byte[] writeEnd() { + return new byte[0]; + } + + /** + * Unused + * @return An empty byte array. + */ + public byte[] write() { + return new byte[0]; + } + + /** + * Tests whether two RtfParagraphStyles are equal. Equality + * is determined via the name. + */ + public boolean equals(Object o) { + if(o == null || !(o instanceof RtfParagraphStyle)) { + return false; + } + RtfParagraphStyle paragraphStyle = (RtfParagraphStyle) o; + boolean result = this.getStyleName().equals(paragraphStyle.getStyleName()); + return result; + } + + /** + * Gets the hash code of this RtfParagraphStyle. + */ + public int hashCode() { + return this.styleName.hashCode(); + } + + /** + * Gets the number of this RtfParagraphStyle in the stylesheet list. + * + * @return The number of this RtfParagraphStyle in the stylesheet list. + */ + private int getStyleNumber() { + return this.styleNumber; + } + + /** + * Sets the number of this RtfParagraphStyle in the stylesheet list. + * + * @param styleNumber The number to use. + */ + protected void setStyleNumber(int styleNumber) { + this.styleNumber = styleNumber; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/style/RtfStylesheetList.java b/src/main/java/com/lowagie/text/rtf/style/RtfStylesheetList.java new file mode 100644 index 0000000..edb04ea --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/style/RtfStylesheetList.java @@ -0,0 +1,121 @@ +/* + * Created on Sep 22, 2005 + * + * To change the template for this generated file go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ +package com.lowagie.text.rtf.style; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; + +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.RtfExtendedElement; +import com.lowagie.text.rtf.document.RtfDocument; + +/** + * The RtfStylesheetList stores the RtfParagraphStyles that are used in the document. + * + * @version $Revision: 1.1 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfStylesheetList extends RtfElement implements RtfExtendedElement { + + /** + * The HashMap containing the RtfParagraphStyles. + */ + private HashMap styleMap = null; + /** + * Whether the default settings have been loaded. + */ + private boolean defaultsLoaded = false; + + /** + * Constructs a new RtfStylesheetList for the RtfDocument. + * + * @param doc The RtfDocument this RtfStylesheetList belongs to. + */ + public RtfStylesheetList(RtfDocument doc) { + super(doc); + this.styleMap = new HashMap(); + } + + /** + * Register a RtfParagraphStyle with this RtfStylesheetList. + * + * @param rtfParagraphStyle The RtfParagraphStyle to add. + */ + public void registerParagraphStyle(RtfParagraphStyle rtfParagraphStyle) { + RtfParagraphStyle tempStyle = new RtfParagraphStyle(this.document, rtfParagraphStyle); + tempStyle.setStyleNumber(this.styleMap.size()); + tempStyle.handleInheritance(); + this.styleMap.put(tempStyle.getStyleName(), tempStyle); + } + + /** + * Registers all default styles. If styles with the given name have already been registered, + * then they are NOT overwritten. + */ + private void registerDefaultStyles() { + defaultsLoaded = true; + if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_NORMAL.getStyleName())) { + registerParagraphStyle(RtfParagraphStyle.STYLE_NORMAL); + } + if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_HEADING_1.getStyleName())) { + registerParagraphStyle(RtfParagraphStyle.STYLE_HEADING_1); + } + if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_HEADING_2.getStyleName())) { + registerParagraphStyle(RtfParagraphStyle.STYLE_HEADING_2); + } + if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_HEADING_3.getStyleName())) { + registerParagraphStyle(RtfParagraphStyle.STYLE_HEADING_3); + } + } + + /** + * Gets the RtfParagraphStyle with the given name. Makes sure that the defaults + * have been loaded. + * + * @param styleName The name of the RtfParagraphStyle to get. + * @return The RtfParagraphStyle with the given name or null. + */ + public RtfParagraphStyle getRtfParagraphStyle(String styleName) { + if(!defaultsLoaded) { + registerDefaultStyles(); + } + if(this.styleMap.containsKey(styleName)) { + return (RtfParagraphStyle) this.styleMap.get(styleName); + } else { + return null; + } + } + + /** + * Writes the definition of the stylesheet list. + */ + public byte[] writeDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write("{".getBytes()); + result.write("\\stylesheet".getBytes()); + result.write(RtfBasicElement.DELIMITER); + if(this.document.getDocumentSettings().isOutputDebugLineBreaks()) { + result.write("\n".getBytes()); + } + Iterator it = this.styleMap.values().iterator(); + while(it.hasNext()) { + result.write(((RtfParagraphStyle) it.next()).writeDefinition()); + } + result.write("}".getBytes()); + if(this.document.getDocumentSettings().isOutputDebugLineBreaks()) { + result.write('\n'); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/table/RtfBorder.java b/src/main/java/com/lowagie/text/rtf/table/RtfBorder.java new file mode 100644 index 0000000..8a35867 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/table/RtfBorder.java @@ -0,0 +1,577 @@ +/* + * $Id: RtfBorder.java,v 1.16 2005/05/04 14:33:54 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.table; + +import java.awt.Color; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.style.RtfColor; + + +/** + * The RtfBorder handle one row or cell border. + * INTERNAL USE ONLY + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Unknown + */ +public class RtfBorder extends RtfElement { + + /** + * Constant for the left row border + */ + protected static final byte[] ROW_BORDER_LEFT = "\\trbrdrl".getBytes(); + /** + * Constant for the top row border + */ + protected static final byte[] ROW_BORDER_TOP = "\\trbrdrt".getBytes(); + /** + * Constant for the right row border + */ + protected static final byte[] ROW_BORDER_RIGHT = "\\trbrdrr".getBytes(); + /** + * Constant for the bottom row border + */ + protected static final byte[] ROW_BORDER_BOTTOM = "\\trbrdrb".getBytes(); + /** + * Constant for the horizontal line + */ + protected static final byte[] ROW_BORDER_HORIZONTAL = "\\trbrdrh".getBytes(); + /** + * Constant for the vertical line + */ + protected static final byte[] ROW_BORDER_VERTICAL = "\\trbrdrv".getBytes(); + /** + * Constant for the left cell border + */ + protected static final byte[] CELL_BORDER_LEFT = "\\clbrdrl".getBytes(); + /** + * Constant for the top cell border + */ + protected static final byte[] CELL_BORDER_TOP = "\\clbrdrt".getBytes(); + /** + * Constant for the right cell border + */ + protected static final byte[] CELL_BORDER_RIGHT = "\\clbrdrr".getBytes(); + /** + * Constant for the bottom cell border + */ + protected static final byte[] CELL_BORDER_BOTTOM = "\\clbrdrb".getBytes(); + /** + * Constant for the border width + */ + protected static final byte[] BORDER_WIDTH = "\\brdrw".getBytes(); + /** + * Constant for the border colour number + */ + protected static final byte[] BORDER_COLOR_NUMBER = "\\brdrcf".getBytes(); + /** + * Constant for the single border style + */ + protected static final byte[] BORDER_STYLE_SINGLE = "\\brdrs".getBytes(); + /** + * Constant for the double thick border style + */ + protected static final byte[] BORDER_STYLE_DOUBLE_THICK = "\\brdrth".getBytes(); + /** + * Constant for the shadowed border style + */ + protected static final byte[] BORDER_STYLE_SHADOWED = "\\brdrsh".getBytes(); + /** + * Constant for the dotted border style + */ + protected static final byte[] BORDER_STYLE_DOTTED = "\\brdrdot".getBytes(); + /** + * Constant for the dashed border style + */ + protected static final byte[] BORDER_STYLE_DASHED = "\\brdrdash".getBytes(); + /** + * Constant for the hairline border style + */ + protected static final byte[] BORDER_STYLE_HAIRLINE = "\\brdrhair".getBytes(); + /** + * Constant for the double border style + */ + protected static final byte[] BORDER_STYLE_DOUBLE = "\\brdrdb".getBytes(); + /** + * Constant for the dot dash border style + */ + protected static final byte[] BORDER_STYLE_DOT_DASH = "\\brdrdashd".getBytes(); + /** + * Constant for the dot dot dash border style + */ + protected static final byte[] BORDER_STYLE_DOT_DOT_DASH = "\\brdrdashdd".getBytes(); + /** + * Constant for the triple border style + */ + protected static final byte[] BORDER_STYLE_TRIPLE = "\\brdrtriple".getBytes(); + /** + * Constant for the thick thin border style + */ + protected static final byte[] BORDER_STYLE_THICK_THIN = "\\brdrtnthsg".getBytes(); + /** + * Constant for the thin thick border style + */ + protected static final byte[] BORDER_STYLE_THIN_THICK = "\\brdrthtnsg".getBytes(); + /** + * Constant for the thin thick thin border style + */ + protected static final byte[] BORDER_STYLE_THIN_THICK_THIN = "\\brdrtnthtnsg".getBytes(); + /** + * Constant for the thick thin medium border style + */ + protected static final byte[] BORDER_STYLE_THICK_THIN_MED = "\\brdrtnthmg".getBytes(); + /** + * Constant for the thin thick medium border style + */ + protected static final byte[] BORDER_STYLE_THIN_THICK_MED = "\\brdrthtnmg".getBytes(); + /** + * Constant for the thin thick thin medium border style + */ + protected static final byte[] BORDER_STYLE_THIN_THICK_THIN_MED = "\\brdrtnthtnmg".getBytes(); + /** + * Constant for the thick thin large border style + */ + protected static final byte[] BORDER_STYLE_THICK_THIN_LARGE = "\\brdrtnthlg".getBytes(); + /** + * Constant for the thin thick large border style + */ + protected static final byte[] BORDER_STYLE_THIN_THICK_LARGE = "\\brdrthtnlg".getBytes(); + /** + * Constant for the thin thick thin large border style + */ + protected static final byte[] BORDER_STYLE_THIN_THICK_THIN_LARGE = "\\brdrtnthtnlg".getBytes(); + /** + * Constant for the wavy border style + */ + protected static final byte[] BORDER_STYLE_WAVY = "\\brdrwavy".getBytes(); + /** + * Constant for the double wavy border style + */ + protected static final byte[] BORDER_STYLE_DOUBLE_WAVY = "\\brdrwavydb".getBytes(); + /** + * Constant for the striped border style + */ + protected static final byte[] BORDER_STYLE_STRIPED = "\\brdrdashdotstr".getBytes(); + /** + * Constant for the embossed border style + */ + protected static final byte[] BORDER_STYLE_EMBOSS = "\\brdremboss".getBytes(); + /** + * Constant for the engraved border style + */ + protected static final byte[] BORDER_STYLE_ENGRAVE = "\\brdrengrave".getBytes(); + + /** + * Constant for a row border + */ + protected static final int ROW_BORDER = 1; + /** + * Constant for a cell border + */ + protected static final int CELL_BORDER = 2; + + /** + * This border is no border :-) + */ + protected static final int NO_BORDER = 0; + /** + * Constant for a left border + */ + protected static final int LEFT_BORDER = 1; + /** + * Constant for a top border + */ + protected static final int TOP_BORDER = 2; + /** + * Constant for a right border + */ + protected static final int RIGHT_BORDER = 4; + /** + * Constant for a bottom border + */ + protected static final int BOTTOM_BORDER = 8; + /** + * Constant for a box (left, top, right, bottom) border + */ + protected static final int BOX_BORDER = 15; + /** + * Constant for a vertical line + */ + protected static final int VERTICAL_BORDER = 16; + /** + * Constant for a horizontal line + */ + protected static final int HORIZONTAL_BORDER = 32; + + /** + * Constant for a border with no border + */ + public static final int BORDER_NONE = 0; + /** + * Constant for a single border + */ + public static final int BORDER_SINGLE = 1; + /** + * Constant for a double thick border + */ + public static final int BORDER_DOUBLE_THICK = 2; + /** + * Constant for a shadowed border + */ + public static final int BORDER_SHADOWED = 3; + /** + * Constant for a dotted border + */ + public static final int BORDER_DOTTED = 4; + /** + * Constant for a dashed border + */ + public static final int BORDER_DASHED = 5; + /** + * Constant for a hairline border + */ + public static final int BORDER_HAIRLINE = 6; + /** + * Constant for a double border + */ + public static final int BORDER_DOUBLE = 7; + /** + * Constant for a dot dash border + */ + public static final int BORDER_DOT_DASH = 8; + /** + * Constant for a dot dot dash border + */ + public static final int BORDER_DOT_DOT_DASH = 9; + /** + * Constant for a triple border + */ + public static final int BORDER_TRIPLE = 10; + /** + * Constant for a thick thin border + */ + public static final int BORDER_THICK_THIN = 11; + /** + * Constant for a thin thick border + */ + public static final int BORDER_THIN_THICK = 12; + /** + * Constant for a thin thick thin border + */ + public static final int BORDER_THIN_THICK_THIN = 13; + /** + * Constant for a thick thin medium border + */ + public static final int BORDER_THICK_THIN_MED = 14; + /** + * Constant for a thin thick medium border + */ + public static final int BORDER_THIN_THICK_MED = 15; + /** + * Constant for a thin thick thin medium border + */ + public static final int BORDER_THIN_THICK_THIN_MED = 16; + /** + * Constant for a thick thin large border + */ + public static final int BORDER_THICK_THIN_LARGE = 17; + /** + * Constant for a thin thick large border + */ + public static final int BORDER_THIN_THICK_LARGE = 18; + /** + * Constant for a thin thick thin large border + */ + public static final int BORDER_THIN_THICK_THIN_LARGE = 19; + /** + * Constant for a wavy border + */ + public static final int BORDER_WAVY = 20; + /** + * Constant for a double wavy border + */ + public static final int BORDER_DOUBLE_WAVY = 21; + /** + * Constant for a striped border + */ + public static final int BORDER_STRIPED = 22; + /** + * Constant for an embossed border + */ + public static final int BORDER_EMBOSS = 23; + /** + * Constant for an engraved border + */ + public static final int BORDER_ENGRAVE = 24; + + /** + * The type of this RtfBorder + */ + private int borderType = ROW_BORDER; + /** + * The position of this RtfBorder + */ + private int borderPosition = NO_BORDER; + /** + * The style of this RtfBorder + */ + private int borderStyle = BORDER_NONE; + /** + * The width of this RtfBorder + */ + private int borderWidth = 20; + /** + * The colour of this RtfBorder + */ + private RtfColor borderColor = null; + + /** + * Makes a copy of the given RtfBorder + * + * @param doc The RtfDocument this RtfBorder belongs to + * @param borderType The border type of this RtfBorder + * @param border The RtfBorder to copy + */ + protected RtfBorder(RtfDocument doc, int borderType, RtfBorder border) { + super(doc); + this.borderType = borderType; + this.borderPosition = border.getBorderPosition(); + this.borderStyle = border.getBorderStyle(); + this.borderWidth = border.getBorderWidth(); + this.borderColor = new RtfColor(this.document, border.getBorderColor()); + } + + /** + * Constructs a RtfBorder + * + * @param doc The RtfDocument this RtfBorder belongs to + * @param borderType The type of border this RtfBorder is + * @param borderPosition The position of this RtfBorder + * @param borderStyle The style of this RtfBorder + * @param borderWidth The width of this RtfBorder + * @param borderColor The colour of this RtfBorder + */ + protected RtfBorder(RtfDocument doc, int borderType, int borderPosition, int borderStyle, float borderWidth, Color borderColor) { + super(doc); + this.borderType = borderType; + this.borderPosition = borderPosition; + this.borderStyle = borderStyle; + if(borderWidth > 2) { + borderWidth = 2; + } + this.borderWidth = (int) (borderWidth * TWIPS_FACTOR); + if(this.borderWidth == 0) { + this.borderStyle = BORDER_NONE; + } + if(borderColor == null) { + this.borderColor = new RtfColor(this.document, new Color(0, 0, 0)); + } else { + this.borderColor = new RtfColor(this.document, borderColor); + } + } + + /** + * Writes the RtfBorder settings + * + * @return A byte array with the RtfBorder settings + */ + public byte[] write() { + if(this.borderStyle == BORDER_NONE || this.borderPosition == NO_BORDER || this.borderWidth == 0) { + return new byte[0]; + } + + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(this.borderType == ROW_BORDER) { + switch(this.borderPosition) { + case LEFT_BORDER: + result.write(ROW_BORDER_LEFT); + break; + case TOP_BORDER: + result.write(ROW_BORDER_TOP); + break; + case RIGHT_BORDER: + result.write(ROW_BORDER_RIGHT); + break; + case BOTTOM_BORDER: + result.write(ROW_BORDER_BOTTOM); + break; + case HORIZONTAL_BORDER: + result.write(ROW_BORDER_HORIZONTAL); + break; + case VERTICAL_BORDER: + result.write(ROW_BORDER_VERTICAL); + break; + default: + return new byte[0]; + } + result.write(writeBorderStyle()); + result.write(BORDER_WIDTH); + result.write(intToByteArray(this.borderWidth)); + result.write(BORDER_COLOR_NUMBER); + result.write(intToByteArray(this.borderColor.getColorNumber())); + result.write('\n'); + } else if(this.borderType == CELL_BORDER) { + switch(this.borderPosition) { + case LEFT_BORDER: + result.write(CELL_BORDER_LEFT); + break; + case TOP_BORDER: + result.write(CELL_BORDER_TOP); + break; + case RIGHT_BORDER: + result.write(CELL_BORDER_RIGHT); + break; + case BOTTOM_BORDER: + result.write(CELL_BORDER_BOTTOM); + break; + default: + return new byte[0]; + } + result.write(writeBorderStyle()); + result.write(BORDER_WIDTH); + result.write(intToByteArray(this.borderWidth)); + result.write(BORDER_COLOR_NUMBER); + result.write(intToByteArray(this.borderColor.getColorNumber())); + result.write('\n'); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + + return result.toByteArray(); + } + + /** + * Writes the style of this RtfBorder + * + * @return A byte array containing the style of this RtfBorder + */ + private byte[] writeBorderStyle() { + switch(this.borderStyle) { + case BORDER_NONE : return new byte[0]; + case BORDER_SINGLE : return BORDER_STYLE_SINGLE; + case BORDER_DOUBLE_THICK : return BORDER_STYLE_DOUBLE_THICK; + case BORDER_SHADOWED : return BORDER_STYLE_SHADOWED; + case BORDER_DOTTED : return BORDER_STYLE_DOTTED; + case BORDER_DASHED : return BORDER_STYLE_DASHED; + case BORDER_HAIRLINE : return BORDER_STYLE_HAIRLINE; + case BORDER_DOUBLE : return BORDER_STYLE_DOUBLE; + case BORDER_DOT_DASH : return BORDER_STYLE_DOT_DASH; + case BORDER_DOT_DOT_DASH : return BORDER_STYLE_DOT_DOT_DASH; + case BORDER_TRIPLE : return BORDER_STYLE_TRIPLE; + case BORDER_THICK_THIN : return BORDER_STYLE_THICK_THIN; + case BORDER_THIN_THICK : return BORDER_STYLE_THIN_THICK; + case BORDER_THIN_THICK_THIN : return BORDER_STYLE_THIN_THICK_THIN; + case BORDER_THICK_THIN_MED : return BORDER_STYLE_THICK_THIN_MED; + case BORDER_THIN_THICK_MED : return BORDER_STYLE_THIN_THICK_MED; + case BORDER_THIN_THICK_THIN_MED : return BORDER_STYLE_THIN_THICK_THIN_MED; + case BORDER_THICK_THIN_LARGE : return BORDER_STYLE_THICK_THIN_LARGE; + case BORDER_THIN_THICK_LARGE : return BORDER_STYLE_THIN_THICK_LARGE; + case BORDER_THIN_THICK_THIN_LARGE : return BORDER_STYLE_THIN_THICK_THIN_LARGE; + case BORDER_WAVY : return BORDER_STYLE_WAVY; + case BORDER_DOUBLE_WAVY : return BORDER_STYLE_DOUBLE_WAVY; + case BORDER_STRIPED : return BORDER_STYLE_STRIPED; + case BORDER_EMBOSS : return BORDER_STYLE_EMBOSS; + case BORDER_ENGRAVE : return BORDER_STYLE_ENGRAVE; + default : return BORDER_STYLE_SINGLE; + } + } + + /** + * Gets the colour of this RtfBorder + * + * @return Returns RtfColor of this RtfBorder + */ + protected RtfColor getBorderColor() { + return borderColor; + } + + /** + * Gets the position of this RtfBorder + * @return Returns the position of this RtfBorder + */ + protected int getBorderPosition() { + return borderPosition; + } + + /** + * Gets the style of this RtfBorder + * + * @return Returns the style of this RtfBorder + */ + protected int getBorderStyle() { + return borderStyle; + } + + /** + * Gets the type of this RtfBorder + * + * @return Returns the type of this RtfBorder + */ + protected int getBorderType() { + return borderType; + } + + /** + * Gets the width of this RtfBorder + * + * @return Returns the width of this RtfBorder + */ + protected int getBorderWidth() { + return borderWidth; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/table/RtfBorderGroup.java b/src/main/java/com/lowagie/text/rtf/table/RtfBorderGroup.java new file mode 100644 index 0000000..5b8904f --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/table/RtfBorderGroup.java @@ -0,0 +1,232 @@ +/* + * $Id: RtfBorderGroup.java,v 1.8 2004/12/14 12:51:39 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.table; + +import java.awt.Color; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Hashtable; + +import com.lowagie.text.Rectangle; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.document.RtfDocument; + + +/** + * The RtfBorderGroup represents a collection of RtfBorders to use in a RtfCell + * or RtfTable. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfBorderGroup extends RtfElement { + /** + * The type of borders this RtfBorderGroup contains. + * RtfBorder.ROW_BORDER or RtfBorder.CELL_BORDER + */ + private int borderType = RtfBorder.ROW_BORDER; + /** + * The borders in this RtfBorderGroup + */ + private Hashtable borders = null; + + /** + * Constructs an empty RtfBorderGroup. + */ + public RtfBorderGroup() { + super(null); + this.borders = new Hashtable(); + } + + /** + * Constructs a RtfBorderGroup with on border style for multiple borders. + * + * @param bordersToAdd The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX) + * @param borderStyle The style of border to add (from RtfBorder) + * @param borderWidth The border width to use + * @param borderColor The border color to use + */ + public RtfBorderGroup(int bordersToAdd, int borderStyle, float borderWidth, Color borderColor) { + super(null); + this.borders = new Hashtable(); + addBorder(bordersToAdd, borderStyle, borderWidth, borderColor); + } + + /** + * Constructs a RtfBorderGroup based on another RtfBorderGroup. + * + * @param doc The RtfDocument this RtfBorderGroup belongs to + * @param borderType The type of borders this RtfBorderGroup contains + * @param borderGroup The RtfBorderGroup to use as a base + */ + protected RtfBorderGroup(RtfDocument doc, int borderType, RtfBorderGroup borderGroup) { + super(doc); + this.borders = new Hashtable(); + this.borderType = borderType; + if(borderGroup != null) { + Enumeration borderEnum = borderGroup.getBorders().keys(); + while(borderEnum.hasMoreElements()) { + Integer borderPos = (Integer) borderEnum.nextElement(); + RtfBorder border = (RtfBorder) borderGroup.getBorders().get(borderPos); + this.borders.put(borderPos, new RtfBorder(this.document, this.borderType, border)); + } + } + } + + /** + * Constructs a RtfBorderGroup with certain borders + * + * @param doc The RtfDocument this RtfBorderGroup belongs to + * @param borderType The type of borders this RtfBorderGroup contains + * @param bordersToUse The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX) + * @param borderWidth The border width to use + * @param borderColor The border color to use + */ + protected RtfBorderGroup(RtfDocument doc, int borderType, int bordersToUse, float borderWidth, Color borderColor) { + super(doc); + this.borderType = borderType; + this.borders = new Hashtable(); + addBorder(bordersToUse, RtfBorder.BORDER_SINGLE, borderWidth, borderColor); + } + + /** + * Sets a border in the Hashtable of borders + * + * @param borderPosition The position of this RtfBorder + * @param borderStyle The type of borders this RtfBorderGroup contains + * @param borderWidth The border width to use + * @param borderColor The border color to use + */ + private void setBorder(int borderPosition, int borderStyle, float borderWidth, Color borderColor) { + RtfBorder border = new RtfBorder(this.document, this.borderType, borderPosition, borderStyle, borderWidth, borderColor); + this.borders.put(new Integer(borderPosition), border); + } + + /** + * Adds borders to the RtfBorderGroup + * + * @param bordersToAdd The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX) + * @param borderStyle The style of border to add (from RtfBorder) + * @param borderWidth The border width to use + * @param borderColor The border color to use + */ + public void addBorder(int bordersToAdd, int borderStyle, float borderWidth, Color borderColor) { + if((bordersToAdd & Rectangle.LEFT) == Rectangle.LEFT) { + setBorder(RtfBorder.LEFT_BORDER, borderStyle, borderWidth, borderColor); + } + if((bordersToAdd & Rectangle.TOP) == Rectangle.TOP) { + setBorder(RtfBorder.TOP_BORDER, borderStyle, borderWidth, borderColor); + } + if((bordersToAdd & Rectangle.RIGHT) == Rectangle.RIGHT) { + setBorder(RtfBorder.RIGHT_BORDER, borderStyle, borderWidth, borderColor); + } + if((bordersToAdd & Rectangle.BOTTOM) == Rectangle.BOTTOM) { + setBorder(RtfBorder.BOTTOM_BORDER, borderStyle, borderWidth, borderColor); + } + if((bordersToAdd & Rectangle.BOX) == Rectangle.BOX && this.borderType == RtfBorder.ROW_BORDER) { + setBorder(RtfBorder.VERTICAL_BORDER, borderStyle, borderWidth, borderColor); + setBorder(RtfBorder.HORIZONTAL_BORDER, borderStyle, borderWidth, borderColor); + } + } + + /** + * Removes borders from the list of borders + * + * @param bordersToRemove The borders to remove (from Rectangle) + */ + public void removeBorder(int bordersToRemove) { + if((bordersToRemove & Rectangle.LEFT) == Rectangle.LEFT) { + this.borders.remove(new Integer(RtfBorder.LEFT_BORDER)); + } + if((bordersToRemove & Rectangle.TOP) == Rectangle.TOP) { + this.borders.remove(new Integer(RtfBorder.TOP_BORDER)); + } + if((bordersToRemove & Rectangle.RIGHT) == Rectangle.RIGHT) { + this.borders.remove(new Integer(RtfBorder.RIGHT_BORDER)); + } + if((bordersToRemove & Rectangle.BOTTOM) == Rectangle.BOTTOM) { + this.borders.remove(new Integer(RtfBorder.BOTTOM_BORDER)); + } + if((bordersToRemove & Rectangle.BOX) == Rectangle.BOX && this.borderType == RtfBorder.ROW_BORDER) { + this.borders.remove(new Integer(RtfBorder.VERTICAL_BORDER)); + this.borders.remove(new Integer(RtfBorder.HORIZONTAL_BORDER)); + } + } + + /** + * Writes the borders of this RtfBorderGroup + * + * @return A byte array with the borders of this RtfBorderGroup + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + Enumeration borderEnum = this.borders.keys(); + while(borderEnum.hasMoreElements()) { + result.write(((RtfBorder) this.borders.get(borderEnum.nextElement())).write()); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + + return result.toByteArray(); + } + + /** + * Gets the RtfBorders of this RtfBorderGroup + * + * @return The RtfBorders of this RtfBorderGroup + */ + protected Hashtable getBorders() { + return this.borders; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/table/RtfCell.java b/src/main/java/com/lowagie/text/rtf/table/RtfCell.java new file mode 100644 index 0000000..abfee02 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/table/RtfCell.java @@ -0,0 +1,534 @@ +/* + * $Id: RtfCell.java,v 1.15 2006/02/09 17:13:11 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.table; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Iterator; +import java.util.Properties; +import java.util.ArrayList; + +import com.lowagie.text.BadElementException; +import com.lowagie.text.Cell; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.List; +import com.lowagie.text.Paragraph; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.RtfExtendedElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.style.RtfColor; +import com.lowagie.text.rtf.style.RtfParagraphStyle; +import com.lowagie.text.rtf.text.RtfParagraph; + + +/** + * The RtfCell wraps a Cell, but can also be added directly to a Table. + * The RtfCell is an extension of Cell, that supports a multitude of different + * borderstyles. + * + * @version $Id: RtfCell.java,v 1.15 2006/02/09 17:13:11 hallm Exp $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Steffen Stundzig + * @author Benoit WIART + * @see com.lowagie.text.rtf.table.RtfBorder + */ +public class RtfCell extends Cell implements RtfExtendedElement { + + /** + * This cell is not merged + */ + private static final int MERGE_NONE = 0; + /** + * This cell is the parent cell of a vertical merge operation + */ + private static final int MERGE_VERT_PARENT = 1; + /** + * This cell is a child cell of a vertical merge operation + */ + private static final int MERGE_VERT_CHILD = 2; + + /** + * The parent RtfRow of this RtfCell + */ + private RtfRow parentRow = null; + /** + * The content of this RtfCell + */ + private ArrayList content = null; + /** + * The right margin of this RtfCell + */ + private int cellRight = 0; + /** + * The width of this RtfCell + */ + private int cellWidth = 0; + /** + * The borders of this RtfCell + */ + private RtfBorderGroup borders = null; + /** + * The vertical alignment of this RtfCell + */ + private int verticalAlignment = Cell.ALIGN_MIDDLE; + /** + * The background color of this RtfCell + */ + private RtfColor backgroundColor = null; + /** + * The padding of this RtfCell + */ + private int cellPadding = 0; + /** + * The merge type of this RtfCell + */ + private int mergeType = MERGE_NONE; + /** + * The number of columns spanned by this RtfCell + */ + private int colspan = 1; + /** + * The number of rows spanned by this RtfCell + */ + private int rowspan = 1; + /** + * The RtfDocument this RtfCell belongs to + */ + private RtfDocument document = null; + /** + * Whether this RtfCell is in a header + */ + private boolean inHeader = false; + + /** + * Constructs an empty RtfCell + */ + public RtfCell() { + super(); + this.borders = new RtfBorderGroup(); + } + + /** + * Constructs a RtfCell based upon a String + * + * @param content The String to base the RtfCell on + */ + public RtfCell(String content) { + super(content); + this.borders = new RtfBorderGroup(); + } + + /** + * Constructs a RtfCell based upon an Element + * + * @param element The Element to base the RtfCell on + * @throws BadElementException If the Element is not valid + */ + public RtfCell(Element element) throws BadElementException { + super(element); + this.borders = new RtfBorderGroup(); + } + + /** + * Constructs a RtfCell based upon certain Properties + * + * @param properties The Properties for this RtfCell + */ + public RtfCell(Properties properties) { + super(properties); + this.borders = new RtfBorderGroup(); + } + + /** + * Constructs a RtfCell based on a Cell. + * + * @param doc The RtfDocument this RtfCell belongs to + * @param row The RtfRow this RtfCell lies in + * @param cell The Cell to base this RtfCell on + */ + protected RtfCell(RtfDocument doc, RtfRow row, Cell cell) { + this.document = doc; + this.parentRow = row; + importCell(cell); + } + + /** + * Imports the Cell properties into the RtfCell + * + * @param cell The Cell to import + */ + private void importCell(Cell cell) { + this.content = new ArrayList(); + + if(cell == null) { + this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, this.parentRow.getParentTable().getBorders()); + return; + } + + this.colspan = cell.colspan(); + this.rowspan = cell.rowspan(); + if(cell.rowspan() > 1) { + this.mergeType = MERGE_VERT_PARENT; + } + if(cell instanceof RtfCell) { + this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, ((RtfCell) cell).getBorders()); + } else { + this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, cell.border(), cell.borderWidth(), cell.borderColor()); + } + this.verticalAlignment = cell.verticalAlignment(); + if(cell.backgroundColor() == null) { + this.backgroundColor = new RtfColor(this.document, 255, 255, 255); + } else { + this.backgroundColor = new RtfColor(this.document, cell.backgroundColor()); + } + + this.cellPadding = (int) this.parentRow.getParentTable().getCellPadding(); + + if(cell != null) { + Iterator cellIterator = cell.getElements(); + Paragraph container = null; + while(cellIterator.hasNext()) { + try { + Element element = (Element) cellIterator.next(); + // should we wrap it in a paragraph + if(!(element instanceof Paragraph) && !(element instanceof List)) { + if(container != null) { + container.add(element); + } else { + container = new Paragraph(); + container.setAlignment(cell.horizontalAlignment()); + container.add(element); + } + } else { + if(container != null) { + RtfBasicElement rtfElement = this.document.getMapper().mapElement(container); + rtfElement.setInTable(true); + this.content.add(rtfElement); + container = null; + } + // if horizontal alignment is undefined overwrite + // with that of enclosing cell + if (element instanceof Paragraph && ((Paragraph) element).alignment() == Element.ALIGN_UNDEFINED) { + ((Paragraph) element).setAlignment(cell.horizontalAlignment()); + } + + RtfBasicElement rtfElement = this.document.getMapper().mapElement(element); + rtfElement.setInTable(true); + this.content.add(rtfElement); + } + } catch(DocumentException de) { + de.printStackTrace(); + } + } + if(container != null) { + try { + RtfBasicElement rtfElement = this.document.getMapper().mapElement(container); + rtfElement.setInTable(true); + this.content.add(rtfElement); + } catch(DocumentException de) { + de.printStackTrace(); + } + } + } + } + + /** + * Write the cell definition part of this RtfCell + * + * @return A byte array with the cell definition + */ + public byte[] writeDefinition() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(this.mergeType == MERGE_VERT_PARENT) { + result.write("\\clvmgf".getBytes()); + } else if(this.mergeType == MERGE_VERT_CHILD) { + result.write("\\clvmrg".getBytes()); + } + switch (verticalAlignment) { + case Element.ALIGN_BOTTOM: + result.write("\\clvertalb".getBytes()); + break; + case Element.ALIGN_CENTER: + case Element.ALIGN_MIDDLE: + result.write("\\clvertalc".getBytes()); + break; + case Element.ALIGN_TOP: + result.write("\\clvertalt".getBytes()); + break; + } + result.write(this.borders.write()); + + if(this.backgroundColor != null) { + result.write("\\clcbpat".getBytes()); + result.write(intToByteArray(this.backgroundColor.getColorNumber())); + } + result.write('\n'); + + result.write("\\clftsWidth3".getBytes()); + result.write('\n'); + + result.write("\\clwWidth".getBytes()); + result.write(intToByteArray(this.cellWidth)); + result.write('\n'); + + if(this.cellPadding > 0) { + result.write("\\clpadl".getBytes()); + result.write(intToByteArray(this.cellPadding / 2)); + result.write("\\clpadt".getBytes()); + result.write(intToByteArray(this.cellPadding / 2)); + result.write("\\clpadr".getBytes()); + result.write(intToByteArray(this.cellPadding / 2)); + result.write("\\clpadb".getBytes()); + result.write(intToByteArray(this.cellPadding / 2)); + result.write("\\clpadfl3".getBytes()); + result.write("\\clpadft3".getBytes()); + result.write("\\clpadfr3".getBytes()); + result.write("\\clpadfb3".getBytes()); + } + result.write("\\cellx".getBytes()); + result.write(intToByteArray(this.cellRight)); + + } catch(IOException ioe) { + ioe.printStackTrace(); + } + + return result.toByteArray(); + } + + /** + * Write the content of this RtfCell + * + * @return A byte array with the content of this RtfCell + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(this.content.size() == 0) { + result.write(RtfParagraph.PARAGRAPH_DEFAULTS); + if(this.parentRow.getParentTable().getTableFitToPage()) { + result.write(RtfParagraphStyle.KEEP_TOGETHER_WITH_NEXT); + } + result.write(RtfParagraph.IN_TABLE); + } else { + for(int i = 0; i < this.content.size(); i++) { + RtfBasicElement rtfElement = (RtfBasicElement) this.content.get(i); + if(rtfElement instanceof RtfParagraph) { + ((RtfParagraph) rtfElement).setKeepTogetherWithNext(this.parentRow.getParentTable().getTableFitToPage()); + } + result.write(rtfElement.write()); + if(rtfElement instanceof RtfParagraph && i < (this.content.size() - 1)) { + result.write(RtfParagraph.PARAGRAPH); + } + } + } + result.write("\\cell".getBytes()); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + + return result.toByteArray(); + } + + /** + * Sets the right margin of this cell. Used in merge operations + * + * @param cellRight The right margin to use + */ + protected void setCellRight(int cellRight) { + this.cellRight = cellRight; + } + + /** + * Gets the right margin of this RtfCell + * + * @return The right margin of this RtfCell. + */ + protected int getCellRight() { + return this.cellRight; + } + + /** + * Sets the cell width of this RtfCell. Used in merge operations. + * + * @param cellWidth The cell width to use + */ + protected void setCellWidth(int cellWidth) { + this.cellWidth = cellWidth; + } + + /** + * Gets the cell width of this RtfCell + * + * @return The cell width of this RtfCell + */ + protected int getCellWidth() { + return this.cellWidth; + } + + /** + * Gets the number of columns this RtfCell spans + * + * @return The number of columns this RtfCell spans + */ + protected int getColspan() { + return this.colspan; + } + + /** + * Gets the number of rows this RtfCell spans + * + * @return The number of rows this RtfCell spans + */ + protected int getRowspan() { + return this.rowspan; + } + + /** + * Gets the cell padding of this RtfCell + * + * @return The cell padding of this RtfCell + */ + protected int getCellpadding() { + return this.cellPadding; + } + + /** + * Gets the borders of this RtfCell + * + * @return The borders of this RtfCell + */ + protected RtfBorderGroup getBorders() { + return this.borders; + } + + /** + * Set the borders of this RtfCell + * + * @param borderGroup The RtfBorderGroup to use as borders + */ + public void setBorders(RtfBorderGroup borderGroup) { + this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, borderGroup); + } + + /** + * Get the vertical alignment of this RtfCell + * + * @return The vertical alignment of this RtfCell + */ + protected int getVerticalAlignment() { + return this.verticalAlignment; + } + + /** + * Get the background color of this RtfCell + * + * @return The background color of this RtfCell + */ + protected RtfColor getBackgroundColor() { + return this.backgroundColor; + } + + /** + * Merge this cell into the parent cell. + * + * @param mergeParent The RtfCell to merge with + */ + protected void setCellMergeChild(RtfCell mergeParent) { + this.mergeType = MERGE_VERT_CHILD; + this.cellWidth = mergeParent.getCellWidth(); + this.cellRight = mergeParent.getCellRight(); + this.cellPadding = mergeParent.getCellpadding(); + this.borders = mergeParent.getBorders(); + this.verticalAlignment = mergeParent.getVerticalAlignment(); + this.backgroundColor = mergeParent.getBackgroundColor(); + } + + /** + * Sets the RtfDocument this RtfCell belongs to + * + * @param doc The RtfDocument to use + */ + public void setRtfDocument(RtfDocument doc) { + this.document = doc; + } + + /** + * Unused + * @param inTable + */ + public void setInTable(boolean inTable) { + } + + /** + * Sets whether this RtfCell is in a header + * + * @param inHeader True if this RtfCell is in a header, false otherwise + */ + public void setInHeader(boolean inHeader) { + this.inHeader = inHeader; + for(int i = 0; i < this.content.size(); i++) { + ((RtfBasicElement) this.content.get(i)).setInHeader(inHeader); + } + } + + /** + * Transforms an integer into its String representation and then returns the bytes + * of that string. + * + * @param i The integer to convert + * @return A byte array representing the integer + */ + private byte[] intToByteArray(int i) { + return Integer.toString(i).getBytes(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/table/RtfRow.java b/src/main/java/com/lowagie/text/rtf/table/RtfRow.java new file mode 100644 index 0000000..4075ed2 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/table/RtfRow.java @@ -0,0 +1,377 @@ +/* + * $Id: RtfRow.java,v 1.16 2005/05/24 16:30:53 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004, 2005 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.table; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +import com.lowagie.text.Cell; +import com.lowagie.text.Element; +import com.lowagie.text.Row; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.document.RtfDocument; + + +/** + * The RtfRow wraps one Row for a RtfTable. + * INTERNAL USE ONLY + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Steffen Stundzig + * @author Lorenz Maierhofer + */ +public class RtfRow extends RtfElement { + + /** + * Constant for the RtfRow beginning + */ + private static final byte[] ROW_BEGIN = "\\trowd".getBytes(); + /** + * Constant for the RtfRow width style + */ + private static final byte[] ROW_WIDTH_STYLE = "\\trftsWidth3".getBytes(); + /** + * Constant for the RtfRow width + */ + private static final byte[] ROW_WIDTH = "\\trwWidth".getBytes(); + /** + * Constant to specify that this RtfRow are not to be broken across pages + */ + private static final byte[] ROW_KEEP_TOGETHER = "\\trkeep".getBytes(); + /** + * Constant to specify that this is a header RtfRow + */ + private static final byte[] ROW_HEADER_ROW = "\\trhdr".getBytes(); + /** + * Constant for left alignment of this RtfRow + */ + private static final byte[] ROW_ALIGN_LEFT = "\\trql".getBytes(); + /** + * Constant for right alignment of this RtfRow + */ + private static final byte[] ROW_ALIGN_RIGHT = "\\trqr".getBytes(); + /** + * Constant for center alignment of this RtfRow + */ + private static final byte[] ROW_ALIGN_CENTER = "\\trqc".getBytes(); + /** + * Constant for justified alignment of this RtfRow + */ + private static final byte[] ROW_ALIGN_JUSTIFIED = "\\trqj".getBytes(); + /** + * Constant for the graph style of this RtfRow + */ + private static final byte[] ROW_GRAPH = "\\trgaph10".getBytes(); + /** + * Constant for the cell left spacing + */ + private static final byte[] ROW_CELL_SPACING_LEFT = "\\trspdl".getBytes(); + /** + * Constant for the cell top spacing + */ + private static final byte[] ROW_CELL_SPACING_TOP = "\\trspdt".getBytes(); + /** + * Constant for the cell right spacing + */ + private static final byte[] ROW_CELL_SPACING_RIGHT = "\\trspdr".getBytes(); + /** + * Constant for the cell bottom spacing + */ + private static final byte[] ROW_CELL_SPACING_BOTTOM = "\\trspdb".getBytes(); + /** + * Constant for the cell left spacing style + */ + private static final byte[] ROW_CELL_SPACING_LEFT_STYLE = "\\trspdfl3".getBytes(); + /** + * Constant for the cell top spacing style + */ + private static final byte[] ROW_CELL_SPACING_TOP_STYLE = "\\trspdft3".getBytes(); + /** + * Constant for the cell right spacing style + */ + private static final byte[] ROW_CELL_SPACING_RIGHT_STYLE = "\\trspdfr3".getBytes(); + /** + * Constant for the cell bottom spacing style + */ + private static final byte[] ROW_CELL_SPACING_BOTTOM_STYLE = "\\trspdfb3".getBytes(); + /** + * Constant for the cell left padding + */ + private static final byte[] ROW_CELL_PADDING_LEFT = "\\trpaddl".getBytes(); + /** + * Constant for the cell right padding + */ + private static final byte[] ROW_CELL_PADDING_RIGHT = "\\trpaddr".getBytes(); + /** + * Constant for the cell left padding style + */ + private static final byte[] ROW_CELL_PADDING_LEFT_STYLE = "\\trpaddfl3".getBytes(); + /** + * Constant for the cell right padding style + */ + private static final byte[] ROW_CELL_PADDING_RIGHT_STYLE = "\\trpaddfr3".getBytes(); + /** + * Constant for the end of a row + */ + private static final byte[] ROW_END = "\\row".getBytes(); + + /** + * The RtfTable this RtfRow belongs to + */ + private RtfTable parentTable = null; + /** + * The cells of this RtfRow + */ + private ArrayList cells = null; + /** + * The width of this row + */ + private int width = 0; + /** + * The row number + */ + private int rowNumber = 0; + + /** + * Constructs a RtfRow for a Row. + * + * @param doc The RtfDocument this RtfRow belongs to + * @param rtfTable The RtfTable this RtfRow belongs to + * @param row The Row this RtfRow is based on + * @param rowNumber The number of this row + */ + protected RtfRow(RtfDocument doc, RtfTable rtfTable, Row row, int rowNumber) { + super(doc); + this.parentTable = rtfTable; + this.rowNumber = rowNumber; + importRow(row); + } + + /** + * Imports a Row and copies all settings + * + * @param row The Row to import + */ + private void importRow(Row row) { + this.cells = new ArrayList(); + this.width = this.document.getDocumentHeader().getPageSetting().getPageWidth() - this.document.getDocumentHeader().getPageSetting().getMarginLeft() - this.document.getDocumentHeader().getPageSetting().getMarginRight(); + this.width = (int) (this.width / 100 * this.parentTable.getTableWidthPercent()); + + int cellRight = 0; + int cellWidth = 0; + for(int i = 0; i < row.columns(); i++) { + cellWidth = (int) (this.width / 100 * this.parentTable.getProportionalWidths()[i]); + cellRight = cellRight + cellWidth; + + Cell cell = (Cell) row.getCell(i); + RtfCell rtfCell = new RtfCell(this.document, this, cell); + rtfCell.setCellRight(cellRight); + rtfCell.setCellWidth(cellWidth); + this.cells.add(rtfCell); + } + } + + /** + * Performs a second pass over all cells to handle cell row/column spanning. + */ + protected void handleCellSpanning() { + int realCellIndex = 0; + for(int i = 0; i < this.cells.size(); i++) { + RtfCell rtfCell = (RtfCell) this.cells.get(i); + if(rtfCell.getColspan() > 1) { + int j = rtfCell.getColspan(); + while(j > 1) { + if(i + 1 < this.cells.size()) { + RtfCell rtfCellMerge = (RtfCell) this.cells.get(i + 1); + rtfCell.setCellRight(rtfCell.getCellRight() + rtfCellMerge.getCellWidth()); + rtfCell.setCellWidth(rtfCell.getCellWidth() + rtfCellMerge.getCellWidth()); + this.cells.remove(i + 1); + j--; + } + } + } + if(rtfCell.getRowspan() > 1) { + ArrayList rows = this.parentTable.getRows(); + for(int j = 1; j < rtfCell.getRowspan(); j++) { + RtfRow mergeRow = (RtfRow) rows.get(this.rowNumber + j); + if(this.rowNumber + j < rows.size()) { + RtfCell rtfCellMerge = (RtfCell) mergeRow.getCells().get(realCellIndex); + rtfCellMerge.setCellMergeChild(rtfCell); + } + if(rtfCell.getColspan() > 1) { + int k = rtfCell.getColspan(); + while(k > 1 && (realCellIndex + 1 < mergeRow.getCells().size())) { + mergeRow.getCells().remove(realCellIndex + 1); + k--; + } + } + } + } + realCellIndex = realCellIndex + rtfCell.getColspan(); + } + } + + private byte[] writeRowDefinitions() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(ROW_BEGIN); + result.write('\n'); + result.write(ROW_WIDTH_STYLE); + result.write(ROW_WIDTH); + result.write(intToByteArray(this.width)); + if(this.parentTable.getCellsFitToPage()) { + result.write(ROW_KEEP_TOGETHER); + } + if(this.rowNumber <= this.parentTable.getHeaderRows()) { + result.write(ROW_HEADER_ROW); + } + switch (this.parentTable.getAlignment()) { + case Element.ALIGN_LEFT: + result.write(ROW_ALIGN_LEFT); + break; + case Element.ALIGN_RIGHT: + result.write(ROW_ALIGN_RIGHT); + break; + case Element.ALIGN_CENTER: + result.write(ROW_ALIGN_CENTER); + break; + case Element.ALIGN_JUSTIFIED: + case Element.ALIGN_JUSTIFIED_ALL: + result.write(ROW_ALIGN_JUSTIFIED); + break; + } + result.write(ROW_GRAPH); + + result.write(this.parentTable.getBorders().write()); + + if(this.parentTable.getCellSpacing() > 0) { + result.write(ROW_CELL_SPACING_LEFT); + result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); + result.write(ROW_CELL_SPACING_LEFT_STYLE); + result.write(ROW_CELL_SPACING_TOP); + result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); + result.write(ROW_CELL_SPACING_TOP_STYLE); + result.write(ROW_CELL_SPACING_RIGHT); + result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); + result.write(ROW_CELL_SPACING_RIGHT_STYLE); + result.write(ROW_CELL_SPACING_BOTTOM); + result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); + result.write(ROW_CELL_SPACING_BOTTOM_STYLE); + } + + result.write(ROW_CELL_PADDING_LEFT); + result.write(intToByteArray((int) (this.parentTable.getCellPadding() / 2))); + result.write(ROW_CELL_PADDING_RIGHT); + result.write(intToByteArray((int) (this.parentTable.getCellPadding() / 2))); + result.write(ROW_CELL_PADDING_LEFT_STYLE); + result.write(ROW_CELL_PADDING_RIGHT_STYLE); + + result.write('\n'); + + for(int i = 0; i < this.cells.size(); i++) { + RtfCell rtfCell = (RtfCell) this.cells.get(i); + result.write(rtfCell.writeDefinition()); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Writes the content of this RtfRow + * + * @return A byte array with the content of this RtfRow + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(writeRowDefinitions()); + + for(int i = 0; i < this.cells.size(); i++) { + RtfCell rtfCell = (RtfCell) this.cells.get(i); + result.write(rtfCell.write()); + } + + result.write(DELIMITER); + + if(this.document.getDocumentSettings().isOutputTableRowDefinitionAfter()) { + result.write(writeRowDefinitions()); + } + + result.write(ROW_END); + result.write("\n".getBytes()); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Gets the parent RtfTable of this RtfRow + * + * @return The parent RtfTable of this RtfRow + */ + protected RtfTable getParentTable() { + return this.parentTable; + } + + /** + * Gets the cells of this RtfRow + * + * @return The cells of this RtfRow + */ + protected ArrayList getCells() { + return this.cells; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/table/RtfTable.java b/src/main/java/com/lowagie/text/rtf/table/RtfTable.java new file mode 100644 index 0000000..285d9e0 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/table/RtfTable.java @@ -0,0 +1,271 @@ +/* + * $Id: RtfTable.java,v 1.11 2005/07/16 11:39:30 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.table; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Iterator; +import java.util.ArrayList; + +import com.lowagie.text.Element; +import com.lowagie.text.Row; +import com.lowagie.text.Table; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.text.RtfParagraph; + + +/** + * The RtfTable wraps a Table. + * INTERNAL USE ONLY + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + * @author Steffen Stundzig + * @author Benoit WIART + */ +public class RtfTable extends RtfElement { + + /** + * The rows of this RtfTable + */ + private ArrayList rows = null; + /** + * The percentage of the page width that this RtfTable covers + */ + private float tableWidthPercent = 80; + /** + * An array with the proportional widths of the cells in each row + */ + private float[] proportionalWidths = null; + /** + * The cell padding + */ + private float cellPadding = 0; + /** + * The cell spacing + */ + private float cellSpacing = 0; + /** + * The border style of this RtfTable + */ + private RtfBorderGroup borders = null; + /** + * The alignment of this RtfTable + */ + private int alignment = Element.ALIGN_CENTER; + /** + * Whether the cells in this RtfTable must fit in a page + */ + private boolean cellsFitToPage = false; + /** + * Whether the whole RtfTable must fit in a page + */ + private boolean tableFitToPage = false; + /** + * The number of header rows in this RtfTable + */ + private int headerRows = 0; + + /** + * Constructs a RtfTable based on a Table for a RtfDocument. + * + * @param doc The RtfDocument this RtfTable belongs to + * @param table The Table that this RtfTable wraps + */ + public RtfTable(RtfDocument doc, Table table) { + super(doc); + table.complete(); + importTable(table); + } + + /** + * Imports the rows and settings from the Table into this + * RtfTable. + * + * @param table The source Table + */ + private void importTable(Table table) { + this.rows = new ArrayList(); + this.tableWidthPercent = table.widthPercentage(); + this.proportionalWidths = table.getProportionalWidths(); + this.cellPadding = (float) (table.cellpadding() * TWIPS_FACTOR); + this.cellSpacing = (float) (table.cellspacing() * TWIPS_FACTOR); + this.borders = new RtfBorderGroup(this.document, RtfBorder.ROW_BORDER, table.border(), table.borderWidth(), table.borderColor()); + this.alignment = table.alignment(); + + int i = 0; + Iterator rowIterator = table.iterator(); + while(rowIterator.hasNext()) { + this.rows.add(new RtfRow(this.document, this, (Row) rowIterator.next(), i)); + i++; + } + for(i = 0; i < this.rows.size(); i++) { + ((RtfRow) this.rows.get(i)).handleCellSpanning(); + } + this.headerRows = table.lastHeaderRow(); + this.cellsFitToPage = table.hasToFitPageCells(); + this.tableFitToPage = table.hasToFitPageTable(); + } + + /** + * Writes the content of this RtfTable + * + * @return A byte array with the content of this RtfTable + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(!inHeader) { + result.write(RtfParagraph.PARAGRAPH); + } + + for(int i = 0; i < this.rows.size(); i++) { + result.write(((RtfElement) this.rows.get(i)).write()); + } + + result.write(RtfParagraph.PARAGRAPH_DEFAULTS); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Gets the alignment of this RtfTable + * + * @return The alignment of this RtfTable. + */ + protected int getAlignment() { + return alignment; + } + + /** + * Gets the borders of this RtfTable + * + * @return The borders of this RtfTable. + */ + protected RtfBorderGroup getBorders() { + return this.borders; + } + + /** + * Gets the cell padding of this RtfTable + * + * @return The cell padding of this RtfTable. + */ + protected float getCellPadding() { + return cellPadding; + } + + /** + * Gets the cell spacing of this RtfTable + * + * @return The cell spacing of this RtfTable. + */ + protected float getCellSpacing() { + return cellSpacing; + } + + /** + * Gets the proportional cell widths of this RtfTable + * + * @return The proportional widths of this RtfTable. + */ + protected float[] getProportionalWidths() { + return (float[]) proportionalWidths.clone(); + } + + /** + * Gets the percentage of the page width this RtfTable covers + * + * @return The percentage of the page width. + */ + protected float getTableWidthPercent() { + return tableWidthPercent; + } + + /** + * Gets the rows of this RtfTable + * + * @return The rows of this RtfTable + */ + protected ArrayList getRows() { + return this.rows; + } + + /** + * Gets the cellsFitToPage setting of this RtfTable. + * + * @return The cellsFitToPage setting of this RtfTable. + */ + protected boolean getCellsFitToPage() { + return this.cellsFitToPage; + } + + /** + * Gets the tableFitToPage setting of this RtfTable. + * + * @return The tableFitToPage setting of this RtfTable. + */ + protected boolean getTableFitToPage() { + return this.tableFitToPage; + } + + /** + * Gets the number of header rows of this RtfTable + * + * @return The number of header rows + */ + protected int getHeaderRows() { + return this.headerRows; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/text/RtfAnnotation.java b/src/main/java/com/lowagie/text/rtf/text/RtfAnnotation.java new file mode 100644 index 0000000..f7c02c2 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/text/RtfAnnotation.java @@ -0,0 +1,133 @@ +/* + * $Id: RtfAnnotation.java,v 1.16 2005/05/04 14:33:46 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.text; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.Annotation; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.document.RtfDocument; + + +/** + * The RtfAnnotation provides support for adding Annotations to the rtf document. + * Only simple Annotations with Title / Content are supported. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfAnnotation extends RtfElement { + + /** + * Constant for the id of the annotation + */ + private static final byte[] ANNOTATION_ID = "\\*\\atnid".getBytes(); + /** + * Constant for the author of the annotation + */ + private static final byte[] ANNOTATION_AUTHOR = "\\*\\atnauthor".getBytes(); + /** + * Constant for the actual annotation + */ + private static final byte[] ANNOTATION = "\\*\\annotation".getBytes(); + + /** + * The title of this RtfAnnotation + */ + private String title = ""; + /** + * The content of this RtfAnnotation + */ + private String content = ""; + + /** + * Constructs a RtfAnnotation based on an Annotation. + * + * @param doc The RtfDocument this RtfAnnotation belongs to + * @param annotation The Annotation this RtfAnnotation is based off + */ + public RtfAnnotation(RtfDocument doc, Annotation annotation) { + super(doc); + title = annotation.title(); + content = annotation.content(); + } + + /** + * Writes the content of the RtfAnnotation + * + * @return The content of this RtfAnnotation + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(OPEN_GROUP); + result.write(ANNOTATION_ID); + result.write(DELIMITER); + result.write(intToByteArray(document.getRandomInt())); + result.write(CLOSE_GROUP); + result.write(OPEN_GROUP); + result.write(ANNOTATION_AUTHOR); + result.write(DELIMITER); + result.write(title.getBytes()); + result.write(CLOSE_GROUP); + result.write(OPEN_GROUP); + result.write(ANNOTATION); + result.write(RtfParagraph.PARAGRAPH_DEFAULTS); + result.write(DELIMITER); + result.write(content.getBytes()); + result.write(CLOSE_GROUP); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/text/RtfChapter.java b/src/main/java/com/lowagie/text/rtf/text/RtfChapter.java new file mode 100644 index 0000000..df176ca --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/text/RtfChapter.java @@ -0,0 +1,105 @@ +/* + * $Id: RtfChapter.java,v 1.18 2005/09/11 20:17:41 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.text; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.Chapter; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.document.RtfDocument; + + +/** + * The RtfChapter wraps a Chapter element. + * INTERNAL CLASS + * + * @version $Revision: 1.18 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfChapter extends RtfSection { + + /** + * Constructs a RtfChapter for a given Chapter + * + * @param doc The RtfDocument this RtfChapter belongs to + * @param chapter The Chapter this RtfChapter is based on + */ + public RtfChapter(RtfDocument doc, Chapter chapter) { + super(doc, chapter); + } + + /** + * Writes the RtfChapter and its contents + * + * @return A byte array containing the RtfChapter and its contents + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(this.document.getLastElementWritten() != null && !(this.document.getLastElementWritten() instanceof RtfChapter)) { + result.write("\\page".getBytes()); + } + result.write("\\sectd".getBytes()); + result.write(document.getDocumentHeader().writeSectionDefinition()); + if(this.title != null) { + result.write(this.title.write()); + } + for(int i = 0; i < items.size(); i++) { + result.write(((RtfBasicElement) items.get(i)).write()); + } + result.write("\\sect".getBytes()); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/text/RtfChunk.java b/src/main/java/com/lowagie/text/rtf/text/RtfChunk.java new file mode 100644 index 0000000..7368c48 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/text/RtfChunk.java @@ -0,0 +1,202 @@ +/* + * $Id: RtfChunk.java,v 1.12 2005/07/23 10:57:32 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.text; + +import java.awt.Color; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.Chunk; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.style.RtfColor; +import com.lowagie.text.rtf.style.RtfFont; + + +/** + * The RtfChunk contains one piece of text. The smallest text element available + * in iText. + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfChunk extends RtfElement { + + /** + * Constant for the subscript flag + */ + private static final byte[] FONT_SUBSCRIPT = "\\sub".getBytes(); + /** + * Constant for the superscript flag + */ + private static final byte[] FONT_SUPERSCRIPT = "\\super".getBytes(); + /** + * Constant for the end of sub / superscript flag + */ + private static final byte[] FONT_END_SUPER_SUBSCRIPT = "\\nosupersub".getBytes(); + /** + * Constant for background colour. + */ + private static final byte[] HIGHLIGHT = "\\highlight".getBytes(); + + /** + * The font of this RtfChunk + */ + private RtfFont font = null; + /** + * The actual content of this RtfChunk + */ + private String content = ""; + /** + * Whether to use soft line breaks instead of hard ones. + */ + private boolean softLineBreaks = false; + /** + * The super / subscript of this RtfChunk + */ + private float superSubScript = 0; + /** + * An optional background colour. + */ + private RtfColor background = null; + + /** + * Constructs a RtfChunk based on the content of a Chunk + * + * @param doc The RtfDocument that this Chunk belongs to + * @param chunk The Chunk that this RtfChunk is based on + */ + public RtfChunk(RtfDocument doc, Chunk chunk) { + super(doc); + + if(chunk == null) { + return; + } + + if(chunk.getAttributes() != null && chunk.getAttributes().get(Chunk.SUBSUPSCRIPT) != null) { + this.superSubScript = ((Float)chunk.getAttributes().get(Chunk.SUBSUPSCRIPT)).floatValue(); + } + if(chunk.getAttributes() != null && chunk.getAttributes().get(Chunk.BACKGROUND) != null) { + this.background = new RtfColor(this.document, (Color) ((Object[]) chunk.getAttributes().get(Chunk.BACKGROUND))[0]); + } + font = new RtfFont(doc, chunk.font()); + content = chunk.content(); + } + + /** + * Writes the content of this RtfChunk. First the font information + * is written, then the content, and then more font information + * + * @return A byte array with the content of this RtfChunk + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + if(this.background != null) { + result.write(OPEN_GROUP); + } + + result.write(font.writeBegin()); + if(superSubScript < 0) { + result.write(FONT_SUBSCRIPT); + } else if(superSubScript > 0) { + result.write(FONT_SUPERSCRIPT); + } + if(this.background != null) { + result.write(HIGHLIGHT); + result.write(intToByteArray(this.background.getColorNumber())); + } + result.write(DELIMITER); + + result.write(document.filterSpecialChar(content, false, softLineBreaks || this.document.getDocumentSettings().isAlwaysGenerateSoftLinebreaks()).getBytes()); + + if(superSubScript != 0) { + result.write(FONT_END_SUPER_SUBSCRIPT); + } + result.write(font.writeEnd()); + + if(this.background != null) { + result.write(CLOSE_GROUP); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Sets the RtfDocument this RtfChunk belongs to. + * + * @param doc The RtfDocument to use + */ + public void setRtfDocument(RtfDocument doc) { + super.setRtfDocument(doc); + this.font.setRtfDocument(this.document); + } + + /** + * Sets whether to use soft line breaks instead of default hard ones. + * + * @param softLineBreaks whether to use soft line breaks instead of default hard ones. + */ + public void setSoftLineBreaks(boolean softLineBreaks) { + this.softLineBreaks = softLineBreaks; + } + + /** + * Gets whether to use soft line breaks instead of default hard ones. + * + * @return whether to use soft line breaks instead of default hard ones. + */ + public boolean getSoftLineBreaks() { + return this.softLineBreaks; + } +} diff --git a/src/main/java/com/lowagie/text/rtf/text/RtfNewPage.java b/src/main/java/com/lowagie/text/rtf/text/RtfNewPage.java new file mode 100644 index 0000000..3bb7a88 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/text/RtfNewPage.java @@ -0,0 +1,53 @@ +/* + * Created on Aug 12, 2004 + * + * To change the template for this generated file go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ +package com.lowagie.text.rtf.text; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.document.RtfDocument; + + +/** + * The RtfNewPage creates a new page. INTERNAL CLASS + * + * @version $Version:$ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfNewPage extends RtfElement { + + /** + * Constant for a new page + */ + private static final byte[] NEW_PAGE = "\\page".getBytes(); + + /** + * Constructs a RtfNewPage + * + * @param doc The RtfDocument this RtfNewPage belongs to + */ + public RtfNewPage(RtfDocument doc) { + super(doc); + } + + /** + * Writes a new page + * + * @return A byte array with the new page set + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(NEW_PAGE); + result.write(RtfParagraph.PARAGRAPH_DEFAULTS); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/text/RtfParagraph.java b/src/main/java/com/lowagie/text/rtf/text/RtfParagraph.java new file mode 100644 index 0000000..c600069 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/text/RtfParagraph.java @@ -0,0 +1,211 @@ +/* + * $Id: RtfParagraph.java,v 1.20 2005/12/24 13:12:43 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.text; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.Chunk; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.Paragraph; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.graphic.RtfImage; +import com.lowagie.text.rtf.style.RtfFont; +import com.lowagie.text.rtf.style.RtfParagraphStyle; + + +/** + * The RtfParagraph is an extension of the RtfPhrase that adds alignment and + * indentation properties. It wraps a Paragraph. + * + * @version $Revision: 1.20 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfParagraph extends RtfPhrase { + + /** + * Constant for the end of a paragraph + */ + public static final byte[] PARAGRAPH = "\\par".getBytes(); + + /** + * An optional RtfParagraphStyle to use for styling. + */ + private RtfParagraphStyle paragraphStyle = null; + + /** + * Constructs a RtfParagraph belonging to a RtfDocument based on a Paragraph. + * + * @param doc The RtfDocument this RtfParagraph belongs to + * @param paragraph The Paragraph that this RtfParagraph is based on + */ + public RtfParagraph(RtfDocument doc, Paragraph paragraph) { + super(doc); + + RtfFont baseFont = null; + if(paragraph.font() instanceof RtfParagraphStyle) { + this.paragraphStyle = this.document.getDocumentHeader().getRtfParagraphStyle(((RtfParagraphStyle) paragraph.font()).getStyleName()); + baseFont = this.paragraphStyle; + } else { + baseFont = new RtfFont(this.document, paragraph.font()); + this.paragraphStyle = new RtfParagraphStyle(this.document, this.document.getDocumentHeader().getRtfParagraphStyle("Normal")); + this.paragraphStyle.setAlignment(paragraph.alignment()); + this.paragraphStyle.setIndentLeft((int) (paragraph.indentationLeft() * RtfElement.TWIPS_FACTOR)); + this.paragraphStyle.setIndentRight((int) (paragraph.indentationRight() * RtfElement.TWIPS_FACTOR)); + this.paragraphStyle.setSpacingBefore((int) (paragraph.spacingBefore() * RtfElement.TWIPS_FACTOR)); + this.paragraphStyle.setSpacingAfter((int) (paragraph.spacingAfter() * RtfElement.TWIPS_FACTOR)); + if(paragraph.leadingDefined()) { + this.paragraphStyle.setLineLeading((int) (paragraph.leading() * RtfElement.TWIPS_FACTOR)); + } + this.paragraphStyle.setKeepTogether(paragraph.getKeepTogether()); + } + + for(int i = 0; i < paragraph.size(); i++) { + Element chunk = (Element) paragraph.get(i); + if(chunk instanceof Chunk) { + ((Chunk) chunk).setFont(baseFont.difference(((Chunk) chunk).font())); + } else if(chunk instanceof RtfImage) { + ((RtfImage) chunks.get(i)).setAlignment(this.paragraphStyle.getAlignment()); + } + try { + chunks.add(doc.getMapper().mapElement(chunk)); + } catch(DocumentException de) { + } + } + } + + /** + * Set whether this RtfParagraph must stay on the same page as the next one. + * + * @param keepTogetherWithNext Whether this RtfParagraph must keep together with the next. + */ + public void setKeepTogetherWithNext(boolean keepTogetherWithNext) { + this.paragraphStyle.setKeepTogetherWithNext(keepTogetherWithNext); + } + + /** + * Writes the content of this RtfParagraph. First paragraph specific data is written + * and then the RtfChunks of this RtfParagraph are added. + * + * @return The content of this RtfParagraph + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(PARAGRAPH_DEFAULTS); + + if(inTable) { + result.write(IN_TABLE); + } + + if(this.paragraphStyle != null) { + result.write(this.paragraphStyle.writeBegin()); + } + + for(int i = 0; i < chunks.size(); i++) { + result.write(((RtfBasicElement) chunks.get(i)).write()); + } + + if(this.paragraphStyle != null) { + result.write(this.paragraphStyle.writeEnd()); + } + + if(!inTable) { + result.write(PARAGRAPH); + } + if(this.document.getDocumentSettings().isOutputDebugLineBreaks()) { + result.write('\n'); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Gets the left indentation of this RtfParagraph. + * + * @return The left indentation. + */ + public int getIndentLeft() { + return this.paragraphStyle.getIndentLeft(); + } + + /** + * Sets the left indentation of this RtfParagraph. + * + * @param indentLeft The left indentation to use. + */ + public void setIndentLeft(int indentLeft) { + this.paragraphStyle.setIndentLeft(indentLeft); + } + + /** + * Gets the right indentation of this RtfParagraph. + * + * @return The right indentation. + */ + public int getIndentRight() { + return this.paragraphStyle.getIndentRight(); + } + + /** + * Sets the right indentation of this RtfParagraph. + * + * @param indentRight The right indentation to use. + */ + public void setIndentRight(int indentRight) { + this.paragraphStyle.setIndentRight(indentRight); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/text/RtfPhrase.java b/src/main/java/com/lowagie/text/rtf/text/RtfPhrase.java new file mode 100644 index 0000000..f5d79a9 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/text/RtfPhrase.java @@ -0,0 +1,203 @@ +/* + * $Id: RtfPhrase.java,v 1.14 2006/02/09 17:13:35 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.text; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +import com.lowagie.text.Chunk; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.Phrase; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.style.RtfFont; + + +/** + * The RtfPhrase contains multiple RtfChunks + * + * @version $Id: RtfPhrase.java,v 1.14 2006/02/09 17:13:35 hallm Exp $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfPhrase extends RtfElement { + + /** + * Constant for the resetting of the paragraph defaults + */ + public static final byte[] PARAGRAPH_DEFAULTS = "\\pard".getBytes(); + /** + * Constant for phrase in a table indication + */ + public static final byte[] IN_TABLE = "\\intbl".getBytes(); + /** + * Constant for the line spacing. + */ + public static final byte[] LINE_SPACING = "\\sl".getBytes(); + + /** + * ArrayList containing the RtfChunks of this RtfPhrase + */ + protected ArrayList chunks = new ArrayList(); + /** + * The height of each line. + */ + private int lineLeading = 0; + + /** + * A basically empty constructor that is used by the RtfParagraph. + * + * @param doc The RtfDocument this RtfPhrase belongs to. + */ + protected RtfPhrase(RtfDocument doc) { + super(doc); + } + + /** + * Constructs a new RtfPhrase for the RtfDocument with the given Phrase + * + * @param doc The RtfDocument this RtfPhrase belongs to + * @param phrase The Phrase this RtfPhrase is based on + */ + public RtfPhrase(RtfDocument doc, Phrase phrase) { + super(doc); + + if(phrase == null) { + return; + } + + if(phrase.leadingDefined()) { + this.lineLeading = (int) (phrase.leading() * RtfElement.TWIPS_FACTOR); + } else { + this.lineLeading = 0; + } + + RtfFont phraseFont = new RtfFont(null, phrase.font()); + for(int i = 0; i < phrase.size(); i++) { + Element chunk = (Element) phrase.get(i); + if(chunk instanceof Chunk) { + ((Chunk) chunk).setFont(phraseFont.difference(((Chunk) chunk).font())); + } + try { + chunks.add(doc.getMapper().mapElement(chunk)); + } catch(DocumentException de) { + } + } + } + + /** + * Write the content of this RtfPhrase. First resets to the paragraph defaults + * then if the RtfPhrase is in a RtfCell a marker for this is written and finally + * the RtfChunks of this RtfPhrase are written. + * + * @return The content of this RtfPhrase + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(PARAGRAPH_DEFAULTS); + if(inTable) { + result.write(IN_TABLE); + } + if(this.lineLeading > 0) { + result.write(LINE_SPACING); + result.write(intToByteArray(this.lineLeading)); + } + for(int i = 0; i < chunks.size(); i++) { + result.write(((RtfBasicElement) chunks.get(i)).write()); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Sets whether this RtfPhrase is in a table. Sets the correct inTable setting for all + * child elements. + * + * @param inTable True if this RtfPhrase is in a table, false otherwise + */ + public void setInTable(boolean inTable) { + super.setInTable(inTable); + for(int i = 0; i < this.chunks.size(); i++) { + ((RtfBasicElement) this.chunks.get(i)).setInTable(inTable); + } + } + + /** + * Sets whether this RtfPhrase is in a header. Sets the correct inTable setting for all + * child elements. + * + * @param inHeader True if this RtfPhrase is in a header, false otherwise + */ + public void setInHeader(boolean inHeader) { + super.setInHeader(inHeader); + for(int i = 0; i < this.chunks.size(); i++) { + ((RtfBasicElement) this.chunks.get(i)).setInHeader(inHeader); + } + } + + /** + * Sets the RtfDocument this RtfPhrase belongs to. Also sets the RtfDocument for all child + * elements. + * + * @param doc The RtfDocument to use + */ + public void setRtfDocument(RtfDocument doc) { + super.setRtfDocument(doc); + for(int i = 0; i < this.chunks.size(); i++) { + ((RtfBasicElement) this.chunks.get(i)).setRtfDocument(this.document); + } + } +} diff --git a/src/main/java/com/lowagie/text/rtf/text/RtfSection.java b/src/main/java/com/lowagie/text/rtf/text/RtfSection.java new file mode 100644 index 0000000..2b5ad86 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/text/RtfSection.java @@ -0,0 +1,201 @@ +/* + * $Id: RtfSection.java,v 1.11 2005/08/19 21:17:04 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.text; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Iterator; +import java.util.ArrayList; + +import com.lowagie.text.Chunk; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.Section; +import com.lowagie.text.rtf.RtfBasicElement; +import com.lowagie.text.rtf.RtfElement; +import com.lowagie.text.rtf.document.RtfDocument; +import com.lowagie.text.rtf.field.RtfTOCEntry; + + +/** + * The RtfSection wraps a Section element. + * INTERNAL CLASS + * + * @version $Revision: 1.11 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfSection extends RtfElement { + + /** + * The title paragraph of this RtfSection + */ + protected RtfParagraph title = null; + /** + * The sub-items of this RtfSection + */ + protected ArrayList items = null; + + /** + * Constructs a RtfSection for a given Section. If the autogenerateTOCEntries + * property of the RtfDocument is set and the title is not empty then a TOC entry + * is generated for the title. + * + * @param doc The RtfDocument this RtfSection belongs to + * @param section The Section this RtfSection is based on + */ + public RtfSection(RtfDocument doc, Section section) { + super(doc); + items = new ArrayList(); + try { + if(section.title() != null) { + this.title = (RtfParagraph) doc.getMapper().mapElement(section.title()); + } + if(document.getAutogenerateTOCEntries()) { + StringBuffer titleText = new StringBuffer(); + Iterator it = section.title().iterator(); + while(it.hasNext()) { + Element element = (Element) it.next(); + if(element.type() == Element.CHUNK) { + titleText.append(((Chunk) element).content()); + } + } + if(titleText.toString().trim().length() > 0) { + RtfTOCEntry tocEntry = new RtfTOCEntry(titleText.toString(), section.title().font()); + tocEntry.setRtfDocument(this.document); + this.items.add(tocEntry); + } + } + Iterator iterator = section.iterator(); + while(iterator.hasNext()) { + Element element = (Element) iterator.next(); + RtfBasicElement rtfElement = doc.getMapper().mapElement(element); + if(rtfElement != null) { + items.add(rtfElement); + } + } + + updateIndentation(section.indentationLeft(), section.indentationRight(), section.indentation()); + } catch(DocumentException de) { + de.printStackTrace(); + } + } + + /** + * Write this RtfSection and its contents + * + * @return A byte array with the RtfSection and its contents + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + result.write(RtfParagraph.PARAGRAPH); + if(this.title != null) { + result.write(this.title.write()); + } + for(int i = 0; i < items.size(); i++) { + result.write(((RtfBasicElement) items.get(i)).write()); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } + + /** + * Sets whether this RtfSection is in a table. Sets the correct inTable setting for all + * child elements. + * + * @param inTable True if this RtfSection is in a table, false otherwise + */ + public void setInTable(boolean inTable) { + super.setInTable(inTable); + for(int i = 0; i < this.items.size(); i++) { + ((RtfBasicElement) this.items.get(i)).setInTable(inTable); + } + } + + /** + * Sets whether this RtfSection is in a header. Sets the correct inTable setting for all + * child elements. + * + * @param inHeader True if this RtfSection is in a header, false otherwise + */ + public void setInHeader(boolean inHeader) { + super.setInHeader(inHeader); + for(int i = 0; i < this.items.size(); i++) { + ((RtfBasicElement) this.items.get(i)).setInHeader(inHeader); + } + } + + /** + * Updates the left, right and content indentation of all RtfParagraph and RtfSection + * elements that this RtfSection contains. + * + * @param indentLeft The left indentation to add. + * @param indentRight The right indentation to add. + * @param indentContent The content indentation to add. + */ + private void updateIndentation(float indentLeft, float indentRight, float indentContent) { + if(this.title != null) { + this.title.setIndentLeft((int) (this.title.getIndentLeft() + indentLeft * RtfElement.TWIPS_FACTOR)); + this.title.setIndentRight((int) (this.title.getIndentRight() + indentRight * RtfElement.TWIPS_FACTOR)); + } + for(int i = 0; i < this.items.size(); i++) { + RtfBasicElement rtfElement = (RtfBasicElement) this.items.get(i); + if(rtfElement instanceof RtfSection) { + ((RtfSection) rtfElement).updateIndentation(indentLeft + indentContent, indentRight, 0); + } else if(rtfElement instanceof RtfParagraph) { + ((RtfParagraph) rtfElement).setIndentLeft((int) (((RtfParagraph) rtfElement).getIndentLeft() + (indentLeft + indentContent) * RtfElement.TWIPS_FACTOR)); + ((RtfParagraph) rtfElement).setIndentRight((int) (((RtfParagraph) rtfElement).getIndentRight() + indentRight * RtfElement.TWIPS_FACTOR)); + } + } + } +} diff --git a/src/main/java/com/lowagie/text/rtf/text/RtfTab.java b/src/main/java/com/lowagie/text/rtf/text/RtfTab.java new file mode 100644 index 0000000..1041ae6 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/text/RtfTab.java @@ -0,0 +1,140 @@ +/* + * $Id: RtfTab.java,v 1.1 2006/06/17 09:51:30 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * Co-Developer of the code is Mark Hall. Portions created by the Co-Developer are + * Copyright (C) 2006 by Mark Hall. All Rights Reserved + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.text; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.lowagie.text.rtf.RtfAddableElement; + +/** + * The RtfTab encapsulates a tab position and tab type in a paragraph. + * To add tabs to a paragraph construct new RtfTab objects with the desired + * tab position and alignment and then add them to the paragraph. In the actual + * text the tabs are then defined as standard \t characters.

+ * + * RtfTab tab = new RtfTab(300, RtfTab.TAB_LEFT_ALIGN);
+ * Paragraph para = new Paragraph();
+ * para.add(tab);
+ * para.add("This paragraph has a\ttab defined.");
+ * + * @version $Revision: 1.1 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfTab extends RtfAddableElement { + + /** + * A tab where the text is left aligned. + */ + public static final int TAB_LEFT_ALIGN = 0; + /** + * A tab where the text is centre aligned. + */ + public static final int TAB_CENTER_ALIGN = 1; + /** + * A tab where the text is right aligned. + */ + public static final int TAB_RIGHT_ALIGN = 2; + /** + * A tab where the text is aligned on the decimal character. Which + * character that is depends on the language settings of the viewer. + */ + public static final int TAB_DECIMAL_ALIGN = 3; + + /** + * The tab position in twips. + */ + private int position = 0; + /** + * The tab alignment. + */ + private int type = TAB_LEFT_ALIGN; + + /** + * Constructs a new RtfTab with the given position and type. The position + * is in standard iText points. The type is one of the tab alignment + * constants defined in the RtfTab. + * + * @param position The position of the tab in points. + * @param type The tab type constant. + */ + public RtfTab(float position, int type) { + this.position = (int) Math.round(position * TWIPS_FACTOR); + switch(type) { + case TAB_LEFT_ALIGN: this.type = TAB_LEFT_ALIGN; break; + case TAB_CENTER_ALIGN: this.type = TAB_CENTER_ALIGN; break; + case TAB_RIGHT_ALIGN: this.type = TAB_RIGHT_ALIGN; break; + case TAB_DECIMAL_ALIGN: this.type = TAB_DECIMAL_ALIGN; break; + default: this.type = TAB_LEFT_ALIGN; break; + } + } + + /** + * Writes the tab settings. + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + switch(this.type) { + case TAB_CENTER_ALIGN: result.write("\\tqc".getBytes()); break; + case TAB_RIGHT_ALIGN: result.write("\\tqr".getBytes()); break; + case TAB_DECIMAL_ALIGN: result.write("\\tqdec".getBytes()); break; + } + result.write("\\tx".getBytes()); + result.write(intToByteArray(this.position)); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } +} diff --git a/src/main/java/com/lowagie/text/rtf/text/RtfTabGroup.java b/src/main/java/com/lowagie/text/rtf/text/RtfTabGroup.java new file mode 100644 index 0000000..e298221 --- /dev/null +++ b/src/main/java/com/lowagie/text/rtf/text/RtfTabGroup.java @@ -0,0 +1,127 @@ +/* + * $Id: RtfTabGroup.java,v 1.1 2006/06/17 09:51:30 hallm Exp $ + * $Name: $ + * + * Copyright 2001, 2002, 2003, 2004 by Mark Hall + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * Co-Developer of the code is Mark Hall. Portions created by the Co-Developer are + * Copyright (C) 2006 by Mark Hall. All Rights Reserved + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.rtf.text; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +import com.lowagie.text.rtf.RtfAddableElement; + +/** + * The RtfTabGroup is a convenience class if the same tabs are to be added + * to multiple paragraphs.

+ * + * RtfTabGroup tabs = new RtfTabGroup();
+ * tabs.add(new RtfTab(70, RtfTab.TAB_LEFT_ALIGN));
+ * tabs.add(new RtfTab(160, RtfTab.TAB_CENTER_ALIGN));
+ * tabs.add(new RtfTab(250, RtfTab.TAB_DECIMAL_ALIGN));
+ * tabs.add(new RtfTab(500, RtfTab.TAB_RIGHT_ALIGN));
+ * Paragraph para = new Paragraph();
+ * para.add(tabs);
+ * para.add("\tLeft aligned\tCentre aligned\t12,45\tRight aligned");
+ * + * @version $Revision: 1.1 $ + * @author Mark Hall (mhall@edu.uni-klu.ac.at) + */ +public class RtfTabGroup extends RtfAddableElement { + /** + * The tabs to add. + */ + private ArrayList tabs = null; + + /** + * Constructs an empty RtfTabGroup. + */ + public RtfTabGroup() { + this.tabs = new ArrayList(); + } + + /** + * Constructs a RtfTabGroup with a set of tabs. + * + * @param tabs An ArrayList with the RtfTabs to group in this RtfTabGroup. + */ + public RtfTabGroup(ArrayList tabs) { + this.tabs = new ArrayList(); + for(int i = 0; i < tabs.size(); i++) { + if(tabs.get(i) instanceof RtfTab) { + this.tabs.add(tabs.get(i)); + } + } + } + + /** + * Adds a RtfTab to the list of grouped tabs. + * + * @param tab The RtfTab to add. + */ + public void add(RtfTab tab) { + this.tabs.add(tab); + } + + /** + * Combines the tab output form all grouped tabs. + */ + public byte[] write() { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try { + for(int i = 0; i < this.tabs.size(); i++) { + result.write(((RtfTab) this.tabs.get(i)).write()); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + return result.toByteArray(); + } +} -- cgit v1.2.3