Browse Source

Implementation for initial values of the column-number property

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@289865 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_90-alpha1
Andreas L. Delmelle 18 years ago
parent
commit
3aedc53326

+ 2
- 3
src/java/org/apache/fop/fo/FOPropertyMapping.java View File

@@ -28,6 +28,7 @@ import org.apache.fop.fo.properties.BorderWidthPropertyMaker;
import org.apache.fop.fo.properties.BoxPropShorthandParser;
import org.apache.fop.fo.properties.CharacterProperty;
import org.apache.fop.fo.properties.ColorTypeProperty;
import org.apache.fop.fo.properties.ColumnNumberPropertyMaker;
import org.apache.fop.fo.properties.CondLengthProperty;
import org.apache.fop.fo.properties.CorrespondingPropertyMaker;
import org.apache.fop.fo.properties.DimensionPropertyMaker;
@@ -2386,9 +2387,7 @@ public class FOPropertyMapping implements Constants {
addPropertyMaker("caption-side", m);

// column-number
m = new NumberProperty.Maker(PR_COLUMN_NUMBER);
m.setInherited(false);
m.setDefault("0");
m = new ColumnNumberPropertyMaker(PR_COLUMN_NUMBER);
addPropertyMaker("column-number", m);

// column-width

+ 79
- 14
src/java/org/apache/fop/fo/flow/Table.java View File

@@ -18,6 +18,7 @@

package org.apache.fop.fo.flow;

import java.util.BitSet;
import java.util.List;

import org.xml.sax.Locator;
@@ -41,7 +42,7 @@ import org.apache.fop.fo.properties.LengthRangeProperty;
/**
* Class modelling the fo:table object.
*/
public class Table extends FObj {
public class Table extends TableFObj {
// The value of properties relevant for fo:table.
private CommonAccessibility commonAccessibility;
private CommonAural commonAural;
@@ -49,12 +50,8 @@ public class Table extends FObj {
private CommonMarginBlock commonMarginBlock;
private CommonRelativePosition commonRelativePosition;
private LengthRangeProperty blockProgressionDimension;
private Numeric borderAfterPrecedence;
private Numeric borderBeforePrecedence;
private int borderCollapse;
private Numeric borderEndPrecedence;
private LengthPairProperty borderSeparation;
private Numeric borderStartPrecedence;
private int breakAfter;
private int breakBefore;
private String id;
@@ -75,6 +72,8 @@ public class Table extends FObj {

/** collection of columns in this table */
protected List columns = null;
private BitSet usedColumnIndices = new BitSet();
private int columnIndex = 1;
private TableBody tableHeader = null;
private TableBody tableFooter = null;
@@ -106,12 +105,8 @@ public class Table extends FObj {
commonMarginBlock = pList.getMarginBlockProps();
commonRelativePosition = pList.getRelativePositionProps();
blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
borderAfterPrecedence = pList.get(PR_BORDER_AFTER_PRECEDENCE).getNumeric();
borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric();
borderCollapse = pList.get(PR_BORDER_COLLAPSE).getEnum();
borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric();
borderSeparation = pList.get(PR_BORDER_SEPARATION).getLengthPair();
borderStartPrecedence = pList.get(PR_BORDER_START_PRECEDENCE).getNumeric();
breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
id = pList.get(PR_ID).getString();
@@ -126,6 +121,7 @@ public class Table extends FObj {
tableOmitHeaderAtBreak = pList.get(PR_TABLE_OMIT_HEADER_AT_BREAK).getEnum();
//width = pList.get(PR_WIDTH).getLength();
writingMode = pList.get(PR_WRITING_MODE).getEnum();
super.bind(pList);

//Create default column in case no table-columns will be defined.
defaultColumn = new TableColumn(this, true);
@@ -213,7 +209,8 @@ public class Table extends FObj {
missingChildElementError(
"(marker*,table-column*,table-header?,table-footer?,table-body+)");
}

//release reference
usedColumnIndices = null;
getFOEventHandler().endTable(this);
}

@@ -222,10 +219,7 @@ public class Table extends FObj {
*/
protected void addChildNode(FONode child) throws FOPException {
if (child.getName().equals("fo:table-column")) {
if (columns == null) {
columns = new java.util.ArrayList();
}
columns.add(((TableColumn)child));
addColumnNode((TableColumn) child);
} else if (child.getName().equals("fo:table-footer")) {
tableFooter = (TableBody)child;
} else if (child.getName().equals("fo:table-header")) {
@@ -236,6 +230,48 @@ public class Table extends FObj {
}
}

/**
* Adds a column to the columns List, and updates the columnIndex
* used for determining initial values for column-number
*
* @param col the column to add
* @throws FOPException
*/
private void addColumnNode(TableColumn col) throws FOPException {
int colNumber = col.getColumnNumber();
int colRepeat = col.getNumberColumnsRepeated();
if (columns == null) {
columns = new java.util.ArrayList();
}
if( columns.size() < colNumber ) {
//add nulls for non-occupied indices between
//the last column up to and including the current one
while( columns.size() < colNumber ) {
columns.add(null);
}
}
//replace the null-value with the actual column
columns.set(colNumber - 1, col);
if( colRepeat > 1 ) {
//in case column is repeated:
//for the time being, add the same column
//(colRepeat - 1) times to the columns list
//TODO: need to force the column-number
//TODO: need to make sure START/END BorderInfo
// are completely independent instances (clones?)
// = necessary for border-collapse="collapse"
// if collapsing is handled in FOTree
for( int i = colRepeat - 1; --i >= 0; ) {
columns.add(col);
}
}
//flag column indices used by this column
usedColumnIndices.set(colNumber - 1, colNumber - 1 + colRepeat);
//set index for the next column to use
while( usedColumnIndices.get(columnIndex - 1) ) {
columnIndex++;
}
}
/** @return true of table-layout="auto" */
public boolean isAutoLayout() {
return (tableLayout != EN_FIXED);
@@ -376,4 +412,33 @@ public class Table extends FObj {
public int getNameId() {
return FO_TABLE;
}

/**
* Returns the current column index of the Table
*
* @return the next column number to use
*/
public int getCurrentColumnIndex() {
return columnIndex;
}

/**
* Sets the current column index of the given Table
* (used by TableColumn.bind() in case the column-number
* was explicitly specified)
*
*/
protected void setCurrentColumnIndex(int newIndex) {
columnIndex = newIndex;
}

/**
* Checks if a certain column-number is already occupied
*
* @param colNr the column-number to check
* @return true if column-number is already in use
*/
protected boolean isColumnNumberUsed(int colNr) {
return usedColumnIndices.get(colNr - 1);
}
}

+ 191
- 12
src/java/org/apache/fop/fo/flow/TableBody.java View File

@@ -19,6 +19,7 @@
package org.apache.fop.fo.flow;

// Java
import java.util.BitSet;
import java.util.Iterator;
import java.util.List;

@@ -39,23 +40,24 @@ import org.apache.fop.fo.properties.CommonRelativePosition;
/**
* Class modelling the fo:table-body object.
*/
public class TableBody extends FObj {
public class TableBody extends TableFObj {
// The value of properties relevant for fo:table-body.
private CommonAccessibility commonAccessibility;
private CommonAural commonAural;
private CommonBorderPaddingBackground commonBorderPaddingBackground;
private CommonRelativePosition commonRelativePosition;
private Numeric borderAfterPrecedence;
private Numeric borderBeforePrecedence;
private Numeric borderEndPrecedence;
private Numeric borderStartPrecedence;
private int visibility;
// End of property values
private PropertyList savedPropertyList;

protected boolean tableRowsFound = false;
protected boolean tableCellsFound = false;
protected boolean tableCellsFound = false;
private int columnIndex = 1;
protected List pendingSpans;
protected BitSet usedColumnIndices = new BitSet();
private boolean firstRow = true;
/**
* @param parent FONode that is the parent of the object
@@ -72,12 +74,8 @@ public class TableBody extends FObj {
commonAural = pList.getAuralProps();
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonRelativePosition = pList.getRelativePositionProps();
borderAfterPrecedence = pList.get(PR_BORDER_AFTER_PRECEDENCE).getNumeric();
borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric();
borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric();
borderStartPrecedence = pList.get(PR_BORDER_START_PRECEDENCE).getNumeric();
visibility = pList.get(PR_VISIBILITY).getEnum();
super.bind(pList);
//Used by convertCellsToRows()
savedPropertyList = pList;
}
@@ -86,6 +84,7 @@ public class TableBody extends FObj {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
initPendingSpans();
getFOEventHandler().startBody(this);
}

@@ -107,7 +106,10 @@ public class TableBody extends FObj {
if (tableCellsFound) {
convertCellsToRows();
}*/
savedPropertyList = null; //Release reference
//release references
savedPropertyList = null;
pendingSpans = null;
usedColumnIndices = null;
}

/**
@@ -142,6 +144,78 @@ public class TableBody extends FObj {
invalidChildError(loc, nsURI, localName);
}
}
/**
* @see org.apache.fop.fo.FONode#addChildNode(FONode)
*/
protected void addChildNode(FONode child) throws FOPException {
if( child.getNameId() == FO_TABLE_CELL ) {
addCellNode( (TableCell) child);
} else {
super.addChildNode(child);
}
}

/**
* Adds a cell to the list of child nodes, and updates the columnIndex
* used for determining the initial value of column-number
*
* @param cell cell to add
* @throws FOPException
*/
private void addCellNode(TableCell cell) throws FOPException {
//if firstRow flag is still true, the cell starts a row,
//and there was a previous cell that didn't explicitly
//end the previous row => set firstRow flag to false
if( firstRow && cell.startsRow() && !lastCellEndedRow() ) {
firstRow = false;
}
int rowSpan = cell.getNumberRowsSpanned();
int colSpan = cell.getNumberColumnsSpanned();
//if there were no explicit columns, pendingSpans
//will not be properly initialized for the first row
if( firstRow && ((Table) parent).columns == null ) {
if( pendingSpans == null ) {
pendingSpans = new java.util.ArrayList();
}
for( int i = colSpan; --i >= 0; ) {
pendingSpans.add(null);
}
}
//if the current cell spans more than one row,
//update pending span list for the next row
if( rowSpan > 1 ) {
for( int i = colSpan; --i >= 0; ) {
pendingSpans.set(columnIndex - 1 + i,
new PendingSpan(rowSpan));
}
}
//flag column indices used by this cell,
//take into account that possibly not all column-numbers
//are used by columns in the parent table (if any),
//so a cell spanning three columns, might actually
//take up more than three columnIndices...
int startIndex = columnIndex - 1;
int endIndex = startIndex + colSpan;
if( ((Table) parent).columns != null ) {
List cols = ((Table) parent).columns;
int tmpIndex = endIndex;
for( int i = startIndex; i <= tmpIndex; ++i ) {
if( i < cols.size() && cols.get(i) == null ) {
endIndex++;
}
}
}
usedColumnIndices.set(startIndex, endIndex);
setNextColumnIndex();
super.addChildNode(cell);
if( cell.endsRow() ) {
if( firstRow ) {
firstRow = false;
}
resetColumnIndex();
}
}

/**
* If table-cells are used as direct children of a table-body|header|footer
@@ -215,5 +289,110 @@ public class TableBody extends FObj {
return (childNodes.size() > 0)
&& (childNodes.get(childNodes.size() - 1) == obj);
}
/**
* Initializes pending spans list; used for correctly
* assigning initial value for column-number for the
* cells of following rows
*
*/
protected void initPendingSpans() {
if( ((Table) parent).columns != null ) {
List tableCols = ((Table) parent).columns;
pendingSpans = new java.util.ArrayList(tableCols.size());
for( int i = tableCols.size(); --i >= 0; ) {
pendingSpans.add(null);
}
}
}
/**
* Returns the current column index of the TableBody
*
* @return the next column number to use
*/
public int getCurrentColumnIndex() {
return columnIndex;
}

/**
* Sets the current column index to a specific value
* (used by TableCell.bind() in case the column-number
* was explicitly specified)
*
*/
protected void setCurrentColumnIndex(int newIndex) {
columnIndex = newIndex;
}

/**
* Resets the current column index for the TableBody
*
*/
public void resetColumnIndex() {
columnIndex = 1;
usedColumnIndices.clear();
PendingSpan pSpan;
for( int i = pendingSpans.size(); --i >= 0; ) {
pSpan = (PendingSpan) pendingSpans.get(i);
if( pSpan != null ) {
pSpan.rowsLeft--;
if( pSpan.rowsLeft == 0 ) {
pendingSpans.set(i, null);
}
}
usedColumnIndices.set(i, pendingSpans.get(i) != null);
}
if( !firstRow ) {
setNextColumnIndex();
}
}

/**
* Increases columnIndex to the next available value
*
*/
private void setNextColumnIndex() {
while( usedColumnIndices.get(columnIndex - 1) ) {
//increment columnIndex
columnIndex++;
//if the table has explicit columns, and
//the updated index is not assigned to any
//column, increment further until the next
//index occupied by a column...
if( ((Table) parent).columns != null ) {
while( columnIndex <= ((Table) parent).columns.size()
&& !((Table) parent).isColumnNumberUsed(columnIndex) ) {
columnIndex++;
}
}
}
}

/**
* Checks whether the previous cell had 'ends-row="true"'
*
* @return false only if there was a previous cell, which
* had ends-row="false" (implicit or explicit)
*/
public boolean lastCellEndedRow() {
if( childNodes != null ) {
FONode prevNode = (FONode) childNodes.get(childNodes.size() - 1);
if( prevNode.getNameId() == FO_TABLE_CELL ) {
return ((TableCell) prevNode).endsRow();
}
}
return true;
}

/**
* Checks whether a given column-number is already in use
* for the current row (used by TableCell.bind());
*
* @return true if column-number is already occupied
*/
protected boolean isColumnNumberUsed(int colNr) {
return usedColumnIndices.get(colNr - 1);
}
}


+ 25
- 18
src/java/org/apache/fop/fo/flow/TableCell.java View File

@@ -38,16 +38,12 @@ import org.apache.fop.fo.properties.LengthRangeProperty;
* Class modelling the fo:table-cell object.
* @todo check need for all instance variables stored here
*/
public class TableCell extends FObj {
public class TableCell extends TableFObj {
// The value of properties relevant for fo:table-cell.
private CommonAccessibility commonAccessibility;
private CommonAural commonAural;
private CommonBorderPaddingBackground commonBorderPaddingBackground;
private CommonRelativePosition commonRelativePosition;
private Numeric borderAfterPrecedence;
private Numeric borderBeforePrecedence;
private Numeric borderEndPrecedence;
private Numeric borderStartPrecedence;
private LengthRangeProperty blockProgressionDimension;
private int borderCollapse; //inherited from fo:table
private LengthPairProperty borderSeparation; //inherited from fo:table
@@ -118,10 +114,6 @@ public class TableCell extends FObj {
commonAural = pList.getAuralProps();
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonRelativePosition = pList.getRelativePositionProps();
borderAfterPrecedence = pList.get(PR_BORDER_AFTER_PRECEDENCE).getNumeric();
borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric();
borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric();
borderStartPrecedence = pList.get(PR_BORDER_START_PRECEDENCE).getNumeric();
blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
borderCollapse = pList.get(PR_BORDER_COLLAPSE).getEnum();
borderSeparation = pList.get(PR_BORDER_SEPARATION).getLengthPair();
@@ -137,6 +129,24 @@ public class TableCell extends FObj {
numberRowsSpanned = pList.get(PR_NUMBER_ROWS_SPANNED).getNumeric();
startsRow = pList.get(PR_STARTS_ROW).getEnum();
width = pList.get(PR_WIDTH).getLength();
super.bind(pList);
//check if any of the column-numbers occupied by this cell
//are already in use in the current row...
for( int i = getColumnNumber();
++i <= getColumnNumber() + getNumberColumnsSpanned(); ) {
if( ((TableFObj) parent).isColumnNumberUsed(i - 1) ) {
throw new FOPException("cell overlaps in column " + (i - 1),
locator);
}
}
//if column-number was explicitly specified, force the parent's current
//column index to the specified value, so that the updated index will
//be the correct initial value for the next cell (see Rec 7.26.8)
if( pList.getExplicit(PR_COLUMN_NUMBER) != null ) {
((TableFObj) parent).setCurrentColumnIndex(
pList.getExplicit(PR_COLUMN_NUMBER).getNumeric().getValue());
}
}

/**
@@ -156,7 +166,11 @@ public class TableCell extends FObj {
if (!blockItemFound) {
missingChildElementError("marker* (%block;)+");
}
//TODO Complain about startsRow|endsRow=true if parent is a table-row
if( (startsRow() || endsRow())
&& getParent().getNameId() == FO_TABLE_ROW ) {
getLogger().warn("starts-row/ends-row for fo:table-cells "
+ "non-applicable for children of an fo:table-row.");
}
getFOEventHandler().endCell(this);
}

@@ -287,18 +301,11 @@ public class TableCell extends FObj {
return commonBorderPaddingBackground;
}

/**
* @return true if the "column-number" property was set.
*/
public boolean hasColumnNumber() {
return (columnNumber.getValue() >= 1);
}

/**
* @return the "column-number" property.
*/
public int getColumnNumber() {
return Math.max(columnNumber.getValue(), 0);
return columnNumber.getValue();
}

/** @return true if "empty-cells" is "show" */

+ 22
- 24
src/java/org/apache/fop/fo/flow/TableColumn.java View File

@@ -34,13 +34,9 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
/**
* Class modelling the fo:table-column object.
*/
public class TableColumn extends FObj {
public class TableColumn extends TableFObj {
// The value of properties relevant for fo:table-column.
private CommonBorderPaddingBackground commonBorderPaddingBackground;
private Numeric borderAfterPrecedence;
private Numeric borderBeforePrecedence;
private Numeric borderEndPrecedence;
private Numeric borderStartPrecedence;
private Numeric columnNumber;
private Length columnWidth;
private Numeric numberColumnsRepeated;
@@ -72,21 +68,32 @@ public class TableColumn extends FObj {
*/
public void bind(PropertyList pList) throws FOPException {
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
borderAfterPrecedence = pList.get(PR_BORDER_AFTER_PRECEDENCE).getNumeric();
borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric();
borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric();
borderStartPrecedence = pList.get(PR_BORDER_START_PRECEDENCE).getNumeric();
columnNumber = pList.get(PR_COLUMN_NUMBER).getNumeric();
columnWidth = pList.get(PR_COLUMN_WIDTH).getLength();
numberColumnsRepeated = pList.get(PR_NUMBER_COLUMNS_REPEATED).getNumeric();
numberColumnsSpanned = pList.get(PR_NUMBER_COLUMNS_SPANNED).getNumeric();
visibility = pList.get(PR_VISIBILITY).getEnum();
super.bind(pList);
if (columnNumber.getValue() < 0) {
//not catching 0 here because it is the indication that no
//column-number has been specified
throw new PropertyException("column-number must be 1 or bigger, "
+ "but got " + columnNumber.getValue());
if( pList.getExplicit(PR_COLUMN_NUMBER) != null ) {
if (columnNumber.getValue() <= 0) {
//TODO: This is actually a non-fatal error. See Rec 7.26.8:
//"A positive integer. If a negative or non-integer value
// is provided, the value will be rounded to the
// nearest integer value greater than or equal to 1."
throw new PropertyException("column-number must be 1 or bigger, "
+ "but got " + columnNumber);
} else if( ((Table) parent).isColumnNumberUsed(columnNumber.getValue()) ) {
throw new PropertyException("specified column-number \""
+ columnNumber
+ "\" has already been assigned to a previous column");
} else {
//force parent table's current column index
//to the specified value, so that the updated index
//will be the correct initial value for the next column
//(see Rec 7.26.8)
((Table) parent).setCurrentColumnIndex(columnNumber.getValue());
}
}
if (numberColumnsRepeated.getValue() <= 0) {
throw new PropertyException("number-columns-repeated must be 1 or bigger, "
@@ -135,13 +142,6 @@ public class TableColumn extends FObj {
return columnWidth;
}

/**
* @return true if the "column-number" property was set.
*/
public boolean hasColumnNumber() {
return (columnNumber.getValue() >= 1);
}

/**
* @return the "column-number" property.
*/
@@ -182,9 +182,7 @@ public class TableColumn extends FObj {
/** @see java.lang.Object#toString() */
public String toString() {
StringBuffer sb = new StringBuffer("fo:table-column");
if (hasColumnNumber()) {
sb.append(" column-number=").append(getColumnNumber());
}
sb.append(" column-number=").append(getColumnNumber());
if (getNumberColumnsRepeated() > 1) {
sb.append(" number-columns-repeated=").append(getNumberColumnsRepeated());
}

+ 110
- 0
src/java/org/apache/fop/fo/flow/TableFObj.java View File

@@ -0,0 +1,110 @@
package org.apache.fop.fo.flow;

import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.Numeric;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;


public abstract class TableFObj extends FObj {

private Numeric borderAfterPrecedence;
private Numeric borderBeforePrecedence;
private Numeric borderEndPrecedence;
private Numeric borderStartPrecedence;
protected static class PendingSpan {
protected int rowsLeft;
public PendingSpan( int rows ) {
rowsLeft = rows;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("pending span: rowsLeft=").append(rowsLeft);
return sb.toString();
}
}
public TableFObj(FONode parent) {
super(parent);
}
public void bind(PropertyList pList) throws FOPException {
borderAfterPrecedence = pList.get(PR_BORDER_AFTER_PRECEDENCE).getNumeric();
borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric();
borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric();
borderStartPrecedence = pList.get(PR_BORDER_START_PRECEDENCE).getNumeric();
}
/**
*
* @param side the side for which to return the border precedence
* @return the "border-precedence" value for the given side
*/
public Numeric getBorderPrecedence(int side) {
switch( side ) {
case CommonBorderPaddingBackground.BEFORE:
return borderBeforePrecedence;
case CommonBorderPaddingBackground.AFTER:
return borderAfterPrecedence;
case CommonBorderPaddingBackground.START:
return borderStartPrecedence;
case CommonBorderPaddingBackground.END:
return borderEndPrecedence;
default:
return null;
}
}
protected void setBorderPrecedence(int side, Numeric newPrecedence) {
switch( side ) {
case CommonBorderPaddingBackground.BEFORE:
borderBeforePrecedence = newPrecedence;
case CommonBorderPaddingBackground.AFTER:
borderAfterPrecedence = newPrecedence;
case CommonBorderPaddingBackground.START:
borderStartPrecedence = newPrecedence;
case CommonBorderPaddingBackground.END:
borderEndPrecedence = newPrecedence;
}
}
/**
* Returns the current column index of the given TableFObj
* (overridden for Table, TableBody, TableRow)
*
* @return the next column number to use
*/
public int getCurrentColumnIndex() {
return 0;
}
/**
* Sets the current column index of the given TableFObj
* (overridden for Table, TableBody, TableRow)
*/
protected void setCurrentColumnIndex(int newIndex) {
//do nothing by default
}
/**
* Checks if a certain column-number is already occupied
* (overridden for Table, TableBody, TableRow)
*
* @param colNr the column-number to check
* @return true if column-number is already in use
*/
protected boolean isColumnNumberUsed(int colNr) {
return false;
}
/**
* @return the Common Border, Padding, and Background Properties.
*/
public abstract CommonBorderPaddingBackground getCommonBorderPaddingBackground();

}

+ 2
- 1
src/java/org/apache/fop/fo/flow/TableFooter.java View File

@@ -39,7 +39,8 @@ public class TableFooter extends TableBody {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
// getFOEventHandler().startBody(this);
initPendingSpans();
//getFOEventHandler().startBody(this);
}

/**

+ 2
- 1
src/java/org/apache/fop/fo/flow/TableHeader.java View File

@@ -39,7 +39,8 @@ public class TableHeader extends TableBody {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
// getFOEventHandler().startHeader(this);
initPendingSpans();
//getFOEventHandler().startHeader(this);
}

/**

+ 103
- 9
src/java/org/apache/fop/fo/flow/TableRow.java View File

@@ -18,6 +18,9 @@

package org.apache.fop.fo.flow;

import java.util.BitSet;
import java.util.List;

import org.xml.sax.Locator;

import org.apache.fop.apps.FOPException;
@@ -37,17 +40,13 @@ import org.apache.fop.fo.properties.LengthRangeProperty;
/**
* Class modelling the fo:table-row object.
*/
public class TableRow extends FObj {
public class TableRow extends TableFObj {
// The value of properties relevant for fo:table-row.
private CommonAccessibility commonAccessibility;
private LengthRangeProperty blockProgressionDimension;
private CommonAural commonAural;
private CommonBorderPaddingBackground commonBorderPaddingBackground;
private CommonRelativePosition commonRelativePosition;
private Numeric borderAfterPrecedence;
private Numeric borderBeforePrecedence;
private Numeric borderEndPrecedence;
private Numeric borderStartPrecedence;
private int breakAfter;
private int breakBefore;
private Length height;
@@ -59,6 +58,10 @@ public class TableRow extends FObj {
// End of property values

private boolean setup = false;
private List pendingSpans;
private BitSet usedColumnIndices;
private int columnIndex = 1;

/**
* @param parent FONode that is the parent of this object
@@ -76,10 +79,6 @@ public class TableRow extends FObj {
commonAural = pList.getAuralProps();
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonRelativePosition = pList.getRelativePositionProps();
borderAfterPrecedence = pList.get(PR_BORDER_AFTER_PRECEDENCE).getNumeric();
borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric();
borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric();
borderStartPrecedence = pList.get(PR_BORDER_START_PRECEDENCE).getNumeric();
breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
id = pList.get(PR_ID).getString();
@@ -88,6 +87,7 @@ public class TableRow extends FObj {
keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
visibility = pList.get(PR_VISIBILITY).getEnum();
super.bind(pList);
}

/**
@@ -107,6 +107,12 @@ public class TableRow extends FObj {
* @see org.apache.fop.fo.FONode#startOfNode
*/
protected void startOfNode() throws FOPException {
pendingSpans = ((TableBody) parent).pendingSpans;
usedColumnIndices = ((TableBody) parent).usedColumnIndices;
while( usedColumnIndices.get(columnIndex - 1) ) {
columnIndex++;
}
checkId(id);
getFOEventHandler().startRow(this);
}
@@ -118,6 +124,16 @@ public class TableRow extends FObj {
if (childNodes == null) {
missingChildElementError("(table-cell+)");
}
if( ((TableBody) parent).isFirst(this)
&& ((Table) parent.getParent()).columns == null ) {
//force parent body's pendingSpans
//to the one accumulated after processing this row
((TableBody) parent).pendingSpans = pendingSpans;
}
((TableBody) parent).resetColumnIndex();
//release references
pendingSpans = null;
usedColumnIndices = null;
getFOEventHandler().endRow(this);
}

@@ -131,6 +147,55 @@ public class TableRow extends FObj {
invalidChildError(loc, nsURI, localName);
}
}
/**
* @see org.apache.fop.fo.FONode#addChildNode(FONode)
*/
protected void addChildNode(FONode child) throws FOPException {
TableCell cell = (TableCell) child;
int rowSpan = cell.getNumberRowsSpanned();
int colSpan = cell.getNumberColumnsSpanned();
if( ((TableBody) parent).isFirst(this)
&& ((Table) parent.getParent()).columns == null ) {
if( pendingSpans == null ) {
pendingSpans = new java.util.ArrayList();
}
pendingSpans.add(null);
if( usedColumnIndices == null ) {
usedColumnIndices = new BitSet();
}
}
//if the current cell spans more than one row,
//update pending span list for the next row
if( rowSpan > 1 ) {
for( int i = colSpan; --i >= 0; ) {
pendingSpans.set(columnIndex - 1 + i,
new PendingSpan(rowSpan));
}
}
//flag column indices used by this cell,
//take into account that possibly not all column-numbers
//are used by columns in the parent table (if any),
//so a cell spanning three columns, might actually
//take up more than three columnIndices...
int startIndex = columnIndex - 1;
int endIndex = startIndex + colSpan;
if( ((Table) parent.getParent()).columns != null ) {
List cols = ((Table) parent.getParent()).columns;
int tmpIndex = endIndex;
for( int i = startIndex; i <= tmpIndex; ++i ) {
if( i < cols.size() && cols.get(i) == null ) {
endIndex++;
}
}
}
usedColumnIndices.set(startIndex, endIndex);
//update columnIndex for the next cell
while( usedColumnIndices.get(columnIndex - 1) ) {
columnIndex++;
}
super.addChildNode(cell);
}

/**
* @return the "id" property.
@@ -221,4 +286,33 @@ public class TableRow extends FObj {
public int getNameId() {
return FO_TABLE_ROW;
}
/**
* Returns the current column index of the TableRow
*
* @return the next column number to use
*/
public int getCurrentColumnIndex() {
return columnIndex;
}

/**
* Sets the current column index to a specific value
* in case a column-number was explicitly specified
* (used by TableCell.bind())
*
*/
protected void setCurrentColumnIndex(int newIndex) {
columnIndex = newIndex;
}

/**
* Checks whether a given column-number is already in use
* for the current row (used by TableCell.bind());
*
* @return true if column-number is already occupied
*/
protected boolean isColumnNumberUsed(int colNr) {
return usedColumnIndices.get(colNr - 1);
}
}

+ 67
- 0
src/java/org/apache/fop/fo/properties/ColumnNumberPropertyMaker.java View File

@@ -0,0 +1,67 @@
/*
* Copyright 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.
* 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$ */

package org.apache.fop.fo.properties;

import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.PropertyException;
import org.apache.fop.fo.flow.TableFObj;
import org.apache.fop.fo.flow.TableBody;

public class ColumnNumberPropertyMaker extends NumberProperty.Maker {

public ColumnNumberPropertyMaker(int propId) {
super(propId);
}
/**
* Set default column-number from parent's currentColumnIndex
*
* @return the default value for column-number
*/
public Property make(PropertyList propertyList) throws PropertyException {
FObj fo = propertyList.getFObj();
if( fo.getNameId() == Constants.FO_TABLE_CELL
|| fo.getNameId() == Constants.FO_TABLE_COLUMN ) {
TableFObj parent = (TableFObj) propertyList.getParentFObj();
int columnIndex = parent.getCurrentColumnIndex();
if( fo.getNameId() == Constants.FO_TABLE_CELL
&& parent.getNameId() == Constants.FO_TABLE_BODY ) {
boolean startsRow = propertyList.get(Constants.PR_STARTS_ROW)
.getEnum() == Constants.EN_TRUE;
//cell w/ starts-row="true", but previous cell
//didn't have ends-row="true", so index has still has
//to be reset (for other cases this already happened in
//body.addChildNode())
if( startsRow && !((TableBody) parent).lastCellEndedRow() ) {
//reset column index, and reassign...
((TableBody) parent).resetColumnIndex();
columnIndex = parent.getCurrentColumnIndex();
}
}
return new NumberProperty(columnIndex);
} else {
throw new PropertyException("column-number property is only allowed on "
+ "fo:table-cell or fo:table-column, not on " + fo.getName());
}
}
}

+ 4
- 2
src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java View File

@@ -60,7 +60,7 @@ public class ColumnSetup {
ListIterator iter = rawCols.listIterator();
while (iter.hasNext()) {
TableColumn col = (TableColumn)iter.next();
if (col.hasColumnNumber()) {
if( col != null ) {
colnum = col.getColumnNumber();
}
for (int i = 0; i < col.getNumberColumnsRepeated(); i++) {
@@ -151,7 +151,9 @@ public class ColumnSetup {
public int getXOffset(int col, PercentBaseContext context) {
int xoffset = 0;
for (int i = 1; i < col; i++) {
xoffset += getColumn(i).getColumnWidth().getValue(context);
if( getColumn(i) != null ) {
xoffset += getColumn(i).getColumnWidth().getValue(context);
}
}
return xoffset;
}

+ 4
- 2
src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java View File

@@ -439,8 +439,10 @@ public class TableContentLayoutManager implements PercentBaseContext {
i < primary.getStartCol()
+ primary.getCell().getNumberColumnsSpanned();
i++) {
spanWidth += getTableLM().getColumns().getColumn(i + 1)
.getColumnWidth().getValue(getTableLM());
if( getTableLM().getColumns().getColumn(i + 1) != null ) {
spanWidth += getTableLM().getColumns().getColumn(i + 1)
.getColumnWidth().getValue(getTableLM());
}
}
LayoutContext childLC = new LayoutContext(0);
childLC.setStackLimit(context.getStackLimit()); //necessary?

+ 6
- 4
src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java View File

@@ -156,10 +156,12 @@ public class TableLayoutManager extends BlockStackingLayoutManager
float factors = 0;
for (Iterator i = columns.iterator(); i.hasNext();) {
TableColumn column = (TableColumn) i.next();
Length width = column.getColumnWidth();
sumCols += width.getValue(this);
if (width instanceof TableColLength) {
factors += ((TableColLength) width).getTableUnits();
if( column != null ) {
Length width = column.getColumnWidth();
sumCols += width.getValue(this);
if (width instanceof TableColLength) {
factors += ((TableColLength) width).getTableUnits();
}
}
}
// sets TABLE_UNITS in case where one or more oldColumns is defined using

+ 5
- 8
src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java View File

@@ -362,15 +362,12 @@ public class TableRowIterator {
while (iter.hasNext()) {
TableCell cell = (TableCell)iter.next();
if (cell.hasColumnNumber()) {
colnum = cell.getColumnNumber();
} else {
//Skip columns with spanning grid units
while (safelyGetListItem(gridUnits, colnum - 1) != null) {
colnum++;
}
}
colnum = cell.getColumnNumber();

//TODO: remove the check below???
//shouldn't happen here, since
//overlapping cells already caught in
//fo.flow.TableCell.bind()...
if (safelyGetListItem(gridUnits, colnum - 1) != null) {
log.error("Overlapping cell at position " + colnum);
//TODO throw layout exception

Loading…
Cancel
Save