#59056 - Render individual slideshow shapes

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1732974 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2016-02-29 23:59:49 +00:00
parent e5baa15b25
commit 261ef4934c
6 changed files with 88 additions and 6 deletions

View File

@ -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,6 +170,40 @@ 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.

View File

@ -17,6 +17,7 @@
package org.apache.poi.sl.usermodel;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
public interface Shape<
@ -37,4 +38,13 @@ public interface Shape<
* @return the anchor of this shape
*/
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);
}

View File

@ -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<XSLFShape,XSLFTextParagraph> {
}
return (fillProps == null) ? null : selectPaint(fillProps, phClr, theme.getPackagePart());
}
@Override
public void draw(Graphics2D graphics, Rectangle2D bounds) {
DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds);
}
}

View File

@ -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<HSLFShape,HSLFTextParagraph> {
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() {

View File

@ -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;
@ -880,6 +884,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);
return (HSLFSlideShow)SlideShowFactory.create(sample);

View File

@ -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();
}