diff options
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java | 125 | ||||
-rw-r--r-- | status.xml | 3 | ||||
-rw-r--r-- | test/layoutengine/disabled-testcases.xml | 6 | ||||
-rw-r--r-- | test/layoutengine/hyphenation-testcases/footnote_in_inline.xml | 3 |
4 files changed, 76 insertions, 61 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java index 91b7270eb..849ae08d8 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java @@ -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; - } } diff --git a/status.xml b/status.xml index 33f9f514b..7078fab7c 100644 --- a/status.xml +++ b/status.xml @@ -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> diff --git a/test/layoutengine/disabled-testcases.xml b/test/layoutengine/disabled-testcases.xml index 9767533d2..d81c0dc27 100644 --- a/test/layoutengine/disabled-testcases.xml +++ b/test/layoutengine/disabled-testcases.xml @@ -105,12 +105,6 @@ 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> <description>Element lists for lists are created by combining the diff --git a/test/layoutengine/hyphenation-testcases/footnote_in_inline.xml b/test/layoutengine/hyphenation-testcases/footnote_in_inline.xml index baf0ed73e..4f049c791 100644 --- a/test/layoutengine/hyphenation-testcases/footnote_in_inline.xml +++ b/test/layoutengine/hyphenation-testcases/footnote_in_inline.xml @@ -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> |