]> source.dussan.org Git - poi.git/commitdiff
support for preset shape geometries in xslf
authorYegor Kozlov <yegor@apache.org>
Wed, 26 Oct 2011 10:10:05 +0000 (10:10 +0000)
committerYegor Kozlov <yegor@apache.org>
Wed, 26 Oct 2011 10:10:05 +0000 (10:10 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1189105 13f79535-47bb-0310-9956-ffa450edef68

42 files changed:
src/ooxml/java/org/apache/poi/xslf/model/geom/AbsExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/AddDivideExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/AddSubtractExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/AdjustValue.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/ArcTanExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/ArcToCommand.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/ClosePathCommand.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/Context.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/CosExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/CosineArcTanExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/CurveToCommand.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/CustomGeometry.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/Expression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/ExpressionParser.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/Formula.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/Guide.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/IAdjustableShape.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/IfElseExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/LineToCommand.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/LiteralValueExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/MaxExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/MinExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/ModExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/MoveToCommand.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/MultiplyDivideExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/Path.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/PathCommand.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/PinExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/PresetGeometries.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/QuadToCommand.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/SinArcTanExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/SinExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/SqrtExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/geom/TanExpression.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPresetGeometry.java [deleted file]
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
src/ooxml/testcases/org/apache/poi/xslf/geom/TestFormulaParser.java [new file with mode: 0644]
src/ooxml/testcases/org/apache/poi/xslf/geom/TestPresetGeometries.java [new file with mode: 0644]
src/resources/scratchpad/org/apache/poi/xslf/usermodel/presetShapeDefinitions.xml

diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/AbsExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/AbsExpression.java
new file mode 100644 (file)
index 0000000..5790e53
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Absolute Value Formula
+ *
+ * @author Yegor Kozlov
+ */
+public class AbsExpression implements Expression {
+    private String arg;
+
+    AbsExpression(Matcher m){
+        arg = m.group(1);
+    }
+
+    public double evaluate(Context ctx){
+        double val = ctx.getValue(arg);
+        return Math.abs(val);
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/AddDivideExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/AddDivideExpression.java
new file mode 100644 (file)
index 0000000..7fe14e8
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Add Divide Formula
+ *
+ * @author Yegor Kozlov
+ */
+public class AddDivideExpression implements Expression {
+    private String arg1, arg2, arg3;
+
+    AddDivideExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+        arg3 = m.group(3);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        double z = ctx.getValue(arg3);
+        return (x + y ) / z;
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/AddSubtractExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/AddSubtractExpression.java
new file mode 100644 (file)
index 0000000..bd7e47e
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Add Subtract Formula
+ *
+ * @author Yegor Kozlov
+ */
+public class AddSubtractExpression implements Expression {
+    private String arg1, arg2, arg3;
+
+    AddSubtractExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+        arg3 = m.group(3);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        double z = ctx.getValue(arg3);
+        return (x + y ) - z;
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/AdjustValue.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/AdjustValue.java
new file mode 100644 (file)
index 0000000..8df1d6f
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide;
+
+/**
+ * Represents a shape adjust values (see section 20.1.9.5 in the spec)
+ *
+ * @author Yegor Kozlov
+ */
+public class AdjustValue extends Guide {
+
+    public AdjustValue(CTGeomGuide gd) {
+        super(gd.getName(), gd.getFmla());
+    }
+
+    @Override
+    public double evaluate(Context ctx){
+        String name = getName();
+        Guide adj = ctx.getAdjustValue(name);
+        if(adj != null) {
+            return adj.evaluate(ctx);
+        }
+        return super.evaluate(ctx);
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/ArcTanExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/ArcTanExpression.java
new file mode 100644 (file)
index 0000000..252c0fc
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Date: 10/24/11
+ *
+ * @author Yegor Kozlov
+ */
+public class ArcTanExpression implements Expression {
+    private String arg1, arg2;
+
+    ArcTanExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        return Math.atan(y / x);
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/ArcToCommand.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/ArcToCommand.java
new file mode 100644 (file)
index 0000000..9b2e1bc
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DArcTo;
+
+import java.awt.geom.Arc2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+
+/**
+ * ArcTo command within a shape path in DrawingML:
+ *
+ * <arcTo wR="wr" hR="hr" stAng="stAng" swAng="swAng"/>
+ *
+ * Where <code>wr</code> and <code>wh</code> are the height and width radiuses
+ * of the supposed circle being used to draw the arc.  This gives the circle
+ * a total height of (2 * hR)  and a total width of (2 * wR)
+ *
+ * stAng is the <code>start</code> angle and <code></>swAng</code> is the swing angle
+ *
+ * @author Yegor Kozlov
+ */
+public class ArcToCommand implements PathCommand {
+    private String hr, wr, stAng, swAng;
+
+    ArcToCommand(CTPath2DArcTo arc){
+        hr = arc.getHR().toString();
+        wr = arc.getWR().toString();
+        stAng = arc.getStAng().toString();
+        swAng = arc.getSwAng().toString();
+    }
+
+    public void execute(GeneralPath path, Context ctx){
+        double rx = ctx.getValue(wr);
+        double ry = ctx.getValue(hr);
+        double start = ctx.getValue(stAng) / 60000;
+        double extent = ctx.getValue(swAng) / 60000;
+        Point2D pt = path.getCurrentPoint();
+        double x0 = pt.getX() - rx - rx * Math.cos(Math.toRadians(start));
+        double y0 = pt.getY() - ry - ry * Math.sin(Math.toRadians(start));
+
+        if(start == 180 && extent == 180) {
+            x0 -= rx*2;   //YK: TODO revisit the code and get rid of this hack
+        }
+
+        Arc2D arc = new Arc2D.Double(
+                         x0,
+                         y0,
+                         2 * rx, 2 * ry,
+                         -start, -extent, // negate angles because DrawingML rotates counter-clockwise
+                         Arc2D.OPEN);
+               path.append(arc, true);
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/ClosePathCommand.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/ClosePathCommand.java
new file mode 100644 (file)
index 0000000..b9a9540
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.awt.geom.GeneralPath;
+
+/**
+ * Date: 10/25/11
+ *
+ * @author Yegor Kozlov
+ */
+public class ClosePathCommand implements PathCommand {
+
+    ClosePathCommand(){
+    }
+
+    public void execute(GeneralPath path, Context ctx){
+        path.closePath();
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/Context.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/Context.java
new file mode 100644 (file)
index 0000000..230524c
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.awt.geom.Rectangle2D;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Date: 10/24/11
+ *
+ * @author Yegor Kozlov
+ */
+public class Context {
+    Map<String, Double> _ctx = new HashMap<String, Double>();
+    IAdjustableShape _props;
+
+   public Context(CustomGeometry geom, IAdjustableShape props){
+        _props = props;
+        for(Guide gd : geom.adjusts) evaluate(gd);
+        for(Guide gd : geom.guides) evaluate(gd);
+    }
+
+    public Rectangle2D getShapeAnchor(){
+        return _props.getAnchor();
+    }
+
+    public Guide getAdjustValue(String name){
+        return _props.getAdjustValue(name);
+    }
+
+    public double getValue(String key){
+        if(key.matches("(\\+|-)?\\d+")){
+            return Double.parseDouble(key);
+        }
+
+        Formula builtIn = Formula.builtInFormulas.get(key);
+        if(builtIn != null){
+            return builtIn.evaluate(this);
+        }
+
+        if(!_ctx.containsKey(key)) {
+            throw new RuntimeException("undefined variable: " + key);
+        }
+
+        return _ctx.get(key);
+    }
+
+    public double evaluate(Formula fmla){
+        double result = fmla.evaluate(this);
+        String key = fmla.getName();
+        if(key != null) _ctx.put(key, result);
+        return result;
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/CosExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/CosExpression.java
new file mode 100644 (file)
index 0000000..47e38f1
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Date: 10/24/11
+ *
+ * @author Yegor Kozlov
+ */
+public class CosExpression implements Expression {
+    private String arg1, arg2;
+
+    CosExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2)/ 60000;
+        return x * Math.cos(Math.toRadians(y));
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/CosineArcTanExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/CosineArcTanExpression.java
new file mode 100644 (file)
index 0000000..cb9928b
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Date: 10/24/11
+ *
+ * @author Yegor Kozlov
+ */
+public class CosineArcTanExpression implements Expression {
+    private String arg1, arg2, arg3;
+
+    CosineArcTanExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+        arg3 = m.group(3);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        double z = ctx.getValue(arg3);
+        return x*Math.cos(Math.atan(z / y));
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/CurveToCommand.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/CurveToCommand.java
new file mode 100644 (file)
index 0000000..dcfde7e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import org.openxmlformats.schemas.drawingml.x2006.main.CTAdjPoint2D;
+
+import java.awt.geom.GeneralPath;
+
+/**
+ * Date: 10/25/11
+ *
+ * @author Yegor Kozlov
+ */
+public class CurveToCommand implements PathCommand {
+    private String arg1, arg2, arg3, arg4, arg5, arg6;
+
+    CurveToCommand(CTAdjPoint2D pt1, CTAdjPoint2D pt2, CTAdjPoint2D pt3){
+        arg1 = pt1.getX().toString();
+        arg2 = pt1.getY().toString();
+        arg3 = pt2.getX().toString();
+        arg4 = pt2.getY().toString();
+        arg5 = pt3.getX().toString();
+        arg6 = pt3.getY().toString();
+    }
+
+    public void execute(GeneralPath 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(x1, y1, x2, y2, x3, y3);
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/CustomGeometry.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/CustomGeometry.java
new file mode 100644 (file)
index 0000000..7507f55
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import org.openxmlformats.schemas.drawingml.x2006.main.*;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Definition of a custom geometric shape
+ *
+ * @author Yegor Kozlov
+ */
+public class CustomGeometry implements Iterable<Path>{
+    List<Guide> adjusts = new ArrayList<Guide>();
+    List<Guide> guides = new ArrayList<Guide>();
+    List<Path> paths = new ArrayList<Path>();
+
+    public CustomGeometry(CTCustomGeometry2D geom){
+        CTGeomGuideList avLst = geom.getAvLst();
+        if(avLst != null) for(CTGeomGuide gd : avLst.getGdList()){
+            adjusts.add(new AdjustValue(gd));
+        }
+
+        CTGeomGuideList gdLst = geom.getGdLst();
+        if(gdLst != null) for(CTGeomGuide gd : gdLst.getGdList()){
+            guides.add(new Guide(gd));
+        }
+
+        CTPath2DList pathLst = geom.getPathLst();
+        if(pathLst != null) for(CTPath2D spPath : pathLst.getPathList()){
+            paths.add(new Path(spPath));
+        }
+    }
+
+
+
+    public Iterator<Path> iterator() {
+        return paths.iterator();
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/Expression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/Expression.java
new file mode 100644 (file)
index 0000000..2b0f751
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+/**
+ * Date: 10/24/11
+ *
+ * @author Yegor Kozlov
+ */
+public interface Expression {
+
+    double evaluate(Context ctx);
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/ExpressionParser.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/ExpressionParser.java
new file mode 100644 (file)
index 0000000..699f995
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A simple regexp-based parser of shape guide formulas in DrawingML
+ *
+ * @author Yegor Kozlov
+ */
+public class ExpressionParser {
+    static final HashMap<String, Class> impls = new HashMap<String, Class>();
+    static {
+        impls.put("\\*/ +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", MultiplyDivideExpression.class);
+        impls.put("\\+- +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)( 0)?", AddSubtractExpression.class);
+        impls.put("\\+/ +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", AddDivideExpression.class);
+        impls.put("\\?: +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", IfElseExpression.class);
+        impls.put("val +([\\-\\w]+)", LiteralValueExpression.class);
+        impls.put("abs +([\\-\\w]+)", AbsExpression.class);
+        impls.put("sqrt +([\\-\\w]+)", SqrtExpression.class);
+        impls.put("max +([\\-\\w]+) +([\\-\\w]+)", MaxExpression.class);
+        impls.put("min +([\\-\\w]+) +([\\-\\w]+)", MinExpression.class);
+        impls.put("at2 +([\\-\\w]+) +([\\-\\w]+)", ArcTanExpression.class);
+        impls.put("sin +([\\-\\w]+) +([\\-\\w]+)", SinExpression.class);
+        impls.put("cos +([\\-\\w]+) +([\\-\\w]+)", CosExpression.class);
+        impls.put("tan +([\\-\\w]+) +([\\-\\w]+)", TanExpression.class);
+        impls.put("cat2 +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", CosineArcTanExpression.class);
+        impls.put("sat2 +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", SinArcTanExpression.class);
+        impls.put("pin +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", PinExpression.class);
+        impls.put("mod +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", ModExpression.class);
+
+    }
+
+    public static Expression parse(String str){
+        for(String regexp : impls.keySet()) {
+            Pattern ptrn = Pattern.compile(regexp);
+            Matcher m = ptrn.matcher(str);
+            if(m.matches()) {
+                Class c = impls.get(regexp);
+                try {
+                    return (Expression)c.getDeclaredConstructor(Matcher.class).newInstance(m);
+                } catch (Exception e){
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+        throw new RuntimeException("Unsupported formula: " + str);
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/Formula.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/Formula.java
new file mode 100644 (file)
index 0000000..a0ba201
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.awt.geom.Rectangle2D;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A guide formula in DrawingML.
+ * This is a base class for adjust values, geometric guides and bilt-in guides
+ *
+ * @author Yegor Kozlov
+ */
+public abstract class Formula {
+
+    String getName(){
+        return null;
+    }
+
+    abstract double evaluate(Context ctx);
+
+    static Map<String, Formula> builtInFormulas = new HashMap<String, Formula>();
+    static {
+        // 3 x 360¡ / 4 = 270¡
+        builtInFormulas.put("3cd4",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return 270 * 60000;
+            }
+
+         });
+
+        // 3 x 360¡ / 8 = 135¡
+        builtInFormulas.put("3cd8",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return 135 * 60000;
+            }
+
+         });
+
+        // 5 x 360¡ / 8 = 225¡
+        builtInFormulas.put("5cd8",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return 270 * 60000;
+            }
+
+         });
+
+        // 7 x 360¡ / 8 = 315¡
+        builtInFormulas.put("7cd8",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return 270 * 60000;
+            }
+
+         });
+
+        // bottom
+        builtInFormulas.put("b",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getY() + anchor.getHeight();
+            }
+
+         });
+
+        // 360¡ / 2 = 180¡
+        builtInFormulas.put("cd2",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return 180 * 60000;
+            }
+
+         });
+
+        // 360¡ / 4 = 90¡
+        builtInFormulas.put("cd4",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return 90 * 60000;
+            }
+
+         });
+
+        // 360¡ / 8 = 45¡
+        builtInFormulas.put("cd8",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return 45 * 60000;
+            }
+
+         });
+
+        // horizontal center
+        builtInFormulas.put("hc",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getX() + anchor.getWidth()/2;
+            }
+
+         });
+
+        // height
+        builtInFormulas.put("h",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getHeight();
+            }
+
+         });
+
+        // height / 2
+        builtInFormulas.put("hd2",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getHeight()/2;
+            }
+
+         });
+
+        // height / 3
+        builtInFormulas.put("hd3",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getHeight()/3;
+            }
+
+         });
+
+        // height / 4
+        builtInFormulas.put("hd4",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getHeight()/4;
+            }
+
+         });
+
+        // height / 5
+        builtInFormulas.put("hd5",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getHeight()/5;
+            }
+
+         });
+
+        // height / 6
+        builtInFormulas.put("hd6",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getHeight()/6;
+            }
+
+         });
+
+        // height / 8
+        builtInFormulas.put("hd8",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getHeight()/8;
+            }
+
+         });
+
+        // left
+        builtInFormulas.put("l",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getX();
+            }
+
+         });
+
+        // long side
+        builtInFormulas.put("ls",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return Math.max(anchor.getWidth(), anchor.getHeight());
+            }
+
+         });
+
+        // right
+        builtInFormulas.put("r",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getX() + anchor.getWidth();
+            }
+
+         });
+
+        // short side
+        builtInFormulas.put("ss",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return Math.min(anchor.getWidth(), anchor.getHeight());
+            }
+
+         });
+
+        // short side / 2
+        builtInFormulas.put("ssd2",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                double ss = Math.min(anchor.getWidth(), anchor.getHeight());
+                return ss / 2;
+            }
+         });
+
+        // short side / 4
+        builtInFormulas.put("ssd4",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                double ss = Math.min(anchor.getWidth(), anchor.getHeight());
+                return ss / 4;
+            }
+         });
+
+        // short side / 6
+        builtInFormulas.put("ssd6",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                double ss = Math.min(anchor.getWidth(), anchor.getHeight());
+                return ss / 6;
+            }
+         });
+
+        // short side / 8
+        builtInFormulas.put("ssd8",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                double ss = Math.min(anchor.getWidth(), anchor.getHeight());
+                return ss / 8;
+            }
+         });
+
+        // short side / 16
+        builtInFormulas.put("ssd16",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                double ss = Math.min(anchor.getWidth(), anchor.getHeight());
+                return ss / 16;
+            }
+         });
+
+        // short side / 32
+        builtInFormulas.put("ssd32",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                double ss = Math.min(anchor.getWidth(), anchor.getHeight());
+                return ss / 32;
+            }
+         });
+
+        // top
+        builtInFormulas.put("t",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return ctx.getShapeAnchor().getY();
+            }
+         });
+
+        // vertical center
+        builtInFormulas.put("vc",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                Rectangle2D anchor = ctx.getShapeAnchor();
+                return anchor.getY() + anchor.getHeight()/2;
+            }
+         });
+
+        // width
+        builtInFormulas.put("w",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return ctx.getShapeAnchor().getWidth();
+            }
+         });
+
+        // width / 2
+        builtInFormulas.put("wd2",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return ctx.getShapeAnchor().getWidth()/2;
+            }
+         });
+
+        // width / 3
+        builtInFormulas.put("wd3",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return ctx.getShapeAnchor().getWidth()/3;
+            }
+         });
+
+        // width / 4
+        builtInFormulas.put("wd4",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return ctx.getShapeAnchor().getWidth()/4;
+            }
+         });
+
+        // width / 5
+        builtInFormulas.put("wd5",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return ctx.getShapeAnchor().getWidth()/5;
+            }
+         });
+
+        // width / 6
+        builtInFormulas.put("wd6",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return ctx.getShapeAnchor().getWidth()/6;
+            }
+         });
+
+        // width / 8
+        builtInFormulas.put("wd8",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return ctx.getShapeAnchor().getWidth()/8;
+            }
+         });
+
+        // width / 10
+        builtInFormulas.put("wd10",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return ctx.getShapeAnchor().getWidth()/10;
+            }
+         });
+
+        // width / 32
+        builtInFormulas.put("wd32",  new Formula(){
+            @Override
+            double evaluate(Context ctx){
+                return ctx.getShapeAnchor().getWidth()/32;
+            }
+         });
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/Guide.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/Guide.java
new file mode 100644 (file)
index 0000000..584e224
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide;
+
+/**
+ * Date: 10/24/11
+ *
+ * @author Yegor Kozlov
+ */
+public class Guide extends Formula {
+    private String name, fmla;
+    private Expression expr;
+
+    public Guide(CTGeomGuide gd) {
+        this(gd.getName(), gd.getFmla());
+    }
+
+    public Guide(String nm, String fm){
+        name = nm;
+        fmla = fm;
+        expr = ExpressionParser.parse(fm);
+    }
+
+
+    String getName(){
+        return name;
+    }
+
+    String getFormula(){
+        return fmla;
+    }
+
+    @Override
+    public double evaluate(Context ctx){
+        return expr.evaluate(ctx);
+    }
+
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/IAdjustableShape.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/IAdjustableShape.java
new file mode 100644 (file)
index 0000000..174af3d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * A bridge to the consumer application.
+ *
+ * To get a shape geometry one needs to pass shape bounds and adjust values.
+ *
+ * @author Yegor Kozlov
+ */
+public interface IAdjustableShape {
+    /**
+     *
+     * @return bounds of the shape
+     */
+    Rectangle2D getAnchor();
+
+    /**
+     *
+     * @param  name name of a adjust value, e.g. adj1
+     * @return adjust guide defined in the shape or null
+     */
+    Guide getAdjustValue(String name);
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/IfElseExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/IfElseExpression.java
new file mode 100644 (file)
index 0000000..3e16645
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * If Else Formula:
+ * <p>
+ *     Arguments: 3 (fmla="?: x y z")
+ *     Usage: "?: x y z" = if (x > 0), then y = value of this guide,
+ *     else z = value of this guide
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+public class IfElseExpression implements Expression {
+    private String arg1, arg2, arg3;
+
+    IfElseExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+        arg3 = m.group(3);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        double z = ctx.getValue(arg3);
+        return x > 0 ? y : z;
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/LineToCommand.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/LineToCommand.java
new file mode 100644 (file)
index 0000000..7306362
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import org.openxmlformats.schemas.drawingml.x2006.main.CTAdjPoint2D;
+
+import java.awt.geom.GeneralPath;
+
+/**
+ * Date: 10/25/11
+ *
+ * @author Yegor Kozlov
+ */
+public class LineToCommand implements PathCommand {
+    private String arg1, arg2;
+
+    LineToCommand(CTAdjPoint2D pt){
+        arg1 = pt.getX().toString();
+        arg2 = pt.getY().toString();
+    }
+
+    public void execute(GeneralPath path, Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        path.lineTo(x, y);
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/LiteralValueExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/LiteralValueExpression.java
new file mode 100644 (file)
index 0000000..f84483c
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Date: 10/24/11
+ *
+ * @author Yegor Kozlov
+ */
+public class LiteralValueExpression implements Expression {
+    private String arg;
+
+    LiteralValueExpression(Matcher m){
+        arg = m.group(1);
+    }
+
+    public double evaluate(Context ctx){
+        return ctx.getValue(arg);
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/MaxExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/MaxExpression.java
new file mode 100644 (file)
index 0000000..0c7ac3e
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Maximum Value Formula
+ *
+ * @author Yegor Kozlov
+ */
+public class MaxExpression implements Expression {
+    private String arg1, arg2;
+
+    MaxExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        return Math.max(x, y);
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/MinExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/MinExpression.java
new file mode 100644 (file)
index 0000000..3e28cdd
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Minimum Value Formula
+ *
+ * @author Yegor Kozlov
+ */
+public class MinExpression implements Expression {
+    private String arg1, arg2;
+
+    MinExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        return Math.min(x, y);
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/ModExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/ModExpression.java
new file mode 100644 (file)
index 0000000..cf17f05
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Modulo Formula:
+ * <p>
+ *     Arguments: 3 (fmla="mod x y z")
+ *     Usage: "mod x y z" = sqrt(x^2 + b^2 + c^2) = value of this guide
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+public class ModExpression implements Expression {
+    private String arg1, arg2, arg3;
+
+    ModExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+        arg3 = m.group(3);
+    }
+
+   public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        double z = ctx.getValue(arg3);
+        return Math.sqrt(x*x + y*y + z*z);
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/MoveToCommand.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/MoveToCommand.java
new file mode 100644 (file)
index 0000000..534534d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import org.openxmlformats.schemas.drawingml.x2006.main.CTAdjPoint2D;
+
+import java.awt.geom.GeneralPath;
+
+/**
+ * Date: 10/25/11
+ *
+ * @author Yegor Kozlov
+ */
+public class MoveToCommand implements PathCommand {
+    private String arg1, arg2;
+
+    MoveToCommand(CTAdjPoint2D pt){
+        arg1 = pt.getX().toString();
+        arg2 = pt.getY().toString();
+    }
+
+    public void execute(GeneralPath path, Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        path.moveTo(x, y);
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/MultiplyDivideExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/MultiplyDivideExpression.java
new file mode 100644 (file)
index 0000000..17aca48
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Multiply Divide Formula
+ *
+ * @author Yegor Kozlov
+ */
+public class MultiplyDivideExpression implements Expression {
+    private String arg1, arg2, arg3;
+
+    MultiplyDivideExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+        arg3 = m.group(3);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        double z = ctx.getValue(arg3);
+        return (x * y ) / z;
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/Path.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/Path.java
new file mode 100644 (file)
index 0000000..9d5e9f7
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import org.apache.poi.util.Units;
+import org.apache.xmlbeans.XmlObject;
+import org.openxmlformats.schemas.drawingml.x2006.main.*;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Specifies a creation path consisting of a series of moves, lines and curves
+ * that when combined forms a geometric shape
+ *
+ * @author Yegor Kozlov
+ */
+public class Path {
+    private final List<PathCommand> commands;
+    boolean _fill, _stroke;
+
+    public Path(CTPath2D spPath){
+        _fill = spPath.getFill() != STPathFillMode.NONE;
+        _stroke = spPath.getStroke();
+
+        commands = new ArrayList<PathCommand>();
+        for(XmlObject ch : spPath.selectPath("*")){
+            if(ch instanceof CTPath2DMoveTo){
+                CTAdjPoint2D pt = ((CTPath2DMoveTo)ch).getPt();
+                commands.add(new MoveToCommand(pt));
+            } else if (ch instanceof CTPath2DLineTo){
+                CTAdjPoint2D pt = ((CTPath2DLineTo)ch).getPt();
+                commands.add(new LineToCommand(pt));
+            } else if (ch instanceof CTPath2DArcTo){
+                CTPath2DArcTo arc = (CTPath2DArcTo)ch;
+                commands.add(new ArcToCommand(arc));
+            } else if (ch instanceof CTPath2DQuadBezierTo){
+                CTPath2DQuadBezierTo bez = ((CTPath2DQuadBezierTo)ch);
+                CTAdjPoint2D pt1 = bez.getPtArray(0);
+                CTAdjPoint2D pt2 = bez.getPtArray(1);
+                commands.add(new QuadToCommand(pt1, pt2));
+            } else if (ch instanceof CTPath2DCubicBezierTo){
+                CTPath2DCubicBezierTo bez = ((CTPath2DCubicBezierTo)ch);
+                CTAdjPoint2D pt1 = bez.getPtArray(0);
+                CTAdjPoint2D pt2 = bez.getPtArray(1);
+                CTAdjPoint2D pt3 = bez.getPtArray(2);
+                commands.add(new CurveToCommand(pt1, pt2, pt3));
+            } else if (ch instanceof CTPath2DClose){
+                commands.add(new ClosePathCommand());
+            }  else {
+                throw new IllegalStateException("Unsupported path segment: " + ch);
+            }
+        }
+    }
+
+    public GeneralPath getPath(Context ctx) {
+        GeneralPath path = new GeneralPath();
+        for(PathCommand cmd : commands)
+            cmd.execute(path, ctx);
+        return path;
+    }
+
+    public boolean isStroked(){
+        return _stroke;
+    }
+
+    public boolean isFilled(){
+        return _fill;
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/PathCommand.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/PathCommand.java
new file mode 100644 (file)
index 0000000..7b3ec49
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.awt.geom.GeneralPath;
+
+/**
+ * A path command in DrawingML. One of:
+ *
+ *  - arcTo
+ *  - moveTo
+ *  - lineTo
+ *  - cubicBezTo
+ *  - quadBezTo
+ *  - close
+ *
+ *
+ * @author Yegor Kozlov
+ */
+public interface PathCommand {
+    /**
+     * Execute the command an append a segment to the specified path
+     *
+     * @param path  the path to append the result to
+     * @param ctx   the context to lookup variables
+     */
+    void execute(GeneralPath path, Context ctx);
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/PinExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/PinExpression.java
new file mode 100644 (file)
index 0000000..c1b7fe4
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Pin To Formula:
+ * <gd name="enAng" fmla="pin 0 adj2 21599999"/>
+ *
+ * <p>
+ *     Usage: "pin x y z" = if (y < x), then x = value of this guide
+ *     else if (y > z), then z = value of this guide
+ *     else y = value of this guide
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+public class PinExpression implements Expression {
+    private String arg1, arg2, arg3;
+
+    PinExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+        arg3 = m.group(3);
+    }
+
+   public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        double z = ctx.getValue(arg3);
+        if(y < x) return x;
+        else if (y > z) return z;
+        else return y;
+    }
+
+}
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
new file mode 100644 (file)
index 0000000..433c0cb
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import org.apache.poi.xslf.usermodel.XMLSlideShow;
+import org.apache.xmlbeans.XmlObject;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D;
+
+import java.io.InputStream;
+import java.util.LinkedHashMap;
+
+/**
+ * Date: 10/25/11
+ *
+ * @author Yegor Kozlov
+ */
+public class PresetGeometries extends LinkedHashMap<String, CustomGeometry> {
+    private static PresetGeometries _inst;
+
+    private PresetGeometries(){
+        try {
+            InputStream is =
+                    XMLSlideShow.class.getResourceAsStream("presetShapeDefinitions.xml");
+            read(is);
+        } catch (Exception e){
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void read(InputStream is) throws Exception {
+        XmlObject obj = XmlObject.Factory.parse(is);
+        for (XmlObject def : obj.selectPath("*/*")) {
+
+            String name = def.getDomNode().getLocalName();
+            CTCustomGeometry2D geom = CTCustomGeometry2D.Factory.parse(def.toString());
+
+            put(name, new CustomGeometry(geom));
+        }
+    }
+
+    public static PresetGeometries getInstance(){
+        if(_inst == null) _inst = new PresetGeometries();
+
+        return _inst;
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/QuadToCommand.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/QuadToCommand.java
new file mode 100644 (file)
index 0000000..9a0f240
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import org.openxmlformats.schemas.drawingml.x2006.main.CTAdjPoint2D;
+
+import java.awt.geom.GeneralPath;
+
+/**
+ * Date: 10/25/11
+ *
+ * @author Yegor Kozlov
+ */
+public class QuadToCommand implements PathCommand {
+    private String arg1, arg2, arg3, arg4;
+
+    QuadToCommand(CTAdjPoint2D pt1, CTAdjPoint2D pt2){
+        arg1 = pt1.getX().toString();
+        arg2 = pt1.getY().toString();
+        arg3 = pt2.getX().toString();
+        arg4 = pt2.getY().toString();
+    }
+
+    public void execute(GeneralPath 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(x1, y1, x2, y2);
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/SinArcTanExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/SinArcTanExpression.java
new file mode 100644 (file)
index 0000000..8ac68e0
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Sine ArcTan Formula:
+ * <gd name="dy1" fmla="sat2 x y z"/>
+ *
+ * <p>
+ *     Arguments: 3 (fmla="sat2 x y z")
+ *     Usage: "sat2 x y z" = (x*sin(arctan(z / y))) = value of this guide
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+public class SinArcTanExpression implements Expression {
+    private String arg1, arg2, arg3;
+
+    SinArcTanExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+        arg3 = m.group(3);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        double z = ctx.getValue(arg3);
+        return x*Math.sin(Math.atan(z / y));
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/SinExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/SinExpression.java
new file mode 100644 (file)
index 0000000..9e82f5a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Sine Formula:
+ * <gd name="z" fmla="sin x y"/>
+ *
+ * <p>
+ *     Arguments: 2 (fmla="sin x y")
+ *     Usage: "sin x y" = (x * sin( y )) = value of this guide
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+public class SinExpression implements Expression {
+    private String arg1, arg2;
+
+    SinExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2) / 60000;
+        return x * Math.sin(Math.toRadians(y));
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/SqrtExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/SqrtExpression.java
new file mode 100644 (file)
index 0000000..d798e93
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Square Root Formula:
+ * <gd name="x" fmla="sqrt y"/>
+ *
+ * <p>
+ *     Arguments: 1 (fmla="sqrt x")
+ *     Usage: "sqrt x" = sqrt(x) = value of this guide
+ * </p>
+ * @author Yegor Kozlov
+ */
+public class SqrtExpression implements Expression {
+    private String arg;
+
+    SqrtExpression(Matcher m){
+        arg =m.group(1);
+    }
+
+    public double evaluate(Context ctx){
+        double val = ctx.getValue(arg);
+        return Math.sqrt(val);
+    }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/model/geom/TanExpression.java b/src/ooxml/java/org/apache/poi/xslf/model/geom/TanExpression.java
new file mode 100644 (file)
index 0000000..3435f35
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xslf.model.geom;
+
+import java.util.regex.Matcher;
+
+/**
+ * Tangent Formula:
+ *
+ * <gd name="z" fmla="tan x y"/>
+ *
+ * <p>
+ * Arguments: 2 (fmla="tan x y")
+ * Usage: "tan x y" = (x * tan( y )) = value of this guide
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+public class TanExpression implements Expression {
+    private String arg1, arg2;
+
+    TanExpression(Matcher m){
+        arg1 = m.group(1);
+        arg2 = m.group(2);
+    }
+
+    public double evaluate(Context ctx){
+        double x = ctx.getValue(arg1);
+        double y = ctx.getValue(arg2);
+        return x * Math.tan(Math.toRadians(y / 60000));
+    }
+
+}
index e37259459fde474601e4eb9364566e52353ec6f8..193e5f023fca35068528a14694e21ca6c3211e2e 100644 (file)
@@ -21,6 +21,10 @@ package org.apache.poi.xslf.usermodel;
 \r
 import org.apache.poi.util.Beta;\r
 import org.apache.poi.util.Units;\r
+import org.apache.poi.xslf.model.geom.Context;\r
+import org.apache.poi.xslf.model.geom.CustomGeometry;\r
+import org.apache.poi.xslf.model.geom.Path;\r
+import org.apache.poi.xslf.model.geom.PresetGeometries;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuideList;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;\r
@@ -42,6 +46,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
 \r
 import java.awt.*;\r
 import java.awt.geom.AffineTransform;\r
+import java.awt.geom.GeneralPath;\r
 import java.awt.geom.Rectangle2D;\r
 import java.util.ArrayList;\r
 import java.util.List;\r
@@ -100,39 +105,4 @@ public class XSLFAutoShape extends XSLFTextShape {
         }\r
         return txBody;\r
     }\r
-\r
-    int getAdjustValue(String name, int defaultValue){\r
-        /*\r
-        CTShape shape = (CTShape) getXmlObject();\r
-        CTGeomGuideList av = shape.getSpPr().getPrstGeom().getAvLst();\r
-        if(av != null){\r
-            for(CTGeomGuide gd : av.getGdList()){\r
-                if(gd.getName().equals(name)) {\r
-                    String fmla = gd.getFmla();\r
-                    Matcher m = adjPtrn.matcher(fmla);\r
-                    if(m.matches()){\r
-                        int val = Integer.parseInt(m.group(1));\r
-                        return 21600*val/100000;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        */\r
-        return defaultValue;\r
-    }\r
-\r
-    @Override\r
-    protected java.awt.Shape getOutline(){\r
-        java.awt.Shape outline = XSLFPresetGeometry.getOutline(this);\r
-        Rectangle2D anchor = getAnchor();\r
-\r
-        AffineTransform at = new AffineTransform();\r
-        at.translate(anchor.getX(), anchor.getY());\r
-        at.scale(\r
-                1.0f/21600*anchor.getWidth(),\r
-                1.0f/21600*anchor.getHeight()\r
-        );\r
-        return outline == null ? anchor : at.createTransformedShape(outline);\r
-    }\r
-\r
 }\r
index beb23bdec0b910b71553d534759ed5d472566975..cc16d26ebc83e0ef7f26da8595040171dc08dd93 100644 (file)
@@ -223,18 +223,6 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
         }\r
     }\r
 \r
-    @Override\r
-    protected java.awt.Shape getOutline() {\r
-        Rectangle2D anchor = getAnchor();\r
-        double x1 = anchor.getX(),\r
-                y1 = anchor.getY(),\r
-                x2 = anchor.getX() + anchor.getWidth(),\r
-                y2 = anchor.getY() + anchor.getHeight();\r
-\r
-\r
-        return new Line2D.Double(x1, y1, x2, y2);\r
-    }\r
-\r
     Shape getTailDecoration() {\r
         LineEndLength tailLength = getLineTailLength();\r
         LineEndWidth tailWidth = getLineTailWidth();\r
@@ -307,9 +295,10 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
         double scaleX = 1;\r
         switch (getLineHeadDecoration()) {\r
             case OVAL:\r
-                scaleY = Math.pow(2, headWidth.ordinal());\r
-                scaleX = Math.pow(2, headLength.ordinal());\r
                 shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);\r
+                bounds = shape.getBounds2D();\r
+                at.translate(x1 - bounds.getWidth() / 2, y1 - bounds.getHeight() / 2);\r
+                at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);\r
                 break;\r
             case STEALTH:\r
             case ARROW:\r
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPresetGeometry.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPresetGeometry.java
deleted file mode 100644 (file)
index dcd4910..0000000
+++ /dev/null
@@ -1,637 +0,0 @@
-/*\r
- *  ====================================================================\r
- *    Licensed to the Apache Software Foundation (ASF) under one or more\r
- *    contributor license agreements.  See the NOTICE file distributed with\r
- *    this work for additional information regarding copyright ownership.\r
- *    The ASF licenses this file to You under the Apache License, Version 2.0\r
- *    (the "License"); you may not use this file except in compliance with\r
- *    the License.  You may obtain a copy of the License at\r
- *\r
- *        http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- *    Unless required by applicable law or agreed to in writing, software\r
- *    distributed under the License is distributed on an "AS IS" BASIS,\r
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- *    See the License for the specific language governing permissions and\r
- *    limitations under the License.\r
- * ====================================================================\r
- */\r
-\r
-package org.apache.poi.xslf.usermodel;\r
-\r
-import java.awt.*;\r
-import java.awt.geom.*;\r
-\r
-/**\r
- * TODO: re-write and initialize from presetShapeDefinitions.xml\r
- *\r
- * @author Yegor Kozlov\r
- */\r
-public class XSLFPresetGeometry {\r
-    public static final int LINE = 1;\r
-    public static final int LINE_INV = 2;\r
-    public static final int TRIANGLE = 3;\r
-    public static final int RT_TRIANGLE = 4;\r
-    public static final int RECT = 5;\r
-    public static final int DIAMOND = 6;\r
-    public static final int PARALLELOGRAM = 7;\r
-    public static final int TRAPEZOID = 8;\r
-    public static final int NON_ISOSCELES_TRAPEZOID = 9;\r
-    public static final int PENTAGON = 10;\r
-    public static final int HEXAGON = 11;\r
-    public static final int HEPTAGON = 12;\r
-    public static final int OCTAGON = 13;\r
-    public static final int DECAGON = 14;\r
-    public static final int DODECAGON = 15;\r
-    public static final int STAR_4 = 16;\r
-    public static final int STAR_5 = 17;\r
-    public static final int STAR_6 = 18;\r
-    public static final int STAR_7 = 19;\r
-    public static final int STAR_8 = 20;\r
-    public static final int STAR_10 = 21;\r
-    public static final int STAR_12 = 22;\r
-    public static final int STAR_16 = 23;\r
-    public static final int STAR_24 = 24;\r
-    public static final int STAR_32 = 25;\r
-    public static final int ROUND_RECT = 26;\r
-    public static final int ROUND_1_RECT = 27;\r
-    public static final int ROUND_2_SAME_RECT = 28;\r
-    public static final int ROUND_2_DIAG_RECT = 29;\r
-    public static final int SNIP_ROUND_RECT = 30;\r
-    public static final int SNIP_1_RECT = 31;\r
-    public static final int SNIP_2_SAME_RECT = 32;\r
-    public static final int SNIP_2_DIAG_RECT = 33;\r
-    public static final int PLAQUE = 34;\r
-    public static final int ELLIPSE = 35;\r
-    public static final int TEARDROP = 36;\r
-    public static final int HOME_PLATE = 37;\r
-    public static final int CHEVRON = 38;\r
-    public static final int PIE_WEDGE = 39;\r
-    public static final int PIE = 40;\r
-    public static final int BLOCK_ARC = 41;\r
-    public static final int DONUT = 42;\r
-    public static final int NO_SMOKING = 43;\r
-    public static final int RIGHT_ARROW = 44;\r
-    public static final int LEFT_ARROW = 45;\r
-    public static final int UP_ARROW = 46;\r
-    public static final int DOWN_ARROW = 47;\r
-    public static final int STRIPED_RIGHT_ARROW = 48;\r
-    public static final int NOTCHED_RIGHT_ARROW = 49;\r
-    public static final int BENT_UP_ARROW = 50;\r
-    public static final int LEFT_RIGHT_ARROW = 51;\r
-    public static final int UP_DOWN_ARROW = 52;\r
-    public static final int LEFT_UP_ARROW = 53;\r
-    public static final int LEFT_RIGHT_UP_ARROW = 54;\r
-    public static final int QUAD_ARROW = 55;\r
-    public static final int LEFT_ARROW_CALLOUT = 56;\r
-    public static final int RIGHT_ARROW_CALLOUT = 57;\r
-    public static final int UP_ARROW_CALLOUT = 58;\r
-    public static final int DOWN_ARROW_CALLOUT = 59;\r
-    public static final int LEFT_RIGHT_ARROW_CALLOUT = 60;\r
-    public static final int UP_DOWN_ARROW_CALLOUT = 61;\r
-    public static final int QUAD_ARROW_CALLOUT = 62;\r
-    public static final int BENT_ARROW = 63;\r
-    public static final int UTURN_ARROW = 64;\r
-    public static final int CIRCULAR_ARROW = 65;\r
-    public static final int LEFT_CIRCULAR_ARROW = 66;\r
-    public static final int LEFT_RIGHT_CIRCULAR_ARROW = 67;\r
-    public static final int CURVED_RIGHT_ARROW = 68;\r
-    public static final int CURVED_LEFT_ARROW = 69;\r
-    public static final int CURVED_UP_ARROW = 70;\r
-    public static final int CURVED_DOWN_ARROW = 71;\r
-    public static final int SWOOSH_ARROW = 72;\r
-    public static final int CUBE = 73;\r
-    public static final int CAN = 74;\r
-    public static final int LIGHTNING_BOLT = 75;\r
-    public static final int HEART = 76;\r
-    public static final int SUN = 77;\r
-    public static final int MOON = 78;\r
-    public static final int SMILEY_FACE = 79;\r
-    public static final int IRREGULAR_SEAL_1 = 80;\r
-    public static final int IRREGULAR_SEAL_2 = 81;\r
-    public static final int FOLDED_CORNER = 82;\r
-    public static final int BEVEL = 83;\r
-    public static final int FRAME = 84;\r
-    public static final int HALF_FRAME = 85;\r
-    public static final int CORNER = 86;\r
-    public static final int DIAG_STRIPE = 87;\r
-    public static final int CHORD = 88;\r
-    public static final int ARC = 89;\r
-    public static final int LEFT_BRACKET = 90;\r
-    public static final int RIGHT_BRACKET = 91;\r
-    public static final int LEFT_BRACE = 92;\r
-    public static final int RIGHT_BRACE = 93;\r
-    public static final int BRACKET_PAIR = 94;\r
-    public static final int BRACE_PAIR = 95;\r
-    public static final int STRAIGHT_CONNECTOR_1 = 96;\r
-    public static final int BENT_CONNECTOR_2 = 97;\r
-    public static final int BENT_CONNECTOR_3 = 98;\r
-    public static final int BENT_CONNECTOR_4 = 99;\r
-    public static final int BENT_CONNECTOR_5 = 100;\r
-    public static final int CURVED_CONNECTOR_2 = 101;\r
-    public static final int CURVED_CONNECTOR_3 = 102;\r
-    public static final int CURVED_CONNECTOR_4 = 103;\r
-    public static final int CURVED_CONNECTOR_5 = 104;\r
-    public static final int CALLOUT_1 = 105;\r
-    public static final int CALLOUT_2 = 106;\r
-    public static final int CALLOUT_3 = 107;\r
-    public static final int ACCENT_CALLOUT_1 = 108;\r
-    public static final int ACCENT_CALLOUT_2 = 109;\r
-    public static final int ACCENT_CALLOUT_3 = 110;\r
-    public static final int BORDER_CALLOUT_1 = 111;\r
-    public static final int BORDER_CALLOUT_2 = 112;\r
-    public static final int BORDER_CALLOUT_3 = 113;\r
-    public static final int ACCENT_BORDER_CALLOUT_1 = 114;\r
-    public static final int ACCENT_BORDER_CALLOUT_2 = 115;\r
-    public static final int ACCENT_BORDER_CALLOUT_3 = 116;\r
-    public static final int WEDGE_RECT_CALLOUT = 117;\r
-    public static final int WEDGE_ROUND_RECT_CALLOUT = 118;\r
-    public static final int WEDGE_ELLIPSE_CALLOUT = 119;\r
-    public static final int CLOUD_CALLOUT = 120;\r
-    public static final int CLOUD = 121;\r
-    public static final int RIBBON = 122;\r
-    public static final int RIBBON_2 = 123;\r
-    public static final int ELLIPSE_RIBBON = 124;\r
-    public static final int ELLIPSE_RIBBON_2 = 125;\r
-    public static final int LEFT_RIGHT_RIBBON = 126;\r
-    public static final int VERTICAL_SCROLL = 127;\r
-    public static final int HORIZONTAL_SCROLL = 128;\r
-    public static final int WAVE = 129;\r
-    public static final int DOUBLE_WAVE = 130;\r
-    public static final int PLUS = 131;\r
-    public static final int FLOW_CHART_PROCESS = 132;\r
-    public static final int FLOW_CHART_DECISION = 133;\r
-    public static final int FLOW_CHART_INPUT_OUTPUT = 134;\r
-    public static final int FLOW_CHART_PREDEFINED_PROCESS = 135;\r
-    public static final int FLOW_CHART_INTERNAL_STORAGE = 136;\r
-    public static final int FLOW_CHART_DOCUMENT = 137;\r
-    public static final int FLOW_CHART_MULTIDOCUMENT = 138;\r
-    public static final int FLOW_CHART_TERMINATOR = 139;\r
-    public static final int FLOW_CHART_PREPARATION = 140;\r
-    public static final int FLOW_CHART_MANUAL_INPUT = 141;\r
-    public static final int FLOW_CHART_MANUAL_OPERATION = 142;\r
-    public static final int FLOW_CHART_CONNECTOR = 143;\r
-    public static final int FLOW_CHART_PUNCHED_CARD = 144;\r
-    public static final int FLOW_CHART_PUNCHED_TAPE = 145;\r
-    public static final int FLOW_CHART_SUMMING_JUNCTION = 146;\r
-    public static final int FLOW_CHART_OR = 147;\r
-    public static final int FLOW_CHART_COLLATE = 148;\r
-    public static final int FLOW_CHART_SORT = 149;\r
-    public static final int FLOW_CHART_EXTRACT = 150;\r
-    public static final int FLOW_CHART_MERGE = 151;\r
-    public static final int FLOW_CHART_OFFLINE_STORAGE = 152;\r
-    public static final int FLOW_CHART_ONLINE_STORAGE = 153;\r
-    public static final int FLOW_CHART_MAGNETIC_TAPE = 154;\r
-    public static final int FLOW_CHART_MAGNETIC_DISK = 155;\r
-    public static final int FLOW_CHART_MAGNETIC_DRUM = 156;\r
-    public static final int FLOW_CHART_DISPLAY = 157;\r
-    public static final int FLOW_CHART_DELAY = 158;\r
-    public static final int FLOW_CHART_ALTERNATE_PROCESS = 159;\r
-    public static final int FLOW_CHART_OFFPAGE_CONNECTOR = 160;\r
-    public static final int ACTION_BUTTON_BLANK = 161;\r
-    public static final int ACTION_BUTTON_HOME = 162;\r
-    public static final int ACTION_BUTTON_HELP = 163;\r
-    public static final int ACTION_BUTTON_INFORMATION = 164;\r
-    public static final int ACTION_BUTTON_FORWARD_NEXT = 165;\r
-    public static final int ACTION_BUTTON_BACK_PREVIOUS = 166;\r
-    public static final int ACTION_BUTTON_END = 167;\r
-    public static final int ACTION_BUTTON_BEGINNING = 168;\r
-    public static final int ACTION_BUTTON_RETURN = 169;\r
-    public static final int ACTION_BUTTON_DOCUMENT = 170;\r
-    public static final int ACTION_BUTTON_SOUND = 171;\r
-    public static final int ACTION_BUTTON_MOVIE = 172;\r
-    public static final int GEAR_6 = 173;\r
-    public static final int GEAR_9 = 174;\r
-    public static final int FUNNEL = 175;\r
-    public static final int MATH_PLUS = 176;\r
-    public static final int MATH_MINUS = 177;\r
-    public static final int MATH_MULTIPLY = 178;\r
-    public static final int MATH_DIVIDE = 179;\r
-    public static final int MATH_EQUAL = 180;\r
-    public static final int MATH_NOT_EQUAL = 181;\r
-    public static final int CORNER_TABS = 182;\r
-    public static final int SQUARE_TABS = 183;\r
-    public static final int PLAQUE_TABS = 184;\r
-    public static final int CHART_X = 185;\r
-    public static final int CHART_STAR = 186;\r
-    public static final int CHART_PLUS = 187;\r
-\r
-    private static interface ShapeOutline {\r
-        java.awt.Shape getOutline(XSLFAutoShape shape);\r
-    }\r
-    \r
-    \r
-    static ShapeOutline[] shapes;\r
-    static {\r
-        shapes = new ShapeOutline[255];\r
-\r
-        shapes[RECT] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                Rectangle2D path = new Rectangle2D.Float(0, 0, 21600, 21600);\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[ROUND_RECT] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                int adjval = shape.getAdjustValue("adj1", 5400);\r
-                RoundRectangle2D path = new RoundRectangle2D.Float(0, 0, 21600, 21600, adjval, adjval);\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[ELLIPSE] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                Ellipse2D path = new Ellipse2D.Float(0, 0, 21600, 21600);\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[DIAMOND] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(10800, 0);\r
-                path.lineTo(21600, 10800);\r
-                path.lineTo(10800, 21600);\r
-                path.lineTo(0, 10800);\r
-                path.closePath();\r
-                return path;\r
-           }\r
-        };\r
-\r
-        //m@0,l,21600r21600\r
-        shapes[TRIANGLE] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                int adjval = shape.getAdjustValue("adj1", 5400);\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(adjval, 0);\r
-                path.lineTo(0, 21600);\r
-                path.lineTo(21600, 21600);\r
-                path.closePath();\r
-                return path;\r
-           }\r
-        };\r
-\r
-        shapes[RT_TRIANGLE] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(0, 0);\r
-                path.lineTo(21600, 21600);\r
-                path.lineTo(0, 21600);\r
-                path.closePath();\r
-                return path;\r
-           }\r
-        };\r
-\r
-        shapes[PARALLELOGRAM] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                int adjval = shape.getAdjustValue("adj1", 5400);\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(adjval, 0);\r
-                path.lineTo(21600, 0);\r
-                path.lineTo(21600 - adjval, 21600);\r
-                path.lineTo(0, 21600);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[TRAPEZOID] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                int adjval = shape.getAdjustValue("adj1", 5400);\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(0, 0);\r
-                path.lineTo(adjval, 21600);\r
-                path.lineTo(21600 - adjval, 21600);\r
-                path.lineTo(21600, 0);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[HEXAGON] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                int adjval = shape.getAdjustValue("adj1", 5400);\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(adjval, 0);\r
-                path.lineTo(21600 - adjval, 0);\r
-                path.lineTo(21600, 10800);\r
-                path.lineTo(21600 - adjval, 21600);\r
-                path.lineTo(adjval, 21600);\r
-                path.lineTo(0, 10800);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[OCTAGON] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                int adjval = shape.getAdjustValue("adj1", 6324);\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(adjval, 0);\r
-                path.lineTo(21600 - adjval, 0);\r
-                path.lineTo(21600, adjval);\r
-                path.lineTo(21600, 21600-adjval);\r
-                path.lineTo(21600-adjval, 21600);\r
-                path.lineTo(adjval, 21600);\r
-                path.lineTo(0, 21600-adjval);\r
-                path.lineTo(0, adjval);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[PLUS] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                int adjval = shape.getAdjustValue("adj1", 5400);\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(adjval, 0);\r
-                path.lineTo(21600 - adjval, 0);\r
-                path.lineTo(21600 - adjval, adjval);\r
-                path.lineTo(21600, adjval);\r
-                path.lineTo(21600, 21600-adjval);\r
-                path.lineTo(21600-adjval, 21600-adjval);\r
-                path.lineTo(21600-adjval, 21600);\r
-                path.lineTo(adjval, 21600);\r
-                path.lineTo(adjval, 21600-adjval);\r
-                path.lineTo(0, 21600-adjval);\r
-                path.lineTo(0, adjval);\r
-                path.lineTo(adjval, adjval);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[PENTAGON] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(10800, 0);\r
-                path.lineTo(21600, 8259);\r
-                path.lineTo(21600 - 4200, 21600);\r
-                path.lineTo(4200, 21600);\r
-                path.lineTo(0, 8259);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[HOME_PLATE] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                int adjval = shape.getAdjustValue("adj1", 16200);\r
-                path.moveTo(0, 0);\r
-                path.lineTo(adjval, 0 );\r
-                path.lineTo(21600, 10800);\r
-                path.lineTo(adjval, 21600);\r
-                path.lineTo(0, 21600);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[CHEVRON] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                GeneralPath path = new GeneralPath();\r
-                int adjval = shape.getAdjustValue("adj1", 16200);\r
-                path.moveTo(0, 0);\r
-                path.lineTo(adjval, 0 );\r
-                path.lineTo(21600, 10800);\r
-                path.lineTo(adjval, 21600);\r
-                path.lineTo(0, 21600);\r
-                path.lineTo(21600 - adjval, 10800);\r
-                path.closePath();\r
-                return path;\r
-           }\r
-        };\r
-\r
-        shapes[CAN] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                int adjval = shape.getAdjustValue("adj1", 5400);\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(0, 0);\r
-                path.lineTo(21600, 0);\r
-                path.lineTo(21600, 21600);\r
-                path.lineTo(0, 21600);\r
-\r
-                //path.lineTo(21600, adjval);\r
-\r
-                path.closePath();\r
-                path.moveTo(10800, 0);\r
-                //path.append(new Arc2D.Float(10800, 0, 10800, adjval, 0, 90, Arc2D.OPEN), true);\r
-                path.moveTo(10800, adjval/2);\r
-                path.append(new Arc2D.Float(10800, adjval/2, 10800, adjval, 90, 180, Arc2D.OPEN), true);\r
-                //path.append(new Arc2D.Float(0, adjval/2, 10800, adjval, 180, 270, Arc2D.OPEN), true);\r
-                //path.append(new Arc2D.Float(0, 0, 10800, adjval, 270, 360, Arc2D.OPEN), true);\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[DOWN_ARROW] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                //m0@0 l@1@0 @1,0 @2,0 @2@0,21600@0,10800,21600xe\r
-                int adjval = shape.getAdjustValue("adj1", 16200);\r
-                int adjval2 = shape.getAdjustValue("adj2", 5400);\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(0, adjval);\r
-                path.lineTo(adjval2, adjval);\r
-                path.lineTo(adjval2, 0);\r
-                path.lineTo(21600-adjval2, 0);\r
-                path.lineTo(21600-adjval2, adjval);\r
-                path.lineTo(21600, adjval);\r
-                path.lineTo(10800, 21600);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[UP_ARROW] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                //m0@0 l@1@0 @1,21600@2,21600@2@0,21600@0,10800,xe\r
-                int adjval = shape.getAdjustValue("adj1", 5400);\r
-                int adjval2 = shape.getAdjustValue("adj2", 5400);\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(0, adjval);\r
-                path.lineTo(adjval2, adjval);\r
-                path.lineTo(adjval2, 21600);\r
-                path.lineTo(21600-adjval2, 21600);\r
-                path.lineTo(21600-adjval2, adjval);\r
-                path.lineTo(21600, adjval);\r
-                path.lineTo(10800, 0);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[RIGHT_ARROW] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                //m@0, l@0@1 ,0@1,0@2@0@2@0,21600,21600,10800xe\r
-                int adjval = shape.getAdjustValue("adj1", 16200);\r
-                int adjval2 = shape.getAdjustValue("adj2", 5400);\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(adjval, 0);\r
-                path.lineTo(adjval, adjval2);\r
-                path.lineTo(0, adjval2);\r
-                path.lineTo(0, 21600-adjval2);\r
-                path.lineTo(adjval, 21600-adjval2);\r
-                path.lineTo(adjval, 21600);\r
-                path.lineTo(21600, 10800);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[LEFT_ARROW] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                //m@0, l@0@1,21600@1,21600@2@0@2@0,21600,,10800xe\r
-                int adjval = shape.getAdjustValue("adj1", 5400);\r
-                int adjval2 = shape.getAdjustValue("adj2", 5400);\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(adjval, 0);\r
-                path.lineTo(adjval, adjval2);\r
-                path.lineTo(21600, adjval2);\r
-                path.lineTo(21600, 21600-adjval2);\r
-                path.lineTo(adjval, 21600-adjval2);\r
-                path.lineTo(adjval, 21600);\r
-                path.lineTo(0, 10800);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-        shapes[LEFT_BRACE] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                //m21600,qx10800@0l10800@2qy0@11,10800@3l10800@1qy21600,21600e\r
-                int adjval = shape.getAdjustValue("adj1", 1800);\r
-                int adjval2 = shape.getAdjustValue("adj2", 10800);\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(21600, 0);\r
-\r
-                path.append(new Arc2D.Float(10800, 0, 21600, adjval*2, 90, 90, Arc2D.OPEN), false);\r
-                path.moveTo(10800, adjval);\r
-\r
-                path.lineTo(10800, adjval2 - adjval);\r
-\r
-                path.append(new Arc2D.Float(-10800, adjval2 - 2*adjval, 21600, adjval*2, 270, 90, Arc2D.OPEN), false);\r
-                path.moveTo(0, adjval2);\r
-\r
-                path.append(new Arc2D.Float(-10800, adjval2, 21600, adjval*2, 0, 90, Arc2D.OPEN), false);\r
-                path.moveTo(10800, adjval2 + adjval);\r
-\r
-                path.lineTo(10800, 21600 - adjval);\r
-\r
-                path.append(new Arc2D.Float(10800, 21600 - 2*adjval, 21600, adjval*2, 180, 90, Arc2D.OPEN), false);\r
-\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[RIGHT_BRACE] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                //m,qx10800@0 l10800@2qy21600@11,10800@3l10800@1qy,21600e\r
-                int adjval = shape.getAdjustValue("adj1", 1800);\r
-                int adjval2 = shape.getAdjustValue("adj2", 10800);\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(0, 0);\r
-\r
-                path.append(new Arc2D.Float(-10800, 0, 21600, adjval*2, 0, 90, Arc2D.OPEN), false);\r
-                path.moveTo(10800, adjval);\r
-\r
-                path.lineTo(10800, adjval2 - adjval);\r
-\r
-                path.append(new Arc2D.Float(10800, adjval2 - 2*adjval, 21600, adjval*2, 180, 90, Arc2D.OPEN), false);\r
-                path.moveTo(21600, adjval2);\r
-\r
-                path.append(new Arc2D.Float(10800, adjval2, 21600, adjval*2, 90, 90, Arc2D.OPEN), false);\r
-                path.moveTo(10800, adjval2 + adjval);\r
-\r
-                path.lineTo(10800, 21600 - adjval);\r
-\r
-                path.append(new Arc2D.Float(-10800, 21600 - 2*adjval, 21600, adjval*2, 270, 90, Arc2D.OPEN), false);\r
-\r
-                return path;\r
-            }\r
-        };\r
-\r
-\r
-        shapes[LEFT_RIGHT_ARROW] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                //m,10800l@0,21600@0@3@2@3@2,21600,21600,10800@2,0@2@1@0@1@0,xe\r
-                int adjval = shape.getAdjustValue("adj1", 4320);\r
-                int adjval2 = shape.getAdjustValue("adj2", 5400);\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(0, 10800);\r
-                path.lineTo(adjval, 0);\r
-                path.lineTo(adjval, adjval2);\r
-                path.lineTo(21600 - adjval, adjval2);\r
-                path.lineTo(21600 - adjval, 0);\r
-                path.lineTo(21600, 10800);\r
-                path.lineTo(21600 - adjval, 21600);\r
-                path.lineTo(21600 - adjval, 21600 - adjval2);\r
-                path.lineTo(adjval, 21600 - adjval2);\r
-                path.lineTo(adjval, 21600);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[UP_DOWN_ARROW] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                //m10800,l21600@0@3@0@3@2,21600@2,10800,21600,0@2@1@2@1@0,0@0xe\r
-                int adjval1 = shape.getAdjustValue("adj1", 5400);\r
-                int adjval2 = shape.getAdjustValue("adj2", 4320);\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(10800, 0);\r
-                path.lineTo(21600, adjval2);\r
-                path.lineTo(21600 - adjval1, adjval2);\r
-                path.lineTo(21600 - adjval1, 21600 - adjval2);\r
-                path.lineTo(21600, 21600 - adjval2);\r
-\r
-                path.lineTo(10800, 21600);\r
-                path.lineTo(0, 21600 - adjval2);\r
-                path.lineTo(adjval1, 21600 - adjval2);\r
-                path.lineTo(adjval1, adjval2);\r
-                path.lineTo(0, adjval2);\r
-\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-\r
-        shapes[NOTCHED_RIGHT_ARROW] = new ShapeOutline(){\r
-            public java.awt.Shape getOutline(XSLFAutoShape shape){\r
-                //m@0,l@0@1,0@1@5,10800,0@2@0@2@0,21600,21600,10800xe\r
-                int adjval1 = shape.getAdjustValue("adj1", 16200);\r
-                int adjval2 = shape.getAdjustValue("adj2", 5400);\r
-\r
-                GeneralPath path = new GeneralPath();\r
-                path.moveTo(adjval1, 0);\r
-                path.lineTo(adjval1, adjval2);\r
-                path.lineTo(0, adjval2);\r
-                //The notch at the end stays adjusted so that it matches the shape of the arrowhead.\r
-                int notch = (21600-2*adjval2)*(21600-adjval1)/21600;\r
-                path.lineTo(notch, 10800);\r
-                path.lineTo(0, 21600 - adjval2);\r
-                path.lineTo(adjval1, 21600 - adjval2);\r
-                path.lineTo(adjval1, 21600);\r
-                path.lineTo(21600, 10800);\r
-                path.closePath();\r
-                return path;\r
-            }\r
-        };\r
-    }\r
-    \r
-    static Shape getOutline(XSLFAutoShape shape){\r
-        ShapeOutline outline = shapes[shape.getShapeType()];\r
-        return outline == null ? null : outline.getOutline(shape);\r
-    }\r
-}\r
index c7efb5ff51f858a6be8152903abd39a19dcf4eec..049a2d321e99d257cf6fabdfa88f5cb963615f04 100644 (file)
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
+import org.apache.poi.xslf.model.geom.*;\r
 import org.apache.poi.xslf.usermodel.LineCap;\r
 import org.apache.poi.xslf.usermodel.LineDash;\r
 import org.apache.poi.xslf.model.PropertyFetcher;\r
 import org.apache.poi.util.Beta;\r
 import org.apache.poi.util.Units;\r
 import org.apache.xmlbeans.XmlObject;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;\r
 \r
 import java.awt.*;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.GeneralPath;\r
 import java.awt.geom.Rectangle2D;\r
+import java.util.ArrayList;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
@@ -674,4 +661,55 @@ public abstract class XSLFSimpleShape extends XSLFShape {
         return ok;\r
     }\r
 \r
+\r
+    @Override\r
+    protected java.awt.Shape getOutline(){\r
+        PresetGeometries dict = PresetGeometries.getInstance();\r
+        String name = getSpPr().getPrstGeom().getPrst().toString();\r
+        CustomGeometry geom = dict.get(name);\r
+        Rectangle2D anchor = getAnchor();\r
+        if(geom != null) {\r
+            // the guides in the shape definitions are all defined relative to each other,\r
+            // so we build the path starting from (0,0).\r
+            final Rectangle2D anchorEmu = new Rectangle2D.Double(\r
+                    0,\r
+                    0,\r
+                    Units.toEMU(anchor.getWidth()),\r
+                    Units.toEMU(anchor.getHeight())\r
+            );\r
+\r
+            GeneralPath path = new GeneralPath();\r
+            Context ctx = new Context(geom, new IAdjustableShape() {\r
+                public Rectangle2D getAnchor() {\r
+                    return anchorEmu;\r
+                }\r
+\r
+                public Guide getAdjustValue(String name) {\r
+                    CTPresetGeometry2D prst = getSpPr().getPrstGeom();\r
+                    if(prst.isSetAvLst()) {\r
+                        for(CTGeomGuide g : prst.getAvLst().getGdList()){\r
+                            if(g.getName().equals(name)) {\r
+                                return new Guide(g);\r
+                            }\r
+                        }\r
+                    }\r
+                    return null;\r
+                }\r
+            });\r
+\r
+            for(Path p : geom){\r
+                path.append( p.getPath(ctx) , false);\r
+            }\r
+\r
+            // translate the result to the canvas coordinates in points\r
+            AffineTransform at = new AffineTransform();\r
+            at.scale(\r
+                    1.0/Units.EMU_PER_POINT, 1.0/Units.EMU_PER_POINT);\r
+            at.translate(Units.toEMU(anchor.getX()), Units.toEMU(anchor.getY()));\r
+            return at.createTransformedShape(path);\r
+        } else {\r
+            return anchor;\r
+        }\r
+     }\r
+\r
 }\r
index d17f1ce7592cf003665c6aec170a175e47577543..c925922d5b96e1fdc5f9ccfde696585800006682 100644 (file)
@@ -23,6 +23,9 @@ import org.apache.poi.util.Beta;
 import org.apache.poi.util.Units;
 import org.apache.poi.xslf.model.PropertyFetcher;
 import org.apache.poi.xslf.model.TextBodyPropertyFetcher;
+import org.apache.poi.xslf.model.geom.Context;
+import org.apache.poi.xslf.model.geom.CustomGeometry;
+import org.apache.poi.xslf.model.geom.Path;
 import org.apache.xmlbeans.XmlObject;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
@@ -33,6 +36,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
 
 import java.awt.*;
+import java.awt.geom.GeneralPath;
 import java.awt.image.BufferedImage;
 import java.awt.geom.Rectangle2D;
 import java.util.ArrayList;
@@ -391,15 +395,14 @@ public abstract class XSLFTextShape extends XSLFSimpleShape {
         Color fillColor = getFillColor();
         Color lineColor = getLineColor();
         if(shadow != null) {
-               shadow.draw(graphics);
+               //shadow.draw(graphics);
         }
-
         if (fillColor != null) {
                graphics.setColor(fillColor);
             applyFill(graphics);
             graphics.fill(outline);
         }
+
         if (lineColor != null){
             graphics.setColor(lineColor);
             applyStroke(graphics);
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/geom/TestFormulaParser.java b/src/ooxml/testcases/org/apache/poi/xslf/geom/TestFormulaParser.java
new file mode 100644 (file)
index 0000000..b9f1513
--- /dev/null
@@ -0,0 +1,40 @@
+package org.apache.poi.xslf.geom;
+
+import junit.framework.TestCase;
+import org.apache.poi.xslf.model.geom.*;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D;
+
+/**
+ * Date: 10/24/11
+ *
+ * @author Yegor Kozlov
+ */
+public class TestFormulaParser extends TestCase {
+    public void testParse(){
+
+        Formula[] ops = {
+            new Guide("adj1", "val 100"),
+            new Guide("adj2", "val 200"),
+            new Guide("adj3", "val -1"),
+            new Guide("a1", "*/ adj1 2 adj2"), // a1 = 100*2 / 200
+            new Guide("a2", "+- adj2 a1 adj1"), // a2 = 200 + a1 - 100
+            new Guide("a3", "+/ adj1 adj2 adj2"), // a3 = (100 + 200) / 200
+            new Guide("a4", "?: adj3 adj1 adj2"), // a4 = adj3 > 0 ? adj1 : adj2
+            new Guide("a5", "abs -2"),
+        };
+
+        CustomGeometry geom = new CustomGeometry(CTCustomGeometry2D.Factory.newInstance());
+        Context ctx = new Context(geom, null);
+        for(Formula fmla : ops) {
+            ctx.evaluate(fmla);
+        }
+
+        assertEquals(100.0, ctx.getValue("adj1"));
+        assertEquals(200.0, ctx.getValue("adj2"));
+        assertEquals(1.0, ctx.getValue("a1"));
+        assertEquals(101.0, ctx.getValue("a2"));
+        assertEquals(1.5, ctx.getValue("a3"));
+        assertEquals(200.0, ctx.getValue("a4"));
+        assertEquals(2.0, ctx.getValue("a5"));
+    }
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/geom/TestPresetGeometries.java b/src/ooxml/testcases/org/apache/poi/xslf/geom/TestPresetGeometries.java
new file mode 100644 (file)
index 0000000..5c19b4e
--- /dev/null
@@ -0,0 +1,39 @@
+package org.apache.poi.xslf.geom;
+
+import junit.framework.TestCase;
+import org.apache.poi.xslf.model.geom.*;
+
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Rectangle2D;
+import java.util.Map;
+
+/**
+ * Date: 10/24/11
+ *
+ * @author Yegor Kozlov
+ */
+public class TestPresetGeometries extends TestCase {
+    public void testRead(){
+
+        Map<String, CustomGeometry> shapes = PresetGeometries.getInstance();
+        assertEquals(186, shapes.size());
+
+
+        for(String name : shapes.keySet()) {
+            CustomGeometry geom = shapes.get(name);
+            Context ctx = new Context(geom, new IAdjustableShape() {
+                public Rectangle2D getAnchor() {
+                    return new Rectangle2D.Double(0, 0, 100, 100);
+                }
+
+                public Guide getAdjustValue(String name) {
+                    return null;
+                }
+            });
+            for(Path p : geom){
+                GeneralPath path = p.getPath(ctx);
+                assertNotNull(path);
+            }
+        }
+    }
+}
index d65e93595b4062187764f26e951ab73ec9178738..f5fead717fe06e46e3de7b2bf0c1e70322fe409f 100755 (executable)
       <gd name="dx2" fmla="*/ ss a2 100000" />\r
       <gd name="x2" fmla="+- l dx2 0" />\r
       <gd name="dy1" fmla="*/ h a1 200000" />\r
-      <gd name="y1" fmla="+- vc 0 dy" />\r
+      <gd name="y1" fmla="+- vc 0 dy1" />\r
       <gd name="y2" fmla="+- vc dy1 0" />\r
       <gd name="dx1" fmla="*/ y1 dx2 hd2" />\r
       <gd name="x1" fmla="+- x2  0 dx1" />\r
       </path>\r
     </pathLst>\r
   </wedgeRoundRectCallout>\r
-</presetShapeDefinitons>
\ No newline at end of file
+</presetShapeDefinitons>\r