Browse Source

Bugfix: Nested tables with headers and footers were not handled correctly and could overlap with the region-after.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@453900 13f79535-47bb-0310-9956-ffa450edef68
pull/25/head
Jeremias Maerki 17 years ago
parent
commit
2702903a69

+ 11
- 0
src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java View File

@@ -619,6 +619,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
List positions = new java.util.ArrayList();
List headerElements = null;
List footerElements = null;
int nestedPenaltyArea = 0;
Position firstPos = null;
Position lastPos = null;
Position lastCheckPos = null;
@@ -668,6 +669,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
if (penaltyPos.footerElements != null) {
footerElements = penaltyPos.footerElements;
}
nestedPenaltyArea = penaltyPos.nestedPenaltyLength;
}

Map markers = getTableLM().getTable().getMarkers();
@@ -689,6 +691,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
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);
@@ -792,6 +795,10 @@ public class TableContentLayoutManager implements PercentBaseContext {
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);
@@ -1208,6 +1215,8 @@ public class TableContentLayoutManager implements PercentBaseContext {
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
@@ -1225,6 +1234,8 @@ public class TableContentLayoutManager implements PercentBaseContext {
sb.append(headerElements);
sb.append(", footer:");
sb.append(footerElements);
sb.append(", inner penalty length:");
sb.append(nestedPenaltyLength);
sb.append(")");
return sb.toString();
}

+ 22
- 6
src/java/org/apache/fop/layoutmgr/table/TableStepper.java View File

@@ -65,6 +65,7 @@ public class TableStepper {
private boolean skippedStep;
private boolean[] keepWithNextSignals;
private boolean[] forcedBreaks;
private int lastMaxPenalty;
/**
* Main constructor
@@ -261,7 +262,7 @@ public class TableStepper {
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++) {
@@ -328,6 +329,18 @@ public class TableStepper {
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;
@@ -359,13 +372,14 @@ public class TableStepper {
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) {
@@ -388,6 +402,7 @@ public class TableStepper {
}
private int getNextStep(int lastStep) {
this.lastMaxPenalty = 0;
//Check for forced break conditions
/*
if (isBreakCondition()) {
@@ -452,6 +467,7 @@ public class TableStepper {
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;

+ 4
- 0
status.xml View File

@@ -28,6 +28,10 @@

<changes>
<release version="FOP Trunk">
<action context="Code" dev="JM" type="fix">
Bugfix: Nested tables with headers and footers were not handled correctly and could
overlap with the region-after.
</action>
<action context="Code" dev="JM" type="add" fixes-bug="40519" due-to="Oliver Hernàndez Valls">
Added support for CCITT compression in the TIFFRenderer by switching to the ImageWriter
abstraction from XML Graphics Commons.

+ 179
- 0
test/layoutengine/standard-testcases/table-header_table-footer_4.xml View File

@@ -0,0 +1,179 @@
<?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>

Loading…
Cancel
Save