Przeglądaj źródła

Regression findings - fix missing moveto exception

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1873515 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_4_1_2
Andreas Beeker 4 lat temu
rodzic
commit
33fd0b22d6

+ 2
- 1
src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java Wyświetl plik

); );


static final Set<String> EXCLUDES_HANDLE_FILE = unmodifiableHashSet( static final Set<String> EXCLUDES_HANDLE_FILE = unmodifiableHashSet(
"hpsf/Test_Humor-Generation.ppt"
"hpsf/Test_Humor-Generation.ppt",
"slideshow/missing-moveto.ppt" // POIFS properties corrupted
); );





+ 1
- 1
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java Wyświetl plik

private static final String files = private static final String files =
"53446.ppt, alterman_security.ppt, alterman_security.pptx, KEY02.pptx, themes.pptx, " + "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," + "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 @BeforeClass
public static void checkHslf() { public static void checkHslf() {

+ 107
- 71
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java Wyświetl plik



package org.apache.poi.hslf.usermodel; 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.Arc2D;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
static final byte[] SEGMENTINFO_CLOSE = new byte[]{0x01, (byte)0x60}; static final byte[] SEGMENTINFO_CLOSE = new byte[]{0x01, (byte)0x60};
static final byte[] SEGMENTINFO_END = new byte[]{0x00, (byte)0x80}; 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 PATH_INFO = BitFieldFactory.getInstance(0xE000);
private static final BitField ESCAPE_INFO = BitFieldFactory.getInstance(0x1F00); 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 { enum PathInfo {
lineTo(0),curveTo(1),moveTo(2),close(3),end(4),escape(5),clientEscape(6); lineTo(0),curveTo(1),moveTo(2),close(3),end(4),escape(5),clientEscape(6);
private final int flag; private final int flag;
} }


CustomGeometry getGeometry(Path2D path2D) { 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(); final AbstractEscherOptRecord opt = getEscherOptRecord();


final int[] xyPoints = new int[2]; final int[] xyPoints = new int[2];
boolean isClosed = false; 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(); final List<Object> moveLst = pathCT.getCloseOrMoveToOrLnTo();
pathLst.getPath().add(pathCT); pathLst.getPath().add(pathCT);
cusGeo.setPathLst(pathLst); cusGeo.setPathLst(pathLst);
continue; continue;
} }
switch (pi) { switch (pi) {
case escape: {
case escape:
handleEscapeInfo(pathCT, path2D, segElem, vertIter); handleEscapeInfo(pathCT, path2D, segElem, vertIter);
break; break;
}
case moveTo: 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; break;
case lineTo: 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; 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; break;
}
case close: case close:
moveLst.add(of.createCTPath2DClose());
path2D.closePath();
if (path2D.getCurrentPoint() != null) {
moveLst.add(OF.createCTPath2DClose());
path2D.closePath();
}
isClosed = true; isClosed = true;
break; break;
default: default:
} }
} }


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 geoLeft = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__LEFT);
EscherSimpleProperty geoRight = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__RIGHT); EscherSimpleProperty geoRight = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__RIGHT);
EscherSimpleProperty geoTop = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__TOP); EscherSimpleProperty geoTop = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__TOP);
EscherSimpleProperty geoBottom = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__BOTTOM); EscherSimpleProperty geoBottom = getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__BOTTOM);


final Rectangle2D bounds;
if (geoLeft != null && geoRight != null && geoTop != null && geoBottom != null) { if (geoLeft != null && geoRight != null && geoTop != null && geoBottom != null) {
bounds = new Rectangle2D.Double();
final Rectangle2D bounds = new Rectangle2D.Double();
bounds.setFrameFromDiagonal( 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 { } 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); HSLFFreeformShape.EscapeInfo ei = getEscapeInfo(segElem);
if (ei == null) { if (ei == null) {
return; return;
path2D.append(arc2D, true); path2D.append(arc2D, true);




CTPath2DArcTo arcTo = of.createCTPath2DArcTo();
CTPath2DArcTo arcTo = OF.createCTPath2DArcTo();
arcTo.setHR(d2s(bounds.getHeight()/2.0)); arcTo.setHR(d2s(bounds.getHeight()/2.0));
arcTo.setWR(d2s(bounds.getWidth()/2.0)); arcTo.setWR(d2s(bounds.getWidth()/2.0));


} }




private CTAdjPoint2D fillPoint(byte[] xyMaster, int[] xyPoints) {
private static CTAdjPoint2D fillPoint(byte[] xyMaster, int[] xyPoints) {
if (xyMaster == null || xyPoints == null) { if (xyMaster == null || xyPoints == null) {
LOG.log(POILogger.WARN, "Master bytes or points not set - ignore point"); LOG.log(POILogger.WARN, "Master bytes or points not set - ignore point");
return null; return null;
} }


private static CTAdjPoint2D toPoint(int[] xyPoints) { private static CTAdjPoint2D toPoint(int[] xyPoints) {
CTAdjPoint2D pt = new CTAdjPoint2D();
CTAdjPoint2D pt = OF.createCTAdjPoint2D();
pt.setX(Integer.toString(xyPoints[0])); pt.setX(Integer.toString(xyPoints[0]));
pt.setY(Integer.toString(xyPoints[1])); pt.setY(Integer.toString(xyPoints[1]));
return pt; return pt;

+ 7
- 7
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java Wyświetl plik



public final static double DEFAULT_LINE_WIDTH = 0.75; 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__ADJUSTVALUE,
EscherPropertyTypes.GEOMETRY__ADJUST2VALUE, EscherPropertyTypes.GEOMETRY__ADJUST2VALUE,
EscherPropertyTypes.GEOMETRY__ADJUST3VALUE, EscherPropertyTypes.GEOMETRY__ADJUST3VALUE,
* Hyperlink * Hyperlink
*/ */
protected HSLFHyperlink _hyperlink; protected HSLFHyperlink _hyperlink;
/** /**
* Create a SimpleShape object and initialize it from the supplied Record container. * Create a SimpleShape object and initialize it from the supplied Record container.
* *
public HSLFShapePlaceholderDetails getPlaceholderDetails() { public HSLFShapePlaceholderDetails getPlaceholderDetails() {
return new HSLFShapePlaceholderDetails(this); return new HSLFShapePlaceholderDetails(this);
} }
@Override @Override
public Placeholder getPlaceholder() { public Placeholder getPlaceholder() {
return getPlaceholderDetails().getPlaceholder(); return getPlaceholderDetails().getPlaceholder();
public HSLFHyperlink getHyperlink(){ public HSLFHyperlink getHyperlink(){
return _hyperlink; return _hyperlink;
} }
@Override @Override
public HSLFHyperlink createHyperlink() { public HSLFHyperlink createHyperlink() {
if (_hyperlink == null) { if (_hyperlink == null) {
} }
return _hyperlink; return _hyperlink;
} }
/** /**
* Sets the hyperlink - used when the document is parsed * Sets the hyperlink - used when the document is parsed
* *
protected void setHyperlink(HSLFHyperlink link) { protected void setHyperlink(HSLFHyperlink link) {
_hyperlink = link; _hyperlink = link;
} }
@Override @Override
public boolean isPlaceholder() { public boolean isPlaceholder() {
// currently we only identify TextShapes as placeholders // currently we only identify TextShapes as placeholders

BIN
test-data/slideshow/missing-moveto.ppt Wyświetl plik


Ładowanie…
Anuluj
Zapisz