List positions = new java.util.ArrayList();
List headerElements = null;
List footerElements = null;
+ int nestedPenaltyArea = 0;
Position firstPos = null;
Position lastPos = null;
Position lastCheckPos = null;
if (penaltyPos.footerElements != null) {
footerElements = penaltyPos.footerElements;
}
+ nestedPenaltyArea = penaltyPos.nestedPenaltyLength;
}
Map markers = getTableLM().getTable().getMarkers();
iterateAndPaintPositions(posIter, painter);
painter.addAreasAndFlushRow(true);
+ painter.notifyNestedPenaltyArea(nestedPenaltyArea);
if (footerElements != null) {
//Positions for footers are simply added at the end
PositionIterator nestedIter = new KnuthPossPosIter(footerElements);
this.accumulatedBPD += lastRowHeight; //for last row
}
+ public void notifyNestedPenaltyArea(int length) {
+ this.lastRowHeight += length;
+ }
+
public void handleTableContentPosition(TableContentPosition tcpos) {
if (lastRow != tcpos.row && lastRow != null) {
addAreasAndFlushRow(false);
protected List headerElements;
/** Element list for the footer */
protected List footerElements;
+ /** Penalty length to be respected for nested content */
+ protected int nestedPenaltyLength;
/**
* Creates a new TableHFPenaltyPosition
sb.append(headerElements);
sb.append(", footer:");
sb.append(footerElements);
+ sb.append(", inner penalty length:");
+ sb.append(nestedPenaltyLength);
sb.append(")");
return sb.toString();
}
private boolean skippedStep;
private boolean[] keepWithNextSignals;
private boolean[] forcedBreaks;
+ private int lastMaxPenalty;
/**
* Main constructor
int penaltyLen = step + getMaxRemainingHeight() - totalHeight;
int boxLen = step - addedBoxLen - penaltyLen;
addedBoxLen += boxLen;
-
+
//Put all involved grid units into a list
List gridUnitParts = new java.util.ArrayList(maxColumnCount);
for (int i = 0; i < start.length; i++) {
penaltyPos.footerElements = tclm.getFooterElements();
}
}
+
+ //Handle a penalty length coming from nested content
+ //Example: nested table with header/footer
+ if (this.lastMaxPenalty != 0) {
+ penaltyPos.nestedPenaltyLength = this.lastMaxPenalty;
+ if (log.isDebugEnabled()) {
+ log.debug("Additional penalty length from table-cell break: "
+ + this.lastMaxPenalty);
+ }
+ }
+ effPenaltyLen += this.lastMaxPenalty;
+
int p = 0;
boolean allCellsHaveContributed = true;
signalKeepWithNext = false;
p = -KnuthPenalty.INFINITE; //Overrides any keeps (see 4.8 in XSL 1.0)
clearBreakCondition();
}
- //returnList.add(new KnuthPenalty(effPenaltyLen, p, false, penaltyPos, false));
returnList.add(new BreakElement(penaltyPos, effPenaltyLen, p, -1, context));
- log.debug("step=" + step + " (+" + increase + ")"
- + " box=" + boxLen
- + " penalty=" + penaltyLen
- + " effPenalty=" + effPenaltyLen);
+ if (log.isDebugEnabled()) {
+ log.debug("step=" + step + " (+" + increase + ")"
+ + " box=" + boxLen
+ + " penalty=" + penaltyLen
+ + " effPenalty=" + effPenaltyLen);
+ }
laststep = step;
if (rowBacktrackForLastStep) {
}
private int getNextStep(int lastStep) {
+ this.lastMaxPenalty = 0;
//Check for forced break conditions
/*
if (isBreakCondition()) {
end[i]++;
KnuthElement el = (KnuthElement)elementLists[i].get(end[i]);
if (el.isPenalty()) {
+ this.lastMaxPenalty = Math.max(this.lastMaxPenalty, el.getW());
if (el.getP() <= -KnuthElement.INFINITE) {
log.debug("FORCED break encountered!");
forcedBreaks[i] = true;
--- /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 tables, especially headers and footers. Focus is on respect for after
+ regions when headers and footers are used.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="3in">
+ <fo:region-body margin-top="0.5in" margin-bottom="0.5in"/>
+ <fo:region-before extent="0.5in" background-color="lightgray"/>
+ <fo:region-after extent="0.5in" background-color="lightgray"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal" white-space-collapse="true">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-column/>
+ <fo:table-header color="red">
+ <fo:table-row>
+ <fo:table-cell id="outer-header">
+ <fo:block>Outer header</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-header>
+ <fo:table-footer color="red">
+ <fo:table-row>
+ <fo:table-cell id="outer-footer">
+ <fo:block>Outer footer</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-footer>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell id="outer-table-cell">
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-column/>
+ <fo:table-header color="orange">
+ <fo:table-row>
+ <fo:table-cell id="inner-header">
+ <fo:block>Inner header</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-header>
+ <fo:table-footer color="orange">
+ <fo:table-row>
+ <fo:table-cell id="inner-footer">
+ <fo:block>Inner footer</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-footer>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>content content content</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>content content content</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>content content content</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>content content content</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>content content content</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>content content content</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>content content content</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>content content content</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>content content content</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>content content content</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>content content content</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <element-list category="breaker">
+ <box w="14400"/>
+ <penalty w="57600" p="0"/> <!-- outer and inner header/footer = 4 * 14400 = 57600 -->
+ <box w="14400"/>
+ <penalty w="57600" p="0"/>
+ <box w="14400"/>
+ <penalty w="57600" p="0"/>
+ <box w="14400"/>
+ <penalty w="57600" p="0"/>
+ <box w="14400"/>
+ <penalty w="57600" p="0"/>
+ <box w="14400"/>
+ <penalty w="57600" p="0"/>
+ <box w="14400"/>
+ <penalty w="57600" p="0"/>
+ <box w="14400"/>
+ <penalty w="57600" p="0"/>
+ <box w="14400"/>
+ <penalty w="57600" p="0"/>
+ <box w="14400"/>
+ <penalty w="57600" p="0"/>
+ <box w="43200"/> <!-- including nested header/footer -->
+ <box w="14400"/> <!--header-->
+ <box w="14400"/> <!--footer-->
+ <skip>3</skip>
+ </element-list>
+
+ <!-- top-offset of outer table-cell on first page -->
+ <eval expected="14400" xpath="//pageViewport[@nr=1]//flow/block[1]/block[2]/@top-offset"/>
+ <!-- last row in nested table on first page -->
+ <eval expected="86400" xpath="//pageViewport[@nr=1]//flow/block[1]/block[2]/block[1]/block[7]/@top-offset"/>
+ <!-- top-offset of footer of nested tableon first page -->
+ <eval expected="100800" xpath="//pageViewport[@nr=1]//flow/block[1]/block[2]/block[1]/block[8]/@top-offset"/>
+ <!-- top-offset of outer footer on first page -->
+ <eval expected="129600" xpath="//pageViewport[@nr=1]//flow/block[1]/block[3]/@top-offset"/>
+
+ <!-- content lengths of both pages -->
+ <eval expected="144000" xpath="//pageViewport[@nr=1]//flow/@bpd"/>
+ <eval expected="129600" xpath="//pageViewport[@nr=2]//flow/@bpd"/>
+ </checks>
+</testcase>