klease 01/07/04 14:16:02
Modified: src/org/apache/fop/fo/flow TableBody.java TableCell.java
TableRow.java
Log:
Implements spanning table rows
Revision Changes Path
1.36 +11 -30 xml-fop/src/org/apache/fop/fo/flow/TableBody.java
Index: TableBody.java
===================================================================
RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/flow/TableBody.java,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- TableBody.java 2001/07/04 07:37:42 1.35
+++ TableBody.java 2001/07/04 21:16:02 1.36
@@ -1,4 +1,4 @@
-/*-- $Id: TableBody.java,v 1.35 2001/07/04 07:37:42 keiron Exp $ --
+/*-- $Id: TableBody.java,v 1.36 2001/07/04 21:16:02 klease Exp $ --
*
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
@@ -37,6 +37,7 @@
String id;
Vector columns;
+ RowSpanMgr rowSpanMgr; // manage information about spanning rows
AreaContainer areaContainer;
@@ -82,6 +83,10 @@
area.end();
}
+ if (rowSpanMgr == null) {
+ rowSpanMgr = new RowSpanMgr(columns.size());
+ }
+
//if (this.isInListBody) {
//startIndent += bodyIndent + distanceBetweenStarts;
//}
@@ -131,6 +136,7 @@
}
TableRow row = (TableRow) child;
+ row.setRowSpanMgr(rowSpanMgr);
row.setColumns(columns);
row.doSetup(areaContainer);
if (row.getKeepWithPrevious().getType() !=
@@ -145,6 +151,7 @@
Status status;
if ((status = row.layout(areaContainer)).isIncomplete()) {
+ // BUG!!! don't
distinguish between break-before and after!
if (status.isPageBreak()) {
this.marker = i;
area.addChild(areaContainer);
@@ -162,6 +169,7 @@
return status;
}
if (keepWith.size() > 0) { // && status.getCode() ==
Status.AREA_FULL_NONE
+ //
FIXME!!! Handle rows spans!!!
row.removeLayout(areaContainer);
for (Enumeration e = keepWith.elements();
e.hasMoreElements();) {
@@ -179,34 +187,6 @@
(status.getCode() == Status.AREA_FULL_NONE)) {
status = new Status(Status.AREA_FULL_SOME);
}
- // if (i
< widows && numChildren >= widows) {
- //
resetMarker();
- //
return new Status(Status.AREA_FULL_NONE);
- // }
- // if
(numChildren <= orphans) {
- //
resetMarker();
- //
return new Status(Status.AREA_FULL_NONE);
- // }
- // if
(numChildren - i < orphans && numChildren >= orphans) {
- //
for (int count = i;
- //
count > numChildren - orphans - 1; count--) {
- //
row = (TableRow) children.elementAt(count);
- //
row.removeLayout(areaContainer);
- //
i--;
- //
}
- //
if (i < widows && numChildren >= widows) {
- //
resetMarker();
- //
return new Status(Status.AREA_FULL_NONE);
- //
}
- //
this.marker = i;
- //
area.addChild(areaContainer);
- //
//areaContainer.end();
-
- //
area.increaseHeight(areaContainer.getHeight());
- //
area.setAbsoluteHeight(
- //
areaContainer.getAbsoluteHeight());
- //
return new Status(Status.AREA_FULL_SOME);
- // }
if (!((i == 0) &&
(areaContainer.getContentHeight() <= 0))) {
area.addChild(areaContainer);
@@ -217,7 +197,8 @@
areaContainer.getAbsoluteHeight());
}
return status;
- } else if (status.getCode() == Status.KEEP_WITH_NEXT) {
+ } else if (status.getCode() == Status.KEEP_WITH_NEXT ||
+
rowSpanMgr.hasUnfinishedSpans()) {
keepWith.addElement(row);
endKeepGroup = false;
} else {
1.33 +33 -15 xml-fop/src/org/apache/fop/fo/flow/TableCell.java
Index: TableCell.java
===================================================================
RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/flow/TableCell.java,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- TableCell.java 2001/06/14 21:22:54 1.32
+++ TableCell.java 2001/07/04 21:16:02 1.33
@@ -1,4 +1,4 @@
-/*-- $Id: TableCell.java,v 1.32 2001/06/14 21:22:54 klease Exp $ --
+/*-- $Id: TableCell.java,v 1.33 2001/07/04 21:16:02 klease Exp $ --
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
@@ -33,6 +33,7 @@
String id;
int numColumnsSpanned;
int numRowsSpanned;
+ int iColNumber = -1; // uninitialized
/** Offset of content rectangle in inline-progression-direction,
* relative to table.
@@ -49,13 +50,14 @@
/* ivan demakov */
protected int borderHeight = 0;
+ protected int cellHeight = 0;
protected int height = 0;
protected int top; // Ypos of cell ???
protected int verticalAlign ;
protected boolean bRelativeAlign = false;
- boolean setup = false;
+ // boolean setup = false;
boolean bSepBorders = true;
/** Border separation value in the block-progression dimension.
@@ -68,6 +70,7 @@
public TableCell(FObj parent, PropertyList propertyList) {
super(parent, propertyList);
this.name = "fo:table-cell";
+ doSetup(); // init some basic property values
}
// Set position relative to table (set by body?)
@@ -81,6 +84,11 @@
this.width = width;
}
+ public int getColumnNumber()
+ {
+ return iColNumber;
+ }
+
public int getNumColumnsSpanned()
{
return numColumnsSpanned;
@@ -91,22 +99,22 @@
return numRowsSpanned;
}
- public void doSetup(Area area) throws FOPException
+ public void doSetup()// throws FOPException
{
+ this.iColNumber =
properties.get("column-number").getNumber().intValue();
+ if (iColNumber < 0) { iColNumber = 0; }
this.numColumnsSpanned =
this.properties.get("number-columns-spanned").getNumber().intValue();
+ if (numColumnsSpanned < 1) { numColumnsSpanned = 1; }
this.numRowsSpanned =
this.properties.get("number-rows-spanned").getNumber().intValue();
+ if (numRowsSpanned < 1) { numRowsSpanned = 1; }
- /**
- this.spaceBefore =
- this.properties.get("space-before.optimum").getLength().mvalue();
- this.spaceAfter =
- this.properties.get("space-after.optimum").getLength().mvalue();
- **/
this.backgroundColor =
this.properties.get("background-color").getColorType();
+
this.id = this.properties.get("id").getString();
+
bSepBorders =
(this.properties.get("border-collapse").getEnum() ==
BorderCollapse.SEPARATE);
// Vertical cell alignment
@@ -118,6 +126,7 @@
}
else bRelativeAlign = false; // Align on a per-cell basis
+ this.cellHeight =
this.properties.get("height").getLength().mvalue();
}
@@ -128,9 +137,9 @@
}
if (this.marker == START) {
- if (!setup) {
- doSetup(area);
- }
+// if (!setup) {
+// doSetup(area);
+// }
// Calculate cell borders
calcBorders(propMgr.getBorderAndPadding());
@@ -151,14 +160,14 @@
area.getIDReferences().configureID(id,area);
}
- int spaceLeft = area.spaceLeft();
+ int spaceLeft = area.spaceLeft() -
m_borderSeparation/2 + borderHeight/2 ;
// The Area position defines the content rectangle!
Borders
// and padding are outside of this rectangle.
this.cellArea =
new
AreaContainer(propMgr.getFontState(area.getFontInfo()),
startOffset, beforeOffset,
-
width, area.spaceLeft()- m_borderSeparation/2 +
borderHeight/2,
+
width, spaceLeft,
Position.RELATIVE);
cellArea.foCreator=this; // G Seshadri
@@ -194,6 +203,7 @@
return
new Status(Status.AREA_FULL_SOME);
}
}
+
area.setMaxHeight(area.getMaxHeight()
- spaceLeft +
this.cellArea.getMaxHeight());
}
@@ -218,7 +228,8 @@
// TableRow calls this. Anyone else?
public int getHeight() {
// return cellArea.getHeight() + spaceBefore +
spaceAfter;
- return cellArea.getHeight() + m_borderSeparation -
borderHeight / 2;
+ if (cellHeight > 0) return cellHeight;
+ return cellArea.getHeight() + m_borderSeparation -
borderHeight/2;
}
/** Called by TableRow to set final size of cell content rectangles and
@@ -290,6 +301,10 @@
this.beforeOffset =
m_borderSeparation/2 +
bp.getBorderTopWidth(false) + bp.getPaddingTop(false);
// bp.getBorderBeforeWidth(false) +
bp.getPaddingBefore(false);
+ if (this.cellHeight > 0) {
+ this.cellHeight +=
this.beforeOffset + m_borderSeparation/2 +
+
bp.getBorderBottomWidth(false) + bp.getPaddingBottom(false);
+ }
}
else {
//System.err.println("Collapse
borders");
@@ -332,6 +347,9 @@
this.beforeOffset = borderBefore/2 +
bp.getPaddingTop(false);
this.borderHeight = borderBefore +
borderAfter;
+ if (this.cellHeight > 0) {
+ this.cellHeight +=
this.beforeOffset + borderAfter/2 + bp.getPaddingBottom(false);
+ }
}
}
}
1.45 +488 -517 xml-fop/src/org/apache/fop/fo/flow/TableRow.java
Index: TableRow.java
===================================================================
RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/flow/TableRow.java,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- TableRow.java 2001/05/02 21:00:45 1.44
+++ TableRow.java 2001/07/04 21:16:02 1.45
@@ -1,4 +1,4 @@
-/*-- $Id: TableRow.java,v 1.44 2001/05/02 21:00:45 klease Exp $ --
+/*-- $Id: TableRow.java,v 1.45 2001/07/04 21:16:02 klease Exp $ --
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
@@ -16,526 +16,497 @@
// Java
import java.util.Vector;
+import java.util.Enumeration;
public class TableRow extends FObj {
- public static class Maker extends FObj.Maker {
- public FObj make(FObj parent,
-
PropertyList propertyList) throws FOPException {
- return new TableRow(parent,
propertyList);
- }
- }
-
- public static FObj.Maker maker() {
- return new TableRow.Maker();
- }
-
- boolean setup = false;
-
- int spaceBefore;
- int spaceAfter;
- int breakBefore;
- int breakAfter;
- ColorType backgroundColor;
- String id;
-
- KeepValue keepWithNext;
- KeepValue keepWithPrevious;
-
- int widthOfCellsSoFar = 0;
- int largestCellHeight = 0;
-
- Vector columns;
-
- AreaContainer areaContainer;
-
- // added by Dresdner Bank, Germany
- DisplaySpace spacer = null;
- boolean hasAddedSpacer = false;
- DisplaySpace spacerAfter = null;
- boolean areaAdded = false;
-
- /**
- * 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;
-
- private int column = 0;
-
- /**
- * 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 int getColumn() {
- return column;
- }
-
- public void setColumn(int col) {
- column = col;
- }
- }
-
-
- public TableRow(FObj parent, PropertyList propertyList) {
- super(parent, propertyList);
- this.name = "fo:table-row";
- }
-
- public void setColumns(Vector columns) {
- this.columns = columns;
- }
-
- public KeepValue getKeepWithPrevious() {
- return keepWithPrevious;
- }
-
- public void doSetup(Area area) throws FOPException {
-
- this.spaceBefore = this.properties.get(
-
"space-before.optimum").getLength().mvalue();
- this.spaceAfter = this.properties.get(
-
"space-after.optimum").getLength().mvalue();
- this.breakBefore =
this.properties.get("break-before").getEnum();
- this.breakAfter =
this.properties.get("break-after").getEnum();
- this.backgroundColor =
-
this.properties.get("background-color").getColorType();
-
- this.keepWithNext =
getKeepValue("keep-with-next.within-column");
- this.keepWithPrevious =
getKeepValue("keep-with-previous.within-column");
-
- this.id = this.properties.get("id").getString();
- setup = true;
- }
-
- private KeepValue getKeepValue(String sPropName) {
- Property p= this.properties.get(sPropName);
- Number n = p.getNumber();
- if (n != null)
- return new
KeepValue(KeepValue.KEEP_WITH_VALUE, n.intValue());
- switch(p.getEnum()) {
- case Constants.ALWAYS:
- return new
KeepValue(KeepValue.KEEP_WITH_ALWAYS, 0);
- //break;
- case Constants.AUTO:
- default:
- return new
KeepValue(KeepValue.KEEP_WITH_AUTO, 0);
- //break;
- }
- }
-
- public Status layout(Area area) throws FOPException {
- boolean configID = false;
-
- if (this.marker == BREAK_AFTER) {
- return new Status(Status.OK);
- }
-
- if (this.marker == START) {
- if (!setup)
- doSetup(area);
-
- if (area instanceof BlockArea) {
- area.end();
- }
- if (cells == null) { // check to make sure this row hasn't
been partially
- //
laid out yet (with an id created already)
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent,
+ PropertyList propertyList) throws FOPException {
+ return new TableRow(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new TableRow.Maker();
+ }
+
+ boolean setup = false;
+
+ int breakAfter;
+ ColorType backgroundColor;
+ String id;
+
+ KeepValue keepWithNext;
+ KeepValue keepWithPrevious;
+ KeepValue keepTogether;
+
+ int widthOfCellsSoFar = 0;
+ int largestCellHeight = 0;
+
+ Vector columns;
+
+ AreaContainer areaContainer;
+
+ boolean areaAdded = false;
+
+ private RowSpanMgr rowSpanMgr = null;
+ private CellArray cellArray = null;
+
+ private static class CellArray {
+ public static final byte EMPTY=0;
+ public static final byte CELLSTART=1;
+ public static final byte CELLSPAN=2;
+
+ private TableCell[] cells;
+ private byte[] states;
+
+ public CellArray(RowSpanMgr rsi, int numColumns) {
+ // Initialize the cell array by marking any cell positions
+ // occupied by spans from previous rows
+ cells = new TableCell[numColumns];
+ states = new byte[numColumns];
+ for (int i=0; i <numColumns; i++) {
+ if (rsi.isSpanned(i+1)) {
+ cells[i] = rsi.getSpanningCell(i+1);
+ states[i]=CELLSPAN;
+ }
+ else states[i]=EMPTY;
+ }
+ }
+
+ /**
+ * Return column which doesn't already contain a span or a cell
+ * If past the end or no free cells after colNum, return -1
+ * Otherwise return value >= input value.
+ */
+ int getNextFreeCell(int colNum) {
+ for (int i=colNum-1; i<cells.length; i++) {
+ if (cells[i] == null) return i+1;
+ }
+ return -1;
+ }
+
+
+ /**
+ * Return type of cell in colNum (1 based)
+ */
+ int getCellType(int colNum) {
+ if (colNum > 0 && colNum<=cells.length) {
+ return states[colNum-1];
+ }
+ else return -1; // probably should throw exception
+ }
+
+ /**
+ * Return cell in colNum (1 based)
+ */
+ TableCell getCell(int colNum) {
+ if (colNum > 0 && colNum<=cells.length) {
+ return cells[colNum-1];
+ }
+ else return null; // probably should throw exception
+ }
+
+ /**
+ * Store cell starting at cellColNum (1 based) and spanning numCols
+ * If any of the columns is already occupied, return false, else true
+ */
+ boolean storeCell(TableCell cell, int colNum, int numCols) {
+ boolean rslt=true;
+ int index=colNum-1;
+ for (int count=0; index<cells.length && count<numCols; count++,
index++) {
+ if (cells[index] == null) {
+ cells[index] = cell;
+ states[index] = (count==0)? CELLSTART : CELLSPAN;
+ }
+ else {
+ rslt=false;
+ // print a message but continue!!!
+ }
+ }
+ return rslt;
+ }
+
+// private class EnumCells implements Enumeration {
+// private int iNextIndex=0;
+// private Object nextCell = null;
+// EnumCells() {
+// findNextCell();
+// }
+
+// private void findNextCell() {
+// for (; iNextIndex < cells.length; iNextIndex++) {
+// if (states[iNextIndex] == CELLSTART) {
+// nextCell = cells[iNextIndex];
+// return;
+// }
+// }
+// nextCell = null;
+// }
+
+// public boolean hasMoreElements() {
+// return (nextCell != null);
+// }
+
+// public Object nextElement() {
+// if (nextCell != null) {
+// Object cell = nextCell;
+// findNextCell();
+// return cell;
+// }
+// else throw new java.util.NoSuchElementException("No more cells");
+// }
+// }
+
+// /**
+// * Return an enumeration over all cells in this row
+// * Return each element in cells whose state is CELLSTART or EMPTY?
+// * Skip spanning elements.
+// */
+// Enumeration getCells() {
+// return new EnumCells();
+// }
+ }
+
+
+ public TableRow(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:table-row";
+ }
+
+ public void setColumns(Vector columns) {
+ this.columns = columns;
+ }
+
+ public KeepValue getKeepWithPrevious() {
+ return keepWithPrevious;
+ }
+
+ public void doSetup(Area area) throws FOPException {
+
+ this.breakAfter = this.properties.get("break-after").getEnum();
+ this.backgroundColor =
+ this.properties.get("background-color").getColorType();
+
+ this.keepTogether = getKeepValue("keep-together.within-column");
+ this.keepWithNext = getKeepValue("keep-with-next.within-column");
+ this.keepWithPrevious = getKeepValue("keep-with-previous.within-column");
+
+ this.id = this.properties.get("id").getString();
+ setup = true;
+ }
+
+ private KeepValue getKeepValue(String sPropName) {
+ Property p= this.properties.get(sPropName);
+ Number n = p.getNumber();
+ if (n != null)
+ return new KeepValue(KeepValue.KEEP_WITH_VALUE, n.intValue());
+ switch(p.getEnum()) {
+ case Constants.ALWAYS:
+ return new KeepValue(KeepValue.KEEP_WITH_ALWAYS, 0);
+ //break;
+ case Constants.AUTO:
+ default:
+ return new KeepValue(KeepValue.KEEP_WITH_AUTO, 0);
+ //break;
+ }
+ }
+
+ public Status layout(Area area) throws FOPException {
+ boolean configID = false;
+
+ if (this.marker == BREAK_AFTER) {
+ return new Status(Status.OK);
+ }
+
+ // Layout the first area for this FO
+ if (this.marker == START) {
+ if (!setup)
+ doSetup(area);
+
+ // Only do this once. If the row is "thrown" and we start
+ // layout over again, we can skip this.
+ if (cellArray == null) {
+ initCellArray();
+ // check to make sure this row hasn't been partially
+ // laid out yet (with an id created already)
area.getIDReferences().createID(id);
configID = true;
- }
-
-
- this.marker = 0;
- if (breakBefore == BreakBefore.PAGE) {
- return new
Status(Status.FORCE_PAGE_BREAK);
- }
-
- if (breakBefore ==
BreakBefore.ODD_PAGE) {
- return new
Status(Status.FORCE_PAGE_BREAK_ODD);
- }
-
- if (breakBefore ==
BreakBefore.EVEN_PAGE) {
- return new
Status(Status.FORCE_PAGE_BREAK_EVEN);
- }
-
- if (breakBefore == BreakBefore.COLUMN)
{
- return new
Status(Status.FORCE_COLUMN_BREAK);
- }
- }
-
- if ((spaceBefore != 0) && (this.marker == 0)) {
- spacer = new DisplaySpace(spaceBefore);
- area.increaseHeight(spaceBefore);
- }
- else spacer=null; // Not first area created by the row!
-
- if (marker == 0 && configID) {
- // configure id
- area.getIDReferences().configureID(id,
area);
- }
-
- int spaceLeft = area.spaceLeft();
- // int origMaxHeight = area.getMaxHeight();
- this.areaContainer =
- new
AreaContainer(propMgr.getFontState(area.getFontInfo()),
-
0,0,
-
area.getContentWidth(),
-
spaceLeft,
-
Position.RELATIVE);
- areaContainer.foCreator=this; // G Seshadri
- areaContainer.setPage(area.getPage());
-
- areaContainer.setBackgroundColor(backgroundColor);
- //
areaContainer.setBorderAndPadding(propMgr.getBorderAndPadding());
- areaContainer.start();
-
-
areaContainer.setAbsoluteHeight(area.getAbsoluteHeight());
- areaContainer.setIDReferences(area.getIDReferences());
-
- // 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..
- {
- widthOfCellsSoFar = 0;
- cells = new Vector();
- int colCount = 0;
- int numChildren = this.children.size();
- for (int i = 0; i < numChildren; i++) {
- TableCell cell =
(TableCell) children.elementAt(i);
-
cell.doSetup(areaContainer);
- int numCols =
cell.getNumColumnsSpanned();
- int numRows =
cell.getNumRowsSpanned();
- int width = 0;
- CellState state =
- new
CellState(i, false, widthOfCellsSoFar);
-
state.setColumn(colCount);
- // add the state of a
cell.
-
cells.insertElementAt(state, i);
- if(colCount + numCols
> columns.size()) {
-
MessageHandler.errorln("WARNING: Number of cell columns under table-row not equal to
number of table-columns");
- return new
Status(Status.OK);
- }
- for (int count = 0;
-
count < numCols && count < columns.size();
-
count++) {
- width
+= ((TableColumn) columns.elementAt(colCount)).
-
getColumnWidth();
-
colCount++;
- }
-
- cell.setWidth(width);
- widthOfCellsSoFar +=
width;
-
- }
- if(colCount < columns.size()) {
-
MessageHandler.errorln("WARNING: Number of cell columns under table-row not equal to
number of table-columns");
- return new Status(Status.OK);
- }
- }
-
- int numChildren = this.children.size();
- // if (numChildren != columns.size()) {
- // MessageHandler.errorln("WARNING: Number of
children under table-row not equal to number of table-columns");
- // return new Status(Status.OK);
- // }
-
- // added by Eric Schaeffer
- largestCellHeight = 0;
-
- // added by Hani Elabed 11/27/2000
- boolean someCellDidNotLayoutCompletely = false;
-
- // If it takes multiple calls to completely layout the
row, we need to process
- // all of the children (cells) not just those from the
marker so that the borders
- // will be drawn properly.
- for (int i = 0; i < numChildren; i++) {
- TableCell cell = (TableCell)
children.elementAt(i);
-
- // added by Hani Elabed 11/22/2000
- CellState cellState = (CellState)
cells.elementAt(i);
-
- //--- this is modified to preserve the
state of start
- //--- offset of the cell.
- //--- change by Hani Elabed 11/22/2000
-
cell.setStartOffset(cellState.getWidthOfCellSoFar());
-
- // Each column in the row should start
with the same height available
- // True: we now don't set the row
height until all cells in it are
- // (at least partially) composed, so
this is not necssary.
- // -Karen Lease, 01 may 2001
-// if ( i > 0 )
-// {
-//
areaContainer.increaseHeight(areaContainer.spaceLeft() - areaContainer.getMaxHeight()
- spaceLeft + origMaxHeight);
-//
areaContainer.setMaxHeight(spaceLeft);
-// }
-
- Status status;
- if ((status =
cell.layout(areaContainer)).isIncomplete()) {
- this.marker = i;
- if (status.getCode()
== Status.AREA_FULL_SOME) {
- //
this whole block added by
- //
Hani Elabed 11/27/2000
-
-
cellState.setLayoutComplete(false);
-
someCellDidNotLayoutCompletely = true;
- } else {
- /*
None of the cell content was laid out.
- * In
this case, we stop doing this row and
- *
reset the marker to start it in the next
- *
column or page. Note that the row height hasn't been
- * set
and the row area hasn't yet
- *
been added to its parent at this point!
- */
-
- //
added on 11/28/2000, by Dresdner Bank, Germany
- if
(spacer != null) {
-
area.increaseHeight(-spaceBefore);
-
// area.removeChild(spacer);
-
// spacer = null;
- }
-//
hasAddedSpacer = false;
-//
if(spacerAfter != null)
-//
area.removeChild(spacerAfter);
-//
spacerAfter = null;
-
- //
removing something that was added by succession
- // of
cell.layout()
- //
just to keep my sanity here, Hani
- //
area.increaseHeight(areaContainer.getHeight());
- //
area.removeChild(areaContainer);
-
this.resetMarker();
-
this.removeID(area.getIDReferences());
-
- //
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;
- }
- }
-
- // This is in case a float was composed in the cells
- area.setMaxHeight(area.getMaxHeight() - spaceLeft +
-
this.areaContainer.getMaxHeight());
-
- for (int i = 0; i < numChildren; i++) {
- TableCell cell = (TableCell)
children.elementAt(i);
- cell.setRowHeight(largestCellHeight);
- }
-
- // added by Dresdner Bank, Germany
- if (!hasAddedSpacer && spacer != null) {
- area.addChild(spacer);
- hasAddedSpacer = true;
- }
-
- area.addChild(areaContainer);
- areaContainer.setHeight(largestCellHeight);
- areaAdded = true;
- areaContainer.end();
-
- /* The method addDisplaySpace increases both the
content
- * height of the parent area (table body, head or
footer) and
- * also its "absolute height". So we don't need to do
this
- * explicitly.
- *
- * Note: it doesn't look from the CR as though we
should take
- * into account borders and padding on rows, only
background.
- * The exception is perhaps if the borders are
"collapsed", but
- * they should still be rendered only on cells and not
on the
- * rows themselves. (Karen Lease - 01may2001)
- */
- area.addDisplaySpace(largestCellHeight +
-
areaContainer.getPaddingTop() +
-
areaContainer.getBorderTopWidth() +
-
areaContainer.getPaddingBottom() +
-
areaContainer.getBorderBottomWidth());
-
-
- if (!someCellDidNotLayoutCompletely && spaceAfter !=
0) {
- spacerAfter = new
DisplaySpace(spaceAfter);
- area.addChild(spacerAfter);
- area.increaseHeight(spaceAfter);
- }
-
-
- // replaced by Hani Elabed 11/27/2000
- //return new Status(Status.OK);
-
- if (someCellDidNotLayoutCompletely) {
- return new
Status(Status.AREA_FULL_SOME);
- } else {
- if (breakAfter == BreakAfter.PAGE) {
- this.marker = BREAK_AFTER;
- return new
Status(Status.FORCE_PAGE_BREAK);
- }
-
- if (breakAfter == BreakAfter.ODD_PAGE) {
- this.marker = BREAK_AFTER;
- return new
Status(Status.FORCE_PAGE_BREAK_ODD);
- }
-
- if (breakAfter == BreakAfter.EVEN_PAGE) {
- this.marker = BREAK_AFTER;
- return new
Status(Status.FORCE_PAGE_BREAK_EVEN);
- }
-
- if (breakAfter == BreakAfter.COLUMN) {
- this.marker = BREAK_AFTER;
- return new
Status(Status.FORCE_COLUMN_BREAK);
- }
- if (keepWithNext.getType() !=
KeepValue.KEEP_WITH_AUTO) {
- return new
Status(Status.KEEP_WITH_NEXT);
- }
- return new Status(Status.OK);
- }
+ }
- }
-
- public int getAreaHeight() {
- return areaContainer.getHeight();
- }
-
- public void removeLayout(Area area) {
- if (spacer != null) {
- if(hasAddedSpacer) {
-
area.removeChild(spacer);
- } else {
-
area.increaseHeight(-spaceBefore);
- }
- }
- if(spacerAfter != null)
- area.removeChild(spacerAfter);
- //area.increaseHeight(areaContainer.getHeight());
- if(areaAdded)
- area.removeChild(areaContainer);
- areaAdded = false;
- this.resetMarker();
- this.removeID(area.getIDReferences());
- }
-
- public void resetMarker()
- {
- super.resetMarker();
- spacer = null;
- spacerAfter = null;
- hasAddedSpacer = false;
- cells = null;
- }
+ this.marker = 0;
+ int breakStatus = propMgr.checkBreakBefore();
+ if (breakStatus != Status.OK)
+ return new Status(breakStatus);
+ }
+
+ // if (marker == 0 && configID) {
+ if (marker == 0) { // KDL: need to do this if thrown or if split?
+ // configure id
+ area.getIDReferences().configureID(id, area);
+ }
+
+ int spaceLeft = area.spaceLeft();
+
+ this.areaContainer =
+ new AreaContainer(propMgr.getFontState(area.getFontInfo()),
+ 0,0,
+ area.getContentWidth(),
+ spaceLeft,
+ Position.RELATIVE);
+ areaContainer.foCreator=this; // G Seshadri
+ areaContainer.setPage(area.getPage());
+
+ areaContainer.setBackgroundColor(backgroundColor);
+ areaContainer.start();
+
+ areaContainer.setAbsoluteHeight(area.getAbsoluteHeight());
+ areaContainer.setIDReferences(area.getIDReferences());
+
+ largestCellHeight = 0;
+
+ // Flag indicaing whether any cell didn't fit in available space
+ boolean someCellDidNotLayoutCompletely = false;
+
+ /* If it takes multiple calls to completely layout the row,
+ * we need to process all of the children (cells)
+ * not just those from the marker so that the borders
+ * will be drawn properly.
+ */
+ int offset=0; // Offset of each cell from table start edge
+ int iColIndex = 0; // 1-based column index
+ Enumeration eCols = columns.elements();
+ /* Ideas: set offset on each column when they are initialized
+ * no need to calculate for each row.
+ * Pass column object to cell to get offset and width and border
+ * info if borders are "collapsed".
+ */
+
+ while (eCols.hasMoreElements()) {
+ TableCell cell;
+ ++iColIndex;
+ TableColumn tcol = (TableColumn)eCols.nextElement();
+ int colWidth = tcol.getColumnWidth();
+ if (cellArray.getCellType(iColIndex) == CellArray.CELLSTART) {
+ cell = cellArray.getCell(iColIndex);
+ } else {
+ /* If this cell is spanned from a previous row,
+ * and this is the last row, get the remaining height
+ * and use it to increase maxCellHeight if necessary
+ */
+ if (rowSpanMgr.isInLastRow(iColIndex)) {
+ int h = rowSpanMgr.getRemainingHeight(iColIndex);
+ if (h > largestCellHeight)
+ largestCellHeight = h;
+ }
+ offset += colWidth;
+ continue;
+ }
+ // cell.setTableColumn(tcol);
+ cell.setStartOffset(offset);
+ offset += colWidth;
+
+
+ int rowSpan = cell.getNumRowsSpanned();
+ Status status;
+ if ((status = cell.layout(areaContainer)).isIncomplete()) {
+ if ((keepTogether.getType() == KeepValue.KEEP_WITH_ALWAYS) ||
+ (status.getCode() == Status.AREA_FULL_NONE) ||
+ rowSpan > 1) {
+ // We will put this row into the next column/page
+ // Note: the only time this shouldn't be honored is
+ // if this row is at the top of the column area.
+ // Remove spanning cells from RowSpanMgr?
+ this.resetMarker();
+ this.removeID(area.getIDReferences());
+ return new Status(Status.AREA_FULL_NONE);
+ }
+ else if (status.getCode() == Status.AREA_FULL_SOME) {
+ /* Row is not keep-together, cell isn't spanning
+ * and part of it fits. We can break the cell and
+ * the row.
+ */
+ someCellDidNotLayoutCompletely = true;
+ }
+ } //else {
+ // layout was complete for a particular cell
+ int h = cell.getHeight(); // allocation height of cell
+ if (rowSpan > 1) { // pass cell fo or area???
+ rowSpanMgr.addRowSpan(cell, iColIndex,
+ cell.getNumColumnsSpanned(), h, rowSpan);
+ }
+ else if (h > largestCellHeight) {
+ largestCellHeight = h;
+ }
+ // }
+ } // end of loop over all columns/cells
+
+ // This is in case a float was composed in the cells
+ area.setMaxHeight(area.getMaxHeight() - spaceLeft +
+ this.areaContainer.getMaxHeight());
+
+ // Only do this for "STARTCELL", ending spans are handled separately
+ // What about empty cells? Yes, we should set their height too!
+ for (int iCol = 1; iCol <= columns.size(); iCol++) {
+ if (cellArray.getCellType(iCol) == CellArray.CELLSTART) {
+ cellArray.getCell(iCol).setRowHeight(largestCellHeight);
+ }
+ }
+
+ // Adjust spanning row information
+ // ??? what if some cells are broken???
+ rowSpanMgr.finishRow(largestCellHeight);
+
+ area.addChild(areaContainer);
+ areaContainer.setHeight(largestCellHeight);
+ areaAdded = true;
+ areaContainer.end();
+
+ /* The method addDisplaySpace increases both the content
+ * height of the parent area (table body, head or footer) and
+ * also its "absolute height". So we don't need to do this
+ * explicitly.
+ *
+ * Note: it doesn't look from the CR as though we should take
+ * into account borders and padding on rows, only background.
+ * The exception is perhaps if the borders are "collapsed", but
+ * they should still be rendered only on cells and not on the
+ * rows themselves. (Karen Lease - 01may2001)
+ */
+ area.addDisplaySpace(largestCellHeight +
+ areaContainer.getPaddingTop() +
+ areaContainer.getBorderTopWidth() +
+ areaContainer.getPaddingBottom() +
+ areaContainer.getBorderBottomWidth());
+
+
+ // replaced by Hani Elabed 11/27/2000
+ //return new Status(Status.OK);
+
+ if (someCellDidNotLayoutCompletely) {
+ return new Status(Status.AREA_FULL_SOME);
+ } else {
+ if (rowSpanMgr.hasUnfinishedSpans()) {
+ // Ignore break after if row span!
+ return new Status(Status.KEEP_WITH_NEXT);
+ }
+ if (breakAfter == BreakAfter.PAGE) {
+ this.marker = BREAK_AFTER;
+ return new Status(Status.FORCE_PAGE_BREAK);
+ }
+
+ if (breakAfter == BreakAfter.ODD_PAGE) {
+ this.marker = BREAK_AFTER;
+ return new Status(Status.FORCE_PAGE_BREAK_ODD);
+ }
+
+ if (breakAfter == BreakAfter.EVEN_PAGE) {
+ this.marker = BREAK_AFTER;
+ return new Status(Status.FORCE_PAGE_BREAK_EVEN);
+ }
+
+ if (breakAfter == BreakAfter.COLUMN) {
+ this.marker = BREAK_AFTER;
+ return new Status(Status.FORCE_COLUMN_BREAK);
+ }
+ if (keepWithNext.getType() != KeepValue.KEEP_WITH_AUTO) {
+ return new Status(Status.KEEP_WITH_NEXT);
+ }
+ return new Status(Status.OK);
+ }
+
+ }
+
+ public int getAreaHeight() {
+ return areaContainer.getHeight();
+ }
+
+ public void removeLayout(Area area) {
+ if(areaAdded)
+ area.removeChild(areaContainer);
+ areaAdded = false;
+ this.resetMarker();
+ this.removeID(area.getIDReferences());
+ }
+
+ public void resetMarker()
+ {
+ super.resetMarker();
+ // Just reset all the states to not laid out and fix up row spans
+ }
+
+ /**
+ * Called by parent FO to initialize information about
+ * cells started in previous rows which span into this row.
+ * The layout operation modifies rowSpanMgr
+ */
+ public void setRowSpanMgr(RowSpanMgr rowSpanMgr) {
+ this.rowSpanMgr = rowSpanMgr;
+ }
+
+ /**
+ * Before starting layout for the first time, initialize information
+ * about spanning rows, empty cells and spanning columns.
+ */
+ private void initCellArray() {
+ cellArray = new CellArray(rowSpanMgr, columns.size());
+ int colNum = 1;
+ Enumeration eCells = children.elements();
+ while (eCells.hasMoreElements()) {
+ colNum = cellArray.getNextFreeCell(colNum);
+ // If off the end, the rest of the cells had better be
+ // explicitly positioned!!! (returns -1)
+
+ TableCell cell = (TableCell) eCells.nextElement();
+ int numCols = cell.getNumColumnsSpanned();
+ int numRows = cell.getNumRowsSpanned();
+ int cellColNum = cell.getColumnNumber();
+
+ if (cellColNum == 0) {
+ // Not explicitly specified, so put in next available colummn
+ // cell.setColumnNumber(colNum);
+ // If cellColNum "off the end", this cell is in limbo!
+ if (colNum < 1) {
+ // ERROR!!!
+ continue;
+ }
+ else cellColNum = colNum;
+ }
+ else if (cellColNum > columns.size()) {
+ // Explicit specification out of range!
+ // Skip it and print an ERROR MESSAGE
+ continue;
+ }
+ // see if it fits and doesn't overwrite anything
+ if (cellColNum + numCols - 1 > columns.size()) {
+ // MESSAGE: TOO MANY COLUMNS SPANNED!
+ numCols = columns.size() - cellColNum + 1;
+ }
+ // Check for overwriting other cells (returns false)
+ if (cellArray.storeCell(cell, cellColNum, numCols) == false) {
+ // Print out some kind of warning message.
+ }
+ if (cellColNum > colNum) {
+ // Cells are initialized as empty already
+ colNum = cellColNum;
+ }
+ else if (cellColNum < colNum) {
+ // MESSAGE ? cells out of order?
+ colNum = cellColNum; // CR "to the letter"!
+ }
+ int cellWidth = getCellWidth(cellColNum, numCols);
+ cell.setWidth(cellWidth);
+ colNum += numCols; // next cell in this column
+ }
+ }
+
+ // ATTENTION if startCol + numCols > number of columns in table!
+ private int getCellWidth(int startCol, int numCols) {
+ int width = 0;
+ for (int count = 0; count < numCols; count++) {
+ width += ((TableColumn)
columns.elementAt(startCol+count-1)).getColumnWidth();
+ }
+ return width;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]