in fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java [395:592]
public void addAreas(PositionIterator parentIter, LayoutContext layoutContext, int[] spannedGridRowHeights,
int startRow, int endRow, int borderBeforeWhich, int borderAfterWhich,
boolean firstOnPage, boolean lastOnPage, RowPainter painter, int firstRowHeight) {
getParentArea(null);
addId();
int borderBeforeWidth = primaryGridUnit.getBeforeBorderWidth(startRow, borderBeforeWhich);
int borderAfterWidth = primaryGridUnit.getAfterBorderWidth(endRow, borderAfterWhich);
CommonBorderPaddingBackground padding = primaryGridUnit.getCell()
.getCommonBorderPaddingBackground();
int paddingRectBPD = totalHeight - borderBeforeWidth - borderAfterWidth;
int cellBPD = paddingRectBPD;
cellBPD -= padding.getPaddingBefore(borderBeforeWhich == ConditionalBorder.REST, this);
cellBPD -= padding.getPaddingAfter(borderAfterWhich == ConditionalBorder.REST, this);
addBackgroundAreas(painter, firstRowHeight, borderBeforeWidth, paddingRectBPD);
if (isSeparateBorderModel()) {
if (!emptyCell || getTableCell().showEmptyCells()) {
if (borderBeforeWidth > 0) {
int halfBorderSepBPD = getTableCell().getTable().getBorderSeparation().getBPD()
.getLength().getValue() / 2;
adjustYOffset(curBlockArea, halfBorderSepBPD);
}
TraitSetter.addBorders(curBlockArea,
getTableCell().getCommonBorderPaddingBackground(),
borderBeforeWidth == 0, borderAfterWidth == 0,
false, false, this);
}
} else {
boolean inFirstColumn = (primaryGridUnit.getColIndex() == 0);
boolean inLastColumn = (primaryGridUnit.getColIndex()
+ getTableCell().getNumberColumnsSpanned() == getTable()
.getNumberOfColumns());
if (!primaryGridUnit.hasSpanning()) {
adjustYOffset(curBlockArea, -borderBeforeWidth);
//Can set the borders directly if there's no span
boolean[] outer = new boolean[] {firstOnPage, lastOnPage, inFirstColumn,
inLastColumn};
TraitSetter.addCollapsingBorders(curBlockArea,
primaryGridUnit.getBorderBefore(borderBeforeWhich),
primaryGridUnit.getBorderAfter(borderAfterWhich),
primaryGridUnit.getBorderStart(),
primaryGridUnit.getBorderEnd(), outer);
} else {
adjustYOffset(curBlockArea, borderBeforeWidth);
Block[][] blocks = new Block[getTableCell().getNumberRowsSpanned()][getTableCell()
.getNumberColumnsSpanned()];
GridUnit[] gridUnits = primaryGridUnit.getRows().get(startRow);
int level = getTableCell().getBidiLevelRecursive();
for (int x = 0; x < getTableCell().getNumberColumnsSpanned(); x++) {
GridUnit gu = gridUnits[x];
BorderInfo border = gu.getBorderBefore(borderBeforeWhich);
int borderWidth = border.getRetainedWidth() / 2;
if (borderWidth > 0) {
addBorder(blocks, startRow, x, Trait.BORDER_BEFORE, border,
firstOnPage, level);
adjustYOffset(blocks[startRow][x], -borderWidth);
adjustBPD(blocks[startRow][x], -borderWidth);
}
}
gridUnits = primaryGridUnit.getRows().get(endRow);
for (int x = 0; x < getTableCell().getNumberColumnsSpanned(); x++) {
GridUnit gu = gridUnits[x];
BorderInfo border = gu.getBorderAfter(borderAfterWhich);
int borderWidth = border.getRetainedWidth() / 2;
if (borderWidth > 0) {
addBorder(blocks, endRow, x, Trait.BORDER_AFTER, border,
lastOnPage, level);
adjustBPD(blocks[endRow][x], -borderWidth);
}
}
for (int y = startRow; y <= endRow; y++) {
gridUnits = primaryGridUnit.getRows().get(y);
BorderInfo border = gridUnits[0].getBorderStart();
int borderWidth = border.getRetainedWidth() / 2;
if (borderWidth > 0) {
if (level == 1) {
addBorder(blocks, y, gridUnits.length - 1, Trait.BORDER_START, border,
inFirstColumn, level);
adjustIPD(blocks[y][gridUnits.length - 1], -borderWidth);
} else {
addBorder(blocks, y, 0, Trait.BORDER_START, border,
inFirstColumn, level);
adjustXOffset(blocks[y][0], borderWidth);
adjustIPD(blocks[y][0], -borderWidth);
}
}
border = gridUnits[gridUnits.length - 1].getBorderEnd();
borderWidth = border.getRetainedWidth() / 2;
if (borderWidth > 0) {
if (level == 1) {
addBorder(blocks, y, 0, Trait.BORDER_END, border,
inLastColumn, level);
adjustXOffset(blocks[y][0], borderWidth);
adjustIPD(blocks[y][0], -borderWidth);
} else {
addBorder(blocks, y, gridUnits.length - 1, Trait.BORDER_END, border,
inLastColumn, level);
adjustIPD(blocks[y][gridUnits.length - 1], -borderWidth);
}
}
}
int dy = yoffset;
for (int y = startRow; y <= endRow; y++) {
int bpd = spannedGridRowHeights[y - startRow];
int dx = xoffset;
for (int x = 0; x < gridUnits.length; x++) {
int ipd = getTable().getColumn(primaryGridUnit.getColIndex() + x)
.getColumnWidth().getValue(getParent());
if (blocks[y][x] != null) {
Block block = blocks[y][x];
adjustYOffset(block, dy);
adjustXOffset(block, dx);
adjustIPD(block, ipd);
adjustBPD(block, bpd);
parentLayoutManager.addChildArea(block);
}
dx += ipd;
}
dy += bpd;
}
}
}
TraitSetter.addPadding(curBlockArea,
padding,
borderBeforeWhich == ConditionalBorder.REST,
borderAfterWhich == ConditionalBorder.REST,
false, false, this);
//Handle display-align
if (usedBPD < cellBPD) {
if (getTableCell().getDisplayAlign() == EN_CENTER) {
Block space = new Block();
space.setChangeBarList(getChangeBarList());
space.setBPD((cellBPD - usedBPD) / 2);
space.setBidiLevel(getTableCell().getBidiLevelRecursive());
curBlockArea.addBlock(space);
} else if (getTableCell().getDisplayAlign() == EN_AFTER) {
Block space = new Block();
space.setChangeBarList(getChangeBarList());
space.setBPD(cellBPD - usedBPD);
space.setBidiLevel(getTableCell().getBidiLevelRecursive());
curBlockArea.addBlock(space);
}
}
if (isDescendantOfTableHeaderOrFooter()) {
if (hasRetrieveTableMarker) {
if (isDescendantOfTableHeader && !savedAddAreasArguments) {
saveAddAreasArguments(parentIter, layoutContext, spannedGridRowHeights, startRow, endRow,
borderBeforeWhich, borderAfterWhich, firstOnPage, lastOnPage, painter,
firstRowHeight);
}
recreateChildrenLMs();
int displayAlign = ((TableCell) this.getFObj()).getDisplayAlign();
TableCellBreaker breaker = new TableCellBreaker(this, cellIPD, displayAlign);
breaker.setDescendantOfTableFooter(isDescendantOfTableHeader);
if (isDescendantOfTableHeader) {
breaker.setRepeatedHeader(hasRepeatedHeader);
} else {
breaker.setRepeatedFooter(layoutContext.treatAsArtifact());
}
breaker.doLayout(usedBPD, false);
// this is needed so the next time the LMs are recreated they look like the originals; this
// is due to the fact that during the doLayout() above the FO tree changes when the
// retrieve-table-markers are resolved
clearRetrieveTableMarkerChildNodes(getChildLMs());
}
}
// if hasRetrieveTableMarker == true the areas were already added when the re-layout was done above
if (!hasRetrieveTableMarker) {
AreaAdditionUtil.addAreas(this, parentIter, layoutContext);
}
// Re-adjust the cell's bpd as it may have been modified by the previous call
// for some reason (?)
curBlockArea.setBPD(cellBPD);
// Add background after we know the BPD
if (!isSeparateBorderModel() || !emptyCell || getTableCell().showEmptyCells()) {
TraitSetter.addBackground(curBlockArea,
getTableCell().getCommonBorderPaddingBackground(), this);
}
if (flushArea) {
flush();
} else {
flushArea = true;
}
curBlockArea = null;
notifyEndOfLayout();
}