Browse Source

- fix the painting of borders for spanning cells in collapsing model

- rename gridUnit into primaryGridUnit in TableCellLM for clarity
- fix some checkstyle issues


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

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

@@ -28,8 +28,8 @@ public class KnuthPossPosIter extends PositionIterator {
/**
* Main constructor
* @param elementList List of Knuth elements
* @param startPos starting position
* @param endPos ending position
* @param startPos starting position, inclusive
* @param endPos ending position, exclusive
*/
public KnuthPossPosIter(List elementList, int startPos, int endPos) {
super(elementList.listIterator(startPos));

+ 33
- 10
src/java/org/apache/fop/layoutmgr/table/RowPainter.java View File

@@ -179,7 +179,8 @@ class RowPainter {
//row-spanned cell because no GridUnitParts are generated after a cell is
//finished with its content.
//See table-cell_number-rows-spanned_bug38397.xml
addAreasForCell(primaryGridUnits[i], start[i], end[i], lastRow, partBPD[i], actualRowHeight);
addAreasForCell(primaryGridUnits[i], start[i], end[i], lastRow, partBPD[i],
actualRowHeight);
primaryGridUnits[i] = null;
start[i] = 0;
end[i] = -1;
@@ -191,7 +192,8 @@ class RowPainter {
//A row-spanned cell has finished contributing content on the previous page
//and now still has to cause grid units to be painted.
//See table-cell_page-break_span.xml
addAreasForCell(currentGU.getPrimary(), start[i], end[i], lastRow, partBPD[i], actualRowHeight);
addAreasForCell(currentGU.getPrimary(), start[i], end[i], lastRow, partBPD[i],
actualRowHeight);
start[i] = 0;
end[i] = -1;
partBPD[i] = 0;
@@ -221,11 +223,12 @@ class RowPainter {
* @param start index of the first element of the cell occuring on the current page
* @param end index of the last element of the cell occuring on the current page
* @param columnIndex column index of the cell
* @param bodyType {@link TableRowIterator#HEADER}, {@link TableRowIterator#FOOTER},
* @param bodyType {@link TableRowIterator#HEADER}, {@link TableRowIterator#FOOTER}, or
* {@link TableRowIterator#BODY}
* @return the cell's height
*/
private int computeSpanHeight(PrimaryGridUnit pgu, int start, int end, int columnIndex, int bodyType) {
private int computeSpanHeight(PrimaryGridUnit pgu, int start, int end, int columnIndex,
int bodyType) {
if (log.isTraceEnabled()) {
log.trace("getting len for " + columnIndex + " "
+ start + "-" + end);
@@ -299,14 +302,33 @@ class RowPainter {
firstRow[bt] = row.getIndex();
}
//Determine the first row in this sequence
int startRow = Math.max(pgu.getStartRow(), firstRow[bt]);
int startRowIndex = Math.max(pgu.getStartRow(), firstRow[bt]);
int lastRowIndex = lastRow.getIndex();

// In collapsing-border model, if the cell spans over several columns/rows then
// dedicated areas will be created for each grid unit to hold the corresponding
// borders. For that we need to know the height of each grid unit, that is of each
// grid row spanned over by the cell
int[] spannedGridRowHeights = null;
if (!tclm.getTableLM().getTable().isSeparateBorderModel() && pgu.hasSpanning()) {
spannedGridRowHeights = new int[lastRowIndex - startRowIndex + 1];
int prevOffset = ((Integer)rowOffsets[bt].get(new Integer(startRowIndex))).intValue();
for (int i = 0; i < lastRowIndex - startRowIndex; i++) {
int newOffset = ((Integer) rowOffsets[bt].get(new Integer(startRowIndex + i + 1)))
.intValue();
spannedGridRowHeights[i] = newOffset - prevOffset;
prevOffset = newOffset;
}
spannedGridRowHeights[lastRowIndex - startRowIndex] = rowHeight;
}

//Determine y offset for the cell
Integer offset = (Integer)rowOffsets[bt].get(new Integer(startRow));
Integer offset = (Integer)rowOffsets[bt].get(new Integer(startRowIndex));
while (offset == null) {
//TODO Figure out what this does and when it's triggered
//This block is probably never used, at least it's not triggered by any of our tests
startRow--;
offset = (Integer)rowOffsets[bt].get(new Integer(startRow));
startRowIndex--;
offset = (Integer)rowOffsets[bt].get(new Integer(startRowIndex));
}
int effYOffset = offset.intValue();
int effCellHeight = rowHeight;
@@ -329,7 +351,8 @@ class RowPainter {
SpaceResolver.performConditionalsNotification(pgu.getElements(),
startPos, endPos, prevBreak);
}
cellLM.addAreas(new KnuthPossPosIter(pgu.getElements(),
startPos, endPos + 1), layoutContext);
cellLM.addAreas(new KnuthPossPosIter(pgu.getElements(), startPos, endPos + 1),
layoutContext, spannedGridRowHeights, startRowIndex - pgu.getStartRow(),
lastRowIndex - pgu.getStartRow() + 1);
}
}

+ 94
- 85
src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java View File

@@ -16,13 +16,14 @@
*/

/* $Id$ */
package org.apache.fop.layoutmgr.table;

import java.util.LinkedList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.flow.Table;
import org.apache.fop.fo.flow.TableCell;
@@ -48,20 +49,20 @@ import org.apache.fop.traits.MinOptMax;
* LayoutManager for a table-cell FO.
* A cell contains blocks. These blocks fill the cell.
*/
public class TableCellLayoutManager extends BlockStackingLayoutManager
public class TableCellLayoutManager extends BlockStackingLayoutManager
implements BlockLevelLayoutManager {

/**
* logging instance
*/
private static Log log = LogFactory.getLog(TableCellLayoutManager.class);
private PrimaryGridUnit gridUnit;
private PrimaryGridUnit primaryGridUnit;
private Block curBlockArea;

private int inRowIPDOffset;
private int xoffset;
private int yoffset;
private int cellIPD;
@@ -75,23 +76,23 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
/**
* Create a new Cell layout manager.
* @param node table-cell FO for which to create the LM
* @param pgu primary grid unit for the cell
* @param pgu primary grid unit for the cell
*/
public TableCellLayoutManager(TableCell node, PrimaryGridUnit pgu) {
super(node);
fobj = node;
this.gridUnit = pgu;
this.primaryGridUnit = pgu;
}

/** @return the table-cell FO */
public TableCell getTableCell() {
return (TableCell)this.fobj;
}
private boolean isSeparateBorderModel() {
return getTable().isSeparateBorderModel();
}
/** @see org.apache.fop.layoutmgr.LayoutManager#initialize() */
public void initialize() {
borderAndPaddingBPD = 0;
@@ -107,7 +108,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
borderAndPaddingBPD += getTableCell().getCommonBorderPaddingBackground()
.getPaddingAfter(false, this);
}
/**
* @return the table owning this cell
*/
@@ -118,12 +119,12 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
}
return (Table)node;
}

/** @see org.apache.fop.layoutmgr.BlockStackingLayoutManager#getIPIndents() */
protected int getIPIndents() {
int iIndents = 0;
int[] startEndBorderWidths = gridUnit.getStartEndBorderWidths();
int[] startEndBorderWidths = primaryGridUnit.getStartEndBorderWidths();
startBorderWidth += startEndBorderWidths[0];
endBorderWidth += startEndBorderWidths[1];
iIndents += startBorderWidth;
@@ -135,14 +136,14 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
iIndents += getTableCell().getCommonBorderPaddingBackground().getPaddingEnd(false, this);
return iIndents;
}
/**
* @see org.apache.fop.layoutmgr.LayoutManager
*/
public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
MinOptMax stackLimit = new MinOptMax(context.getStackLimit());

referenceIPD = context.getRefIPD();
referenceIPD = context.getRefIPD();
cellIPD = referenceIPD;
cellIPD -= getIPIndents();
if (isSeparateBorderModel()) {
@@ -173,7 +174,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
}
if (returnedList.size() == 1
&& ((ListElement)returnedList.getFirst()).isForcedBreak()) {
// a descendant of this block has break-before
@@ -193,13 +194,13 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager

//Space resolution
SpaceResolver.resolveElementList(returnList);
return returnList;
} else {
if (prevLM != null) {
// there is a block handled by prevLM
// before the one handled by curLM
if (mustKeepTogether()
if (mustKeepTogether()
|| context.isKeepWithNextPending()
|| childLC.isKeepWithPreviousPending()) {
//Clear keep pending flag
@@ -242,7 +243,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager

//Space resolution
SpaceResolver.resolveElementList(returnList);
return returnList;
}
}
@@ -256,16 +257,16 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager

returnedList = new LinkedList();
wrapPositionElements(contentList, returnList);
//Space resolution
SpaceResolver.resolveElementList(returnList);
getPSLM().notifyEndOfLayout(((TableCell)getFObj()).getId());
setFinished(true);
return returnList;
}
/**
* Set the y offset of this cell.
* This offset is used to set the absolute position of the cell.
@@ -294,7 +295,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
public void setInRowIPDOffset(int off) {
this.inRowIPDOffset = off;
}
/**
* Set the content height for this cell. This method is used during
* addAreas() stage.
@@ -304,7 +305,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
public void setContentHeight(int h) {
usedBPD = h;
}
/**
* Set the row height that contains this cell. This method is used during
* addAreas() stage.
@@ -328,24 +329,36 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
} else {
bpd -= gu.getPrimary().getHalfMaxBorderWidth();
}
CommonBorderPaddingBackground cbpb
= gu.getCell().getCommonBorderPaddingBackground();
CommonBorderPaddingBackground cbpb
= gu.getCell().getCommonBorderPaddingBackground();
bpd -= cbpb.getPaddingBefore(false, this);
bpd -= cbpb.getPaddingAfter(false, this);
bpd -= 2 * ((TableLayoutManager)getParent()).getHalfBorderSeparationBPD();
return bpd;
}
/**
* Add the areas for the break points.
* The cell contains block stacking layout managers
* that add block areas.
*
* Add the areas for the break points. The cell contains block stacking layout
* managers that add block areas.
*
* <p>In the collapsing-border model, the borders of a cell that spans over several
* rows or columns are drawn separately for each grid unit. Therefore we must know the
* height of each grid row spanned over by the cell. Also, if the cell is broken over
* two pages we must know which spanned grid rows are present on the current page.</p>
*
* @param parentIter the iterator of the break positions
* @param layoutContext the layout context for adding the areas
* @param spannedGridRowHeights in collapsing-border model for a spanning cell, height
* of each spanned grid row
* @param startRow first grid row on the current page spanned over by the cell,
* inclusive
* @param endRow last grid row on the current page spanned over by the cell, exclusive
*/
public void addAreas(PositionIterator parentIter,
LayoutContext layoutContext) {
LayoutContext layoutContext,
int[] spannedGridRowHeights,
int startRow,
int endRow) {
getParentArea(null);

getPSLM().addIDToPage(getTableCell().getId());
@@ -358,68 +371,65 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
false, false, false, false, this);
}
} else {
boolean[] outer = new boolean[] {
gridUnit.getFlag(GridUnit.FIRST_IN_TABLE),
gridUnit.getFlag(GridUnit.LAST_IN_TABLE),
gridUnit.getFlag(GridUnit.IN_FIRST_COLUMN),
gridUnit.getFlag(GridUnit.IN_LAST_COLUMN)};
if (!gridUnit.hasSpanning()) {
if (!primaryGridUnit.hasSpanning()) {
//Can set the borders directly if there's no span
TraitSetter.addCollapsingBorders(curBlockArea,
gridUnit.getBorders(), outer, this);
boolean[] outer = new boolean[] {
primaryGridUnit.getFlag(GridUnit.FIRST_IN_TABLE),
primaryGridUnit.getFlag(GridUnit.LAST_IN_TABLE),
primaryGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN),
primaryGridUnit.getFlag(GridUnit.IN_LAST_COLUMN)};
TraitSetter.addCollapsingBorders(curBlockArea,
primaryGridUnit.getBorders(), outer, this);
} else {
boolean[] outer = new boolean[4];
int dy = yoffset;
for (int y = 0; y < gridUnit.getRows().size(); y++) {
GridUnit[] gridUnits = (GridUnit[])gridUnit.getRows().get(y);
for (int y = startRow; y < endRow; y++) {
GridUnit[] gridUnits = (GridUnit[])primaryGridUnit.getRows().get(y);
int dx = xoffset;
int lastRowHeight = 0;
for (int x = 0; x < gridUnits.length; x++) {
GridUnit gu = gridUnits[x];
if (!gu.hasBorders()) {
continue;
}
//Blocks for painting grid unit borders
Block block = new Block();
block.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
block.setPositioning(Block.ABSOLUTE);

int bpd = getContentHeight(gu);
if (isSeparateBorderModel()) {
bpd += (gu.getBorders().getBorderBeforeWidth(false));
bpd += (gu.getBorders().getBorderAfterWidth(false));
} else {
bpd += gridUnit.getHalfMaxBeforeBorderWidth()
- (gu.getBorders().getBorderBeforeWidth(false) / 2);
bpd += gridUnit.getHalfMaxAfterBorderWidth()
- (gu.getBorders().getBorderAfterWidth(false) / 2);
}
int bpd = spannedGridRowHeights[y - startRow];
bpd -= gu.getBorders().getBorderBeforeWidth(false) / 2;
bpd -= gu.getBorders().getBorderAfterWidth(false) / 2;
block.setBPD(bpd);
lastRowHeight = rowHeight;
int ipd = gu.getColumn().getColumnWidth().getValue(this);
int borderStartWidth = gu.getBorders().getBorderStartWidth(false) / 2;
if (log.isTraceEnabled()) {
log.trace("pgu: " + primaryGridUnit + "; gu: " + gu + "; yoffset: "
+ (dy - gu.getBorders().getBorderBeforeWidth(false) / 2)
+ "; bpd: " + bpd);
}
int ipd = gu.getColumn().getColumnWidth().getValue(
(PercentBaseContext) getParent());
int borderStartWidth = gu.getBorders().getBorderStartWidth(false) / 2;
ipd -= borderStartWidth;
ipd -= gu.getBorders().getBorderEndWidth(false) / 2;
block.setIPD(ipd);
block.setXOffset(dx + borderStartWidth);
int halfCollapsingBorderHeight = 0;
if (!isSeparateBorderModel()) {
halfCollapsingBorderHeight
+= gu.getBorders().getBorderBeforeWidth(false) / 2;
}
block.setYOffset(dy - halfCollapsingBorderHeight);
block.setYOffset(dy - gu.getBorders().getBorderBeforeWidth(false) / 2);
outer[0] = gu.getFlag(GridUnit.FIRST_IN_TABLE);
outer[1] = gu.getFlag(GridUnit.LAST_IN_TABLE);
outer[2] = gu.getFlag(GridUnit.IN_FIRST_COLUMN);
outer[3] = gu.getFlag(GridUnit.IN_LAST_COLUMN);
TraitSetter.addCollapsingBorders(block, gu.getBorders(), outer, this);
parentLM.addChildArea(block);
dx += gu.getColumn().getColumnWidth().getValue(this);
dx += gu.getColumn().getColumnWidth().getValue(
(PercentBaseContext) getParent());
}
dy += lastRowHeight;
dy += spannedGridRowHeights[y - startRow];
}
log.warn("TODO Add collapsed border painting for spanned cells");
}
}

//Handle display-align
int contentBPD = getContentHeight(gridUnit);
int contentBPD = getContentHeight(primaryGridUnit);
if (usedBPD < contentBPD) {
if (getTableCell().getDisplayAlign() == EN_CENTER) {
Block space = new Block();
@@ -433,7 +443,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
}

AreaAdditionUtil.addAreas(this, parentIter, layoutContext);
curBlockArea.setBPD(contentBPD);

// Add background after we know the BPD
@@ -448,7 +458,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
getTableCell().getCommonBorderPaddingBackground(),
this);
}
flush();

curBlockArea = null;
@@ -473,8 +483,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
curBlockArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
TraitSetter.setProducerID(curBlockArea, getTableCell().getId());
curBlockArea.setPositioning(Block.ABSOLUTE);
int indent = 0;
indent += startBorderWidth;
int indent = startBorderWidth;
if (!isSeparateBorderModel()) {
indent /= 2;
}
@@ -483,18 +492,18 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
// set position
int borderAdjust = 0;
if (!isSeparateBorderModel()) {
if (gridUnit.hasSpanning()) {
borderAdjust -= gridUnit.getHalfMaxBeforeBorderWidth();
if (primaryGridUnit.hasSpanning()) {
borderAdjust -= primaryGridUnit.getHalfMaxBeforeBorderWidth();
} else {
borderAdjust += gridUnit.getHalfMaxBeforeBorderWidth();
borderAdjust += primaryGridUnit.getHalfMaxBeforeBorderWidth();
}
} else {
//borderAdjust += gridUnit.getBorders().getBorderBeforeWidth(false);
//borderAdjust += primaryGridUnit.getBorders().getBorderBeforeWidth(false);
}
TableLayoutManager tableLM = (TableLayoutManager)getParent();
curBlockArea.setXOffset(xoffset + inRowIPDOffset
curBlockArea.setXOffset(xoffset + inRowIPDOffset
+ tableLM.getHalfBorderSeparationIPD() + indent);
curBlockArea.setYOffset(yoffset - borderAdjust
curBlockArea.setYOffset(yoffset - borderAdjust
+ tableLM.getHalfBorderSeparationBPD());
curBlockArea.setIPD(cellIPD);
//curBlockArea.setHeight();
@@ -550,8 +559,8 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
public boolean mustKeepTogether() {
//TODO Keeps will have to be more sophisticated sooner or later
boolean keep = ((BlockLevelLayoutManager)getParent()).mustKeepTogether();
if (gridUnit.getRow() != null) {
keep |= gridUnit.getRow().mustKeepTogether();
if (primaryGridUnit.getRow() != null) {
keep |= primaryGridUnit.getRow().mustKeepTogether();
}
return keep;
}
@@ -577,9 +586,9 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
|| !fobj.getKeepWithNext().getWithinColumn().isAuto();
*/
}
// --------- Property Resolution related functions --------- //
/**
* Returns the IPD of the content area
* @return the IPD of the content area
@@ -587,7 +596,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
public int getContentAreaIPD() {
return cellIPD;
}
/**
* Returns the BPD of the content area
* @return the BPD of the content area
@@ -600,14 +609,14 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
return -1;
}
}
/**
* @see org.apache.fop.layoutmgr.LayoutManager#getGeneratesReferenceArea
*/
public boolean getGeneratesReferenceArea() {
return true;
}
/**
* @see org.apache.fop.layoutmgr.LayoutManager#getGeneratesBlockArea
*/

Loading…
Cancel
Save