]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Fixing a problem with disappearing footnotes inside inlines when hyphenation is enabl...
authorLuca Furini <lfurini@apache.org>
Tue, 15 May 2007 15:11:34 +0000 (15:11 +0000)
committerLuca Furini <lfurini@apache.org>
Tue, 15 May 2007 15:11:34 +0000 (15:11 +0000)
As the FootnoteLM was completely "bypassed", it could not add the anchor in the getChangedKnuthElement() phase.
Testcase updated with an example of the "hyphenated inline child" case.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@538198 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java
status.xml
test/layoutengine/disabled-testcases.xml
test/layoutengine/hyphenation-testcases/footnote_in_inline.xml

index 91b7270ebe7ad4d39723bfe7558403d6ef8eeb90..849ae08d86b75460848502efb30477ba13a5830c 100644 (file)
@@ -26,19 +26,20 @@ import java.util.ListIterator;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.fop.fo.flow.Footnote;
-import org.apache.fop.layoutmgr.AbstractLayoutManager;
 import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager;
 import org.apache.fop.layoutmgr.InlineKnuthSequence;
 import org.apache.fop.layoutmgr.KnuthElement;
 import org.apache.fop.layoutmgr.KnuthSequence;
 import org.apache.fop.layoutmgr.LayoutContext;
-import org.apache.fop.layoutmgr.Position;
+import org.apache.fop.layoutmgr.LayoutManager;
+import org.apache.fop.layoutmgr.ListElement;
+import org.apache.fop.layoutmgr.NonLeafPosition;
+import org.apache.fop.layoutmgr.PositionIterator;
 
 /**
  * Layout manager for fo:footnote.
  */
-public class FootnoteLayoutManager extends AbstractLayoutManager 
-                                   implements InlineLevelLayoutManager {
+public class FootnoteLayoutManager extends InlineStackingLayoutManager {
 
     /**
      * logging instance
@@ -72,13 +73,10 @@ public class FootnoteLayoutManager extends AbstractLayoutManager
     /** @see org.apache.fop.layoutmgr.LayoutManager */
     public LinkedList getNextKnuthElements(LayoutContext context,
                                            int alignment) {
-        // this is the only method that must be implemented:
-        // all other methods will never be called, as the returned elements
-        // contain Positions created by the citationLM, so its methods will
-        // be called instead
-
-        // set the citationLM parent to be this LM's parent
-        citationLM.setParent(getParent());
+        // for the moment, this LM is set as the citationLM's parent
+        // later on, when this LM will have nothing more to do, the citationLM's parent
+        // will be set to the fotnoteLM's parent
+        citationLM.setParent(this);
         citationLM.initialize();
         bodyLM.setParent(this);
         bodyLM.initialize();
@@ -104,22 +102,82 @@ public class FootnoteLayoutManager extends AbstractLayoutManager
 
         addAnchor(returnedList);
 
+        // "wrap" the Position stored in each list inside returnedList
+        ListIterator listIterator = returnedList.listIterator();
+        ListIterator elementIterator = null;
+        KnuthSequence list = null;
+        ListElement element = null;
+        while (listIterator.hasNext()) {
+            list = (KnuthSequence) listIterator.next();
+            elementIterator = list.listIterator();
+            while (elementIterator.hasNext()) {
+                element = (KnuthElement) elementIterator.next();
+                element.setPosition(notifyPos(new NonLeafPosition(this, element.getPosition())));
+            }
+        }
+
+        return returnedList;
+    }
+
+    /**
+     * @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(java.util.List, int)
+     */
+    public LinkedList getChangedKnuthElements(List oldList,
+                                              int alignment) {
+        LinkedList returnedList = super.getChangedKnuthElements(oldList, alignment);
+        addAnchor(returnedList);
         return returnedList;
     }
 
+
+    /**
+     * @see org.apache.fop.layoutmgr.LayoutManager#addAreas(PositionIterator posIter, LayoutContext context);
+     */
+    public void addAreas(PositionIterator posIter, LayoutContext context) {
+        // "Unwrap" the NonLeafPositions stored in posIter and put
+        // them in a new list, that will be given to the citationLM
+        LinkedList positionList = new LinkedList();
+        NonLeafPosition pos = null;
+        while (posIter.hasNext()) {
+            pos = (NonLeafPosition) posIter.next();
+            if (pos != null && pos.getPosition() != null) {
+                positionList.add(pos.getPosition());
+            }
+        }
+        
+        // FootnoteLM does not create any area, 
+        // so the citationLM child will add directly to the FootnoteLM parent area
+        citationLM.setParent(getParent());
+        
+        // make the citationLM add its areas
+        LayoutContext childContext = new LayoutContext(context);
+        StackingIter childPosIter = new StackingIter(positionList.listIterator());
+        LayoutManager childLM;
+        while ((childLM = childPosIter.getNextChildLM()) != null) {
+            childLM.addAreas(childPosIter, childContext);
+            childContext.setLeadingSpace(childContext.getTrailingSpace());
+            childContext.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
+        }
+    }
+
+    /**
+     * Find the last box in the sequence, and add a reference to the FootnoteBodyLM
+     * @param citationList the list of elements representing the footnote citation
+     */
     private void addAnchor(LinkedList citationList) {
-        // find the last box in the sequence, and add a reference
-        // to the FootnoteBodyLM
         KnuthInlineBox lastBox = null;
+        // the list of elements is searched backwards, until we find a box
         ListIterator citationIterator = citationList.listIterator(citationList.size());
         while (citationIterator.hasPrevious() && lastBox == null) {
             Object obj = citationIterator.previous();
             if (obj instanceof KnuthElement) {
+                // obj is an element
                 KnuthElement element = (KnuthElement)obj;
                 if (element instanceof KnuthInlineBox) {
                     lastBox = (KnuthInlineBox) element;
                 }
             } else {
+                // obj is a sequence of elements
                 KnuthSequence seq = (KnuthSequence)obj;
                 ListIterator nestedIterator = seq.listIterator(seq.size());
                 while (nestedIterator.hasPrevious() && lastBox == null) {
@@ -137,45 +195,4 @@ public class FootnoteLayoutManager extends AbstractLayoutManager
             //throw new IllegalStateException("No anchor box was found for a footnote.");
         }
     }
-
-    /** @see org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager */
-    public List addALetterSpaceTo(List oldList) {
-        log.warn("null implementation of addALetterSpaceTo() called!");
-        return oldList;
-    }
-
-    /**
-     * Remove the word space represented by the given elements
-     *
-     * @param oldList the elements representing the word space
-     */
-    public void removeWordSpace(List oldList) {
-        // do nothing
-        log.warn(this.getClass().getName() + " should not receive a call to removeWordSpace(list)");
-    }
-
-    /** @see org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager */
-    public void getWordChars(StringBuffer sbChars, Position pos) {
-        log.warn("null implementation of getWordChars() called!");
-    }
-
-    /** @see org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager */
-    public void hyphenate(Position pos, HyphContext hc) {
-        log.warn("null implementation of hyphenate called!");
-    }
-
-    /** @see org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager */
-    public boolean applyChanges(List oldList) {
-        log.warn("null implementation of applyChanges() called!");
-        return false;
-    }
-
-    /**
-     * @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(java.util.List, int)
-     */
-    public LinkedList getChangedKnuthElements(List oldList,
-                                              int alignment) {
-        log.warn("null implementation of getChangeKnuthElement() called!");
-        return null;
-    }
 }
index 33f9f514b8d83428f08b848d5ed9129893bb3d54..7078fab7ce9419b2a638f943c96e1372ee106c23 100644 (file)
@@ -28,6 +28,9 @@
 
   <changes>
     <release version="FOP Trunk">
+      <action context="Code" dev="LF" type="fix">
+        Fixed a problem with disappearing footnotes inside hyphenated inlines (and footnotes with hyphenated inline child).
+      </action>
       <action context="Code" dev="JM" type="add" fixes-bug="42067" due-to="Paul Vinkenoog">
         Add support for exact positioning of internal PDF links.
       </action>
index 9767533d220adfaca24ad41701fc33e27f8155ac..d81c0dc27fe5cc2fc0cd873eef4287d7deaf18cc 100644 (file)
     <description>Space resolution does not work between footnote
     regions.</description>
   </testcase>
-  <testcase>
-    <name>Footnotes swallowed in hyphenated fo:inlines</name>
-    <file>footnote_in_inline.xml</file>
-    <description>getChangedKnuthElements probably loses the footnote 
-    layout manager somewhere along the way.</description>
-  </testcase>
   <testcase>
     <name>Footnotes swallowed in lists</name>
     <file>footnote_in_list.xml</file>
index baf0ed73e2d8a6e8748878cf0bf080d3d0380ca4..4f049c791cd191a84af01700becd8142ab633240 100644 (file)
@@ -33,6 +33,7 @@
         <fo:flow flow-name="xsl-region-body" language="en">
           <fo:block>This is a block with a <fo:inline font-style="italic">footnote<fo:footnote><fo:inline font-size="50%" vertical-align="top">1</fo:inline><fo:footnote-body><fo:block><fo:inline font-size="50%" vertical-align="top">1</fo:inline>I'm a footnote!</fo:block></fo:footnote-body></fo:footnote></fo:inline> in it.</fo:block>
           <fo:block hyphenate="true">This is a hyphenated block with a <fo:inline font-style="italic">footnote<fo:footnote><fo:inline font-size="50%" vertical-align="top">2</fo:inline><fo:footnote-body><fo:block><fo:inline font-size="50%" vertical-align="top">2</fo:inline>I'm a footnote!</fo:block></fo:footnote-body></fo:footnote></fo:inline> in it.</fo:block>
+          <fo:block hyphenate="true">This is a hyphenated block with a footnote<fo:footnote><fo:inline font-size="50%" vertical-align="top">hyphenation</fo:inline><fo:footnote-body><fo:block><fo:inline font-size="50%" vertical-align="top">hyphenation</fo:inline>I'm yet another footnote!</fo:block></fo:footnote-body></fo:footnote> in it.</fo:block>
           <fo:block>This is another block without a footnote.</fo:block>
         </fo:flow>
       </fo:page-sequence>
@@ -42,6 +43,6 @@
     <eval expected="1" xpath="count(//pageViewport)"/>
     
     <!-- the footnotes -->
-    <eval expected="2" xpath="count(//pageViewport[1]/page/regionViewport/regionBody/footnote/block)"/>
+    <eval expected="3" xpath="count(//pageViewport[1]/page/regionViewport/regionBody/footnote/block)"/>
   </checks>
 </testcase>