import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.ListIterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
+import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.layoutmgr.KnuthPossPosIter;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.ListElement;
while ((rowGroup = iter.getNextRowGroup()) != null) {
rowGroupLM = new RowGroupLayoutManager(getTableLM(), rowGroup, stepper);
nextRowGroupElems = rowGroupLM.getNextKnuthElements(context, alignment, bodyType);
+ /*
+ * The last break element produced by TableStepper (for the previous row
+ * group) may be used to represent the break between the two row groups.
+ * Its penalty value and break class must just be overridden by the
+ * characteristics of the keep or break between the two.
+ *
+ * However, we mustn't forget that if the after border of the last row of
+ * the row group is thicker in the normal case than in the trailing case,
+ * an additional glue will be appended to the element list. So we may have
+ * to go two steps backwards in the list.
+ */
int penaltyValue = 0;
keepBetween |= context.isKeepWithPreviousPending();
if (keepBetween || tableLM.getTable().mustKeepTogether()) {
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();
- }
+ BreakElement breakElement;
+ ListIterator elemIter = returnList.listIterator(returnList.size());
+ ListElement elem = (ListElement) elemIter.previous();
+ if (elem instanceof KnuthGlue) {
+ breakElement = (BreakElement) elemIter.previous();
+ } else {
+ breakElement = (BreakElement) elem;
}
- returnList.add(new BreakElement(penaltyPos,
- penaltyLen, penaltyValue, breakBetween, context));
+ breakElement.setPenaltyValue(penaltyValue);
+ breakElement.setBreakClass(breakBetween);
returnList.addAll(nextRowGroupElems);
breakBetween = context.getBreakAfter();
keepBetween = context.isKeepWithNextPending();
}
}
+ /*
+ * The last break produced for the last row-group of this table part must be
+ * removed, because the breaking after the table will be handled by TableLM.
+ * Unless the element list ends with a glue, which must be kept to accurately
+ * represent the content. In such a case the break is simply disabled by setting
+ * its penalty to infinite.
+ */
+ ListIterator elemIter = returnList.listIterator(returnList.size());
+ ListElement elem = (ListElement) elemIter.previous();
+ if (elem instanceof KnuthGlue) {
+ BreakElement breakElement = (BreakElement) elemIter.previous();
+ breakElement.setPenaltyValue(KnuthElement.INFINITE);
+ } else {
+ elemIter.remove();
+ }
context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, keepWithPrevious);
context.setBreakBefore(breakBefore);
</fo:table-row>
</fo:table-body>
</fo:table>
+
+ <fo:block space-before="20pt" space-after="10pt">The after border of cell 1, in the normal
+ case, is thicker than in the trailing case.</fo:block>
+ <fo:table width="100%" table-layout="fixed"
+ font-size="8pt" line-height="10pt">
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="1pt solid black">
+ <fo:block>Cell 1</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="2pt solid black">
+ <fo:block>Cell 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+
</fo:flow>
</fo:page-sequence>
</fo:root>
</fo>
<checks>
+ <!-- table 1 -->
<eval expected="39000" xpath="//pageViewport//flow/block[2]/@bpd"/>
<eval expected="39000" xpath="//pageViewport//flow/block[2]/@bpda"/>
<!-- cell 1.1 -->
<eval expected="10000" xpath="//pageViewport//flow/block[2]/block[6]/@bpd"/>
<eval expected="18000" xpath="//pageViewport//flow/block[2]/block[6]/@bpda"/>
+ <!-- table 2 -->
+ <eval expected="23500" xpath="//pageViewport//flow/block[4]/@bpd"/>
+ <eval expected="23500" xpath="//pageViewport//flow/block[4]/@bpda"/>
+ <!-- cell 1 -->
+ <eval expected="10000" xpath="//pageViewport//flow/block[4]/block[1]/@bpd"/>
+ <eval expected="13000" xpath="//pageViewport//flow/block[4]/block[1]/@bpda"/>
+ <!-- cell 2 -->
+ <eval expected="10000" xpath="//pageViewport//flow/block[4]/block[2]/@bpd"/>
+ <eval expected="14000" xpath="//pageViewport//flow/block[4]/block[2]/@bpda"/>
+
<element-list category="breaker">
<skip>4</skip>
<box w="12000"/>
- <penalty w="14000" p="0"/><!-- should be 15000 -->
+ <penalty w="15000" p="0"/>
<box w="13000"/>
<box w="14000"/>
+ <skip>6</skip>
+ <box w="11000"/>
+ <penalty w="0" p="0"/>
+ <glue w="500"/>
+ <box w="12000"/>
<skip>3</skip>
</element-list>
</checks>