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 2018/09/24 23:55:52 UTC

svn commit: r1841897 - in /poi/branches/hemf/src: java/org/apache/poi/sl/draw/ resources/main/META-INF/ resources/scratchpad/META-INF/ scratchpad/src/org/apache/poi/hemf/draw/ scratchpad/src/org/apache/poi/hemf/record/emf/ scratchpad/src/org/apache/poi...

Author: kiwiwings
Date: Mon Sep 24 23:55:52 2018
New Revision: 1841897

URL: http://svn.apache.org/viewvc?rev=1841897&view=rev
Log:
#60656 - Support export file that contains emf and render it correctly

Removed:
    poi/branches/hemf/src/resources/main/META-INF/
    poi/branches/hemf/src/resources/scratchpad/META-INF/
Modified:
    poi/branches/hemf/src/java/org/apache/poi/sl/draw/DrawPictureShape.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfDrawProperties.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
    poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java

Modified: poi/branches/hemf/src/java/org/apache/poi/sl/draw/DrawPictureShape.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/java/org/apache/poi/sl/draw/DrawPictureShape.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/java/org/apache/poi/sl/draw/DrawPictureShape.java (original)
+++ poi/branches/hemf/src/java/org/apache/poi/sl/draw/DrawPictureShape.java Mon Sep 24 23:55:52 2018
@@ -33,7 +33,10 @@ import org.apache.poi.util.POILogger;
 
 public class DrawPictureShape extends DrawSimpleShape {
     private static final POILogger LOG = POILogFactory.getLogger(DrawPictureShape.class);
-    private static final ServiceLoader<ImageRenderer> rendererLoader = ServiceLoader.load(ImageRenderer.class);
+    private static final String[] KNOWN_RENDERER = {
+        "org.apache.poi.hwmf.draw.HwmfImageRenderer",
+        "org.apache.poi.hemf.draw.HemfImageRenderer"
+    };
 
     public DrawPictureShape(PictureShape<?,?> shape) {
         super(shape);
@@ -62,24 +65,44 @@ public class DrawPictureShape extends Dr
      * @param graphics the graphics context
      * @return the image renderer
      */
-    @SuppressWarnings("WeakerAccess")
+    @SuppressWarnings({"WeakerAccess", "unchecked"})
     public static ImageRenderer getImageRenderer(Graphics2D graphics, String contentType) {
-        ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
-        if (renderer != null) {
+        final ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
+        if (renderer != null && renderer.canRender(contentType)) {
             return renderer;
         }
 
-        for (ImageRenderer ir : rendererLoader) {
+        // first try with our default image renderer
+        final BitmapImageRenderer bir = new BitmapImageRenderer();
+        if (bir.canRender(contentType)) {
+            return bir;
+        }
+
+        // then iterate through the scratchpad renderers
+        //
+        // this could be nicely implemented via a j.u.ServiceLoader, but OSGi makes things complicated ...
+        // https://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html
+        // ... therefore falling back to classloading attempts
+        ClassLoader cl = ImageRenderer.class.getClassLoader();
+        for (String kr : KNOWN_RENDERER) {
+            final ImageRenderer ir;
+            try {
+                ir = ((Class<? extends ImageRenderer>)cl.loadClass(kr)).newInstance();
+            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+                // scratchpad was not on the path, ignore and continue
+                LOG.log(POILogger.INFO, "Known image renderer '"+kr+" not found/loaded - include poi-scratchpad jar!", e);
+                continue;
+            }
             if (ir.canRender(contentType)) {
                 return ir;
             }
         }
 
-        LOG.log(POILogger.ERROR, "No suiteable image renderer found for content-type '"+
+        LOG.log(POILogger.WARN, "No suiteable image renderer found for content-type '"+
                 contentType+"' - include poi-scratchpad jar!");
 
-        // falling back to BitmapImageRenderer although this doesn't make much sense ...
-        return new BitmapImageRenderer();
+        // falling back to BitmapImageRenderer, at least it gracefully handles invalid images
+        return bir;
     }
     
     @Override

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfDrawProperties.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfDrawProperties.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfDrawProperties.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfDrawProperties.java Mon Sep 24 23:55:52 2018
@@ -24,16 +24,15 @@ import org.apache.poi.hwmf.draw.HwmfDraw
 public class HemfDrawProperties extends HwmfDrawProperties {
 
     /** Path for path bracket operations */
-    protected final Path2D path;
+    protected Path2D path = null;
 
 
     public HemfDrawProperties() {
-        path = new Path2D.Double();
     }
 
     public HemfDrawProperties(HemfDrawProperties other) {
         super(other);
-        path = (Path2D)other.path.clone();
+        path = (other.path != null) ? (Path2D)other.path.clone() : null;
     }
 
     /**
@@ -42,4 +41,21 @@ public class HemfDrawProperties extends
     public Path2D getPath() {
         return path;
     }
+
+    /**
+     * Un-/Sets the bracket path
+     * @param path the bracket path
+     */
+    public void setPath(Path2D path) {
+        this.path = path;
+    }
+
+    /**
+     * Use path (bracket) or graphics context for drawing operations
+     * @return {@code true}, if the drawing should go to the path bracket,
+     *      if {@code false} draw directly to the graphics context
+     */
+    public boolean usePathBracket() {
+        return path != null;
+    }
 }

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java Mon Sep 24 23:55:52 2018
@@ -19,13 +19,18 @@ package org.apache.poi.hemf.draw;
 
 import java.awt.Graphics2D;
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Path2D;
+import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.util.ArrayDeque;
 import java.util.Deque;
+import java.util.function.Consumer;
 
 import org.apache.poi.hemf.record.emf.HemfBounded;
 import org.apache.poi.hemf.record.emf.HemfRecord;
 import org.apache.poi.hwmf.draw.HwmfGraphics;
+import org.apache.poi.hwmf.record.HwmfObjectTableEntry;
+import org.apache.poi.util.Internal;
 
 public class HemfGraphics extends HwmfGraphics {
 
@@ -80,6 +85,59 @@ public class HemfGraphics extends HwmfGr
         }
     }
 
+    @Internal
+    public void draw(Consumer<Path2D> pathConsumer) {
+        final HemfDrawProperties prop = getProperties();
+        final boolean useBracket = prop.usePathBracket();
+
+        final Path2D path;
+        if (useBracket) {
+            path = prop.getPath();
+        } else {
+            path = new Path2D.Double();
+            Point2D pnt = prop.getLocation();
+            path.moveTo(pnt.getX(),pnt.getY());
+        }
+
+        pathConsumer.accept(path);
+
+        prop.setLocation(path.getCurrentPoint());
+        if (!useBracket) {
+            // TODO: when to use draw vs. fill?
+            graphicsCtx.draw(path);
+        }
+
+    }
+
+    /**
+     * Adds or sets an record of type {@link HwmfObjectTableEntry} to the object table.
+     * If the {@code index} is less than 1, the method acts the same as
+     * {@link HwmfGraphics#addObjectTableEntry(HwmfObjectTableEntry)}, otherwise the
+     * index is used to access the object table.
+     * As the table is filled successively, the index must be between 1 and size+1
+     *
+     * @param entry the record to be stored
+     * @param index the index to be overwritten, regardless if its content was unset before
+     *
+     * @see HwmfGraphics#addObjectTableEntry(HwmfObjectTableEntry)
+     */
+    public void addObjectTableEntry(HwmfObjectTableEntry entry, int index) {
+        if (index < 1) {
+            super.addObjectTableEntry(entry);
+            return;
+        }
+
+        if (index > objectTable.size()) {
+            throw new IllegalStateException("object table hasn't grown to this index yet");
+        }
+
+        if (index == objectTable.size()) {
+            objectTable.add(entry);
+        } else {
+            objectTable.set(index, entry);
+        }
+    }
+
 
     /** saves the current affine transform on the stack */
     private void saveTransform() {

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java Mon Sep 24 23:55:52 2018
@@ -32,6 +32,7 @@ import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
+import org.apache.poi.util.LocaleUtil;
 import org.apache.poi.util.RecordFormatException;
 
 /**
@@ -97,6 +98,11 @@ public class HemfComment {
         public EmfCommentData getCommentData() {
             return data;
         }
+
+        @Override
+        public String toString() {
+            return "{ data: "+data+" }";
+        }
     }
 
     public static class EmfCommentDataIterator implements Iterator<EmfCommentData> {
@@ -208,6 +214,11 @@ public class HemfComment {
             leis.readFully(privateData);
             return privateData.length;
         }
+
+        @Override
+        public String toString() {
+            return "\""+new String(privateData, LocaleUtil.CHARSET_1252)+"\"";
+        }
     }
 
     /** The EMR_COMMENT_EMFPLUS record contains embedded EMF+ records. */

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java Mon Sep 24 23:55:52 2018
@@ -53,6 +53,28 @@ public class HemfDraw {
         private static final HwmfColorRef DKGRAY = new HwmfColorRef(new Color(0x00404040));
         private static final HwmfColorRef BLACK = new HwmfColorRef(Color.BLACK);
 
+        private static final String[] STOCK_IDS = {
+            "0x80000000 /* WHITE_BRUSH */",
+            "0x80000001 /* LTGRAY_BRUSH */",
+            "0x80000002 /* GRAY_BRUSH */",
+            "0x80000003 /* DKGRAY_BRUSH */",
+            "0x80000004 /* BLACK_BRUSH */",
+            "0x80000005 /* NULL_BRUSH */",
+            "0x80000006 /* WHITE_PEN */",
+            "0x80000007 /* BLACK_PEN */",
+            "0x80000008 /* NULL_PEN */",
+            "0x8000000A /* OEM_FIXED_FONT */",
+            "0x8000000B /* ANSI_FIXED_FONT */",
+            "0x8000000C /* ANSI_VAR_FONT */",
+            "0x8000000D /* SYSTEM_FONT */",
+            "0x8000000E /* DEVICE_DEFAULT_FONT */",
+            "0x8000000F /* DEFAULT_PALETTE */",
+            "0x80000010 /* SYSTEM_FIXED_FONT */",
+            "0x80000011 /* DEFAULT_GUI_FONT */",
+            "0x80000012 /* DC_BRUSH */",
+            "0x80000013 /* DC_PEN */"
+        };
+
         @Override
         public HemfRecordType getEmfRecordType() {
             return HemfRecordType.selectObject;
@@ -184,6 +206,14 @@ public class HemfDraw {
             }
         }
 
+        @Override
+        public String toString() {
+            return "{ index: "+
+                (((objectIndex & 0x80000000) != 0 && (objectIndex & 0x3FFFFFFF) <= 13 )
+                ? STOCK_IDS[objectIndex & 0x3FFFFFFF]
+                : objectIndex)+" }";
+        }
+
     }
 
 
@@ -220,7 +250,7 @@ public class HemfDraw {
             final int points = Math.min(count, 16384);
             size += LittleEndianConsts.INT_SIZE;
 
-            poly.reset();
+            poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, points);
 
             /* Cubic Bezier curves are defined using the endpoints and control points
              * specified by the points field. The first curve is drawn from the first
@@ -324,6 +354,8 @@ public class HemfDraw {
             final int points = Math.min(count, 16384);
             size += LittleEndianConsts.INT_SIZE;
 
+            poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, points);
+
             Point2D pnt = new Point2D.Double();
             for (int i=0; i<points; i++) {
                 size += readPoint(leis, pnt);
@@ -541,7 +573,7 @@ public class HemfDraw {
                  * An array of WMF PointL objects that specifies the points for all polygons in logical units.
                  * The number of points is specified by the Count field value.
                  */
-                Path2D poly = new Path2D.Double();
+                Path2D poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, (int)nPoints);
                 for (int i=0; i<nPoints; i++) {
                     size += readPoint(leis, pnt);
                     if (i == 0) {
@@ -659,11 +691,8 @@ public class HemfDraw {
         }
 
         @Override
-        public void draw(HemfGraphics ctx) {
-            HemfDrawProperties prop = ctx.getProperties();
-            final Path2D path = prop.getPath();
-            path.moveTo(point.getX(), point.getY());
-            prop.setLocation(point);
+        public void draw(final HemfGraphics ctx) {
+            ctx.draw((path) -> path.moveTo(point.getX(), point.getY()));
         }
     }
 
@@ -802,11 +831,8 @@ public class HemfDraw {
         }
 
         @Override
-        public void draw(HemfGraphics ctx) {
-            final HemfDrawProperties prop = ctx.getProperties();
-            final Path2D path = prop.getPath();
-            path.lineTo(point.getX(), point.getY());
-            prop.setLocation(point);
+        public void draw(final HemfGraphics ctx) {
+            ctx.draw((path) -> path.lineTo(point.getX(), point.getY()));
         }
     }
 
@@ -829,11 +855,9 @@ public class HemfDraw {
         }
 
         @Override
-        public void draw(HemfGraphics ctx) {
-            final Path2D path = ctx.getProperties().getPath();
-            Arc2D arc = getShape();
-            path.append(arc, true);
-            ctx.getProperties().setLocation(endPoint);
+        public void draw(final HemfGraphics ctx) {
+            final Arc2D arc = getShape();
+            ctx.draw((path) -> path.append(arc, true));
         }
     }
 
@@ -860,7 +884,7 @@ public class HemfDraw {
                  size += readPoint(leis, points[i]);
             }
 
-            poly.reset();
+            poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, count);
 
             for (int i=0; i<count; i++) {
                 int mode = leis.readUByte();
@@ -958,8 +982,7 @@ public class HemfDraw {
         @Override
         public void draw(HemfGraphics ctx) {
             final HemfDrawProperties prop = ctx.getProperties();
-            final Path2D path = prop.getPath();
-            path.reset();
+            prop.setPath(new Path2D.Double());
         }
     }
 
@@ -996,8 +1019,7 @@ public class HemfDraw {
         @Override
         public void draw(HemfGraphics ctx) {
             final HemfDrawProperties prop = ctx.getProperties();
-            final Path2D path = prop.getPath();
-            path.reset();
+            prop.setPath(null);
         }
     }
 
@@ -1036,8 +1058,10 @@ public class HemfDraw {
         public void draw(HemfGraphics ctx) {
             final HemfDrawProperties prop = ctx.getProperties();
             final Path2D path = prop.getPath();
-            path.closePath();
-            prop.setLocation(path.getCurrentPoint());
+            if (path != null) {
+                path.closePath();
+                prop.setLocation(path.getCurrentPoint());
+            }
 
         }
     }
@@ -1140,16 +1164,12 @@ public class HemfDraw {
         return 2*LittleEndianConsts.INT_SIZE;
     }
 
-    private static void polyTo(HemfGraphics ctx, Path2D poly) {
-        final HemfDrawProperties prop = ctx.getProperties();
-        final Path2D path = prop.getPath();
-        PathIterator pi = poly.getPathIterator(null);
+    private static void polyTo(final HemfGraphics ctx, final Path2D poly) {
+        final PathIterator pi = poly.getPathIterator(null);
         // ignore dummy start point (moveTo)
         pi.next();
-        assert(!pi.isDone());
-        path.append(pi, true);
-        prop.setLocation(path.getCurrentPoint());
-    }
-
+        assert (!pi.isDone());
 
+        ctx.draw((path) -> path.append(pi, true));
+    }
 }

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java Mon Sep 24 23:55:52 2018
@@ -655,6 +655,9 @@ public class HemfFill {
         @Override
         public void draw(HemfGraphics ctx) {
             final HemfDrawProperties prop = ctx.getProperties();
+            if (!prop.usePathBracket()) {
+                return;
+            }
             final Path2D path = (Path2D)prop.getPath().clone();
             path.setWindingRule(ctx.getProperties().getWindingRule());
             if (prop.getBrushStyle() == HwmfBrushStyle.BS_NULL) {

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java Mon Sep 24 23:55:52 2018
@@ -98,7 +98,7 @@ public class HemfMisc {
     /**
      * The EMF_SAVEDC record saves the playback device context for later retrieval.
      */
-    public static class EmfSaveDc implements HemfRecord {
+    public static class EmfSaveDc extends HwmfMisc.WmfSaveDc implements HemfRecord {
         @Override
         public HemfRecordType getEmfRecordType() {
             return HemfRecordType.saveDc;
@@ -108,25 +108,13 @@ public class HemfMisc {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return 0;
         }
-
-        @Override
-        public void draw(HemfGraphics ctx) {
-            ctx.saveProperties();
-        }
     }
 
     /**
      * The EMF_RESTOREDC record restores the playback device context from a previously saved device
      * context.
      */
-    public static class EmfRestoreDc implements HemfRecord {
-
-        /**
-         * SavedDC (4 bytes): A 32-bit signed integer that specifies the saved state to restore relative to
-         * the current state. This value MUST be negative; –1 represents the state that was most
-         * recently saved on the stack, –2 the one before that, etc.
-         */
-        private int nSavedDC;
+    public static class EmfRestoreDc extends HwmfMisc.WmfRestoreDc implements HemfRecord {
 
         @Override
         public HemfRecordType getEmfRecordType() {
@@ -135,23 +123,19 @@ public class HemfMisc {
 
         @Override
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+            // A 32-bit signed integer that specifies the saved state to restore relative to
+            // the current state. This value MUST be negative; –1 represents the state that was most
+            // recently saved on the stack, –2 the one before that, etc.
             nSavedDC = leis.readInt();
             return LittleEndianConsts.INT_SIZE;
         }
-
-        @Override
-        public void draw(HemfGraphics ctx) {
-            ctx.restoreProperties(nSavedDC);
-        }
     }
 
     /**
      * The META_SETBKCOLOR record sets the background color in the playback device context to a
      * specified color, or to the nearest physical color if the device cannot represent the specified color.
      */
-    public static class EmfSetBkColor implements HemfRecord {
-
-        private HwmfColorRef colorRef;
+    public static class EmfSetBkColor extends HwmfMisc.WmfSetBkColor implements HemfRecord {
 
         @Override
         public HemfRecordType getEmfRecordType() {
@@ -160,14 +144,8 @@ public class HemfMisc {
 
         @Override
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
-            colorRef = new HwmfColorRef();
             return colorRef.init(leis);
         }
-
-        @Override
-        public void draw(HemfGraphics ctx) {
-            ctx.getProperties().setBackgroundColor(colorRef);
-        }
     }
 
 
@@ -287,8 +265,13 @@ public class HemfMisc {
             int size = colorRef.init(leis);
             brushHatch = HwmfHatchStyle.valueOf((int) leis.readUInt());
             return size + 3 * LittleEndianConsts.INT_SIZE;
+        }
 
+        @Override
+        public void draw(HemfGraphics ctx) {
+            ctx.addObjectTableEntry(this, brushIdx);
         }
+
     }
 
     /**
@@ -341,6 +324,11 @@ public class HemfMisc {
 
             return size + 4 * LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public void draw(HemfGraphics ctx) {
+            ctx.addObjectTableEntry(this, penIndex);
+        }
     }
 
     public static class EmfExtCreatePen extends EmfCreatePen {

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java Mon Sep 24 23:55:52 2018
@@ -19,6 +19,7 @@ package org.apache.poi.hemf.record.emf;
 
 import java.io.IOException;
 
+import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hwmf.record.HwmfPalette;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
@@ -67,6 +68,11 @@ public class HemfPalette {
             int size = readPaletteEntries(leis, -1);
             return size + LittleEndianConsts.INT_SIZE + LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HemfGraphics ctx) {
+            ctx.addObjectTableEntry(this, paletteIndex);
+        }
     }
 
     /**
@@ -93,6 +99,11 @@ public class HemfPalette {
             int size = readPaletteEntries(leis, nbrOfEntries);
             return size + 3*LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public void draw(HemfGraphics ctx) {
+            ctx.addObjectTableEntry(this, paletteIndex);
+        }
     }
 
     /**
@@ -118,6 +129,11 @@ public class HemfPalette {
 
             return 2*LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public void draw(HemfGraphics ctx) {
+            ctx.addObjectTableEntry(this, paletteIndex);
+        }
     }
 
     /**

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java Mon Sep 24 23:55:52 2018
@@ -47,7 +47,7 @@ public enum HemfRecordType {
     setStretchBltMode(0x00000015, HemfMisc.EmfSetStretchBltMode::new),
     setTextAlign(0x00000016, HemfText.EmfSetTextAlign::new),
     setcoloradjustment(0x00000017, UnimplementedHemfRecord::new),
-    setTextColor(0x00000018, HemfText.SetTextColor::new),
+    setTextColor(0x00000018, HemfText.EmfSetTextColor::new),
     setBkColor(0x00000019, HemfMisc.EmfSetBkColor::new),
     setOffsetClipRgn(0x0000001A, HemfWindowing.EmfSetOffsetClipRgn::new),
     setMoveToEx(0x0000001B, HemfDraw.EmfSetMoveToEx::new),
@@ -106,8 +106,8 @@ public enum HemfRecordType {
     setDiBitsToDevice(0x00000050, HemfFill.EmfSetDiBitsToDevice::new),
     stretchdibits(0x00000051, UnimplementedHemfRecord::new),
     extCreateFontIndirectW(0x00000052, HemfText.ExtCreateFontIndirectW::new),
-    exttextouta(0x00000053, HemfText.ExtTextOutA::new),
-    exttextoutw(0x00000054, HemfText.ExtTextOutW::new),
+    exttextouta(0x00000053, HemfText.EmfExtTextOutA::new),
+    exttextoutw(0x00000054, HemfText.EmfExtTextOutW::new),
     polyBezier16(0x00000055, HemfDraw.EmfPolyBezier16::new),
     polygon16(0x00000056, HemfDraw.EmfPolygon16::new),
     polyline16(0x00000057, HemfDraw.EmfPolyline16::new),

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java Mon Sep 24 23:55:52 2018
@@ -29,7 +29,7 @@ import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.poi.hwmf.record.HwmfColorRef;
+import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hwmf.record.HwmfText;
 import org.apache.poi.hwmf.record.HwmfText.WmfSetTextAlign;
 import org.apache.poi.util.Dimension2DDouble;
@@ -53,9 +53,9 @@ public class HemfText {
         GM_COMPATIBLE, GM_ADVANCED
     }
 
-    public static class ExtTextOutA implements HemfRecord {
+    public static class EmfExtTextOutA implements HemfRecord {
 
-        protected final Rectangle2D boundsIgnored = new Rectangle2D.Double();
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
 
         protected EmfGraphicsMode graphicsMode;
 
@@ -67,11 +67,11 @@ public class HemfText {
 
         protected final EmrTextObject textObject;
 
-        public ExtTextOutA() {
+        public EmfExtTextOutA() {
             this(false);
         }
 
-        protected ExtTextOutA(boolean isUnicode) {
+        protected EmfExtTextOutA(boolean isUnicode) {
             textObject = new EmrTextObject(isUnicode);
         }
 
@@ -87,7 +87,7 @@ public class HemfText {
             }
 
             // A WMF RectL object. It is not used and MUST be ignored on receipt.
-            long size = readRectL(leis, boundsIgnored);
+            long size = readRectL(leis, bounds);
 
             // A 32-bit unsigned integer that specifies the graphics mode from the GraphicsMode enumeration
             graphicsMode = EmfGraphicsMode.values()[leis.readInt()-1];
@@ -104,10 +104,10 @@ public class HemfText {
         /**
          *
          * To be implemented!  We need to get the current character set
-         * from the current font for {@link ExtTextOutA},
+         * from the current font for {@link EmfExtTextOutA},
          * which has to be tracked in the playback device.
          *
-         * For {@link ExtTextOutW}, the charset is "UTF-16LE"
+         * For {@link EmfExtTextOutW}, the charset is "UTF-16LE"
          *
          * @param charset the charset to be used to decode the character bytes
          * @return text from this text element
@@ -132,11 +132,24 @@ public class HemfText {
         public Dimension2D getScale() {
             return scale;
         }
+
+        @Override
+        public String toString() {
+            return
+                "{ bounds: { x: "+bounds.getX()+
+                ", y: "+bounds.getY()+
+                ", w: "+bounds.getWidth()+
+                ", h: "+bounds.getHeight()+
+                "}, graphicsMode: '"+graphicsMode+"'"+
+                ", scale: { w: "+scale.getWidth()+", h: "+scale.getHeight()+" }"+
+                ", textObject: "+textObject+
+                "}";
+        }
     }
 
-    public static class ExtTextOutW extends ExtTextOutA {
+    public static class EmfExtTextOutW extends EmfExtTextOutA {
 
-        public ExtTextOutW() {
+        public EmfExtTextOutW() {
             super(true);
         }
 
@@ -175,10 +188,7 @@ public class HemfText {
     /**
      * The EMR_SETTEXTCOLOR record defines the current text color.
      */
-    public static class SetTextColor implements HemfRecord {
-        /** A WMF ColorRef object that specifies the text color value. */
-        private final HwmfColorRef colorRef = new HwmfColorRef();
-
+    public static class EmfSetTextColor extends HwmfText.WmfSetTextColor implements HemfRecord {
         @Override
         public HemfRecordType getEmfRecordType() {
             return HemfRecordType.setTextColor;
@@ -284,6 +294,16 @@ public class HemfText {
             int size = font.init(leis, (int)(recordSize-LittleEndianConsts.INT_SIZE));
             return size+LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public void draw(HemfGraphics ctx) {
+            ctx.addObjectTableEntry(this, fontIdx);
+        }
+
+        @Override
+        public String toString() {
+            return "{ index: "+fontIdx+", font: "+font+" } ";
+        }
     }
 
     public static class EmfExtTextOutOptions extends HwmfText.WmfExtTextOutOptions {

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java Mon Sep 24 23:55:52 2018
@@ -55,10 +55,10 @@ public class HwmfGraphics {
     protected final List<HwmfDrawProperties> propStack = new LinkedList<>();
     protected HwmfDrawProperties prop;
     protected final Graphics2D graphicsCtx;
+    protected final List<HwmfObjectTableEntry> objectTable = new ArrayList<>();
 
     private static final Charset DEFAULT_CHARSET = LocaleUtil.CHARSET_1252;
-    private final List<HwmfObjectTableEntry> objectTable = new ArrayList<>();
-    /** Bounding box from the placeable header */ 
+    /** Bounding box from the placeable header */
     private final Rectangle2D bbox;
     private final AffineTransform initialAT;
 

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java Mon Sep 24 23:55:52 2018
@@ -69,4 +69,9 @@ public class HwmfColorRef implements Clo
             throw new InternalError();
         }
     }
+
+    @Override
+    public String toString() {
+        return String.format("%#8X", colorRef.getRGB());
+    }
 }

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java Mon Sep 24 23:55:52 2018
@@ -23,6 +23,7 @@ import java.awt.geom.Area;
 import java.awt.geom.Ellipse2D;
 import java.awt.geom.Line2D;
 import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.geom.RoundRectangle2D;
@@ -57,6 +58,11 @@ public class HwmfDraw {
         public void draw(HwmfGraphics ctx) {
             ctx.getProperties().setLocation(point);
         }
+
+        @Override
+        public String toString() {
+            return "{ x: "+point.getX()+", y: "+point.getY()+" }";
+        }
     }
 
     /**
@@ -84,6 +90,11 @@ public class HwmfDraw {
             ctx.draw(line);
             ctx.getProperties().setLocation(point);
         }
+
+        @Override
+        public String toString() {
+            return "{ x: "+point.getX()+", y: "+point.getY()+" }";
+        }
     }
 
     /**
@@ -93,7 +104,7 @@ public class HwmfDraw {
      */
     public static class WmfPolygon implements HwmfRecord {
 
-        protected Path2D poly = new Path2D.Double();
+        protected Path2D poly;
         
         @Override
         public HwmfRecordType getWmfRecordType() {
@@ -107,6 +118,7 @@ public class HwmfDraw {
              */
             int numberofPoints = leis.readShort();
 
+            poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, numberofPoints);
             for (int i=0; i<numberofPoints; i++) {
                 // A 16-bit signed integer that defines the horizontal (x) coordinate of the point.
                 int x = leis.readShort();
@@ -134,6 +146,11 @@ public class HwmfDraw {
             }
         }
 
+        @Override
+        public String toString() {
+            return "{ poly: "+polyToString(poly)+" }";
+        }
+
         /**
          * @return true, if the shape should be filled
          */
@@ -279,7 +296,7 @@ public class HwmfDraw {
                  * An array of 16-bit signed integers that define the coordinates of the polygons.
                  * (Note: MS-WMF wrongly says unsigned integers ...)
                  */
-                Path2D poly = new Path2D.Double();
+                Path2D poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, nPoints);
                 for (int i=0; i<nPoints; i++) {
                     int x = leis.readShort();
                     int y = leis.readShort();
@@ -556,6 +573,11 @@ public class HwmfDraw {
         public void draw(HwmfGraphics ctx) {
             ctx.applyObjectTableEntry(objectIndex);
         }
+
+        @Override
+        public String toString() {
+            return "{ index: "+objectIndex +" }";
+        }
     }
     
     static int readBounds(LittleEndianInputStream leis, Rectangle2D bounds) {
@@ -603,4 +625,34 @@ public class HwmfDraw {
         point.setLocation(x, y);
         return 2*LittleEndianConsts.SHORT_SIZE;
     }
+
+    static String polyToString(Path2D poly) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        final PathIterator iter = poly.getPathIterator(null);
+        double[] pnts = new double[6];
+        while (!iter.isDone()) {
+            int segType = iter.currentSegment(pnts);
+            switch (segType) {
+                case PathIterator.SEG_MOVETO:
+                    sb.append("{ type: 'move', x: "+pnts[0]+", y: "+pnts[1]+" }, ");
+                    break;
+                case PathIterator.SEG_LINETO:
+                    sb.append("{ type: 'lineto', x: "+pnts[0]+", y: "+pnts[1]+" }, ");
+                    break;
+                case PathIterator.SEG_QUADTO:
+                    sb.append("{ type: 'quad', x1: "+pnts[0]+", y1: "+pnts[1]+", x2: "+pnts[2]+", y2: "+pnts[3]+" }, ");
+                    break;
+                case PathIterator.SEG_CUBICTO:
+                    sb.append("{ type: 'cubic', x1: "+pnts[0]+", y1: "+pnts[1]+", x2: "+pnts[2]+", y2: "+pnts[3]+", x3: "+pnts[4]+", y3: "+pnts[5]+" }, ");
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    sb.append("{ type: 'close' }, ");
+                    break;
+            }
+            iter.next();
+        }
+        sb.append("]");
+        return sb.toString();
+    }
 }

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java Mon Sep 24 23:55:52 2018
@@ -146,6 +146,20 @@ public class HwmfFont implements FontInf
             flag = leis.readUByte();
             return LittleEndianConsts.BYTE_SIZE;
         }
+
+        @Override
+        public String toString() {
+            return
+                (((flag&0x3) == 0 ? "default " : " ")+
+                (CLIP_CHARACTER_PRECIS.isSet(flag) ? "char " : " ")+
+                (CLIP_STROKE_PRECIS.isSet(flag) ? "stroke " : " ")+
+                (CLIP_LH_ANGLES.isSet(flag) ? "angles " : " ")+
+                (CLIP_TT_ALWAYS.isSet(flag) ? "tt_always " : " ")+
+                (CLIP_DFA_DISABLE.isSet(flag) ? "dfa " : " ")+
+                (CLIP_EMBEDDED.isSet(flag) ? "embedded " : " ")
+                ).trim()
+            ;
+        }
     }
 
     /**
@@ -453,6 +467,25 @@ public class HwmfFont implements FontInf
         throw new UnsupportedOperationException("setCharset not supported by HwmfFont.");
     }
 
+    @Override
+    public String toString() {
+        return "{ height: "+height+
+                ", width: "+width+
+                ", escapment: "+escapement+
+                ", weight: "+weight+
+                ", italic: "+italic+
+                ", underline: "+underline+
+                ", strikeOut: "+strikeOut+
+                ", charset: '"+charSet+"'"+
+                ", outPrecision: '"+outPrecision+"'"+
+                ", clipPrecision: '"+clipPrecision+"'"+
+                ", qualtiy: '"+quality+"'"+
+                ", pitch: '"+getPitch()+"'"+
+                ", family: '"+getFamily()+"'"+
+                ", facename: '"+facename+"'"+
+                "}";
+    }
+
     protected int readString(LittleEndianInputStream leis, StringBuilder sb, int limit) throws IOException {
         byte buf[] = new byte[limit], b, readBytes = 0;
         do {

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java Mon Sep 24 23:55:52 2018
@@ -49,6 +49,11 @@ public class HwmfMisc {
         public void draw(HwmfGraphics ctx) {
             ctx.saveProperties();
         }
+
+        @Override
+        public String toString() {
+            return "{}";
+        }
     }
 
     /**
@@ -80,7 +85,7 @@ public class HwmfMisc {
          * member is positive, nSavedDC represents a specific instance of the state to be restored. If
          * this member is negative, nSavedDC represents an instance relative to the current state.
          */
-        private int nSavedDC;
+        protected int nSavedDC;
 
         @Override
         public HwmfRecordType getWmfRecordType() {
@@ -97,6 +102,11 @@ public class HwmfMisc {
         public void draw(HwmfGraphics ctx) {
             ctx.restoreProperties(nSavedDC);
         }
+
+        @Override
+        public String toString() {
+            return "{ nSavedDC: "+nSavedDC+" }";
+        }
     }
 
     /**
@@ -105,7 +115,7 @@ public class HwmfMisc {
      */
     public static class WmfSetBkColor implements HwmfRecord {
 
-        private HwmfColorRef colorRef;
+        protected final HwmfColorRef colorRef = new HwmfColorRef();
 
         @Override
         public HwmfRecordType getWmfRecordType() {
@@ -114,7 +124,6 @@ public class HwmfMisc {
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            colorRef = new HwmfColorRef();
             return colorRef.init(leis);
         }
 
@@ -122,6 +131,11 @@ public class HwmfMisc {
         public void draw(HwmfGraphics ctx) {
             ctx.getProperties().setBackgroundColor(colorRef);
         }
+
+        @Override
+        public String toString() {
+            return "{ colorRef: "+colorRef+" }";
+        }
     }
 
     /**
@@ -465,6 +479,11 @@ public class HwmfMisc {
 
             ctx.unsetObjectTableEntry(objectIndex);
         }
+
+        @Override
+        public String toString() {
+            return "{ index: "+objectIndex+" }";
+        }
     }
 
     public static class WmfCreatePatternBrush implements HwmfRecord, HwmfObjectTableEntry {

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java Mon Sep 24 23:55:52 2018
@@ -82,7 +82,7 @@ public class HwmfText {
      */
     public static class WmfSetTextColor implements HwmfRecord {
         
-        private HwmfColorRef colorRef;
+        protected final HwmfColorRef colorRef = new HwmfColorRef();
         
         @Override
         public HwmfRecordType getWmfRecordType() {
@@ -91,7 +91,6 @@ public class HwmfText {
         
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            colorRef = new HwmfColorRef();
             return colorRef.init(leis);
         }
 
@@ -99,6 +98,11 @@ public class HwmfText {
         public void draw(HwmfGraphics ctx) {
             ctx.getProperties().setTextColor(colorRef);
         }
+
+        @Override
+        public String toString() {
+            return "{ colorRef: "+colorRef+" }";
+        }
     }
     
     /**
@@ -645,5 +649,10 @@ public class HwmfText {
         public HwmfFont getFont() {
             return font;
         }
+
+        @Override
+        public String toString() {
+            return "{ font: "+font+" } ";
+        }
     }
 }

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java Mon Sep 24 23:55:52 2018
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hwmf.record;
 
+import static org.apache.poi.hwmf.record.HwmfDraw.readBounds;
+
 import java.awt.Shape;
 import java.awt.geom.Area;
 import java.awt.geom.Rectangle2D;
@@ -446,20 +448,7 @@ public class HwmfWindowing {
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            // A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-            // lower-right corner of the rectangle.
-            final int bottom = leis.readShort();
-            // A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-            // lower-right corner of the rectangle.
-            final int right = leis.readShort();
-            // A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-            // upper-left corner of the rectangle.
-            final int top = leis.readShort();
-            // A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-            // upper-left corner of the rectangle.
-            final int left = leis.readShort();
-            bounds.setRect(left, top, right-left, bottom-top);
-            return 4*LittleEndianConsts.SHORT_SIZE;
+            return readBounds(leis, bounds);
         }
 
         @Override
@@ -470,6 +459,16 @@ public class HwmfWindowing {
         @Override
         public void applyObject(HwmfGraphics ctx) {
         }
+
+        @Override
+        public String toString() {
+            return
+                "{ x: "+bounds.getX()+
+                ", y: "+bounds.getY()+
+                ", w: "+bounds.getWidth()+
+                ", h: "+bounds.getHeight()+
+                "}";
+        }
     }
 
     /**

Modified: poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java?rev=1841897&r1=1841896&r2=1841897&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java (original)
+++ poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java Mon Sep 24 23:55:52 2018
@@ -32,6 +32,7 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.HashSet;
@@ -63,7 +64,7 @@ public class HemfPictureTest {
     @Test
     @Ignore("Only for manual tests")
     public void paint() throws IOException {
-        File f = sl_samples.getFile("wrench.emf");
+        File f = new File("picture_14.emf"); // sl_samples.getFile("wrench.emf");
         try (FileInputStream fis = new FileInputStream(f)) {
             HemfPicture emf = new HemfPicture(fis);
 
@@ -84,6 +85,14 @@ public class HemfPictureTest {
             g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
             g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
 
+            FileWriter fw = new FileWriter("record-list.txt");
+            int i=0;
+            for (HemfRecord r : emf.getRecords())  {
+                fw.write(i + " "+r.getEmfRecordType()+" "+r.toString()+"\n");
+                i++;
+            }
+            fw.close();
+
             emf.draw(g, new Rectangle2D.Double(0,0,width,height));
 
             g.dispose();
@@ -160,7 +169,7 @@ public class HemfPictureTest {
             StringBuilder sb = new StringBuilder();
             for (HemfRecord record : pic) {
                 if (record.getEmfRecordType().equals(HemfRecordType.exttextoutw)) {
-                    HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record;
+                    HemfText.EmfExtTextOutW extTextOutW = (HemfText.EmfExtTextOutW) record;
                     Point2D reference = extTextOutW.getTextObject().getReference();
                     if (lastY > -1 && lastY != reference.getY()) {
                         sb.append("\n");
@@ -194,7 +203,7 @@ public class HemfPictureTest {
             int foundExpected = 0;
             for (HemfRecord record : pic) {
                 if (record.getEmfRecordType().equals(HemfRecordType.exttextoutw)) {
-                    HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record;
+                    HemfText.EmfExtTextOutW extTextOutW = (HemfText.EmfExtTextOutW) record;
                     Point2D reference = extTextOutW.getTextObject().getReference();
                     if (lastY > -1 && lastY != reference.getY()) {
                         sb.append("\n");



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