aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/layoutmgr/table
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2005-02-08 16:25:12 +0000
committerJeremias Maerki <jeremias@apache.org>2005-02-08 16:25:12 +0000
commitf64b3f5563ca8af4d2d0ffdc8a669c072cfa7d34 (patch)
treec153bb1a149c5e316c3c3ea6a1f98458443a41f5 /src/java/org/apache/fop/layoutmgr/table
parent692ba9ae389a092ffac93f0ab4859b1e55767bab (diff)
downloadxmlgraphics-fop-f64b3f5563ca8af4d2d0ffdc8a669c072cfa7d34.tar.gz
xmlgraphics-fop-f64b3f5563ca8af4d2d0ffdc8a669c072cfa7d34.zip
Support for column-number on table-cell.
RowLM now also handles gaps (=empty cells) properly. Positioning of cells inside the row changed. More responsibility into getNextBreakPoss stage because it is a lot easier to implement and there's less redundancy. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198396 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/layoutmgr/table')
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/Cell.java25
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/Row.java241
2 files changed, 191 insertions, 75 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/table/Cell.java b/src/java/org/apache/fop/layoutmgr/table/Cell.java
index 4acb8e59e..79f3dcc26 100644
--- a/src/java/org/apache/fop/layoutmgr/table/Cell.java
+++ b/src/java/org/apache/fop/layoutmgr/table/Cell.java
@@ -50,6 +50,8 @@ public class Cell extends BlockStackingLayoutManager {
private List childBreaks = new ArrayList();
+ private int inRowIPDOffset;
+
private int xoffset;
private int yoffset;
private int referenceIPD;
@@ -72,11 +74,6 @@ public class Cell extends BlockStackingLayoutManager {
return this.fobj;
}
- /** @return this cell's reference IPD */
- public int getReferenceIPD() {
- return this.referenceIPD;
- }
-
private int getIPIndents() {
int iIndents = 0;
iIndents += fobj.getCommonBorderPaddingBackground().getIPPaddingAndBorder(false);
@@ -188,8 +185,8 @@ public class Cell extends BlockStackingLayoutManager {
}
/**
- * Set the x offset of this cell.
- * This offset is used to set the absolute position of the cell.
+ * Set the x offset of this cell (usually the same as its parent row).
+ * This offset is used to determine the absolute position of the cell.
*
* @param off the x offset
*/
@@ -198,6 +195,15 @@ public class Cell extends BlockStackingLayoutManager {
}
/**
+ * Set the IPD offset of this cell inside the table-row.
+ * This offset is used to determine the absolute position of the cell.
+ * @param off the IPD offset
+ */
+ public void setInRowIPDOffset(int off) {
+ this.inRowIPDOffset = off;
+ }
+
+ /**
* Set the row height that contains this cell. This method is used during
* addAreas() stage.
*
@@ -285,7 +291,8 @@ public class Cell extends BlockStackingLayoutManager {
curBlockArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
curBlockArea.setPositioning(Block.ABSOLUTE);
// set position
- int x = xoffset; //mimic start-indent
+ int x = xoffset + inRowIPDOffset;
+ //mimic start-indent
x += fobj.getCommonBorderPaddingBackground().getBorderStartWidth(false);
curBlockArea.setXOffset(x);
curBlockArea.setYOffset(yoffset);
@@ -294,8 +301,6 @@ public class Cell extends BlockStackingLayoutManager {
// Set up dimensions
Area parentArea = parentLM.getParentArea(curBlockArea);
- int referenceIPD = parentArea.getIPD();
- //curBlockArea.setIPD(referenceIPD);
// Get reference IPD from parentArea
setCurrentArea(curBlockArea); // ??? for generic operations
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/Row.java b/src/java/org/apache/fop/layoutmgr/table/Row.java
index 24a97a811..9747af908 100644
--- a/src/java/org/apache/fop/layoutmgr/table/Row.java
+++ b/src/java/org/apache/fop/layoutmgr/table/Row.java
@@ -20,6 +20,7 @@ package org.apache.fop.layoutmgr.table;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.flow.Table;
+import org.apache.fop.fo.flow.TableCell;
import org.apache.fop.fo.flow.TableRow;
import org.apache.fop.fo.properties.LengthRangeProperty;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
@@ -40,6 +41,7 @@ import org.apache.fop.traits.MinOptMax;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
+import java.util.ListIterator;
/**
* LayoutManager for a table-row FO.
@@ -49,6 +51,14 @@ import java.util.List;
* but effect the occupied columns of future rows.
*/
public class Row extends BlockStackingLayoutManager {
+
+ /** Used by CellInfo: Indicates start of cell. */
+ public static final int CI_START_OF_CELL = 0;
+ /** Used by CellInfo: Indicates part of a spanned cell in column direction. */
+ public static final int CI_COL_SPAN = 1;
+ /** Used by CellInfo: Indicates part of a spanned cell in row direction. */
+ public static final int CI_ROW_SPAN = 2;
+
private TableRow fobj;
private List cellList = null;
@@ -96,30 +106,77 @@ public class Row extends BlockStackingLayoutManager {
}
private void setupCells() {
- cellList = new ArrayList();
+ cellList = new java.util.ArrayList();
+ List availableCells = new java.util.ArrayList();
// add cells to list
while (childLMiter.hasNext()) {
curChildLM = (LayoutManager) childLMiter.next();
curChildLM.setParent(this);
curChildLM.initialize();
- cellList.add(curChildLM);
+ availableCells.add(curChildLM);
+ }
+
+ //Transfer available cells to their slots
+ int colnum = 1;
+ ListIterator iter = availableCells.listIterator();
+ while (iter.hasNext()) {
+ Cell cellLM = (Cell)iter.next();
+ TableCell cell = cellLM.getFObj();
+ if (cell.hasColumnNumber()) {
+ colnum = cell.getColumnNumber();
+ }
+ while (colnum > cellList.size()) {
+ cellList.add(null);
+ }
+ if (cellList.get(colnum - 1) != null) {
+ log.error("Overlapping cell at position " + colnum);
+ }
+ //Add cell info for primary slot
+ cellList.set(colnum - 1, new CellInfo(cellLM));
+
+ //Add cell infos on spanned slots if any
+ for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
+ colnum++;
+ if (colnum > cellList.size()) {
+ cellList.add(new CellInfo(CI_COL_SPAN));
+ } else {
+ if (cellList.get(colnum - 1) != null) {
+ log.error("Overlapping cell at position " + colnum);
+ }
+ cellList.set(colnum - 1, new CellInfo(CI_COL_SPAN));
+ }
+ }
+ colnum++;
+ }
+
+ //Post-processing the list (looking for gaps)
+ int pos = 1;
+ ListIterator ppIter = cellList.listIterator();
+ while (ppIter.hasNext()) {
+ CellInfo cellInfo = (CellInfo)ppIter.next();
+ if (cellInfo == null) {
+ //Add cell info on empty cell
+ ppIter.set(new CellInfo(CI_START_OF_CELL));
+ }
+ pos++;
}
}
/**
- * Get the layout manager for a cell.
+ * Get the cell info for a cell.
*
- * @param pos the position of the cell
- * @return the cell layout manager
+ * @param pos the position of the cell (must be >= 1)
+ * @return the cell info object
*/
- protected Cell getCellLM(int pos) {
+ protected CellInfo getCellInfo(int pos) {
if (cellList == null) {
setupCells();
}
- if (pos < cellList.size()) {
- return (Cell)cellList.get(pos);
+ if (pos <= cellList.size()) {
+ return (CellInfo)cellList.get(pos - 1);
+ } else {
+ return null;
}
- return null;
}
/**
@@ -131,7 +188,8 @@ public class Row extends BlockStackingLayoutManager {
* @return the next break possibility
*/
public BreakPoss getNextBreakPoss(LayoutContext context) {
- LayoutManager curLM; // currently active LM
+ //LayoutManager curLM; // currently active LM
+ CellInfo curCellInfo; //currently active cell info
BreakPoss lastPos = null;
List breakList = new java.util.ArrayList();
@@ -141,12 +199,19 @@ public class Row extends BlockStackingLayoutManager {
int opt = 0;
int max = 0;
+ // This is used for the displacement of the individual cells
+ int ipdOffset = 0;
+
int startColumn = 1;
- int cellLMIndex = 0;
boolean over = false;
- while ((curLM = getCellLM(cellLMIndex++)) != null) {
- Cell cellLM = (Cell)curLM;
+ while ((curCellInfo = getCellInfo(startColumn)) != null) {
+ Cell cellLM = curCellInfo.layoutManager;
+ if (curCellInfo.isColSpan()) {
+ //skip spanned slots
+ startColumn++;
+ continue;
+ }
List childBreaks = new ArrayList();
MinOptMax stackSize = new MinOptMax();
@@ -161,6 +226,7 @@ public class Row extends BlockStackingLayoutManager {
MinOptMax.subtract(context.getStackLimit(),
stackSize));
+ //Determine which columns this cell will occupy
getColumnsForCell(cellLM, startColumn, spannedColumns);
int childRefIPD = 0;
Iterator i = spannedColumns.iterator();
@@ -175,35 +241,52 @@ public class Row extends BlockStackingLayoutManager {
}
childLC.setRefIPD(childRefIPD);
- while (!curLM.isFinished()) {
- if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
- if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) {
- // reset to last break
- if (lastPos != null) {
- LayoutManager lm = lastPos.getLayoutManager();
- lm.resetPosition(lastPos.getPosition());
- if (lm != curLM) {
- curLM.resetPosition(null);
+ if (cellLM != null) {
+ cellLM.setInRowIPDOffset(ipdOffset);
+ while (!cellLM.isFinished()) {
+ if ((bp = cellLM.getNextBreakPoss(childLC)) != null) {
+ if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) {
+ // reset to last break
+ if (lastPos != null) {
+ LayoutManager lm = lastPos.getLayoutManager();
+ lm.resetPosition(lastPos.getPosition());
+ if (lm != cellLM) {
+ cellLM.resetPosition(null);
+ }
+ } else {
+ cellLM.resetPosition(null);
}
- } else {
- curLM.resetPosition(null);
+ over = true;
+ break;
}
- over = true;
- break;
- }
- stackSize.add(bp.getStackingSize());
- lastPos = bp;
- childBreaks.add(bp);
+ stackSize.add(bp.getStackingSize());
+ lastPos = bp;
+ childBreaks.add(bp);
- if (bp.nextBreakOverflows()) {
- over = true;
- break;
- }
+ if (bp.nextBreakOverflows()) {
+ over = true;
+ break;
+ }
- childLC.setStackLimit(MinOptMax.subtract(
- context.getStackLimit(), stackSize));
+ childLC.setStackLimit(MinOptMax.subtract(
+ context.getStackLimit(), stackSize));
+ }
}
+ startColumn += cellLM.getFObj().getNumberColumnsSpanned();
+ } else {
+ //Skipping empty cells
+ //log.debug("empty cell at pos " + startColumn);
+ startColumn++;
+ }
+
+ //Adjust in-row x offset for individual cells
+ //TODO Probably needs more work to support writing modes
+ ipdOffset += childRefIPD;
+ if (getTable().getBorderCollapse() == EN_SEPARATE) {
+ ipdOffset += getTable().getBorderSeparation().getIPD().getLength().getValue();
}
+
+
// the min is the maximum min of all cells
if (stackSize.min > min) {
min = stackSize.min;
@@ -217,9 +300,9 @@ public class Row extends BlockStackingLayoutManager {
max = stackSize.max;
}
- breakList.add(childBreaks);
-
- startColumn += cellLM.getFObj().getNumberColumnsSpanned();
+ if (childBreaks.size() > 0) {
+ breakList.add(childBreaks);
+ }
}
MinOptMax rowSize = new MinOptMax(min, opt, max);
LengthRangeProperty specifiedBPD = fobj.getBlockProgressionDimension();
@@ -234,13 +317,20 @@ public class Row extends BlockStackingLayoutManager {
rowHeight = rowSize.opt;
boolean fin = true;
- cellLMIndex = 0;
+ startColumn = 1;
//Check if any of the cell LMs haven't finished, yet
- while ((curLM = getCellLM(cellLMIndex++)) != null) {
- if (!curLM.isFinished()) {
+ while ((curCellInfo = getCellInfo(startColumn)) != null) {
+ Cell cellLM = curCellInfo.layoutManager;
+ if (cellLM == null) {
+ //skip empty cell
+ startColumn++;
+ continue;
+ }
+ if (!cellLM.isFinished()) {
fin = false;
break;
}
+ startColumn += cellLM.getFObj().getNumberColumnsSpanned();
}
setFinished(fin);
@@ -274,7 +364,12 @@ public class Row extends BlockStackingLayoutManager {
* @param spannedColumns List to receive the applicable columns
*/
private void getColumnsForCell(Cell cellLM, int startCell, List spannedColumns) {
- int count = cellLM.getFObj().getNumberColumnsSpanned();
+ int count;
+ if (cellLM != null) {
+ count = cellLM.getFObj().getNumberColumnsSpanned();
+ } else {
+ count = 1;
+ }
spannedColumns.clear();
for (int i = 0; i < count; i++) {
spannedColumns.add(getColumn(startCell + i));
@@ -290,22 +385,28 @@ public class Row extends BlockStackingLayoutManager {
* If pos is null, then back up to the first child LM.
*/
protected void reset(Position pos) {
- LayoutManager curLM; // currently active LM
- int cellcount = 0;
+ //LayoutManager curLM; // currently active LM
+ CellInfo curCellInfo;
+ int cellIndex = 0;
if (pos == null) {
- while ((curLM = getCellLM(cellcount)) != null) {
- curLM.resetPosition(null);
- cellcount++;
+ while ((curCellInfo = getCellInfo(cellIndex)) != null) {
+ if (curCellInfo.layoutManager != null) {
+ curCellInfo.layoutManager.resetPosition(null);
+ }
+ cellIndex++;
}
} else {
RowPosition rpos = (RowPosition)pos;
List breaks = rpos.cellBreaks;
- while ((curLM = getCellLM(cellcount)) != null) {
- List childbreaks = (List)breaks.get(cellcount);
- curLM.resetPosition((Position)childbreaks.get(childbreaks.size() - 1));
- cellcount++;
+ while ((curCellInfo = getCellInfo(cellIndex)) != null) {
+ if (curCellInfo.layoutManager != null) {
+ List childbreaks = (List)breaks.get(cellIndex);
+ curCellInfo.layoutManager.resetPosition(
+ (Position)childbreaks.get(childbreaks.size() - 1));
+ }
+ cellIndex++;
}
}
@@ -364,30 +465,18 @@ public class Row extends BlockStackingLayoutManager {
parentLM.addChild(rowArea);
}
- int cellcount = 0;
- int x = this.xoffset;
- //int x = (TableLayoutManager)getParent()).;
for (Iterator iter = lfp.cellBreaks.iterator(); iter.hasNext();) {
List cellsbr = (List)iter.next();
BreakPossPosIter breakPosIter;
breakPosIter = new BreakPossPosIter(cellsbr, 0, cellsbr.size());
iStartPos = lfp.getLeafPos() + 1;
- int cellWidth = 0;
while ((childLM = (Cell)breakPosIter.getNextChildLM()) != null) {
- cellWidth = childLM.getReferenceIPD();
- childLM.setXOffset(x);
+ childLM.setXOffset(xoffset);
childLM.setYOffset(yoffset);
childLM.setRowHeight(rowHeight);
childLM.addAreas(breakPosIter, lc);
}
- x += cellWidth;
-
- //Handle border-separation
- Table table = getTable();
- if (table.getBorderCollapse() == EN_SEPARATE) {
- x += table.getBorderSeparation().getIPD().getLength().getValue();
- }
}
}
@@ -461,5 +550,27 @@ public class Row extends BlockStackingLayoutManager {
}
}
+ private class CellInfo {
+
+ /** layout manager for this cell, may be null */
+ public Cell layoutManager;
+ /** flags for this cell, on of Row.CI_* */
+ public int flags = CI_START_OF_CELL;
+
+ public CellInfo(Cell layoutManager) {
+ this.layoutManager = layoutManager;
+ }
+
+ public CellInfo(int flags) {
+ this.flags = flags;
+ }
+
+ /** @return true if the cell is part of a span in column direction */
+ public boolean isColSpan() {
+ return (flags & CI_COL_SPAN) != 0;
+ }
+
+ }
+
}