}
}
+ /**
+ * Returns true if the enclosing (if any) fo:table-row element of this row, or if any
+ * of the cells starting on this row, have keep-with-previous set.
+ *
+ * @return true if this row must be kept with the previous content
+ */
+ public boolean mustKeepWithPrevious() {
+ boolean keepWithPrevious = false;
+ TableRow row = getTableRow();
+ if (row != null) {
+ keepWithPrevious = row.mustKeepWithPrevious();
+ }
+ for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
+ GridUnit gu = (GridUnit) iter.next();
+ if (gu.isPrimary()) {
+ keepWithPrevious |= gu.getPrimary().mustKeepWithPrevious();
+ }
+ }
+ return keepWithPrevious;
+ }
+
+ /**
+ * Returns true if the enclosing (if any) fo:table-row element of this row, or if any
+ * of the cells ending on this row, have keep-with-next set.
+ *
+ * @return true if this row must be kept with the next content
+ */
+ public boolean mustKeepWithNext() {
+ boolean keepWithNext = false;
+ TableRow row = getTableRow();
+ if (row != null) {
+ keepWithNext = row.mustKeepWithNext();
+ }
+ for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
+ GridUnit gu = (GridUnit) iter.next();
+ if (!gu.isEmpty() && gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan()) {
+ keepWithNext |= gu.getPrimary().mustKeepWithNext();
+ }
+ }
+ return keepWithNext;
+ }
+
+ /**
+ * Returns true if this row is enclosed by an fo:table-row element that has
+ * keep-together set.
+ *
+ * @return true if this row must be kept together
+ */
+ public boolean mustKeepTogether() {
+ TableRow row = getTableRow();
+ return row != null && row.mustKeepTogether();
+ }
/**
* Returns the break class for this row. This is a combination of break-before set on
* the first children of any cells starting on this row.
+ * <p><strong>Note:</strong> this method doesn't take into account break-before set on
+ * the enclosing fo:table-row element, if any, as it must be ignored if the row
+ * belongs to a group of spanned rows (see XSL-FO 1.1, 7.20.2).
* <p><strong>Note:</strong> this works only after getNextKuthElements on the
* corresponding TableCellLM have been called!</p>
*
/**
* Returns the break class for this row. This is a combination of break-after set on
* the last children of any cells ending on this row.
+ * <p><strong>Note:</strong> this method doesn't take into account break-after set on
+ * the enclosing fo:table-row element, if any, as it must be ignored if the row
+ * belongs to a group of spanned rows (see XSL-FO 1.1, 7.20.1).
* <p><strong>Note:</strong> this works only after getNextKuthElements on the
* corresponding TableCellLM have been called!</p>
*
* @param colIndex column index, 0-based
*/
EmptyGridUnit(Table table, TableRow row, int colIndex) {
- super(table, row, 0, 0);
+ super(table, 0, 0);
+ setRow(row);
}
/** {@inheritDoc} */
package org.apache.fop.fo.flow.table;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
rows.add(effRow);
}
int columnIndex = cell.getColumnNumber() - 1;
- PrimaryGridUnit pgu = new PrimaryGridUnit(cell, currentTableRow, columnIndex);
+ PrimaryGridUnit pgu = new PrimaryGridUnit(cell, columnIndex);
List row = (List) rows.get(currentRowIndex);
row.set(columnIndex, pgu);
// TODO
GridUnit[] cellRow = new GridUnit[cell.getNumberColumnsSpanned()];
cellRow[0] = pgu;
for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
- GridUnit gu = new GridUnit(pgu, currentTableRow, j, 0);
+ GridUnit gu = new GridUnit(pgu, j, 0);
row.set(columnIndex + j, gu);
cellRow[j] = gu;
}
row = (List) rows.get(currentRowIndex + i);
cellRow = new GridUnit[cell.getNumberColumnsSpanned()];
for (int j = 0; j < cell.getNumberColumnsSpanned(); j++) {
- GridUnit gu = new GridUnit(pgu, currentTableRow, j, i);
+ GridUnit gu = new GridUnit(pgu, j, i);
row.set(columnIndex + j, gu);
cellRow[j] = gu;
}
}
/** {@inheritDoc} */
- void startRow(TableRow tableRow) {
+ void startTableRow(TableRow tableRow) {
currentTableRow = tableRow;
}
/** {@inheritDoc} */
- void endRow(TableRow row) {
- if (currentRowIndex > 0 && row.getBreakBefore() != Constants.EN_AUTO) {
- row.attributeWarning("break-before ignored because of row spanning "
+ void endTableRow() {
+ assert currentTableRow != null;
+ if (currentRowIndex > 0 && currentTableRow.getBreakBefore() != Constants.EN_AUTO) {
+ currentTableRow.attributeWarning("break-before ignored because of row spanning "
+ "in progress (See XSL 1.1, 7.20.2)");
}
- if (currentRowIndex < rows.size() - 1 && row.getBreakAfter() != Constants.EN_AUTO) {
- row.attributeWarning("break-after ignored because of row spanning "
+ if (currentRowIndex < rows.size() - 1
+ && currentTableRow.getBreakAfter() != Constants.EN_AUTO) {
+ currentTableRow.attributeWarning("break-after ignored because of row spanning "
+ "in progress (See XSL 1.1, 7.20.1)");
}
- handleRowEnd(row);
+ for (Iterator iter = ((List) rows.get(currentRowIndex)).iterator(); iter.hasNext();) {
+ GridUnit gu = (GridUnit) iter.next();
+ // The row hasn't been filled with empty grid units yet
+ if (gu != null) {
+ gu.setRow(currentTableRow);
+ }
+ }
+ handleRowEnd(currentTableRow);
}
/** {@inheritDoc} */
}
/** {@inheritDoc} */
- void endTable(TableBody lastTablePart) {
+ void endTable() {
borderResolver.endTable();
}
}
* Creates a new grid unit.
*
* @param table the containing table
- * @param row the table-row element this grid unit belongs to (if any)
* @param colSpanIndex index of this grid unit in the span, in column direction
* @param rowSpanIndex index of this grid unit in the span, in row direction
*/
- protected GridUnit(Table table, TableRow row, int colSpanIndex, int rowSpanIndex) {
- this(row, colSpanIndex, rowSpanIndex);
+ protected GridUnit(Table table, int colSpanIndex, int rowSpanIndex) {
+ this(colSpanIndex, rowSpanIndex);
setBorders(table);
}
* Creates a new grid unit.
*
* @param cell table cell which occupies this grid unit
- * @param row the table-row element this grid unit belongs to (if any)
* @param colSpanIndex index of this grid unit in the span, in column direction
* @param rowSpanIndex index of this grid unit in the span, in row direction
*/
- protected GridUnit(TableCell cell, TableRow row, int colSpanIndex, int rowSpanIndex) {
- this(row, colSpanIndex, rowSpanIndex);
+ protected GridUnit(TableCell cell, int colSpanIndex, int rowSpanIndex) {
+ this(colSpanIndex, rowSpanIndex);
this.cell = cell;
setBorders(cell.getTable());
}
* Creates a new grid unit.
*
* @param primary the before-start grid unit of the cell containing this grid unit
- * @param row the table-row element this grid unit belongs to (if any)
* @param colSpanIndex index of this grid unit in the span, in column direction
* @param rowSpanIndex index of this grid unit in the span, in row direction
*/
- GridUnit(PrimaryGridUnit primary, TableRow row, int colSpanIndex, int rowSpanIndex) {
- this(primary.getCell(), row, colSpanIndex, rowSpanIndex);
+ GridUnit(PrimaryGridUnit primary, int colSpanIndex, int rowSpanIndex) {
+ this(primary.getCell(), colSpanIndex, rowSpanIndex);
this.primary = primary;
}
- private GridUnit(TableRow row, int colSpanIndex, int rowSpanIndex) {
- this.row = row;
+ private GridUnit(int colSpanIndex, int rowSpanIndex) {
this.colSpanIndex = colSpanIndex;
this.rowSpanIndex = rowSpanIndex;
}
return row;
}
+ void setRow(TableRow row) {
+ this.row = row;
+ }
+
public TableBody getBody() {
FONode node = getCell();
while (node != null && !(node instanceof TableBody)) {
private boolean isSeparateBorderModel;
private int halfBorderSeparationBPD;
+ private boolean keepWithPrevious;
+ private boolean keepWithNext;
private int breakBefore = Constants.EN_AUTO;
private int breakAfter = Constants.EN_AUTO;
* Creates a new primary grid unit.
*
* @param cell table cell which occupies this grid unit
- * @param row the table-row element this grid unit belongs to (if any)
* @param colIndex index of the column this grid unit belongs to, zero-based
*/
- PrimaryGridUnit(TableCell cell, TableRow row, int colIndex) {
- super(cell, row, 0, 0);
+ PrimaryGridUnit(TableCell cell, int colIndex) {
+ super(cell, 0, 0);
this.colIndex = colIndex;
this.isSeparateBorderModel = cell.getTable().isSeparateBorderModel(); // TODO
this.halfBorderSeparationBPD = cell.getTable().getBorderSeparation().getBPD().getLength()
cellLM = new TableCellLayoutManager(cell, this);
}
+ /**
+ * Returns true if the first child block (or its descendants) of this cell has
+ * keep-with-previous.
+ *
+ * @return the value of keep-with-previous
+ */
+ public boolean mustKeepWithPrevious() {
+ return keepWithPrevious;
+ }
+
+ /**
+ * Don't use, reserved for TableCellLM. TODO
+ */
+ public void setKeepWithPrevious() {
+ this.keepWithPrevious = true;
+ }
+
+ /**
+ * Returns true if the last child block (or its descendants) of this cell has
+ * keep-with-next.
+ *
+ * @return the value of keep-with-next
+ */
+ public boolean mustKeepWithNext() {
+ return keepWithNext;
+ }
+
+ /**
+ * Don't use, reserved for TableCellLM. TODO
+ */
+ public void setKeepWithNext() {
+ this.keepWithNext = true;
+ }
+
/**
* Returns the class of the before break for the first child element of this cell.
*
*
* @param tableRow the row being started
*/
- abstract void startRow(TableRow tableRow);
+ abstract void startTableRow(TableRow tableRow);
/**
* Receives notification of the end of the current row. If the current row finishes
* the row group, the {@link TableBody#addRowGroup(List)} method of the parent table
* part will be called.
- *
- * @param row the row being finished
*/
- abstract void endRow(TableRow row);
+ abstract void endTableRow();
/**
* Receives notification of the end of the current row, when the source contains no
* {@link TableBody#addRowGroup(List)} method of the given table part will be called.
*
* <p>If the source does contain explicit fo:table-row elements, then the
- * {@link #endRow(TableRow)} method will be called instead.</p>
+ * {@link #endTableRow()} method will be called instead.</p>
*
* @param part the part containing the current row
*/
/**
* Receives notification of the end of the table.
*
- * @param lastTablePart the last part of the table
* @throws ValidationException if a row-spanning cell overflows one of the table's parts
*/
- abstract void endTable(TableBody lastTablePart) throws ValidationException;
+ abstract void endTable() throws ValidationException;
}
orphanContentLimit = pList.get(PR_X_ORPHAN_CONTENT_LIMIT).getLength();
if (!blockProgressionDimension.getOptimum(null).isAuto()) {
- attributeWarning("only a value of \"auto\" for block-progression-dimension has a well-specified"
- + " behavior on fo:table. Falling back to \"auto\"");
+ attributeWarning("only a value of \"auto\" for block-progression-dimension has a"
+ + " well-specified behavior on fo:table. Falling back to \"auto\"");
// Anyway, the bpd of a table is not used by the layout code
}
if (tableLayout == EN_AUTO) {
+ ",table-body+)");
}
if (!inMarker()) {
- if (tableFooter != null) {
- rowGroupBuilder.endTable(tableFooter);
- } else {
- rowGroupBuilder.endTable((TableBody) getChildNodes().lastNode());
- }
+ rowGroupBuilder.endTable();
/* clean up */
for (int i = columns.size(); --i >= 0;) {
TableColumn col = (TableColumn) columns.get(i);
}
}
+ /** {@inheritDoc} */
protected void setCollapsedBorders() {
createBorder(CommonBorderPaddingBackground.START);
createBorder(CommonBorderPaddingBackground.END);
if (!inMarker()) {
RowGroupBuilder rowGroupBuilder = getTable().getRowGroupBuilder();
if (tableRowsFound) {
- rowGroupBuilder.endRow(lastRow);
+ rowGroupBuilder.endTableRow();
} else if (!lastCellEndsRow) {
rowGroupBuilder.endRow(this);
}
} else if (localName.equals("table-row")) {
tableRowsFound = true;
if (tableCellsFound) {
- invalidChildError(loc, nsURI, localName, "Either fo:table-rows" +
- " or fo:table-cells may be children of an " + getName() +
- " but not both");
+ invalidChildError(loc, nsURI, localName, "Either fo:table-rows"
+ + " or fo:table-cells may be children of an " + getName()
+ + " but not both");
}
} else if (localName.equals("table-cell")) {
tableCellsFound = true;
getTable().getRowGroupBuilder().startTablePart(this);
} else {
columnNumberManager.prepareForNextRow(pendingSpans);
- getTable().getRowGroupBuilder().endRow(lastRow);
+ getTable().getRowGroupBuilder().endTableRow();
}
rowsStarted = true;
lastRow = (TableRow) child;
- getTable().getRowGroupBuilder().startRow(lastRow);
+ getTable().getRowGroupBuilder().startTableRow(lastRow);
break;
case FO_TABLE_CELL:
if (!rowsStarted) {
}
/** {@inheritDoc} */
- void startRow(final TableRow tableRow) {
+ void startTableRow(final TableRow tableRow) {
events.add(new Event() {
public void play(RowGroupBuilder rowGroupBuilder) {
- rowGroupBuilder.startRow(tableRow);
+ rowGroupBuilder.startTableRow(tableRow);
}
});
}
/** {@inheritDoc} */
- void endRow(final TableRow row) {
+ void endTableRow() {
events.add(new Event() {
public void play(RowGroupBuilder rowGroupBuilder) {
- rowGroupBuilder.endRow(row);
+ rowGroupBuilder.endTableRow();
}
});
}
}
/** {@inheritDoc} */
- void endTable(final TableBody lastTablePart) throws ValidationException {
+ void endTable() throws ValidationException {
RowGroupBuilder delegate = new FixedColRowGroupBuilder(table);
for (Iterator eventIter = events.iterator(); eventIter.hasNext();) {
((Event) eventIter.next()).play(delegate);
}
- delegate.endTable(lastTablePart);
+ delegate.endTable();
}
}
/** Amount of space to reserve at the end of each line */
private int lineEndBorderAndPaddingWidth = 0;
+ private int breakBefore;
+
+ private int breakAfter;
+
/**
* Copy constructor for creating child layout contexts.
* @param parentLC the parent layout context to copy from
public void setSpaceAfter(int spaceAfter) {
this.spaceAfter = spaceAfter;
}
-
+
+ /**
+ * Returns the value of the break before the element whose
+ * {@link LayoutManager#getNextKnuthElements(LayoutContext, int)} method has just been
+ * called.
+ *
+ * @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
+ * {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE}, or
+ * {@link Constants#EN_ODD_PAGE}
+ */
+ public int getBreakBefore() {
+ return breakBefore;
+ }
+
+ /**
+ * Sets the value of the break before the current element.
+ *
+ * @param breakBefore the value of the break-before
+ * @see #getBreakBefore()
+ */
+ public void setBreakBefore(int breakBefore) {
+ this.breakBefore = breakBefore;
+ }
+
+ /**
+ * Returns the value of the break after the element whose
+ * {@link LayoutManager#getNextKnuthElements(LayoutContext, int)} method has just been
+ * called.
+ *
+ * @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
+ * {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE}, or
+ * {@link Constants#EN_ODD_PAGE}
+ */
+ public int getBreakAfter() {
+ return breakAfter;
+ }
+
+
+ /**
+ * Sets the value of the break after the current element.
+ *
+ * @param breakAfter the value of the break-after
+ * @see #getBreakAfter()
+ */
+ public void setBreakAfter(int breakAfter) {
+ this.breakAfter = breakAfter;
+ }
+
/** {@inheritDoc} */
public String toString() {
return "Layout Context:" +
"\nIs Last Area: \t" + isLastArea() +
"\nTry Hyphenate: \t" + tryHyphenate() +
"\nKeeps: \t[" + (isKeepWithNextPending() ? "keep-with-next" : "") + "]["
- + (isKeepWithPreviousPending() ? "keep-with-previous" : "") + "] pending";
+ + (isKeepWithPreviousPending() ? "keep-with-previous" : "") + "] pending" +
+ "\nBreaks: \tforced [" + (breakBefore != Constants.EN_AUTO ? "break-before" : "") + "]["
+ + (breakAfter != Constants.EN_AUTO ? "break-after" : "") + "]";
}
}
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.flow.table.ConditionalBorder;
import org.apache.fop.fo.flow.table.EffRow;
-import org.apache.fop.fo.flow.table.GridUnit;
import org.apache.fop.fo.flow.table.PrimaryGridUnit;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.layoutmgr.ElementListUtils;
makeBoxForWholeRow = true;
}
}
- if (pgu.isLastGridUnitRowSpan() && pgu.getRow() != null) {
- makeBoxForWholeRow |= pgu.getRow().mustKeepTogether();
- makeBoxForWholeRow |= tableLM.getTable().mustKeepTogether();
- }
if (makeBoxForWholeRow) {
elementList = new java.util.ArrayList(1);
int height = row.getHeight().opt;
*/
CellPart createCellPart() {
if (nextStep.end + 1 == elementList.size()) {
- if (pgu.getFlag(GridUnit.KEEP_WITH_NEXT_PENDING)) {
- keepWithNextSignal = true;
- }
- if (pgu.getRow() != null && pgu.getRow().mustKeepWithNext()) {
- keepWithNextSignal = true;
- }
+ keepWithNextSignal = pgu.mustKeepWithNext();
+ // TODO if keep-with-next is set on the row, must every cell of the row
+ // contribute some content from children blocks?
+ // see http://mail-archives.apache.org/mod_mbox/xmlgraphics-fop-dev/200802.mbox/
+ // %3c47BDA379.4050606@anyware-tech.com%3e
+ // Assuming no, but if yes the following code should enable this behaviour
+// if (pgu.getRow() != null && pgu.getRow().mustKeepWithNext()) {
+// keepWithNextSignal = true;
+// }
}
int bpBeforeFirst;
if (nextStep.start == 0) {
package org.apache.fop.layoutmgr.table;
-import org.apache.fop.fo.flow.table.GridUnit;
import org.apache.fop.fo.flow.table.PrimaryGridUnit;
/**
return sb.toString();
}
- boolean mustKeepWithPrevious() {
- return pgu.getFlag(GridUnit.KEEP_WITH_PREVIOUS_PENDING)
- || (pgu.getRow() != null && pgu.getRow().mustKeepWithPrevious());
- }
-
}
import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.LengthRangeProperty;
-import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.ElementListObserver;
-import org.apache.fop.layoutmgr.KnuthElement;
-import org.apache.fop.layoutmgr.KnuthPenalty;
import org.apache.fop.layoutmgr.LayoutContext;
-import org.apache.fop.layoutmgr.ListElement;
import org.apache.fop.layoutmgr.MinOptMaxUtil;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.util.BreakUtil;
class RowGroupLayoutManager {
- private static Log log = LogFactory.getLog(TableContentLayoutManager.class);
+ private static Log log = LogFactory.getLog(RowGroupLayoutManager.class);
private EffRow[] rowGroup;
this.tableStepper = tableStepper;
}
- /**
- *
- * @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
- * {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE}, or
- * {@link Constants#EN_ODD_PAGE}
- */
- int getBreakBefore() {
- TableRow rowFO = rowGroup[0].getTableRow();
- int breakBefore;
- if (rowFO == null) {
- breakBefore = Constants.EN_AUTO;
- } else {
- breakBefore = rowFO.getBreakBefore();
- }
- return BreakUtil.compareBreakClasses(breakBefore, rowGroup[0].getBreakBefore());
- }
-
- /**
- *
- * @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
- * {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE}, or
- * {@link Constants#EN_ODD_PAGE}
- */
- int getBreakAfter() {
- TableRow rowFO = rowGroup[rowGroup.length - 1].getTableRow();
- int breakAfter;
- if (rowFO == null) {
- breakAfter = Constants.EN_AUTO;
- } else {
- breakAfter = rowFO.getBreakAfter();
- }
- return BreakUtil.compareBreakClasses(breakAfter,
- rowGroup[rowGroup.length - 1].getBreakAfter());
- }
-
public LinkedList getNextKnuthElements(LayoutContext context, int alignment, int bodyType) {
LinkedList returnList = new LinkedList();
-
- //Reset keep-with-next when remaining inside the table.
- //The context flag is only used to propagate keep-with-next to the outside.
- //The clearing is ok here because createElementsForRowGroup already handles
- //the keep when inside a table.
- context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
-
- //Element list creation
createElementsForRowGroup(context, alignment, bodyType, returnList);
- //Handle keeps
- if (context.isKeepWithNextPending()) {
- log.debug("child LM (row group) signals pending keep-with-next");
+ context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING,
+ rowGroup[0].mustKeepWithPrevious());
+ context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING,
+ rowGroup[rowGroup.length - 1].mustKeepWithNext());
+
+ int breakBefore = Constants.EN_AUTO;
+ TableRow firstRow = rowGroup[0].getTableRow();
+ if (firstRow != null) {
+ breakBefore = firstRow.getBreakBefore();
}
- if (context.isKeepWithPreviousPending()) {
- log.debug("child LM (row group) signals pending keep-with-previous");
- if (returnList.size() > 0) {
- //Modify last penalty
- ListElement last = (ListElement)returnList.getLast();
- if (last.isPenalty()) {
- BreakElement breakPoss = (BreakElement)last;
- //Only honor keep if there's no forced break
- if (!breakPoss.isForcedBreak()) {
- breakPoss.setPenaltyValue(KnuthPenalty.INFINITE);
- }
- }
- }
+ context.setBreakBefore(BreakUtil.compareBreakClasses(breakBefore,
+ rowGroup[0].getBreakBefore()));
+
+ int breakAfter = Constants.EN_AUTO;
+ TableRow lastRow = rowGroup[rowGroup.length - 1].getTableRow();
+ if (lastRow != null) {
+ breakAfter = lastRow.getBreakAfter();
}
+ context.setBreakAfter(BreakUtil.compareBreakClasses(breakAfter,
+ rowGroup[rowGroup.length - 1].getBreakAfter()));
return returnList;
}
PrimaryGridUnit primary = gu.getPrimary();
if (gu.isPrimary()) {
- primary.createCellLM(); // TODO a new LM must be created for every new static-content
+ // TODO a new LM must be created for every new static-content
+ primary.createCellLM();
primary.getCellLM().setParent(tableLM);
//Determine the table-row if any
LinkedList elems = primary.getCellLM().getNextKnuthElements(
childLC, alignment);
ElementListObserver.observe(elems, "table-cell", primary.getCell().getId());
-
- if ((elems.size() > 0)
- && ((KnuthElement)elems.getLast()).isForcedBreak()) {
- // a descendant of this block has break-after
- log.debug("Descendant of table-cell signals break: "
- + primary.getCellLM().isFinished());
- }
-
primary.setElements(elems);
-
- if (childLC.isKeepWithNextPending()) {
- log.debug("child LM signals pending keep-with-next");
- primary.setFlag(GridUnit.KEEP_WITH_NEXT_PENDING, true);
- }
- if (childLC.isKeepWithPreviousPending()) {
- log.debug("child LM signals pending keep-with-previous");
- primary.setFlag(GridUnit.KEEP_WITH_PREVIOUS_PENDING, true);
- }
}
//Calculate height of row, see CSS21, 17.5.3 Table height algorithms
log.debug(" height=" + rowHeights[i] + " explicit=" + explicitRowHeights[i]);
}
}
- LinkedList returnedList = tableStepper.getCombinedKnuthElementsForRowGroup(context,
+ LinkedList elements = tableStepper.getCombinedKnuthElementsForRowGroup(context,
rowGroup, bodyType);
- if (returnedList != null) {
- returnList.addAll(returnedList);
- }
-
+ returnList.addAll(elements);
}
}
log.debug("child LM signals pending keep with next");
}
if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) {
- context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
+ primaryGridUnit.setKeepWithPrevious();
childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
}
}
prevLM = curLM;
}
+ if (context.isKeepWithNextPending()) {
+ primaryGridUnit.setKeepWithNext();
+ }
returnedList = new LinkedList();
if (contentList.size() > 0) {
import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.KnuthBox;
-import org.apache.fop.layoutmgr.KnuthPenalty;
+import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthPossPosIter;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.ListElement;
ColumnSetup getColumns() {
return getTableLM().getColumns();
}
-
+
/** @return the net header height */
protected int getHeaderNetHeight() {
return this.headerNetHeight;
private LinkedList getKnuthElementsForRowIterator(TableRowIterator iter,
LayoutContext context, int alignment, int bodyType) {
LinkedList returnList = new LinkedList();
- EffRow[] rowGroup = null;
- int breakBetween = Constants.EN_AUTO;
- while ((rowGroup = iter.getNextRowGroup()) != null) {
+ EffRow[] rowGroup = iter.getNextRowGroup();
+ // TODO homogenize the handling of keeps and breaks
+ context.unsetFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING
+ | LayoutContext.KEEP_WITH_NEXT_PENDING);
+ context.setBreakBefore(Constants.EN_AUTO);
+ context.setBreakAfter(Constants.EN_AUTO);
+ boolean keepWithPrevious = false;
+ int breakBefore = Constants.EN_AUTO;
+ if (rowGroup != null) {
RowGroupLayoutManager rowGroupLM = new RowGroupLayoutManager(getTableLM(), rowGroup,
stepper);
- // TODO
- // The RowGroupLM.getBreakBefore method will work correctly only after
- // getNextKnuthElements is called. Indeed TableCellLM will set the values for
- // breaks on PrimaryGridUnit once it has got the Knuth elements of its
- // children. This can be changed once all the LMs adopt the same scheme of
- // querying childrens LMs for breaks instead of producing penalty elements
List nextRowGroupElems = rowGroupLM.getNextKnuthElements(context, alignment, bodyType);
- breakBetween = BreakUtil.compareBreakClasses(breakBetween, rowGroupLM.getBreakBefore());
- if (breakBetween != Constants.EN_AUTO) {
- if (returnList.size() > 0) {
- BreakElement breakPoss = (BreakElement) returnList.getLast();
- breakPoss.setPenaltyValue(-KnuthPenalty.INFINITE);
- breakPoss.setBreakClass(breakBetween);
- } else {
- returnList.add(new BreakElement(new Position(tableLM),
- 0, -KnuthPenalty.INFINITE, breakBetween, context));
- }
- }
+ keepWithPrevious = context.isKeepWithPreviousPending();
+ boolean keepBetween = context.isKeepWithNextPending();
+ breakBefore = context.getBreakBefore();
+ int breakBetween = context.getBreakAfter();
returnList.addAll(nextRowGroupElems);
- breakBetween = rowGroupLM.getBreakAfter();
- }
- // Break after the table's last row
- // TODO should eventually be handled at the table level
- if (breakBetween != Constants.EN_AUTO) {
- if (returnList.size() > 0 && ((ListElement) returnList.getLast()).isPenalty()) {
- // May be a glue if the unbroken height is greater than the broken heights
- BreakElement breakPoss = (BreakElement) returnList.getLast();
- breakPoss.setPenaltyValue(-KnuthPenalty.INFINITE);
- breakPoss.setBreakClass(breakBetween);
- } else {
- returnList.add(new BreakElement(new Position(tableLM),
- 0, -KnuthPenalty.INFINITE, breakBetween, context));
- }
- }
- if (returnList.size() > 0) {
- //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()) {
- //Only remove if we don't signal a forced break
- returnList.removeLast();
+ while ((rowGroup = iter.getNextRowGroup()) != null) {
+ rowGroupLM = new RowGroupLayoutManager(getTableLM(), rowGroup, stepper);
+ nextRowGroupElems = rowGroupLM.getNextKnuthElements(context, alignment, bodyType);
+ int penaltyValue = 0;
+ keepBetween |= context.isKeepWithPreviousPending();
+ if (keepBetween || tableLM.getTable().mustKeepTogether()) {
+ penaltyValue = KnuthElement.INFINITE;
+ }
+ breakBetween = BreakUtil.compareBreakClasses(breakBetween,
+ context.getBreakBefore());
+ if (breakBetween != Constants.EN_AUTO) {
+ penaltyValue = -KnuthElement.INFINITE;
+ }
+ TableHFPenaltyPosition penaltyPos = new TableHFPenaltyPosition(getTableLM());
+ int penaltyLen = 0;
+ if (bodyType == TableRowIterator.BODY) {
+ if (!getTableLM().getTable().omitHeaderAtBreak()) {
+ penaltyLen += getHeaderNetHeight();
+ penaltyPos.headerElements = getHeaderElements();
+ }
+ if (!getTableLM().getTable().omitFooterAtBreak()) {
+ penaltyLen += getFooterNetHeight();
+ penaltyPos.footerElements = getFooterElements();
+ }
}
+ returnList.add(new BreakElement(penaltyPos,
+ penaltyLen, penaltyValue, breakBetween, context));
+ returnList.addAll(nextRowGroupElems);
+ breakBetween = context.getBreakAfter();
+ keepBetween = context.isKeepWithNextPending();
}
}
+ context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, keepWithPrevious);
+ context.setBreakBefore(breakBefore);
//fox:widow-content-limit
int widowContentLimit = getTableLM().getTable().getWidowContentLimit().getValue();
package org.apache.fop.layoutmgr.table;
+import java.util.Iterator;
+import java.util.LinkedList;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.area.Area;
+import org.apache.fop.area.Block;
+import org.apache.fop.datatypes.LengthBase;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableColumn;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
+import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.ConditionalElementListener;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.ListElement;
-import org.apache.fop.layoutmgr.NonLeafPosition;
import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.layoutmgr.Position;
import org.apache.fop.layoutmgr.RelSide;
import org.apache.fop.layoutmgr.TraitSetter;
-import org.apache.fop.area.Area;
-import org.apache.fop.area.Block;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.traits.SpaceVal;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import org.apache.fop.datatypes.LengthBase;
-import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.FObj;
+import org.apache.fop.util.BreakUtil;
/**
* LayoutManager for a table FO.
public int getHalfBorderSeparationIPD() {
return halfBorderSeparationIPD;
}
-
- /**
- * Handles the Knuth elements at the table level: mainly breaks, spaces and borders
- * before and after the table. The Knuth elements for the table cells are handled by
- * TableContentLayoutManager.
- *
- * @see org.apache.fop.layoutmgr.LayoutManager
- * @see TableContentLayoutManager#getNextKnuthElements(LayoutContext, int)
- */
+
+ /** {@inheritDoc} */
public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
LinkedList returnList = new LinkedList();
-
- if (!breakBeforeServed) {
- breakBeforeServed = true;
- if (addKnuthElementsForBreakBefore(returnList, context)) {
- return returnList;
- }
- }
/*
* Compute the IPD and adjust it if necessary (overconstrained)
// Elements for the table-header/footer/body
LinkedList contentKnuthElements = null;
- LinkedList contentList = new LinkedList();
- //Position returnPosition = new NonLeafPosition(this, null);
- //Body prevLM = null;
-
+ contentLM = new TableContentLayoutManager(this);
LayoutContext childLC = new LayoutContext(0);
/*
childLC.setStackLimit(
childLC.setRefIPD(context.getRefIPD());
childLC.copyPendingMarksFrom(context);
- if (contentLM == null) {
- contentLM = new TableContentLayoutManager(this);
- }
contentKnuthElements = contentLM.getNextKnuthElements(childLC, alignment);
- if (childLC.isKeepWithNextPending()) {
- log.debug("TableContentLM signals pending keep-with-next");
- context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
- }
- if (childLC.isKeepWithPreviousPending()) {
- log.debug("TableContentLM signals pending keep-with-previous");
- context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
- }
-
- // Check if the table's content starts/ends with a forced break
- // TODO this is hacky and will need to be handled better eventually
- if (contentKnuthElements.size() > 0) {
- ListElement element = (ListElement)contentKnuthElements.getFirst();
- if (element.isForcedBreak()) {
- // The first row of the table(-body), or (the content of) one of its cells
- // has a forced break-before
- int breakBeforeTable = ((Table) fobj).getBreakBefore();
- if (breakBeforeTable == EN_PAGE
- || breakBeforeTable == EN_COLUMN
- || breakBeforeTable == EN_EVEN_PAGE
- || breakBeforeTable == EN_ODD_PAGE) {
- // There is already a forced break before the table; remove this one
- // to prevent a double break
- contentKnuthElements.removeFirst();
- } else {
- element.setPosition(new NonLeafPosition(this, null));
- }
- }
- element = (ListElement)contentKnuthElements.getLast();
- if (element.isForcedBreak()) {
- // The last row of the table(-body), or (the content of) one of its cells
- // has a forced break-after
- element.setPosition(new NonLeafPosition(this, null));
- }
- }
-
//Set index values on elements coming from the content LM
Iterator iter = contentKnuthElements.iterator();
while (iter.hasNext()) {
notifyPos(el.getPosition());
}
log.debug(contentKnuthElements);
- contentList.addAll(contentKnuthElements);
- wrapPositionElements(contentList, returnList);
+ wrapPositionElements(contentKnuthElements, returnList);
+
+ if (mustKeepWithPrevious() || childLC.isKeepWithPreviousPending()) {
+ context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
+ }
+ if (mustKeepWithNext() || childLC.isKeepWithNextPending()) {
+ context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
+ }
+
if (getTable().isSeparateBorderModel()) {
addKnuthElementsForBorderPaddingAfter(returnList, true);
}
addKnuthElementsForSpaceAfter(returnList, alignment);
- addKnuthElementsForBreakAfter(returnList, context);
- if (mustKeepWithNext()) {
- context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
+
+ //addKnuthElementsForBreakBefore(returnList, context);
+ int breakBefore = BreakUtil.compareBreakClasses(getTable().getBreakBefore(),
+ childLC.getBreakBefore());
+ if (breakBefore != Constants.EN_AUTO) {
+ returnList.addFirst(new BreakElement(getAuxiliaryPosition(),
+ 0, -KnuthElement.INFINITE, breakBefore, context));
}
- if (mustKeepWithPrevious()) {
- context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
+
+ //addKnuthElementsForBreakAfter(returnList, context);
+ int breakAfter = BreakUtil.compareBreakClasses(getTable().getBreakAfter(),
+ childLC.getBreakAfter());
+ if (breakAfter != Constants.EN_AUTO) {
+ returnList.add(new BreakElement(getAuxiliaryPosition(),
+ 0, -KnuthElement.INFINITE, breakAfter, context));
}
+
setFinished(true);
resetSpaces();
return returnList;
activateCells(activeCells, 0);
calcTotalHeight();
- boolean signalKeepWithNext = false;
int cumulateLength = 0; // Length of the content accumulated before the break
TableContentPosition lastTCPos = null;
LinkedList returnList = new LinkedList();
ActiveCell activeCell = (ActiveCell) iter.next();
CellPart part = activeCell.createCellPart();
cellParts.add(part);
- if (returnList.size() == 0 && part.isFirstPart()
- && part.mustKeepWithPrevious()) {
- context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
- }
}
//Create elements for step
}
int p = 0;
- signalKeepWithNext = false;
+ boolean keepWithNext = false;
for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
ActiveCell activeCell = (ActiveCell) iter.next();
- signalKeepWithNext |= activeCell.keepWithNextSignal();
+ keepWithNext |= activeCell.keepWithNextSignal();
}
- if (signalKeepWithNext || getTableLM().mustKeepTogether()) {
+ if (keepWithNext || getTableLM().mustKeepTogether()) {
p = KnuthPenalty.INFINITE;
}
- if (rowFinished && activeRowIndex < rowGroup.length - 1) {
+ if (!rowFinished) {
+ if (rowGroup[activeRowIndex].mustKeepTogether()) {
+ p = KnuthPenalty.INFINITE;
+ }
+ } else if (activeRowIndex < rowGroup.length - 1) {
+ if (rowGroup[activeRowIndex].mustKeepWithNext()
+ || rowGroup[activeRowIndex + 1].mustKeepWithPrevious()) {
+ p = KnuthPenalty.INFINITE;
+ }
nextBreakClass = BreakUtil.compareBreakClasses(nextBreakClass,
rowGroup[activeRowIndex].getBreakAfter());
nextBreakClass = BreakUtil.compareBreakClasses(nextBreakClass,
laststep = step;
step = getNextStep();
} while (step >= 0);
- if (signalKeepWithNext) {
- //Last step signalled a keep-with-next. Since the last penalty will be removed,
- //we have to signal the still pending last keep-with-next using the LayoutContext.
- context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
- }
- if (lastTCPos != null) {
+ if (!returnList.isEmpty()) {
lastTCPos.setFlag(TableContentPosition.LAST_IN_ROWGROUP, true);
+ // It's not up to TableStepper to decide whether there can/must be a break
+ // after the row group or not, but to ancestor stacking elements
+ assert returnList.getLast() instanceof BreakElement;
+ returnList.removeLast();
}
return returnList;
}
<changes>
<release version="FOP Trunk">
+ <action context="Layout" dev="VH" type="add">
+ Added full support for keep-with-previous on fo:table-row and in fo:table-cell elements.
+ </action>
<action context="Code" dev="MB" type="add">
Turned on XInclude processing for the main source given on the command line.
</action>
<fo:page-sequence master-reference="normal">
<fo:flow flow-name="xsl-region-body">
<fo:block>block1</fo:block>
- <fo:table table-layout="fixed">
- <fo:table-column/>
- <fo:table-column/>
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell id="cell1">
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks that keep-together works on blocks in table-cells.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page" page-height="3in" page-width="5in"
+ margin="0.5in">
+ <fo:region-body background-color="#F0F0F0"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <!-- table 1 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="118pt">1. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block keep-together="always">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid olive">
+ <fo:block>Cell 3.1 Line 1</fo:block>
+ <fo:block>Cell 3.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 2 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="118pt">2. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal" number-rows-spanned="2">
+ <fo:block keep-together="always">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.2 Line 1</fo:block>
+ <fo:block>Cell 2.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 3 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="100">3. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="collapse" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue" number-rows-spanned="2">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid olive">
+ <fo:block keep-together="always">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+ <checks>
+
+ <!-- table 1 -->
+ <eval expected="2" xpath="count(//pageSequence[1]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="1" xpath="count(//pageViewport[@nr=1]//flow/block)"/>
+ <eval expected="1. Before the table" xpath="//pageViewport[@nr=1]//flow/block[1]/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=2]//flow/block)"/>
+ <eval expected="48000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpd"/>
+ <eval expected="56000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-after"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=2]//flow/block[2]/lineArea"/>
+
+ <!-- table 2 -->
+ <eval expected="2" xpath="count(//pageSequence[2]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="1" xpath="count(//pageViewport[@nr=3]//flow/block)"/>
+ <eval expected="2. Before the table" xpath="//pageViewport[@nr=3]//flow/block[1]/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=4]//flow/block)"/>
+ <eval expected="48000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpd"/>
+ <eval expected="56000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=4]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=4]//flow/block[1]/@border-after"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=4]//flow/block[2]/lineArea"/>
+
+ <!-- table 3 -->
+ <eval expected="2" xpath="count(//pageSequence[3]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=5]//flow/block)"/>
+ <eval expected="3. Before the table" xpath="//pageViewport[@nr=5]//flow/block[1]/lineArea"/>
+ <eval expected="23000" xpath="//pageViewport[@nr=5]//flow/block[2]/@bpd"/>
+ <eval expected="23000" xpath="//pageViewport[@nr=5]//flow/block[2]/@bpda"/>
+ <!-- cell 1.1 -->
+ <eval expected="21000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="25000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@border-after"/>
+ <eval expected="21000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="21000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="2" xpath="count(//pageViewport[@nr=5]//flow/block[2]/block[2]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/block[1]/lineArea"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/block[2]/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[3]/@bpd"/>
+ <eval expected="26000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[3]/@bpda"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=5]//flow/block[2]/block[3]/@border-before"/>
+ <eval expected="(solid,#008080,2000,collapse-outer)" xpath="//pageViewport[@nr=5]//flow/block[2]/block[3]/@border-after"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=6]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=6]//flow/block[2]/lineArea"/>
+ <eval expected="23000" xpath="//pageViewport[@nr=6]//flow/block[1]/@bpd"/>
+ <eval expected="23000" xpath="//pageViewport[@nr=6]//flow/block[1]/@bpda"/>
+ <!-- cell 1.1 -->
+ <eval expected="21000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="25000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="21000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="21000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="0" xpath="count(//pageViewport[@nr=6]//flow/block[1]/block[2]/block)"/>
+ <!-- cell 2.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="26000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="(solid,#808000,2000,collapse-outer)" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@border-after"/>
+
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks that keep-with-next works on blocks in table-cells.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page" page-height="3in" page-width="5in"
+ margin="0.5in">
+ <fo:region-body background-color="#F0F0F0"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <!-- table 1 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="106pt">1. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block keep-with-next="always">Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid olive">
+ <fo:block>Cell 3.1 Line 1</fo:block>
+ <fo:block>Cell 3.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 2 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="106pt">2. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block keep-with-next="always">Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal" number-rows-spanned="2">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 3 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="78pt">3. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal" number-rows-spanned="2">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block keep-with-next="always">Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 4 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="88">4. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="collapse" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue" number-rows-spanned="2">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid olive">
+ <fo:block>Cell 2.2 Line 1</fo:block>
+ <fo:block keep-with-next="always">Cell 2.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+ <checks>
+
+ <!-- table 1 -->
+ <eval expected="2" xpath="count(//pageSequence[1]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=1]//flow/block)"/>
+ <eval expected="1. Before the table" xpath="//pageViewport[@nr=1]//flow/block[1]/lineArea"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/@bpd"/>
+ <eval expected="16000" xpath="//pageViewport[@nr=1]//flow/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=1]//flow/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=1]//flow/block[2]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/block/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=1]//flow/block[2]/block[2]/block)"/>
+ <eval expected="Cell 1.2 Line 1" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/block/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=2]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=2]//flow/block[2]/lineArea"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpd"/>
+ <eval expected="40000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=2]//flow/block[1]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/block/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@border-before"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=2]//flow/block[1]/block[2]/block)"/>
+ <eval expected="Cell 1.2 Line 2" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/block/lineArea"/>
+ <!-- cell 2.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@border-after"/>
+ <!-- cell 2.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@bpda"/>
+ <eval expected="(solid,#808000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@border-before"/>
+ <eval expected="(solid,#808000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@border-after"/>
+
+ <!-- table 2 -->
+ <eval expected="2" xpath="count(//pageSequence[2]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=3]//flow/block)"/>
+ <eval expected="2. Before the table" xpath="//pageViewport[@nr=3]//flow/block[1]/lineArea"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=3]//flow/block[2]/@bpd"/>
+ <eval expected="16000" xpath="//pageViewport[@nr=3]//flow/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=3]//flow/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=3]//flow/block[2]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/block/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=3]//flow/block[2]/block[2]/block)"/>
+ <eval expected="Cell 1.2 Line 1" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/block/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=4]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=4]//flow/block[2]/lineArea"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpd"/>
+ <eval expected="40000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=4]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=4]//flow/block[1]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=4]//flow/block[1]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/block/lineArea"/>
+ <!-- cell 2.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@border-before"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@border-after"/>
+ <!-- cell 1.2 -->
+ <eval expected="34000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=4]//flow/block[1]/block[3]/block)"/>
+ <eval expected="Cell 1.2 Line 2" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/block/lineArea"/>
+
+ <!-- table 3 -->
+ <eval expected="2" xpath="count(//pageSequence[3]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=5]//flow/block)"/>
+ <eval expected="3. Before the table" xpath="//pageViewport[@nr=5]//flow/block[1]/lineArea"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=5]//flow/block[2]/@bpd"/>
+ <eval expected="16000" xpath="//pageViewport[@nr=5]//flow/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=5]//flow/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=5]//flow/block[2]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=5]//flow/block[2]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/block[1]/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=5]//flow/block[2]/block[2]/block)"/>
+ <eval expected="Cell 1.2 Line 1" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/block[1]/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=6]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=6]//flow/block[2]/lineArea"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=6]//flow/block[1]/@bpd"/>
+ <eval expected="40000" xpath="//pageViewport[@nr=6]//flow/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=6]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=6]//flow/block[1]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=6]//flow/block[1]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/block[1]/lineArea"/>
+ <!-- cell 2.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=6]//flow/block[1]/block[2]/@border-before"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=6]//flow/block[1]/block[2]/@border-after"/>
+ <!-- cell 1.2 -->
+ <eval expected="34000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=6]//flow/block[1]/block[3]/block)"/>
+ <eval expected="Cell 1.2 Line 2" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/block[1]/lineArea"/>
+
+ <!-- table 4 -->
+ <eval expected="2" xpath="count(//pageSequence[4]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=7]//flow/block)"/>
+ <eval expected="4. Before the table" xpath="//pageViewport[@nr=7]//flow/block[1]/lineArea"/>
+ <eval expected="34000" xpath="//pageViewport[@nr=7]//flow/block[2]/@bpd"/>
+ <eval expected="34000" xpath="//pageViewport[@nr=7]//flow/block[2]/@bpda"/>
+ <!-- cell 1.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=7]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="26000" xpath="//pageViewport[@nr=7]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=7]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="(solid,#008080,2000,collapse-inner)" xpath="//pageViewport[@nr=7]//flow/block[2]/block[1]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="21000" xpath="//pageViewport[@nr=7]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="25000" xpath="//pageViewport[@nr=7]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=7]//flow/block[2]/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=7]//flow/block[2]/block[2]/@border-after"/>
+ <eval expected="11000" xpath="//pageViewport[@nr=7]//flow/block[2]/block[3]/@bpd"/>
+ <eval expected="11000" xpath="//pageViewport[@nr=7]//flow/block[2]/block[3]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=7]//flow/block[2]/block[3]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=7]//flow/block[2]/block[3]/@border-after"/>
+ <eval expected="32000" xpath="//pageViewport[@nr=7]//flow/block[2]/block[4]/@bpd"/>
+ <eval expected="32000" xpath="//pageViewport[@nr=7]//flow/block[2]/block[4]/@bpda"/>
+ <eval expected="2" xpath="count(//pageViewport[@nr=7]//flow/block[2]/block[4]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=7]//flow/block[2]/block[4]/block[1]/lineArea"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=7]//flow/block[2]/block[4]/block[2]/lineArea"/>
+ <!-- cell 2.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=7]//flow/block[2]/block[5]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=7]//flow/block[2]/block[5]/@bpda"/>
+ <eval expected="(solid,#808000,2000,collapse-inner)" xpath="//pageViewport[@nr=7]//flow/block[2]/block[5]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=7]//flow/block[2]/block[5]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=7]//flow/block[2]/block[5]/block)"/>
+ <eval expected="Cell 2.2 Line 1" xpath="//pageViewport[@nr=7]//flow/block[2]/block[5]/block[1]/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=8]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=8]//flow/block[2]/lineArea"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=8]//flow/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=8]//flow/block[1]/@bpda"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=8]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="14000" xpath="//pageViewport[@nr=8]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=8]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=8]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="10000" xpath="//pageViewport[@nr=8]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="10000" xpath="//pageViewport[@nr=8]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="0" xpath="count(//pageViewport[@nr=8]//flow/block[1]/block[2]/block)"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=8]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="14000" xpath="//pageViewport[@nr=8]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=8]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=8]//flow/block[1]/block[3]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=8]//flow/block[1]/block[3]/block)"/>
+ <eval expected="Cell 2.2 Line 2" xpath="//pageViewport[@nr=8]//flow/block[1]/block[3]/block[1]/lineArea"/>
+
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks that keep-with-previous works on blocks in table-cells.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page" page-height="3in" page-width="5in"
+ margin="0.5in">
+ <fo:region-body background-color="#F0F0F0"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <!-- table 1 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="106pt">1. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid olive">
+ <fo:block keep-with-previous="always">Cell 3.1 Line 1</fo:block>
+ <fo:block>Cell 3.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 2 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="106pt">2. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal" number-rows-spanned="2">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block keep-with-previous="always">Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 3 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="124">3. Before the table</fo:block>
+ <fo:block>Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal" number-rows-spanned="2">
+ <fo:block keep-with-previous="always">Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+ <checks>
+
+ <!-- table 1 -->
+ <eval expected="2" xpath="count(//pageSequence[1]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=1]//flow/block)"/>
+ <eval expected="1. Before the table" xpath="//pageViewport[@nr=1]//flow/block[1]/lineArea"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/@bpd"/>
+ <eval expected="16000" xpath="//pageViewport[@nr=1]//flow/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=1]//flow/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=1]//flow/block[2]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/block/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=1]//flow/block[2]/block[2]/block)"/>
+ <eval expected="Cell 1.2 Line 1" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/block/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=2]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=2]//flow/block[2]/lineArea"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpd"/>
+ <eval expected="40000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=2]//flow/block[1]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/block/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@border-before"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=2]//flow/block[1]/block[2]/block)"/>
+ <eval expected="Cell 1.2 Line 2" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/block/lineArea"/>
+ <!-- cell 2.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@border-after"/>
+ <!-- cell 2.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@bpda"/>
+ <eval expected="(solid,#808000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@border-before"/>
+ <eval expected="(solid,#808000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@border-after"/>
+
+ <!-- table 2 -->
+ <eval expected="2" xpath="count(//pageSequence[2]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=3]//flow/block)"/>
+ <eval expected="2. Before the table" xpath="//pageViewport[@nr=3]//flow/block[1]/lineArea"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=3]//flow/block[2]/@bpd"/>
+ <eval expected="16000" xpath="//pageViewport[@nr=3]//flow/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=3]//flow/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=3]//flow/block[2]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/block/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=3]//flow/block[2]/block[2]/block)"/>
+ <eval expected="Cell 1.2 Line 1" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/block/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=4]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=4]//flow/block[2]/lineArea"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpd"/>
+ <eval expected="40000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=4]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=4]//flow/block[1]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=4]//flow/block[1]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/block/lineArea"/>
+ <!-- cell 2.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@border-before"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@border-after"/>
+ <!-- cell 1.2 -->
+ <eval expected="34000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=4]//flow/block[1]/block[3]/block)"/>
+ <eval expected="Cell 1.2 Line 2" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/block/lineArea"/>
+
+ <!-- table 3 -->
+ <eval expected="2" xpath="count(//pageSequence[3]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="1" xpath="count(//pageViewport[@nr=5]//flow/block)"/>
+ <eval expected="3. Before the table" xpath="//pageViewport[@nr=5]//flow/block[1]/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="3" xpath="count(//pageViewport[@nr=6]//flow/block)"/>
+ <eval expected="Before the table" xpath="//pageViewport[@nr=6]//flow/block[1]/lineArea"/>
+ <eval expected="48000" xpath="//pageViewport[@nr=6]//flow/block[2]/@bpd"/>
+ <eval expected="56000" xpath="//pageViewport[@nr=6]//flow/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=6]//flow/block[2]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=6]//flow/block[2]/@border-after"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=6]//flow/block[3]/lineArea"/>
+
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks that keep-together works on table-row.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page" page-height="3in" page-width="5in"
+ margin="0.5in">
+ <fo:region-body background-color="#F0F0F0"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <!-- table 1 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="118pt">1. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row keep-together="always">
+ <fo:table-cell border="2pt solid blue" keep-together="auto">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal" keep-together="auto">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid olive">
+ <fo:block>Cell 3.1 Line 1</fo:block>
+ <fo:block>Cell 3.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 2 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="118">2. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row keep-together="always">
+ <fo:table-cell border="2pt solid blue" keep-together="auto">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal" number-rows-spanned="2" keep-together="auto">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 3 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="100">3. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="collapse" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue" number-rows-spanned="2">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row keep-together="always">
+ <fo:table-cell border="2pt solid olive" keep-together="auto">
+ <fo:block>Cell 2.2 Line 1</fo:block>
+ <fo:block>Cell 2.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+ <checks>
+
+ <!-- table 1 -->
+ <eval expected="2" xpath="count(//pageSequence[1]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="1" xpath="count(//pageViewport[@nr=1]//flow/block)"/>
+ <eval expected="1. Before the table" xpath="//pageViewport[@nr=1]//flow/block[1]/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=2]//flow/block)"/>
+ <eval expected="48000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpd"/>
+ <eval expected="56000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-after"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=2]//flow/block[2]/lineArea"/>
+
+ <!-- table 2 -->
+ <eval expected="2" xpath="count(//pageSequence[2]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="1" xpath="count(//pageViewport[@nr=3]//flow/block)"/>
+ <eval expected="2. Before the table" xpath="//pageViewport[@nr=3]//flow/block[1]/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=4]//flow/block)"/>
+ <eval expected="48000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpd"/>
+ <eval expected="56000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=4]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=4]//flow/block[1]/@border-after"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=4]//flow/block[2]/lineArea"/>
+
+ <!-- table 3 -->
+ <eval expected="2" xpath="count(//pageSequence[3]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=5]//flow/block)"/>
+ <eval expected="3. Before the table" xpath="//pageViewport[@nr=5]//flow/block[1]/lineArea"/>
+ <eval expected="23000" xpath="//pageViewport[@nr=5]//flow/block[2]/@bpd"/>
+ <eval expected="23000" xpath="//pageViewport[@nr=5]//flow/block[2]/@bpda"/>
+ <!-- cell 1.1 -->
+ <eval expected="21000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="25000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=5]//flow/block[2]/block[1]/@border-after"/>
+ <eval expected="21000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="21000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="2" xpath="count(//pageViewport[@nr=5]//flow/block[2]/block[2]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/block[1]/lineArea"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=5]//flow/block[2]/block[2]/block[2]/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[3]/@bpd"/>
+ <eval expected="26000" xpath="//pageViewport[@nr=5]//flow/block[2]/block[3]/@bpda"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=5]//flow/block[2]/block[3]/@border-before"/>
+ <eval expected="(solid,#008080,2000,collapse-outer)" xpath="//pageViewport[@nr=5]//flow/block[2]/block[3]/@border-after"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=6]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=6]//flow/block[2]/lineArea"/>
+ <eval expected="23000" xpath="//pageViewport[@nr=6]//flow/block[1]/@bpd"/>
+ <eval expected="23000" xpath="//pageViewport[@nr=6]//flow/block[1]/@bpda"/>
+ <!-- cell 1.1 -->
+ <eval expected="21000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="25000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=6]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="21000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="21000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="0" xpath="count(//pageViewport[@nr=6]//flow/block[1]/block[2]/block)"/>
+ <!-- cell 2.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="26000" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="(solid,#808000,2000,collapse-outer)" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=6]//flow/block[1]/block[3]/@border-after"/>
+
+ </checks>
+</testcase>
<fo:page-sequence master-reference="normal">
<fo:flow flow-name="xsl-region-body">
<fo:block>block1</fo:block>
- <fo:table table-layout="fixed">
- <fo:table-column/>
- <fo:table-column/>
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/>
<fo:table-body>
<fo:table-row keep-with-next.within-page="always">
<fo:table-cell id="cell1">
<box w="14400"/>
<penalty w="0" p="0"/>
<box w="14400"/>
- <penalty w="0" p="INF"/>
+ <penalty w="0" p="0"/>
<box w="14400"/>
<penalty w="0" p="INF"/>
<box w="14400"/>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks that keep-with-next works on table-row.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page" page-height="3in" page-width="5in"
+ margin="0.5in">
+ <fo:region-body background-color="#F0F0F0"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <!-- table 1 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="106pt">1. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row keep-with-next="always">
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal" number-rows-spanned="2">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 2 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="88">2. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="collapse" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue" number-rows-spanned="2">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row keep-with-next="always">
+ <fo:table-cell border="2pt solid olive">
+ <fo:block>Cell 2.2 Line 1</fo:block>
+ <fo:block>Cell 2.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+ <checks>
+
+ <!-- table 1 -->
+ <eval expected="2" xpath="count(//pageSequence[1]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=1]//flow/block)"/>
+ <eval expected="1. Before the table" xpath="//pageViewport[@nr=1]//flow/block[1]/lineArea"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/@bpd"/>
+ <eval expected="16000" xpath="//pageViewport[@nr=1]//flow/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=1]//flow/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=1]//flow/block[2]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/block/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=1]//flow/block[2]/block[2]/block)"/>
+ <eval expected="Cell 1.2 Line 1" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/block/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=2]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=2]//flow/block[2]/lineArea"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpd"/>
+ <eval expected="40000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=2]//flow/block[1]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/block/lineArea"/>
+ <!-- cell 2.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@border-before"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@border-after"/>
+ <!-- cell 1.2 -->
+ <eval expected="34000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=2]//flow/block[1]/block[3]/block)"/>
+ <eval expected="Cell 1.2 Line 2" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/block/lineArea"/>
+
+ <!-- table 2 -->
+ <eval expected="2" xpath="count(//pageSequence[2]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=3]//flow/block)"/>
+ <eval expected="2. Before the table" xpath="//pageViewport[@nr=3]//flow/block[1]/lineArea"/>
+ <eval expected="34000" xpath="//pageViewport[@nr=3]//flow/block[2]/@bpd"/>
+ <eval expected="34000" xpath="//pageViewport[@nr=3]//flow/block[2]/@bpda"/>
+ <!-- cell 1.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="26000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="(solid,#008080,2000,collapse-inner)" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="21000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="25000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@border-after"/>
+ <eval expected="11000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[3]/@bpd"/>
+ <eval expected="11000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[3]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/block[3]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/block[3]/@border-after"/>
+ <eval expected="32000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[4]/@bpd"/>
+ <eval expected="32000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[4]/@bpda"/>
+ <eval expected="2" xpath="count(//pageViewport[@nr=3]//flow/block[2]/block[4]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=3]//flow/block[2]/block[4]/block[1]/lineArea"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=3]//flow/block[2]/block[4]/block[2]/lineArea"/>
+ <!-- cell 2.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[5]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[5]/@bpda"/>
+ <eval expected="(solid,#808000,2000,collapse-inner)" xpath="//pageViewport[@nr=3]//flow/block[2]/block[5]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/block[5]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=3]//flow/block[2]/block[5]/block)"/>
+ <eval expected="Cell 2.2 Line 1" xpath="//pageViewport[@nr=3]//flow/block[2]/block[5]/block[1]/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=4]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=4]//flow/block[2]/lineArea"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpda"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="14000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="10000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="10000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="0" xpath="count(//pageViewport[@nr=4]//flow/block[1]/block[2]/block)"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="14000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=4]//flow/block[1]/block[3]/block)"/>
+ <eval expected="Cell 2.2 Line 2" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/block[1]/lineArea"/>
+
+ </checks>
+</testcase>
</fo:layout-master-set>
<fo:page-sequence master-reference="normal">
<fo:flow flow-name="xsl-region-body">
- <fo:block>block1</fo:block>
- <fo:table table-layout="fixed">
- <fo:table-column/>
- <fo:table-column/>
+ <fo:block space-after="1.5*14.4pt">block1</fo:block>
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/>
<fo:table-body>
<fo:table-row keep-with-previous.within-page="always">
<fo:table-cell id="cell1">
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks that keep-with-previous works on table-row.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page" page-height="3in" page-width="5in"
+ margin="0.5in">
+ <fo:region-body background-color="#F0F0F0"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <!-- table 1 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="106pt">1. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row keep-with-previous="always">
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid olive">
+ <fo:block>Cell 3.1 Line 1</fo:block>
+ <fo:block>Cell 3.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 2 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="106pt">2. Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal" number-rows-spanned="2">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row keep-with-previous="always">
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 3 -->
+ <fo:page-sequence master-reference="page" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="124">3. Before the table</fo:block>
+ <fo:block>Before the table</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="collapse" border="4pt solid black">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row keep-with-previous="always">
+ <fo:table-cell border="2pt solid blue" number-rows-spanned="2">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid olive">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+ <checks>
+
+ <!-- table 1 -->
+ <eval expected="2" xpath="count(//pageSequence[1]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=1]//flow/block)"/>
+ <eval expected="1. Before the table" xpath="//pageViewport[@nr=1]//flow/block[1]/lineArea"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/@bpd"/>
+ <eval expected="16000" xpath="//pageViewport[@nr=1]//flow/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=1]//flow/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=1]//flow/block[2]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=1]//flow/block[2]/block[1]/block/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=1]//flow/block[2]/block[2]/block)"/>
+ <eval expected="Cell 1.2 Line 1" xpath="//pageViewport[@nr=1]//flow/block[2]/block[2]/block/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=2]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=2]//flow/block[2]/lineArea"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpd"/>
+ <eval expected="40000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=2]//flow/block[1]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/block/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@border-before"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=2]//flow/block[1]/block[2]/block)"/>
+ <eval expected="Cell 1.2 Line 2" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/block/lineArea"/>
+ <!-- cell 2.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@border-after"/>
+ <!-- cell 2.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@bpda"/>
+ <eval expected="(solid,#808000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@border-before"/>
+ <eval expected="(solid,#808000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@border-after"/>
+
+ <!-- table 2 -->
+ <eval expected="2" xpath="count(//pageSequence[2]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=3]//flow/block)"/>
+ <eval expected="2. Before the table" xpath="//pageViewport[@nr=3]//flow/block[1]/lineArea"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=3]//flow/block[2]/@bpd"/>
+ <eval expected="16000" xpath="//pageViewport[@nr=3]//flow/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=3]//flow/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@bpda"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=3]//flow/block[2]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 1" xpath="//pageViewport[@nr=3]//flow/block[2]/block[1]/block/lineArea"/>
+ <!-- cell 1.2 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@bpda"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@border-before"/>
+ <eval expected="" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=3]//flow/block[2]/block[2]/block)"/>
+ <eval expected="Cell 1.2 Line 1" xpath="//pageViewport[@nr=3]//flow/block[2]/block[2]/block/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=4]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=4]//flow/block[2]/lineArea"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpd"/>
+ <eval expected="40000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=4]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=4]//flow/block[1]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="10000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="12000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=4]//flow/block[1]/block[1]/block)"/>
+ <eval expected="Cell 1.1 Line 2" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/block/lineArea"/>
+ <!-- cell 2.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@border-before"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@border-after"/>
+ <!-- cell 1.2 -->
+ <eval expected="34000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="36000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@border-after"/>
+ <eval expected="1" xpath="count(//pageViewport[@nr=4]//flow/block[1]/block[3]/block)"/>
+ <eval expected="Cell 1.2 Line 2" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/block/lineArea"/>
+
+ <!-- table 3 -->
+ <eval expected="2" xpath="count(//pageSequence[3]/pageViewport)"/>
+ <!-- page 1 -->
+ <eval expected="1" xpath="count(//pageViewport[@nr=5]//flow/block)"/>
+ <eval expected="3. Before the table" xpath="//pageViewport[@nr=5]//flow/block[1]/lineArea"/>
+ <!-- page 2 -->
+ <eval expected="3" xpath="count(//pageViewport[@nr=6]//flow/block)"/>
+ <eval expected="Before the table" xpath="//pageViewport[@nr=6]//flow/block[1]/lineArea"/>
+ <eval expected="46000" xpath="//pageViewport[@nr=6]//flow/block[2]/@bpd"/>
+ <eval expected="46000" xpath="//pageViewport[@nr=6]//flow/block[2]/@bpda"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=6]//flow/block[3]/lineArea"/>
+
+ </checks>
+</testcase>
<eval expected="5" xpath="count(//pageViewport)"/>
<!-- table -->
<eval expected="18400" xpath="//pageViewport[@nr=3]//flow/block[1]/@bpd"/>
- <!--
- <eval expected="26400" xpath="//pageViewport[@nr=3]//flow/block[1]/@bpda"/>
- <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=3]//flow/block[1]/@border-before"/>
- <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=3]//flow/block[1]/@border-after"/>
- -->
+ <!--eval expected="26400" xpath="//pageViewport[@nr=3]//flow/block[1]/@bpda"/-->
+ <!--eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=3]//flow/block[1]/@border-before"/-->
+ <!--eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=3]//flow/block[1]/@border-after"/-->
<!-- cell 1 -->
<eval expected="14400" xpath="//pageViewport[@nr=3]//flow/block[1]/block[1]/@bpd"/>
<eval expected="18400" xpath="//pageViewport[@nr=3]//flow/block[1]/block[1]/@bpda"/>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks that keep-together works on tables.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page" page-height="3in" page-width="5in"
+ margin="0.5in">
+ <fo:region-body background-color="#F0F0F0"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <!-- table 1 -->
+ <fo:page-sequence master-reference="page" font-family="serif" font-size="8pt"
+ line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="106pt">First line</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="separate" border="4pt solid black"
+ keep-together="always">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body keep-together="auto">
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid olive">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <!-- table 2 -->
+ <fo:page-sequence master-reference="page" font-family="serif" font-size="8pt"
+ line-height="10pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="100">First line</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ border-collapse="collapse" border="4pt solid black"
+ keep-together="always">
+ <fo:table-column number-columns-repeated="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body keep-together="auto">
+ <fo:table-row>
+ <fo:table-cell border="2pt solid blue">
+ <fo:block>Cell 1.1 Line 1</fo:block>
+ <fo:block>Cell 1.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid teal">
+ <fo:block>Cell 1.2 Line 1</fo:block>
+ <fo:block>Cell 1.2 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid green">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell border="2pt solid olive">
+ <fo:block>Cell 2.1 Line 1</fo:block>
+ <fo:block>Cell 2.1 Line 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block>After the table</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+ <checks>
+
+ <!-- table 1 -->
+ <!-- Two pages -->
+ <eval expected="2" xpath="count(//pageSequence[1]/pageViewport)"/>
+ <!-- Only one line on the first page -->
+ <eval expected="1" xpath="count(//pageViewport[@nr=1]//flow/block)"/>
+ <eval expected="First line" xpath="//pageViewport[@nr=1]//flow/block[1]/lineArea/text[1]"/>
+ <!-- Line "Before the table" plus the table itself on the second page -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=2]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=2]//flow/block[2]/lineArea/text[1]"/>
+ <!-- table -->
+ <eval expected="48000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpd"/>
+ <eval expected="56000" xpath="//pageViewport[@nr=2]//flow/block[1]/@bpda"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-before"/>
+ <eval expected="(solid,#000000,4000)" xpath="//pageViewport[@nr=2]//flow/block[1]/@border-after"/>
+ <!-- cell 1.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#0000ff,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[1]/@border-after"/>
+ <!-- cell 1.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@border-before"/>
+ <eval expected="(solid,#008080,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[2]/@border-after"/>
+ <!-- cell 2.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#008000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[3]/@border-after"/>
+ <!-- cell 2.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@bpd"/>
+ <eval expected="24000" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@bpda"/>
+ <eval expected="(solid,#808000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@border-before"/>
+ <eval expected="(solid,#808000,2000)" xpath="//pageViewport[@nr=2]//flow/block[1]/block[4]/@border-after"/>
+
+ <!-- table 2 -->
+ <!-- Two pages -->
+ <eval expected="2" xpath="count(//pageSequence[2]/pageViewport)"/>
+ <!-- Only one line on the first page -->
+ <eval expected="1" xpath="count(//pageViewport[@nr=3]//flow/block)"/>
+ <eval expected="First line" xpath="//pageViewport[@nr=3]//flow/block[1]/lineArea/text[1]"/>
+ <!-- Line "Before the table" plus the table itself on the second page -->
+ <eval expected="2" xpath="count(//pageViewport[@nr=4]//flow/block)"/>
+ <eval expected="After the table" xpath="//pageViewport[@nr=4]//flow/block[2]/lineArea/text[1]"/>
+ <!-- table -->
+ <eval expected="46000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpd"/>
+ <eval expected="46000" xpath="//pageViewport[@nr=4]//flow/block[1]/@bpda"/>
+ <!-- cell 1.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@bpd"/>
+ <eval expected="26000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@bpda"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@border-before"/>
+ <eval expected="(solid,#0000ff,2000,collapse-inner)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[1]/@border-after"/>
+ <!-- cell 1.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@bpd"/>
+ <eval expected="26000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@bpda"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@border-before"/>
+ <eval expected="(solid,#008080,2000,collapse-inner)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[2]/@border-after"/>
+ <!-- cell 2.1 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@bpd"/>
+ <eval expected="26000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@bpda"/>
+ <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@border-before"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[3]/@border-after"/>
+ <!-- cell 2.2 -->
+ <eval expected="20000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[4]/@bpd"/>
+ <eval expected="26000" xpath="//pageViewport[@nr=4]//flow/block[1]/block[4]/@bpda"/>
+ <eval expected="(solid,#808000,2000,collapse-inner)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[4]/@border-before"/>
+ <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//pageViewport[@nr=4]//flow/block[1]/block[4]/@border-after"/>
+
+ </checks>
+</testcase>