]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Hani Elabed's fix to prevent infinite looping when TableCell or TableRow
authorSteve Coffman <gears@apache.org>
Wed, 29 Nov 2000 21:24:21 +0000 (21:24 +0000)
committerSteve Coffman <gears@apache.org>
Wed, 29 Nov 2000 21:24:21 +0000 (21:24 +0000)
is Larger than a page.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193849 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/fo/FOText.java
src/org/apache/fop/fo/flow/Block.java
src/org/apache/fop/fo/flow/TableCell.java
src/org/apache/fop/fo/flow/TableRow.java
src/org/apache/fop/layout/LineArea.java

index 90b79671a3487a671b0e23a5ad815b77b1c7b9e0..325aeccbcc14933a2ac68c9c5341041623436262 100644 (file)
@@ -132,7 +132,18 @@ public class FOText extends FONode {
                       wrapOption, this.getLinkSet(), whiteSpaceCollapse, ca,
                       this.marker, length, underlined);
         if (this.marker == -1) {
-            this.marker = 0;
+
+                       
+                               // commented out by Hani Elabed, 11/28/2000
+                               // if this object has been laid out
+                               // successfully, leave it alone....
+                               // Now, to prevent the array index out of
+                               // bound of LineArea.addText(), I have added
+                               // the following test at the beginning of that method.
+                               // if( start == -1 ) return -1;
+                               // see LineArea.addText()
+
+                       //this.marker = 0;
             return new Status(Status.OK);
         } else if (this.marker != orig_start) {
             return new Status(Status.AREA_FULL_SOME);
index 6c80aea6e04d8612b89681d2f3ed7e914bb828e4..9f4edb778e6630a7286c3d68bc9cf533cc67dd48 100644 (file)
@@ -294,17 +294,41 @@ public class Block extends FObjMixed {
                fo.setBodyIndent(this.bodyIndent);
            }
            Status status;
-           if ((status = fo.layout(blockArea)).isIncomplete()) {
-               this.marker = i;
-               if ((i != 0) && (status.getCode() == Status.AREA_FULL_NONE)) {
-                   status = new Status(Status.AREA_FULL_SOME);
-               }
-               //blockArea.end();
-               area.addChild(blockArea);
-               area.increaseHeight(blockArea.getHeight());
-                area.setAbsoluteHeight(blockArea.getAbsoluteHeight());
-               anythingLaidOut = true;
-               return status;
+           if ((status = fo.layout(blockArea)).isIncomplete()) 
+           {
+                       this.marker = i;
+                               // this block was modified by
+                               // Hani Elabed 11/27/2000
+                       //if ((i != 0) && (status.getCode() == Status.AREA_FULL_NONE)) 
+                       //{
+                       //    status = new Status(Status.AREA_FULL_SOME);
+                       //}
+                       
+                               // new block to replace the one above
+                               // Hani Elabed 11/27/2000
+                       if( status.getCode() == Status.AREA_FULL_NONE )
+                       {
+                                       // something has already been laid out
+                               if( (i != 0)  )
+                               {
+                                       status = new Status(Status.AREA_FULL_SOME);
+                                   anythingLaidOut = true;
+
+                                       return status;
+                               }
+                               else    // i == 0 nothing was laid out..
+                               {
+                                   anythingLaidOut = false;
+                                       return status;  
+                               }
+                       }
+                       
+                       //blockArea.end();
+                       area.addChild(blockArea);
+                       area.increaseHeight(blockArea.getHeight());             
+               area.setAbsoluteHeight(blockArea.getAbsoluteHeight());
+                       anythingLaidOut = true;
+                       return status;
            }
            anythingLaidOut = true;
        }
index ccb397b3d51266c892b073217d09cdd10fafacfe..f3147191c1e702f50b6345e6e0b7724fbc4868e3 100644 (file)
@@ -253,6 +253,9 @@ public class TableCell extends FObj {
                if ((i == 0) && (status.getCode() == Status.AREA_FULL_NONE)) {
                    return new Status(Status.AREA_FULL_NONE);
                } else {
+                                       // hani Elabed 11/21/2000
+                        area.addChild(areaContainer);
+
                    return new Status(Status.AREA_FULL_SOME);
                }
            }
index 28c02f242672e8086dd2a9ab71abc3418e8cbc54..408582c4b7fe407c1e0a46f6e6f59e3480b45431 100644 (file)
@@ -104,8 +104,128 @@ public class TableRow extends FObj {
     Vector columns;
 
     AreaContainer areaContainer;
+
+               // added by Dresdner Bank, Germany
     DisplaySpace spacer = null;
 
+
+
+       /** 
+       * The list of cell states for this row. This is the location of
+       * where I will be storing the state of each cell so that I can
+       * spread a cell over multiple pages if I have to. This is part
+       * of fixing the TableRow larger than a single page bug. 
+       * Hani Elabed, 11/22/2000. 
+       */
+       public Vector cells = null;
+
+   /**
+       * CellState<BR>
+       *
+       * <B>Copyright @ 2000 Circuit Court Automation Program.
+       * state of Wisconsin. 
+       * All Rights Reserved.</B>
+       * <p>
+       * This class is a container class for encapsulating a the
+       * state of a cell
+       * <TABLE>
+       * <TR><TD><B>Name:</B></TD>        <TD>CellState</TD></TR>
+       *
+       * <TR><TD><B>Purpose:</B></TD>     <TD>a helpful container class</TD></TR>
+       *
+       * <TR><TD><B>Description:</B></TD> <TD>This class is a container class for 
+       *                                      encapsulating the state of a
+       *                                                                          cell belonging to a TableRow class
+       *                                  </TD></TR> 
+       *
+       * </TABLE> 
+       * 
+       * @author      Hani Elabed
+       * @version     0.14.0, 11/22/2000
+       * @since       JDK1.1
+       */
+       public final class CellState
+   {
+         /** the cell location or index starting at 0.*/
+         private       int     location;
+         
+         /** true if the layout of the cell was complete, false otherwise.*/
+         private       boolean layoutCompleted;
+         
+         /** the width of the cell so far.*/
+         private       int     widthOfCellSoFar;
+
+
+         /**
+         * simple no args constructor.
+         */
+         public CellState()
+         { 
+                this( 0, false, 0 );
+         }
+         
+         /**
+         * three argument fill everything constructor.
+         * @param int the location(index) of the cell.
+         * @param boolean flag of wether the cell was completely laid out or not.
+         * @param int the horizontal offset(width so far) of the cell.
+         */
+         public CellState( int aLocation, boolean completed, int aWidth )
+         {
+          
+            location = aLocation;
+                layoutCompleted = completed;
+                widthOfCellSoFar = aWidth;
+         }
+         
+         /**
+         * returns the index of the cell starting at 0.
+         * @return int the location of the cell.
+         */
+         public final int getLocation() 
+         { return location; }
+         
+         /**
+         * sets the location of the cell.
+         * @param int, the location of the cell.
+         */
+         public final void   setLocation(int aLocation) 
+         { location = aLocation; }
+
+         
+         /**
+         * returns true if the cell was completely laid out.
+         * @return false if cell was partially laid out.
+         */
+         public final boolean isLayoutComplete() 
+         { return layoutCompleted; }
+         
+         /**
+         * sets the layoutCompleted flag.
+         * @param boolean, the layout Complete state of the cell.
+         */
+         public final void  setLayoutComplete(boolean completed ) 
+         { layoutCompleted = completed; }
+
+         
+         /**
+         * returns the horizontal offset of the cell.
+         * @return int the horizontal offset of the cell, also known as width
+         * of the cell so far.
+         */
+         public final int getWidthOfCellSoFar() 
+         { return widthOfCellSoFar; }
+         
+         /**
+         * sets the width of the Cell So Far, i.e the cell's offset.
+         * @param int, the horizontal offset of the cell.
+         */
+         public final void setWidthOfCellSoFar(int aWidth) 
+         { widthOfCellSoFar = aWidth; }
+
+   } 
+
+
     public TableRow(FObj parent, PropertyList propertyList) {
        super(parent, propertyList);
        this.name = "fo:table-row";
@@ -209,6 +329,34 @@ public class TableRow extends FObj {
 
            this.marker = 0;
 
+
+               // cells is The list of cell states for this row. This is the location of
+               // where I will be storing the state of each cell so that I can
+               // spread a cell over multiple pages if I have to. This is part
+               // of fixing the TableRow larger than a single page bug. 
+               // Hani Elabed, 11/22/2000. 
+               if( cells == null ) // do it once..
+               {
+                       int numOfCols = columns.size();
+                       cells = new Vector( numOfCols );
+                       int cumulativeWidth = 0;
+                               // populating the cells vector with initial states.
+                       for (int i = 0; i < numOfCols; i++)
+                       {
+                               int width = ((TableColumn) columns.elementAt(i)).getColumnWidth();
+                                       
+                               CellState state = new CellState( i, false, cumulativeWidth );
+                                       // add the state of a cell.
+                               cells.add( i, state );
+                                       // cumulative width, i.e start offset of cell
+                                       // also known as widthOfCellSoFar...
+                               cumulativeWidth += width;
+                       }
+
+               }
+
+
+
        }
 
        if ((spaceBefore != 0) && (this.marker ==0)) {
@@ -247,49 +395,109 @@ public class TableRow extends FObj {
        widthOfCellsSoFar = 0;
        largestCellHeight = 0;
 
+               // added by Hani Elabed 11/27/2000
+       boolean someCellDidNotLayoutCompletely = false;
+       
+       
        for (int i = this.marker; i < numChildren; i++) {
            TableCell cell = (TableCell) children.elementAt(i);
 
+                       // added by Hani Elabed 11/22/2000
+               CellState cellState = (CellState) cells.elementAt( i );
+
+
            //if (this.isInListBody) {
            //fo.setIsInListBody();
            //fo.setDistanceBetweenStarts(this.distanceBetweenStarts);
            //fo.setBodyIndent(this.bodyIndent);
            //}
 
-           cell.setStartOffset(widthOfCellsSoFar);
+
+                       //--- this is modified to preserve the state of start
+                       //--- offset of the cell.
+                       //--- change by Hani Elabed 11/22/2000
+               //cell.setStartOffset(widthOfCellsSoFar);
+               cell.setStartOffset( cellState.getWidthOfCellSoFar() );
+
            int width = ((TableColumn) columns.elementAt(i)).getColumnWidth();
 
            cell.setWidth(width);
            widthOfCellsSoFar += width;
 
            Status status;
-           if ((status = cell.layout(areaContainer)).isIncomplete()) {
-               this.marker = i;
-               if ((i != 0) && (status.getCode() == Status.AREA_FULL_NONE)) {
-                   status = new Status(Status.AREA_FULL_SOME);
-               }
-               
+           if ((status = cell.layout(areaContainer)).isIncomplete()) 
+           {
+                       this.marker = i;
+                       if ((i != 0) && (status.getCode() == Status.AREA_FULL_NONE)) 
+                       {
+                           status = new Status(Status.AREA_FULL_SOME);
+                       }
+
+
+                       if( status.getCode() == Status.AREA_FULL_SOME )
+                       {
+                                       // this whole block added by 
+                                       // Hani Elabed 11/27/2000                       
+                               
+                               cellState.setLayoutComplete( false );
+
+                                       // locate the first cell
+                                       // that need to be laid out further
+                               
+                               for (int j = 0; j < numChildren; j++)
+                               {
+                                       CellState state = (CellState) cells.elementAt( j );
+
+                                       if( ! state.isLayoutComplete() )
+                                       {
+                                               this.marker = j;
+                                               break; // out of for loop
+                                       }
+                               }
+                       }
+                       else
+                       {
+                                       // added on 11/28/2000, by Dresdner Bank, Germany               
                if(spacer != null)
                        area.removeChild(spacer);
+
+                                       // removing something that was added by succession
+                                       // of cell.layout()
+                                       // just to keep my sanity here, Hani
                area.removeChild(areaContainer);
                 this.resetMarker();                
                 this.removeID(area.getIDReferences());
                                 
-               return status;
+                                       // hani elabed 11/27/2000
+                               cellState.setLayoutComplete( false );
+                                       
+                               return status;
+                       }
            }
+               else    // layout was complete for a particular cell
+               {               // Hani Elabed
+                       cellState.setLayoutComplete( true );
+               }
+           
+
 
            int h = cell.getHeight();
-           if (h > largestCellHeight) {
-               largestCellHeight = h;
+           if (h > largestCellHeight) 
+           {
+                       largestCellHeight = h;
            }
        }
-       for (int i = 0; i < numChildren; i++) {
+
+       for (int i = 0; i < numChildren; i++) 
+       {
            TableCell cell = (TableCell)children.elementAt(i);
-            cell.setHeight(largestCellHeight);
+        cell.setHeight(largestCellHeight);
        }
 
+               // added by Dresdner Bank, Germany
     if(spacer != null)
         area.addChild(spacer);
+
        area.addChild(areaContainer);
        areaContainer.end();
         area.addDisplaySpace(largestCellHeight
@@ -309,7 +517,36 @@ public class TableRow extends FObj {
            area.start();
        }
 
-       return new Status(Status.OK);
+
+               // test to see if some cells are not
+               // completely laid out.
+               // Hani Elabed 11/22/2000
+       for (int i = 0; i < numChildren; i++)
+       {
+               CellState cellState = (CellState) cells.elementAt( i );
+
+               if( ! cellState.isLayoutComplete() )
+               {
+                       someCellDidNotLayoutCompletely = true;
+                       break; // out of for loop
+               }
+       }
+       
+       
+       
+       
+               // replaced by Hani Elabed 11/27/2000
+       //return new Status(Status.OK);
+       
+       if( someCellDidNotLayoutCompletely )
+       {
+               return new Status(Status.AREA_FULL_SOME);
+       }
+       else
+       {
+               return new Status(Status.OK);
+       }
+       
     }   
 
     public int getAreaHeight() {
index e1100007324d9df76c82bf9561b0bedafb95db50..a35a2b4bd9efd8e25b214784bd7d63b6c23ce82b 100644 (file)
@@ -199,6 +199,12 @@ public class LineArea extends Area {
             data[count] = odata[count];
         }
 
+                       // added by hani 9/13/2000 to maintain  my sanity
+                       // and to prevent array index out of bounds.
+               if( start == -1 )
+                       return -1;
+       
+
         /* iterate over each character */
         for (int i = start; i < end; i++) {
             int charWidth;
@@ -525,6 +531,7 @@ public class LineArea extends Area {
       */
     public void addPending() {
         if (spaceWidth > 0) {
+                       // by Dresdner Bank, Germany        
             // this should handle the correct amount of space after
             // the text if there is no more text, important for right alignment
             if(this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE || pendingAreas.size() > 0) {