// and determine border behaviour for empty cells
boolean firstCellPart = true;
boolean lastCellPart = true;
int actualRowHeight = 0;
for (int i = 0; i < colCount; i++) {
GridUnit currentGU = currentRow.getGridUnit(i);
if (currentGU.isEmpty()) {
continue;
}
if (currentGU.getColSpanIndex() == 0
&& (lastInPart || currentGU.isLastGridUnitRowSpan())
&& firstCellParts[i] != null) {
// TODO
// The last test above is a workaround for the stepping algorithm's
// fundamental flaw making it unable to produce the right element list for
// multiple breaks inside a same row group.
// (see http://wiki.apache.org/xmlgraphics-fop/TableLayout/KnownProblems)
// In some extremely rare cases (forced breaks, very small page height), a
// TableContentPosition produced during row delaying may end up alone on a
// page. It will not contain the CellPart instances for the cells starting
// the next row, so firstCellParts[i] will still be null for those ones.
int cellHeight = cellHeights[i];
cellHeight += lastCellParts[i].getConditionalAfterContentLength();
cellHeight += lastCellParts[i].getBorderPaddingAfter(lastInPart);
int cellOffset = getRowOffset(Math.max(firstCellParts[i].pgu.getRowIndex(),
firstRowIndex));
actualRowHeight = Math.max(actualRowHeight, cellOffset + cellHeight
- currentRowOffset);
}
if (firstCellParts[i] != null && !firstCellParts[i].isFirstPart()) {
firstCellPart = false;
}
if (lastCellParts[i] != null && !lastCellParts[i].isLastPart()) {
lastCellPart = false;
}
}
// Then add areas for cells finishing on the current row
for (int i = 0; i < colCount; i++) {
GridUnit currentGU = currentRow.getGridUnit(i);
if (currentGU.isEmpty() && !tclm.isSeparateBorderModel()) {
int borderBeforeWhich;
if (firstCellPart) {
if (firstCellOnPage[i]) {
borderBeforeWhich = ConditionalBorder.LEADING_TRAILING;
} else {
borderBeforeWhich = ConditionalBorder.NORMAL;
}
} else {
borderBeforeWhich = ConditionalBorder.REST;
}
int borderAfterWhich;
if (lastCellPart) {
if (lastInPart) {
borderAfterWhich = ConditionalBorder.LEADING_TRAILING;
} else {
borderAfterWhich = ConditionalBorder.NORMAL;
}
} else {
borderAfterWhich = ConditionalBorder.REST;
}
addAreaForEmptyGridUnit((EmptyGridUnit)currentGU,
currentRow.getIndex(), i,
actualRowHeight,
borderBeforeWhich, borderAfterWhich,
lastOnPage);
firstCellOnPage[i] = false;
} else if (currentGU.getColSpanIndex() == 0
&& (lastInPart || currentGU.isLastGridUnitRowSpan())
&& firstCellParts[i] != null) {
assert firstCellParts[i].pgu == currentGU.getPrimary();
int borderBeforeWhich;
if (firstCellParts[i].isFirstPart()) {
if (firstCellOnPage[i]) {
borderBeforeWhich = ConditionalBorder.LEADING_TRAILING;
} else {
borderBeforeWhich = ConditionalBorder.NORMAL;
}
} else {
assert firstCellOnPage[i];
borderBeforeWhich = ConditionalBorder.REST;
}
int borderAfterWhich;
if (lastCellParts[i].isLastPart()) {
if (lastInPart) {
borderAfterWhich = ConditionalBorder.LEADING_TRAILING;
} else {
borderAfterWhich = ConditionalBorder.NORMAL;
}
} else {
borderAfterWhich = ConditionalBorder.REST;
}
addAreasForCell(firstCellParts[i].pgu,
firstCellParts[i].start, lastCellParts[i].end,
actualRowHeight, borderBeforeWhich, borderAfterWhich,
lastOnPage);
firstCellParts[i] = null;
Arrays.fill(firstCellOnPage, i, i + currentGU.getCell().getNumberColumnsSpanned(),
false);
}
}
currentRowOffset += actualRowHeight;
if (lastInPart) {