Example with borders and headers and footers in separate border model
See http://people.apache.org/~jeremias/fop/KnuthBoxesForTablesWithBorders.pdf (page 4) for a graphical representation of the example.
<fo:table table-layout="fixed" border-collapse="separate" border="solid 5pt black">
<fo:table-column column-width="proportional-column-width(1)"/>
<fo:table-column column-width="proportional-column-width(1)"/>
<fo:table-column column-width="proportional-column-width(1)"/>
<fo:table-header>
<fo:table-row>
<fo:table-cell font-size="8pt" line-height="8pt" border="solid 1pt orange" number-columns-spanned="3">
<fo:block>HEADER</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-header>
<fo:table-footer>
<fo:table-row>
<fo:table-cell font-size="8pt" line-height="8pt" border="solid 1pt orange" number-columns-spanned="3">
<fo:block>FOOTER</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-footer>
<fo:table-body>
<fo:table-row>
<fo:table-cell font-size="8pt" line-height="10pt" border="solid 1pt orange" number-rows-spanned="2">
<fo:block>
<fo:block background-color="yellow">block1</fo:block>
<fo:block>block2</fo:block>
<fo:block background-color="yellow">block3</fo:block>
</fo:block>
</fo:table-cell>
<fo:table-cell line-height="15pt" border="solid 1pt orange">
<fo:block background-color="yellow">blockA</fo:block>
</fo:table-cell>
<fo:table-cell line-height="15pt" border="solid 4pt violet">
<fo:block>blockA</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell line-height="20pt" border="solid 1pt orange">
<fo:block background-color="yellow">blockB</fo:block>
</fo:table-cell>
<fo:table-cell line-height="20pt" border="solid 4pt violet">
<fo:block>blockB</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>A full XSL-FO file with this example can be downloaded from: http://people.apache.org/~jeremias/fop/table-border-special1-sep.fo
An sketch of this example:
no breaks | step 1 | step 2 | step 3 | step 4 | step 5 | step 6 |
| | | | | | |
5 | 5 | 5 | 5 | 5 | 5 | 5 |
1 | 1 | 1 | 1 | 1 | 1 | 1 |
8 | 8 | 8 | 8 | 8 | 8 | 8 |
1 | 1 | 1 | 1 | 1 | 1 | 1 |
1 1 4 | 1 1 4 | 1 1 4 | 1 1 4 | 1 1 4 | 1 1 4 | 1 1 4 |
XX | XX | XX | XX | XX | XX | XX |
10 15 15 | 10 - - | 10 15 - | 10 15 - | 10 15 15 | 10 15 15 | 10 15 15 |
10 1+1 4+4 | | | 10 | 10 | 10 1+1 4+4 | 10 1+1 4+4 |
| | | | | | XX |
10 20 20 | | | | | 10 | 10 20 - |
1 1 4 | 1 1 4 1 1 4 | 1 1 4 | 1 1 4 | 1 1 4 | 1 1 4 |
1 | 1 | 1 | 1 | 1 | 1 | 1 |
8 | 8 | 8 | 8 | 8 | 8 | 8 |
1 | 1 | 1 | 1 | 1 | 1 | 1 |
5 | 5 | 5 | 5 | 5 | 5 | 5 |
-------------------------------------------------------------------------------------------------- page break
| 5 | 5 | 5 | 5 | 5 | 5 |
| 1 | 1 | 1 | 1 | 1 | 1 |
| 8 | 8 | 8 | 8 | 8 | 8 |
| 1 | 1 | 1 | 1 | 1 | 1 |
| 1 1 4 1 1 4 | 1 1 4 | 1 1 4 | 1 1 4 | 1 1 4 |
| XX | XX | XX | XX | XX | XX |
| 10 15 15 | 10 - 15 | 10 - 15 | 10 20 20 | - 20 20 | - - 20 |
| 10 1+1 4+4 | 10 1+1 4+4 | 1+1 4+4 | | | |
| 20 20 | 20 20 | 20 20 | | | |
| 1 1 4 1 1 4 | 1 1 4 | 1 1 4 | 1 1 4 | 1 1 4 |
| 1 | 1 | 1 | 1 | 1 | 1 |
| 8 | 8 | 8 | 8 | 8 | 8 |
| 1 | 1 | 1 | 1 | 1 | 1 |
| 5 | 5 | 5 | 5 | 5 | 5 |
================================================================================================== result
81 | 42/81 | 47/81 | 52/81 | 53/58 | 62/58 | 75/58 |
Note like steps 3 and 4 differ from the RowBorder2 example.
(XX) indicates the height determining columnNote: In contrast to collapsing border model the headers and footers have constant height which makes things a lot simpler.
Table header and footer length
Header is 5 + 1 + 8 + 1 = 15 Footer is 1 + 8 + 1 + 5 = 15
Row heights
row1: 4 + 15 + 4 => (23,23,23) row2: 4 + 20 + 4 => (28,28,28) row group (51,51,51)
Note: Incidentally, the nominal row height are the same as in the RowBorder2 example. The lengths could easily be different.
Steps
Step 1: stepw = 1 (r1) + 10 + 1 (r1) = 12 maxRemainingHeight = 51 addedBoxHeight = 0 penalty = 12 + 51 - 51 = 12 effPenalty: w = 12 (space for block1) + 15 (header) + 15 (footer) = 42 box = 12 - 0 - 12 = 0 Step 2: stepw = 1 (r1) + 15 + 1 (r1) = 17 maxRemainingHeight = 51 addedBoxHeight = 0 penalty = 17 + 51 - 51 = 17 effPenalty: w = 17 (calc penalty) + 15 + 15 = 47 box = 17 - 0 - (17) = 0 Step 3: stepw = 1 (r1) + 10 + 10 + 1 (r1) = 22 maxRemainingHeight = 51 addedBoxHeight = 0 penalty = 22 + 51 - 51 = 22 effPenalty: w = 22 (calc penalty) + 15 + 15 = 52 box = 22 - 0 - (22) = 0 Step 4: stepw = 4 (r1) + 15 + 4 (r1) = 23 maxRemainingHeight = 28 addedBoxHeight = 0 penalty = 23 + 28 - 51 = 0 effPenalty: w = 0 (calc penalty) + 15 + 15 = 30 box = 23 - 0 - (0) = 23 Step 5: stepw = 1 (r1) + 10 + 10 + 10 + 1 (r1) = 32 maxRemainingHeight = 28 addedBoxHeight = 23 penalty = 32 + 28 - 51 = 9 effPenalty: w = 9 (calc penalty) + 15 + 15 = 39 box = 32 - 23 - (9) = 0 Step 6: stepw = 4 (r1, col3) + 15 + 4 (r1, col3) + 1 (r2, col2) + 20 + 1 (r2, col2) = 45 maxRemainingHeight = 28 addedBoxHeight = 23 penalty = 45 + 28 - 51 = 22 effPenalty: w = 22 (calc penalty) + 15 + 15 = 52 box = 45 - 23 - (22) = 0 Step 7: stepw = 4 (r1, col3) + 15 + 4 (r1, col3) + 4 (r2, col3) + 20 + 4 (r2, col3) = 51 maxRemainingHeight = 0 addedBoxHeight = 23 penalty = 51 + 0 - 51 = 0 (last step, omit penalty) box = 51 - 23 - 0 = 28
End result (with raw penalties)
box(0)
penalty(12) -> 12/51
box(0)
penalty(17) -> 17/51
box(0)
penalty(22) -> 22/51
box(23)
penalty(0) -> 23/28
box(0)
penalty(9) -> 32/28
box(0)
penalty(22) -> 45/28
box(28)
-> 51
End result (effective)
box(0)
penalty(42) //incl. header and footer -> 42/81
box(0)
penalty(47) //incl. header and footer -> 47/81
box(0)
penalty(52) //incl. header and footer -> 52/81
box(23)
penalty(30) //incl. header and footer -> 53/58
box(0)
penalty(39) //incl. header and footer -> 62/58
box(0)
penalty(52) //incl. header and footer -> 75/58
box(28)
box(15) //header
box(15) //footer
-> 81