Skip to content

Commit 8b87371

Browse files
committed
Do not change renderer's properties during table layout(). Add tests.
Use borders saved in bordersHandler. DEVSIX-1276
1 parent 5241f6f commit 8b87371

File tree

5 files changed

+76
-14
lines changed

5 files changed

+76
-14
lines changed

layout/src/main/java/com/itextpdf/layout/renderer/TableRenderer.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,6 @@ public LayoutResult layout(LayoutContext layoutContext) {
326326
bordersHandler.fixHeaderOccupiedArea(occupiedArea.getBBox(), layoutBox);
327327
}
328328

329-
330-
bordersHandler.setTableBoundingBorders(getBorders());
331329
topBorderMaxWidth = bordersHandler.getMaxTopWidth();
332330
bordersHandler.applyLeftAndRightTableBorder(layoutBox, false);
333331
// Table should have a row and some child elements in order to be considered non empty
@@ -474,8 +472,10 @@ public LayoutResult layout(LayoutContext layoutContext) {
474472
overflowRenderer.setProperty(Property.MARGIN_BOTTOM, 0);
475473
overflowRenderer.setProperty(Property.MARGIN_LEFT, 0);
476474
overflowRenderer.setProperty(Property.MARGIN_RIGHT, 0);
477-
overflowRenderer.deleteOwnProperty(Property.BORDER_BOTTOM);
478-
475+
// we've already applied the top table border on header
476+
if (null != headerRenderer) {
477+
overflowRenderer.setProperty(Property.BORDER_TOP, Border.NO_BORDER);
478+
}
479479
overflowRenderer.rowRange = new Table.RowRange(0, rows.size() - row - 1);
480480
overflowRenderer.bordersHandler = bordersHandler;
481481
// save old bordersHandler properties
@@ -572,8 +572,6 @@ public LayoutResult layout(LayoutContext layoutContext) {
572572
boolean skip = false;
573573
if (null != footerRenderer && tableModel.isComplete() && tableModel.isSkipLastFooter() && !split) {
574574
footerRenderer = null;
575-
// delete #layout() related properties
576-
deleteOwnProperty(Property.BORDER_BOTTOM);
577575
if (tableModel.isEmpty()) {
578576
this.deleteOwnProperty(Property.BORDER_TOP);
579577
}
@@ -596,6 +594,9 @@ public LayoutResult layout(LayoutContext layoutContext) {
596594
prepareFooterOrHeaderRendererForLayout(footerRenderer, layoutBox.getWidth());
597595

598596
bordersHandler.collapseTableWithFooter(footerRenderer.bordersHandler, hasContent || 0 != childRenderers.size());
597+
if (bordersHandler instanceof CollapsedTableBorders) {
598+
footerRenderer.setBorders(CollapsedTableBorders.getCollapsedBorder(footerRenderer.getBorders()[2], getBorders()[2]), 2);
599+
}
599600
footerRenderer.layout(new LayoutContext(new LayoutArea(area.getPageNumber(), layoutBox)));
600601
bordersHandler.applyLeftAndRightTableBorder(layoutBox, false);
601602
float footerHeight = footerRenderer.getOccupiedAreaBBox().getHeight();
@@ -873,7 +874,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
873874
// we should process incomplete table's footer only dureing splitting
874875
if (!tableModel.isComplete() && null != footerRenderer) {
875876
footerRenderer = null;
876-
bordersHandler.skipFooter(getBorders());
877+
bordersHandler.skipFooter(bordersHandler.tableBoundingBorders);
877878
}
878879
adjustFooterAndFixOccupiedArea(layoutBox);
879880
removeUnnecessaryFloatRendererAreas(floatRendererAreas);
@@ -1337,7 +1338,7 @@ protected void drawBorders(DrawContext drawContext, boolean hasHeader, boolean h
13371338

13381339
// process halves of the borders here
13391340
if (childRenderers.size() == 0) {
1340-
Border[] borders = this.getBorders();
1341+
Border[] borders = bordersHandler.tableBoundingBorders;
13411342
if (null != borders[0]) {
13421343
if (null != borders[2]) {
13431344
if (0 == heights.size()) {
@@ -1437,7 +1438,7 @@ private void applyFixedXOrYPosition(boolean isXPosition, Rectangle layoutBox) {
14371438
if (isFixedLayout()) {
14381439
if (isXPosition) {
14391440
float x = (float) this.getPropertyAsFloat(Property.X);
1440-
layoutBox.setX( x);
1441+
layoutBox.setX(x);
14411442
} else {
14421443
float y = (float) this.getPropertyAsFloat(Property.Y);
14431444
move(0, y - occupiedArea.getBBox().getY());
@@ -1471,7 +1472,8 @@ private void correctLayoutedCellsOccupiedAreas(LayoutResult[] splits, int row, i
14711472
bordersHandler.setFinishRow(finish);
14721473
if (skip) {
14731474
// Update bordersHandler
1474-
bordersHandler.skipFooter(getBorders());
1475+
bordersHandler.tableBoundingBorders[2] = getBorders()[2];
1476+
bordersHandler.skipFooter(bordersHandler.tableBoundingBorders);
14751477
}
14761478
float currentBottomIndent = null == currentBorder ? 0 : currentBorder.getWidth();
14771479
float realBottomIndent = bordersHandler.getMaxBottomWidth();
@@ -1603,20 +1605,18 @@ private TableRenderer initFooterOrHeaderRenderer(boolean footer, Border[] tableB
16031605
Border[] borders = renderer.getBorders();
16041606
if (table.isEmpty()) {
16051607
renderer.setBorders(CollapsedTableBorders.getCollapsedBorder(borders[innerBorder], tableBorders[innerBorder]), innerBorder);
1606-
setBorders(Border.NO_BORDER, innerBorder);
1608+
bordersHandler.tableBoundingBorders[innerBorder] = Border.NO_BORDER;
16071609
}
16081610
renderer.setBorders(CollapsedTableBorders.getCollapsedBorder(borders[1], tableBorders[1]), 1);
16091611
renderer.setBorders(CollapsedTableBorders.getCollapsedBorder(borders[3], tableBorders[3]), 3);
16101612
renderer.setBorders(CollapsedTableBorders.getCollapsedBorder(borders[outerBorder], tableBorders[outerBorder]), outerBorder);
1611-
setBorders(Border.NO_BORDER, outerBorder);
1613+
bordersHandler.tableBoundingBorders[outerBorder] = Border.NO_BORDER;
16121614

16131615
renderer.bordersHandler = new CollapsedTableBorders(renderer.rows, ((Table) renderer.getModelElement()).getNumberOfColumns(), renderer.getBorders());
16141616
renderer.bordersHandler.initializeBorders();
16151617
renderer.bordersHandler.setRowRange(renderer.rowRange.getStartRow(), renderer.rowRange.getFinishRow());
16161618
((CollapsedTableBorders) renderer.bordersHandler).collapseAllBordersAndEmptyRows();
16171619
renderer.correctRowRange();
1618-
// update bounding borders
1619-
bordersHandler.setTableBoundingBorders(getBorders());
16201620
return renderer;
16211621
}
16221622

layout/src/test/java/com/itextpdf/layout/KeepWithNextTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@ This file is part of the iText (R) project.
4848
import com.itextpdf.kernel.pdf.PdfDocument;
4949
import com.itextpdf.kernel.pdf.PdfWriter;
5050
import com.itextpdf.kernel.utils.CompareTool;
51+
import com.itextpdf.layout.border.SolidBorder;
5152
import com.itextpdf.layout.element.List;
5253
import com.itextpdf.layout.element.Paragraph;
54+
import com.itextpdf.layout.element.Table;
5355
import com.itextpdf.layout.property.ListNumberingType;
5456
import com.itextpdf.layout.property.Property;
5557
import com.itextpdf.test.ExtendedITextTest;
@@ -292,4 +294,27 @@ public void keepWithNextTest10() throws IOException, InterruptedException {
292294
Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff"));
293295
}
294296

297+
@Test
298+
public void keepWithNextTest11() throws IOException, InterruptedException {
299+
String outFileName = destinationFolder + "keepWithNextTest11.pdf";
300+
String cmpFileName = sourceFolder + "cmp_keepWithNextTest11.pdf";
301+
302+
PdfDocument pdf = new PdfDocument(new PdfWriter(outFileName));
303+
Document document = new Document(pdf);
304+
305+
Style style = new Style();
306+
style.setProperty(Property.KEEP_WITH_NEXT, true);
307+
document.add(new Paragraph("A").addStyle(style));
308+
309+
Table table = new Table(1)
310+
.setBorderTop(new SolidBorder(2))
311+
.setBorderBottom(new SolidBorder(2));
312+
table.addCell("Body").addHeaderCell("Header");
313+
314+
document.add(table);
315+
document.close();
316+
317+
Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff"));
318+
}
319+
295320
}

layout/src/test/java/com/itextpdf/layout/TableBorderTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ This file is part of the iText (R) project.
4545
import com.itextpdf.io.LogMessageConstant;
4646
import com.itextpdf.kernel.color.Color;
4747
import com.itextpdf.kernel.geom.PageSize;
48+
import com.itextpdf.kernel.geom.Rectangle;
4849
import com.itextpdf.kernel.pdf.PdfDocument;
4950
import com.itextpdf.kernel.pdf.PdfWriter;
5051
import com.itextpdf.kernel.utils.CompareTool;
@@ -55,8 +56,12 @@ This file is part of the iText (R) project.
5556
import com.itextpdf.layout.element.Cell;
5657
import com.itextpdf.layout.element.Paragraph;
5758
import com.itextpdf.layout.element.Table;
59+
import com.itextpdf.layout.layout.LayoutArea;
60+
import com.itextpdf.layout.layout.LayoutContext;
61+
import com.itextpdf.layout.layout.LayoutResult;
5862
import com.itextpdf.layout.property.Property;
5963
import com.itextpdf.layout.property.UnitValue;
64+
import com.itextpdf.layout.renderer.TableRenderer;
6065
import com.itextpdf.test.ExtendedITextTest;
6166
import com.itextpdf.test.annotations.LogMessage;
6267
import com.itextpdf.test.annotations.LogMessages;
@@ -1414,6 +1419,38 @@ public void tableWithHeaderFooterTest15() throws IOException, InterruptedExcepti
14141419
Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, testName + "_diff"));
14151420
}
14161421

1422+
@Test
1423+
public void tableWithHeaderFooterTest16() throws IOException, InterruptedException {
1424+
String testName = "tableWithHeaderFooterTest16.pdf";
1425+
String outFileName = destinationFolder + testName;
1426+
String cmpFileName = sourceFolder + "cmp_" + testName;
1427+
1428+
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
1429+
Document doc = new Document(pdfDoc);
1430+
1431+
Table table = new Table(1);
1432+
1433+
table.addHeaderCell(new Cell().add("Header 1").setBorderBottom(new SolidBorder(Color.RED, 25)).setBorderTop(new SolidBorder(Color.ORANGE, 27)));
1434+
table.getHeader().addHeaderCell("Header 2");
1435+
1436+
table.addCell(new Cell().add("Body 1").setBorderTop(new SolidBorder(Color.GREEN, 20)));
1437+
1438+
table.addFooterCell(new Cell().add("Footer 1").setBorderTop(new SolidBorder(Color.RED, 25)).setBorderBottom(new SolidBorder(Color.ORANGE, 27)));
1439+
table.getFooter().addFooterCell("Footer 2");
1440+
1441+
1442+
table.setBorderTop(new SolidBorder(Color.BLUE, 30)).setBorderBottom(new SolidBorder(Color.BLUE, 30));
1443+
table.getFooter().setBorderBottom(new SolidBorder(Color.YELLOW, 50));
1444+
table.getHeader().setBorderTop(new SolidBorder(Color.YELLOW, 50));
1445+
1446+
table.setBackgroundColor(Color.MAGENTA);
1447+
1448+
doc.add(table);
1449+
1450+
doc.close();
1451+
Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, testName + "_diff"));
1452+
}
1453+
14171454
@Test
14181455
@LogMessages(messages = {
14191456
@LogMessage(messageTemplate = LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, count = 2)

0 commit comments

Comments
 (0)