You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2016/02/24 23:43:52 UTC
svn commit: r1732236 [1/2] - in /poi/trunk/src:
integrationtest/org/apache/poi/stress/ java/org/apache/poi/ddf/
java/org/apache/poi/sl/draw/ java/org/apache/poi/sl/draw/geom/
java/org/apache/poi/sl/usermodel/ ooxml/java/org/apache/poi/xslf/usermodel/
o...
Author: kiwiwings
Date: Wed Feb 24 22:43:51 2016
New Revision: 1732236
URL: http://svn.apache.org/viewvc?rev=1732236&view=rev
Log:
Regression fixes for H/XSLF and HWMF
see http://apache-poi.1045710.n5.nabble.com/3-14-beta-2-3-14-final-tt5721829.html
Added:
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBinaryRasterOp.java
Modified:
poi/trunk/src/integrationtest/org/apache/poi/stress/SlideShowHandler.java
poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java
poi/trunk/src/java/org/apache/poi/sl/draw/DrawBackground.java
poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java
poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java
poi/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java
poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java
poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextShape.java
poi/trunk/src/java/org/apache/poi/sl/draw/PathGradientPaint.java
poi/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java
poi/trunk/src/java/org/apache/poi/sl/draw/geom/ArcToCommand.java
poi/trunk/src/java/org/apache/poi/sl/draw/geom/ClosePathCommand.java
poi/trunk/src/java/org/apache/poi/sl/draw/geom/CurveToCommand.java
poi/trunk/src/java/org/apache/poi/sl/draw/geom/LineToCommand.java
poi/trunk/src/java/org/apache/poi/sl/draw/geom/MoveToCommand.java
poi/trunk/src/java/org/apache/poi/sl/draw/geom/Path.java
poi/trunk/src/java/org/apache/poi/sl/draw/geom/PathCommand.java
poi/trunk/src/java/org/apache/poi/sl/draw/geom/QuadToCommand.java
poi/trunk/src/java/org/apache/poi/sl/usermodel/FreeformShape.java
poi/trunk/src/java/org/apache/poi/sl/usermodel/PlaceableShape.java
poi/trunk/src/java/org/apache/poi/sl/usermodel/Shape.java
poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java
poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java
poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java
poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfo.java
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Record.java
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPalette.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfTernaryRasterOp.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java
poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestFreeform.java
poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java
poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java
poi/trunk/src/testcases/org/apache/poi/sl/draw/geom/TestPresetGeometries.java
Modified: poi/trunk/src/integrationtest/org/apache/poi/stress/SlideShowHandler.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/integrationtest/org/apache/poi/stress/SlideShowHandler.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/integrationtest/org/apache/poi/stress/SlideShowHandler.java (original)
+++ poi/trunk/src/integrationtest/org/apache/poi/stress/SlideShowHandler.java Wed Feb 24 22:43:51 2016
@@ -26,10 +26,8 @@ import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import org.apache.poi.sl.draw.Drawable;
+import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.sl.usermodel.ShapeContainer;
@@ -39,7 +37,6 @@ import org.apache.poi.sl.usermodel.Slide
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.sl.usermodel.TextShape;
-import org.apache.poi.util.JvmBugs;
public abstract class SlideShowHandler extends POIFSFileHandler {
public void handleSlideShow(SlideShow<?,?> ss) throws IOException {
@@ -55,10 +52,12 @@ public abstract class SlideShowHandler e
// read in the writen file
SlideShow<?,?> read = SlideShowFactory.create(new ByteArrayInputStream(out.toByteArray()));
- assertNotNull(read);
-
- readContent(read);
-
+ try {
+ assertNotNull(read);
+ readContent(read);
+ } finally {
+ read.close();
+ }
}
private ByteArrayOutputStream writeToArray(SlideShow<?,?> ss) throws IOException {
@@ -109,7 +108,7 @@ public abstract class SlideShowHandler e
for (Slide<?,?> s : ss.getSlides()) {
BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = img.createGraphics();
- fixFonts(graphics);
+ DrawFactory.getInstance(graphics).fixFonts(graphics);
// default rendering options
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
@@ -124,15 +123,4 @@ public abstract class SlideShowHandler e
img.flush();
}
}
-
- @SuppressWarnings("unchecked")
- private static void fixFonts(Graphics2D graphics) {
- if (!JvmBugs.hasLineBreakMeasurerBug()) return;
- Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);
- if (fontMap == null) fontMap = new HashMap<String,String>();
- fontMap.put("Calibri", "Lucida Sans");
- fontMap.put("Cambria", "Lucida Bright");
- graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
- }
-
}
\ No newline at end of file
Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java Wed Feb 24 22:43:51 2016
@@ -43,7 +43,7 @@ public final class EscherArrayProperty e
private boolean sizeIncludesHeaderSize = true;
/**
- * When reading a property from data stream remeber if the complex part is empty and set this flag.
+ * When reading a property from data stream remember if the complex part is empty and set this flag.
*/
private boolean emptyComplexPart = false;
@@ -65,10 +65,7 @@ public final class EscherArrayProperty e
}
public int getNumberOfElementsInArray() {
- if (emptyComplexPart){
- return 0;
- }
- return LittleEndian.getUShort(_complexData, 0);
+ return (emptyComplexPart) ? 0 : LittleEndian.getUShort(_complexData, 0);
}
public void setNumberOfElementsInArray(int numberOfElements) {
@@ -82,7 +79,7 @@ public final class EscherArrayProperty e
}
public int getNumberOfElementsInMemory() {
- return LittleEndian.getUShort(_complexData, 2);
+ return (emptyComplexPart) ? 0 : LittleEndian.getUShort(_complexData, 2);
}
public void setNumberOfElementsInMemory(int numberOfElements) {
@@ -96,7 +93,7 @@ public final class EscherArrayProperty e
}
public short getSizeOfElements() {
- return LittleEndian.getShort( _complexData, 4 );
+ return (emptyComplexPart) ? 0 : LittleEndian.getShort( _complexData, 4 );
}
public void setSizeOfElements(int sizeOfElements) {
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawBackground.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawBackground.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawBackground.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawBackground.java Wed Feb 24 22:43:51 2016
@@ -25,6 +25,7 @@ import java.awt.geom.Rectangle2D;
import org.apache.poi.sl.usermodel.Background;
import org.apache.poi.sl.usermodel.PlaceableShape;
import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.Sheet;
public class DrawBackground extends DrawShape {
@@ -47,6 +48,7 @@ public class DrawBackground extends Draw
public void setFlipVertical(boolean flip) {}
public boolean getFlipHorizontal() { return false; }
public boolean getFlipVertical() { return false; }
+ public Sheet<?,?> getSheet() { return shape.getSheet(); }
};
DrawFactory drawFact = DrawFactory.getInstance(graphics);
@@ -55,6 +57,7 @@ public class DrawBackground extends Draw
Rectangle2D anchor2 = getAnchor(graphics, anchor);
if(fill != null) {
+ graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, anchor);
graphics.setPaint(fill);
graphics.fill(anchor2);
}
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java Wed Feb 24 22:43:51 2016
@@ -17,11 +17,11 @@
package org.apache.poi.sl.draw;
-import static org.apache.poi.sl.draw.Drawable.DRAW_FACTORY;
-
import java.awt.Graphics2D;
import java.awt.font.TextLayout;
import java.text.AttributedString;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.poi.sl.usermodel.Background;
import org.apache.poi.sl.usermodel.ConnectorShape;
@@ -38,6 +38,7 @@ import org.apache.poi.sl.usermodel.Table
import org.apache.poi.sl.usermodel.TextBox;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextShape;
+import org.apache.poi.util.JvmBugs;
public class DrawFactory {
protected static final ThreadLocal<DrawFactory> defaultFactory = new ThreadLocal<DrawFactory>();
@@ -58,7 +59,7 @@ public class DrawFactory {
DrawFactory factory = null;
boolean isHint = false;
if (graphics != null) {
- factory = (DrawFactory)graphics.getRenderingHint(DRAW_FACTORY);
+ factory = (DrawFactory)graphics.getRenderingHint(Drawable.DRAW_FACTORY);
isHint = (factory != null);
}
// secondly try the thread local default
@@ -70,7 +71,7 @@ public class DrawFactory {
factory = new DrawFactory();
}
if (graphics != null && !isHint) {
- graphics.setRenderingHint(DRAW_FACTORY, factory);
+ graphics.setRenderingHint(Drawable.DRAW_FACTORY, factory);
}
return factory;
}
@@ -166,4 +167,29 @@ public class DrawFactory {
public DrawPaint getPaint(PlaceableShape<?,?> shape) {
return new DrawPaint(shape);
}
-}
+
+
+ /**
+ * 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
+ *
+ * @param graphics the graphics context which will contain the font mapping
+ */
+ public void fixFonts(Graphics2D graphics) {
+ if (!JvmBugs.hasLineBreakMeasurerBug()) return;
+ @SuppressWarnings("unchecked")
+ Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);
+ if (fontMap == null) {
+ fontMap = new HashMap<String,String>();
+ graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
+ }
+
+ String fonts[][] = { { "Calibri", "Lucida Sans" }, { "Cambria", "Lucida Bright" } };
+
+ for (String f[] : fonts) {
+ if (!fontMap.containsKey(f[0])) {
+ fontMap.put(f[0], f[1]);
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java Wed Feb 24 22:43:51 2016
@@ -134,8 +134,11 @@ public class DrawPaint {
ImageRenderer renderer = DrawPictureShape.getImageRenderer(graphics, fill.getContentType());
try {
- renderer.loadImage(is, fill.getContentType());
- is.close();
+ try {
+ renderer.loadImage(is, fill.getContentType());
+ } finally {
+ is.close();
+ }
} catch (IOException e) {
LOG.log(POILogger.ERROR, "Can't load image data - using transparent color", e);
return null;
@@ -274,15 +277,35 @@ public class DrawPaint {
Point2D p2 = new Point2D.Double(anchor.getX() + anchor.getWidth(), anchor.getY() + anchor.getHeight() / 2);
p2 = at.transform(p2, null);
-
+
snapToAnchor(p1, anchor);
snapToAnchor(p2, anchor);
+ if (p1.equals(p2)) {
+ // gradient paint on the same point throws an exception ... and doesn't make sense
+ return null;
+ }
+
float[] fractions = fill.getGradientFractions();
Color[] colors = new Color[fractions.length];
int i = 0;
for (ColorStyle fc : fill.getGradientColors()) {
+ if (fc == null) {
+ // get color of background
+ fc = new ColorStyle() {
+ public int getTint() { return -1; }
+ public int getShade() { return -1; }
+ public int getSatOff() { return -1; }
+ public int getSatMod() { return -1; }
+ public int getLumOff() { return -1; }
+ public int getLumMod() { return -1; }
+ public int getHueOff() { return -1; }
+ public int getHueMod() { return -1; }
+ public Color getColor() { return Color.white; }
+ public int getAlpha() { return 0; }
+ };
+ }
colors[i++] = applyColorTransform(fc);
}
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java Wed Feb 24 22:43:51 2016
@@ -52,8 +52,7 @@ public class DrawPictureShape extends Dr
renderer.loadImage(data.getData(), data.getContentType());
renderer.drawImage(graphics, anchor, insets);
} catch (IOException e) {
- // TODO: draw specific runtime exception?
- throw new RuntimeException(e);
+ LOG.log(POILogger.ERROR, "image can't be loaded/rendered.", e);
}
}
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java Wed Feb 24 22:43:51 2016
@@ -90,17 +90,23 @@ public class DrawShape implements Drawab
Rectangle2D anchor2 = txs.createTransformedShape(ps.getAnchor()).getBounds2D();
- scaleX = anchor.getWidth() == 0. ? 1.0 : anchor.getWidth() / anchor2.getWidth();
- scaleY = anchor.getHeight() == 0. ? 1.0 : anchor.getHeight() / anchor2.getHeight();
+ scaleX = safeScale(anchor.getWidth(), anchor2.getWidth());
+ scaleY = safeScale(anchor.getHeight(), anchor2.getHeight());
} else {
quadrant = 0;
}
// transformation is applied reversed ...
graphics.translate(centerX, centerY);
- graphics.rotate(Math.toRadians(rotation-quadrant*90.));
+ double rot = Math.toRadians(rotation-quadrant*90.);
+ if (rot != 0) {
+ graphics.rotate(rot);
+ }
graphics.scale(scaleX, scaleY);
- graphics.rotate(Math.toRadians(quadrant*90));
+ rot = Math.toRadians(quadrant*90);
+ if (rot != 0) {
+ graphics.rotate(rot);
+ }
graphics.translate(-centerX, -centerY);
}
@@ -119,6 +125,12 @@ public class DrawShape implements Drawab
}
}
+ private static double safeScale(double dim1, double dim2) {
+ if (dim1 == 0.) {
+ return 1;
+ }
+ return (dim2 == 0.) ? 1 : dim1/dim2;
+ }
public void draw(Graphics2D graphics) {
}
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java Wed Feb 24 22:43:51 2016
@@ -23,7 +23,7 @@ import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.InputStream;
@@ -179,20 +179,20 @@ public class DrawSimpleShape extends Dra
case STEALTH:
case ARROW:
p = new Path(false, true);
- GeneralPath arrow = new GeneralPath();
- arrow.moveTo((float) (-lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
+ Path2D.Double arrow = new Path2D.Double();
+ arrow.moveTo((-lineWidth * scaleX), (-lineWidth * scaleY / 2));
arrow.lineTo(0, 0);
- arrow.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
+ arrow.lineTo((-lineWidth * scaleX), (lineWidth * scaleY / 2));
tailShape = arrow;
at.translate(x2, y2);
at.rotate(alpha);
break;
case TRIANGLE:
p = new Path();
- GeneralPath triangle = new GeneralPath();
- triangle.moveTo((float) (-lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
+ Path2D.Double triangle = new Path2D.Double();
+ triangle.moveTo((-lineWidth * scaleX), (-lineWidth * scaleY / 2));
triangle.lineTo(0, 0);
- triangle.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
+ triangle.lineTo((-lineWidth * scaleX), (lineWidth * scaleY / 2));
triangle.closePath();
tailShape = triangle;
at.translate(x2, y2);
@@ -252,20 +252,20 @@ public class DrawSimpleShape extends Dra
case STEALTH:
case ARROW:
p = new Path(false, true);
- GeneralPath arrow = new GeneralPath();
- arrow.moveTo((float) (lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
+ Path2D.Double arrow = new Path2D.Double();
+ arrow.moveTo((lineWidth * scaleX), (-lineWidth * scaleY / 2));
arrow.lineTo(0, 0);
- arrow.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
+ arrow.lineTo((lineWidth * scaleX), (lineWidth * scaleY / 2));
headShape = arrow;
at.translate(x1, y1);
at.rotate(alpha);
break;
case TRIANGLE:
p = new Path();
- GeneralPath triangle = new GeneralPath();
- triangle.moveTo((float) (lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
+ Path2D.Double triangle = new Path2D.Double();
+ triangle.moveTo((lineWidth * scaleX), (-lineWidth * scaleY / 2));
triangle.lineTo(0, 0);
- triangle.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
+ triangle.lineTo((lineWidth * scaleX), (lineWidth * scaleY / 2));
triangle.closePath();
headShape = triangle;
at.translate(x1, y1);
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java Wed Feb 24 22:43:51 2016
@@ -38,6 +38,7 @@ import org.apache.poi.sl.usermodel.Inset
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PlaceableShape;
import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.Sheet;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextParagraph.BulletStyle;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
@@ -465,6 +466,7 @@ public class DrawTextParagraph implement
public void setFlipVertical(boolean flip) {}
public boolean getFlipHorizontal() { return false; }
public boolean getFlipVertical() { return false; }
+ public Sheet<?,?> getSheet() { return paragraph.getParentShape().getSheet(); }
};
return ps;
}
@@ -530,7 +532,7 @@ public class DrawTextParagraph implement
attList.add(new AttributedStringData(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, beginIndex, endIndex));
}
- Hyperlink hl = run.getHyperlink();
+ Hyperlink<?,?> hl = run.getHyperlink();
if (hl != null) {
attList.add(new AttributedStringData(HYPERLINK_HREF, hl.getAddress(), beginIndex, endIndex));
attList.add(new AttributedStringData(HYPERLINK_LABEL, hl.getLabel(), beginIndex, endIndex));
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextShape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextShape.java Wed Feb 24 22:43:51 2016
@@ -21,11 +21,15 @@ import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
-import java.util.*;
+import java.util.Iterator;
-import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.sl.usermodel.Insets2D;
+import org.apache.poi.sl.usermodel.PlaceableShape;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextParagraph.BulletStyle;
-import org.apache.poi.util.JvmBugs;
+import org.apache.poi.sl.usermodel.TextRun;
+import org.apache.poi.sl.usermodel.TextShape;
public class DrawTextShape extends DrawSimpleShape {
@@ -35,7 +39,7 @@ public class DrawTextShape extends DrawS
@Override
public void drawContent(Graphics2D graphics) {
- fixFonts(graphics);
+ DrawFactory.getInstance(graphics).fixFonts(graphics);
TextShape<?,?> s = getShape();
@@ -71,7 +75,7 @@ public class DrawTextShape extends DrawS
}
Double textRot = s.getTextRotation();
- if (textRot != null) {
+ if (textRot != null && textRot != 0) {
graphics.translate(anchor.getCenterX(), anchor.getCenterY());
graphics.rotate(Math.toRadians(textRot));
graphics.translate(-anchor.getCenterX(), -anchor.getCenterY());
@@ -110,8 +114,9 @@ public class DrawTextShape extends DrawS
double y0 = y;
//noinspection RedundantCast
- Iterator<? extends TextParagraph<?,?,? extends TextRun>> paragraphs = (Iterator<? extends TextParagraph<?, ?, ? extends TextRun>>) getShape().iterator();
-
+ Iterator<? extends TextParagraph<?,?,? extends TextRun>> paragraphs =
+ (Iterator<? extends TextParagraph<?,?,? extends TextRun>>) getShape().iterator();
+
boolean isFirstLine = true;
for (int autoNbrIdx=0; paragraphs.hasNext(); autoNbrIdx++){
TextParagraph<?,?,? extends TextRun> p = paragraphs.next();
@@ -170,23 +175,10 @@ public class DrawTextShape extends DrawS
// dry-run in a 1x1 image and return the vertical advance
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
- fixFonts(graphics);
+ DrawFactory.getInstance(graphics).fixFonts(graphics);
return drawParagraphs(graphics, 0, 0);
}
- @SuppressWarnings("unchecked")
- private static void fixFonts(Graphics2D graphics) {
- if (!JvmBugs.hasLineBreakMeasurerBug()) return;
- Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);
- if (fontMap == null) {
- fontMap = new HashMap<String,String>();
- graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
- }
-
- if (!fontMap.containsKey("Calibri")) fontMap.put("Calibri", "Lucida Sans");
- if (!fontMap.containsKey("Cambria")) fontMap.put("Cambria", "Lucida Bright");
- }
-
@Override
protected TextShape<?,?> getShape() {
return (TextShape<?,?>)shape;
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/PathGradientPaint.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/PathGradientPaint.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/PathGradientPaint.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/PathGradientPaint.java Wed Feb 24 22:43:51 2016
@@ -87,7 +87,7 @@ class PathGradientPaint implements Paint
) {
shape = (Shape)hints.get(Drawable.GRADIENT_SHAPE);
if (shape == null) {
- throw new IllegalPathStateException("PathGradientPaint needs a shape to be set via the rendering hint PathGradientPaint.GRADIANT_SHAPE.");
+ throw new IllegalPathStateException("PathGradientPaint needs a shape to be set via the rendering hint Drawable.GRADIANT_SHAPE.");
}
this.deviceBounds = deviceBounds;
@@ -137,14 +137,14 @@ class PathGradientPaint implements Paint
return childRaster;
}
- protected int getGradientSteps(Shape shape) {
- Rectangle rect = shape.getBounds();
+ protected int getGradientSteps(Shape gradientShape) {
+ Rectangle rect = gradientShape.getBounds();
int lower = 1;
int upper = (int)(Math.max(rect.getWidth(),rect.getHeight())/2.0);
while (lower < upper-1) {
int mid = lower + (upper - lower) / 2;
BasicStroke bs = new BasicStroke(mid, capStyle, joinStyle);
- Area area = new Area(bs.createStrokedShape(shape));
+ Area area = new Area(bs.createStrokedShape(gradientShape));
if (area.isSingular()) {
upper = mid;
} else {
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/SLGraphics.java Wed Feb 24 22:43:51 2016
@@ -42,6 +42,7 @@ import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
@@ -243,7 +244,7 @@ public final class SLGraphics extends Gr
* @see #setComposite
*/
public void draw(Shape shape){
- GeneralPath path = new GeneralPath(_transform.createTransformedShape(shape));
+ Path2D.Double path = new Path2D.Double(_transform.createTransformedShape(shape));
FreeformShape<?,?> p = _group.createFreeform();
p.setPath(path);
p.setFillColor(null);
@@ -339,7 +340,7 @@ public final class SLGraphics extends Gr
* @see #setClip
*/
public void fill(Shape shape){
- GeneralPath path = new GeneralPath(_transform.createTransformedShape(shape));
+ Path2D.Double path = new Path2D.Double(_transform.createTransformedShape(shape));
FreeformShape<?,?> p = _group.createFreeform();
p.setPath(path);
applyPaint(p);
@@ -450,7 +451,7 @@ public final class SLGraphics extends Gr
*/
public void drawRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight){
- RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);
+ RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight);
draw(rect);
}
@@ -481,7 +482,7 @@ public final class SLGraphics extends Gr
* @see java.awt.Graphics#drawOval
*/
public void fillOval(int x, int y, int width, int height){
- Ellipse2D oval = new Ellipse2D.Float(x, y, width, height);
+ Ellipse2D oval = new Ellipse2D.Double(x, y, width, height);
fill(oval);
}
@@ -504,7 +505,7 @@ public final class SLGraphics extends Gr
public void fillRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight){
- RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight);
+ RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight);
fill(rect);
}
@@ -544,9 +545,8 @@ public final class SLGraphics extends Gr
* relative to the start angle.
* @see java.awt.Graphics#drawArc
*/
- public void fillArc(int x, int y, int width, int height,
- int startAngle, int arcAngle){
- Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE);
+ public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle){
+ Arc2D arc = new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.PIE);
fill(arc);
}
@@ -587,9 +587,8 @@ public final class SLGraphics extends Gr
* relative to the start angle.
* @see java.awt.Graphics#fillArc
*/
- public void drawArc(int x, int y, int width, int height,
- int startAngle, int arcAngle) {
- Arc2D arc = new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN);
+ public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
+ Arc2D arc = new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN);
draw(arc);
}
@@ -636,7 +635,7 @@ public final class SLGraphics extends Gr
* @see java.awt.Graphics#fillOval
*/
public void drawOval(int x, int y, int width, int height){
- Ellipse2D oval = new Ellipse2D.Float(x, y, width, height);
+ Ellipse2D oval = new Ellipse2D.Double(x, y, width, height);
draw(oval);
}
@@ -932,7 +931,7 @@ public final class SLGraphics extends Gr
* @param y2 the second point's <i>y</i> coordinate.
*/
public void drawLine(int x1, int y1, int x2, int y2){
- Line2D line = new Line2D.Float(x1, y1, x2, y2);
+ Line2D line = new Line2D.Double(x1, y1, x2, y2);
draw(line);
}
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/geom/ArcToCommand.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/geom/ArcToCommand.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/geom/ArcToCommand.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/geom/ArcToCommand.java Wed Feb 24 22:43:51 2016
@@ -19,12 +19,12 @@
package org.apache.poi.sl.draw.geom;
-import org.apache.poi.sl.draw.binding.CTPath2DArcTo;
-
import java.awt.geom.Arc2D;
-import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
+import org.apache.poi.sl.draw.binding.CTPath2DArcTo;
+
/**
* ArcTo command within a shape path in DrawingML:
*
@@ -48,7 +48,7 @@ public class ArcToCommand implements Pat
swAng = arc.getSwAng().toString();
}
- public void execute(GeneralPath path, Context ctx){
+ public void execute(Path2D.Double path, Context ctx){
double rx = ctx.getValue(wr);
double ry = ctx.getValue(hr);
double start = ctx.getValue(stAng) / 60000;
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/geom/ClosePathCommand.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/geom/ClosePathCommand.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/geom/ClosePathCommand.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/geom/ClosePathCommand.java Wed Feb 24 22:43:51 2016
@@ -19,7 +19,7 @@
package org.apache.poi.sl.draw.geom;
-import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
/**
* Date: 10/25/11
@@ -31,7 +31,7 @@ public class ClosePathCommand implements
ClosePathCommand(){
}
- public void execute(GeneralPath path, Context ctx){
+ public void execute(Path2D.Double path, Context ctx){
path.closePath();
}
}
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/geom/CurveToCommand.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/geom/CurveToCommand.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/geom/CurveToCommand.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/geom/CurveToCommand.java Wed Feb 24 22:43:51 2016
@@ -19,9 +19,9 @@
package org.apache.poi.sl.draw.geom;
-import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
+import java.awt.geom.Path2D;
-import java.awt.geom.GeneralPath;
+import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
/**
* Date: 10/25/11
@@ -40,13 +40,13 @@ public class CurveToCommand implements P
arg6 = pt3.getY().toString();
}
- public void execute(GeneralPath path, Context ctx){
+ public void execute(Path2D.Double path, Context ctx){
double x1 = ctx.getValue(arg1);
double y1 = ctx.getValue(arg2);
double x2 = ctx.getValue(arg3);
double y2 = ctx.getValue(arg4);
double x3 = ctx.getValue(arg5);
double y3 = ctx.getValue(arg6);
- path.curveTo((float)x1, (float)y1, (float)x2, (float)y2, (float)x3, (float)y3);
+ path.curveTo(x1, y1, x2, y2, x3, y3);
}
}
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/geom/LineToCommand.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/geom/LineToCommand.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/geom/LineToCommand.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/geom/LineToCommand.java Wed Feb 24 22:43:51 2016
@@ -19,9 +19,9 @@
package org.apache.poi.sl.draw.geom;
-import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
+import java.awt.geom.Path2D;
-import java.awt.geom.GeneralPath;
+import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
/**
* Date: 10/25/11
@@ -41,9 +41,9 @@ public class LineToCommand implements Pa
arg2 = s2;
}
- public void execute(GeneralPath path, Context ctx){
+ public void execute(Path2D.Double path, Context ctx){
double x = ctx.getValue(arg1);
double y = ctx.getValue(arg2);
- path.lineTo((float)x, (float)y);
+ path.lineTo(x, y);
}
}
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/geom/MoveToCommand.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/geom/MoveToCommand.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/geom/MoveToCommand.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/geom/MoveToCommand.java Wed Feb 24 22:43:51 2016
@@ -19,9 +19,9 @@
package org.apache.poi.sl.draw.geom;
-import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
+import java.awt.geom.Path2D;
-import java.awt.geom.GeneralPath;
+import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
/**
* Date: 10/25/11
@@ -41,9 +41,9 @@ public class MoveToCommand implements Pa
arg2 = s2;
}
- public void execute(GeneralPath path, Context ctx){
+ public void execute(Path2D.Double path, Context ctx){
double x = ctx.getValue(arg1);
double y = ctx.getValue(arg2);
- path.moveTo((float)x, (float)y);
+ path.moveTo(x, y);
}
}
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/geom/Path.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/geom/Path.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/geom/Path.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/geom/Path.java Wed Feb 24 22:43:51 2016
@@ -19,11 +19,19 @@
package org.apache.poi.sl.draw.geom;
-import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.List;
-import org.apache.poi.sl.draw.binding.*;
+import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
+import org.apache.poi.sl.draw.binding.CTPath2D;
+import org.apache.poi.sl.draw.binding.CTPath2DArcTo;
+import org.apache.poi.sl.draw.binding.CTPath2DClose;
+import org.apache.poi.sl.draw.binding.CTPath2DCubicBezierTo;
+import org.apache.poi.sl.draw.binding.CTPath2DLineTo;
+import org.apache.poi.sl.draw.binding.CTPath2DMoveTo;
+import org.apache.poi.sl.draw.binding.CTPath2DQuadBezierTo;
+import org.apache.poi.sl.draw.binding.STPathFillMode;
/**
* Specifies a creation path consisting of a series of moves, lines and curves
@@ -90,10 +98,10 @@ public class Path {
}
/**
- * Convert the internal represenation to java.awt.GeneralPath
+ * Convert the internal represenation to java.awt.geom.Path2D
*/
- public GeneralPath getPath(Context ctx) {
- GeneralPath path = new GeneralPath();
+ public Path2D.Double getPath(Context ctx) {
+ Path2D.Double path = new Path2D.Double();
for(PathCommand cmd : commands)
cmd.execute(path, ctx);
return path;
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/geom/PathCommand.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/geom/PathCommand.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/geom/PathCommand.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/geom/PathCommand.java Wed Feb 24 22:43:51 2016
@@ -19,7 +19,7 @@
package org.apache.poi.sl.draw.geom;
-import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
/**
* A path command in DrawingML. One of:
@@ -41,5 +41,5 @@ public interface PathCommand {
* @param path the path to append the result to
* @param ctx the context to lookup variables
*/
- void execute(GeneralPath path, Context ctx);
+ void execute(Path2D.Double path, Context ctx);
}
Modified: poi/trunk/src/java/org/apache/poi/sl/draw/geom/QuadToCommand.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/geom/QuadToCommand.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/geom/QuadToCommand.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/geom/QuadToCommand.java Wed Feb 24 22:43:51 2016
@@ -19,9 +19,9 @@
package org.apache.poi.sl.draw.geom;
-import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
+import java.awt.geom.Path2D;
-import java.awt.geom.GeneralPath;
+import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
/**
* Date: 10/25/11
@@ -38,11 +38,11 @@ public class QuadToCommand implements Pa
arg4 = pt2.getY().toString();
}
- public void execute(GeneralPath path, Context ctx){
+ public void execute(Path2D.Double path, Context ctx){
double x1 = ctx.getValue(arg1);
double y1 = ctx.getValue(arg2);
double x2 = ctx.getValue(arg3);
double y2 = ctx.getValue(arg4);
- path.quadTo((float)x1, (float)y1, (float)x2, (float)y2);
+ path.quadTo(x1, y1, x2, y2);
}
}
Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/FreeformShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/FreeformShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/usermodel/FreeformShape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/usermodel/FreeformShape.java Wed Feb 24 22:43:51 2016
@@ -17,7 +17,7 @@
package org.apache.poi.sl.usermodel;
-import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
public interface FreeformShape<
S extends Shape<S,P>,
@@ -33,7 +33,7 @@ public interface FreeformShape<
*
* @return the path
*/
- GeneralPath getPath();
+ Path2D.Double getPath();
/**
* Set the shape path
@@ -41,5 +41,5 @@ public interface FreeformShape<
* @param path shape outline
* @return the number of points written
*/
- int setPath(GeneralPath path);
+ int setPath(Path2D.Double path);
}
Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/PlaceableShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/PlaceableShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/usermodel/PlaceableShape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/usermodel/PlaceableShape.java Wed Feb 24 22:43:51 2016
@@ -26,6 +26,11 @@ public interface PlaceableShape<
ShapeContainer<S,P> getParent();
/**
+ * @return the sheet this shape belongs to
+ */
+ Sheet<S,P> getSheet();
+
+ /**
* @return the position of this shape within the drawing canvas.
* The coordinates are expressed in points
*/
Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/Shape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/Shape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/usermodel/Shape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/usermodel/Shape.java Wed Feb 24 22:43:51 2016
@@ -25,8 +25,7 @@ public interface Shape<
> {
ShapeContainer<S,P> getParent();
- /**
- *
+ /**
* @return the sheet this shape belongs to
*/
Sheet<S,P> getSheet();
Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java Wed Feb 24 22:43:51 2016
@@ -20,7 +20,7 @@
package org.apache.poi.xslf.usermodel;
import java.awt.geom.AffineTransform;
-import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
@@ -57,7 +57,7 @@ public class XSLFFreeformShape extends X
}
@Override
- public int setPath(GeneralPath path) {
+ public int setPath(Path2D.Double path) {
CTPath2D ctPath = CTPath2D.Factory.newInstance();
Rectangle2D bounds = path.getBounds2D();
@@ -119,8 +119,8 @@ public class XSLFFreeformShape extends X
}
@Override
- public GeneralPath getPath() {
- GeneralPath path = new GeneralPath();
+ public Path2D.Double getPath() {
+ Path2D.Double path = new Path2D.Double();
Rectangle2D bounds = getAnchor();
CTCustomGeometry2D geom = getSpPr().getCustGeom();
@@ -168,7 +168,7 @@ public class XSLFFreeformShape extends X
// The returned path should fit in the bounding rectangle
AffineTransform at = new AffineTransform();
at.translate(bounds.getX(), bounds.getY());
- return new GeneralPath(at.createTransformedShape(path));
+ return new Path2D.Double(at.createTransformedShape(path));
}
/**
* @param shapeId 1-based shapeId
Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java Wed Feb 24 22:43:51 2016
@@ -48,11 +48,11 @@ public class XSLFHyperlink implements Hy
@Override
public String getAddress() {
- if (!_link.isSetId()) {
+ String id = _link.getId();
+ if (id == null || "".equals(id)) {
return _link.getAction();
}
- String id = _link.getId();
URI targetURI = _sheet.getPackagePart().getRelationship(id).getTargetURI();
return targetURI.toASCIIString();
Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java Wed Feb 24 22:43:51 2016
@@ -455,8 +455,15 @@ public class XSLFTextRun implements Text
@Override
public XSLFHyperlink getHyperlink(){
- if(!_r.getRPr().isSetHlinkClick()) return null;
- return new XSLFHyperlink(_r.getRPr().getHlinkClick(), _p.getParentShape().getSheet());
+ CTTextCharacterProperties rPr = _r.getRPr();
+ if (rPr == null) {
+ return null;
+ }
+ CTHyperlink hl = rPr.getHlinkClick();
+ if (hl == null) {
+ return null;
+ }
+ return new XSLFHyperlink(hl, _p.getParentShape().getSheet());
}
private boolean fetchCharacterProperty(CharacterPropertyFetcher<?> fetcher){
Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java Wed Feb 24 22:43:51 2016
@@ -24,18 +24,17 @@ import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
-import java.util.HashMap;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import javax.imageio.ImageIO;
-import org.apache.poi.sl.draw.Drawable;
+import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
-import org.apache.poi.util.JvmBugs;
/**
* An utility to convert slides of a .pptx slide show to a PNG image
@@ -65,7 +64,7 @@ public class PPTX2PNG {
return;
}
- int slidenum = -1;
+ String slidenumStr = "-1";
float scale = 1;
File file = null;
String format = "png";
@@ -77,7 +76,7 @@ public class PPTX2PNG {
if ("-scale".equals(args[i])) {
scale = Float.parseFloat(args[++i]);
} else if ("-slide".equals(args[i])) {
- slidenum = Integer.parseInt(args[++i]);
+ slidenumStr = args[++i];
} else if ("-format".equals(args[i])) {
format = args[++i];
} else if ("-outdir".equals(args[i])) {
@@ -120,9 +119,11 @@ public class PPTX2PNG {
SlideShow<?,?> ss = SlideShowFactory.create(file, null, true);
List<? extends Slide<?,?>> slides = ss.getSlides();
+ Set<Integer> slidenum = slideIndexes(slides.size(), slidenumStr);
- if (slidenum < -1 || slidenum == 0 || slidenum > slides.size()) {
+ if (slidenum.isEmpty()) {
usage("slidenum must be either -1 (for all) or within range: [1.."+slides.size()+"] for "+file);
+ ss.close();
return;
}
@@ -130,39 +131,36 @@ public class PPTX2PNG {
int width = (int) (pgsize.width * scale);
int height = (int) (pgsize.height * scale);
- int slideNo=1;
- for(Slide<?,?> slide : slides) {
- if (slidenum == -1 || slideNo == slidenum) {
- String title = slide.getTitle();
- if (!quiet) {
- System.out.println("Rendering slide " + slideNo + (title == null ? "" : ": " + title));
- }
+ for(Integer slideNo : slidenum) {
+ Slide<?,?> slide = slides.get(slideNo);
+ String title = slide.getTitle();
+ if (!quiet) {
+ System.out.println("Rendering slide " + slideNo + (title == null ? "" : ": " + title));
+ }
- BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
- Graphics2D graphics = img.createGraphics();
- fixFonts(graphics);
-
- // default rendering options
- graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
- graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
- graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
-
- graphics.scale(scale, scale);
-
- // draw stuff
- slide.draw(graphics);
-
- // save the result
- if (!"null".equals(format)) {
- String outname = file.getName().replaceFirst(".pptx?", "");
- outname = String.format(Locale.ROOT, "%1$s-%2$04d.%3$s", outname, slideNo, format);
- File outfile = new File(outdir, outname);
- ImageIO.write(img, format, outfile);
- }
- }
- slideNo++;
- }
+ BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D graphics = img.createGraphics();
+ DrawFactory.getInstance(graphics).fixFonts(graphics);
+
+ // default rendering options
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+ graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+ graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+ graphics.scale(scale, scale);
+
+ // draw stuff
+ slide.draw(graphics);
+
+ // save the result
+ if (!"null".equals(format)) {
+ String outname = file.getName().replaceFirst(".pptx?", "");
+ outname = String.format(Locale.ROOT, "%1$s-%2$04d.%3$s", outname, slideNo, format);
+ File outfile = new File(outdir, outname);
+ ImageIO.write(img, format, outfile);
+ }
+ }
if (!quiet) {
System.out.println("Done");
@@ -170,14 +168,43 @@ public class PPTX2PNG {
ss.close();
}
-
- @SuppressWarnings("unchecked")
- private static void fixFonts(Graphics2D graphics) {
- if (!JvmBugs.hasLineBreakMeasurerBug()) return;
- Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);
- if (fontMap == null) fontMap = new HashMap<String,String>();
- fontMap.put("Calibri", "Lucida Sans");
- fontMap.put("Cambria", "Lucida Bright");
- graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
+
+ private static Set<Integer> slideIndexes(final int slideCount, String range) {
+ Set<Integer> slideIdx = new TreeSet<Integer>();
+ if ("-1".equals(range)) {
+ for (int i=0; i<slideCount; i++) {
+ slideIdx.add(i);
+ }
+ } else {
+ for (String subrange : range.split(",")) {
+ String idx[] = subrange.split("-");
+ switch (idx.length) {
+ default:
+ case 0: break;
+ case 1: {
+ int subidx = Integer.parseInt(idx[0]);
+ if (subrange.contains("-")) {
+ int startIdx = subrange.startsWith("-") ? 0 : subidx;
+ int endIdx = subrange.endsWith("-") ? slideCount : Math.min(subidx,slideCount);
+ for (int i=Math.max(startIdx,1); i<endIdx; i++) {
+ slideIdx.add(i-1);
+ }
+ } else {
+ slideIdx.add(Math.max(subidx,1)-1);
+ }
+ break;
+ }
+ case 2: {
+ int startIdx = Math.min(Integer.parseInt(idx[0]), slideCount);
+ int endIdx = Math.min(Integer.parseInt(idx[1]), slideCount);
+ for (int i=Math.max(startIdx,1); i<endIdx; i++) {
+ slideIdx.add(i-1);
+ }
+ break;
+ }
+ }
+ }
+ }
+ return slideIdx;
}
}
Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java Wed Feb 24 22:43:51 2016
@@ -36,17 +36,28 @@ public class TestPPTX2PNG {
public void render() throws Exception {
POIDataSamples samples = POIDataSamples.getSlideShowInstance();
- String[] testFiles = {"alterman_security.ppt","alterman_security.pptx","KEY02.pptx","themes.pptx","backgrounds.pptx","layouts.pptx", "sample.pptx", "shapes.pptx",};
-// String[] testFiles = {"41246-2.ppt","45543.ppt","53446.ppt","ParagraphStylesShorterThanCharStyles.ppt"};
+// File testFilesX[] = new File("tmp_ppt").listFiles(new FileFilter() {
+// public boolean accept(File pathname) {
+// return pathname.getName().toLowerCase().contains("ppt");
+// }
+// });
+// String testFiles[] = new String[testFilesX.length];
+// for (int i=0; i<testFilesX.length; i++) {
+// testFiles[i] = testFilesX[i].getPath();
+// }
+
+
+ String[] testFiles = {"53446.ppt", "alterman_security.ppt","alterman_security.pptx","KEY02.pptx","themes.pptx","backgrounds.pptx","layouts.pptx", "sample.pptx", "shapes.pptx",};
String[] args = {
"-format", "null", // png,gif,jpg or null for test
"-slide", "-1", // -1 for all
"-outdir", new File("build/tmp/").getCanonicalPath(),
- "-quite",
+ "-quiet",
"dummyfile"
};
for(String sampleFile : testFiles){
args[args.length-1] = samples.getFile(sampleFile).getCanonicalPath();
+// args[args.length-1] = new File(sampleFile).getCanonicalPath();
try {
PPTX2PNG.main(args);
} catch (IllegalStateException e) {
Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java Wed Feb 24 22:43:51 2016
@@ -19,8 +19,9 @@ package org.apache.poi.xslf.usermodel;
import static org.junit.Assert.assertEquals;
import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
+import java.io.IOException;
import org.junit.Test;
@@ -30,16 +31,16 @@ import org.junit.Test;
public class TestXSLFFreeformShape {
@Test
- public void testSetPath() {
+ public void testSetPath() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide();
XSLFFreeformShape shape1 = slide.createFreeform();
// comples path consisting of a rectangle and an ellipse inside it
- GeneralPath path1 = new GeneralPath(new Rectangle2D.Double(150, 150, 300, 300));
+ Path2D.Double path1 = new Path2D.Double(new Rectangle2D.Double(150, 150, 300, 300));
path1.append(new Ellipse2D.Double(200, 200, 100, 50), false);
shape1.setPath(path1);
- GeneralPath path2 = shape1.getPath();
+ Path2D.Double path2 = shape1.getPath();
// YK: how to compare the original path1 and the value returned by XSLFFreeformShape.getPath() ?
// one way is to create another XSLFFreeformShape from path2 and compare the resulting xml
@@ -49,5 +50,7 @@ public class TestXSLFFreeformShape {
shape2.setPath(path2);
assertEquals(shape1.getSpPr().getCustGeom().toString(), shape2.getSpPr().getCustGeom().toString());
+
+ ppt.close();
}
}
\ No newline at end of file
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java Wed Feb 24 22:43:51 2016
@@ -42,6 +42,7 @@ import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
@@ -244,7 +245,7 @@ public final class PPGraphics2D extends
* @see #setComposite
*/
public void draw(Shape shape){
- GeneralPath path = new GeneralPath(_transform.createTransformedShape(shape));
+ Path2D.Double path = new Path2D.Double(_transform.createTransformedShape(shape));
HSLFFreeformShape p = new HSLFFreeformShape(_group);
p.setPath(path);
p.getFill().setForegroundColor(null);
@@ -346,7 +347,7 @@ public final class PPGraphics2D extends
* @see #setClip
*/
public void fill(Shape shape){
- GeneralPath path = new GeneralPath(_transform.createTransformedShape(shape));
+ Path2D.Double path = new Path2D.Double(_transform.createTransformedShape(shape));
HSLFFreeformShape p = new HSLFFreeformShape(_group);
p.setPath(path);
applyPaint(p);
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfo.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfo.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfo.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfo.java Wed Feb 24 22:43:51 2016
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.OutputStream;
import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogger;
/**
* This class represents the metadata of a link in a slide/notes/etc.
@@ -59,11 +60,12 @@ public class InteractiveInfo extends Rec
*/
private void findInterestingChildren() {
// First child should be the InteractiveInfoAtom
- if(_children[0] instanceof InteractiveInfoAtom) {
- infoAtom = (InteractiveInfoAtom)_children[0];
- } else {
- throw new IllegalStateException("First child record wasn't a InteractiveInfoAtom, was of type " + _children[0].getRecordType());
- }
+ if (_children == null || _children.length == 0 || !(_children[0] instanceof InteractiveInfoAtom)) {
+ logger.log(POILogger.WARN, "First child record wasn't a InteractiveInfoAtom - leaving this atom in an invalid state...");
+ return;
+ }
+
+ infoAtom = (InteractiveInfoAtom)_children[0];
}
/**
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Record.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Record.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Record.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/Record.java Wed Feb 24 22:43:51 2016
@@ -168,7 +168,7 @@ public abstract class Record
try {
c = RecordTypes.forTypeID((short)type).handlingClass;
if(c == null) {
- // How odd. RecordTypes normally subsitutes in
+ // How odd. RecordTypes normally substitutes in
// a default handler class if it has heard of the record
// type but there's no support for it. Explicitly request
// that now
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java Wed Feb 24 22:43:51 2016
@@ -23,23 +23,28 @@ import java.io.InputStream;
import java.util.List;
import org.apache.poi.ddf.AbstractEscherOptRecord;
+import org.apache.poi.ddf.EscherArrayProperty;
import org.apache.poi.ddf.EscherBSERecord;
+import org.apache.poi.ddf.EscherColorRef;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherProperties;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.hslf.record.Document;
import org.apache.poi.sl.draw.DrawPaint;
+import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.FillStyle;
import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
+import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint.GradientType;
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
+import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
+import org.apache.poi.util.Units;
/**
* Represents functionality provided by the 'Fill Effects' dialog in PowerPoint.
- *
- * @author Yegor Kozlov
*/
public final class HSLFFill {
// For logging
@@ -118,36 +123,110 @@ public final class HSLFFill {
public FillStyle getFillStyle() {
return new FillStyle() {
public PaintStyle getPaint() {
- switch (getFillType()) {
+ final int fillType = getFillType();
+ // TODO: fix gradient types, this mismatches with the MS-ODRAW definition ...
+ // need to handle (not only) the type (radial,rectangular,linear),
+ // the direction, e.g. top right, and bounds (e.g. for rectangular boxes)
+ switch (fillType) {
case FILL_SOLID:
return DrawPaint.createSolidPaint(getForegroundColor());
- case FILL_PICTURE: {
- final HSLFPictureData pd = getPictureData();
- if (pd == null) break;
-
- return new TexturePaint() {
- public InputStream getImageData() {
- return new ByteArrayInputStream(pd.getData());
- }
-
- public String getContentType() {
- return pd.getContentType();
- }
-
- public int getAlpha() {
- return (int)(shape.getAlpha(EscherProperties.FILL__FILLOPACITY)*100000.0);
- }
- };
- }
+ case FILL_SHADE_SHAPE:
+ return getGradientPaint(GradientType.shape);
+ case FILL_SHADE_CENTER:
+ case FILL_SHADE_TITLE:
+ return getGradientPaint(GradientType.circular);
+ case FILL_SHADE:
+ case FILL_SHADE_SCALE:
+ return getGradientPaint(GradientType.linear);
+ case FILL_PICTURE:
+ return getTexturePaint();
default:
- logger.log(POILogger.WARN, "unsuported fill type: " + getFillType());
- break;
+ logger.log(POILogger.WARN, "unsuported fill type: " + fillType);
+ return null;
}
- return null;
}
};
}
+
+
+ private GradientPaint getGradientPaint(final GradientType gradientType) {
+ final AbstractEscherOptRecord opt = shape.getEscherOptRecord();
+ final EscherArrayProperty ep = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__SHADECOLORS);
+ final int colorCnt = (ep == null) ? 0 : ep.getNumberOfElementsInArray();
+
+ return new GradientPaint() {
+ public double getGradientAngle() {
+ // A value of type FixedPoint, as specified in [MS-OSHARED] section 2.2.1.6,
+ // that specifies the angle of the gradient fill. Zero degrees represents a vertical vector from
+ // bottom to top. The default value for this property is 0x00000000.
+ int rot = shape.getEscherProperty(EscherProperties.FILL__ANGLE);
+ return 90-Units.fixedPointToDouble(rot);
+ }
+ public ColorStyle[] getGradientColors() {
+ ColorStyle cs[];
+ if (colorCnt == 0) {
+ cs = new ColorStyle[2];
+ cs[0] = wrapColor(getBackgroundColor());
+ cs[1] = wrapColor(getForegroundColor());
+ } else {
+ cs = new ColorStyle[colorCnt];
+ int idx = 0;
+ // TODO: handle palette colors and alpha(?) value
+ for (byte data[] : ep) {
+ EscherColorRef ecr = new EscherColorRef(data, 0, 4);
+ cs[idx++] = wrapColor(shape.getColor(ecr));
+ }
+ }
+ return cs;
+ }
+ private ColorStyle wrapColor(Color col) {
+ return (col == null) ? null : DrawPaint.createSolidPaint(col).getSolidColor();
+ }
+ public float[] getGradientFractions() {
+ float frc[];
+ if (colorCnt == 0) {
+ frc = new float[]{0, 1};
+ } else {
+ frc = new float[colorCnt];
+ int idx = 0;
+ for (byte data[] : ep) {
+ double pos = Units.fixedPointToDouble(LittleEndian.getInt(data, 4));
+ frc[idx++] = (float)pos;
+ }
+ }
+ return frc;
+ }
+ public boolean isRotatedWithShape() {
+ return false;
+ }
+ public GradientType getGradientType() {
+ return gradientType;
+ }
+ };
+ }
+
+ private TexturePaint getTexturePaint() {
+ final HSLFPictureData pd = getPictureData();
+ if (pd == null) {
+ return null;
+ }
+
+ return new TexturePaint() {
+ public InputStream getImageData() {
+ return new ByteArrayInputStream(pd.getData());
+ }
+
+ public String getContentType() {
+ return pd.getContentType();
+ }
+
+ public int getAlpha() {
+ return (int)(shape.getAlpha(EscherProperties.FILL__FILLOPACITY)*100000.0);
+ }
+ };
+ }
+
/**
* Returns fill type.
* Must be one of the <code>FILL_*</code> constants defined in this class.
@@ -172,6 +251,7 @@ public final class HSLFFill {
}
}
+ @SuppressWarnings("resource")
protected EscherBSERecord getEscherBSERecord(int idx){
HSLFSheet sheet = shape.getSheet();
if(sheet == null) {
@@ -258,6 +338,7 @@ public final class HSLFFill {
/**
* <code>PictureData</code> object used in a texture, pattern of picture fill.
*/
+ @SuppressWarnings("resource")
public HSLFPictureData getPictureData(){
AbstractEscherOptRecord opt = shape.getEscherOptRecord();
EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java Wed Feb 24 22:43:51 2016
@@ -18,22 +18,25 @@
package org.apache.poi.hslf.usermodel;
import java.awt.geom.AffineTransform;
-import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
import org.apache.poi.ddf.AbstractEscherOptRecord;
import org.apache.poi.ddf.EscherArrayProperty;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherProperty;
import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.sl.usermodel.FreeformShape;
import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.Units;
@@ -57,6 +60,85 @@ public final class HSLFFreeformShape ext
public static final byte[] SEGMENTINFO_CLOSE = new byte[]{0x01, (byte)0x60};
public static final byte[] SEGMENTINFO_END = new byte[]{0x00, (byte)0x80};
+ private static BitField PATH_INFO = BitFieldFactory.getInstance(0xE000);
+ private static BitField ESCAPE_INFO = BitFieldFactory.getInstance(0x1F00);
+
+ enum PathInfo {
+ lineTo(0),curveTo(1),moveTo(2),close(3),end(4),escape(5),clientEscape(6);
+ int flag;
+ PathInfo(int flag) {
+ this.flag = flag;
+ }
+ static PathInfo valueOf(int flag) {
+ for (PathInfo v : values()) {
+ if (v.flag == flag) {
+ return v;
+ }
+ }
+ return null;
+ }
+ }
+
+ enum EscapeInfo {
+ EXTENSION(0x0000),
+ ANGLE_ELLIPSE_TO(0x0001),
+ ANGLE_ELLIPSE(0x0002),
+ ARC_TO(0x0003),
+ ARC(0x0004),
+ CLOCKWISE_ARC_TO(0x0005),
+ CLOCKWISE_ARC(0x0006),
+ ELLIPTICAL_QUADRANT_X(0x0007),
+ ELLIPTICAL_QUADRANT_Y(0x0008),
+ QUADRATIC_BEZIER(0x0009),
+ NO_FILL(0X000A),
+ NO_LINE(0X000B),
+ AUTO_LINE(0X000C),
+ AUTO_CURVE(0X000D),
+ CORNER_LINE(0X000E),
+ CORNER_CURVE(0X000F),
+ SMOOTH_LINE(0X0010),
+ SMOOTH_CURVE(0X0011),
+ SYMMETRIC_LINE(0X0012),
+ SYMMETRIC_CURVE(0X0013),
+ FREEFORM(0X0014),
+ FILL_COLOR(0X0015),
+ LINE_COLOR(0X0016);
+
+ int flag;
+ EscapeInfo(int flag) {
+ this.flag = flag;
+ }
+ static EscapeInfo valueOf(int flag) {
+ for (EscapeInfo v : values()) {
+ if (v.flag == flag) {
+ return v;
+ }
+ }
+ return null;
+ }
+ }
+
+ enum ShapePath {
+ LINES(0),
+ LINES_CLOSED(1),
+ CURVES(2),
+ CURVES_CLOSED(3),
+ COMPLEX(4);
+
+ int flag;
+ ShapePath(int flag) {
+ this.flag = flag;
+ }
+ static ShapePath valueOf(int flag) {
+ for (ShapePath v : values()) {
+ if (v.flag == flag) {
+ return v;
+ }
+ }
+ return null;
+ }
+ }
+
/**
* Create a Freeform object and initialize it from the supplied Record container.
*
@@ -88,7 +170,7 @@ public final class HSLFFreeformShape ext
}
@Override
- public int setPath(GeneralPath path) {
+ public int setPath(Path2D.Double path) {
Rectangle2D bounds = path.getBounds2D();
PathIterator it = path.getPathIterator(new AffineTransform());
@@ -174,23 +256,19 @@ public final class HSLFFreeformShape ext
opt.sortProperties();
setAnchor(bounds);
-
+
return numPoints;
}
@Override
- public GeneralPath getPath(){
+ public Path2D.Double getPath(){
AbstractEscherOptRecord opt = getEscherOptRecord();
- opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__SHAPEPATH, 0x4));
-
- EscherArrayProperty verticesProp = getEscherProperty(opt, (short)(EscherProperties.GEOMETRY__VERTICES + 0x4000));
- if(verticesProp == null) verticesProp = getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
- EscherArrayProperty segmentsProp = getEscherProperty(opt, (short)(EscherProperties.GEOMETRY__SEGMENTINFO + 0x4000));
- if(segmentsProp == null) segmentsProp = getEscherProperty(opt, EscherProperties.GEOMETRY__SEGMENTINFO);
+ EscherArrayProperty verticesProp = getShapeProp(opt, EscherProperties.GEOMETRY__VERTICES);
+ EscherArrayProperty segmentsProp = getShapeProp(opt, EscherProperties.GEOMETRY__SEGMENTINFO);
// return empty path if either GEOMETRY__VERTICES or GEOMETRY__SEGMENTINFO is missing, see Bugzilla 54188
- GeneralPath path = new GeneralPath();
+ Path2D.Double path = new Path2D.Double();
//sanity check
if(verticesProp == null) {
@@ -202,46 +280,60 @@ public final class HSLFFreeformShape ext
return path;
}
- int numPoints = verticesProp.getNumberOfElementsInArray();
- int numSegments = segmentsProp.getNumberOfElementsInArray();
- for (int i = 0, j = 0; i < numSegments && j < numPoints; i++) {
- byte[] elem = segmentsProp.getElement(i);
- if(Arrays.equals(elem, SEGMENTINFO_MOVETO)){
- byte[] p = verticesProp.getElement(j++);
- short x = LittleEndian.getShort(p, 0);
- short y = LittleEndian.getShort(p, 2);
- path.moveTo(Units.masterToPoints(x), Units.masterToPoints(y));
- } else if (Arrays.equals(elem, SEGMENTINFO_CUBICTO) || Arrays.equals(elem, SEGMENTINFO_CUBICTO2)){
- i++;
- byte[] p1 = verticesProp.getElement(j++);
- short x1 = LittleEndian.getShort(p1, 0);
- short y1 = LittleEndian.getShort(p1, 2);
- byte[] p2 = verticesProp.getElement(j++);
- short x2 = LittleEndian.getShort(p2, 0);
- short y2 = LittleEndian.getShort(p2, 2);
- byte[] p3 = verticesProp.getElement(j++);
- short x3 = LittleEndian.getShort(p3, 0);
- short y3 = LittleEndian.getShort(p3, 2);
- path.curveTo(
- Units.masterToPoints(x1), Units.masterToPoints(y1),
- Units.masterToPoints(x2), Units.masterToPoints(y2),
- Units.masterToPoints(x3), Units.masterToPoints(y3));
-
- } else if (Arrays.equals(elem, SEGMENTINFO_LINETO)){
- i++;
- byte[] pnext = segmentsProp.getElement(i);
- if(Arrays.equals(pnext, SEGMENTINFO_ESCAPE)){
- if(j + 1 < numPoints){
- byte[] p = verticesProp.getElement(j++);
- short x = LittleEndian.getShort(p, 0);
- short y = LittleEndian.getShort(p, 2);
- path.lineTo(Units.masterToPoints(x), Units.masterToPoints(y));
+ Iterator<byte[]> vertIter = verticesProp.iterator();
+ Iterator<byte[]> segIter = segmentsProp.iterator();
+
+ byte segPushBack[] = null;
+ while (vertIter.hasNext() && segIter.hasNext()) {
+ byte[] segElem = (segPushBack != null) ? segPushBack : segIter.next();
+ segPushBack = null;
+ PathInfo pi = getPathInfo(segElem);
+ switch (pi) {
+ case escape: {
+ handleEscapeInfo(path, segElem, vertIter);
+ break;
+ }
+ case moveTo: {
+ byte[] p = vertIter.next();
+ double x = Units.masterToPoints(LittleEndian.getShort(p, 0));
+ double y = Units.masterToPoints(LittleEndian.getShort(p, 2));
+ path.moveTo(x,y);
+ break;
+ }
+ case curveTo: {
+ byte[] p1 = vertIter.next();
+ double x1 = Units.masterToPoints(LittleEndian.getShort(p1, 0));
+ double y1 = Units.masterToPoints(LittleEndian.getShort(p1, 2));
+ byte[] p2 = vertIter.next();
+ double x2 = Units.masterToPoints(LittleEndian.getShort(p2, 0));
+ double y2 = Units.masterToPoints(LittleEndian.getShort(p2, 2));
+ byte[] p3 = vertIter.next();
+ double x3 = Units.masterToPoints(LittleEndian.getShort(p3, 0));
+ double y3 = Units.masterToPoints(LittleEndian.getShort(p3, 2));
+ path.curveTo(x1,y1,x2,y2,x3,y3);
+ break;
+ }
+ case lineTo:
+ if (vertIter.hasNext()) {
+ byte[] p = vertIter.next();
+ double x = Units.masterToPoints(LittleEndian.getShort(p, 0));
+ double y = Units.masterToPoints(LittleEndian.getShort(p, 2));
+ path.lineTo(x,y);
}
- } else if (Arrays.equals(pnext, SEGMENTINFO_CLOSE)){
+ break;
+ case close:
path.closePath();
- }
+ break;
+ default:
+ break;
}
}
+
+ EscherSimpleProperty shapePath = getShapeProp(opt, EscherProperties.GEOMETRY__SHAPEPATH);
+ ShapePath sp = ShapePath.valueOf(shapePath == null ? 1 : shapePath.getPropertyValue());
+ if (sp == ShapePath.LINES_CLOSED || sp == ShapePath.CURVES_CLOSED) {
+ path.closePath();
+ }
Rectangle2D anchor = getAnchor();
Rectangle2D bounds = path.getBounds2D();
@@ -251,6 +343,81 @@ public final class HSLFFreeformShape ext
anchor.getWidth()/bounds.getWidth(),
anchor.getHeight()/bounds.getHeight()
);
- return new GeneralPath(at.createTransformedShape(path));
+ return new Path2D.Double(at.createTransformedShape(path));
+ }
+
+ private static <T extends EscherProperty> T getShapeProp(AbstractEscherOptRecord opt, int propId) {
+ T prop = getEscherProperty(opt, (short)(propId + 0x4000));
+ if (prop == null) {
+ prop = getEscherProperty(opt, propId);
+ }
+ return prop;
+ }
+
+ private void handleEscapeInfo(Path2D path, byte segElem[], Iterator<byte[]> vertIter) {
+ EscapeInfo ei = getEscapeInfo(segElem);
+ switch (ei) {
+ case EXTENSION:
+ break;
+ case ANGLE_ELLIPSE_TO:
+ break;
+ case ANGLE_ELLIPSE:
+ break;
+ case ARC_TO:
+ break;
+ case ARC:
+ break;
+ case CLOCKWISE_ARC_TO:
+ break;
+ case CLOCKWISE_ARC:
+ break;
+ case ELLIPTICAL_QUADRANT_X:
+ break;
+ case ELLIPTICAL_QUADRANT_Y:
+ break;
+ case QUADRATIC_BEZIER:
+ break;
+ case NO_FILL:
+ break;
+ case NO_LINE:
+ break;
+ case AUTO_LINE:
+ break;
+ case AUTO_CURVE:
+ break;
+ case CORNER_LINE:
+ break;
+ case CORNER_CURVE:
+ break;
+ case SMOOTH_LINE:
+ break;
+ case SMOOTH_CURVE:
+ break;
+ case SYMMETRIC_LINE:
+ break;
+ case SYMMETRIC_CURVE:
+ break;
+ case FREEFORM:
+ break;
+ case FILL_COLOR:
+ break;
+ case LINE_COLOR:
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ private static PathInfo getPathInfo(byte elem[]) {
+ int elemUS = LittleEndian.getUShort(elem, 0);
+ int pathInfo = PATH_INFO.getValue(elemUS);
+ return PathInfo.valueOf(pathInfo);
+ }
+
+ private static EscapeInfo getEscapeInfo(byte elem[]) {
+ int elemUS = LittleEndian.getUShort(elem, 0);
+ int escInfo = ESCAPE_INFO.getValue(elemUS);
+ return EscapeInfo.valueOf(escInfo);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org