In this approach for each cell a single box plus stretchable penalty is created to represent the cell as a whole. All the boxes for a row are combined to one which is used for page breaking. The approach is described here: [http://mail-archives.eu.apache.org/mod_mbox/xmlgraphics-fop-dev/200503.mbox/%3c20050322132704.9D77.DEV.JEREMIAS@greenmail.ch%3elink]

In this approach for each cell a single box plus stretchable penalty is created to represent the cell as a whole. All the boxes for a row are combined to one which is used for page breaking. The approach is described here: [[http://mail-archives.eu.apache.org/mod_mbox/xmlgraphics-fop-dev/200503.mbox/%3c20050322132704.9D77.DEV.JEREMIAS@greenmail.ch%3e|link]]

Knuth element generation for tables

Overview

At the moment we see two fundamental approachs for generating Knuth elements for tables. Note: Some of the considerations made here can also be applied to lists.

1. Combined element list

In this approach the individual element lists of each cell are combined to a single element list that can be used in page breaking. The approach is described in detail further down.

2. Combined stretch boxes

In this approach for each cell a single box plus stretchable penalty is created to represent the cell as a whole. All the boxes for a row are combined to one which is used for page breaking. The approach is described here: link

For each cell-list, we must know, besides the total height, the height of the elements already combined into the new ones.

The nextStep() method looks at each cell-list, computing the height of the first sub-sequence, chooses the smallest increase and updates in each list the height of the elements already combined; maxRemainingHeight() returns the greatest difference between the total height of a cell-list and the height of the elements already combined.

Handling row spanning with this approach

The meaning of "totalHeight" in the above algorithm needs to be extended for the combined list. totalHeight will not only be the total height of a single row, but of a row group. A row group in this context is the minimum number of consecutive rows which contains all spanned grid units of its cells. An example:

Here we'd have two such row groups, the first is equivalent to the first row, the second contains rows 2 to 5. Note that we can't just sum up the heights of the individual cells in the row group per column. We have to add the space used by the cell borders (and optional cell spacing in separate mode), too, because they are also elements that create steps in the algorithm.

Determining the row height for each row (with row spanning)

for each row
effRowHeight = minoptmax(0, 0, INF) (=auto height)
if (bpd of row != auto)
effRowHeight = minoptmax(bpd of row)
for each cell ending in the current row
effCellHeight = minoptmax(0, 0, INF) (=auto height)
if (bpd of cell != auto)
effCellHeight = minoptmax(bpd of cell)
MinOptMax contentHeight = calcContentHeightOfCell()
if collapsing border model then
contentHeight += half of before and after borders for that cell (assuming no break happens)
else
contentHeight += before and after borders of that cell plus half the BPD border-separation
//handle spanned cells
contentHeight -= sum of all heights of previous occupied spanned grid units
check if cell content overflows available cell BPD
extend effCellHeight based on the contentHeight (handling auto height)
check if cell content overflows available row BPD
extend effRowHeight based on the effCellHeight
remember the newly determined row height (effRowHeight)

Further details on nextStep()

There are a few additional things that have to be done in nextStep() (or at least in its context):

Propagating hard breaks from child elements

Creating elements in a way that keeps are fulfilled

Determining the different effective borders for each grid unit

Handling table-header|footer

More complex example with row spans, headers, footers and borders

This example tries to examine a few more aspects of the whole process.

Knowns problems

There's a problem when a cell is broken over more than two pages. In this case the steps may not be accurate anymore for breaking between the second and third page. This is only the case when the step generator has to create penalties. If we wanted to fix this, we would have to discard all elements starting on the second page, so the elements can be recreated based on the earlier break decision.