You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2016/01/16 01:11:01 UTC

svn commit: r1724897 - in /poi: site/src/documentation/content/xdocs/ trunk/src/java/org/apache/poi/ddf/ trunk/src/java/org/apache/poi/sl/draw/ trunk/src/java/org/apache/poi/sl/usermodel/ trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/ trunk/src/oo...

Author: kiwiwings
Date: Sat Jan 16 00:11:01 2016
New Revision: 1724897

URL: http://svn.apache.org/viewvc?rev=1724897&view=rev
Log:
#56004 - Support for WMF rendering

Added:
    poi/trunk/src/java/org/apache/poi/sl/draw/BitmapImageRenderer.java
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawGraphicalFrame.java
    poi/trunk/src/java/org/apache/poi/sl/usermodel/GraphicalFrame.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfSLImageRenderer.java
Modified:
    poi/site/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/ddf/EscherProperties.java
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
    poi/trunk/src/java/org/apache/poi/sl/draw/ImageRenderer.java
    poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java
    poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
    poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java

Modified: poi/site/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/site/src/documentation/content/xdocs/status.xml?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/site/src/documentation/content/xdocs/status.xml (original)
+++ poi/site/src/documentation/content/xdocs/status.xml Sat Jan 16 00:11:01 2016
@@ -40,6 +40,7 @@
     </devs>
 
     <release version="3.14-beta2" date="2016-??-??">
+        <action dev="PD" type="add" fixes-bug="56004">Support for WMF rendering</action>
         <action dev="PD" type="add" fixes-bug="56892">Add API for inserting ignored warnings into XSSF sheets. This can be used e.g. to suppress 'number stored as text' warnings.</action>
         <action dev="PD" type="add" fixes-bug="58847">Getters/setters/removers for the additional well-known document summary information properties from Office 12</action>
         <action dev="PD" type="add" fixes-bug="57796">Support hyperlink extraction when rendering slides</action>

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherProperties.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherProperties.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherProperties.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherProperties.java Sat Jan 16 00:11:01 2016
@@ -186,6 +186,10 @@ public final class EscherProperties {
 	public static final short LINESTYLE__HITLINETEST = 509;
 	public static final short LINESTYLE__LINEFILLSHAPE = 510;
 	public static final short LINESTYLE__NOLINEDRAWDASH = 511;
+	public static final short LINESTYLE__NOLINEDRAWDASH_LEFT = 0x057F;
+	public static final short LINESTYLE__NOLINEDRAWDASH_TOP = 0x05BF;
+	public static final short LINESTYLE__NOLINEDRAWDASH_BOTTOM = 0x063F;
+	public static final short LINESTYLE__NOLINEDRAWDASH_RIGHT = 0x05FF;
 	public static final short SHADOWSTYLE__TYPE = 512;
 	public static final short SHADOWSTYLE__COLOR = 513;
 	public static final short SHADOWSTYLE__HIGHLIGHT = 514;
@@ -488,6 +492,10 @@ public final class EscherProperties {
 		addProp(m, LINESTYLE__HITLINETEST, "linestyle.hitlinetest");
 		addProp(m, LINESTYLE__LINEFILLSHAPE, "linestyle.linefillshape");
 		addProp(m, LINESTYLE__NOLINEDRAWDASH, "linestyle.nolinedrawdash", EscherPropertyMetaData.TYPE_BOOLEAN);
+        addProp(m, LINESTYLE__NOLINEDRAWDASH_LEFT, "linestyle.nolinedrawdash.left", EscherPropertyMetaData.TYPE_BOOLEAN);
+        addProp(m, LINESTYLE__NOLINEDRAWDASH_TOP, "linestyle.nolinedrawdash.top", EscherPropertyMetaData.TYPE_BOOLEAN);
+        addProp(m, LINESTYLE__NOLINEDRAWDASH_BOTTOM, "linestyle.nolinedrawdash.bottom", EscherPropertyMetaData.TYPE_BOOLEAN);
+        addProp(m, LINESTYLE__NOLINEDRAWDASH_RIGHT, "linestyle.nolinedrawdash.right", EscherPropertyMetaData.TYPE_BOOLEAN);
 		addProp(m, SHADOWSTYLE__TYPE, "shadowstyle.type");
 		addProp(m, SHADOWSTYLE__COLOR, "shadowstyle.color", EscherPropertyMetaData.TYPE_RGB);
 		addProp(m, SHADOWSTYLE__HIGHLIGHT, "shadowstyle.highlight");

Added: poi/trunk/src/java/org/apache/poi/sl/draw/BitmapImageRenderer.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/BitmapImageRenderer.java?rev=1724897&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/BitmapImageRenderer.java (added)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/BitmapImageRenderer.java Sat Jan 16 00:11:01 2016
@@ -0,0 +1,142 @@
+/* ====================================================================
+   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 java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.RescaleOp;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.imageio.ImageIO;
+
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * For now this class renders only images supported by the javax.imageio.ImageIO framework.
+ **/
+public class BitmapImageRenderer implements ImageRenderer {
+    private final static POILogger LOG = POILogFactory.getLogger(ImageRenderer.class);
+
+    protected BufferedImage img;
+
+    @Override
+    public void loadImage(InputStream data, String contentType) throws IOException {
+        img = convertBufferedImage(ImageIO.read(data), contentType);
+    }
+
+    @Override
+    public void loadImage(byte data[], String contentType) throws IOException {
+        img = convertBufferedImage(ImageIO.read(new ByteArrayInputStream(data)), contentType);
+    }
+
+    /**
+     * Add alpha channel to buffered image
+     */
+    private static BufferedImage convertBufferedImage(BufferedImage img, String contentType) {
+        if (img == null) {
+            LOG.log(POILogger.WARN, "Content-type: "+contentType+" is not support. Image ignored.");
+            return null;
+        }
+
+        BufferedImage bi = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
+        Graphics g = bi.getGraphics();
+        g.drawImage(img, 0, 0, null);
+        g.dispose();
+        return bi;
+    }
+
+
+    /**
+     * @return the buffered image
+     */
+    public BufferedImage getImage() {
+        return img;
+    }
+
+    @Override
+    public Dimension getDimension() {
+        return (img == null)
+            ? new Dimension(0,0)
+            : new Dimension(img.getWidth(),img.getHeight());
+    }
+
+    @Override
+    public void setAlpha(double alpha) {
+        if (img == null) return;
+
+        Dimension dim = getDimension();
+        BufferedImage newImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g = newImg.createGraphics();
+        RescaleOp op = new RescaleOp(new float[]{1.0f, 1.0f, 1.0f, (float)alpha}, new float[]{0,0,0,0}, null);
+        g.drawImage(img, op, 0, 0);
+        g.dispose();
+
+        img = newImg;
+    }
+
+
+    @Override
+    public boolean drawImage(
+        Graphics2D graphics,
+        Rectangle2D anchor) {
+        return drawImage(graphics, anchor, null);
+    }
+
+    @Override
+    public boolean drawImage(
+        Graphics2D graphics,
+        Rectangle2D anchor,
+        Insets clip) {
+        if (img == null) return false;
+
+        boolean isClipped = true;
+        if (clip == null) {
+            isClipped = false;
+            clip = new Insets(0,0,0,0);
+        }
+
+        int iw = img.getWidth();
+        int ih = img.getHeight();
+
+
+        double cw = (100000-clip.left-clip.right) / 100000.0;
+        double ch = (100000-clip.top-clip.bottom) / 100000.0;
+        double sx = anchor.getWidth()/(iw*cw);
+        double sy = anchor.getHeight()/(ih*ch);
+        double tx = anchor.getX()-(iw*sx*clip.left/100000.0);
+        double ty = anchor.getY()-(ih*sy*clip.top/100000.0);
+
+        AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;
+
+        Shape clipOld = graphics.getClip();
+        if (isClipped) graphics.clip(anchor.getBounds2D());
+        graphics.drawRenderedImage(img, at);
+        graphics.setClip(clipOld);
+
+        return true;
+    }
+}

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java Sat Jan 16 00:11:01 2016
@@ -26,6 +26,7 @@ import java.text.AttributedString;
 import org.apache.poi.sl.usermodel.Background;
 import org.apache.poi.sl.usermodel.ConnectorShape;
 import org.apache.poi.sl.usermodel.FreeformShape;
+import org.apache.poi.sl.usermodel.GraphicalFrame;
 import org.apache.poi.sl.usermodel.GroupShape;
 import org.apache.poi.sl.usermodel.MasterSheet;
 import org.apache.poi.sl.usermodel.PictureShape;
@@ -87,6 +88,8 @@ public class DrawFactory {
             return getDrawable((GroupShape<?,?>)shape);
         } else if (shape instanceof PictureShape) {
             return getDrawable((PictureShape<?,?>)shape);
+        } else if (shape instanceof GraphicalFrame) {
+            return getDrawable((GraphicalFrame<?,?>)shape);
         } else if (shape instanceof Background) {
             return getDrawable((Background<?,?>)shape);
         } else if (shape instanceof ConnectorShape) {
@@ -144,6 +147,10 @@ public class DrawFactory {
         return new DrawPictureShape(shape);
     }
     
+    public DrawGraphicalFrame getDrawable(GraphicalFrame<?,?> shape) {
+        return new DrawGraphicalFrame(shape);
+    }
+    
     public DrawTextParagraph getDrawable(TextParagraph<?,?,?> paragraph) {
         return new DrawTextParagraph(paragraph);
     }

Added: poi/trunk/src/java/org/apache/poi/sl/draw/DrawGraphicalFrame.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawGraphicalFrame.java?rev=1724897&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawGraphicalFrame.java (added)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawGraphicalFrame.java Sat Jan 16 00:11:01 2016
@@ -0,0 +1,40 @@
+/* ====================================================================
+   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 java.awt.Graphics2D;
+
+import org.apache.poi.sl.usermodel.GraphicalFrame;
+import org.apache.poi.sl.usermodel.PictureShape;
+
+
+public class DrawGraphicalFrame extends DrawShape {
+
+    public DrawGraphicalFrame(GraphicalFrame<?,?> shape) {
+        super(shape);
+    }
+    
+    public void draw(Graphics2D context) {
+        PictureShape<?,?> ps = ((GraphicalFrame<?,?>)getShape()).getFallbackPicture();
+        if (ps == null) {
+            return;
+        }
+        DrawPictureShape dps = DrawFactory.getInstance(context).getDrawable(ps);
+        dps.draw(context);
+    }
+}

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java Sat Jan 16 00:11:01 2016
@@ -130,8 +130,7 @@ public class DrawPaint {
         if (is == null) return null;
         assert(graphics != null);
         
-        ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
-        if (renderer == null) renderer = new ImageRenderer();
+        ImageRenderer renderer = DrawPictureShape.getImageRenderer(graphics, fill.getContentType());
 
         try {
             renderer.loadImage(is, fill.getContentType());

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawPictureShape.java Sat Jan 16 00:11:01 2016
@@ -24,11 +24,17 @@ import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 
 import org.apache.poi.sl.usermodel.PictureData;
+import org.apache.poi.sl.usermodel.PictureData.PictureType;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
 import org.apache.poi.sl.usermodel.PictureShape;
 import org.apache.poi.sl.usermodel.RectAlign;
 
 
 public class DrawPictureShape extends DrawSimpleShape {
+    private static final POILogger LOG = POILogFactory.getLogger(DrawPictureShape.class);
+    private static final String WMF_IMAGE_RENDERER = "org.apache.poi.hwmf.draw.HwmfSLImageRenderer";
+    
     public DrawPictureShape(PictureShape<?,?> shape) {
         super(shape);
     }
@@ -38,14 +44,11 @@ public class DrawPictureShape extends Dr
         PictureData data = getShape().getPictureData();
         if(data == null) return;
 
-        ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
-        if (renderer == null) renderer = new ImageRenderer();
-        
         Rectangle2D anchor = getAnchor(graphics, getShape());
-
         Insets insets = getShape().getClipping();
 
         try {
+            ImageRenderer renderer = getImageRenderer(graphics, data.getContentType());
             renderer.loadImage(data.getData(), data.getContentType());
             renderer.drawImage(graphics, anchor, insets);
         } catch (IOException e) {
@@ -54,6 +57,34 @@ public class DrawPictureShape extends Dr
         }
     }    
 
+    /**
+     * Returns an ImageRenderer for the PictureData
+     *
+     * @param graphics
+     * @return
+     */
+    public static ImageRenderer getImageRenderer(Graphics2D graphics, String contentType) {
+        ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
+        if (renderer != null) {
+            return renderer;
+        }
+        
+        if (PictureType.WMF.contentType.equals(contentType)) {
+            try {
+                @SuppressWarnings("unchecked")
+                Class<? extends ImageRenderer> irc = (Class<? extends ImageRenderer>)
+                    Thread.currentThread().getContextClassLoader().loadClass(WMF_IMAGE_RENDERER);
+                return irc.newInstance();
+            } catch (Exception e) {
+                // WMF image renderer is not on the classpath, continuing with BitmapRenderer
+                // although this doesn't make much sense ...
+                LOG.log(POILogger.ERROR, "WMF image renderer is not on the classpath - include poi-scratchpad jar!", e);
+            }
+        }
+        
+        return new BitmapImageRenderer();
+    }
+    
     @Override
     protected PictureShape<?,?> getShape() {
         return (PictureShape<?,?>)shape;

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java Sat Jan 16 00:11:01 2016
@@ -98,6 +98,7 @@ public class DrawSimpleShape extends Dra
         // then stroke the shape outline
         if(line != null) {
             graphics.setPaint(line);
+            graphics.setStroke(stroke);
             for(Outline o : elems){
                 if(o.getPath().isStroked()){
                     java.awt.Shape s = o.getOutline();

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/ImageRenderer.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/ImageRenderer.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/ImageRenderer.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/ImageRenderer.java Sat Jan 16 00:11:01 2016
@@ -31,13 +31,12 @@ import org.apache.poi.util.POILogFactory
 import org.apache.poi.util.POILogger;
 
 /**
- * For now this class renders only images supported by the javax.imageio.ImageIO
- * framework. Subclasses can override this class to support other formats, for
+ * Classes can implement this interfaces to support other formats, for
  * example, use Apache Batik to render WMF, PICT can be rendered using Apple QuickTime API for Java:
  *
  * <pre>
  * <code>
- * public class MyImageRendener extends ImageRendener {
+ * public class MyImageRendener implements ImageRendener {
  *     InputStream data;
  *
  *     public boolean drawImage(Graphics2D graphics,Rectangle2D anchor,Insets clip) {
@@ -79,127 +78,49 @@ import org.apache.poi.util.POILogger;
  * </code>
  * </pre>
  */
-public class ImageRenderer {
-    private final static POILogger LOG = POILogFactory.getLogger(ImageRenderer.class);
-    
-    protected BufferedImage img;
-
+public interface ImageRenderer {
     /**
      * Load and buffer the image
      *
      * @param data the raw image stream
      * @param contentType the content type
      */
-    public void loadImage(InputStream data, String contentType) throws IOException {
-        img = convertBufferedImage(ImageIO.read(data), contentType);
-    }
+    void loadImage(InputStream data, String contentType) throws IOException;
 
     /**
      * Load and buffer the image
      *
-     * @param data the raw image stream
+     * @param data the raw image bytes
      * @param contentType the content type
      */
-    public void loadImage(byte data[], String contentType) throws IOException {
-        img = convertBufferedImage(ImageIO.read(new ByteArrayInputStream(data)), contentType);
-    }
-
-    /**
-     * Add alpha channel to buffered image 
-     */
-    private static BufferedImage convertBufferedImage(BufferedImage img, String contentType) {
-        if (img == null) {
-            LOG.log(POILogger.WARN, "Content-type: "+contentType+" is not support. Image ignored.");
-            return null;
-        }
-        
-        BufferedImage bi = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
-        Graphics g = bi.getGraphics();
-        g.drawImage(img, 0, 0, null);
-        g.dispose();
-        return bi;
-    }
-    
-    
-    /**
-     * @return the buffered image
-     */
-    public BufferedImage getImage() {
-        return img;
-    }
+    void loadImage(byte data[], String contentType) throws IOException;
 
     /**
      * @return the dimension of the buffered image
      */
-    public Dimension getDimension() {
-        return (img == null)
-            ? new Dimension(0,0)
-            : new Dimension(img.getWidth(),img.getHeight());
-    }
+    Dimension getDimension();
 
     /**
      * @param alpha the alpha [0..1] to be added to the image (possibly already containing an alpha channel)
      */
-    public void setAlpha(double alpha) {
-        if (img == null) return;
-
-        Dimension dim = getDimension();
-        BufferedImage newImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);
-        Graphics2D g = newImg.createGraphics();
-        RescaleOp op = new RescaleOp(new float[]{1.0f, 1.0f, 1.0f, (float)alpha}, new float[]{0,0,0,0}, null);
-        g.drawImage(img, op, 0, 0);
-        g.dispose();
-        
-        img = newImg;
-    }
-
+    void setAlpha(double alpha);
 
     /**
+     * @return the image as buffered image
+     */
+    BufferedImage getImage();
+    
+    /**
      * Render picture data into the supplied graphics
      *
      * @return true if the picture data was successfully rendered
      */
-    public boolean drawImage(
-        Graphics2D graphics,
-        Rectangle2D anchor) {
-        return drawImage(graphics, anchor, null);
-    }
+    boolean drawImage(Graphics2D graphics, Rectangle2D anchor);
 
     /**
      * Render picture data into the supplied graphics
      *
      * @return true if the picture data was successfully rendered
      */
-    public boolean drawImage(
-        Graphics2D graphics,
-        Rectangle2D anchor,
-        Insets clip) {
-        if (img == null) return false;
-
-        boolean isClipped = true;
-        if (clip == null) {
-            isClipped = false;
-            clip = new Insets(0,0,0,0);
-        }
-
-        int iw = img.getWidth();
-        int ih = img.getHeight();
-
-        
-        double cw = (100000-clip.left-clip.right) / 100000.0;
-        double ch = (100000-clip.top-clip.bottom) / 100000.0;
-        double sx = anchor.getWidth()/(iw*cw);
-        double sy = anchor.getHeight()/(ih*ch);
-        double tx = anchor.getX()-(iw*sx*clip.left/100000.0);
-        double ty = anchor.getY()-(ih*sy*clip.top/100000.0);
-
-        AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;
-
-        Shape clipOld = graphics.getClip();
-        if (isClipped) graphics.clip(anchor.getBounds2D());
-        graphics.drawRenderedImage(img, at);
-        graphics.setClip(clipOld);
-
-        return true;
-    }
-}
+    boolean drawImage(Graphics2D graphics, Rectangle2D anchor, Insets clip);
+}
\ No newline at end of file

Added: poi/trunk/src/java/org/apache/poi/sl/usermodel/GraphicalFrame.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/usermodel/GraphicalFrame.java?rev=1724897&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/usermodel/GraphicalFrame.java (added)
+++ poi/trunk/src/java/org/apache/poi/sl/usermodel/GraphicalFrame.java Sat Jan 16 00:11:01 2016
@@ -0,0 +1,29 @@
+/* ====================================================================
+   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;
+
+public interface GraphicalFrame<
+    S extends Shape<S,P>,
+    P extends TextParagraph<S,P,?>
+> extends Shape<S,P>, PlaceableShape<S,P> {
+
+    /**
+     * @return a fallback representation as picture shape
+     */
+    PictureShape<S,P> getFallbackPicture();
+}

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java Sat Jan 16 00:11:01 2016
@@ -27,25 +27,26 @@ import org.apache.poi.POIXMLException;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
-import org.apache.poi.sl.draw.DrawNotImplemented;
-import org.apache.poi.sl.usermodel.PlaceableShape;
+import org.apache.poi.sl.usermodel.GraphicalFrame;
 import org.apache.poi.sl.usermodel.ShapeType;
 import org.apache.poi.util.Beta;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
 import org.apache.poi.util.Units;
 import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlObject;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
 
-/**
- * @author Yegor Kozlov
- */
 @Beta
-@DrawNotImplemented
-public class XSLFGraphicFrame extends XSLFShape implements PlaceableShape<XSLFShape, XSLFTextParagraph> {
+public class XSLFGraphicFrame extends XSLFShape implements GraphicalFrame<XSLFShape, XSLFTextParagraph> {
+    private static final POILogger LOG = POILogFactory.getLogger(XSLFGraphicFrame.class);
+
     /*package*/ XSLFGraphicFrame(CTGraphicalObjectFrame shape, XSLFSheet sheet){
         super(shape,sheet);
     }
@@ -104,7 +105,7 @@ public class XSLFGraphicFrame extends XS
     public void setRotation(double theta){
     	throw new IllegalArgumentException("Operation not supported");
     }
-   
+
     /**
      * Rotation angle in degrees
      * <p>
@@ -125,7 +126,7 @@ public class XSLFGraphicFrame extends XS
     public void setFlipVertical(boolean flip){
     	throw new IllegalArgumentException("Operation not supported");
     }
-    
+
     /**
      * Whether the shape is horizontally flipped
      *
@@ -189,4 +190,30 @@ public class XSLFGraphicFrame extends XS
         }
     }
 
+    @Override
+    public XSLFPictureShape getFallbackPicture() {
+        String xquery =
+                  "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main'; "
+                + "declare namespace mc='http://schemas.openxmlformats.org/markup-compatibility/2006' "
+                + ".//mc:Fallback/*/p:pic"
+                ;
+        XmlObject xo = selectProperty(XmlObject.class, xquery);
+        if (xo == null) {
+            return null;
+        }
+
+        CTGroupShape gs;
+        try {
+            gs = CTGroupShape.Factory.parse(xo.newDomNode());
+        } catch (XmlException e) {
+            LOG.log(POILogger.WARN, "Can't parse fallback picture stream of graphical frame", e);
+            return null;
+        }
+
+        if (gs.sizeOfPicArray() == 0) {
+            return null;
+        }
+
+        return new XSLFPictureShape(gs.getPicArray(0), getSheet());
+    }
 }
\ No newline at end of file

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java Sat Jan 16 00:11:01 2016
@@ -257,7 +257,7 @@ public abstract class XSLFShape implemen
 
     public Placeholder getPlaceholder() {
         CTPlaceholder ph = getCTPlaceholder();
-        if (ph == null || !ph.isSetType()) {
+        if (ph == null || !(ph.isSetType() || ph.isSetIdx())) {
             return null;
         }
         return Placeholder.lookupOoxml(ph.getType().intValue());

Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java Sat Jan 16 00:11:01 2016
@@ -37,6 +37,7 @@ public class TestPPTX2PNG {
         POIDataSamples samples = POIDataSamples.getSlideShowInstance();
 
         String[] testFiles = {"alterman_security.ppt","alterman_security.pptx","KEY02.pptx","themes.pptx","backgrounds.pptx","layouts.pptx", "sample.pptx", "shapes.pptx",};
+//        String[] testFiles = {"41246-2.ppt","45543.ppt","53446.ppt","ParagraphStylesShorterThanCharStyles.ppt"};
         String[] args = {
             "-format", "null", // png,gif,jpg or null for test
             "-slide", "-1", // -1 for all

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java Sat Jan 16 00:11:01 2016
@@ -100,7 +100,7 @@ public abstract class HSLFSimpleShape ex
         opt.setRecordId(EscherOptRecord.RECORD_ID);
         _escherContainer.addChildRecord(opt);
 
-        EscherRecord anchor; 
+        EscherRecord anchor;
         if(isChild) {
             anchor = new EscherChildAnchorRecord();
         } else {
@@ -155,7 +155,7 @@ public abstract class HSLFSimpleShape ex
     }
 
     /**
-     * @return color of the line. If color is not set returns <code>java.awt.Color.black</code>
+     * @return color of the line. If color is not set returns {@code null}
      */
     public Color getLineColor(){
         AbstractEscherOptRecord opt = getEscherOptRecord();
@@ -164,7 +164,7 @@ public abstract class HSLFSimpleShape ex
         if(p != null && (p.getPropertyValue() & 0x8) == 0) return null;
 
         Color clr = getColor(EscherProperties.LINESTYLE__COLOR, EscherProperties.LINESTYLE__OPACITY, -1);
-        return clr == null ? Color.black : clr;
+        return clr == null ? null : clr;
     }
 
     /**
@@ -187,7 +187,7 @@ public abstract class HSLFSimpleShape ex
         AbstractEscherOptRecord opt = getEscherOptRecord();
         setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDCAPSTYLE, pen == LineCap.FLAT ? -1 : pen.nativeId);
     }
-    
+
     /**
      * Gets line dashing.
      *
@@ -417,7 +417,7 @@ public abstract class HSLFSimpleShape ex
 
         };
     }
-    
+
     public DecorationShape getLineHeadDecoration(){
         AbstractEscherOptRecord opt = getEscherOptRecord();
         EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWHEAD);
@@ -428,7 +428,7 @@ public abstract class HSLFSimpleShape ex
         AbstractEscherOptRecord opt = getEscherOptRecord();
         setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWHEAD, decoShape == null ? -1 : decoShape.nativeId);
     }
-    
+
     public DecorationSize getLineHeadWidth(){
         AbstractEscherOptRecord opt = getEscherOptRecord();
         EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWWIDTH);
@@ -439,7 +439,7 @@ public abstract class HSLFSimpleShape ex
         AbstractEscherOptRecord opt = getEscherOptRecord();
         setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWWIDTH, decoSize == null ? -1 : decoSize.nativeId);
     }
-    
+
     public DecorationSize getLineHeadLength(){
         AbstractEscherOptRecord opt = getEscherOptRecord();
         EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWLENGTH);
@@ -450,7 +450,7 @@ public abstract class HSLFSimpleShape ex
         AbstractEscherOptRecord opt = getEscherOptRecord();
         setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWLENGTH, decoSize == null ? -1 : decoSize.nativeId);
     }
-    
+
     public DecorationShape getLineTailDecoration(){
         AbstractEscherOptRecord opt = getEscherOptRecord();
         EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWHEAD);
@@ -461,7 +461,7 @@ public abstract class HSLFSimpleShape ex
         AbstractEscherOptRecord opt = getEscherOptRecord();
         setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWHEAD, decoShape == null ? -1 : decoShape.nativeId);
     }
-    
+
     public DecorationSize getLineTailWidth(){
         AbstractEscherOptRecord opt = getEscherOptRecord();
         EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWWIDTH);
@@ -472,7 +472,7 @@ public abstract class HSLFSimpleShape ex
         AbstractEscherOptRecord opt = getEscherOptRecord();
         setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWWIDTH, decoSize == null ? -1 : decoSize.nativeId);
     }
-    
+
     public DecorationSize getLineTailLength(){
         AbstractEscherOptRecord opt = getEscherOptRecord();
         EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWLENGTH);
@@ -484,8 +484,8 @@ public abstract class HSLFSimpleShape ex
         setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWLENGTH, decoSize == null ? -1 : decoSize.nativeId);
     }
 
-    
-    
+
+
     public LineDecoration getLineDecoration() {
         return new LineDecoration() {
 
@@ -514,7 +514,7 @@ public abstract class HSLFSimpleShape ex
             }
         };
     }
-    
+
     @Override
     public Placeholder getPlaceholder() {
         List<? extends Record> clRecords = getClientRecords();
@@ -530,10 +530,10 @@ public abstract class HSLFSimpleShape ex
                 return Placeholder.lookupNative(rtp.getPlaceholderId());
             }
         }
-        
+
         return null;
     }
-    
+
     @Override
     public void setPlaceholder(Placeholder placeholder) {
         EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
@@ -547,7 +547,7 @@ public abstract class HSLFSimpleShape ex
 
         // Placeholders can't be grouped
         setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, (placeholder == null ? -1 : 262144));
-        
+
         HSLFEscherClientDataRecord clientData = getClientData(false);
         if (placeholder == null) {
             if (clientData != null) {
@@ -560,7 +560,7 @@ public abstract class HSLFSimpleShape ex
             }
             return;
         }
-        
+
         if (clientData == null) {
             clientData = getClientData(true);
         }
@@ -596,11 +596,11 @@ public abstract class HSLFSimpleShape ex
         } else {
             phId = (byte)placeholder.nativeSlideId;
         }
-        
+
         if (phId == -2) {
             throw new HSLFException("Placeholder "+placeholder.name()+" not supported for this sheet type ("+sheet.getClass()+")");
         }
-        
+
         switch (placeholder) {
             case HEADER:
             case FOOTER:
@@ -637,7 +637,7 @@ public abstract class HSLFSimpleShape ex
             setLineColor(null);
             return;
         }
-        
+
         // TODO: handle PaintStyle
         for (Object st : styles) {
             if (st instanceof Number) {

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java Sat Jan 16 00:11:01 2016
@@ -270,7 +270,6 @@ public class HwmfGraphics {
      * This methods gathers and sets the corresponding graphics transformations.
      */
     public void updateWindowMapMode() {
-        GraphicsConfiguration gc = graphicsCtx.getDeviceConfiguration();
         Rectangle2D win = prop.getWindow();
         HwmfMapMode mapMode = prop.getMapMode();
         graphicsCtx.setTransform(initialAT);
@@ -292,12 +291,14 @@ public class HwmfGraphics {
         case MM_HIMETRIC:
         case MM_LOENGLISH:
         case MM_HIENGLISH:
-        case MM_TWIPS:
+        case MM_TWIPS: {
             // TODO: to be validated ...
+            GraphicsConfiguration gc = graphicsCtx.getDeviceConfiguration();
             graphicsCtx.transform(gc.getNormalizingTransform());
             graphicsCtx.scale(1./mapMode.scale, -1./mapMode.scale);
             graphicsCtx.translate(-win.getX(), -win.getY());
             break;
+        }
         case MM_TEXT:
             // TODO: to be validated ...
             break;

Added: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfSLImageRenderer.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfSLImageRenderer.java?rev=1724897&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfSLImageRenderer.java (added)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfSLImageRenderer.java Sat Jan 16 00:11:01 2016
@@ -0,0 +1,115 @@
+/* ====================================================================
+   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.hwmf.draw;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.RenderingHints;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.RescaleOp;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.hwmf.usermodel.HwmfPicture;
+import org.apache.poi.sl.draw.ImageRenderer;
+import org.apache.poi.sl.usermodel.PictureData;
+import org.apache.poi.util.Units;
+
+public class HwmfSLImageRenderer implements ImageRenderer {
+    HwmfPicture image = null;
+    double alpha = 0;
+    
+    @Override
+    public void loadImage(InputStream data, String contentType) throws IOException {
+        if (!PictureData.PictureType.WMF.contentType.equals(contentType)) {
+            throw new IOException("Invalid picture type");
+        }
+        image = new HwmfPicture(data);
+    }
+
+    @Override
+    public void loadImage(byte[] data, String contentType) throws IOException {
+        if (!PictureData.PictureType.WMF.contentType.equals(contentType)) {
+            throw new IOException("Invalid picture type");
+        }
+        image = new HwmfPicture(new ByteArrayInputStream(data));
+    }
+
+    @Override
+    public Dimension getDimension() {
+        int width = 0, height = 0;
+        if (image != null) {
+            Dimension dim = image.getSize();
+            width = Units.pointsToPixel(dim.getWidth());
+            // keep aspect ratio for height
+            height = Units.pointsToPixel(dim.getHeight());
+        }
+        return new Dimension(width, height);
+    }
+
+    @Override
+    public void setAlpha(double alpha) {
+        this.alpha = alpha;
+    }
+
+    @Override
+    public BufferedImage getImage() {
+        if (image == null) {
+            return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); 
+        }
+        
+        Dimension dim = getDimension();
+        BufferedImage bufImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g = bufImg.createGraphics();
+        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+        g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+        image.draw(g);
+        g.dispose();
+        
+        if (alpha != 0) {
+            BufferedImage newImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);
+            g = newImg.createGraphics();
+            RescaleOp op = new RescaleOp(new float[]{1.0f, 1.0f, 1.0f, (float)alpha}, new float[]{0,0,0,0}, null);
+            g.drawImage(bufImg, op, 0, 0);
+            g.dispose();
+            bufImg = newImg;
+        }
+        
+        return bufImg;
+    }
+
+    @Override
+    public boolean drawImage(Graphics2D graphics, Rectangle2D anchor) {
+        return drawImage(graphics, anchor, null);
+    }
+
+    @Override
+    public boolean drawImage(Graphics2D graphics, Rectangle2D anchor, Insets clip) {
+        if (image == null) {
+            return false;
+        } else {
+            image.draw(graphics, anchor);
+            return true;
+        }
+    }
+}

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java Sat Jan 16 00:11:01 2016
@@ -339,7 +339,7 @@ public class HwmfMisc {
      * The META_DIBCREATEPATTERNBRUSH record creates a Brush Object with a
      * pattern specified by a DeviceIndependentBitmap (DIB) Object
      */
-    public static class WmfDibCreatePatternBrush implements HwmfRecord, HwmfImageRecord {
+    public static class WmfDibCreatePatternBrush implements HwmfRecord, HwmfImageRecord, HwmfObjectTableEntry {
 
         private HwmfBrushStyle style;
 
@@ -388,6 +388,11 @@ public class HwmfMisc {
 
         @Override
         public void draw(HwmfGraphics ctx) {
+            ctx.addObjectTableEntry(this);
+        }
+        
+        @Override
+        public void applyObject(HwmfGraphics ctx) {
             HwmfDrawProperties prop = ctx.getProperties();
             prop.setBrushStyle(style);
             prop.setBrushBitmap(getImage());

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java?rev=1724897&r1=1724896&r2=1724897&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java Sat Jan 16 00:11:01 2016
@@ -102,11 +102,11 @@ public class HwmfPicture {
         try {
             Rectangle2D wmfBounds = getBounds();
             // scale output bounds to image bounds
+            ctx.translate(graphicsBounds.getX(), graphicsBounds.getY());
             ctx.scale(graphicsBounds.getWidth()/wmfBounds.getWidth(), graphicsBounds.getHeight()/wmfBounds.getHeight());
-            ctx.translate(-wmfBounds.getX(), -wmfBounds.getY());
             
             HwmfGraphics g = new HwmfGraphics(ctx, wmfBounds);
-            for (HwmfRecord r : records)  {
+            for (HwmfRecord r : records) {
                 r.draw(g);
             }
         } finally {




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