diff --git a/thirdparties-extension/fr.opensagres.odfdom.converter.pdf.openpdf/src/main/java/fr/opensagres/odfdom/converter/pdf/internal/stylable/StylableTable.java b/thirdparties-extension/fr.opensagres.odfdom.converter.pdf.openpdf/src/main/java/fr/opensagres/odfdom/converter/pdf/internal/stylable/StylableTable.java index 88d3f321b..243145952 100644 --- a/thirdparties-extension/fr.opensagres.odfdom.converter.pdf.openpdf/src/main/java/fr/opensagres/odfdom/converter/pdf/internal/stylable/StylableTable.java +++ b/thirdparties-extension/fr.opensagres.odfdom.converter.pdf.openpdf/src/main/java/fr/opensagres/odfdom/converter/pdf/internal/stylable/StylableTable.java @@ -26,11 +26,14 @@ import com.lowagie.text.Element; +import com.lowagie.text.pdf.PdfPCell; import fr.opensagres.odfdom.converter.pdf.internal.styles.Style; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleTableProperties; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleTableRowProperties; import fr.opensagres.xdocreport.openpdf.extension.ExtendedPdfPTable; +import java.util.Arrays; + public class StylableTable extends ExtendedPdfPTable implements IStylableContainer @@ -45,6 +48,10 @@ public class StylableTable private boolean inTableRow; + // keeps an indication of how many rows are already occupied (by row- or col-spans from the rows above) + private int[] spansFromAbove; + private int spansFromAboveIdx; + private Style currentRowStyle; public StylableTable( StylableDocument ownerDocument, IStylableContainer parent, int numColumns ) @@ -57,6 +64,10 @@ public StylableTable( StylableDocument ownerDocument, IStylableContainer parent, super.setSplitLate( false ); this.ownerDocument = ownerDocument; this.parent = parent; + + this.spansFromAbove = new int[numColumns]; + Arrays.fill(spansFromAbove, 0); + this.spansFromAboveIdx = 0; } public Style getCurrentRowStyle() @@ -74,10 +85,43 @@ public void endTableHeaderRows() inTableHeaderRows = false; } + private void fitCellIntoSpansFromAbove(PdfPCell cell) { + int rowSpan = cell.getRowspan(); + int colSpan = cell.getColspan(); + + // skip all the cell places already spanned from above + while (spansFromAbove[spansFromAboveIdx] > 0){ + if (spansFromAboveIdx < getNumberOfColumns()) { + spansFromAbove[spansFromAboveIdx]--; + spansFromAboveIdx++; + } + if (spansFromAboveIdx >= getNumberOfColumns()) { + // we have no more place in the current row; finish it up, and start a new one + endTableRow(); + beginTableRow(currentRowStyle); + } + } + + for (int col = 0; col < colSpan; col++){ + if (spansFromAbove[spansFromAboveIdx] > 0){ + break; // this is an error situation. cell spans over a cell that already has been spanned from above + } + else { + spansFromAbove[spansFromAboveIdx] = rowSpan - 1; + } + spansFromAboveIdx++; + } + } + + private boolean reachedEndOfRow(){ + return spansFromAboveIdx == getNumberOfColumns(); + } + public void beginTableRow( Style currentRowStyle ) { // beginTableRow/addElement/endTableRow protects before too many/too less cells in a row than declared inTableRow = true; + spansFromAboveIdx = 0; this.currentRowStyle = currentRowStyle; if ( inTableHeaderRows ) { @@ -89,7 +133,7 @@ public void beginTableRow( Style currentRowStyle ) public void endTableRow() { // fill row with empty cells if necessary - while ( currentRowIdx != 0 ) + while ( ! reachedEndOfRow() ) { StylableTableCell cell = new StylableTableCell( ownerDocument, this ); if ( currentRowStyle != null ) @@ -107,9 +151,12 @@ public void addElement( Element element ) { if ( inTableRow ) { + if (element instanceof PdfPCell){ + fitCellIntoSpansFromAbove ((PdfPCell) element); + } super.addElement( element ); } - if ( currentRowIdx == 0 ) + if ( reachedEndOfRow() ) { // row fully filled, end row endTableRow(); diff --git a/thirdparties-extension/fr.opensagres.odfdom.converter.pdf.openpdf/src/test/java/org/odftoolkit/odfdom/converter/core/AbstractODFDOMConverterTest.java b/thirdparties-extension/fr.opensagres.odfdom.converter.pdf.openpdf/src/test/java/org/odftoolkit/odfdom/converter/core/AbstractODFDOMConverterTest.java index dfc5812bb..5f737d568 100644 --- a/thirdparties-extension/fr.opensagres.odfdom.converter.pdf.openpdf/src/test/java/org/odftoolkit/odfdom/converter/core/AbstractODFDOMConverterTest.java +++ b/thirdparties-extension/fr.opensagres.odfdom.converter.pdf.openpdf/src/test/java/org/odftoolkit/odfdom/converter/core/AbstractODFDOMConverterTest.java @@ -125,6 +125,13 @@ public void Issue377() { doGenerate( "Issue377.odt" ); } + + @Test + public void Issue682() + throws Exception + { + doGenerate( "Issue682.odt" ); + } @Test public void ODTBig() diff --git a/thirdparties-extension/fr.opensagres.odfdom.converter.pdf.openpdf/src/test/resources/org/odftoolkit/odfdom/converter/core/Issue682.odt b/thirdparties-extension/fr.opensagres.odfdom.converter.pdf.openpdf/src/test/resources/org/odftoolkit/odfdom/converter/core/Issue682.odt new file mode 100644 index 000000000..aec42193e Binary files /dev/null and b/thirdparties-extension/fr.opensagres.odfdom.converter.pdf.openpdf/src/test/resources/org/odftoolkit/odfdom/converter/core/Issue682.odt differ