The purpose of the stepping algorithm is to find potential breaks inside a row group; that is, a set of all the rows spanned over by one or more table cells:

One issue of this stepping algorithm is to determine when the current row ends, and when we can switch to the next one. In fact, determining when a row ends is easy: it is when all of the cells ending on the row have contributed all of their contents. The only thing that must be taken into account is that the conditionality of their after borders no longer applies, since the row has ended. This may increase the next step and leave space for the spanning cells to contribute more content.

But this is not all: the next row can actually start only once the next step is big enough to encompass the before borders of the cells starting on the row, plus at least a piece of content for each of those cells.

As long as this condition is not met, the next row can’t start and we must stay on the current row. This mechanism was formerly known (in the code and documentation) as backtracking: after switching to the next row, the code was activating the cells starting on this row, computing those cells’ first steps and reverting to the previous row if necessary.

The removal of the 900-penalty mechanism (that is, put a break penalty of 900 to avoid breaking at places where not all cells starting on a row can contribute content) was an opportunity to improve this mechanism, and take advantage of the fact that the next row can’t be started yet to put more content from spanning cells on the current row. The next row is actually delayed, and we will call that row-delaying mechanism.

The idea is quite simple:

In practice we must take into account additional elements:

All the details are to be found in the o.a.f.layoutmgr.table.TableStepper and o.a.f.layoutmgr.table.ActiveCell classes.


There’s a fundamental limitation in the stepping algorithm: apart from forced breaks all the generated penalties have the same value of 0. There is no means to privilege one over another one. This is not related to the row-delaying mechanism but can be seen when that latter is triggered.

Look below at the two different ways the example can be rendered:

Obviously the second is preferable to the first one, but since both of the corresponding penalties have the same value the breaking algorithm will not try to privilege one over the other. The computation of demerits like it is used for other elements doesn’t apply here, since the stepping algorithm produces no glue. And even if it would the glues that it would generate would probably not correspond to the individual glues of the table cells. The only variable we can play with is the value of the penalty, which would somehow be related to the amount of whitespace generated by each step. But it must carefully be computed to not overflow the value of the infinite penalty, and be progressive enough, etc. Not speaking of TableLayout/KnownProblems...

TableLayout/RowDelayingMechanism (last edited 2009-09-20 23:52:29 by localhost)