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 vh...@apache.org on 2013/10/08 13:29:05 UTC
svn commit: r1530232 - in /xmlgraphics/fop/trunk:
src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
test/layoutengine/standard-testcases/footnote_jira2106.xml
Author: vhennebert
Date: Tue Oct 8 11:29:05 2013
New Revision: 1530232
URL: http://svn.apache.org/r1530232
Log:
FOP-2106: Footnote put on earlier page than the one that contains the footnote call
Patch by Alexey Neyman, committed with minor modifications
Added:
xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/footnote_jira2106.xml (with props)
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java?rev=1530232&r1=1530231&r2=1530232&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java Tue Oct 8 11:29:05 2013
@@ -140,7 +140,10 @@ class PageBreakingAlgorithm extends Brea
*/
protected class KnuthPageNode extends KnuthNode {
- /** Additional length due to footnotes. */
+ /** Additional length due to already inserted footnotes. */
+ public int insertedFootnotes;
+
+ /** Total length of the footnotes. */
public int totalFootnotes;
/** Index of the last inserted footnote. */
@@ -152,7 +155,8 @@ class PageBreakingAlgorithm extends Brea
public KnuthPageNode(int position,
int line, int fitness,
int totalWidth, int totalStretch, int totalShrink,
- int totalFootnotes, int footnoteListIndex, int footnoteElementIndex,
+ int insertedFootnotes, int totalFootnotes,
+ int footnoteListIndex, int footnoteElementIndex,
double adjustRatio, int availableShrink, int availableStretch,
int difference, double totalDemerits, KnuthNode previous) {
super(position, line, fitness,
@@ -160,6 +164,7 @@ class PageBreakingAlgorithm extends Brea
adjustRatio, availableShrink, availableStretch,
difference, totalDemerits, previous);
this.totalFootnotes = totalFootnotes;
+ this.insertedFootnotes = insertedFootnotes;
this.footnoteListIndex = footnoteListIndex;
this.footnoteElementIndex = footnoteElementIndex;
}
@@ -172,7 +177,8 @@ class PageBreakingAlgorithm extends Brea
*/
protected class BestPageRecords extends BestRecords {
- private int[] bestFootnotesLength = new int[4];
+ private int[] bestInsertedFootnotesLength = new int[4];
+ private int[] bestTotalFootnotesLength = new int[4];
private int[] bestFootnoteListIndex = new int[4];
private int[] bestFootnoteElementIndex = new int[4];
@@ -182,13 +188,18 @@ class PageBreakingAlgorithm extends Brea
super.addRecord(demerits, node, adjust,
availableShrink, availableStretch,
difference, fitness);
- bestFootnotesLength[fitness] = insertedFootnotesLength;
+ bestInsertedFootnotesLength[fitness] = insertedFootnotesLength;
+ bestTotalFootnotesLength[fitness] = totalFootnotesLength;
bestFootnoteListIndex[fitness] = footnoteListIndex;
bestFootnoteElementIndex[fitness] = footnoteElementIndex;
}
- public int getFootnotesLength(int fitness) {
- return bestFootnotesLength[fitness];
+ public int getInsertedFootnotesLength(int fitness) {
+ return bestInsertedFootnotesLength[fitness];
+ }
+
+ public int getTotalFootnotesLength(int fitness) {
+ return bestTotalFootnotesLength[fitness];
}
public int getFootnoteListIndex(int fitness) {
@@ -287,7 +298,8 @@ class PageBreakingAlgorithm extends Brea
int difference, double totalDemerits, KnuthNode previous) {
return new KnuthPageNode(position, line, fitness,
totalWidth, totalStretch, totalShrink,
- insertedFootnotesLength, footnoteListIndex, footnoteElementIndex,
+ insertedFootnotesLength, totalFootnotesLength,
+ footnoteListIndex, footnoteElementIndex,
adjustRatio, availableShrink, availableStretch,
difference, totalDemerits, previous);
}
@@ -298,7 +310,8 @@ class PageBreakingAlgorithm extends Brea
int totalWidth, int totalStretch, int totalShrink) {
return new KnuthPageNode(position, line, fitness,
totalWidth, totalStretch, totalShrink,
- ((BestPageRecords) best).getFootnotesLength(fitness),
+ ((BestPageRecords) best).getInsertedFootnotesLength(fitness),
+ ((BestPageRecords) best).getTotalFootnotesLength(fitness),
((BestPageRecords) best).getFootnoteListIndex(fitness),
((BestPageRecords) best).getFootnoteElementIndex(fitness),
best.getAdjust(fitness), best.getAvailableShrink(fitness),
@@ -405,6 +418,12 @@ class PageBreakingAlgorithm extends Brea
resetFootnotes(((KnuthBlockBox) resetElement).getElementLists());
}
}
+ assert restartingNode instanceof KnuthPageNode;
+ KnuthPageNode restartingPageNode = (KnuthPageNode) restartingNode;
+ footnoteElementIndex = restartingPageNode.footnoteElementIndex;
+ footnoteListIndex = restartingPageNode.footnoteListIndex;
+ totalFootnotesLength = restartingPageNode.totalFootnotes;
+ insertedFootnotesLength = restartingPageNode.insertedFootnotes;
}
return returnValue;
}
@@ -413,13 +432,6 @@ class PageBreakingAlgorithm extends Brea
for (int i = 0; i < elementLists.size(); i++) {
ListUtil.removeLast(footnotesList);
ListUtil.removeLast(lengthList);
-
- // update totalFootnotesLength
- if (!lengthList.isEmpty()) {
- totalFootnotesLength = ListUtil.getLast(lengthList);
- } else {
- totalFootnotesLength = 0;
- }
}
// update footnotesPending;
if (footnotesList.size() == 0) {
@@ -502,7 +514,7 @@ class PageBreakingAlgorithm extends Brea
}
if (footnotesPending) {
// compute the total length of the footnotes not yet inserted
- int allFootnotes = totalFootnotesLength - pageNode.totalFootnotes;
+ int allFootnotes = totalFootnotesLength - pageNode.insertedFootnotes;
if (allFootnotes > 0) {
// this page contains some footnote citations
// add the footnote separator width
@@ -511,7 +523,7 @@ class PageBreakingAlgorithm extends Brea
// there is enough space to insert all footnotes:
// add the whole allFootnotes length
actualWidth += allFootnotes;
- insertedFootnotesLength = pageNode.totalFootnotes + allFootnotes;
+ insertedFootnotesLength = pageNode.insertedFootnotes + allFootnotes;
footnoteListIndex = footnotesList.size() - 1;
footnoteElementIndex
= getFootnoteList(footnoteListIndex).size() - 1;
@@ -528,7 +540,7 @@ class PageBreakingAlgorithm extends Brea
// this is the first feasible break; in this case it is allowed
// to break and defer, if necessary, old and new footnotes
actualWidth += footnoteSplit;
- insertedFootnotesLength = pageNode.totalFootnotes + footnoteSplit;
+ insertedFootnotesLength = pageNode.insertedFootnotes + footnoteSplit;
// footnoteListIndex has been set in getFootnoteSplit()
// footnoteElementIndex has been set in getFootnoteSplit()
} else {
@@ -538,7 +550,7 @@ class PageBreakingAlgorithm extends Brea
// that cannot be broken:
// add the whole allFootnotes length, so this breakpoint will be discarded
actualWidth += allFootnotes;
- insertedFootnotesLength = pageNode.totalFootnotes + allFootnotes;
+ insertedFootnotesLength = pageNode.insertedFootnotes + allFootnotes;
footnoteListIndex = footnotesList.size() - 1;
footnoteElementIndex
= getFootnoteList(footnoteListIndex).size() - 1;
@@ -569,7 +581,7 @@ class PageBreakingAlgorithm extends Brea
private boolean canDeferOldFootnotes(KnuthPageNode node, int contentElementIndex) {
return (noBreakBetween(node.position, contentElementIndex)
&& deferredFootnotes(node.footnoteListIndex,
- node.footnoteElementIndex, node.totalFootnotes));
+ node.footnoteElementIndex, node.insertedFootnotes));
}
/**
@@ -649,7 +661,7 @@ class PageBreakingAlgorithm extends Brea
boolean canDeferOldFootnotes) {
return getFootnoteSplit(activeNode.footnoteListIndex,
activeNode.footnoteElementIndex,
- activeNode.totalFootnotes,
+ activeNode.insertedFootnotes,
availableLength, canDeferOldFootnotes);
}
@@ -714,10 +726,8 @@ class PageBreakingAlgorithm extends Brea
int prevIndex = -1;
int index = -1;
- while (!(somethingAdded && splitLength > availableLength)) {
- if (!somethingAdded) {
- somethingAdded = true;
- } else {
+ while (splitLength <= availableLength) {
+ if (somethingAdded) {
prevSplitLength = splitLength;
prevIndex = index;
}
@@ -733,6 +743,10 @@ class PageBreakingAlgorithm extends Brea
// element is a box
splitLength += element.getWidth();
boxPreceding = true;
+ if (splitLength > prevSplitLength) {
+ // and it is non-empty
+ somethingAdded = true;
+ }
} else if (element.isGlue()) {
// element is a glue
if (boxPreceding) {
@@ -749,6 +763,7 @@ class PageBreakingAlgorithm extends Brea
index = noteListIterator.previousIndex();
break;
}
+ boxPreceding = false;
}
}
}
@@ -758,7 +773,6 @@ class PageBreakingAlgorithm extends Brea
// page here
// if prevSplitLength is > 0 we can insert some footnote content in this page
// and insert the remaining in the following one
- //TODO: check this conditional, as the first one is always false...?
if (!somethingAdded) {
// there was not enough space to add a piece of the first new footnote
// this is not a good break
@@ -781,7 +795,7 @@ class PageBreakingAlgorithm extends Brea
if (difference > 0) {
int maxAdjustment = totalStretch - activeNode.totalStretch;
// add the footnote separator stretch if some footnote content will be added
- if (((KnuthPageNode) activeNode).totalFootnotes < totalFootnotesLength) {
+ if (((KnuthPageNode) activeNode).insertedFootnotes < totalFootnotesLength) {
maxAdjustment += footnoteSeparatorLength.getStretch();
}
if (maxAdjustment > 0) {
@@ -792,7 +806,7 @@ class PageBreakingAlgorithm extends Brea
} else if (difference < 0) {
int maxAdjustment = totalShrink - activeNode.totalShrink;
// add the footnote separator shrink if some footnote content will be added
- if (((KnuthPageNode) activeNode).totalFootnotes < totalFootnotesLength) {
+ if (((KnuthPageNode) activeNode).insertedFootnotes < totalFootnotesLength) {
maxAdjustment += footnoteSeparatorLength.getShrink();
}
if (maxAdjustment > 0) {
@@ -866,7 +880,7 @@ class PageBreakingAlgorithm extends Brea
for (KnuthPageNode node = (KnuthPageNode) getNode(i);
node != null;
node = (KnuthPageNode) node.next) {
- if (node.totalFootnotes < totalFootnotesLength) {
+ if (node.insertedFootnotes < totalFootnotesLength) {
// layout remaining footnote bodies
createFootnotePages(node);
}
@@ -876,7 +890,7 @@ class PageBreakingAlgorithm extends Brea
private void createFootnotePages(KnuthPageNode lastNode) {
- insertedFootnotesLength = lastNode.totalFootnotes;
+ insertedFootnotesLength = lastNode.insertedFootnotes;
footnoteListIndex = lastNode.footnoteListIndex;
footnoteElementIndex = lastNode.footnoteElementIndex;
int availableBPD = getLineWidth(lastNode.line);
@@ -902,7 +916,7 @@ class PageBreakingAlgorithm extends Brea
// cannot add any content: create a new node and start again
KnuthPageNode node = (KnuthPageNode)
createNode(lastNode.position, prevNode.line + 1, 1,
- insertedFootnotesLength - prevNode.totalFootnotes,
+ insertedFootnotesLength - prevNode.insertedFootnotes,
0, 0,
0, 0, 0,
0, 0, prevNode);
@@ -916,7 +930,7 @@ class PageBreakingAlgorithm extends Brea
// create the last node
KnuthPageNode node = (KnuthPageNode)
createNode(lastNode.position, prevNode.line + 1, 1,
- totalFootnotesLength - prevNode.totalFootnotes, 0, 0,
+ totalFootnotesLength - prevNode.insertedFootnotes, 0, 0,
0, 0, 0,
0, 0, prevNode);
addNode(node.line, node);
Added: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/footnote_jira2106.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/footnote_jira2106.xml?rev=1530232&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/footnote_jira2106.xml (added)
+++ xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/footnote_jira2106.xml Tue Oct 8 11:29:05 2013
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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$ -->
+<testcase>
+ <info>
+ <p>
+ Test for FOP-2106: footnote must be positioned on the same page as the inline reference (not
+ on the page before).
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-size="10pt">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="body" page-width="100pt" page-height="35pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="body">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Page 1 line 1</fo:block>
+ <fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Page 1 line 2</fo:block>
+ <fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Page 2 line 1</fo:block>
+ <fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Page 3 line
+ 1<fo:footnote><fo:inline>*</fo:inline><fo:footnote-body><fo:block
+ font-size="6pt">Footnote should be on page
+ 3</fo:block></fo:footnote-body></fo:footnote></fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <!-- The block with footnote reference is on page 3 -->
+ <eval expected="Page 3 line 1" xpath="//pageViewport[3]//mainReference//text"/>
+ <!-- ... and so is the footnote itself -->
+ <eval expected="Footnote" xpath="//pageViewport[3]//footnote//word[1]"/>
+ </checks>
+</testcase>
Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/footnote_jira2106.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/footnote_jira2106.xml
------------------------------------------------------------------------------
svn:keywords = Revision Id
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org