diff options
5 files changed, 138 insertions, 19 deletions
diff --git a/src/java/org/apache/poi/sl/draw/DrawPaint.java b/src/java/org/apache/poi/sl/draw/DrawPaint.java index 80c5bcb00b..4fda618d0e 100644 --- a/src/java/org/apache/poi/sl/draw/DrawPaint.java +++ b/src/java/org/apache/poi/sl/draw/DrawPaint.java @@ -143,7 +143,7 @@ public class DrawPaint { public Paint getPaint(Graphics2D graphics, PaintStyle paint, PaintModifier modifier) { if (modifier == PaintModifier.NONE) { - return null; + return TRANSPARENT; } if (paint instanceof SolidPaint) { return getSolidPaint((SolidPaint)paint, graphics, modifier); @@ -152,7 +152,7 @@ public class DrawPaint { } else if (paint instanceof TexturePaint) { return getTexturePaint((TexturePaint)paint, graphics); } - return null; + return TRANSPARENT; } @SuppressWarnings({"WeakerAccess", "unused"}) @@ -236,7 +236,7 @@ public class DrawPaint { protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) { InputStream is = fill.getImageData(); if (is == null) { - return null; + return TRANSPARENT; } assert(graphics != null); @@ -250,7 +250,7 @@ public class DrawPaint { } } catch (IOException e) { LOG.log(POILogger.ERROR, "Can't load image data - using transparent color", e); - return null; + return TRANSPARENT; } int alpha = fill.getAlpha(); @@ -270,7 +270,7 @@ public class DrawPaint { if(image == null) { LOG.log(POILogger.ERROR, "Can't load image data"); - return null; + return TRANSPARENT; } return new java.awt.TexturePaint(image, textAnchor); diff --git a/src/java/org/apache/poi/sl/draw/DrawShape.java b/src/java/org/apache/poi/sl/draw/DrawShape.java index df5960b538..0c6054c8a9 100644 --- a/src/java/org/apache/poi/sl/draw/DrawShape.java +++ b/src/java/org/apache/poi/sl/draw/DrawShape.java @@ -121,7 +121,10 @@ public class DrawShape implements Drawable { } public static Rectangle2D getAnchor(Graphics2D graphics, PlaceableShape<?,?> shape) { -// return getAnchor(graphics, shape.getAnchor()); + final Rectangle2D shapeAnchor = shape.getAnchor(); + if (shapeAnchor == null) { + return null; + } final boolean isHSLF = isHSLF(shape); AffineTransform tx = graphics == null ? null : (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM); @@ -146,7 +149,6 @@ public class DrawShape implements Drawable { // and later on, turn it around again to compare it with its original size ... - final Rectangle2D shapeAnchor = shape.getAnchor(); final Rectangle2D anchorO = tx.createTransformedShape(shapeAnchor).getBounds2D(); final Rectangle2D anchorT; @@ -190,7 +192,7 @@ public class DrawShape implements Drawable { normalizedShape = txs2.createTransformedShape(shapeAnchor).getBounds2D(); } } else { - normalizedShape = shape.getAnchor(); + normalizedShape = shapeAnchor; } if (tx.isIdentity()) { diff --git a/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java b/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java index a8d6fb534e..eacc6ed806 100644 --- a/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java +++ b/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java @@ -69,6 +69,10 @@ public class DrawSimpleShape extends DrawShape { @Override public void draw(Graphics2D graphics) { + if (getAnchor(graphics, getShape()) == null) { + return; + } + DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(getShape()); Paint fill = drawPaint.getPaint(graphics, getShape().getFillStyle().getPaint()); Paint line = drawPaint.getPaint(graphics, getShape().getStrokeStyle().getPaint()); diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java index c8624f071a..5266c13c09 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java @@ -159,6 +159,16 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow return row; } + /** + * Remove the row on the given index + * @param rowIdx the row index + */ + public void removeRow(int rowIdx) { + _table.removeTr(rowIdx); + _rows.remove(rowIdx); + updateRowColIndexes(); + } + static CTGraphicalObjectFrame prototype(int shapeId){ CTGraphicalObjectFrame frame = CTGraphicalObjectFrame.Factory.newInstance(); CTGraphicalObjectFrameNonVisual nvGr = frame.addNewNvGraphicFramePr(); @@ -275,12 +285,15 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow } } - /* package */ void updateCellAnchor() { + /** + * Calculates the bounding boxes of all cells and updates the dimension of the table + */ + public void updateCellAnchor() { int rows = getNumberOfRows(); int cols = getNumberOfColumns(); - double colWidths[] = new double[cols]; - double rowHeights[] = new double[rows]; + double[] colWidths = new double[cols]; + double[] rowHeights = new double[rows]; for (int row=0; row<rows; row++) { rowHeights[row] = getRowHeight(row); @@ -292,7 +305,8 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow Rectangle2D tblAnc = getAnchor(); DrawFactory df = DrawFactory.getInstance(null); - double newY = tblAnc.getY(); + double nextY = tblAnc.getY(); + double nextX = tblAnc.getX(); // #1 pass - determine row heights, the height values might be too low or 0 ... for (int row=0; row<rows; row++) { @@ -312,16 +326,16 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow // #2 pass - init properties for (int row=0; row<rows; row++) { - double newX = tblAnc.getX(); + nextX = tblAnc.getX(); for (int col=0; col<cols; col++) { - Rectangle2D bounds = new Rectangle2D.Double(newX, newY, colWidths[col], rowHeights[row]); + Rectangle2D bounds = new Rectangle2D.Double(nextX, nextY, colWidths[col], rowHeights[row]); XSLFTableCell tc = getCell(row, col); if (tc != null) { tc.setAnchor(bounds); - newX += colWidths[col]+DrawTableShape.borderSize; + nextX += colWidths[col]+DrawTableShape.borderSize; } } - newY += rowHeights[row]+DrawTableShape.borderSize; + nextY += rowHeights[row]+DrawTableShape.borderSize; } // #3 pass - update merge info @@ -347,6 +361,9 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow tc.setAnchor(mergedBounds); } } - + + setAnchor(new Rectangle2D.Double(tblAnc.getX(),tblAnc.getY(), + nextX-tblAnc.getX(), + nextY-tblAnc.getY())); } } diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java index 1df72597d5..498f302dec 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java @@ -26,22 +26,118 @@ import static org.junit.Assert.assertTrue; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; -import java.awt.RenderingHints; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.util.List; +import java.util.Random; -import org.apache.poi.sl.draw.DrawFactory; +import org.apache.poi.sl.usermodel.ShapeType; import org.apache.poi.sl.usermodel.Slide; +import org.apache.poi.sl.usermodel.StrokeStyle; import org.apache.poi.sl.usermodel.TableCell.BorderEdge; import org.apache.poi.sl.usermodel.VerticalAlignment; +import org.apache.poi.util.TempFile; import org.apache.poi.xslf.XSLFTestDataSamples; +import org.apache.poi.xslf.util.PPTX2PNG; import org.junit.Test; import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell; import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; public class TestXSLFTable { + + @Test + public void testResize() throws Exception { + String[][] data = getDummyData(20); + final int maxHeight = 400; + + XMLSlideShow ppt = new XMLSlideShow(); + int rowIdx=1; + while (rowIdx<data.length) { + XSLFSlide slide = ppt.createSlide(); + // a red bordered box in the background, to show/verify the table dimensions + XSLFAutoShape as = slide.createAutoShape(); + as.setShapeType(ShapeType.RECT); + as.setStrokeStyle(Color.RED, 2., StrokeStyle.LineDash.LG_DASH); + + XSLFTable tab = slide.createTable(1, data[0].length); + tab.setAnchor(new Rectangle2D.Double(50,50,0,0)); + tab.setColumnWidth(0, 60); + tab.setColumnWidth(1, 60); + tab.setColumnWidth(2, 60); + + int startRow = rowIdx; + + XSLFTableRow row = tab.getRows().get(0); + for (int colIdx=0; colIdx<data[0].length; colIdx++) { + XSLFTextRun tr = row.getCells().get(colIdx).setText(data[0][colIdx]); + tr.setFontSize(20.); + tr.setFontFamily("Arial"); + } + + + while (rowIdx<data.length) { + row = tab.addRow(); + for (int col=0; col<data[rowIdx].length; col++) { + XSLFTextRun tr = row.addCell().setText(data[rowIdx][col]); + tr.setFontSize(15.); + tr.setFontFamily("Arial"); + } + tab.updateCellAnchor(); + if (tab.getAnchor().getHeight() > maxHeight) { + tab.removeRow(rowIdx-startRow); + break; + } + rowIdx++; + } + + tab.updateCellAnchor(); + as.setAnchor(tab.getAnchor()); + } + + File fileOut = TempFile.createTempFile("tabtest", "pptx"); + try (FileOutputStream fos = new FileOutputStream(fileOut)) { + ppt.write(fos); + } + + String[] args = { + "-format", "null", // png,gif,jpg or null for test + "-slide", "-1", // -1 for all + "-outdir", fileOut.getParentFile().getCanonicalPath(), + "-quiet", + fileOut.getAbsolutePath() + }; + PPTX2PNG.main(args); + } + + private static String[][] getDummyData(int rows) { + String[] header = { "Row#", "ID", "Name", "Description", "Price", "Percent", "Current Value" }; + String[][] data = new String[rows+1][header.length]; + System.arraycopy(header, 0, data[0], 0, header.length); + + String[] names = { "car", "rubber duckie", "phone", "gadget" }; + String[] desc = { "new", "used", "untouched" }; + + Random r = new Random(); + + for (int row=1; row<=rows; row++) { + String[] line = new String[header.length]; + line[0] = Integer.toString(row); + line[1] = Integer.toString(r.nextInt(1000)); + line[2] = names[r.nextInt(names.length)]; + line[3] = "The "+desc[r.nextInt(desc.length)]+" "+line[2]+" in "+(2017+row); + line[4] = "$"+r.nextInt(50000); + line[5] = r.nextInt(100)+"%"; + line[6] = "$"+r.nextInt(50000); + System.arraycopy(line, 0, data[row], 0, header.length); + } + + return data; + } + + @Test public void testRead() throws IOException { XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); |