]> source.dussan.org Git - poi.git/commitdiff
- #58216 - provide picture-shape resize that maintains the aspect ratio
authorAndreas Beeker <kiwiwings@apache.org>
Mon, 21 Sep 2015 00:09:45 +0000 (00:09 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Mon, 21 Sep 2015 00:09:45 +0000 (00:09 +0000)
- moved SlideShowFactory to Common SL
- changed get/setAnchor to Rectangle instead of Rectangle2D
- Fixed some Common SL generic definitions
- picture dimensions are now in points and an additional method exists for pixels

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1704206 13f79535-47bb-0310-9956-ffa450edef68

49 files changed:
src/examples/src/org/apache/poi/xslf/usermodel/Tutorial4.java
src/integrationtest/org/apache/poi/stress/SlideShowHandler.java
src/java/org/apache/poi/sl/draw/DrawBackground.java
src/java/org/apache/poi/sl/draw/DrawPictureShape.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/usermodel/GroupShape.java
src/java/org/apache/poi/sl/usermodel/PictureData.java
src/java/org/apache/poi/sl/usermodel/PlaceableShape.java
src/java/org/apache/poi/sl/usermodel/RectAlign.java [new file with mode: 0644]
src/java/org/apache/poi/sl/usermodel/Shadow.java
src/java/org/apache/poi/sl/usermodel/Shape.java
src/java/org/apache/poi/sl/usermodel/SimpleShape.java
src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.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/XSLFSlideShowFactory.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java
src/ooxml/testcases/org/apache/poi/sl/draw/TestDrawPictureShape.java [new file with mode: 0644]
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFGroupShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShowFactory.java [new file with mode: 0644]
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java
src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java
src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java
src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFGroupShape.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowFactory.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestMovieShape.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestOleEmbedding.java
src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShowFactory.java [new file with mode: 0644]
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java
src/testcases/org/apache/poi/sl/draw/geom/TestPresetGeometries.java
src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java [new file with mode: 0644]

index 0742cddea4d2c0ade8ea30af892cff9984551a29..ecfc986670493e2b3e109b5ca194bc6078d190cd 100644 (file)
@@ -20,7 +20,7 @@
 package org.apache.poi.xslf.usermodel;\r
 \r
 import java.awt.Color;\r
-import java.awt.geom.Rectangle2D;\r
+import java.awt.Rectangle;\r
 import java.io.FileOutputStream;\r
 import java.io.IOException;\r
 \r
@@ -40,7 +40,7 @@ public class Tutorial4 {
         XSLFSlide slide = ppt.createSlide();\r
 \r
         XSLFTable tbl = slide.createTable();\r
-        tbl.setAnchor(new Rectangle2D.Double(50, 50, 450, 300));\r
+        tbl.setAnchor(new Rectangle(50, 50, 450, 300));\r
 \r
         int numColumns = 3;\r
         int numRows = 5;\r
index 34830f1e01a9be19682eea58d15374ddb3826109..9d6d1b3dcdaaa52e76ab62675fe967acdb0ec987 100644 (file)
@@ -29,14 +29,13 @@ import java.io.IOException;
 import java.util.HashMap;\r
 import java.util.Map;\r
 \r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.sl.SlideShowFactory;\r
 import org.apache.poi.sl.draw.Drawable;\r
 import org.apache.poi.sl.usermodel.PictureData;\r
 import org.apache.poi.sl.usermodel.Shape;\r
 import org.apache.poi.sl.usermodel.ShapeContainer;\r
 import org.apache.poi.sl.usermodel.Slide;\r
 import org.apache.poi.sl.usermodel.SlideShow;\r
+import org.apache.poi.sl.usermodel.SlideShowFactory;\r
 import org.apache.poi.sl.usermodel.TextParagraph;\r
 import org.apache.poi.sl.usermodel.TextRun;\r
 import org.apache.poi.sl.usermodel.TextShape;\r
@@ -55,12 +54,7 @@ public abstract class SlideShowHandler extends POIFSFileHandler {
         readContent(ss);\r
 \r
         // read in the writen file\r
-        SlideShow<?,?> read;\r
-        try {\r
-            read = SlideShowFactory.create(new ByteArrayInputStream(out.toByteArray()));\r
-        } catch (InvalidFormatException e) {\r
-            throw new IllegalStateException(e);\r
-        }\r
+        SlideShow<?,?> read = SlideShowFactory.create(new ByteArrayInputStream(out.toByteArray()));\r
         assertNotNull(read);\r
         \r
         readContent(read);\r
index 4072fe4bcd01f11521aa7145b474d1f5120a202b..a06c2da23f4919e7b32b0b53fff5c8bcfafabd3f 100644 (file)
@@ -20,6 +20,7 @@ package org.apache.poi.sl.draw;
 import java.awt.Dimension;\r
 import java.awt.Graphics2D;\r
 import java.awt.Paint;\r
+import java.awt.Rectangle;\r
 import java.awt.geom.Rectangle2D;\r
 \r
 import org.apache.poi.sl.usermodel.Background;\r
@@ -35,12 +36,12 @@ public class DrawBackground extends DrawShape {
     @SuppressWarnings("rawtypes")\r
     public void draw(Graphics2D graphics) {\r
         Dimension pg = shape.getSheet().getSlideShow().getPageSize();\r
-        final Rectangle2D anchor = new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight());\r
+        final Rectangle anchor = new Rectangle(0, 0, (int)pg.getWidth(), (int)pg.getHeight());\r
 \r
         PlaceableShape<?,?> ps = new PlaceableShape(){\r
             public ShapeContainer<?,?> getParent() { return null; }\r
-            public Rectangle2D getAnchor() { return anchor; }\r
-            public void setAnchor(Rectangle2D anchor) {}\r
+            public Rectangle getAnchor() { return anchor; }\r
+            public void setAnchor(Rectangle newAnchor) {}\r
             public double getRotation() { return 0; }\r
             public void setRotation(double theta) {}\r
             public void setFlipHorizontal(boolean flip) {}\r
index 43586f111f857636dc2a96749d7cd4bc71cc324b..534d246adc15239fa0a95a6732bc290c1bd76bb6 100644 (file)
 \r
 package org.apache.poi.sl.draw;\r
 \r
+import java.awt.Dimension;\r
 import java.awt.Graphics2D;\r
 import java.awt.Insets;\r
+import java.awt.Rectangle;\r
 import java.awt.geom.Rectangle2D;\r
 import java.io.IOException;\r
 \r
 import org.apache.poi.sl.usermodel.PictureData;\r
 import org.apache.poi.sl.usermodel.PictureShape;\r
+import org.apache.poi.sl.usermodel.RectAlign;\r
 \r
 \r
 public class DrawPictureShape extends DrawSimpleShape {\r
@@ -56,4 +59,117 @@ public class DrawPictureShape extends DrawSimpleShape {
     protected PictureShape<?,?> getShape() {\r
         return (PictureShape<?,?>)shape;\r
     }\r
+    \r
+    /**\r
+     * Resize this picture to the default size.\r
+     *\r
+     * For PNG and JPEG resizes the image to 100%,\r
+     * for other types, if the size can't be determined it will be 200x200 pixels.\r
+     */\r
+    public void resize() {\r
+        PictureShape<?,?> ps = getShape();\r
+        Dimension dim = ps.getPictureData().getImageDimension();\r
+\r
+        Rectangle origRect = ps.getAnchor();\r
+        int x = (int)origRect.getX();\r
+        int y = (int)origRect.getY();\r
+        int w = (int)dim.getWidth();\r
+        int h = (int)dim.getHeight();\r
+        ps.setAnchor(new Rectangle(x, y, w, h));\r
+    }\r
+\r
+\r
+    /**\r
+     * Fit picture shape into the target rectangle, maintaining the aspect ratio\r
+     * and repositioning within the target rectangle with a centered alignment.\r
+     *\r
+     * @param target    The target rectangle\r
+     */\r
+    public void resize(Rectangle target) {\r
+        resize(target, RectAlign.CENTER);\r
+    }\r
+\r
+\r
+    /**\r
+     * Fit picture shape into the target rectangle, maintaining the aspect ratio\r
+     * and repositioning within the target rectangle based on the specified\r
+     * alignment (gravity).\r
+     *\r
+     * @param target    The target rectangle\r
+     * @param align\r
+     *            The alignment within the target rectangle when resizing.\r
+     *            A null value corresponds to RectAlign.CENTER\r
+     */\r
+    public void resize(Rectangle target, RectAlign align) {\r
+        PictureShape<?,?> ps = getShape();\r
+        Dimension dim = ps.getPictureData().getImageDimension();\r
+        if (dim.width <= 0 || dim.height <= 0) {\r
+            // nothing useful to be done for this case\r
+            ps.setAnchor(target);\r
+            return;\r
+        }\r
+\r
+        double w = target.getWidth();\r
+        double h = target.getHeight();\r
+\r
+        // scaling\r
+        double sx = w / dim.width;\r
+        double sy = h / dim.height;\r
+\r
+        // position adjustments\r
+        double dx = 0, dy = 0;\r
+\r
+        if (sx > sy) {\r
+            // use y-scaling for both, reposition x accordingly\r
+            w  = sy * dim.width;\r
+            dx = target.getWidth() - w;\r
+        } else if (sy > sx) {\r
+            // use x-scaling for both, reposition y accordingly\r
+            h  = sx * dim.height;\r
+            dy = target.getHeight() - h;\r
+        } else {\r
+            // uniform scaling, can use target values directly\r
+            ps.setAnchor(target);\r
+            return;\r
+        }\r
+\r
+        // the positioning\r
+        double x = target.getX();\r
+        double y = target.getY();\r
+        switch (align) {\r
+            case TOP:           // X=balance, Y=ok\r
+                x += dx/2;\r
+                break;\r
+            case TOP_RIGHT:     // X=shift, Y=ok\r
+                x += dx;\r
+                break;\r
+            case RIGHT:         // X=shift, Y=balance\r
+                x += dx;\r
+                y += dy/2;\r
+                break;\r
+            case BOTTOM_RIGHT:  // X=shift, Y=shift\r
+                x += dx;\r
+                y += dy;\r
+                break;\r
+            case BOTTOM:        // X=balance, Y=shift\r
+                x += dx/2;\r
+                y += dy;\r
+                break;\r
+            case BOTTOM_LEFT:   // X=ok, Y=shift\r
+                y += dy;\r
+                break;\r
+            case LEFT:          // X=ok, Y=balance\r
+                y += dy/2;\r
+                break;\r
+            case TOP_LEFT:      // X=ok, Y=ok\r
+                /* no-op */\r
+                break;\r
+            default:            // CENTER: X=balance, Y=balance\r
+                x += dx/2;\r
+                y += dy/2;\r
+                break;\r
+        }\r
+\r
+        ps.setAnchor(new Rectangle((int)x, (int)y, (int)w, (int)h));\r
+    }\r
 }\r
index 37cd6d8b8839875d430ce1e8dec20968ea077a34..941e5c72d958137958b5acec32c4da130f1206d3 100644 (file)
@@ -25,10 +25,8 @@ import java.awt.geom.AffineTransform;
 import java.awt.geom.Ellipse2D;\r
 import java.awt.geom.GeneralPath;\r
 import java.awt.geom.Rectangle2D;\r
+import java.io.IOException;\r
 import java.io.InputStream;\r
-import java.io.InputStreamReader;\r
-import java.io.Reader;\r
-import java.nio.charset.Charset;\r
 import java.util.ArrayList;\r
 import java.util.Collection;\r
 import java.util.HashMap;\r
@@ -145,7 +143,7 @@ public class DrawSimpleShape extends DrawShape {
         double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());\r
     \r
         AffineTransform at = new AffineTransform();\r
-        java.awt.Shape shape = null;\r
+        java.awt.Shape tailShape = null;\r
         Path p = null;\r
         Rectangle2D bounds;\r
         final double scaleY = Math.pow(2, tailWidth.ordinal()+1);\r
@@ -153,8 +151,8 @@ public class DrawSimpleShape extends DrawShape {
         switch (deco.getTailShape()) {\r
             case OVAL:\r
                 p = new Path();\r
-                shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);\r
-                bounds = shape.getBounds2D();\r
+                tailShape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);\r
+                bounds = tailShape.getBounds2D();\r
                 at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2);\r
                 at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);\r
                 break;\r
@@ -165,7 +163,7 @@ public class DrawSimpleShape extends DrawShape {
                 arrow.moveTo((float) (-lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));\r
                 arrow.lineTo(0, 0);\r
                 arrow.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2));\r
-                shape = arrow;\r
+                tailShape = arrow;\r
                 at.translate(x2, y2);\r
                 at.rotate(alpha);\r
                 break;\r
@@ -176,7 +174,7 @@ public class DrawSimpleShape extends DrawShape {
                 triangle.lineTo(0, 0);\r
                 triangle.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2));\r
                 triangle.closePath();\r
-                shape = triangle;\r
+                tailShape = triangle;\r
                 at.translate(x2, y2);\r
                 at.rotate(alpha);\r
                 break;\r
@@ -184,10 +182,10 @@ public class DrawSimpleShape extends DrawShape {
                 break;\r
         }\r
     \r
-        if (shape != null) {\r
-            shape = at.createTransformedShape(shape);\r
+        if (tailShape != null) {\r
+            tailShape = at.createTransformedShape(tailShape);\r
         }\r
-        return shape == null ? null : new Outline(shape, p);\r
+        return tailShape == null ? null : new Outline(tailShape, p);\r
     }\r
     \r
     protected Outline getHeadDecoration(Graphics2D graphics, LineDecoration deco, BasicStroke stroke) {\r
@@ -203,7 +201,7 @@ public class DrawSimpleShape extends DrawShape {
         double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());\r
     \r
         AffineTransform at = new AffineTransform();\r
-        java.awt.Shape shape = null;\r
+        java.awt.Shape headShape = null;\r
         Path p = null;\r
         Rectangle2D bounds;\r
         final double scaleY = Math.pow(2, headWidth.ordinal()+1);\r
@@ -211,8 +209,8 @@ public class DrawSimpleShape extends DrawShape {
         switch (deco.getHeadShape()) {\r
             case OVAL:\r
                 p = new Path();\r
-                shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);\r
-                bounds = shape.getBounds2D();\r
+                headShape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);\r
+                bounds = headShape.getBounds2D();\r
                 at.translate(x1 - bounds.getWidth() / 2, y1 - bounds.getHeight() / 2);\r
                 at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);\r
                 break;\r
@@ -223,7 +221,7 @@ public class DrawSimpleShape extends DrawShape {
                 arrow.moveTo((float) (lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));\r
                 arrow.lineTo(0, 0);\r
                 arrow.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2));\r
-                shape = arrow;\r
+                headShape = arrow;\r
                 at.translate(x1, y1);\r
                 at.rotate(alpha);\r
                 break;\r
@@ -234,7 +232,7 @@ public class DrawSimpleShape extends DrawShape {
                 triangle.lineTo(0, 0);\r
                 triangle.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2));\r
                 triangle.closePath();\r
-                shape = triangle;\r
+                headShape = triangle;\r
                 at.translate(x1, y1);\r
                 at.rotate(alpha);\r
                 break;\r
@@ -242,10 +240,10 @@ public class DrawSimpleShape extends DrawShape {
                 break;\r
         }\r
     \r
-        if (shape != null) {\r
-            shape = at.createTransformedShape(shape);\r
+        if (headShape != null) {\r
+            headShape = at.createTransformedShape(headShape);\r
         }\r
-        return shape == null ? null : new Outline(shape, p);\r
+        return headShape == null ? null : new Outline(headShape, p);\r
     }\r
     \r
     public BasicStroke getStroke() {\r
@@ -296,7 +294,7 @@ public class DrawSimpleShape extends DrawShape {
           , Paint fill\r
           , Paint line\r
     ) {\r
-          Shadow shadow = getShape().getShadow();\r
+          Shadow<?,?> shadow = getShape().getShadow();\r
           if (shadow == null || (fill == null && line == null)) return;\r
 \r
           SolidPaint shadowPaint = shadow.getFillStyle();\r
@@ -347,7 +345,6 @@ public class DrawSimpleShape extends DrawShape {
             \r
             String packageName = "org.apache.poi.sl.draw.binding";\r
             InputStream presetIS = Drawable.class.getResourceAsStream("presetShapeDefinitions.xml");\r
-            Reader xml = new InputStreamReader( presetIS, Charset.forName("UTF-8") );\r
     \r
             // StAX:\r
             EventFilter startElementFilter = new EventFilter() {\r
@@ -359,7 +356,7 @@ public class DrawSimpleShape extends DrawShape {
             \r
             try {\r
                 XMLInputFactory staxFactory = XMLInputFactory.newInstance();\r
-                XMLEventReader staxReader = staxFactory.createXMLEventReader(xml);\r
+                XMLEventReader staxReader = staxFactory.createXMLEventReader(presetIS);\r
                 XMLEventReader staxFiltRd = staxFactory.createFilteredReader(staxReader, startElementFilter);\r
                 // Ignore StartElement:\r
                 staxFiltRd.nextEvent();\r
@@ -378,6 +375,12 @@ public class DrawSimpleShape extends DrawShape {
                 }\r
             } catch (Exception e) {\r
                 throw new RuntimeException("Unable to load preset geometries.", e);\r
+            } finally {\r
+                try {\r
+                    presetIS.close();\r
+                } catch (IOException e) {\r
+                    throw new RuntimeException("Unable to load preset geometries.", e);\r
+                }\r
             }\r
         }\r
         \r
index 8cfa481626926f92af29f5b6da75bd5e5e8a8e11..735205ec4e6f82333eae41dc56ccc3d00382fdef 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.sl.draw;
 \r
 import java.awt.Graphics2D;\r
 import java.awt.Paint;\r
+import java.awt.Rectangle;\r
 import java.awt.font.FontRenderContext;\r
 import java.awt.font.LineBreakMeasurer;\r
 import java.awt.font.TextAttribute;\r
@@ -416,8 +417,8 @@ public class DrawTextParagraph implements Drawable {
     private PlaceableShape<?,?> getParagraphShape() {\r
         PlaceableShape<?,?> ps = new PlaceableShape(){\r
             public ShapeContainer<?,?> getParent() { return null; }\r
-            public Rectangle2D getAnchor() { return paragraph.getParentShape().getAnchor(); }\r
-            public void setAnchor(Rectangle2D anchor) {}\r
+            public Rectangle getAnchor() { return paragraph.getParentShape().getAnchor(); }\r
+            public void setAnchor(Rectangle anchor) {}\r
             public double getRotation() { return 0; }\r
             public void setRotation(double theta) {}\r
             public void setFlipHorizontal(boolean flip) {}\r
index a7545a4d4d510e7a84162d33e507662d6396b616..87396b5873659f3d740bb24e6223a27a4b1f1571 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.sl.usermodel;
 
-import java.awt.geom.Rectangle2D;
+import java.awt.Rectangle;
 
 public interface GroupShape<
     S extends Shape<S,P>,
@@ -30,7 +30,7 @@ public interface GroupShape<
      *
      * @return the coordinate space of this group
      */
-    Rectangle2D getInteriorAnchor();
+    Rectangle getInteriorAnchor();
     
     /**
      * Sets the coordinate space of this group.  All children are constrained
@@ -38,5 +38,5 @@ public interface GroupShape<
      *
      * @param anchor the coordinate space of this group
      */
-    void setInteriorAnchor(Rectangle2D anchor);
+    void setInteriorAnchor(Rectangle anchor);
 }
index 62780773eac37b96e5ef8902de9738b355af435b..60e6266b7eeebc4656239352ff0f3ca66ddc88d5 100644 (file)
@@ -106,10 +106,16 @@ public interface PictureData {
        byte[] getChecksum();
        
     /**
-     * Return the original image dimensions
+     * Return the original image dimensions in points
      * (for formats supported by BufferedImage).
      *
-     * Will return a Dimension with zero width/height if the format unsupported.
+     * Will return a Dimension with a default width of 200x200 if the format unsupported.
      */
        Dimension getImageDimension();
+       
+    /**
+     * Return the original image dimensions in pixels
+     * @see PictureData#getImageDimension()
+     */
+       Dimension getImageDimensionInPixels();
 }
\ No newline at end of file
index 191bad65f6058ef1fe145ec34437b64a333d1106..bcba7401c29ad5c253007e144e1ce9fe98b9601a 100644 (file)
@@ -17,7 +17,7 @@
 \r
 package org.apache.poi.sl.usermodel;\r
 \r
-import java.awt.geom.Rectangle2D;\r
+import java.awt.Rectangle;\r
 \r
 public interface PlaceableShape<\r
     S extends Shape<S,P>,\r
@@ -29,13 +29,13 @@ public interface PlaceableShape<
      * @return the position of this shape within the drawing canvas.\r
      *         The coordinates are expressed in points\r
      */\r
-    Rectangle2D getAnchor();\r
+    Rectangle getAnchor();\r
 \r
     /**\r
      * @param anchor the position of this shape within the drawing canvas.\r
      *               The coordinates are expressed in points\r
      */\r
-    void setAnchor(Rectangle2D anchor);\r
+    void setAnchor(Rectangle anchor);\r
 \r
     /**\r
      * Rotation angle in degrees\r
diff --git a/src/java/org/apache/poi/sl/usermodel/RectAlign.java b/src/java/org/apache/poi/sl/usermodel/RectAlign.java
new file mode 100644 (file)
index 0000000..9ca8d87
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+package org.apache.poi.sl.usermodel;
+
+/**
+ * Specifies possible rectangle alignment types.
+ *
+ * @see {@link org.openxmlformats.schemas.drawingml.x2006.main.STRectAlignment}
+ * @see {@link org.apache.poi.sl.draw.binding.STRectAlignment}
+ */
+public enum RectAlign {
+    /** Top-Left rectangle alignment */
+    TOP_LEFT("tl"),
+
+    /** Top rectangle alignment */
+    TOP("t"),
+
+    /** Top-Right rectangle alignment */
+    TOP_RIGHT("tr"),
+
+    /** Left rectangle alignment */
+    LEFT("l"),
+
+    /** Center rectangle alignment */
+    CENTER("ctr"),
+
+    /** Right rectangle alignment */
+    RIGHT("r"),
+
+    /** Bottom-Left rectangle alignment */
+    BOTTOM_LEFT("bl"),
+
+    /** Bottom rectangle alignment */
+    BOTTOM("b"),
+
+    /** Bottom-Right rectangle alignment */
+    BOTTOM_RIGHT("br");
+
+    /** The corresponding xml enum value */
+    private final String dir;
+
+    private RectAlign(String dir) {
+        this.dir = dir;
+    }
+
+
+    /**
+     * The string representation,
+     * which corresponds to the internal XML enum value
+     */
+    @Override
+    public String toString() {
+        return dir;
+    }
+
+}
+
+/* ************************************************************************** */
index 430dbe3840645518fedc85a36b19ef7f6acaf496..9afc4e64e9128f8a0e5d97cfb48a632322fb990e 100644 (file)
@@ -21,8 +21,11 @@ import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
 \r
 \r
 \r
-public interface Shadow {\r
-    SimpleShape getShadowParent();\r
+public interface Shadow<\r
+S extends Shape<S,P>,\r
+P extends TextParagraph<S,P,?>\r
+> {\r
+    SimpleShape<S,P> getShadowParent();\r
     \r
     /**\r
      * @return the offset of this shadow in points\r
index 13996fa6ccc361966c77600201134585022468e8..a05e3bf45de1ae8e8d98275073e648169121567b 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.sl.usermodel;
 
+import java.awt.Rectangle;
 
 public interface Shape<
     S extends Shape<S,P>,
@@ -29,4 +30,12 @@ public interface Shape<
     * @return the sheet this shape belongs to
     */
    Sheet<S,P> getSheet();
+   
+   /**
+    * Returns the anchor (the bounding box rectangle) of this shape.
+    * All coordinates are expressed in points (72 dpi).
+    *
+    * @return the anchor of this shape
+    */
+   Rectangle getAnchor();   
 }
index 95f4590ebeaea597539370c2d6b95af5290953fb..ceed729e09710a78b877769f6cb3bb12a3049c6b 100644 (file)
@@ -35,5 +35,5 @@ public interface SimpleShape<
 
     boolean isPlaceholder();
     
-       Shadow getShadow();
+       Shadow<S,P> getShadow();
 }
diff --git a/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java b/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java
new file mode 100644 (file)
index 0000000..9e705df
--- /dev/null
@@ -0,0 +1,315 @@
+/* ====================================================================\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.usermodel;\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.lang.reflect.InvocationTargetException;\r
+import java.lang.reflect.Method;\r
+import java.security.GeneralSecurityException;\r
+\r
+import org.apache.poi.EncryptedDocumentException;\r
+import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;\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.util.IOUtils;\r
+\r
+public class SlideShowFactory {\r
+    /** The first 4 bytes of an OOXML file, used in detection */\r
+    private static final byte[] OOXML_FILE_HEADER = { 0x50, 0x4b, 0x03, 0x04 };\r
+    \r
+    /**\r
+     * Creates a SlideShow from the given NPOIFSFileSystem.\r
+     *\r
+     * @param fs The {@link NPOIFSFileSystem} to read the document from\r
+     *\r
+     * @return The created SlideShow\r
+     *\r
+     * @throws IOException if an error occurs while reading the data\r
+     */\r
+    public static SlideShow<?,?> create(NPOIFSFileSystem fs) throws IOException {\r
+        return create(fs, null);\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
+     */\r
+    public static SlideShow<?,?> create(NPOIFSFileSystem fs, String password) throws IOException {\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
+\r
+                if (!passwordCorrect) {\r
+                    String err = (password != null)\r
+                        ? "Password incorrect"\r
+                        : "The supplied spreadsheet is protected, but no password was supplied";\r
+                    throw new EncryptedDocumentException(err);\r
+                }\r
+\r
+                return createXSLFSlideShow(stream);\r
+            } catch (GeneralSecurityException e) {\r
+                throw new IOException(e);\r
+            } finally {\r
+                if (stream != null) stream.close();\r
+            }\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
+        try {\r
+            return createHSLFSlideShow(fs);\r
+        } finally {\r
+            Biff8EncryptionKey.setCurrentUserPassword(null);\r
+        }\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 EncryptedDocumentException If the SlideShow given is password protected\r
+     */\r
+    public static SlideShow<?,?> create(InputStream inp) throws IOException, 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 EncryptedDocumentException If the wrong password is given for a protected file\r
+     */\r
+    @SuppressWarnings("resource")\r
+    public static SlideShow<?,?> create(InputStream inp, String password) throws IOException, 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 (hasOOXMLHeader(inp)) {\r
+            return createXSLFSlideShow(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 EncryptedDocumentException If the SlideShow given is password protected\r
+     */\r
+    public static SlideShow<?,?> create(File file) throws IOException, 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 EncryptedDocumentException If the wrong password is given for a protected file\r
+     */\r
+    public static SlideShow<?,?> create(File file, String password) throws IOException, 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 EncryptedDocumentException If the wrong password is given for a protected file\r
+     */\r
+    @SuppressWarnings("resource")\r
+    public static SlideShow<?,?> create(File file, String password, boolean readOnly) throws IOException, 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
+            return createXSLFSlideShow(file, readOnly);\r
+        }\r
+    }\r
+    \r
+    protected static SlideShow<?,?> createHSLFSlideShow(Object... args) throws IOException, EncryptedDocumentException {\r
+        return createSlideShow("org.apache.poi.hslf.usermodel.HSLFSlideShowFactory", args);\r
+    }\r
+    \r
+    protected static SlideShow<?,?> createXSLFSlideShow(Object... args) throws IOException, EncryptedDocumentException {\r
+        return createSlideShow("org.apache.poi.xslf.usermodel.XSLFSlideShowFactory", args);\r
+    }\r
+    \r
+    protected static SlideShow<?,?> createSlideShow(String factoryClass, Object args[]) throws IOException, EncryptedDocumentException {\r
+        try {\r
+            Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(factoryClass);\r
+            Class<?> argsClz[] = new Class<?>[args.length];\r
+            int i=0;\r
+            for (Object o : args) {\r
+                Class<?> c = o.getClass();\r
+                if (Boolean.class.isAssignableFrom(c)) {\r
+                    c = boolean.class;\r
+                } else if (InputStream.class.isAssignableFrom(c)) {\r
+                    c = InputStream.class;\r
+                }\r
+                argsClz[i++] = c;\r
+            }\r
+            Method m = clazz.getMethod("createSlideShow", argsClz);\r
+            return (SlideShow<?,?>)m.invoke(null, args);\r
+        } catch (InvocationTargetException e) {\r
+            Throwable t = e.getCause();\r
+            if (t instanceof IOException) {\r
+                throw (IOException)t;\r
+            } else if (t instanceof EncryptedDocumentException) {\r
+                throw (EncryptedDocumentException)t;\r
+            } else {\r
+                throw new IOException(t);\r
+            }\r
+        } catch (Exception e) {\r
+            throw new IOException(e);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This copied over from ooxml, because we can't rely on these classes in the main package\r
+     * \r
+     * @see org.apache.poi.POIXMLDocument#hasOOXMLHeader(InputStream)\r
+     */\r
+    protected static boolean hasOOXMLHeader(InputStream inp) throws IOException {\r
+        // We want to peek at the first 4 bytes\r
+        inp.mark(4);\r
+\r
+        byte[] header = new byte[4];\r
+        int bytesRead = IOUtils.readFully(inp, header);\r
+\r
+        // Wind back those 4 bytes\r
+        if(inp instanceof PushbackInputStream) {\r
+            PushbackInputStream pin = (PushbackInputStream)inp;\r
+            pin.unread(header, 0, bytesRead);\r
+        } else {\r
+            inp.reset();\r
+        }\r
+\r
+        // Did it match the ooxml zip signature?\r
+        return (\r
+            bytesRead == 4 &&\r
+            header[0] == OOXML_FILE_HEADER[0] &&\r
+            header[1] == OOXML_FILE_HEADER[1] &&\r
+            header[2] == OOXML_FILE_HEADER[2] &&\r
+            header[3] == OOXML_FILE_HEADER[3]\r
+        );\r
+    }\r
+\r
+}\r
index 6dbdf2d4f123fbc8085c2ba7806eecd722c16a30..817d2edccd13e4fed8b9476524a7fe9806cbd44b 100644 (file)
@@ -19,7 +19,7 @@ package org.apache.poi.xslf.usermodel;
 \r
 import java.awt.Color;\r
 import java.awt.Dimension;\r
-import java.awt.geom.Rectangle2D;\r
+import java.awt.Rectangle;\r
 \r
 import org.apache.poi.sl.draw.DrawPaint;\r
 import org.apache.poi.sl.usermodel.Background;\r
@@ -43,9 +43,9 @@ public class XSLFBackground extends XSLFSimpleShape
     }\r
 \r
     @Override\r
-    public Rectangle2D getAnchor(){\r
+    public Rectangle getAnchor(){\r
         Dimension pg = getSheet().getSlideShow().getPageSize();\r
-        return new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight());\r
+        return new Rectangle(0, 0, (int)pg.getWidth(), (int)pg.getHeight());\r
     }\r
 \r
     @Override\r
index 1f23523938144c7cd8be0a1eedecb87e547876ef..4f14fc1a8a5db0b20aad147875a121734a54fa1b 100644 (file)
@@ -19,6 +19,7 @@
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
+import java.awt.Rectangle;\r
 import java.awt.geom.AffineTransform;\r
 import java.awt.geom.GeneralPath;\r
 import java.awt.geom.PathIterator;\r
@@ -60,7 +61,7 @@ public class XSLFFreeformShape extends XSLFAutoShape
     public int setPath(GeneralPath path) {\r
         CTPath2D ctPath = CTPath2D.Factory.newInstance();\r
 \r
-        Rectangle2D bounds = path.getBounds2D();\r
+        Rectangle bounds = path.getBounds();\r
         int x0 = Units.toEMU(bounds.getX());\r
         int y0 = Units.toEMU(bounds.getY());\r
         PathIterator it = path.getPathIterator(new AffineTransform());\r
index 82a3fe1f639575c214a738e482d6532081fc17b7..930acd402b859619df6b5a72ebd55554da1eb304 100644 (file)
@@ -19,7 +19,7 @@
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import java.awt.geom.Rectangle2D;\r
+import java.awt.Rectangle;\r
 \r
 import javax.xml.namespace.QName;\r
 \r
@@ -53,20 +53,19 @@ public class XSLFGraphicFrame extends XSLFShape {
         throw new UnsupportedOperationException();\r
     }\r
 \r
-    public Rectangle2D getAnchor(){\r
+    @Override\r
+    public Rectangle getAnchor(){\r
         CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm();\r
         CTPoint2D off = xfrm.getOff();\r
-        long x = off.getX();\r
-        long y = off.getY();\r
+        int x = (int)Units.toPoints(off.getX());\r
+        int y = (int)Units.toPoints(off.getY());\r
         CTPositiveSize2D ext = xfrm.getExt();\r
-        long cx = ext.getCx();\r
-        long cy = ext.getCy();\r
-        return new Rectangle2D.Double(\r
-                Units.toPoints(x), Units.toPoints(y),\r
-                Units.toPoints(cx), Units.toPoints(cy));\r
+        int cx = (int)Units.toPoints(ext.getCx());\r
+        int cy = (int)Units.toPoints(ext.getCy());\r
+        return new Rectangle(x, y, cx, cy);\r
     }\r
 \r
-    public void setAnchor(Rectangle2D anchor){\r
+    public void setAnchor(Rectangle anchor){\r
         CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm();\r
         CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();\r
         long x = Units.toEMU(anchor.getX());\r
index 6199501178139d45bb81d51d68c3e78a744a02b6..ae9c8bac661ca6416937083e092436ed6b717410 100644 (file)
@@ -19,7 +19,7 @@
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import java.awt.geom.Rectangle2D;\r
+import java.awt.Rectangle;\r
 import java.util.ArrayList;\r
 import java.util.Iterator;\r
 import java.util.List;\r
@@ -27,6 +27,7 @@ import java.util.List;
 import org.apache.poi.openxml4j.opc.PackagePart;\r
 import org.apache.poi.openxml4j.opc.PackageRelationship;\r
 import org.apache.poi.openxml4j.opc.TargetMode;\r
+import org.apache.poi.sl.draw.DrawPictureShape;\r
 import org.apache.poi.sl.usermodel.GroupShape;\r
 import org.apache.poi.sl.usermodel.PictureData;\r
 import org.apache.poi.util.Beta;\r
@@ -78,21 +79,19 @@ implements XSLFShapeContainer, GroupShape<XSLFShape,XSLFTextParagraph> {
     }\r
 \r
     @Override\r
-    public Rectangle2D getAnchor(){\r
+    public Rectangle getAnchor(){\r
         CTGroupTransform2D xfrm = getXfrm();\r
         CTPoint2D off = xfrm.getOff();\r
-        long x = off.getX();\r
-        long y = off.getY();\r
+        int x = (int)Units.toPoints(off.getX());\r
+        int y = (int)Units.toPoints(off.getY());\r
         CTPositiveSize2D ext = xfrm.getExt();\r
-        long cx = ext.getCx();\r
-        long cy = ext.getCy();\r
-        return new Rectangle2D.Double(\r
-                Units.toPoints(x), Units.toPoints(y),\r
-                Units.toPoints(cx), Units.toPoints(cy));\r
+        int cx = (int)Units.toPoints(ext.getCx());\r
+        int cy = (int)Units.toPoints(ext.getCy());\r
+        return new Rectangle(x,y,cx,cy);\r
     }\r
 \r
     @Override\r
-    public void setAnchor(Rectangle2D anchor){\r
+    public void setAnchor(Rectangle anchor){\r
         CTGroupTransform2D xfrm = getSafeXfrm();\r
         CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();\r
         long x = Units.toEMU(anchor.getX());\r
@@ -112,17 +111,15 @@ implements XSLFShapeContainer, GroupShape<XSLFShape,XSLFTextParagraph> {
      * used for calculations of grouping, scaling, and rotation\r
      * behavior of shapes placed within a group.\r
      */\r
-    public Rectangle2D getInteriorAnchor(){\r
+    public Rectangle getInteriorAnchor(){\r
         CTGroupTransform2D xfrm = getXfrm();\r
         CTPoint2D off = xfrm.getChOff();\r
-        long x = off.getX();\r
-        long y = off.getY();\r
+        int x = (int)Units.toPoints(off.getX());\r
+        int y = (int)Units.toPoints(off.getY());\r
         CTPositiveSize2D ext = xfrm.getChExt();\r
-        long cx = ext.getCx();\r
-        long cy = ext.getCy();\r
-        return new Rectangle2D.Double(\r
-                Units.toPoints(x), Units.toPoints(y),\r
-                Units.toPoints(cx), Units.toPoints(cy));\r
+        int cx = (int)Units.toPoints(ext.getCx());\r
+        int cy = (int)Units.toPoints(ext.getCy());\r
+        return new Rectangle(x, y, cx, cy);\r
     }\r
 \r
     /**\r
@@ -131,7 +128,7 @@ implements XSLFShapeContainer, GroupShape<XSLFShape,XSLFTextParagraph> {
      * used for calculations of grouping, scaling, and rotation\r
      * behavior of shapes placed within a group.\r
      */\r
-    public void setInteriorAnchor(Rectangle2D anchor) {\r
+    public void setInteriorAnchor(Rectangle anchor) {\r
         CTGroupTransform2D xfrm = getSafeXfrm();\r
         CTPoint2D off = xfrm.isSetChOff() ? xfrm.getChOff() : xfrm.addNewChOff();\r
         long x = Units.toEMU(anchor.getX());\r
@@ -250,7 +247,7 @@ implements XSLFShapeContainer, GroupShape<XSLFShape,XSLFTextParagraph> {
                 pic.getPartName(), TargetMode.INTERNAL, XSLFRelation.IMAGES.getRelation());\r
 \r
         XSLFPictureShape sh = getDrawing().createPicture(rel.getId());\r
-        sh.resize();\r
+        new DrawPictureShape(sh).resize();\r
         _shapes.add(sh);\r
         sh.setParent(this);\r
         return sh;\r
index b2d407d23142339134feb50cc8e59bad5bcdf266..cd3cbf05634fd73d725239572828bed767c124c4 100644 (file)
@@ -42,6 +42,7 @@ import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
+import org.apache.poi.util.Units;
 
 /**
  * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type
@@ -134,6 +135,15 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture
         return _origSize;
     }
 
+    @Override
+    public Dimension getImageDimensionInPixels() {
+        Dimension dim = getImageDimension();
+        return new Dimension(
+            Units.pointsToPixel(dim.getWidth()),
+            Units.pointsToPixel(dim.getHeight())
+        );
+    }
+    
     /**
      * Determine and cache image properties
      */
@@ -155,14 +165,19 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture
                 _origSize = new PICT.NativeHeader(data, 0).getSize();
                 break;
             default:
+                BufferedImage img = null;
                 try {
-                    BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
-                    _origSize = (img == null) ? new Dimension() : new Dimension(img.getWidth(), img.getHeight());
+                    img = ImageIO.read(new ByteArrayInputStream(data));
                 } catch (IOException e) {
                     logger.log(POILogger.WARN, "Can't determine image dimensions", e);
-                    // failed to get information, set dummy size
-                    _origSize = new Dimension(200,200);
                 }
+                // set dummy size, in case of dummy dimension can't be set
+                _origSize = (img == null)
+                    ? new Dimension(200,200)
+                    : new Dimension(
+                        (int)Units.pixelToPoints(img.getWidth()),
+                        (int)Units.pixelToPoints(img.getHeight())
+                    );
                 break;
             }
         }
index df352b57d00a55c756b80995021dc0319f179efa..44de46e1edffbdb005d2b313852ceba7dd8df3b1 100644 (file)
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import java.awt.Dimension;\r
 import java.awt.Insets;\r
-import java.awt.Rectangle;\r
 import java.net.URI;\r
+\r
 import javax.xml.namespace.QName;\r
 \r
 import org.apache.poi.POIXMLException;\r
@@ -83,24 +82,6 @@ public class XSLFPictureShape extends XSLFSimpleShape
         return ct;\r
     }\r
 \r
-    /**\r
-     * Resize this picture to the default size.\r
-     *\r
-     * For PNG and JPEG resizes the image to 100%,\r
-     * for other types sets the default size to 200x200 pixels.\r
-     */\r
-    public void resize() {\r
-        Dimension dim = getPictureData().getImageDimension();\r
-        if (dim.width > 0 && dim.height > 0)\r
-        {\r
-            setAnchor(new Rectangle(0, 0, dim.width, dim.height));\r
-        }\r
-        else\r
-        {\r
-            // unsupported/unknown formats\r
-            setAnchor(new Rectangle(50, 50, 200, 200));\r
-        }\r
-    }\r
 \r
     /**\r
      * Is this an internal picture (image data included within\r
index fd42bc2d76e0f12e382dae3fb907c47cb2743dc0..f5d41c2937a381f8e013f420380ec3434fe210bc 100644 (file)
@@ -18,7 +18,7 @@
 package org.apache.poi.xslf.usermodel;\r
 \r
 import java.awt.Color;\r
-import java.awt.geom.Rectangle2D;\r
+import java.awt.Rectangle;\r
 \r
 import org.apache.poi.sl.draw.DrawPaint;\r
 import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
@@ -32,7 +32,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
  *\r
  * @author Yegor Kozlov\r
  */\r
-public class XSLFShadow extends XSLFShape implements Shadow {\r
+public class XSLFShadow extends XSLFShape implements Shadow<XSLFShape,XSLFTextParagraph> {\r
 \r
     private XSLFSimpleShape _parent;\r
 \r
@@ -47,11 +47,12 @@ public class XSLFShadow extends XSLFShape implements Shadow {
         return _parent;\r
     }\r
 \r
-    public Rectangle2D getAnchor(){\r
+    @Override\r
+    public Rectangle getAnchor(){\r
         return _parent.getAnchor();\r
     }\r
 \r
-    public void setAnchor(Rectangle2D anchor){\r
+    public void setAnchor(Rectangle anchor){\r
         throw new IllegalStateException("You can't set anchor of a shadow");\r
     }\r
 \r
index 627f97310b95be86f123acc685300d53be5fd3a8..f5d0207b78bf804c5ba0247b8850b7dfef49644e 100644 (file)
@@ -36,6 +36,7 @@ import org.apache.poi.openxml4j.opc.PackagePartName;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.TargetMode;
 import org.apache.poi.sl.draw.DrawFactory;
+import org.apache.poi.sl.draw.DrawPictureShape;
 import org.apache.poi.sl.draw.Drawable;
 import org.apache.poi.sl.usermodel.PictureData;
 import org.apache.poi.sl.usermodel.Sheet;
@@ -213,7 +214,7 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> {
         addRelation(rel.getId(), new XSLFPictureData(pic, rel));
 
         XSLFPictureShape sh = getDrawing().createPicture(rel.getId());
-        sh.resize();
+        new DrawPictureShape(sh).resize();
         getShapes().add(sh);
         sh.setParent(this);
         return sh;
@@ -537,6 +538,7 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> {
      * @param packagePart   package part containing the data to import
      * @return ID of the created relationship
      */
+    @SuppressWarnings("resource")
     String importBlip(String blipId, PackagePart packagePart) {
         PackageRelationship blipRel = packagePart.getRelationship(blipId);
         PackagePart blipPart;
@@ -561,6 +563,7 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> {
     /**
      * Import a package part into this sheet.
      */
+    @SuppressWarnings("resource")
     PackagePart importPart(PackageRelationship srcRel, PackagePart srcPafrt) {
         PackagePart destPP = getPackagePart();
         PackagePartName srcPPName = srcPafrt.getPartName();
@@ -574,10 +577,11 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> {
         destPP.addRelationship(srcPPName, TargetMode.INTERNAL, srcRel.getRelationshipType());
 
         PackagePart part = pkg.createPart(srcPPName, srcPafrt.getContentType());
-        OutputStream out = part.getOutputStream();
         try {
+            OutputStream out = part.getOutputStream();
             InputStream is = srcPafrt.getInputStream();
             IOUtils.copy(is, out);
+            is.close();
             out.close();
         } catch (IOException e){
             throw new POIXMLException(e);
index 4ada16bf847e41de940c30709ffa9ea78515f26b..821cb07dff73691d08166d32d1a72cc9b8a818e3 100644 (file)
@@ -20,7 +20,7 @@
 package org.apache.poi.xslf.usermodel;\r
 \r
 import java.awt.Color;\r
-import java.awt.geom.Rectangle2D;\r
+import java.awt.Rectangle;\r
 \r
 import javax.xml.stream.XMLStreamException;\r
 import javax.xml.stream.XMLStreamReader;\r
@@ -45,7 +45,33 @@ import org.apache.poi.util.Beta;
 import org.apache.poi.util.Units;\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.CTBaseStyles;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTLineStyleList;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;\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.CTTransform2D;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STCompoundLine;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
 \r
 /**\r
@@ -97,23 +123,21 @@ public abstract class XSLFSimpleShape extends XSLFShape
     }\r
 \r
     @Override\r
-    public Rectangle2D getAnchor() {\r
+    public Rectangle getAnchor() {\r
 \r
         CTTransform2D xfrm = getXfrm();\r
 \r
         CTPoint2D off = xfrm.getOff();\r
-        long x = off.getX();\r
-        long y = off.getY();\r
+        int x = (int)Units.toPoints(off.getX());\r
+        int y = (int)Units.toPoints(off.getY());\r
         CTPositiveSize2D ext = xfrm.getExt();\r
-        long cx = ext.getCx();\r
-        long cy = ext.getCy();\r
-        return new Rectangle2D.Double(\r
-                Units.toPoints(x), Units.toPoints(y),\r
-                Units.toPoints(cx), Units.toPoints(cy));\r
+        int cx = (int)Units.toPoints(ext.getCx());\r
+        int cy = (int)Units.toPoints(ext.getCy());\r
+        return new Rectangle(x, y, cx, cy);\r
     }\r
 \r
     @Override\r
-    public void setAnchor(Rectangle2D anchor) {\r
+    public void setAnchor(Rectangle anchor) {\r
         CTTransform2D xfrm = getSafeXfrm();\r
         CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();\r
         long x = Units.toEMU(anchor.getX());\r
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShowFactory.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShowFactory.java
new file mode 100644 (file)
index 0000000..346d81b
--- /dev/null
@@ -0,0 +1,100 @@
+/* ====================================================================\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
+\r
+package org.apache.poi.xslf.usermodel;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+\r
+import org.apache.poi.EncryptedDocumentException;\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.sl.usermodel.SlideShow;\r
+import org.apache.poi.sl.usermodel.SlideShowFactory;\r
+import org.apache.poi.util.Internal;\r
+\r
+@Internal\r
+public class XSLFSlideShowFactory extends SlideShowFactory {\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
+     * @throws InvalidFormatException \r
+     */\r
+    public static SlideShow<?,?> createSlideShow(OPCPackage pkg) throws IOException {\r
+        try {\r
+            return new XMLSlideShow(pkg);\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
+     * Creates the XMLSlideShow from the given File, which must exist and be readable.\r
+     * <p>Note that in order to properly release resources theSlideShow should be closed after use.\r
+     *\r
+     *  @param file The file to read data from.\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 EncryptedDocumentException If the wrong password is given for a protected file\r
+     */\r
+    @SuppressWarnings("resource")\r
+    public static SlideShow<?,?> createSlideShow(File file, boolean readOnly)\r
+    throws IOException, InvalidFormatException {\r
+        OPCPackage pkg = OPCPackage.open(file, readOnly ? PackageAccess.READ : PackageAccess.READ_WRITE);\r
+        return createSlideShow(pkg);\r
+    }\r
+\r
+    /**\r
+     * Creates a XMLSlideShow from the given InputStream\r
+     *\r
+     * <p>Note that in order to properly release resources the\r
+     * SlideShow should be closed after use.</p>\r
+     *\r
+     * @param stream 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 \r
+     */\r
+    @SuppressWarnings("resource")\r
+    public static SlideShow<?,?> createSlideShow(InputStream stream) throws IOException, InvalidFormatException {\r
+        OPCPackage pkg = OPCPackage.open(stream);\r
+        return createSlideShow(pkg);\r
+    }\r
+\r
+}\r
index 034b50cddb287b972f5458647341b6291ff2f9db..8cc90f979f0738570cbd692e59af153be6808c8d 100644 (file)
@@ -19,7 +19,7 @@
 
 package org.apache.poi.xslf.usermodel;
 
-import java.awt.geom.Rectangle2D;
+import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -466,8 +466,8 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
      *
      * @return a <code>Rectangle2D</code> that is the bounds of this shape.
      */
-    public Rectangle2D resizeToFitText(){
-        Rectangle2D anchor = getAnchor();
+    public Rectangle resizeToFitText(){
+        Rectangle anchor = getAnchor();
         if(anchor.getWidth() == 0.)  throw new POIXMLException(
                 "Anchor of the shape was not set.");
         double height = getTextHeight(); 
index 9318a08941b60f4162a06760f5b2aea75df2149a..2f97426935ad101c639d953cbf5522f7232242eb 100644 (file)
@@ -31,10 +31,10 @@ import java.util.Map;
 \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.sl.usermodel.SlideShowFactory;\r
 import org.apache.poi.util.JvmBugs;\r
 \r
 /**\r
diff --git a/src/ooxml/testcases/org/apache/poi/sl/draw/TestDrawPictureShape.java b/src/ooxml/testcases/org/apache/poi/sl/draw/TestDrawPictureShape.java
new file mode 100644 (file)
index 0000000..2fd0be3
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+package org.apache.poi.sl.draw;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.sl.usermodel.PictureData;
+import org.apache.poi.sl.usermodel.PictureShape;
+import org.apache.poi.sl.usermodel.RectAlign;
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.sl.usermodel.Slide;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.sl.usermodel.SlideShowFactory;
+import org.junit.Test;
+
+public class TestDrawPictureShape {
+    final static POIDataSamples ssSamples = POIDataSamples.getSlideShowInstance();
+
+    @Test
+    public void testResize() throws Exception {
+        String files[] = { "pictures.ppt", "shapes.pptx" };
+        for (String file : files) {
+            SlideShow<?,?> ss = SlideShowFactory.create(ssSamples.getFile(file));
+            Slide<?,?> slide = ss.getSlides().get(0);
+            PictureShape<?,?> picShape = null;
+            for (Shape<?,?> shape : slide.getShapes()) {
+                if (shape instanceof PictureShape) {
+                    picShape = (PictureShape<?,?>)shape;
+                    break;
+                }
+            }
+            assertNotNull(picShape);
+            PictureData pd = picShape.getPictureData();
+            Dimension dimPd = pd.getImageDimension();
+            new DrawPictureShape(picShape).resize();
+            Dimension dimShape = picShape.getAnchor().getSize();
+            assertEquals(dimPd, dimShape);
+            
+            int newWidth = (int)(dimPd.getWidth()*(100d/dimPd.getHeight()));
+            // ... -1 is a rounding error
+            Rectangle expRect = new Rectangle(50+300-newWidth-1, 50, newWidth, 100);
+            Rectangle target = new Rectangle(50,50,300,100);
+            new DrawPictureShape(picShape).resize(target, RectAlign.BOTTOM_RIGHT);
+            Rectangle actRect = picShape.getAnchor();
+            assertEquals(expRect, actRect);
+        }
+    }
+    
+    
+}
index 4a6e0ff2a0772765d1985a2bbb473aacd195c0fb..f5d180121aec8e180e6ea4bf06466e48b22c3425 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.assertSame;\r
+import static org.junit.Assert.assertTrue;\r
 \r
 import java.awt.Dimension;\r
-import java.awt.geom.Rectangle2D;\r
+import java.awt.Rectangle;\r
 \r
 import org.junit.Test;\r
 \r
@@ -29,7 +31,7 @@ import org.junit.Test;
 public class TestXSLFGroupShape {\r
 \r
     @Test\r
-    public void testCreateShapes() {\r
+    public void testCreateShapes() throws Exception {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
 \r
@@ -38,11 +40,11 @@ public class TestXSLFGroupShape {
         XSLFGroupShape group = slide.createGroup();\r
         assertEquals(1, slide.getShapes().size());\r
 \r
-        Rectangle2D interior = new Rectangle2D.Double(-10, -10, 20, 20);\r
+        Rectangle interior = new Rectangle(-10, -10, 20, 20);\r
         group.setInteriorAnchor(interior);\r
         assertEquals(interior, group.getInteriorAnchor());\r
 \r
-        Rectangle2D anchor = new Rectangle2D.Double(0, 0, 792, 612);\r
+        Rectangle anchor = new Rectangle(0, 0, 792, 612);\r
         group.setAnchor(anchor);\r
         assertEquals(anchor, group.getAnchor());\r
 \r
@@ -83,10 +85,12 @@ public class TestXSLFGroupShape {
         group.removeShape(shape1);\r
         group.removeShape(shape4);\r
         assertTrue(group.getShapes().isEmpty());\r
+        \r
+        ppt.close();\r
     }\r
 \r
     @Test\r
-    public void testRemoveShapes() {\r
+    public void testRemoveShapes() throws Exception {\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
 \r
@@ -99,5 +103,6 @@ public class TestXSLFGroupShape {
         slide.removeShape(group2);\r
         slide.removeShape(group3);\r
 \r
+        ppt.close();\r
     }\r
 }
\ No newline at end of file
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShowFactory.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShowFactory.java
new file mode 100644 (file)
index 0000000..8b9ac97
--- /dev/null
@@ -0,0 +1,66 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.xslf.usermodel;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.GeneralSecurityException;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.poifs.crypt.EncryptionInfo;
+import org.apache.poi.poifs.crypt.EncryptionMode;
+import org.apache.poi.poifs.crypt.Encryptor;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.sl.usermodel.BaseTestSlideShowFactory;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.TempFile;
+import org.junit.Test;
+
+public final class TestXSLFSlideShowFactory extends BaseTestSlideShowFactory {
+    private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
+    
+    @Test
+    public void testFactory() throws Exception {
+        File pFile = createProtected("SampleShow.pptx", "foobaa");
+        testFactory("SampleShow.pptx", pFile.getAbsolutePath(), "foobaa");
+    }
+    
+    private static File createProtected(String basefile, String password)
+    throws IOException, GeneralSecurityException {
+        NPOIFSFileSystem fs = new NPOIFSFileSystem();
+        EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
+        Encryptor enc = info.getEncryptor();
+        enc.confirmPassword(password);
+        InputStream fis = _slTests.openResourceAsStream("SampleShow.pptx");
+        OutputStream os = enc.getDataStream(fs);
+        IOUtils.copy(fis, os);
+        os.close();
+        fis.close();
+        
+        File tf = TempFile.createTempFile("test-xslf-slidefactory", "pptx");
+        FileOutputStream fos = new FileOutputStream(tf);
+        fs.writeFilesystem(fos);
+        fos.close();
+        fs.close();
+
+        return tf;
+    }
+}
index a2ddfadbbcab97e0a4437c20f79225c6e2782de4..a57771080d187ec35ad772aaf4c093431f6e44db 100644 (file)
@@ -25,7 +25,6 @@ import static org.junit.Assert.assertTrue;
 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
@@ -75,7 +74,7 @@ public class TestXSLFTextParagraph {
                 "of text within a shape. Properties here apply to all text " +\r
                 "residing within the corresponding paragraph.");\r
 \r
-        Rectangle2D anchor = new Rectangle(50, 50, 300, 200);\r
+        Rectangle anchor = new Rectangle(50, 50, 300, 200);\r
         sh.setAnchor(anchor);\r
         \r
         DrawTextParagraphProxy dtp = new DrawTextParagraphProxy(p);\r
index c25d7de84f559ad8bba98d84671cba713bc213ad..f584bd8a8b0dba600e4eae768c831aec0347d232 100644 (file)
@@ -26,6 +26,7 @@ import java.io.IOException;
 import javax.imageio.ImageIO;
 
 import org.apache.poi.hslf.usermodel.HSLFPictureData;
+import org.apache.poi.util.Units;
 
 /**
  * Represents a bitmap picture data:  JPEG or PNG.
@@ -55,10 +56,14 @@ public abstract class Bitmap extends HSLFPictureData {
         setRawData(out.toByteArray());
     }
 
+    @Override
     public Dimension getImageDimension() {
         try {
             BufferedImage bi = ImageIO.read(new ByteArrayInputStream(getData()));
-            return new Dimension(bi.getWidth(), bi.getHeight());
+            return new Dimension(
+                (int)Units.pixelToPoints(bi.getWidth()),
+                (int)Units.pixelToPoints(bi.getHeight())
+            );
         } catch (IOException e) {
             return new Dimension(200,200);
         }
index 74a793f5abab7d32f0152ceebad2cc5166765fb9..55a62ebffafc585230dfe5d012182d023e13d19c 100644 (file)
@@ -126,7 +126,7 @@ public abstract class Metafile extends HSLFPictureData {
         return out.toByteArray();
     }
 
-
+    @Override
     public Dimension getImageDimension() {
         int prefixLen = 16*uidInstanceCount;
         Header header = new Header();
index 7ba654c02a8d589af96b5f8f31f1b81e535d6653..834dea5ff0e329b04fe0edeecbb99218e223f171 100644 (file)
@@ -42,7 +42,6 @@ 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;
@@ -327,7 +326,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable {
           Java graphics sets string coordinates by the baseline of the first character
           so we need to shift down by the height of the textbox
         */
-        txt.setAnchor(new Rectangle2D.Float(x, y, width, height));
+        txt.setAnchor(new Rectangle((int)x, (int)y, (int)width, (int)height));
 
         _group.addShape(txt);
     }
index e576cceef45181dc390654c809f83b4c27abdbb6..dbfc6ec1fc6fb438d1b5f6f60cffd0ade6ba94b2 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hslf.usermodel;
 
+import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.GeneralPath;
 import java.awt.geom.PathIterator;
@@ -45,7 +46,6 @@ import org.apache.poi.util.Units;
  * Shapes drawn with the "Freeform" tool have cubic bezier curve segments in the smooth sections
  * and straight-line segments in the straight sections. This object closely corresponds to <code>java.awt.geom.GeneralPath</code>.
  * </p>
- * @author Yegor Kozlov
  */
 public final class HSLFFreeformShape extends HSLFAutoShape implements FreeformShape<HSLFShape,HSLFTextParagraph> {
 
@@ -90,7 +90,7 @@ public final class HSLFFreeformShape extends HSLFAutoShape implements FreeformSh
 
     @Override
     public int setPath(GeneralPath path) {
-        Rectangle2D bounds = path.getBounds2D();
+        Rectangle bounds = path.getBounds();
         PathIterator it = path.getPathIterator(new AffineTransform());
 
         List<byte[]> segInfo = new ArrayList<byte[]>();
@@ -241,7 +241,7 @@ public final class HSLFFreeformShape extends HSLFAutoShape implements FreeformSh
             }
         }
         
-        Rectangle2D anchor = getAnchor2D();
+        Rectangle2D anchor = getAnchor();
         Rectangle2D bounds = path.getBounds2D();
         AffineTransform at = new AffineTransform();
         at.translate(anchor.getX(), anchor.getY());
index 0ba1d379be4da9910107ee816c242af3b2535012..22317fb62ad0c571020184f69286d8d5776553d4 100644 (file)
@@ -18,7 +18,6 @@
 package org.apache.poi.hslf.usermodel;
 
 import java.awt.Rectangle;
-import java.awt.geom.Rectangle2D;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -105,7 +104,7 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
     }
 
     @Override
-    public void setInteriorAnchor(Rectangle2D anchor){
+    public void setInteriorAnchor(Rectangle anchor){
         EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
 
         int x1 = Units.pointsToMaster(anchor.getX());
@@ -121,13 +120,13 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
     }
 
     @Override
-    public Rectangle2D getInteriorAnchor(){
+    public Rectangle getInteriorAnchor(){
         EscherSpgrRecord rec = getEscherChild(EscherSpgrRecord.RECORD_ID);
-        double x1 = Units.masterToPoints(rec.getRectX1());
-        double y1 = Units.masterToPoints(rec.getRectY1());
-        double x2 = Units.masterToPoints(rec.getRectX2());
-        double y2 = Units.masterToPoints(rec.getRectY2());
-        return new Rectangle2D.Double(x1,y1,x2-x1,y2-y1);
+        int x1 = (int)Units.masterToPoints(rec.getRectX1());
+        int y1 = (int)Units.masterToPoints(rec.getRectY1());
+        int x2 = (int)Units.masterToPoints(rec.getRectX2());
+        int y2 = (int)Units.masterToPoints(rec.getRectY2());
+        return new Rectangle(x1,y1,x2-x1,y2-y1);
     }
 
     /**
@@ -181,7 +180,7 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
      * @param y the y coordinate of the top left corner of the shape in new location
      */
     public void moveTo(int x, int y){
-        java.awt.Rectangle anchor = getAnchor();
+        Rectangle anchor = getAnchor();
         int dx = x - anchor.x;
         int dy = y - anchor.y;
         anchor.translate(dx, dy);
@@ -189,7 +188,7 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
 
         
         for (HSLFShape shape : getShapes()) {
-            java.awt.Rectangle chanchor = shape.getAnchor();
+            Rectangle chanchor = shape.getAnchor();
             chanchor.translate(dx, dy);
             shape.setAnchor(chanchor);
         }
@@ -201,7 +200,7 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
      *
      * @return the anchor of this shape group
      */
-    public Rectangle2D getAnchor2D(){
+    public Rectangle getAnchor(){
         EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
         int x1,y1,x2,y2;
         if(clientAnchor == null){
@@ -217,11 +216,11 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
             x2 = clientAnchor.getDx1();
             y2 = clientAnchor.getRow1();
         }
-        Rectangle2D anchor= new Rectangle2D.Double(
-            (x1 == -1 ? -1 : Units.masterToPoints(x1)),
-            (y1 == -1 ? -1 : Units.masterToPoints(y1)),
-            (x2 == -1 ? -1 : Units.masterToPoints(x2-x1)),
-            (y2 == -1 ? -1 : Units.masterToPoints(y2-y1))
+        Rectangle anchor= new Rectangle(
+            (int)(x1 == -1 ? -1 : Units.masterToPoints(x1)),
+            (int)(y1 == -1 ? -1 : Units.masterToPoints(y1)),
+            (int)(x2 == -1 ? -1 : Units.masterToPoints(x2-x1)),
+            (int)(y2 == -1 ? -1 : Units.masterToPoints(y2-y1))
         );
 
         return anchor;
index 0100658fe40cee45396ba63d1c3739698ef8e059..7c5fc5179e01d9d7e0eaf5447e65371a149d0b44 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hslf.usermodel;
 
+import java.awt.Dimension;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.security.MessageDigest;
@@ -219,4 +220,13 @@ public abstract class HSLFPictureData implements PictureData {
     public final String getContentType() {
         return getType().contentType;
     }
+
+    @Override
+    public Dimension getImageDimensionInPixels() {
+        Dimension dim = getImageDimension();
+        return new Dimension(
+            Units.pointsToPixel(dim.getWidth()),
+            Units.pointsToPixel(dim.getHeight())
+        );
+    }
 }
index 58ce1a1f2229c62f82c73fd5e2a0b28069e6d6ed..713ecad705639f4ad1899fe3f0f145011855dded 100644 (file)
@@ -17,9 +17,8 @@
 
 package org.apache.poi.hslf.usermodel;
 
-import java.awt.Dimension;
 import java.awt.Insets;
-import java.awt.geom.Rectangle2D;
+import java.awt.Rectangle;
 import java.util.List;
 
 import org.apache.poi.ddf.AbstractEscherOptRecord;
@@ -31,6 +30,7 @@ import org.apache.poi.ddf.EscherRecord;
 import org.apache.poi.ddf.EscherSimpleProperty;
 import org.apache.poi.ddf.EscherSpRecord;
 import org.apache.poi.hslf.record.Document;
+import org.apache.poi.sl.draw.DrawPictureShape;
 import org.apache.poi.sl.usermodel.PictureShape;
 import org.apache.poi.sl.usermodel.ShapeContainer;
 import org.apache.poi.sl.usermodel.ShapeType;
@@ -113,21 +113,6 @@ public class HSLFPictureShape extends HSLFSimpleShape implements PictureShape<HS
         return _escherContainer;
     }
 
-    /**
-     * Resize this picture to the default size.
-     * For PNG and JPEG resizes the image to 100%,
-     * for other types, if the size can't be determined it will be 200x200 pixels.
-     */
-    public void setDefaultSize(){
-        Dimension dim = getPictureData().getImageDimension();
-        Rectangle2D origRect = getAnchor2D();
-        double x = origRect.getX();
-        double y = origRect.getY();
-        double w = Units.pixelToPoints((int)dim.getWidth());
-        double h = Units.pixelToPoints((int)dim.getHeight());
-        setAnchor(new Rectangle2D.Double(x, y, w, h));
-    }
-
     @Override
     public HSLFPictureData getPictureData(){
         HSLFSlideShow ppt = getSheet().getSlideShow();
@@ -199,9 +184,9 @@ public class HSLFPictureShape extends HSLFSimpleShape implements PictureShape<HS
         EscherBSERecord bse = getEscherBSERecord();
         bse.setRef(bse.getRef() + 1);
 
-        java.awt.Rectangle anchor = getAnchor();
-        if (anchor.equals(new java.awt.Rectangle())){
-            setDefaultSize();
+        Rectangle anchor = getAnchor();
+        if (anchor.isEmpty()){
+            new DrawPictureShape(this).resize();
         }
     }
 
index 2af2678b20815ce1324b302aa4235ae0959d1900..85f3a906ea4161e78b465565498b4500317d1379 100644 (file)
@@ -19,14 +19,29 @@ package org.apache.poi.hslf.usermodel;
 
 import java.awt.Color;
 import java.awt.Graphics2D;
-import java.awt.geom.Rectangle2D;
+import java.awt.Rectangle;
 import java.util.Iterator;
 
-import org.apache.poi.ddf.*;
+import org.apache.poi.ddf.AbstractEscherOptRecord;
+import org.apache.poi.ddf.EscherChildAnchorRecord;
+import org.apache.poi.ddf.EscherClientAnchorRecord;
+import org.apache.poi.ddf.EscherColorRef;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherProperty;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherSimpleProperty;
+import org.apache.poi.ddf.EscherSpRecord;
 import org.apache.poi.hslf.record.ColorSchemeAtom;
 import org.apache.poi.hslf.record.RecordTypes;
-import org.apache.poi.sl.usermodel.*;
-import org.apache.poi.util.*;
+import org.apache.poi.sl.usermodel.FillStyle;
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.Units;
 
 /**
  *  <p>
@@ -126,18 +141,7 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> {
      *
      * @return the anchor of this shape
      */
-    public java.awt.Rectangle getAnchor(){
-        Rectangle2D anchor2d = getAnchor2D();
-        return anchor2d.getBounds();
-    }
-
-    /**
-     * Returns the anchor (the bounding box rectangle) of this shape.
-     * All coordinates are expressed in points (72 dpi).
-     *
-     * @return the anchor of this shape
-     */
-    public Rectangle2D getAnchor2D(){
+    public Rectangle getAnchor() {
         EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
         int flags = spRecord.getFlags();
         int x1,y1,x2,y2;
@@ -160,11 +164,11 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> {
         }
 
         // TODO: find out where this -1 value comes from at #57820 (link to ms docs?)
-        Rectangle2D anchor = new Rectangle2D.Double(
-            (x1 == -1 ? -1 : Units.masterToPoints(x1)),
-            (y1 == -1 ? -1 : Units.masterToPoints(y1)),
-            (x2 == -1 ? -1 : Units.masterToPoints(x2-x1)),
-            (y2 == -1 ? -1 : Units.masterToPoints(y2-y1))
+        Rectangle anchor = new Rectangle(
+            (int)(x1 == -1 ? -1 : Units.masterToPoints(x1)),
+            (int)(y1 == -1 ? -1 : Units.masterToPoints(y1)),
+            (int)(x2 == -1 ? -1 : Units.masterToPoints(x2-x1)),
+            (int)(y2 == -1 ? -1 : Units.masterToPoints(y2-y1))
         );
         
         return anchor;
@@ -176,7 +180,7 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> {
      *
      * @param anchor new anchor
      */
-    public void setAnchor(Rectangle2D anchor){
+    public void setAnchor(Rectangle anchor){
         int x = Units.pointsToMaster(anchor.getX());
         int y = Units.pointsToMaster(anchor.getY());
         int w = Units.pointsToMaster(anchor.getWidth() + anchor.getX());
@@ -206,7 +210,7 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> {
      * @param y the y coordinate of the top left corner of the shape
      */
     public void moveTo(float x, float y){
-        Rectangle2D anchor = getAnchor2D();
+        Rectangle anchor = getAnchor();
         anchor.setRect(x, y, anchor.getWidth(), anchor.getHeight());
         setAnchor(anchor);
     }
index aeb36beb56316c0e4b00a2ec871e956a1e72d911..dc5cde23d47e6117507d949896b6227c6b308faa 100644 (file)
@@ -414,12 +414,12 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
         return clr == null ? Color.black : clr;
     }    
     
-    public Shadow getShadow() {
+    public Shadow<HSLFShape,HSLFTextParagraph> getShadow() {
         AbstractEscherOptRecord opt = getEscherOptRecord();
         EscherProperty shadowType = opt.lookup(EscherProperties.SHADOWSTYLE__TYPE);
         if (shadowType == null) return null;
         
-        return new Shadow(){
+        return new Shadow<HSLFShape,HSLFTextParagraph>(){
             public SimpleShape<HSLFShape,HSLFTextParagraph> getShadowParent() {
                 return HSLFSimpleShape.this;
             }
index 697f10521abc25cf1c317cdfb4d37591a0bb25da..c300bd81c22d86440e2a2be5aad87f0c5a0cf0c9 100644 (file)
@@ -69,6 +69,7 @@ import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
 import org.apache.poi.hslf.record.SlidePersistAtom;
 import org.apache.poi.hslf.record.UserEditAtom;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.sl.usermodel.MasterSheet;
 import org.apache.poi.sl.usermodel.PictureData.PictureType;
@@ -159,8 +160,8 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
     /**
      * Constructs a Powerpoint document from an POIFSFileSystem.
      */
-    public HSLFSlideShow(POIFSFileSystem inputStream) throws IOException {
-        this(new HSLFSlideShowImpl(inputStream));
+    public HSLFSlideShow(NPOIFSFileSystem npoifs) throws IOException {
+        this(new HSLFSlideShowImpl(npoifs));
     }
 
     /**
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowFactory.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowFactory.java
new file mode 100644 (file)
index 0000000..3ae91f7
--- /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
+\r
+package org.apache.poi.hslf.usermodel;\r
+\r
+import java.io.IOException;\r
+\r
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;\r
+import org.apache.poi.sl.usermodel.SlideShow;\r
+import org.apache.poi.sl.usermodel.SlideShowFactory;\r
+import org.apache.poi.util.Internal;\r
+\r
+@Internal\r
+public class HSLFSlideShowFactory extends SlideShowFactory {\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<?,?> createSlideShow(NPOIFSFileSystem fs) throws IOException {\r
+        return new HSLFSlideShow(fs);\r
+    }\r
+\r
+}\r
index 5ca39b991960d5ea9cfe3c39349911b5b06d75c7..1b5bbb83fd08d279ec23b68066d22d3aaa974799 100644 (file)
@@ -139,15 +139,15 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
 
         storeText();
         
-        EscherTextboxWrapper _txtbox = getEscherTextboxWrapper();
-        if(_txtbox != null){
-            _escherContainer.addChildRecord(_txtbox.getEscherRecord());
+        EscherTextboxWrapper thisTxtbox = getEscherTextboxWrapper();
+        if(thisTxtbox != null){
+            _escherContainer.addChildRecord(thisTxtbox.getEscherRecord());
             
             PPDrawing ppdrawing = sh.getPPDrawing();
-            ppdrawing.addTextboxWrapper(_txtbox);
+            ppdrawing.addTextboxWrapper(thisTxtbox);
             // Ensure the escher layer knows about the added records
             try {
-                _txtbox.writeOut(null);
+                thisTxtbox.writeOut(null);
             } catch (IOException e){
                 throw new HSLFException(e);
             }
@@ -192,10 +192,10 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
      * @return a <code>Rectangle2D</code> that is the bounds of this shape.
      */
     public Rectangle2D resizeToFitText(){
-        Rectangle2D anchor = getAnchor();
+        Rectangle anchor = getAnchor();
         if(anchor.getWidth() == 0.) {
             logger.log(POILogger.WARN, "Width of shape wasn't set. Defaulting to 200px");
-            anchor = new Rectangle2D.Double(anchor.getX(), anchor.getY(), 200, anchor.getHeight());
+            anchor.setSize(200, (int)anchor.getHeight());
             setAnchor(anchor);
         }
         double height = getTextHeight(); 
index df696d021d63ed395df8887b8067417a1f2b06be..7b6e762cf68c3bd5bcedcd5682e9102c45702f90 100644 (file)
@@ -21,7 +21,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import java.awt.geom.Rectangle2D;
+import java.awt.Rectangle;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 
@@ -34,8 +34,6 @@ import org.junit.Test;
 
 /**
  * Test <code>MovieShape</code> object.
- *
- * @author Yegor Kozlov
  */
 public final class TestMovieShape {
 
@@ -52,7 +50,7 @@ public final class TestMovieShape {
         HSLFPictureData thumbnailData = ppt.addPicture(_slTests.readFile("tomcat.png"), PictureType.PNG);
 
         MovieShape shape = new MovieShape(movieIdx, thumbnailData);
-        shape.setAnchor(new Rectangle2D.Float(300,225,120,90));
+        shape.setAnchor(new Rectangle(300,225,120,90));
         slide.addShape(shape);
 
         assertEquals(path, shape.getPath());
index a03c253130163d978a64af05912b9b41b966e8e5..5babd1bf89bc33575dbea5fbd03e96f051f8f623 100644 (file)
@@ -20,18 +20,26 @@ package org.apache.poi.hslf.model;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 
-import java.awt.geom.Rectangle2D;
-import java.io.*;
+import java.awt.Rectangle;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
 import java.util.List;
 
 import org.apache.poi.POIDataSamples;
-import org.apache.poi.hslf.usermodel.*;
+import org.apache.poi.hslf.usermodel.HSLFObjectData;
+import org.apache.poi.hslf.usermodel.HSLFPictureData;
+import org.apache.poi.hslf.usermodel.HSLFShape;
+import org.apache.poi.hslf.usermodel.HSLFSlide;
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hwpf.HWPFDocument;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-import org.apache.poi.util.IOUtils;
 import org.apache.poi.sl.usermodel.PictureData.PictureType;
+import org.apache.poi.util.IOUtils;
 import org.junit.Test;
 
 public final class TestOleEmbedding {
@@ -109,7 +117,7 @@ public final class TestOleEmbedding {
        OLEShape oleShape1 = new OLEShape(pictData);
        oleShape1.setObjectID(oleObjectId1);
        slide1.addShape(oleShape1);
-       oleShape1.setAnchor(new Rectangle2D.Double(100,100,100,100));
+       oleShape1.setAnchor(new Rectangle(100,100,100,100));
        
        // add second slide with different order in object creation
        HSLFSlide slide2 = ppt.createSlide();
@@ -123,7 +131,7 @@ public final class TestOleEmbedding {
 
         oleShape2.setObjectID(oleObjectId2);
         slide2.addShape(oleShape2);
-        oleShape2.setAnchor(new Rectangle2D.Double(100,100,100,100));
+        oleShape2.setAnchor(new Rectangle(100,100,100,100));
         
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ppt.write(bos);
index 3dfdd578336d85366c6d137f0260ed2d72742c56..f7fe4c43f4ec76336ad1bc9dc5fe4e9828c88088 100644 (file)
@@ -27,7 +27,6 @@ import static org.junit.Assert.assertTrue;
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Rectangle;
-import java.awt.geom.Rectangle2D;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -63,8 +62,6 @@ import org.junit.Test;
 
 /**
  * Test drawing shapes via Graphics2D
- *
- * @author Yegor Kozlov
  */
 public final class TestShapes {
     private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
@@ -165,8 +162,8 @@ public final class TestShapes {
     @SuppressWarnings("unused")
     @Test
     public void testParagraphs() throws Exception {
-        HSLFSlideShow ppt = new HSLFSlideShow();
-        HSLFSlide slide = ppt.createSlide();
+        HSLFSlideShow ss = new HSLFSlideShow();
+        HSLFSlide slide = ss.createSlide();
         HSLFTextBox shape = new HSLFTextBox();
         HSLFTextRun p1r1 = shape.setText("para 1 run 1. ");
         HSLFTextRun p1r2 = shape.appendText("para 1 run 2.", false);
@@ -178,15 +175,15 @@ public final class TestShapes {
         p2r2.setStrikethrough(true);
         // run 3 has same text properties as run 2 and will be merged when saving
         HSLFTextRun p2r3 = shape.appendText("para 2 run 3.", false);
-        shape.setAnchor(new Rectangle2D.Double(100,100,100,10));
+        shape.setAnchor(new Rectangle(100,100,100,10));
         slide.addShape(shape);
         shape.resizeToFitText();
         
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        ppt.write(bos);
+        ss.write(bos);
         
-        ppt = new HSLFSlideShow(new ByteArrayInputStream(bos.toByteArray()));
-        slide = ppt.getSlides().get(0);
+        ss = new HSLFSlideShow(new ByteArrayInputStream(bos.toByteArray()));
+        slide = ss.getSlides().get(0);
         HSLFTextBox tb = (HSLFTextBox)slide.getShapes().get(0);
         List<HSLFTextParagraph> para = tb.getTextParagraphs();
         HSLFTextRun tr = para.get(0).getTextRuns().get(0);
@@ -289,8 +286,8 @@ public final class TestShapes {
     }
 
     private void textBoxSet(String filename) throws Exception {
-        HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream(filename));
-        for (HSLFSlide sld : ppt.getSlides()) {
+        HSLFSlideShow ss = new HSLFSlideShow(_slTests.openResourceAsStream(filename));
+        for (HSLFSlide sld : ss.getSlides()) {
             ArrayList<String> lst1 = new ArrayList<String>();
             for (List<HSLFTextParagraph> txt : sld.getTextParagraphs()) {
                 for (HSLFTextParagraph p : txt) {
@@ -321,17 +318,17 @@ public final class TestShapes {
      */
     @Test
     public void shapeGroup() throws Exception {
-        HSLFSlideShow ppt = new HSLFSlideShow();
+        HSLFSlideShow ss = new HSLFSlideShow();
 
-        HSLFSlide slide = ppt.createSlide();
-        Dimension pgsize = ppt.getPageSize();
+        HSLFSlide slide = ss.createSlide();
+        Dimension pgsize = ss.getPageSize();
 
         HSLFGroupShape group = new HSLFGroupShape();
 
         group.setAnchor(new Rectangle(0, 0, (int)pgsize.getWidth(), (int)pgsize.getHeight()));
         slide.addShape(group);
 
-        HSLFPictureData data = ppt.addPicture(_slTests.readFile("clock.jpg"), PictureType.JPEG);
+        HSLFPictureData data = ss.addPicture(_slTests.readFile("clock.jpg"), PictureType.JPEG);
         HSLFPictureShape pict = new HSLFPictureShape(data, group);
         pict.setAnchor(new Rectangle(0, 0, 200, 200));
         group.addShape(pict);
@@ -342,14 +339,14 @@ public final class TestShapes {
 
         //serialize and read again.
         ByteArrayOutputStream  out = new ByteArrayOutputStream();
-        ppt.write(out);
+        ss.write(out);
         out.close();
 
         ByteArrayInputStream is = new ByteArrayInputStream(out.toByteArray());
-        ppt = new HSLFSlideShow(is);
+        ss = new HSLFSlideShow(is);
         is.close();
 
-        slide = ppt.getSlides().get(0);
+        slide = ss.getSlides().get(0);
 
         List<HSLFShape> shape = slide.getShapes();
         assertEquals(1, shape.size());
@@ -374,8 +371,8 @@ public final class TestShapes {
     @Test
     public void removeShapes() throws IOException {
         String file = "with_textbox.ppt";
-        HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream(file));
-        HSLFSlide sl = ppt.getSlides().get(0);
+        HSLFSlideShow ss = new HSLFSlideShow(_slTests.openResourceAsStream(file));
+        HSLFSlide sl = ss.getSlides().get(0);
         List<HSLFShape> sh = sl.getShapes();
         assertEquals("expected four shaped in " + file, 4, sh.size());
         //remove all
@@ -388,11 +385,11 @@ public final class TestShapes {
 
         //serialize and read again. The file should be readable and contain no shapes
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        ppt.write(out);
+        ss.write(out);
         out.close();
 
-        ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
-        sl = ppt.getSlides().get(0);
+        ss = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
+        sl = ss.getSlides().get(0);
         assertEquals("expected 0 shaped in " + file, 0, sl.getShapes().size());
     }
 
@@ -413,12 +410,12 @@ public final class TestShapes {
 
     @Test
     public void shapeId() {
-        HSLFSlideShow ppt = new HSLFSlideShow();
-        HSLFSlide slide = ppt.createSlide();
+        HSLFSlideShow ss = new HSLFSlideShow();
+        HSLFSlide slide = ss.createSlide();
         HSLFShape shape = null;
 
         //EscherDgg is a document-level record which keeps track of the drawing groups
-        EscherDggRecord dgg = ppt.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
+        EscherDggRecord dgg = ss.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
         EscherDgRecord dg = slide.getSheetContainer().getPPDrawing().getEscherDgRecord();
 
         int dggShapesUsed = dgg.getNumShapesSaved();   //total number of shapes in the ppt
@@ -463,8 +460,8 @@ public final class TestShapes {
 
     @Test
     public void lineColor() throws IOException {
-        HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("51731.ppt"));
-        List<HSLFShape> shape = ppt.getSlides().get(0).getShapes();
+        HSLFSlideShow ss = new HSLFSlideShow(_slTests.openResourceAsStream("51731.ppt"));
+        List<HSLFShape> shape = ss.getSlides().get(0).getShapes();
 
         assertEquals(4, shape.size());
 
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShowFactory.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShowFactory.java
new file mode 100644 (file)
index 0000000..9c305ef
--- /dev/null
@@ -0,0 +1,28 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hslf.usermodel;
+
+import org.apache.poi.sl.usermodel.BaseTestSlideShowFactory;
+import org.junit.Test;
+
+public final class TestHSLFSlideShowFactory extends BaseTestSlideShowFactory {
+    @Test
+    public void testFactory() throws Exception {
+        testFactory("pictures.ppt", "Password_Protected-hello.ppt", "hello");
+    }
+}
index d45f18222cd71a8acc86b013761c68017597dc46..3afcfe5962cc253736f4d7a70e7bc9e72cb241d4 100644 (file)
@@ -35,6 +35,7 @@ import org.apache.poi.hslf.blip.PICT;
 import org.apache.poi.hslf.blip.PNG;
 import org.apache.poi.hslf.blip.WMF;
 import org.apache.poi.sl.usermodel.PictureData.PictureType;
+import org.apache.poi.util.Units;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -46,8 +47,6 @@ import org.junit.Test;
 public final class TestPictures {
     private static POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
 
-    //protected File cwd;
-
     /**
      * Test read/write Macintosh PICT
      */
@@ -64,9 +63,9 @@ public final class TestPictures {
         assertEquals(expWidth, nDim.getWidth(), 0);
         assertEquals(expHeight, nDim.getHeight(), 0);
         
-        Dimension dim = data.getImageDimension();
-        assertEquals(expWidth, dim.getWidth(), 0);
-        assertEquals(expHeight, dim.getHeight(), 0);
+        Dimension dim = data.getImageDimensionInPixels();
+        assertEquals(Units.pointsToPixel(expWidth), dim.getWidth(), 0);
+        assertEquals(Units.pointsToPixel(expHeight), dim.getHeight(), 0);
         
         HSLFPictureShape pict = new HSLFPictureShape(data);
         assertEquals(data.getIndex(), pict.getPictureIndex());
@@ -127,9 +126,9 @@ public final class TestPictures {
         assertEquals(expWidth, nDim.getWidth(), 0);
         assertEquals(expHeight, nDim.getHeight(), 0);
 
-        Dimension dim = data.getImageDimension();
-        assertEquals(expWidth, dim.getWidth(), 0);
-        assertEquals(expHeight, dim.getHeight(), 0);
+        Dimension dim = data.getImageDimensionInPixels();
+        assertEquals(Units.pointsToPixel(expWidth), dim.getWidth(), 0);
+        assertEquals(Units.pointsToPixel(expHeight), dim.getHeight(), 0);
         
         HSLFPictureShape pict = new HSLFPictureShape(data);
         assertEquals(data.getIndex(), pict.getPictureIndex());
@@ -189,9 +188,9 @@ public final class TestPictures {
         assertEquals(expWidth, nDim.getWidth(), 0);
         assertEquals(expHeight, nDim.getHeight(), 0);
 
-        Dimension dim = data.getImageDimension();
-        assertEquals(expWidth, dim.getWidth(), 0);
-        assertEquals(expHeight, dim.getHeight(), 0);
+        Dimension dim = data.getImageDimensionInPixels();
+        assertEquals(Units.pointsToPixel(expWidth), dim.getWidth(), 0);
+        assertEquals(Units.pointsToPixel(expHeight), dim.getHeight(), 0);
         
         HSLFPictureShape pict = new HSLFPictureShape(data);
         assertEquals(data.getIndex(), pict.getPictureIndex());
index 61bd850b6a8a63c6eebdafc3c047c62345594d50..59dd694da73dd2ae9f23ea3cd2df18a48158bf72 100644 (file)
@@ -22,19 +22,14 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.awt.Rectangle;
 import java.awt.geom.GeneralPath;
-import java.awt.geom.Rectangle2D;
 import java.net.URL;
 import java.util.Enumeration;
 import java.util.Map;
 
 import org.junit.Test;
 
-/**
- * Date: 10/24/11
- *
- * @author Yegor Kozlov
- */
 public class TestPresetGeometries {
     @Test
     public void testRead(){
@@ -43,8 +38,8 @@ public class TestPresetGeometries {
 
         for(String name : shapes.keySet()) {
             CustomGeometry geom = shapes.get(name);
-            Context ctx = new Context(geom, new Rectangle2D.Double(0, 0, 100, 100), new IAdjustableShape() {
-                public Guide getAdjustValue(String name) {
+            Context ctx = new Context(geom, new Rectangle(0, 0, 100, 100), new IAdjustableShape() {
+                public Guide getAdjustValue(String presetName) {
                     return null;
                 }
             });
diff --git a/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java b/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java
new file mode 100644 (file)
index 0000000..ab8c168
--- /dev/null
@@ -0,0 +1,73 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.sl.usermodel;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+
+public class BaseTestSlideShowFactory {
+    private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
+
+    public void testFactory(String file, String protectedFile, String password)
+    throws Exception {
+        SlideShow<?,?> ss;
+        // from file
+        ss = SlideShowFactory.create(fromFile(file));
+        assertNotNull(ss);
+        // from stream
+        ss = SlideShowFactory.create(fromStream(file));
+        assertNotNull(ss);
+        // from NPOIFS
+        if (!file.contains("pptx")) {
+            NPOIFSFileSystem npoifs = new NPOIFSFileSystem(fromFile(file));
+            ss = SlideShowFactory.create(npoifs);
+            assertNotNull(ss);
+            npoifs.close();
+        }
+        // from protected file
+        ss = SlideShowFactory.create(fromFile(protectedFile), password);
+        assertNotNull(ss);
+        // from protected stream
+        ss = SlideShowFactory.create(fromStream(protectedFile), password);
+        assertNotNull(ss);
+        // from protected NPOIFS
+        NPOIFSFileSystem npoifs = new NPOIFSFileSystem(fromFile(protectedFile));
+        ss = SlideShowFactory.create(npoifs, password);
+        assertNotNull(ss);
+        npoifs.close();
+    }
+    
+    private static File fromFile(String file) {
+        return (file.contains("/") || file.contains("\\"))
+            ? new File(file)
+            : _slTests.getFile(file);
+    }
+
+    private static InputStream fromStream(String file) throws IOException {
+        return (file.contains("/") || file.contains("\\"))
+            ? new FileInputStream(file)
+            : _slTests.openResourceAsStream(file);
+    }
+}