aboutsummaryrefslogtreecommitdiffstats
path: root/src/scratchpad
diff options
context:
space:
mode:
authorAndreas Beeker <kiwiwings@apache.org>2020-02-02 22:53:09 +0000
committerAndreas Beeker <kiwiwings@apache.org>2020-02-02 22:53:09 +0000
commit33fd0b22d6515bd9ec3a1ad6bf738089a0bc86b7 (patch)
tree9053465e126eff533b1a8934d0b4513fa7f40a70 /src/scratchpad
parentd20e85387e8c48d70249f5349f796a7cc4db8199 (diff)
downloadpoi-33fd0b22d6515bd9ec3a1ad6bf738089a0bc86b7.tar.gz
poi-33fd0b22d6515bd9ec3a1ad6bf738089a0bc86b7.zip
Regression findings - fix missing moveto exception
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1873515 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/scratchpad')
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java178
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java14
2 files changed, 114 insertions, 78 deletions
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<HSLFShape,
static final byte[] SEGMENTINFO_CLOSE = new byte[]{0x01, (byte)0x60};
static final byte[] SEGMENTINFO_END = new byte[]{0x00, (byte)0x80};
+ private static final ObjectFactory OF = new ObjectFactory();
private static final BitField PATH_INFO = BitFieldFactory.getInstance(0xE000);
private static final BitField ESCAPE_INFO = BitFieldFactory.getInstance(0x1F00);
- private static final EscherPropertyTypes[] ADJUST_VALUES = {
- EscherPropertyTypes.GEOMETRY__ADJUSTVALUE,
- EscherPropertyTypes.GEOMETRY__ADJUST2VALUE,
- EscherPropertyTypes.GEOMETRY__ADJUST3VALUE,
- EscherPropertyTypes.GEOMETRY__ADJUST4VALUE,
- EscherPropertyTypes.GEOMETRY__ADJUST5VALUE,
- EscherPropertyTypes.GEOMETRY__ADJUST6VALUE,
- EscherPropertyTypes.GEOMETRY__ADJUST7VALUE,
- EscherPropertyTypes.GEOMETRY__ADJUST8VALUE,
- EscherPropertyTypes.GEOMETRY__ADJUST9VALUE,
- EscherPropertyTypes.GEOMETRY__ADJUST10VALUE
- };
-
enum PathInfo {
lineTo(0),curveTo(1),moveTo(2),close(3),end(4),escape(5),clientEscape(6);
private final int flag;
@@ -220,12 +211,11 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape<HSLFShape,
}
CustomGeometry getGeometry(Path2D path2D) {
- final ObjectFactory of = new ObjectFactory();
- final CTCustomGeometry2D cusGeo = of.createCTCustomGeometry2D();
- cusGeo.setAvLst(of.createCTGeomGuideList());
- cusGeo.setGdLst(of.createCTGeomGuideList());
- cusGeo.setAhLst(of.createCTAdjustHandleList());
- cusGeo.setCxnLst(of.createCTConnectionSiteList());
+ final CTCustomGeometry2D cusGeo = OF.createCTCustomGeometry2D();
+ cusGeo.setAvLst(OF.createCTGeomGuideList());
+ cusGeo.setGdLst(OF.createCTGeomGuideList());
+ cusGeo.setAhLst(OF.createCTAdjustHandleList());
+ cusGeo.setCxnLst(OF.createCTConnectionSiteList());
final AbstractEscherOptRecord opt = getEscherOptRecord();
@@ -249,8 +239,8 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape<HSLFShape,
final int[] xyPoints = new int[2];
boolean isClosed = false;
- final CTPath2DList pathLst = of.createCTPath2DList();
- final CTPath2D pathCT = of.createCTPath2D();
+ final CTPath2DList pathLst = OF.createCTPath2DList();
+ final CTPath2D pathCT = OF.createCTPath2D();
final List<Object> moveLst = pathCT.getCloseOrMoveToOrLnTo();
pathLst.getPath().add(pathCT);
cusGeo.setPathLst(pathLst);
@@ -262,46 +252,23 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape<HSLFShape,
continue;
}
switch (pi) {
- case escape: {
+ case escape:
handleEscapeInfo(pathCT, path2D, segElem, vertIter);
break;
- }
case moveTo:
- if (vertIter.hasNext()) {
- final CTPath2DMoveTo m = of.createCTPath2DMoveTo();
- m.setPt(fillPoint(vertIter.next(), xyPoints));
- moveLst.add(m);
- path2D.moveTo(xyPoints[0], xyPoints[1]);
- }
+ handleMoveTo(vertIter, xyPoints, moveLst, path2D);
break;
case lineTo:
- if (vertIter.hasNext()) {
- final CTPath2DLineTo m = of.createCTPath2DLineTo();
- m.setPt(fillPoint(vertIter.next(), xyPoints));
- moveLst.add(m);
- path2D.lineTo(xyPoints[0], xyPoints[1]);
- }
+ handleLineTo(vertIter, xyPoints, moveLst, path2D);
break;
- case curveTo: {
- final CTPath2DCubicBezierTo m = of.createCTPath2DCubicBezierTo();
- List<CTAdjPoint2D> 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,37 +276,106 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape<HSLFShape,
}
}
- EscherSimpleProperty shapePath = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__SHAPEPATH);
- HSLFFreeformShape.ShapePath sp = HSLFFreeformShape.ShapePath.valueOf(shapePath == null ? 1 : shapePath.getPropertyValue());
- if ((sp == HSLFFreeformShape.ShapePath.LINES_CLOSED || sp == HSLFFreeformShape.ShapePath.CURVES_CLOSED) && !isClosed) {
- moveLst.add(of.createCTPath2DClose());
- path2D.closePath();
+ if (!isClosed) {
+ handleClosedShape(opt, moveLst, path2D);
}
+ final Rectangle2D bounds = getBounds(opt, path2D);
+
+ pathCT.setW((int)Math.rint(bounds.getWidth()));
+ pathCT.setH((int)Math.rint(bounds.getHeight()));
+
+ return new CustomGeometry(cusGeo);
+ }
+
+ 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);
- final Rectangle2D bounds;
if (geoLeft != null && geoRight != null && geoTop != null && geoBottom != null) {
- bounds = new Rectangle2D.Double();
+ final Rectangle2D bounds = new Rectangle2D.Double();
bounds.setFrameFromDiagonal(
- new Point2D.Double(geoLeft.getPropertyValue(), geoTop.getPropertyValue()),
- new Point2D.Double(geoRight.getPropertyValue(), geoBottom.getPropertyValue())
+ new Point2D.Double(geoLeft.getPropertyValue(), geoTop.getPropertyValue()),
+ new Point2D.Double(geoRight.getPropertyValue(), geoBottom.getPropertyValue())
);
+ return bounds;
} else {
- bounds = path2D.getBounds2D();
+ return path2D.getBounds2D();
}
+ }
- pathCT.setW((int)Math.rint(bounds.getWidth()));
- pathCT.setH((int)Math.rint(bounds.getHeight()));
+ private static void handleClosedShape(AbstractEscherOptRecord opt, List<Object> 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();
+ }
+ }
- return new CustomGeometry(cusGeo);
+ private static void handleMoveTo(Iterator<byte[]> vertIter, int[] xyPoints, List<Object> 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<byte[]> vertIter, int[] xyPoints, List<Object> 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<byte[]> vertIter, int[] xyPoints, List<Object> moveLst, Path2D path2D) {
+ if (!vertIter.hasNext()) {
+ return;
+ }
+ handleMoveTo0(moveLst, path2D);
+
+ final CTPath2DCubicBezierTo m = OF.createCTPath2DCubicBezierTo();
+ List<CTAdjPoint2D> 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<Object> 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 void handleEscapeInfo(CTPath2D pathCT, Path2D path2D, byte[] segElem, Iterator<byte[]> vertIter) {
- final ObjectFactory of = new ObjectFactory();
+ private static void handleEscapeInfo(CTPath2D pathCT, Path2D path2D, byte[] segElem, Iterator<byte[]> vertIter) {
HSLFFreeformShape.EscapeInfo ei = getEscapeInfo(segElem);
if (ei == null) {
return;
@@ -376,7 +412,7 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape<HSLFShape,
path2D.append(arc2D, true);
- CTPath2DArcTo arcTo = of.createCTPath2DArcTo();
+ CTPath2DArcTo arcTo = OF.createCTPath2DArcTo();
arcTo.setHR(d2s(bounds.getHeight()/2.0));
arcTo.setWR(d2s(bounds.getWidth()/2.0));
@@ -451,7 +487,7 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape<HSLFShape,
}
- private CTAdjPoint2D fillPoint(byte[] xyMaster, int[] xyPoints) {
+ private static CTAdjPoint2D fillPoint(byte[] xyMaster, int[] xyPoints) {
if (xyMaster == null || xyPoints == null) {
LOG.log(POILogger.WARN, "Master bytes or points not set - ignore point");
return null;
@@ -477,7 +513,7 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape<HSLFShape,
}
private static CTAdjPoint2D toPoint(int[] xyPoints) {
- CTAdjPoint2D pt = new CTAdjPoint2D();
+ CTAdjPoint2D pt = OF.createCTAdjPoint2D();
pt.setX(Integer.toString(xyPoints[0]));
pt.setY(Integer.toString(xyPoints[1]));
return pt;
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
index dd7afa4f9a..097342ffe8 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
@@ -62,7 +62,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
public final static double DEFAULT_LINE_WIDTH = 0.75;
- private static final EscherPropertyTypes[] ADJUST_VALUES = {
+ protected static final EscherPropertyTypes[] ADJUST_VALUES = {
EscherPropertyTypes.GEOMETRY__ADJUSTVALUE,
EscherPropertyTypes.GEOMETRY__ADJUST2VALUE,
EscherPropertyTypes.GEOMETRY__ADJUST3VALUE,
@@ -79,7 +79,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
* Hyperlink
*/
protected HSLFHyperlink _hyperlink;
-
+
/**
* Create a SimpleShape object and initialize it from the supplied Record container.
*
@@ -563,8 +563,8 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
public HSLFShapePlaceholderDetails getPlaceholderDetails() {
return new HSLFShapePlaceholderDetails(this);
}
-
-
+
+
@Override
public Placeholder getPlaceholder() {
return getPlaceholderDetails().getPlaceholder();
@@ -604,7 +604,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
public HSLFHyperlink getHyperlink(){
return _hyperlink;
}
-
+
@Override
public HSLFHyperlink createHyperlink() {
if (_hyperlink == null) {
@@ -612,7 +612,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
}
return _hyperlink;
}
-
+
/**
* Sets the hyperlink - used when the document is parsed
*
@@ -621,7 +621,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
protected void setHyperlink(HSLFHyperlink link) {
_hyperlink = link;
}
-
+
@Override
public boolean isPlaceholder() {
// currently we only identify TextShapes as placeholders