org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fop Show documentation
Show all versions of fop Show documentation
Apache FOP (Formatting Objects Processor) is the world's first print formatter driven by XSL formatting objects (XSL-FO) and the world's first output independent formatter. It is a Java application that reads a formatting object (FO) tree and renders the resulting pages to a specified output. Output formats currently supported include PDF, PCL, PS, AFP, TIFF, PNG, SVG, XML (area tree representation), Print, AWT and TXT. The primary output target is PDF.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id: RtfParagraph.java 1610839 2014-07-15 20:25:58Z vhennebert $ */
package org.apache.fop.render.rtf.rtflib.rtfdoc;
/*
* This file is part of the RTF library of the FOP project, which was originally
* created by Bertrand Delacretaz and by other
* contributors to the jfor project (www.jfor.org), who agreed to donate jfor to
* the FOP project.
*/
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import org.apache.fop.apps.FOPException;
/**
* Model of an RTF paragraph, which can contain RTF text elements.
*
* This work was authored by Bertrand Delacretaz ([email protected]),
* Andreas Putz ([email protected]), and
* Boris Poudérous ([email protected]).
*/
public class RtfParagraph extends RtfBookmarkContainerImpl
implements IRtfTextContainer, IRtfPageBreakContainer, IRtfHyperLinkContainer,
IRtfExternalGraphicContainer, IRtfPageNumberContainer,
IRtfPageNumberCitationContainer {
private RtfText text;
private RtfHyperLink hyperlink;
private RtfExternalGraphic externalGraphic;
private RtfPageNumber pageNumber;
private RtfPageNumberCitation pageNumberCitation;
// Above line added by Boris POUDEROUS on 2002/07/09
private boolean keepn;
private boolean resetProperties;
/* needed for importing Rtf into FrameMaker
FrameMaker is not as forgiving as word in rtf
thus /pard/par must be written in a page break directly
after a table. /pard is probably needed in other places
also, this is just a hack to make FrameMaker import Jfor rtf
correctly */
private boolean writeForBreak;
/** Set of attributes that must be copied at the start of a paragraph */
private static final String[] PARA_ATTRIBUTES = {"intbl"};
/** Create an RTF paragraph as a child of given container with default attributes */
RtfParagraph(IRtfParagraphContainer parent, Writer w) throws IOException {
super((RtfContainer)parent, w);
}
/** Create an RTF paragraph as a child of given container with given attributes */
RtfParagraph(IRtfParagraphContainer parent, Writer w, RtfAttributes attr) throws IOException {
super((RtfContainer)parent, w, attr);
}
/**
* Accessor for the paragraph text
* @return the paragraph text
*/
public String getText() {
return (text.getText());
}
/** Set the keepn attribute for this paragraph */
public void setKeepn() {
this.keepn = true;
}
/** Force reset properties */
public void setResetProperties() {
this.resetProperties = true;
}
/**
* IRtfTextContainer requirement: return a copy of our attributes
* @return a copy of this paragraphs attributes
* @throws FOPException if attributes cannot be cloned
*/
public RtfAttributes getTextContainerAttributes() throws FOPException {
if (attrib == null) {
return null;
}
try {
return (RtfAttributes)this.attrib.clone();
} catch (CloneNotSupportedException e) {
throw new FOPException(e);
}
}
/**
* Overridden to write our attributes before our content
* @throws IOException for I/O problems
*/
protected void writeRtfPrefix() throws IOException {
//Reset paragraph properties if needed
if (resetProperties) {
writeControlWord("pard");
}
/*
* Original comment said "do not write text attributes here, they are
* handled by RtfText." However, the text attributes appear to be
* relevant to paragraphs as well.
*/
writeAttributes(attrib, RtfText.ATTR_NAMES);
writeAttributes(attrib, PARA_ATTRIBUTES);
// Added by Normand Masse
// Write alignment attributes after \intbl for cells
if (attrib.isSet("intbl") && mustWriteAttributes()) {
writeAttributes(attrib, RtfText.ALIGNMENT);
}
//Set keepn if needed (Keep paragraph with the next paragraph)
if (keepn) {
writeControlWord("keepn");
}
// start a group for this paragraph and write our own attributes if needed
if (mustWriteGroupMark()) {
writeGroupMark(true);
}
if (mustWriteAttributes()) {
// writeAttributes(m_attrib, new String [] {"cs"});
// Added by Normand Masse
// If \intbl then attributes have already been written (see higher in method)
if (!attrib.isSet("intbl")) {
writeAttributes(attrib, RtfText.ALIGNMENT);
}
//this line added by Chris Scott, Westinghouse
writeAttributes(attrib, RtfText.BORDER);
writeAttributes(attrib, RtfText.INDENT);
writeAttributes(attrib, RtfText.TABS);
if (writeForBreak) {
writeControlWord("pard\\par");
}
}
}
/**
* Overridden to close paragraph
* @throws IOException for I/O problems
*/
protected void writeRtfSuffix() throws IOException {
// sometimes the end of paragraph mark must be suppressed in table cells
boolean writeMark = true;
if (parent instanceof RtfTableCell) {
writeMark = ((RtfTableCell)parent).paragraphNeedsPar(this);
}
if (writeMark) {
writeControlWord("par");
}
if (mustWriteGroupMark()) {
writeGroupMark(false);
}
}
/**
* Close current text run if any and start a new one with default attributes
* @param str if not null, added to the RtfText created
* @return the new RtfText object
* @throws IOException for I/O problems
*/
public RtfText newText(String str) throws IOException {
return newText(str, null);
}
/**
* Close current text run if any and start a new one
* @param str if not null, added to the RtfText created
* @param attr attributes of the text
* @return the new RtfText object
* @throws IOException for I/O problems
*/
public RtfText newText(String str, RtfAttributes attr) throws IOException {
closeAll();
text = new RtfText(this, writer, str, attr);
return text;
}
/**
* add a page break
* @throws IOException for I/O problems
*/
public void newPageBreak() throws IOException {
writeForBreak = true;
new RtfPageBreak(this, writer);
}
/**
* add a line break
* @throws IOException for I/O problems
*/
public void newLineBreak() throws IOException {
new RtfLineBreak(this, writer);
}
/**
* Add a page number
* @return new RtfPageNumber object
* @throws IOException for I/O problems
*/
public RtfPageNumber newPageNumber()throws IOException {
pageNumber = new RtfPageNumber(this, writer);
return pageNumber;
}
/**
* Added by Boris POUDEROUS on 2002/07/09
* @param id string containing the citation text
* @return the new RtfPageNumberCitation object
* @throws IOException for I/O problems
*/
public RtfPageNumberCitation newPageNumberCitation(String id) throws IOException {
pageNumberCitation = new RtfPageNumberCitation(this, writer, id);
return pageNumberCitation;
}
/**
* Creates a new hyperlink.
* @param str string containing the hyperlink text
* @param attr attributes of new hyperlink
* @return the new RtfHyperLink object
* @throws IOException for I/O problems
*/
public RtfHyperLink newHyperLink(String str, RtfAttributes attr) throws IOException {
hyperlink = new RtfHyperLink(this, writer, str, attr);
return hyperlink;
}
/**
* Start a new external graphic after closing all other elements
* @return the new RtfExternalGraphic
* @throws IOException for I/O problems
*/
public RtfExternalGraphic newImage() throws IOException {
closeAll();
externalGraphic = new RtfExternalGraphic(this, writer);
return externalGraphic;
}
private void closeCurrentText() throws IOException {
if (text != null) {
text.close();
}
}
private void closeCurrentHyperLink() throws IOException {
if (hyperlink != null) {
hyperlink.close();
}
}
private void closeAll() throws IOException {
closeCurrentText();
closeCurrentHyperLink();
}
/**
* Depending on RtfOptions, do not emit any RTF for empty paragraphs
* @return true if RTF should be written
*/
protected boolean okToWriteRtf() {
boolean result = super.okToWriteRtf();
if (parent.getOptions().ignoreEmptyParagraphs() && getChildCount() == 0) {
// TODO should test that this is the last RtfParagraph in the cell instead
// of simply testing for last child??
result = false;
}
return result;
}
/** true if we must write our own (non-text) attributes in the RTF */
private boolean mustWriteAttributes() {
boolean writeAttributes = false;
final int children = getChildCount();
if (children > 0) {
final List childList = getChildren();
for (int i = 0; i < children; i++) {
final RtfElement el = (RtfElement) childList.get(i);
if (!el.isEmpty()) {
if (el.getClass() == RtfText.class) {
boolean tmp = ((RtfText) el).isNbsp();
if (!tmp) {
writeAttributes = true;
break;
}
} else {
writeAttributes = true;
break;
}
}
}
}
return writeAttributes;
}
/** true if we must write a group mark around this paragraph
* TODO is this correct, study interaction with mustWriteAttributes()
* <-- On implementation i have noticed if the groupmark set, the
* format attributes are only for this content, i think this
* implementation is ok
*/
private boolean mustWriteGroupMark() {
return getChildCount() > 0;
}
/**
* accessor for text attributes
* @return attributes of the text
*/
public RtfAttributes getTextAttributes() {
if (text == null) {
return null;
}
return text.getTextAttributes();
}
}