diff --git a/src/java/org/apache/poi/sl/draw/DrawFactory.java b/src/java/org/apache/poi/sl/draw/DrawFactory.java index a7edeafbb..d0584dadb 100644 --- a/src/java/org/apache/poi/sl/draw/DrawFactory.java +++ b/src/java/org/apache/poi/sl/draw/DrawFactory.java @@ -19,6 +19,8 @@ package org.apache.poi.sl.draw; import java.awt.Graphics2D; import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; import java.text.AttributedString; import java.util.HashMap; import java.util.Map; @@ -168,7 +170,41 @@ public class DrawFactory { return new DrawPaint(shape); } + /** + * Convenience method for drawing single shapes. + * For drawing whole slides, use {@link Slide#draw(Graphics2D)} + * + * @param graphics the graphics context to draw to + * @param shape the shape + * @param bounds the bounds within the graphics context to draw to + */ + public void drawShape(Graphics2D graphics, Shape shape, Rectangle2D bounds) { + Rectangle2D shapeBounds = shape.getAnchor(); + if (shapeBounds.isEmpty() || (bounds != null && bounds.isEmpty())) { + return; + } + AffineTransform txg = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM); + AffineTransform tx = new AffineTransform(); + try { + if (bounds != null) { + double scaleX = bounds.getWidth()/shapeBounds.getWidth(); + double scaleY = bounds.getHeight()/shapeBounds.getHeight(); + tx.translate(bounds.getCenterX(), bounds.getCenterY()); + tx.scale(scaleX, scaleY); + tx.translate(-shapeBounds.getCenterX(), -shapeBounds.getCenterY()); + } + graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, tx); + + Drawable d = getDrawable(shape); + d.applyTransform(graphics); + d.draw(graphics); + } finally { + graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, txg); + } + } + + /** * Replace font families for Windows JVM 6, which contains a font rendering error. * This is likely to be removed, when POI upgrades to JDK 7 diff --git a/src/java/org/apache/poi/sl/usermodel/Shape.java b/src/java/org/apache/poi/sl/usermodel/Shape.java index 4d053df6f..0115f8b9a 100644 --- a/src/java/org/apache/poi/sl/usermodel/Shape.java +++ b/src/java/org/apache/poi/sl/usermodel/Shape.java @@ -17,6 +17,7 @@ package org.apache.poi.sl.usermodel; +import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; public interface Shape< @@ -24,17 +25,26 @@ public interface Shape< P extends TextParagraph > { ShapeContainer getParent(); - + /** * @return the sheet this shape belongs to */ Sheet getSheet(); - + /** * Returns the anchor (the bounding box rectangle) of this shape. * All coordinates are expressed in points (72 dpi). * * @return the anchor of this shape */ - Rectangle2D getAnchor(); + Rectangle2D getAnchor(); + + /** + * Convenience method to draw a single shape + * + * @param graphics the graphics context + * @param bounds the rectangle to fit the shape to. + * if null, the bounds of the shape are used. + */ + void draw(Graphics2D graphics, Rectangle2D bounds); } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java index b9f98c3a8..29ca2e654 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java @@ -19,6 +19,8 @@ package org.apache.poi.xslf.usermodel; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; @@ -27,6 +29,7 @@ import java.util.Comparator; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.poi.sl.draw.DrawFactory; import org.apache.poi.sl.draw.DrawPaint; import org.apache.poi.sl.usermodel.ColorStyle; import org.apache.poi.sl.usermodel.PaintStyle; @@ -537,4 +540,9 @@ public abstract class XSLFShape implements Shape { } return (fillProps == null) ? null : selectPaint(fillProps, phClr, theme.getPackagePart()); } + + @Override + public void draw(Graphics2D graphics, Rectangle2D bounds) { + DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds); + } } \ No newline at end of file diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java index 12f781ee4..ff53b5075 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java @@ -38,6 +38,7 @@ import org.apache.poi.hslf.record.ColorSchemeAtom; import org.apache.poi.hslf.record.HSLFEscherClientDataRecord; import org.apache.poi.hslf.record.Record; import org.apache.poi.hslf.record.RecordTypes; +import org.apache.poi.sl.draw.DrawFactory; import org.apache.poi.sl.usermodel.FillStyle; import org.apache.poi.sl.usermodel.Shape; import org.apache.poi.sl.usermodel.ShapeContainer; @@ -447,8 +448,9 @@ public abstract class HSLFShape implements Shape { return getFill().getFillStyle(); } - public void draw(Graphics2D graphics){ - logger.log(POILogger.INFO, "Rendering " + getShapeName()); + @Override + public void draw(Graphics2D graphics, Rectangle2D bounds){ + DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds); } public AbstractEscherOptRecord getEscherOptRecord() { diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java index e3b2683e5..612c71481 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java @@ -24,6 +24,9 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -52,6 +55,7 @@ import org.apache.poi.hslf.record.SlideListWithText; import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; import org.apache.poi.hslf.record.TextHeaderAtom; import org.apache.poi.hssf.usermodel.DummyGraphics2d; +import org.apache.poi.sl.draw.DrawFactory; import org.apache.poi.sl.draw.DrawPaint; import org.apache.poi.sl.draw.DrawTextParagraph; import org.apache.poi.sl.usermodel.PaintStyle; @@ -879,6 +883,26 @@ public final class TestBugs { ppt.close(); } + + @Test + public void bug59056() throws IOException { + HSLFSlideShow ppt = open("54541_cropped_bitmap.ppt"); + + for (HSLFShape shape : ppt.getSlides().get(0).getShapes()) { + BufferedImage img = new BufferedImage(500, 300, BufferedImage.TYPE_INT_ARGB); + Graphics2D graphics = img.createGraphics(); + Rectangle2D box = new Rectangle2D.Double(50,50,300,100); + graphics.setPaint(Color.red); + graphics.fill(box); + box = new Rectangle2D.Double(box.getX()+1,box.getY()+1,box.getWidth()-2,box.getHeight()-2); + DrawFactory.getInstance(graphics).drawShape(graphics, shape, box); + graphics.dispose(); + // ImageIO.write(img, "png", new File("bla"+shape.getShapeId()+".png")); + } + + ppt.close(); + + } private static HSLFSlideShow open(String fileName) throws IOException { File sample = HSLFTestDataSamples.getSampleFile(fileName); diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java index 08d6c6421..7a7a7b452 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java @@ -27,6 +27,7 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Rectangle; +import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.File; @@ -106,13 +107,14 @@ public final class TestPicture { HSLFPictureData pd = HSLFPictureData.create(PictureType.PNG); HSLFPictureShape pict = new HSLFPictureShape(pd); //index to non-existing picture data + pict.setAnchor(new Rectangle2D.Double(50,50,100,100)); pict.setSheet(slide); HSLFPictureData data = pict.getPictureData(); assertNull(data); BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = img.createGraphics(); - pict.draw(graphics); + pict.draw(graphics, null); ppt.close(); }