]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Correction to footnotes handling: break a footnote body only if its citation is in...
authorLuca Furini <lfurini@apache.org>
Thu, 19 May 2005 16:41:29 +0000 (16:41 +0000)
committerLuca Furini <lfurini@apache.org>
Thu, 19 May 2005 16:41:29 +0000 (16:41 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198662 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java

index 64ad6f4a31de185fa848b36f9058d941bb9c66da..11e1254751a8f4d488a3545e39ab94f84b6c88ae 100644 (file)
@@ -429,7 +429,7 @@ public abstract class BreakingAlgorithm {
         lastTooShort = lastTooLong = null;
     }
 
-    private void considerLegalBreak(KnuthElement element, int elementIdx) {
+    protected void considerLegalBreak(KnuthElement element, int elementIdx) {
 
         if (log.isTraceEnabled()) {
             log.trace("Feasible breakpoint at " + par.indexOf(element) + " " + totalWidth + "+" + totalStretch + "-" + totalShrink);
index 40fc6cab7cdc7df1dac12c2408dec3f2952ff952..e5ec2fdf140282977b322a036a6d1479e34719e2 100644 (file)
@@ -35,6 +35,16 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
     private int totalFootnotesLength = 0;
     private int insertedFootnotesLength = 0;
     private boolean bPendingFootnotes = false;
+    /**
+     * bNewFootnotes is true if the elements met after the previous break point
+     * contain footnote citations
+     */
+    private boolean bNewFootnotes = false;
+    /**
+     * iNewFootnoteIndex is the index of the first footnote met after the 
+     * previous break point
+     */
+    private int iNewFootnoteIndex = 0;
     private int footnoteListIndex = 0;
     private int footnoteElementIndex = -1;
 
@@ -155,6 +165,10 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
         if (box instanceof KnuthBlockBox
             && ((KnuthBlockBox) box).hasAnchors()) {
             handleFootnotes(((KnuthBlockBox) box).getElementLists());
+            if (!bNewFootnotes) {
+                bNewFootnotes = true;
+                iNewFootnoteIndex = footnotesList.size() - 1;
+            }
         }
     }
 
@@ -188,6 +202,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
 
     protected void restartFrom(KnuthNode restartingNode, int currentIndex) {
         super.restartFrom(restartingNode, currentIndex);
+        bNewFootnotes = false;
         if (bPendingFootnotes) {
             // remove from footnotesList the note lists that will be met
             // after the restarting point
@@ -219,6 +234,11 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
         }
     }
 
+    protected void considerLegalBreak(KnuthElement element, int elementIdx) {
+        super.considerLegalBreak(element, elementIdx);
+        bNewFootnotes = false;
+    }
+
     /**
      * Return the difference between the line width and the width of the break that
      * ends in 'element'.
@@ -229,63 +249,59 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
      */
     protected int computeDifference(KnuthNode activeNode, KnuthElement element) {
         int actualWidth = totalWidth - activeNode.totalWidth;
+        int footnoteSplit;
         if (element.isPenalty()) {
             actualWidth += element.getW();
         }
         if (bPendingFootnotes) {
+            // compute the total length of the footnotes not yet inserted
             int newFootnotes = totalFootnotesLength - ((KnuthPageNode) activeNode).totalFootnotes;
-            // add the footnote separator width if some footnote content will be added
-            if (((KnuthPageNode) activeNode).totalFootnotes < totalFootnotesLength) {
+            if (newFootnotes > 0) {
+                // this page contains some footnote citations
+                // add the footnote separator width
                 actualWidth += footnoteSeparatorLength.opt;
-            }
-            if (actualWidth + newFootnotes <= lineWidth) {
-                // there is enough space to insert all footnotes:
-                // add the whole newFootnotes length
-                actualWidth += newFootnotes;
-                insertedFootnotesLength = ((KnuthPageNode) activeNode).totalFootnotes + newFootnotes;
-                footnoteListIndex = footnotesList.size() - 1;
-                footnoteElementIndex = ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1;
-            } else {
-                // check if there is enough space to insert at least a piece
-                // of the last footnote (and all the previous ones)
-                int footnoteSplit = getFootnoteSplit((KnuthPageNode) activeNode, lineWidth - actualWidth);
-                if (actualWidth + footnoteSplit <= lineWidth) {
-                    // the last footnote will be split
-                    // add more footnote content as possible
+                if (actualWidth + newFootnotes <= lineWidth) {
+                    // there is enough space to insert all footnotes:
+                    // add the whole newFootnotes length
+                    actualWidth += newFootnotes;
+                    insertedFootnotesLength = ((KnuthPageNode) activeNode).totalFootnotes + newFootnotes;
+                    footnoteListIndex = footnotesList.size() - 1;
+                    footnoteElementIndex = ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1;
+                } else if (bNewFootnotes
+                    && (footnoteSplit = getFootnoteSplit((KnuthPageNode) activeNode, lineWidth - actualWidth)) > 0) {
+                    // the last footnote, whose citation is in the last piece of content
+                    // added to the page, will be split:
+                    // add as much footnote content as possible
                     actualWidth += footnoteSplit;
                     insertedFootnotesLength = ((KnuthPageNode) activeNode).totalFootnotes + footnoteSplit;
                     footnoteListIndex = footnotesList.size() - 1;
                     // footnoteElementIndex has been set in getFootnoteSplit()
                 } else {
-                    // there is no space to add the smallest piece of the last footnote:
+                    // there is no space to add the smallest piece of the last footnote,
+                    // or we are trying to add a piece of content with no footnotes and
+                    // it does not fit in the page, because of the previous footnote bodies
+                    // that cannot be broken:
                     // add the whole newFootnotes length, so this breakpoint will be discarded
                     actualWidth += newFootnotes;
                     insertedFootnotesLength = ((KnuthPageNode) activeNode).totalFootnotes + newFootnotes;
                     footnoteListIndex = footnotesList.size() - 1;
                     footnoteElementIndex = ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1;
                 }
+            } else {
+                // all footnotes have already been placed on previous pages
             }
+        } else {
+            // there are no footnotes
         }
         return lineWidth - actualWidth;
     }
 
     private int getFootnoteSplit(KnuthPageNode activeNode, int availableLength) {
-        // length of all the not-yet-inserted footnotes
-        int newFootnotes = totalFootnotesLength - activeNode.totalFootnotes;
         if (availableLength <= 0) {
-            return newFootnotes;
+            return 0;
         } else {
             // the split must contain a piece of the last footnote
             // together with all previous, not yet inserted footnotes
-            int firstFootnoteIndex = activeNode.footnoteListIndex;
-            int firstElementIndex = activeNode.footnoteElementIndex;
-            if (firstElementIndex == ((LinkedList) footnotesList.get(firstFootnoteIndex)).size() - 1) {
-                // advance to the next list
-                firstFootnoteIndex ++;
-                firstElementIndex = 0;
-            } else {
-                firstElementIndex ++;
-            }
             int splitLength = 0;
             ListIterator noteListIterator = null;
             KnuthElement element = null;
@@ -343,10 +359,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
             // and insert the remaining in the following one
             if (prevSplitLength > 0 ) {
                 footnoteElementIndex = prevIndex;
-                return prevSplitLength;
-            } else {
-                return newFootnotes;
             }
+            return prevSplitLength;
         }
     }
 
@@ -428,9 +442,6 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
             } else if (footnoteElementIndex < ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1) {
                 // add demerits for the footnote split between pages
                 demerits += splitFootnoteDemerits;
-            } else {
-                // reduce demerits when all footnotes are inserted in the page where their citations are
-               demerits /= 2;
             }
         }
         demerits += activeNode.totalDemerits;
@@ -538,4 +549,4 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
     public LinkedList getFootnoteList(int index) {
         return (LinkedList) footnotesList.get(index);
     }
-}
\ No newline at end of file
+}