aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Victor Mote <vmote@apache.org>2003-09-18 15:57:25 +0000
committerWilliam Victor Mote <vmote@apache.org>2003-09-18 15:57:25 +0000
commit1519516c352043282afe61f8b425cff5788f40d1 (patch)
treeeb191f86452124ef0cbebe7ece15fb0f4092f8d1
parent61c06c40922ead3eabb28cd3c6b7c13beada2906 (diff)
downloadxmlgraphics-fop-1519516c352043282afe61f8b425cff5788f40d1.tar.gz
xmlgraphics-fop-1519516c352043282afe61f8b425cff5788f40d1.zip
changes for RTF tables, submitted by Peter Herweg, see http://nagoya.apache.org/bugzilla/show_bug.cgi?id=23166
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@196921 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/fop/fo/flow/TableBody.java18
-rw-r--r--src/java/org/apache/fop/rtf/renderer/BuilderContext.java199
-rw-r--r--src/java/org/apache/fop/rtf/renderer/FoUnitsConverter.java177
-rw-r--r--src/java/org/apache/fop/rtf/renderer/RTFHandler.java184
-rw-r--r--src/java/org/apache/fop/rtf/renderer/TableAttributesConverter.java440
-rw-r--r--src/java/org/apache/fop/rtf/renderer/TableContext.java224
-rw-r--r--src/java/org/apache/fop/rtf/rtflib/rtfdoc/ITableAttributes.java1
-rwxr-xr-xsrc/java/org/apache/fop/rtf/rtflib/rtfdoc/RtfTable.java4
8 files changed, 1229 insertions, 18 deletions
diff --git a/src/java/org/apache/fop/fo/flow/TableBody.java b/src/java/org/apache/fop/fo/flow/TableBody.java
index 71cd68b85..474acc814 100644
--- a/src/java/org/apache/fop/fo/flow/TableBody.java
+++ b/src/java/org/apache/fop/fo/flow/TableBody.java
@@ -50,6 +50,9 @@
*/
package org.apache.fop.fo.flow;
+// XML
+import org.xml.sax.Attributes;
+
// FOP
import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.ColorType;
@@ -123,5 +126,20 @@ public class TableBody extends FObj {
fotv.serveTableBody(this);
}
+ /**
+ * @see org.apache.fop.fo.FObj#handleAttrs
+ */
+ public void handleAttrs(Attributes attlist) throws FOPException {
+ super.handleAttrs(attlist);
+
+ setupID();
+
+ getFOTreeControl().getFOInputHandler().startBody(this);
+ }
+
+ protected void end() {
+ getFOTreeControl().getFOInputHandler().endBody(this);
+ }
+
}
diff --git a/src/java/org/apache/fop/rtf/renderer/BuilderContext.java b/src/java/org/apache/fop/rtf/renderer/BuilderContext.java
new file mode 100644
index 000000000..00e41c524
--- /dev/null
+++ b/src/java/org/apache/fop/rtf/renderer/BuilderContext.java
@@ -0,0 +1,199 @@
+/*
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.rtf.renderer;
+
+import java.util.Stack;
+import org.apache.fop.rtf.rtflib.rtfdoc.*;
+
+
+/** A BuilderContext holds context information when building an RTF document
+ *
+ * @author Bertrand Delacretaz <bdelacretaz@codeconsult.ch>
+ * @author putzi
+ * @author Peter Herweg <pherweg@web.de>
+ *
+ * This class was originally developed by Bertrand Delacretaz bdelacretaz@codeconsult.ch
+ * for the JFOR project and is now integrated into FOP.
+ */
+
+
+class BuilderContext
+{
+ /** stack of RtfContainers */
+ private final Stack m_containers = new Stack();
+
+ /** stack of TableContexts */
+ private final Stack m_tableContexts = new Stack();
+
+ /** stack of IBuilders */
+ private final Stack m_builders = new Stack();
+
+ /** Rtf options */
+ IRtfOptions m_options;
+
+ BuilderContext(IRtfOptions rtfOptions)
+ {
+ m_options = rtfOptions;
+ }
+
+ /** find first object of given class from top of stack s
+ * @return null if not found
+ */
+ private Object getObjectFromStack(Stack s,Class desiredClass)
+ {
+ Object result = null;
+ final Stack copy = (Stack)s.clone();
+ while(!copy.isEmpty()) {
+ final Object o = copy.pop();
+ if(desiredClass.isAssignableFrom(o.getClass())) {
+ result = o;
+ break;
+ }
+ }
+ return result;
+ }
+
+ /* find the "nearest" IBuilder of given class /
+ Object getBuilder(Class builderClass,boolean required)
+ throws Exception
+ {
+ final IBuilder result = (IBuilder)getObjectFromStack(m_builders,builderClass);
+ if(result == null && required) {
+ throw new Exception(
+ "IBuilder of class '" + builderClass.getName() + "' not found on builders stack"
+ );
+ }
+ return result;
+ }*/
+
+ /** find the "nearest" container that implements the given interface on our stack
+ * @param required if true, ConverterException is thrown if no container found
+ * @param forWhichBuilder used in error message if container not found
+ */
+ RtfContainer getContainer(Class containerClass,boolean required,Object /*IBuilder*/ forWhichBuilder) throws Exception
+ {
+ // TODO what to do if the desired container is not at the top of the stack?
+ // close top-of-stack container?
+ final RtfContainer result = (RtfContainer)getObjectFromStack(m_containers,containerClass);
+
+ if(result == null && required) {
+ throw new Exception(
+ "No RtfContainer of class '" + containerClass.getName()
+ + "' available for '" + forWhichBuilder.getClass().getName() + "' builder"
+ );
+ }
+
+ return result;
+ }
+
+ /** push an RtfContainer on our stack */
+ void pushContainer(RtfContainer c)
+ {
+ m_containers.push(c);
+ }
+
+ /** in some cases an RtfContainer must be replaced by another one on the stack.
+ * this happens when handling nested fo:blocks for example: after handling a nested block
+ * the enclosing block must switch to a new paragraph container to handle what follows the nested block.
+ * TODO: what happens to elements that are "more on top" than oldC on the stack? shouldn't they be closed
+ * or something?
+ */
+ void replaceContainer(RtfContainer oldC,RtfContainer newC)
+ throws Exception
+ {
+ // treating the Stack as a Vector allows such manipulations (yes, I hear you screaming ;-)
+ final int index = m_containers.indexOf(oldC);
+ if(index < 0) throw new Exception("container to replace not found:" + oldC);
+ m_containers.setElementAt(newC,index);
+ }
+
+ /** pop the topmost RtfContainer from our stack */
+ void popContainer()
+ {
+ m_containers.pop();
+ }
+
+ /* push an IBuilder to our stack /
+ void pushBuilder(IBuilder b)
+ {
+ m_builders.push(b);
+ }*/
+
+ /** pop the topmost IBuilder from our stack and return previous builder on stack
+ * @return null if builders stack is empty
+
+ IBuilder popBuilderAndGetPreviousOne()
+ {
+ IBuilder result = null;
+ m_builders.pop();
+ if(!m_builders.isEmpty()) {
+ result = (IBuilder)m_builders.peek();
+ }
+ return result;
+ }
+ */
+ /** return the current TableContext */
+ TableContext getTableContext()
+ {
+ return (TableContext)m_tableContexts.peek();
+ }
+
+ /** push a TableContext to our stack */
+ void pushTableContext(TableContext tc)
+ {
+ m_tableContexts.push(tc);
+ }
+
+ /** pop a TableContext from our stack */
+ void popTableContext()
+ {
+ m_tableContexts.pop();
+ }
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/rtf/renderer/FoUnitsConverter.java b/src/java/org/apache/fop/rtf/renderer/FoUnitsConverter.java
new file mode 100644
index 000000000..99bec8fd4
--- /dev/null
+++ b/src/java/org/apache/fop/rtf/renderer/FoUnitsConverter.java
@@ -0,0 +1,177 @@
+/*
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.rtf.renderer;
+
+import java.util.*;
+
+//FOP
+import org.apache.fop.apps.FOPException;
+
+
+/** Converts XSL-FO units to RTF units
+ *
+ * @author Bertrand Delacretaz <bdelacretaz@codeconsult.ch>
+ * @author putzi
+ * @author Peter Herweg <pherweg@web.de>
+ *
+ * This class was originally developed by Bertrand Delacretaz bdelacretaz@codeconsult.ch
+ * for the JFOR project and is now integrated into FOP.
+ */
+
+class FoUnitsConverter
+{
+ private static final FoUnitsConverter m_instance = new FoUnitsConverter();
+
+ /** points to twips: 1 twip is 1/20 of a point */
+ public static final float POINT_TO_TWIPS = 20f;
+
+ /** millimeters and centimeters to twips: , one point is 1/72 of an inch, one inch is 25.4 mm */
+ public static final float IN_TO_TWIPS = 72f * POINT_TO_TWIPS;
+ public static final float MM_TO_TWIPS = IN_TO_TWIPS / 25.4f;
+ public static final float CM_TO_TWIPS = 10 * MM_TO_TWIPS;
+
+
+ /** conversion factors keyed by xsl:fo units names */
+ private static final Map m_twipFactors = new HashMap();
+ static {
+ m_twipFactors.put("mm",new Float(MM_TO_TWIPS));
+ m_twipFactors.put("cm",new Float(CM_TO_TWIPS));
+ m_twipFactors.put("pt",new Float(POINT_TO_TWIPS));
+ m_twipFactors.put("in",new Float(IN_TO_TWIPS));
+ }
+
+ /** singleton pattern */
+ private FoUnitsConverter()
+ {
+ }
+
+ /** singleton pattern */
+ static FoUnitsConverter getInstance()
+ {
+ return m_instance;
+ }
+
+ /** convert given value to RTF units
+ * @param foValue a value like "12mm"
+ * TODO: tested with "mm" units only, needs work to comply with FO spec
+ * Why does it search for period instead of simply breaking last two
+ * Characters into another units string? - Chris
+ */
+ float convertToTwips(String foValue)
+ throws FOPException
+ {
+ foValue = foValue.trim();
+
+ // break value into number and units
+ final StringBuffer number = new StringBuffer();
+ final StringBuffer units = new StringBuffer();
+
+ for(int i=0; i < foValue.length(); i++) {
+ final char c = foValue.charAt(i);
+ if(Character.isDigit(c) || c == '.') {
+ number.append(c);
+ } else {
+ // found the end of the digits
+ units.append(foValue.substring(i).trim());
+ break;
+ }
+ }
+
+ return numberToTwips(number.toString(),units.toString());
+ }
+
+
+ /** convert given value to twips according to given units */
+ private float numberToTwips(String number,String units)
+ throws FOPException
+ {
+ float result = 0;
+
+ // convert number to integer
+ try {
+ if(number != null && number.trim().length() > 0) {
+ result = Float.valueOf(number).floatValue();
+ }
+ } catch(Exception e) {
+ throw new FOPException("number format error: cannot convert '" + number + "' to float value");
+ }
+
+ // find conversion factor
+ if(units != null && units.trim().length() > 0) {
+ final Float factor = (Float)m_twipFactors.get(units.toLowerCase());
+ if(factor == null) throw new FOPException("conversion factor not found for '" + units + "' units");
+ result *= factor.floatValue();
+ }
+
+ return result;
+ }
+
+ /** convert a font size given in points like "12pt" */
+ int convertFontSize(String size)
+ throws FOPException
+ {
+ size = size.trim();
+ final String FONT_SUFFIX = "pt";
+ if(!size.endsWith(FONT_SUFFIX)) {
+ throw new FOPException("Invalid font size '" + size + "', must end with '" + FONT_SUFFIX + "'");
+ }
+
+ float result = 0;
+ size = size.substring(0,size.length() - FONT_SUFFIX.length());
+ try {
+ result = (Float.valueOf(size).floatValue());
+ } catch(Exception e) {
+ throw new FOPException("Invalid font size value '" + size + "'");
+ }
+
+ // RTF font size units are in half-points
+ return (int)(result * 2.0);
+ }
+}
diff --git a/src/java/org/apache/fop/rtf/renderer/RTFHandler.java b/src/java/org/apache/fop/rtf/renderer/RTFHandler.java
index 2de35ed58..cb38defab 100644
--- a/src/java/org/apache/fop/rtf/renderer/RTFHandler.java
+++ b/src/java/org/apache/fop/rtf/renderer/RTFHandler.java
@@ -55,7 +55,8 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import org.apache.fop.apps.Driver;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.ColorType;
import org.apache.fop.fo.FOInputHandler;
@@ -73,7 +74,9 @@ import org.apache.fop.fo.flow.TableRow;
import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.properties.Constants;
+import org.apache.fop.fo.Property;
import org.apache.fop.apps.Document;
+import org.apache.fop.rtf.rtflib.rtfdoc.IRtfParagraphContainer;
import org.apache.fop.rtf.rtflib.rtfdoc.RtfAttributes;
import org.apache.fop.rtf.rtflib.rtfdoc.RtfColorTable;
import org.apache.fop.rtf.rtflib.rtfdoc.RtfDocumentArea;
@@ -81,22 +84,31 @@ import org.apache.fop.rtf.rtflib.rtfdoc.RtfFile;
import org.apache.fop.rtf.rtflib.rtfdoc.RtfParagraph;
import org.apache.fop.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.rtf.rtflib.rtfdoc.RtfText;
+import org.apache.fop.rtf.rtflib.rtfdoc.RtfTable;
+import org.apache.fop.rtf.rtflib.rtfdoc.RtfTableRow;
+import org.apache.fop.rtf.rtflib.rtfdoc.RtfTableCell;
+import org.apache.fop.rtf.rtflib.rtfdoc.IRtfTableContainer;
import org.xml.sax.SAXException;
/**
* RTF Handler: generates RTF output using the structure events from
* the FO Tree sent to this structure handler.
*
- * @author bdelacretaz@apache.org
+ * @author Bertrand Delacretaz <bdelacretaz@codeconsult.ch>
+ * @author Trembicki-Guy, Ed <GuyE@DNB.com>
+ * @author Boris Poudérous <boris.pouderous@eads-telecom.com>
+ * @author Peter Herweg <pherweg@web.de>
*/
public class RTFHandler extends FOInputHandler {
private RtfFile rtfFile;
private final OutputStream os;
+ private final Logger log=new ConsoleLogger();
private RtfSection sect;
private RtfDocumentArea docArea;
private RtfParagraph para;
private boolean warned = false;
+ private BuilderContext m_context=new BuilderContext(null);
private static final String ALPHA_WARNING = "WARNING: RTF renderer is "
+ "veryveryalpha at this time, see class org.apache.fop.rtf.renderer.RTFHandler";
@@ -116,7 +128,7 @@ public class RTFHandler extends FOInputHandler {
this.os = os;
// use pdf fonts for now, this is only for resolving names
org.apache.fop.render.pdf.FontSetup.setup(doc, null);
- System.err.println(ALPHA_WARNING);
+ log.warn(ALPHA_WARNING);
}
/**
@@ -151,12 +163,14 @@ public class RTFHandler extends FOInputHandler {
public void startPageSequence(PageSequence pageSeq) {
try {
sect = docArea.newSection();
+ m_context.pushContainer(sect);
if (!warned) {
sect.newParagraph().newText(ALPHA_WARNING);
warned = true;
}
} catch (IOException ioe) {
// FIXME could we throw Exception in all FOInputHandler events?
+ log.error("startPageSequence: " + ioe.getMessage());
throw new Error("IOException: " + ioe);
}
}
@@ -165,6 +179,7 @@ public class RTFHandler extends FOInputHandler {
* @see org.apache.fop.fo.FOInputHandler#endPageSequence(PageSequence)
*/
public void endPageSequence(PageSequence pageSeq) throws FOPException {
+ m_context.popContainer();
}
/**
@@ -190,11 +205,20 @@ public class RTFHandler extends FOInputHandler {
attrBlockFontSize(bl, rtfAttr);
attrBlockFontWeight(bl, rtfAttr);
- para = sect.newParagraph(rtfAttr);
+ IRtfParagraphContainer pc=(IRtfParagraphContainer)m_context.getContainer(IRtfParagraphContainer.class,true,null);
+ para = pc.newParagraph(rtfAttr);
+
+ m_context.pushContainer(para);
} catch (IOException ioe) {
// FIXME could we throw Exception in all FOInputHandler events?
+ log.error("startBlock: " + ioe.getMessage());
throw new Error("IOException: " + ioe);
}
+ catch(Exception e)
+ {
+ log.error("startBlock: " + e.getMessage());
+ throw new Error("Exception: " + e);
+ }
}
@@ -202,18 +226,65 @@ public class RTFHandler extends FOInputHandler {
* @see org.apache.fop.fo.FOInputHandler#endBlock(Block)
*/
public void endBlock(Block bl) {
+ m_context.popContainer();
}
/**
* @see org.apache.fop.fo.FOInputHandler#startTable(Table)
*/
public void startTable(Table tbl) {
+ // create an RtfTable in the current table container
+ TableContext tableContext = new TableContext(m_context);
+ RtfAttributes atts=new RtfAttributes();
+
+ try
+ {
+ final IRtfTableContainer tc = (IRtfTableContainer)m_context.getContainer(IRtfTableContainer.class,true,null);
+ m_context.pushContainer(tc.newTable(atts, tableContext));
+ }
+ catch(Exception e)
+ {
+ log.error("startTable:" + e.getMessage());
+ throw new Error(e.getMessage());
+ }
+
+ m_context.pushTableContext(tableContext);
}
/**
* @see org.apache.fop.fo.FOInputHandler#endTable(Table)
*/
public void endTable(Table tbl) {
+ m_context.popTableContext();
+ m_context.popContainer();
+ }
+
+ /**
+ *
+ * @param th TableColumn that is starting;
+ */
+
+ public void startColumn(TableColumn tc) {
+ try
+ {
+ Integer iWidth=new Integer(tc.getColumnWidth()/1000);
+ m_context.getTableContext().setNextColumnWidth(iWidth.toString()+"pt");
+ m_context.getTableContext().setNextColumnRowSpanning(new Integer(0),null);
+ }
+ catch(Exception e)
+ {
+ log.error("startColumn: " + e.getMessage());
+ throw new Error(e.getMessage());
+ }
+
+ }
+
+ /**
+ *
+ * @param th TableColumn that is ending;
+ */
+
+ public void endColumn(TableColumn tc){
}
/**
@@ -244,50 +315,124 @@ public class RTFHandler extends FOInputHandler {
* @see org.apache.fop.fo.FOInputHandler#startBody(TableBody)
*/
public void startBody(TableBody tb) {
+ try
+ {
+ RtfAttributes atts=TableAttributesConverter.convertRowAttributes (tb.properties, null, null);
+
+ RtfTable tbl = (RtfTable)m_context.getContainer(RtfTable.class,true,this);
+ tbl.setHeaderAttribs(atts);
+ }
+ catch(Exception e)
+ {
+ log.error("startBody: " + e.getMessage());
+ throw new Error(e.getMessage());
+ }
}
/**
* @see org.apache.fop.fo.FOInputHandler#endBody(TableBody)
*/
public void endBody(TableBody tb) {
- }
-
- /**
- *
- * @param tc TableColumn that is starting;
- */
- public void startColumn(TableColumn tc) {
- }
-
- /**
- *
- * @param tc TableColumn that is ending;
- */
- public void endColumn(TableColumn tc) {
+ try
+ {
+ RtfTable tbl = (RtfTable)m_context.getContainer(RtfTable.class,true,this);
+ tbl.setHeaderAttribs( null );
+ }
+ catch(Exception e)
+ {
+ log.error("endBody: " + e.getMessage());
+ throw new Error(e.getMessage());
+ }
}
/**
* @see org.apache.fop.fo.FOInputHandler#startRow(TableRow)
*/
public void startRow(TableRow tr) {
+ try
+ {
+ // create an RtfTableRow in the current RtfTable
+ final RtfTable tbl = (RtfTable)m_context.getContainer(RtfTable.class,true,null);
+
+ RtfAttributes tblAttribs = tbl.getRtfAttributes();
+ RtfAttributes tblRowAttribs = new RtfAttributes();
+ RtfAttributes atts=TableAttributesConverter.convertRowAttributes(tr.properties,null,tbl.getHeaderAttribs());
+
+ m_context.pushContainer(tbl.newTableRow( atts ));
+
+ // reset column iteration index to correctly access column widths
+ m_context.getTableContext().selectFirstColumn();
+ }
+ catch(Exception e)
+ {
+ log.error("startRow: " + e.getMessage());
+ throw new Error(e.getMessage());
+ }
}
/**
* @see org.apache.fop.fo.FOInputHandler#endRow(TableRow)
*/
public void endRow(TableRow tr) {
+ m_context.popContainer();
+ m_context.getTableContext().decreaseRowSpannings();
}
/**
* @see org.apache.fop.fo.FOInputHandler#startCell(TableCell)
*/
public void startCell(TableCell tc) {
+ try
+ {
+ TableContext tctx=m_context.getTableContext();
+ final RtfTableRow row = (RtfTableRow)m_context.getContainer(RtfTableRow.class,true,null);
+
+
+ //while the current column is in row-spanning, act as if
+ //a vertical merged cell would have been specified.
+ while(tctx.getNumberOfColumns()>tctx.getColumnIndex() && tctx.getColumnRowSpanningNumber().intValue()>0)
+ {
+ row.newTableCellMergedVertically((int)tctx.getColumnWidth(),tctx.getColumnRowSpanningAttrs());
+ tctx.selectNextColumn();
+ }
+
+ //get the width of the currently started cell
+ float width=tctx.getColumnWidth();
+
+ // create an RtfTableCell in the current RtfTableRow
+ RtfAttributes atts=TableAttributesConverter.convertCellAttributes(tc.properties,null);
+ RtfTableCell cell=row.newTableCell((int)width, atts);
+
+ //process number-rows-spanned attribute
+ Property p=null;
+ if ((p=tc.properties.get("number-rows-spanned")) != null && false)
+ {
+ // Start vertical merge
+ cell.setVMerge(RtfTableCell.MERGE_START);
+
+ // set the number of rows spanned
+ tctx.setCurrentColumnRowSpanning(new Integer(p.getNumber().intValue()), cell.getRtfAttributes());
+ }
+ else
+ {
+ tctx.setCurrentColumnRowSpanning(new Integer(1),null);
+ }
+
+ m_context.pushContainer(cell);
+ }
+ catch(Exception e)
+ {
+ log.error("startCell: " + e.getMessage());
+ throw new Error(e.getMessage());
+ }
}
/**
* @see org.apache.fop.fo.FOInputHandler#endCell(TableCell)
*/
public void endCell(TableCell tc) {
+ m_context.popContainer();
+ m_context.getTableContext().selectNextColumn();
}
// Lists
@@ -414,6 +559,7 @@ public class RTFHandler extends FOInputHandler {
para.newText(new String(data, start, length));
} catch (IOException ioe) {
// FIXME could we throw Exception in all FOInputHandler events?
+ log.error("characters: " + ioe.getMessage());
throw new Error("IOException: " + ioe);
}
}
@@ -468,6 +614,8 @@ public class RTFHandler extends FOInputHandler {
if ((fopValue.getRed() == 0) && (fopValue.getGreen() == 0)
&& (fopValue.getBlue() == 0) && (fopValue.getAlpha() == 0)) {
rtfColor = RtfColorTable.getInstance().getColorNumber("white").intValue();
+ currentRTFBackgroundColor = -1;
+ return;
} else {
rtfColor = convertFOPColorToRTF(fopValue);
}
diff --git a/src/java/org/apache/fop/rtf/renderer/TableAttributesConverter.java b/src/java/org/apache/fop/rtf/renderer/TableAttributesConverter.java
new file mode 100644
index 000000000..49f7bb669
--- /dev/null
+++ b/src/java/org/apache/fop/rtf/renderer/TableAttributesConverter.java
@@ -0,0 +1,440 @@
+/*
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.rtf.renderer;
+
+//RTF
+import org.apache.fop.rtf.rtflib.rtfdoc.BorderAttributesConverter;
+
+//FOP
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.EnumProperty;
+import org.apache.fop.fo.expr.NCnameProperty;
+import org.apache.fop.fo.properties.Constants;
+import org.apache.fop.fo.LengthProperty;
+import org.apache.fop.fo.ListProperty;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.Property;
+import org.apache.fop.fo.ColorTypeProperty;
+import org.apache.fop.fo.NumberProperty;
+import org.apache.fop.datatypes.ColorType;
+
+import org.xml.sax.Attributes;
+import org.apache.fop.rtf.rtflib.rtfdoc.RtfAttributes;
+import org.apache.fop.rtf.rtflib.rtfdoc.ITableAttributes;
+import org.apache.fop.rtf.rtflib.rtfdoc.RtfColorTable;
+
+/**
+ * Contributor(s):
+ * @author Roberto Marra <roberto@link-u.com>
+ * @author Boris Poudérous <boris.pouderous@eads-telecom.com>
+ * @author Normand Massé
+ * @author Peter Herweg <pherweg@web.de>
+ *
+ * This class was originally developed for the JFOR project and
+ * is now integrated into FOP.
+-----------------------------------------------------------------------------*/
+
+/**
+ * Provides methods to convert the attributes to RtfAttributes.
+ */
+
+public class TableAttributesConverter {
+
+ static Logger log=new ConsoleLogger();
+
+ //////////////////////////////////////////////////
+ // @@ Construction
+ //////////////////////////////////////////////////
+
+ /**
+ * Constructor.
+ */
+ private TableAttributesConverter() {
+ }
+
+ //////////////////////////////////////////////////
+ // @@ Static converter methods
+ //////////////////////////////////////////////////
+
+
+ /**
+ * Converts cell attributes to rtf attributes.
+ * @param attrs Given attributes
+ * @param defaultAttributes Default rtf attributes
+ *
+ * @return All valid rtf attributes together
+ *
+ * @throws ConverterException On convertion error
+ */
+ static RtfAttributes convertCellAttributes(PropertyList props, PropertyList defProps)
+ throws FOPException {
+
+ Property p;
+ EnumProperty ep;
+ RtfColorTable colorTable=RtfColorTable.getInstance();
+
+ RtfAttributes attrib=null;
+
+ if(defProps!=null)
+ {
+ attrib=convertCellAttributes(defProps,null);
+ }
+ else
+ {
+ attrib=new RtfAttributes();
+ }
+
+ boolean isBorderPresent=false;
+
+ // Cell background color
+ if ((p=props.getNearestSpecified("background-color"))!=null)
+ {
+ ColorType color=p.getColorType();
+ if(color!=null)
+ {
+ if(color.getAlpha()!=0
+ || color.getRed()!=0
+ || color.getGreen()!=0
+ || color.getBlue()!=0)
+ {
+ attrib.set(
+ ITableAttributes.CELL_COLOR_BACKGROUND,
+ RTFHandler.convertFOPColorToRTF(color));
+ }
+ }
+ else
+ {
+ log.warn("Named color '" + p.toString() + "' not found. ");
+ }
+
+ }
+
+ // Cell borders :
+ if ((p=props.getExplicit("border-color"))!=null){
+ ListProperty listprop=(ListProperty)p;
+ ColorType color=null;
+ if(listprop.getList().get(0) instanceof NCnameProperty){
+ color=new ColorType(((NCnameProperty)listprop.getList().get(0)).getNCname());
+ }
+ else if(listprop.getList().get(0) instanceof ColorTypeProperty){
+ color=((ColorTypeProperty)listprop.getList().get(0)).getColorType();
+ }
+
+ attrib.set(
+ BorderAttributesConverter.BORDER_COLOR,
+ colorTable.getColorNumber((int)color.getRed(),(int)color.getGreen(),(int)color.getBlue()).intValue());
+ }
+ if ((p=props.getExplicit("border-top-color"))!=null){
+ ColorType color=p.getColorType();
+ attrib.set(
+ BorderAttributesConverter.BORDER_COLOR,
+ colorTable.getColorNumber((int)color.getRed(),(int)color.getGreen(),(int)color.getBlue()).intValue());
+ }
+ if((p=props.getExplicit("border-bottom-color"))!=null){
+ ColorType color=p.getColorType();
+ attrib.set(
+ BorderAttributesConverter.BORDER_COLOR,
+ colorTable.getColorNumber((int)color.getRed(),(int)color.getGreen(),(int)color.getBlue()).intValue());
+ }
+ if((p=props.getExplicit("border-left-color"))!=null){
+ ColorType color=p.getColorType();
+ attrib.set(
+ BorderAttributesConverter.BORDER_COLOR,
+ colorTable.getColorNumber((int)color.getRed(),(int)color.getGreen(),(int)color.getBlue()).intValue());
+ }
+ if((p=props.getExplicit("border-right-color"))!=null){
+ ColorType color=p.getColorType();
+ attrib.set(
+ BorderAttributesConverter.BORDER_COLOR,
+ colorTable.getColorNumber((int)color.getRed(),(int)color.getGreen(),(int)color.getBlue()).intValue());
+ }
+
+ // Border styles do not inherit from parent
+ if((p=props.get("border-style"))!=null){
+ log.warn("border-style not implemented. Please use border-style-left, ...-right, ...-top or ...-bottom");
+ /*
+ attrib.set(ITableAttributes.CELL_BORDER_LEFT, "\\"+convertAttributetoRtf(e.getEnum()));
+ attrib.set(ITableAttributes.CELL_BORDER_RIGHT, "\\"+convertAttributetoRtf(e.getEnum()));
+ attrib.set(ITableAttributes.CELL_BORDER_BOTTOM,"\\"+convertAttributetoRtf(e.getEnum()));
+ attrib.set(ITableAttributes.CELL_BORDER_TOP, "\\"+convertAttributetoRtf(e.getEnum()));
+ isBorderPresent=true;
+ */
+ }
+ ep=(EnumProperty)props.get("border-top-style");
+ if(ep!=null && ep.getEnum()!=Constants.NONE){
+ attrib.set(ITableAttributes.CELL_BORDER_TOP, "\\"+convertAttributetoRtf(ep.getEnum()));
+ isBorderPresent=true;
+ }
+ ep=(EnumProperty)props.get("border-bottom-style");
+ if(ep!=null && ep.getEnum()!=Constants.NONE){
+ attrib.set(ITableAttributes.CELL_BORDER_BOTTOM,"\\"+convertAttributetoRtf(ep.getEnum()));
+ isBorderPresent=true;
+ }
+ ep=(EnumProperty)props.get("border-left-style");
+ if(ep!=null && ep.getEnum()!=Constants.NONE){
+ attrib.set(ITableAttributes.CELL_BORDER_LEFT, "\\"+convertAttributetoRtf(ep.getEnum()));
+ isBorderPresent=true;
+ }
+ ep=(EnumProperty)props.get("border-right-style");
+ if(ep!=null && ep.getEnum()!=Constants.NONE){
+ attrib.set(ITableAttributes.CELL_BORDER_RIGHT, "\\"+convertAttributetoRtf(ep.getEnum()));
+ isBorderPresent=true;
+ }
+
+ if((p=props.get("border-width"))!=null) {
+ ListProperty listprop=(ListProperty)p;
+ LengthProperty lengthprop=(LengthProperty)listprop.getList().get(0);
+
+ Float f=new Float(lengthprop.getLength().getValue()/1000f);
+ String sValue = f.toString() + "pt";
+
+ attrib.set(BorderAttributesConverter.BORDER_WIDTH, (int)FoUnitsConverter.getInstance().convertToTwips(sValue));
+ }
+ else if(isBorderPresent){
+ //if not defined, set default border width
+ //note 20 twips = 1 point
+ attrib.set(BorderAttributesConverter.BORDER_WIDTH, (int)FoUnitsConverter.getInstance().convertToTwips("1pt"));
+ }
+
+
+ // Column spanning :
+ NumberProperty n=(NumberProperty)props.get("number-columns-spanned");
+ if(n!=null && n.getNumber().intValue()>1) {
+ attrib.set(ITableAttributes.COLUMN_SPAN, n.getNumber().intValue());
+ }
+
+ return attrib;
+ }
+
+
+ /**
+ * Converts table and row attributes to rtf attributes.
+ *
+ * @param attrs Given attributes
+ * @param defaultAttributes Default rtf attributes
+ *
+ * @return All valid rtf attributes together
+ *
+ * @throws ConverterException On convertion error
+ */
+ static RtfAttributes convertRowAttributes(PropertyList props, PropertyList defProps, RtfAttributes rtfatts)
+ throws FOPException {
+
+ Property p;
+ EnumProperty ep;
+ RtfColorTable colorTable=RtfColorTable.getInstance();
+
+ RtfAttributes attrib=null;
+
+ if(defProps!=null)
+ {
+ attrib=convertRowAttributes(defProps,null,rtfatts);
+ }
+ else
+ {
+ if(rtfatts==null)
+ attrib=new RtfAttributes();
+ else
+ attrib=rtfatts;
+ }
+
+ String attrValue;
+ boolean isBorderPresent=false;
+ //need to set a default width
+
+ //check for keep-together row attribute
+ if ((p=props.get("keep-together.within-page"))!=null){
+ attrib.set(ITableAttributes.ROW_KEEP_TOGETHER);
+ }
+
+ if ((p=props.get("keep-together"))!=null){
+ attrib.set(ITableAttributes.ROW_KEEP_TOGETHER);
+ }
+
+ //Check for keep-with-next row attribute.
+ if ((p=props.get("keep-together"))!=null){
+ attrib.set(ITableAttributes.ROW_KEEP_WITH_NEXT);
+ }
+
+ //Check for keep-with-previous row attribute.
+ if ((p=props.get("keep-with-previous"))!=null){
+ attrib.set(ITableAttributes.ROW_KEEP_WITH_PREVIOUS);
+ }
+
+ //Check for height row attribute.
+ if ((p=props.get("height"))!=null){
+ Float f=new Float(p.getLength().getValue()/1000);
+ attrValue = f.toString() + "pt";
+ attrib.set(ITableAttributes.ROW_HEIGHT, (int)FoUnitsConverter.getInstance().convertToTwips(attrValue));
+ }
+
+ /* to write a border to a side of a cell one must write the directional side (ie. left, right) and the inside value
+ * if one needs to be taken out ie if the cell lies on the edge of a table or not, the offending value will be taken out
+ * by RtfTableRow. This is because you can't say BORDER_TOP and BORDER_HORIZONTAL if the cell lies at the
+ * top of the table. Similarly using BORDER_BOTTOM and BORDER_HORIZONTAL will not work if the cell lies at th
+ * bottom of the table. The same rules apply for left right and vertical.
+
+ * Also, the border type must be written after every control word. Thus it is implemented that the border type is the value
+ * of the border place.
+ */
+ if((p=props.get("border-style"))!=null){
+ log.warn("border-style not implemented. Please use border-style-left, ...-right, ...-top or ...-bottom");
+
+// attrValue = new String(AbstractBuilder.getValue( attrs, "border-style", defAttrs ));
+// attrib.set(ITableAttributes.ROW_BORDER_LEFT,"\\"+BorderAttributesConverter.convertAttributetoRtf(attrValue));
+// attrib.set(ITableAttributes.ROW_BORDER_RIGHT,"\\"+BorderAttributesConverter.convertAttributetoRtf(attrValue));
+// attrib.set(ITableAttributes.ROW_BORDER_HORIZONTAL,"\\"+BorderAttributesConverter.convertAttributetoRtf(attrValue));
+// attrib.set(ITableAttributes.ROW_BORDER_VERTICAL,"\\"+BorderAttributesConverter.convertAttributetoRtf(attrValue));
+// attrib.set(ITableAttributes.ROW_BORDER_BOTTOM,"\\"+BorderAttributesConverter.convertAttributetoRtf(attrValue));
+// attrib.set(ITableAttributes.ROW_BORDER_TOP,"\\"+BorderAttributesConverter.convertAttributetoRtf(attrValue));
+// isBorderPresent=true;
+ }
+ ep=(EnumProperty)props.get("border-top-style");
+ if(ep!=null && ep.getEnum()!=Constants.NONE){
+ attrib.set(ITableAttributes.ROW_BORDER_TOP, "\\"+convertAttributetoRtf(ep.getEnum()));
+ attrib.set(ITableAttributes.ROW_BORDER_HORIZONTAL,"\\"+convertAttributetoRtf(ep.getEnum()));
+ isBorderPresent=true;
+ }
+ ep=(EnumProperty)props.get("border-bottom-style");
+ if(ep!=null && ep.getEnum()!=Constants.NONE){
+ attrib.set(ITableAttributes.ROW_BORDER_BOTTOM, "\\"+convertAttributetoRtf(ep.getEnum()));
+ attrib.set(ITableAttributes.ROW_BORDER_HORIZONTAL,"\\"+convertAttributetoRtf(ep.getEnum()));
+ isBorderPresent=true;
+ }
+ ep=(EnumProperty)props.get("border-left-style");
+ if(ep!=null && ep.getEnum()!=Constants.NONE){
+ attrib.set(ITableAttributes.ROW_BORDER_LEFT, "\\"+convertAttributetoRtf(ep.getEnum()));
+ attrib.set(ITableAttributes.ROW_BORDER_VERTICAL, "\\"+convertAttributetoRtf(ep.getEnum()));
+ isBorderPresent=true;
+ }
+ ep=(EnumProperty)props.get("border-right-style");
+ if(ep!=null && ep.getEnum()!=Constants.NONE){
+ attrib.set(ITableAttributes.ROW_BORDER_RIGHT, "\\"+convertAttributetoRtf(ep.getEnum()));
+ attrib.set(ITableAttributes.ROW_BORDER_VERTICAL, "\\"+convertAttributetoRtf(ep.getEnum()));
+ isBorderPresent=true;
+ }
+ ep=(EnumProperty)props.get("border-horizontal-style");
+ if(ep!=null && ep.getEnum()!=Constants.NONE){
+ attrib.set(ITableAttributes.ROW_BORDER_HORIZONTAL, "\\"+convertAttributetoRtf(ep.getEnum()));
+ attrib.set(ITableAttributes.ROW_BORDER_TOP, "\\"+convertAttributetoRtf(ep.getEnum()));
+ attrib.set(ITableAttributes.ROW_BORDER_BOTTOM, "\\"+convertAttributetoRtf(ep.getEnum()));
+ isBorderPresent=true;
+ }
+ ep=(EnumProperty)props.get("border-vertical-style");
+ if(ep!=null && ep.getEnum()!=Constants.NONE){
+ attrib.set(ITableAttributes.ROW_BORDER_VERTICAL, "\\"+convertAttributetoRtf(ep.getEnum()));
+ attrib.set(ITableAttributes.ROW_BORDER_LEFT, "\\"+convertAttributetoRtf(ep.getEnum()));
+ attrib.set(ITableAttributes.ROW_BORDER_RIGHT, "\\"+convertAttributetoRtf(ep.getEnum()));
+ isBorderPresent=true;
+ }
+
+ if((p=props.get("border-width"))!=null){
+ ListProperty listprop=(ListProperty)p;
+ LengthProperty lengthprop=(LengthProperty)listprop.getList().get(0);
+
+ Float f=new Float(lengthprop.getLength().getValue()/1000f);
+ String sValue = f.toString() + "pt";
+
+ attrib.set(BorderAttributesConverter.BORDER_WIDTH, (int)FoUnitsConverter.getInstance().convertToTwips(sValue));
+ }
+ else if(isBorderPresent){
+ //if not defined, set default border width
+ //note 20 twips = 1 point
+ attrib.set(BorderAttributesConverter.BORDER_WIDTH, (int)FoUnitsConverter.getInstance().convertToTwips("1pt"));
+ }
+
+ return attrib;
+ }
+
+
+
+ public static String convertAttributetoRtf(int iBorderStyle) {
+ // Added by Normand Masse
+ // "solid" is interpreted like "thin"
+ if (iBorderStyle==Constants.SOLID) {
+ return BorderAttributesConverter.BORDER_SINGLE_THICKNESS;
+/* } else if (iBorderStyle==Constants.THIN) {
+ return BorderAttributesConverter.BORDER_SINGLE_THICKNESS;
+ } else if (iBorderStyle==Constants.THICK) {
+ return BorderAttributesConverter.BORDER_DOUBLE_THICKNESS;
+ } else if (iBorderStyle==Constants. value.equals("shadowed")) {
+ return BorderAttributesConverter.BORDER_SHADOWED;*/
+ } else if (iBorderStyle==Constants.DOUBLE) {
+ return BorderAttributesConverter.BORDER_DOUBLE;
+ } else if (iBorderStyle==Constants.DOTTED) {
+ return BorderAttributesConverter.BORDER_DOTTED;
+ } else if (iBorderStyle==Constants.DASHED) {
+ return BorderAttributesConverter.BORDER_DASH;
+/* } else if (iBorderStyle==Constants value.equals("hairline")) {
+ return BorderAttributesConverter.BORDER_HAIRLINE;*/
+/* } else if (iBorderStyle==Constant value.equals("dot-dash")) {
+ return BorderAttributesConverter.BORDER_DOT_DASH;
+ } else if (iBorderStyle==Constant value.equals("dot-dot-dash")) {
+ return BorderAttributesConverter.BORDER_DOT_DOT_DASH;
+ } else if (iBorderStyle==Constant value.equals("triple")) {
+ return BorderAttributesConverter.BORDER_TRIPLE;
+ } else if (iBorderStyle==Constant value.equals("wavy")) {
+ return BorderAttributesConverter.BORDER_WAVY;
+ } else if (iBorderStyle==Constant value.equals("wavy-double")) {
+ return BorderAttributesConverter.BORDER_WAVY_DOUBLE;
+ } else if (iBorderStyle==Constant value.equals("striped")) {
+ return BorderAttributesConverter.BORDER_STRIPED;
+ } else if (iBorderStyle==Constant value.equals("emboss")) {
+ return BorderAttributesConverter.BORDER_EMBOSS;
+ } else if (iBorderStyle==Constant value.equals("engrave")) {
+ return BorderAttributesConverter.BORDER_ENGRAVE;*/
+ } else {
+ return null;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/rtf/renderer/TableContext.java b/src/java/org/apache/fop/rtf/renderer/TableContext.java
new file mode 100644
index 000000000..088da98a9
--- /dev/null
+++ b/src/java/org/apache/fop/rtf/renderer/TableContext.java
@@ -0,0 +1,224 @@
+/*
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.rtf.renderer;
+
+import java.util.*;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.fop.rtf.rtflib.rtfdoc.RtfAttributes;
+import org.apache.fop.rtf.rtflib.interfaces.ITableColumnsInfo;
+
+
+/** Used when handling fo:table to hold information to build the table.
+ *
+ * Contributor(s):
+ * @author Bertrand Delacretaz <bdelacretaz@codeconsult.ch>
+ * @author Trembicki-Guy, Ed <GuyE@DNB.com>
+ * @author Boris Poudérous <boris.pouderous@eads-telecom.com>
+ * @author Peter Herweg <pherweg@web.de>
+ *
+ * This class was originally developed for the JFOR project and
+ * is now integrated into FOP.
+ */
+
+class TableContext implements ITableColumnsInfo
+{
+ private final Logger log=new ConsoleLogger();
+ private final BuilderContext m_context;
+ private final ArrayList m_colWidths = new ArrayList();
+ private int m_colIndex;
+
+ /**
+ * Added by Peter Herweg on 2002-06-29
+ * This ArrayList contains one element for each column in the table.
+ * value == 0 means there is no row-spanning
+ * value > 0 means there is row-spanning
+ * Each value in the list is decreased by 1 after each finished table-row
+ */
+ private final ArrayList m_colRowSpanningNumber = new ArrayList();
+
+ /**
+ * Added by Peter Herweg on 2002-06-29
+ * If there has a vertical merged cell to be created, its attributes are
+ * inherited from the corresponding MERGE_START-cell.
+ * For this purpose the attributes of a cell are stored in this array, as soon
+ * as a number-rows-spanned attribute has been found.
+ */
+ private final ArrayList m_colRowSpanningAttrs = new ArrayList(); //Added by Peter Herweg on 2002-06-29
+
+ private boolean m_bNextRowBelongsToHeader=false;
+
+ public void setNextRowBelongsToHeader(boolean bNextRowBelongsToHeader)
+ {
+ m_bNextRowBelongsToHeader=bNextRowBelongsToHeader;
+ }
+
+ public boolean getNextRowBelongsToHeader()
+ {
+ return m_bNextRowBelongsToHeader;
+ }
+
+ TableContext(BuilderContext ctx)
+ {
+ m_context = ctx;
+ }
+
+ void setNextColumnWidth(String strWidth)
+ throws Exception
+ {
+
+ m_colWidths.add( new Float(FoUnitsConverter.getInstance().convertToTwips(strWidth)));
+ }
+
+ //Added by Peter Herweg on 2002-06-29
+ RtfAttributes getColumnRowSpanningAttrs()
+ {
+ return (RtfAttributes)m_colRowSpanningAttrs.get(m_colIndex);
+ }
+
+ //Added by Peter Herweg on 2002-06-29
+ Integer getColumnRowSpanningNumber()
+ {
+ return (Integer)m_colRowSpanningNumber.get(m_colIndex);
+ }
+
+ //Added by Peter Herweg on 2002-06-29
+ void setCurrentColumnRowSpanning(Integer iRowSpanning, RtfAttributes attrs)
+ throws Exception
+ {
+
+ if(m_colIndex<m_colRowSpanningNumber.size())
+ {
+ m_colRowSpanningNumber.set(m_colIndex, iRowSpanning);
+ m_colRowSpanningAttrs.set(m_colIndex, attrs);
+ }
+ else
+ {
+ m_colRowSpanningNumber.add(iRowSpanning);
+ m_colRowSpanningAttrs.add(m_colIndex, attrs);
+ }
+ }
+
+ //Added by Peter Herweg on 2002-06-29
+ public void setNextColumnRowSpanning(Integer iRowSpanning, RtfAttributes attrs)
+ {
+ m_colRowSpanningNumber.add(iRowSpanning);
+ m_colRowSpanningAttrs.add(m_colIndex, attrs);
+ }
+
+ /**
+ * Added by Peter Herweg on 2002-06-29
+ * This function is called after each finished table-row.
+ * It decreases all values in m_colRowSpanningNumber by 1. If a value
+ * reaches 0 row-spanning is finished, and the value won't be decreased anymore.
+ */
+ public void decreaseRowSpannings()
+ {
+ for(int z=0;z<m_colRowSpanningNumber.size();++z)
+ {
+ Integer i=(Integer)m_colRowSpanningNumber.get(z);
+
+ if(i.intValue()>0)
+ i=new Integer(i.intValue()-1);
+
+ m_colRowSpanningNumber.set(z,i);
+
+ if(i.intValue()==0)
+ m_colRowSpanningAttrs.set(z,null);
+ }
+ }
+
+ /** reset the column iteration index, meant to be called when creating a new row
+ * The 'public' modifier has been added by Boris Poudérous for 'number-columns-spanned' processing
+ */
+ public void selectFirstColumn()
+ {
+ m_colIndex = 0;
+ }
+
+ /** increment the column iteration index
+ * The 'public' modifier has been added by Boris Poudérous for 'number-columns-spanned' processing
+ */
+ public void selectNextColumn()
+ {
+ m_colIndex++;
+ }
+
+ /** get current column width according to column iteration index
+ * @return INVALID_COLUMN_WIDTH if we cannot find the value
+ * The 'public' modifier has been added by Boris Poudérous for 'number-columns-spanned' processing
+ */
+ public float getColumnWidth()
+ {
+ try {
+ return ((Float)m_colWidths.get(m_colIndex)).floatValue();
+ } catch (IndexOutOfBoundsException ex) {
+ // this code contributed by Trembicki-Guy, Ed <GuyE@DNB.com>
+ log.warn("fo:table-column width not defined, using " + INVALID_COLUM_WIDTH);
+ return INVALID_COLUM_WIDTH;
+ }
+ }
+
+ /** Added by Boris Poudérous on 07/22/2002 */
+ public int getColumnIndex()
+ {
+ return m_colIndex;
+ }
+ /** - end - */
+
+ /** Added by Boris Poudérous on 07/22/2002 */
+ public int getNumberOfColumns()
+ {
+ return m_colWidths.size();
+ }
+ /** - end - */
+}
+
diff --git a/src/java/org/apache/fop/rtf/rtflib/rtfdoc/ITableAttributes.java b/src/java/org/apache/fop/rtf/rtflib/rtfdoc/ITableAttributes.java
index c3d1a2d5f..6314e303a 100644
--- a/src/java/org/apache/fop/rtf/rtflib/rtfdoc/ITableAttributes.java
+++ b/src/java/org/apache/fop/rtf/rtflib/rtfdoc/ITableAttributes.java
@@ -152,6 +152,7 @@ public interface ITableAttributes {
//Table row attributes
/** row attribute, keep-together */
public static final String ROW_KEEP_TOGETHER = "trkeep";
+ public static final String ROW_HEIGHT = "trrh";
/**
* This control word is nonexistent in RTF, used to simulate the
diff --git a/src/java/org/apache/fop/rtf/rtflib/rtfdoc/RtfTable.java b/src/java/org/apache/fop/rtf/rtflib/rtfdoc/RtfTable.java
index be05e4c77..a874dc21a 100755
--- a/src/java/org/apache/fop/rtf/rtflib/rtfdoc/RtfTable.java
+++ b/src/java/org/apache/fop/rtf/rtflib/rtfdoc/RtfTable.java
@@ -176,6 +176,10 @@ public class RtfTable extends RtfContainer {
headerAttribs = attrs;
}
+ public RtfAttributes getHeaderAttribs() {
+ return headerAttribs;
+ }
+
/**
* Added by Normand Masse
* @return the table-header attributes if they are present, otherwise the