]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Bugzilla #43606:
authorJeremias Maerki <jeremias@apache.org>
Sun, 6 Jul 2008 15:09:10 +0000 (15:09 +0000)
committerJeremias Maerki <jeremias@apache.org>
Sun, 6 Jul 2008 15:09:10 +0000 (15:09 +0000)
column-width accepts percent values (proportional-column-width and % working)
Table width accepts percent values (100% of the page width as standard)
Nested tables are working
It is also possible to make nested tables with a higher depth than 3 without causing word to crash
Submitted by: Maximilan Aster <maximilian.aster.at.boc-eu.com>

Changes to the patch by Jeremias:
- Patch simplified (reuse of ColumnSetup from the layoutmgr package)
- Percentages and proportional-column-width didn't work properly in my tests -> fixed
- Adjustments for FOP code conventions

Bugzilla #43824:
page-number-citation working but has to be refreshed inside word to show the correct values
Submitted by: Maximilan Aster <maximilian.aster.at.boc-eu.com>

Changes to the patch by Jeremias:
- Adjustments for FOP code conventions

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/fop-0_95@674304 13f79535-47bb-0310-9956-ffa450edef68

12 files changed:
src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
src/java/org/apache/fop/render/rtf/FoUnitsConverter.java
src/java/org/apache/fop/render/rtf/PageAttributesConverter.java
src/java/org/apache/fop/render/rtf/RTFHandler.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfAttributes.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfPage.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfPageNumberCitation.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTable.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTableRow.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java
src/java/org/apache/fop/render/rtf/rtflib/tools/PercentContext.java [new file with mode: 0644]
status.xml

index 2ef2be9080b7d01edc7910ddd4d07ffc6948980b..b3ffb4d306f5739b156841e70c7187e44095ce4f 100644 (file)
@@ -25,9 +25,9 @@ import java.util.ListIterator;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.fop.datatypes.PercentBaseContext;
-import org.apache.fop.datatypes.Length;
 
+import org.apache.fop.datatypes.Length;
+import org.apache.fop.datatypes.PercentBaseContext;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableColumn;
@@ -44,9 +44,9 @@ public class ColumnSetup {
     private Table table;
     private List columns = new java.util.ArrayList();
     private List colWidths = new java.util.ArrayList();
-    
+
     private int maxColIndexReferenced = 0;
-    
+
     /**
      * Main Constructor.
      * @param table the table to construct this column setup for
@@ -56,7 +56,7 @@ public class ColumnSetup {
         prepareColumns();
         initializeColumnWidths();
     }
-    
+
     private void prepareColumns() {
         List rawCols = table.getColumns();
         if (rawCols != null) {
@@ -119,7 +119,7 @@ public class ColumnSetup {
             return (TableColumn) columns.get(index - 1);
         }
     }
+
     /** {@inheritDoc} */
     public String toString() {
         return columns.toString();
@@ -133,15 +133,15 @@ public class ColumnSetup {
             return columns.size();
         }
    }
-    
+
     /** @return an Iterator over all columns */
     public Iterator iterator() {
         return this.columns.iterator();
     }
-    
+
     /*
     private void createColumnsFromFirstRow() {
-        //TODO Create oldColumns from first row here 
+        //TODO Create oldColumns from first row here
         //--> rule 2 in "fixed table layout", see CSS2, 17.5.2
         //Alternative: extend oldColumns on-the-fly, but in this case we need the
         //new property evaluation context so proportional-column-width() works
@@ -154,13 +154,13 @@ public class ColumnSetup {
 
     /**
      * Initializes the column's widths
-     * 
+     *
      */
     private void initializeColumnWidths() {
-        
+
         TableColumn col;
         Length colWidth;
-        
+
         for (int i = columns.size(); --i >= 0;) {
             if (columns.get(i) != null) {
                 col = (TableColumn) columns.get(i);
@@ -170,49 +170,60 @@ public class ColumnSetup {
         }
         colWidths.add(0, null);
     }
-    
+
     /**
      * Works out the base unit for resolving proportional-column-width()
      * [p-c-w(x) = x * base_unit_ipd]
-     * 
+     *
      * @param tlm   the TableLayoutManager
      * @return the computed base unit (in millipoint)
      */
     protected double computeTableUnit(TableLayoutManager tlm) {
-        
+        return computeTableUnit(tlm, tlm.getContentAreaIPD());
+    }
+
+    /**
+     * Works out the base unit for resolving proportional-column-width()
+     * [p-c-w(x) = x * base_unit_ipd]
+     *
+     * @param percentBaseContext the percent base context for relative values
+     * @param contentAreaIPD the IPD of the available content area
+     * @return the computed base unit (in millipoints)
+     */
+    public float computeTableUnit(PercentBaseContext percentBaseContext, int contentAreaIPD) {
+
         int sumCols = 0;
         float factors = 0;
-        double unit = 0;
-        
-        /* calculate the total width (specified absolute/percentages), 
+        float unit = 0;
+
+        /* calculate the total width (specified absolute/percentages),
          * and work out the total number of factors to use to distribute
          * the remaining space (if any)
          */
         for (Iterator i = colWidths.iterator(); i.hasNext();) {
             Length colWidth = (Length) i.next();
             if (colWidth != null) {
-                sumCols += colWidth.getValue(tlm);
+                sumCols += colWidth.getValue(percentBaseContext);
                 if (colWidth instanceof TableColLength) {
-                    factors += 
-                        ((TableColLength) colWidth).getTableUnits();
+                    factors += ((TableColLength) colWidth).getTableUnits();
                 }
             }
         }
-        
-        /* distribute the remaining space over the accumulated 
-         * factors (if any) 
+
+        /* distribute the remaining space over the accumulated
+         * factors (if any)
          */
         if (factors > 0) {
-            if (sumCols < tlm.getContentAreaIPD()) {
-                unit = (tlm.getContentAreaIPD() - sumCols) / factors;
+            if (sumCols < contentAreaIPD) {
+                unit = (contentAreaIPD - sumCols) / factors;
             } else {
                 log.warn("No space remaining to distribute over columns.");
             }
         }
-        
+
         return unit;
     }
-    
+
     /**
      * @param col column index (1 is first column)
      * @param context the context for percentage based calculations
@@ -252,5 +263,5 @@ public class ColumnSetup {
         }
         return sum;
     }
-    
+
 }
index fa95b8502e7bcf9322a342758e3b459fe672bbcf..33a2ff90472ccb6df4df788c9f97ffa7d46e7df0 100644 (file)
@@ -5,9 +5,9 @@
  * 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.
 
 package org.apache.fop.render.rtf;
 
-import java.util.Map;
 import java.util.HashMap;
+import java.util.Map;
 
-//FOP
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.fo.properties.FixedLength;
 
@@ -143,4 +142,8 @@ final class FoUnitsConverter {
         // RTF font size units are in half-points
         return (int)(result * 2.0);
     }
+
+    public float convertMptToTwips(int width) {
+        return width * POINT_TO_TWIPS / 1000;
+    }
 }
index 50355e14539bc32ab9ebff517df5c12f6d0692dd..d50a8165671d1e9fbcec1e82a10bae11f1935a70 100644 (file)
@@ -5,9 +5,9 @@
  * 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.
@@ -21,6 +21,7 @@ package org.apache.fop.render.rtf;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.impl.SimpleLog;
+
 import org.apache.fop.datatypes.Length;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.expr.NumericOp;
@@ -46,19 +47,21 @@ final class PageAttributesConverter {
      */
     private PageAttributesConverter() {
     }
-    
+
     /** convert xsl:fo attributes to RTF text attributes */
     static RtfAttributes convertPageAttributes(SimplePageMaster pagemaster) {
         FOPRtfAttributes attrib = new FOPRtfAttributes();
-        
+
         try {
             RegionBA before = (RegionBA) pagemaster.getRegion(Constants.FO_REGION_BEFORE);
             RegionBody body   = (RegionBody) pagemaster.getRegion(Constants.FO_REGION_BODY);
             RegionBA after  = (RegionBA) pagemaster.getRegion(Constants.FO_REGION_AFTER);
-            
+
             attrib.setTwips(RtfPage.PAGE_WIDTH, pagemaster.getPageWidth());
             attrib.setTwips(RtfPage.PAGE_HEIGHT, pagemaster.getPageHeight());
-            
+            //Sets the document level property
+            attrib.set(RtfPage.ITAP, "0");
+
             Object widthRaw = attrib.getValue(RtfPage.PAGE_WIDTH);
             Object heightRaw = attrib.getValue(RtfPage.PAGE_HEIGHT);
             if ((widthRaw instanceof Integer) && (heightRaw instanceof Integer)
@@ -84,7 +87,7 @@ final class PageAttributesConverter {
                 bodyLeft = (Length) NumericOp.addition(pageLeft, bodyMargin.marginLeft);
                 bodyRight = (Length) NumericOp.addition(pageRight, bodyMargin.marginRight);
             }
-            
+
             attrib.setTwips(RtfPage.MARGIN_TOP, bodyTop);
             attrib.setTwips(RtfPage.MARGIN_BOTTOM, bodyBottom);
             attrib.setTwips(RtfPage.MARGIN_LEFT, bodyLeft);
@@ -102,9 +105,9 @@ final class PageAttributesConverter {
             if (after != null) {
                 afterBottom = (Length) NumericOp.addition(pageBottom, after.getExtent());
             }
-            attrib.setTwips(RtfPage.FOOTERY, beforeTop);
+            attrib.setTwips(RtfPage.FOOTERY, afterBottom);
         } catch (Exception e) {
-            log.error("Exception in convertPageAttributes: " 
+            log.error("Exception in convertPageAttributes: "
                 + e.getMessage() + "- page attributes ignored");
             attrib = new FOPRtfAttributes();
         }
index 568fe75aa2655c73a1254af2a31804375b4554bb..dd7a9bb3fffbbe3db2b1cfdb565559de8602cbf8 100644 (file)
@@ -50,7 +50,6 @@ import org.apache.xmlgraphics.image.loader.util.ImageUtil;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.datatypes.LengthBase;
-import org.apache.fop.datatypes.SimplePercentBaseContext;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.FOEventHandler;
 import org.apache.fop.fo.FONode;
@@ -72,6 +71,7 @@ import org.apache.fop.fo.flow.ListItem;
 import org.apache.fop.fo.flow.ListItemBody;
 import org.apache.fop.fo.flow.ListItemLabel;
 import org.apache.fop.fo.flow.PageNumber;
+import org.apache.fop.fo.flow.PageNumberCitation;
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableBody;
 import org.apache.fop.fo.flow.table.TableCell;
@@ -85,8 +85,9 @@ import org.apache.fop.fo.pagination.Region;
 import org.apache.fop.fo.pagination.SimplePageMaster;
 import org.apache.fop.fo.pagination.StaticContent;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
-import org.apache.fop.fo.properties.FixedLength;
+import org.apache.fop.fo.properties.EnumLength;
 import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.layoutmgr.table.ColumnSetup;
 import org.apache.fop.render.DefaultFontResolver;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfAfterContainer;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfBeforeContainer;
@@ -105,6 +106,7 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFootnote;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfHyperLink;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfList;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfPage;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell;
@@ -112,6 +114,7 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTextrun;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem.RtfListItemLabel;
 import org.apache.fop.render.rtf.rtflib.tools.BuilderContext;
+import org.apache.fop.render.rtf.rtflib.tools.PercentContext;
 import org.apache.fop.render.rtf.rtflib.tools.TableContext;
 
 /**
@@ -145,6 +148,10 @@ public class RTFHandler extends FOEventHandler {
 
     private SimplePageMaster pagemaster;
 
+    private int nestedTableDepth = 1;
+
+    private PercentContext percentManager = new PercentContext();
+
     /**
      * Creates a new RTF structure handler.
      * @param userAgent the FOUserAgent for this process
@@ -158,9 +165,7 @@ public class RTFHandler extends FOEventHandler {
         FontSetup.setup(fontInfo, null, new DefaultFontResolver(userAgent));
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startDocument() throws SAXException {
         // TODO sections should be created
         try {
@@ -172,9 +177,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endDocument() throws SAXException {
         try {
             rtfFile.flush();
@@ -184,9 +187,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startPageSequence(PageSequence pageSeq)  {
         try {
             //This is needed for region handling
@@ -195,10 +196,10 @@ public class RTFHandler extends FOEventHandler {
                 this.pagemaster
                         = pageSeq.getRoot().getLayoutMasterSet().getSimplePageMaster(reference);
                 if (this.pagemaster == null) {
-                    log.warn("Only simple-page-masters are supported on page-sequences: " 
+                    log.warn("Only simple-page-masters are supported on page-sequences: "
                             + reference);
                     log.warn("Using default simple-page-master from page-sequence-master...");
-                    PageSequenceMaster master 
+                    PageSequenceMaster master
                         = pageSeq.getRoot().getLayoutMasterSet().getPageSequenceMaster(reference);
                     this.pagemaster = master.getNextSimplePageMaster(
                             false, false, false, false, false);
@@ -223,6 +224,14 @@ public class RTFHandler extends FOEventHandler {
 
             builderContext.pushContainer(sect);
 
+            //Calculate usable page width for this flow
+            int useAblePageWidth = pagemaster.getPageWidth().getValue()
+                - pagemaster.getCommonMarginBlock().marginLeft.getValue()
+                - pagemaster.getCommonMarginBlock().marginRight.getValue()
+                - sect.getRtfAttributes().getValueAsInteger(RtfPage.MARGIN_LEFT).intValue()
+                - sect.getRtfAttributes().getValueAsInteger(RtfPage.MARGIN_RIGHT).intValue();
+            percentManager.setDimension(pageSeq, useAblePageWidth);
+
             bHeaderSpecified = false;
             bFooterSpecified = false;
         } catch (IOException ioe) {
@@ -235,9 +244,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endPageSequence(PageSequence pageSeq) {
         if (bDefer) {
             //If endBlock was called while SAX parsing, and the passed FO is Block
@@ -255,9 +262,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startFlow(Flow fl) {
         if (bDefer) {
             return;
@@ -294,7 +299,7 @@ public class RTFHandler extends FOEventHandler {
                     contAfter.newAfter(attr);
                 }
                 handled = true;
-            } else if (regionBefore != null 
+            } else if (regionBefore != null
                     && fl.getFlowName().equals(regionBefore.getRegionName())) {
                 bHeaderSpecified = true;
                 bPrevHeaderSpecified = true;
@@ -313,7 +318,7 @@ public class RTFHandler extends FOEventHandler {
                 RtfBefore before = c.newBefore(beforeAttributes);
                 builderContext.pushContainer(before);
                 handled = true;
-            } else if (regionAfter != null 
+            } else if (regionAfter != null
                     && fl.getFlowName().equals(regionAfter.getRegionName())) {
                 bFooterSpecified = true;
                 bPrevFooterSpecified = true;
@@ -346,9 +351,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endFlow(Flow fl) {
         if (bDefer) {
             return;
@@ -360,10 +363,10 @@ public class RTFHandler extends FOEventHandler {
             Region regionAfter = pagemaster.getRegion(Constants.FO_REGION_AFTER);
             if (fl.getFlowName().equals(regionBody.getRegionName())) {
                 //just do nothing
-            } else if (regionBefore != null 
+            } else if (regionBefore != null
                     && fl.getFlowName().equals(regionBefore.getRegionName())) {
                 builderContext.popContainer();
-            } else if (regionAfter != null 
+            } else if (regionAfter != null
                     && fl.getFlowName().equals(regionAfter.getRegionName())) {
                 builderContext.popContainer();
             }
@@ -373,9 +376,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startBlock(Block bl) {
         if (bDefer) {
             return;
@@ -405,10 +406,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endBlock(Block bl) {
 
         if (bDefer) {
@@ -435,9 +433,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startBlockContainer(BlockContainer blc) {
         if (bDefer) {
             return;
@@ -466,9 +462,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endBlockContainer(BlockContainer bl) {
         if (bDefer) {
             return;
@@ -494,9 +488,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startTable(Table tbl) {
         if (bDefer) {
             return;
@@ -509,15 +501,17 @@ public class RTFHandler extends FOEventHandler {
             final IRtfTableContainer tc
                 = (IRtfTableContainer)builderContext.getContainer(
                         IRtfTableContainer.class, true, null);
-            
+
             RtfAttributes atts
                 = TableAttributesConverter.convertTableAttributes(tbl);
-            
+
             RtfTable table = tc.newTable(atts, tableContext);
-            
+            table.setNestedTableDepth(nestedTableDepth);
+            nestedTableDepth++;
+
             CommonBorderPaddingBackground border = tbl.getCommonBorderPaddingBackground();
             RtfAttributes borderAttributes = new RtfAttributes();
-                    
+
             BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.BEFORE,
                     borderAttributes, ITableAttributes.CELL_BORDER_TOP);
             BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.AFTER,
@@ -526,9 +520,9 @@ public class RTFHandler extends FOEventHandler {
                     borderAttributes, ITableAttributes.CELL_BORDER_LEFT);
             BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.END,
                     borderAttributes,  ITableAttributes.CELL_BORDER_RIGHT);
-            
+
             table.setBorderAttributes(borderAttributes);
-            
+
             builderContext.pushContainer(table);
         } catch (Exception e) {
             log.error("startTable:" + e.getMessage());
@@ -538,53 +532,32 @@ public class RTFHandler extends FOEventHandler {
         builderContext.pushTableContext(tableContext);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endTable(Table tbl) {
         if (bDefer) {
             return;
         }
 
+        nestedTableDepth--;
         builderContext.popTableContext();
         builderContext.popContainer();
     }
 
-    /**
-    *
-    * @param tc TableColumn that is starting;
-    */
-
+    /** {@inheritDoc} */
     public void startColumn(TableColumn tc) {
         if (bDefer) {
             return;
         }
 
         try {
-            /**
-             * Pass a SimplePercentBaseContext to getValue in order to
-             * avoid a NullPointerException, which occurs when you use
-             * proportional-column-width function in column-width attribute.
-             * Of course the results won't be correct, but at least the
-             * rest of the document will be rendered. Usage of the
-             * TableLayoutManager is not welcome due to design reasons and
-             * it also does not provide the correct values.
-             * TODO: Make proportional-column-width working for rtf output 
-             */
-             SimplePercentBaseContext context
-                = new SimplePercentBaseContext(null,
-                                               LengthBase.TABLE_UNITS,
-                                               100000);
-            
-            Integer iWidth
-                = new Integer(tc.getColumnWidth().getValue(context) / 1000);
-            
-            String strWidth = iWidth.toString() + FixedLength.POINT;
-            Float width = new Float(
-                    FoUnitsConverter.getInstance().convertToTwips(strWidth));
+            int iWidth = tc.getColumnWidth().getValue(percentManager);
+            percentManager.setDimension(tc, iWidth);
+
+            //convert to twips
+            Float width = new Float(FoUnitsConverter.getInstance().convertMptToTwips(iWidth));
             builderContext.getTableContext().setNextColumnWidth(width);
             builderContext.getTableContext().setNextColumnRowSpanning(
-                    new Integer(0), null);
+                  new Integer(0), null);
             builderContext.getTableContext().setNextFirstSpanningCol(false);
         } catch (Exception e) {
             log.error("startColumn: " + e.getMessage());
@@ -593,45 +566,30 @@ public class RTFHandler extends FOEventHandler {
 
     }
 
-     /**
-     *
-     * @param tc TableColumn that is ending;
-     */
-
+    /** {@inheritDoc} */
     public void endColumn(TableColumn tc) {
         if (bDefer) {
             return;
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startHeader(TableBody th) {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endHeader(TableBody th) {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startFooter(TableBody tf) {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endFooter(TableBody tf) {
     }
 
-    /**
-     *
-     * @param inl Inline that is starting.
-     */
+    /** {@inheritDoc} */
     public void startInline(Inline inl) {
         if (bDefer) {
             return;
@@ -660,10 +618,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     *
-     * @param inl Inline that is ending.
-     */
+    /** {@inheritDoc} */
     public void endInline(Inline inl) {
         if (bDefer) {
             return;
@@ -685,9 +640,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-     /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startBody(TableBody tb) {
         if (bDefer) {
             return;
@@ -704,9 +657,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endBody(TableBody tb) {
         if (bDefer) {
             return;
@@ -721,9 +672,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startRow(TableRow tr) {
         if (bDefer) {
             return;
@@ -751,14 +700,12 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endRow(TableRow tr) {
         if (bDefer) {
             return;
         }
-        
+
         try {
             TableContext tctx = builderContext.getTableContext();
             final RtfTableRow row = (RtfTableRow)builderContext.getContainer(RtfTableRow.class,
@@ -771,11 +718,11 @@ public class RTFHandler extends FOEventHandler {
                 RtfTableCell vCell = row.newTableCellMergedVertically(
                         (int)tctx.getColumnWidth(),
                         tctx.getColumnRowSpanningAttrs());
-                
+
                 if (!tctx.getFirstSpanningCol()) {
                     vCell.setHMerge(RtfTableCell.MERGE_WITH_PREVIOUS);
                 }
-                
+
                 tctx.selectNextColumn();
             }
         } catch (Exception e) {
@@ -788,9 +735,7 @@ public class RTFHandler extends FOEventHandler {
         builderContext.getTableContext().decreaseRowSpannings();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startCell(TableCell tc) {
         if (bDefer) {
             return;
@@ -811,11 +756,11 @@ public class RTFHandler extends FOEventHandler {
                 RtfTableCell vCell = row.newTableCellMergedVertically(
                         (int)tctx.getColumnWidth(),
                         tctx.getColumnRowSpanningAttrs());
-                
+
                 if (!tctx.getFirstSpanningCol()) {
                     vCell.setHMerge(RtfTableCell.MERGE_WITH_PREVIOUS);
                 }
-                
+
                 tctx.selectNextColumn();
             }
 
@@ -825,14 +770,14 @@ public class RTFHandler extends FOEventHandler {
             // create an RtfTableCell in the current RtfTableRow
             RtfAttributes atts = TableAttributesConverter.convertCellAttributes(tc);
             RtfTableCell cell = row.newTableCell((int)width, atts);
-            
+
             //process number-rows-spanned attribute
             if (numberRowsSpanned > 1) {
                 // Start vertical merge
                 cell.setVMerge(RtfTableCell.MERGE_START);
 
                 // set the number of rows spanned
-                tctx.setCurrentColumnRowSpanning(new Integer(numberRowsSpanned), 
+                tctx.setCurrentColumnRowSpanning(new Integer(numberRowsSpanned),
                         cell.getRtfAttributes());
             } else {
                 tctx.setCurrentColumnRowSpanning(
@@ -842,33 +787,36 @@ public class RTFHandler extends FOEventHandler {
             //process number-columns-spanned attribute
             if (numberColumnsSpanned > 0) {
                 // Get the number of columns spanned
-                RtfTable table = row.getTable();
                 tctx.setCurrentFirstSpanningCol(true);
-                
+
                 // We widthdraw one cell because the first cell is already created
                 // (it's the current cell) !
                  for (int i = 0; i < numberColumnsSpanned - 1; ++i) {
                     tctx.selectNextColumn();
-                    
+
+                    //aggregate width for further elements
+                    width += tctx.getColumnWidth();
                     tctx.setCurrentFirstSpanningCol(false);
                     RtfTableCell hCell = row.newTableCellMergedHorizontally(
                             0, null);
-                    
+
                     if (numberRowsSpanned > 1) {
                         // Start vertical merge
                         hCell.setVMerge(RtfTableCell.MERGE_START);
 
                         // set the number of rows spanned
                         tctx.setCurrentColumnRowSpanning(
-                                new Integer(numberRowsSpanned), 
+                                new Integer(numberRowsSpanned),
                                 cell.getRtfAttributes());
                     } else {
                         tctx.setCurrentColumnRowSpanning(
-                                new Integer(numberRowsSpanned), null);
+                                new Integer(numberRowsSpanned), cell.getRtfAttributes());
                     }
                 }
             }
-            
+            //save width of the cell, convert from twips to mpt
+            percentManager.setDimension(tc, (int)width * 50);
+
             builderContext.pushContainer(cell);
         } catch (Exception e) {
             log.error("startCell: " + e.getMessage());
@@ -876,9 +824,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endCell(TableCell tc) {
         if (bDefer) {
             return;
@@ -889,9 +835,7 @@ public class RTFHandler extends FOEventHandler {
     }
 
     // Lists
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startList(ListBlock lb) {
         if (bDefer) {
             return;
@@ -917,9 +861,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endList(ListBlock lb) {
         if (bDefer) {
             return;
@@ -928,19 +870,17 @@ public class RTFHandler extends FOEventHandler {
         builderContext.popContainer();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startListItem(ListItem li) {
         if (bDefer) {
             return;
         }
-        
+
         // create an RtfListItem in the current RtfList
         try {
             RtfList list = (RtfList)builderContext.getContainer(
                     RtfList.class, true, this);
-            
+
             /**
              * If the current list already contains a list item, then close the
              * list and open a new one, so every single list item gets its own
@@ -954,11 +894,11 @@ public class RTFHandler extends FOEventHandler {
                 this.endList((ListBlock) li.getParent());
                 this.startList((ListBlock) li.getParent());
                 this.startListBody();
-                
+
                 list = (RtfList)builderContext.getContainer(
                         RtfList.class, true, this);
-            }            
-            
+            }
+
             builderContext.pushContainer(list.newListItem());
         } catch (IOException ioe) {
             log.error("startList: " + ioe.getMessage());
@@ -969,9 +909,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endListItem(ListItem li) {
         if (bDefer) {
             return;
@@ -980,9 +918,7 @@ public class RTFHandler extends FOEventHandler {
         builderContext.popContainer();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startListLabel() {
         if (bDefer) {
             return;
@@ -1003,9 +939,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endListLabel() {
         if (bDefer) {
             return;
@@ -1014,46 +948,32 @@ public class RTFHandler extends FOEventHandler {
         builderContext.popContainer();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startListBody() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endListBody() {
     }
 
     // Static Regions
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startStatic() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endStatic() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startMarkup() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endMarkup() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startLink(BasicLink basicLink) {
         if (bDefer) {
             return;
@@ -1085,9 +1005,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endLink() {
         if (bDefer) {
             return;
@@ -1096,9 +1014,7 @@ public class RTFHandler extends FOEventHandler {
         builderContext.popContainer();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void image(ExternalGraphic eg) {
         if (bDefer) {
             return;
@@ -1115,32 +1031,30 @@ public class RTFHandler extends FOEventHandler {
                 log.error("Image could not be found: " + uri);
                 return;
             }
-            
+
             putGraphic(eg, info);
         } catch (Exception e) {
             log.error("Error while handling an external-graphic: " + e.getMessage(), e);
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void foreignObject(InstreamForeignObject ifo) {
         if (bDefer) {
             return;
         }
-        
+
         try {
-            XMLObj child = (XMLObj) ifo.getChildXMLObj();
+            XMLObj child = ifo.getChildXMLObj();
             Document doc = child.getDOMDocument();
             String ns = child.getNamespaceURI();
-            
+
             ImageInfo info = new ImageInfo(null, null);
             // Set the resolution to that of the FOUserAgent
             FOUserAgent ua = ifo.getUserAgent();
             ImageSize size = new ImageSize();
             size.setResolution(ua.getSourceResolution());
-            
+
             // Set the image size to the size of the svg.
             Point2D csize = new Point2D.Float(-1, -1);
             Point2D intrinsicDimensions = child.getDimension(csize);
@@ -1151,13 +1065,13 @@ public class RTFHandler extends FOEventHandler {
             info.setSize(size);
 
             ImageXMLDOM image = new ImageXMLDOM(info, doc, ns);
-            
+
             FOUserAgent userAgent = ifo.getUserAgent();
             ImageManager manager = userAgent.getFactory().getImageManager();
             Map hints = ImageUtil.getDefaultHints(ua.getImageSessionContext());
             Image converted = manager.convertImage(image, FLAVORS, hints);
             putGraphic(ifo, converted);
-            
+
         } catch (Exception e) {
             log.error("Error while handling an instream-foreign-object: " + e.getMessage(), e);
         }
@@ -1166,14 +1080,14 @@ public class RTFHandler extends FOEventHandler {
     private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
         ImageFlavor.RAW_EMF, ImageFlavor.RAW_PNG, ImageFlavor.RAW_JPEG
     };
-    
+
     /**
      * Puts a graphic/image into the generated RTF file.
      * @param abstractGraphic the graphic (external-graphic or instream-foreign-object)
      * @param info the image info object
      * @throws IOException In case of an I/O error
      */
-    private void putGraphic(AbstractGraphics abstractGraphic, ImageInfo info) 
+    private void putGraphic(AbstractGraphics abstractGraphic, ImageInfo info)
             throws IOException {
         try {
             FOUserAgent userAgent = abstractGraphic.getUserAgent();
@@ -1187,17 +1101,17 @@ public class RTFHandler extends FOEventHandler {
             log.error("Error while loading/processing image: " + info.getOriginalURI(), ie);
         }
     }
-    
+
     /**
      * Puts a graphic/image into the generated RTF file.
      * @param abstractGraphic the graphic (external-graphic or instream-foreign-object)
      * @param image the image
      * @throws IOException In case of an I/O error
      */
-    private void putGraphic(AbstractGraphics abstractGraphic, Image image) 
+    private void putGraphic(AbstractGraphics abstractGraphic, Image image)
             throws IOException {
         byte[] rawData = null;
-        
+
         ImageInfo info = image.getInfo();
 
         if (image instanceof ImageRawStream) {
@@ -1221,7 +1135,7 @@ public class RTFHandler extends FOEventHandler {
                 IRtfTextrunContainer.class, true, this);
 
         final RtfExternalGraphic rtfGraphic = c.getTextrun().newImage();
-   
+
         //set URL
         if (info.getOriginalURI() != null) {
             rtfGraphic.setURL(info.getOriginalURI());
@@ -1296,16 +1210,12 @@ public class RTFHandler extends FOEventHandler {
             }
         }
     }
-    
-    /**
-     * {@inheritDoc}
-     */
+
+    /** {@inheritDoc} */
     public void pageRef() {
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startFootnote(Footnote footnote) {
         if (bDefer) {
             return;
@@ -1332,9 +1242,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endFootnote(Footnote footnote) {
         if (bDefer) {
             return;
@@ -1343,9 +1251,7 @@ public class RTFHandler extends FOEventHandler {
         builderContext.popContainer();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void startFootnoteBody(FootnoteBody body) {
         if (bDefer) {
             return;
@@ -1368,9 +1274,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void endFootnoteBody(FootnoteBody body) {
         if (bDefer) {
             return;
@@ -1393,9 +1297,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public void leader(Leader l) {
     }
 
@@ -1432,10 +1334,7 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     *
-     * @param pagenum PageNumber that is starting.
-     */
+    /** {@inheritDoc} */
     public void startPageNumber(PageNumber pagenum) {
         if (bDefer) {
             return;
@@ -1461,16 +1360,64 @@ public class RTFHandler extends FOEventHandler {
         }
     }
 
-    /**
-     *
-     * @param pagenum PageNumber that is ending.
-     */
+    /** {@inheritDoc} */
     public void endPageNumber(PageNumber pagenum) {
         if (bDefer) {
             return;
         }
     }
 
+    /** {@inheritDoc} */
+    public void startPageNumberCitation(PageNumberCitation l) {
+        if (bDefer) {
+            return;
+        }
+        try {
+
+            IRtfTextrunContainer container
+                  = (IRtfTextrunContainer)builderContext.getContainer(
+                      IRtfTextrunContainer.class, true, this);
+            RtfTextrun textrun = container.getTextrun();
+
+            textrun.addPageNumberCitation(l.getRefId());
+
+        } catch (Exception e) {
+            log.error("startPageNumberCitation: " + e.getMessage());
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    private void prepareTable(Table tab) {
+        // Allows to receive the available width of the table
+        percentManager.setDimension(tab);
+
+        // Table gets expanded by half of the border on each side inside Word
+        // When using wide borders the table gets cut off
+        int tabDiff = tab.getCommonBorderPaddingBackground().getBorderStartWidth(false) / 2
+                + tab.getCommonBorderPaddingBackground().getBorderEndWidth(false);
+
+        // check for "auto" value
+        if (!(tab.getInlineProgressionDimension().getMaximum(null).getLength()
+                    instanceof EnumLength)) {
+            // value specified
+            percentManager.setDimension(tab,
+                    tab.getInlineProgressionDimension().getMaximum(null)
+                        .getLength().getValue(percentManager)
+                    - tabDiff);
+        } else {
+            // set table width again without border width
+            percentManager.setDimension(tab, percentManager.getBaseLength(
+                    LengthBase.CONTAINING_BLOCK_WIDTH, tab) - tabDiff);
+        }
+
+        ColumnSetup columnSetup = new ColumnSetup(tab);
+        //int sumOfColumns = columnSetup.getSumOfColumnWidths(percentManager);
+        float tableWidth = percentManager.getBaseLength(LengthBase.CONTAINING_BLOCK_WIDTH, tab);
+        float tableUnit = columnSetup.computeTableUnit(percentManager, Math.round(tableWidth));
+        percentManager.setTableUnit(tab, Math.round(tableUnit));
+
+    }
+
     /**
      * Calls the appropriate event handler for the passed FObj.
      *
@@ -1611,6 +1558,12 @@ public class RTFHandler extends FOEventHandler {
             } else {
                 endCell( (TableCell) foNode);
             }
+        } else if (foNode instanceof PageNumberCitation) {
+            if (bStart) {
+                startPageNumberCitation((PageNumberCitation) foNode);
+            } else {
+                endPageNumberCitation((PageNumberCitation) foNode);
+            }
         } else {
             log.warn("Ignored deferred event for " + foNode);
         }
@@ -1651,9 +1604,12 @@ public class RTFHandler extends FOEventHandler {
 
             //recurse all table-columns
             if (table.getColumns() != null) {
-                for (Iterator it = table.getColumns().iterator(); it.hasNext();) {
-                    recurseFONode( (FONode) it.next() );
-                }
+              //Calculation for column-widths which are not set
+              prepareTable(table);
+
+              for (Iterator it = table.getColumns().iterator(); it.hasNext();) {
+                  recurseFONode( (FONode) it.next() );
+              }
             } else {
                 //TODO Implement implicit column setup handling!
                 log.warn("No table-columns found on table. RTF output requires that all"
index 92d6a56558731a47e24b6f28da2d76a164f5352d..5ec5e907e6c139f894b00bf601f0679270036555 100644 (file)
@@ -5,9 +5,9 @@
  * 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.
@@ -28,6 +28,7 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
 
 import java.util.HashMap;
 import java.util.Iterator;
+
 import org.xml.sax.Attributes;
 import org.xml.sax.helpers.AttributesImpl;
 
@@ -163,6 +164,15 @@ implements java.lang.Cloneable {
         return values.get(name);
     }
 
+    /**
+     * Returns a value as an Integer. The value is simply cast to an Integer.
+     * @param name String containing attribute name
+     * @return the value of an attribute, null if not found
+     */
+    public Integer getValueAsInteger(String name) {
+        return (Integer)values.get(name);
+    }
+
     /**
      * @param name String containing attribute name
      * @return true if given attribute is set
@@ -215,17 +225,17 @@ implements java.lang.Cloneable {
             xslAttributes = new org.xml.sax.helpers.AttributesImpl(pAttribs);
         }
     }
-    
+
     /**
      * Add integer value <code>addValue</code> to attribute with name <code>name</code>.
-     * If there is no such setted attribute, then value of this attribure is equal to 
+     * If there is no such setted attribute, then value of this attribure is equal to
      * <code>addValue</code>.
      * @param addValue the increment of value
      * @param name the name of attribute
      */
     public void addIntegerValue(int addValue, String name) {
         Integer value = (Integer) getValue(name);
-        int v = (value != null) ? value.intValue() : 0; 
+        int v = (value != null) ? value.intValue() : 0;
         set(name, v + addValue);
     }
 }
index bd2e9e62dad3d061633557545318e33d37b9421f..3662fb27844b0ab282f8252aac7872cd8b30b896 100644 (file)
@@ -60,11 +60,13 @@ extends RtfContainer {
     public static final String HEADERY = "headery";
     /** constant for footer position */
     public static final String FOOTERY = "footery";
-
+    /** constant for itap level */
+    public static final String ITAP = "itap";
+    
     /** String array of RtfPage attributes */
     public static final String[] PAGE_ATTR = new String[]{
         PAGE_WIDTH, PAGE_HEIGHT, LANDSCAPE, MARGIN_TOP, MARGIN_BOTTOM,
-        MARGIN_LEFT, MARGIN_RIGHT, HEADERY, FOOTERY
+        MARGIN_LEFT, MARGIN_RIGHT, HEADERY, FOOTERY, ITAP
     };
 
     /**    RtfPage creates new page attributes with the parent container, the writer
index c7f455c70249f93c6d128ec0f159cb4ea1d52fd1..44c03c316ed09e7866ed0d0a8deecf3ceaf45557 100644 (file)
@@ -5,9 +5,9 @@
  * 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.
@@ -26,8 +26,8 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
  * the FOP project.
  */
 
-import java.io.Writer;
 import java.io.IOException;
+import java.io.Writer;
 
 /**
  * @author Christopher Scott, scottc@westinghouse.com
@@ -50,9 +50,9 @@ public class RtfPageNumberCitation extends RtfContainer {
     private String id = null;
 
     /** Create an RTF page number citation as a child of given container with default attributes */
-    RtfPageNumberCitation (IRtfPageNumberCitationContainer parent, Writer w, String id)
+    RtfPageNumberCitation (RtfContainer parent, Writer w, String id)
             throws IOException {
-        super((RtfContainer)parent, w);
+        super(parent, w);
         this.id = id;
     }
 
@@ -78,8 +78,8 @@ public class RtfPageNumberCitation extends RtfContainer {
             // Build page reference field
             String pageRef = RTF_FIELD_PAGEREF_MODEL;
             final int insertionIndex = pageRef.indexOf("}");
-            pageRef = pageRef.substring(0, insertionIndex) 
-                + "\"" + id 
+            pageRef = pageRef.substring(0, insertionIndex)
+                + "\"" + id
                 + "\"" + " "
                 + pageRef.substring(insertionIndex, pageRef.length());
             id = null;
@@ -92,7 +92,7 @@ public class RtfPageNumberCitation extends RtfContainer {
             writeStarControlWord(pageRef);
             writeGroupMark(false);
             writeGroupMark(true);
-            writeControlWord(RTF_FIELD_RESULT);
+            writeControlWord(RTF_FIELD_RESULT + '#'); //To see where the page-number would be
             writeGroupMark(false);
             writeGroupMark(false);
         }
index b8bb4b03239a36d36f4e44aa486b1b2b11adc850..3747103d139a599ba697eadf5d8557c48bcce0aa 100644 (file)
@@ -5,9 +5,9 @@
  * 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.
@@ -26,8 +26,8 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
  * the FOP project.
  */
 
-import java.io.Writer;
 import java.io.IOException;
+import java.io.Writer;
 
 /**  Container for RtfRow elements
  *  @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
@@ -43,6 +43,9 @@ public class RtfTable extends RtfContainer {
      *  number-columns-spanned attribute */
     private ITableColumnsInfo tableContext;
 
+    /** Shows the table depth necessary for nested tables */
+    private int nestedTableDepth = 0;
+
     /** Create an RTF element as a child of given container */
     RtfTable(IRtfTableContainer parent, Writer w, ITableColumnsInfo tc)
             throws IOException {
@@ -110,16 +113,16 @@ public class RtfTable extends RtfContainer {
             writeControlWordNS("pard");
         }
 
-        writeGroupMark(true);   
+        writeGroupMark(true);
     }
-    
+
     /**
      * Overridden to write RTF suffix code, what comes after our children
      * @throws IOException for I/O problems
      */
     protected void writeRtfSuffix() throws IOException {
         writeGroupMark(false);
-        
+
         if (isNestedTable()) {
             getRow().writeRowAndCellsDefintions();
         }
@@ -154,7 +157,7 @@ public class RtfTable extends RtfContainer {
     }
 
     /**
-     * 
+     *
      * @return RtfAttributes of Header
      */
     public RtfAttributes getHeaderAttribs() {
@@ -173,7 +176,7 @@ public class RtfTable extends RtfContainer {
 
         return super.getRtfAttributes();
     }
-    
+
     /** @return true if the the table is a nested table */
     public boolean isNestedTable() {
         if (isNestedTable == null) {
@@ -194,9 +197,9 @@ public class RtfTable extends RtfContainer {
 
         return false;
     }
-    
+
     /**
-     * 
+     *
      * @return Parent row table (for nested tables only)
      */
     public RtfTableRow getRow() {
@@ -209,7 +212,23 @@ public class RtfTable extends RtfContainer {
             e = e.parent;
         }
 
-        return null;  
+        return null;
+    }
+
+    /**
+     * Sets the nested table depth.
+     * @param nestedTableDepth the nested table depth
+     */
+    public void setNestedTableDepth(int nestedTableDepth) {
+        this.nestedTableDepth = nestedTableDepth;
+    }
+
+    /**
+     * Returns the nested table depth.
+     * @return the nested table depth
+     */
+    public int getNestedTableDepth() {
+        return this.nestedTableDepth;
     }
 
     /**
@@ -219,7 +238,7 @@ public class RtfTable extends RtfContainer {
     public void setBorderAttributes(RtfAttributes attributes) {
         borderAttributes = attributes;
     }
-    
+
     /**
      * Returns the RtfAttributes for the borders of the table.
      * @return Border attributes of the table.
index 2182f94ecc5caf65c1cd1ff8e3eda43a4299e4f2..f5e5978ecf2992af09a7dca0ba94ce977f02065a 100644 (file)
@@ -5,9 +5,9 @@
  * 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.
@@ -133,11 +133,11 @@ public class RtfTableRow extends RtfContainer implements ITableAttributes {
      * @throws IOException for I/O problems
      */
     protected void writeRtfContent() throws IOException {
-
         if (getTable().isNestedTable()) {
             //nested table
             writeControlWord("intbl");
-            writeControlWord("itap2");
+            //itap is the depth (level) of the current nested table
+            writeControlWord("itap" + getTable().getNestedTableDepth());
         } else {
             //normal (not nested) table
             writeRowAndCellsDefintions();
@@ -145,15 +145,15 @@ public class RtfTableRow extends RtfContainer implements ITableAttributes {
         // now children can write themselves, we have the correct RTF prefix code
         super.writeRtfContent();
     }
-    
+
     /**
-     * 
+     *
      * @throws IOException In case of a IO-problem
      */
     public void writeRowAndCellsDefintions() throws IOException {
         // render the row and cells definitions
         writeControlWord("trowd");
-        
+
         if (!getTable().isNestedTable()) {
             writeControlWord("itap0");
         }
@@ -181,24 +181,24 @@ public class RtfTableRow extends RtfContainer implements ITableAttributes {
 
         // write X positions of our cells
         int xPos = 0;
-        
+
         final Object leftIndent = attrib.getValue(ITableAttributes.ATTR_ROW_LEFT_INDENT);
         if (leftIndent != null) {
             xPos = ((Integer)leftIndent).intValue();
         }
-        
+
         RtfAttributes tableBorderAttributes = getTable().getBorderAttributes();
-        
+
         int index = 0;
         for (Iterator it = getChildren().iterator(); it.hasNext();) {
             final RtfElement e = (RtfElement)it.next();
             if (e instanceof RtfTableCell) {
-                
+
                 RtfTableCell rtfcell = (RtfTableCell)e;
-                
+
                 // Adjust the cell's display attributes so the table's/row's borders
                 // are drawn properly.
-                
+
                 if (tableBorderAttributes != null) {
                     // get border attributes from table
                     if (index == 0) {
@@ -233,7 +233,7 @@ public class RtfTableRow extends RtfContainer implements ITableAttributes {
                         }
                     }
                 }
-                
+
                 // get border attributes from row
                 if (index == 0) {
                     if (!rtfcell.getRtfAttributes().isSet(ITableAttributes.CELL_BORDER_LEFT)) {
@@ -268,7 +268,7 @@ public class RtfTableRow extends RtfContainer implements ITableAttributes {
             }
           index++; // Added by Boris POUDEROUS on 2002/07/02
         }
-        
+
         newLine();
     }
 
@@ -366,9 +366,9 @@ public class RtfTableRow extends RtfContainer implements ITableAttributes {
     public boolean isHighestCell(int cellId) {
         return (highestCell == cellId) ? true : false;
     }
-    
+
     /**
-     * 
+     *
      * @return Parent table of the row.
      */
     public RtfTable getTable() {
@@ -381,6 +381,6 @@ public class RtfTableRow extends RtfContainer implements ITableAttributes {
             e = e.parent;
         }
 
-        return null;  
+        return null;
     }
 }
index 05a97ffd4a8e5a2317fb2bcb2bda92187846b82d..b0db4576b489b439826ea02e2401462b42d3a857 100644 (file)
@@ -5,9 +5,9 @@
  * 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.
@@ -22,40 +22,37 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
 // Java
 import java.io.IOException;
 import java.io.Writer;
-import java.util.List;
 import java.util.Iterator;
+import java.util.List;
 import java.util.ListIterator;
 
-// FOP
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfExternalGraphic;
-
-/** 
- * Class which contains a linear text run. It has methods to add attributes, 
+/**
+ * Class which contains a linear text run. It has methods to add attributes,
  * text, paragraph breaks....
  * @author Peter Herweg, pherweg@web.de
  */
 public class RtfTextrun extends RtfContainer {
     private boolean bSuppressLastPar = false;
     private RtfListItem rtfListItem;
-    
+
     /** Manager for handling space-* property. */
     private RtfSpaceManager rtfSpaceManager = new RtfSpaceManager();
-    
+
     /**  Class which represents the opening of a RTF group mark.*/
     private class RtfOpenGroupMark extends RtfElement {
-                
+
         RtfOpenGroupMark(RtfContainer parent, Writer w, RtfAttributes attr)
                 throws IOException {
             super(parent, w, attr);
         }
-        
+
         /**
          * @return true if this element would generate no "useful" RTF content
          */
         public boolean isEmpty() {
             return false;
         }
-        
+
         /**
          * write RTF code of all our children
          * @throws IOException for I/O problems
@@ -65,22 +62,22 @@ public class RtfTextrun extends RtfContainer {
             writeAttributes(getRtfAttributes(), null);
         }
     }
-    
+
     /**  Class which represents the closing of a RTF group mark.*/
     private class RtfCloseGroupMark extends RtfElement {
-        
+
         RtfCloseGroupMark(RtfContainer parent, Writer w)
                 throws IOException {
             super(parent, w);
         }
-        
+
         /**
          * @return true if this element would generate no "useful" RTF content
          */
         public boolean isEmpty() {
             return false;
         }
-        
+
         /**
          * write RTF code of all our children
          * @throws IOException for I/O problems
@@ -92,19 +89,19 @@ public class RtfTextrun extends RtfContainer {
 
     /**  Class which represents a paragraph break.*/
     private class RtfParagraphBreak extends RtfElement {
-        
+
         RtfParagraphBreak(RtfContainer parent, Writer w)
                 throws IOException {
             super(parent, w);
         }
-    
+
         /**
          * @return true if this element would generate no "useful" RTF content
          */
         public boolean isEmpty() {
             return false;
         }
-    
+
         /**
          * write RTF code of all our children
          * @throws IOException for I/O problems
@@ -113,16 +110,16 @@ public class RtfTextrun extends RtfContainer {
             writeControlWord("par");
         }
     }
-              
+
     /** Create an RTF container as a child of given container */
     RtfTextrun(RtfContainer parent, Writer w, RtfAttributes attrs) throws IOException {
         super(parent, w, attrs);
     }
-    
-    
+
+
     /**
      * Adds instance of <code>OpenGroupMark</code> as a child with attributes.
-     * 
+     *
      * @param attrs  attributes to add
      * @throws IOException for I/O problems
      */
@@ -132,17 +129,17 @@ public class RtfTextrun extends RtfContainer {
 
     /**
      * Adds instance of <code>CloseGroupMark</code> as a child.
-     * 
+     *
      * @throws IOException for I/O problems
      */
     private void addCloseGroupMark() throws IOException {
         RtfCloseGroupMark r = new RtfCloseGroupMark(this, writer);
     }
-    
+
     /**
-     * Pushes block attributes, notifies all opened blocks about pushing block 
+     * Pushes block attributes, notifies all opened blocks about pushing block
      * attributes, adds <code>OpenGroupMark</code> as a child.
-     * 
+     *
      * @param attrs  the block attributes to push
      * @throws IOException for I/O problems
      */
@@ -151,11 +148,11 @@ public class RtfTextrun extends RtfContainer {
         RtfSpaceSplitter splitter = rtfSpaceManager.pushRtfSpaceSplitter(attrs);
         addOpenGroupMark(splitter.getCommonAttributes());
     }
-    
+
     /**
-     * Pops block attributes, notifies all opened blocks about pushing block 
+     * Pops block attributes, notifies all opened blocks about pushing block
      * attributes, adds <code>CloseGroupMark</code> as a child.
-     * 
+     *
      * @throws IOException for I/O problems
      */
     public void popBlockAttributes() throws IOException {
@@ -166,7 +163,7 @@ public class RtfTextrun extends RtfContainer {
 
     /**
      * Pushes inline attributes.
-     * 
+     *
      * @param attrs  the inline attributes to push
      * @throws IOException for I/O problems
      */
@@ -175,19 +172,28 @@ public class RtfTextrun extends RtfContainer {
         addOpenGroupMark(attrs);
     }
 
+    /**
+     * Inserts a page number citation.
+     * @param refId the identifier being referenced
+     * @throws IOException for I/O problems
+     */
+    public void addPageNumberCitation(String refId) throws IOException {
+        RtfPageNumberCitation r = new RtfPageNumberCitation(this, writer, refId);
+    }
+
     /**
      * Pop inline attributes.
-     * 
+     *
      * @throws IOException for I/O problems
      */
     public void popInlineAttributes() throws IOException {
         rtfSpaceManager.popInlineAttributes();
         addCloseGroupMark();
     }
-    
+
     /**
      * Add string to children list.
-     * 
+     *
      * @param s  string to add
      * @throws IOException for I/O problems
      */
@@ -202,20 +208,20 @@ public class RtfTextrun extends RtfContainer {
         RtfString r = new RtfString(this, writer, s);
         rtfSpaceManager.popRtfSpaceSplitter();
     }
-    
+
     /**
      * Inserts a footnote.
-     * 
+     *
      * @return inserted footnote
      * @throws IOException for I/O problems
      */
     public RtfFootnote addFootnote() throws IOException {
         return new RtfFootnote(this, writer);
     }
-    
+
     /**
      * Inserts paragraph break before all close group marks.
-     * 
+     *
      * @throws IOException  for I/O problems
      */
     public void addParagraphBreak() throws IOException {
@@ -241,7 +247,7 @@ public class RtfTextrun extends RtfContainer {
             }
         }
     }
-    
+
     /**
      * Inserts a page number.
      * @param attr Attributes for the page number to insert.
@@ -250,7 +256,7 @@ public class RtfTextrun extends RtfContainer {
     public void addPageNumber(RtfAttributes attr) throws IOException {
         RtfPageNumber r = new RtfPageNumber(this, writer, attr);
     }
-    
+
     /**
      * Inserts a hyperlink.
      * @param attr Attributes for the hyperlink to insert.
@@ -260,7 +266,7 @@ public class RtfTextrun extends RtfContainer {
     public RtfHyperLink addHyperlink(RtfAttributes attr) throws IOException {
         return new RtfHyperLink(this, writer, attr);
     }
-    
+
     /**
      * Inserts a bookmark.
      * @param id Id for the inserted bookmark
@@ -294,7 +300,7 @@ public class RtfTextrun extends RtfContainer {
             throws IOException {
 
         List list = container.getChildren();
-                
+
         if (list.size() == 0) {
             //add a new RtfTextrun
             RtfTextrun textrun = new RtfTextrun(container, writer, attrs);
@@ -302,7 +308,7 @@ public class RtfTextrun extends RtfContainer {
 
             return textrun;
         }
-        
+
         Object obj = list.get(list.size() - 1);
 
         if (obj instanceof RtfTextrun) {
@@ -313,18 +319,18 @@ public class RtfTextrun extends RtfContainer {
         //add a new RtfTextrun as the last child
         RtfTextrun textrun = new RtfTextrun(container, writer, attrs);
         list.add(textrun);
-        
+
         return textrun;
     }
-   
+
     /**
      * specify, if the last paragraph control word (\par) should be suppressed.
      * @param bSuppress true, if the last \par should be suppressed
-     */    
+     */
     public void setSuppressLastPar(boolean bSuppress) {
         bSuppressLastPar = bSuppress;
     }
-   
+
     /**
      * write RTF code of all our children
      * @throws IOException for I/O problems
@@ -336,7 +342,7 @@ public class RtfTextrun extends RtfContainer {
          * 2. To write the children
          * Maybe this can be done more efficient.
          */
-        
+
         boolean bHasTableCellParent =
             this.getParentOfClass(RtfTableCell.class) != null;
         RtfAttributes attrBlockLevel = new RtfAttributes();
@@ -349,7 +355,7 @@ public class RtfTextrun extends RtfContainer {
                 break;
             }
         }
-        
+
         //get last RtfParagraphBreak, which is not followed by any visible child
         RtfParagraphBreak lastParagraphBreak = null;
         if (bLast) {
@@ -366,10 +372,10 @@ public class RtfTextrun extends RtfContainer {
                 }
             }
         }
-        
+
         //may contain for example \intbl
         writeAttributes(attrib, null);
-        
+
         if (rtfListItem != null) {
             rtfListItem.getRtfListStyle().writeParagraphPrefix(this);
         }
@@ -384,8 +390,8 @@ public class RtfTextrun extends RtfContainer {
             if (bHasTableCellParent) {
                 attrBlockLevel.set(e.getRtfAttributes());
             }
-            
-            
+
+
             /**
              * -Write RtfParagraphBreak only, if the previous visible child
              * was't also a RtfParagraphBreak.
@@ -396,21 +402,21 @@ public class RtfTextrun extends RtfContainer {
              */
             boolean bHide = false;
             bHide = bRtfParagraphBreak;
-            bHide = bHide 
-                && (bPrevPar 
-                    || bFirst 
-                    || (bSuppressLastPar && bLast && lastParagraphBreak != null 
+            bHide = bHide
+                && (bPrevPar
+                    || bFirst
+                    || (bSuppressLastPar && bLast && lastParagraphBreak != null
                         && e == lastParagraphBreak));
-                
+
             if (!bHide) {
                 newLine();
-                e.writeRtf(); 
-                
+                e.writeRtf();
+
                 if (rtfListItem != null && e instanceof RtfParagraphBreak) {
                     rtfListItem.getRtfListStyle().writeParagraphPrefix(this);
                 }
             }
-            
+
             if (e instanceof RtfParagraphBreak) {
                 bPrevPar = true;
             } else if (e instanceof RtfCloseGroupMark) {
@@ -422,26 +428,26 @@ public class RtfTextrun extends RtfContainer {
                 bFirst = bFirst && e.isEmpty();
             }
         } //for (Iterator it = ...)
-        
+
         //
         if (bHasTableCellParent) {
             writeAttributes(attrBlockLevel, null);
         }
-        
+
     }
-    
+
     /**
      * Set the parent list-item of the textrun.
-     * 
+     *
      * @param listItem parent list-item of the textrun
      */
     public void setRtfListItem(RtfListItem listItem) {
         rtfListItem = listItem;
     }
-    
+
     /**
-     * Gets the parent list-item of the textrun. 
-     * 
+     * Gets the parent list-item of the textrun.
+     *
      * @return parent list-item of the textrun
      */
     public RtfListItem getRtfListItem() {
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/tools/PercentContext.java b/src/java/org/apache/fop/render/rtf/rtflib/tools/PercentContext.java
new file mode 100644 (file)
index 0000000..732ecf9
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * 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$ */
+
+package org.apache.fop.render.rtf.rtflib.tools;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.datatypes.LengthBase;
+import org.apache.fop.datatypes.PercentBaseContext;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.pagination.PageSequence;
+
+/**
+ * PercentBaseContext implementation to track base widths for percentage calculations.
+ */
+public class PercentContext implements PercentBaseContext {
+    private static Log log = LogFactory.getLog(PercentContext.class);
+
+    private static final String BLOCKCONTAINER = "fo:block-container";
+    private static final String INLINECONTAINER = "fo:inline-container";
+    private static final String TABLE = "fo:table";
+    private static final String TABLECOLUMN = "fo:table-column";
+    private static final String PAGESEQUENCE = "fo:page-sequence";
+    private static final String EXTERNALGRAPHIC = "fo:external-graphic";
+
+    /** String array of Elements having a width property */
+    public static final String[] WIDTH_OBJECTS = new String[] {
+            BLOCKCONTAINER, INLINECONTAINER,
+            TABLE, TABLECOLUMN, PAGESEQUENCE, EXTERNALGRAPHIC};
+
+    /** Map containing the FObj and its width */
+    private Map lengthMap = new java.util.HashMap();
+
+    /** Map containing the Tables and their table units */
+    private Map tableUnitMap = new java.util.HashMap();
+
+    /** Variable to check if a base width is set */
+    private boolean baseWidthSet = false;
+
+    /**
+     * Returns the available width for a specific FObj
+     *
+     * @param lengthBase
+     *                lengthBase not used
+     * @param fobj
+     *                the FObj
+     * @return Available Width
+     */
+    public int getBaseLength(int lengthBase, FObj fobj) {
+        if (fobj == null) {
+            return 0;
+        }
+        switch (lengthBase) {
+        case LengthBase.CONTAINING_BLOCK_WIDTH:
+        case LengthBase.PARENT_AREA_WIDTH:
+        case LengthBase.CONTAINING_REFAREA_WIDTH:
+            Object width = lengthMap.get(fobj);
+            if (width != null) {
+                return Integer.parseInt(width.toString());
+            } else {
+                return -1;
+            }
+        case LengthBase.TABLE_UNITS:
+            Object unit = tableUnitMap.get(fobj);
+            /*
+            if (unit == null && !(fobj instanceof Table)) {
+                FONode node = fobj;
+                do {
+                    node = node.getParent();
+                } while (!(node instanceof FObj) || node != null);
+                return getBaseLength(lengthBase, (FObj)node);
+            }
+            */
+            return (unit != null) ? ((Integer)unit).intValue() : 0;
+        default:
+            log.error(new Exception("Unsupported base type for LengthBase:" + lengthBase));
+            return 0;
+        }
+    }
+
+    /**
+     * Elements having a width property can call this function if their width is
+     * calculated in RTFHandler
+     *
+     * @param fobj the FObj
+     * @param width width of the FObj (in millipoints)
+     */
+    public void setDimension(FObj fobj, int width) {
+        // TODO ACCEPT only objects above for setting a width
+        if (fobj instanceof PageSequence) {
+            baseWidthSet = true;
+        }
+        // width in mpt
+        lengthMap.put(fobj, new Integer(width));
+    }
+
+    /**
+     * Records the calculated table unit for a given table.
+     * @param table the table for which the table unit is set
+     * @param tableUnit the table unit value (in millipoints)
+     */
+    public void setTableUnit(Table table, int tableUnit) {
+        tableUnitMap.put(table, new Integer(tableUnit));
+    }
+
+    /**
+     * Searches for the parent object of fobj.
+     */
+    private Integer findParent(FONode fobj) {
+        if (fobj.getRoot() != fobj) {
+            if (lengthMap.containsKey(fobj)) {
+                return new Integer(lengthMap.get(fobj).toString());
+            } else {
+                return findParent(fobj.getParent());
+            }
+        } else {
+            log.error("Base Value for element " + fobj.getName() + " not found");
+            return new Integer(-1);
+        }
+    }
+
+    /**
+     * Elements willing to use this context have to register themselves by
+     * calling this function.
+     *
+     * @param fobj the FObj
+     */
+    public void setDimension(FObj fobj) {
+        if (baseWidthSet) {
+            Integer width = findParent(fobj.getParent());
+            if (width.intValue() != -1) {
+                lengthMap.put(fobj, width);
+            }
+        }
+    }
+}
index 6c557c25191feac48fe210ed5281b55effa8d119..5367daf3fb924b43747d5ea76549b89d1d3a6b50 100644 (file)
       -->
     <!--/release-->
     <release version="0.95" date="TBD">
+      <action context="Renderers" dev="JM" type="add" fixes-bug="43824" due-to="Maximilian Aster">
+        Added support for page-number-citation for RTF output.
+      </action>
+      <action context="Renderers" dev="JM" type="fix" fixes-bug="43606" due-to="Maximilian Aster">
+        Fixed handling of proportional-column-width() and percentages for table column in RTF
+        output.
+      </action>
       <action context="Images" dev="JM" type="fix">
         Fixed two bugs concerning resolution handling with SVG images and their
         conversion to bitmaps for RTF output.