poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ye...@apache.org
Subject svn commit: r1198658 [2/5] - in /poi/trunk: ./ src/examples/src/org/apache/poi/xslf/usermodel/tutorial/ src/ooxml/java/org/apache/poi/xslf/extractor/ src/ooxml/java/org/apache/poi/xslf/model/geom/ src/ooxml/java/org/apache/poi/xslf/usermodel/ src/ooxml...
Date Mon, 07 Nov 2011 09:12:18 GMT
Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java?rev=1198658&r1=1198657&r2=1198658&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java Mon Nov  7 09:12:16 2011
@@ -33,12 +33,14 @@ import org.openxmlformats.schemas.presen
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPictureNonVisual;
 
 import javax.imageio.ImageIO;
-import java.awt.*;
+import java.awt.Graphics2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayInputStream;
 
 /**
+ * Represents a picture shape
+ *
  * @author Yegor Kozlov
  */
 @Beta
@@ -114,37 +116,14 @@ public class XSLFPictureShape extends XS
     }
 
     @Override
-    public void draw(Graphics2D graphics){
-        java.awt.Shape outline = getOutline();
-
-        // shadow
-        XSLFShadow shadow = getShadow();
-
-        Paint fill = getFill(graphics);
-        Paint line = getLinePaint(graphics);
-        if(shadow != null) {
-        	shadow.draw(graphics);
-        }
-
-        if(fill != null) {
-            graphics.setPaint(fill);
-            graphics.fill(outline);
-        }
-
+    public void drawContent(Graphics2D graphics) {
 
         XSLFPictureData data = getPictureData();
     	if(data == null) return;
-    	
+
         XSLFImageRendener renderer = (XSLFImageRendener)graphics.getRenderingHint(XSLFRenderingHint.IMAGE_RENDERER);
         if(renderer == null) renderer = new XSLFImageRendener();
 
         renderer.drawImage(graphics, data, getAnchor());
-
-        if (line != null){
-            graphics.setPaint(line);
-            applyStroke(graphics);
-            graphics.draw(outline);
-        }
     }
-
 }

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRenderingHint.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRenderingHint.java?rev=1198658&r1=1198657&r2=1198658&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRenderingHint.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRenderingHint.java Mon Nov  7 09:12:16 2011
@@ -19,7 +19,7 @@
 
 package org.apache.poi.xslf.usermodel;
 
-import java.awt.*;
+import java.awt.RenderingHints;
 
 /**
  *
@@ -38,5 +38,37 @@ public class XSLFRenderingHint extends R
 
     public static final XSLFRenderingHint GSAVE = new XSLFRenderingHint(1);
     public static final XSLFRenderingHint GRESTORE = new XSLFRenderingHint(2);
+
+    /**
+     * Use a custom image rendener
+     *
+     * @see XSLFImageRendener
+     */
     public static final XSLFRenderingHint IMAGE_RENDERER = new XSLFRenderingHint(3);
+
+    /**
+     *  how to render text:
+     *
+     *  {@link #TEXT_MODE_CHARACTERS} (default) means to draw via
+     *   {@link java.awt.Graphics2D#drawString(java.text.AttributedCharacterIterator, float, float)}.
+     *   This mode draws text as characters. Use it if the target graphics writes the actual
+     *   character codes instead of glyph outlines (PDFGraphics2D, SVGGraphics2D, etc.)
+     *
+     *   {@link #TEXT_MODE_GLYPHS} means to render via
+     *   {@link java.awt.font.TextLayout#draw(java.awt.Graphics2D, float, float)}.
+     *   This mode draws glyphs as shapes and provides some advanced capabilities such as
+     *   justification and font substitution. Use it if the target graphics is an image.
+     *
+     */
+    public static final XSLFRenderingHint TEXT_RENDERING_MODE = new XSLFRenderingHint(4);
+
+    /**
+     * draw text via {@link java.awt.Graphics2D#drawString(java.text.AttributedCharacterIterator, float, float)}
+     */
+    public static final int TEXT_MODE_CHARACTERS = 1;
+
+    /**
+     * draw text via {@link java.awt.font.TextLayout#draw(java.awt.Graphics2D, float, float)}
+     */
+    public static final int TEXT_MODE_GLYPHS = 2;
 }
\ No newline at end of file

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java?rev=1198658&r1=1198657&r2=1198658&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java Mon Nov  7 09:12:16 2011
@@ -19,8 +19,11 @@ package org.apache.poi.xslf.usermodel;
 
 import org.apache.poi.util.Units;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
 
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Shape;
 import java.awt.geom.Rectangle2D;
 
 /**
@@ -37,36 +40,44 @@ public class XSLFShadow extends XSLFSimp
         _parent = parentShape;
     }
 
-     @Override
-    public void draw(Graphics2D graphics) {
-        Shape outline = _parent.getOutline();
 
-        Paint parentFillColor = _parent.getFill(graphics);
-        Paint parentLineColor = _parent.getLinePaint(graphics);
+    public void fill(Graphics2D graphics, Shape outline) {
 
         double angle = getAngle();
         double dist = getDistance();
-        double dx = dist * Math.cos( Math.toRadians(angle));
-        double dy = dist * Math.sin( Math.toRadians(angle));
+        double dx = dist * Math.cos(Math.toRadians(angle));
+        double dy = dist * Math.sin(Math.toRadians(angle));
 
         graphics.translate(dx, dy);
 
         Color fillColor = getFillColor();
         if (fillColor != null) {
             graphics.setColor(fillColor);
+            graphics.fill(outline);
         }
 
-        if(parentFillColor != null) {
-            graphics.fill(outline);
-     	}
-    	if(parentLineColor != null) {
-            _parent.applyStroke(graphics);
-             graphics.draw(outline);
-     	}
+        graphics.translate(-dx, -dy);
+    }
+
+    public void draw(Graphics2D graphics, Shape outline) {
+
+        double angle = getAngle();
+        double dist = getDistance();
+        double dx = dist * Math.cos(Math.toRadians(angle));
+        double dy = dist * Math.sin(Math.toRadians(angle));
+
+        graphics.translate(dx, dy);
+
+        Color fillColor = getFillColor();
+        if (fillColor != null) {
+            graphics.setColor(fillColor);
+            graphics.draw(outline);
+        }
 
         graphics.translate(-dx, -dy);
     }
 
+
     @Override
     public Rectangle2D getAnchor(){
         return _parent.getAnchor();
@@ -112,6 +123,11 @@ public class XSLFShadow extends XSLFSimp
     public Color getFillColor() {
         XSLFTheme theme = getSheet().getTheme();
         CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
-        return ct == null ? null : new XSLFColor(ct, theme).getColor();
+        if(ct == null) {
+            return null;
+        } else {
+            CTSchemeColor phClr = ct.getSchemeClr();
+            return new XSLFColor(ct, theme, phClr).getColor();
+        }
     }
 }
\ No newline at end of file

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=1198658&r1=1198657&r2=1198658&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 Mon Nov  7 09:12:16 2011
@@ -22,24 +22,54 @@ package org.apache.poi.xslf.usermodel;
 import org.apache.poi.util.Beta;
 import org.apache.xmlbeans.XmlObject;
 
-import java.awt.*;
+import java.awt.Graphics2D;
 import java.awt.geom.Rectangle2D;
 
 /**
+ * Base super-class class for all shapes in PresentationML
+ *
  * @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);
 
+    /**
+     *
+     * @return the xml bean holding this shape's data
+     */
     public abstract XmlObject getXmlObject();
 
+    /**
+     *
+     * @return human-readable name of this shape, e.g. "Rectange 3"
+     */
     public abstract String getShapeName();
 
+    /**
+     * Returns a unique identifier for this shape within the current document.
+     * This ID may be used to assist in uniquely identifying this object so that it can
+     * be referred to by other parts of the document.
+     * <p>
+     *     If multiple objects within the same document share the same id attribute value,
+     *     then the document shall be considered non-conformant.
+     * </p>
+     *
+     * @return unique id of this shape
+     */
     public abstract int getShapeId();
 
     /**
@@ -64,8 +94,16 @@ public abstract class XSLFShape {
      */
     public abstract double getRotation();
 
+    /**
+     * @param flip whether the shape is horizontally flipped
+     */
     public abstract void setFlipHorizontal(boolean flip);
 
+    /**
+     * Whether the shape is vertically flipped
+     *
+     * @param flip whether the shape is vertically flipped
+     */
     public abstract void setFlipVertical(boolean flip);
     
     /**
@@ -75,14 +113,25 @@ public abstract class XSLFShape {
      */
     public abstract boolean getFlipHorizontal();
 
+    /**
+     * Whether the shape is vertically flipped
+     *
+     * @return whether the shape is vertically flipped
+     */
     public abstract boolean getFlipVertical();
 
+    /**
+     * Draw this shape into the supplied canvas
+     *
+     * @param graphics the graphics to draw into
+     */
     public abstract void draw(Graphics2D graphics);
 
-    protected java.awt.Shape getOutline(){
-        return getAnchor();
-    }
-    
+    /**
+     * Apply 2-D transforms before drawing this shape. This includes rotation and flipping.
+     *
+     * @param graphics the graphics whos transform matrix will be modified
+     */
     protected void applyTransform(Graphics2D graphics){
         Rectangle2D anchor = getAnchor();
 
@@ -112,5 +161,5 @@ public abstract class XSLFShape {
             graphics.translate(-anchor.getX(), -anchor.getY());
         }
     }
-    
+
 }
\ No newline at end of file

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=1198658&r1=1198657&r2=1198658&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 Mon Nov  7 09:12:16 2011
@@ -21,9 +21,9 @@ import org.apache.poi.openxml4j.opc.Pack
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.TargetMode;
 import org.apache.poi.util.Beta;
+import org.apache.poi.util.Internal;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle;
 import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTCommonSlideData;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
@@ -34,22 +34,25 @@ import org.openxmlformats.schemas.presen
 import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
 
 import javax.xml.namespace.QName;
-import java.awt.*;
+import java.awt.Graphics2D;
 import java.awt.geom.AffineTransform;
 import java.io.IOException;
 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 {
+public abstract class XSLFSheet extends POIXMLDocumentPart implements Iterable<XSLFShape> {
     private XSLFCommonSlideData _commonSlideData;
     private XSLFDrawing _drawing;
     private List<XSLFShape> _shapes;
     private CTGroupShape _spTree;
+
+    private List<XSLFTextShape>_placeholders;
     private Map<Integer, XSLFSimpleShape> _placeholderByIdMap;
     private Map<Integer, XSLFSimpleShape> _placeholderByTypeMap;
 
@@ -61,6 +64,10 @@ public abstract class XSLFSheet extends 
         super(part, rel);
     }
 
+    /**
+     *
+     * @return the XMLSlideShow this sheet belongs to
+     */
     public XMLSlideShow getSlideShow() {
         POIXMLDocumentPart p = getParent();
         while(p != null) {
@@ -69,7 +76,7 @@ public abstract class XSLFSheet extends 
             }
             p = p.getParent();
         }
-        return null;
+        throw new IllegalStateException("SlideShow was not found");
     }
 
     protected List<XSLFShape> buildShapes(CTGroupShape spTree){
@@ -92,11 +99,16 @@ public abstract class XSLFSheet extends 
         return shapes;
     }
 
+    /**
+     * @return top-level Xml bean representing this sheet
+     */
     public abstract XmlObject getXmlObject();
 
+    @Internal
     public XSLFCommonSlideData getCommonSlideData() {
        return _commonSlideData;
     }
+
     protected void setCommonSlideData(CTCommonSlideData data) {
        if(data == null) {
           _commonSlideData = null;
@@ -180,10 +192,34 @@ public abstract class XSLFSheet extends 
         return sh;
     }
 
+    /**
+     * Returns an array containing all of the shapes in this sheet
+     *
+     * @return an array of all shapes in this sheet
+     */
     public XSLFShape[] getShapes(){
         return getShapeList().toArray(new XSLFShape[_shapes.size()]);
     }
 
+    /**
+     * Returns an iterator over the shapes in this sheet
+     *
+     * @return an iterator over the shapes in this sheet
+     */
+    public Iterator<XSLFShape> iterator(){
+        return getShapeList().iterator();
+    }
+
+    /**
+     * 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)
+     */
     public boolean removeShape(XSLFShape xShape) {
         XmlObject obj = xShape.getXmlObject();
         CTGroupShape spTree = getSpTree();
@@ -199,10 +235,6 @@ public abstract class XSLFSheet extends 
         return getShapeList().remove(xShape);
     }
 
-    public XSLFBackground getBackground(){
-        return null;
-    }
-
     protected abstract String getRootElementName();
 
     protected CTGroupShape getSpTree(){
@@ -248,22 +280,22 @@ public abstract class XSLFSheet extends 
         getXmlObject().set(src.getXmlObject());
     }
 
-    public XSLFTheme getTheme(){
-    	return null;
-    }
-
-    public XSLFSlideMaster getSlideMaster(){
+    /**
+     * @return theme (shared styles) associated with this theme.
+     *  By default returns <code>null</code> which means that this sheet is theme-less.
+     *  Sheets that support the notion of themes (slides, masters, layouts, etc.) should override this
+     *  method and return the corresposnding package part.
+     */
+    XSLFTheme getTheme(){
     	return null;
     }
 
-    public XSLFSlideLayout getSlideLayout(){
-    	return null;
-    }
+    /**
+     *
+     * @return master of this sheet.
+     */
+    public abstract XSLFSheet getMasterSheet();
 
-    protected CTTextListStyle getTextProperties(Placeholder textType) {
-        return null;
-    }
-    
     protected XSLFTextShape getTextShapeByType(Placeholder type){
         for(XSLFShape shape : this.getShapes()){
             if(shape instanceof XSLFTextShape) {
@@ -286,72 +318,107 @@ public abstract class XSLFSheet extends 
         return shape;
     }
 
-    XSLFSimpleShape getPlaceholderById(int id) {
-        if(_placeholderByIdMap == null) {
+    void initPlaceholders() {
+        if(_placeholders == null) {
+            _placeholders = new ArrayList<XSLFTextShape>();
             _placeholderByIdMap = new HashMap<Integer, XSLFSimpleShape>();
+            _placeholderByTypeMap = new HashMap<Integer, XSLFSimpleShape>();
+
             for(XSLFShape sh : getShapes()){
-                if(sh instanceof XSLFSimpleShape){
-                    XSLFSimpleShape sShape = (XSLFSimpleShape)sh;
+                if(sh instanceof XSLFTextShape){
+                    XSLFTextShape sShape = (XSLFTextShape)sh;
                     CTPlaceholder ph = sShape.getCTPlaceholder();
-                    if(ph != null && ph.isSetIdx()){
-                        int idx = (int)ph.getIdx();
-                        _placeholderByIdMap.put(idx, sShape);
+                    if(ph != null) {
+                        _placeholders.add(sShape);
+                        if(ph.isSetIdx()) {
+                            int idx = (int)ph.getIdx();
+                            _placeholderByIdMap.put(idx, sShape);
+                        }
+                        if(ph.isSetType()){
+                            _placeholderByTypeMap.put(ph.getType().intValue(), sShape);
+                        }
                     }
                 }
             }
         }
+    }
+
+    XSLFSimpleShape getPlaceholderById(int id) {
+        initPlaceholders();
         return _placeholderByIdMap.get(id);
     }
 
     XSLFSimpleShape getPlaceholderByType(int ordinal) {
-        if(_placeholderByTypeMap == null) {
-            _placeholderByTypeMap = new HashMap<Integer, XSLFSimpleShape>();
-            for(XSLFShape sh : getShapes()){
-                if(sh instanceof XSLFSimpleShape){
-                    XSLFSimpleShape sShape = (XSLFSimpleShape)sh;
-                    CTPlaceholder ph = sShape.getCTPlaceholder();
-                    if(ph != null && ph.isSetType()){
-                        _placeholderByTypeMap.put(ph.getType().intValue(), sShape);
-                    }
-                }
-            }
-        }
+        initPlaceholders();
         return _placeholderByTypeMap.get(ordinal);
     }
 
     /**
+     *
+     * @param idx 0-based index of a placeholder in the sheet
+     * @return placeholder
+     */
+    public XSLFTextShape getPlaceholder(int idx) {
+        initPlaceholders();
+        return _placeholders.get(idx);
+    }
+
+    /**
+     *
+     * @return all placeholder shapes in this sheet
+     */
+    public XSLFTextShape[] getPlaceholders() {
+        initPlaceholders();
+        return _placeholders.toArray(new XSLFTextShape[_placeholders.size()]);
+    }
+
+    /**
      * Checks if this <code>sheet</code> displays the specified shape.
      *
-     * Subclasses can override it and skip certain shapes from drawings.
+     * Subclasses can override it and skip certain shapes from drawings,
+     * for instance, slide masters and layouts don't display placeholders
      */
     protected boolean canDraw(XSLFShape shape){
         return true;
     }
 
     /**
+     *
+     * @return whether shapes on the master sheet should be shown. By default master graphics is turned off.
+     * Sheets that support the notion of master (slide, slideLayout) should override it and
+     * check this setting in the sheet XML
+     */
+    public boolean getFollowMasterGraphics(){
+        return false;
+    }
+
+    /**
      * Render this sheet into the supplied graphics object
      *
      * @param graphics
      */
     public void draw(Graphics2D graphics){
-        XSLFBackground bg = getBackground();
-        if(bg != null) bg.draw(graphics);
+        XSLFSheet master = getMasterSheet();
+        if(getFollowMasterGraphics() && master != null) master.draw(graphics);
 
         for(XSLFShape shape : getShapeList()) {
             if(!canDraw(shape)) continue;
 
         	// remember the initial transform and restore it after we are done with drawing
-        	AffineTransform at0 = graphics.getTransform();
+        	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(at0);
+            graphics.setTransform(at);
+
             graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true);
 
         }

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=1198658&r1=1198657&r2=1198658&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 Mon Nov  7 09:12:16 2011
@@ -19,8 +19,6 @@
 
 package org.apache.poi.xslf.usermodel;
 
-import org.apache.poi.openxml4j.opc.PackagePart;
-import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.util.Beta;
 import org.apache.poi.util.Units;
 import org.apache.poi.xslf.model.PropertyFetcher;
@@ -28,36 +26,50 @@ import org.apache.poi.xslf.model.geom.Co
 import org.apache.poi.xslf.model.geom.CustomGeometry;
 import org.apache.poi.xslf.model.geom.Guide;
 import org.apache.poi.xslf.model.geom.IAdjustableShape;
+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.drawingml.x2006.main.CTEffectStyleItem;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
+import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
+import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
 import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
 
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.Shape;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.GeneralPath;
-import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.awt.Paint;
-import java.awt.Graphics2D;
-import java.awt.Color;
-import java.awt.TexturePaint;
-import java.awt.AlphaComposite;
-import java.awt.GradientPaint;
-import java.awt.BasicStroke;
-import java.awt.Stroke;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Constructor;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 
 /**
+ * Represents a single (non-group) shape in a .pptx slide show
+ *
  * @author Yegor Kozlov
  */
 @Beta
 public abstract class XSLFSimpleShape extends XSLFShape {
+
     private final XmlObject _shape;
     private final XSLFSheet _sheet;
     private CTShapeProperties _spPr;
@@ -70,10 +82,15 @@ public abstract class XSLFSimpleShape ex
         _sheet = sheet;
     }
 
+    @Override
     public XmlObject getXmlObject() {
         return _shape;
     }
 
+    /**
+     *
+     * @return the sheet this shape belongs to
+     */
     public XSLFSheet getSheet() {
         return _sheet;
     }
@@ -88,10 +105,12 @@ public abstract class XSLFSimpleShape ex
         return stEnum == null ? 0 : stEnum.intValue();
     }
 
+    @Override
     public String getShapeName() {
         return getNvPr().getName();
     }
 
+    @Override
     public int getShapeId() {
         return (int) getNvPr().getId();
     }
@@ -132,22 +151,22 @@ public abstract class XSLFSimpleShape ex
         return _spStyle;
     }
 
-    protected CTPlaceholder getCTPlaceholder(){
-        if(_ph == null){
+    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];
+            if (obj.length == 1) {
+                _ph = (CTPlaceholder) obj[0];
             }
         }
         return _ph;
     }
 
-    private CTTransform2D getXfrm(){
-        PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>(){
-            public boolean fetch(XSLFSimpleShape shape){
+    private CTTransform2D getXfrm() {
+        PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {
+            public boolean fetch(XSLFSimpleShape shape) {
                 CTShapeProperties pr = shape.getSpPr();
-                if(pr.isSetXfrm()){
+                if (pr.isSetXfrm()) {
                     setValue(pr.getXfrm());
                     return true;
                 }
@@ -158,10 +177,11 @@ public abstract class XSLFSimpleShape ex
         return fetcher.getValue();
     }
 
+    @Override
     public Rectangle2D getAnchor() {
 
         CTTransform2D xfrm = getXfrm();
-        
+
         CTPoint2D off = xfrm.getOff();
         long x = off.getX();
         long y = off.getY();
@@ -173,6 +193,7 @@ public abstract class XSLFSimpleShape ex
                 Units.toPoints(cx), Units.toPoints(cy));
     }
 
+    @Override
     public void setAnchor(Rectangle2D anchor) {
         CTShapeProperties spPr = getSpPr();
         CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
@@ -189,64 +210,46 @@ public abstract class XSLFSimpleShape ex
         ext.setCy(cy);
     }
 
-    /**
-     * 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>
-     *
-     * @param theta the rotation angle in degrees.
-     */
+    @Override
     public void setRotation(double theta) {
         CTShapeProperties spPr = getSpPr();
         CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
         xfrm.setRot((int) (theta * 60000));
     }
 
-    /**
-     * 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
-     */
+    @Override
     public double getRotation() {
         CTTransform2D xfrm = getXfrm();
         return (double) xfrm.getRot() / 60000;
     }
 
+    @Override
     public void setFlipHorizontal(boolean flip) {
         CTShapeProperties spPr = getSpPr();
         CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
         xfrm.setFlipH(flip);
     }
 
+    @Override
     public void setFlipVertical(boolean flip) {
         CTShapeProperties spPr = getSpPr();
         CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
         xfrm.setFlipV(flip);
     }
 
-    /**
-     * Whether the shape is horizontally flipped
-     *
-     * @return whether the shape is horizontally flipped
-     */
+    @Override
     public boolean getFlipHorizontal() {
         return getXfrm().getFlipH();
     }
 
+    @Override
     public boolean getFlipVertical() {
         return getXfrm().getFlipV();
     }
 
     /**
-     * Get line properties defined in the theme (if any)
+     * Get default line properties defined in the theme (if any).
+     * Used internally to resolve shape properties.
      *
      * @return line propeties from the theme of null
      */
@@ -262,6 +265,10 @@ public abstract class XSLFSimpleShape ex
         return ln;
     }
 
+    /**
+    * @param color  the color to paint the shape outline.
+     * A <code>null</code> value turns off the shape outline.
+     */
     public void setLineColor(Color color) {
         CTShapeProperties spPr = getSpPr();
         if (color == null) {
@@ -281,48 +288,24 @@ public abstract class XSLFSimpleShape ex
         }
     }
 
+    /**
+     *
+     * @return the color of the shape outline or <code>null</code>
+     * if outline is turned off
+     */
     public Color getLineColor() {
-        Paint paint = getLinePaint(null);
-        if(paint instanceof Color){
-            return (Color)paint;
+        RenderableShape rShape = new RenderableShape(this);
+        Paint paint = rShape.getLinePaint(null);
+        if (paint instanceof Color) {
+            return (Color) paint;
         }
         return null;
     }
 
-    public Paint getLinePaint(final Graphics2D graphics) {
-        final XSLFTheme theme = _sheet.getTheme();
-        final Color nofill = new Color(0,0,0,0);
-        PropertyFetcher<Paint> fetcher = new PropertyFetcher<Paint>(){
-            public boolean fetch(XSLFSimpleShape shape){
-                CTLineProperties spPr = shape.getSpPr().getLn();
-                if (spPr != null) {
-                    if (spPr.isSetNoFill()) {
-                        setValue(nofill); // use it as 'nofill' value
-                        return true;
-                    }
-                    Paint paint = getPaint(graphics, spPr);
-                    if (paint != null) {
-                        setValue( paint );
-                        return true;
-                    }
-                }
-                return false;
-
-            }
-        };
-        fetchShapeProperty(fetcher);
-
-        Paint color = fetcher.getValue();
-        if(color == null){
-            // line color was not found, check if it is defined in the theme
-            CTShapeStyle style = getSpStyle();
-            if (style != null) {
-                color = new XSLFColor(style.getLnRef(), theme).getColor();
-            }
-        }
-        return color == nofill ? null : color;
-    }
-
+    /**
+     *
+     * @param width line width in points. <code>0</code> means no line
+     */
     public void setLineWidth(double width) {
         CTShapeProperties spPr = getSpPr();
         if (width == 0.) {
@@ -335,9 +318,13 @@ 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){
+        PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>() {
+            public boolean fetch(XSLFSimpleShape shape) {
                 CTShapeProperties spPr = shape.getSpPr();
                 CTLineProperties ln = spPr.getLn();
                 if (ln != null) {
@@ -347,7 +334,7 @@ public abstract class XSLFSimpleShape ex
                     }
 
                     if (ln.isSetW()) {
-                        setValue( Units.toPoints(ln.getW()) );
+                        setValue(Units.toPoints(ln.getW()));
                         return true;
                     }
                 }
@@ -357,7 +344,7 @@ public abstract class XSLFSimpleShape ex
         fetchShapeProperty(fetcher);
 
         double lineWidth = 0;
-        if(fetcher.getValue() == null) {
+        if (fetcher.getValue() == null) {
             CTLineProperties defaultLn = getDefaultLineProperties();
             if (defaultLn != null) {
                 if (defaultLn.isSetW()) lineWidth = Units.toPoints(defaultLn.getW());
@@ -369,6 +356,10 @@ public abstract class XSLFSimpleShape ex
         return lineWidth;
     }
 
+    /**
+     *
+     * @param dash a preset line dashing scheme to stroke thr shape outline
+     */
     public void setLineDash(LineDash dash) {
         CTShapeProperties spPr = getSpPr();
         if (dash == null) {
@@ -384,16 +375,19 @@ public abstract class XSLFSimpleShape ex
         }
     }
 
+    /**
+     * @return  a preset line dashing scheme to stroke thr shape outline
+     */
     public LineDash getLineDash() {
 
-        PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>(){
-            public boolean fetch(XSLFSimpleShape shape){
+        PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>() {
+            public boolean fetch(XSLFSimpleShape 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.values()[ctDash.getVal().intValue() - 1]);
                         return true;
                     }
                 }
@@ -403,7 +397,7 @@ public abstract class XSLFSimpleShape ex
         fetchShapeProperty(fetcher);
 
         LineDash dash = fetcher.getValue();
-        if(dash == null){
+        if (dash == null) {
             CTLineProperties defaultLn = getDefaultLineProperties();
             if (defaultLn != null) {
                 CTPresetLineDashProperties ctDash = defaultLn.getPrstDash();
@@ -415,6 +409,10 @@ public abstract class XSLFSimpleShape ex
         return dash;
     }
 
+    /**
+     *
+     * @param cap the line end cap style
+     */
     public void setLineCap(LineCap cap) {
         CTShapeProperties spPr = getSpPr();
         if (cap == null) {
@@ -427,15 +425,19 @@ public abstract class XSLFSimpleShape ex
         }
     }
 
+    /**
+     *
+     * @return the line end cap style
+     */
     public LineCap getLineCap() {
-        PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>(){
-            public boolean fetch(XSLFSimpleShape shape){
+        PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>() {
+            public boolean fetch(XSLFSimpleShape 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.values()[stCap.intValue() - 1]);
                         return true;
                     }
                 }
@@ -445,7 +447,7 @@ public abstract class XSLFSimpleShape ex
         fetchShapeProperty(fetcher);
 
         LineCap cap = fetcher.getValue();
-        if(cap == null){
+        if (cap == null) {
             CTLineProperties defaultLn = getDefaultLineProperties();
             if (defaultLn != null) {
                 STLineCap.Enum stCap = defaultLn.getCap();
@@ -469,10 +471,10 @@ public abstract class XSLFSimpleShape ex
         if (color == null) {
             if (spPr.isSetSolidFill()) spPr.unsetSolidFill();
 
-            if(!spPr.isSetNoFill()) spPr.addNewNoFill();
+            if (!spPr.isSetNoFill()) spPr.addNewNoFill();
         } else {
-            if(spPr.isSetNoFill()) spPr.unsetNoFill();
-            
+            if (spPr.isSetNoFill()) spPr.unsetNoFill();
+
             CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr
                     .getSolidFill() : spPr.addNewSolidFill();
 
@@ -485,55 +487,24 @@ public abstract class XSLFSimpleShape ex
     }
 
     /**
-     * @return solid fill color of null if not set
+     * @return solid fill color of null if not set or fill color
+     * is not solid (pattern or gradient)
      */
     public Color getFillColor() {
-        Paint paint = getFill(null);
-        if(paint instanceof Color){
-            return (Color)paint;
+        RenderableShape rShape = new RenderableShape(this);
+        Paint paint = rShape.getFillPaint(null);
+        if (paint instanceof Color) {
+            return (Color) paint;
         }
         return null;
     }
 
     /**
-     * fetch shape fill as a java.awt.Paint
-     *
-     * @return either Color or GradientPaint or TexturePaint or null
+     * @return shadow of this shape or null if shadow is disabled
      */
-    Paint getFill(final Graphics2D graphics) {
-        final XSLFTheme theme = _sheet.getTheme();
-        final Color nofill = new Color(0xFF,0xFF,0xFF, 0);
-        PropertyFetcher<Paint> fetcher = new PropertyFetcher<Paint>(){
-            public boolean fetch(XSLFSimpleShape shape){
-                CTShapeProperties spPr = shape.getSpPr();
-                if (spPr.isSetNoFill()) {
-                    setValue(nofill); // use it as 'nofill' value
-                    return true;
-                }
-                Paint paint = getPaint(graphics, spPr);
-                if (paint != null) {
-                    setValue( paint );
-                    return true;
-                }
-                return false;
-            }
-        };
-        fetchShapeProperty(fetcher);
-
-        Paint paint = fetcher.getValue();
-        if(paint == null){
-            // fill color was not found, check if it is defined in the theme
-            CTShapeStyle style = getSpStyle();
-            if (style != null) {
-                paint = new XSLFColor(style.getFillRef(), theme).getColor();
-            }
-        }
-        return paint == nofill ? null : paint;
-    }
-
-    public XSLFShadow getShadow(){
-        PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>(){
-            public boolean fetch(XSLFSimpleShape shape){
+    public XSLFShadow getShadow() {
+        PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>() {
+            public boolean fetch(XSLFSimpleShape shape) {
                 CTShapeProperties spPr = shape.getSpPr();
                 if (spPr.isSetEffectLst()) {
                     CTOuterShadowEffect obj = spPr.getEffectLst().getOuterShdw();
@@ -546,233 +517,48 @@ public abstract class XSLFSimpleShape ex
         fetchShapeProperty(fetcher);
 
         CTOuterShadowEffect obj = fetcher.getValue();
-        if(obj == null){
+        if (obj == null) {
             // fill color was not found, check if it is defined in the theme
             CTShapeStyle style = getSpStyle();
             if (style != null) {
                 // 1-based index of a shadow style within the style matrix
                 int idx = (int) style.getEffectRef().getIdx();
-                
-                CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme();
-                CTEffectStyleItem ef = styleMatrix.getEffectStyleLst().getEffectStyleArray(idx - 1);
-                obj = ef.getEffectLst().getOuterShdw();
+                if(idx != 0) {
+                    CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme();
+                    CTEffectStyleItem ef = styleMatrix.getEffectStyleLst().getEffectStyleArray(idx - 1);
+                    obj = ef.getEffectLst().getOuterShdw();
+                }
             }
         }
         return obj == null ? null : new XSLFShadow(obj, this);
     }
 
+    @Override
     public void draw(Graphics2D graphics) {
-
+        RenderableShape rShape = new RenderableShape(this);
+        rShape.render(graphics);
     }
 
-    @SuppressWarnings("deprecation") //  getXYZArray() array accessors are deprecated
-    protected Paint getPaint(Graphics2D graphics, XmlObject spPr) {
-        XSLFTheme theme = getSheet().getTheme();
-        Rectangle2D anchor = getAnchor();
-
-        Paint paint = null;
-        for(XmlObject obj : spPr.selectPath("*")){
-            if(obj instanceof CTNoFillProperties){
-                paint = null;
-                break;
-            }
-            if(obj instanceof CTSolidColorFillProperties){
-                CTSolidColorFillProperties solidFill = (CTSolidColorFillProperties)obj;
-                XSLFColor c = new XSLFColor(solidFill, theme);
-                paint = c.getColor();
-            }
-            if(obj instanceof CTBlipFillProperties){
-                CTBlipFillProperties blipFill = (CTBlipFillProperties)obj;
-                CTBlip blip = blipFill.getBlip();
-                String blipId = blip.getEmbed();
-                PackagePart p = getSheet().getPackagePart();
-                PackageRelationship rel = p.getRelationship(blipId);
-                if (rel != null) {
-                    XSLFImageRendener renderer = null;
-                    if(graphics != null) renderer = (XSLFImageRendener)graphics.getRenderingHint(XSLFRenderingHint.IMAGE_RENDERER);
-                    if(renderer == null) renderer = new XSLFImageRendener();
-
-                    try {
-                        BufferedImage img = renderer.readImage(p.getRelatedPart(rel).getInputStream());
-                        if(blip.sizeOfAlphaModFixArray() > 0){
-                            float alpha = blip.getAlphaModFixArray(0).getAmt()/100000.f;
-                            AlphaComposite ac = AlphaComposite.getInstance(
-                                                   AlphaComposite.SRC_OVER, alpha);
-                            if(graphics != null) graphics.setComposite(ac);
-                        }
-
-                        paint = new TexturePaint(
-                                img, new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight()));
-                    }
-                    catch (Exception e) {
-                        return null;
-                    }
-                }
-            }
-            if(obj instanceof CTGradientFillProperties){
-                CTGradientFillProperties gradFill = (CTGradientFillProperties)obj;
-                double angle;
-                if(gradFill.isSetLin()) {
-                    angle = gradFill.getLin().getAng() / 60000;
-                } else {
-                    // XSLF only supports linear gradient fills. Other types are filled as liner with angle=90 degrees
-                    angle = 90;
-                }
-                CTGradientStop[] gs =  gradFill.getGsLst().getGsArray();
-
-                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);
-                    }
-                });
-
-                Color[] colors = new Color[gs.length];
-                float[] fractions = new float[gs.length];
-
-                AffineTransform at = AffineTransform.getRotateInstance(
-                        Math.toRadians(angle),
-                        anchor.getX() + anchor.getWidth()/2,
-                        anchor.getY() + anchor.getHeight()/2);
-
-                double diagonal = Math.sqrt(anchor.getHeight()*anchor.getHeight() + anchor.getWidth()*anchor.getWidth());
-                Point2D p1 = new Point2D.Double(anchor.getX() + anchor.getWidth()/2 - diagonal/2,
-                        anchor.getY() + anchor.getHeight()/2);
-                p1 = at.transform(p1, null);
-
-                Point2D p2 = new Point2D.Double(anchor.getX() + anchor.getWidth(), anchor.getY() + anchor.getHeight()/2);
-                p2 = at.transform(p2, null);
-
-                norm(p1, anchor);
-                norm(p2, anchor);
-
-                for(int i = 0; i < gs.length; i++){
-                    CTGradientStop stop = gs[i];
-                    colors[i] = new XSLFColor(stop, theme).getColor();
-                    fractions[i] = stop.getPos() / 100000.f;
-                }
-
-                paint = createGradientPaint(p1, p2, fractions, colors);
-            }
-        }
-        return paint;
-    }
-
-    /**
-     * Trick to return GradientPaint on JDK 1.5 and LinearGradientPaint on JDK 1.6+
-     */
-    private Paint createGradientPaint(Point2D p1, Point2D p2, float[] fractions, Color[] colors){
-        Paint paint;
-        try {
-            Class clz = Class.forName("java.awt.LinearGradientPaint");
-            Constructor c =
-                    clz.getConstructor(Point2D.class, Point2D.class, float[].class, Color[].class);
-            paint = (Paint)c.newInstance(p1, p2, fractions, colors);
-        } catch (ClassNotFoundException e){
-            paint = new GradientPaint(p1, colors[0], p2, colors[colors.length - 1]);
-        } catch (Exception e){
-            throw new RuntimeException(e);
-        }
-        return paint;
-    }
-
-    void norm(Point2D p, Rectangle2D anchor){
-        if(p.getX() < anchor.getX()){
-            p.setLocation(anchor.getX(), p.getY());
-        } else if(p.getX() > (anchor.getX() + anchor.getWidth())){
-            p.setLocation(anchor.getX() + anchor.getWidth(), p.getY());
-        }
-
-        if(p.getY() < anchor.getY()){
-            p.setLocation(p.getX(), anchor.getY());
-        } else if (p.getY() > (anchor.getY() + anchor.getHeight())){
-            p.setLocation(p.getX(), anchor.getY() + anchor.getHeight());
-        }
-    }
-
-    protected float[] getDashPattern(LineDash lineDash, float lineWidth) {
-        float[] dash = null;
-        switch (lineDash) {
-            case SYS_DOT:
-                dash = new float[]{lineWidth, lineWidth};
-                break;
-            case SYS_DASH:
-                dash = new float[]{2 * lineWidth, 2 * lineWidth};
-                break;
-            case DASH:
-                dash = new float[]{3 * lineWidth, 4 * lineWidth};
-                break;
-            case DASH_DOT:
-                dash = new float[]{4 * lineWidth, 3 * lineWidth, lineWidth,
-                        3 * lineWidth};
-                break;
-            case LG_DASH:
-                dash = new float[]{8 * lineWidth, 3 * lineWidth};
-                break;
-            case LG_DASH_DOT:
-                dash = new float[]{8 * lineWidth, 3 * lineWidth, lineWidth,
-                        3 * lineWidth};
-                break;
-            case LG_DASH_DOT_DOT:
-                dash = new float[]{8 * lineWidth, 3 * lineWidth, lineWidth,
-                        3 * lineWidth, lineWidth, 3 * lineWidth};
-                break;
-        }
-        return dash;
-    }
-
-    protected void applyStroke(Graphics2D graphics) {
-
-        float lineWidth = (float) getLineWidth();
-        LineDash lineDash = getLineDash();
-        float[] dash = null;
-        float dash_phase = 0;
-        if (lineDash != null) {
-            dash = getDashPattern(lineDash, lineWidth);
-        }
-
-        int cap = BasicStroke.CAP_BUTT;
-        LineCap lineCap = getLineCap();
-        if (lineCap != null) {
-            switch (lineCap) {
-                case ROUND:
-                    cap = BasicStroke.CAP_ROUND;
-                    break;
-                case SQUARE:
-                    cap = BasicStroke.CAP_SQUARE;
-                    break;
-                default:
-                    cap = BasicStroke.CAP_BUTT;
-                    break;
-            }
-        }
-
-        int meter = BasicStroke.JOIN_ROUND;
-
-        Stroke stroke = new BasicStroke(lineWidth, cap, meter, Math.max(1, lineWidth), dash,
-                dash_phase);
-        graphics.setStroke(stroke);
-    }
 
     /**
-     * Walk up the inheritance tree and fetch properties.
-     *
-     * slide <-- slideLayout <-- slideMaster
+     * Walk up the inheritance tree and fetch shape properties.
      *
+     * The following order of inheritance is assumed:
+     * <p>
+     * slide <-- slideLayout <-- slideMaster <-- default styles in the slideMaster
+     * </p>
      *
-     * @param visitor   the object that collects the desired property
+     * @param visitor the object that collects the desired property
      * @return true if the property was fetched
      */
-    boolean fetchShapeProperty(PropertyFetcher visitor){
+    boolean fetchShapeProperty(PropertyFetcher visitor) {
         boolean ok = visitor.fetch(this);
 
         XSLFSimpleShape masterShape;
-        if(!ok){
-
-            // first try to fetch from the slide layout
-            XSLFSlideLayout layout = getSheet().getSlideLayout();
-            if(layout != null) {
+        XSLFSheet layout = getSheet().getMasterSheet();
+        if (layout != null) {
+            if (!ok) {
+                // first try to fetch from the slide layout
                 CTPlaceholder ph = getCTPlaceholder();
                 if (ph != null) {
                     masterShape = layout.getPlaceholder(ph);
@@ -781,96 +567,77 @@ public abstract class XSLFSimpleShape ex
                     }
                 }
             }
-        }
 
-        // try slide master
-        if (!ok) {
-            int textType;
-            CTPlaceholder ph = getCTPlaceholder();
-            if(ph == null || !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;
-                }
-            }
-            XSLFSlideMaster master = getSheet().getSlideMaster();
-            if(master != null) {
-                masterShape = master.getPlaceholderByType(textType);
-                if (masterShape != null) {
-                    ok = visitor.fetch(masterShape);
+            // try slide master
+            if (!ok) {
+                int textType;
+                CTPlaceholder ph = getCTPlaceholder();
+                if (ph == null || !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 = layout.getMasterSheet();
+                if (master != null) {
+                    masterShape = master.getPlaceholderByType(textType);
+                    if (masterShape != null) {
+                        ok = visitor.fetch(masterShape);
+                    }
                 }
             }
         }
-
         return ok;
     }
 
-
-    @Override
-    protected java.awt.Shape getOutline(){
-        PresetGeometries dict = PresetGeometries.getInstance();
+    /**
+     *
+     * @return definition of the shape geometry
+     */
+    CustomGeometry getGeometry(){
         CTShapeProperties spPr = getSpPr();
-        String name;
-        if(spPr.isSetPrstGeom()) {
-            name = spPr.getPrstGeom().getPrst().toString();
+        CustomGeometry geom;
+        PresetGeometries dict = PresetGeometries.getInstance();
+        if(spPr.isSetPrstGeom()){
+            String name = spPr.getPrstGeom().getPrst().toString();
+            geom = dict.get(name);
+            if(geom == null) {
+                throw new IllegalStateException("Unknown shape geometry: " + name);
+            }
+        } else if (spPr.isSetCustGeom()){
+            geom = new CustomGeometry(spPr.getCustGeom());
         } else {
-            name = "rect";
+            geom = dict.get("rect");
         }
-        CustomGeometry geom = dict.get(name);
-        Rectangle2D anchor = getAnchor();
-        if(geom != null) {
-            // the guides in the shape definitions are all defined relative to each other,
-            // so we build the path starting from (0,0).
-            final Rectangle2D anchorEmu = new Rectangle2D.Double(
-                    0,
-                    0,
-                    Units.toEMU(anchor.getWidth()),
-                    Units.toEMU(anchor.getHeight())
-            );
-
-            GeneralPath path = new GeneralPath();
-            Context ctx = new Context(geom, new IAdjustableShape() {
-                public Rectangle2D getAnchor() {
-                    return anchorEmu;
-                }
-
-                public Guide getAdjustValue(String name) {
-                    CTPresetGeometry2D prst = getSpPr().getPrstGeom();
-                    if(prst.isSetAvLst()) {
-                        for(CTGeomGuide g : prst.getAvLst().getGdList()){
-                            if(g.getName().equals(name)) {
-                                return new Guide(g);
-                            }
-                        }
-                    }
-                    return null;
-                }
-            });
+        return geom;
+    }
 
-            for(Path p : geom){
-                path.append( p.getPath(ctx) , false);
-            }
 
-            // translate the result to the canvas coordinates in points
-            AffineTransform at = new AffineTransform();
-            at.scale(
-                    1.0/Units.EMU_PER_POINT, 1.0/Units.EMU_PER_POINT);
-            at.translate(Units.toEMU(anchor.getX()), Units.toEMU(anchor.getY()));
-            return at.createTransformedShape(path);
-        } else {
-            return anchor;
-        }
-     }
+    /**
+     * @return any shape-specific geometry that is not included in presetShapeDefinitions.xml
+     * (line decorations, etc)
+     */
+    List<Outline>  getCustomOutlines(){
+        return Collections.emptyList();
+    }
 
+    /**
+     * draw any content within this shape (image, text, etc.).
+     *
+     * @param graphics the graphics to draw into
+     */
+    public void drawContent(Graphics2D graphics){
+
+    }
 }

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=1198658&r1=1198657&r2=1198658&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 Mon Nov  7 09:12:16 2011
@@ -32,7 +32,7 @@ import org.openxmlformats.schemas.presen
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
 import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument;
 
-import java.awt.*;
+import java.awt.Graphics2D;
 import java.io.IOException;
 
 @Beta
@@ -109,11 +109,11 @@ public final class XSLFSlide extends XSL
         return "sld";        
     }
 
-    public XSLFSlideMaster getMasterSheet(){
-        return getSlideLayout().getSlideMaster();
+    @Override
+    public XSLFSlideLayout getMasterSheet(){
+        return getSlideLayout();
     }
 
-    @Override
     public XSLFSlideLayout getSlideLayout(){
         if(_layout == null){
              for (POIXMLDocumentPart p : getRelations()) {
@@ -128,7 +128,6 @@ public final class XSLFSlide extends XSL
         return _layout;
     }
 
-    @Override
     public XSLFSlideMaster getSlideMaster(){
         return getSlideLayout().getSlideMaster();
     }
@@ -159,20 +158,12 @@ public final class XSLFSlide extends XSL
        }
        if(_notes == null) {
           // This slide lacks notes
-          // Not al have them, sorry...
+          // Not all have them, sorry...
           return null;
        }
        return _notes;
     }
 
-    public void setFollowMasterBackground(boolean value){
-        _slide.setShowMasterSp(value);    
-    }
-
-    public boolean getFollowMasterBackground(){
-        return !_slide.isSetShowMasterSp() || _slide.getShowMasterSp();    
-    }
-
     /**
      *
      * @return title of this slide or empty string if title is not set
@@ -182,27 +173,59 @@ public final class XSLFSlide extends XSL
         return txt == null ? "" : txt.getText();
     }
     
+    @Override
     public XSLFTheme getTheme(){
     	return getSlideLayout().getSlideMaster().getTheme();
     }
 
-    @Override
-    public void draw(Graphics2D graphics){
-
-        if (getFollowMasterBackground()){
-            XSLFSlideLayout layout = getSlideLayout();
-            layout.draw(graphics);
-        }
+    /**
+     *
+     * @return the information about background appearance of this slide
+     */
+    public XSLFBackground getBackground() {
 
-        super.draw(graphics);
-    }
 
-    @Override
-    public XSLFBackground getBackground(){
         if(_slide.getCSld().isSetBg()) {
             return new XSLFBackground(_slide.getCSld().getBg(), this);
         }
+
+        XSLFSlideLayout layout = getMasterSheet();
+        if(layout.getXmlObject().getCSld().isSetBg()) {
+            return new XSLFBackground(layout.getXmlObject().getCSld().getBg(), this);
+        }
+
+        XSLFSlideMaster master = layout.getMasterSheet();
+        if(master.getXmlObject().getCSld().isSetBg()) {
+            return new XSLFBackground(master.getXmlObject().getCSld().getBg(), this);
+        }
         return null;
     }
 
+    /**
+     *
+     * @return whether shapes on the master slide should be shown  or not.
+     */
+    public boolean getFollowMasterGraphics(){
+        return !_slide.isSetShowMasterSp() || _slide.getShowMasterSp();
+    }
+
+    /**
+     *
+     * @param value whether shapes on the master slide should be shown or not.
+     */
+    public void setFollowMasterGraphics(boolean value){
+        _slide.setShowMasterSp(value);
+    }
+
+
+    @Override
+    public void draw(Graphics2D graphics){
+
+        XSLFBackground bg = getBackground();
+        if(bg != null) bg.draw(graphics);
+
+        super.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=1198658&r1=1198657&r2=1198658&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 Mon Nov  7 09:12:16 2011
@@ -22,7 +22,6 @@ import org.apache.poi.openxml4j.opc.Pack
 import org.apache.poi.util.Beta;
 import org.apache.poi.util.Internal;
 import org.apache.xmlbeans.XmlException;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideLayout;
 import org.openxmlformats.schemas.presentationml.x2006.main.SldLayoutDocument;
@@ -42,13 +41,13 @@ public class XSLFSlideLayout extends XSL
     public XSLFSlideLayout(PackagePart part, PackageRelationship rel) throws IOException, XmlException {
         super(part, rel);
         SldLayoutDocument doc =
-            SldLayoutDocument.Factory.parse(getPackagePart().getInputStream());
+                SldLayoutDocument.Factory.parse(getPackagePart().getInputStream());
         _layout = doc.getSldLayout();
         setCommonSlideData(_layout.getCSld());
     }
 
 
-    public String getName(){
+    public String getName() {
         return _layout.getCSld().getName();
     }
 
@@ -61,79 +60,92 @@ public class XSLFSlideLayout extends XSL
     }
 
     @Override
-    protected String getRootElementName(){
+    protected String getRootElementName() {
         return "sldLayout";
     }
 
     /**
      * Slide master object associated with this layout.
-     * <p>
-     *  Within a slide master slide are contained all elements
-     * that describe the objects and their corresponding formatting
-     * for within a presentation slide.
-     * </p>
-     * <p>
-     * Within a slide master slide are two main elements.
-     * The cSld element specifies the common slide elements such as shapes and
-     * their attached text bodies. Then the txStyles element specifies the
-     * formatting for the text within each of these shapes. The other properties
-     * within a slide master slide specify other properties for within a presentation slide
-     * such as color information, headers and footers, as well as timing and
-     * transition information for all corresponding presentation slides.
-     * </p>
      *
      * @return slide master. Never null.
      * @throws IllegalStateException if slide master was not found
      */
-    @Override
-    public XSLFSlideMaster getSlideMaster(){
-        if(_master == null){
+    public XSLFSlideMaster getSlideMaster() {
+        if (_master == null) {
             for (POIXMLDocumentPart p : getRelations()) {
-               if (p instanceof XSLFSlideMaster){
-                  _master = (XSLFSlideMaster)p;
-               }
-           }
+                if (p instanceof XSLFSlideMaster) {
+                    _master = (XSLFSlideMaster) p;
+                }
+            }
         }
-        if(_master == null) {
+        if (_master == null) {
             throw new IllegalStateException("SlideMaster was not found for " + this.toString());
         }
         return _master;
     }
 
-    
-    public XSLFTheme getTheme(){
-    	return getSlideMaster().getTheme();
-    }    
+    @Override
+    public XSLFSlideMaster getMasterSheet() {
+        return getSlideMaster();
+    }
+
+    @Override
+    public XSLFTheme getTheme() {
+        return getSlideMaster().getTheme();
+    }
 
 
     @Override
-    protected CTTextListStyle getTextProperties(Placeholder textType) {
-        XSLFTextShape lp = getTextShapeByType(textType);
-        CTTextListStyle props = lp.getTextBody(false).getLstStyle();
-        return props;
+    public boolean getFollowMasterGraphics() {
+        return !_layout.isSetShowMasterSp() || _layout.getShowMasterSp();
     }
 
     /**
      * Render this sheet into the supplied graphics object
-     *
      */
     @Override
-    protected boolean canDraw(XSLFShape shape){
-        if(shape instanceof XSLFSimpleShape){
-            XSLFSimpleShape txt = (XSLFSimpleShape)shape;
+    protected boolean canDraw(XSLFShape shape) {
+        if (shape instanceof XSLFSimpleShape) {
+            XSLFSimpleShape txt = (XSLFSimpleShape) shape;
             CTPlaceholder ph = txt.getCTPlaceholder();
-            if(ph != null) {
+            if (ph != null) {
                 return false;
             }
         }
         return true;
     }
 
-    @Override
-    public XSLFBackground getBackground(){
-        if(_layout.getCSld().isSetBg()) {
-            return new XSLFBackground(_layout.getCSld().getBg(), this);
+    /**
+     * Copy placeholders from this layout to the destination slide
+     *
+     * @param slide destination slide
+     */
+    public void copyLayout(XSLFSlide slide) {
+        for (XSLFShape sh : getShapes()) {
+            if (sh instanceof XSLFTextShape) {
+                XSLFTextShape tsh = (XSLFTextShape) sh;
+                Placeholder ph = tsh.getTextType();
+                if (ph == null) continue;
+
+                switch (ph) {
+                    // these are special and not copied by default
+                    case DATETIME:
+                    case SLIDE_NUMBER:
+                    case FOOTER:
+                        break;
+                    default:
+                        slide.getSpTree().addNewSp().set(tsh.getXmlObject().copy());
+                }
+            }
         }
-        return getSlideMaster().getBackground();
+    }
+
+    /**
+     *
+     * @return type of this layout
+     */
+    public SlideLayout getType(){
+        int ordinal = _layout.getType().intValue() - 1;
+        return SlideLayout.values()[ordinal];
     }
 }
\ No newline at end of file

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=1198658&r1=1198657&r2=1198658&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 Mon Nov  7 09:12:16 2011
@@ -21,7 +21,9 @@ import org.apache.poi.openxml4j.opc.Pack
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.util.Beta;
 import org.apache.xmlbeans.XmlException;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterTextStyles;
 import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument;
@@ -78,7 +80,12 @@ import java.util.Map;
         return "sldMaster";
     }
 
-    public XSLFSlideLayout getLayout(String name){
+    @Override
+    public XSLFSheet getMasterSheet() {
+        return null;
+    }
+
+    private Map<String, XSLFSlideLayout> getLayouts(){
         if(_layouts == null){
             _layouts = new HashMap<String, XSLFSlideLayout>();
             for (POIXMLDocumentPart p : getRelations()) {
@@ -88,14 +95,36 @@ import java.util.Map;
                 }
             }
         }
-        return _layouts.get(name);
+        return _layouts;
     }
 
+    /**
+     *
+     * @return all slide layouts referencing this master
+     */
+    public XSLFSlideLayout[] getSlideLayouts() {
+        return getLayouts().values().toArray(new XSLFSlideLayout[_layouts.size()]);
+    }
+
+    public XSLFSlideLayout getLayout(SlideLayout type){
+        for(XSLFSlideLayout layout : getLayouts().values()){
+            if(layout.getType() == type) {
+                return layout;
+            }
+        }
+        return null;
+    }
+
+    @Override
     public XSLFTheme getTheme(){
         if(_theme == null){
             for (POIXMLDocumentPart p : getRelations()) {
                 if (p instanceof XSLFTheme){
                     _theme = (XSLFTheme)p;
+                    CTColorMapping cmap = _slide.getClrMap();
+                    if(cmap != null){
+                        _theme.initColorMap(cmap);
+                    }
                     break;
                 }
             }
@@ -122,11 +151,20 @@ import java.util.Map;
         return props;
     }
 
+    /**
+     * Render this sheet into the supplied graphics object
+     *
+     */
     @Override
-    public XSLFBackground getBackground(){
-        if(_slide.getCSld().isSetBg()) {
-            return new XSLFBackground(_slide.getCSld().getBg(), this);
+    protected boolean canDraw(XSLFShape shape){
+        if(shape instanceof XSLFSimpleShape){
+            XSLFSimpleShape txt = (XSLFSimpleShape)shape;
+            CTPlaceholder ph = txt.getCTPlaceholder();
+            if(ph != null) {
+                return false;
+            }
         }
-        return null;
+        return true;
     }
+
 }
\ No newline at end of file

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java?rev=1198658&r1=1198657&r2=1198658&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java Mon Nov  7 09:12:16 2011
@@ -35,7 +35,7 @@ import org.openxmlformats.schemas.drawin
 import org.openxmlformats.schemas.drawingml.x2006.main.STPenAlignment;
 import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
 
-import java.awt.*;
+import java.awt.Color;
 
 /**
  * Represents a cell of a table in a .pptx presentation
@@ -77,7 +77,7 @@ public class XSLFTableCell extends XSLFT
     }
 
     @Override
-    public void setMarginLeft(double margin){
+    public void setLeftInset(double margin){
         CTTableCellProperties pr = getXmlObject().getTcPr();
         if(pr == null) pr = getXmlObject().addNewTcPr();
 
@@ -85,7 +85,7 @@ public class XSLFTableCell extends XSLFT
     }
     
     @Override
-    public void setMarginRight(double margin){
+    public void setRightInset(double margin){
         CTTableCellProperties pr = getXmlObject().getTcPr();
         if(pr == null) pr = getXmlObject().addNewTcPr();
 
@@ -93,7 +93,7 @@ public class XSLFTableCell extends XSLFT
     }
 
     @Override
-    public void setMarginTop(double margin){
+    public void setTopInset(double margin){
         CTTableCellProperties pr = getXmlObject().getTcPr();
         if(pr == null) pr = getXmlObject().addNewTcPr();
 
@@ -101,7 +101,7 @@ public class XSLFTableCell extends XSLFT
     }
 
     @Override
-    public void setMarginBottom(double margin){
+    public void setBottomInset(double margin){
         CTTableCellProperties pr = getXmlObject().getTcPr();
         if(pr == null) pr = getXmlObject().addNewTcPr();
 

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java?rev=1198658&r1=1198657&r2=1198658&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java Mon Nov  7 09:12:16 2011
@@ -63,23 +63,4 @@ public class XSLFTextBox extends XSLFAut
 
         return ct;
     }
-
-    /**
-     * 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
-     *
-     * @param placeholder
-     */
-    public void setPlaceholder(Placeholder placeholder){
-        CTShape sh =  (CTShape)getXmlObject();
-        CTApplicationNonVisualDrawingProps nv = sh.getNvSpPr().getNvPr();
-        if(placeholder == null) {
-            if(nv.isSetPh()) nv.unsetPh();
-        } else {
-            nv.addNewPh().setType(STPlaceholderType.Enum.forInt(placeholder.ordinal() + 1));
-        }
-    }
 }
\ No newline at end of file

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java?rev=1198658&r1=1198657&r2=1198658&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java Mon Nov  7 09:12:16 2011
@@ -30,7 +30,8 @@ import org.openxmlformats.schemas.drawin
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
 import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
 
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Graphics2D;
 import java.awt.font.LineBreakMeasurer;
 import java.awt.font.TextAttribute;
 import java.awt.font.TextLayout;
@@ -80,6 +81,23 @@ public class XSLFTextParagraph implement
         return out.toString();
     }
 
+    private String getVisibleText(){
+        StringBuilder out = new StringBuilder();
+        for (XSLFTextRun r : _runs) {
+            String txt = r.getText();
+            switch (r.getTextCap()){
+                case ALL:
+                    txt = txt.toUpperCase();
+                    break;
+                case SMALL:
+                    txt = txt.toLowerCase();
+                    break;
+            }
+            out.append(txt);
+        }
+        return out.toString();
+    }
+
     @Internal
     public CTTextParagraph getXmlObject(){
         return _p;
@@ -89,6 +107,7 @@ public class XSLFTextParagraph implement
         return _shape;
 
     }
+
     public List<XSLFTextRun> getTextRuns(){
         return _runs;
     }
@@ -186,7 +205,7 @@ public class XSLFTextParagraph implement
         ParagraphPropertyFetcher<Color> fetcher = new ParagraphPropertyFetcher<Color>(getLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetBuClr()){
-                    XSLFColor c = new XSLFColor(props.getBuClr(), theme);
+                    XSLFColor c = new XSLFColor(props.getBuClr(), theme, null);
                     setValue(c.getColor());
                     return true;
                 }
@@ -496,17 +515,18 @@ public class XSLFTextParagraph implement
         return "[" + getClass() + "]" + getText();
     }
 
-    public List<TextFragment> getTextLines(){
+    List<TextFragment> getTextLines(){
         return _lines;
     }
 
     public double draw(Graphics2D graphics, double x, double y){
-        double marginLeft = _shape.getMarginLeft();
-        double marginRight = _shape.getMarginRight();
+        double marginLeft = _shape.getLeftInset();
+        double marginRight = _shape.getRightInset();
         Rectangle2D anchor = _shape.getAnchor();
         double penY = y;
 
         double textOffset = getLeftMargin();
+        boolean firstLine = true;
         for(TextFragment line : _lines){
             double penX = x;
             switch (getTextAlign()) {
@@ -521,7 +541,7 @@ public class XSLFTextParagraph implement
                     break;
             }
 
-            if(_bullet != null){
+            if(_bullet != null && firstLine){
                 _bullet.draw(graphics, penX  + getIndent(),  penY);
             }
             line.draw(graphics, penX,  penY);
@@ -535,6 +555,8 @@ public class XSLFTextParagraph implement
                 // positive value means absolute spacing in points
                 penY += -spacing;
             }
+
+            firstLine = false;
         }
         return penY - y;
     }
@@ -551,8 +573,12 @@ public class XSLFTextParagraph implement
         void draw(Graphics2D graphics, double x, double y){
             double yBaseline = y + _layout.getAscent();
 
-            graphics.drawString(_str.getIterator(), (float)x, (float)yBaseline );
-
+            Integer textMode = (Integer)graphics.getRenderingHint(XSLFRenderingHint.TEXT_RENDERING_MODE);
+            if(textMode != null && textMode == XSLFRenderingHint.TEXT_MODE_GLYPHS){
+                _layout.draw(graphics, (float)x, (float)yBaseline);
+            } else {
+                graphics.drawString(_str.getIterator(), (float)x, (float)yBaseline );
+            }
         }
         
         public float getHeight(){
@@ -564,8 +590,8 @@ public class XSLFTextParagraph implement
 
     }
 
-    public AttributedString getAttributedString(){
-        String text = getText();
+    AttributedString getAttributedString(Graphics2D graphics){
+        String text = getVisibleText();
 
         AttributedString string = new AttributedString(text);
 
@@ -579,7 +605,10 @@ public class XSLFTextParagraph implement
             int endIndex = startIndex + length;
 
             string.addAttribute(TextAttribute.FOREGROUND, run.getFontColor(), startIndex, endIndex);
+
+            // user can pass an object to convert fonts via a rendering hint
             string.addAttribute(TextAttribute.FAMILY, run.getFontFamily(), startIndex, endIndex);
+
             string.addAttribute(TextAttribute.SIZE, (float)run.getFontSize(), startIndex, endIndex);
             if(run.isBold()) {
                 string.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIndex, endIndex);
@@ -601,6 +630,7 @@ public class XSLFTextParagraph implement
                 string.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, startIndex, endIndex);
             }
 
+
             startIndex = endIndex;
         }
 
@@ -610,7 +640,7 @@ public class XSLFTextParagraph implement
     void breakText(Graphics2D graphics){
         _lines = new ArrayList<TextFragment>();
 
-        AttributedString at = getAttributedString();
+        AttributedString at = getAttributedString(graphics);
         AttributedCharacterIterator it = at.getIterator();
         if(it.getBeginIndex() == it.getEndIndex()) {
             return;
@@ -628,7 +658,8 @@ public class XSLFTextParagraph implement
 
             int endIndex = measurer.getPosition();
 
-            if(getTextAlign() == TextAlign.JUSTIFY) {
+            TextAlign hAlign = getTextAlign();
+            if(hAlign == TextAlign.JUSTIFY || hAlign == TextAlign.JUSTIFY_LOW) {
                 layout = layout.getJustifiedLayout((float)wrappingWidth);
             }
             
@@ -673,7 +704,7 @@ public class XSLFTextParagraph implement
             width = _shape.getSheet().getSlideShow().getPageSize().getWidth();
         } else {
             width = _shape.getAnchor().getWidth() -
-                    _shape.getMarginLeft() - _shape.getMarginRight() - getLeftMargin();
+                    _shape.getLeftInset() - _shape.getRightInset() - getLeftMargin();
         }
         return width;
     }
@@ -700,7 +731,13 @@ public class XSLFTextParagraph implement
         }
 
         int level = getLevel();
-        XmlObject[] o = _shape.getSheet().getSlideMaster().getXmlObject().selectPath(
+
+        XSLFSheet masterSheet = _shape.getSheet();
+        while (masterSheet.getMasterSheet() != null){
+            masterSheet = masterSheet.getMasterSheet();
+        }
+
+        XmlObject[] o = masterSheet.getXmlObject().selectPath(
                 "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " +
                 "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " +
                 ".//p:txStyles/p:" + defaultStyleSelector +"/a:lvl" +(level+1)+ "pPr");

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java?rev=1198658&r1=1198657&r2=1198658&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java Mon Nov  7 09:12:16 2011
@@ -20,14 +20,17 @@ import org.apache.poi.util.Beta;
 import org.apache.poi.xslf.model.CharacterPropertyFetcher;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
 
-import java.awt.*;
+import java.awt.Color;
 
 /**
  * Represents a run of text within the containing text body. The run element is the
@@ -70,12 +73,14 @@ public class XSLFTextRun {
 
     public Color getFontColor(){
         final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
+        CTShapeStyle style = _p.getParentShape().getSpStyle();
+        final CTSchemeColor shapeStyle = style == null ? null : style.getFontRef().getSchemeClr();
 
         CharacterPropertyFetcher<Color> fetcher = new CharacterPropertyFetcher<Color>(_p.getLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 CTSolidColorFillProperties solidFill = props.getSolidFill();
-                if(solidFill != null){
-                    Color c = new XSLFColor(solidFill, theme).getColor();
+                if(solidFill != null) {
+                    Color c = new XSLFColor(solidFill, theme, shapeStyle).getColor();
                     setValue(c);
                     return true;
                 }
@@ -104,6 +109,10 @@ public class XSLFTextRun {
      * @return font size in points or -1 if font size is not set.
      */
     public double getFontSize(){
+        double scale = 1;
+        CTTextNormalAutofit afit = getParentParagraph().getParentShape().getTextBodyPr().getNormAutofit();
+        if(afit != null) scale = (double)afit.getFontScale() / 100000;
+
         CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 if(props.isSetSz()){
@@ -114,7 +123,27 @@ public class XSLFTextRun {
             }
         };
         fetchCharacterProperty(fetcher);
-        return fetcher.getValue() == null ? -1 : fetcher.getValue();
+        return fetcher.getValue() == null ? -1 : fetcher.getValue()*scale;
+    }
+
+    /**
+     *
+     * @return the spacing between characters within a text run,
+     * If this attribute is omitted than a value of 0 or no adjustment is assumed.
+     */
+    public double getCharacterSpacing(){
+
+        CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getLevel()){
+            public boolean fetch(CTTextCharacterProperties props){
+                if(props.isSetSpc()){
+                    setValue(props.getSpc()*0.01);
+                    return true;
+                }
+                return false;
+            }
+        };
+        fetchCharacterProperty(fetcher);
+        return fetcher.getValue() == null ? 0 : fetcher.getValue();
     }
 
     /**
@@ -235,6 +264,24 @@ public class XSLFTextRun {
     }
 
     /**
+     * @return whether a run of text will be formatted as a superscript text. Default is false.
+     */
+    public TextCap getTextCap() {
+        CharacterPropertyFetcher<TextCap> fetcher = new CharacterPropertyFetcher<TextCap>(_p.getLevel()){
+            public boolean fetch(CTTextCharacterProperties props){
+                if(props.isSetCap()){
+                    int idx = props.getCap().intValue() - 1;
+                    setValue(TextCap.values()[idx]);
+                    return true;
+                }
+                return false;
+            }
+        };
+        fetchCharacterProperty(fetcher);
+        return fetcher.getValue() == null ? TextCap.NONE : fetcher.getValue();
+    }
+
+    /**
      * Specifies whether this run of text will be formatted as bold text
      *
      * @param bold whether this run of text will be formatted as bold text



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


Mime
View raw message