You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2005/11/14 19:02:25 UTC

svn commit: r344172 - in /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf: RTFHandler.java rtflib/rtfdoc/RtfSpaceManager.java rtflib/rtfdoc/RtfSpaceSplitter.java rtflib/rtfdoc/RtfTextrun.java

Author: jeremias
Date: Mon Nov 14 10:02:14 2005
New Revision: 344172

URL: http://svn.apache.org/viewcvs?rev=344172&view=rev
Log:
Bugzilla #36480:
Improved space-before/space-after support for RTF output. Fixes problems with space support in the existing code.
Submitted by: Sergey Simonchik <Sergey.Simonchik.at.borland.com>

Added:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceManager.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceSplitter.java   (with props)
Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java?rev=344172&r1=344171&r2=344172&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java Mon Nov 14 10:02:14 2005
@@ -336,7 +336,7 @@
             RtfTextrun textrun = container.getTextrun();
 
             textrun.addParagraphBreak();
-            textrun.pushAttributes(rtfAttr);
+            textrun.pushBlockAttributes(rtfAttr);
             textrun.addBookmark(bl.getId());
         } catch (IOException ioe) {
             // TODO could we throw Exception in all FOEventHandler events?
@@ -367,7 +367,7 @@
             RtfTextrun textrun = container.getTextrun();
 
             textrun.addParagraphBreak();
-            textrun.popAttributes();
+            textrun.popBlockAttributes();
 
         } catch (IOException ioe) {
             log.error("startBlock:" + ioe.getMessage());
@@ -398,7 +398,7 @@
             RtfTextrun textrun = container.getTextrun();
 
             textrun.addParagraphBreak();
-            textrun.pushAttributes(rtfAttr);
+            textrun.pushBlockAttributes(rtfAttr);
         } catch (IOException ioe) {
             // TODO could we throw Exception in all FOEventHandler events?
             log.error("startBlock: " + ioe.getMessage());
@@ -426,7 +426,7 @@
             RtfTextrun textrun = container.getTextrun();
 
             textrun.addParagraphBreak();
-            textrun.popAttributes();
+            textrun.popBlockAttributes();
 
         } catch (IOException ioe) {
             log.error("startBlock:" + ioe.getMessage());
@@ -552,7 +552,7 @@
                     IRtfTextrunContainer.class, true, this);
 
             RtfTextrun textrun = container.getTextrun();
-            textrun.pushAttributes(rtfAttr);
+            textrun.pushInlineAttributes(rtfAttr);
             textrun.addBookmark(inl.getId());
         } catch (IOException ioe) {
             log.error("startInline:" + ioe.getMessage());
@@ -581,7 +581,7 @@
                     IRtfTextrunContainer.class, true, this);
 
             RtfTextrun textrun = container.getTextrun();
-            textrun.popAttributes();
+            textrun.popInlineAttributes();
         } catch (IOException ioe) {
             log.error("startInline:" + ioe.getMessage());
             throw new RuntimeException(ioe.getMessage());
@@ -1146,9 +1146,9 @@
             RtfAttributes rtfAttr
                 = TextAttributesConverter.convertCharacterAttributes(text);
 
-            textrun.pushAttributes(rtfAttr);
+            textrun.pushInlineAttributes(rtfAttr);
             textrun.addString(new String(data, start, length - start));
-            textrun.popAttributes();
+            textrun.popInlineAttributes();
          } catch (IOException ioe) {
             // FIXME could we throw Exception in all FOEventHandler events?
             log.error("characters: " + ioe.getMessage());

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceManager.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceManager.java?rev=344172&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceManager.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceManager.java Mon Nov 14 10:02:14 2005
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.rtfdoc;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+/**
+ * This class is responsible for saving space-before/space-after attributes 
+ * history and adding spacing to established candidates (i.e. attributes) or 
+ * accumulation spacing in case of candidate absence.
+ */
+public class RtfSpaceManager {
+    /** Stack for saving rtf block-level attributes. */
+    private LinkedList blockAttributes = new LinkedList();
+
+    /** Stack for saving rtf inline-level attributes. */
+    private LinkedList inlineAttributes = new LinkedList();
+
+    /**
+     * Keeps value of accumulated space in twips. For example if block has
+     * nonzero space-before or space-after properties and has no plain text
+     * inside, then the next block should has increased value of space-before
+     * property.
+     */
+    private int accumulatedSpace = 0;
+    
+    /**
+     * Construct a newly allocated <code>RtfSpaceManager</code> object.
+     */
+    public RtfSpaceManager() {
+    }
+
+    /**
+     * Iterates block-level stack (i.e. all open blocks) and stops updating 
+     * candidate for adding space-before/space-after attribute in case of 
+     * candidate presence.
+     */
+    public void stopUpdatingSpaceBefore() {
+        for (Iterator it = blockAttributes.iterator(); it.hasNext();) {
+            RtfSpaceSplitter splitter = (RtfSpaceSplitter) it.next();
+            if (splitter.isBeforeCadidateSet()) {
+                splitter.stopUpdatingSpaceBefore();
+            }
+        }
+    }
+    
+    /**
+     * Set attributes as candidate for space attributes inheritance.
+     * 
+     * @param attrs  attributes to set
+     */
+    public void setCandidate(RtfAttributes attrs) {
+        for (Iterator it = blockAttributes.iterator(); it.hasNext();) {
+            RtfSpaceSplitter splitter = (RtfSpaceSplitter) it.next();
+            splitter.setSpaceBeforeCandidate(attrs);
+            splitter.setSpaceAfterCandidate(attrs);
+        }
+    }
+    
+    /**
+     * Builds RtfSpaceSplitter on <code>attrs</code> and adds it to the 
+     * block-level stack.
+     * 
+     * @param attrs  RtfAttribute to add
+     * @return instance of RtfSpaceSplitter
+     */
+    public RtfSpaceSplitter pushRtfSpaceSplitter(RtfAttributes attrs) {
+        RtfSpaceSplitter splitter;
+        splitter = new RtfSpaceSplitter(attrs, accumulatedSpace);
+        // set accumulatedSpace to 0, because now accumulatedSpace used 
+        // in splitter
+        accumulatedSpace = 0;
+        blockAttributes.addLast(splitter);
+        return splitter;
+    }
+    
+    /**
+     * Removes RtfSpaceSplitter from top of block-level stack.
+     */
+    public void popRtfSpaceSplitter() {
+        if (!blockAttributes.isEmpty()) {
+            RtfSpaceSplitter splitter;
+            splitter = (RtfSpaceSplitter) blockAttributes.removeLast();
+            accumulatedSpace += splitter.flush();
+        }
+    }
+
+    /**
+     * Pushes inline attributes to inline-level stack.
+     * 
+     * @param attrs attributes to add
+     */
+    public void pushInlineAttributes(RtfAttributes attrs) {
+        inlineAttributes.addLast(attrs);
+    }
+
+    /**
+     * Pops inline attributes from inline-level stack.
+     */
+    public void popInlineAttributes() {
+        if (!inlineAttributes.isEmpty()) {
+            inlineAttributes.removeLast();
+        }
+    }
+
+    /**
+     * Peeks at inline-level attribute stack.
+     * 
+     * @return RtfAttributes from top of inline-level stack
+     */
+    public RtfAttributes getLastInlineAttribute() {
+        return (RtfAttributes) inlineAttributes.getLast();
+    }
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceSplitter.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceSplitter.java?rev=344172&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceSplitter.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceSplitter.java Mon Nov 14 10:02:14 2005
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.rtfdoc;
+
+/**
+ * This class splits block attributes into space-before attribute, space-after
+ * attribute and common attributes.
+ */
+public class RtfSpaceSplitter {
+
+    /** Common attributes for all text. */
+    private RtfAttributes commonAttributes;
+
+    /** Space-before attributes of a block. */
+    private int spaceBefore;
+
+    /** Space-after attributes of a block. */
+    private int spaceAfter;
+
+    /** Indicate that we can update candidate for space-before. */
+    private boolean updatingSpaceBefore;
+
+    /** Candidate for adding space-before. */
+    private RtfAttributes spaceBeforeCandidate;
+
+    /** Candidate for adding space-before. */
+    private RtfAttributes spaceAfterCandidate;
+
+    /**
+     * Create RtfSpaceSplitter with given RtfAttributes.
+     * 
+     * @param attrs  RtfAttributes for splitting
+     * @param previousSpace  integer, representing accumulated spacing
+     */
+    public RtfSpaceSplitter(RtfAttributes attrs, int previousSpace) {
+        commonAttributes = attrs;
+        updatingSpaceBefore = true;
+        spaceBeforeCandidate = null;
+        spaceAfterCandidate = null;
+
+        spaceBefore = split(RtfText.SPACE_BEFORE) + previousSpace;
+        spaceAfter = split(RtfText.SPACE_AFTER);
+    }
+
+    /**
+     * Remove attributes with name <code>key</code> from
+     * <code>commonAttributes</code> and return it as int.
+     * 
+     * @param key  attributes name to extract
+     * @return integer, representing value of extracted attributes
+     */
+    public int split(String key) {
+        Integer i = (Integer) commonAttributes.getValue(key);
+        if (i == null) {
+            i = new Integer(0);
+        }
+
+        commonAttributes.unset(key);
+        return i.intValue();
+    }
+
+    /** @return attributes, applicable to whole block. */
+    public RtfAttributes getCommonAttributes() {
+        return commonAttributes;
+    }
+
+    /** @return space-before value. */
+    public int getSpaceBefore() {
+        return spaceBefore;
+    }
+
+    /** 
+     * Sets a candidate for space-before property.
+     * 
+     * @param candidate  instance of <code>RtfAttributes</code>, considered as 
+     *        a candidate for space-before adding
+     */
+    public void setSpaceBeforeCandidate(RtfAttributes candidate) {
+        if (updatingSpaceBefore) {
+            this.spaceBeforeCandidate = candidate;
+        }
+    }
+
+    /** 
+     * Sets a candidate for space-after property.
+     * 
+     * @param candidate  instance of <code>RtfAttributes</code>, considered as 
+     *        a candidate for space-after adding
+     */
+    public void setSpaceAfterCandidate(RtfAttributes candidate) {
+        this.spaceAfterCandidate = candidate;
+    }
+
+    /** @return true, if candidate for space-before is set. */
+    public boolean isBeforeCadidateSet() {
+        return spaceBeforeCandidate != null;
+    }
+
+    /** @return true, if candidate for space-after is set. */
+    public boolean isAfterCadidateSet() {
+        return spaceAfterCandidate != null;
+    }
+    
+    /**
+     * Stops updating candidates for space-before attribute.
+     */
+    public void stopUpdatingSpaceBefore() {
+        updatingSpaceBefore = false;
+    } 
+
+    /**
+     * Adds corresponding attributes to their candidates.
+     * 
+     * @return integer, representing value of space-before/space-after 
+     *   attributes, that can't be added anywhere (i.e. these attributes 
+     *   hasn't their candidates)
+     */
+    public int flush() {
+        int accumulatingSpace = 0;
+        if (!isBeforeCadidateSet()) {
+            accumulatingSpace += spaceBefore;
+        } else {
+            spaceBeforeCandidate.addIntegerValue(spaceBefore,
+                    RtfText.SPACE_BEFORE);
+        }
+
+        if (!isAfterCadidateSet()) {
+            accumulatingSpace += spaceAfter;
+        } else {
+            spaceAfterCandidate.addIntegerValue(spaceAfter, 
+                            RtfText.SPACE_AFTER);
+        }
+
+        return accumulatingSpace;
+    }
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSpaceSplitter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java?rev=344172&r1=344171&r2=344172&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java Mon Nov 14 10:02:14 2005
@@ -30,6 +30,7 @@
 import java.io.Writer;
 import java.util.List;
 import java.util.Iterator;
+import java.util.ListIterator;
 
 // FOP
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfExternalGraphic;
@@ -43,6 +44,9 @@
     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 {
                 
@@ -121,24 +125,121 @@
         super(parent, w, attrs);
     }
     
-    public void pushAttributes(RtfAttributes attrs) throws IOException {
+    
+    /**
+     * Adds instance of <code>OpenGroupMark</code> as a child with attributes.
+     * 
+     * @param attrs  attributes to add
+     * @throws IOException for I/O problems
+     */
+    public void addOpenGroupMark(RtfAttributes attrs) throws IOException {
         RtfOpenGroupMark r = new RtfOpenGroupMark(this, writer, attrs);
     }
-    
-    public void popAttributes() throws IOException {
+
+    /**
+     * Adds instance of <code>CloseGroupMark</code> as a child.
+     * 
+     * @throws IOException for I/O problems
+     */
+    public void addCloseGroupMark() throws IOException {
         RtfCloseGroupMark r = new RtfCloseGroupMark(this, writer);
     }
     
+    /**
+     * 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
+     */
+    public void pushBlockAttributes(RtfAttributes attrs) throws IOException {
+        rtfSpaceManager.stopUpdatingSpaceBefore();
+        RtfSpaceSplitter splitter = rtfSpaceManager.pushRtfSpaceSplitter(attrs);
+        addOpenGroupMark(splitter.getCommonAttributes());
+    }
+    
+    /**
+     * 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 {
+        rtfSpaceManager.popRtfSpaceSplitter();
+        rtfSpaceManager.stopUpdatingSpaceBefore();
+        addCloseGroupMark();
+    }
+
+    /**
+     * Pushes inline attributes.
+     * 
+     * @param attrs  the inline attributes to push
+     * @throws IOException for I/O problems
+     */
+    public void pushInlineAttributes(RtfAttributes attrs) throws IOException {
+        rtfSpaceManager.pushInlineAttributes(attrs);
+        addOpenGroupMark(attrs);
+    }
+
+    /**
+     * 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
+     */
     public void addString(String s) throws IOException {
+        if (s.equals("")) {
+            return;
+        }
+        RtfAttributes attrs = rtfSpaceManager.getLastInlineAttribute();
+        //add RtfSpaceSplitter to inherit accumulated space
+        rtfSpaceManager.pushRtfSpaceSplitter(attrs);
+        rtfSpaceManager.setCandidate(attrs);
         RtfString r = new RtfString(this, writer, s);
+        rtfSpaceManager.popRtfSpaceSplitter();
     }
     
     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 {
-        RtfParagraphBreak r = new RtfParagraphBreak(this, writer);
+        // get copy of children list
+        List children = getChildren();
+
+        // delete all previous CloseGroupMark
+        int deletedCloseGroupCount = 0;
+
+        ListIterator lit = children.listIterator(children.size());
+        while (lit.hasPrevious()
+                && (lit.previous() instanceof RtfCloseGroupMark)) {
+            lit.remove();
+            deletedCloseGroupCount++;
+        }
+
+        if (children.size() != 0) {
+            // add paragraph break and restore all deleted close group marks
+            setChildren(children);
+            new RtfParagraphBreak(this, writer);
+            for (int i = 0; i < deletedCloseGroupCount; i++) {
+                addCloseGroupMark();
+            }
+        }
     }
     
     public void addPageNumber(RtfAttributes attr) throws IOException {



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org