]> source.dussan.org Git - poi.git/commitdiff
more progress with XSLF: made some methods publis as suggested on poi-dev, more tests
authorYegor Kozlov <yegor@apache.org>
Thu, 24 Nov 2011 16:13:42 +0000 (16:13 +0000)
committerYegor Kozlov <yegor@apache.org>
Thu, 24 Nov 2011 16:13:42 +0000 (16:13 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1205902 13f79535-47bb-0310-9956-ffa450edef68

19 files changed:
src/ooxml/java/org/apache/poi/xslf/usermodel/RenderableShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFImageRendener.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.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/XSLFSlideLayout.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.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/usermodel/XSLFTextShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTheme.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
src/resources/ooxml/org/apache/poi/xslf/usermodel/empty.pptx
test-data/slideshow/prProps.pptx [new file with mode: 0644]

index 21ab67124f9f90dff4511081e45e35f9a1363df7..67af3a179c4c3d87598ce2a0025d342a2c1b0472 100644 (file)
@@ -65,6 +65,7 @@ import java.util.ArrayList;
 import java.util.Arrays;\r
 import java.util.Collection;\r
 import java.util.Comparator;\r
+import java.util.List;\r
 \r
 /**\r
  * Encapsulates logic to translate DrawingML objects to Java2D\r
@@ -125,6 +126,8 @@ class RenderableShape {
                 CTPathShadeProperties ps = gradFill.getPath();\r
                 if(ps.getPath() ==  STPathShadeType.CIRCLE){\r
                     paint = createRadialGradientPaint(gradFill, anchor, theme, phClr);\r
+                } else if (ps.getPath() ==  STPathShadeType.SHAPE){\r
+                    paint = toRadialGradientPaint(gradFill, anchor, theme, phClr);\r
                 }\r
             }\r
         }\r
@@ -165,7 +168,7 @@ class RenderableShape {
         return paint;\r
     }\r
 \r
-    private static Paint createLinearGradientPaint(\r
+    private Paint createLinearGradientPaint(\r
             Graphics2D graphics,\r
             CTGradientFillProperties gradFill, Rectangle2D anchor,\r
             XSLFTheme theme, CTSchemeColor phClr) {\r
@@ -205,15 +208,16 @@ class RenderableShape {
             fractions[i] = stop.getPos() / 100000.f;\r
         }\r
 \r
-        AffineTransform grAt;\r
-        if(gradFill.getRotWithShape()) grAt = new AffineTransform();\r
-        else {\r
-            // gradient fill is not rotated with the shape\r
-            try {\r
-                grAt = graphics.getTransform().createInverse();\r
-            } catch (Exception e){\r
-                // should not happen.\r
-                grAt = new AffineTransform();\r
+        AffineTransform grAt  = new AffineTransform();\r
+        if(gradFill.isSetRotWithShape() || !gradFill.getRotWithShape()) {\r
+            double rotation = _shape.getRotation();\r
+            if (rotation != 0.) {\r
+                double centerX = anchor.getX() + anchor.getWidth() / 2;\r
+                double centerY = anchor.getY() + anchor.getHeight() / 2;\r
+\r
+                grAt.translate(centerX, centerY);\r
+                grAt.rotate(Math.toRadians(-rotation));\r
+                grAt.translate(-centerX, -centerY);\r
             }\r
         }\r
 \r
@@ -237,6 +241,30 @@ class RenderableShape {
         return paint;\r
     }\r
 \r
+    /**\r
+     * gradients with type=shape are enot supported by Java graphics.\r
+     * We approximate it with a radial gradient.\r
+     */\r
+    private static Paint toRadialGradientPaint(\r
+            CTGradientFillProperties gradFill, Rectangle2D anchor,\r
+            XSLFTheme theme, CTSchemeColor phClr) {\r
+\r
+        CTGradientStop[] gs = gradFill.getGsLst().getGsArray();\r
+        Arrays.sort(gs, new Comparator<CTGradientStop>() {\r
+            public int compare(CTGradientStop o1, CTGradientStop o2) {\r
+                Integer pos1 = o1.getPos();\r
+                Integer pos2 = o2.getPos();\r
+                return pos1.compareTo(pos2);\r
+            }\r
+        });\r
+        gs[1].setPos(50000);\r
+\r
+        CTGradientFillProperties g = CTGradientFillProperties.Factory.newInstance();\r
+        g.set(gradFill);\r
+        g.getGsLst().setGsArray(new CTGradientStop[]{gs[0], gs[1]});\r
+        return createRadialGradientPaint(g, anchor, theme, phClr);\r
+    }\r
+\r
     private static Paint createRadialGradientPaint(\r
             CTGradientFillProperties gradFill, Rectangle2D anchor,\r
             XSLFTheme theme, CTSchemeColor phClr) {\r
@@ -498,7 +526,7 @@ class RenderableShape {
         if(shadow != null) for(Outline o : elems){\r
             if(o.getPath().isFilled()){\r
                 if(fill != null) shadow.fill(graphics, o.getOutline());\r
-                if(line != null) shadow.draw(graphics, o.getOutline());\r
+                else if(line != null) shadow.draw(graphics, o.getOutline());\r
             }\r
         }\r
         // then fill the shape interior\r
index 9de0c7493a4e3186e1a123c4d8c694faf8094c46..9ffcee684bc8bab1bf0bbce5e56131233f8f8e28 100644 (file)
@@ -32,7 +32,9 @@ import org.apache.poi.util.PackageHelper;
 import org.apache.poi.util.Units;
 import org.apache.poi.xslf.XSLFSlideShow;
 import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
 import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPresentation;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdList;
@@ -355,4 +357,15 @@ public class XMLSlideShow  extends POIXMLDocument {
         return _tableStyles;
     }
 
+    CTTextParagraphProperties getDefaultParagraphStyle(int level) {
+        XmlObject[] o = _presentation.selectPath(
+                "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " +
+                "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " +
+                ".//p:defaultTextStyle/a:lvl" +(level+1)+ "pPr");
+        if(o.length == 1){
+            return (CTTextParagraphProperties)o[0];
+        }
+        return null;
+    }
+
 }
index 7d8cb061ef029d01b57e14bba9753c607fbba38f..0c60ec6046875d77705886d2aeb5fa302b0d0150 100644 (file)
@@ -20,7 +20,9 @@ package org.apache.poi.xslf.usermodel;
 import org.apache.xmlbeans.XmlObject;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTBackgroundFillStyleList;\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.CTStyleMatrixReference;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;\r
 \r
 import java.awt.Color;\r
@@ -91,4 +93,15 @@ public class XSLFBackground extends XSLFSimpleShape {
         }\r
         return null;\r
     }\r
+\r
+    /**\r
+     * background does not have a associated transform.\r
+     * we return a dummy transform object to prevent exceptions in inherited methods.\r
+     *\r
+     * @return  dummy  CTTransform2D bean\r
+     */\r
+    @Override\r
+    CTTransform2D getXfrm() {\r
+        return CTTransform2D.Factory.newInstance();\r
+    }\r
 }\r
index a8bbe8b6a25f1b739d5d6d1070d202d422c8bee8..3c3d49bfca0321cb8c52beb8a96e62e34fd929ac 100644 (file)
@@ -24,6 +24,8 @@ import org.apache.poi.util.Beta;
 \r
 import javax.imageio.ImageIO;\r
 import java.awt.Graphics2D;\r
+import java.awt.Image;\r
+import java.awt.geom.AffineTransform;\r
 import java.awt.geom.Rectangle2D;\r
 import java.awt.image.BufferedImage;\r
 import java.io.ByteArrayInputStream;\r
@@ -78,9 +80,19 @@ public class XSLFImageRendener {
                        Rectangle2D anchor) {\r
                try {\r
                        BufferedImage img = ImageIO.read(data.getPackagePart().getInputStream());\r
-            graphics.drawImage(img,\r
-                    (int) anchor.getX(), (int) anchor.getY(),\r
-                    (int) anchor.getWidth(), (int) anchor.getHeight(), null);\r
+            Number groupScale = (Number)graphics.getRenderingHint(XSLFRenderingHint.GROUP_SCALE);\r
+            if(groupScale != null) {\r
+                double sx = anchor.getWidth()/img.getWidth();\r
+                double sy = anchor.getHeight()/img.getHeight();\r
+                double tx = anchor.getX();\r
+                double ty = anchor.getY();\r
+                AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;\r
+                graphics.drawRenderedImage(img, at);\r
+            } else {\r
+                graphics.drawImage(img,\r
+                        (int) anchor.getX(), (int) anchor.getY(),\r
+                        (int) anchor.getWidth(), (int) anchor.getHeight(), null);\r
+            }\r
                        return true;\r
                } catch (Exception e) {\r
                        return false;\r
index 7c2128e8fbd2f129f868feca21d3b879569bc8c1..42dc360cd6f7cfd530095c495f642b13b378d03c 100644 (file)
@@ -44,7 +44,11 @@ public class XSLFShadow extends XSLFSimpleShape {
 \r
     public void fill(Graphics2D graphics, Shape outline) {\r
 \r
-        double angle = getAngle();\r
+        double shapeRotation = _parent.getRotation();\r
+        if(_parent.getFlipVertical()){\r
+            shapeRotation += 180;\r
+        }\r
+        double angle = getAngle() - shapeRotation;\r
         double dist = getDistance();\r
         double dx = dist * Math.cos(Math.toRadians(angle));\r
         double dy = dist * Math.sin(Math.toRadians(angle));\r
index 8a74e2d0f61fd9ed2c2589af63e4375ad749f642..fb8da22e1783c50612ca0e7a914476c82a432223 100644 (file)
@@ -413,6 +413,14 @@ public abstract class XSLFSheet extends POIXMLDocumentPart implements Iterable<X
         return false;
     }
 
+    /**
+     *
+     * @return  background for this sheet
+     */
+    public XSLFBackground getBackground() {
+        return null;
+    }
+
     /**
      * Render this sheet into the supplied graphics object
      *
index 16ecef862372d8dcae76702993c791f06cae9c85..7b4af9d3c2af9d7f86a1def1566753500d7c26f4 100644 (file)
@@ -154,7 +154,7 @@ public abstract class XSLFSimpleShape extends XSLFShape {
         return _ph;\r
     }\r
 \r
-    private CTTransform2D getXfrm() {\r
+    CTTransform2D getXfrm() {\r
         PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {\r
             public boolean fetch(XSLFSimpleShape shape) {\r
                 CTShapeProperties pr = shape.getSpPr();\r
@@ -561,7 +561,7 @@ public abstract class XSLFSimpleShape extends XSLFShape {
      *\r
      * The following order of inheritance is assumed:\r
      * <p>\r
-     * slide <-- slideLayout <-- slideMaster <-- default styles in the slideMaster\r
+     * slide <-- slideLayout <-- slideMaster\r
      * </p>\r
      *\r
      * @param visitor the object that collects the desired property\r
@@ -571,24 +571,21 @@ public abstract class XSLFSimpleShape extends XSLFShape {
         boolean ok = visitor.fetch(this);\r
 \r
         XSLFSimpleShape masterShape;\r
-        XSLFSheet layout = getSheet().getMasterSheet();\r
-        if (layout != null) {\r
+        XSLFSheet masterSheet = getSheet().getMasterSheet();\r
+        CTPlaceholder ph = getCTPlaceholder();\r
+\r
+        if (masterSheet != null && ph != null) {\r
             if (!ok) {\r
-                // first try to fetch from the slide layout\r
-                CTPlaceholder ph = getCTPlaceholder();\r
-                if (ph != null) {\r
-                    masterShape = layout.getPlaceholder(ph);\r
-                    if (masterShape != null) {\r
-                        ok = visitor.fetch(masterShape);\r
-                    }\r
+                masterShape = masterSheet.getPlaceholder(ph);\r
+                if (masterShape != null) {\r
+                    ok = visitor.fetch(masterShape);\r
                 }\r
             }\r
 \r
             // try slide master\r
-            if (!ok) {\r
+            if (!ok ) {\r
                 int textType;\r
-                CTPlaceholder ph = getCTPlaceholder();\r
-                if (ph == null || !ph.isSetType()) textType = STPlaceholderType.INT_BODY;\r
+                if ( !ph.isSetType()) textType = STPlaceholderType.INT_BODY;\r
                 else {\r
                     switch (ph.getType().intValue()) {\r
                         case STPlaceholderType.INT_TITLE:\r
@@ -605,7 +602,7 @@ public abstract class XSLFSimpleShape extends XSLFShape {
                             break;\r
                     }\r
                 }\r
-                XSLFSheet master = layout.getMasterSheet();\r
+                XSLFSheet master = masterSheet.getMasterSheet();\r
                 if (master != null) {\r
                     masterShape = master.getPlaceholderByType(textType);\r
                     if (masterShape != null) {\r
index aee9ef0020a29711e6e1f74f698dd7a35b784d3b..91566cb09a23dc1fdcf8c58e921e4b346682ef81 100644 (file)
@@ -184,23 +184,14 @@ public final class XSLFSlide extends XSLFSheet {
      *
      * @return the information about background appearance of this slide
      */
+    @Override
     public XSLFBackground getBackground() {
-
-
-        if(_slide.getCSld().isSetBg()) {
-            return new XSLFBackground(_slide.getCSld().getBg(), this);
-        }
-
-        XSLFSlideLayout layout = getMasterSheet();
-        if(layout.getXmlObject().getCSld().isSetBg()) {
-            return new XSLFBackground(layout.getXmlObject().getCSld().getBg(), this);
-        }
-
-        XSLFSlideMaster master = layout.getMasterSheet();
-        if(master.getXmlObject().getCSld().isSetBg()) {
-            return new XSLFBackground(master.getXmlObject().getCSld().getBg(), this);
+        CTBackground bg = _slide.getCSld().getBg();
+        if(bg != null) {
+            return new XSLFBackground(bg, this);
+        } else {
+            return getMasterSheet().getBackground();
         }
-        return null;
     }
 
     /**
index 4a505972dc63d99d54bdb80e7f05488b4e72042c..f8cd23ccde588266e2b53db3a6743be47dc98c1b 100644 (file)
@@ -22,6 +22,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.util.Beta;
 import org.apache.poi.util.Internal;
 import org.apache.xmlbeans.XmlException;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideLayout;
 import org.openxmlformats.schemas.presentationml.x2006.main.SldLayoutDocument;
@@ -115,6 +116,17 @@ public class XSLFSlideLayout extends XSLFSheet {
         return true;
     }
 
+
+    @Override
+    public XSLFBackground getBackground() {
+        CTBackground bg = _layout.getCSld().getBg();
+        if(bg != null) {
+            return new XSLFBackground(bg, this);
+        } else {
+            return getMasterSheet().getBackground();
+        }
+    }
+
     /**
      * Copy placeholders from this layout to the destination slide
      *
index e73ee7a4c1902ae929af24a9980e6c7d1cdc4175..d4383c4d9f5058543c347dfce6573c44da290037 100644 (file)
@@ -23,6 +23,7 @@ import org.apache.poi.util.Beta;
 import org.apache.xmlbeans.XmlException;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterTextStyles;
@@ -167,4 +168,14 @@ import java.util.Map;
         return true;
     }
 
+    @Override
+    public XSLFBackground getBackground() {
+        CTBackground bg = _slide.getCSld().getBg();
+        if(bg != null) {
+            return new XSLFBackground(bg, this);
+        } else {
+            return null;
+        }
+    }
+
 }
\ No newline at end of file
index dcca92fbf94078a2922cd8df471fb4e4601274a4..67a5013c8311e5bb6365ee8a328650f9d93746f9 100644 (file)
@@ -570,7 +570,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
 \r
     /**\r
      *\r
-     * @return the text level of this paragraph. Default is 0.\r
+     * @return the text level of this paragraph (0-based). Default is 0.\r
      */\r
     public int getLevel(){\r
         CTTextParagraphProperties pr = _p.getPPr();\r
@@ -823,7 +823,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
 \r
         AttributedString at = getAttributedString(graphics);\r
         AttributedCharacterIterator it = at.getIterator();\r
-        LineBreakMeasurer measurer = new LineBreakMeasurer(it, graphics.getFontRenderContext());\r
+        LineBreakMeasurer measurer = new LineBreakMeasurer(it, graphics.getFontRenderContext())  ;\r
         for (;;) {\r
             int startIndex = measurer.getPosition();\r
 \r
@@ -898,29 +898,27 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
         return _lines;\r
     }\r
 \r
-    CTTextParagraphProperties getDefaultStyle(){\r
+    CTTextParagraphProperties getDefaultMasterStyle(){\r
         CTPlaceholder ph = _shape.getCTPlaceholder();\r
         String defaultStyleSelector;\r
-        if(ph == null) defaultStyleSelector = "otherStyle";\r
-        else {\r
-            switch(ph.getType().intValue()){\r
-                case STPlaceholderType.INT_TITLE:\r
-                case STPlaceholderType.INT_CTR_TITLE:\r
-                    defaultStyleSelector = "titleStyle";\r
-                    break;\r
-                case STPlaceholderType.INT_FTR:\r
-                case STPlaceholderType.INT_SLD_NUM:\r
-                case STPlaceholderType.INT_DT:\r
-                    defaultStyleSelector = "otherStyle";\r
-                    break;\r
-                default:\r
-                    defaultStyleSelector = "bodyStyle";\r
-                    break;\r
-            }\r
+        switch(ph.getType().intValue()){\r
+            case STPlaceholderType.INT_TITLE:\r
+            case STPlaceholderType.INT_CTR_TITLE:\r
+                defaultStyleSelector = "titleStyle";\r
+                break;\r
+            case STPlaceholderType.INT_FTR:\r
+            case STPlaceholderType.INT_SLD_NUM:\r
+            case STPlaceholderType.INT_DT:\r
+                defaultStyleSelector = "otherStyle";\r
+                break;\r
+            default:\r
+                defaultStyleSelector = "bodyStyle";\r
+                break;\r
         }\r
 \r
         int level = getLevel();\r
 \r
+        // wind up and find the root master sheet which must be slide master\r
         XSLFSheet masterSheet = _shape.getSheet();\r
         while (masterSheet.getMasterSheet() != null){\r
             masterSheet = masterSheet.getMasterSheet();\r
@@ -946,9 +944,18 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
         if(!ok) {\r
             XSLFTextShape shape = getParentShape();\r
             ok = shape.fetchShapeProperty(visitor);\r
-            if(!ok) {\r
-                CTTextParagraphProperties defaultProps = getDefaultStyle();\r
-                if(defaultProps != null) ok = visitor.fetch(defaultProps);\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(getLevel());\r
+                    if(themeProps != null) ok = visitor.fetch(themeProps);\r
+                } else {\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
         }\r
 \r
index f67fde8ae1004753b1e19a80bffb0065a0b52b10..cb7e5fc12fc7f67fbd64c238e14f33b6a05fb796 100644 (file)
@@ -30,6 +30,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;\r
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
 \r
 import java.awt.Color;\r
 import java.awt.font.FontRenderContext;\r
@@ -467,11 +468,23 @@ public class XSLFTextRun {
         if(!ok) {\r
             XSLFTextShape shape = _p.getParentShape();\r
             ok = shape.fetchShapeProperty(fetcher);\r
-            if(!ok) {\r
-                CTTextParagraphProperties defaultProps = _p.getDefaultStyle();\r
-                if(defaultProps != null) {\r
-                    fetcher.isFetchingFromMaster = true;\r
-                    ok = fetcher.fetch(defaultProps);\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.getLevel());\r
+                    if(themeProps != null) {\r
+                        fetcher.isFetchingFromMaster = true;\r
+                        ok = fetcher.fetch(themeProps);\r
+                    }\r
+                } else {\r
+                    // defaults for placeholders are defined in the slide master\r
+                    CTTextParagraphProperties defaultProps =  _p.getDefaultMasterStyle();\r
+                    if(defaultProps != null) {\r
+                        fetcher.isFetchingFromMaster = true;\r
+                        ok = fetcher.fetch(defaultProps);\r
+                    }\r
                 }\r
             }\r
         }\r
index 2aabbd2b18fccc34e80fc400e67552ddc8a30730..c54d74e1f4c325f294686b5d8ed2763a5722916e 100644 (file)
@@ -51,6 +51,11 @@ import java.util.List;
 public abstract class XSLFTextShape extends XSLFSimpleShape implements Iterable<XSLFTextParagraph>{
     private final List<XSLFTextParagraph> _paragraphs;
 
+    /**
+     * whether the text was broken into lines.
+     */
+    private boolean _isTextBroken;
+
     /*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) {
         super(shape, sheet);
 
@@ -441,17 +446,23 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements Iterable<
     /**
      * Compute the cumulative height occupied by the text
      */
-    private double getTextHeight(){
+    public double getTextHeight(){
         // dry-run in a 1x1 image and return the vertical advance
         BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
-        return drawParagraphs(img.createGraphics(), 0, 0);
+        Graphics2D graphics = img.createGraphics();
+        breakText(graphics);
+        return drawParagraphs(graphics, 0, 0);
     }
 
     /**
      * break the contained text into lines
     */
     private void breakText(Graphics2D graphics){
-        for(XSLFTextParagraph p : _paragraphs) p.breakText(graphics);
+        if(!_isTextBroken) {
+            for(XSLFTextParagraph p : _paragraphs) p.breakText(graphics);
+
+            _isTextBroken = true;
+        }
     }
 
     @Override
index b996dd5fb4458df46d098d54a13505854dcc1908..41f2109fcde04361261338535471bfda006171f5 100644 (file)
@@ -29,6 +29,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeStyleSheet;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
 import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument;
 
 import javax.xml.namespace.QName;
@@ -150,4 +151,17 @@ public class XSLFTheme extends POIXMLDocumentPart {
     public String getMinorFont(){
         return _theme.getThemeElements().getFontScheme().getMinorFont().getLatin().getTypeface();
     }
+
+
+    CTTextParagraphProperties getDefaultParagraphStyle(){
+        XmlObject[] o = _theme.selectPath(
+                "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " +
+                "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " +
+                ".//a:objectDefaults/a:spDef/a:lstStyle/a:defPPr");
+        if(o.length == 1){
+            return (CTTextParagraphProperties)o[0];
+        }
+        return null;
+    }
+
 }
index 06b5f1b9ab7e98f1d3e165783b97e909d88de7d5..4f921ac05aca8bc4bc73c1279ae9b30ef2ff3979 100644 (file)
@@ -17,6 +17,7 @@
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
@@ -33,5 +34,33 @@ public class TestXSLFTextBox extends TestCase {
         assertEquals(Placeholder.TITLE, shape.getTextType());\r
         shape.setPlaceholder(null);\r
         assertNull(shape.getTextType());\r
+        shape.setText("Apache POI");\r
+    }\r
+\r
+    /**\r
+     * text box inherits default text proeprties from presentation.xml\r
+     */\r
+    public void testDefaultTextStyle() {\r
+        XMLSlideShow ppt = new XMLSlideShow();\r
+        XSLFSlide slide = ppt.createSlide();\r
+\r
+        // default character properties for paragraphs with level=1\r
+        CTTextCharacterProperties pPr = ppt.getCTPresentation().getDefaultTextStyle().getLvl1PPr().getDefRPr();\r
+\r
+        XSLFTextBox shape = slide.createTextBox();\r
+        shape.setText("Apache POI");\r
+        assertEquals(1, shape.getTextParagraphs().size());\r
+        assertEquals(1, shape.getTextParagraphs().get(0).getTextRuns().size());\r
+\r
+        XSLFTextRun r = shape.getTextParagraphs().get(0).getTextRuns().get(0);\r
+\r
+        assertEquals(1800, pPr.getSz());\r
+        assertEquals(18.0, r.getFontSize());\r
+        assertEquals("Calibri", r.getFontFamily());\r
+\r
+        pPr.setSz(900);\r
+        pPr.getLatin().setTypeface("Arial");\r
+        assertEquals(9.0, r.getFontSize());\r
+        assertEquals("Arial", r.getFontFamily());\r
     }\r
 }
\ No newline at end of file
index 2974dd69fe728477590a67c44717232badc95ce3..62d3c52397a246e5be9623e05e2033e9c5bebad2 100755 (executable)
@@ -3,6 +3,7 @@ package org.apache.poi.xslf.usermodel;
 import junit.framework.TestCase;\r
 import org.apache.poi.util.POILogFactory;\r
 import org.apache.poi.util.POILogger;\r
+import org.apache.poi.xslf.XSLFTestDataSamples;\r
 \r
 import java.awt.*;\r
 import java.awt.geom.Rectangle2D;\r
@@ -105,22 +106,13 @@ public class TestXSLFTextParagraph extends TestCase {
 \r
     /**\r
      * test breaking test into lines.\r
-     * This test is platform-dependent and will run only if the test fonr (Arial)\r
-     * is present in local graphics environment\r
+     * This test requires that the Arial font is available and will run only on windows\r
      */\r
     public void testBreakLines(){\r
-        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();\r
-        String testFont = "Arial";\r
-        boolean testFontAvailable = false;\r
-        for(String family : env.getAvailableFontFamilyNames()) {\r
-            if(family.equals(testFont)) {\r
-                testFontAvailable = true;\r
-                break;\r
-            }\r
-        }\r
-\r
-        if(!testFontAvailable) {\r
-            _logger.log(POILogger.WARN, "the Arial font family is not available in local graphics environment");\r
+        String os = System.getProperty("os.name");\r
+        if(os == null || !os.contains("Windows")) {\r
+            _logger.log(POILogger.WARN, "Skipping testBreakLines(), it is executed only on Windows machines");\r
+            return;\r
         }\r
 \r
         XMLSlideShow ppt = new XMLSlideShow();\r
@@ -198,4 +190,20 @@ public class TestXSLFTextParagraph extends TestCase {
         assertTrue(lines.get(0).getHeight() > lines.get(1).getHeight()*2);\r
 \r
     }\r
+\r
+    public void testThemeInheritance(){\r
+        XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("prProps.pptx");\r
+        XSLFShape[] shapes = ppt.getSlides()[0].getShapes();\r
+        XSLFTextShape sh1 = (XSLFTextShape)shapes[0];\r
+        assertEquals("Apache", sh1.getText());\r
+        assertEquals(TextAlign.CENTER, sh1.getTextParagraphs().get(0).getTextAlign());\r
+        XSLFTextShape sh2 = (XSLFTextShape)shapes[1];\r
+        assertEquals("Software", sh2.getText());\r
+        assertEquals(TextAlign.CENTER, sh2.getTextParagraphs().get(0).getTextAlign());\r
+        XSLFTextShape sh3 = (XSLFTextShape)shapes[2];\r
+        assertEquals("Foundation", sh3.getText());\r
+        assertEquals(TextAlign.CENTER, sh3.getTextParagraphs().get(0).getTextAlign());\r
+\r
+\r
+    }\r
 }\r
index 07e64de1eb6337bb772526b53269d907e305b3da..79063a3083272560a417e32624e5905c59708226 100644 (file)
@@ -19,6 +19,9 @@ package org.apache.poi.xslf.usermodel;
 import junit.framework.TestCase;\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\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
@@ -606,4 +609,288 @@ public class TestXSLFTextShape extends TestCase {
         XSLFTextShape sldNum = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_SLD_NUM);\r
         assertEquals("10", sldNum.getText());\r
     }\r
+\r
+\r
+    public void testTitleStyles(){\r
+        XMLSlideShow ppt = new XMLSlideShow();\r
+\r
+        XSLFSlideMaster master = ppt.getSlideMasters()[0];\r
+        XSLFTheme theme = master.getTheme();\r
+        XSLFSlideLayout layout = master.getLayout(SlideLayout.TITLE);\r
+        XSLFSlide slide = ppt.createSlide(layout) ;\r
+        assertSame(layout, slide.getSlideLayout());\r
+        assertSame(master, slide.getSlideMaster());\r
+\r
+        XSLFTextShape titleShape = (XSLFTextShape)slide.getPlaceholder(0);\r
+        titleShape.setText("Apache POI");\r
+        XSLFTextParagraph paragraph = titleShape.getTextParagraphs().get(0);\r
+        XSLFTextRun textRun = paragraph.getTextRuns().get(0);\r
+\r
+        // level 1 : default title style on the master slide\r
+        // /p:sldMaster/p:txStyles/p:titleStyle/a:lvl1pPr\r
+        CTTextParagraphProperties lv1PPr = master.getXmlObject().getTxStyles().getTitleStyle().getLvl1PPr();\r
+        CTTextCharacterProperties lv1CPr = lv1PPr.getDefRPr();\r
+        assertEquals(4400, lv1CPr.getSz());\r
+        assertEquals(44.0, textRun.getFontSize());\r
+        assertEquals("+mj-lt", lv1CPr.getLatin().getTypeface());\r
+        assertEquals("Calibri", theme.getMajorFont());\r
+        assertEquals("Calibri", textRun.getFontFamily());\r
+        lv1CPr.setSz(3200);\r
+        assertEquals(32.0, textRun.getFontSize());\r
+        lv1CPr.getLatin().setTypeface("Arial");\r
+        assertEquals("Arial", textRun.getFontFamily());\r
+        assertEquals(STTextAlignType.CTR, lv1PPr.getAlgn());\r
+        assertEquals(TextAlign.CENTER, paragraph.getTextAlign());\r
+        lv1PPr.setAlgn(STTextAlignType.L);\r
+        assertEquals(TextAlign.LEFT, paragraph.getTextAlign());\r
+\r
+        // level 2: title placeholder on the master slide\r
+        // /p:sldMaster/p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="title"]\r
+        XSLFTextShape tx2 = master.getPlaceholder(0);\r
+        CTTextParagraphProperties lv2PPr = tx2.getTextBody(true).getLstStyle().addNewLvl1PPr();\r
+        CTTextCharacterProperties lv2CPr = lv2PPr.addNewDefRPr();\r
+        lv2CPr.setSz(3300);\r
+        assertEquals(33.0, textRun.getFontSize());\r
+        lv2CPr.addNewLatin().setTypeface("Times");\r
+        assertEquals("Times", textRun.getFontFamily());\r
+        lv2PPr.setAlgn(STTextAlignType.R);\r
+        assertEquals(TextAlign.RIGHT, paragraph.getTextAlign());\r
+\r
+\r
+        // level 3: title placeholder on the slide layout\r
+        // /p:sldLayout /p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="ctrTitle"]\r
+        XSLFTextShape tx3 = layout.getPlaceholder(0);\r
+        CTTextParagraphProperties lv3PPr = tx3.getTextBody(true).getLstStyle().addNewLvl1PPr();\r
+        CTTextCharacterProperties lv3CPr = lv3PPr.addNewDefRPr();\r
+        lv3CPr.setSz(3400);\r
+        assertEquals(34.0, textRun.getFontSize());\r
+        lv3CPr.addNewLatin().setTypeface("Courier New");\r
+        assertEquals("Courier New", textRun.getFontFamily());\r
+        lv3PPr.setAlgn(STTextAlignType.CTR);\r
+        assertEquals(TextAlign.CENTER, paragraph.getTextAlign());\r
+\r
+        // level 4: default text properties in the shape itself\r
+        // ./p:sp/p:txBody/a:lstStyle/a:lvl1pPr\r
+        CTTextParagraphProperties lv4PPr = titleShape.getTextBody(true).getLstStyle().addNewLvl1PPr();\r
+        CTTextCharacterProperties lv4CPr = lv4PPr.addNewDefRPr();\r
+        lv4CPr.setSz(3500);\r
+        assertEquals(35.0, textRun.getFontSize());\r
+        lv4CPr.addNewLatin().setTypeface("Arial");\r
+        assertEquals("Arial", textRun.getFontFamily());\r
+        lv4PPr.setAlgn(STTextAlignType.L);\r
+        assertEquals(TextAlign.LEFT, paragraph.getTextAlign());\r
+\r
+        // level 5: text properties are defined in the text run\r
+        CTTextParagraphProperties lv5PPr = paragraph.getXmlObject().addNewPPr();\r
+        CTTextCharacterProperties lv5CPr = textRun.getXmlObject().getRPr();\r
+        lv5CPr.setSz(3600);\r
+        assertEquals(36.0, textRun.getFontSize());\r
+        lv5CPr.addNewLatin().setTypeface("Calibri");\r
+        assertEquals("Calibri", textRun.getFontFamily());\r
+        lv5PPr.setAlgn(STTextAlignType.CTR);\r
+        assertEquals(TextAlign.CENTER, paragraph.getTextAlign());\r
+    }\r
+\r
+    public void testBodyStyles(){\r
+        XMLSlideShow ppt = new XMLSlideShow();\r
+\r
+        XSLFSlideMaster master = ppt.getSlideMasters()[0];\r
+        XSLFTheme theme = master.getTheme();\r
+        XSLFSlideLayout layout = master.getLayout(SlideLayout.TITLE_AND_CONTENT);\r
+        XSLFSlide slide = ppt.createSlide(layout) ;\r
+        assertSame(layout, slide.getSlideLayout());\r
+        assertSame(master, slide.getSlideMaster());\r
+\r
+        XSLFTextShape tx1 = (XSLFTextShape)slide.getPlaceholder(1);\r
+        tx1.clearText();\r
+\r
+        XSLFTextParagraph p1 = tx1.addNewTextParagraph();\r
+        assertEquals(0, p1.getLevel());\r
+        XSLFTextRun r1 = p1.addNewTextRun();\r
+        r1.setText("Apache POI");\r
+\r
+        XSLFTextParagraph p2 = tx1.addNewTextParagraph();\r
+        p2.setLevel(1);\r
+        assertEquals(1, p2.getLevel());\r
+        XSLFTextRun r2 = p2.addNewTextRun();\r
+        r2.setText("HSLF");\r
+\r
+        XSLFTextParagraph p3 = tx1.addNewTextParagraph();\r
+        p3.setLevel(2);\r
+        assertEquals(2, p3.getLevel());\r
+        XSLFTextRun r3 = p3.addNewTextRun();\r
+        r3.setText("XSLF");\r
+\r
+        // level 1 : default title style on the master slide\r
+        // /p:sldMaster/p:txStyles/p:bodyStyle/a:lvl1pPr\r
+        CTTextParagraphProperties lv1PPr = master.getXmlObject().getTxStyles().getBodyStyle().getLvl1PPr();\r
+        CTTextCharacterProperties lv1CPr = lv1PPr.getDefRPr();\r
+        CTTextParagraphProperties lv2PPr = master.getXmlObject().getTxStyles().getBodyStyle().getLvl2PPr();\r
+        CTTextCharacterProperties lv2CPr = lv2PPr.getDefRPr();\r
+        CTTextParagraphProperties lv3PPr = master.getXmlObject().getTxStyles().getBodyStyle().getLvl3PPr();\r
+        CTTextCharacterProperties lv3CPr = lv3PPr.getDefRPr();\r
+        // lv1\r
+        assertEquals(3200, lv1CPr.getSz());\r
+        assertEquals(32.0, r1.getFontSize());\r
+        assertEquals("+mn-lt", lv1CPr.getLatin().getTypeface());\r
+        assertEquals("Calibri", theme.getMinorFont());\r
+        assertEquals("Calibri", r1.getFontFamily());\r
+        lv1CPr.setSz(3300);\r
+        assertEquals(33.0, r1.getFontSize());\r
+        lv1CPr.getLatin().setTypeface("Arial");\r
+        assertEquals("Arial", r1.getFontFamily());\r
+        assertEquals(STTextAlignType.L, lv1PPr.getAlgn());\r
+        assertEquals(TextAlign.LEFT, p1.getTextAlign());\r
+        lv1PPr.setAlgn(STTextAlignType.R);\r
+        assertEquals(TextAlign.RIGHT, p1.getTextAlign());\r
+        //lv2\r
+        assertEquals(2800, lv2CPr.getSz());\r
+        assertEquals(28.0, r2.getFontSize());\r
+        lv2CPr.setSz(3300);\r
+        assertEquals(33.0, r2.getFontSize());\r
+        lv2CPr.getLatin().setTypeface("Times");\r
+        assertEquals("Times", r2.getFontFamily());\r
+        assertEquals(STTextAlignType.L, lv2PPr.getAlgn());\r
+        assertEquals(TextAlign.LEFT, p2.getTextAlign());\r
+        lv2PPr.setAlgn(STTextAlignType.R);\r
+        assertEquals(TextAlign.RIGHT, p2.getTextAlign());\r
+        //lv3\r
+        assertEquals(2400, lv3CPr.getSz());\r
+        assertEquals(24.0, r3.getFontSize());\r
+        lv3CPr.setSz(2500);\r
+        assertEquals(25.0, r3.getFontSize());\r
+        lv3CPr.getLatin().setTypeface("Courier New");\r
+        assertEquals("Courier New", r3.getFontFamily());\r
+        assertEquals(STTextAlignType.L, lv3PPr.getAlgn());\r
+        assertEquals(TextAlign.LEFT, p3.getTextAlign());\r
+        lv3PPr.setAlgn(STTextAlignType.R);\r
+        assertEquals(TextAlign.RIGHT, p3.getTextAlign());\r
+\r
+\r
+        // level 2: body placeholder on the master slide\r
+        // /p:sldMaster/p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="body"]\r
+        XSLFTextShape tx2 = master.getPlaceholder(1);\r
+        assertEquals(Placeholder.BODY, tx2.getTextType());\r
+\r
+        lv1PPr = tx2.getTextBody(true).getLstStyle().addNewLvl1PPr();\r
+        lv1CPr = lv1PPr.addNewDefRPr();\r
+        lv2PPr = tx2.getTextBody(true).getLstStyle().addNewLvl2PPr();\r
+        lv2CPr = lv2PPr.addNewDefRPr();\r
+        lv3PPr = tx2.getTextBody(true).getLstStyle().addNewLvl3PPr();\r
+        lv3CPr = lv3PPr.addNewDefRPr();\r
+\r
+        lv1CPr.setSz(3300);\r
+        assertEquals(33.0, r1.getFontSize());\r
+        lv1CPr.addNewLatin().setTypeface("Times");\r
+        assertEquals("Times", r1.getFontFamily());\r
+        lv1PPr.setAlgn(STTextAlignType.L);\r
+        assertEquals(TextAlign.LEFT, p1.getTextAlign());\r
+\r
+        lv2CPr.setSz(3300);\r
+        assertEquals(33.0, r2.getFontSize());\r
+        lv2CPr.addNewLatin().setTypeface("Times");\r
+        assertEquals("Times", r2.getFontFamily());\r
+        lv2PPr.setAlgn(STTextAlignType.L);\r
+        assertEquals(TextAlign.LEFT, p2.getTextAlign());\r
+\r
+        lv3CPr.setSz(3300);\r
+        assertEquals(33.0, r3.getFontSize());\r
+        lv3CPr.addNewLatin().setTypeface("Times");\r
+        assertEquals("Times", r3.getFontFamily());\r
+        lv3PPr.setAlgn(STTextAlignType.L);\r
+        assertEquals(TextAlign.LEFT, p3.getTextAlign());\r
+\r
+        // level 3: body placeholder on the slide layout\r
+        // /p:sldLayout /p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="ctrTitle"]\r
+        XSLFTextShape tx3 = layout.getPlaceholder(1);\r
+        assertEquals(Placeholder.BODY, tx2.getTextType());\r
+        lv1PPr = tx3.getTextBody(true).getLstStyle().addNewLvl1PPr();\r
+        lv1CPr = lv1PPr.addNewDefRPr();\r
+        lv2PPr = tx3.getTextBody(true).getLstStyle().addNewLvl2PPr();\r
+        lv2CPr = lv2PPr.addNewDefRPr();\r
+        lv3PPr = tx3.getTextBody(true).getLstStyle().addNewLvl3PPr();\r
+        lv3CPr = lv3PPr.addNewDefRPr();\r
+\r
+        lv1CPr.setSz(3400);\r
+        assertEquals(34.0, r1.getFontSize());\r
+        lv1CPr.addNewLatin().setTypeface("Courier New");\r
+        assertEquals("Courier New", r1.getFontFamily());\r
+        lv1PPr.setAlgn(STTextAlignType.CTR);\r
+        assertEquals(TextAlign.CENTER, p1.getTextAlign());\r
+\r
+        lv2CPr.setSz(3400);\r
+        assertEquals(34.0, r2.getFontSize());\r
+        lv2CPr.addNewLatin().setTypeface("Courier New");\r
+        assertEquals("Courier New", r2.getFontFamily());\r
+        lv2PPr.setAlgn(STTextAlignType.CTR);\r
+        assertEquals(TextAlign.CENTER, p2.getTextAlign());\r
+\r
+        lv3CPr.setSz(3400);\r
+        assertEquals(34.0, r3.getFontSize());\r
+        lv3CPr.addNewLatin().setTypeface("Courier New");\r
+        assertEquals("Courier New", r3.getFontFamily());\r
+        lv3PPr.setAlgn(STTextAlignType.CTR);\r
+        assertEquals(TextAlign.CENTER, p3.getTextAlign());\r
+\r
+        // level 4: default text properties in the shape itself\r
+        // ./p:sp/p:txBody/a:lstStyle/a:lvl1pPr\r
+        lv1PPr = tx1.getTextBody(true).getLstStyle().addNewLvl1PPr();\r
+        lv1CPr = lv1PPr.addNewDefRPr();\r
+        lv2PPr = tx1.getTextBody(true).getLstStyle().addNewLvl2PPr();\r
+        lv2CPr = lv2PPr.addNewDefRPr();\r
+        lv3PPr = tx1.getTextBody(true).getLstStyle().addNewLvl3PPr();\r
+        lv3CPr = lv3PPr.addNewDefRPr();\r
+\r
+        lv1CPr.setSz(3500);\r
+        assertEquals(35.0, r1.getFontSize());\r
+        lv1CPr.addNewLatin().setTypeface("Arial");\r
+        assertEquals("Arial", r1.getFontFamily());\r
+        lv1PPr.setAlgn(STTextAlignType.L);\r
+        assertEquals(TextAlign.LEFT, p1.getTextAlign());\r
+\r
+        lv2CPr.setSz(3500);\r
+        assertEquals(35.0, r2.getFontSize());\r
+        lv2CPr.addNewLatin().setTypeface("Arial");\r
+        assertEquals("Arial", r2.getFontFamily());\r
+        lv2PPr.setAlgn(STTextAlignType.L);\r
+        assertEquals(TextAlign.LEFT, p2.getTextAlign());\r
+\r
+        lv3CPr.setSz(3500);\r
+        assertEquals(35.0, r3.getFontSize());\r
+        lv3CPr.addNewLatin().setTypeface("Arial");\r
+        assertEquals("Arial", r3.getFontFamily());\r
+        lv3PPr.setAlgn(STTextAlignType.L);\r
+        assertEquals(TextAlign.LEFT, p3.getTextAlign());\r
+\r
+        // level 5: text properties are defined in the text run\r
+        lv1PPr = p1.getXmlObject().isSetPPr() ? p1.getXmlObject().getPPr() : p1.getXmlObject().addNewPPr();\r
+        lv1CPr = r1.getXmlObject().getRPr();\r
+        lv2PPr = p2.getXmlObject().isSetPPr() ? p2.getXmlObject().getPPr() : p2.getXmlObject().addNewPPr();\r
+        lv2CPr = r2.getXmlObject().getRPr();\r
+        lv3PPr = p3.getXmlObject().isSetPPr() ? p3.getXmlObject().getPPr() : p3.getXmlObject().addNewPPr();\r
+        lv3CPr = r3.getXmlObject().getRPr();\r
+\r
+        lv1CPr.setSz(3600);\r
+        assertEquals(36.0, r1.getFontSize());\r
+        lv1CPr.addNewLatin().setTypeface("Calibri");\r
+        assertEquals("Calibri", r1.getFontFamily());\r
+        lv1PPr.setAlgn(STTextAlignType.CTR);\r
+        assertEquals(TextAlign.CENTER, p1.getTextAlign());\r
+\r
+        lv2CPr.setSz(3600);\r
+        assertEquals(36.0, r2.getFontSize());\r
+        lv2CPr.addNewLatin().setTypeface("Calibri");\r
+        assertEquals("Calibri", r2.getFontFamily());\r
+        lv2PPr.setAlgn(STTextAlignType.CTR);\r
+        assertEquals(TextAlign.CENTER, p2.getTextAlign());\r
+\r
+        lv3CPr.setSz(3600);\r
+        assertEquals(36.0, r3.getFontSize());\r
+        lv3CPr.addNewLatin().setTypeface("Calibri");\r
+        assertEquals("Calibri", r3.getFontFamily());\r
+        lv3PPr.setAlgn(STTextAlignType.CTR);\r
+        assertEquals(TextAlign.CENTER, p3.getTextAlign());\r
+\r
+    }\r
+\r
 }
\ No newline at end of file
index eea1e064e93d56146d6b196ecc9c4f8fcba8f1b1..ababa9379101da3043aa5d798574476094d1e6b9 100755 (executable)
Binary files a/src/resources/ooxml/org/apache/poi/xslf/usermodel/empty.pptx and b/src/resources/ooxml/org/apache/poi/xslf/usermodel/empty.pptx differ
diff --git a/test-data/slideshow/prProps.pptx b/test-data/slideshow/prProps.pptx
new file mode 100644 (file)
index 0000000..2829fca
Binary files /dev/null and b/test-data/slideshow/prProps.pptx differ