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/14 21:37:38 UTC

svn commit: r1840956 [5/5] - in /poi/branches/hemf/src: java/org/apache/poi/util/ ooxml/java/org/apache/poi/xdgf/geom/ ooxml/java/org/apache/poi/xdgf/usermodel/ ooxml/java/org/apache/poi/xdgf/util/ scratchpad/src/org/apache/poi/hemf/draw/ scratchpad/sr...

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecordType.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecordType.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecordType.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecordType.java Fri Sep 14 21:37:37 2018
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hwmf.record;
 
+import java.util.function.Supplier;
+
 /**
  * Available record types for WMF
  * 
@@ -24,83 +26,83 @@ package org.apache.poi.hwmf.record;
  */
 public enum HwmfRecordType {
      eof(0x0000, null)
-    ,animatePalette(0x0436, HwmfPalette.WmfAnimatePalette.class)
-    ,arc(0x0817, HwmfDraw.WmfArc.class)
-    ,bitBlt(0x0922, HwmfFill.WmfBitBlt.class)
-    ,chord(0x0830, HwmfDraw.WmfChord.class)
-    ,createBrushIndirect(0x02fc, HwmfMisc.WmfCreateBrushIndirect.class)
-    ,createFontIndirect(0x02fb, HwmfText.WmfCreateFontIndirect.class)
-    ,createPalette(0x00f7, HwmfPalette.WmfCreatePalette.class)
-    ,createPatternBrush(0x01f9, HwmfMisc.WmfCreatePatternBrush.class)
-    ,createPenIndirect(0x02fa, HwmfMisc.WmfCreatePenIndirect.class)
-    ,createRegion(0x06ff, HwmfWindowing.WmfCreateRegion.class)
-    ,deleteObject(0x01f0, HwmfMisc.WmfDeleteObject.class)
-    ,dibBitBlt(0x0940, HwmfFill.WmfDibBitBlt.class)
-    ,dibCreatePatternBrush(0x0142, HwmfMisc.WmfDibCreatePatternBrush.class)
-    ,dibStretchBlt(0x0b41, HwmfFill.WmfDibStretchBlt.class)
-    ,ellipse(0x0418, HwmfDraw.WmfEllipse.class)
-    ,escape(0x0626, HwmfEscape.class)
-    ,excludeClipRect(0x0415, HwmfWindowing.WmfExcludeClipRect.class)
-    ,extFloodFill(0x0548, HwmfFill.WmfExtFloodFill.class)
-    ,extTextOut(0x0a32, HwmfText.WmfExtTextOut.class)
-    ,fillRegion(0x0228, HwmfFill.WmfFillRegion.class)
-    ,floodFill(0x0419, HwmfFill.WmfFloodFill.class)
-    ,frameRegion(0x0429, HwmfDraw.WmfFrameRegion.class)
-    ,intersectClipRect(0x0416, HwmfWindowing.WmfIntersectClipRect.class)
-    ,invertRegion(0x012a, HwmfFill.WmfInvertRegion.class)
-    ,lineTo(0x0213, HwmfDraw.WmfLineTo.class)
-    ,moveTo(0x0214, HwmfDraw.WmfMoveTo.class)
-    ,offsetClipRgn(0x0220, HwmfWindowing.WmfOffsetClipRgn.class)
-    ,offsetViewportOrg(0x0211, HwmfWindowing.WmfOffsetViewportOrg.class)
-    ,offsetWindowOrg(0x020f, HwmfWindowing.WmfOffsetWindowOrg.class)
-    ,paintRegion(0x012b, HwmfFill.WmfPaintRegion.class)
-    ,patBlt(0x061d, HwmfFill.WmfPatBlt.class)
-    ,pie(0x081a, HwmfDraw.WmfPie.class)
-    ,polygon(0x0324, HwmfDraw.WmfPolygon.class)
-    ,polyline(0x0325, HwmfDraw.WmfPolyline.class)
-    ,polyPolygon(0x0538, HwmfDraw.WmfPolyPolygon.class)
-    ,realizePalette(0x0035, HwmfPalette.WmfRealizePalette.class)
-    ,rectangle(0x041b, HwmfDraw.WmfRectangle.class)
-    ,resizePalette(0x0139, HwmfPalette.WmfResizePalette.class)
-    ,restoreDc(0x0127, HwmfMisc.WmfRestoreDc.class)
-    ,roundRect(0x061c, HwmfDraw.WmfRoundRect.class)
-    ,saveDc(0x001e, HwmfMisc.WmfSaveDc.class)
-    ,scaleViewportExt(0x0412, HwmfWindowing.WmfScaleViewportExt.class) 
-    ,scaleWindowExt(0x0410, HwmfWindowing.WmfScaleWindowExt.class)
-    ,selectClipRegion(0x012c, HwmfWindowing.WmfSelectClipRegion.class)
-    ,selectObject(0x012d, HwmfDraw.WmfSelectObject.class)
-    ,selectPalette(0x0234, HwmfPalette.WmfSelectPalette.class)
-    ,setBkColor(0x0201, HwmfMisc.WmfSetBkColor.class)
-    ,setBkMode(0x0102, HwmfMisc.WmfSetBkMode.class)
-    ,setDibToDev(0x0d33, HwmfFill.WmfSetDibToDev.class)
-    ,setLayout(0x0149, HwmfMisc.WmfSetLayout.class)
-    ,setMapMode(0x0103, HwmfMisc.WmfSetMapMode.class)
-    ,setMapperFlags(0x0231, HwmfMisc.WmfSetMapperFlags.class)
-    ,setPalEntries(0x0037, HwmfPalette.WmfSetPaletteEntries.class)
-    ,setPixel(0x041f, HwmfDraw.WmfSetPixel.class)
-    ,setPolyFillMode(0x0106, HwmfFill.WmfSetPolyfillMode.class)
-    ,setRelabs(0x0105, HwmfMisc.WmfSetRelabs.class)
-    ,setRop2(0x0104, HwmfMisc.WmfSetRop2.class)
-    ,setStretchBltMode(0x0107, HwmfMisc.WmfSetStretchBltMode.class)
-    ,setTextAlign(0x012e, HwmfText.WmfSetTextAlign.class)
-    ,setTextCharExtra(0x0108, HwmfText.WmfSetTextCharExtra.class)
-    ,setTextColor(0x0209, HwmfText.WmfSetTextColor.class)
-    ,setTextJustification(0x020a, HwmfText.WmfSetTextJustification.class)
-    ,setViewportExt(0x020e, HwmfWindowing.WmfSetViewportExt.class)
-    ,setViewportOrg(0x020d, HwmfWindowing.WmfSetViewportOrg.class)
-    ,setWindowExt(0x020c, HwmfWindowing.WmfSetWindowExt.class)
-    ,setWindowOrg(0x020b, HwmfWindowing.WmfSetWindowOrg.class)
-    ,stretchBlt(0x0b23, HwmfFill.WmfStretchBlt.class)
-    ,stretchDib(0x0f43, HwmfFill.WmfStretchDib.class)
-    ,textOut(0x0521, HwmfText.WmfTextOut.class)
+    ,animatePalette(0x0436, HwmfPalette.WmfAnimatePalette::new)
+    ,arc(0x0817, HwmfDraw.WmfArc::new)
+    ,bitBlt(0x0922, HwmfFill.WmfBitBlt::new)
+    ,chord(0x0830, HwmfDraw.WmfChord::new)
+    ,createBrushIndirect(0x02fc, HwmfMisc.WmfCreateBrushIndirect::new)
+    ,createFontIndirect(0x02fb, HwmfText.WmfCreateFontIndirect::new)
+    ,createPalette(0x00f7, HwmfPalette.WmfCreatePalette::new)
+    ,createPatternBrush(0x01f9, HwmfMisc.WmfCreatePatternBrush::new)
+    ,createPenIndirect(0x02fa, HwmfMisc.WmfCreatePenIndirect::new)
+    ,createRegion(0x06ff, HwmfWindowing.WmfCreateRegion::new)
+    ,deleteObject(0x01f0, HwmfMisc.WmfDeleteObject::new)
+    ,dibBitBlt(0x0940, HwmfFill.WmfDibBitBlt::new)
+    ,dibCreatePatternBrush(0x0142, HwmfMisc.WmfDibCreatePatternBrush::new)
+    ,dibStretchBlt(0x0b41, HwmfFill.WmfDibStretchBlt::new)
+    ,ellipse(0x0418, HwmfDraw.WmfEllipse::new)
+    ,escape(0x0626, HwmfEscape::new)
+    ,excludeClipRect(0x0415, HwmfWindowing.WmfExcludeClipRect::new)
+    ,extFloodFill(0x0548, HwmfFill.WmfExtFloodFill::new)
+    ,extTextOut(0x0a32, HwmfText.WmfExtTextOut::new)
+    ,fillRegion(0x0228, HwmfFill.WmfFillRegion::new)
+    ,floodFill(0x0419, HwmfFill.WmfFloodFill::new)
+    ,frameRegion(0x0429, HwmfDraw.WmfFrameRegion::new)
+    ,intersectClipRect(0x0416, HwmfWindowing.WmfIntersectClipRect::new)
+    ,invertRegion(0x012a, HwmfFill.WmfInvertRegion::new)
+    ,lineTo(0x0213, HwmfDraw.WmfLineTo::new)
+    ,moveTo(0x0214, HwmfDraw.WmfMoveTo::new)
+    ,offsetClipRgn(0x0220, HwmfWindowing.WmfOffsetClipRgn::new)
+    ,offsetViewportOrg(0x0211, HwmfWindowing.WmfOffsetViewportOrg::new)
+    ,offsetWindowOrg(0x020f, HwmfWindowing.WmfOffsetWindowOrg::new)
+    ,paintRegion(0x012b, HwmfFill.WmfPaintRegion::new)
+    ,patBlt(0x061d, HwmfFill.WmfPatBlt::new)
+    ,pie(0x081a, HwmfDraw.WmfPie::new)
+    ,polygon(0x0324, HwmfDraw.WmfPolygon::new)
+    ,polyline(0x0325, HwmfDraw.WmfPolyline::new)
+    ,polyPolygon(0x0538, HwmfDraw.WmfPolyPolygon::new)
+    ,realizePalette(0x0035, HwmfPalette.WmfRealizePalette::new)
+    ,rectangle(0x041b, HwmfDraw.WmfRectangle::new)
+    ,resizePalette(0x0139, HwmfPalette.WmfResizePalette::new)
+    ,restoreDc(0x0127, HwmfMisc.WmfRestoreDc::new)
+    ,roundRect(0x061c, HwmfDraw.WmfRoundRect::new)
+    ,saveDc(0x001e, HwmfMisc.WmfSaveDc::new)
+    ,scaleViewportExt(0x0412, HwmfWindowing.WmfScaleViewportExt::new)
+    ,scaleWindowExt(0x0410, HwmfWindowing.WmfScaleWindowExt::new)
+    ,selectClipRegion(0x012c, HwmfWindowing.WmfSelectClipRegion::new)
+    ,selectObject(0x012d, HwmfDraw.WmfSelectObject::new)
+    ,selectPalette(0x0234, HwmfPalette.WmfSelectPalette::new)
+    ,setBkColor(0x0201, HwmfMisc.WmfSetBkColor::new)
+    ,setBkMode(0x0102, HwmfMisc.WmfSetBkMode::new)
+    ,setDibToDev(0x0d33, HwmfFill.WmfSetDibToDev::new)
+    ,setLayout(0x0149, HwmfMisc.WmfSetLayout::new)
+    ,setMapMode(0x0103, HwmfMisc.WmfSetMapMode::new)
+    ,setMapperFlags(0x0231, HwmfMisc.WmfSetMapperFlags::new)
+    ,setPalEntries(0x0037, HwmfPalette.WmfSetPaletteEntries::new)
+    ,setPixel(0x041f, HwmfDraw.WmfSetPixel::new)
+    ,setPolyFillMode(0x0106, HwmfFill.WmfSetPolyfillMode::new)
+    ,setRelabs(0x0105, HwmfMisc.WmfSetRelabs::new)
+    ,setRop2(0x0104, HwmfMisc.WmfSetRop2::new)
+    ,setStretchBltMode(0x0107, HwmfMisc.WmfSetStretchBltMode::new)
+    ,setTextAlign(0x012e, HwmfText.WmfSetTextAlign::new)
+    ,setTextCharExtra(0x0108, HwmfText.WmfSetTextCharExtra::new)
+    ,setTextColor(0x0209, HwmfText.WmfSetTextColor::new)
+    ,setTextJustification(0x020a, HwmfText.WmfSetTextJustification::new)
+    ,setViewportExt(0x020e, HwmfWindowing.WmfSetViewportExt::new)
+    ,setViewportOrg(0x020d, HwmfWindowing.WmfSetViewportOrg::new)
+    ,setWindowExt(0x020c, HwmfWindowing.WmfSetWindowExt::new)
+    ,setWindowOrg(0x020b, HwmfWindowing.WmfSetWindowOrg::new)
+    ,stretchBlt(0x0b23, HwmfFill.WmfStretchBlt::new)
+    ,stretchDib(0x0f43, HwmfFill.WmfStretchDib::new)
+    ,textOut(0x0521, HwmfText.WmfTextOut::new)
     ;
     
     public final int id;
-    public final Class<? extends HwmfRecord> clazz;
+    public final Supplier<? extends HwmfRecord> constructor;
     
-    HwmfRecordType(int id, Class<? extends HwmfRecord> clazz) {
+    HwmfRecordType(int id, Supplier<? extends HwmfRecord> constructor) {
         this.id = id;
-        this.clazz = clazz;
+        this.constructor = constructor;
     }
     
     public static HwmfRecordType getById(int id) {

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=1840956&r1=1840955&r2=1840956&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 Fri Sep 14 21:37:37 2018
@@ -17,8 +17,16 @@
 
 package org.apache.poi.hwmf.record;
 
+import static org.apache.poi.hwmf.record.HwmfDraw.readPointS;
+import static org.apache.poi.hwmf.record.HwmfDraw.readRectS;
+
+import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
 import java.nio.charset.Charset;
 
 import org.apache.poi.hwmf.draw.HwmfDrawProperties;
@@ -31,6 +39,7 @@ import org.apache.poi.util.LittleEndianC
 import org.apache.poi.util.LittleEndianInputStream;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
+import org.apache.poi.util.RecordFormatException;
 
 public class HwmfText {
     private static final POILogger logger = POILogFactory.getLogger(HwmfText.class);
@@ -52,7 +61,7 @@ public class HwmfText {
         private int charExtra;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setTextCharExtra;
         }
         
@@ -76,7 +85,7 @@ public class HwmfText {
         private HwmfColorRef colorRef;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setTextColor;
         }
         
@@ -112,7 +121,7 @@ public class HwmfText {
         private int breakExtra;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setBkColor;
         }
         
@@ -159,7 +168,7 @@ public class HwmfText {
         private int xStart;  
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.textOut;
         }
         
@@ -195,41 +204,48 @@ public class HwmfText {
             return ret;
         }
     }
-    
-    /**
-     * The META_EXTTEXTOUT record outputs text by using the font, background color, and text color that
-     * are defined in the playback device context. Optionally, dimensions can be provided for clipping,
-     * opaquing, or both.
-     */
-    public static class WmfExtTextOut implements HwmfRecord {
 
+    public static class WmfExtTextOutOptions {
         /**
-         * Indicates that the background color that is defined in the playback device context 
+         * Indicates that the background color that is defined in the playback device context
          * SHOULD be used to fill the rectangle.
-         */ 
+         */
         private static final BitField ETO_OPAQUE = BitFieldFactory.getInstance(0x0002);
-        
+
         /**
          * Indicates that the text SHOULD be clipped to the rectangle.
          */
         private static final BitField ETO_CLIPPED = BitFieldFactory.getInstance(0x0004);
 
         /**
-         * Indicates that the string to be output SHOULD NOT require further processing 
-         * with respect to the placement of the characters, and an array of character 
-         * placement values SHOULD be provided. This character placement process is 
+         * Indicates that the string to be output SHOULD NOT require further processing
+         * with respect to the placement of the characters, and an array of character
+         * placement values SHOULD be provided. This character placement process is
          * useful for fonts in which diacritical characters affect character spacing.
          */
         private static final BitField ETO_GLYPH_INDEX = BitFieldFactory.getInstance(0x0010);
 
         /**
-         * Indicates that the text MUST be laid out in right-to-left reading order, instead of 
-         * the default left-to-right order. This SHOULD be applied only when the font that is 
+         * Indicates that the text MUST be laid out in right-to-left reading order, instead of
+         * the default left-to-right order. This SHOULD be applied only when the font that is
          * defined in the playback device context is either Hebrew or Arabic.
          */
         private static final BitField ETO_RTLREADING = BitFieldFactory.getInstance(0x0080);
 
         /**
+         * This bit indicates that the record does not specify a bounding rectangle for the
+         * text output.
+         */
+        private static final BitField ETO_NO_RECT = BitFieldFactory.getInstance(0x0100);
+
+        /**
+         * This bit indicates that the codes for characters in an output text string are 8 bits,
+         * derived from the low bytes of 16-bit Unicode UTF16-LE character codes, in which
+         * the high byte is assumed to be 0.
+         */
+        private static final BitField ETO_SMALL_CHARS = BitFieldFactory.getInstance(0x0200);
+
+        /**
          * Indicates that to display numbers, digits appropriate to the locale SHOULD be used.
          */
         private static final BitField ETO_NUMERICSLOCAL = BitFieldFactory.getInstance(0x0400);
@@ -240,32 +256,58 @@ public class HwmfText {
         private static final BitField ETO_NUMERICSLATIN = BitFieldFactory.getInstance(0x0800);
 
         /**
-         * Indicates that both horizontal and vertical character displacement values 
+         * This bit indicates that no special operating system processing for glyph placement
+         * should be performed on right-to-left strings; that is, all glyph positioning
+         * SHOULD be taken care of by drawing and state records in the metafile
+         */
+        private static final BitField ETO_IGNORELANGUAGE = BitFieldFactory.getInstance(0x1000);
+
+        /**
+         * Indicates that both horizontal and vertical character displacement values
          * SHOULD be provided.
          */
         private static final BitField ETO_PDY = BitFieldFactory.getInstance(0x2000);
 
+        /** This bit is reserved and SHOULD NOT be used. */
+        private static final BitField ETO_REVERSE_INDEX_MAP = BitFieldFactory.getInstance(0x10000);
+
+        protected int flag;
+
+        public int init(LittleEndianInputStream leis) {
+            flag = leis.readUShort();
+            return LittleEndianConsts.SHORT_SIZE;
+        }
+
+        public boolean isOpaque() {
+            return ETO_OPAQUE.isSet(flag);
+        }
+
+        public boolean isClipped() {
+            return ETO_CLIPPED.isSet(flag);
+        }
+    }
+
+    /**
+     * The META_EXTTEXTOUT record outputs text by using the font, background color, and text color that
+     * are defined in the playback device context. Optionally, dimensions can be provided for clipping,
+     * opaquing, or both.
+     */
+    public static class WmfExtTextOut implements HwmfRecord {
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, where the 
-        text string is to be located.
+         * The location, in logical units, where the text string is to be placed.
          */
-        private int y;  
+        protected final Point2D reference = new Point2D.Double();
+
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, where the 
-        text string is to be located.
+         * A 16-bit signed integer that defines the length of the string.
          */
-        private int x;  
+        protected int stringLength;
         /**
-         * A 16-bit signed integer that defines the length of the string.
+         * A 16-bit unsigned integer that defines the use of the application-defined
+         * rectangle. This member can be a combination of one or more values in the
+         * ExtTextOutOptions Flags (ETO_*)
          */
-        private int stringLength;
-
-         /**
-          * A 16-bit unsigned integer that defines the use of the application-defined 
-          * rectangle. This member can be a combination of one or more values in the 
-          * ExtTextOutOptions Flags (ETO_*)
-          */
-        private int fwOpts;
+        protected final WmfExtTextOutOptions options;
         /**
          * An optional 8-byte Rect Object (section 2.2.2.18) that defines the 
          * dimensions, in logical coordinates, of a rectangle that is used for clipping, opaquing, or both.
@@ -274,14 +316,14 @@ public class HwmfText {
          * Each value is a 16-bit signed integer that defines the coordinate, in logical coordinates, of 
          * the upper-left corner of the rectangle
          */
-        private int left,top,right,bottom;
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
         /**
          * A variable-length string that specifies the text to be drawn. The string does 
          * not need to be null-terminated, because StringLength specifies the length of the string. If 
          * the length is odd, an extra byte is placed after it so that the following member (optional Dx) is 
          * aligned on a 16-bit boundary.
          */
-        private byte[] rawTextBytes;
+        protected byte[] rawTextBytes;
         /**
          * An optional array of 16-bit signed integers that indicate the distance between 
          * origins of adjacent character cells. For example, Dx[i] logical units separate the origins of 
@@ -289,9 +331,17 @@ public class HwmfText {
          * number of values as there are characters in the string.
          */
         private int dx[];
-        
+
+        public WmfExtTextOut() {
+            this(new WmfExtTextOutOptions());
+        }
+
+        protected WmfExtTextOut(WmfExtTextOutOptions options) {
+            this.options = options;
+        }
+
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.extTextOut;
         }
         
@@ -299,22 +349,17 @@ public class HwmfText {
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             // -6 bytes of record function and length header
             final int remainingRecordSize = (int)(recordSize-6);
-            
-            y = leis.readShort();
-            x = leis.readShort();
+
+            int size = readPointS(leis, reference);
+
             stringLength = leis.readShort();
-            fwOpts = leis.readUShort();
-            
-            int size = 4*LittleEndianConsts.SHORT_SIZE;
-            
+            size += LittleEndianConsts.SHORT_SIZE;
+            size += options.init(leis);
+
             // Check if we have a rectangle
-            if ((ETO_OPAQUE.isSet(fwOpts) || ETO_CLIPPED.isSet(fwOpts)) && size+8<=remainingRecordSize) {
-                // the bounding rectangle is optional and only read when fwOpts are given
-                left = leis.readShort();
-                top = leis.readShort();
-                right = leis.readShort();
-                bottom = leis.readShort();
-                size += 4*LittleEndianConsts.SHORT_SIZE;
+            if ((options.isOpaque() || options.isClipped()) && size+8<=remainingRecordSize) {
+                // the bounding rectangle is optional and only read when options are given
+                size += readRectS(leis, bounds);
             }
             
             rawTextBytes = IOUtils.safelyAllocate(stringLength+(stringLength&1), MAX_RECORD_LENGTH);
@@ -342,12 +387,46 @@ public class HwmfText {
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            Rectangle2D bounds = new Rectangle2D.Double(x, y, 0, 0);
+            Rectangle2D bounds = new Rectangle2D.Double(reference.getX(), reference.getY(), 0, 0);
             ctx.drawString(getTextBytes(), bounds, dx);
         }
 
-        public String getText(Charset charset) {
-            return new String(getTextBytes(), charset);
+
+        public String getText(Charset charset) throws IOException {
+            StringBuilder sb = new StringBuilder();
+            try (Reader r = new InputStreamReader(new ByteArrayInputStream(rawTextBytes), charset)) {
+                for (int i = 0; i < stringLength; i++) {
+                    sb.appendCodePoint(readCodePoint(r));
+                }
+            }
+            return sb.toString();
+        }
+
+        //TODO: move this to IOUtils?
+        private int readCodePoint(Reader r) throws IOException {
+            int c1 = r.read();
+            if (c1 == -1) {
+                throw new EOFException("Tried to read beyond byte array");
+            }
+            if (!Character.isHighSurrogate((char)c1)) {
+                return c1;
+            }
+            int c2 = r.read();
+            if (c2 == -1) {
+                throw new EOFException("Tried to read beyond byte array");
+            }
+            if (!Character.isLowSurrogate((char)c2)) {
+                throw new RecordFormatException("Expected low surrogate after high surrogate");
+            }
+            return Character.toCodePoint((char)c1, (char)c2);
+        }
+
+        public Point2D getReference() {
+            return reference;
+        }
+
+        public Rectangle2D getBounds() {
+            return bounds;
         }
 
         /**
@@ -482,10 +561,10 @@ public class HwmfText {
          * for text with a horizontal baseline, and VerticalTextAlignmentMode Flags
          * for text with a vertical baseline.
          */
-        private int textAlignmentMode;
+        protected int textAlignmentMode;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setTextAlign;
         }
         
@@ -533,17 +612,24 @@ public class HwmfText {
     }
     
     public static class WmfCreateFontIndirect implements HwmfRecord, HwmfObjectTableEntry {
-        private HwmfFont font;
-        
+        protected final HwmfFont font;
+
+        public WmfCreateFontIndirect() {
+            this(new HwmfFont());
+        }
+
+        protected WmfCreateFontIndirect(HwmfFont font) {
+            this.font = font;
+        }
+
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.createFontIndirect;
         }
         
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            font = new HwmfFont();
-            return font.init(leis);
+            return font.init(leis, recordSize);
         }
 
         @Override

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=1840956&r1=1840955&r2=1840956&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 Fri Sep 14 21:37:37 2018
@@ -33,18 +33,14 @@ public class HwmfWindowing {
      */
     public static class WmfSetViewportOrg implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the vertical offset, in device units.
-         */
-        private int y;
+        /** A signed integer that defines the vertical offset, in device units. */
+        protected int y;
 
-        /**
-         * A 16-bit signed integer that defines the horizontal offset, in device units.
-         */
-        private int x;
+        /** A signed integer that defines the horizontal offset, in device units. */
+        protected int x;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setViewportOrg;
         }
 
@@ -67,20 +63,14 @@ public class HwmfWindowing {
      */
     public static class WmfSetViewportExt implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the vertical extent
-         * of the viewport in device units.
-         */
-        private int height;
+        /** A signed integer that defines the vertical extent of the viewport in device units. */
+        protected int height;
 
-        /**
-         * A 16-bit signed integer that defines the horizontal extent
-         * of the viewport in device units.
-         */
-        private int width;
+        /** A signed integer that defines the horizontal extent of the viewport in device units. */
+        protected int width;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setViewportExt;
         }
 
@@ -114,7 +104,7 @@ public class HwmfWindowing {
         private int xOffset;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.offsetViewportOrg;
         }
 
@@ -139,18 +129,14 @@ public class HwmfWindowing {
      */
     public static class WmfSetWindowOrg implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units.
-         */
-        private int y;
+        /** A signed integer that defines the y-coordinate, in logical units. */
+        protected int y;
 
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units.
-         */
-        private int x;
+        /** A signed integer that defines the x-coordinate, in logical units. */
+        protected int x;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setWindowOrg;
         }
 
@@ -182,20 +168,14 @@ public class HwmfWindowing {
      */
     public static class WmfSetWindowExt implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the vertical extent of
-         * the window in logical units.
-         */
-        private int height;
+        /** A signed integer that defines the vertical extent of the window in logical units. */
+        protected int height;
 
-        /**
-         * A 16-bit signed integer that defines the horizontal extent of
-         * the window in logical units.
-         */
-        private int width;
+        /** A signed integer that defines the horizontal extent of the window in logical units. */
+        protected int width;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setWindowExt;
         }
 
@@ -238,7 +218,7 @@ public class HwmfWindowing {
         private int xOffset;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.offsetWindowOrg;
         }
 
@@ -264,31 +244,31 @@ public class HwmfWindowing {
     public static class WmfScaleWindowExt implements HwmfRecord {
 
         /**
-         * A 16-bit signed integer that defines the amount by which to divide the
+         * A signed integer that defines the amount by which to divide the
          * result of multiplying the current y-extent by the value of the yNum member.
          */
-        private int yDenom;
+        protected int yDenom;
 
         /**
-         * A 16-bit signed integer that defines the amount by which to multiply the
+         * A signed integer that defines the amount by which to multiply the
          * current y-extent.
          */
-        private int yNum;
+        protected int yNum;
 
         /**
-         * A 16-bit signed integer that defines the amount by which to divide the
+         * A signed integer that defines the amount by which to divide the
          * result of multiplying the current x-extent by the value of the xNum member.
          */
-        private int xDenom;
+        protected int xDenom;
 
         /**
-         * A 16-bit signed integer that defines the amount by which to multiply the
+         * A signed integer that defines the amount by which to multiply the
          * current x-extent.
          */
-        private int xNum;
+        protected int xNum;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.scaleWindowExt;
         }
 
@@ -320,31 +300,31 @@ public class HwmfWindowing {
     public static class WmfScaleViewportExt implements HwmfRecord {
 
         /**
-         * A 16-bit signed integer that defines the amount by which to divide the
+         * A signed integer that defines the amount by which to divide the
          * result of multiplying the current y-extent by the value of the yNum member.
          */
-        private int yDenom;
+        protected int yDenom;
 
         /**
-         * A 16-bit signed integer that defines the amount by which to multiply the
+         * A signed integer that defines the amount by which to multiply the
          * current y-extent.
          */
-        private int yNum;
+        protected int yNum;
 
         /**
-         * A 16-bit signed integer that defines the amount by which to divide the
+         * A signed integer that defines the amount by which to divide the
          * result of multiplying the current x-extent by the value of the xNum member.
          */
-        private int xDenom;
+        protected int xDenom;
 
         /**
-         * A 16-bit signed integer that defines the amount by which to multiply the
+         * A signed integer that defines the amount by which to multiply the
          * current x-extent.
          */
-        private int xNum;
+        protected int xNum;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.scaleViewportExt;
         }
 
@@ -376,17 +356,17 @@ public class HwmfWindowing {
     public static class WmfOffsetClipRgn implements HwmfRecord, HwmfObjectTableEntry {
 
         /**
-         * A 16-bit signed integer that defines the number of logical units to move up or down.
+         * A signed integer that defines the number of logical units to move up or down.
          */
-        private int yOffset;
+        protected int yOffset;
 
         /**
-         * A 16-bit signed integer that defines the number of logical units to move left or right.
+         * A signed integer that defines the number of logical units to move left or right.
          */
-        private int xOffset;
+        protected int xOffset;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.offsetClipRgn;
         }
 
@@ -413,41 +393,29 @@ public class HwmfWindowing {
      */
     public static class WmfExcludeClipRect implements HwmfRecord, HwmfObjectTableEntry {
 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * lower-right corner of the rectangle.
-         */
-        private int bottom;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * lower-right corner of the rectangle.
-         */
-        private int right;
-
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int top;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int left;
+        /** a rectangle in logical units */
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.excludeClipRect;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            bottom = leis.readShort();
-            right = leis.readShort();
-            top = leis.readShort();
-            left = leis.readShort();
+            // 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;
         }
 
@@ -468,41 +436,29 @@ public class HwmfWindowing {
      */
     public static class WmfIntersectClipRect implements HwmfRecord, HwmfObjectTableEntry {
 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * lower-right corner of the rectangle.
-         */
-        private int bottom;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * lower-right corner of the rectangle.
-         */
-        private int right;
-
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int top;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int left;
+        /** a rectangle in logical units */
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.intersectClipRect;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            bottom = leis.readShort();
-            right = leis.readShort();
-            top = leis.readShort();
-            left = leis.readShort();
+            // 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;
         }
 
@@ -528,7 +484,7 @@ public class HwmfWindowing {
         private int region;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.selectClipRegion;
         }
 
@@ -650,7 +606,7 @@ public class HwmfWindowing {
         private WmfScanObject scanObjects[];
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.createRegion;
         }
 

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java Fri Sep 14 21:37:37 2018
@@ -51,8 +51,7 @@ public class HwmfPicture {
     
     public HwmfPicture(InputStream inputStream) throws IOException {
 
-        try (BufferedInputStream bis = new BufferedInputStream(inputStream, 10000);
-             LittleEndianInputStream leis = new LittleEndianInputStream(bis)) {
+        try (LittleEndianInputStream leis = new LittleEndianInputStream(inputStream)) {
             placeableHeader = HwmfPlaceableHeader.readHeader(leis);
             header = new HwmfHeader(leis);
 
@@ -82,17 +81,12 @@ public class HwmfPicture {
                 if (wrt == HwmfRecordType.eof) {
                     break;
                 }
-                if (wrt.clazz == null) {
+                if (wrt.constructor == null) {
                     throw new IOException("unsupported record type: "+recordFunction);
                 }
 
-                HwmfRecord wr;
-                try {
-                    wr = wrt.clazz.newInstance();
-                    records.add(wr);
-                } catch (Exception e) {
-                    throw (IOException)new IOException("can't create wmf record").initCause(e);
-                }
+                final HwmfRecord wr = wrt.constructor.get();
+                records.add(wr);
 
                 consumedSize += wr.init(leis, recordSize, recordFunction);
                 int remainingSize = (int)(recordSize - consumedSize);

Modified: poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java (original)
+++ poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java Fri Sep 14 21:37:37 2018
@@ -25,13 +25,13 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.poi.POIDataSamples;
-import org.apache.poi.hemf.extractor.HemfExtractor;
-import org.apache.poi.hemf.hemfplus.record.HemfPlusHeader;
-import org.apache.poi.hemf.hemfplus.record.HemfPlusRecord;
-import org.apache.poi.hemf.hemfplus.record.HemfPlusRecordType;
-import org.apache.poi.hemf.record.HemfCommentEMFPlus;
-import org.apache.poi.hemf.record.HemfCommentRecord;
-import org.apache.poi.hemf.record.HemfRecord;
+import org.apache.poi.hemf.record.emf.HemfComment.EmfComment;
+import org.apache.poi.hemf.record.emf.HemfComment.EmfCommentDataPlus;
+import org.apache.poi.hemf.record.emf.HemfRecord;
+import org.apache.poi.hemf.record.emfplus.HemfPlusHeader;
+import org.apache.poi.hemf.record.emfplus.HemfPlusRecord;
+import org.apache.poi.hemf.record.emfplus.HemfPlusRecordType;
+import org.apache.poi.hemf.usermodel.HemfPicture;
 import org.junit.Test;
 
 public class HemfPlusExtractorTest {
@@ -39,7 +39,7 @@ public class HemfPlusExtractorTest {
     @Test
     public void testBasic() throws Exception {
         //test header
-        HemfCommentEMFPlus emfPlus = getCommentRecord("SimpleEMF_windows.emf", 0);
+        EmfCommentDataPlus emfPlus = getCommentRecord("SimpleEMF_windows.emf", 0);
         List<HemfPlusRecord> records = emfPlus.getRecords();
         assertEquals(1, records.size());
         assertEquals(HemfPlusRecordType.header, records.get(0).getRecordType());
@@ -72,24 +72,20 @@ public class HemfPlusExtractorTest {
     }
 
 
-    private HemfCommentEMFPlus getCommentRecord(String testFileName, int recordIndex) throws Exception {
-        InputStream is = null;
-        HemfCommentEMFPlus returnRecord = null;
-
-        try {
-            is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream(testFileName);
-            HemfExtractor ex = new HemfExtractor(is);
+    private EmfCommentDataPlus getCommentRecord(String testFileName, int recordIndex) throws Exception {
+        EmfCommentDataPlus returnRecord = null;
+
+        try (InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream(testFileName)) {
+            HemfPicture ex = new HemfPicture(is);
             int i = 0;
             for (HemfRecord record : ex) {
                 if (i == recordIndex) {
-                    HemfCommentRecord commentRecord = ((HemfCommentRecord) record);
-                    returnRecord = (HemfCommentEMFPlus) commentRecord.getComment();
+                    EmfComment commentRecord = ((EmfComment) record);
+                    returnRecord = (EmfCommentDataPlus) commentRecord.getCommentData();
                     break;
                 }
                 i++;
             }
-        } finally {
-            is.close();
         }
         return returnRecord;
     }

Copied: poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java (from r1840385, poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/extractor/HemfExtractorTest.java)
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java?p2=poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java&p1=poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/extractor/HemfExtractorTest.java&r1=1840385&r2=1840956&rev=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/extractor/HemfExtractorTest.java (original)
+++ poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java Fri Sep 14 21:37:37 2018
@@ -16,179 +16,182 @@
 ==================================================================== */
 
 
-package org.apache.poi.hemf.extractor;
+package org.apache.poi.hemf.usermodel;
 
 import static org.apache.poi.POITestCase.assertContains;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
+import java.awt.geom.Point2D;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import org.apache.poi.POIDataSamples;
-import org.apache.poi.hemf.record.AbstractHemfComment;
-import org.apache.poi.hemf.record.HemfCommentPublic;
-import org.apache.poi.hemf.record.HemfCommentRecord;
-import org.apache.poi.hemf.record.HemfHeader;
-import org.apache.poi.hemf.record.HemfRecord;
-import org.apache.poi.hemf.record.HemfRecordType;
-import org.apache.poi.hemf.record.HemfText;
+import org.apache.poi.hemf.record.emf.HemfComment;
+import org.apache.poi.hemf.record.emf.HemfComment.EmfComment;
+import org.apache.poi.hemf.record.emf.HemfComment.EmfCommentDataFormat;
+import org.apache.poi.hemf.record.emf.HemfComment.EmfCommentDataMultiformats;
+import org.apache.poi.hemf.record.emf.HemfHeader;
+import org.apache.poi.hemf.record.emf.HemfRecord;
+import org.apache.poi.hemf.record.emf.HemfRecordType;
+import org.apache.poi.hemf.record.emf.HemfText;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.RecordFormatException;
 import org.junit.Test;
 
-public class HemfExtractorTest {
+public class HemfPictureTest {
+
+    private POIDataSamples samples = POIDataSamples.getSpreadSheetInstance();
 
     @Test
     public void testBasicWindows() throws Exception {
-        InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleEMF_windows.emf");
-        HemfExtractor ex = new HemfExtractor(is);
-        HemfHeader header = ex.getHeader();
-        assertEquals(27864, header.getBytes());
-        assertEquals(31, header.getRecords());
-        assertEquals(3, header.getHandles());
-        assertEquals(346000, header.getMicrometersX());
-        assertEquals(194000, header.getMicrometersY());
-
-        int records = 0;
-        for (HemfRecord record : ex) {
-            records++;
-        }
+        try (InputStream is = samples.openResourceAsStream("SimpleEMF_windows.emf")) {
+            HemfPicture pic = new HemfPicture(is);
+            HemfHeader header = pic.getHeader();
+            assertEquals(27864, header.getBytes());
+            assertEquals(31, header.getRecords());
+            assertEquals(3, header.getHandles());
+            assertEquals(346000, header.getMicrometersX());
+            assertEquals(194000, header.getMicrometersY());
 
-        assertEquals(header.getRecords() - 1, records);
+            List<HemfRecord> records = pic.getRecords();
+
+            assertEquals(31, records.size());
+        }
     }
 
     @Test
     public void testBasicMac() throws Exception {
-        InputStream is =
-                POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleEMF_mac.emf");
-        HemfExtractor ex = new HemfExtractor(is);
-        HemfHeader header = ex.getHeader();
-
-        int records = 0;
-        boolean extractedData = false;
-        for (HemfRecord record : ex) {
-            if (record.getRecordType() == HemfRecordType.comment) {
-                AbstractHemfComment comment = ((HemfCommentRecord) record).getComment();
-                if (comment instanceof HemfCommentPublic.MultiFormats) {
-                    for (HemfCommentPublic.HemfMultiFormatsData d : ((HemfCommentPublic.MultiFormats) comment).getData()) {
-                        byte[] data = d.getData();
-                        //make sure header starts at 0
-                        assertEquals('%', data[0]);
-                        assertEquals('P', data[1]);
-                        assertEquals('D', data[2]);
-                        assertEquals('F', data[3]);
-
-                        //make sure byte array ends at EOF\n
-                        assertEquals('E', data[data.length - 4]);
-                        assertEquals('O', data[data.length - 3]);
-                        assertEquals('F', data[data.length - 2]);
-                        assertEquals('\n', data[data.length - 1]);
-                        extractedData = true;
+        try (InputStream is = samples.openResourceAsStream("SimpleEMF_mac.emf")) {
+            HemfPicture pic = new HemfPicture(is);
+            HemfHeader header = pic.getHeader();
+
+            int records = 0;
+            boolean extractedData = false;
+            for (HemfRecord record : pic) {
+                if (record.getEmfRecordType() == HemfRecordType.comment) {
+                    HemfComment.EmfCommentData comment = ((EmfComment) record).getCommentData();
+                    if (comment instanceof EmfCommentDataMultiformats) {
+                        for (EmfCommentDataFormat d : ((EmfCommentDataMultiformats) comment).getFormats()) {
+                            byte[] data = d.getRawData();
+                            //make sure header starts at 0
+                            assertEquals('%', data[0]);
+                            assertEquals('P', data[1]);
+                            assertEquals('D', data[2]);
+                            assertEquals('F', data[3]);
+
+                            //make sure byte array ends at EOF\n
+                            assertEquals('E', data[data.length - 4]);
+                            assertEquals('O', data[data.length - 3]);
+                            assertEquals('F', data[data.length - 2]);
+                            assertEquals('\n', data[data.length - 1]);
+                            extractedData = true;
+                        }
                     }
                 }
+                records++;
             }
-            records++;
+            assertTrue(extractedData);
+            assertEquals(header.getRecords(), records);
         }
-        assertTrue(extractedData);
-        assertEquals(header.getRecords() - 1, records);
     }
 
     @Test
     public void testMacText() throws Exception {
-        InputStream is =
-                POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleEMF_mac.emf");
-        HemfExtractor ex = new HemfExtractor(is);
-
-        long lastY = -1;
-        long lastX = -1;
-        long fudgeFactorX = 1000;//derive this from the font information!
-        StringBuilder sb = new StringBuilder();
-        for (HemfRecord record : ex) {
-            if (record.getRecordType().equals(HemfRecordType.exttextoutw)) {
-                HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record;
-                if (lastY > -1 && lastY != extTextOutW.getY()) {
-                    sb.append("\n");
-                    lastX = -1;
-                }
-                if (lastX > -1 && extTextOutW.getX() - lastX > fudgeFactorX) {
-                    sb.append(" ");
+        try (InputStream is = samples.openResourceAsStream("SimpleEMF_mac.emf")) {
+            HemfPicture pic = new HemfPicture(is);
+
+            double lastY = -1;
+            double lastX = -1;
+            //derive this from the font information!
+            long fudgeFactorX = 1000;
+            StringBuilder sb = new StringBuilder();
+            for (HemfRecord record : pic) {
+                if (record.getEmfRecordType().equals(HemfRecordType.exttextoutw)) {
+                    HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record;
+                    Point2D reference = extTextOutW.getTextObject().getReference();
+                    if (lastY > -1 && lastY != reference.getY()) {
+                        sb.append("\n");
+                        lastX = -1;
+                    }
+                    if (lastX > -1 && reference.getX() - lastX > fudgeFactorX) {
+                        sb.append(" ");
+                    }
+                    sb.append(extTextOutW.getText());
+                    lastY = reference.getY();
+                    lastX = reference.getX();
                 }
-                sb.append(extTextOutW.getText());
-                lastY = extTextOutW.getY();
-                lastX = extTextOutW.getX();
             }
+            String txt = sb.toString();
+            assertContains(txt, "Tika http://incubator.apache.org");
+            assertContains(txt, "Latest News\n");
         }
-        String txt = sb.toString();
-        assertContains(txt, "Tika http://incubator.apache.org");
-        assertContains(txt, "Latest News\n");
     }
 
     @Test
     public void testWindowsText() throws Exception {
-        InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleEMF_windows.emf");
-        HemfExtractor ex = new HemfExtractor(is);
-        long lastY = -1;
-        long lastX = -1;
-        long fudgeFactorX = 1000;//derive this from the font or frame/bounds information
-        StringBuilder sb = new StringBuilder();
-        Set<String> expectedParts = new HashSet<>();
-        expectedParts.add("C:\\Users\\tallison\\");
-        expectedParts.add("testPDF.pdf");
-        int foundExpected = 0;
-        for (HemfRecord record : ex) {
-            if (record.getRecordType().equals(HemfRecordType.exttextoutw)) {
-                HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record;
-                if (lastY > -1 && lastY != extTextOutW.getY()) {
-                    sb.append("\n");
-                    lastX = -1;
-                }
-                if (lastX > -1 && extTextOutW.getX() - lastX > fudgeFactorX) {
-                    sb.append(" ");
-                }
-                String txt = extTextOutW.getText();
-                if (expectedParts.contains(txt)) {
-                    foundExpected++;
+        try (InputStream is = samples.openResourceAsStream("SimpleEMF_windows.emf")) {
+            HemfPicture pic = new HemfPicture(is);
+            double lastY = -1;
+            double lastX = -1;
+            long fudgeFactorX = 1000;//derive this from the font or frame/bounds information
+            StringBuilder sb = new StringBuilder();
+            Set<String> expectedParts = new HashSet<>();
+            expectedParts.add("C:\\Users\\tallison\\");
+            expectedParts.add("testPDF.pdf");
+            int foundExpected = 0;
+            for (HemfRecord record : pic) {
+                if (record.getEmfRecordType().equals(HemfRecordType.exttextoutw)) {
+                    HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record;
+                    Point2D reference = extTextOutW.getTextObject().getReference();
+                    if (lastY > -1 && lastY != reference.getY()) {
+                        sb.append("\n");
+                        lastX = -1;
+                    }
+                    if (lastX > -1 && reference.getX() - lastX > fudgeFactorX) {
+                        sb.append(" ");
+                    }
+                    String txt = extTextOutW.getText();
+                    if (expectedParts.contains(txt)) {
+                        foundExpected++;
+                    }
+                    sb.append(txt);
+                    lastY = reference.getY();
+                    lastX = reference.getX();
                 }
-                sb.append(txt);
-                lastY = extTextOutW.getY();
-                lastX = extTextOutW.getX();
             }
+            String txt = sb.toString();
+            assertContains(txt, "C:\\Users\\tallison\\\n");
+            assertContains(txt, "asf2-git-1.x\\tika-\n");
+            assertEquals(expectedParts.size(), foundExpected);
         }
-        String txt = sb.toString();
-        assertContains(txt, "C:\\Users\\tallison\\\n");
-        assertContains(txt, "asf2-git-1.x\\tika-\n");
-        assertEquals(expectedParts.size(), foundExpected);
     }
 
     @Test(expected = RecordFormatException.class)
     public void testInfiniteLoopOnFile() throws Exception {
-        InputStream is = null;
-        try {
-            is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("61294.emf");
-
-            HemfExtractor ex = new HemfExtractor(is);
-            for (HemfRecord record : ex) {
+        try (InputStream is = samples.openResourceAsStream("61294.emf")) {
+            HemfPicture pic = new HemfPicture(is);
+            for (HemfRecord record : pic) {
 
             }
-        } finally {
-            IOUtils.closeQuietly(is);
         }
     }
 
     @Test(expected = RecordFormatException.class)
     public void testInfiniteLoopOnByteArray() throws Exception {
-        InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("61294.emf");
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        IOUtils.copy(is, bos);
-        is.close();
+        try (InputStream is = samples.openResourceAsStream("61294.emf")) {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            IOUtils.copy(is, bos);
+            is.close();
 
-        HemfExtractor ex = new HemfExtractor(new ByteArrayInputStream(bos.toByteArray()));
-        for (HemfRecord record : ex) {
+            HemfPicture pic = new HemfPicture(new ByteArrayInputStream(bos.toByteArray()));
+            for (HemfRecord record : pic) {
 
+            }
         }
     }
 

Modified: poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java (original)
+++ poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java Fri Sep 14 21:37:37 2018
@@ -222,11 +222,11 @@ public class TestHwmfParsing {
         //this happens to work on this test file, but you need to
         //do what Graphics does by maintaining the stack, etc.!
         for (HwmfRecord r : wmf.getRecords()) {
-            if (r.getRecordType().equals(HwmfRecordType.createFontIndirect)) {
+            if (r.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) {
                 HwmfFont font = ((HwmfText.WmfCreateFontIndirect)r).getFont();
                 charset = (font.getCharset().getCharset() == null) ? LocaleUtil.CHARSET_1252 : font.getCharset().getCharset();
             }
-            if (r.getRecordType().equals(HwmfRecordType.extTextOut)) {
+            if (r.getWmfRecordType().equals(HwmfRecordType.extTextOut)) {
                 HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut)r;
                 sb.append(textOut.getText(charset)).append("\n");
             }
@@ -250,11 +250,11 @@ public class TestHwmfParsing {
         //this happens to work on this test file, but you need to
         //do what Graphics does by maintaining the stack, etc.!
         for (HwmfRecord r : wmf.getRecords()) {
-            if (r.getRecordType().equals(HwmfRecordType.createFontIndirect)) {
+            if (r.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) {
                 HwmfFont font = ((HwmfText.WmfCreateFontIndirect)r).getFont();
                 charset = (font.getCharset().getCharset() == null) ? LocaleUtil.CHARSET_1252 : font.getCharset().getCharset();
             }
-            if (r.getRecordType().equals(HwmfRecordType.extTextOut)) {
+            if (r.getWmfRecordType().equals(HwmfRecordType.extTextOut)) {
                 HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut)r;
                 sb.append(textOut.getText(charset)).append("\n");
             }



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