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 je...@apache.org on 2006/08/04 17:13:55 UTC

svn commit: r428750 - in /xmlgraphics/fop/trunk: ./ src/java/org/apache/fop/layoutmgr/ test/layoutengine/standard-testcases/

Author: jeremias
Date: Fri Aug  4 08:13:53 2006
New Revision: 428750

URL: http://svn.apache.org/viewvc?rev=428750&view=rev
Log:
Bugzilla #39840:
Changed the way overflowing pages are handled. The overflow property on region-body is now used to define the behaviour. It removes the "Some content could not fit..." exception that bugged so many. However, the change does not yet change any keep behaviour.

Added:
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_keep-together_overflow_1.xml   (with props)
Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
    xmlgraphics/fop/trunk/status.xml

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java?rev=428750&r1=428749&r2=428750&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java Fri Aug  4 08:13:53 2006
@@ -196,6 +196,15 @@
         return null;
     }
     
+    /**
+     * Returns a PageBreakingLayoutListener for the PageBreakingAlgorithm to notify about layout
+     * problems.
+     * @return the listener instance or null if no notifications are needed
+     */
+    protected PageBreakingAlgorithm.PageBreakingLayoutListener getLayoutListener() {
+        return null;
+    }
+    
     /*
      * This method is to contain the logic to determine the LM's
      * getNextKnuthElements() implementation(s) that are to be called. 
@@ -310,7 +319,7 @@
                 log.debug("PLM> start of algorithm (" + this.getClass().getName() 
                         + "), flow BPD =" + flowBPD);
                 PageBreakingAlgorithm alg = new PageBreakingAlgorithm(getTopLevelLM(),
-                        getPageProvider(),
+                        getPageProvider(), getLayoutListener(),
                         alignment, alignmentLast, footnoteSeparatorLength,
                         isPartOverflowRecoveryActivated(), autoHeight, isSinglePartFavored());
                 int iOptPageCount;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java?rev=428750&r1=428749&r2=428750&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java Fri Aug  4 08:13:53 2006
@@ -21,6 +21,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener;
 import org.apache.fop.traits.MinOptMax;
 
 /**
@@ -37,11 +38,13 @@
     
     public BalancingColumnBreakingAlgorithm(LayoutManager topLevelLM,
             PageSequenceLayoutManager.PageProvider pageProvider,
+            PageBreakingLayoutListener layoutListener,
             int alignment, int alignmentLast,
             MinOptMax footnoteSeparatorLength,
             boolean partOverflowRecovery,
             int columnCount) {
-        super(topLevelLM, pageProvider, alignment, alignmentLast, 
+        super(topLevelLM, pageProvider, layoutListener,
+                alignment, alignmentLast, 
                 footnoteSeparatorLength, partOverflowRecovery, false, false);
         this.columnCount = columnCount;
         this.considerTooShort = true; //This is important!

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java?rev=428750&r1=428749&r2=428750&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java Fri Aug  4 08:13:53 2006
@@ -50,7 +50,7 @@
     /** Maximum adjustment ration */
     protected static final int INFINITE_RATIO = 1000;
 
-    private static final int MAX_RECOVERY_ATTEMPTS = 50;
+    private static final int MAX_RECOVERY_ATTEMPTS = 5;
 
     // constants identifying a subset of the feasible breaks
     /** All feasible breaks are ok. */
@@ -156,6 +156,7 @@
 
     /** @see #isPartOverflowRecoveryActivated() */
     private boolean partOverflowRecoveryActivated = true;
+    private KnuthNode lastRecovered;
 
     /**
      * Create a new instance.
@@ -495,6 +496,12 @@
                 }
                 if (lastTooShort == null || lastForced.position == lastTooShort.position) {
                     if (isPartOverflowRecoveryActivated()) {
+                        if (this.lastRecovered == null) {
+                            this.lastRecovered = lastTooLong;
+                            if (log.isDebugEnabled()) {
+                                log.debug("Recovery point: " + lastRecovered);
+                            }
+                        }
                         // content would overflow, insert empty line/page and try again
                         KnuthNode node = createNode(
                                 lastTooLong.previous.position, lastTooLong.previous.line + 1, 1,
@@ -503,23 +510,34 @@
                                 0, 0, lastTooLong.previous);
                         lastForced = node;
                         node.fitRecoveryCounter = lastTooLong.previous.fitRecoveryCounter + 1;
-                        log.debug("first part doesn't fit into line, recovering: " 
-                                + node.fitRecoveryCounter);
+                        if (log.isDebugEnabled()) {
+                            log.debug("first part doesn't fit into line, recovering: " 
+                                    + node.fitRecoveryCounter);
+                        }
                         if (node.fitRecoveryCounter > getMaxRecoveryAttempts()) {
-                            FONode contextFO = findContextFO(par, node.position + 1);
-                            throw new RuntimeException(FONode.decorateWithContextInfo(
-                                    "Some content could not fit "
-                                    + "into a line/page after " + getMaxRecoveryAttempts() 
-                                    + " attempts. Giving up to avoid an endless loop.", contextFO));
+                            while (lastForced.fitRecoveryCounter > 0) {
+                                lastForced = lastForced.previous;
+                                lastDeactivated = lastForced.previous;
+                                startLine--;
+                                endLine--;
+                            }
+                            lastForced = this.lastRecovered;
+                            this.lastRecovered = null;
+                            startLine = lastForced.line;
+                            endLine = lastForced.line;
+                            log.debug("rolled back...");
                         }
                     } else {
                         lastForced = lastTooLong;
                     }
                 } else {
                     lastForced = lastTooShort;
+                    this.lastRecovered = null;
                 }
 
-                log.debug("Restarting at node " + lastForced);
+                if (log.isDebugEnabled()) {
+                    log.debug("Restarting at node " + lastForced);
+                }
                 i = restartFrom(lastForced, i);
             }
         }

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=428750&r1=428749&r2=428750&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 Fri Aug  4 08:13:53 2006
@@ -39,6 +39,7 @@
 
     private LayoutManager topLevelLM;
     private PageSequenceLayoutManager.PageProvider pageProvider;
+    private PageBreakingLayoutListener layoutListener;
     /** List of PageBreakPosition elements. */
     private LinkedList pageBreaks = null;
 
@@ -94,6 +95,7 @@
     
     public PageBreakingAlgorithm(LayoutManager topLevelLM,
                                  PageSequenceLayoutManager.PageProvider pageProvider,
+                                 PageBreakingLayoutListener layoutListener,
                                  int alignment, int alignmentLast,
                                  MinOptMax footnoteSeparatorLength,
                                  boolean partOverflowRecovery, boolean autoHeight,
@@ -102,6 +104,7 @@
         this.log = classLog;
         this.topLevelLM = topLevelLM;
         this.pageProvider = pageProvider;
+        this.layoutListener = layoutListener;
         best = new BestPageRecords();
         this.footnoteSeparatorLength = (MinOptMax) footnoteSeparatorLength.clone();
         // add some stretch, to avoid a restart for every page containing footnotes
@@ -746,11 +749,15 @@
         //      ? bestActiveNode.difference : bestActiveNode.difference + fillerMinWidth;
         int difference = bestActiveNode.difference;
         if (difference + bestActiveNode.availableShrink < 0) {
-            if (!autoHeight && log.isWarnEnabled()) {
-                log.warn(FONode.decorateWithContextInfo(
-                        "Part/page " + (getPartCount() + 1) 
-                        + " overflows the available area in block-progression dimension.", 
-                        getFObj()));
+            if (!autoHeight) {
+                if (layoutListener != null) {
+                    layoutListener.notifyOverflow(bestActiveNode.line - 1, getFObj());
+                } else if (log.isWarnEnabled()) {
+                    log.warn(FONode.decorateWithContextInfo(
+                            "Part/page " + (bestActiveNode.line - 1) 
+                            + " overflows the available area in block-progression dimension.", 
+                            getFObj()));
+                }
             }
         }
         boolean isNonLastPage = (bestActiveNode.line < total);
@@ -850,6 +857,20 @@
             log.trace("getLineWidth(" + line + ") -> " + bpd);
         }
         return bpd;
+    }
+    
+    /**
+     * Interface to notify about layout events during page breaking.
+     */
+    public interface PageBreakingLayoutListener {
+
+        /**
+         * Issued when an overflow is detected
+         * @param part the number of the part (page) this happens on
+         * @param obj the root FO object where this happens
+         */
+        void notifyOverflow(int part, FObj obj);
+        
     }
     
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java?rev=428750&r1=428749&r2=428750&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java Fri Aug  4 08:13:53 2006
@@ -33,6 +33,8 @@
 import org.apache.fop.area.Resolvable;
 
 import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.flow.Marker;
 import org.apache.fop.fo.flow.RetrieveMarker;
 
@@ -43,6 +45,7 @@
 import org.apache.fop.fo.pagination.SideRegion;
 import org.apache.fop.fo.pagination.SimplePageMaster;
 import org.apache.fop.fo.pagination.StaticContent;
+import org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener;
 import org.apache.fop.layoutmgr.inline.ContentLayoutManager;
 
 import org.apache.fop.traits.MinOptMax;
@@ -192,8 +195,9 @@
             context.setRefIPD(flowIPD);
         }
         
+        /** @see org.apache.fop.layoutmgr.AbstractBreaker#getTopLevelLM() */
         protected LayoutManager getTopLevelLM() {
-            return null;  // unneeded for PSLM
+            return pslm;
         }
         
         /** @see org.apache.fop.layoutmgr.AbstractBreaker#getPageProvider() */
@@ -201,6 +205,32 @@
             return pageProvider;
         }
         
+        /**
+         * @see org.apache.fop.layoutmgr.AbstractBreaker#getLayoutListener()
+         */
+        protected PageBreakingLayoutListener getLayoutListener() {
+            return new PageBreakingLayoutListener() {
+
+                public void notifyOverflow(int part, FObj obj) {
+                    Page p = pageProvider.getPage(
+                                false, part, PageProvider.RELTO_CURRENT_ELEMENT_LIST);
+                    RegionBody body = (RegionBody)p.getSimplePageMaster().getRegion(
+                            Region.FO_REGION_BODY);
+                    String err = FONode.decorateWithContextInfo(
+                            "Content of the region-body on page " 
+                            + p.getPageViewport().getPageNumberString() 
+                            + " overflows the available area in block-progression dimension.", 
+                            obj);
+                    if (body.getOverflow() == Constants.EN_ERROR_IF_OVERFLOW) {
+                        throw new RuntimeException(err);
+                    } else {
+                        PageSequenceLayoutManager.log.warn(err);
+                    }
+                }
+                
+            };
+        }
+
         /** @see org.apache.fop.layoutmgr.AbstractBreaker */
         protected int handleSpanChange(LayoutContext childLC, int nextSequenceStartsOn) {
             needColumnBalancing = false;
@@ -373,7 +403,7 @@
             //Restart last page
             PageBreakingAlgorithm algRestart = new PageBreakingAlgorithm(
                     getTopLevelLM(),
-                    getPageProvider(),
+                    getPageProvider(), getLayoutListener(),
                     alg.getAlignment(), alg.getAlignmentLast(), 
                     footnoteSeparatorLength,
                     isPartOverflowRecoveryActivated(), false, false);
@@ -433,7 +463,7 @@
             //Restart last page
             PageBreakingAlgorithm algRestart = new BalancingColumnBreakingAlgorithm(
                     getTopLevelLM(),
-                    getPageProvider(),
+                    getPageProvider(), getLayoutListener(),
                     alignment, Constants.EN_START, footnoteSeparatorLength,
                     isPartOverflowRecoveryActivated(),
                     getCurrentPV().getBodyRegion().getColumnCount());

Modified: xmlgraphics/fop/trunk/status.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/status.xml?rev=428750&r1=428749&r2=428750&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/status.xml (original)
+++ xmlgraphics/fop/trunk/status.xml Fri Aug  4 08:13:53 2006
@@ -28,6 +28,10 @@
 
   <changes>
     <release version="FOP Trunk">
+      <action context="Code" dev="JM" type="update">
+        Changed the way overflowing pages are handled. The overflow property on region-body
+        is now used to define the behaviour.
+      </action>
       <action context="Code" dev="JM" type="fix">
         Fixed a memory-leak: The FO tree part of a page-sequence was not released when a
         page-sequence was finished.

Added: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_keep-together_overflow_1.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_keep-together_overflow_1.xml?rev=428750&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_keep-together_overflow_1.xml (added)
+++ xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_keep-together_overflow_1.xml Fri Aug  4 08:13:53 2006
@@ -0,0 +1,85 @@
+<?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>
+      This test checks keep-together with overflow conditions.
+    </p>
+    <p>
+      Widows and Orphans are disabled in this test to avoid side-effects.
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" widows="0" orphans="0">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="normal" page-width="5in" page-height="4.5 * 14.4pt">
+          <fo:region-body overflow="hidden"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master master-name="longer" page-width="5in" page-height="5.5 * 14.4pt">
+          <fo:region-body overflow="hidden"/>
+        </fo:simple-page-master>
+        <fo:page-sequence-master master-name="mix">
+          <fo:repeatable-page-master-reference master-reference="normal" maximum-repeats="2"/>
+          <fo:repeatable-page-master-reference master-reference="longer" maximum-repeats="1"/>
+          <fo:repeatable-page-master-reference master-reference="normal"/>
+        </fo:page-sequence-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="mix">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block>block1</fo:block>
+          <fo:block>block2</fo:block>
+          <fo:block keep-together.within-page="10" color="blue">
+            <fo:block>block3</fo:block>
+            <fo:block>block4</fo:block>
+            <fo:block>block5</fo:block>
+            <fo:block>block6</fo:block>
+            <fo:block>block7</fo:block>
+          </fo:block>
+          <fo:block>block8</fo:block>
+          <fo:block>block9</fo:block>
+          <fo:block keep-together.within-page="10" color="green">
+            <fo:block>block10</fo:block>
+            <fo:block>block11</fo:block>
+            <fo:block>block12</fo:block>
+            <fo:block>block13</fo:block>
+            <fo:block>block14</fo:block>
+          </fo:block>
+          <fo:block>block15</fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="1" xpath="//lineArea[starts-with(., 'block1')]/ancestor::pageViewport/@nr"/>
+    <eval expected="1" xpath="//lineArea[starts-with(., 'block2')]/ancestor::pageViewport/@nr"/>
+    <eval expected="3" xpath="//lineArea[starts-with(., 'block3')]/ancestor::pageViewport/@nr"/>
+    <eval expected="3" xpath="//lineArea[starts-with(., 'block4')]/ancestor::pageViewport/@nr"/>
+    <eval expected="3" xpath="//lineArea[starts-with(., 'block5')]/ancestor::pageViewport/@nr"/>
+    <eval expected="3" xpath="//lineArea[starts-with(., 'block6')]/ancestor::pageViewport/@nr"/>
+    <eval expected="3" xpath="//lineArea[starts-with(., 'block7')]/ancestor::pageViewport/@nr"/>
+    <eval expected="4" xpath="//lineArea[starts-with(., 'block8')]/ancestor::pageViewport/@nr"/>
+    <eval expected="4" xpath="//lineArea[starts-with(., 'block9')]/ancestor::pageViewport/@nr"/>
+    <eval expected="5" xpath="//lineArea[starts-with(., 'block10')]/ancestor::pageViewport/@nr"/>
+    <eval expected="5" xpath="//lineArea[starts-with(., 'block11')]/ancestor::pageViewport/@nr"/>
+    <eval expected="5" xpath="//lineArea[starts-with(., 'block12')]/ancestor::pageViewport/@nr"/>
+    <eval expected="5" xpath="//lineArea[starts-with(., 'block13')]/ancestor::pageViewport/@nr"/>
+    <eval expected="5" xpath="//lineArea[starts-with(., 'block14')]/ancestor::pageViewport/@nr"/>
+    <eval expected="6" xpath="//lineArea[starts-with(., 'block15')]/ancestor::pageViewport/@nr"/>
+  </checks>
+</testcase>

Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_keep-together_overflow_1.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_keep-together_overflow_1.xml
------------------------------------------------------------------------------
    svn:keywords = Id



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org