]> source.dussan.org Git - poi.git/commitdiff
#56519 - XSLFSlide.draw is not working with text embeded in PPTX
authorAndreas Beeker <kiwiwings@apache.org>
Sun, 9 Aug 2015 22:44:13 +0000 (22:44 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Sun, 9 Aug 2015 22:44:13 +0000 (22:44 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1694925 13f79535-47bb-0310-9956-ffa450edef68

41 files changed:
src/java/org/apache/poi/sl/draw/DrawPaint.java
src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
src/java/org/apache/poi/sl/draw/DrawTextShape.java
src/java/org/apache/poi/sl/usermodel/ColorStyle.java
src/java/org/apache/poi/sl/usermodel/PaintStyle.java
src/java/org/apache/poi/sl/usermodel/Slide.java
src/java/org/apache/poi/sl/usermodel/SlideShow.java
src/java/org/apache/poi/sl/usermodel/TextParagraph.java
src/java/org/apache/poi/sl/usermodel/TextRun.java
src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextRun.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java
src/scratchpad/src/org/apache/poi/hslf/model/Line.java
src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTextRun.java
src/testcases/org/apache/poi/sl/TestCommonSL.java [new file with mode: 0644]
test-data/slideshow/KEY02.pptx [new file with mode: 0644]
test-data/slideshow/alterman_security.pptx [new file with mode: 0644]
test-data/slideshow/alterman_security2.pptx [deleted file]

index 26a94ed34722646a687517c72fc5da404206210e..2221c2f2f61a8c170dc7481a63ea202315cc2d2e 100644 (file)
 \r
 package org.apache.poi.sl.draw;\r
 \r
-import static org.apache.poi.sl.usermodel.PaintStyle.TRANSPARENT_PAINT;\r
-\r
-import java.awt.*;\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.LinearGradientPaint;\r
 import java.awt.MultipleGradientPaint.ColorSpaceType;\r
 import java.awt.MultipleGradientPaint.CycleMethod;\r
-import java.awt.geom.*;\r
+import java.awt.Paint;\r
+import java.awt.RadialGradientPaint;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Point2D;\r
+import java.awt.geom.Rectangle2D;\r
 import java.io.IOException;\r
 import java.io.InputStream;\r
 \r
-import org.apache.poi.sl.usermodel.*;\r
+import org.apache.poi.sl.usermodel.ColorStyle;\r
+import org.apache.poi.sl.usermodel.PaintStyle;\r
 import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;\r
 import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
 import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;\r
+import org.apache.poi.sl.usermodel.PlaceableShape;\r
 import org.apache.poi.util.POILogFactory;\r
 import org.apache.poi.util.POILogger;\r
 \r
 \r
 /**\r
- * This class handles color transformations\r
+ * This class handles color transformations.\r
  * \r
  * @see <a href="https://tips4java.wordpress.com/2009/07/05/hsl-color/">HSL code taken from Java Tips Weblog</a>\r
  */\r
@@ -50,19 +56,45 @@ public class DrawPaint {
         this.shape = shape;\r
     }\r
 \r
-    public static SolidPaint createSolidPaint(final Color color) {\r
-        return new SolidPaint() {\r
-            public ColorStyle getSolidColor() {\r
-                return new ColorStyle(){\r
+    private static class SimpleSolidPaint implements SolidPaint {\r
+        private final ColorStyle solidColor;\r
+\r
+        SimpleSolidPaint(final Color color) {\r
+            if (color == null) {\r
+                throw new NullPointerException("Color needs to be specified");\r
+            }\r
+            this.solidColor = new ColorStyle(){\r
                     public Color getColor() { return color; }\r
                     public int getAlpha() { return -1; }\r
+                    public int getHueOff() { return -1; }\r
+                    public int getHueMod() { return -1; }\r
+                    public int getSatOff() { return -1; }\r
+                    public int getSatMod() { return -1; }\r
                     public int getLumOff() { return -1; }\r
                     public int getLumMod() { return -1; }\r
                     public int getShade() { return -1; }\r
                     public int getTint() { return -1; }\r
                 };\r
+        }\r
+\r
+        SimpleSolidPaint(ColorStyle color) {\r
+            if (color == null) {\r
+                throw new NullPointerException("Color needs to be specified");\r
             }\r
-        };\r
+            this.solidColor = color;\r
+        }\r
+        \r
+        public ColorStyle getSolidColor() {\r
+            return solidColor;\r
+        }\r
+    }\r
+    \r
+    public static SolidPaint createSolidPaint(final Color color) {\r
+        return (color == null) ? null : new SimpleSolidPaint(color);\r
+    }\r
+    \r
+    public static SolidPaint createSolidPaint(final ColorStyle color) {\r
+        return (color == null) ? null : new SimpleSolidPaint(color);\r
     }\r
     \r
     public Paint getPaint(Graphics2D graphics, PaintStyle paint) {\r
@@ -95,26 +127,26 @@ public class DrawPaint {
 \r
     protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) {\r
         InputStream is = fill.getImageData();\r
-        if (is == null) return TRANSPARENT_PAINT.getSolidColor().getColor();\r
+        if (is == null) return null;\r
         assert(graphics != null);\r
         \r
         ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);\r
         if (renderer == null) renderer = new ImageRenderer();\r
 \r
         try {\r
-            renderer.loadImage(fill.getImageData(), fill.getContentType());\r
+            renderer.loadImage(is, fill.getContentType());\r
+            is.close();\r
         } catch (IOException e) {\r
             LOG.log(POILogger.ERROR, "Can't load image data - using transparent color", e);\r
-            return TRANSPARENT_PAINT.getSolidColor().getColor();\r
+            return null;\r
         }\r
 \r
         int alpha = fill.getAlpha();\r
-        if (alpha != -1) {\r
+        if (0 <= alpha && alpha < 100000) {\r
             renderer.setAlpha(alpha/100000.f);\r
         }\r
         \r
-        Dimension dim = renderer.getDimension();\r
-        Rectangle2D textAnchor = new Rectangle2D.Double(0, 0, dim.getWidth(), dim.getHeight());\r
+        Rectangle2D textAnchor = shape.getAnchor();\r
         Paint paint = new java.awt.TexturePaint(renderer.getImage(), textAnchor);\r
 \r
         return paint;\r
@@ -122,106 +154,102 @@ public class DrawPaint {
     \r
     /**\r
      * Convert color transformations in {@link ColorStyle} to a {@link Color} instance\r
+     * \r
+     * @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>\r
+     * @see <a href="https://social.msdn.microsoft.com/Forums/office/en-US/040e0a1f-dbfe-4ce5-826b-38b4b6f6d3f7/saturation-modulation-satmod">saturation modulation (satMod)</a>\r
+     * @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>\r
      */\r
     public static Color applyColorTransform(ColorStyle color){\r
+        // TODO: The colors don't match 100% the results of Powerpoint, maybe because we still\r
+        // operate in sRGB and not scRGB ... work in progress ...\r
+\r
         Color result = color.getColor();\r
+        if (result == null) return null;\r
 \r
-        if (result == null || color.getAlpha() == 100) {\r
-            return TRANSPARENT_PAINT.getSolidColor().getColor();\r
-        }\r
-        \r
-        result = applyAlpha(result, color);\r
-        result = applyLuminance(result, color);\r
-        result = applyShade(result, color);\r
-        result = applyTint(result, color);\r
+        double alpha = getAlpha(result, color);\r
+        double hsl[] = RGB2HSL(result); // values are in the range [0..100] (usually ...)\r
+        applyHslModOff(hsl, 0, color.getHueMod(), color.getHueOff());\r
+        applyHslModOff(hsl, 1, color.getSatMod(), color.getSatOff());\r
+        applyHslModOff(hsl, 2, color.getLumMod(), color.getLumOff());\r
+        applyShade(hsl, color);\r
+        applyTint(hsl, color);\r
 \r
+        result = HSL2RGB(hsl[0], hsl[1], hsl[2], alpha);\r
+        \r
         return result;\r
     }\r
 \r
-    protected static Color applyAlpha(Color c, ColorStyle fc) {\r
-        int alpha = c.getAlpha();\r
-        return (alpha == 255) ? c : new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha); \r
+    private static double getAlpha(Color c, ColorStyle fc) {\r
+        double alpha = c.getAlpha()/255d;\r
+        int fcAlpha = fc.getAlpha();\r
+        if (fcAlpha != -1) {\r
+            alpha *= fcAlpha/100000d;\r
+        }\r
+        return Math.min(1, Math.max(0, alpha));\r
     }\r
     \r
     /**\r
-     * Apply lumMod / lumOff adjustments\r
-     *\r
-     * @param c the color to modify\r
-     * @param fc the color style containing the lumMod / lumOff adjustments\r
-     * @return  modified color\r
+     * Apply the modulation and offset adjustments to the given HSL part\r
+     * \r
+     * Example for lumMod/lumOff:\r
+     * The lumMod value is the percent luminance. A lumMod value of "60000",\r
+     * is 60% of the luminance of the original color.\r
+     * When the color is a shade of the original theme color, the lumMod\r
+     * attribute is the only one of the tags shown here that appears.\r
+     * The <a:lumOff> tag appears after the <a:lumMod> tag when the color is a\r
+     * tint of the original. The lumOff value always equals 1-lumMod, which is used in the tint calculation\r
+     * \r
+     * Despite having different ways to display the tint and shade percentages,\r
+     * all of the programs use the same method to calculate the resulting color.\r
+     * Convert the original RGB value to HSL ... and then adjust the luminance (L)\r
+     * with one of the following equations before converting the HSL value back to RGB.\r
+     * (The % tint in the following equations refers to the tint, themetint, themeshade,\r
+     * or lumMod values, as applicable.)\r
+     * \r
+     * @param hsl the hsl values\r
+     * @param hslPart the hsl part to modify [0..2]\r
+     * @param mod the modulation adjustment\r
+     * @param off the offset adjustment\r
+     * @return the modified hsl value\r
      * \r
-     * @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>\r
      */\r
-    protected static Color applyLuminance(Color c, ColorStyle fc) {\r
-        int lumMod = fc.getLumMod();\r
-        if (lumMod == -1) lumMod = 100000;\r
-\r
-        int lumOff = fc.getLumOff();\r
-        if (lumOff == -1) lumOff = 0;\r
-        \r
-        if (lumMod == 100000 && lumOff == 0) return c;\r
-\r
-        // The lumMod value is the percent luminance. A lumMod value of "60000",\r
-        // is 60% of the luminance of the original color.\r
-        // When the color is a shade of the original theme color, the lumMod\r
-        // attribute is the only one of the tags shown here that appears.\r
-        // The <a:lumOff> tag appears after the <a:lumMod> tag when the color is a\r
-        // tint of the original. The lumOff value always equals 1-lumMod, which is used in the tint calculation\r
-        //\r
-        // Despite having different ways to display the tint and shade percentages,\r
-        // all of the programs use the same method to calculate the resulting color.\r
-        // Convert the original RGB value to HSL ... and then adjust the luminance (L)\r
-        // with one of the following equations before converting the HSL value back to RGB.\r
-        // (The % tint in the following equations refers to the tint, themetint, themeshade,\r
-        // or lumMod values, as applicable.)\r
-        //\r
-        // For a shade, the equation is luminance * %tint.\r
-        //\r
-        // For a tint, the equation is luminance * %tint + (1-%tint).\r
-        // (Note that 1-%tint is equal to the lumOff value in DrawingML.)\r
-        \r
-        double fLumOff = lumOff / 100000d;\r
-        double fLumMod = lumMod / 100000d;\r
-        \r
-        double hsl[] = RGB2HSL(c);\r
-        hsl[2] = hsl[2]*fLumMod+fLumOff;\r
-\r
-        Color c2 = HSL2RGB(hsl[0], hsl[1], hsl[2], c.getAlpha()/255d);\r
-        return c2;\r
+    private static void applyHslModOff(double hsl[], int hslPart, int mod, int off) {\r
+        if (mod == -1) mod = 100000;\r
+        if (off == -1) off = 0;\r
+        if (!(mod == 100000 && off == 0)) {\r
+            double fOff = off / 1000d;\r
+            double fMod = mod / 100000d;\r
+            hsl[hslPart] = hsl[hslPart]*fMod+fOff;\r
+        }\r
     }\r
     \r
     /**\r
-     * This algorithm returns result different from PowerPoint.\r
-     * TODO: revisit and improve\r
+     * Apply the shade\r
+     * \r
+     * For a shade, the equation is luminance * %tint.\r
      */\r
-    protected static Color applyShade(Color c, ColorStyle fc) {\r
+    private static void applyShade(double hsl[], ColorStyle fc) {\r
         int shade = fc.getShade();\r
-        if (shade == -1) return c;\r
+        if (shade == -1) return;\r
         \r
-        float fshade = shade / 100000.f;\r
-\r
-        float red = c.getRed() * fshade;\r
-        float green = c.getGreen() * fshade;\r
-        float blue = c.getGreen() * fshade;\r
+        double fshade = shade / 100000.d;\r
         \r
-        return new Color(Math.round(red), Math.round(green), Math.round(blue), c.getAlpha());\r
+        hsl[2] *= fshade;\r
     }\r
 \r
     /**\r
-     * This algorithm returns result different from PowerPoint.\r
-     * TODO: revisit and improve\r
+     * Apply the tint\r
+     * \r
+     * For a tint, the equation is luminance * %tint + (1-%tint).\r
+     * (Note that 1-%tint is equal to the lumOff value in DrawingML.)\r
      */\r
-    protected static Color applyTint(Color c, ColorStyle fc) {\r
+    private static void applyTint(double hsl[], ColorStyle fc) {\r
         int tint = fc.getTint();\r
-        if (tint == -1) return c;\r
+        if (tint == -1) return;\r
         \r
-        float ftint = tint / 100000.f;\r
-\r
-        float red = ftint * c.getRed() + (1.f - ftint) * 255.f;\r
-        float green = ftint * c.getGreen() + (1.f - ftint) * 255.f;\r
-        float blue = ftint * c.getBlue() + (1.f - ftint) * 255.f;\r
+        double ftint = tint / 100000.f;\r
 \r
-        return new Color(Math.round(red), Math.round(green), Math.round(blue), c.getAlpha());\r
+        hsl[2] = hsl[2] * ftint + (100 - ftint*100.);\r
     }\r
     \r
 \r
index d62b93006d73c6b4513b488223fae6c2b30d5952..8ffc57e606f98b181420a5c93b2a50a3cf678d26 100644 (file)
@@ -47,9 +47,6 @@ public class DrawSimpleShape<T extends SimpleShape> extends DrawShape<T> {
 \r
     @Override\r
     public void draw(Graphics2D graphics) {\r
-//        RenderableShape rShape = new RenderableShape(this);\r
-//        rShape.render(graphics);\r
-\r
         DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(shape);\r
         Paint fill = drawPaint.getPaint(graphics, shape.getFillStyle().getPaint());\r
         Paint line = drawPaint.getPaint(graphics, shape.getStrokeStyle().getPaint());\r
index e4ce1d760adc5838c7558b28723608f4e86bb04e..1a40372be04a1c5934b28d669b1ad52201ac0014 100644 (file)
 \r
 package org.apache.poi.sl.draw;\r
 \r
-import java.awt.Color;\r
 import java.awt.Graphics2D;\r
-import java.awt.font.*;\r
+import java.awt.Paint;\r
+import java.awt.font.FontRenderContext;\r
+import java.awt.font.LineBreakMeasurer;\r
+import java.awt.font.TextAttribute;\r
+import java.awt.font.TextLayout;\r
 import java.awt.geom.Rectangle2D;\r
-import java.text.*;\r
+import java.text.AttributedCharacterIterator;\r
 import java.text.AttributedCharacterIterator.Attribute;\r
-import java.util.*;\r
-\r
-import org.apache.poi.sl.usermodel.*;\r
+import java.text.AttributedString;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.apache.poi.sl.usermodel.AutoNumberingScheme;\r
+import org.apache.poi.sl.usermodel.Insets2D;\r
+import org.apache.poi.sl.usermodel.PaintStyle;\r
+import org.apache.poi.sl.usermodel.PlaceableShape;\r
+import org.apache.poi.sl.usermodel.Shape;\r
+import org.apache.poi.sl.usermodel.ShapeContainer;\r
+import org.apache.poi.sl.usermodel.TextParagraph;\r
 import org.apache.poi.sl.usermodel.TextParagraph.BulletStyle;\r
 import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;\r
+import org.apache.poi.sl.usermodel.TextRun;\r
 import org.apache.poi.sl.usermodel.TextRun.TextCap;\r
+import org.apache.poi.sl.usermodel.TextShape;\r
 import org.apache.poi.util.Units;\r
 \r
 public class DrawTextParagraph<T extends TextRun> implements Drawable {\r
@@ -69,9 +83,6 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
     public void draw(Graphics2D graphics){\r
         if (lines.isEmpty()) return;\r
         \r
-        Insets2D insets = paragraph.getParentShape().getInsets();\r
-        double leftInset = insets.left;\r
-        double rightInset = insets.right;\r
         double penY = y;\r
 \r
         boolean firstLine = true;\r
@@ -79,12 +90,17 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
         Double leftMargin = paragraph.getLeftMargin();\r
         if (leftMargin == null) {\r
             // if the marL attribute is omitted, then a value of 347663 is implied\r
-            leftMargin = Units.toPoints(347663*(indentLevel+1));\r
+            leftMargin = Units.toPoints(347663*indentLevel);\r
         }\r
         Double indent = paragraph.getIndent();\r
         if (indent == null) {\r
             indent = Units.toPoints(347663*indentLevel);\r
         }\r
+        if (paragraph.getClass().getName().contains("HSLF")) {\r
+            // special handling for HSLF\r
+            indent -= leftMargin;\r
+        }\r
+        \r
         Double rightMargin = paragraph.getRightMargin();\r
         if (rightMargin == null) {\r
             rightMargin = 0d;\r
@@ -104,25 +120,30 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
                 }\r
                 \r
                 if (bullet != null){\r
-                    bullet.setPosition(x + indent, penY);\r
+                    bullet.setPosition(x+leftMargin+indent, penY);\r
                     bullet.draw(graphics);\r
                     // don't let text overlay the bullet and advance by the bullet width\r
                     double bulletWidth = bullet.getLayout().getAdvance() + 1;\r
-                    penX = x + Math.max(leftMargin, indent+bulletWidth);\r
+                    penX = x + Math.max(leftMargin, leftMargin+indent+bulletWidth);\r
                 } else {\r
-                    penX = x + indent;\r
+                    penX = x + leftMargin;\r
                 }\r
             } else {\r
                 penX = x + leftMargin;\r
             }\r
 \r
             Rectangle2D anchor = DrawShape.getAnchor(graphics, paragraph.getParentShape());\r
+            // Insets are already applied on DrawTextShape.drawContent\r
+            // but (outer) anchor need to be adjusted\r
+            Insets2D insets = paragraph.getParentShape().getInsets();\r
+            double leftInset = insets.left;\r
+            double rightInset = insets.right;\r
 \r
             TextAlign ta = paragraph.getTextAlign();\r
             if (ta == null) ta = TextAlign.LEFT;\r
             switch (ta) {\r
                 case CENTER:\r
-                    penX += (anchor.getWidth() - leftMargin - line.getWidth() - leftInset - rightInset) / 2;\r
+                    penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset - leftMargin) / 2;\r
                     break;\r
                 case RIGHT:\r
                     penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset);\r
@@ -245,8 +266,14 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
         if (buFont == null) buFont = paragraph.getDefaultFontFamily();\r
         assert(buFont != null);\r
 \r
-        Color buColor = bulletStyle.getBulletFontColor();\r
-        if (buColor == null) buColor = (Color)firstLineAttr.getAttribute(TextAttribute.FOREGROUND);\r
+        PlaceableShape ps = getParagraphShape();\r
+        PaintStyle fgPaintStyle = bulletStyle.getBulletFontColor();\r
+        Paint fgPaint;\r
+        if (fgPaintStyle == null) {\r
+            fgPaint = (Paint)firstLineAttr.getAttribute(TextAttribute.FOREGROUND);\r
+        } else {\r
+            fgPaint = new DrawPaint(ps).getPaint(graphics, fgPaintStyle);\r
+        }\r
 \r
         float fontSize = (Float)firstLineAttr.getAttribute(TextAttribute.SIZE);\r
         Double buSz = bulletStyle.getBulletFontSize();\r
@@ -256,7 +283,7 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
 \r
         \r
         AttributedString str = new AttributedString(buCharacter);\r
-        str.addAttribute(TextAttribute.FOREGROUND, buColor);\r
+        str.addAttribute(TextAttribute.FOREGROUND, fgPaint);\r
         str.addAttribute(TextAttribute.FAMILY, buFont);\r
         str.addAttribute(TextAttribute.SIZE, fontSize);\r
 \r
@@ -382,11 +409,31 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
             this.endIndex = endIndex;\r
         }\r
     }\r
+    \r
+    /**\r
+     * Helper method for paint style relative to bounds, e.g. gradient paint\r
+     */\r
+    private PlaceableShape getParagraphShape() {\r
+        PlaceableShape ps = new PlaceableShape(){\r
+            public ShapeContainer<? extends Shape> getParent() { return null; }\r
+            public Rectangle2D getAnchor() { return paragraph.getParentShape().getAnchor(); }\r
+            public void setAnchor(Rectangle2D anchor) {}\r
+            public double getRotation() { return 0; }\r
+            public void setRotation(double theta) {}\r
+            public void setFlipHorizontal(boolean flip) {}\r
+            public void setFlipVertical(boolean flip) {}\r
+            public boolean getFlipHorizontal() { return false; }\r
+            public boolean getFlipVertical() { return false; }\r
+        };\r
+        return ps;\r
+    }\r
 \r
     protected AttributedString getAttributedString(Graphics2D graphics, StringBuilder text){\r
         List<AttributedStringData> attList = new ArrayList<AttributedStringData>();\r
         if (text == null) text = new StringBuilder();\r
 \r
+        PlaceableShape ps = getParagraphShape();\r
+        \r
         DrawFontManager fontHandler = (DrawFontManager)graphics.getRenderingHint(Drawable.FONT_HANDLER);\r
 \r
         for (TextRun run : paragraph){\r
@@ -398,9 +445,9 @@ public class DrawTextParagraph<T extends TextRun> implements Drawable {
             text.append(runText);\r
             int endIndex = text.length();\r
 \r
-            Color fgColor = run.getFontColor();\r
-            if (fgColor == null) fgColor = Color.BLACK;\r
-            attList.add(new AttributedStringData(TextAttribute.FOREGROUND, fgColor, beginIndex, endIndex));\r
+            PaintStyle fgPaintStyle = run.getFontColor();\r
+            Paint fgPaint = new DrawPaint(ps).getPaint(graphics, fgPaintStyle);\r
+            attList.add(new AttributedStringData(TextAttribute.FOREGROUND, fgPaint, beginIndex, endIndex));\r
 \r
             // user can pass an custom object to convert fonts\r
             String fontFamily = run.getFontFamily();\r
index 3be880ec02bf74687378e040113de1419331f63a..36896ba688e8711f3da0dbb7595e9f8b0abe4457 100644 (file)
@@ -102,7 +102,6 @@ public class DrawTextShape<T extends TextShape<? extends TextParagraph<? extends
      */\r
     public double drawParagraphs(Graphics2D graphics, double x, double y) {\r
         DrawFactory fact = DrawFactory.getInstance(graphics);\r
-        Insets2D shapePadding = shape.getInsets();\r
 \r
         double y0 = y;\r
         Iterator<? extends TextParagraph<? extends TextRun>> paragraphs = shape.iterator();\r
index 9be847b36c04dbc17c51e0433e0ddca50fa27687..fba7f5eae054a9efadfe9aa945cd3a450b73bcac 100644 (file)
@@ -32,17 +32,55 @@ public interface ColorStyle {
     int getAlpha();\r
     \r
     /**\r
-     * the luminance shift as expressed by a percentage relative to the input color\r
+     * the hue shift as expressed by a percentage relative to the input color.\r
+     * Be aware that OOXML also returns values greater than 100%\r
+     * \r
+     * @return  hue shift in percents in the range [0..100000] (usually ...)\r
+     * or -1 if the value is not set\r
+     */\r
+    int getHueOff();\r
+    \r
+    /**\r
+     * the hue as expressed by a percentage relative to the input color.\r
+     * Be aware that OOXML also returns values greater than 100%\r
+     * \r
+     * @return  hue in percents in the range [0..100000] (usually ...)\r
+     * or -1 if the value is not set\r
+     */\r
+    int getHueMod();\r
+    \r
+    /**\r
+     * the saturation shift as expressed by a percentage relative to the input color.\r
+     * Be aware that OOXML also returns values greater than 100%\r
+     * \r
+     * @return  saturation shift in percents in the range [0..100000] (usually ...)\r
+     * or -1 if the value is not set\r
+     */\r
+    int getSatOff();\r
+    \r
+    /**\r
+     * the saturation as expressed by a percentage relative to the input color.\r
+     * Be aware that OOXML also returns values greater than 100%\r
+     * \r
+     * @return  saturation in percents in the range [0..100000] (usually ...)\r
+     * or -1 if the value is not set\r
+     */\r
+    int getSatMod();\r
+    \r
+    /**\r
+     * the luminance shift as expressed by a percentage relative to the input color.\r
+     * Be aware that OOXML also returns values greater than 100%\r
      *\r
-     * @return  luminance shift in percents in the range [0..100000]\r
+     * @return  luminance shift in percents in the range [0..100000] (usually ...)\r
      * or -1 if the value is not set\r
      */\r
     int getLumOff();\r
     \r
     /**\r
-     * the luminance as expressed by a percentage relative to the input color\r
+     * the luminance as expressed by a percentage relative to the input color.\r
+     * Be aware that OOXML also returns values greater than 100%.\r
      *\r
-     * @return  luminance in percents in the range [0..100000]\r
+     * @return  luminance in percents in the range [0..100000] (usually ...)\r
      * or -1 if the value is not set\r
      */\r
     int getLumMod();\r
@@ -50,8 +88,9 @@ public interface ColorStyle {
     /**\r
      * specifies a darker version of its input color.\r
      * A 10% shade is 10% of the input color combined with 90% black.\r
+     * Be aware that OOXML also returns values greater than 100%.\r
      * \r
-     * @return the value of the shade specified as percents in the range [0..100000]\r
+     * @return the value of the shade specified as percents in the range [0..100000] (usually ...)\r
      * with 0% indicating minimal shade and 100% indicating maximum\r
      * or -1 if the value is not set\r
      */\r
@@ -60,8 +99,9 @@ public interface ColorStyle {
     /**\r
      * specifies a lighter version of its input color.\r
      * A 10% tint is 10% of the input color combined with 90% white.\r
+     * Be aware that OOXML also returns values greater than 100%\r
      *\r
-     * @return the value of the tint specified as percents in the range [0..100000]\r
+     * @return the value of the tint specified as percents in the range [0..100000] (usually ...)\r
      * with 0% indicating minimal tint and 100% indicating maximum\r
      * or -1 if the value is not set\r
      */\r
index 2551201692e865f93bb2d541669b94d5c688bdc8..25651043b74aa168c158e954859ac8fb3be10aa1 100644 (file)
 
 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));
 }
index 7b238de1762b4fdec685185c06b4fa536cc81b3a..b992a5e3c6b7f1199e81bb49f015ae3630cae4cb 100644 (file)
 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);
+    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();
 
-       /**
-        * @return the 1-based slide no.
-        */
-       int getSlideNumber();
 }
index 5ced5b21e2d6ef639deb15863efac2d16eba5091..e8f442821aa90e00b3ded888996cac2810c01c94 100644 (file)
@@ -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 {
index 0b2eb062c20d53c81b21c00c88f4b45ec6e19474..97296bb0bc54039d0a246e7807be321a61b5331a 100644 (file)
@@ -20,6 +20,7 @@ package org.apache.poi.sl.usermodel;
 import java.awt.Color;\r
 \r
 \r
+\r
 public interface TextParagraph<T extends TextRun> extends Iterable<T> {\r
 \r
     /**\r
@@ -113,7 +114,20 @@ public interface TextParagraph<T extends TextRun> extends Iterable<T> {
          * @return the bullet point font size\r
          */\r
         Double getBulletFontSize();\r
-        Color getBulletFontColor();\r
+\r
+        /**\r
+         * Convenience function to set a solid color\r
+         */\r
+        void setBulletFontColor(Color color);\r
+        \r
+        void setBulletFontColor(PaintStyle color);\r
+\r
+        /**\r
+         *\r
+         * @return the color of bullet characters within a given paragraph.\r
+         * A {@code null} value means to use the text font color.\r
+         */\r
+        PaintStyle getBulletFontColor();\r
         \r
         AutoNumberingScheme getAutoNumberingScheme();\r
         /**\r
index 946bfc3217c65028ec9b161949ae76738c7259ae..ff76a98e08e292d9a4ba4b662c97dafee8ffb950 100644 (file)
@@ -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);
        
        
     /**
diff --git a/src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java b/src/ooxml/java/org/apache/poi/sl/SlideShowFactory.java
new file mode 100644 (file)
index 0000000..19446c9
--- /dev/null
@@ -0,0 +1,298 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.sl;\r
+\r
+import java.io.File;\r
+import java.io.FileNotFoundException;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.PushbackInputStream;\r
+import java.security.GeneralSecurityException;\r
+\r
+import org.apache.poi.EmptyFileException;\r
+import org.apache.poi.EncryptedDocumentException;\r
+import org.apache.poi.POIXMLDocument;\r
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;\r
+import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;\r
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
+import org.apache.poi.openxml4j.opc.OPCPackage;\r
+import org.apache.poi.openxml4j.opc.PackageAccess;\r
+import org.apache.poi.poifs.crypt.Decryptor;\r
+import org.apache.poi.poifs.crypt.EncryptionInfo;\r
+import org.apache.poi.poifs.filesystem.DirectoryNode;\r
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;\r
+import org.apache.poi.poifs.filesystem.OfficeXmlFileException;\r
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;\r
+import org.apache.poi.sl.usermodel.SlideShow;\r
+import org.apache.poi.util.IOUtils;\r
+import org.apache.poi.xslf.usermodel.XMLSlideShow;\r
+\r
+public class SlideShowFactory {\r
+    /**\r
+     * Creates a HSLFSlideShow from the given POIFSFileSystem\r
+     * <p>Note that in order to properly release resources the\r
+     *  SlideShow should be closed after use.\r
+     */\r
+    public static SlideShow create(POIFSFileSystem fs) throws IOException {\r
+        return new HSLFSlideShow(fs);\r
+    }\r
+\r
+    /**\r
+     * Creates a HSLFSlideShow from the given NPOIFSFileSystem\r
+     * <p>Note that in order to properly release resources the\r
+     *  SlideShow should be closed after use.\r
+     */\r
+    public static SlideShow create(NPOIFSFileSystem fs) throws IOException {\r
+        try {\r
+            return create(fs, null);\r
+        } catch (InvalidFormatException e) {\r
+            // Special case of OOXML-in-POIFS which is broken\r
+            throw new IOException(e);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Creates a SlideShow from the given NPOIFSFileSystem, which may\r
+     *  be password protected\r
+     *\r
+     *  @param fs The {@link NPOIFSFileSystem} to read the document from\r
+     *  @param password The password that should be used or null if no password is necessary.\r
+     *\r
+     *  @return The created SlideShow\r
+     *\r
+     *  @throws IOException if an error occurs while reading the data\r
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}\r
+     */\r
+    private static SlideShow create(NPOIFSFileSystem fs, String password) throws IOException, InvalidFormatException {\r
+        DirectoryNode root = fs.getRoot();\r
+\r
+        // Encrypted OOXML files go inside OLE2 containers, is this one?\r
+        if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {\r
+            EncryptionInfo info = new EncryptionInfo(fs);\r
+            Decryptor d = Decryptor.getInstance(info);\r
+\r
+            boolean passwordCorrect = false;\r
+            InputStream stream = null;\r
+            try {\r
+                if (password != null && d.verifyPassword(password)) {\r
+                    passwordCorrect = true;\r
+                }\r
+                if (!passwordCorrect && d.verifyPassword(Decryptor.DEFAULT_PASSWORD)) {\r
+                    passwordCorrect = true;\r
+                }\r
+                if (passwordCorrect) {\r
+                    stream = d.getDataStream(root);\r
+                }\r
+            } catch (GeneralSecurityException e) {\r
+                throw new IOException(e);\r
+            }\r
+\r
+            if (! passwordCorrect) {\r
+                if (password != null)\r
+                    throw new EncryptedDocumentException("Password incorrect");\r
+                else\r
+                    throw new EncryptedDocumentException("The supplied spreadsheet is protected, but no password was supplied");\r
+            }\r
+\r
+            OPCPackage pkg = OPCPackage.open(stream);\r
+            return create(pkg);\r
+        }\r
+\r
+        // If we get here, it isn't an encrypted PPTX file\r
+        // So, treat it as a regular HSLF PPT one\r
+        if (password != null) {\r
+            Biff8EncryptionKey.setCurrentUserPassword(password);\r
+        }\r
+        SlideShow wb = new HSLFSlideShow(root);\r
+        Biff8EncryptionKey.setCurrentUserPassword(null);\r
+        return wb;\r
+    }\r
+\r
+    /**\r
+     * Creates a XMLSlideShow from the given OOXML Package\r
+     *\r
+     * <p>Note that in order to properly release resources the\r
+     *  SlideShow should be closed after use.</p>\r
+     *\r
+     *  @param pkg The {@link OPCPackage} opened for reading data.\r
+     *\r
+     *  @return The created SlideShow\r
+     *\r
+     *  @throws IOException if an error occurs while reading the data\r
+     */\r
+    public static SlideShow create(OPCPackage pkg) throws IOException {\r
+        return new XMLSlideShow(pkg);\r
+    }\r
+\r
+    /**\r
+     * Creates the appropriate HSLFSlideShow / XMLSlideShow from\r
+     *  the given InputStream.\r
+     *\r
+     * <p>Your input stream MUST either support mark/reset, or\r
+     *  be wrapped as a {@link PushbackInputStream}! Note that\r
+     *  using an {@link InputStream} has a higher memory footprint\r
+     *  than using a {@link File}.</p>\r
+     *\r
+     * <p>Note that in order to properly release resources the\r
+     *  SlideShow should be closed after use. Note also that loading\r
+     *  from an InputStream requires more memory than loading\r
+     *  from a File, so prefer {@link #create(File)} where possible.\r
+     *\r
+     *  @param inp The {@link InputStream} to read data from.\r
+     *\r
+     *  @return The created SlideShow\r
+     *\r
+     *  @throws IOException if an error occurs while reading the data\r
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}\r
+     *  @throws EncryptedDocumentException If the SlideShow given is password protected\r
+     */\r
+    public static SlideShow create(InputStream inp) throws IOException, InvalidFormatException, EncryptedDocumentException {\r
+        return create(inp, null);\r
+    }\r
+\r
+    /**\r
+     * Creates the appropriate HSLFSlideShow / XMLSlideShow from\r
+     *  the given InputStream, which may be password protected.\r
+     * <p>Your input stream MUST either support mark/reset, or\r
+     *  be wrapped as a {@link PushbackInputStream}! Note that\r
+     *  using an {@link InputStream} has a higher memory footprint\r
+     *  than using a {@link File}.</p>\r
+     *\r
+     * <p>Note that in order to properly release resources the\r
+     *  SlideShow should be closed after use. Note also that loading\r
+     *  from an InputStream requires more memory than loading\r
+     *  from a File, so prefer {@link #create(File)} where possible.</p>\r
+     *\r
+     *  @param inp The {@link InputStream} to read data from.\r
+     *  @param password The password that should be used or null if no password is necessary.\r
+     *\r
+     *  @return The created SlideShow\r
+     *\r
+     *  @throws IOException if an error occurs while reading the data\r
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}\r
+     *  @throws EncryptedDocumentException If the wrong password is given for a protected file\r
+     *  @throws EmptyFileException If an empty stream is given\r
+     */\r
+    public static SlideShow create(InputStream inp, String password) throws IOException, InvalidFormatException, EncryptedDocumentException {\r
+        // If clearly doesn't do mark/reset, wrap up\r
+        if (! inp.markSupported()) {\r
+            inp = new PushbackInputStream(inp, 8);\r
+        }\r
+\r
+        // Ensure that there is at least some data there\r
+        byte[] header8 = IOUtils.peekFirst8Bytes(inp);\r
+\r
+        // Try to create\r
+        if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {\r
+            NPOIFSFileSystem fs = new NPOIFSFileSystem(inp);\r
+            return create(fs, password);\r
+        }\r
+        if (POIXMLDocument.hasOOXMLHeader(inp)) {\r
+            return new XMLSlideShow(OPCPackage.open(inp));\r
+        }\r
+        throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");\r
+    }\r
+\r
+    /**\r
+     * Creates the appropriate HSLFSlideShow / XMLSlideShow from\r
+     *  the given File, which must exist and be readable.\r
+     * <p>Note that in order to properly release resources the\r
+     *  SlideShow should be closed after use.\r
+     *\r
+     *  @param file The file to read data from.\r
+     *\r
+     *  @return The created SlideShow\r
+     *\r
+     *  @throws IOException if an error occurs while reading the data\r
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}\r
+     *  @throws EncryptedDocumentException If the SlideShow given is password protected\r
+     */\r
+    public static SlideShow create(File file) throws IOException, InvalidFormatException, EncryptedDocumentException {\r
+        return create(file, null);\r
+    }\r
+\r
+    /**\r
+     * Creates the appropriate HSLFSlideShow / XMLSlideShow from\r
+     *  the given File, which must exist and be readable, and\r
+     *  may be password protected\r
+     * <p>Note that in order to properly release resources the\r
+     *  SlideShow should be closed after use.\r
+     *\r
+     *  @param file The file to read data from.\r
+     *  @param password The password that should be used or null if no password is necessary.\r
+     *\r
+     *  @return The created SlideShow\r
+     *\r
+     *  @throws IOException if an error occurs while reading the data\r
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}\r
+     *  @throws EncryptedDocumentException If the wrong password is given for a protected file\r
+     *  @throws EmptyFileException If an empty stream is given\r
+     */\r
+    public static SlideShow create(File file, String password) throws IOException, InvalidFormatException, EncryptedDocumentException {\r
+        return create(file, password, false);\r
+    }\r
+\r
+    /**\r
+     * Creates the appropriate HSLFSlideShow / XMLSlideShow from\r
+     *  the given File, which must exist and be readable, and\r
+     *  may be password protected\r
+     * <p>Note that in order to properly release resources the\r
+     *  SlideShow should be closed after use.\r
+     *\r
+     *  @param file The file to read data from.\r
+     *  @param password The password that should be used or null if no password is necessary.\r
+     *  @param readOnly If the SlideShow should be opened in read-only mode to avoid writing back\r
+     *      changes when the document is closed.\r
+     *\r
+     *  @return The created SlideShow\r
+     *\r
+     *  @throws IOException if an error occurs while reading the data\r
+     *  @throws InvalidFormatException if the contents of the file cannot be parsed into a {@link SlideShow}\r
+     *  @throws EncryptedDocumentException If the wrong password is given for a protected file\r
+     *  @throws EmptyFileException If an empty stream is given\r
+     */\r
+    public static SlideShow create(File file, String password, boolean readOnly) throws IOException, InvalidFormatException, EncryptedDocumentException {\r
+        if (! file.exists()) {\r
+            throw new FileNotFoundException(file.toString());\r
+        }\r
+\r
+        try {\r
+            NPOIFSFileSystem fs = new NPOIFSFileSystem(file, readOnly);\r
+            return create(fs, password);\r
+        } catch(OfficeXmlFileException e) {\r
+            // opening as .ppt failed => try opening as .pptx\r
+            OPCPackage pkg = OPCPackage.open(file, readOnly ? PackageAccess.READ : PackageAccess.READ_WRITE);\r
+            try {\r
+                return new XMLSlideShow(pkg);\r
+//            } catch (IOException ioe) {\r
+//                // ensure that file handles are closed (use revert() to not re-write the file)\r
+//                pkg.revert();\r
+//                //pkg.close();\r
+//\r
+//                // rethrow exception\r
+//                throw ioe;\r
+            } catch (IllegalArgumentException ioe) {\r
+                // ensure that file handles are closed (use revert() to not re-write the file)\r
+                pkg.revert();\r
+                //pkg.close();\r
+\r
+                // rethrow exception\r
+                throw ioe;\r
+            }\r
+        }\r
+    }\r
+}\r
index ced941ccb33b5f5cd681cac07e83bcf85a1faf53..c20f94259bcda27a9c37a2c21de2324c964275d9 100644 (file)
@@ -27,8 +27,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties
  * @author Yegor Kozlov\r
  */\r
 public abstract class CharacterPropertyFetcher<T> extends ParagraphPropertyFetcher<T> {\r
-    public boolean isFetchingFromMaster = false;\r
-\r
     public CharacterPropertyFetcher(int level) {\r
         super(level);\r
     }\r
index 09e05d9648e1fcd94af42ba90b1fc76d68bdaf08..67a41faec2422617148b87976ffcb860d59b83e7 100644 (file)
@@ -78,6 +78,22 @@ public class XSLFColor {
                 return getRawValue("alpha");\r
             }\r
 \r
+            public int getHueOff() {\r
+                return getRawValue("hueOff");\r
+            }\r
+\r
+            public int getHueMod() {\r
+                return getRawValue("hueMod");\r
+            }\r
+\r
+            public int getSatOff() {\r
+                return getRawValue("satOff");\r
+            }\r
+\r
+            public int getSatMod() {\r
+                return getRawValue("satMod");\r
+            }\r
+\r
             public int getLumOff() {\r
                 return getRawValue("lumOff");\r
             }\r
index c3b0b1a5116fd23b00fe3f59e5dcb6f1de7e28c8..f312145b9b10df74754a26f9fb704e9d0a0a3552 100644 (file)
@@ -44,8 +44,12 @@ public class XSLFDrawing {
         XmlObject[] cNvPr = sheet.getSpTree().selectPath(\r
                 "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");\r
         for(XmlObject o : cNvPr) {\r
-            CTNonVisualDrawingProps p = (CTNonVisualDrawingProps)o;\r
-            _shapeId = (int)Math.max(_shapeId, p.getId());\r
+            // powerpoint generates AlternateContent elements which cNvPr elements aren't recognized\r
+            // ignore them for now\r
+            if (o instanceof CTNonVisualDrawingProps) {\r
+                CTNonVisualDrawingProps p = (CTNonVisualDrawingProps)o;\r
+                _shapeId = (int)Math.max(_shapeId, p.getId());\r
+            }\r
         }\r
     }\r
 \r
index 85e85b6a4630762ca9d3b52070d86e58aefc00a3..fd42bc2d76e0f12e382dae3fb907c47cb2743dc0 100644 (file)
@@ -21,8 +21,6 @@ import java.awt.Color;
 import java.awt.geom.Rectangle2D;\r
 \r
 import org.apache.poi.sl.draw.DrawPaint;\r
-import org.apache.poi.sl.usermodel.ColorStyle;\r
-import org.apache.poi.sl.usermodel.PaintStyle;\r
 import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
 import org.apache.poi.sl.usermodel.Shadow;\r
 import org.apache.poi.util.Units;\r
@@ -90,7 +88,7 @@ public class XSLFShadow extends XSLFShape implements Shadow {
      */\r
     public Color getFillColor() {\r
         SolidPaint ps = getFillStyle();\r
-        if (ps == PaintStyle.TRANSPARENT_PAINT) return null;\r
+        if (ps == null) return null;\r
         Color col = DrawPaint.applyColorTransform(ps.getSolidColor());\r
         return col;\r
     }\r
@@ -99,14 +97,10 @@ public class XSLFShadow extends XSLFShape implements Shadow {
     public SolidPaint getFillStyle() {\r
         XSLFTheme theme = getSheet().getTheme();\r
         CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();\r
-        if(ct == null) return PaintStyle.TRANSPARENT_PAINT;\r
+        if(ct == null) return null;\r
             \r
         CTSchemeColor phClr = ct.getSchemeClr();\r
         final XSLFColor xc = new XSLFColor(ct, theme, phClr);\r
-        return new SolidPaint(){\r
-            public ColorStyle getSolidColor() {\r
-                return xc.getColorStyle();\r
-            }\r
-        };\r
+        return DrawPaint.createSolidPaint(xc.getColorStyle());\r
     }\r
 }
\ No newline at end of file
index 3ea1d3a7ca1865b065b8be8c335a862d25424f00..d0c5123825bc8074b6b595e3633cb8ebc51eda31 100644 (file)
@@ -27,10 +27,10 @@ import java.util.Comparator;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
 import org.apache.poi.openxml4j.opc.PackagePart;\r
 import org.apache.poi.openxml4j.opc.PackageRelationship;\r
+import org.apache.poi.sl.draw.DrawPaint;\r
 import org.apache.poi.sl.usermodel.ColorStyle;\r
 import org.apache.poi.sl.usermodel.PaintStyle;\r
 import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;\r
-import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
 import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;\r
 import org.apache.poi.sl.usermodel.PlaceableShape;\r
 import org.apache.poi.sl.usermodel.Shape;\r
@@ -38,7 +38,20 @@ import org.apache.poi.util.Beta;
 import org.apache.poi.util.Internal;\r
 import org.apache.poi.xslf.model.PropertyFetcher;\r
 import org.apache.xmlbeans.XmlObject;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientStop;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNoFillProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;\r
@@ -139,7 +152,7 @@ public abstract class XSLFShape implements Shape {
                 try {\r
                     pr = shape.getSpPr();\r
                     if (((CTShapeProperties)pr).isSetNoFill()) {\r
-                        setValue(PaintStyle.TRANSPARENT_PAINT);\r
+                        setValue(null);\r
                         return true;\r
                     }                    \r
                 } catch (IllegalStateException e) {}\r
@@ -156,21 +169,19 @@ public abstract class XSLFShape implements Shape {
                     }\r
                 }\r
                 \r
-                if (pr == null) {\r
-                    setValue(PaintStyle.TRANSPARENT_PAINT);\r
-                    return true;\r
-                }\r
+                if (pr == null) return false;\r
                 \r
                 PaintStyle paint = null;\r
+                PackagePart pp = getSheet().getPackagePart();\r
                 for (XmlObject obj : pr.selectPath("*")) {\r
-                    paint = selectPaint(obj, null, getSheet().getPackagePart());\r
-                    if (paint != null) break;\r
+                    paint = selectPaint(obj, null, pp);\r
+                    if (paint != null) {\r
+                        setValue(paint);\r
+                        return true;\r
+                    };\r
                 }\r
                 \r
-                if (paint == null) return false;\r
-                \r
-                setValue(paint);\r
-                return true;\r
+                return false;\r
             }\r
         };\r
         fetchShapeProperty(fetcher);\r
@@ -190,7 +201,7 @@ public abstract class XSLFShape implements Shape {
         }\r
         paint = selectPaint(fillRef);\r
 \r
-        return paint == null ? PaintStyle.TRANSPARENT_PAINT : paint;\r
+        return paint;\r
     }\r
 \r
     protected CTBackgroundProperties getBgPr() {\r
@@ -347,8 +358,8 @@ public abstract class XSLFShape implements Shape {
             paint = selectPaint(obj, phClr, pp);\r
             if(paint != null) break;\r
         }\r
-        return paint == null ? PaintStyle.TRANSPARENT_PAINT : paint;\r
-    }    \r
+        return paint;\r
+    }\r
     \r
     /**\r
      * Convert shape fill into java.awt.Paint. The result is either Color or\r
@@ -371,13 +382,13 @@ public abstract class XSLFShape implements Shape {
      */\r
     protected PaintStyle selectPaint(XmlObject obj, final CTSchemeColor phClr, final PackagePart parentPart) {\r
         if (obj instanceof CTNoFillProperties) {\r
-            return PaintStyle.TRANSPARENT_PAINT;\r
+            return null;\r
         } else if (obj instanceof CTSolidColorFillProperties) {\r
-            return selectPaint((CTSolidColorFillProperties)obj, phClr, parentPart);\r
+            return selectPaint((CTSolidColorFillProperties)obj, phClr);\r
         } else if (obj instanceof CTBlipFillProperties) {\r
-            return selectPaint((CTBlipFillProperties)obj, phClr, parentPart);\r
+            return selectPaint((CTBlipFillProperties)obj, parentPart);\r
         } else if (obj instanceof CTGradientFillProperties) {\r
-            return selectPaint((CTGradientFillProperties) obj, phClr, parentPart);\r
+            return selectPaint((CTGradientFillProperties) obj, phClr);\r
         } else if (obj instanceof CTStyleMatrixReference) {\r
             return selectPaint((CTStyleMatrixReference)obj);\r
         } else {\r
@@ -385,17 +396,16 @@ public abstract class XSLFShape implements Shape {
         }\r
     }\r
 \r
-    protected PaintStyle selectPaint(final CTSolidColorFillProperties solidFill, final CTSchemeColor phClr, final PackagePart parentPart) {\r
+    protected PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr) {\r
         final XSLFTheme theme = getSheet().getTheme();\r
+        if (phClr == null && solidFill.isSetSchemeClr()) {\r
+            phClr = solidFill.getSchemeClr();\r
+        }\r
         final XSLFColor c = new XSLFColor(solidFill, theme, phClr);\r
-        return new SolidPaint() {\r
-            public ColorStyle getSolidColor() {\r
-                return c.getColorStyle();\r
-            }\r
-        };\r
+        return DrawPaint.createSolidPaint(c.getColorStyle());\r
     }\r
     \r
-    protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, final CTSchemeColor phClr, final PackagePart parentPart) {\r
+    protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart) {\r
         final CTBlip blip = blipFill.getBlip();\r
         return new TexturePaint() {\r
             private PackagePart getPart() {\r
@@ -424,12 +434,12 @@ public abstract class XSLFShape implements Shape {
             public int getAlpha() {\r
                 return (blip.sizeOfAlphaModFixArray() > 0)\r
                     ? blip.getAlphaModFixArray(0).getAmt()\r
-                    : 0;\r
+                    : 100000;\r
             }\r
         };        \r
     }\r
     \r
-    protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, final CTSchemeColor phClr, final PackagePart parentPart) {\r
+    protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr) {\r
 \r
         @SuppressWarnings("deprecation")\r
         final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();\r
@@ -448,7 +458,11 @@ public abstract class XSLFShape implements Shape {
         \r
         int i=0;\r
         for (CTGradientStop cgs : gs) {\r
-            cs[i] = new XSLFColor(cgs, theme, phClr).getColorStyle();\r
+            CTSchemeColor phClrCgs = phClr;\r
+            if (phClrCgs == null && cgs.isSetSchemeClr()) {\r
+                phClrCgs = cgs.getSchemeClr();\r
+            }\r
+            cs[i] = new XSLFColor(cgs, theme, phClrCgs).getColorStyle();\r
             fractions[i] = cgs.getPos() / 100000.f;\r
             i++;\r
         }\r
index bd29667c8cb254782febf0541949c6e0c4077c16..3b08748762894d41dd3ee0756e834380902a7881 100644 (file)
@@ -19,8 +19,6 @@
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import static org.apache.poi.sl.usermodel.PaintStyle.TRANSPARENT_PAINT;\r
-\r
 import java.awt.Color;\r
 import java.awt.geom.Rectangle2D;\r
 \r
@@ -31,10 +29,15 @@ import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.sl.draw.geom.CustomGeometry;\r
 import org.apache.poi.sl.draw.geom.Guide;\r
 import org.apache.poi.sl.draw.geom.PresetGeometries;\r
-import org.apache.poi.sl.usermodel.*;\r
+import org.apache.poi.sl.usermodel.FillStyle;\r
+import org.apache.poi.sl.usermodel.LineDecoration;\r
 import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;\r
 import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;\r
+import org.apache.poi.sl.usermodel.PaintStyle;\r
 import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
+import org.apache.poi.sl.usermodel.ShapeType;\r
+import org.apache.poi.sl.usermodel.SimpleShape;\r
+import org.apache.poi.sl.usermodel.StrokeStyle;\r
 import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;\r
 import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;\r
 import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;\r
@@ -219,7 +222,6 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape {
      */\r
     public Color getLineColor() {\r
         PaintStyle ps = getLinePaint();\r
-        if (ps == null || ps == TRANSPARENT_PAINT) return null;\r
         if (ps instanceof SolidPaint) {\r
             return ((SolidPaint)ps).getSolidColor().getColor();\r
         }\r
@@ -232,7 +234,7 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape {
                 CTLineProperties spPr = shape.getSpPr().getLn();\r
                 if (spPr != null) {\r
                     if (spPr.isSetNoFill()) {\r
-                        setValue(TRANSPARENT_PAINT); // use it as 'nofill' value\r
+                        setValue(null); // use it as 'nofill' value\r
                         return true;\r
                     }\r
                     \r
@@ -266,7 +268,7 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape {
         \r
         // line color was not found, check if it is defined in the theme\r
         CTShapeStyle style = getSpStyle();\r
-        if (style == null) return TRANSPARENT_PAINT;\r
+        if (style == null) return null;\r
         \r
         // get a reference to a line style within the style matrix.\r
         CTStyleMatrixReference lnRef = style.getLnRef();\r
@@ -279,7 +281,7 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape {
             paint = getPaint(lnProps, phClr);\r
         }\r
 \r
-        return paint == null ? TRANSPARENT_PAINT : paint;\r
+        return paint;\r
     }\r
     \r
     /**\r
@@ -524,7 +526,6 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape {
      */\r
     public Color getFillColor() {\r
         PaintStyle ps = getFillPaint();\r
-        if (ps == null || ps == TRANSPARENT_PAINT) return null;\r
         if (ps instanceof SolidPaint) {\r
             return ((SolidPaint)ps).getSolidColor().getColor();\r
         }\r
index 83024ee2efd23fce400dd829895c7aeffb5335dd..83453573cd00445069baff0833285553afb37300 100644 (file)
@@ -168,13 +168,10 @@ public final class XSLFSlide extends XSLFSheet implements Slide<XSLFShape, XMLSl
        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
index f9bad78be24a8002a509d9ec4ef31a3dafce3374..6cffd94701193adaa1437a0dc418d4fd6a47bf12 100644 (file)
@@ -21,7 +21,10 @@ import java.util.ArrayList;
 import java.util.Iterator;\r
 import java.util.List;\r
 \r
+import org.apache.poi.sl.draw.DrawPaint;\r
 import org.apache.poi.sl.usermodel.AutoNumberingScheme;\r
+import org.apache.poi.sl.usermodel.PaintStyle;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
 import org.apache.poi.sl.usermodel.TextParagraph;\r
 import org.apache.poi.util.Beta;\r
 import org.apache.poi.util.Internal;\r
@@ -264,7 +267,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
      * @return the color of bullet characters within a given paragraph.\r
      * A <code>null</code> value means to use the text font color.\r
      */\r
-    public Color getBulletFontColor(){\r
+    public PaintStyle getBulletFontColor(){\r
         final XSLFTheme theme = getParentShape().getSheet().getTheme();\r
         ParagraphPropertyFetcher<Color> fetcher = new ParagraphPropertyFetcher<Color>(getIndentLevel()){\r
             public boolean fetch(CTTextParagraphProperties props){\r
@@ -277,19 +280,33 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
             }\r
         };\r
         fetchParagraphProperty(fetcher);\r
-        return fetcher.getValue();\r
+        Color col = fetcher.getValue();\r
+        return (col == null) ? null : DrawPaint.createSolidPaint(col);\r
     }\r
 \r
+    public void setBulletFontColor(Color color) {\r
+        setBulletFontColor(DrawPaint.createSolidPaint(color));\r
+    }\r
+    \r
+    \r
     /**\r
      * Set the color to be used on bullet characters within a given paragraph.\r
      *\r
      * @param color the bullet color\r
      */\r
-    public void setBulletFontColor(Color color){\r
+    public void setBulletFontColor(PaintStyle color) {\r
+        if (!(color instanceof SolidPaint)) {\r
+            throw new IllegalArgumentException("Currently XSLF only supports SolidPaint");\r
+        }\r
+\r
+        // TODO: implement setting bullet color to null\r
+        SolidPaint sp = (SolidPaint)color;\r
+        Color col = DrawPaint.applyColorTransform(sp.getSolidColor());\r
+        \r
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();\r
         CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr();\r
         CTSRgbColor clr = c.isSetSrgbClr() ? c.getSrgbClr() : c.addNewSrgbClr();\r
-        clr.setVal(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()});\r
+        clr.setVal(new byte[]{(byte) col.getRed(), (byte) col.getGreen(), (byte) col.getBlue()});\r
     }\r
 \r
     /**\r
@@ -729,7 +746,6 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
         XSLFSheet masterSheet = _shape.getSheet();\r
         for (XSLFSheet m = masterSheet; m != null; m = (XSLFSheet)m.getMasterSheet()) {\r
             masterSheet = m;\r
-\r
             XmlObject xo = masterSheet.getXmlObject();\r
             for (String xpath : xpaths) {\r
                 XmlObject[] o = xo.selectPath(xpath);\r
@@ -767,32 +783,35 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
 \r
     private <T> boolean fetchParagraphProperty(ParagraphPropertyFetcher<T> visitor){\r
         boolean ok = false;\r
-\r
+        XSLFTextShape shape = getParentShape();\r
+        XSLFSheet sheet = shape.getSheet();\r
+        \r
         if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr());\r
+        if (ok) return true;\r
 \r
-        if(!ok) {\r
-            XSLFTextShape shape = getParentShape();\r
-            ok = shape.fetchShapeProperty(visitor);\r
-            if(!ok){\r
-                CTPlaceholder ph = shape.getCTPlaceholder();\r
-                if(ph == null){\r
-                    // if it is a plain text box then take defaults from presentation.xml\r
-                    XMLSlideShow ppt = getParentShape().getSheet().getSlideShow();\r
-                    CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel());\r
-                    if(themeProps != null) ok = visitor.fetch(themeProps);\r
-                }\r
-\r
-                if(!ok){\r
-                    // defaults for placeholders are defined in the slide master\r
-                    CTTextParagraphProperties defaultProps = getDefaultMasterStyle();\r
-                    if(defaultProps != null) ok = visitor.fetch(defaultProps);\r
-                }\r
-            }\r
+        ok = shape.fetchShapeProperty(visitor);\r
+        if (ok) return true;\r
+                \r
+        \r
+        CTPlaceholder ph = shape.getCTPlaceholder();\r
+        if(ph == null){\r
+            // if it is a plain text box then take defaults from presentation.xml\r
+            XMLSlideShow ppt = sheet.getSlideShow();\r
+            CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel());\r
+            if (themeProps != null) ok = visitor.fetch(themeProps);\r
         }\r
+        if (ok) return true;\r
+\r
+        // defaults for placeholders are defined in the slide master\r
+        CTTextParagraphProperties defaultProps = getDefaultMasterStyle();\r
+        // TODO: determine master shape\r
+        if(defaultProps != null) ok = visitor.fetch(defaultProps);\r
+        if (ok) return true;\r
 \r
-        return ok;\r
+        return false;\r
     }\r
 \r
+    @SuppressWarnings("deprecation")\r
     void copy(XSLFTextParagraph other){\r
         if (other == this) return;\r
         \r
@@ -848,7 +867,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
                 if(buChar != null && !buChar.equals(getBulletCharacter())){\r
                     setBulletCharacter(buChar);\r
                 }\r
-                Color buColor = other.getBulletFontColor();\r
+                PaintStyle buColor = other.getBulletFontColor();\r
                 if(buColor != null && !buColor.equals(getBulletFontColor())){\r
                     setBulletFontColor(buColor);\r
                 }\r
@@ -920,10 +939,20 @@ public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
             }\r
 \r
             @Override\r
-            public Color getBulletFontColor() {\r
+            public PaintStyle getBulletFontColor() {\r
                 return XSLFTextParagraph.this.getBulletFontColor();\r
             }\r
             \r
+            @Override\r
+            public void setBulletFontColor(Color color) {\r
+                setBulletFontColor(DrawPaint.createSolidPaint(color));\r
+            }\r
+\r
+            @Override\r
+            public void setBulletFontColor(PaintStyle color) {\r
+                XSLFTextParagraph.this.setBulletFontColor(color);\r
+            }\r
+            \r
             @Override\r
             public AutoNumberingScheme getAutoNumberingScheme() {\r
                 return XSLFTextParagraph.this.getAutoNumberingScheme();\r
index 7a5c78b1982cd86742cc7ced25e1f827c7acb48e..fd0f44d75ac7ca7f5bfeafe160cdf9a928114f60 100644 (file)
@@ -18,6 +18,9 @@ package org.apache.poi.xslf.usermodel;
 \r
 import java.awt.Color;\r
 \r
+import org.apache.poi.sl.draw.DrawPaint;\r
+import org.apache.poi.sl.usermodel.PaintStyle;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
 import org.apache.poi.sl.usermodel.TextRun;\r
 import org.apache.poi.util.Beta;\r
 import org.apache.poi.xslf.model.CharacterPropertyFetcher;\r
@@ -84,10 +87,21 @@ public class XSLFTextRun implements TextRun {
 \r
     @Override\r
     public void setFontColor(Color color) {\r
+        setFontColor(DrawPaint.createSolidPaint(color));\r
+    }\r
+    \r
+    @Override\r
+    public void setFontColor(PaintStyle color) {\r
+        if (!(color instanceof SolidPaint)) {\r
+            throw new IllegalArgumentException("Currently only SolidPaint is supported!");\r
+        }\r
+        SolidPaint sp = (SolidPaint)color;\r
+        \r
         CTTextCharacterProperties rPr = getRPr();\r
         CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();\r
         CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr();\r
-        clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});\r
+        Color c = DrawPaint.applyColorTransform(sp.getSolidColor());\r
+        clr.setVal(new byte[]{(byte)c.getRed(), (byte)c.getGreen(), (byte)c.getBlue()});\r
 \r
         if(fill.isSetHslClr()) fill.unsetHslClr();\r
         if(fill.isSetPrstClr()) fill.unsetPrstClr();\r
@@ -98,22 +112,22 @@ public class XSLFTextRun implements TextRun {
     }\r
 \r
     @Override\r
-    public Color getFontColor(){\r
-        final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();\r
-        CTShapeStyle style = _p.getParentShape().getSpStyle();\r
-        final CTSchemeColor phClr = style == null ? null : style.getFontRef().getSchemeClr();\r
-\r
-        CharacterPropertyFetcher<Color> fetcher = new CharacterPropertyFetcher<Color>(_p.getIndentLevel()){\r
+    public PaintStyle getFontColor(){\r
+        CharacterPropertyFetcher<PaintStyle> fetcher = new CharacterPropertyFetcher<PaintStyle>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                CTSolidColorFillProperties solidFill = props.getSolidFill();\r
-                if(solidFill != null) {\r
-                    boolean useCtxColor =\r
-                            (solidFill.isSetSchemeClr() && solidFill.getSchemeClr().getVal() == STSchemeColorVal.PH_CLR)\r
-                            || isFetchingFromMaster;\r
-                    Color c = new XSLFColor(solidFill, theme, useCtxColor ? phClr : null).getColor();\r
-                    setValue(c);\r
+                XSLFShape shape = _p.getParentShape();\r
+                CTShapeStyle style = shape.getSpStyle();\r
+                CTSchemeColor phClr = null;\r
+                if (style != null && style.getFontRef() != null) {\r
+                    phClr = style.getFontRef().getSchemeClr();\r
+                }\r
+\r
+                PaintStyle ps = shape.getPaint(props, phClr);\r
+                if (ps != null)  {\r
+                    setValue(ps);\r
                     return true;\r
                 }\r
+                \r
                 return false;\r
             }\r
         };\r
@@ -250,7 +264,7 @@ public class XSLFTextRun implements TextRun {
     }\r
 \r
     public byte getPitchAndFamily(){\r
-        final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();\r
+        // final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();\r
 \r
         CharacterPropertyFetcher<Byte> visitor = new CharacterPropertyFetcher<Byte>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
@@ -474,35 +488,36 @@ public class XSLFTextRun implements TextRun {
     }\r
 \r
     private boolean fetchCharacterProperty(CharacterPropertyFetcher<?> fetcher){\r
+        XSLFTextShape shape = _p.getParentShape();\r
+        XSLFSheet sheet = shape.getSheet();\r
         boolean ok = false;\r
 \r
-        if(_r.isSetRPr()) ok = fetcher.fetch(getRPr());\r
-\r
-        if(!ok) {\r
-            XSLFTextShape shape = _p.getParentShape();\r
-            ok = shape.fetchShapeProperty(fetcher);\r
-            if(!ok){\r
-                CTPlaceholder ph = shape.getCTPlaceholder();\r
-                if(ph == null){\r
-                    // if it is a plain text box then take defaults from presentation.xml\r
-                    XMLSlideShow ppt = shape.getSheet().getSlideShow();\r
-                    CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel());\r
-                    if(themeProps != null) {\r
-                        fetcher.isFetchingFromMaster = true;\r
-                        ok = fetcher.fetch(themeProps);\r
-                    }\r
-                }\r
-                if (!ok) {\r
-                    CTTextParagraphProperties defaultProps =  _p.getDefaultMasterStyle();\r
-                    if(defaultProps != null) {\r
-                        fetcher.isFetchingFromMaster = true;\r
-                        ok = fetcher.fetch(defaultProps);\r
-                    }\r
-                }\r
+        if (_r.isSetRPr()) ok = fetcher.fetch(getRPr());\r
+        if (ok) return true;\r
+        \r
+        ok = shape.fetchShapeProperty(fetcher);\r
+        if (ok) return true;\r
+        \r
+        CTPlaceholder ph = shape.getCTPlaceholder();\r
+        if (ph == null){\r
+            // if it is a plain text box then take defaults from presentation.xml\r
+            XMLSlideShow ppt = sheet.getSlideShow();\r
+            CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel());\r
+            if (themeProps != null) {\r
+                // TODO: determine master shape\r
+                ok = fetcher.fetch(themeProps);\r
             }\r
         }\r
+        if (ok) return true;\r
+\r
+        CTTextParagraphProperties defaultProps =  _p.getDefaultMasterStyle();\r
+        if(defaultProps != null) {\r
+            // TODO: determine master shape\r
+            ok = fetcher.fetch(defaultProps);\r
+        }\r
+        if (ok) return true;\r
 \r
-        return ok;\r
+        return false;\r
     }\r
 \r
     void copy(XSLFTextRun r){\r
@@ -511,7 +526,7 @@ public class XSLFTextRun implements TextRun {
             setFontFamily(srcFontFamily);\r
         }\r
 \r
-        Color srcFontColor = r.getFontColor();\r
+        PaintStyle srcFontColor = r.getFontColor();\r
         if(srcFontColor != null && !srcFontColor.equals(getFontColor())){\r
             setFontColor(srcFontColor);\r
         }\r
index 400c637ca8c6549fe3a7e7bc4694366ddcf882b2..43fefedf54cd25862784508dcd30a354bd13b07b 100644 (file)
 \r
 package org.apache.poi.xslf.util;\r
 \r
-import org.apache.poi.openxml4j.opc.OPCPackage;\r
-import org.apache.poi.xslf.usermodel.XMLSlideShow;\r
-import org.apache.poi.xslf.usermodel.XSLFSlide;\r
-\r
-import javax.imageio.ImageIO;\r
-\r
-import java.awt.Color;\r
 import java.awt.Dimension;\r
 import java.awt.Graphics2D;\r
 import java.awt.RenderingHints;\r
 import java.awt.image.BufferedImage;\r
-import java.io.FileOutputStream;\r
+import java.io.File;\r
+import java.util.HashMap;\r
 import java.util.List;\r
+import java.util.Map;\r
+\r
+import javax.imageio.ImageIO;\r
+\r
+import org.apache.poi.sl.SlideShowFactory;\r
+import org.apache.poi.sl.draw.Drawable;\r
+import org.apache.poi.sl.usermodel.Slide;\r
+import org.apache.poi.sl.usermodel.SlideShow;\r
+import org.apache.poi.util.JvmBugs;\r
 \r
 /**\r
  * An utulity to convert slides of a .pptx slide show to a PNG image\r
@@ -40,22 +43,33 @@ import java.util.List;
  */\r
 public class PPTX2PNG {\r
 \r
-    static void usage(){\r
-        System.out.println("Usage: PPTX2PNG [options] <pptx file>");\r
-        System.out.println("Options:");\r
-        System.out.println("    -scale <float>   scale factor");\r
-        System.out.println("    -slide <integer> 1-based index of a slide to render");\r
+    static void usage(String error){\r
+        String msg =\r
+            "Usage: PPTX2PNG [options] <ppt or pptx file>\n" +\r
+            (error == null ? "" : ("Error: "+error+"\n")) +\r
+            "Options:\n" +\r
+            "    -scale <float>   scale factor\n" +\r
+            "    -slide <integer> 1-based index of a slide to render\n" +\r
+            "    -format <type>   png,gif,jpg (,null for testing)" +\r
+            "    -outdir <dir>    output directory, defaults to origin of the ppt/pptx file" +\r
+            "    -quite           do not write to console (for normal processing)";\r
+\r
+        System.out.println(msg);\r
+        // no System.exit here, as we also run in junit tests!\r
     }\r
 \r
     public static void main(String[] args) throws Exception {\r
         if (args.length == 0) {\r
-            usage();\r
+            usage(null);\r
             return;\r
         }\r
 \r
         int slidenum = -1;\r
         float scale = 1;\r
-        String file = null;\r
+        File file = null;\r
+        String format = "png";\r
+        File outdir = null;\r
+        boolean quite = false;\r
 \r
         for (int i = 0; i < args.length; i++) {\r
             if (args[i].startsWith("-")) {\r
@@ -63,55 +77,104 @@ public class PPTX2PNG {
                     scale = Float.parseFloat(args[++i]);\r
                 } else if ("-slide".equals(args[i])) {\r
                     slidenum = Integer.parseInt(args[++i]);\r
+                } else if ("-format".equals(args[i])) {\r
+                    format = args[++i];\r
+                } else if ("-outdir".equals(args[i])) {\r
+                    outdir = new File(args[++i]);\r
+                } else if ("-quite".equals(args[i])) {\r
+                    quite = true;\r
                 }\r
             } else {\r
-                file = args[i];\r
+                file = new File(args[i]);\r
             }\r
         }\r
 \r
-        if(file == null){\r
-            usage();\r
+        if (file == null || !file.exists()) {\r
+            usage("File not specified or it doesn't exist");\r
+            return;\r
+        }\r
+\r
+        if (outdir == null) {\r
+            outdir = file.getParentFile();\r
+        }\r
+        \r
+        if (outdir == null || !outdir.exists() || !outdir.isDirectory()) {\r
+            usage("Output directory doesn't exist");\r
             return;\r
         }\r
 \r
-        System.out.println("Processing " + file);\r
-        XMLSlideShow ppt = new XMLSlideShow(OPCPackage.open(file));\r
+        if (scale < 0) {\r
+            usage("Invalid scale given");\r
+            return;\r
+        }\r
+        \r
+        if (format == null || !format.matches("^(png|gif|jpg|null)$")) {\r
+            usage("Invalid format given");\r
+            return;\r
+        }\r
+    \r
+        if (!quite) {\r
+            System.out.println("Processing " + file);\r
+        }\r
+        SlideShow ss = SlideShowFactory.create(file, null, true);\r
+        List<? extends Slide<?,?,?>> slides = ss.getSlides();\r
 \r
-        Dimension pgsize = ppt.getPageSize();\r
+        \r
+        if (slidenum < -1 || slidenum == 0 || slidenum > slides.size()) {\r
+            usage("slidenum must be either -1 (for all) or within range: [1.."+slides.size()+"] for "+file);\r
+            return;\r
+        }\r
+        \r
+        Dimension pgsize = ss.getPageSize();\r
         int width = (int) (pgsize.width * scale);\r
         int height = (int) (pgsize.height * scale);\r
 \r
-        List<XSLFSlide> slide = ppt.getSlides();\r
-        for (int i = 0; i < slide.size(); i++) {\r
-            if (slidenum != -1 && slidenum != (i + 1)) continue;\r
-\r
-            String title = slide.get(i).getTitle();\r
-            System.out.println("Rendering slide " + (i + 1) + (title == null ? "" : ": " + title));\r
-\r
-            BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);\r
-            Graphics2D graphics = img.createGraphics();\r
-\r
-            // default rendering options\r
-            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
-            graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);\r
-            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);\r
-            graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);\r
-\r
-            graphics.setColor(Color.white);\r
-            graphics.clearRect(0, 0, width, height);\r
-\r
-            graphics.scale(scale, scale);\r
-\r
-            // draw stuff\r
-            slide.get(i).draw(graphics);\r
+        int slideNo=1;\r
+        for(Slide<?,?,?> slide : slides) {\r
+            if (slidenum == -1 || slideNo == slidenum) {\r
+                String title = slide.getTitle();\r
+                if (!quite) {\r
+                    System.out.println("Rendering slide " + slideNo + (title == null ? "" : ": " + title));\r
+                }\r
 \r
-            // save the result\r
-            int sep = file.lastIndexOf(".");\r
-            String fname = file.substring(0, sep == -1 ? file.length() : sep) + "-" + (i + 1) +".png";\r
-            FileOutputStream out = new FileOutputStream(fname);\r
-            ImageIO.write(img, "png", out);\r
-            out.close();\r
+                BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);\r
+                Graphics2D graphics = img.createGraphics();\r
+                fixFonts(graphics);\r
+            \r
+                // default rendering options\r
+                graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
+                graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);\r
+                graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);\r
+                graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);\r
+\r
+                graphics.scale(scale, scale);\r
+\r
+                // draw stuff\r
+                slide.draw(graphics);\r
+\r
+                // save the result\r
+                if (!"null".equals(format)) {\r
+                    String outname = file.getName().replaceFirst(".pptx?", "");\r
+                    outname = String.format("%1$s-%2$04d.%3$s", outname, slideNo, format);\r
+                    File outfile = new File(outdir, outname);\r
+                    ImageIO.write(img, format, outfile);\r
+                }\r
+            }                \r
+            slideNo++;\r
         }\r
-        System.out.println("Done");\r
+        \r
+        if (!quite) {\r
+            System.out.println("Done");\r
+        }\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    private static void fixFonts(Graphics2D graphics) {\r
+        if (!JvmBugs.hasLineBreakMeasurerBug()) return;\r
+        Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);\r
+        if (fontMap == null) fontMap = new HashMap<String,String>();\r
+        fontMap.put("Calibri", "Lucida Sans");\r
+        fontMap.put("Cambria", "Lucida Bright");\r
+        graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);        \r
     }\r
 }\r
index a0a937aee82cfcaec9dec243fd79bfaf3545ac2d..2c72f0a4472dfcf828efcfa73277e3df1b3de9e9 100644 (file)
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import java.awt.Dimension;\r
-import java.awt.Graphics2D;\r
-import java.awt.image.BufferedImage;\r
+import java.io.File;\r
 import java.lang.reflect.Field;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
 \r
-import org.apache.poi.sl.draw.Drawable;\r
-import org.apache.poi.util.JvmBugs;\r
-import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import org.apache.poi.POIDataSamples;\r
+import org.apache.poi.xslf.util.PPTX2PNG;\r
 import org.junit.AfterClass;\r
 import org.junit.BeforeClass;\r
 import org.junit.Test;\r
@@ -44,7 +39,6 @@ public class TestPPTX2PNG {
     @BeforeClass\r
     public static void activateJaxpDebug() {\r
         jaxpDebugEnable = setDebugFld(true);\r
-//        setXmlInputFactory();\r
     }\r
 \r
     @AfterClass\r
@@ -66,48 +60,26 @@ public class TestPPTX2PNG {
             return false;\r
         }\r
     }\r
-\r
-//    private static void setXmlInputFactory() {\r
-//        String propName = "javax.xml.stream.XMLInputFactory";\r
-//        String propVal = "com.sun.xml.internal.stream.XMLInputFactoryImpl";\r
-//        try {\r
-//            Class.forName(propVal);\r
-//            System.setProperty(propName, propVal);\r
-//        } catch (Exception e){\r
-//            // ignore\r
-//        }\r
-//    }\r
-    \r
     \r
     @Test\r
     public void render() throws Exception {\r
-        String[] testFiles = {"backgrounds.pptx","layouts.pptx", "sample.pptx", "shapes.pptx", "themes.pptx",};\r
+        POIDataSamples samples = POIDataSamples.getSlideShowInstance();\r
+\r
+        String[] testFiles = {"alterman_security.ppt","alterman_security.pptx","KEY02.pptx","themes.pptx","backgrounds.pptx","layouts.pptx", "sample.pptx", "shapes.pptx",};\r
+        String[] args = {\r
+            "-format", "null", // png,gif,jpg or null for test\r
+            "-slide", "-1", // -1 for all\r
+            "-outdir", new File("build/tmp/").getCanonicalPath(),\r
+            "-quite",\r
+            "dummyfile"\r
+        };\r
         for(String sampleFile : testFiles){\r
+            args[args.length-1] = samples.getFile(sampleFile).getCanonicalPath();\r
             try {\r
-                XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument(sampleFile);\r
-                Dimension pg = pptx.getPageSize();\r
-                //int slideNo=1;\r
-                for(XSLFSlide slide : pptx.getSlides()){\r
-                    BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_ARGB);\r
-                    Graphics2D graphics = img.createGraphics();\r
-                    fixFonts(graphics);\r
-                    slide.draw(graphics);\r
-                    // ImageIO.write(img, "PNG", new File("build/tmp/"+sampleFile.replaceFirst(".pptx?", "-")+slideNo+".png"));\r
-                    //slideNo++;\r
-                }\r
+                PPTX2PNG.main(args);\r
             } catch (IllegalStateException e) {\r
                 throw new IllegalStateException("While reading file " + sampleFile, e);\r
             }\r
         }\r
     }\r
-    \r
-    @SuppressWarnings("unchecked")\r
-    private void fixFonts(Graphics2D graphics) {\r
-        if (!JvmBugs.hasLineBreakMeasurerBug()) return;\r
-        Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);\r
-        if (fontMap == null) fontMap = new HashMap<String,String>();\r
-        fontMap.put("Calibri", "Lucida Sans");\r
-        fontMap.put("Cambria", "Lucida Bright");\r
-        graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);        \r
-    }\r
 }\r
index 6088eeee71f9f1103fd149b088825acfebbfaed9..db2c9833f7b468dcf23b3750b16721cab47d2be2 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import static org.junit.Assert.*;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.assertTrue;\r
+import static org.junit.Assert.fail;\r
 \r
 import java.awt.Color;\r
 import java.io.IOException;\r
index 3314855c70a5e4c2e20f7d29f5679c24e17dfad6..691d9941ad18b5247d8810c4fbaa0093a12af9f9 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import static org.junit.Assert.*;\r
+import static org.apache.poi.sl.TestCommonSL.sameColor;\r
+import static org.junit.Assert.assertArrayEquals;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.assertTrue;\r
 \r
 import java.awt.Color;\r
+import java.io.IOException;\r
 import java.util.List;\r
 \r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
@@ -98,7 +104,7 @@ public class TestXSLFSlide {
     }\r
 \r
     @Test\r
-    public void testCreateSlide(){\r
+    public void testCreateSlide() throws IOException {\r
         XMLSlideShow  ppt = new XMLSlideShow();\r
         assertEquals(0, ppt.getSlides().size());\r
 \r
@@ -108,10 +114,12 @@ public class TestXSLFSlide {
         assertFalse(slide.getFollowMasterGraphics());\r
         slide.setFollowMasterGraphics(true);\r
         assertTrue(slide.getFollowMasterGraphics());\r
+        \r
+        ppt.close();\r
     }\r
 \r
     @Test\r
-    public void testImportContent(){\r
+    public void testImportContent() throws IOException {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
 \r
         XMLSlideShow  src = XSLFTestDataSamples.openSampleDocument("themes.pptx");\r
@@ -128,7 +136,7 @@ public class TestXSLFSlide {
         assertEquals(40.0, r1.getFontSize(), 0);\r
         assertTrue(r1.isBold());\r
         assertTrue(r1.isItalic());\r
-        assertEquals(new Color(148, 198, 0), r1.getFontColor());\r
+        assertTrue(sameColor(new Color(148, 198, 0), r1.getFontColor()));\r
         assertNull(sh1.getFillColor());\r
         assertNull(sh1.getLineColor());\r
 \r
@@ -141,7 +149,7 @@ public class TestXSLFSlide {
         assertEquals(18.0, r2.getFontSize(), 0);\r
         assertFalse(r2.isBold());\r
         assertFalse(r2.isItalic());\r
-        assertEquals(Color.white, r2.getFontColor());\r
+        assertTrue(sameColor(Color.white, r2.getFontColor()));\r
         assertEquals(new Color(148, 198, 0), sh2.getFillColor());\r
         assertEquals(new Color(148, 198, 0), sh2.getLineColor()); // slightly different from PowerPoint!\r
 \r
@@ -157,17 +165,19 @@ public class TestXSLFSlide {
         //assertEquals(32.4.0, r3.getFontSize());\r
         assertTrue(r3.isBold());\r
         assertTrue(r3.isItalic());\r
-        assertEquals(new Color(148, 198, 0), r3.getFontColor());\r
+        assertTrue(sameColor(new Color(148, 198, 0), r3.getFontColor()));\r
         assertNull(sh3.getFillColor());\r
         assertNull(sh3.getLineColor());\r
 \r
         XSLFPictureShape sh4 = (XSLFPictureShape)shapes2.get(1);\r
         XSLFPictureShape srcPic = (XSLFPictureShape)src.getSlides().get(4).getShapes().get(1);\r
         assertArrayEquals(sh4.getPictureData().getData(), srcPic.getPictureData().getData());\r
+        \r
+        ppt.close();\r
     }\r
 \r
     @Test\r
-    public void testMergeSlides(){\r
+    public void testMergeSlides() throws IOException {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         String[] pptx = {"shapes.pptx", "themes.pptx", "layouts.pptx", "backgrounds.pptx"};\r
 \r
@@ -179,5 +189,7 @@ public class TestXSLFSlide {
             }\r
         }\r
         assertEquals(30, ppt.getSlides().size());\r
+        \r
+        ppt.close();\r
     }    \r
 }
\ No newline at end of file
index e71cf2419fe52dff4bd1160ec2bda5f01c8d9779..1ad525011c2266b8a3a2e454fbee0ac152bec914 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import static org.junit.Assert.*;\r
-\r
-import java.awt.*;\r
+import static org.apache.poi.sl.TestCommonSL.sameColor;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.assertTrue;\r
+\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.Rectangle;\r
 import java.awt.geom.Rectangle2D;\r
 import java.awt.image.BufferedImage;\r
+import java.io.IOException;\r
 import java.util.List;\r
 \r
 import org.apache.poi.sl.draw.DrawTextFragment;\r
 import org.apache.poi.sl.draw.DrawTextParagraph;\r
 import org.apache.poi.sl.usermodel.AutoNumberingScheme;\r
 import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;\r
-import org.apache.poi.util.POILogFactory;\r
-import org.apache.poi.util.POILogger;\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
 import org.junit.Assume;\r
 import org.junit.Test;\r
@@ -37,7 +42,7 @@ import org.junit.Test;
  * @author Yegor Kozlov\r
  */\r
 public class TestXSLFTextParagraph {\r
-    private static POILogger _logger = POILogFactory.getLogger(XSLFTextParagraph.class);\r
+    // private static POILogger _logger = POILogFactory.getLogger(XSLFTextParagraph.class);\r
 \r
     static class DrawTextParagraphProxy extends DrawTextParagraph<XSLFTextRun> {\r
         DrawTextParagraphProxy(XSLFTextParagraph p) {\r
@@ -58,7 +63,7 @@ public class TestXSLFTextParagraph {
     }\r
     \r
     @Test\r
-    public void testWrappingWidth() throws Exception {\r
+    public void testWrappingWidth() throws IOException {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
         XSLFTextShape sh = slide.createAutoShape();\r
@@ -142,6 +147,8 @@ public class TestXSLFTextParagraph {
         expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;\r
         assertEquals(244.0, expectedWidth, 0); // 300 - 10 - 10 - 36 \r
         assertEquals(expectedWidth, dtp.getWrappingWidth(false, null), 0);\r
+        \r
+        ppt.close();\r
      }\r
 \r
     /**\r
@@ -149,7 +156,7 @@ public class TestXSLFTextParagraph {
      * This test requires that the Arial font is available and will run only on windows\r
      */\r
     @Test\r
-    public void testBreakLines(){\r
+    public void testBreakLines() throws IOException {\r
         String os = System.getProperty("os.name");\r
         Assume.assumeTrue("Skipping testBreakLines(), it is executed only on Windows machines", (os != null && os.contains("Windows")));\r
 \r
@@ -237,10 +244,11 @@ public class TestXSLFTextParagraph {
         // the first line is at least two times higher than the second\r
         assertTrue(lines.get(0).getHeight() > lines.get(1).getHeight()*2);\r
 \r
+        ppt.close();\r
     }\r
 \r
     @Test\r
-    public void testThemeInheritance(){\r
+    public void testThemeInheritance() throws IOException {\r
         XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("prProps.pptx");\r
         List<XSLFShape> shapes = ppt.getSlides().get(0).getShapes();\r
         XSLFTextShape sh1 = (XSLFTextShape)shapes.get(0);\r
@@ -252,10 +260,11 @@ public class TestXSLFTextParagraph {
         XSLFTextShape sh3 = (XSLFTextShape)shapes.get(2);\r
         assertEquals("Foundation", sh3.getText());\r
         assertEquals(TextAlign.CENTER, sh3.getTextParagraphs().get(0).getTextAlign());\r
+        ppt.close();\r
     }\r
 \r
     @Test\r
-    public void testParagraphProperties(){\r
+    public void testParagraphProperties() throws IOException {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
         XSLFTextShape sh = slide.createAutoShape();\r
@@ -275,7 +284,7 @@ public class TestXSLFTextParagraph {
 \r
         assertEquals(null, p.getBulletFontColor());\r
         p.setBulletFontColor(Color.red);\r
-        assertEquals(Color.red, p.getBulletFontColor());\r
+        assertTrue(sameColor(Color.red, p.getBulletFontColor()));\r
 \r
         assertNull(p.getBulletFontSize());\r
         p.setBulletFontSize(200.);\r
@@ -342,34 +351,35 @@ public class TestXSLFTextParagraph {
 \r
         assertEquals(72.0, p.getDefaultTabSize(), 0);\r
 \r
+        ppt.close();\r
     }\r
 \r
-    @Test\r
-    public void testLineBreak(){\r
+    @Test(expected = IllegalStateException.class)\r
+    public void testLineBreak() throws IOException {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
-        XSLFSlide slide = ppt.createSlide();\r
-        XSLFTextShape sh = slide.createAutoShape();\r
-\r
-        XSLFTextParagraph p = sh.addNewTextParagraph();\r
-        XSLFTextRun r1 = p.addNewTextRun();\r
-        r1.setText("Hello,");\r
-        XSLFTextRun r2 = p.addLineBreak();\r
-        assertEquals("\n", r2.getRawText());\r
-        r2.setFontSize(10.0);\r
-        assertEquals(10.0, r2.getFontSize(), 0);\r
-        XSLFTextRun r3 = p.addNewTextRun();\r
-        r3.setText("World!");\r
-        r3.setFontSize(20.0);\r
-        XSLFTextRun r4 = p.addLineBreak();\r
-        assertEquals(20.0, r4.getFontSize(), 0);\r
-\r
-        assertEquals("Hello,\nWorld!\n",sh.getText());\r
-\r
         try {\r
+            XSLFSlide slide = ppt.createSlide();\r
+            XSLFTextShape sh = slide.createAutoShape();\r
+    \r
+            XSLFTextParagraph p = sh.addNewTextParagraph();\r
+            XSLFTextRun r1 = p.addNewTextRun();\r
+            r1.setText("Hello,");\r
+            XSLFTextRun r2 = p.addLineBreak();\r
+            assertEquals("\n", r2.getRawText());\r
+            r2.setFontSize(10.0);\r
+            assertEquals(10.0, r2.getFontSize(), 0);\r
+            XSLFTextRun r3 = p.addNewTextRun();\r
+            r3.setText("World!");\r
+            r3.setFontSize(20.0);\r
+            XSLFTextRun r4 = p.addLineBreak();\r
+            assertEquals(20.0, r4.getFontSize(), 0);\r
+    \r
+            assertEquals("Hello,\nWorld!\n",sh.getText());\r
+\r
+            // "You cannot change text of a line break, it is always '\\n'"\r
             r2.setText("aaa");\r
-            fail("Expected IllegalStateException");\r
-        } catch (IllegalStateException e){\r
-            assertEquals("You cannot change text of a line break, it is always '\\n'", e.getMessage());\r
+        } finally {\r
+            ppt.close();\r
         }\r
     }\r
 }\r
index eb7553ecc45fe9fdbc7de8e36bc368094c520b8b..a3d2c50e889704cd6198e1a2c1ef4e59bb2af5c6 100644 (file)
  */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import junit.framework.TestCase;\r
+import static org.apache.poi.sl.TestCommonSL.sameColor;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertTrue;\r
 \r
-import java.awt.*;\r
+import java.awt.Color;\r
+import java.io.IOException;\r
+\r
+import org.junit.Test;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
  */\r
-public class TestXSLFTextRun extends TestCase {\r
+public class TestXSLFTextRun {\r
 \r
-    public void testRunProperties(){\r
+    @Test\r
+    public void testRunProperties() throws IOException {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
         XSLFTextShape sh = slide.createAutoShape();\r
@@ -35,26 +42,26 @@ public class TestXSLFTextRun extends TestCase {
         XSLFTextRun r = sh.addNewTextParagraph().addNewTextRun();\r
         assertEquals("en-US", r.getRPr().getLang());\r
 \r
-        assertEquals(0., r.getCharacterSpacing());\r
+        assertEquals(0., r.getCharacterSpacing(), 0);\r
         r.setCharacterSpacing(3);\r
-        assertEquals(3., r.getCharacterSpacing());\r
+        assertEquals(3., r.getCharacterSpacing(), 0);\r
         r.setCharacterSpacing(-3);\r
-        assertEquals(-3., r.getCharacterSpacing());\r
+        assertEquals(-3., r.getCharacterSpacing(), 0);\r
         r.setCharacterSpacing(0);\r
-        assertEquals(0., r.getCharacterSpacing());\r
+        assertEquals(0., r.getCharacterSpacing(), 0);\r
         assertFalse(r.getRPr().isSetSpc());\r
 \r
-        assertEquals(Color.black, r.getFontColor());\r
+        assertTrue(sameColor(Color.black, r.getFontColor()));\r
         r.setFontColor(Color.red);\r
-        assertEquals(Color.red, r.getFontColor());\r
+        assertTrue(sameColor(Color.red, r.getFontColor()));\r
 \r
         assertEquals("Calibri", r.getFontFamily());\r
         r.setFontFamily("Arial");\r
         assertEquals("Arial", r.getFontFamily());\r
 \r
-        assertEquals(18.0, r.getFontSize());\r
+        assertEquals(18.0, r.getFontSize(), 0);\r
         r.setFontSize(13.0);\r
-        assertEquals(13.0, r.getFontSize());\r
+        assertEquals(13.0, r.getFontSize(), 0);\r
 \r
         assertEquals(false, r.isSuperscript());\r
         r.setSuperscript(true);\r
@@ -67,5 +74,7 @@ public class TestXSLFTextRun extends TestCase {
         assertEquals(true, r.isSubscript());\r
         r.setSubscript(false);\r
         assertEquals(false, r.isSubscript());\r
+        \r
+        ppt.close();\r
     }\r
 }\r
index de0d1a36a43c46c1540e795608ec7c0e31e5d550..e0c4f9dd96305af6cf29dbef3814f2affff162cd 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import static org.junit.Assert.*;\r
+import static org.apache.poi.sl.TestCommonSL.sameColor;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.assertSame;\r
+import static org.junit.Assert.assertTrue;\r
 \r
 import java.awt.Color;\r
+import java.io.IOException;\r
 import java.util.List;\r
 \r
 import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;\r
 import org.apache.poi.sl.usermodel.VerticalAlignment;\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
 import org.junit.Test;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;\r
 \r
@@ -82,7 +92,7 @@ public class TestXSLFTextShape {
         XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals("Calibri", r1.getFontFamily());\r
         assertEquals(44.0, r1.getFontSize(), 0);\r
-        assertEquals(Color.black, r1.getFontColor());\r
+        assertTrue(sameColor(Color.black, r1.getFontColor()));\r
 \r
         XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);\r
         CTPlaceholder ph2 = shape2.getCTPlaceholder();\r
@@ -151,7 +161,7 @@ public class TestXSLFTextShape {
         XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);\r
         assertEquals("Calibri", r1.getFontFamily());\r
         assertEquals(44.0, r1.getFontSize(), 0);\r
-        assertEquals(Color.black, r1.getFontColor());\r
+        assertTrue(sameColor(Color.black, r1.getFontColor()));\r
 \r
         XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);\r
         CTPlaceholder ph2 = shape2.getCTPlaceholder();\r
@@ -262,7 +272,7 @@ public class TestXSLFTextShape {
         assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign());\r
         assertEquals("Calibri", r1.getFontFamily());\r
         assertEquals(40.0, r1.getFontSize(), 0);\r
-        assertEquals(Color.black, r1.getFontColor());\r
+        assertTrue(sameColor(Color.black, r1.getFontColor()));\r
         assertTrue(r1.isBold());\r
         assertFalse(r1.isItalic());\r
         assertFalse(r1.isUnderlined());\r
@@ -336,7 +346,7 @@ public class TestXSLFTextShape {
         assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());\r
         assertEquals("Calibri", r1.getFontFamily());\r
         assertEquals(44.0, r1.getFontSize(), 0);\r
-        assertEquals(Color.black, r1.getFontColor());\r
+        assertTrue(sameColor(Color.black, r1.getFontColor()));\r
 \r
         XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);\r
         CTPlaceholder ph2 = shape2.getCTPlaceholder();\r
@@ -404,7 +414,7 @@ public class TestXSLFTextShape {
         assertEquals(0, pr5.getParentParagraph().getIndentLevel());\r
         assertEquals("Right", pr5.getRawText());\r
         assertEquals("Calibri", pr5.getFontFamily());\r
-        assertEquals(Color.black, pr5.getFontColor());\r
+        assertTrue(sameColor(Color.black, pr5.getFontColor()));\r
     }\r
 \r
     @SuppressWarnings("unused")\r
@@ -444,7 +454,7 @@ public class TestXSLFTextShape {
         assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());\r
         assertEquals("Calibri", r1.getFontFamily());\r
         assertEquals(44.0, r1.getFontSize(), 0);\r
-        assertEquals(Color.black, r1.getFontColor());\r
+        assertTrue(sameColor(Color.black, r1.getFontColor()));\r
         assertFalse(r1.isBold());\r
 \r
         XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);\r
@@ -517,7 +527,7 @@ public class TestXSLFTextShape {
         assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign());\r
         assertEquals("Calibri", r1.getFontFamily());\r
         assertEquals(20.0, r1.getFontSize(), 0);\r
-        assertEquals(Color.black, r1.getFontColor());\r
+        assertTrue(sameColor(Color.black, r1.getFontColor()));\r
         assertTrue(r1.isBold());\r
 \r
         XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);\r
@@ -605,7 +615,7 @@ public class TestXSLFTextShape {
         assertEquals("Calibri", r1.getFontFamily());\r
         assertEquals(12.0, r1.getFontSize(), 0);\r
         // TODO calculation of tint is incorrect\r
-        assertEquals(new Color(64,64,64), r1.getFontColor());\r
+        assertTrue(sameColor(new Color(64,64,64), r1.getFontColor()));\r
 \r
         XSLFTextShape dt = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_DT);\r
         assertEquals("Friday, October 21, 2011", dt.getText());\r
@@ -615,7 +625,7 @@ public class TestXSLFTextShape {
     }\r
 \r
     @Test\r
-    public void testTitleStyles(){\r
+    public void testTitleStyles() throws IOException {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
 \r
         XSLFSlideMaster master = ppt.getSlideMasters().get(0);\r
@@ -693,10 +703,12 @@ public class TestXSLFTextShape {
         assertEquals("Calibri", textRun.getFontFamily());\r
         lv5PPr.setAlgn(STTextAlignType.CTR);\r
         assertEquals(TextAlign.CENTER, paragraph.getTextAlign());\r
+        \r
+        ppt.close();\r
     }\r
 \r
     @Test\r
-    public void testBodyStyles(){\r
+    public void testBodyStyles() throws IOException {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
 \r
         XSLFSlideMaster master = ppt.getSlideMasters().get(0);\r
@@ -895,7 +907,7 @@ public class TestXSLFTextShape {
         assertEquals("Calibri", r3.getFontFamily());\r
         lv3PPr.setAlgn(STTextAlignType.CTR);\r
         assertEquals(TextAlign.CENTER, p3.getTextAlign());\r
-\r
+        \r
+        ppt.close();\r
     }\r
-\r
 }
\ No newline at end of file
index f928124c42ff525090e0c92ee150e7d5b77fc646..ee95e771d4ce21fe6c1f7fabf7e4a44d08ff731d 100644 (file)
@@ -16,6 +16,7 @@
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
+import static org.apache.poi.sl.TestCommonSL.sameColor;\r
 import static org.junit.Assert.*;\r
 \r
 import java.awt.Color;\r
@@ -66,7 +67,7 @@ public class TestXSLFTheme {
 \r
         XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 3");\r
         XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);\r
-        assertEquals(Color.white, run1.getFontColor());\r
+        assertTrue(sameColor(Color.white, run1.getFontColor()));\r
         assertEquals(new Color(79, 129, 189), sh1.getFillColor());\r
         assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ;   // solid fill\r
 \r
@@ -89,13 +90,13 @@ public class TestXSLFTheme {
 \r
         XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Rectangle 4");\r
         XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);\r
-        assertEquals(Color.white, run1.getFontColor());\r
+        assertTrue(sameColor(Color.white, run1.getFontColor()));\r
         assertEquals(new Color(148, 198, 0), sh1.getFillColor());\r
         assertTrue(sh1.getFillStyle().getPaint() instanceof SolidPaint) ;   // solid fill\r
 \r
         XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 3");\r
         XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);\r
-        assertEquals(new Color(148, 198, 0), run2.getFontColor());\r
+        assertTrue(sameColor(new Color(148, 198, 0), run2.getFontColor()));\r
         assertNull(sh2.getFillColor());  // no fill\r
 \r
         assertTrue(slide.getSlideLayout().getFollowMasterGraphics());\r
@@ -107,7 +108,7 @@ public class TestXSLFTheme {
 \r
         XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 1");\r
         XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);\r
-        assertEquals(new Color(148, 198, 0), run2.getFontColor());\r
+        assertTrue(sameColor(new Color(148, 198, 0), run2.getFontColor()));\r
         assertNull(sh2.getFillColor());  // no fill\r
         // font size is 40pt and scale factor is 90%\r
         assertEquals(36.0, run2.getFontSize(), 0);\r
@@ -119,12 +120,12 @@ public class TestXSLFTheme {
 \r
         XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Subtitle 3");\r
         XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);\r
-        assertEquals(new Color(66, 66, 66), run1.getFontColor());\r
+        assertTrue(sameColor(new Color(66, 66, 66), run1.getFontColor()));\r
         assertNull(sh1.getFillColor());  // no fill\r
 \r
         XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Title 2");\r
         XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);\r
-        assertEquals(new Color(148, 198, 0), run2.getFontColor());\r
+        assertTrue(sameColor(new Color(148, 198, 0), run2.getFontColor()));\r
         assertNull(sh2.getFillColor());  // no fill\r
 \r
         assertFalse(slide.getSlideLayout().getFollowMasterGraphics());\r
@@ -154,12 +155,12 @@ public class TestXSLFTheme {
 \r
         XSLFTextShape sh1 = (XSLFTextShape)getShape(slide, "Title 3");\r
         XSLFTextRun run1 = sh1.getTextParagraphs().get(0).getTextRuns().get(0);\r
-        assertEquals(Color.white, run1.getFontColor());\r
+        assertTrue(sameColor(Color.white, run1.getFontColor()));\r
         assertNull(sh1.getFillColor());  // no fill\r
 \r
         XSLFTextShape sh2 = (XSLFTextShape)getShape(slide, "Subtitle 4");\r
         XSLFTextRun run2 = sh2.getTextParagraphs().get(0).getTextRuns().get(0);\r
-        assertEquals(Color.white, run2.getFontColor());\r
+        assertTrue(sameColor(Color.white, run2.getFontColor()));\r
         assertNull(sh2.getFillColor());  // no fill\r
     }\r
 }\r
index 67b12be8b46814935bfc602619a7ef4f55e216d6..c71395980b380873b81910ef84aff12c13adb7d2 100644 (file)
 
 package org.apache.poi.hslf.model;
 
-import org.apache.poi.ddf.*;
-import org.apache.poi.hslf.usermodel.*;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.hslf.usermodel.HSLFGroupShape;
+import org.apache.poi.hslf.usermodel.HSLFShape;
+import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
+import org.apache.poi.hslf.usermodel.HSLFTextShape;
 import org.apache.poi.sl.usermodel.ShapeContainer;
 import org.apache.poi.sl.usermodel.ShapeType;
 
@@ -27,7 +33,7 @@ import org.apache.poi.sl.usermodel.ShapeType;
  *
  *  @author Yegor Kozlov
  */
-public final class Line extends HSLFSimpleShape {
+public final class Line extends HSLFTextShape implements org.apache.poi.sl.usermodel.Line<HSLFTextParagraph> {
     public Line(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
         super(escherRecord, parent);
     }
@@ -64,23 +70,23 @@ public final class Line extends HSLFSimpleShape {
         return _escherContainer;
     }
     
-    /**
-     * Sets the orientation of the line, if inverse is false, then line goes
-     * from top-left to bottom-right, otherwise use inverse equals true 
-     *
-     * @param inverse the orientation of the line
-     */
-    public void setInverse(boolean inverse) {
-        setShapeType(inverse ? ShapeType.LINE_INV : ShapeType.LINE);
-    }
-    
-    /**
-     * Gets the orientation of the line, if inverse is false, then line goes
-     * from top-left to bottom-right, otherwise inverse equals true 
-     *
-     * @return inverse the orientation of the line
-     */
-    public boolean isInverse() {
-        return (getShapeType() == ShapeType.LINE_INV);
-    }
+//    /**
+//     * Sets the orientation of the line, if inverse is false, then line goes
+//     * from top-left to bottom-right, otherwise use inverse equals true 
+//     *
+//     * @param inverse the orientation of the line
+//     */
+//    public void setInverse(boolean inverse) {
+//        setShapeType(inverse ? ShapeType.LINE_INV : ShapeType.LINE);
+//    }
+//    
+//    /**
+//     * Gets the orientation of the line, if inverse is false, then line goes
+//     * from top-left to bottom-right, otherwise inverse equals true 
+//     *
+//     * @return inverse the orientation of the line
+//     */
+//    public boolean isInverse() {
+//        return (getShapeType() == ShapeType.LINE_INV);
+//    }
 }
index 3b22227b99a321db6528ed48fbcf739d57419ec5..02cb9154fa8ebeafe429ac72be670c4b9e02ef05 100644 (file)
 package org.apache.poi.hslf.model;
 
 
-import java.awt.*;
-import java.awt.font.*;
-import java.awt.geom.*;
-import java.awt.image.*;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Paint;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.Toolkit;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.TextLayout;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ImageObserver;
+import java.awt.image.RenderedImage;
 import java.awt.image.renderable.RenderableImage;
 import java.text.AttributedCharacterIterator;
 import java.util.Map;
 
 import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.hslf.usermodel.*;
+import org.apache.poi.hslf.usermodel.HSLFFreeformShape;
+import org.apache.poi.hslf.usermodel.HSLFGroupShape;
+import org.apache.poi.hslf.usermodel.HSLFSimpleShape;
+import org.apache.poi.hslf.usermodel.HSLFTextBox;
+import org.apache.poi.hslf.usermodel.HSLFTextRun;
+import org.apache.poi.sl.draw.DrawPaint;
 import org.apache.poi.sl.usermodel.StrokeStyle;
 import org.apache.poi.sl.usermodel.VerticalAlignment;
-import org.apache.poi.ss.usermodel.HorizontalAlignment;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 
@@ -259,7 +289,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable {
         rt.setFontSize((double)_font.getSize());
         rt.setFontFamily(_font.getFamily());
 
-        if (getColor() != null) rt.setFontColor(getColor());
+        if (getColor() != null) rt.setFontColor(DrawPaint.createSolidPaint(getColor()));
         if (_font.isBold()) rt.setBold(true);
         if (_font.isItalic()) rt.setItalic(true);
 
index 77cb18e21efb561dbefe45f21eb566bcf4cb3655..e0b056714705ad3f9f2f772cc8f7fd1b3203adf1 100644 (file)
@@ -22,10 +22,16 @@ import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.List;
 
-import org.apache.poi.ddf.*;
+import org.apache.poi.ddf.EscherBSERecord;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherSimpleProperty;
 import org.apache.poi.hslf.record.Document;
-import org.apache.poi.sl.usermodel.*;
-import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+import org.apache.poi.sl.draw.DrawPaint;
+import org.apache.poi.sl.usermodel.FillStyle;
+import org.apache.poi.sl.usermodel.PaintStyle;
 import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -113,20 +119,8 @@ public final class HSLFFill {
         return new FillStyle() {
             public PaintStyle getPaint() {
                 switch (getFillType()) {
-                    case FILL_SOLID: {
-                        return new SolidPaint() {
-                            public ColorStyle getSolidColor() {
-                                return new ColorStyle() {
-                                    public Color getColor() { return getForegroundColor(); }
-                                    public int getAlpha() { return -1; }
-                                    public int getLumOff() { return -1; }
-                                    public int getLumMod() { return -1; }
-                                    public int getShade()  { return -1; }
-                                    public int getTint()  { return -1; }
-                                };
-                            }
-                        };
-                    }
+                    case FILL_SOLID:
+                        return DrawPaint.createSolidPaint(getForegroundColor());
                     case FILL_PICTURE: {
                         final HSLFPictureData pd = getPictureData();
                         if (pd == null) break;
@@ -149,7 +143,7 @@ public final class HSLFFill {
                         logger.log(POILogger.WARN, "unsuported fill type: " + getFillType());
                         break;
                 }
-                return PaintStyle.TRANSPARENT_PAINT;
+                return null;
             }
         };
     }
index 8feee2312bdfb4aa6cb930a7192576b3ef1a1287..bbffdc5e1b177244bbdbbf57ad7eedafcff64090 100644 (file)
@@ -188,16 +188,14 @@ public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFSl
        // Complex Accesser methods follow
 
        /**
-        * Return title of this slide or <code>null</code> if the slide does not have title.
         * <p>
         * The title is a run of text of type <code>TextHeaderAtom.CENTER_TITLE_TYPE</code> or
         * <code>TextHeaderAtom.TITLE_TYPE</code>
         * </p>
         *
         * @see TextHeaderAtom
-        *
-        * @return title of this slide
         */
+       @Override
        public String getTitle(){
                for (List<HSLFTextParagraph> tp : getTextParagraphs()) {
                    if (tp.isEmpty()) continue;
index 9f4d311982ba7ec82d40317d1a14f38fa6baa9c5..86604bf09be499cd1672206ec8ed3e1daf44d040 100644 (file)
@@ -132,6 +132,20 @@ public final class HSLFSlideShow implements SlideShow {
                this(new HSLFSlideShowImpl(inputStream));
        }
 
+    /**
+     * Constructs a Powerpoint document from an POIFSFileSystem.
+     */
+    public HSLFSlideShow(POIFSFileSystem inputStream) throws IOException {
+        this(new HSLFSlideShowImpl(inputStream));
+    }
+
+    /**
+     * Constructs a Powerpoint document from an DirectoryNode.
+     */
+    public HSLFSlideShow(DirectoryNode root) throws IOException {
+        this(new HSLFSlideShowImpl(root));
+    }
+
        /**
         * Use the PersistPtrHolder entries to figure out what is the "most recent"
         * version of all the core records (Document, Notes, Slide etc), and save a
index 0dc8de65f4024341f2e140dad82d50f8416c952e..529d73316395ad38d553645355f4bfd885ed5ef5 100644 (file)
@@ -27,7 +27,10 @@ import org.apache.poi.hslf.model.PPFont;
 import org.apache.poi.hslf.model.textproperties.*;\r
 import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;\r
 import org.apache.poi.hslf.record.*;\r
+import org.apache.poi.sl.draw.DrawPaint;\r
 import org.apache.poi.sl.usermodel.AutoNumberingScheme;\r
+import org.apache.poi.sl.usermodel.PaintStyle;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
 import org.apache.poi.sl.usermodel.TextParagraph;\r
 import org.apache.poi.util.*;\r
 \r
@@ -403,8 +406,24 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
             }\r
 \r
             @Override\r
-            public Color getBulletFontColor() {\r
-                return HSLFTextParagraph.this.getBulletColor();\r
+            public void setBulletFontColor(Color color) {\r
+                setBulletFontColor(DrawPaint.createSolidPaint(color));\r
+            }\r
+            \r
+            @Override\r
+            public void setBulletFontColor(PaintStyle color) {\r
+                if (!(color instanceof SolidPaint)) {\r
+                    throw new IllegalArgumentException("HSLF only supports SolidPaint");\r
+                }\r
+                SolidPaint sp = (SolidPaint)color;\r
+                Color col = DrawPaint.applyColorTransform(sp.getSolidColor());\r
+                HSLFTextParagraph.this.setBulletColor(col);\r
+            }\r
+            \r
+            @Override\r
+            public PaintStyle getBulletFontColor() {\r
+                Color col = HSLFTextParagraph.this.getBulletColor();\r
+                return DrawPaint.createSolidPaint(col);\r
             }\r
 \r
             @Override\r
@@ -497,7 +516,9 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
         TextProp tp = getPropVal(_paragraphStyle, "bullet.color", this);\r
         if (tp == null) {\r
             // if bullet color is undefined, return color of first run\r
-            return (_runs.isEmpty()) ? null : _runs.get(0).getFontColor();\r
+            if (_runs.isEmpty()) return null;\r
+            SolidPaint sp = _runs.get(0).getFontColor();\r
+            return DrawPaint.applyColorTransform(sp.getSolidColor());\r
         }\r
 \r
         return getColorFromColorIndexStruct(tp.getValue(), _sheet);\r
index 08565e3da65ec27c70685a75b416b78109edea16..fbb908c1c70136cb52758bb50fe8a5e8f1e88d18 100644 (file)
@@ -21,8 +21,14 @@ import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.getPropVal;
 
 import java.awt.Color;
 
-import org.apache.poi.hslf.model.textproperties.*;
+import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
+import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
+import org.apache.poi.hslf.model.textproperties.TextProp;
+import org.apache.poi.hslf.model.textproperties.TextPropCollection;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
+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.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -315,13 +321,15 @@ public final class HSLFTextRun implements TextRun {
        }
 
        /**
-        * @return font color as RGB value
-        * @see java.awt.Color
+        * @return font color as PaintStyle
         */
-       public Color getFontColor() {
+       @Override
+       public SolidPaint getFontColor() {
                TextProp tp = getPropVal(characterStyle, "font.color", parentParagraph);
-               return (tp == null) ? null
-               : HSLFTextParagraph.getColorFromColorIndexStruct(tp.getValue(), parentParagraph.getSheet());
+               if (tp == null) return null;
+               Color color = HSLFTextParagraph.getColorFromColorIndexStruct(tp.getValue(), parentParagraph.getSheet());
+               SolidPaint ps = DrawPaint.createSolidPaint(color);
+               return ps;
        }
 
        /**
@@ -334,12 +342,21 @@ public final class HSLFTextRun implements TextRun {
                setCharTextPropVal("font.color", bgr);
        }
 
-       /**
-        * Sets color of the text, as a java.awt.Color
-        */
-       public void setFontColor(Color color) {
+
+    @Override
+    public void setFontColor(Color color) {
+        setFontColor(DrawPaint.createSolidPaint(color));
+    }
+       
+       @Override
+       public void setFontColor(PaintStyle color) {
+           if (!(color instanceof SolidPaint)) {
+               throw new IllegalArgumentException("HSLF only supports solid paint");
+           }
                // In PowerPont RGB bytes are swapped, as BGR
-               int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 254).getRGB();
+           SolidPaint sp = (SolidPaint)color;
+           Color c = DrawPaint.applyColorTransform(sp.getSolidColor());
+               int rgb = new Color(c.getBlue(), c.getGreen(), c.getRed(), 254).getRGB();
                setFontColor(rgb);
        }
 
index ed9ca3819d0b7de81d01fb9d8b40bb42c9f2149a..8141650fe75bc745988c377c532c6fc7a8a261cd 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hslf.model;
 
+import static org.apache.poi.sl.TestCommonSL.sameColor;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -53,9 +54,9 @@ import org.apache.poi.hslf.usermodel.HSLFTextBox;
 import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
 import org.apache.poi.hslf.usermodel.HSLFTextRun;
 import org.apache.poi.hslf.usermodel.HSLFTextShape;
+import org.apache.poi.sl.usermodel.PictureData.PictureType;
 import org.apache.poi.sl.usermodel.ShapeType;
 import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
-import org.apache.poi.sl.usermodel.PictureData.PictureType;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -189,16 +190,16 @@ public final class TestShapes {
         List<HSLFTextParagraph> para = tb.getTextParagraphs();
         HSLFTextRun tr = para.get(0).getTextRuns().get(0);
         assertEquals("para 1 run 1. ", tr.getRawText());
-        assertEquals(Color.black, tr.getFontColor());
+        assertTrue(sameColor(Color.black, tr.getFontColor()));
         tr = para.get(0).getTextRuns().get(1);
         assertEquals("para 1 run 2.\r",  tr.getRawText());
-        assertEquals(Color.red, tr.getFontColor());
+        assertTrue(sameColor(Color.red, tr.getFontColor()));
         tr = para.get(1).getTextRuns().get(0);
         assertEquals("para 2 run 1. ", tr.getRawText());
-        assertEquals(Color.yellow, tr.getFontColor());
+        assertTrue(sameColor(Color.yellow, tr.getFontColor()));
         tr = para.get(1).getTextRuns().get(1);
         assertEquals("para 2 run 2. para 2 run 3.", tr.getRawText());
-        assertEquals(Color.black, tr.getFontColor());
+        assertTrue(sameColor(Color.black, tr.getFontColor()));
         assertTrue(tr.isStrikethrough());
     }
         
@@ -235,7 +236,7 @@ public final class TestShapes {
         assertTrue(rt.isItalic());
         assertFalse(rt.isUnderlined());
         assertEquals("Arial", rt.getFontFamily());
-        assertEquals(Color.red, rt.getFontColor());
+        assertTrue(sameColor(Color.red, rt.getFontColor()));
 
         // Serialize and read again
         ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -255,7 +256,7 @@ public final class TestShapes {
         assertTrue(rt.isItalic());
         assertFalse(rt.isUnderlined());
         assertEquals("Arial", rt.getFontFamily());
-        assertEquals(Color.red, rt.getFontColor());
+        assertTrue(sameColor(Color.red, rt.getFontColor()));
     }
 
     /**
index aa0c307f936c34e9da7c9bb80be289ace677b643..1cbf238de690e367b47c70b98cf3731319a236b6 100644 (file)
 
 package org.apache.poi.hslf.usermodel;
 
-import static org.junit.Assert.*;
+import static org.apache.poi.sl.TestCommonSL.sameColor;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 
 import java.awt.Color;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.util.List;
 
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection;
-import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.record.TextBytesAtom;
+import org.apache.poi.hslf.record.TextCharsAtom;
+import org.apache.poi.hslf.record.TextHeaderAtom;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -539,7 +550,7 @@ public final class TestTextRun {
                     List<HSLFTextParagraph> run = tx.getTextParagraphs();
                     HSLFTextRun rt = run.get(0).getTextRuns().get(0);
                     assertTrue(rt.isBold());
-                    assertEquals(rt.getFontColor(), Color.RED);
+                    assertTrue(sameColor(Color.RED, rt.getFontColor()));
                 }
             }
         }
diff --git a/src/testcases/org/apache/poi/sl/TestCommonSL.java b/src/testcases/org/apache/poi/sl/TestCommonSL.java
new file mode 100644 (file)
index 0000000..ab27ca4
--- /dev/null
@@ -0,0 +1,38 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.sl;\r
+\r
+import java.awt.Color;\r
+\r
+import org.apache.poi.sl.draw.DrawPaint;\r
+import org.apache.poi.sl.usermodel.PaintStyle;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
+import org.junit.Ignore;\r
+\r
+/**\r
+ * Currently only contains helper methods\r
+ */\r
+@Ignore\r
+public class TestCommonSL {\r
+\r
+    public static boolean sameColor(Color colorExpected, PaintStyle paintActual) {\r
+        if (!(paintActual instanceof SolidPaint)) return false;\r
+        Color thisC = DrawPaint.applyColorTransform(((SolidPaint)paintActual).getSolidColor());\r
+        return thisC.equals(colorExpected);\r
+    }\r
+\r
+}\r
diff --git a/test-data/slideshow/KEY02.pptx b/test-data/slideshow/KEY02.pptx
new file mode 100644 (file)
index 0000000..142c6dd
Binary files /dev/null and b/test-data/slideshow/KEY02.pptx differ
diff --git a/test-data/slideshow/alterman_security.pptx b/test-data/slideshow/alterman_security.pptx
new file mode 100644 (file)
index 0000000..e9869b9
Binary files /dev/null and b/test-data/slideshow/alterman_security.pptx differ
diff --git a/test-data/slideshow/alterman_security2.pptx b/test-data/slideshow/alterman_security2.pptx
deleted file mode 100644 (file)
index 1329228..0000000
Binary files a/test-data/slideshow/alterman_security2.pptx and /dev/null differ