diff --git a/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java b/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java index cd6b601642..ba2e1bc617 100644 --- a/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java +++ b/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java @@ -59,7 +59,8 @@ public class HPSFFileHandler extends POIFSFileHandler { ); static final Set EXCLUDES_HANDLE_FILE = unmodifiableHashSet( - "hpsf/Test_Humor-Generation.ppt" + "hpsf/Test_Humor-Generation.ppt", + "slideshow/missing-moveto.ppt" // POIFS properties corrupted ); diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java index 10757fbe02..bf6f56581e 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java @@ -47,7 +47,7 @@ public class TestPPTX2PNG { private static final String files = "53446.ppt, alterman_security.ppt, alterman_security.pptx, KEY02.pptx, themes.pptx, " + "backgrounds.pptx, layouts.pptx, sample.pptx, shapes.pptx, 54880_chinese.ppt, keyframes.pptx," + - "customGeo.pptx, customGeo.ppt, wrench.emf, santa.wmf"; + "customGeo.pptx, customGeo.ppt, wrench.emf, santa.wmf, missing-moveto.ppt"; @BeforeClass public static void checkHslf() { diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java index 3b57ccb3b8..206bb1641b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java @@ -17,6 +17,9 @@ package org.apache.poi.hslf.usermodel; +import static org.apache.poi.hslf.usermodel.HSLFFreeformShape.ShapePath.CURVES_CLOSED; +import static org.apache.poi.hslf.usermodel.HSLFFreeformShape.ShapePath.LINES_CLOSED; + import java.awt.geom.Arc2D; import java.awt.geom.Path2D; import java.awt.geom.Point2D; @@ -69,22 +72,10 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape moveLst = pathCT.getCloseOrMoveToOrLnTo(); pathLst.getPath().add(pathCT); cusGeo.setPathLst(pathLst); @@ -262,46 +252,23 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape mLst = m.getPt(); - - int[] pts = new int[6]; - - for (int i=0; vertIter.hasNext() && i<3; i++) { - mLst.add(fillPoint(vertIter.next(), xyPoints)); - pts[i*2] = xyPoints[0]; - pts[i*2+1] = xyPoints[1]; - if (i == 2) { - moveLst.add(m); - path2D.curveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]); - } - } + case curveTo: + handleCurveTo(vertIter, xyPoints, moveLst, path2D); break; - } case close: - moveLst.add(of.createCTPath2DClose()); - path2D.closePath(); + if (path2D.getCurrentPoint() != null) { + moveLst.add(OF.createCTPath2DClose()); + path2D.closePath(); + } isClosed = true; break; default: @@ -309,28 +276,11 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape vertIter) { - final ObjectFactory of = new ObjectFactory(); + private static Rectangle2D getBounds(AbstractEscherOptRecord opt, Path2D path2D) { + EscherSimpleProperty geoLeft = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__LEFT); + EscherSimpleProperty geoRight = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__RIGHT); + EscherSimpleProperty geoTop = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__TOP); + EscherSimpleProperty geoBottom = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__BOTTOM); + + if (geoLeft != null && geoRight != null && geoTop != null && geoBottom != null) { + final Rectangle2D bounds = new Rectangle2D.Double(); + bounds.setFrameFromDiagonal( + new Point2D.Double(geoLeft.getPropertyValue(), geoTop.getPropertyValue()), + new Point2D.Double(geoRight.getPropertyValue(), geoBottom.getPropertyValue()) + ); + return bounds; + } else { + return path2D.getBounds2D(); + } + } + + private static void handleClosedShape(AbstractEscherOptRecord opt, List moveLst, Path2D path2D) { + EscherSimpleProperty shapePath = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__SHAPEPATH); + HSLFFreeformShape.ShapePath sp = HSLFFreeformShape.ShapePath.valueOf(shapePath == null ? 1 : shapePath.getPropertyValue()); + if (sp == LINES_CLOSED || sp == CURVES_CLOSED) { + moveLst.add(OF.createCTPath2DClose()); + path2D.closePath(); + } + } + + private static void handleMoveTo(Iterator vertIter, int[] xyPoints, List moveLst, Path2D path2D) { + if (!vertIter.hasNext()) { + return; + } + final CTPath2DMoveTo m = OF.createCTPath2DMoveTo(); + m.setPt(fillPoint(vertIter.next(), xyPoints)); + moveLst.add(m); + path2D.moveTo(xyPoints[0], xyPoints[1]); + } + + private static void handleLineTo(Iterator vertIter, int[] xyPoints, List moveLst, Path2D path2D) { + if (!vertIter.hasNext()) { + return; + } + handleMoveTo0(moveLst, path2D); + + final CTPath2DLineTo m = OF.createCTPath2DLineTo(); + m.setPt(fillPoint(vertIter.next(), xyPoints)); + moveLst.add(m); + path2D.lineTo(xyPoints[0], xyPoints[1]); + } + + private static void handleCurveTo(Iterator vertIter, int[] xyPoints, List moveLst, Path2D path2D) { + if (!vertIter.hasNext()) { + return; + } + handleMoveTo0(moveLst, path2D); + + final CTPath2DCubicBezierTo m = OF.createCTPath2DCubicBezierTo(); + List mLst = m.getPt(); + + int[] pts = new int[6]; + + for (int i=0; vertIter.hasNext() && i<3; i++) { + mLst.add(fillPoint(vertIter.next(), xyPoints)); + pts[i*2] = xyPoints[0]; + pts[i*2+1] = xyPoints[1]; + if (i == 2) { + moveLst.add(m); + path2D.curveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]); + } + } + } + + /** + * Sometimes the path2D is not initialized - this initializes it with the 0,0 position + */ + private static void handleMoveTo0(List moveLst, Path2D path2D) { + if (path2D.getCurrentPoint() == null) { + final CTPath2DMoveTo m = OF.createCTPath2DMoveTo(); + + CTAdjPoint2D pt = OF.createCTAdjPoint2D(); + pt.setX("0"); + pt.setY("0"); + m.setPt(pt); + moveLst.add(m); + path2D.moveTo(0, 0); + } + } + + private static void handleEscapeInfo(CTPath2D pathCT, Path2D path2D, byte[] segElem, Iterator vertIter) { HSLFFreeformShape.EscapeInfo ei = getEscapeInfo(segElem); if (ei == null) { return; @@ -376,7 +412,7 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape