Browse Source

Documentation, cleanup, log statements in the table layout code.


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@519975 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_94
Vincent Hennebert 17 years ago
parent
commit
12deb5966a

+ 5
- 1
src/java/org/apache/fop/fo/flow/Table.java View File

@@ -349,7 +349,11 @@ public class Table extends TableFObj {
return (tableLayout == EN_AUTO);
}

/** @return the list of table-column elements. */
/**
* Returns the list of table-column elements.
*
* @return a list of {@link TableColumn} elements, may contain null elements
*/
public List getColumns() {
return columns;
}

+ 8
- 0
src/java/org/apache/fop/layoutmgr/LayoutContext.java View File

@@ -298,10 +298,18 @@ public class LayoutContext {
return stackLimit;
}

/**
* Sets the inline-progression-dimension of the nearest ancestor reference area.
*/
public void setRefIPD(int ipd) {
refIPD = ipd;
}

/**
* Returns the inline-progression-dimension of the nearest ancestor reference area.
*
* @return the inline-progression-dimension of the nearest ancestor reference area
*/
public int getRefIPD() {
return refIPD;
}

+ 12
- 2
src/java/org/apache/fop/layoutmgr/Position.java View File

@@ -43,11 +43,21 @@ public class Position {
public boolean generatesAreas() {
return false;
}

/**
* Sets the index of this position in the sequence of Position elements.
*
* @param value this position's index
*/
public void setIndex(int value) {
this.index = value;
}

/**
* Returns the index of this position in the sequence of Position elements.
*
* @return the index of this position in the sequence of Position elements
*/
public int getIndex() {
return this.index;
}

+ 26
- 3
src/java/org/apache/fop/layoutmgr/table/GridUnit.java View File

@@ -19,6 +19,8 @@

package org.apache.fop.layoutmgr.table;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.flow.Table;
import org.apache.fop.fo.flow.TableBody;
@@ -33,6 +35,8 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
*/
public class GridUnit {

private static Log log = LogFactory.getLog(GridUnit.class);

/** Indicates that the grid unit is in the first column. */
public static final int IN_FIRST_COLUMN = 0;
/** Indicates that the grid unit is in the last column. */
@@ -86,7 +90,7 @@ public class GridUnit {
/**
* Creates a new grid unit.
*
* @param primary ??
* @param primary the before-start grid unit of the cell containing 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
@@ -98,7 +102,7 @@ public class GridUnit {
/**
* Creates a new grid unit.
*
* @param primary ??
* @param primary the before-start grid unit of the cell containing this 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
@@ -158,16 +162,28 @@ public class GridUnit {
}

/**
* @return the primary grid unit if this is a spanned grid unit
* Returns the before-start grid unit of the cell containing this grid unit.
*
* @return the before-start grid unit of the cell containing this grid unit.
*/
public PrimaryGridUnit getPrimary() {
return (isPrimary() ? (PrimaryGridUnit)this : primary);
}

/**
* Is this grid unit the before-start grid unit of the cell?
*
* @return true if this grid unit is the before-start grid unit of the cell
*/
public boolean isPrimary() {
return false;
}

/**
* Does this grid unit belong to an empty cell?
*
* @return true if this grid unit belongs to an empty cell
*/
public boolean isEmpty() {
return cell == null;
}
@@ -273,6 +289,13 @@ public class GridUnit {
if (cell != null) {
effectiveBorders.setPadding(cell.getCommonBorderPaddingBackground());
}
if (log.isDebugEnabled()) {
log.debug(this + " resolved borders: "
+ "before=" + effectiveBorders.getBorderBeforeWidth(false) + ", "
+ "after=" + effectiveBorders.getBorderAfterWidth(false) + ", "
+ "start=" + effectiveBorders.getBorderStartWidth(false) + ", "
+ "end=" + effectiveBorders.getBorderEndWidth(false));
}
}

/**

+ 7
- 1
src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java View File

@@ -22,14 +22,19 @@ package org.apache.fop.layoutmgr.table;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.fo.flow.TableCell;
import org.apache.fop.fo.flow.TableColumn;

/**
* This class represents a primary grid unit of a spanned cell.
* This class represents a primary grid unit of a spanned cell. This is the "before-start"
* (top-left, usually) grid unit of the span.
*/
public class PrimaryGridUnit extends GridUnit {

private static Log log = LogFactory.getLog(PrimaryGridUnit.class);

/** Cell layout manager. */
private TableCellLayoutManager cellLM;
/** List of Knuth elements representing the contents of the cell. */
@@ -52,6 +57,7 @@ public class PrimaryGridUnit extends GridUnit {
public PrimaryGridUnit(TableCell cell, TableColumn column, int startCol, int startRow) {
super(cell, column, startCol, 0);
this.startRow = startRow;
log.trace("PrimaryGridUnit created, row " + startRow + " col " + startCol);
if (cell != null) {
cellLM = new TableCellLayoutManager(cell, this);
}

+ 64
- 27
src/java/org/apache/fop/layoutmgr/table/RowPainter.java View File

@@ -34,21 +34,40 @@ import org.apache.fop.layoutmgr.SpaceResolver;

class RowPainter {
private static Log log = LogFactory.getLog(RowPainter.class);
/** The fo:table-row containing the currently handled grid rows. */
private TableRow rowFO = null;
private int colCount;
private int yoffset = 0;
private int accumulatedBPD = 0;
/** Currently handled row (= last encountered row). */
private EffRow lastRow = null;
private LayoutContext layoutContext;
private int lastRowHeight = 0;
/**
* For each part of the table (header, footer, body), index of the first row of that
* part present on the current page.
*/
private int[] firstRow = new int[3];
private Map[] rowOffsets = new Map[] {new java.util.HashMap(),
new java.util.HashMap(), new java.util.HashMap()};

//These three variables are our buffer to recombine the individual steps into cells
private PrimaryGridUnit[] gridUnits;
/** Primary grid units corresponding to the currently handled grid units, per row. */
private PrimaryGridUnit[] primaryGridUnits;
/**
* Index, in the corresponding table cell's list of Knuth elements, of the first
* element present on the current page, per column.
*/
private int[] start;
/**
* Index, in the corresponding table cell's list of Knuth elements, of the last
* element present on the current page, per column.
*/
private int[] end;
/**
* Length, for each column, of the elements from the current cell put on the
* current page.
*/
private int[] partLength;
private TableContentLayoutManager tclm;

@@ -56,7 +75,7 @@ class RowPainter {
this.tclm = tclm;
this.layoutContext = layoutContext;
this.colCount = tclm.getColumns().getColumnCount();
this.gridUnits = new PrimaryGridUnit[colCount];
this.primaryGridUnits = new PrimaryGridUnit[colCount];
this.start = new int[colCount];
this.end = new int[colCount];
this.partLength = new int[colCount];
@@ -76,6 +95,12 @@ class RowPainter {
this.lastRowHeight += length;
}

/**
* Records the fragment of row represented by the given position. If it belongs to
* another (grid) row than the current one, that latter is painted and flushed first.
*
* @param tcpos a position representing the row fragment
*/
public void handleTableContentPosition(TableContentPosition tcpos) {
if (lastRow != tcpos.row && lastRow != null) {
addAreasAndFlushRow(false);
@@ -95,12 +120,12 @@ class RowPainter {
log.debug(">" + gup);
}
int colIndex = gup.pgu.getStartCol();
if (gridUnits[colIndex] != gup.pgu) {
if (gridUnits[colIndex] != null) {
if (primaryGridUnits[colIndex] != gup.pgu) {
if (primaryGridUnits[colIndex] != null) {
log.warn("Replacing GU in slot " + colIndex
+ ". Some content may not be painted.");
}
gridUnits[colIndex] = gup.pgu;
primaryGridUnits[colIndex] = gup.pgu;
start[colIndex] = gup.start;
end[colIndex] = gup.end;
} else {
@@ -112,6 +137,16 @@ class RowPainter {
}
}

/**
* Create the areas corresponding to the last row. This method is called either
* because the row is finished (all of the elements present on this row have been
* added), or because this is the last row on the current page, and the part of it
* lying on the current page must be drawn.
*
* @param forcedFlush true if the elements must be drawn even if the row isn't
* finished yet (last row on the page)
* @return the height of the (grid) row
*/
public int addAreasAndFlushRow(boolean forcedFlush) {
int actualRowHeight = 0;
int readyCount = 0;
@@ -122,30 +157,29 @@ class RowPainter {
}
rowOffsets[bt].put(new Integer(lastRow.getIndex()), new Integer(yoffset));

for (int i = 0; i < gridUnits.length; i++) {
if ((gridUnits[i] != null)
&& (forcedFlush || (end[i] == gridUnits[i].getElements().size() - 1))) {
for (int i = 0; i < primaryGridUnits.length; i++) {
if ((primaryGridUnits[i] != null)
&& (forcedFlush || (end[i] == primaryGridUnits[i].getElements().size() - 1))) {
if (log.isTraceEnabled()) {
log.trace("getting len for " + i + " "
+ start[i] + "-" + end[i]);
}
readyCount++;
int len = ElementListUtils.calcContentLength(
gridUnits[i].getElements(), start[i], end[i]);
primaryGridUnits[i].getElements(), start[i], end[i]);
partLength[i] = len;
if (log.isTraceEnabled()) {
log.trace("len of part: " + len);
}

if (start[i] == 0) {
LengthRangeProperty bpd = gridUnits[i].getCell()
LengthRangeProperty bpd = primaryGridUnits[i].getCell()
.getBlockProgressionDimension();
if (!bpd.getMinimum(tclm.getTableLM()).isAuto()) {
int min = bpd.getMinimum(tclm.getTableLM())
.getLength().getValue(tclm.getTableLM());
if (min > 0) {
len = Math.max(len, bpd.getMinimum(tclm.getTableLM())
.getLength().getValue(tclm.getTableLM()));
len = Math.max(len, min);
}
}
if (!bpd.getOptimum(tclm.getTableLM()).isAuto()) {
@@ -155,8 +189,8 @@ class RowPainter {
len = Math.max(len, opt);
}
}
if (gridUnits[i].getRow() != null) {
bpd = gridUnits[i].getRow().getBlockProgressionDimension();
if (primaryGridUnits[i].getRow() != null) {
bpd = primaryGridUnits[i].getRow().getBlockProgressionDimension();
if (!bpd.getMinimum(tclm.getTableLM()).isAuto()) {
int min = bpd.getMinimum(tclm.getTableLM()).getLength()
.getValue(tclm.getTableLM());
@@ -168,17 +202,20 @@ class RowPainter {
}

// Add the padding if any
len += gridUnits[i].getBorders()
.getPaddingBefore(false, gridUnits[i].getCellLM());
len += gridUnits[i].getBorders()
.getPaddingAfter(false, gridUnits[i].getCellLM());
len += primaryGridUnits[i].getBorders()
.getPaddingBefore(false, primaryGridUnits[i].getCellLM());
len += primaryGridUnits[i].getBorders()
.getPaddingAfter(false, primaryGridUnits[i].getCellLM());

//Now add the borders to the contentLength
if (tclm.isSeparateBorderModel()) {
len += gridUnits[i].getBorders().getBorderBeforeWidth(false);
len += gridUnits[i].getBorders().getBorderAfterWidth(false);
len += primaryGridUnits[i].getBorders().getBorderBeforeWidth(false);
len += primaryGridUnits[i].getBorders().getBorderAfterWidth(false);
} else {
len += primaryGridUnits[i].getHalfMaxBeforeBorderWidth();
len += primaryGridUnits[i].getHalfMaxAfterBorderWidth();
}
int startRow = Math.max(gridUnits[i].getStartRow(), firstRow[bt]);
int startRow = Math.max(primaryGridUnits[i].getStartRow(), firstRow[bt]);
Integer storedOffset = (Integer)rowOffsets[bt].get(new Integer(startRow));
int effYOffset;
if (storedOffset != null) {
@@ -198,12 +235,12 @@ class RowPainter {

//Add areas for row
tclm.addRowBackgroundArea(rowFO, actualRowHeight, layoutContext.getRefIPD(), yoffset);
for (int i = 0; i < gridUnits.length; i++) {
for (int i = 0; i < primaryGridUnits.length; i++) {
GridUnit currentGU = lastRow.safelyGetGridUnit(i);
if ((gridUnits[i] != null)
&& (forcedFlush || ((end[i] == gridUnits[i].getElements().size() - 1))
if ((primaryGridUnits[i] != null)
&& (forcedFlush || (end[i] == primaryGridUnits[i].getElements().size() - 1)
&& (currentGU == null || currentGU.isLastGridUnitRowSpan()))
|| (gridUnits[i] == null && currentGU != null)) {
|| (primaryGridUnits[i] == null && currentGU != null)) {
//the last line in the "if" above is to avoid a premature end of an
//row-spanned cell because no GridUnitParts are generated after a cell is
//finished with its content. currentGU can be null if there's no grid unit
@@ -212,7 +249,7 @@ class RowPainter {
log.debug((forcedFlush ? "FORCED " : "") + "flushing..." + i + " "
+ start[i] + "-" + end[i]);
}
PrimaryGridUnit gu = gridUnits[i];
PrimaryGridUnit gu = primaryGridUnits[i];
if (gu == null
&& !currentGU.isEmpty()
&& currentGU.getColSpanIndex() == 0
@@ -224,7 +261,7 @@ class RowPainter {
addAreasForCell(gu, start[i], end[i],
lastRow,
partLength[i], actualRowHeight);
gridUnits[i] = null;
primaryGridUnits[i] = null;
start[i] = 0;
end[i] = -1;
partLength[i] = 0;

+ 14
- 6
src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java View File

@@ -278,7 +278,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
}
if (returnList.size() > 0) {
//Remove last penalty
//Remove the last penalty produced by the combining algorithm (see TableStepper), for the last step
ListElement last = (ListElement)returnList.getLast();
if (last.isPenalty() || last instanceof BreakElement) {
if (!last.isForcedBreak()) {
@@ -326,7 +326,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
//whole body iterator to be prefetched!
prevRow = this.bodyIter.getLastRow();
}
log.debug(prevRow + " - " + row + " - " + nextRow);
log.debug("prevRow-row-nextRow: " + prevRow + " - " + row + " - " + nextRow);
//Determine the grid units necessary for getting all the borders right
int guCount = row.getGridUnits().size();
@@ -400,7 +400,6 @@ public class TableContentLayoutManager implements PercentBaseContext {
CommonBorderPaddingBackground.AFTER, flags);
}
}

}
}
}
@@ -429,7 +428,9 @@ public class TableContentLayoutManager implements PercentBaseContext {
pgus.clear();
TableRow tableRow = null;
int minContentHeight = 0; // Minimum content height for the row
// The row's minimum content height; 0 if the row's height is auto, otherwise
// the .minimum component of the explicitely specified value
int minContentHeight = 0;
int maxCellHeight = 0;
int effRowContentHeight = 0;
for (int j = 0; j < row.getGridUnits().size(); j++) {
@@ -698,7 +699,13 @@ public class TableContentLayoutManager implements PercentBaseContext {
false, getTableLM().isFirst(firstPos), getTableLM().isLast(lastCheckPos));
}
}

/**
* Iterates over a part of the table and paints the related elements.
*
* @param iterator iterator over the table's header, body or footer elements
* @param painter
*/
private void iterateAndPaintPositions(Iterator iterator, RowPainter painter) {
List lst = new java.util.ArrayList();
boolean firstPos = false;
@@ -713,13 +720,14 @@ public class TableContentLayoutManager implements PercentBaseContext {
if (body == null) {
body = part.pgu.getBody();
}
if (tcpos.getFlag(TableContentPosition.FIRST_IN_ROWGROUP)
if (tcpos.getFlag(TableContentPosition.FIRST_IN_ROWGROUP)
&& tcpos.row.getFlag(EffRow.FIRST_IN_PART)) {
firstPos = true;

}
if (tcpos.getFlag(TableContentPosition.LAST_IN_ROWGROUP)
&& tcpos.row.getFlag(EffRow.LAST_IN_PART)) {
log.trace("LAST_IN_ROWGROUP + LAST_IN_PART");
lastPos = true;
getTableLM().getCurrentPV().addMarkers(body.getMarkers(),
true, firstPos, lastPos);

+ 12
- 8
src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java View File

@@ -134,12 +134,18 @@ public class TableLayoutManager extends BlockStackingLayoutManager
this.effSpaceAfter = null;
}
/** @return half the value of border-separation.block-progression-dimension. */
/**
* @return half the value of border-separation.block-progression-dimension, or 0 if
* border-collapse="collapse".
*/
public int getHalfBorderSeparationBPD() {
return halfBorderSeparationBPD;
}

/** @return half the value of border-separation.inline-progression-dimension. */
/**
* @return half the value of border-separation.inline-progression-dimension, or 0 if
* border-collapse="collapse".
*/
public int getHalfBorderSeparationIPD() {
return halfBorderSeparationIPD;
}
@@ -157,12 +163,9 @@ public class TableLayoutManager extends BlockStackingLayoutManager
LinkedList returnList = new LinkedList();
if (!breakBeforeServed) {
try {
if (addKnuthElementsForBreakBefore(returnList, context)) {
return returnList;
}
} finally {
breakBeforeServed = true;
breakBeforeServed = true;
if (addKnuthElementsForBreakBefore(returnList, context)) {
return returnList;
}
}

@@ -344,6 +347,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager
// add column, body then row areas

// BPD of the table, i.e., height of its content; table's borders and paddings not counted
int tableHeight = 0;
//Body childLM;
LayoutContext lc = new LayoutContext(0);

+ 6
- 14
src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java View File

@@ -35,7 +35,7 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground;


/**
* Iterator that lets the table layout manager step over all of the rows of a part of the
* Iterator that lets the table layout manager step over all the rows of a part of the
* table (table-header, table-footer or table-body).
* <p>Note: This class is not thread-safe.</p>
*/
@@ -72,7 +72,9 @@ public class TableRowIterator {
/** 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. */
/**
* Number of 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
@@ -125,16 +127,6 @@ public class TableRowIterator {
}
}

/**
* Preloads the whole table.
* <p>Note:This is inefficient for large tables.</p>
*/
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
* consecutive rows which contains all spanned grid units of its cells.
@@ -259,7 +251,7 @@ public class TableRowIterator {
* @return the requested effective row or null if (index &lt; 0 || index &gt;= the
* number of already fetched rows)
*/
public EffRow getCachedRow(int index) {
private EffRow getCachedRow(int index) {
if (index < 0 || index >= fetchedRows.size()) {
return null;
} else {
@@ -387,7 +379,7 @@ public class TableRowIterator {
/**
* Builds the list of grid units corresponding to the given table row.
*
* @param cells list of cells belonging to the row
* @param cells list of cells starting at the current row
* @param rowFO the fo:table-row object containing the row, possibly null
* @return the list of grid units
*/

+ 36
- 9
src/java/org/apache/fop/layoutmgr/table/TableStepper.java View File

@@ -59,18 +59,22 @@ public class TableStepper {
private int[] startRow;
/**
* For each column, index, in the cell's list of Knuth elements, of the element
* starting the current row.
* starting the current step.
*/
private int[] start;
/**
* For each column, index, in the cell's list of Knuth elements, of the element
* ending the current row.
* ending the current step.
*/
private int[] end;
/**
* For each column, widths of the Knuth elements which will be on the current row.
* For each column, widths of the Knuth elements already included in the steps, up to
* the current one.
*/
private int[] widths;
/**
* ?? Width from the start of the row-group up to the current row.
*/
private int[] baseWidth;
private int[] borderBefore;
private int[] paddingBefore;
@@ -240,6 +244,9 @@ public class TableStepper {
//Copy elements (LinkedList) to array lists to improve
//element access performance
elementLists[column] = new java.util.ArrayList(pgu.getElements());
if (log.isTraceEnabled()) {
log.trace("column " + (column+1) + ": recording " + elementLists[column].size() + " element(s)");
}
}
if (isSeparateBorderModel()) {
borderBefore[column] = pgu.getBorders().getBorderBeforeWidth(false);
@@ -267,6 +274,7 @@ public class TableStepper {
* the current row group.
*/
private void initializeElementLists() {
log.trace("Entering initializeElementLists()");
for (int i = 0; i < start.length; i++) {
setupElementList(i);
}
@@ -443,8 +451,15 @@ public class TableStepper {
}
return returnList;
}

/**
* Finds the smallest increment leading to the next legal break inside the row-group.
*
* @param lastStep used for log only
* @return the size of the increment, -1 if no next step is available (end of row-group reached)
*/
private int getNextStep(int lastStep) {
log.trace("Entering getNextStep");
this.lastMaxPenaltyLength = 0;
//Check for forced break conditions
/*
@@ -460,6 +475,7 @@ public class TableStepper {
// boolean will be reset (see below)
boolean currentGridRowFinished = true;
for (int i = 0; i < start.length; i++) {
// null element lists probably correspond to empty cells
if (elementLists[i] == null) {
continue;
}
@@ -474,8 +490,9 @@ public class TableStepper {
currentGridRowFinished = false;
}
} else {
start[i] = -1; //end of list reached
end[i] = -1;
throw new IllegalStateException("end[i] overflows elementList[i].size()");
// start[i] = -1; //end of list reached
// end[i] = -1;
}
}

@@ -539,6 +556,10 @@ public class TableStepper {
}
}
if (end[i] < start[i]) {
if (log.isTraceEnabled()) {
log.trace("column " + (i + 1) + ": (end=" + end[i] + ") < (start=" + start[i]
+ ") => resetting width to backupWidth");
}
widths[i] = backupWidths[i];
} else {
seqCount++;
@@ -563,8 +584,8 @@ public class TableStepper {
}
}
if (log.isTraceEnabled()) {
log.trace("column " + i + ": borders before=" + borderBefore[i] + " after=" + borderAfter[i]);
log.trace("column " + i + ": padding before=" + paddingBefore[i] + " after=" + paddingAfter[i]);
log.trace("column " + (i+1) + ": borders before=" + borderBefore[i] + " after=" + borderAfter[i]);
log.trace("column " + (i+1) + ": padding before=" + paddingBefore[i] + " after=" + paddingAfter[i]);
}
}
if (seqCount == 0) {
@@ -608,7 +629,13 @@ public class TableStepper {
widths[i] = backupWidths[i];
end[i] = start[i] - 1;
if (baseWidth[i] + widths[i] > minStep) {
log.debug("minStep vs. border/padding increase conflict:");
if (log.isDebugEnabled()) {
log.debug("column "
+ (i + 1)
+ ": minStep vs. border/padding increase conflict: basewidth + width = "
+ baseWidth[i] + " + " + widths[i] + " = "
+ (baseWidth[i] + widths[i]));
}
if (activeRowIndex == 0) {
log.debug(" First row. Skip this step.");
skippedStep = true;

Loading…
Cancel
Save