From 2198e6f7dabc6ea704d5e0cd2f56013ea4e8cca1 Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Fri, 24 Nov 2006 17:32:48 +0000 Subject: [PATCH] Small improvements of the table layout code: - javadoc - code cleanup - give more explicit names (I believe) to some variables - remove whitespaces at ends of lines git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@478928 13f79535-47bb-0310-9956-ffa450edef68 --- .../CommonBorderPaddingBackground.java | 16 + .../layoutmgr/BlockStackingLayoutManager.java | 2 +- .../CollapsingBorderModelEyeCatching.java | 8 +- .../apache/fop/layoutmgr/table/EffRow.java | 20 +- .../apache/fop/layoutmgr/table/GridUnit.java | 97 +++-- .../fop/layoutmgr/table/PrimaryGridUnit.java | 84 ++-- .../table/TableContentLayoutManager.java | 68 ++-- .../layoutmgr/table/TableLayoutManager.java | 30 +- .../fop/layoutmgr/table/TableRowIterator.java | 373 +++++++++++------- 9 files changed, 419 insertions(+), 279 deletions(-) diff --git a/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java b/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java index 53b90fea9..168a3b145 100755 --- a/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java +++ b/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java @@ -249,18 +249,34 @@ public class CommonBorderPaddingBackground implements Cloneable { return this.fopimage; } + /** + * @param bDiscard indicates whether the .conditionality component should be + * considered (start of a reference-area) + */ public int getBorderStartWidth(boolean bDiscard) { return getBorderWidth(START, bDiscard); } + /** + * @param bDiscard indicates whether the .conditionality component should be + * considered (end of a reference-area) + */ public int getBorderEndWidth(boolean bDiscard) { return getBorderWidth(END, bDiscard); } + /** + * @param bDiscard indicates whether the .conditionality component should be + * considered (start of a reference-area) + */ public int getBorderBeforeWidth(boolean bDiscard) { return getBorderWidth(BEFORE, bDiscard); } + /** + * @param bDiscard indicates whether the .conditionality component should be + * considered (end of a reference-area) + */ public int getBorderAfterWidth(boolean bDiscard) { return getBorderWidth(AFTER, bDiscard); } diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index 7b81ad478..ca6939e56 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -1444,7 +1444,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager * SourceList to targetList * @param sourceList source list * @param targetList target list receiving the wrapped position elements - * @param force if true, every Position is wrapper regardless of its LM of origin + * @param force if true, every Position is wrapped regardless of its LM of origin */ protected void wrapPositionElements(List sourceList, List targetList, boolean force) { diff --git a/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java b/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java index e1f573162..cf57947fb 100644 --- a/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java +++ b/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java @@ -98,8 +98,8 @@ public class CollapsingBorderModelEyeCatching extends CollapsingBorderModel { other[1] = otherRow.getCommonBorderPaddingBackground().getBorderInfo(otherSide); } if (currentBody != null - && ((side == BEFORE && currentGridUnit.getFlag(GridUnit.FIRST_IN_BODY)) - || (side == AFTER && currentGridUnit.getFlag(GridUnit.LAST_IN_BODY)) + && ((side == BEFORE && currentGridUnit.getFlag(GridUnit.FIRST_IN_PART)) + || (side == AFTER && currentGridUnit.getFlag(GridUnit.LAST_IN_PART)) || (currentGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN) && side == START) || (currentGridUnit.getFlag(GridUnit.IN_LAST_COLUMN) && side == END))) { //row group (=body, table-header or table-footer) @@ -107,8 +107,8 @@ public class CollapsingBorderModelEyeCatching extends CollapsingBorderModel { } if (otherGridUnit != null && otherBody != null - && ((otherSide == BEFORE && otherGridUnit.getFlag(GridUnit.FIRST_IN_BODY)) - || (otherSide == AFTER && otherGridUnit.getFlag(GridUnit.LAST_IN_BODY)))) { + && ((otherSide == BEFORE && otherGridUnit.getFlag(GridUnit.FIRST_IN_PART)) + || (otherSide == AFTER && otherGridUnit.getFlag(GridUnit.LAST_IN_PART)))) { //row group (=body, table-header or table-footer) other[2] = otherBody.getCommonBorderPaddingBackground().getBorderInfo(otherSide); } diff --git a/src/java/org/apache/fop/layoutmgr/table/EffRow.java b/src/java/org/apache/fop/layoutmgr/table/EffRow.java index 982ba8c45..1e184e767 100644 --- a/src/java/org/apache/fop/layoutmgr/table/EffRow.java +++ b/src/java/org/apache/fop/layoutmgr/table/EffRow.java @@ -29,15 +29,16 @@ import org.apache.fop.traits.MinOptMax; * This class represents an effective row in a table and holds a list of grid units occupying * the row as well as some additional values. */ -public class EffRow { +class EffRow { /** Indicates that the row is the first in a table-body */ - public static final int FIRST_IN_BODY = GridUnit.FIRST_IN_BODY; + public static final int FIRST_IN_PART = GridUnit.FIRST_IN_PART; /** Indicates that the row is the last in a table-body */ - public static final int LAST_IN_BODY = GridUnit.LAST_IN_BODY; + public static final int LAST_IN_PART = GridUnit.LAST_IN_PART; private List gridUnits = new java.util.ArrayList(); private int index; + /** One of HEADER, FOOTER, BODY */ private int bodyType; private MinOptMax height; private MinOptMax explicitHeight; @@ -142,14 +143,15 @@ public class EffRow { /** * Returns a flag for this effective row. Only a subset of the flags on GridUnit is supported. * The flag is determined by inspecting flags on the EffRow's GridUnits. - * @param which the requested flag + * @param which the requested flag (one of {@link EffRow#FIRST_IN_PART} or {@link + * EffRow#LAST_IN_PART}) * @return true if the flag is set */ public boolean getFlag(int which) { - if (which == FIRST_IN_BODY) { - return getGridUnit(0).getFlag(GridUnit.FIRST_IN_BODY); - } else if (which == LAST_IN_BODY) { - return getGridUnit(0).getFlag(GridUnit.LAST_IN_BODY); + if (which == FIRST_IN_PART) { + return getGridUnit(0).getFlag(GridUnit.FIRST_IN_PART); + } else if (which == LAST_IN_PART) { + return getGridUnit(0).getFlag(GridUnit.LAST_IN_PART); } else { throw new IllegalArgumentException("Illegal flag queried: " + which); } @@ -172,4 +174,4 @@ public class EffRow { sb.append("}"); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/fop/layoutmgr/table/GridUnit.java b/src/java/org/apache/fop/layoutmgr/table/GridUnit.java index 2716f13f3..029e9c93c 100644 --- a/src/java/org/apache/fop/layoutmgr/table/GridUnit.java +++ b/src/java/org/apache/fop/layoutmgr/table/GridUnit.java @@ -37,28 +37,28 @@ public class GridUnit { public static final int IN_FIRST_COLUMN = 0; /** Indicates that the grid unit is in the last column. */ public static final int IN_LAST_COLUMN = 1; - /** Indicates that the grid unit is in the first row (context: table). */ + /** Indicates that the grid unit is in the first row of the table. */ public static final int FIRST_IN_TABLE = 2; - /** Indicates that the grid unit is in the first row (context: body). */ - public static final int FIRST_IN_BODY = 3; - /** Indicates that the grid unit is in the last row (context: body). */ - public static final int LAST_IN_BODY = 4; - /** Indicates that the grid unit is in the last row (context: table). */ + /** Indicates that the grid unit is in the first row of the table part (header, footer, body). */ + public static final int FIRST_IN_PART = 3; + /** Indicates that the grid unit is in the last row of the table part (header, footer, body). */ + public static final int LAST_IN_PART = 4; + /** Indicates that the grid unit is in the last row of the table. */ public static final int LAST_IN_TABLE = 5; /** Indicates that the primary grid unit has a pending keep-with-next. */ public static final int KEEP_WITH_NEXT_PENDING = 6; /** Indicates that the primary grid unit has a pending keep-with-previous. */ public static final int KEEP_WITH_PREVIOUS_PENDING = 7; - + /** Primary grid unit */ private PrimaryGridUnit primary; /** Table cell which occupies this grid unit */ private TableCell cell; - /** Table row which occupied this grid unit (may be null) */ + /** Table row which occupies this grid unit (may be null) */ private TableRow row; /** Table column that this grid unit belongs to */ private TableColumn column; - + /** start index of grid unit within row in column direction */ private int startCol; /** index of grid unit within cell in column direction */ @@ -69,16 +69,41 @@ public class GridUnit { private CommonBorderPaddingBackground effectiveBorders; /** flags for the grid unit */ private byte flags = 0; - - + + + /** + * Creates a new grid unit. + * + * @param cell table cell which occupies this grid unit + * @param column table column this grid unit belongs to + * @param startCol index of the column this grid unit belongs to + * @param colSpanIndex index of this grid unit in the span, in column direction + */ public GridUnit(TableCell cell, TableColumn column, int startCol, int colSpanIndex) { this(null, cell, column, startCol, colSpanIndex); } - + + /** + * Creates a new grid unit. + * + * @param primary ?? + * @param column table column this grid unit belongs to + * @param startCol index of the column this grid unit belongs to + * @param colSpanIndex index of this grid unit in the span, in column direction + */ public GridUnit(PrimaryGridUnit primary, TableColumn column, int startCol, int colSpanIndex) { this(primary, primary.getCell(), column, startCol, colSpanIndex); } - + + /** + * Creates a new grid unit. + * + * @param primary ?? + * @param cell table cell which occupies this grid unit + * @param column table column this grid unit belongs to + * @param startCol index of the column this grid unit belongs to + * @param colSpanIndex index of this grid unit in the span, in column direction + */ protected GridUnit(PrimaryGridUnit primary, TableCell cell, TableColumn column, int startCol, int colSpanIndex) { this.primary = primary; this.cell = cell; @@ -86,15 +111,15 @@ public class GridUnit { this.startCol = startCol; this.colSpanIndex = colSpanIndex; } - + public TableCell getCell() { return cell; } - + public TableColumn getColumn() { return column; } - + public TableRow getRow() { if (row != null) { return row; @@ -104,7 +129,7 @@ public class GridUnit { return null; } } - + /** * Sets the table-row FO, if applicable. * @param row the table-row FO @@ -120,7 +145,7 @@ public class GridUnit { } return (TableBody)node; } - + public Table getTable() { FONode node = getBody(); while (node != null && !(node instanceof Table)) { @@ -131,7 +156,7 @@ public class GridUnit { } return (Table)node; } - + /** * @return the primary grid unit if this is a spanned grid unit */ @@ -142,15 +167,15 @@ public class GridUnit { public boolean isPrimary() { return false; } - + public boolean isEmpty() { return cell == null; } - + public int getStartCol() { return startCol; } - + /** @return true if the grid unit is the last in column spanning direction */ public boolean isLastGridUnitColSpan() { if (cell != null) { @@ -159,8 +184,8 @@ public class GridUnit { return true; } } - - /** @return true if the grid unit is the last in column spanning direction */ + + /** @return true if the grid unit is the last in row spanning direction */ public boolean isLastGridUnitRowSpan() { if (cell != null) { return (rowSpanIndex == cell.getNumberRowsSpanned() - 1); @@ -168,14 +193,14 @@ public class GridUnit { return true; } } - + /** * @return the index of the grid unit inside a cell in row direction */ public int getRowSpanIndex() { return rowSpanIndex; } - + /** * @return the index of the grid unit inside a cell in column direction */ @@ -186,7 +211,7 @@ public class GridUnit { /** * Returns a BorderInfo instance for a side of the currently applicable cell before border * resolution (i.e. the value from the FO). A return value of null indicates an empty cell. - * See CollapsingBorderModel(EyeCatching) where this method is used. + * See CollapsingBorderModel(EyeCatching) where this method is used. * @param side for which side to return the BorderInfo * @return the requested BorderInfo instance or null if the grid unit is an empty cell */ @@ -197,21 +222,21 @@ public class GridUnit { return null; } } - + /** * @return the resolved normal borders for this grid unit */ public CommonBorderPaddingBackground getBorders() { return effectiveBorders; } - + /** * @return true if the grid unit has any borders. */ public boolean hasBorders() { return (getBorders() != null) && getBorders().hasBorder(); } - + /** * Assigns the borders from the given cell to this cell info. Used in * case of separate border model. @@ -221,7 +246,7 @@ public class GridUnit { effectiveBorders = cell.getCommonBorderPaddingBackground(); } } - + /** * Resolve collapsing borders for the given cell. Used in case of the collapsing border model. * @param other neighbouring grid unit if any @@ -230,7 +255,7 @@ public class GridUnit { public void resolveBorder(GridUnit other, int side) { resolveBorder(other, side, 0); } - + /** * Resolve collapsing borders for the given cell. Used in case of the collapsing border model. * @param other neighbouring grid unit if any @@ -243,13 +268,13 @@ public class GridUnit { if (effectiveBorders == null) { effectiveBorders = new CommonBorderPaddingBackground(); } - effectiveBorders.setBorderInfo(borderModel.determineWinner(this, other, + effectiveBorders.setBorderInfo(borderModel.determineWinner(this, other, side, resFlags), side); if (cell != null) { effectiveBorders.setPadding(cell.getCommonBorderPaddingBackground()); } } - + /** * Returns a flag for this GridUnit. * @param which the requested flag @@ -258,7 +283,7 @@ public class GridUnit { public boolean getFlag(int which) { return (flags & (1 << which)) != 0; } - + /** * Sets a flag on a GridUnit. * @param which the flag to set @@ -271,7 +296,7 @@ public class GridUnit { flags &= ~(1 << which); //clear flag } } - + /** * @return the grid unit just below this grid unit if the cell is spanning. */ diff --git a/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java b/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java index 73f5e5acb..19ccee592 100644 --- a/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java +++ b/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java @@ -36,11 +36,19 @@ public class PrimaryGridUnit extends GridUnit { private LinkedList elements; /** Index of row where this cell starts */ private int startRow; - /** Links to the spanned grid units. (List of GridUnit arrays, one array represents a row) */ + /** Links to the spanned grid units. (List of GridUnit arrays, one array represents a row) */ private List rows; /** The calculated size of the cell's content. (cached value) */ private int contentLength = -1; - + + /** + * Creates a new primary grid unit. + * + * @param cell table cell which occupies this grid unit + * @param column table column this grid unit belongs to + * @param startCol index of the column this grid unit belongs to, zero-based + * @param startRow index of the row this grid unit belongs to, zero-based + */ public PrimaryGridUnit(TableCell cell, TableColumn column, int startCol, int startRow) { super(cell, column, startCol, 0); this.startRow = startRow; @@ -48,25 +56,30 @@ public class PrimaryGridUnit extends GridUnit { cellLM = new TableCellLayoutManager(cell, this); } } - + public TableCellLayoutManager getCellLM() { return cellLM; } - + public boolean isPrimary() { return true; } - + + /** + * Sets the Knuth elements for the table cell containing this grid unit. + * + * @param elements a list of ListElement (?) + */ public void setElements(LinkedList elements) { this.elements = elements; } - + public LinkedList getElements() { return this.elements; } - - /** - * @return Returns the half the maximum before border width of this cell. + + /** + * @return half the maximum before border width of this cell. */ public int getHalfMaxBeforeBorderWidth() { int value = 0; @@ -76,7 +89,7 @@ public class PrimaryGridUnit extends GridUnit { GridUnit[] row = (GridUnit[])getRows().get(0); for (int i = 0; i < row.length; i++) { if (row[i].hasBorders()) { - before = Math.max(before, + before = Math.max(before, row[i].getBorders().getBorderBeforeWidth(false)); } } @@ -88,9 +101,9 @@ public class PrimaryGridUnit extends GridUnit { } return value; } - - /** - * @return Returns the half the maximum after border width of this cell. + + /** + * @return half the maximum after border width of this cell. */ public int getHalfMaxAfterBorderWidth() { int value = 0; @@ -111,21 +124,21 @@ public class PrimaryGridUnit extends GridUnit { } return value; } - - /** - * @return Returns the sum of half the maximum before and after border + + /** + * @return the sum of half the maximum before and after border * widths of this cell. */ public int getHalfMaxBorderWidth() { return getHalfMaxBeforeBorderWidth() + getHalfMaxAfterBorderWidth(); } - + /** @param value The length of the cell content to remember. */ public void setContentLength(int value) { this.contentLength = value; } - - /** @return Returns the length of the cell content. */ + + /** @return the length of the cell content. */ public int getContentLength() { return contentLength; } @@ -135,28 +148,45 @@ public class PrimaryGridUnit extends GridUnit { if (!getCell().getBlockProgressionDimension().getOptimum(null).isAuto()) { return true; } - if (getRow() != null + if (getRow() != null && !getRow().getBlockProgressionDimension().getOptimum(null).isAuto()) { return true; } return false; } + /** + * Returns the grid units belonging to the same span as this one. + * + * @return a list of GridUnit[], each array corresponds to a row + */ public List getRows() { return this.rows; } - + public void addRow(GridUnit[] row) { if (rows == null) { rows = new java.util.ArrayList(); } rows.add(row); } - + + /** + * Returns the index of the row this grid unit belongs to. + * + * @return the index of the row this grid unit belongs to. + */ public int getStartRow() { return this.startRow; } + /** + * Returns the widths of the start- and end-borders of the span this grid unit belongs + * to. + * + * @return a two-element array containing the widths of the start-border then the + * end-border + */ public int[] getStartEndBorderWidths() { int[] widths = new int[2]; if (rows == null) { @@ -165,17 +195,17 @@ public class PrimaryGridUnit extends GridUnit { } else { for (int i = 0; i < rows.size(); i++) { GridUnit[] gridUnits = (GridUnit[])rows.get(i); - widths[0] = Math.max(widths[0], + widths[0] = Math.max(widths[0], (gridUnits[0]). getBorders().getBorderStartWidth(false)); - widths[1] = Math.max(widths[1], + widths[1] = Math.max(widths[1], (gridUnits[gridUnits.length - 1]). getBorders().getBorderEndWidth(false)); } } return widths; } - + /** @see java.lang.Object#toString() */ public String toString() { StringBuffer sb = new StringBuffer(super.toString()); @@ -185,8 +215,8 @@ public class PrimaryGridUnit extends GridUnit { /** @return true if this cell spans over more than one grid unit. */ public boolean hasSpanning() { - return (getCell().getNumberColumnsSpanned() > 1) + return (getCell().getNumberColumnsSpanned() > 1) || (getCell().getNumberRowsSpanned() > 1); } - + } diff --git a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java index e0eaf079e..2ab9a1cde 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java @@ -65,7 +65,7 @@ public class TableContentLayoutManager implements PercentBaseContext { private static Log log = LogFactory.getLog(TableContentLayoutManager.class); private TableLayoutManager tableLM; - private TableRowIterator trIter; + private TableRowIterator bodyIter; private TableRowIterator headerIter; private TableRowIterator footerIter; private LinkedList headerList; @@ -86,7 +86,8 @@ public class TableContentLayoutManager implements PercentBaseContext { public TableContentLayoutManager(TableLayoutManager parent) { this.tableLM = parent; Table table = getTableLM().getTable(); - this.trIter = new TableRowIterator(table, getTableLM().getColumns(), TableRowIterator.BODY); + this.bodyIter = new TableRowIterator(table, getTableLM().getColumns(), + TableRowIterator.BODY); if (table.getTableHeader() != null) { headerIter = new TableRowIterator(table, getTableLM().getColumns(), TableRowIterator.HEADER); @@ -146,8 +147,8 @@ public class TableContentLayoutManager implements PercentBaseContext { this.headerList = getKnuthElementsForRowIterator( headerIter, context, alignment, TableRowIterator.HEADER); ElementListUtils.removeLegalBreaks(this.headerList); - this.headerNetHeight = - ElementListUtils.calcContentLength(this.headerList); + this.headerNetHeight + = ElementListUtils.calcContentLength(this.headerList); if (log.isDebugEnabled()) { log.debug("==> Header: " + headerNetHeight + " - " + this.headerList); @@ -167,8 +168,8 @@ public class TableContentLayoutManager implements PercentBaseContext { this.footerList = getKnuthElementsForRowIterator( footerIter, context, alignment, TableRowIterator.FOOTER); ElementListUtils.removeLegalBreaks(this.footerList); - this.footerNetHeight = - ElementListUtils.calcContentLength(this.footerList); + this.footerNetHeight + = ElementListUtils.calcContentLength(this.footerList); if (log.isDebugEnabled()) { log.debug("==> Footer: " + footerNetHeight + " - " + this.footerList); @@ -180,7 +181,7 @@ public class TableContentLayoutManager implements PercentBaseContext { footerAsLast = box; } LinkedList returnList = getKnuthElementsForRowIterator( - trIter, context, alignment, TableRowIterator.BODY); + bodyIter, context, alignment, TableRowIterator.BODY); if (headerAsFirst != null) { returnList.add(0, headerAsFirst); } else if (headerAsSecondToLast != null) { @@ -312,36 +313,31 @@ public class TableContentLayoutManager implements PercentBaseContext { TableRowIterator iter) { for (int rgi = 0; rgi < rowGroup.length; rgi++) { EffRow row = rowGroup[rgi]; - EffRow prev = iter.getCachedRow(row.getIndex() - 1); - EffRow next = iter.getCachedRow(row.getIndex() + 1); - if (next == null) { - //It wasn't read, yet, or we are at the last row - next = iter.getNextRow(); - iter.backToPreviousRow(); + EffRow prevRow = iter.getPrecedingRow(row); + EffRow nextRow = iter.getFollowingRow(row); + if ((prevRow == null) && (iter == this.bodyIter) && (this.headerIter != null)) { + prevRow = this.headerIter.getLastRow(); } - if ((prev == null) && (iter == this.trIter) && (this.headerIter != null)) { - prev = this.headerIter.getLastRow(); + if ((nextRow == null) && (iter == this.headerIter)) { + nextRow = this.bodyIter.getFirstRow(); } - if ((next == null) && (iter == this.headerIter)) { - next = this.trIter.getFirstRow(); + if ((nextRow == null) && (iter == this.bodyIter) && (this.footerIter != null)) { + nextRow = this.footerIter.getFirstRow(); } - if ((next == null) && (iter == this.trIter) && (this.footerIter != null)) { - next = this.footerIter.getFirstRow(); - } - if ((prev == null) && (iter == this.footerIter)) { + if ((prevRow == null) && (iter == this.footerIter)) { //TODO This could be bad for memory consumption because it already causes the //whole body iterator to be prefetched! - prev = this.trIter.getLastRow(); + prevRow = this.bodyIter.getLastRow(); } - log.debug(prev + " - " + row + " - " + next); + log.debug(prevRow + " - " + row + " - " + nextRow); //Determine the grid units necessary for getting all the borders right int guCount = row.getGridUnits().size(); - if (prev != null) { - guCount = Math.max(guCount, prev.getGridUnits().size()); + if (prevRow != null) { + guCount = Math.max(guCount, prevRow.getGridUnits().size()); } - if (next != null) { - guCount = Math.max(guCount, next.getGridUnits().size()); + if (nextRow != null) { + guCount = Math.max(guCount, nextRow.getGridUnits().size()); } GridUnit gu = row.getGridUnit(0); //Create empty grid units to hold resolved borders of neighbouring cells @@ -362,8 +358,8 @@ public class TableContentLayoutManager implements PercentBaseContext { gu = row.getGridUnit(i); GridUnit other; int flags = 0; - if (prev != null && i < prev.getGridUnits().size()) { - other = prev.getGridUnit(i); + if (prevRow != null && i < prevRow.getGridUnits().size()) { + other = prevRow.getGridUnit(i); } else { other = null; } @@ -371,7 +367,7 @@ public class TableContentLayoutManager implements PercentBaseContext { || other.isEmpty() || gu.isEmpty() || gu.getPrimary() != other.getPrimary()) { - if ((iter == this.trIter) + if ((iter == this.bodyIter) && gu.getFlag(GridUnit.FIRST_IN_TABLE) && (this.headerIter == null)) { flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE; @@ -385,8 +381,8 @@ public class TableContentLayoutManager implements PercentBaseContext { } flags = 0; - if (next != null && i < next.getGridUnits().size()) { - other = next.getGridUnit(i); + if (nextRow != null && i < nextRow.getGridUnits().size()) { + other = nextRow.getGridUnit(i); } else { other = null; } @@ -394,7 +390,7 @@ public class TableContentLayoutManager implements PercentBaseContext { || other.isEmpty() || gu.isEmpty() || gu.getPrimary() != other.getPrimary()) { - if ((iter == this.trIter) + if ((iter == this.bodyIter) && gu.getFlag(GridUnit.LAST_IN_TABLE) && (this.footerIter == null)) { flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE; @@ -608,7 +604,7 @@ public class TableContentLayoutManager implements PercentBaseContext { } /** - * Adds the areas generated my this layout manager to the area tree. + * Adds the areas generated by this layout manager to the area tree. * @param parentIter the position iterator * @param layoutContext the layout context for adding areas */ @@ -723,12 +719,12 @@ public class TableContentLayoutManager implements PercentBaseContext { body = part.pgu.getBody(); } if (tcpos.getFlag(TableContentPosition.FIRST_IN_ROWGROUP) - && tcpos.row.getFlag(EffRow.FIRST_IN_BODY)) { + && tcpos.row.getFlag(EffRow.FIRST_IN_PART)) { firstPos = true; } if (tcpos.getFlag(TableContentPosition.LAST_IN_ROWGROUP) - && tcpos.row.getFlag(EffRow.LAST_IN_BODY)) { + && tcpos.row.getFlag(EffRow.LAST_IN_PART)) { lastPos = true; getTableLM().getCurrentPV().addMarkers(body.getMarkers(), true, firstPos, lastPos); diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java index f51023615..2e653e23d 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java @@ -46,10 +46,10 @@ import org.apache.fop.fo.FObj; /** * LayoutManager for a table FO. - * A table consists of oldColumns, table header, table footer and multiple + * A table consists of columns, table header, table footer and multiple * table bodies. * The header, footer and body add the areas created from the table cells. - * The table then creates areas for the oldColumns, bodies and rows + * The table then creates areas for the columns, bodies and rows * the render background. */ public class TableLayoutManager extends BlockStackingLayoutManager @@ -210,7 +210,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager //Spaces, border and padding to be repeated at each break addPendingMarks(context); - LinkedList returnedList = null; + LinkedList contentKnuthElements = null; LinkedList contentList = new LinkedList(); //Position returnPosition = new NonLeafPosition(this, null); //Body prevLM = null; @@ -226,7 +226,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager if (contentLM == null) { contentLM = new TableContentLayoutManager(this); } - returnedList = contentLM.getNextKnuthElements(childLC, alignment); + contentKnuthElements = contentLM.getNextKnuthElements(childLC, alignment); if (childLC.isKeepWithNextPending()) { log.debug("TableContentLM signals pending keep-with-next"); context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING); @@ -237,15 +237,15 @@ public class TableLayoutManager extends BlockStackingLayoutManager } //Set index values on elements coming from the content LM - Iterator iter = returnedList.iterator(); + Iterator iter = contentKnuthElements.iterator(); while (iter.hasNext()) { ListElement el = (ListElement)iter.next(); notifyPos(el.getPosition()); } - log.debug(returnedList); + log.debug(contentKnuthElements); - if (returnedList.size() == 1 - && ((ListElement)returnedList.getFirst()).isForcedBreak()) { + if (contentKnuthElements.size() == 1 + && ((ListElement)contentKnuthElements.getFirst()).isForcedBreak()) { // a descendant of this block has break-before if (returnList.size() == 0) { // the first child (or its first child ...) has @@ -256,11 +256,11 @@ public class TableLayoutManager extends BlockStackingLayoutManager //FIX ME //bSpaceBeforeServed = false; } - contentList.addAll(returnedList); + contentList.addAll(contentKnuthElements); // "wrap" the Position inside each element // moving the elements from contentList to returnList - returnedList = new LinkedList(); + contentKnuthElements = new LinkedList(); wrapPositionElements(contentList, returnList); return returnList; @@ -287,9 +287,9 @@ public class TableLayoutManager extends BlockStackingLayoutManager // a penalty } }*/ - contentList.addAll(returnedList); - if (returnedList.size() > 0) { - if (((ListElement)returnedList.getLast()).isForcedBreak()) { + contentList.addAll(contentKnuthElements); + if (contentKnuthElements.size() > 0) { + if (((ListElement)contentKnuthElements.getLast()).isForcedBreak()) { // a descendant of this block has break-after if (false /*curLM.isFinished()*/) { // there is no other content in this block; @@ -297,7 +297,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager setFinished(true); } - returnedList = new LinkedList(); + contentKnuthElements = new LinkedList(); wrapPositionElements(contentList, returnList); return returnList; @@ -317,7 +317,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager /** * The table area is a reference area that contains areas for - * oldColumns, bodies, rows and the contents are in cells. + * columns, bodies, rows and the contents are in cells. * * @param parentIter the position iterator * @param layoutContext the layout context for adding areas diff --git a/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java b/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java index 0e193c3ff..2fc91cb4b 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java @@ -35,89 +35,108 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground; /** - *

Iterator that lets the table layout manager step over all rows of a table. - *

- *

Note: This class is not thread-safe. - *

+ * Iterator that lets the table layout manager step over all of the rows of a part of the + * table (table-header, table-footer or table-body). + *

Note: This class is not thread-safe.

*/ public class TableRowIterator { - /** Selects the list of table-body elements for iteration. */ + /** Selects the table-body elements for iteration. */ public static final int BODY = 0; - /** Selects the table-header element for iteration. */ + /** Selects the table-header elements for iteration. */ public static final int HEADER = 1; - /** Selects the table-footer element for iteration. */ - public static final int FOOTER = 2; - + /** Selects the table-footer elements for iteration. */ + public static final int FOOTER = 2; + /** Logger **/ private static Log log = LogFactory.getLog(TableRowIterator.class); - /** The table on with this instance operates. */ + /** The table on which this instance operates. */ protected Table table; + /** Column setup of the operated table. */ private ColumnSetup columns; - private int type; - - /** Holds the current row (TableCell instances) */ + + /** Part of the table over which to iterate. One of BODY, HEADER or FOOTER. */ + private int tablePart; + + /** Holds the currently fetched row (TableCell instances). */ private List currentRow = new java.util.ArrayList(); - /** Holds the grid units of cell from the last row while will span over the current row - * (GridUnit instance) */ - private List lastRowsSpanningCells = new java.util.ArrayList(); - private int currentRowIndex = -1; - //TODO rows should later be a Jakarta Commons LinkedList so concurrent modifications while - //using a ListIterator are possible - /** List of cache rows. */ - private List rows = new java.util.ArrayList(); - //private int indexOfFirstRowInList; - private int currentIndex = -1; + + /** + * Holds the grid units of cells from the previous row which will span over the + * current row. Should be read "previous row's spanning cells". List of GridUnit + * instances. + */ + private List previousRowsSpanningCells = new java.util.ArrayList(); + + /** Index of the row currently being fetched. */ + private int fetchIndex = -1; + + /** Spans found on the current row which will also span over the next row. */ private int pendingRowSpans; - + + //TODO rows should later be a Jakarta Commons LinkedList so concurrent modifications while + //using a ListIterator are possible + /** List of cached rows. This a list of EffRow elements. */ + private List fetchedRows = new java.util.ArrayList(); + + /** + * Index of the row that will be returned at the next iteration step. Note that there + * is no direct relation between this field and {@link + * TableRowIterator#fetchIndex}. The fetching of rows and the iterating over them are + * two different processes. Hence the two indices. */ + private int iteratorIndex = 0; + //prefetch state - private ListIterator bodyIterator = null; - private ListIterator childInBodyIterator = null; - + /** + * Iterator over the requested table's part(s) (header, footer, body). Note that + * a table may have several table-body children, hence the iterator. + */ + private ListIterator tablePartIterator = null; + /** Iterator over a part's child elements (either table-rows or table-cells). */ + private ListIterator tablePartChildIterator = null; + /** * Creates a new TableRowIterator. * @param table the table to iterate over * @param columns the column setup for the table - * @param what indicates what part of the table to iterate over (HEADER, FOOTER, BODY) + * @param tablePart indicates what part of the table to iterate over (HEADER, FOOTER, BODY) */ - public TableRowIterator(Table table, ColumnSetup columns, int what) { + public TableRowIterator(Table table, ColumnSetup columns, int tablePart) { this.table = table; this.columns = columns; - this.type = what; - switch(what) { + this.tablePart = tablePart; + switch(tablePart) { case HEADER: { List bodyList = new java.util.ArrayList(); bodyList.add(table.getTableHeader()); - this.bodyIterator = bodyList.listIterator(); + this.tablePartIterator = bodyList.listIterator(); break; } case FOOTER: { List bodyList = new java.util.ArrayList(); bodyList.add(table.getTableFooter()); - this.bodyIterator = bodyList.listIterator(); + this.tablePartIterator = bodyList.listIterator(); break; } default: { - this.bodyIterator = table.getChildNodes(); + this.tablePartIterator = table.getChildNodes(); } } } - + /** - *

Preloads the whole table. - *

- *

Note:This is inefficient for large tables. - *

+ * Preloads the whole table. + *

Note:This is inefficient for large tables.

*/ public void prefetchAll() { while (prefetchNext()) { log.trace("found row..."); } } - + /** - * Returns the next row group if any. A row group in this context is the minimum number of + * Returns the next row group if any. A row group in this context is the minimum number of * consecutive rows which contains all spanned grid units of its cells. * @return the next row group, or null */ @@ -154,118 +173,155 @@ public class TableRowIterator { } return rowGroup; } - + /** - * Retuns the next effective row. - * @return the requested effective row. + * Returns the row at the given index, fetching rows up to the requested one if + * necessary. + * + * @return the requested row, or null if there is no row at the given index (index + * < 0 or end of table-part reached) */ - public EffRow getNextRow() { - currentIndex++; + private EffRow getRow(int index) { boolean moreRows = true; - while (moreRows && rows.size() < currentIndex + 1) { + while (moreRows && fetchedRows.size() <= index) { moreRows = prefetchNext(); } - if (currentIndex < rows.size()) { - return getCachedRow(currentIndex); - } else { - return null; - } + // Whatever the value of index, getCachedRow will handle it nicely + return getCachedRow(index); + } + + /** + * Returns the next effective row. + * @return the requested effective row or null if there is no more row. + */ + private EffRow getNextRow() { + return getRow(iteratorIndex++); + } + + /** + * Returns the row preceding the given row, without moving the iterator. + * + * @param row a row in the iterated table part + * @return the preceding row, or null if there is no such row (the given row is the + * first one in the table part) + */ + public EffRow getPrecedingRow(EffRow row) { + return getRow(row.getIndex() - 1); + } + + /** + * Returns the row following the given row, without moving the iterator. + * + * @param row a row in the iterated table part + * @return the following row, or null if there is no more row + */ + public EffRow getFollowingRow(EffRow row) { + return getRow(row.getIndex() + 1); } - + /** * Sets the iterator to the previous row. */ public void backToPreviousRow() { - currentIndex--; + iteratorIndex--; } - + /** * Returns the first effective row. * @return the requested effective row. */ public EffRow getFirstRow() { - if (rows.size() == 0) { + if (fetchedRows.size() == 0) { prefetchNext(); } return getCachedRow(0); } - + /** - *

Returns the last effective row. - *

+ * Returns the last effective row. *

Note:This is inefficient for large tables because the whole table - * if preloaded. - *

+ * if preloaded.

* @return the requested effective row. */ public EffRow getLastRow() { while (prefetchNext()) { //nop } - return getCachedRow(rows.size() - 1); + return getCachedRow(fetchedRows.size() - 1); } - + /** - * Returns a cached effective row. + * Returns a cached effective row. If the given index points outside the range of rows + * (negative or greater than the number of already fetched rows), this methods + * terminates nicely by returning null. + * * @param index index of the row (zero-based) - * @return the requested effective row + * @return the requested effective row or null if (index < 0 || index >= the + * number of already fetched rows) */ public EffRow getCachedRow(int index) { - if (index < 0 || index >= rows.size()) { + if (index < 0 || index >= fetchedRows.size()) { return null; } else { - return (EffRow)rows.get(index); + return (EffRow)fetchedRows.get(index); } } - + + /** + * Fetches the next row. + * + * @return true if there was a row to fetch; otherwise, false (the end of the + * table-part has been reached) + */ private boolean prefetchNext() { boolean firstInTable = false; - boolean firstInBody = false; - if (childInBodyIterator != null) { - if (!childInBodyIterator.hasNext()) { - //force skip on to next body - if (pendingRowSpans > 0) { - this.currentRow.clear(); - this.currentRowIndex++; - EffRow gridUnits = buildGridRow(this.currentRow, null); - log.debug(gridUnits); - rows.add(gridUnits); - return true; - } - childInBodyIterator = null; - if (rows.size() > 0) { - getCachedRow(rows.size() - 1).setFlagForAllGridUnits( - GridUnit.LAST_IN_BODY, true); - } + boolean firstInTablePart = false; + // If we are at the end of the current table part + if (tablePartChildIterator != null && !tablePartChildIterator.hasNext()) { + //force skip on to next component + if (pendingRowSpans > 0) { + this.currentRow.clear(); + this.fetchIndex++; + EffRow gridUnits = buildGridRow(this.currentRow, null); + log.debug(gridUnits); + fetchedRows.add(gridUnits); + return true; + } + tablePartChildIterator = null; + if (fetchedRows.size() > 0) { + getCachedRow(fetchedRows.size() - 1).setFlagForAllGridUnits( + GridUnit.LAST_IN_PART, true); } } - if (childInBodyIterator == null) { - if (bodyIterator.hasNext()) { - childInBodyIterator = ((TableBody)bodyIterator.next()).getChildNodes(); - if (rows.size() == 0) { + // If the iterating over the current table-part has not started yet + if (tablePartChildIterator == null) { + if (tablePartIterator.hasNext()) { + tablePartChildIterator = ((TableBody)tablePartIterator.next()).getChildNodes(); + if (fetchedRows.size() == 0) { firstInTable = true; } - firstInBody = true; + firstInTablePart = true; } else { - //no more rows - if (rows.size() > 0) { - getCachedRow(rows.size() - 1).setFlagForAllGridUnits( - GridUnit.LAST_IN_BODY, true); - if ((type == FOOTER || table.getTableFooter() == null) - && type != HEADER) { - getCachedRow(rows.size() - 1).setFlagForAllGridUnits( + //no more rows in that part of the table + if (fetchedRows.size() > 0) { + getCachedRow(fetchedRows.size() - 1).setFlagForAllGridUnits( + GridUnit.LAST_IN_PART, true); + // If the last row is the last of the table + if (tablePart == FOOTER + || (tablePart == BODY && table.getTableFooter() == null)) { + getCachedRow(fetchedRows.size() - 1).setFlagForAllGridUnits( GridUnit.LAST_IN_TABLE, true); } } return false; } } - Object node = childInBodyIterator.next(); + Object node = tablePartChildIterator.next(); while (node instanceof Marker) { - node = childInBodyIterator.next(); + node = tablePartChildIterator.next(); } this.currentRow.clear(); - this.currentRowIndex++; + this.fetchIndex++; TableRow rowFO = null; if (node instanceof TableRow) { rowFO = (TableRow)node; @@ -276,11 +332,11 @@ public class TableRowIterator { } else if (node instanceof TableCell) { this.currentRow.add(node); if (!((TableCell)node).endsRow()) { - while (childInBodyIterator.hasNext()) { - TableCell cell = (TableCell)childInBodyIterator.next(); + while (tablePartChildIterator.hasNext()) { + TableCell cell = (TableCell)tablePartChildIterator.next(); if (cell.startsRow()) { //next row already starts here, one step back - childInBodyIterator.previous(); + tablePartChildIterator.previous(); break; } this.currentRow.add(cell); @@ -293,25 +349,33 @@ public class TableRowIterator { throw new IllegalStateException("Illegal class found: " + node.getClass().getName()); } EffRow gridUnits = buildGridRow(this.currentRow, rowFO); - if (firstInBody) { - gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_BODY, true); + if (firstInTablePart) { + gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_PART, true); } - if (firstInTable && (type == HEADER || table.getTableHeader() == null) - && type != FOOTER) { + if (firstInTable && (tablePart == HEADER || table.getTableHeader() == null) + && tablePart != FOOTER) { gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_TABLE, true); } log.debug(gridUnits); - rows.add(gridUnits); + fetchedRows.add(gridUnits); return true; } + /** + * Places the given object at the given position in the list, first extending it if + * necessary with null objects to reach the position. + * + * @param list the list in which to place the object + * @param position index at which the object must be placed (0-based) + * @param obj the object to place + */ private void safelySetListItem(List list, int position, Object obj) { while (position >= list.size()) { list.add(null); } list.set(position, obj); } - + private Object safelyGetListItem(List list, int position) { if (position >= list.size()) { return null; @@ -319,18 +383,25 @@ public class TableRowIterator { return list.get(position); } } - + + /** + * Builds the list of grid units corresponding to the given table row. + * + * @param cells list of cells belonging to the row + * @param rowFO the fo:table-row object containing the row, possibly null + * @return the list of grid units + */ private EffRow buildGridRow(List cells, TableRow rowFO) { - EffRow row = new EffRow(this.currentRowIndex, type); + EffRow row = new EffRow(this.fetchIndex, tablePart); List gridUnits = row.getGridUnits(); - + TableBody bodyFO = null; - - //Create all row-spanned grid units based on information from the last row + + //Create all row-spanned grid units based on information from the previous row int colnum = 1; - GridUnit[] horzSpan = null; + GridUnit[] horzSpan = null; // Grid units horizontally spanned by a single cell if (pendingRowSpans > 0) { - ListIterator spanIter = lastRowsSpanningCells.listIterator(); + ListIterator spanIter = previousRowsSpanningCells.listIterator(); while (spanIter.hasNext()) { GridUnit gu = (GridUnit)spanIter.next(); if (gu != null) { @@ -359,40 +430,40 @@ public class TableRowIterator { if (pendingRowSpans < 0) { throw new IllegalStateException("pendingRowSpans must not become negative!"); } - + //Transfer available cells to their slots colnum = 1; ListIterator iter = cells.listIterator(); while (iter.hasNext()) { TableCell cell = (TableCell)iter.next(); - + colnum = cell.getColumnNumber(); //TODO: remove the check below??? //shouldn't happen here, since - //overlapping cells already caught in + //overlapping cells already caught in //fo.flow.TableCell.bind()... - GridUnit other = (GridUnit)safelyGetListItem(gridUnits, colnum - 1); + GridUnit other = (GridUnit)safelyGetListItem(gridUnits, colnum - 1); if (other != null) { - String err = "A table-cell (" - + cell.getContextInfo() - + ") is overlapping with another (" - + other.getCell().getContextInfo() + String err = "A table-cell (" + + cell.getContextInfo() + + ") is overlapping with another (" + + other.getCell().getContextInfo() + ") in column " + colnum; - throw new IllegalStateException(err + throw new IllegalStateException(err + " (this should have been catched by FO tree validation)"); } TableColumn col = columns.getColumn(colnum); //Add grid unit for primary grid unit - PrimaryGridUnit gu = new PrimaryGridUnit(cell, col, colnum - 1, this.currentRowIndex); + PrimaryGridUnit gu = new PrimaryGridUnit(cell, col, colnum - 1, this.fetchIndex); safelySetListItem(gridUnits, colnum - 1, gu); boolean hasRowSpanningLeft = !gu.isLastGridUnitRowSpan(); if (hasRowSpanningLeft) { pendingRowSpans++; - safelySetListItem(lastRowsSpanningCells, colnum - 1, gu); + safelySetListItem(previousRowsSpanningCells, colnum - 1, gu); } - + if (gu.hasSpanning()) { //Add grid units on spanned slots if any horzSpan = new GridUnit[cell.getNumberColumnsSpanned()]; @@ -401,68 +472,68 @@ public class TableRowIterator { colnum++; GridUnit guSpan = new GridUnit(gu, columns.getColumn(colnum), colnum - 1, j); //TODO: remove the check below??? - other = (GridUnit)safelyGetListItem(gridUnits, colnum - 1); + other = (GridUnit)safelyGetListItem(gridUnits, colnum - 1); if (other != null) { - String err = "A table-cell (" - + cell.getContextInfo() - + ") is overlapping with another (" - + other.getCell().getContextInfo() + String err = "A table-cell (" + + cell.getContextInfo() + + ") is overlapping with another (" + + other.getCell().getContextInfo() + ") in column " + colnum; - throw new IllegalStateException(err + throw new IllegalStateException(err + " (this should have been catched by FO tree validation)"); } safelySetListItem(gridUnits, colnum - 1, guSpan); if (hasRowSpanningLeft) { pendingRowSpans++; - safelySetListItem(lastRowsSpanningCells, colnum - 1, gu); + safelySetListItem(previousRowsSpanningCells, colnum - 1, gu); } horzSpan[j] = guSpan; } gu.addRow(horzSpan); } - + //Gather info for empty grid units (used later) if (bodyFO == null) { bodyFO = gu.getBody(); } - + colnum++; } - + //Post-processing the list (looking for gaps and resolve start and end borders) fillEmptyGridUnits(gridUnits, rowFO, bodyFO); resolveStartEndBorders(gridUnits); - + return row; } - + private void fillEmptyGridUnits(List gridUnits, TableRow row, TableBody body) { for (int pos = 1; pos <= gridUnits.size(); pos++) { GridUnit gu = (GridUnit)gridUnits.get(pos - 1); - + //Empty grid units if (gu == null) { //Add grid unit - gu = new EmptyGridUnit(row, columns.getColumn(pos), body, + gu = new EmptyGridUnit(row, columns.getColumn(pos), body, pos - 1); gridUnits.set(pos - 1, gu); } - + //Set flags gu.setFlag(GridUnit.IN_FIRST_COLUMN, (pos == 1)); gu.setFlag(GridUnit.IN_LAST_COLUMN, (pos == gridUnits.size())); } } - + private void resolveStartEndBorders(List gridUnits) { for (int pos = 1; pos <= gridUnits.size(); pos++) { GridUnit starting = (GridUnit)gridUnits.get(pos - 1); - + //Border resolution if (table.isSeparateBorderModel()) { starting.assignBorderForSeparateBorderModel(); } else { - //Neighbouring grid unit at start edge + //Neighbouring grid unit at start edge GridUnit start = null; int find = pos - 1; while (find >= 1) { @@ -473,15 +544,15 @@ public class TableRowIterator { } find--; } - + //Ending grid unit for current cell GridUnit ending = null; if (starting.getCell() != null) { pos += starting.getCell().getNumberColumnsSpanned() - 1; } ending = (GridUnit)gridUnits.get(pos - 1); - - //Neighbouring grid unit at end edge + + //Neighbouring grid unit at end edge GridUnit end = null; find = pos + 1; while (find <= gridUnits.size()) { @@ -492,9 +563,9 @@ public class TableRowIterator { } find++; } - starting.resolveBorder(start, + starting.resolveBorder(start, CommonBorderPaddingBackground.START); - ending.resolveBorder(end, + ending.resolveBorder(end, CommonBorderPaddingBackground.END); //Only start and end borders here, before and after during layout } -- 2.39.5