Author: kiwiwings
Date: Sun Aug  9 22:44:13 2015
New Revision: 1694925

URL: http://svn.apache.org/r1694925
Log:
#56519 - XSLFSlide.draw is not working with text embeded in PPTX

Added:
    poi/trunk/src/ooxml/java/org/apache/poi/sl/
    poi/trunk/src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java
    poi/trunk/src/testcases/org/apache/poi/sl/TestCommonSL.java
    poi/trunk/test-data/slideshow/KEY02.pptx   (with props)
    poi/trunk/test-data/slideshow/alterman_security.pptx
      - copied, changed from r1692593, 
poi/trunk/test-data/slideshow/alterman_security2.pptx
Removed:
    poi/trunk/test-data/slideshow/alterman_security2.pptx
Modified:
    poi/site/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextShape.java
    poi/trunk/src/java/org/apache/poi/sl/usermodel/ColorStyle.java
    poi/trunk/src/java/org/apache/poi/sl/usermodel/PaintStyle.java
    poi/trunk/src/java/org/apache/poi/sl/usermodel/Slide.java
    poi/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java
    poi/trunk/src/java/org/apache/poi/sl/usermodel/TextParagraph.java
    poi/trunk/src/java/org/apache/poi/sl/usermodel/TextRun.java
    
poi/trunk/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java
    poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java
    poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java
    poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java
    poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
    poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
    poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
    
poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
    poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
    poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java
    
poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
    
poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java
    
poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java
    
poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java
    
poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextRun.java
    
poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
    
poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Line.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java
    
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
    
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
    
poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java

Modified: poi/site/src/documentation/content/xdocs/status.xml
URL: 
http://svn.apache.org/viewvc/poi/site/src/documentation/content/xdocs/status.xml?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/site/src/documentation/content/xdocs/status.xml (original)
+++ poi/site/src/documentation/content/xdocs/status.xml Sun Aug  9 22:44:13 2015
@@ -39,6 +39,7 @@
     </devs>
 
     <release version="3.13-beta2" date="2015-10-??">
+        <action dev="PD" type="fix" fixes-bug="56519">XSLFSlide.draw is not 
working with text embeded in PPTX</action>
         <action dev="PD" type="fix" fixes-bug="58205">getSlideMasters() 
returns the master slides in the incorrect order</action>
         <action dev="PD" type="fix" fixes-bug="57786">XSLFFreeformShape 
ignores quadratic bezier curves</action>
         <action dev="PD" type="fix" fixes-bug="58206">provide a mechanism to 
find slide layouts by name</action>

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java Sun Aug  9 
22:44:13 2015
@@ -17,25 +17,31 @@
 
 package org.apache.poi.sl.draw;
 
-import static org.apache.poi.sl.usermodel.PaintStyle.TRANSPARENT_PAINT;
-
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.LinearGradientPaint;
 import java.awt.MultipleGradientPaint.ColorSpaceType;
 import java.awt.MultipleGradientPaint.CycleMethod;
-import java.awt.geom.*;
+import java.awt.Paint;
+import java.awt.RadialGradientPaint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.io.InputStream;
 
-import org.apache.poi.sl.usermodel.*;
+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.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 
 
 /**
- * This class handles color transformations
+ * This class handles color transformations.
  * 
  * @see <a href="https://tips4java.wordpress.com/2009/07/05/hsl-color/";>HSL 
code taken from Java Tips Weblog</a>
  */
@@ -50,19 +56,45 @@ public class DrawPaint {
         this.shape = shape;
     }
 
-    public static SolidPaint createSolidPaint(final Color color) {
-        return new SolidPaint() {
-            public ColorStyle getSolidColor() {
-                return new ColorStyle(){
+    private static class SimpleSolidPaint implements SolidPaint {
+        private final ColorStyle solidColor;
+
+        SimpleSolidPaint(final Color color) {
+            if (color == null) {
+                throw new NullPointerException("Color needs to be specified");
+            }
+            this.solidColor = new ColorStyle(){
                     public Color getColor() { return color; }
                     public int getAlpha() { return -1; }
+                    public int getHueOff() { return -1; }
+                    public int getHueMod() { return -1; }
+                    public int getSatOff() { return -1; }
+                    public int getSatMod() { return -1; }
                     public int getLumOff() { return -1; }
                     public int getLumMod() { return -1; }
                     public int getShade() { return -1; }
                     public int getTint() { return -1; }
                 };
+        }
+
+        SimpleSolidPaint(ColorStyle color) {
+            if (color == null) {
+                throw new NullPointerException("Color needs to be specified");
             }
-        };
+            this.solidColor = color;
+        }
+        
+        public ColorStyle getSolidColor() {
+            return solidColor;
+        }
+    }
+    
+    public static SolidPaint createSolidPaint(final Color color) {
+        return (color == null) ? null : new SimpleSolidPaint(color);
+    }
+    
+    public static SolidPaint createSolidPaint(final ColorStyle color) {
+        return (color == null) ? null : new SimpleSolidPaint(color);
     }
     
     public Paint getPaint(Graphics2D graphics, PaintStyle paint) {
@@ -95,26 +127,26 @@ public class DrawPaint {
 
     protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) {
         InputStream is = fill.getImageData();
-        if (is == null) return TRANSPARENT_PAINT.getSolidColor().getColor();
+        if (is == null) return null;
         assert(graphics != null);
         
         ImageRenderer renderer = 
(ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
         if (renderer == null) renderer = new ImageRenderer();
 
         try {
-            renderer.loadImage(fill.getImageData(), fill.getContentType());
+            renderer.loadImage(is, fill.getContentType());
+            is.close();
         } catch (IOException e) {
             LOG.log(POILogger.ERROR, "Can't load image data - using 
transparent color", e);
-            return TRANSPARENT_PAINT.getSolidColor().getColor();
+            return null;
         }
 
         int alpha = fill.getAlpha();
-        if (alpha != -1) {
+        if (0 <= alpha && alpha < 100000) {
             renderer.setAlpha(alpha/100000.f);
         }
         
-        Dimension dim = renderer.getDimension();
-        Rectangle2D textAnchor = new Rectangle2D.Double(0, 0, dim.getWidth(), 
dim.getHeight());
+        Rectangle2D textAnchor = shape.getAnchor();
         Paint paint = new java.awt.TexturePaint(renderer.getImage(), 
textAnchor);
 
         return paint;
@@ -122,106 +154,102 @@ public class DrawPaint {
     
     /**
      * Convert color transformations in {@link ColorStyle} to a {@link Color} 
instance
+     * 
+     * @see <a 
href="https://msdn.microsoft.com/en-us/library/dd560821%28v=office.12%29.aspx";>Using
 Office Open XML to Customize Document Formatting in the 2007 Office System</a>
+     * @see <a 
href="https://social.msdn.microsoft.com/Forums/office/en-US/040e0a1f-dbfe-4ce5-826b-38b4b6f6d3f7/saturation-modulation-satmod";>saturation
 modulation (satMod)</a>
+     * @see <a 
href="http://stackoverflow.com/questions/6754127/office-open-xml-satmod-results-in-more-than-100-saturation";>Office
 Open XML satMod results in more than 100% saturation</a>
      */
     public static Color applyColorTransform(ColorStyle color){
+        // TODO: The colors don't match 100% the results of Powerpoint, maybe 
because we still
+        // operate in sRGB and not scRGB ... work in progress ...
+
         Color result = color.getColor();
+        if (result == null) return null;
 
-        if (result == null || color.getAlpha() == 100) {
-            return TRANSPARENT_PAINT.getSolidColor().getColor();
-        }
-        
-        result = applyAlpha(result, color);
-        result = applyLuminance(result, color);
-        result = applyShade(result, color);
-        result = applyTint(result, color);
+        double alpha = getAlpha(result, color);
+        double hsl[] = RGB2HSL(result); // values are in the range [0..100] 
(usually ...)
+        applyHslModOff(hsl, 0, color.getHueMod(), color.getHueOff());
+        applyHslModOff(hsl, 1, color.getSatMod(), color.getSatOff());
+        applyHslModOff(hsl, 2, color.getLumMod(), color.getLumOff());
+        applyShade(hsl, color);
+        applyTint(hsl, color);
 
+        result = HSL2RGB(hsl[0], hsl[1], hsl[2], alpha);
+        
         return result;
     }
 
-    protected static Color applyAlpha(Color c, ColorStyle fc) {
-        int alpha = c.getAlpha();
-        return (alpha == 255) ? c : new Color(c.getRed(), c.getGreen(), 
c.getBlue(), alpha); 
+    private static double getAlpha(Color c, ColorStyle fc) {
+        double alpha = c.getAlpha()/255d;
+        int fcAlpha = fc.getAlpha();
+        if (fcAlpha != -1) {
+            alpha *= fcAlpha/100000d;
+        }
+        return Math.min(1, Math.max(0, alpha));
     }
     
     /**
-     * Apply lumMod / lumOff adjustments
-     *
-     * @param c the color to modify
-     * @param fc the color style containing the lumMod / lumOff adjustments
-     * @return  modified color
+     * Apply the modulation and offset adjustments to the given HSL part
+     * 
+     * Example for lumMod/lumOff:
+     * The lumMod value is the percent luminance. A lumMod value of "60000",
+     * is 60% of the luminance of the original color.
+     * When the color is a shade of the original theme color, the lumMod
+     * attribute is the only one of the tags shown here that appears.
+     * The <a:lumOff> tag appears after the <a:lumMod> tag when the color is a
+     * tint of the original. The lumOff value always equals 1-lumMod, which is 
used in the tint calculation
+     * 
+     * Despite having different ways to display the tint and shade percentages,
+     * all of the programs use the same method to calculate the resulting 
color.
+     * Convert the original RGB value to HSL ... and then adjust the luminance 
(L)
+     * with one of the following equations before converting the HSL value 
back to RGB.
+     * (The % tint in the following equations refers to the tint, themetint, 
themeshade,
+     * or lumMod values, as applicable.)
+     * 
+     * @param hsl the hsl values
+     * @param hslPart the hsl part to modify [0..2]
+     * @param mod the modulation adjustment
+     * @param off the offset adjustment
+     * @return the modified hsl value
      * 
-     * @see <a 
href="https://msdn.microsoft.com/en-us/library/dd560821%28v=office.12%29.aspx";>Using
 Office Open XML to Customize Document Formatting in the 2007 Office System</a>
      */
-    protected static Color applyLuminance(Color c, ColorStyle fc) {
-        int lumMod = fc.getLumMod();
-        if (lumMod == -1) lumMod = 100000;
-
-        int lumOff = fc.getLumOff();
-        if (lumOff == -1) lumOff = 0;
-        
-        if (lumMod == 100000 && lumOff == 0) return c;
-
-        // The lumMod value is the percent luminance. A lumMod value of 
"60000",
-        // is 60% of the luminance of the original color.
-        // When the color is a shade of the original theme color, the lumMod
-        // attribute is the only one of the tags shown here that appears.
-        // The <a:lumOff> tag appears after the <a:lumMod> tag when the color 
is a
-        // tint of the original. The lumOff value always equals 1-lumMod, 
which is used in the tint calculation
-        //
-        // Despite having different ways to display the tint and shade 
percentages,
-        // all of the programs use the same method to calculate the resulting 
color.
-        // Convert the original RGB value to HSL ... and then adjust the 
luminance (L)
-        // with one of the following equations before converting the HSL value 
back to RGB.
-        // (The % tint in the following equations refers to the tint, 
themetint, themeshade,
-        // or lumMod values, as applicable.)
-        //
-        // For a shade, the equation is luminance * %tint.
-        //
-        // For a tint, the equation is luminance * %tint + (1-%tint).
-        // (Note that 1-%tint is equal to the lumOff value in DrawingML.)
-        
-        double fLumOff = lumOff / 100000d;
-        double fLumMod = lumMod / 100000d;
-        
-        double hsl[] = RGB2HSL(c);
-        hsl[2] = hsl[2]*fLumMod+fLumOff;
-
-        Color c2 = HSL2RGB(hsl[0], hsl[1], hsl[2], c.getAlpha()/255d);
-        return c2;
+    private static void applyHslModOff(double hsl[], int hslPart, int mod, int 
off) {
+        if (mod == -1) mod = 100000;
+        if (off == -1) off = 0;
+        if (!(mod == 100000 && off == 0)) {
+            double fOff = off / 1000d;
+            double fMod = mod / 100000d;
+            hsl[hslPart] = hsl[hslPart]*fMod+fOff;
+        }
     }
     
     /**
-     * This algorithm returns result different from PowerPoint.
-     * TODO: revisit and improve
+     * Apply the shade
+     * 
+     * For a shade, the equation is luminance * %tint.
      */
-    protected static Color applyShade(Color c, ColorStyle fc) {
+    private static void applyShade(double hsl[], ColorStyle fc) {
         int shade = fc.getShade();
-        if (shade == -1) return c;
+        if (shade == -1) return;
         
-        float fshade = shade / 100000.f;
-
-        float red = c.getRed() * fshade;
-        float green = c.getGreen() * fshade;
-        float blue = c.getGreen() * fshade;
+        double fshade = shade / 100000.d;
         
-        return new Color(Math.round(red), Math.round(green), Math.round(blue), 
c.getAlpha());
+        hsl[2] *= fshade;
     }
 
     /**
-     * This algorithm returns result different from PowerPoint.
-     * TODO: revisit and improve
+     * Apply the tint
+     * 
+     * For a tint, the equation is luminance * %tint + (1-%tint).
+     * (Note that 1-%tint is equal to the lumOff value in DrawingML.)
      */
-    protected static Color applyTint(Color c, ColorStyle fc) {
+    private static void applyTint(double hsl[], ColorStyle fc) {
         int tint = fc.getTint();
-        if (tint == -1) return c;
+        if (tint == -1) return;
         
-        float ftint = tint / 100000.f;
-
-        float red = ftint * c.getRed() + (1.f - ftint) * 255.f;
-        float green = ftint * c.getGreen() + (1.f - ftint) * 255.f;
-        float blue = ftint * c.getBlue() + (1.f - ftint) * 255.f;
+        double ftint = tint / 100000.f;
 
-        return new Color(Math.round(red), Math.round(green), Math.round(blue), 
c.getAlpha());
+        hsl[2] = hsl[2] * ftint + (100 - ftint*100.);
     }
     
 

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java Sun Aug  9 
22:44:13 2015
@@ -47,9 +47,6 @@ public class DrawSimpleShape<T extends S
 
     @Override
     public void draw(Graphics2D graphics) {
-//        RenderableShape rShape = new RenderableShape(this);
-//        rShape.render(graphics);
-
         DrawPaint drawPaint = 
DrawFactory.getInstance(graphics).getPaint(shape);
         Paint fill = drawPaint.getPaint(graphics, 
shape.getFillStyle().getPaint());
         Paint line = drawPaint.getPaint(graphics, 
shape.getStrokeStyle().getPaint());

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java Sun Aug  9 
22:44:13 2015
@@ -17,18 +17,32 @@
 
 package org.apache.poi.sl.draw;
 
-import java.awt.Color;
 import java.awt.Graphics2D;
-import java.awt.font.*;
+import java.awt.Paint;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineBreakMeasurer;
+import java.awt.font.TextAttribute;
+import java.awt.font.TextLayout;
 import java.awt.geom.Rectangle2D;
-import java.text.*;
+import java.text.AttributedCharacterIterator;
 import java.text.AttributedCharacterIterator.Attribute;
-import java.util.*;
-
-import org.apache.poi.sl.usermodel.*;
+import java.text.AttributedString;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.sl.usermodel.AutoNumberingScheme;
+import org.apache.poi.sl.usermodel.Insets2D;
+import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.PlaceableShape;
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.TextParagraph;
 import org.apache.poi.sl.usermodel.TextParagraph.BulletStyle;
 import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
+import org.apache.poi.sl.usermodel.TextRun;
 import org.apache.poi.sl.usermodel.TextRun.TextCap;
+import org.apache.poi.sl.usermodel.TextShape;
 import org.apache.poi.util.Units;
 
 public class DrawTextParagraph<T extends TextRun> implements Drawable {
@@ -69,9 +83,6 @@ public class DrawTextParagraph<T extends
     public void draw(Graphics2D graphics){
         if (lines.isEmpty()) return;
         
-        Insets2D insets = paragraph.getParentShape().getInsets();
-        double leftInset = insets.left;
-        double rightInset = insets.right;
         double penY = y;
 
         boolean firstLine = true;
@@ -79,12 +90,17 @@ public class DrawTextParagraph<T extends
         Double leftMargin = paragraph.getLeftMargin();
         if (leftMargin == null) {
             // if the marL attribute is omitted, then a value of 347663 is 
implied
-            leftMargin = Units.toPoints(347663*(indentLevel+1));
+            leftMargin = Units.toPoints(347663*indentLevel);
         }
         Double indent = paragraph.getIndent();
         if (indent == null) {
             indent = Units.toPoints(347663*indentLevel);
         }
+        if (paragraph.getClass().getName().contains("HSLF")) {
+            // special handling for HSLF
+            indent -= leftMargin;
+        }
+        
         Double rightMargin = paragraph.getRightMargin();
         if (rightMargin == null) {
             rightMargin = 0d;
@@ -104,25 +120,30 @@ public class DrawTextParagraph<T extends
                 }
                 
                 if (bullet != null){
-                    bullet.setPosition(x + indent, penY);
+                    bullet.setPosition(x+leftMargin+indent, penY);
                     bullet.draw(graphics);
                     // don't let text overlay the bullet and advance by the 
bullet width
                     double bulletWidth = bullet.getLayout().getAdvance() + 1;
-                    penX = x + Math.max(leftMargin, indent+bulletWidth);
+                    penX = x + Math.max(leftMargin, 
leftMargin+indent+bulletWidth);
                 } else {
-                    penX = x + indent;
+                    penX = x + leftMargin;
                 }
             } else {
                 penX = x + leftMargin;
             }
 
             Rectangle2D anchor = DrawShape.getAnchor(graphics, 
paragraph.getParentShape());
+            // Insets are already applied on DrawTextShape.drawContent
+            // but (outer) anchor need to be adjusted
+            Insets2D insets = paragraph.getParentShape().getInsets();
+            double leftInset = insets.left;
+            double rightInset = insets.right;
 
             TextAlign ta = paragraph.getTextAlign();
             if (ta == null) ta = TextAlign.LEFT;
             switch (ta) {
                 case CENTER:
-                    penX += (anchor.getWidth() - leftMargin - line.getWidth() 
- leftInset - rightInset) / 2;
+                    penX += (anchor.getWidth() - line.getWidth() - leftInset - 
rightInset - leftMargin) / 2;
                     break;
                 case RIGHT:
                     penX += (anchor.getWidth() - line.getWidth() - leftInset - 
rightInset);
@@ -245,8 +266,14 @@ public class DrawTextParagraph<T extends
         if (buFont == null) buFont = paragraph.getDefaultFontFamily();
         assert(buFont != null);
 
-        Color buColor = bulletStyle.getBulletFontColor();
-        if (buColor == null) buColor = 
(Color)firstLineAttr.getAttribute(TextAttribute.FOREGROUND);
+        PlaceableShape ps = getParagraphShape();
+        PaintStyle fgPaintStyle = bulletStyle.getBulletFontColor();
+        Paint fgPaint;
+        if (fgPaintStyle == null) {
+            fgPaint = 
(Paint)firstLineAttr.getAttribute(TextAttribute.FOREGROUND);
+        } else {
+            fgPaint = new DrawPaint(ps).getPaint(graphics, fgPaintStyle);
+        }
 
         float fontSize = (Float)firstLineAttr.getAttribute(TextAttribute.SIZE);
         Double buSz = bulletStyle.getBulletFontSize();
@@ -256,7 +283,7 @@ public class DrawTextParagraph<T extends
 
         
         AttributedString str = new AttributedString(buCharacter);
-        str.addAttribute(TextAttribute.FOREGROUND, buColor);
+        str.addAttribute(TextAttribute.FOREGROUND, fgPaint);
         str.addAttribute(TextAttribute.FAMILY, buFont);
         str.addAttribute(TextAttribute.SIZE, fontSize);
 
@@ -382,11 +409,31 @@ public class DrawTextParagraph<T extends
             this.endIndex = endIndex;
         }
     }
+    
+    /**
+     * Helper method for paint style relative to bounds, e.g. gradient paint
+     */
+    private PlaceableShape getParagraphShape() {
+        PlaceableShape ps = new PlaceableShape(){
+            public ShapeContainer<? extends Shape> getParent() { return null; }
+            public Rectangle2D getAnchor() { return 
paragraph.getParentShape().getAnchor(); }
+            public void setAnchor(Rectangle2D anchor) {}
+            public double getRotation() { return 0; }
+            public void setRotation(double theta) {}
+            public void setFlipHorizontal(boolean flip) {}
+            public void setFlipVertical(boolean flip) {}
+            public boolean getFlipHorizontal() { return false; }
+            public boolean getFlipVertical() { return false; }
+        };
+        return ps;
+    }
 
     protected AttributedString getAttributedString(Graphics2D graphics, 
StringBuilder text){
         List<AttributedStringData> attList = new 
ArrayList<AttributedStringData>();
         if (text == null) text = new StringBuilder();
 
+        PlaceableShape ps = getParagraphShape();
+        
         DrawFontManager fontHandler = 
(DrawFontManager)graphics.getRenderingHint(Drawable.FONT_HANDLER);
 
         for (TextRun run : paragraph){
@@ -398,9 +445,9 @@ public class DrawTextParagraph<T extends
             text.append(runText);
             int endIndex = text.length();
 
-            Color fgColor = run.getFontColor();
-            if (fgColor == null) fgColor = Color.BLACK;
-            attList.add(new AttributedStringData(TextAttribute.FOREGROUND, 
fgColor, beginIndex, endIndex));
+            PaintStyle fgPaintStyle = run.getFontColor();
+            Paint fgPaint = new DrawPaint(ps).getPaint(graphics, fgPaintStyle);
+            attList.add(new AttributedStringData(TextAttribute.FOREGROUND, 
fgPaint, beginIndex, endIndex));
 
             // user can pass an custom object to convert fonts
             String fontFamily = run.getFontFamily();

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextShape.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextShape.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextShape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawTextShape.java Sun Aug  9 
22:44:13 2015
@@ -102,7 +102,6 @@ public class DrawTextShape<T extends Tex
      */
     public double drawParagraphs(Graphics2D graphics, double x, double y) {
         DrawFactory fact = DrawFactory.getInstance(graphics);
-        Insets2D shapePadding = shape.getInsets();
 
         double y0 = y;
         Iterator<? extends TextParagraph<? extends TextRun>> paragraphs = 
shape.iterator();

Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/ColorStyle.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/ColorStyle.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/usermodel/ColorStyle.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/usermodel/ColorStyle.java Sun Aug  9 
22:44:13 2015
@@ -32,17 +32,55 @@ public interface ColorStyle {
     int getAlpha();
     
     /**
-     * the luminance shift as expressed by a percentage relative to the input 
color
+     * the hue shift as expressed by a percentage relative to the input color.
+     * Be aware that OOXML also returns values greater than 100%
+     * 
+     * @return  hue shift in percents in the range [0..100000] (usually ...)
+     * or -1 if the value is not set
+     */
+    int getHueOff();
+    
+    /**
+     * the hue as expressed by a percentage relative to the input color.
+     * Be aware that OOXML also returns values greater than 100%
+     * 
+     * @return  hue in percents in the range [0..100000] (usually ...)
+     * or -1 if the value is not set
+     */
+    int getHueMod();
+    
+    /**
+     * the saturation shift as expressed by a percentage relative to the input 
color.
+     * Be aware that OOXML also returns values greater than 100%
+     * 
+     * @return  saturation shift in percents in the range [0..100000] (usually 
...)
+     * or -1 if the value is not set
+     */
+    int getSatOff();
+    
+    /**
+     * the saturation as expressed by a percentage relative to the input color.
+     * Be aware that OOXML also returns values greater than 100%
+     * 
+     * @return  saturation in percents in the range [0..100000] (usually ...)
+     * or -1 if the value is not set
+     */
+    int getSatMod();
+    
+    /**
+     * the luminance shift as expressed by a percentage relative to the input 
color.
+     * Be aware that OOXML also returns values greater than 100%
      *
-     * @return  luminance shift in percents in the range [0..100000]
+     * @return  luminance shift in percents in the range [0..100000] (usually 
...)
      * or -1 if the value is not set
      */
     int getLumOff();
     
     /**
-     * the luminance as expressed by a percentage relative to the input color
+     * the luminance as expressed by a percentage relative to the input color.
+     * Be aware that OOXML also returns values greater than 100%.
      *
-     * @return  luminance in percents in the range [0..100000]
+     * @return  luminance in percents in the range [0..100000] (usually ...)
      * or -1 if the value is not set
      */
     int getLumMod();
@@ -50,8 +88,9 @@ public interface ColorStyle {
     /**
      * specifies a darker version of its input color.
      * A 10% shade is 10% of the input color combined with 90% black.
+     * Be aware that OOXML also returns values greater than 100%.
      * 
-     * @return the value of the shade specified as percents in the range 
[0..100000]
+     * @return the value of the shade specified as percents in the range 
[0..100000] (usually ...)
      * with 0% indicating minimal shade and 100% indicating maximum
      * or -1 if the value is not set
      */
@@ -60,8 +99,9 @@ public interface ColorStyle {
     /**
      * specifies a lighter version of its input color.
      * A 10% tint is 10% of the input color combined with 90% white.
+     * Be aware that OOXML also returns values greater than 100%
      *
-     * @return the value of the tint specified as percents in the range 
[0..100000]
+     * @return the value of the tint specified as percents in the range 
[0..100000] (usually ...)
      * with 0% indicating minimal tint and 100% indicating maximum
      * or -1 if the value is not set
      */

Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/PaintStyle.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/PaintStyle.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/usermodel/PaintStyle.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/usermodel/PaintStyle.java Sun Aug  9 
22:44:13 2015
@@ -17,14 +17,12 @@
 
 package org.apache.poi.sl.usermodel;
 
-import java.awt.Color;
 import java.io.InputStream;
 
-import org.apache.poi.sl.draw.DrawPaint;
-
 
 
 public interface PaintStyle {
+
     public interface SolidPaint extends PaintStyle {
         ColorStyle getSolidColor();
     }
@@ -58,6 +56,4 @@ public interface PaintStyle {
          */
         int getAlpha();
     }
-
-    SolidPaint TRANSPARENT_PAINT = DrawPaint.createSolidPaint(new Color(0xFF, 
0xFF, 0xFF, 0));
 }

Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/Slide.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/Slide.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/usermodel/Slide.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/usermodel/Slide.java Sun Aug  9 
22:44:13 2015
@@ -18,20 +18,26 @@
 package org.apache.poi.sl.usermodel;
 
 public interface Slide<T extends Shape, SS extends SlideShow, N extends 
Notes<T,SS>> extends Sheet<T, SS> {
-       N getNotes();
-       void setNotes(N notes);
+    N getNotes();
+    void setNotes(N notes);
 
-       boolean getFollowMasterBackground();
-       void setFollowMasterBackground(boolean follow);
+    boolean getFollowMasterBackground();
+    void setFollowMasterBackground(boolean follow);
 
-       boolean getFollowMasterColourScheme();
-       void setFollowMasterColourScheme(boolean follow);
+    boolean getFollowMasterColourScheme();
+    void setFollowMasterColourScheme(boolean follow);
+
+    boolean getFollowMasterObjects();
+    void setFollowMasterObjects(boolean follow);
+
+    /**
+     * @return the 1-based slide no.
+     */
+    int getSlideNumber();
+
+    /**
+     * @return title of this slide or null if title is not set
+     */
+    String getTitle();
 
-       boolean getFollowMasterObjects();
-       void setFollowMasterObjects(boolean follow);
-
-       /**
-        * @return the 1-based slide no.
-        */
-       int getSlideNumber();
 }

Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/usermodel/SlideShow.java Sun Aug  9 
22:44:13 2015
@@ -21,7 +21,6 @@ import java.awt.Dimension;
 import java.io.IOException;
 import java.util.List;
 
-import org.apache.poi.sl.usermodel.PictureData;
 import org.apache.poi.sl.usermodel.PictureData.PictureType;
 
 public interface SlideShow {

Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/TextParagraph.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/TextParagraph.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/usermodel/TextParagraph.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/usermodel/TextParagraph.java Sun Aug  
9 22:44:13 2015
@@ -20,6 +20,7 @@ package org.apache.poi.sl.usermodel;
 import java.awt.Color;
 
 
+
 public interface TextParagraph<T extends TextRun> extends Iterable<T> {
 
     /**
@@ -113,7 +114,20 @@ public interface TextParagraph<T extends
          * @return the bullet point font size
          */
         Double getBulletFontSize();
-        Color getBulletFontColor();
+
+        /**
+         * Convenience function to set a solid color
+         */
+        void setBulletFontColor(Color color);
+        
+        void setBulletFontColor(PaintStyle color);
+
+        /**
+         *
+         * @return the color of bullet characters within a given paragraph.
+         * A {@code null} value means to use the text font color.
+         */
+        PaintStyle getBulletFontColor();
         
         AutoNumberingScheme getAutoNumberingScheme();
         /**

Modified: poi/trunk/src/java/org/apache/poi/sl/usermodel/TextRun.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/TextRun.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/usermodel/TextRun.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/usermodel/TextRun.java Sun Aug  9 
22:44:13 2015
@@ -19,6 +19,8 @@ package org.apache.poi.sl.usermodel;
 
 import java.awt.Color;
 
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+
 /**
  * Some text.
  */
@@ -34,8 +36,33 @@ public interface TextRun {
 
        TextCap getTextCap();
        
-       Color getFontColor();
-       void setFontColor(Color color);
+       /**
+        * Returns the font color.
+        * This usually returns a {@link SolidPaint}, but but also other 
classes are possible
+        * 
+        * @return the font color/paint
+        * 
+     * @see org.apache.poi.sl.draw.DrawPaint#getPaint(java.awt.Graphics2D, 
PaintStyle)
+     * @see SolidPaint#getSolidColor()
+        * @see org.apache.poi.sl.draw.DrawPaint#applyColorTransform(ColorStyle)
+        */
+       PaintStyle getFontColor();
+
+    /**
+     * Sets the (solid) font color - convenience function
+     *
+     * @param color the color
+     */
+    void setFontColor(Color color);
+
+    /**
+        * Sets the font color
+        *
+        * @param color the color
+        * 
+        * @see org.apache.poi.sl.draw.DrawPaint#createSolidPaint(Color)
+        */
+       void setFontColor(PaintStyle color);
        
        
     /**

Added: poi/trunk/src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java?rev=1694925&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java Sun Aug  9 
22:44:13 2015
@@ -0,0 +1,298 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.sl;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.security.GeneralSecurityException;
+
+import org.apache.poi.EmptyFileException;
+import org.apache.poi.EncryptedDocumentException;
+import org.apache.poi.POIXMLDocument;
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackageAccess;
+import org.apache.poi.poifs.crypt.Decryptor;
+import org.apache.poi.poifs.crypt.EncryptionInfo;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.xslf.usermodel.XMLSlideShow;
+
+public class SlideShowFactory {
+    /**
+     * Creates a HSLFSlideShow from the given POIFSFileSystem
+     * <p>Note that in order to properly release resources the
+     *  SlideShow should be closed after use.
+     */
+    public static SlideShow create(POIFSFileSystem fs) throws IOException {
+        return new HSLFSlideShow(fs);
+    }
+
+    /**
+     * Creates a HSLFSlideShow from the given NPOIFSFileSystem
+     * <p>Note that in order to properly release resources the
+     *  SlideShow should be closed after use.
+     */
+    public static SlideShow create(NPOIFSFileSystem fs) throws IOException {
+        try {
+            return create(fs, null);
+        } catch (InvalidFormatException e) {
+            // Special case of OOXML-in-POIFS which is broken
+            throw new IOException(e);
+        }
+    }
+
+    /**
+     * Creates a SlideShow from the given NPOIFSFileSystem, which may
+     *  be password protected
+     *
+     *  @param fs The {@link NPOIFSFileSystem} to read the document from
+     *  @param password The password that should be used or null if no 
password is necessary.
+     *
+     *  @return The created SlideShow
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be 
parsed into a {@link SlideShow}
+     */
+    private static SlideShow create(NPOIFSFileSystem fs, String password) 
throws IOException, InvalidFormatException {
+        DirectoryNode root = fs.getRoot();
+
+        // Encrypted OOXML files go inside OLE2 containers, is this one?
+        if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {
+            EncryptionInfo info = new EncryptionInfo(fs);
+            Decryptor d = Decryptor.getInstance(info);
+
+            boolean passwordCorrect = false;
+            InputStream stream = null;
+            try {
+                if (password != null && d.verifyPassword(password)) {
+                    passwordCorrect = true;
+                }
+                if (!passwordCorrect && 
d.verifyPassword(Decryptor.DEFAULT_PASSWORD)) {
+                    passwordCorrect = true;
+                }
+                if (passwordCorrect) {
+                    stream = d.getDataStream(root);
+                }
+            } catch (GeneralSecurityException e) {
+                throw new IOException(e);
+            }
+
+            if (! passwordCorrect) {
+                if (password != null)
+                    throw new EncryptedDocumentException("Password incorrect");
+                else
+                    throw new EncryptedDocumentException("The supplied 
spreadsheet is protected, but no password was supplied");
+            }
+
+            OPCPackage pkg = OPCPackage.open(stream);
+            return create(pkg);
+        }
+
+        // If we get here, it isn't an encrypted PPTX file
+        // So, treat it as a regular HSLF PPT one
+        if (password != null) {
+            Biff8EncryptionKey.setCurrentUserPassword(password);
+        }
+        SlideShow wb = new HSLFSlideShow(root);
+        Biff8EncryptionKey.setCurrentUserPassword(null);
+        return wb;
+    }
+
+    /**
+     * Creates a XMLSlideShow from the given OOXML Package
+     *
+     * <p>Note that in order to properly release resources the
+     *  SlideShow should be closed after use.</p>
+     *
+     *  @param pkg The {@link OPCPackage} opened for reading data.
+     *
+     *  @return The created SlideShow
+     *
+     *  @throws IOException if an error occurs while reading the data
+     */
+    public static SlideShow create(OPCPackage pkg) throws IOException {
+        return new XMLSlideShow(pkg);
+    }
+
+    /**
+     * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+     *  the given InputStream.
+     *
+     * <p>Your input stream MUST either support mark/reset, or
+     *  be wrapped as a {@link PushbackInputStream}! Note that
+     *  using an {@link InputStream} has a higher memory footprint
+     *  than using a {@link File}.</p>
+     *
+     * <p>Note that in order to properly release resources the
+     *  SlideShow should be closed after use. Note also that loading
+     *  from an InputStream requires more memory than loading
+     *  from a File, so prefer {@link #create(File)} where possible.
+     *
+     *  @param inp The {@link InputStream} to read data from.
+     *
+     *  @return The created SlideShow
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be 
parsed into a {@link SlideShow}
+     *  @throws EncryptedDocumentException If the SlideShow given is password 
protected
+     */
+    public static SlideShow create(InputStream inp) throws IOException, 
InvalidFormatException, EncryptedDocumentException {
+        return create(inp, null);
+    }
+
+    /**
+     * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+     *  the given InputStream, which may be password protected.
+     * <p>Your input stream MUST either support mark/reset, or
+     *  be wrapped as a {@link PushbackInputStream}! Note that
+     *  using an {@link InputStream} has a higher memory footprint
+     *  than using a {@link File}.</p>
+     *
+     * <p>Note that in order to properly release resources the
+     *  SlideShow should be closed after use. Note also that loading
+     *  from an InputStream requires more memory than loading
+     *  from a File, so prefer {@link #create(File)} where possible.</p>
+     *
+     *  @param inp The {@link InputStream} to read data from.
+     *  @param password The password that should be used or null if no 
password is necessary.
+     *
+     *  @return The created SlideShow
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be 
parsed into a {@link SlideShow}
+     *  @throws EncryptedDocumentException If the wrong password is given for 
a protected file
+     *  @throws EmptyFileException If an empty stream is given
+     */
+    public static SlideShow create(InputStream inp, String password) throws 
IOException, InvalidFormatException, EncryptedDocumentException {
+        // If clearly doesn't do mark/reset, wrap up
+        if (! inp.markSupported()) {
+            inp = new PushbackInputStream(inp, 8);
+        }
+
+        // Ensure that there is at least some data there
+        byte[] header8 = IOUtils.peekFirst8Bytes(inp);
+
+        // Try to create
+        if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {
+            NPOIFSFileSystem fs = new NPOIFSFileSystem(inp);
+            return create(fs, password);
+        }
+        if (POIXMLDocument.hasOOXMLHeader(inp)) {
+            return new XMLSlideShow(OPCPackage.open(inp));
+        }
+        throw new IllegalArgumentException("Your InputStream was neither an 
OLE2 stream, nor an OOXML stream");
+    }
+
+    /**
+     * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+     *  the given File, which must exist and be readable.
+     * <p>Note that in order to properly release resources the
+     *  SlideShow should be closed after use.
+     *
+     *  @param file The file to read data from.
+     *
+     *  @return The created SlideShow
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be 
parsed into a {@link SlideShow}
+     *  @throws EncryptedDocumentException If the SlideShow given is password 
protected
+     */
+    public static SlideShow create(File file) throws IOException, 
InvalidFormatException, EncryptedDocumentException {
+        return create(file, null);
+    }
+
+    /**
+     * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+     *  the given File, which must exist and be readable, and
+     *  may be password protected
+     * <p>Note that in order to properly release resources the
+     *  SlideShow should be closed after use.
+     *
+     *  @param file The file to read data from.
+     *  @param password The password that should be used or null if no 
password is necessary.
+     *
+     *  @return The created SlideShow
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be 
parsed into a {@link SlideShow}
+     *  @throws EncryptedDocumentException If the wrong password is given for 
a protected file
+     *  @throws EmptyFileException If an empty stream is given
+     */
+    public static SlideShow create(File file, String password) throws 
IOException, InvalidFormatException, EncryptedDocumentException {
+        return create(file, password, false);
+    }
+
+    /**
+     * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+     *  the given File, which must exist and be readable, and
+     *  may be password protected
+     * <p>Note that in order to properly release resources the
+     *  SlideShow should be closed after use.
+     *
+     *  @param file The file to read data from.
+     *  @param password The password that should be used or null if no 
password is necessary.
+     *  @param readOnly If the SlideShow should be opened in read-only mode to 
avoid writing back
+     *      changes when the document is closed.
+     *
+     *  @return The created SlideShow
+     *
+     *  @throws IOException if an error occurs while reading the data
+     *  @throws InvalidFormatException if the contents of the file cannot be 
parsed into a {@link SlideShow}
+     *  @throws EncryptedDocumentException If the wrong password is given for 
a protected file
+     *  @throws EmptyFileException If an empty stream is given
+     */
+    public static SlideShow create(File file, String password, boolean 
readOnly) throws IOException, InvalidFormatException, 
EncryptedDocumentException {
+        if (! file.exists()) {
+            throw new FileNotFoundException(file.toString());
+        }
+
+        try {
+            NPOIFSFileSystem fs = new NPOIFSFileSystem(file, readOnly);
+            return create(fs, password);
+        } catch(OfficeXmlFileException e) {
+            // opening as .ppt failed => try opening as .pptx
+            OPCPackage pkg = OPCPackage.open(file, readOnly ? 
PackageAccess.READ : PackageAccess.READ_WRITE);
+            try {
+                return new XMLSlideShow(pkg);
+//            } catch (IOException ioe) {
+//                // ensure that file handles are closed (use revert() to not 
re-write the file)
+//                pkg.revert();
+//                //pkg.close();
+//
+//                // rethrow exception
+//                throw ioe;
+            } catch (IllegalArgumentException ioe) {
+                // ensure that file handles are closed (use revert() to not 
re-write the file)
+                pkg.revert();
+                //pkg.close();
+
+                // rethrow exception
+                throw ioe;
+            }
+        }
+    }
+}

Modified: 
poi/trunk/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- 
poi/trunk/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java
 (original)
+++ 
poi/trunk/src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java
 Sun Aug  9 22:44:13 2015
@@ -27,8 +27,6 @@ import org.openxmlformats.schemas.drawin
  * @author Yegor Kozlov
  */
 public abstract class CharacterPropertyFetcher<T> extends 
ParagraphPropertyFetcher<T> {
-    public boolean isFetchingFromMaster = false;
-
     public CharacterPropertyFetcher(int level) {
         super(level);
     }

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java 
(original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java Sun 
Aug  9 22:44:13 2015
@@ -78,6 +78,22 @@ public class XSLFColor {
                 return getRawValue("alpha");
             }
 
+            public int getHueOff() {
+                return getRawValue("hueOff");
+            }
+
+            public int getHueMod() {
+                return getRawValue("hueMod");
+            }
+
+            public int getSatOff() {
+                return getRawValue("satOff");
+            }
+
+            public int getSatMod() {
+                return getRawValue("satMod");
+            }
+
             public int getLumOff() {
                 return getRawValue("lumOff");
             }

Modified: 
poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java?rev=1694925&r1=1694924&r2=1694925&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java 
(original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java Sun 
Aug  9 22:44:13 2015
@@ -44,8 +44,12 @@ public class XSLFDrawing {
         XmlObject[] cNvPr = sheet.getSpTree().selectPath(
                 "declare namespace 
p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");
         for(XmlObject o : cNvPr) {
-            CTNonVisualDrawingProps p = (CTNonVisualDrawingProps)o;
-            _shapeId = (int)Math.max(_shapeId, p.getId());
+            // powerpoint generates AlternateContent elements which cNvPr 
elements aren't recognized
+            // ignore them for now
+            if (o instanceof CTNonVisualDrawingProps) {
+                CTNonVisualDrawingProps p = (CTNonVisualDrawingProps)o;
+                _shapeId = (int)Math.max(_shapeId, p.getId());
+            }
         }
     }
 

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=1694925&r1=1694924&r2=1694925&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 Sun 
Aug  9 22:44:13 2015
@@ -21,8 +21,6 @@ import java.awt.Color;
 import java.awt.geom.Rectangle2D;
 
 import org.apache.poi.sl.draw.DrawPaint;
-import org.apache.poi.sl.usermodel.ColorStyle;
-import org.apache.poi.sl.usermodel.PaintStyle;
 import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
 import org.apache.poi.sl.usermodel.Shadow;
 import org.apache.poi.util.Units;
@@ -90,7 +88,7 @@ public class XSLFShadow extends XSLFShap
      */
     public Color getFillColor() {
         SolidPaint ps = getFillStyle();
-        if (ps == PaintStyle.TRANSPARENT_PAINT) return null;
+        if (ps == null) return null;
         Color col = DrawPaint.applyColorTransform(ps.getSolidColor());
         return col;
     }
@@ -99,14 +97,10 @@ public class XSLFShadow extends XSLFShap
     public SolidPaint getFillStyle() {
         XSLFTheme theme = getSheet().getTheme();
         CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
-        if(ct == null) return PaintStyle.TRANSPARENT_PAINT;
+        if(ct == null) return null;
             
         CTSchemeColor phClr = ct.getSchemeClr();
         final XSLFColor xc = new XSLFColor(ct, theme, phClr);
-        return new SolidPaint(){
-            public ColorStyle getSolidColor() {
-                return xc.getColorStyle();
-            }
-        };
+        return DrawPaint.createSolidPaint(xc.getColorStyle());
     }
 }
\ 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=1694925&r1=1694924&r2=1694925&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 Sun 
Aug  9 22:44:13 2015
@@ -27,10 +27,10 @@ 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.draw.DrawPaint;
 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;
@@ -38,7 +38,20 @@ 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.drawingml.x2006.main.CTBlip;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
+import 
org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientStop;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNoFillProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
+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.CTStyleMatrixReference;
+import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType;
 import 
org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
 import 
org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
@@ -139,7 +152,7 @@ public abstract class XSLFShape implemen
                 try {
                     pr = shape.getSpPr();
                     if (((CTShapeProperties)pr).isSetNoFill()) {
-                        setValue(PaintStyle.TRANSPARENT_PAINT);
+                        setValue(null);
                         return true;
                     }                    
                 } catch (IllegalStateException e) {}
@@ -156,21 +169,19 @@ public abstract class XSLFShape implemen
                     }
                 }
                 
-                if (pr == null) {
-                    setValue(PaintStyle.TRANSPARENT_PAINT);
-                    return true;
-                }
+                if (pr == null) return false;
                 
                 PaintStyle paint = null;
+                PackagePart pp = getSheet().getPackagePart();
                 for (XmlObject obj : pr.selectPath("*")) {
-                    paint = selectPaint(obj, null, 
getSheet().getPackagePart());
-                    if (paint != null) break;
+                    paint = selectPaint(obj, null, pp);
+                    if (paint != null) {
+                        setValue(paint);
+                        return true;
+                    };
                 }
                 
-                if (paint == null) return false;
-                
-                setValue(paint);
-                return true;
+                return false;
             }
         };
         fetchShapeProperty(fetcher);
@@ -190,7 +201,7 @@ public abstract class XSLFShape implemen
         }
         paint = selectPaint(fillRef);
 
-        return paint == null ? PaintStyle.TRANSPARENT_PAINT : paint;
+        return paint;
     }
 
     protected CTBackgroundProperties getBgPr() {
@@ -347,8 +358,8 @@ public abstract class XSLFShape implemen
             paint = selectPaint(obj, phClr, pp);
             if(paint != null) break;
         }
-        return paint == null ? PaintStyle.TRANSPARENT_PAINT : paint;
-    }    
+        return paint;
+    }
     
     /**
      * Convert shape fill into java.awt.Paint. The result is either Color or
@@ -371,13 +382,13 @@ public abstract class XSLFShape implemen
      */
     protected PaintStyle selectPaint(XmlObject obj, final CTSchemeColor phClr, 
final PackagePart parentPart) {
         if (obj instanceof CTNoFillProperties) {
-            return PaintStyle.TRANSPARENT_PAINT;
+            return null;
         } else if (obj instanceof CTSolidColorFillProperties) {
-            return selectPaint((CTSolidColorFillProperties)obj, phClr, 
parentPart);
+            return selectPaint((CTSolidColorFillProperties)obj, phClr);
         } else if (obj instanceof CTBlipFillProperties) {
-            return selectPaint((CTBlipFillProperties)obj, phClr, parentPart);
+            return selectPaint((CTBlipFillProperties)obj, parentPart);
         } else if (obj instanceof CTGradientFillProperties) {
-            return selectPaint((CTGradientFillProperties) obj, phClr, 
parentPart);
+            return selectPaint((CTGradientFillProperties) obj, phClr);
         } else if (obj instanceof CTStyleMatrixReference) {
             return selectPaint((CTStyleMatrixReference)obj);
         } else {
@@ -385,17 +396,16 @@ public abstract class XSLFShape implemen
         }
     }
 
-    protected PaintStyle selectPaint(final CTSolidColorFillProperties 
solidFill, final CTSchemeColor phClr, final PackagePart parentPart) {
+    protected PaintStyle selectPaint(CTSolidColorFillProperties solidFill, 
CTSchemeColor phClr) {
         final XSLFTheme theme = getSheet().getTheme();
+        if (phClr == null && solidFill.isSetSchemeClr()) {
+            phClr = solidFill.getSchemeClr();
+        }
         final XSLFColor c = new XSLFColor(solidFill, theme, phClr);
-        return new SolidPaint() {
-            public ColorStyle getSolidColor() {
-                return c.getColorStyle();
-            }
-        };
+        return DrawPaint.createSolidPaint(c.getColorStyle());
     }
     
-    protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, 
final CTSchemeColor phClr, final PackagePart parentPart) {
+    protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, 
final PackagePart parentPart) {
         final CTBlip blip = blipFill.getBlip();
         return new TexturePaint() {
             private PackagePart getPart() {
@@ -424,12 +434,12 @@ public abstract class XSLFShape implemen
             public int getAlpha() {
                 return (blip.sizeOfAlphaModFixArray() > 0)
                     ? blip.getAlphaModFixArray(0).getAmt()
-                    : 0;
+                    : 100000;
             }
         };        
     }
     
-    protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, 
final CTSchemeColor phClr, final PackagePart parentPart) {
+    protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, 
CTSchemeColor phClr) {
 
         @SuppressWarnings("deprecation")
         final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();
@@ -448,7 +458,11 @@ public abstract class XSLFShape implemen
         
         int i=0;
         for (CTGradientStop cgs : gs) {
-            cs[i] = new XSLFColor(cgs, theme, phClr).getColorStyle();
+            CTSchemeColor phClrCgs = phClr;
+            if (phClrCgs == null && cgs.isSetSchemeClr()) {
+                phClrCgs = cgs.getSchemeClr();
+            }
+            cs[i] = new XSLFColor(cgs, theme, phClrCgs).getColorStyle();
             fractions[i] = cgs.getPos() / 100000.f;
             i++;
         }

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=1694925&r1=1694924&r2=1694925&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 
Sun Aug  9 22:44:13 2015
@@ -19,8 +19,6 @@
 
 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;
 
@@ -31,10 +29,15 @@ import org.apache.poi.openxml4j.opc.Pack
 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.FillStyle;
+import org.apache.poi.sl.usermodel.LineDecoration;
 import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;
 import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;
+import org.apache.poi.sl.usermodel.PaintStyle;
 import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.sl.usermodel.SimpleShape;
+import org.apache.poi.sl.usermodel.StrokeStyle;
 import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
 import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
 import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
@@ -219,7 +222,6 @@ public abstract class XSLFSimpleShape ex
      */
     public Color getLineColor() {
         PaintStyle ps = getLinePaint();
-        if (ps == null || ps == TRANSPARENT_PAINT) return null;
         if (ps instanceof SolidPaint) {
             return ((SolidPaint)ps).getSolidColor().getColor();
         }
@@ -232,7 +234,7 @@ public abstract class XSLFSimpleShape ex
                 CTLineProperties spPr = shape.getSpPr().getLn();
                 if (spPr != null) {
                     if (spPr.isSetNoFill()) {
-                        setValue(TRANSPARENT_PAINT); // use it as 'nofill' 
value
+                        setValue(null); // use it as 'nofill' value
                         return true;
                     }
                     
@@ -266,7 +268,7 @@ public abstract class XSLFSimpleShape ex
         
         // line color was not found, check if it is defined in the theme
         CTShapeStyle style = getSpStyle();
-        if (style == null) return TRANSPARENT_PAINT;
+        if (style == null) return null;
         
         // get a reference to a line style within the style matrix.
         CTStyleMatrixReference lnRef = style.getLnRef();
@@ -279,7 +281,7 @@ public abstract class XSLFSimpleShape ex
             paint = getPaint(lnProps, phClr);
         }
 
-        return paint == null ? TRANSPARENT_PAINT : paint;
+        return paint;
     }
     
     /**
@@ -524,7 +526,6 @@ public abstract class XSLFSimpleShape ex
      */
     public Color getFillColor() {
         PaintStyle ps = getFillPaint();
-        if (ps == null || ps == TRANSPARENT_PAINT) return null;
         if (ps instanceof SolidPaint) {
             return ((SolidPaint)ps).getSolidColor().getColor();
         }

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=1694925&r1=1694924&r2=1694925&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 Sun 
Aug  9 22:44:13 2015
@@ -168,13 +168,10 @@ public final class XSLFSlide extends XSL
        return _notes;
     }
 
-    /**
-     *
-     * @return title of this slide or empty string if title is not set
-     */
+    @Override
     public String getTitle(){
         XSLFTextShape txt = getTextShapeByType(Placeholder.TITLE);
-        return txt == null ? "" : txt.getText();
+        return txt == null ? null : txt.getText();
     }
     
     @Override

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=1694925&r1=1694924&r2=1694925&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 
Sun Aug  9 22:44:13 2015
@@ -21,7 +21,10 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.poi.sl.draw.DrawPaint;
 import org.apache.poi.sl.usermodel.AutoNumberingScheme;
+import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
 import org.apache.poi.sl.usermodel.TextParagraph;
 import org.apache.poi.util.Beta;
 import org.apache.poi.util.Internal;
@@ -264,7 +267,7 @@ public class XSLFTextParagraph implement
      * @return the color of bullet characters within a given paragraph.
      * A <code>null</code> value means to use the text font color.
      */
-    public Color getBulletFontColor(){
+    public PaintStyle getBulletFontColor(){
         final XSLFTheme theme = getParentShape().getSheet().getTheme();
         ParagraphPropertyFetcher<Color> fetcher = new 
ParagraphPropertyFetcher<Color>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
@@ -277,19 +280,33 @@ public class XSLFTextParagraph implement
             }
         };
         fetchParagraphProperty(fetcher);
-        return fetcher.getValue();
+        Color col = fetcher.getValue();
+        return (col == null) ? null : DrawPaint.createSolidPaint(col);
     }
 
+    public void setBulletFontColor(Color color) {
+        setBulletFontColor(DrawPaint.createSolidPaint(color));
+    }
+    
+    
     /**
      * Set the color to be used on bullet characters within a given paragraph.
      *
      * @param color the bullet color
      */
-    public void setBulletFontColor(Color color){
+    public void setBulletFontColor(PaintStyle color) {
+        if (!(color instanceof SolidPaint)) {
+            throw new IllegalArgumentException("Currently XSLF only supports 
SolidPaint");
+        }
+
+        // TODO: implement setting bullet color to null
+        SolidPaint sp = (SolidPaint)color;
+        Color col = DrawPaint.applyColorTransform(sp.getSolidColor());
+        
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : 
_p.addNewPPr();
         CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr();
         CTSRgbColor clr = c.isSetSrgbClr() ? c.getSrgbClr() : 
c.addNewSrgbClr();
-        clr.setVal(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), 
(byte) color.getBlue()});
+        clr.setVal(new byte[]{(byte) col.getRed(), (byte) col.getGreen(), 
(byte) col.getBlue()});
     }
 
     /**
@@ -729,7 +746,6 @@ public class XSLFTextParagraph implement
         XSLFSheet masterSheet = _shape.getSheet();
         for (XSLFSheet m = masterSheet; m != null; m = 
(XSLFSheet)m.getMasterSheet()) {
             masterSheet = m;
-
             XmlObject xo = masterSheet.getXmlObject();
             for (String xpath : xpaths) {
                 XmlObject[] o = xo.selectPath(xpath);
@@ -767,32 +783,35 @@ public class XSLFTextParagraph implement
 
     private <T> boolean fetchParagraphProperty(ParagraphPropertyFetcher<T> 
visitor){
         boolean ok = false;
-
+        XSLFTextShape shape = getParentShape();
+        XSLFSheet sheet = shape.getSheet();
+        
         if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr());
+        if (ok) return true;
 
-        if(!ok) {
-            XSLFTextShape shape = getParentShape();
-            ok = shape.fetchShapeProperty(visitor);
-            if(!ok){
-                CTPlaceholder ph = shape.getCTPlaceholder();
-                if(ph == null){
-                    // if it is a plain text box then take defaults from 
presentation.xml
-                    XMLSlideShow ppt = 
getParentShape().getSheet().getSlideShow();
-                    CTTextParagraphProperties themeProps = 
ppt.getDefaultParagraphStyle(getIndentLevel());
-                    if(themeProps != null) ok = visitor.fetch(themeProps);
-                }
-
-                if(!ok){
-                    // defaults for placeholders are defined in the slide 
master
-                    CTTextParagraphProperties defaultProps = 
getDefaultMasterStyle();
-                    if(defaultProps != null) ok = visitor.fetch(defaultProps);
-                }
-            }
+        ok = shape.fetchShapeProperty(visitor);
+        if (ok) return true;
+                
+        
+        CTPlaceholder ph = shape.getCTPlaceholder();
+        if(ph == null){
+            // if it is a plain text box then take defaults from 
presentation.xml
+            XMLSlideShow ppt = sheet.getSlideShow();
+            CTTextParagraphProperties themeProps = 
ppt.getDefaultParagraphStyle(getIndentLevel());
+            if (themeProps != null) ok = visitor.fetch(themeProps);
         }
+        if (ok) return true;
+
+        // defaults for placeholders are defined in the slide master
+        CTTextParagraphProperties defaultProps = getDefaultMasterStyle();
+        // TODO: determine master shape
+        if(defaultProps != null) ok = visitor.fetch(defaultProps);
+        if (ok) return true;
 
-        return ok;
+        return false;
     }
 
+    @SuppressWarnings("deprecation")
     void copy(XSLFTextParagraph other){
         if (other == this) return;
         
@@ -848,7 +867,7 @@ public class XSLFTextParagraph implement
                 if(buChar != null && !buChar.equals(getBulletCharacter())){
                     setBulletCharacter(buChar);
                 }
-                Color buColor = other.getBulletFontColor();
+                PaintStyle buColor = other.getBulletFontColor();
                 if(buColor != null && !buColor.equals(getBulletFontColor())){
                     setBulletFontColor(buColor);
                 }
@@ -920,11 +939,21 @@ public class XSLFTextParagraph implement
             }
 
             @Override
-            public Color getBulletFontColor() {
+            public PaintStyle getBulletFontColor() {
                 return XSLFTextParagraph.this.getBulletFontColor();
             }
             
             @Override
+            public void setBulletFontColor(Color color) {
+                setBulletFontColor(DrawPaint.createSolidPaint(color));
+            }
+
+            @Override
+            public void setBulletFontColor(PaintStyle color) {
+                XSLFTextParagraph.this.setBulletFontColor(color);
+            }
+            
+            @Override
             public AutoNumberingScheme getAutoNumberingScheme() {
                 return XSLFTextParagraph.this.getAutoNumberingScheme();
             }

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=1694925&r1=1694924&r2=1694925&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 Sun 
Aug  9 22:44:13 2015
@@ -18,6 +18,9 @@ package org.apache.poi.xslf.usermodel;
 
 import java.awt.Color;
 
+import org.apache.poi.sl.draw.DrawPaint;
+import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
 import org.apache.poi.sl.usermodel.TextRun;
 import org.apache.poi.util.Beta;
 import org.apache.poi.xslf.model.CharacterPropertyFetcher;
@@ -84,10 +87,21 @@ public class XSLFTextRun implements Text
 
     @Override
     public void setFontColor(Color color) {
+        setFontColor(DrawPaint.createSolidPaint(color));
+    }
+    
+    @Override
+    public void setFontColor(PaintStyle color) {
+        if (!(color instanceof SolidPaint)) {
+            throw new IllegalArgumentException("Currently only SolidPaint is 
supported!");
+        }
+        SolidPaint sp = (SolidPaint)color;
+        
         CTTextCharacterProperties rPr = getRPr();
         CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? 
rPr.getSolidFill() : rPr.addNewSolidFill();
         CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : 
fill.addNewSrgbClr();
-        clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), 
(byte)color.getBlue()});
+        Color c = DrawPaint.applyColorTransform(sp.getSolidColor());
+        clr.setVal(new byte[]{(byte)c.getRed(), (byte)c.getGreen(), 
(byte)c.getBlue()});
 
         if(fill.isSetHslClr()) fill.unsetHslClr();
         if(fill.isSetPrstClr()) fill.unsetPrstClr();
@@ -98,22 +112,22 @@ public class XSLFTextRun implements Text
     }
 
     @Override
-    public Color getFontColor(){
-        final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
-        CTShapeStyle style = _p.getParentShape().getSpStyle();
-        final CTSchemeColor phClr = style == null ? null : 
style.getFontRef().getSchemeClr();
-
-        CharacterPropertyFetcher<Color> fetcher = new 
CharacterPropertyFetcher<Color>(_p.getIndentLevel()){
+    public PaintStyle getFontColor(){
+        CharacterPropertyFetcher<PaintStyle> fetcher = new 
CharacterPropertyFetcher<PaintStyle>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
-                CTSolidColorFillProperties solidFill = props.getSolidFill();
-                if(solidFill != null) {
-                    boolean useCtxColor =
-                            (solidFill.isSetSchemeClr() && 
solidFill.getSchemeClr().getVal() == STSchemeColorVal.PH_CLR)
-                            || isFetchingFromMaster;
-                    Color c = new XSLFColor(solidFill, theme, useCtxColor ? 
phClr : null).getColor();
-                    setValue(c);
+                XSLFShape shape = _p.getParentShape();
+                CTShapeStyle style = shape.getSpStyle();
+                CTSchemeColor phClr = null;
+                if (style != null && style.getFontRef() != null) {
+                    phClr = style.getFontRef().getSchemeClr();
+                }
+
+                PaintStyle ps = shape.getPaint(props, phClr);
+                if (ps != null)  {
+                    setValue(ps);
                     return true;
                 }
+                
                 return false;
             }
         };
@@ -250,7 +264,7 @@ public class XSLFTextRun implements Text
     }
 
     public byte getPitchAndFamily(){
-        final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
+        // final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
 
         CharacterPropertyFetcher<Byte> visitor = new 
CharacterPropertyFetcher<Byte>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
@@ -474,35 +488,36 @@ public class XSLFTextRun implements Text
     }
 
     private boolean fetchCharacterProperty(CharacterPropertyFetcher<?> 
fetcher){
+        XSLFTextShape shape = _p.getParentShape();
+        XSLFSheet sheet = shape.getSheet();
         boolean ok = false;
 
-        if(_r.isSetRPr()) ok = fetcher.fetch(getRPr());
-
-        if(!ok) {
-            XSLFTextShape shape = _p.getParentShape();
-            ok = shape.fetchShapeProperty(fetcher);
-            if(!ok){
-                CTPlaceholder ph = shape.getCTPlaceholder();
-                if(ph == null){
-                    // if it is a plain text box then take defaults from 
presentation.xml
-                    XMLSlideShow ppt = shape.getSheet().getSlideShow();
-                    CTTextParagraphProperties themeProps = 
ppt.getDefaultParagraphStyle(_p.getIndentLevel());
-                    if(themeProps != null) {
-                        fetcher.isFetchingFromMaster = true;
-                        ok = fetcher.fetch(themeProps);
-                    }
-                }
-                if (!ok) {
-                    CTTextParagraphProperties defaultProps =  
_p.getDefaultMasterStyle();
-                    if(defaultProps != null) {
-                        fetcher.isFetchingFromMaster = true;
-                        ok = fetcher.fetch(defaultProps);
-                    }
-                }
+        if (_r.isSetRPr()) ok = fetcher.fetch(getRPr());
+        if (ok) return true;
+        
+        ok = shape.fetchShapeProperty(fetcher);
+        if (ok) return true;
+        
+        CTPlaceholder ph = shape.getCTPlaceholder();
+        if (ph == null){
+            // if it is a plain text box then take defaults from 
presentation.xml
+            XMLSlideShow ppt = sheet.getSlideShow();
+            CTTextParagraphProperties themeProps = 
ppt.getDefaultParagraphStyle(_p.getIndentLevel());
+            if (themeProps != null) {
+                // TODO: determine master shape
+                ok = fetcher.fetch(themeProps);
             }
         }
+        if (ok) return true;
+
+        CTTextParagraphProperties defaultProps =  _p.getDefaultMasterStyle();
+        if(defaultProps != null) {
+            // TODO: determine master shape
+            ok = fetcher.fetch(defaultProps);
+        }
+        if (ok) return true;
 
-        return ok;
+        return false;
     }
 
     void copy(XSLFTextRun r){
@@ -511,7 +526,7 @@ public class XSLFTextRun implements Text
             setFontFamily(srcFontFamily);
         }
 
-        Color srcFontColor = r.getFontColor();
+        PaintStyle srcFontColor = r.getFontColor();
         if(srcFontColor != null && !srcFontColor.equals(getFontColor())){
             setFontColor(srcFontColor);
         }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to