]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Added a check for endless loops.
authorJeremias Maerki <jeremias@apache.org>
Wed, 26 Jan 2005 15:00:45 +0000 (15:00 +0000)
committerJeremias Maerki <jeremias@apache.org>
Wed, 26 Jan 2005 15:00:45 +0000 (15:00 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198323 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java

index f3f261694e898c7b8df6880d8b54631617f6f2c3..102e609205131fabd8f30ed3227d7c1ffc69dccb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@ import org.apache.fop.fo.pagination.Flow;
 import org.apache.fop.area.Area;
 import org.apache.fop.area.BlockParent;
 
-import java.util.ArrayList;
 import java.util.List;
 import org.apache.fop.traits.MinOptMax;
 
@@ -34,19 +33,27 @@ import org.apache.fop.traits.MinOptMax;
  * and filling them with block-level areas generated by its children.
  */
 public class FlowLayoutManager extends BlockStackingLayoutManager {
+    
     private Flow fobj;
     
     /** List of break possibilities */
-    protected List blockBreaks = new ArrayList();
+    protected List blockBreaks = new java.util.ArrayList();
 
     /** Array of areas currently being filled stored by area class */
     private BlockParent[] currentAreas = new BlockParent[Area.CLASS_MAX];
 
     private int iStartPos = 0;
 
+    /**
+     * Used to count the number of subsequent times to layout child areas on
+     * multiple pages.
+     */
+    private int numSubsequentOverflows = 0;
+    
     /**
      * This is the top level layout manager.
      * It is created by the PageSequence FO.
+     * @param node Flow object
      */
     public FlowLayoutManager(Flow node) {
         super(node);
@@ -87,6 +94,10 @@ public class FlowLayoutManager extends BlockStackingLayoutManager {
                     childLC.setStackLimit(MinOptMax.subtract(bpd, stackSize));
 
                     if (bp.isForcedBreak() || bp.nextBreakOverflows()) {
+                        if (log.isDebugEnabled()) {
+                            log.debug("BreakPoss signals " + (bp.isForcedBreak() 
+                                    ? "forced break" : "next break overflows"));
+                        }
                         breakPage = true;
                     }
                 }
@@ -99,9 +110,16 @@ public class FlowLayoutManager extends BlockStackingLayoutManager {
                 breakPage = true;
             }
             if (breakPage) {
+                numSubsequentOverflows++;
+                if (numSubsequentOverflows > 50) {
+                    log.error("Content overflows available area. Giving up after 50 attempts.");
+                    setFinished(true);
+                    return null;
+                }
                 return new BreakPoss(
                       new LeafPosition(this, blockBreaks.size() - 1));
             }
+            numSubsequentOverflows = 0; //Reset emergency counter
         }
         setFinished(true);
         if (blockBreaks.size() > 0) {
@@ -121,9 +139,8 @@ public class FlowLayoutManager extends BlockStackingLayoutManager {
         while (parentIter.hasNext()) {
             LeafPosition lfp = (LeafPosition) parentIter.next();
             // Add the block areas to Area
-            PositionIterator breakPosIter =
-              new BreakPossPosIter(blockBreaks, iStartPos,
-                                   lfp.getLeafPos() + 1);
+            PositionIterator breakPosIter =  new BreakPossPosIter(
+                    blockBreaks, iStartPos, lfp.getLeafPos() + 1);
             iStartPos = lfp.getLeafPos() + 1;
             while ((childLM = breakPosIter.getNextChildLM()) != null) {
                 childLM.addAreas(breakPosIter, lc);
@@ -149,8 +166,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager {
      */
     public Area getParentArea(Area childArea) {
         // Get an area from the Page
-        BlockParent parentArea =
-          (BlockParent) parentLM.getParentArea(childArea);
+        BlockParent parentArea = (BlockParent)parentLM.getParentArea(childArea);
         this.currentAreas[parentArea.getAreaClass()] = parentArea;
         setCurrentArea(parentArea);
         return parentArea;