diff options
author | Yegor Kozlov <yegor@apache.org> | 2011-11-21 13:10:14 +0000 |
---|---|---|
committer | Yegor Kozlov <yegor@apache.org> | 2011-11-21 13:10:14 +0000 |
commit | 01039a9d79ed6fc5ff6a3cebb8be78572cfd5eaf (patch) | |
tree | fbf3c75b95de7b1b3a7eee392998347b0957ee48 /src | |
parent | e8a19023a1ad74f93313fbfa525f925e52d620f7 (diff) | |
download | poi-01039a9d79ed6fc5ff6a3cebb8be78572cfd5eaf.tar.gz poi-01039a9d79ed6fc5ff6a3cebb8be78572cfd5eaf.zip |
added missing definition of the upArrow shape, moved support for line decorations to XSLFSimpleShape
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1204477 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
7 files changed, 313 insertions, 311 deletions
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/PresetGeometries.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/PresetGeometries.java index 433c0cbe2f..62accc42f3 100644 --- a/src/ooxml/java/org/apache/poi/xslf/model/geom/PresetGeometries.java +++ b/src/ooxml/java/org/apache/poi/xslf/model/geom/PresetGeometries.java @@ -51,6 +51,9 @@ public class PresetGeometries extends LinkedHashMap<String, CustomGeometry> { String name = def.getDomNode().getLocalName(); CTCustomGeometry2D geom = CTCustomGeometry2D.Factory.parse(def.toString()); + if(containsKey(name)) { + System.out.println("Duplicate definoition of " + name) ; + } put(name, new CustomGeometry(geom)); } } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/RenderableShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/RenderableShape.java index c59ea6d1dd..21ab67124f 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/RenderableShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/RenderableShape.java @@ -120,7 +120,7 @@ class RenderableShape { else if (obj instanceof CTGradientFillProperties) {
CTGradientFillProperties gradFill = (CTGradientFillProperties) obj;
if (gradFill.isSetLin()) {
- paint = createLinearGradientPaint(gradFill, anchor, theme, phClr);
+ paint = createLinearGradientPaint(graphics, gradFill, anchor, theme, phClr);
} else if (gradFill.isSetPath()){
CTPathShadeProperties ps = gradFill.getPath();
if(ps.getPath() == STPathShadeType.CIRCLE){
@@ -166,6 +166,7 @@ class RenderableShape { }
private static Paint createLinearGradientPaint(
+ Graphics2D graphics,
CTGradientFillProperties gradFill, Rectangle2D anchor,
XSLFTheme theme, CTSchemeColor phClr) {
double angle = gradFill.getLin().getAng() / 60000;
@@ -204,13 +205,30 @@ class RenderableShape { fractions[i] = stop.getPos() / 100000.f;
}
+ AffineTransform grAt;
+ if(gradFill.getRotWithShape()) grAt = new AffineTransform();
+ else {
+ // gradient fill is not rotated with the shape
+ try {
+ grAt = graphics.getTransform().createInverse();
+ } catch (Exception e){
+ // should not happen.
+ grAt = new AffineTransform();
+ }
+ }
+
// Trick to return GradientPaint on JDK 1.5 and LinearGradientPaint on JDK 1.6+
Paint paint;
try {
Class clz = Class.forName("java.awt.LinearGradientPaint");
+ Class clzCycleMethod = Class.forName("java.awt.MultipleGradientPaint$CycleMethod");
+ Class clzColorSpaceType = Class.forName("java.awt.MultipleGradientPaint$ColorSpaceType");
Constructor c =
- clz.getConstructor(Point2D.class, Point2D.class, float[].class, Color[].class);
- paint = (Paint) c.newInstance(p1, p2, fractions, colors);
+ clz.getConstructor(Point2D.class, Point2D.class, float[].class, Color[].class,
+ clzCycleMethod, clzColorSpaceType, AffineTransform.class);
+ paint = (Paint) c.newInstance(p1, p2, fractions, colors,
+ Enum.valueOf(clzCycleMethod, "NO_CYCLE"),
+ Enum.valueOf(clzColorSpaceType, "SRGB"), grAt);
} catch (ClassNotFoundException e) {
paint = new GradientPaint(p1, colors[0], p2, colors[colors.length - 1]);
} catch (Exception e) {
@@ -504,9 +522,12 @@ class RenderableShape { }
private Collection<Outline> computeOutlines() {
- CustomGeometry geom = _shape.getGeometry();
Collection<Outline> lst = new ArrayList<Outline>();
+ CustomGeometry geom = _shape.getGeometry();
+ if(geom == null) {
+ return lst;
+ }
Rectangle2D anchor = _shape.getAnchor();
for (Path p : geom) {
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java index 5f4e838a0c..b880e5988d 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java @@ -80,4 +80,9 @@ public class XSLFAutoShape extends XSLFTextShape { }
return txBody;
}
+
+ @Override
+ public String toString(){
+ return "[" + getClass().getSimpleName() + "] " + getShapeName();
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java index cd3a925d54..3f7d88b870 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java @@ -75,262 +75,6 @@ public class XSLFConnectorShape extends XSLFSimpleShape { return ct;
}
- /**
- * Specifies the line end decoration, such as a triangle or arrowhead.
- */
- public void setLineHeadDecoration(LineDecoration style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
- if (style == null) {
- if (lnEnd.isSetType()) lnEnd.unsetType();
- } else {
- lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineDecoration getLineHeadDecoration() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetHeadEnd()) return LineDecoration.NONE;
-
- STLineEndType.Enum end = ln.getHeadEnd().getType();
- return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
- }
-
- /**
- * specifies decorations which can be added to the head of a line.
- */
- public void setLineHeadWidth(LineEndWidth style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
- if (style == null) {
- if (lnEnd.isSetW()) lnEnd.unsetW();
- } else {
- lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineEndWidth getLineHeadWidth() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetHeadEnd()) return LineEndWidth.MEDIUM;
-
- STLineEndWidth.Enum w = ln.getHeadEnd().getW();
- return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];
- }
-
- /**
- * Specifies the line end width in relation to the line width.
- */
- public void setLineHeadLength(LineEndLength style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
-
- if (style == null) {
- if (lnEnd.isSetLen()) lnEnd.unsetLen();
- } else {
- lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineEndLength getLineHeadLength() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetHeadEnd()) return LineEndLength.MEDIUM;
-
- STLineEndLength.Enum len = ln.getHeadEnd().getLen();
- return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
- }
-
- /**
- * Specifies the line end decoration, such as a triangle or arrowhead.
- */
- public void setLineTailDecoration(LineDecoration style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
- if (style == null) {
- if (lnEnd.isSetType()) lnEnd.unsetType();
- } else {
- lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineDecoration getLineTailDecoration() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetTailEnd()) return LineDecoration.NONE;
-
- STLineEndType.Enum end = ln.getTailEnd().getType();
- return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
- }
-
- /**
- * specifies decorations which can be added to the tail of a line.
- */
- public void setLineTailWidth(LineEndWidth style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
- if (style == null) {
- if (lnEnd.isSetW()) lnEnd.unsetW();
- } else {
- lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineEndWidth getLineTailWidth() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetTailEnd()) return LineEndWidth.MEDIUM;
-
- STLineEndWidth.Enum w = ln.getTailEnd().getW();
- return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];
- }
-
- /**
- * Specifies the line end width in relation to the line width.
- */
- public void setLineTailLength(LineEndLength style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
-
- if (style == null) {
- if (lnEnd.isSetLen()) lnEnd.unsetLen();
- } else {
- lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineEndLength getLineTailLength() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetTailEnd()) return LineEndLength.MEDIUM;
-
- STLineEndLength.Enum len = ln.getTailEnd().getLen();
- return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
- }
-
- Outline getTailDecoration() {
- LineEndLength tailLength = getLineTailLength();
- LineEndWidth tailWidth = getLineTailWidth();
-
- double lineWidth = Math.max(2.5, getLineWidth());
-
- Rectangle2D anchor = getAnchor();
- double x2 = anchor.getX() + anchor.getWidth(),
- y2 = anchor.getY() + anchor.getHeight();
-
- double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());
-
- AffineTransform at = new AffineTransform();
- Shape shape = null;
- Path p = null;
- Rectangle2D bounds;
- double scaleY = Math.pow(2, tailWidth.ordinal());
- double scaleX = Math.pow(2, tailLength.ordinal());
- switch (getLineTailDecoration()) {
- case OVAL:
- p = new Path();
- shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
- bounds = shape.getBounds2D();
- at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2);
- at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
- break;
- case ARROW:
- p = new Path();
- GeneralPath arrow = new GeneralPath();
- arrow.moveTo((float) (-lineWidth * 3), (float) (-lineWidth * 2));
- arrow.lineTo(0, 0);
- arrow.lineTo((float) (-lineWidth * 3), (float) (lineWidth * 2));
- shape = arrow;
- at.translate(x2, y2);
- at.rotate(alpha);
- break;
- case TRIANGLE:
- p = new Path();
- scaleY = tailWidth.ordinal() + 1;
- scaleX = tailLength.ordinal() + 1;
- GeneralPath triangle = new GeneralPath();
- triangle.moveTo((float) (-lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
- triangle.lineTo(0, 0);
- triangle.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
- triangle.closePath();
- shape = triangle;
- at.translate(x2, y2);
- at.rotate(alpha);
- break;
- default:
- break;
- }
-
- if (shape != null) {
- shape = at.createTransformedShape(shape);
- }
- return shape == null ? null : new Outline(shape, p);
- }
-
- Outline getHeadDecoration() {
- LineEndLength headLength = getLineHeadLength();
- LineEndWidth headWidth = getLineHeadWidth();
-
- double lineWidth = Math.max(2.5, getLineWidth());
- Rectangle2D anchor = getAnchor();
- double x1 = anchor.getX(),
- y1 = anchor.getY();
-
- double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());
-
- AffineTransform at = new AffineTransform();
- Shape shape = null;
- Path p = null;
- Rectangle2D bounds;
- double scaleY = 1;
- double scaleX = 1;
- switch (getLineHeadDecoration()) {
- case OVAL:
- p = new Path();
- shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
- bounds = shape.getBounds2D();
- at.translate(x1 - bounds.getWidth() / 2, y1 - bounds.getHeight() / 2);
- at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
- break;
- case STEALTH:
- case ARROW:
- p = new Path(false, true);
- GeneralPath arrow = new GeneralPath();
- arrow.moveTo((float) (lineWidth * 3 * scaleX), (float) (-lineWidth * scaleY * 2));
- arrow.lineTo(0, 0);
- arrow.lineTo((float) (lineWidth * 3 * scaleX), (float) (lineWidth * scaleY * 2));
- shape = arrow;
- at.translate(x1, y1);
- at.rotate(alpha);
- break;
- case TRIANGLE:
- p = new Path();
- scaleY = headWidth.ordinal() + 1;
- scaleX = headLength.ordinal() + 1;
- GeneralPath triangle = new GeneralPath();
- triangle.moveTo((float) (lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
- triangle.lineTo(0, 0);
- triangle.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
- triangle.closePath();
- shape = triangle;
- at.translate(x1, y1);
- at.rotate(alpha);
- break;
- default:
- break;
- }
-
- if (shape != null) {
- shape = at.createTransformedShape(shape);
- }
- return shape == null ? null : new Outline(shape, p);
- }
-
- private List<Outline> getDecorationOutlines(){
- List<Outline> lst = new ArrayList<Outline>();
-
- Outline head = getHeadDecoration();
- if(head != null) lst.add(head);
-
- Outline tail = getTailDecoration();
- if(tail != null) lst.add(tail);
- return lst;
- }
/**
* YK: dashing of lines is suppressed for now.
@@ -341,22 +85,4 @@ public class XSLFConnectorShape extends XSLFSimpleShape { return null;
}
- @Override
- public void draw(Graphics2D graphics){
- super.draw(graphics);
-
- // draw line decorations
- Color lineColor = getLineColor();
- if(lineColor != null) {
- graphics.setPaint(lineColor);
- for(Outline o : getDecorationOutlines()){
- if(o.getPath().isFilled()){
- graphics.fill(o.getOutline());
- }
- if(o.getPath().isStroked()){
- graphics.draw(o.getOutline());
- }
- }
- }
- }
}
\ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java index 92adf446e0..16ecef8623 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java @@ -35,25 +35,7 @@ import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.POIXMLException;
import org.apache.xmlbeans.XmlObject;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
-import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
-import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
+import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
@@ -63,8 +45,10 @@ import java.awt.Graphics2D; import java.awt.Paint;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -555,6 +539,20 @@ public abstract class XSLFSimpleShape extends XSLFShape { public void draw(Graphics2D graphics) {
RenderableShape rShape = new RenderableShape(this);
rShape.render(graphics);
+
+ // draw line decorations
+ Color lineColor = getLineColor();
+ if(lineColor != null) {
+ graphics.setPaint(lineColor);
+ for(Outline o : getDecorationOutlines()){
+ if(o.getPath().isFilled()){
+ graphics.fill(o.getOutline());
+ }
+ if(o.getPath().isStroked()){
+ graphics.draw(o.getOutline());
+ }
+ }
+ }
}
@@ -696,4 +694,262 @@ public abstract class XSLFSimpleShape extends XSLFShape { }
}
+
+ /**
+ * Specifies the line end decoration, such as a triangle or arrowhead.
+ */
+ public void setLineHeadDecoration(LineDecoration style) {
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
+ if (style == null) {
+ if (lnEnd.isSetType()) lnEnd.unsetType();
+ } else {
+ lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineDecoration getLineHeadDecoration() {
+ CTLineProperties ln = getSpPr().getLn();
+ if (ln == null || !ln.isSetHeadEnd()) return LineDecoration.NONE;
+
+ STLineEndType.Enum end = ln.getHeadEnd().getType();
+ return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
+ }
+
+ /**
+ * specifies decorations which can be added to the head of a line.
+ */
+ public void setLineHeadWidth(LineEndWidth style) {
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
+ if (style == null) {
+ if (lnEnd.isSetW()) lnEnd.unsetW();
+ } else {
+ lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineEndWidth getLineHeadWidth() {
+ CTLineProperties ln = getSpPr().getLn();
+ if (ln == null || !ln.isSetHeadEnd()) return LineEndWidth.MEDIUM;
+
+ STLineEndWidth.Enum w = ln.getHeadEnd().getW();
+ return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];
+ }
+
+ /**
+ * Specifies the line end width in relation to the line width.
+ */
+ public void setLineHeadLength(LineEndLength style) {
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
+
+ if (style == null) {
+ if (lnEnd.isSetLen()) lnEnd.unsetLen();
+ } else {
+ lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineEndLength getLineHeadLength() {
+ CTLineProperties ln = getSpPr().getLn();
+ if (ln == null || !ln.isSetHeadEnd()) return LineEndLength.MEDIUM;
+
+ STLineEndLength.Enum len = ln.getHeadEnd().getLen();
+ return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
+ }
+
+ /**
+ * Specifies the line end decoration, such as a triangle or arrowhead.
+ */
+ public void setLineTailDecoration(LineDecoration style) {
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
+ if (style == null) {
+ if (lnEnd.isSetType()) lnEnd.unsetType();
+ } else {
+ lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineDecoration getLineTailDecoration() {
+ CTLineProperties ln = getSpPr().getLn();
+ if (ln == null || !ln.isSetTailEnd()) return LineDecoration.NONE;
+
+ STLineEndType.Enum end = ln.getTailEnd().getType();
+ return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
+ }
+
+ /**
+ * specifies decorations which can be added to the tail of a line.
+ */
+ public void setLineTailWidth(LineEndWidth style) {
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
+ if (style == null) {
+ if (lnEnd.isSetW()) lnEnd.unsetW();
+ } else {
+ lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineEndWidth getLineTailWidth() {
+ CTLineProperties ln = getSpPr().getLn();
+ if (ln == null || !ln.isSetTailEnd()) return LineEndWidth.MEDIUM;
+
+ STLineEndWidth.Enum w = ln.getTailEnd().getW();
+ return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];
+ }
+
+ /**
+ * Specifies the line end width in relation to the line width.
+ */
+ public void setLineTailLength(LineEndLength style) {
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
+
+ if (style == null) {
+ if (lnEnd.isSetLen()) lnEnd.unsetLen();
+ } else {
+ lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineEndLength getLineTailLength() {
+ CTLineProperties ln = getSpPr().getLn();
+ if (ln == null || !ln.isSetTailEnd()) return LineEndLength.MEDIUM;
+
+ STLineEndLength.Enum len = ln.getTailEnd().getLen();
+ return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
+ }
+
+ Outline getTailDecoration() {
+ LineEndLength tailLength = getLineTailLength();
+ LineEndWidth tailWidth = getLineTailWidth();
+
+ double lineWidth = Math.max(2.5, getLineWidth());
+
+ Rectangle2D anchor = getAnchor();
+ double x2 = anchor.getX() + anchor.getWidth(),
+ y2 = anchor.getY() + anchor.getHeight();
+
+ double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());
+
+ AffineTransform at = new AffineTransform();
+ Shape shape = null;
+ Path p = null;
+ Rectangle2D bounds;
+ double scaleY = Math.pow(2, tailWidth.ordinal());
+ double scaleX = Math.pow(2, tailLength.ordinal());
+ switch (getLineTailDecoration()) {
+ case OVAL:
+ p = new Path();
+ shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
+ bounds = shape.getBounds2D();
+ at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2);
+ at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
+ break;
+ case ARROW:
+ p = new Path();
+ GeneralPath arrow = new GeneralPath();
+ arrow.moveTo((float) (-lineWidth * 3), (float) (-lineWidth * 2));
+ arrow.lineTo(0, 0);
+ arrow.lineTo((float) (-lineWidth * 3), (float) (lineWidth * 2));
+ shape = arrow;
+ at.translate(x2, y2);
+ at.rotate(alpha);
+ break;
+ case TRIANGLE:
+ p = new Path();
+ scaleY = tailWidth.ordinal() + 1;
+ scaleX = tailLength.ordinal() + 1;
+ GeneralPath triangle = new GeneralPath();
+ triangle.moveTo((float) (-lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
+ triangle.lineTo(0, 0);
+ triangle.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
+ triangle.closePath();
+ shape = triangle;
+ at.translate(x2, y2);
+ at.rotate(alpha);
+ break;
+ default:
+ break;
+ }
+
+ if (shape != null) {
+ shape = at.createTransformedShape(shape);
+ }
+ return shape == null ? null : new Outline(shape, p);
+ }
+
+ Outline getHeadDecoration() {
+ LineEndLength headLength = getLineHeadLength();
+ LineEndWidth headWidth = getLineHeadWidth();
+
+ double lineWidth = Math.max(2.5, getLineWidth());
+ Rectangle2D anchor = getAnchor();
+ double x1 = anchor.getX(),
+ y1 = anchor.getY();
+
+ double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());
+
+ AffineTransform at = new AffineTransform();
+ Shape shape = null;
+ Path p = null;
+ Rectangle2D bounds;
+ double scaleY = 1;
+ double scaleX = 1;
+ switch (getLineHeadDecoration()) {
+ case OVAL:
+ p = new Path();
+ shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
+ bounds = shape.getBounds2D();
+ at.translate(x1 - bounds.getWidth() / 2, y1 - bounds.getHeight() / 2);
+ at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
+ break;
+ case STEALTH:
+ case ARROW:
+ p = new Path(false, true);
+ GeneralPath arrow = new GeneralPath();
+ arrow.moveTo((float) (lineWidth * 3 * scaleX), (float) (-lineWidth * scaleY * 2));
+ arrow.lineTo(0, 0);
+ arrow.lineTo((float) (lineWidth * 3 * scaleX), (float) (lineWidth * scaleY * 2));
+ shape = arrow;
+ at.translate(x1, y1);
+ at.rotate(alpha);
+ break;
+ case TRIANGLE:
+ p = new Path();
+ scaleY = headWidth.ordinal() + 1;
+ scaleX = headLength.ordinal() + 1;
+ GeneralPath triangle = new GeneralPath();
+ triangle.moveTo((float) (lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
+ triangle.lineTo(0, 0);
+ triangle.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
+ triangle.closePath();
+ shape = triangle;
+ at.translate(x1, y1);
+ at.rotate(alpha);
+ break;
+ default:
+ break;
+ }
+
+ if (shape != null) {
+ shape = at.createTransformedShape(shape);
+ }
+ return shape == null ? null : new Outline(shape, p);
+ }
+
+ private List<Outline> getDecorationOutlines(){
+ List<Outline> lst = new ArrayList<Outline>();
+
+ Outline head = getHeadDecoration();
+ if(head != null) lst.add(head);
+
+ Outline tail = getTailDecoration();
+ if(tail != null) lst.add(tail);
+ return lst;
+ }
+
}
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/geom/TestPresetGeometries.java b/src/ooxml/testcases/org/apache/poi/xslf/geom/TestPresetGeometries.java index 7f5e967ccc..50a66667ab 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/geom/TestPresetGeometries.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/geom/TestPresetGeometries.java @@ -39,7 +39,7 @@ public class TestPresetGeometries extends TestCase { public void testRead(){ Map<String, CustomGeometry> shapes = PresetGeometries.getInstance(); - assertEquals(186, shapes.size()); + assertEquals(187, shapes.size()); for(String name : shapes.keySet()) { diff --git a/src/resources/ooxml/org/apache/poi/xslf/usermodel/presetShapeDefinitions.xml b/src/resources/ooxml/org/apache/poi/xslf/usermodel/presetShapeDefinitions.xml index f5fead717f..4a3a0701d3 100755 --- a/src/resources/ooxml/org/apache/poi/xslf/usermodel/presetShapeDefinitions.xml +++ b/src/resources/ooxml/org/apache/poi/xslf/usermodel/presetShapeDefinitions.xml @@ -18822,7 +18822,7 @@ </pathLst>
</upArrowCallout>
- <upDownArrow>
+ <upArrow>
<avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
<gd name="adj1" fmla="val 50000" />
<gd name="adj2" fmla="val 50000" />
@@ -18890,19 +18890,10 @@ <pt x="x2" y="y2" />
</lnTo>
<lnTo>
- <pt x="x2" y="y3" />
- </lnTo>
- <lnTo>
- <pt x="r" y="y3" />
- </lnTo>
- <lnTo>
- <pt x="hc" y="b" />
- </lnTo>
- <lnTo>
- <pt x="l" y="y3" />
+ <pt x="x2" y="b" />
</lnTo>
<lnTo>
- <pt x="x1" y="y3" />
+ <pt x="x1" y="b" />
</lnTo>
<lnTo>
<pt x="x1" y="y2" />
@@ -18910,7 +18901,7 @@ <close />
</path>
</pathLst>
- </upDownArrow>
+ </upArrow>
<upDownArrow>
<avLst xmlns="http://schemas.openxmlformats.org/drawingml/2006/main">
<gd name="adj1" fmla="val 50000" />
|