You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2015/07/24 23:47:58 UTC

svn commit: r1692593 [6/17] - in /poi: site/src/documentation/content/xdocs/ trunk/ trunk/src/examples/src/org/apache/poi/hslf/examples/ trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/ trunk/src/examples/src/org/apache/poi/xslf/usermodel...

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java?rev=1692593&r1=1692592&r2=1692593&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java Fri Jul 24 21:47:55 2015
@@ -19,13 +19,32 @@
 
 package org.apache.poi.xslf.usermodel;
 
-import java.awt.Graphics2D;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.sl.usermodel.ColorStyle;
+import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
+import org.apache.poi.sl.usermodel.PlaceableShape;
+import org.apache.poi.sl.usermodel.Shape;
 import org.apache.poi.util.Beta;
 import org.apache.poi.util.Internal;
+import org.apache.poi.xslf.model.PropertyFetcher;
 import org.apache.xmlbeans.XmlObject;
+import org.openxmlformats.schemas.drawingml.x2006.main.*;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
+import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
 
 /**
  * Base super-class class for all shapes in PresentationML
@@ -33,29 +52,40 @@ import org.apache.xmlbeans.XmlObject;
  * @author Yegor Kozlov
  */
 @Beta
-public abstract class XSLFShape {
-
-    /**
-     * @return the position of this shape within the drawing canvas.
-     *         The coordinates are expressed in points
-     */
-    public abstract Rectangle2D getAnchor();
-
-    /**
-     * @param anchor the position of this shape within the drawing canvas.
-     *               The coordinates are expressed in points
-     */
-    public abstract void setAnchor(Rectangle2D anchor);
-
+public abstract class XSLFShape implements Shape {
+    private final XmlObject _shape;
+    private final XSLFSheet _sheet;
+    private XSLFShapeContainer _parent;
+
+    private CTShapeProperties _spPr;
+    private CTShapeStyle _spStyle;
+    private CTNonVisualDrawingProps _nvPr;
+    private CTPlaceholder _ph;
+
+    protected XSLFShape(XmlObject shape, XSLFSheet sheet) {
+        _shape = shape;
+        _sheet = sheet;
+    }
+    
     /**
      * @return the xml bean holding this shape's data
      */
-    public abstract XmlObject getXmlObject();
-
+    public final XmlObject getXmlObject() {
+        // it's final because the xslf inheritance hierarchy is not necessary the same as
+        // the (not existing) xmlbeans hierarchy and subclasses shouldn't narrow it's return value
+        return _shape;
+    }
+    
+    public XSLFSheet getSheet() {
+        return _sheet;
+    }
+    
     /**
      * @return human-readable name of this shape, e.g. "Rectange 3"
      */
-    public abstract String getShapeName();
+    public String getShapeName(){
+        return getCNvPr().getName();
+    }
 
     /**
      * Returns a unique identifier for this shape within the current document.
@@ -68,148 +98,422 @@ public abstract class XSLFShape {
      *
      * @return unique id of this shape
      */
-    public abstract int getShapeId();
+    public int getShapeId() {
+        return (int)getCNvPr().getId();
+    }
 
     /**
-     * Rotate this shape.
-     * <p>
-     * Positive angles are clockwise (i.e., towards the positive y axis);
-     * negative angles are counter-clockwise (i.e., towards the negative y axis).
-     * </p>
+     * Set the contents of this shape to be a copy of the source shape.
+     * This method is called recursively for each shape when merging slides
      *
-     * @param theta the rotation angle in degrees.
+     * @param  sh the source shape
+     * @see org.apache.poi.xslf.usermodel.XSLFSlide#importContent(XSLFSheet)
      */
-    public abstract void setRotation(double theta);
+    @Internal
+    void copy(XSLFShape sh) {
+        if (!getClass().isInstance(sh)) {
+            throw new IllegalArgumentException(
+                    "Can't copy " + sh.getClass().getSimpleName() + " into " + getClass().getSimpleName());
+        }
 
-    /**
-     * Rotation angle in degrees
-     * <p>
-     * Positive angles are clockwise (i.e., towards the positive y axis);
-     * negative angles are counter-clockwise (i.e., towards the negative y axis).
-     * </p>
-     *
-     * @return rotation angle in degrees
-     */
-    public abstract double getRotation();
+        if (this instanceof PlaceableShape) {
+            PlaceableShape ps = (PlaceableShape)this;
+            ps.setAnchor(((PlaceableShape)sh).getAnchor());
+        }
+        
+        
+    }
+    
+    public void setParent(XSLFShapeContainer parent) {
+        this._parent = parent;
+    }
+    
+    public XSLFShapeContainer getParent() {
+        return this._parent;
+    }
+    
+    protected PaintStyle getFillPaint() {
+        PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
+            public boolean fetch(XSLFShape shape) {
+                XmlObject pr = null;
+                try {
+                    pr = shape.getSpPr();
+                    if (((CTShapeProperties)pr).isSetNoFill()) {
+                        setValue(PaintStyle.TRANSPARENT_PAINT);
+                        return true;
+                    }                    
+                } catch (IllegalStateException e) {}
+                // trying background properties now
+                if (pr == null) {
+                    pr = shape.getBgPr();
+                }
+                if (pr == null) {
+                    pr = shape.getGrpSpPr();
+                }
+                if (pr == null) {
+                    if (shape.getXmlObject() instanceof CTBackground) {
+                        pr = shape.getXmlObject();
+                    }
+                }
+                
+                if (pr == null) {
+                    setValue(PaintStyle.TRANSPARENT_PAINT);
+                    return true;
+                }
+                
+                PaintStyle paint = null;
+                for (XmlObject obj : pr.selectPath("*")) {
+                    paint = selectPaint(obj, null, getSheet().getPackagePart());
+                    if (paint != null) break;
+                }
+                
+                if (paint == null) return false;
+                
+                setValue(paint);
+                return true;
+            }
+        };
+        fetchShapeProperty(fetcher);
 
-    /**
-     * @param flip whether the shape is horizontally flipped
-     */
-    public abstract void setFlipHorizontal(boolean flip);
+        PaintStyle paint = fetcher.getValue();
+        if (paint != null) return paint;
+        
+        // fill color was not found, check if it is defined in the theme
+        // get a reference to a fill style within the style matrix.
+        CTStyleMatrixReference fillRef = null;
+        if (fillRef == null) {
+            CTShapeStyle style = getSpStyle();
+            if (style != null) fillRef = style.getFillRef();
+        }
+        if (fillRef == null) {
+            fillRef = getBgRef();
+        }
+        paint = selectPaint(fillRef);
 
-    /**
-     * Whether the shape is vertically flipped
-     *
-     * @param flip whether the shape is vertically flipped
-     */
-    public abstract void setFlipVertical(boolean flip);
+        return paint == null ? PaintStyle.TRANSPARENT_PAINT : paint;
+    }
+
+    protected CTBackgroundProperties getBgPr() {
+        String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:bgPr";
+        return selectProperty(CTBackgroundProperties.class, xquery);
+    }
+    
+    protected CTStyleMatrixReference getBgRef() {
+        String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:bgRef";
+        return selectProperty(CTStyleMatrixReference.class, xquery);
+    }
+    
+    protected CTGroupShapeProperties getGrpSpPr() {
+        String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:grpSpPr";
+        return selectProperty(CTGroupShapeProperties.class, xquery);
+    }
+    
+    protected CTNonVisualDrawingProps getCNvPr() {
+        if (_nvPr == null) {
+            String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr";
+            _nvPr = selectProperty(CTNonVisualDrawingProps.class, xquery);
+        }
+        return _nvPr;
+    }
+
+    protected CTShapeProperties getSpPr() {
+        if (_spPr == null) {
+            String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:spPr";
+            _spPr = selectProperty(CTShapeProperties.class, xquery);
+        }
+        if (_spPr == null) {
+            throw new IllegalStateException("CTShapeProperties was not found.");
+        }
+        return _spPr;
+    }
+
+    protected CTShapeStyle getSpStyle() {
+        if (_spStyle == null) {
+            String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:style";
+            _spStyle = selectProperty(CTShapeStyle.class, xquery);
+        }
+        return _spStyle;
+    }
+
+    protected CTPlaceholder getCTPlaceholder() {
+        if (_ph == null) {
+            String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph";
+            _ph = selectProperty(CTPlaceholder.class, xquery);
+        }
+        return _ph;
+    }
 
     /**
-     * Whether the shape is horizontally flipped
+     * Specifies that the corresponding shape should be represented by the generating application
+     * as a placeholder. When a shape is considered a placeholder by the generating application
+     * it can have special properties to alert the user that they may enter content into the shape.
+     * Different types of placeholders are allowed and can be specified by using the placeholder
+     * type attribute for this element
      *
-     * @return whether the shape is horizontally flipped
+     * @param placeholder
      */
-    public abstract boolean getFlipHorizontal();
-
+    protected void setPlaceholder(Placeholder placeholder) {
+        String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr";
+        CTApplicationNonVisualDrawingProps nv = selectProperty(CTApplicationNonVisualDrawingProps.class, xquery);
+        if (nv == null) return;
+        if(placeholder == null) {
+            if (nv.isSetPh()) nv.unsetPh();
+            _ph = null;
+        } else {
+            nv.addNewPh().setType(STPlaceholderType.Enum.forInt(placeholder.ordinal() + 1));
+        }
+    }
+    
+    
     /**
-     * Whether the shape is vertically flipped
+     * As there's no xmlbeans hierarchy, but XSLF works with subclassing, not all
+     * child classes work with a {@link CTShape} object, but often contain the same
+     * properties. This method is the generalized form of selecting and casting those
+     * properties.
      *
-     * @return whether the shape is vertically flipped
-     */
-    public abstract boolean getFlipVertical();
+     * @param resultClass
+     * @param xquery
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    protected <T extends XmlObject> T selectProperty(Class<T> resultClass, String xquery) {
+        XmlObject[] rs = getXmlObject().selectPath(xquery);
+        if (rs.length == 0) return null;
+        return (resultClass.isInstance(rs[0])) ? (T)rs[0] : null;
+    }
 
     /**
-     * Draw this shape into the supplied canvas
+     * Walk up the inheritance tree and fetch shape properties.
      *
-     * @param graphics the graphics to draw into
+     * The following order of inheritance is assumed:
+     * <p>
+     * slide <-- slideLayout <-- slideMaster
+     * </p>
+     *
+     * @param visitor the object that collects the desired property
+     * @return true if the property was fetched
      */
-    public abstract void draw(Graphics2D graphics);
+    protected boolean fetchShapeProperty(PropertyFetcher<?> visitor) {
+        boolean ok = visitor.fetch(this);
+
+        XSLFSimpleShape masterShape;
+        XSLFSheet masterSheet = (XSLFSheet)getSheet().getMasterSheet();
+        CTPlaceholder ph = getCTPlaceholder();
+
+        if (masterSheet != null && ph != null) {
+            if (!ok) {
+                masterShape = masterSheet.getPlaceholder(ph);
+                if (masterShape != null) {
+                    ok = visitor.fetch(masterShape);
+                }
+            }
 
+            // try slide master
+            if (!ok ) {
+                int textType;
+                if ( !ph.isSetType()) textType = STPlaceholderType.INT_BODY;
+                else {
+                    switch (ph.getType().intValue()) {
+                        case STPlaceholderType.INT_TITLE:
+                        case STPlaceholderType.INT_CTR_TITLE:
+                            textType = STPlaceholderType.INT_TITLE;
+                            break;
+                        case STPlaceholderType.INT_FTR:
+                        case STPlaceholderType.INT_SLD_NUM:
+                        case STPlaceholderType.INT_DT:
+                            textType = ph.getType().intValue();
+                            break;
+                        default:
+                            textType = STPlaceholderType.INT_BODY;
+                            break;
+                    }
+                }
+                XSLFSheet master = (XSLFSheet)masterSheet.getMasterSheet();
+                if (master != null) {
+                    masterShape = master.getPlaceholderByType(textType);
+                    if (masterShape != null) {
+                        ok = visitor.fetch(masterShape);
+                    }
+                }
+            }
+        }
+        return ok;
+    }
+
+    protected PaintStyle getPaint(XmlObject spPr, CTSchemeColor phClr) {
+        PaintStyle paint = null;
+        PackagePart pp = getSheet().getPackagePart();
+        for (XmlObject obj : spPr.selectPath("*")) {
+            paint = selectPaint(obj, phClr, pp);
+            if(paint != null) break;
+        }
+        return paint == null ? PaintStyle.TRANSPARENT_PAINT : paint;
+    }    
+    
     /**
-     * Apply 2-D transforms before drawing this shape. This includes rotation and flipping.
+     * Convert shape fill into java.awt.Paint. The result is either Color or
+     * TexturePaint or GradientPaint or null
+     *
+     * @param graphics  the target graphics
+     * @param obj       the xml to read. Must contain elements from the EG_ColorChoice group:
+     * <code>
+     *     a:scrgbClr    RGB Color Model - Percentage Variant
+     *     a:srgbClr    RGB Color Model - Hex Variant
+     *     a:hslClr    Hue, Saturation, Luminance Color Model
+     *     a:sysClr    System Color
+     *     a:schemeClr    Scheme Color
+     *     a:prstClr    Preset Color
+     *  </code>
+     *
+     * @param phClr     context color
+     * @param parentPart    the parent package part. Any external references (images, etc.) are resolved relative to it.
      *
-     * @param graphics the graphics whos transform matrix will be modified
+     * @return  the applied Paint or null if none was applied
      */
-    protected void applyTransform(Graphics2D graphics) {
-        Rectangle2D anchor = getAnchor();
-        AffineTransform tx = (AffineTransform)graphics.getRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM);
-        if(tx != null) {
-            anchor = tx.createTransformedShape(anchor).getBounds2D();
+    protected PaintStyle selectPaint(XmlObject obj, final CTSchemeColor phClr, final PackagePart parentPart) {
+        if (obj instanceof CTNoFillProperties) {
+            return PaintStyle.TRANSPARENT_PAINT;
+        } else if (obj instanceof CTSolidColorFillProperties) {
+            return selectPaint((CTSolidColorFillProperties)obj, phClr, parentPart);
+        } else if (obj instanceof CTBlipFillProperties) {
+            return selectPaint((CTBlipFillProperties)obj, phClr, parentPart);
+        } else if (obj instanceof CTGradientFillProperties) {
+            return selectPaint((CTGradientFillProperties) obj, phClr, parentPart);
+        } else if (obj instanceof CTStyleMatrixReference) {
+            return selectPaint((CTStyleMatrixReference)obj);
+        } else {
+            return null;
         }
+    }
 
-        // rotation
-        double rotation = getRotation();
-        if (rotation != 0.) {
-            // PowerPoint rotates shapes relative to the geometric center
-            double centerX = anchor.getCenterX();
-            double centerY = anchor.getCenterY();
+    protected PaintStyle selectPaint(final CTSolidColorFillProperties solidFill, final CTSchemeColor phClr, final PackagePart parentPart) {
+        final XSLFTheme theme = getSheet().getTheme();
+        final XSLFColor c = new XSLFColor(solidFill, theme, phClr);
+        return new SolidPaint() {
+            public ColorStyle getSolidColor() {
+                return c.getColorStyle();
+            }
+        };
+    }
+    
+    protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, final CTSchemeColor phClr, final PackagePart parentPart) {
+        final CTBlip blip = blipFill.getBlip();
+        return new TexturePaint() {
+            private PackagePart getPart() {
+                try {
+                    String blipId = blip.getEmbed();
+                    PackageRelationship rel = parentPart.getRelationship(blipId);
+                    return parentPart.getRelatedPart(rel);
+                } catch (InvalidFormatException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+            
+            public InputStream getImageData() {
+                try {
+                    return getPart().getInputStream();
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
 
-            // normalize rotation
-            rotation = (360.+(rotation%360.))%360.;
-            int quadrant = (((int)rotation+45)/90)%4;
-            double scaleX = 1.0, scaleY = 1.0;
+            public String getContentType() {
+                /* TOOD: map content-type */
+                return getPart().getContentType();
+            }
 
-            // scale to bounding box (bug #53176)
-            if (quadrant == 1 || quadrant == 3) {
-                // In quadrant 1 and 3, which is basically a shape in a more or less portrait orientation 
-                // (45-135 degrees and 225-315 degrees), we need to first rotate the shape by a multiple 
-                // of 90 degrees and then resize the bounding box to its original bbox. After that we can 
-                // rotate the shape to the exact rotation amount.
-                // It's strange that you'll need to rotate the shape back and forth again, but you can
-                // think of it, as if you paint the shape on a canvas. First you rotate the canvas, which might
-                // be already (differently) scaled, so you can paint the shape in its default orientation
-                // and later on, turn it around again to compare it with its original size ...
-                AffineTransform txg = new AffineTransform(); // graphics coordinate space
-                AffineTransform txs = new AffineTransform(tx); // shape coordinate space
-                txg.translate(centerX, centerY);
-                txg.rotate(Math.toRadians(quadrant*90));
-                txg.translate(-centerX, -centerY);
-                txs.translate(centerX, centerY);
-                txs.rotate(Math.toRadians(-quadrant*90));
-                txs.translate(-centerX, -centerY);
-                txg.concatenate(txs);
-                Rectangle2D anchor2 = txg.createTransformedShape(getAnchor()).getBounds2D();
-                scaleX = anchor.getWidth() == 0. ? 1.0 : anchor.getWidth() / anchor2.getWidth();
-                scaleY = anchor.getHeight() == 0. ? 1.0 : anchor.getHeight() / anchor2.getHeight();
+            public int getAlpha() {
+                return (blip.sizeOfAlphaModFixArray() > 0)
+                    ? blip.getAlphaModFixArray(0).getAmt()
+                    : 0;
             }
+        };        
+    }
+    
+    protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, final CTSchemeColor phClr, final PackagePart parentPart) {
 
-            // transformation is applied reversed ...
-            graphics.translate(centerX, centerY);
-            graphics.rotate(Math.toRadians(rotation-(double)(quadrant*90)));
-            graphics.scale(scaleX, scaleY);
-            graphics.rotate(Math.toRadians(quadrant*90));
-            graphics.translate(-centerX, -centerY);
-        }
+        @SuppressWarnings("deprecation")
+        final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();
 
-        //flip horizontal
-        if (getFlipHorizontal()) {
-            graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY());
-            graphics.scale(-1, 1);
-            graphics.translate(-anchor.getX(), -anchor.getY());
-        }
+        Arrays.sort(gs, new Comparator<CTGradientStop>() {
+            public int compare(CTGradientStop o1, CTGradientStop o2) {
+                Integer pos1 = o1.getPos();
+                Integer pos2 = o2.getPos();
+                return pos1.compareTo(pos2);
+            }
+        });
 
-        //flip vertical
-        if (getFlipVertical()) {
-            graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight());
-            graphics.scale(1, -1);
-            graphics.translate(-anchor.getX(), -anchor.getY());
+        final ColorStyle cs[] = new ColorStyle[gs.length];
+        final float fractions[] = new float[gs.length];
+        XSLFTheme theme = getSheet().getTheme();
+        
+        int i=0;
+        for (CTGradientStop cgs : gs) {
+            cs[i] = new XSLFColor(cgs, theme, phClr).getColorStyle();
+            fractions[i] = cgs.getPos() / 100000.f;
+            i++;
         }
-    }
+        
+        return new GradientPaint() {
 
-    /**
-     * Set the contents of this shape to be a copy of the source shape.
-     * This method is called recursively for each shape when merging slides
-     *
-     * @param  sh the source shape
-     * @see org.apache.poi.xslf.usermodel.XSLFSlide#importContent(XSLFSheet)
-     */
-    @Internal
-    void copy(XSLFShape sh) {
-        if (!getClass().isInstance(sh)) {
-            throw new IllegalArgumentException(
-                    "Can't copy " + sh.getClass().getSimpleName() + " into " + getClass().getSimpleName());
-        }
+            public double getGradientAngle() {
+                return (gradFill.isSetLin())
+                    ? gradFill.getLin().getAng() / 60000.d
+                    : 0;
+            }
 
-        setAnchor(sh.getAnchor());
+            public ColorStyle[] getGradientColors() {
+                return cs;
+            }
+
+            public float[] getGradientFractions() {
+                return fractions;
+            }
+
+            public boolean isRotatedWithShape() {
+                // TODO: is this correct???
+                return (gradFill.isSetRotWithShape() || !gradFill.getRotWithShape());
+            }
+
+            public GradientType getGradientType() {
+                if (gradFill.isSetLin()) {
+                    return GradientType.linear;
+                }
+                
+                if (gradFill.isSetPath()) {
+                    /* TODO: handle rect path */
+                    STPathShadeType.Enum ps = gradFill.getPath().getPath();
+                    if (ps == STPathShadeType.CIRCLE) {
+                        return GradientType.circular;
+                    } else if (ps == STPathShadeType.SHAPE) {
+                        return GradientType.shape;
+                    }
+                }
+                
+                return GradientType.linear;
+            }
+        };        
+    }
+    
+    protected PaintStyle selectPaint(CTStyleMatrixReference fillRef) {
+        if (fillRef == null) return null;
+        
+        // The idx attribute refers to the index of a fill style or
+        // background fill style within the presentation's style matrix, defined by the fmtScheme element.
+        // value of 0 or 1000 indicates no background,
+        // values 1-999 refer to the index of a fill style within the fillStyleLst element
+        // values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element.
+        int idx = (int)fillRef.getIdx();
+        CTSchemeColor phClr = fillRef.getSchemeClr();
+        XSLFSheet sheet = getSheet();
+        XSLFTheme theme = sheet.getTheme();
+        XmlObject fillProps = null;
+        CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme();
+        if (idx >= 1 && idx <= 999) {
+            fillProps = matrix.getFillStyleLst().selectPath("*")[idx - 1];
+        } else if (idx >= 1001 ){
+            fillProps = matrix.getBgFillStyleLst().selectPath("*")[idx - 1001];
+        }
+        return (fillProps == null) ? null : selectPaint(fillProps, phClr, theme.getPackagePart());
     }
 }
\ No newline at end of file

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShapeContainer.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShapeContainer.java?rev=1692593&r1=1692592&r2=1692593&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShapeContainer.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShapeContainer.java Fri Jul 24 21:47:55 2015
@@ -19,10 +19,12 @@
 
 package org.apache.poi.xslf.usermodel;
 
+import org.apache.poi.sl.usermodel.ShapeContainer;
+
 /**
  * Common interface for shape containers, e.g. sheets or groups of shapes
  */
-public interface XSLFShapeContainer extends Iterable<XSLFShape> {
+public interface XSLFShapeContainer extends ShapeContainer<XSLFShape> {
 
     /**
      * create a new shape with a predefined geometry and add it to this shape container
@@ -56,27 +58,6 @@ public interface XSLFShapeContainer exte
     XSLFPictureShape createPicture(int pictureIndex);
 
     /**
-     * Returns an array containing all of the elements in this container in proper
-     * sequence (from first to last element).
-     *
-     * @return an array containing all of the elements in this container in proper
-     *         sequence
-     */
-    XSLFShape[] getShapes();
-
-    /**
-     * Removes the specified shape from this sheet, if it is present
-     * (optional operation).  If this sheet does not contain the element,
-     * it is unchanged.
-     *
-     * @param xShape shape to be removed from this sheet, if present
-     * @return <tt>true</tt> if this sheet contained the specified element
-     * @throws IllegalArgumentException if the type of the specified shape
-     *         is incompatible with this sheet (optional)
-     */
-    boolean removeShape(XSLFShape xShape) ;
-
-    /**
      * Removes all of the elements from this container (optional operation).
      * The container will be empty after this call returns.
      */

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java?rev=1692593&r1=1692592&r2=1692593&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java Fri Jul 24 21:47:55 2015
@@ -16,13 +16,30 @@
 ==================================================================== */
 package org.apache.poi.xslf.usermodel;
 
+import java.awt.Graphics2D;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import javax.xml.namespace.QName;
+
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackagePartName;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.TargetMode;
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.sl.draw.DrawFactory;
+import org.apache.poi.sl.draw.Drawable;
+import org.apache.poi.sl.usermodel.Sheet;
 import org.apache.poi.util.Beta;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
@@ -37,21 +54,8 @@ import org.openxmlformats.schemas.presen
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
 
-import javax.xml.namespace.QName;
-import java.awt.Graphics2D;
-import java.awt.geom.AffineTransform;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
 @Beta
-public abstract class XSLFSheet extends POIXMLDocumentPart implements XSLFShapeContainer {
+public abstract class XSLFSheet extends POIXMLDocumentPart implements XSLFShapeContainer, Sheet<XSLFShape, XMLSlideShow> {
     private XSLFCommonSlideData _commonSlideData;
     private XSLFDrawing _drawing;
     private List<XSLFShape> _shapes;
@@ -142,6 +146,7 @@ public abstract class XSLFSheet extends
         List<XSLFShape> shapes = getShapeList();
         XSLFAutoShape sh = getDrawing().createAutoShape();
         shapes.add(sh);
+        sh.setParent(this);
         return sh;
     }
 
@@ -149,6 +154,7 @@ public abstract class XSLFSheet extends
         List<XSLFShape> shapes = getShapeList();
         XSLFFreeformShape sh = getDrawing().createFreeform();
         shapes.add(sh);
+        sh.setParent(this);
         return sh;
     }
 
@@ -156,6 +162,7 @@ public abstract class XSLFSheet extends
         List<XSLFShape> shapes = getShapeList();
         XSLFTextBox sh = getDrawing().createTextBox();
         shapes.add(sh);
+        sh.setParent(this);
         return sh;
     }
 
@@ -163,6 +170,7 @@ public abstract class XSLFSheet extends
         List<XSLFShape> shapes = getShapeList();
         XSLFConnectorShape sh = getDrawing().createConnector();
         shapes.add(sh);
+        sh.setParent(this);
         return sh;
     }
 
@@ -170,6 +178,7 @@ public abstract class XSLFSheet extends
         List<XSLFShape> shapes = getShapeList();
         XSLFGroupShape sh = getDrawing().createGroup();
         shapes.add(sh);
+        sh.setParent(this);
         return sh;
     }
 
@@ -191,6 +200,7 @@ public abstract class XSLFSheet extends
         sh.resize();
 
         getShapeList().add(sh);
+        sh.setParent(this);
         return sh;
     }
 
@@ -198,6 +208,7 @@ public abstract class XSLFSheet extends
         List<XSLFShape> shapes = getShapeList();
         XSLFTable sh = getDrawing().createTable();
         shapes.add(sh);
+        sh.setParent(this);
         return sh;
     }
 
@@ -206,8 +217,8 @@ public abstract class XSLFSheet extends
      *
      * @return an array of all shapes in this sheet
      */
-    public XSLFShape[] getShapes(){
-        return getShapeList().toArray(new XSLFShape[_shapes.size()]);
+    public List<XSLFShape> getShapes(){
+        return getShapeList();
     }
 
     /**
@@ -219,6 +230,12 @@ public abstract class XSLFSheet extends
         return getShapeList().iterator();
     }
 
+    public void addShape(XSLFShape shape) {
+        throw new UnsupportedOperationException(
+            "Adding a shape from a different container is not supported -"
+            + " create it from scratch witht XSLFSheet.create* methods");
+    }
+    
     /**
      * Removes the specified shape from this sheet, if it is present
      * (optional operation).  If this sheet does not contain the element,
@@ -249,7 +266,8 @@ public abstract class XSLFSheet extends
      * The container will be empty after this call returns.
      */
     public void clear() {
-        for(XSLFShape shape : getShapes()){
+        List<XSLFShape> shapes = new ArrayList<XSLFShape>(getShapes());
+        for(XSLFShape shape : shapes){
             removeShape(shape);
         }
     }
@@ -302,6 +320,9 @@ public abstract class XSLFSheet extends
         _spTree = null;
         _placeholders = null;
 
+        // fix-me: wth would this ever happen to work ...
+        
+        
         // first copy the source xml
         getSpTree().set(src.getSpTree());
 
@@ -370,12 +391,6 @@ public abstract class XSLFSheet extends
     	return null;
     }
 
-    /**
-     *
-     * @return master of this sheet.
-     */
-    public abstract XSLFSheet getMasterSheet();
-
     protected XSLFTextShape getTextShapeByType(Placeholder type){
         for(XSLFShape shape : this.getShapes()){
             if(shape instanceof XSLFTextShape) {
@@ -485,32 +500,11 @@ public abstract class XSLFSheet extends
      *
      * @param graphics
      */
+    @Override
     public void draw(Graphics2D graphics){
-        XSLFSheet master = getMasterSheet();
-        if(getFollowMasterGraphics() && master != null) master.draw(graphics);
-
-        graphics.setRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM, new AffineTransform());
-        for(XSLFShape shape : getShapeList()) {
-            if(!canDraw(shape)) continue;
-
-        	// remember the initial transform and restore it after we are done with drawing
-        	AffineTransform at = graphics.getTransform();
-
-            // concrete implementations can make sense of this hint,
-            // for example PSGraphics2D or PDFGraphics2D would call gsave() / grestore
-            graphics.setRenderingHint(XSLFRenderingHint.GSAVE, true);
-
-            // apply rotation and flipping
-            shape.applyTransform(graphics);
-            // draw stuff
-            shape.draw(graphics);
-
-            // restore the coordinate system
-            graphics.setTransform(at);
-
-            graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true);
-
-        }
+        DrawFactory drawFact = DrawFactory.getInstance(graphics);
+        Drawable draw = drawFact.getDrawable(this);
+        draw.draw(graphics);
     }
 
     /**
@@ -545,25 +539,26 @@ public abstract class XSLFSheet extends
      * Import a package part into this sheet.
      */
     PackagePart importPart(PackageRelationship srcRel, PackagePart srcPafrt) {
-
-        OPCPackage pkg = getPackagePart().getPackage();
-        if(!pkg.containPart(srcPafrt.getPartName())){
-            PackageRelationship rel = getPackagePart().addRelationship(
-                    srcPafrt.getPartName(), TargetMode.INTERNAL, srcRel.getRelationshipType());
-
-            PackagePart part = pkg.createPart(srcPafrt.getPartName(), srcPafrt.getContentType());
-            OutputStream out = part.getOutputStream();
-            try {
-                InputStream is = srcPafrt.getInputStream();
-                IOUtils.copy(is, out);
-                out.close();
-            } catch (IOException e){
-                throw new POIXMLException(e);
-            }
-            return part;
-        }  else {
+        PackagePart destPP = getPackagePart();
+        PackagePartName srcPPName = srcPafrt.getPartName();
+        
+        OPCPackage pkg = destPP.getPackage();
+        if(pkg.containPart(srcPPName)){
             // already exists
-            return pkg.getPart(srcPafrt.getPartName());
+            return pkg.getPart(srcPPName);
+        }            
+            
+        destPP.addRelationship(srcPPName, TargetMode.INTERNAL, srcRel.getRelationshipType());
+
+        PackagePart part = pkg.createPart(srcPPName, srcPafrt.getContentType());
+        OutputStream out = part.getOutputStream();
+        try {
+            InputStream is = srcPafrt.getInputStream();
+            IOUtils.copy(is, out);
+            out.close();
+        } catch (IOException e){
+            throw new POIXMLException(e);
         }
+        return part;
     }
 }
\ No newline at end of file

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java?rev=1692593&r1=1692592&r2=1692593&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java Fri Jul 24 21:47:55 2015
@@ -19,26 +19,31 @@
 
 package org.apache.poi.xslf.usermodel;
 
+import static org.apache.poi.sl.usermodel.PaintStyle.TRANSPARENT_PAINT;
+
+import java.awt.Color;
+import java.awt.geom.Rectangle2D;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.sl.draw.geom.CustomGeometry;
+import org.apache.poi.sl.draw.geom.Guide;
+import org.apache.poi.sl.draw.geom.PresetGeometries;
+import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;
+import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
 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.geom.CustomGeometry;
-import org.apache.poi.xslf.model.geom.Outline;
-import org.apache.poi.xslf.model.geom.Path;
-import org.apache.poi.xslf.model.geom.PresetGeometries;
 import org.apache.xmlbeans.XmlObject;
 import org.openxmlformats.schemas.drawingml.x2006.main.*;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
-import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
-
-import java.awt.*;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Represents a single (non-group) shape in a .pptx slide show
@@ -46,110 +51,35 @@ import java.util.List;
  * @author Yegor Kozlov
  */
 @Beta
-public abstract class XSLFSimpleShape extends XSLFShape {
+public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape {
     private static CTOuterShadowEffect NO_SHADOW = CTOuterShadowEffect.Factory.newInstance();
 
-    private final XmlObject _shape;
-    private final XSLFSheet _sheet;
-    private CTShapeProperties _spPr;
-    private CTShapeStyle _spStyle;
-    private CTNonVisualDrawingProps _nvPr;
-    private CTPlaceholder _ph;
-
     /* package */XSLFSimpleShape(XmlObject shape, XSLFSheet sheet) {
-        _shape = shape;
-        _sheet = sheet;
-    }
-
-    @Override
-    public XmlObject getXmlObject() {
-        return _shape;
-    }
-
-    /**
-     *
-     * @return the sheet this shape belongs to
-     */
-    public XSLFSheet getSheet() {
-        return _sheet;
+        super(shape,sheet);
     }
 
     /**
      *
      * @param type
      */
-    public void setShapeType(XSLFShapeType type){
-        CTShape shape = (CTShape) getXmlObject();
-        STShapeType.Enum geom = STShapeType.Enum.forInt(type.getIndex());
-        shape.getSpPr().getPrstGeom().setPrst(geom);
-    }
-
-    public XSLFShapeType getShapeType(){
-        CTShape shape = (CTShape) getXmlObject();
-        STShapeType.Enum geom = shape.getSpPr().getPrstGeom().getPrst();
-        return XSLFShapeType.forInt(geom.intValue());
-    }
-
-    @Override
-    public String getShapeName() {
-        return getNvPr().getName();
-    }
-
-    @Override
-    public int getShapeId() {
-        return (int) getNvPr().getId();
+    public void setShapeType(ShapeType type){
+        STShapeType.Enum geom = STShapeType.Enum.forInt(type.ooxmlId);
+        getSpPr().getPrstGeom().setPrst(geom);
     }
 
-    protected CTNonVisualDrawingProps getNvPr() {
-        if (_nvPr == null) {
-            XmlObject[] rs = _shape
-                    .selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");
-            if (rs.length != 0) {
-                _nvPr = (CTNonVisualDrawingProps) rs[0];
-            }
-        }
-        return _nvPr;
+    public ShapeType getShapeType(){
+        STShapeType.Enum geom = getSpPr().getPrstGeom().getPrst();
+        return ShapeType.forId(geom.intValue(), true);
     }
-
-    protected CTShapeProperties getSpPr() {
-        if (_spPr == null) {
-            for (XmlObject obj : _shape.selectPath("*")) {
-                if (obj instanceof CTShapeProperties) {
-                    _spPr = (CTShapeProperties) obj;
-                }
-            }
-        }
-        if (_spPr == null) {
-            throw new IllegalStateException("CTShapeProperties was not found.");
-        }
-        return _spPr;
-    }
-
-    protected CTShapeStyle getSpStyle() {
-        if (_spStyle == null) {
-            for (XmlObject obj : _shape.selectPath("*")) {
-                if (obj instanceof CTShapeStyle) {
-                    _spStyle = (CTShapeStyle) obj;
-                }
-            }
-        }
-        return _spStyle;
-    }
-
-    protected CTPlaceholder getCTPlaceholder() {
-        if (_ph == null) {
-            XmlObject[] obj = _shape.selectPath(
-                    "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph");
-            if (obj.length == 1) {
-                _ph = (CTPlaceholder) obj[0];
-            }
-        }
-        return _ph;
+    
+    protected CTTransform2D getSafeXfrm() {
+        CTTransform2D xfrm = getXfrm();
+        return (xfrm == null ? getSpPr().addNewXfrm() : xfrm);
     }
-
-    CTTransform2D getXfrm() {
+    
+    protected CTTransform2D getXfrm() {
         PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {
-            public boolean fetch(XSLFSimpleShape shape) {
+            public boolean fetch(XSLFShape shape) {
                 CTShapeProperties pr = shape.getSpPr();
                 if (pr.isSetXfrm()) {
                     setValue(pr.getXfrm());
@@ -180,8 +110,7 @@ public abstract class XSLFSimpleShape ex
 
     @Override
     public void setAnchor(Rectangle2D anchor) {
-        CTShapeProperties spPr = getSpPr();
-        CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
+        CTTransform2D xfrm = getSafeXfrm();
         CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();
         long x = Units.toEMU(anchor.getX());
         long y = Units.toEMU(anchor.getY());
@@ -194,44 +123,41 @@ public abstract class XSLFSimpleShape ex
         ext.setCx(cx);
         ext.setCy(cy);
     }
-
+    
     @Override
     public void setRotation(double theta) {
-        CTShapeProperties spPr = getSpPr();
-        CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
-        xfrm.setRot((int) (theta * 60000));
+        getSafeXfrm().setRot((int) (theta * 60000));
     }
 
     @Override
     public double getRotation() {
         CTTransform2D xfrm = getXfrm();
-        return (double) xfrm.getRot() / 60000;
+        return (xfrm == null || !xfrm.isSetRot()) ? 0 : (xfrm.getRot() / 60000.d);
     }
 
     @Override
     public void setFlipHorizontal(boolean flip) {
-        CTShapeProperties spPr = getSpPr();
-        CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
-        xfrm.setFlipH(flip);
+        getSafeXfrm().setFlipH(flip);
     }
 
     @Override
     public void setFlipVertical(boolean flip) {
-        CTShapeProperties spPr = getSpPr();
-        CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
-        xfrm.setFlipV(flip);
+        getSafeXfrm().setFlipV(flip);
     }
 
     @Override
     public boolean getFlipHorizontal() {
-        return getXfrm().getFlipH();
+        CTTransform2D xfrm = getXfrm();
+        return (xfrm == null || !xfrm.isSetFlipH()) ? false : getXfrm().getFlipH();
     }
 
     @Override
     public boolean getFlipVertical() {
-        return getXfrm().getFlipV();
+        CTTransform2D xfrm = getXfrm();
+        return (xfrm == null || !xfrm.isSetFlipV()) ? false : getXfrm().getFlipV();
     }
 
+    
     /**
      * Get default line properties defined in the theme (if any).
      * Used internally to resolve shape properties.
@@ -239,15 +165,23 @@ public abstract class XSLFSimpleShape ex
      * @return line propeties from the theme of null
      */
     CTLineProperties getDefaultLineProperties() {
-        CTLineProperties ln = null;
         CTShapeStyle style = getSpStyle();
-        if (style != null) {
-            // 1-based index of a line style within the style matrix
-            int idx = (int) style.getLnRef().getIdx();
-            CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme();
-            ln = styleMatrix.getLnStyleLst().getLnArray(idx - 1);
-        }
-        return ln;
+        if (style == null) return null;
+        CTStyleMatrixReference lnRef = style.getLnRef();
+        if (lnRef == null) return null;
+        // 1-based index of a line style within the style matrix
+        int idx = (int)lnRef.getIdx();
+        
+        XSLFTheme theme = getSheet().getTheme();
+        if (theme == null) return null;
+        CTBaseStyles styles = theme.getXmlObject().getThemeElements();
+        if (styles == null) return null;
+        CTStyleMatrix styleMatrix = styles.getFmtScheme();
+        if (styleMatrix == null) return null;
+        CTLineStyleList lineStyles = styleMatrix.getLnStyleLst();
+        if (lineStyles == null || lineStyles.sizeOfLnArray() < idx) return null;
+        
+        return lineStyles.getLnArray(idx - 1);
     }
 
     /**
@@ -284,14 +218,70 @@ public abstract class XSLFSimpleShape ex
      * if outline is turned off
      */
     public Color getLineColor() {
-        RenderableShape rShape = new RenderableShape(this);
-        Paint paint = rShape.getLinePaint(null);
-        if (paint instanceof Color) {
-            return (Color) paint;
+        PaintStyle ps = getLinePaint();
+        if (ps == null || ps == TRANSPARENT_PAINT) return null;
+        if (ps instanceof SolidPaint) {
+            return ((SolidPaint)ps).getSolidColor().getColor();
         }
         return null;
     }
 
+    protected PaintStyle getLinePaint() {
+        PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
+            public boolean fetch(XSLFShape shape) {
+                CTLineProperties spPr = shape.getSpPr().getLn();
+                if (spPr != null) {
+                    if (spPr.isSetNoFill()) {
+                        setValue(TRANSPARENT_PAINT); // use it as 'nofill' value
+                        return true;
+                    }
+                    
+                    PaintStyle paint = null;
+                    PackagePart pp = getSheet().getPackagePart();
+                    for (XmlObject obj : spPr.selectPath("*")) {
+                        paint = selectPaint(obj, null, pp);
+                        if (paint != null) {
+                            setValue(paint);
+                            return true;
+                        }
+                    }
+
+                    CTShapeStyle style = shape.getSpStyle();
+                    if (style != null) {
+                        paint = selectPaint(style.getLnRef());
+                        if (paint != null) {
+                            setValue(paint);
+                            return true;
+                        }
+                    }
+                }
+                return false;
+
+            }
+        };
+        fetchShapeProperty(fetcher);
+
+        PaintStyle paint = fetcher.getValue();
+        if (paint != null) return paint;
+        
+        // line color was not found, check if it is defined in the theme
+        CTShapeStyle style = getSpStyle();
+        if (style == null) return TRANSPARENT_PAINT;
+        
+        // get a reference to a line style within the style matrix.
+        CTStyleMatrixReference lnRef = style.getLnRef();
+        int idx = (int)lnRef.getIdx();
+        CTSchemeColor phClr = lnRef.getSchemeClr();
+        if(idx > 0){
+            XSLFTheme theme = getSheet().getTheme();
+            XmlObject lnProps = theme.getXmlObject().
+                    getThemeElements().getFmtScheme().getLnStyleLst().selectPath("*")[idx - 1];
+            paint = getPaint(lnProps, phClr);
+        }
+
+        return paint == null ? TRANSPARENT_PAINT : paint;
+    }
+    
     /**
      *
      * @param width line width in points. <code>0</code> means no line
@@ -309,12 +299,11 @@ public abstract class XSLFSimpleShape ex
     }
 
     /**
-     *
      * @return line width in points. <code>0</code> means no line.
      */
     public double getLineWidth() {
         PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>() {
-            public boolean fetch(XSLFSimpleShape shape) {
+            public boolean fetch(XSLFShape shape) {
                 CTShapeProperties spPr = shape.getSpPr();
                 CTLineProperties ln = spPr.getLn();
                 if (ln != null) {
@@ -347,6 +336,54 @@ public abstract class XSLFSimpleShape ex
     }
 
     /**
+     * @return the line compound
+     */
+    public LineCompound getLineCompound() {
+        PropertyFetcher<Integer> fetcher = new PropertyFetcher<Integer>() {
+            public boolean fetch(XSLFShape shape) {
+                CTShapeProperties spPr = shape.getSpPr();
+                CTLineProperties ln = spPr.getLn();
+                if (ln != null) {
+                    STCompoundLine.Enum stCmpd = ln.getCmpd();
+                    if (stCmpd != null) {
+                        setValue(stCmpd.intValue());
+                        return true;
+                    }
+                }
+                return false;
+            }
+        };
+        fetchShapeProperty(fetcher);
+
+        Integer cmpd = fetcher.getValue();
+        if (cmpd == null) {
+            CTLineProperties defaultLn = getDefaultLineProperties();
+            if (defaultLn != null) {
+                STCompoundLine.Enum stCmpd = defaultLn.getCmpd();
+                if (stCmpd != null) {
+                    cmpd = stCmpd.intValue();
+                }
+            }
+        }
+        
+        if (cmpd == null) return null;
+
+        switch (cmpd) {
+        default:
+        case STCompoundLine.INT_SNG:
+            return LineCompound.SINGLE;
+        case STCompoundLine.INT_DBL:
+            return LineCompound.DOUBLE;
+        case STCompoundLine.INT_THICK_THIN:
+            return LineCompound.THICK_THIN;
+        case STCompoundLine.INT_THIN_THICK:
+            return LineCompound.THIN_THICK;
+        case STCompoundLine.INT_TRI:
+            return LineCompound.TRIPLE;
+        }
+    }
+
+    /**
      *
      * @param dash a preset line dashing scheme to stroke thr shape outline
      */
@@ -358,7 +395,7 @@ public abstract class XSLFSimpleShape ex
         } else {
             CTPresetLineDashProperties val = CTPresetLineDashProperties.Factory
                     .newInstance();
-            val.setVal(STPresetLineDashVal.Enum.forInt(dash.ordinal() + 1));
+            val.setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId));
             CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
                     .addNewLn();
             ln.setPrstDash(val);
@@ -371,13 +408,13 @@ public abstract class XSLFSimpleShape ex
     public LineDash getLineDash() {
 
         PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>() {
-            public boolean fetch(XSLFSimpleShape shape) {
+            public boolean fetch(XSLFShape shape) {
                 CTShapeProperties spPr = shape.getSpPr();
                 CTLineProperties ln = spPr.getLn();
                 if (ln != null) {
                     CTPresetLineDashProperties ctDash = ln.getPrstDash();
                     if (ctDash != null) {
-                        setValue(LineDash.values()[ctDash.getVal().intValue() - 1]);
+                        setValue(LineDash.fromOoxmlId(ctDash.getVal().intValue()));
                         return true;
                     }
                 }
@@ -392,7 +429,7 @@ public abstract class XSLFSimpleShape ex
             if (defaultLn != null) {
                 CTPresetLineDashProperties ctDash = defaultLn.getPrstDash();
                 if (ctDash != null) {
-                    dash = LineDash.values()[ctDash.getVal().intValue() - 1];
+                    dash = LineDash.fromOoxmlId(ctDash.getVal().intValue());
                 }
             }
         }
@@ -411,7 +448,7 @@ public abstract class XSLFSimpleShape ex
         } else {
             CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
                     .addNewLn();
-            ln.setCap(STLineCap.Enum.forInt(cap.ordinal() + 1));
+            ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId));
         }
     }
 
@@ -421,13 +458,13 @@ public abstract class XSLFSimpleShape ex
      */
     public LineCap getLineCap() {
         PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>() {
-            public boolean fetch(XSLFSimpleShape shape) {
+            public boolean fetch(XSLFShape shape) {
                 CTShapeProperties spPr = shape.getSpPr();
                 CTLineProperties ln = spPr.getLn();
                 if (ln != null) {
                     STLineCap.Enum stCap = ln.getCap();
                     if (stCap != null) {
-                        setValue(LineCap.values()[stCap.intValue() - 1]);
+                        setValue(LineCap.fromOoxmlId(stCap.intValue()));
                         return true;
                     }
                 }
@@ -442,7 +479,7 @@ public abstract class XSLFSimpleShape ex
             if (defaultLn != null) {
                 STLineCap.Enum stCap = defaultLn.getCap();
                 if (stCap != null) {
-                    cap = LineCap.values()[stCap.intValue() - 1];
+                    cap = LineCap.fromOoxmlId(stCap.intValue());
                 }
             }
         }
@@ -486,10 +523,10 @@ public abstract class XSLFSimpleShape ex
      * is not solid (pattern or gradient)
      */
     public Color getFillColor() {
-        RenderableShape rShape = new RenderableShape(this);
-        Paint paint = rShape.getFillPaint(null);
-        if (paint instanceof Color) {
-            return (Color) paint;
+        PaintStyle ps = getFillPaint();
+        if (ps == null || ps == TRANSPARENT_PAINT) return null;
+        if (ps instanceof SolidPaint) {
+            return ((SolidPaint)ps).getSolidColor().getColor();
         }
         return null;
     }
@@ -499,7 +536,7 @@ public abstract class XSLFSimpleShape ex
      */
     public XSLFShadow getShadow() {
         PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>() {
-            public boolean fetch(XSLFSimpleShape shape) {
+            public boolean fetch(XSLFShape shape) {
                 CTShapeProperties spPr = shape.getSpPr();
                 if (spPr.isSetEffectLst()) {
                     CTOuterShadowEffect obj = spPr.getEffectLst().getOuterShdw();
@@ -519,7 +556,7 @@ public abstract class XSLFSimpleShape ex
                 // 1-based index of a shadow style within the style matrix
                 int idx = (int) style.getEffectRef().getIdx();
                 if(idx != 0) {
-                    CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme();
+                    CTStyleMatrix styleMatrix = getSheet().getTheme().getXmlObject().getThemeElements().getFmtScheme();
                     CTEffectStyleItem ef = styleMatrix.getEffectStyleLst().getEffectStyleArray(idx - 1);
                     obj = ef.getEffectLst().getOuterShdw();
                 }
@@ -528,90 +565,11 @@ public abstract class XSLFSimpleShape ex
         return (obj == null || obj == NO_SHADOW) ? null : new XSLFShadow(obj, this);
     }
 
-    @Override
-    public void draw(Graphics2D graphics) {
-        RenderableShape rShape = new RenderableShape(this);
-        rShape.render(graphics);
-
-        // draw line decorations
-        Color lineColor = getLineColor();
-        if(lineColor != null) {
-            graphics.setPaint(lineColor);
-            for(Outline o : getDecorationOutlines(graphics)){
-                if(o.getPath().isFilled()){
-                    graphics.fill(o.getOutline());
-                }
-                if(o.getPath().isStroked()){
-                    graphics.draw(o.getOutline());
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Walk up the inheritance tree and fetch shape properties.
-     *
-     * The following order of inheritance is assumed:
-     * <p>
-     * slide <-- slideLayout <-- slideMaster
-     * </p>
-     *
-     * @param visitor the object that collects the desired property
-     * @return true if the property was fetched
-     */
-    boolean fetchShapeProperty(PropertyFetcher visitor) {
-        boolean ok = visitor.fetch(this);
-
-        XSLFSimpleShape masterShape;
-        XSLFSheet masterSheet = getSheet().getMasterSheet();
-        CTPlaceholder ph = getCTPlaceholder();
-
-        if (masterSheet != null && ph != null) {
-            if (!ok) {
-                masterShape = masterSheet.getPlaceholder(ph);
-                if (masterShape != null) {
-                    ok = visitor.fetch(masterShape);
-                }
-            }
-
-            // try slide master
-            if (!ok ) {
-                int textType;
-                if ( !ph.isSetType()) textType = STPlaceholderType.INT_BODY;
-                else {
-                    switch (ph.getType().intValue()) {
-                        case STPlaceholderType.INT_TITLE:
-                        case STPlaceholderType.INT_CTR_TITLE:
-                            textType = STPlaceholderType.INT_TITLE;
-                            break;
-                        case STPlaceholderType.INT_FTR:
-                        case STPlaceholderType.INT_SLD_NUM:
-                        case STPlaceholderType.INT_DT:
-                            textType = ph.getType().intValue();
-                            break;
-                        default:
-                            textType = STPlaceholderType.INT_BODY;
-                            break;
-                    }
-                }
-                XSLFSheet master = masterSheet.getMasterSheet();
-                if (master != null) {
-                    masterShape = master.getPlaceholderByType(textType);
-                    if (masterShape != null) {
-                        ok = visitor.fetch(masterShape);
-                    }
-                }
-            }
-        }
-        return ok;
-    }
-
     /**
      *
      * @return definition of the shape geometry
      */
-    CustomGeometry getGeometry(){
+    public CustomGeometry getGeometry(){
         CTShapeProperties spPr = getSpPr();
         CustomGeometry geom;
         PresetGeometries dict = PresetGeometries.getInstance();
@@ -622,23 +580,16 @@ public abstract class XSLFSimpleShape ex
                 throw new IllegalStateException("Unknown shape geometry: " + name);
             }
         } else if (spPr.isSetCustGeom()){
-            geom = new CustomGeometry(spPr.getCustGeom());
+            XMLStreamReader staxReader = spPr.getCustGeom().newXMLStreamReader();
+            geom = PresetGeometries.convertCustomGeometry(staxReader);
+            try { staxReader.close(); }
+            catch (XMLStreamException e) {}
         } else {
             geom = dict.get("rect");
         }
         return geom;
     }
-
-
-    /**
-     * draw any content within this shape (image, text, etc.).
-     *
-     * @param graphics the graphics to draw into
-     */
-    public void drawContent(Graphics2D graphics){
-
-    }
-
+    
     @Override
     void copy(XSLFShape sh){
         super.copy(sh);
@@ -688,259 +639,213 @@ public abstract class XSLFSimpleShape ex
     /**
      * Specifies the line end decoration, such as a triangle or arrowhead.
      */
-    public void setLineHeadDecoration(LineDecoration style) {
+    public void setLineHeadDecoration(DecorationShape style) {
         CTLineProperties ln = getSpPr().getLn();
         CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
         if (style == null) {
             if (lnEnd.isSetType()) lnEnd.unsetType();
         } else {
-            lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
+            lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId));
         }
     }
 
-    public LineDecoration getLineHeadDecoration() {
+    public DecorationShape getLineHeadDecoration() {
         CTLineProperties ln = getSpPr().getLn();
-        if (ln == null || !ln.isSetHeadEnd()) return LineDecoration.NONE;
+        if (ln == null || !ln.isSetHeadEnd()) return DecorationShape.NONE;
 
         STLineEndType.Enum end = ln.getHeadEnd().getType();
-        return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
+        return end == null ? DecorationShape.NONE : DecorationShape.fromOoxmlId(end.intValue());
     }
 
     /**
      * specifies decorations which can be added to the head of a line.
      */
-    public void setLineHeadWidth(LineEndWidth style) {
+    public void setLineHeadWidth(DecorationSize style) {
         CTLineProperties ln = getSpPr().getLn();
         CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
         if (style == null) {
             if (lnEnd.isSetW()) lnEnd.unsetW();
         } else {
-            lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
+            lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId));
         }
     }
 
-    public LineEndWidth getLineHeadWidth() {
+    public DecorationSize getLineHeadWidth() {
         CTLineProperties ln = getSpPr().getLn();
-        if (ln == null || !ln.isSetHeadEnd()) return LineEndWidth.MEDIUM;
+        if (ln == null || !ln.isSetHeadEnd()) return DecorationSize.MEDIUM;
 
         STLineEndWidth.Enum w = ln.getHeadEnd().getW();
-        return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];
+        return w == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(w.intValue());
     }
 
     /**
      * Specifies the line end width in relation to the line width.
      */
-    public void setLineHeadLength(LineEndLength style) {
+    public void setLineHeadLength(DecorationSize style) {
         CTLineProperties ln = getSpPr().getLn();
         CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
 
         if (style == null) {
             if (lnEnd.isSetLen()) lnEnd.unsetLen();
         } else {
-            lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
+            lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId));
         }
     }
 
-    public LineEndLength getLineHeadLength() {
+    public DecorationSize getLineHeadLength() {
         CTLineProperties ln = getSpPr().getLn();
-        if (ln == null || !ln.isSetHeadEnd()) return LineEndLength.MEDIUM;
+        if (ln == null || !ln.isSetHeadEnd()) return DecorationSize.MEDIUM;
 
         STLineEndLength.Enum len = ln.getHeadEnd().getLen();
-        return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
+        return len == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(len.intValue());
     }
 
     /**
      * Specifies the line end decoration, such as a triangle or arrowhead.
      */
-    public void setLineTailDecoration(LineDecoration style) {
+    public void setLineTailDecoration(DecorationShape style) {
         CTLineProperties ln = getSpPr().getLn();
         CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
         if (style == null) {
             if (lnEnd.isSetType()) lnEnd.unsetType();
         } else {
-            lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
+            lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId));
         }
     }
 
-    public LineDecoration getLineTailDecoration() {
+    public DecorationShape getLineTailDecoration() {
         CTLineProperties ln = getSpPr().getLn();
-        if (ln == null || !ln.isSetTailEnd()) return LineDecoration.NONE;
+        if (ln == null || !ln.isSetTailEnd()) return DecorationShape.NONE;
 
         STLineEndType.Enum end = ln.getTailEnd().getType();
-        return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
+        return end == null ? DecorationShape.NONE : DecorationShape.fromOoxmlId(end.intValue());
     }
 
     /**
      * specifies decorations which can be added to the tail of a line.
      */
-    public void setLineTailWidth(LineEndWidth style) {
+    public void setLineTailWidth(DecorationSize style) {
         CTLineProperties ln = getSpPr().getLn();
         CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
         if (style == null) {
             if (lnEnd.isSetW()) lnEnd.unsetW();
         } else {
-            lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
+            lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId));
         }
     }
 
-    public LineEndWidth getLineTailWidth() {
+    public DecorationSize getLineTailWidth() {
         CTLineProperties ln = getSpPr().getLn();
-        if (ln == null || !ln.isSetTailEnd()) return LineEndWidth.MEDIUM;
+        if (ln == null || !ln.isSetTailEnd()) return DecorationSize.MEDIUM;
 
         STLineEndWidth.Enum w = ln.getTailEnd().getW();
-        return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];
+        return w == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(w.intValue());
     }
 
     /**
      * Specifies the line end width in relation to the line width.
      */
-    public void setLineTailLength(LineEndLength style) {
+    public void setLineTailLength(DecorationSize style) {
         CTLineProperties ln = getSpPr().getLn();
         CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
 
         if (style == null) {
             if (lnEnd.isSetLen()) lnEnd.unsetLen();
         } else {
-            lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
+            lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId));
         }
     }
 
-    public LineEndLength getLineTailLength() {
+    public DecorationSize getLineTailLength() {
         CTLineProperties ln = getSpPr().getLn();
-        if (ln == null || !ln.isSetTailEnd()) return LineEndLength.MEDIUM;
+        if (ln == null || !ln.isSetTailEnd()) return DecorationSize.MEDIUM;
 
         STLineEndLength.Enum len = ln.getTailEnd().getLen();
-        return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
+        return len == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(len.intValue());
+    }
+
+    public boolean isPlaceholder() {
+        CTPlaceholder ph = getCTPlaceholder();
+        return ph != null;
+    }
+
+    @SuppressWarnings("deprecation")
+    public Guide getAdjustValue(String name) {
+        CTPresetGeometry2D prst = getSpPr().getPrstGeom();
+        if (prst.isSetAvLst()) {
+            for (CTGeomGuide g : prst.getAvLst().getGdArray()) {
+                if (g.getName().equals(name)) {
+                    return new Guide(g.getName(), g.getFmla());
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public LineDecoration getLineDecoration() {
+        return new LineDecoration() {
+            public DecorationShape getHeadShape() {
+                return getLineHeadDecoration();
+            }
+
+            public DecorationSize getHeadWidth() {
+                return getLineHeadWidth();
+            }
+
+            public DecorationSize getHeadLength() {
+                return getLineHeadLength();
+            }
+
+            public DecorationShape getTailShape() {
+                return getLineTailDecoration();
+            }
+
+            public DecorationSize getTailWidth() {
+                return getLineTailWidth();
+            }
+
+            public DecorationSize getTailLength() {
+                return getLineTailLength();
+            }
+        };
     }
 
-    Outline getTailDecoration(Graphics2D graphics) {
-        LineEndLength tailLength = getLineTailLength();
-        LineEndWidth tailWidth = getLineTailWidth();
-
-        double lineWidth = Math.max(2.5, getLineWidth());
-
-        Rectangle2D anchor = new RenderableShape(this).getAnchor(graphics);
-        double x2 = anchor.getX() + anchor.getWidth(),
-                y2 = anchor.getY() + anchor.getHeight();
-
-        double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());
-
-        AffineTransform at = new AffineTransform();
-        Shape shape = null;
-        Path p = null;
-        Rectangle2D bounds;
-        double scaleY = Math.pow(2, tailWidth.ordinal());
-        double scaleX = Math.pow(2, tailLength.ordinal());
-        switch (getLineTailDecoration()) {
-            case OVAL:
-                p = new Path();
-                shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
-                bounds = shape.getBounds2D();
-                at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2);
-                at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
-                break;
-            case ARROW:
-                p = new Path();
-                GeneralPath arrow = new GeneralPath();
-                arrow.moveTo((float) (-lineWidth * 3), (float) (-lineWidth * 2));
-                arrow.lineTo(0, 0);
-                arrow.lineTo((float) (-lineWidth * 3), (float) (lineWidth * 2));
-                shape = arrow;
-                at.translate(x2, y2);
-                at.rotate(alpha);
-                break;
-            case TRIANGLE:
-                p = new Path();
-                scaleY = tailWidth.ordinal() + 1;
-                scaleX = tailLength.ordinal() + 1;
-                GeneralPath triangle = new GeneralPath();
-                triangle.moveTo((float) (-lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
-                triangle.lineTo(0, 0);
-                triangle.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
-                triangle.closePath();
-                shape = triangle;
-                at.translate(x2, y2);
-                at.rotate(alpha);
-                break;
-            default:
-                break;
-        }
-
-        if (shape != null) {
-            shape = at.createTransformedShape(shape);
-        }
-        return shape == null ? null : new Outline(shape, p);
-    }
-
-    Outline getHeadDecoration(Graphics2D graphics) {
-        LineEndLength headLength = getLineHeadLength();
-        LineEndWidth headWidth = getLineHeadWidth();
-
-        double lineWidth = Math.max(2.5, getLineWidth());
-
-        Rectangle2D anchor = new RenderableShape(this).getAnchor(graphics);
-        double x1 = anchor.getX(),
-                y1 = anchor.getY();
-
-        double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());
-
-        AffineTransform at = new AffineTransform();
-        Shape shape = null;
-        Path p = null;
-        Rectangle2D bounds;
-        double scaleY = 1;
-        double scaleX = 1;
-        switch (getLineHeadDecoration()) {
-            case OVAL:
-                p = new Path();
-                shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
-                bounds = shape.getBounds2D();
-                at.translate(x1 - bounds.getWidth() / 2, y1 - bounds.getHeight() / 2);
-                at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
-                break;
-            case STEALTH:
-            case ARROW:
-                p = new Path(false, true);
-                GeneralPath arrow = new GeneralPath();
-                arrow.moveTo((float) (lineWidth * 3 * scaleX), (float) (-lineWidth * scaleY * 2));
-                arrow.lineTo(0, 0);
-                arrow.lineTo((float) (lineWidth * 3 * scaleX), (float) (lineWidth * scaleY * 2));
-                shape = arrow;
-                at.translate(x1, y1);
-                at.rotate(alpha);
-                break;
-            case TRIANGLE:
-                p = new Path();
-                scaleY = headWidth.ordinal() + 1;
-                scaleX = headLength.ordinal() + 1;
-                GeneralPath triangle = new GeneralPath();
-                triangle.moveTo((float) (lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
-                triangle.lineTo(0, 0);
-                triangle.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
-                triangle.closePath();
-                shape = triangle;
-                at.translate(x1, y1);
-                at.rotate(alpha);
-                break;
-            default:
-                break;
-        }
-
-        if (shape != null) {
-            shape = at.createTransformedShape(shape);
-        }
-        return shape == null ? null : new Outline(shape, p);
-    }
-
-    private List<Outline> getDecorationOutlines(Graphics2D graphics){
-        List<Outline> lst = new ArrayList<Outline>();
-
-        Outline head = getHeadDecoration(graphics);
-        if(head != null) lst.add(head);
-
-        Outline tail = getTailDecoration(graphics);
-        if(tail != null) lst.add(tail);
-        return lst;
+    /**
+     * fetch shape fill as a java.awt.Paint
+     *
+     * @return either Color or GradientPaint or TexturePaint or null
+     */
+    public FillStyle getFillStyle() {
+        return new FillStyle() {
+            public PaintStyle getPaint() {
+                return XSLFSimpleShape.this.getFillPaint();
+            }
+        };
     }
 
+    public StrokeStyle getStrokeStyle() {
+        return new StrokeStyle() {
+            public PaintStyle getPaint() {
+                return XSLFSimpleShape.this.getLinePaint();
+            }
+
+            public LineCap getLineCap() {
+                return XSLFSimpleShape.this.getLineCap();
+            }
+
+            public LineDash getLineDash() {
+                return XSLFSimpleShape.this.getLineDash();
+            }
+
+            public double getLineWidth() {
+                return XSLFSimpleShape.this.getLineWidth();
+            }
+
+            public LineCompound getLineCompound() {
+                return XSLFSimpleShape.this.getLineCompound();
+            }
+            
+        };
+    }
 }

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java?rev=1692593&r1=1692592&r2=1692593&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java Fri Jul 24 21:47:55 2015
@@ -16,29 +16,32 @@
 ==================================================================== */
 package org.apache.poi.xslf.usermodel;
 
+import java.awt.Graphics2D;
+import java.io.IOException;
+
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.sl.draw.DrawFactory;
+import org.apache.poi.sl.draw.Drawable;
+import org.apache.poi.sl.usermodel.Slide;
 import org.apache.poi.util.Beta;
 import org.apache.xmlbeans.XmlException;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTCommonSlideData;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
 import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
-
-import java.awt.Graphics2D;
-import java.io.IOException;
 
 @Beta
-public final class XSLFSlide extends XSLFSheet {
+public final class XSLFSlide extends XSLFSheet implements Slide<XSLFShape, XMLSlideShow, XSLFNotes> {
    private final CTSlide _slide;
    private XSLFSlideLayout _layout;
    private XSLFComments _comments;
@@ -111,7 +114,6 @@ public final class XSLFSlide extends XSL
         return "sld";        
     }
 
-    @Override
     public XSLFSlideLayout getMasterSheet(){
         return getSlideLayout();
     }
@@ -211,15 +213,13 @@ public final class XSLFSlide extends XSL
     }
 
 
-    @Override
-    public void draw(Graphics2D graphics){
-
-        XSLFBackground bg = getBackground();
-        if(bg != null) bg.draw(graphics);
-
-        super.draw(graphics);
+    public boolean getFollowMasterObjects() {
+        return getFollowMasterGraphics();
+    }
+    
+    public void setFollowMasterObjects(boolean follow) {
+        setFollowMasterGraphics(follow);
     }
-
 
     @Override
     public XSLFSlide importContent(XSLFSheet src){
@@ -239,4 +239,44 @@ public final class XSLFSlide extends XSL
         return this;
     }
 
+    public boolean getFollowMasterBackground() {
+        return false;
+    }
+    
+    public void setFollowMasterBackground(boolean follow) {
+        // not implemented ... also not in the specs
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean getFollowMasterColourScheme() {
+        return false;
+    }
+    
+    public void setFollowMasterColourScheme(boolean follow) {
+        // not implemented ... only for OLE objects in the specs
+        throw new UnsupportedOperationException();
+    }
+
+    public void setNotes(XSLFNotes notes) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public int getSlideNumber() {
+        int idx = getSlideShow().getSlides().indexOf(this);
+        return (idx == -1) ? idx : idx+1;
+    }
+
+    /**
+     * Render this sheet into the supplied graphics object
+     *
+     * @param graphics
+     */
+    @Override
+    public void draw(Graphics2D graphics){
+        DrawFactory drawFact = DrawFactory.getInstance(graphics);
+        Drawable draw = drawFact.getDrawable(this);
+        draw.draw(graphics);
+    }
 }

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java?rev=1692593&r1=1692592&r2=1692593&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java Fri Jul 24 21:47:55 2015
@@ -16,9 +16,12 @@
 ==================================================================== */
 package org.apache.poi.xslf.usermodel;
 
+import java.io.IOException;
+
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.sl.usermodel.MasterSheet;
 import org.apache.poi.util.Beta;
 import org.apache.poi.util.Internal;
 import org.apache.xmlbeans.XmlException;
@@ -27,10 +30,8 @@ import org.openxmlformats.schemas.presen
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideLayout;
 import org.openxmlformats.schemas.presentationml.x2006.main.SldLayoutDocument;
 
-import java.io.IOException;
-
 @Beta
-public class XSLFSlideLayout extends XSLFSheet {
+public class XSLFSlideLayout extends XSLFSheet implements MasterSheet<XSLFShape, XMLSlideShow> {
     private CTSlideLayout _layout;
     private XSLFSlideMaster _master;
 

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java?rev=1692593&r1=1692592&r2=1692593&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java Fri Jul 24 21:47:55 2015
@@ -16,9 +16,14 @@
 ==================================================================== */
 package org.apache.poi.xslf.usermodel;
 
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.sl.usermodel.MasterSheet;
 import org.apache.poi.util.Beta;
 import org.apache.xmlbeans.XmlException;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
@@ -29,10 +34,6 @@ import org.openxmlformats.schemas.presen
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterTextStyles;
 import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument;
 
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
 /**
 * Slide master object associated with this layout.
 * <p>
@@ -53,7 +54,7 @@ import java.util.Map;
  * @author Yegor Kozlov
 */
 @Beta
- public class XSLFSlideMaster extends XSLFSheet {
+ public class XSLFSlideMaster extends XSLFSheet implements MasterSheet<XSLFShape, XMLSlideShow> {
 	private CTSlideMaster _slide;
     private Map<String, XSLFSlideLayout> _layouts;
     private XSLFTheme _theme;
@@ -82,7 +83,7 @@ import java.util.Map;
     }
 
     @Override
-    public XSLFSheet getMasterSheet() {
+    public MasterSheet<XSLFShape, XMLSlideShow> getMasterSheet() {
         return null;
     }
 
@@ -177,5 +178,4 @@ import java.util.Map;
             return null;
         }
     }
-
 }
\ No newline at end of file

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java?rev=1692593&r1=1692592&r2=1692593&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java Fri Jul 24 21:47:55 2015
@@ -27,6 +27,7 @@ import java.util.List;
 import javax.xml.namespace.QName;
 
 import org.apache.poi.POIXMLException;
+import org.apache.poi.sl.usermodel.TableShape;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.Units;
 import org.apache.xmlbeans.XmlCursor;
@@ -45,7 +46,7 @@ import org.openxmlformats.schemas.presen
  *
  * @author Yegor Kozlov
  */
-public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow> {
+public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow>, TableShape {
     static String TABLE_URI = "http://schemas.openxmlformats.org/drawingml/2006/table";
 
     private CTTable _table;



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org