Index: src/java/org/apache/fop/layoutmgr/ElementListUtils.java =================================================================== --- src/java/org/apache/fop/layoutmgr/ElementListUtils.java (revision 651860) +++ src/java/org/apache/fop/layoutmgr/ElementListUtils.java (working copy) @@ -224,5 +224,51 @@ } return prevBreak; } + + /** + * Scan element lists and collect footnotes information. + * @param elementLists the array of element lists + * @param start the array of start indices + * @param end the array of end indices + * @return the list of FootnoteBodyLMs met, or null if there is none + */ + public static LinkedList collectFootnoteBodyLMs(List[] elementLists, int[] start, int[] end) { + LinkedList footnoteList = new LinkedList(); + LinkedList tmpList; + for (int i = 0; i < elementLists.length; i ++) { + if (elementLists[i] != null) { + tmpList = collectFootnoteBodyLMs( + elementLists[i], start[i], end[i]); + if (tmpList != null) { + footnoteList.addAll(tmpList); + } + } + } + + return footnoteList.size() > 0 ? footnoteList : null; + } + + /** + * Scan a single element list and collect footnotes information. + * @param elementList the element list (should not be null) + * @param start the start index + * @param end the end index + * @return the list of FootnoteBodyLMs met, or null if there is none + */ + public static LinkedList collectFootnoteBodyLMs(List elementList, int start, int end) { + + assert (elementList != null); + LinkedList footnoteList = new LinkedList(); + + for (int j = start; j <= end; j ++) { + ListElement element = (ListElement) elementList.get(j); + if (element instanceof KnuthBlockBox + && ((KnuthBlockBox) element).hasAnchors()) { + footnoteList.addAll(((KnuthBlockBox) element).getFootnoteBodyLMs()); + } + } + return footnoteList.size() > 0 ? footnoteList : null; + } + } Index: src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java (revision 651867) +++ src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java (working copy) @@ -39,6 +39,7 @@ import org.apache.fop.layoutmgr.ElementListObserver; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.KeepUtil; +import org.apache.fop.layoutmgr.KnuthBlockBox; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthPenalty; @@ -312,11 +313,18 @@ int boxHeight = step - addedBoxHeight - penaltyHeight; penaltyHeight += additionalPenaltyHeight; //Add AFTER calculating boxHeight! + // collect footnote information + LinkedList footnoteList = ElementListUtils.collectFootnoteBodyLMs(elementLists, start, end); + // add the new elements addedBoxHeight += boxHeight; - ListItemPosition stepPosition = new ListItemPosition(this, + ListItemPosition stepPosition = new ListItemPosition(this, start[0], end[0], start[1], end[1]); - returnList.add(new KnuthBox(boxHeight, stepPosition, false)); + if (footnoteList == null) { + returnList.add(new KnuthBox(boxHeight, stepPosition, false)); + } else { + returnList.add(new KnuthBlockBox(boxHeight, footnoteList, stepPosition, false)); + } if (addedBoxHeight < totalHeight) { int strength = BlockLevelLayoutManager.KEEP_AUTO; strength = Math.max(strength, keepWithNextActive); Index: src/java/org/apache/fop/layoutmgr/table/ActiveCell.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/ActiveCell.java (revision 651860) +++ src/java/org/apache/fop/layoutmgr/table/ActiveCell.java (working copy) @@ -542,6 +542,13 @@ return keepWithNextStrength; } + /** + * Return the list of elements representing the content of this cell. + * @return the list of elements + */ + public List getElementList(){ + return elementList; + } /** {@inheritDoc} */ public String toString() { Index: src/java/org/apache/fop/layoutmgr/table/CellPart.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/CellPart.java (revision 651860) +++ src/java/org/apache/fop/layoutmgr/table/CellPart.java (working copy) @@ -116,6 +116,22 @@ return condAfterContentLength; } + /** + * Return the index of the first element in this cell part. + * @return the start index + */ + public int getStartIndex() { + return start; + } + + /** + * Return the index of the last element in this cell part. + * @return the end index + */ + public int getEndIndex() { + return end; + } + /** {@inheritDoc} */ public String toString() { StringBuffer sb = new StringBuffer("Part: "); Index: src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java (revision 651860) +++ src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java (working copy) @@ -39,6 +39,7 @@ import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.KeepUtil; +import org.apache.fop.layoutmgr.KnuthBlockBox; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthPossPosIter; @@ -146,7 +147,14 @@ } TableHeaderFooterPosition pos = new TableHeaderFooterPosition( getTableLM(), true, this.headerList); - KnuthBox box = new KnuthBox(headerNetHeight, pos, false); + // collect footnote information + LinkedList footnoteList = ElementListUtils.collectFootnoteBodyLMs(headerList, 0, headerList.size() - 1); + KnuthBox box = null; + if (footnoteList == null) { + box = new KnuthBox(headerNetHeight, pos, false); + } else { + box = new KnuthBlockBox(headerNetHeight, footnoteList, pos, false); + } if (getTableLM().getTable().omitHeaderAtBreak()) { //We can simply add the table header at the start //of the whole list @@ -167,7 +175,14 @@ //We can simply add the table footer at the end of the whole list TableHeaderFooterPosition pos = new TableHeaderFooterPosition( getTableLM(), false, this.footerList); - KnuthBox box = new KnuthBox(footerNetHeight, pos, false); + // collect footnote information + LinkedList footnoteList = ElementListUtils.collectFootnoteBodyLMs(footerList, 0, footerList.size() - 1); + KnuthBox box = null; + if (footnoteList == null) { + box = new KnuthBox(footerNetHeight, pos, false); + } else { + box = new KnuthBlockBox(footerNetHeight, footnoteList, pos, false); + } footerAsLast = box; } LinkedList returnList = getKnuthElementsForRowIterator( Index: src/java/org/apache/fop/layoutmgr/table/TableStepper.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/TableStepper.java (revision 651860) +++ src/java/org/apache/fop/layoutmgr/table/TableStepper.java (working copy) @@ -32,7 +32,9 @@ import org.apache.fop.fo.flow.table.PrimaryGridUnit; import org.apache.fop.layoutmgr.BlockLevelLayoutManager; import org.apache.fop.layoutmgr.BreakElement; +import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.KeepUtil; +import org.apache.fop.layoutmgr.KnuthBlockBox; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; @@ -226,8 +228,26 @@ tcpos.setFlag(TableContentPosition.FIRST_IN_ROWGROUP, true); } lastTCPos = tcpos; - returnList.add(new KnuthBox(boxLen, tcpos, false)); + // collect footnote information + int tmpSize = activeCells.size(); + List[] elementLists = new LinkedList[tmpSize]; + int[] start = new int[tmpSize]; + int[] end = new int[tmpSize]; + for (int i = 0; i < tmpSize; i++) { + elementLists[i] = ((ActiveCell) activeCells.get(i)).getElementList(); + CellPart part = (CellPart) cellParts.get(i); + start[i] = part.getStartIndex(); + end[i] = part.getEndIndex(); + } + LinkedList footnoteList = ElementListUtils.collectFootnoteBodyLMs(elementLists, start, end); + + if (footnoteList == null) { + returnList.add(new KnuthBox(boxLen, tcpos, false)); + } else { + returnList.add(new KnuthBlockBox(boxLen, footnoteList, tcpos, false)); + } + int effPenaltyLen = Math.max(0, penaltyOrGlueLen); TableHFPenaltyPosition penaltyPos = new TableHFPenaltyPosition(getTableLM()); if (bodyType == TableRowIterator.BODY) { Index: test/layoutengine/disabled-testcases.xml =================================================================== --- test/layoutengine/disabled-testcases.xml (revision 651860) +++ test/layoutengine/disabled-testcases.xml (working copy) @@ -97,7 +97,7 @@ Space resolution does not work between footnote regions. - + NPE for table inside an inline inline_block_nested_3.xml